home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
teach.zip
/
TEACH2A.ATF
< prev
next >
Wrap
Text File
|
1997-09-15
|
61KB
|
748 lines
XNÉIO 0 1 °
XNÉCT 0 1E²13 °
XCÉFC 1 6 .,*0_² °
XNÉRL 0 1399399247 °
XCÉPR 1 1 °
XCÉLX 1 5 TEACH °
XNCOINS 1 5 0.01 0.05 0.1 0.25 0.5 °
*(1997 8 4 14 0 49 368) °
FCOMPLEX ÉFX 'COMPLEX' 'Σ Explain complex numbers' °
'''The mysteries of square roots have been known to the ancient Greeks °
.''' °
'''It was Pythagoras or one of his colleagues who discovered that the °
square''' °
'''root of two could not be represented as the ratio of two integers. °
It''' °
'''took another 2000 years before mathematicians could tackle the prob °
lem''' °
'''of the square roots of negative numbers. In order to extend the num °
ber''' °
'''domain, mathematicians developed (invented?) the concept of complex °
''' °
'''numbers. These are number pairs, composed of a "real" number, and a °
n''' °
'''"imaginary" number. The "imaginary" component is a "real" number''' °
'''multiplied by "i", the square root of ²1.'',r' °
'''In APL2, complex numbers are represented as a single "scalar". The' °
'' °
'''"real" and "imaginary" components are separated by the letter J.''' °
'''For example, "i" is written in APL2 as 0J1.'',r' °
'''If you have no experience dealing with complex numbers, you may''' °
'''ignore any and all references to them in these tutorials.''' °
X 'endd' °
*(1997 9 14 12 30 44 504) °
XFDISCLAIMER ÉFX 'DISCLAIMER' 'Σ Copyright statement' 'disclaimer' °
*(1997 4 27 12 39 5 416) °
FDISPLAY ÉFX 'D╜S DISPLAY A;ÉIO;R;C;HL;HC;HT;HB;VL;VB;V;W;N;B' °
'Σ DISPLAY A GENERAL ARRAY IN PICTORIAL FORM' °
'Σ NORMAL CALL IS MONADIC. DYADIC CALL USED ONLY IN' °
'Σ RECURSION TO SPECIFY DISPLAY RANK, SHAPE, AND DEPTH.' 'ÉIO╜0' °
'»(0=ÉNC ''S'')/''S╜µA''' 'R╜╞µ,S Σ PSEUDO RANK.' °
'C╜''┐┌└┘'' Σ UR, UL, LL, AND LR CORNERS.' °
'HL╜''─'' Σ HORIZONTAL LINE.' °
'HC╜HL,''Θ╕'',HL,''~+ε'' Σ HORIZONTAL BORDERS.' °
'HT╜HC[(0<R)⌡1+0<╞²1╞,S]' 'ΣW╜,0╧■╞0µΓ(1⌐µA)╞A' °
'HB╜HC[3+3╛(''2⌡~A╧«A'' ÉEA ''1+╞ε0⌡(1⌐⌡/µA)╞,A'')+3⌡1<µµS]' °
'VL╜''│'' Σ VERTICAL LINE.' °
'VB╜VL,''Φ╟'' Σ VERTICAL BORDER.' °
'V╜VB[(1<R)⌡1+0<²1╞²1╟,S]' °
'»(0εµA)/''A╜(1⌐µA)µΓ╞A'' Σ SHOW PROTOTYPE OF EMPTIES.' °
'╕(1<╧A)/GEN' '╕(2<µµA)/D3' °
'D╜«A Σ SIMPLE ARRAYS.' 'W╜1╞µD╜(²2╞1 1,µD)µD' °
'N╜²1+1╟µD' '╕(0=µµA)/SS' °
'D╜(C[1],V,((W-1)µVL),C[2]),((HT,NµHL),[0]D,[0]HB,NµHL),C[0],(WµVL),C[ °
3]' '╕0' 'SS:HB╜((0 '' '')=╞0µΓA)/'' -''' °
'D╜'' '',('' '',[0]D,[0]HB,Nµ'' ''),'' ''' '╕0' °
'GEN:D╜«DISPLAY■A Σ ENCLOSED ...' 'N╜Dδ.⌠'' ''' °
'D╜(Nδ~1ΦN)≡D' 'D╜(δ≡~'' ''╤D)/D' 'D╜((1,µS)µS)DISPLAY D' °
'╕(2≥µ,S)╟D3E,0' 'D3:D╜0 ²1╟0 1╟«ΓA Σ MULT-DIMENSIONAL ...' °
'W╜1╞µD' 'N╜²1+1╟µD' °
'D╜(C[1],V,((W-1)µVL),C[2]),((HT,NµHL),[0]D,[0]HB,NµHL),C[0],(WµVL),C[ °
3]' 'D3E:N╜²2+µ,S' °
X 'V╜C[Nµ1],[0]VB[1+0<²2╟,S],[0](((²3+╞µD),N)µVL),[0]C[Nµ2]' 'D╜V,D' °
*(1997 4 27 12 39 5 416) °
FEXIT ÉFX 'EXIT' 'Σ Exit from function' '''To log off type: )OFF''' °
X '╕' °
*(1996 4 6 15 59 48 592) °
FGO ÉFX 'GO;T;E;B' 'Σ Expression driver' 'L0:B╜E╜''''' 'æ╜'' ''' °
'T╜æ' '╕(^/'' ''=T)/L0' '╕((^/'')OFF ''=5╞6╟T)doif ''EXIT'')/0' °
'╕(('':''εT)doif ''B╜evaldd (+/^\'''' ''''=T)╟T'')/L0' °
'''E╜ÉEM'' ÉEA T' '╕(0=µ,E)/L0' '╕B/L0' °
'''This is not a valid APL2 expression''' 'æ╜''*''' °
X '╕(''?''⌠╞1╟æ)/L0' 'E' '╕L0' °
*(1997 8 12 12 20 18 348) °
FHELP ÉFX 'HELP;N;I;T' 'Σ Help to student' '''WHAT TO DO'',r' °
''' ° To get out of the lesson''' ''' ENTER: EXIT''' °
''' ° To log off APL2''' °
''' FIRST, ENTER: EXIT THEN ENTER: )OFF''' °
''' ° To get help''' ''' ENTER: HELP''' °
''' ° When you see the prompt on a blank line''' °
''' ENTER AN APL2 EXPRESSION - OR JUST PRESS: ENTER''' 'do' °
''' ° If you get this line'',r' °
'''This is not a valid APL2 expression'',r,''*'',r' °
''' YOU CAN EITHER''' ''' A. PRESS: ENTER''' °
''' B. PRESS: ? and then ENTER to see what was incorrect''' °
''' in your expression causing that response'',r' 'do' °
'''HINTS'',r' °
'''This lesson is made up of '',(«N╜8),'' components named TEACHx, whe °
re''' '''the x stands for a digit:'',r' 'I╜0' °
'L0:T╜''TEACH'',(«I╜I+1)' 'T,'' '',1╟notb(ÉCR T)[2;]' '╕(N>I)/L0' °
'do' °
'''You may review either of these components separately. To do that,'' °
' °
'''first enter EXIT (and RETURN), then enter the name of the lesson.'' °
' '''component (e.g. TEACH4).'',r' °
'''To re-start the lesson, just enter TEACH'',r' °
'''When the screen fills up, it is a good idea to move the cursor to'' °
' '''the start of a convenient paragraph, and press ENTER'',r' °
'''You may also wish to press PAGE UP to review the prevous pages.''' °
'do' '''RESOURCES'',r' °
'''You may also enter ONE of the following words at a time'',r' °
'''RECIPROCAL Avoiding error message with ÷ when vector contains zeros °
''' '''KEYS To display special symbols on the keyboard''' °
'''RULES Explain purpose in having RULES in this tutorial''' °
X '''RULE n Additional comments on Rule n''' 'endd' °
XNNUMBER 1 5 3 5 2 3 0 °
*(1997 9 15 12 35 48 544) °
FRECIPROCAL ÉFX 'RECIPROCAL;ZEROS' °
'Σ Expression for reciprocal of vector with zeros''' °
'''Let us generate vector ZEROS:'',r' °
'show ''ZEROS╜1 0 2 0 3 0 4 0 5''' °
'show ''(1+99⌡ZEROS=0)÷ZEROS+0=ZEROS''' °
'''Can you find a shorter expression?''' 'do' °
'''To get an expression such that ZEROS is the same as ÷÷ZEROS,''' °
'''we merely change the constant:'',r' °
'show ''ZEROS╜(1+²1⌡ZEROS=0)÷ZEROS+0=ZEROS'' ''ZEROS''' °
'''Replacing the 99 by ²1 any zero element again becomes zero. Now''' °
'''applying the same expression to the new vector ZEROS,'',r' °
'show ''(1+²1⌡ZEROS=0)÷ZEROS+0=ZEROS''' °
X '''we get the original vector ZEROS.''' 'endd' °
*(1997 5 30 13 54 49 672) °
FRULE ÉFX 'V RULE W' 'Σ Display rules' '╕(2=ÉNC ''V'')/L0' °
X '2 rule W ╪ ╕0' 'L0:V rule W' °
*(1997 8 5 12 40 15 388) °
FRULES ÉFX 'RULES' 'Σ Explain objective of rules' °
'''When studying a new subject, such as APL2, it may be convenient to' °
'' °
'''simplify a subject to enhance understanding. Rules are introduced'' °
' °
'''here as a kind of scaffold to temporarily support the APL2 theory'' °
' °
'''as it is explained in small increments. When the tutorials reach a' °
'' °
'''certain level of understanding of APL2, a more compact set of rules °
''' °
'''(called "bindings") will be discussed. At that point some of the''' °
'''rules listed here initially can be discarded.'',r' 'do' °
'''Each time a rule is given, you may wish to enter the expression'',r °
' ''' RULE n (where n is the rule number)'',r' °
'''When you do that, you will get additional comments on extensions to °
''' °
'''that rule in subsequent lessons. If you want to see BOTH the rule A °
ND''' °
'''any associated comments, enter a 1 in front of the word RULE. For'' °
' '''example, to see rule #1 and comments, enter'',r,'' 1 RULE 1''' °
X 'do' 'endd' °
*(1997 8 5 12 56 50 592) °
FTEACH ÉFX 'TEACH' 'Σ Start second lesson in APL2 by Zdenek V JIZBA' °
'exit ''TEACH''' 'initialize' 'TEACH1 Σ Vector operations' °
'TEACH2 Σ The reduction operator' 'TEACH3 Σ Zeros and nulls' °
'TEACH4 Σ The DISPLAY function' 'TEACH5 Σ Error messages' °
'TEACH6 Σ Simple APL2 algorithm: average' °
'TEACH7 Σ (Complex conjugate) Signum; avoiding divide by zero' °
'TEACH8 Σ Roll and deal' °
'''That is all for this lesson. You can continue practicing what you'' °
' °
'''have learned so far, but note that if you enter an invalid APL2''' °
X '''expression, you will see the APL2 Error Message.''' °
*(1997 8 25 13 7 5 300) °
FTEACH1 ÉFX 'TEACH1' 'Σ Introduction to lesson 2' 'exit ''TEACH1''' °
'''In the first lesson we introduced the concepts of SCALARS, VECTORS, °
''' °
'''and ARRAYS. We also discussed FUNCTIONS, VARIABLES and ASSIGNMENT.' °
'' °
'''We learned that functions can have only a right argument (MONADIC)' °
'' '''or both a right and a left argument (DYADIC).'',r' °
'''We learned that APL2 supports only two data types: NUMBERS and''' °
'''CHARACTERS. In this lesson we will expand on these concepts, and ad °
d''' '''a few more.'',r' 'do' °
'''First, let us take another look at VECTORS. Consider the following' °
'' '''specification (assignment) expression:'',r' °
'show ''COINS╜0.01 0.05 0.10 0.25 0.50''' °
'''This vector represents the five most common denominator of US coins °
:''' '''A penny, a nickel, a dime, a quarter, and a half dollar.'',r' °
'''Next, we ask someone to tell us the amount of each kind of coin in' °
'' °
'''their posession. We will record this, and store it in variable NUMB °
ER:'',r' 'show ''NUMBER╜3 5 2 3 0''' °
'''The problem now is to calculate the total amount represented by thi °
s''' °
'''collection. We start by entering the following expression:'',r' °
'show ''COINS⌡NUMBER''' °
'''Aha! We have uncovered two new aspects of APL2: First, the names of °
''' °
'''variables can be used as arguments in an expression. This should be °
''' °
'''no news if you have studied programming languages. However, one asp °
ect''' °
'''IS new, namely there was no requirement to write a code segment (su °
ch''' °
'''as a DO loop) to tell the computer how to evaluate that expression. °
''' °
'''So the first new aspect of APL2 is its ability to provide an answer °
''' °
'''without being told the procedure. This property of a computer langu °
age''' °
'''is called NON-PROCEDURAL. So at the level of primitive functions,'' °
' '''APL2 is a NON-PROCEDURAL language.''' 'do' °
'''A second aspect of the expression COINS⌡NUMBER is the fact that''' °
'''primitive functions can be applied to two vectors. As we will see'' °
' °
'''there are strict, but reasonable limitations on this. Both COINS''' °
'''and NUMBER are vectors of length 5. APL2 cannot handle processing'' °
' °
'''of data that is incompatible. This is why the last element of vecto °
r''' °
'''NUMBER is a zero. It indicates that the coin collection has no half °
''' '''dollars by the presence of that zero.'',r' °
'''Does this mean that a vector must always be operated on by another' °
'' °
'''vector of the same length? Not at all. Suppose that someone were to °
''' '''double the number of coins in the collection:'',r' °
'show ''2⌡NUMBER''' °
'''Here we multiplied a scalar (2) by a vector. So for the time being' °
'' '''let us write down the following rule:'',2µr' '0 RULE 1' °
'''Later we will see how this rule can be expanded.''' °
'''RULE 1 applies to arithmetic operations. Does this mean that there' °
'' °
'''are primitive functions that allow processing of vectors with diffe °
rent''' °
'''shapes? Indeed this is the case. We already saw one example:'',r' °
'show ''''''ABORIGINE''''ε''''AEIOU''''''' °
'''In this expression the left argument has shape 9 and the right argu °
ment''' '''has the shape 5.'',r' °
'''Before returning to the coin problem, here are some comments on the °
''' '''rules given in this and in the next few tutorial lessons:'',r' °
X ''' RULES'',r' 'RULES' °
*(1997 5 31 11 14 27 420) °
FTEACH2 ÉFX 'TEACH2' 'Σ Introduce the reduction operator' °
'exit ''TEACH2''' °
'''When we multiply COINS⌡NUMBER, the result is yet another vector.''' °
'''but this is not what we want. What we desire is the SUM of the''' °
'''individual components of this vector.'',r' °
'''APL2 provides a special symbol (/) to solve this type of a problem. °
''' °
'''The slash is neither a primitive function nor a variable. It is''' °
'''called a REDUCTION OPERATOR. An OPERATOR is neither a function nor' °
'' °
'''a variable. It is a special symbol that tells APL2 what kind of''' °
'''process is to be performed. APL2 supports several such OPERATORS.'' °
' '''But now let us see how the REDUCTION OPERATOR works:'',r' °
'show ''+/COINS⌡NUMBER''' °
'''Somehow this expression produced the total amount of money in the'' °
' °
'''coin collection. We already know that COINS⌡NUMBER produce a vector °
:'',r' 'show ''COINS⌡NUMBER''' '''The +/ does the equivalent of:'',r' °
'show ''0.03 + 0.25 + 0.2 + 0.75 + 0''' °
'''(It places the symbol + between all pairs in the vector.)'',r' °
'''But why the name REDUCTION? It is called that because for a vector' °
'' '''right argument it reduces the result to a scalar.'',r' °
'''Note also that the symbols +/ were placed to the LEFT of COINS⌡NUMB °
ER.''' °
'''Since COINS⌡NUMBER must be evaluated first, we MUST conclude that'' °
' '''evaluation proceeds from right to left. More on that later.''' °
'do' '''Let us tentatively write the following rule:'',2µr' °
'0 RULE 2' 'do' '''Let us see some examples:'',r' °
'show ''+/1 1 1'' ''⌡/1 2 3'' ''-/1 2 3''' °
'''The last example brings out a new problem. If we begin from left'', °
r' 'show ''-/1 2''' °
'''and then apply this result to the third element'',r' °
'show ''-/²1 3''' °
'''So if we solve 1 - 2 - 3 by evaluating the expression from left to' °
'' °
'''right, we get the wrong answer. If we do it from right to left:'',r °
' 'show ''-/2 3'' ''-/1 ²1''' °
'''we get the correct answer. So we have yet another rule:'',2µr' °
X '0 RULE 3' 'endd' °
*(1997 5 31 11 20 13 388) °
FTEACH3 ÉFX 'TEACH3' 'Σ Zeros and nulls' 'exit ''TEACH3''' °
'''Before we leave the reduction operator, we must tackle what may''' °
'''appear to be a trivial concept (BUT IS DEFINITELY NOT).'',r' °
''' ZEROS AND NULLS'',r' °
'''IF THIS IS THE FIRST TIME YOU READ ABOUT APL2, THIS SECTION MAY SEE °
M''' °
'''TOO DIFFICULT. PLEASE, TRY TO FOLLOW THE DISCUSSION, BUT DO NOT''' °
'''BE DISCOURAGED IF IT DOES NOT MAKE SENSE TO YOU. THE SUBJECT MAY NO °
T''' '''BE FAMILIAR, BUT IT IS IMPORTANT.''' 'do' °
'''In lesson 1 we learned how to use the ∞ (iota) monadic function to' °
'' °
'''generate vectors of the ordinal sequence of integers. We also learn °
ed''' °
'''to use the monadic function µ (shape) to tell us the length of a''' °
'''vector. APL2 was designed to be LOGICALLY, and MATHEMATICALLY true' °
'' °
'''no matter what the expressions, as long as these are valid. Let us' °
'' '''see where that will lead us:'',r' 'show ''µ5'' ''µ''''X''''''' °
'''Since 5 and ''''X'''' are scalars, they have NO SHAPE. This is refl °
ected''' °
'''in the fact that the shape of a scalar returns nothing. But nothing °
''' °
'''is not a valid datum. There must be some representation of nothing. °
''' 'do' °
'''To see how APL2 resolves this, consider the following sequence of'' °
' '''vectors:'',r' 'show ''∞2'' ''µ∞2'' ''∞1'' ''µ∞1'' ''∞0'' ''µ∞0''' °
'''Obviously, the index generator function ∞ ALWAYS generates a vector °
''' °
'''even for the integer 1. It even generates a vector for the zero!''' °
'''So the result of ∞1 is NOT a scalar, but a VECTOR OF LENGTH 1.''' °
'''Similarly the result of ∞0 is not nothing, but a VECTOR OF LENGTH'' °
' °
'''ZERO. Note that the result of ∞0 is the same as the result of µ5.'' °
' 'do' '''We can test this hypothesis by'',r' 'show ''µµ5''' °
'''So we have the following rules:'',2µr' '0 RULE 4' '0 RULE 5' 'do' °
'''When we wanted to know the shape of the shape of a scalar (µµ5)''' °
'''we obtained a zero. The application of one or more primitive''' °
'''functions in an APL2 expression has a special name. It is called''' °
'''an IDIOM. (∞µ would be an example of another idiom).''' 'do' °
'''The µµ idiom is so important that it has its own name. It is called °
''' °
'''the RANK. The rank of a scalar is zero, and the rank of a vector is °
''' °
'''one. In lesson 1 we used the reshape (dyadic µ) to generate a table °
.''' °
'''Such a table has a rank of 2. In a later lesson we will study APL2' °
'' °
'''objects of rank greater than TWO. Indeed in APL2OS2 the maximum ran °
k''' '''is 64.''' 'do' °
'''Before we leave this subject, we should also study how reduction''' °
'''works on scalars and vectors of length 0.'',r' °
'show ''+/5'' ''+/∞1''' °
'''The reduction of a scalar (or a vector of length one) returns that' °
'' °
'''scalar (or vector). But now, since reduction by definition reduces' °
'' °
'''the rank by one. (We have not stated this, but recall that the''' °
'''reduction of a vector produces a scalar), what should be the shape' °
'' '''of +/5? This is handled in APL2 by another rule:'',2µr' °
'0 RULE 6' 'do' '''This rule has some interesting consequences:''' °
'show ''+/''''A'''''' ''-/5'' ''ε/0''' 'do' °
'''Finally, what happens when we reduce a null vector?'',r' °
'show ''+/∞0'' ''⌡/∞0''' °
'''We will study this in more detail in another session, but right''' °
'''now, note that the result is such that it would have no effect''' °
'''for addition in +/∞0, and no effect for multiplication in ⌡/∞0.''' °
'''The rule that applies here is one that you may for the time''' °
X '''being ignore:'',2µr' '0 RULE 7' 'endd' °
*(1997 5 4 12 14 5 228) °
FTEACH4 ÉFX 'TEACH4' 'Σ IBM function DISPLAY' 'exit ''TEACH4''' °
'''In lesson 1 we alluded to the existence of APL2 programs, but we''' °
'''called them USER DEFINED FUNCTIONS. You already have seen some of'' °
' '''these (EXIT KEYBOARD). Function EXIT will get you out of the''' °
'''lesson, so that you can log off the APL2 session.'',r' °
''' (Function KEYBOARD is available only in lesson 1).''' 'do' °
'''There is another function that you should know about. It is provide °
d''' °
'''by IBM, and is called DISPLAY. It is very useful in decribing''' °
'''graphically the contents of a variable. Let us look at some APL2''' °
'''objects and their shape with DISPLAY:'',r' °
'show ''DISPLAY (∞2) (µ∞2)'' ''DISPLAY (∞1) (µ∞1)'' ''DISPLAY (∞0) (µ∞ °
0)''' °
'''Note that each example shows a box with two boxes inside. Each''' °
'''box has an arrow (╕) in the upper left corner. This means that''' °
'''the object in the box is a vector. When a box contains inner boxes, °
''' °
'''we talk about NESTED VECTORS. We will study these in future lessons °
.''' '''Let us see what scalars look like:'',r' °
'show ''DISPLAY 1 (µ1)'' ''DISPLAY ''''A'''' (µ''''A'''')''' °
'''Note that scalars are not enclosed in a box, but the shape of scala °
rs''' °
'''is indeed a vector. The box enclosing µ1 and µ''''A'''' has the Θ s °
ymbol on''' °
'''top. This symbol indicates that the object is NULL. We will postpon °
e''' °
'''the study of nulls until much later, but meanwhile consider the''' °
'''following strange APL2 objects:'',r' °
X 'show ''DISPLAY (µ1) (µ'''' '''') ('''''''') (∞0)''' 'endd' °
*(1997 5 4 12 15 44 388) °
FTEACH5 ÉFX 'TEACH5' 'Σ Error messages' 'exit ''TEACH5''' °
''' ERROR MESSAGES'',r' °
'''Whenever you enter invalid APL2 expressions, the result is a''' °
'''message describing the nature of the error. In this and all''' °
'''subsequent lessons, this ERROR MESSAGE is TRAPPED (you will NOT''' °
'''see it). Instead you will see the following:'',r' °
'''This is not a valid APL2 expression'',r,''*'',r' °
'''To see the actual error message, you have to enter ? just to the''' °
'''right of the *. Go ahead, and try it, enter a nonsense line, and''' °
'''then press ENTER. Then enter ? and press ENTER again.''' 'do' °
'''In this lesson, nothing else happens. The lesson will continue''' °
'''no matter how bad your expression. Outside this lesson, however,''' °
'''the error message causes an INTERRUPT. This means that further''' °
'''execution has stopped in order to give you a chance to correct''' °
'''the error.''' 'do' °
'''Typically, the error message comes in three lines. The first line'' °
' °
'''identifies the error TYPE. The second line reprints the offending'' °
' °
'''expression. This is needed because in running applications the bad' °
'' °
'''line will not be visible. The third line of the error message shows °
''' °
'''a caret (^) symbol at the place of the expression where the error'' °
' '''was detected.''' 'do' °
'''There will be another lesson with more details. Meanwhile, let us'' °
' '''generate some typical errors:'',r' °
X 'errors ''ONE'' ''2 3+1 2 3'' ''''''A''''⌡3''' 'endd' °
*(1997 5 31 11 21 26 444) °
FTEACH6 ÉFX 'TEACH6;VECTOR;A' 'Σ Average of a vector of numbers' °
'exit ''TEACH6''' °
'''Before we leave this lesson, let us begin solving some real life''' °
'''problems. For example, how about writing a formula for calculating' °
'' °
'''the average of a sequence of numbers. (We already know what to call °
''' '''that sequence: a vector.)''' 'do' °
'''The average is obtained by adding all numbers, and by dividing the' °
'' °
'''sum by the total number of values. Let us generate a random vector: °
'',r' 'show ''VECTOR╜23 64 71 89 34''' °
'''We know how to add these:'',r' 'show ''+/VECTOR''' °
'''We also know how to count the number of entries in VECTOR:'',r' °
'show ''µVECTOR''' °
'A╜(«+/VECTOR),''÷'',(«µVECTOR),'' or '',«(+/VECTOR)÷µVECTOR' °
'''Let'',q,''s see; the average should be '',A' 'do' °
'''Can we combine these calculations into a single expression? What''' °
'''about the following one:'',r' 'show ''+/VECTOR÷µVECTOR''' °
'''It certainly gives the right answer. But let us see how it is''' °
'''obtained. We already know that the evaluation goes from right to''' °
'''left'',r' 'show ''VECTOR÷µVECTOR''' °
'''To get this intermediate value, APL2 had to divide EACH element''' °
'''of the vector by '',(«µVECTOR),''. This is wasteful of resources.'' °
,r' °
'''After all we should get the same answer if we wait to make the''' °
'''division until after obtaining the sum (as we did earlier).''' °
'do' °
'''There is a way to tell APL2 how to sequence computation, and that'' °
' '''is with the usage of parentheses:'',r' °
'show ''(+/VECTOR)÷µVECTOR''' °
'''Now proceeding from right to left as before, APL2 obtains µVECTOR,' °
'' °
'''but before it can apply this value, it encounters a right parend''' °
'''(parend is another word for parenthesis). This stops the normal''' °
'''right to left process until after the expression in parends is''' °
'''calculated (from right to left too of course). Only then can the''' °
'''division proceed.''' 'do' °
'''The moral of this is that even though many problems can be written' °
'' °
'''in a simple linear way, some thought should always be given to''' °
'''the efficiency of the algorithm described by the expression. We hav °
e''' °
'''already commented that in APL2 there are many solutions to any one' °
'' °
'''problem. Clearly some solutions are better than others. We should'' °
' °
'''always seek the best ones, even if these are longer or more complex °
.''' 'do' °
'''While the primitive functions of APL2 are non-procedural, the proce °
dural''' °
'''aspects in problem solving must not be ignored. Therefore:'',2µr' °
X '0 RULE 8' 'endd' °
*(1997 8 25 13 13 21 388) °
FTEACH7 ÉFX 'TEACH7;VECTOR' 'Σ Summary' 'exit ''TEACH7''' °
'''In lesson 1 you were asked to try out various APL2 expressions''' °
'''using the newly defined primitive functions. Did you try to use''' °
'''monadic arithmetic functions?''' 'do' °
'show ''VECTOR╜23 ²33.56 0'' ''+VECTOR'' ''⌡VECTOR'' ''÷VECTOR+0=VECTO °
R''' '''Let us take another look at each of these expressions.'',r' °
'show ''+VECTOR''' °
'''Clearly +VECTOR does not seem to have an effect. It does not for''' °
'''numbers that are REAL. (For COMPLEX numbers the monadic plus''' °
'''produces the COMPLEX CONJUGATE.) Enter COMPLEX for more on complex' °
'' '''numbers.''' 'do' °
'''We will give examples of complex number calculations in subsequent' °
'' °
'''lessons. You should ignore these if you are not familiar with that' °
'' '''subject.''' 'do' 'show ''⌡VECTOR''' °
'''Clearly the monadic ⌡ does have an effect. For positive numbers it' °
'' °
'''produces a 1, it leaves zeros unchanged, and for negative numbers'' °
' °
'''it produces a ²1. The monadic TIMES is called the SIGNUM. It can be °
''' '''used to return the sign of a numeric variable.''' 'do' °
'''Let us take another look at the monadic divide:'',r' °
'show ''÷VECTOR+0=VECTOR'' ''0=VECTOR'' ''VECTOR+0=VECTOR''' °
'''Why did we have to add 0=VECTOR to VECTOR? Having done that''' °
'''is the result correct?''' 'do' '''We can test it with'',r' °
'show ''÷÷VECTOR+0=VECTOR''' °
'''First, as long as the vector does not contain a zero, the''' °
'''monadic divide generates the reciprocals of individual''' °
'''components. Clearly, if an application calls for a reciprocal,''' °
'''and there is a possibility that the variable may contain a zero,''' °
'''then you can expect an interrupt in the processing. This can be''' °
'''avoided, by using a device such as the above expression.''' 'do' °
'''But suppose you desire to see a specific number (say 0) when''' °
'''taking the reciprocal. See if you can come up with an expression''' °
'''that will generate reciprocals, but return 100 in the position''' °
X '''occupied by zeros. (For one answer, enter RECIPROCAL).''' 'endd' °
*(1997 4 28 12 47 49 628) °
FTEACH8 ÉFX 'TEACH8' 'Σ Roll and deal' 'exit ''TEACH8''' °
'''When we want to generate a vector of numbers, we enter a numeric''' °
'''sequence, and press Enter. That takes a lot of keystrokes. Often''' °
'''we may not be interested in the actual numbers. In many games,''' °
'''for example, all we want is a sequence of random numbers. APL2''' °
'''has a special primitive function to do just that. It is called''' °
'''ROLL, and the symbol is a question mark'',r' °
'show ''?100'' ''?100'' ''?100''' °
'''Each time you use roll, you get a random number. The value is an''' °
'''integer in the range one up to the value given as argument.'',r' °
'''To generate more than one value at a time (i.e. a vector), you''' °
'''would enter'',r' 'show ''?100 100 100 100'' ''?4µ100''' °
'''For example, to generate the roll of six dice, you would enter'',r' °
'show ''?6µ6'' ''?6µ6''' °
'''Notice that some values repeat in the results above. Suppose that'' °
' '''in your application you want random values without repetition.''' °
'''For that, there is a dyadic version of ? called DEAL:'',r' °
'show ''6?6'' ''10?10''' °
'''The left argument to deal can be smaller than the right argument'', °
r' 'show ''2?6'' ''5?52''' °
'''The last example corresponds to the deal of 5 cards from a deck.''' °
'''In subsequent lessons we will show how to convert a number in the'' °
' °
'''range from 1 to 52 to the representation of a playing card such as' °
X',r' ''' '',ÉAV[4],''K''' 'endd' °
*(1997 7 13 12 28 49 504) °
Faddquote ÉFX 'u╜addquote w' °
'Σ Put quotes around a string, and double existing quotes' °
X 'u╜ÉAV[40],((1+w=ÉAV[40])/w),ÉAV[40]' °
*(1997 4 27 12 39 6 420) °
XFaq ÉFX 'U╜aq W' 'U╜Γaddquote W' °
*(1997 7 24 13 20 38 476) °
Fav ÉFX 'av;A;N;I;ÉIO' 'Σ Display characters in ÉAV' 'ÉIO╜0' °
'A╜22 78µ'' ''' 'N╜3 0«φ12 22µ1+∞356' 'A[;,(6⌡∞12)°.+2 3 4]╜N' °
'A[;6+6⌡∞12]╜φ12 22µÉAV' 'ΣA[8 10 13;6]╜'' ''' 'A[13;6]╜'' ''' °
X 'A[14+∞8;68 69 70 72]╜'' ''' 'A' °
*(1991 11 11 8 25 13 316) °
Fdate ÉFX 'u╜date w' 'Σ Format date and time of day' 'u╜«6╞w' °
X 'u╜('' ''⌠u)Γu' 'u╜εu,■''-- .. ''' °
XCdig 1 10 1234567890 °
*(1997 9 9 13 0 45 372) °
Fdisclaimer ÉFX 'disclaimer' 'Σ Copyright statement' °
'(10µ'' ''),''Copyright, Z. V. Jizba, 1995,1996,1997'',r' °
''' This and subsequent workspaces labelled TEACHxx are made available °
''' °
'''at no cost to anyone who desires to learn how to use effectively''' °
'''the IBM/OS2 version of APL2.'',r' °
'''This software is provided "AS IS" with no WARRANTY of any kind, eit °
her''' °
'''express or implied. Any risk in its use resides with you, the user °
of''' '''these tutorials.'',r' ''' ACKNOWLEDGEMENTS'',r' °
''' In writing these tutorials, I am greatly indebted to Roy Sykes, wh °
ose''' °
'''excellent lectures increased my understanding of the language.''' °
'''Discussions with the late Harry Bertucelli clarified a number of''' °
'''concepts and caused me to change some improper terminology that was °
''' °
'''used in previous versions of these tutorials. Mr. Benjamin Archer'' °
' °
'''kindly checked out a nearly final version, bringing to my attention °
''' '''some ommisions, misspellings, and invalid terminology.'',r' °
X '''(PRESS ENTER to continue)''' °
*(1997 7 13 12 28 50 508) °
Fdo ÉFX 'do;T;E' 'Σ Expression driver' 'E╜''''' 'æ╜'' ''' 'T╜æ' °
'╕(^/'' ''=T)/0' °
'╕(('':''εT)doif ''B╜evaldd (+/^\'''' ''''=T)╟T'')/2' °
'''E╜ÉEM'' ÉEA T' '╕(0=µ,E)/2' °
'''This is not a valid APL2 expression''' 'æ╜''*''' '╕(''?''⌠╞1╟æ)/2' °
X 'E' '╕2' °
*(1997 7 13 12 28 50 508) °
Fdoif ÉFX 'U╢╜V╢ doif W╢;t╢' 'Σ Rule' '╕(^/~U╢╜V╢)/0' °
X '''U╢╜V╢ doif■ W╢'' ÉEA ''»V╢/W╢''' °
*(1997 9 9 12 50 14 444) °
Fendd ÉFX 'endd' 'Σ end of special feature' '20µ''²'' ╪ ╕(4<µÉLC)/0' °
X 'do' °
*(1997 8 4 13 31 22 380) °
Ferase ÉFX °
'erase;t;EXIT;GO;HELP;DISPLAY;RECIPROCAL;RULE;RULES;DISCLAIMER;COMPLEX °
' 'Σ Erase all global functions and variables' 't╜ÉNL 3' °
't╜(~t^.εlc,'' '')≡t' 't╜ÉEX(~t[;∞5]^.=''TEACH'')≡t' 't╜ÉNL 2' °
X 't╜ÉEX(~t^.εlc,'' '')≡t' 't╜ÉNL 4' 't╜ÉEX(~t^.εlc,'' '')≡t' °
*(1997 4 27 12 39 6 420) °
Ferrors ÉFX 'errors W;EC;RT;R' 'Σ Display error message' °
'╕((1<╧W)doif ''errors■ W'')/0' ''' '',W' '(EC RT R)╜ÉEC W' 'R' °
X 'do' °
*(1997 7 27 13 47 41 608) °
Fevaldd ÉFX 'u╜evaldd w;c;n' 'Σ Evaluate direct definition' 'u╜0' °
'n╜(w∞''Σ'')-1' 'c╜(((n╞w)⌠'':'')Γn╞w),Γ''ΣDD '',(n+1)╟w' °
'╕((1 label╞c)doif ''''''Invalid label'''''')/0' °
'╕((2=µc)doif ''u╜showdd 1╙c'')/0' °
'╕((3=ÉNC╞c)doif ''u╜⌡µÉ╜(╞c),'''' is already defined.'''''')/0' °
'╕((3=µc)doif ''u╜simdd c'')/0' 'c╜(Γ''α∙ aw'')replace■c' °
'u╜ε''u╜'',((''a''εεc[2 3 4])/''a ''),(╞c),'' w;t;b''' °
'u╜u(5πc)(''b╜(t╜'',(3πc),'')/'',addquote ''u╜'',4πc)' °
X 'u╜u,''╕(t doif b)/0''(''u╜'',2πc)' 'u╜╧ÉFX u' °
*(1997 7 25 13 27 52 564) °
Fexit ÉFX 'V exit W;T' 'Σ Exit if too many suspended functions' °
'╕(0⌠ÉNC ''V'')/L0 ╪ V╜10' 'L0:╕(V>µÉLC)/0' °
'''There are too many suspended functions''' '''Please enter '',W' °
X '╕' °
*(1997 7 26 12 33 39 536) °
Fget ÉFX 'U╜V get W;t;T;ÉPR' 'Σ Prompt for response from keyboard' °
'ÉPR╜T╜ÉAV[ÉIO+255] ╪ ╕(0⌠ÉNC ''V'')/L0 ╪ V╜1' 'L0:V╜V╧1' 'æ╜W ╪ t╜æ' °
'U╜(+/^\t=T)╟t' '╕(''╕''⌠╞U)/L1 ╪ ╕' 'L1:╕V/0' 't╜(U⌠'' '')ΓU' °
X 'U╜(µt),(ΓU),t' °
*(1997 7 28 13 33 8 424) °
Fglobals ÉFX 'globals' 'Σ Initialize useful global variables' °
'uc╜''ABCDEFGHIJKLMNOPQRSTUVWXYZ''' °
'lc╜''abcdefghijklmnopqrstuvwxyz''' 'dig╜''1234567890''' °
X 'r╜ÉAV[13+ÉIO]' 'q╜''''''''' °
*(1997 7 3 12 47 6 368) °
Finitialize ÉFX 'initialize;T' 'Σ Initialize workspace' °
'''AT ALL TIMES, TO CONTINUE, PRESS RETURN!'',r' °
'''To see disclaimers enter:'',r,'' disclaimer''' 'do' 'erase' °
'globals' °
'''Make sure the CAP LOCK light on your keyboard (upper right) is ON!' °
X'' 'endd' °
*(1997 7 27 13 14 33 444) °
Flabel ÉFX 'u╜v label w' °
'Σ Return 1 if label w does not begin with a cap' °
'╕(0⌠ÉNC ''v'')/L0 ╪ v╜0' 'L0:v╜v╧1 ╪ w╜εw ╪ ╕v/L1 ╪ ╕(u╜0⌠ÉNC w)/0' °
X 'L1:╕(u╜~^/wεlc,uc,dig)/0' 'u╜w[1]εlc,dig' °
XClc 1 26 abcdefghijklmnopqrstuvwxyz °
*(1997 7 13 12 28 55 528) °
Fnon ÉFX 'non;T;RC;ET;R' 'Σ Ignore keyboard entry' 'æ╜'' ''' 'T╜æ' °
'╕(0=µ(T⌠'' '')/T)/0' '(RC ET R)╜ÉEC T' '╕(0=RC)/2' °
X '╕((1=RC)doif ''R'')/2' '╕2' °
*(1997 7 13 12 28 55 528) °
Fnotb ÉFX 'u╜notb w' 'Σ Remove trailing blanks' °
'╕((1<╧w)doif ''u╜notb■ w'')/0' '╕((1<µµw)doif ''u╜πnotb Γ[2]w'')/0' °
X 'u╜(1-(,'' ''⌠Φw)∞1)╟w' °
*(1997 4 27 12 39 6 420) °
Fpause ÉFX 'V pause W;T' °
'Σ Pause, then print W V spaces right and return' °
X 'T╜(0=ÉNC ''V'')doif ''V╜6''' 'do' '(Vµ'' ''),W' 'do' °
XCq 0 ' °
XCr 0 °
*(1997 7 13 12 28 56 532) °
Freplace ÉFX 'u╜v replace u;i;r;s' 'Σ Replace elements in v in u' °
'i╜Γ∞µu' 's╜2πv╜(v⌠'' '')Γv' 'i╜⌡r╜i⌡■Γ[1]u°.=╞v' °
X 'u[(εi)/εr]╜s[(εi)/εi⌡■∞µs]' °
*(1997 7 13 12 28 56 532) °
Fround ÉFX 'U╜V round W' 'Σ Half adjust to V th decimal' °
X 'U╜(╛0.5+W⌡10*V)÷10*V' °
*(1997 8 5 12 48 37 508) °
Frule ÉFX 'V rule W' 'Σ Additional remarks on rules' °
'╕(2=ÉNC ''V'')/L ╪ V╜0' 'L:╕((╞W)=∞8)/L1,L2,L3,L4,L5,L6,L7,L8' °
'''For rules not described in this lesson, see workspace INDEX''' °
'╕0' 'L1:╕(V>1)/L1X' °
'''RULE 1. For arithmetic operations a vector must be matched with a'' °
' ''' scalar, or another vector of the same length.'',2µr' °
'╕(0=V)/0' °
'L1X:''This is the first of many rules dealing with the concept of''' °
'''CONFORMABILITY. This means that elements to be processed by APL2''' °
'''must in some ways match.''' '╕L0' 'L2:╕(V>1)/L2X' °
'''RULE 2. The reduction operator places the function, (specified to'' °
' °
''' its left), between all pairs of the vector. It then evaluat °
es''' ''' the resulting expression.'',2µr' '╕(0=V)/0' °
'L2X:''It is apropriate to think of an operator as a device to generat °
e''' '''derived functions.''' '╕L0' 'L3:╕(V>1)/L3X' °
'''RULE 3. All APL2 expressions are evaluated from right to left'',2µr °
' '╕(0=V)/0' °
'L3X:''This rule is valid in APL, which is the earlier version of APL2 °
.''' °
'''For APL2, the rule has been restated in a totally different way.''' °
'''However until we introduce some concepts that are new to APL2, the' °
'' '''newer form reduces to RULE 3 as stated.''' '╕L0' 'L4:╕(V>1)/L4X' °
'''RULE 4. Vectors in APL2 can have lengths of zero and one.'',2µr' °
'╕(0=V)/0' °
'L4X:''This is the first concept that begins to introduce the idea tha °
t no''' °
'''matter what the APL expression, if it is valid, it must produce a'' °
' °
'''valid APL2 object. (Shades of which came first, the chicken or the °
egg)''' '╕L0' 'L5:╕(V>1)/L5X' °
'''RULE 5. The shape of a variable is a vector. The shape of a vector' °
'' ''' is a vector of length 1. The shape of a scalar is a''' °
''' vector of length zero.'',2µr' '╕(0=V)/0' °
'L5X:''The left argument of RESHAPE is by definition a vector. If APL2 °
is''' °
'''to be internally consistent, the inverse operation to RESHAPE (whic °
h''' '''is indeed SHAPE) MUST return the same type of object.''' '╕L0' °
'L6:╕(V>1)/L6X' °
'''RULE 6. Reduction of a scalar returns that scalar REGARDLESS of''' °
''' the function to the left of the reduction operator.'',2µr' °
'╕(0=V)/0' °
'L6X:''Reduction BY DEFINITION reduces the RANK by one. The exception °
is''' °
'''for objects whose rank is zero. Since there is no such thing as''' °
'''negative rank, reduction is undefined for scalars, and therefore''' °
'''the result is to leave the APL2 object unchanged.''' '╕L0' °
'L7:╕(V>1)/L7X' °
'''RULE 7. The reduction of a null vector produces the identity''' °
''' element of the function.'',2µr' '╕(0=V)/0' °
'L7X:''A null vector may be empty, but it still has rank equal to one. °
''' °
'''Therefore its reduction MUST be a scalar. Since there is no data''' °
'''in a null vector, the scalar must be such that it has no effect''' °
'''on the operation performed by the function: Zero added to anything' °
'' °
'''has no effect in addition; one multiplied by anything has no effect °
''' °
'''in multiplication; and so on. (Mathematicians call any such value'' °
' °
'''that has NO effect on the operation of a function "The identity''' °
'''element".)''' '╕L0' 'L8:╕(V>1)/L8X' °
'''RULE 8. Parentheses can (and should) be used to modify the right''' °
''' to left rule to improve efficiency'',2µr' '╕(0=V)/0' °
'L8X:''Parentheses are used in APL2 for other purposes as well, but fo °
r''' °
'''now, we will use them just to modify the right to left rule (RULE 3 °
).''' °
'''If you place parentheses where they are not needed, APL2 will ignor °
Xe''' '''them.''' 'L0:''²²²'',r' '╕(0=µW╜1╟W)/0' '╕L' °
*(1997 7 13 12 28 57 536) °
Fshow ÉFX '╢V show ╢W;╢T;╢B' 'Σ Display and execute ╢W' °
'╢T╜(0=ÉNC ''╢V'')doif ''╢V╜0''' °
'╕((0=╧╢W)doif ''show ╢W,'''' '''''')/0' °
'╕((1<╧╢W)doif ''╢V show ■╢W'')/0' ''' '',╢W' °
X '╕((╢V^'':''ε╢W)doif ''╢T╜evaldd ╢W'')/L0' '''ÉEM'' ÉEA ╢W' 'L0:do' °
*(1997 7 13 12 28 57 536) °
Fshowdd ÉFX 'u╜showdd w;a;b;c;r' °
'Σ Display a direct definition function' °
'╕((1=╧w)doif ''u╜showdd Γw'')/u╜0' °
'╕((3⌠ÉNC╞w)doif ''(ε╞w),'''' is not a function'''''')/0' °
'c╜Γ[2]ÉCR╞w' 'c╜notb(2╞c),(Γ''aw α∙'')replace■2╟c' °
'╕((~''ΣDD''╧3╞2πc)doif ''''''Not a direct definition function'''''')/ °
0' 'u╜1' 'b╜('' ''⌠╞c)Γ╞c' 'a╜'' ''' 'r╜2╟3πc' °
'╕((3=µc)doif ''a,(╞w),'''':'''',r,(3<µ2πc)/'''' Σ'''',3╟2πc'')/0' °
'a╜a,(╞w),'':'',(2╟5πc),'':''' 'b╜(+\r=''('')-+\r='')''' 'b╜b∞0' °
X 'a╜a,(²3╟(b-1)╞3╟r),'':'',2╟»(b+2)╟r' 'a,(3<µ2πc)/'' Σ'',3╟2πc' °
*(1997 7 13 12 28 57 536) °
Fshowfn ÉFX 'U╜V showfn W;F;N;T;ÉIO' 'Σ Simulate ╖W[É]' °
'T╜(0=ÉNC ''V'')doif ''V╜0''' 'ÉIO╜0' °
'U╜r,'' '',''╖'',W,''[É]'',(╞V)╞''╖''' 'N╜1╞µF╜ÉCR W' 'N╜«∞N' °
'N╜(N⌠'' '')ΓN' 'F╜(π''['',■N,■Γ''] ''),F' °
'T╜(1<µ,V)doif ''F╜F[1╟V;]'' ''U╜''''''''''' 'U╜²1╟U,r,,F,r' °
X 'U╜((-+/^\'' ''=ΦU)╟U),('' ╖'')[╞V],r' °
*(1997 7 13 12 28 58 540) °
Fsimdd ÉFX 'u╜simdd w;e' 'Σ Direct definition mode' 'u╜0' °
'╕((0⌠ÉNC╞w)doif ''''''Already defined'''''')/0' 'e╜''α''ε2πw' °
'w[2]╜Γ''u╜'',''α∙ aw'' replace 2πw' 'w╜w[1 3 2]' °
X 'w[1]╜Γε''u╜'',(e/''a ''),w[1],'' w''' 'u╜╧ÉFX w' °
*(1992 6 3 9 59 17 424) °
Ftab ÉFX 'U╜V tab W;T;A;B;C;D;E;F;G;M;ÉPW' 'Σ Tabulate list W' °
'T╜(0=ÉNC ''V'')doif ''V╜0''' 'M╜''Invalid data for tabulation''' °
'V╜4╞V' 'ÉPW╜130╛30⌐G╜V[2]+79⌡V[2]=0' °
'L1:╕((1<╧W)doif ''''''W╜∞0'''' ÉEA ''''W╜πW'''''')/L1' °
'╕(((0=µεW)δ2<µµW)doif ''U╜(~V╧4╞0)/M'')/0' °
'T╜(1≥µµU╜«W)doif ''U╜πW╜(U⌠'''' '''')ΓU''' °
'T╜(0<V[1])doif ''U╜(«(Φ1,╞µW)µ(V[3]µ'''' ''''),∞(╞µW)-V[3]),'''' '''' °
,U''' '╕(G<30)/0' 'T╜(F╜µεV[4])+C╜1╟B╜µA╜(V[3],0)╟U' °
'T╜⌐(1╞B)÷1⌐╛(ÉPW+F)÷T' 'U╜(E╜(V[3],C)╞U),[1](B╜T,1╟B)╞A' °
'''D╜εV[4]'' ÉEA ''D╜ÉAV[εV[4]+33⌡V[4]=0]''' 'L0:A╜(T,0)╟A' °
X '╕(0=1╞µA)/0' 'U╜U,(((T+V[3]),µD)µD),E,[1]B╞A' '╕L0' °
*(1997 7 13 12 28 59 544) °
Ftest ÉFX 'U╜V test W;P' °
'Σ Describe problem in W, (correct answer in V)' 'U╜2' 'L1:W' °
'É╜'' ''' 'P╜æ' '''╕L0'' ÉEA ''P╜»P''' '╕(V╧P)/0' °
X 'L0:╕(0=U╜U-1)/0' '''Incorrect. Try again''' '╕L1' °
XCuc 1 26 ABCDEFGHIJKLMNOPQRSTUVWXYZ °