PROGRAMMEREN IN TIBASIC Wat is een programma? Je rijdt rechtdoor. Bij het stoplicht ga je rechtsaf zolang het licht groen is. Voor een rood stoplicht moet je wachten. Een kilometer verderop ga je linksaf en het viaduct onderdoor. Je draait 90 graden over de rotonde, slaat rechtsaf en neemt de veerpont, tenzij die net wegvaart. In dat geval kun je beter 270 graden rondrijden en de brug nemen die 500 meter verderop ligt. Dit is een programma, een lijst met instructies. Dat hierbij sprake is van vrije wil (misschien ben je wel te moe om het programma uit te voeren of heb je plotseling zin om een ijsje te eten) is een kenmerk van het menselijk vermogen. Een computer heeft die keuzevrijheid niet. Die weet niet beter dan elke instructie slaafs op te volgen. Maar hij moet de opdrachten wèl begrijpen. Je moet de taal van de computer gebruiken. Aanvankelijk was het schrijven van een computerprogramma een hoogwaardige, sterk gespecialiseerde bedrevenheid. Programmeurs moesten in staat zijn een probleem tot op het bot uiteen te rafelen in de kleinst mogelijke stapjes om al die duizenden opdrachten (Verplaats de inhoud van het register op adres A naar het register op adres B) in enen en nullen, de machinecode, te vertalen. Dat vereiste diepgaande kennis van de gebruikte hardware (de microprocessor) en grote handigheid met tweetallige en zestientallige rekenstelsels. De constructie van assembler talen vergemakkelijkte het programmeren aanzienlijk, maar op het punt van de leesbaarheid en de bruikbaarheid was er nog veel te verbeteren. In de jaren '60 ontwikkelde men de hogere programmeertalen, zoals ALGOL. Probeer het volgende programmaatje in ALGOL te doorgronden. Telkens wordt een getal ingelezen (de invoer gaat via read). Het teken := moet je lezen als "wordt gelijk aan". De som telt elk getal op bij de vorige som. Zo werkt de kassa op een supermarkt. En het heet een cumulatieve (opstapelende) som. Na het inlezen van achtereenvolgens de getallen 6, 4, 5, 3 en 10 is de uitvoer: 6, 10 (de som van 6 en 4), 15 (de som van 10 en 5), 18 enzovoorts. begin real som, getal; som:=0; HERHAAL: getal:=read; som:=getal+som; print(som); goto HERHAAL; end
In BASIC (Beginners All-purpose Symbolic Instruction Code, ontwikkeld in de jaren '70) ziet alles er nog iets begrijpelijker uit: 10 20 30 40 50
SOM=0 INPUT GETAL SOM=GETAL+SOM PRINT SOM GOTO 20
In latere versies van BASIC (QBASIC, GWBASIC) mochten de regelnummers 10, 20 enzovoorts weggelaten worden. Voorafgaand aan het programmeren moet men vaak nogal wat werk verrichten. Het vertaalprogramma (de compiler of interpreter) moet worden geladen, de layout moet worden ingesteld, de communicatie tussen input en output moet worden geregeld, enzovoorts. De programmeerbare rekenmachines (met name de Texas Instruments modellen) hebben daar geen last van. Je drukt op de knop [PRGM], geeft een naam aan je nieuwe programma, typt je instructies in en verlaat het programma weer via 2nd [QUIT]. De eerstvolgende keer dat je het programma wilt gebruiken druk je weer op [PRGM], zoekt de betreffende naam op en begint met de uitvoering ervan.
-1-
Een simpel voorbeeld van datgene waarin deze schrijver niet geïnteresseerd is. Zie het volgende JAVA fragment met de instructies die nodig waren op mijn huispagina, om een grappig letterslangetje (zie de functie makesnake) te produceren dat kronkelige tekst achter de cursor meesleept. Dat is het moderne programmeren: je knipt, plakt en kopieert (plagieert dus) het moeizame werk van anderen. Beleefdheidshalve wordt de naam van de componist vermeld. <SCRIPT LANGUAGE="javascript" TYPE="text/javascript"> =1; i--) { xpos[i]=xpos[i-1]+step ypos[i]=ypos[i-1] } xpos[0]=x+step ypos[0]=y
}
for (i=0; i<message.length-1; i++) { var thisspan = eval("span"+(i)+".style") thisspan.posLeft=xpos[i] thisspan.posTop=ypos[i] } else if (flag==1 && document.layers) { for (i=message.length-1; i>=1; i--) { xpos[i]=xpos[i-1]+step ypos[i]=ypos[i-1] } xpos[0]=x+step ypos[0]=y for (i=0; i<message.length-1; i++) { var thisspan = eval("document.span"+i) thisspan.left=xpos[i] thisspan.top=ypos[i] } } var timer=setTimeout("makesnake()",30) } //
-2-
Een voorbeeld in de programmeertaal PASCAL, dat ik ook van internet pikte. Het gaat hier om het aftellen (iene-mine-mutte of ie-wie-waai-weg of Keizer-Kiezen) waarbij de als derde aangetikte afvalt. program KeizerKiezer; { (c) 2002, Tom Verhoeff, versie 2 } { Kies keizer uit opgegeven aantal kandidaten, genummerd vanaf 0. Iedere 3e kandidaat valt af volgens aftelversje 'Geen kei-zer'. } { Met record en routines }
function Keizer ( n: Integer ): Kandidaat; { pre: 1 <= n <= MaxNKandidaten ret: wie keizer wordt bij n kandidaten } var deKring: Kring; g: 1 .. NLettergrepen; { doorloopt lettergrepen } { lettergreep g valt op aangewezen kandidaat }
const TEST = True; MaxNKandidaten = 10000; { maximale aantal kandidaten, >= 1 } NLettergrepen = 3; { aantal lettergrepen, >=1 } type Kandidaat = 0 .. MaxNKandidaten - 1; { de kandidaten, eigenlijk 0 .. NKandidaten - 1 } Kring = record N: 1 .. MaxNKandidaten; { aantal kandidaten bij aanvang } inKring: array [ Kandidaat ] of Boolean; { voor alle i: 0 <= i < N: inKring[i] = "i staat in de kring" } rest: 1 .. MaxNKandidaten; { aantal overgebleven kandidaten } { rest = (# i: 0 <= i < N: inKring[i]) } aangewezen: Kandidaat; { doorloopt kring } { er geldt: inKring [ aangewezen ] } end; { Kring }
begin initKring ( deKring, n ) ; while deKring . rest <> 1 do begin for g := 1 to NLettergrepen - 1 do wijsVolgendeAan ( deKring ) ; verwijderAangewezene ( deKring ) end { while } { 1 kandidaat over } ; Result := deKring . aangewezen end; { Keizer } var NKandidaten: 1 .. MaxNKandidaten; { aantal kandidaten (invoer) } begin { 1. Lees aantal kandidaten } write('Aantal kandidaten? ') ; readln ( NKandidaten ) ; writeln ( NKandidaten, ' kandidaten' ) { 2. Schrijf keizer } ; writeln ( 'Kandidaat ', Keizer ( NKandidaten ), ' wordt keizer' ) ; write ( 'Tik
om programma te verlaten: ' ) ; readln end.
procedure initKring ( var k: Kring; const a: Integer ); { pre: 1 <= a < MaxNKandidaten post: k is kring met a kandidaten, en 0 aangewezen } var i: Kandidaat; { doorloopt kandidaten } begin with k do begin N := a ; for i := 0 to N - 1 do inKring [ i ] := True ; rest := N ; aangewezen := 0 end { with k } end; { initKring } procedure wijsVolgendeAan ( var k: Kring ); { pre: Zij k = K post: k = K waarin k.aangewezen = opvolger van K.aangewezen } begin with k do begin repeat aangewezen := ( aangewezen + 1 ) mod N until inKring [ aangewezen ] end { with k } end; { wijsVolgendeAan } procedure verwijderAangewezene ( var k: Kring ); { pre: Zij k = K post: k = K waarbij K.aangewezen is verwijderd en volgende is aangewezen } begin with k do begin if TEST then begin write ( aangewezen, ' valt af, ' ) end { if } ; inKring [ aangewezen ] := False ; rest := rest - 1 ; wijsVolgendeAan ( k ) end { with k } end; { verwijderAangewezene }
In TIBASIC, waarover dit deel gaat kan het ook, zie het volgende programmaatje waarbij het aantal deelnemers (N) en het aantal overgeslagenen (P) vooraf ingevoerd kan worden. Het programma heet AFTELLEN en is terug te vinden in het deel over getallen. Wie dit leest zal moeten toegeven dat het programmeren op de TI-83 of TI-84 inderdaad een fluitje van een cent is. Nüdim(L1 ) Fill(1,L1 ) 0üT:0üX Lbl 0 X+1üX:T+L1 (X)üT If T=P Then Disp X 0üL1 (X):0üT End sum(L1 )üS If X1:Goto 0 Disp "OVER BLIJFT NR.:" For(Y,1,N) If L1 (Y)=1:Disp Y End
-3-
De GR heeft een klein scherm en een relatief klein geheugen, lange namen en teksten kosten echter veel geheugenruimte. Om die reden heeft Texas Instruments een programmeertaal voor de TI-82, 83 en 84 ontworpen die sterk op QBASIC lijkt, echter voor variabelen maar één letter toestaat. Het is mogelijk om via teksten tussen aanhalingstekens de leesbaarheid van het programma te verhogen. Ik geef het vorige programma (op pag. 1) maar nu in TI-BASIC. 0->S Lbl H Input N N+S->S Disp S Goto H
Nu is dit programmaatje niet wereldschokkend. Maar maak je niet ongerust, later krijgen de voorbeelden meer allure. Rekenkunde, kansrekening en wiskunde spelen daarbij een grote rol. De TI83 plus heeft een grote geheugenruimte om programma's in te bewaren (archiveren), de TI-83 plus Silver Edition (SE) is bovendien nog een beetje sneller (ongeveer twee keer zo snel als de standaard TI-83(plus). Al deze modellen zijn onderling gelijkwaardig. De onlangs uitgebrachte versie TI-84 verschilt niet essentieel van de eraan voorafgaande modellen, alleen er is veel meer geheugenruimte. Nadrukkelijk is het hier niet de bedoeling om de zogenaamde algebraïsche of symbolische rekenmachines toe te lichten. Kijk eens naar het volgende plaatje. wit
blauw
groen
wit blauw A
groen
w rood
blauw blau w
groen
Dat illustreert het beroemde vierkleurenprobleem. Hoeveel kleuren zijn er hoogstens nodig om een landkaart zo in te kleuren dat nergens twee landen met een gemeenschappelijke grens dezelfde kleur hebben? Vermoedelijk zijn daarvoor nooit meer dan vier kleuren nodig. Kijk naar de landkaart hierboven. Zelfs rondom het vijflandenpunt A volstaan drie kleuren. Maar een vermoeden is nog geen bewijs. Het heeft eeuwen geduurd tot in 1976 Wolfgang Haken en Kenneth Appel er eindelijk in slaagden het bewijs te leveren, gesteund door een computer die daarvoor 1200 uur rekentijd gebruikte. Computers waren in die tijd, vóór de eerste P.C. verscheen, indrukwekkende apparaten. Een ruimte ter grootte van een klaslokaal, gevuld met grote kasten, panelen met flikkerende lampjes en ratelende flexowriters (een flexowriter was een elektrische schrijf/pons-machine die luidruchtig ponsbanden produceerde).
-4-
Tegenwoordig zit er misschien wel evenveel reken- en geheugencapaciteit in apparaten die passen in een koffertje (de laptop) of zelfs in een broekzak (de grafische rekenmachine). De prijs en afmeting en de -om het zo maar even te noemen- programmeeronvriendelijkheid van een laptop vormen een ernstige beperking voor het gebruik daarvan door scholieren en studenten. De grafische rekenmachine daarentegen is klein en robuust en kost niet veel meer dan een studieboek. Bovendien is het programmeren van de TI-83 niet meer dan een flinke peulenschil. Zoals gezegd: druk op de knop [PRGM] en begin te programmeren. Zo krijg je maatwerk. Veel problemen op gebieden die aan de wiskunde verwant zijn (analyse, kansrekening, statistiek, meetkundige berekeningen) kunnen aangepakt worden met gerichte programmaatjes. Voor degenen die nog niet vertrouwd zijn met het elementaire gebruik van de TI-83 en TI-84 modellen geven we een toelichting op enkele knoppenmenu's, in samenhang met wat wiskunde uit de onderbouw. Herstel eerst alle standaardinstellingen (de defaults) met: 2nd[MEM] 7:Reset 2:Defaults 2:Reset en CLEAR. Voorbeeld 1. Een rit met taxibedrijf A kost € 2,- vooraf en vervolgens € 0,91 voor elke kilometer. Een rit met taxibedrijf B kost € 3,- vooraf plus 75 eurocent per kilometer. Na hoeveel kilometer is taxi B goedkoper geworden dan A? Toelichten met grafiek en tabel. Oplossing Na X km met taxi A is de prijs 2+0.91X; met taxi B: 3 + 0.75X. Zet deze functies onder de knop Y= in Y1 en Y2. Druk eerst op [ZOOM] 6:ZStandard en constateer dat het plaatje niet mooi is. We hebben immers geen belangstelling voor negatieve kilometers en euro's. Verbeter de scherminstelling via [WINDOW] zo, dat Xmin en Ymin nul worden. Zet de roosterpunten aan via 2nd[FORMAT] GridOn. En druk op [GRAPH]. We zoeken het snijpunt. Snijden = intersect. Doe dus: 2nd[CALC] 5:Intersect en driemaal ENTER. Het antwoord op de vraag is dus: Na 6,25 km is B goedkoper dan A. Uiteraard is dit de snelste manier van oplossen. Maar via de tabel krijg je ook een idee hoe het in de buurt van het antwoord is. Ga naar 2nd[TBLSET], blader door de tabel met 2nd[TABLE] en zie dat het antwoord ergens tussen 6 en 7 ligt. Zoom daarna in met 2nd[TBLSET] TblStart=6 en DTBL=.1 en 2nd[TBLSET] TblStart=6.2 en DTBL=.01 . Zo vind je het antwoord dus via inklemmen (inzoomen) in de tabel. Veeg Y1 en Y2 schoon met CLEAR, anders gaan de grafieken van dit voorbeeld en het volgende voorbeeld door elkaar lopen. En zet het rooster uit met 2nd[FORMAT] GridOff . Voorbeeld 2. Uit de beschrijvende statistiek. Je gooit met een dobbelsteen en turft de worpen: ogen 1 2 3 4 5 6
aantal 2 keer 5 ,, 3 ,, 4 ,, 5 ,, 1 ,,
Gevraagd: gemiddelde, mediaan, kwartielen en histogram
-5-
Oplossing De waarnemingsgetallen en de bijbehorende frequenties komen in de lijsten L1 en L2 . Het is verstandig om vooraf alle lijsten schoon te vegen met 2nd[MEM] 4:ClrAllLists . Ga nu naar [ STAT] 1:Edit … en vul de lijsten in: de ogenaantallen in L1 en de frequenties in L2. Statistische berekeningen vinden plaats in het menu [STAT] CALC en wel met keuze 1: 1-Var Stats L1 ,L2 ENTER. In dit geval kan daaruit afgelezen worden dat het gemiddelde ü=3.4 is, de mediaan 3.5 en de kwartielafstand 5-2=3. Het histogram wordt straks geproduceerd via STAT PLOT, maar eerst stellen we het venster in: met Xmin=-0.5 en de schaal Xscl=1 komen de schaalstreepjes precies onder het midden van de staafjes, netjes zoals het hoort. Kijk hiernaast. Tik nu op 2nd[STAT PLOT] en [ENTER] [ON] en nu † ~ ~ ENTER, zie dat de data in Xlist=L1 komen en de frequenties in L1 en teken het plaatje met [GRAPH]. Als de rechte lijnen uit voorbeeld 1 nog over je schermpje lopen, komt dat doordat je vergeten bent met twee keer [CLEAR] de functies Y1 en Y2 te verwijderen. Schakel ook het histogrammetje uit met 2nd[STATPLOT] en 4:PlotsOff. Pas op! Functies in Y= en statistieken in L1 en L2 komen met [GRAPH] door elkaar op het scherm. Functies in Y= kun je ook uitschakelen met [VARS] Y-VARS 4:On/Off… 2:FnOff.
Speciale functies We gaan hierna dieper in op een aantal knoppen. 2nd[TEST] 2nd[LIST] <MATH> MATH 0:Solver : (de dubbele punt als vervanging van ENTER) 2nd[DISTR] VARS 2nd[MATRIX]
Strings 2nd[DRAW] 2nd[STATPLOT]
2nd[TEST] Met het woord TEST wordt aangegeven dat het hier gaat om het "logisch" testen van voorwaarden. Tik bijvoorbeeld in: 5 2nd[TEST] < 8 ENTER. Op je scherm staat dan: 5<8 met het antwoord 1. Waar komt dat vandaan? Je moet het zo zien, dat er maar twee mogelijke uitkomsten van een logische test zijn, waar (uitkomst 1) of onwaar (uitkomst 0). Aangezien 5<8 een ware bewering is, verschijnt er een 1 als uitkomst. De onware test 5>8 geeft een 0. Omdat de uitkomst een getal is, kun je testen ook optellen of vermenigvuldigen (mits je ze tussen haakjes zet!) Probeer maar: (5<8)+(6<9) = 2. Een denkertje. De grafiek hiernaast wordt bewerkstelligd door het volgende functievoorschrift: Y1=X(X£3)+(6-X)(X>3) ; voor x£3 krijg je y=x.1 + (6-x).0 dus y = x; voor x>3 staat er x.0 + (6-x).1 dus y = 6 - x. De logische operaties and en or zijn te vinden onder 2nd[TEST] . Een voorbeeld. Door middel van het functievoorschrift Y1=(X)(X>2 and X<8) wordt voor 2<X<8 het lijnstuk tussen de punten (2,2) en (8,8) getekend. Om lelijke effecten aan de randen te vermijden kun je hier de grafiek [MODE] het best tijdelijk op dot zetten. Het complement (de logische ontkenning) van het lijnstuk krijg je met Y1=(X)(X£2 or X³8) of Y1=(X)(not(X>2 and X<8)).
-6-
2nd[LIST] Een list is een lijst, een rij getallen die tussen accolades op het scherm getoond wordt of als kolom in het menu STAT. [STAT] 5:SetUpEditor stelt de standaardlijsten L1 t/m L6 in en 2nd[MEM] 4:ClrAllLists maakt deze standaardlijsten schoon. Tik in: {1,2,3,4,5,6,7,8,9} ¿ L1 en zie (onder STAT 1:Edit…) hoe dat werkt. Op het gewone rekenscherm verschijnen alleen de eerste paar termen. Met ~ kun je de rest van de rij bekijken. Over de toekenningsopdracht ¿ die op het scherm als een pijltje ü getoond wordt krijgen we het later nog. Er is een compacte manier om rijen te beschrijven, namelijk via de instructie 2nd[LIST] 5:Seq. Sequence betekent ook rij. De definitie van de opdracht seq is: seq(formule,variabele,eerste,laatste). Zo geeft seq(X2,X,1,5) de rij {1,4,9,16,25}. De som van die rij 1+4+9+16+25=55 vind je via 2nd[LIST] <MATH> 5 met: sum(seq(X2,X,1,5)). Begin even opnieuw met ClrAllLists. Zet de eerste vijf positieve gehele getallen in lijst 1 met seq(X,X,1,5)üL1. Doe L12üL2 (het kwadraat met [x2 ]) en kijk op je scherm na indrukken van de toetsen L1 en L2 [ENTER]. Rijen kun je bij elkaar optellen of met elkaar vermenigvuldigen. Het resultaat van L1+L2 is dus {2,6,12,20,30}.Kijk ook onder [STAT] 1:Edit…. Zet nogmaals L2 met [ENTER] op het scherm en direct daaronder L2 <10. Begrijp je wat er gebeurd is? Kun je voorspellen wat het resultaat zal zijn van L1 =L2 , L2 =9 , L2 >L 1 ? 2
MATH 0:Solver De vergelijking oplosser. Stel dat we 5x - x = 1 moeten oplossen. Na [MATH] 0 zijn er twee schermen, (1) het vergelijking scherm met de kop EQUATION SOLVER en daarna eqn:0= en (2) daaronder het oplossingsscherm waarop een eventueel al ingevoerde vergelijking staat met op de tweede regel X=… Als er nog geen vergelijking ingevoerd is, sta je automatisch in het (bovenste) vergelijkingscherm. De vergelijking moet eerst op nul herleid worden dus in ons voorbeeld: 2 5x - x - 1 = 0; achter eqn:0= moet dus komen 5X-X2-1 of 1-5X+X2. Na ENTER kom je in het daaronder liggende oplossingsscherm. Schakel even op en neer met de pijltjestoetsen } en † om beide schermen te bekijken. In het oplossingsscherm knippert de cursor achter X=, vul nu een willekeurige waarde (een gok of guess voor X in, in dit geval eerst X=0 en druk op ALPHA[SOLVE] (rechtsonder). De gok X=0 leidt tot de oplossing x 1 = 0.2087 (ongeveer); de gok X=10 levert de tweede oplossing x 2 = 4.7913 van deze kwadratische vergelijking. MATH [NUM is een afkorting van numbers] abs(A) levert de absolute waarde van A, meestal als |A| genoteerd: de waarde van A zonder op het teken te letten. Bijvoorbeeld abs(-7) = 7. Teken de grafieken van Y1=5X-X2 en van Y2=abs(Y1) in één figuur en je ziet waar het om gaat. Hierbij haal je Y1 en Y2 uit het [VARS] 1:Function… menu. round(A,B) rondt getal A af in B decimalen nauwkeurig. Probeer bijvoorbeeld round(p,4). iPart(A) geeft het gehele deel van getal A; iPart komt van integer part. Probeer bijvoorbeeld iPart(p) en ook fPart(p); fraction part is het decimale gedeelte (de rest). MATH (PRB is een afkorting van probability, waarschijnlijkheid) ! is het faculteitsymbool, zo is 4! = 1.2.3.4 = 24. A nCr B geeft het aantal combinaties, A boven B, bijv 10 nCr 3 = 120. Voorts bevat dit menu de randomgenerator die aselecte (lukraak) getallen produceert. Doe bijvoorbeeld rand en vijf keer [ENTER] en je ziet dat er willekeurige getallen tussen 0 en 1 aangemaakt (gegenereerd) worden. En de integer (gehele getallen) random generator randInt(A,B,C) [ENTER] levert een rij van C gehele getallen tussen A en B. Je kunt zo bijvoorbeeld het 10 keer gooien met een dobbelsteen simuleren met randInt(1,6,10).
-7-
: De dubbele punt wordt gebruikt als scheiding tussen verschillende opdrachten. De dubbele punt is eigenlijk hetzelfde als [ENTER]. In het voorbeeld hiernaast bootsen we het 360 keer werpen met twee dobbelstenen na en tellen hoe vaak de som van ogen kleiner dan of gelijk aan 5 was (volgens de theorie is de kans 10/36, dus moet dit bij 360 worpen ongeveer 100 keer het geval zijn). De gekoppelde instructie voor dit kansexperiment luidt: randInt(1,6,360)+randInt(1,6,360)!L1 :sum(L1 £5) [ENTER]. 2nd[DISTR]
Hier staan de kansverdelingsfuncties (distribution functions):
normalcdf(Xlinks,Xrechts, m, s) levert de oppervlakte onder de Gauss-kromme tussen Xlinks en
Xrechts. Een voorbeeld. Het gemiddeld I.Q. (intelligentiequotiënt) is 100 met een standaarddeviatie van 14. Hoeveel procent van de mensen is hoogbegaafd (I.Q. > 140)? Antwoord: normalcdf(140,1000,100,14)=.002137 dus ongeveer 0,2%. invNorm (oppervlakte, m,s) levert de X-waarde die behoort bij een gegeven oppervlakte. Onder welke grens liggen de 10% laagste I.Q. waarden? Antwoord: invNorm(0.1,100,14)=82.06 dus ongeveer bij I.Q. = 82. binompdf(n,p,X) is de kans op X successen van de n met succeskans p. Je gooit 10 keer met een geldstuk. Bereken de kans op precies 4 keer "kop". Antwoord: binompdf(10,.5,4)=.205 dus ongeveer 20,5% kans. VARS Hier staan de variabelen (variables) en de functies. Onder [VARS] 1:Window… staan o.a. de schermvariabelen Xmin, Xmax, enzovoorts. Doe bijvoorbeeld 20®Xmax en kijk bij [WINDOW] of deze verandering inderdaad ingevoerd is. Via VARS 1:Function… kun je de functies Y1 , Y2 , enzovoorts binnenhalen. Doe bijvoorbeeld (tussen aanhalingstekens) "X2"®Y1:"Y1-6"®Y2 [ENTER] en [ZOOM] 6:ZStandard en kijk wat er gebeurd is. Je kunt een functiewaarde als volgt snel uitrekenen: na [VARS] 1: 1: (5) 2 komt er op het scherm te staan: Y1(5) en de functiewaarde 25 (=5 ). 2nd[MATRIX] De matrix die hiernaast staat is als volgt ingevoerd: 2nd[MATRIX]<EDIT>1: 3 3 en daarna de elementen 0 t/m 8. Na 2nd[QUIT] komt hij op het scherm met nogmaals 2nd[MATRIX] 1. De matrix A2 krijg je met 2nd[MATRIX] 1 en [x2 ]. STRINGS: Een string is een reeks karakters (vaak hoofdletters). De string-variabelen zijn genummerd: Str1, Str2, enzovoorts. Je moet een string in principe invoeren tussen " ". "ABCD1234" [ENTER] geeft de string direct op het scherm en "ABCD1234" gevolgd door STO® VARS 7 Str1 geeft er de naam Str1 aan. Je kunt tekenreeksen ook optellen. Optellen is hetzelfde als aan elkaar plakken. Roep Str1 maar weer even op (met 2nd[ANS] of met [VARS] 7 1) en tik daarachter bijvoorbeeld +"PQRS" [ENTER]. Of doe Str1+Str1. Zie het schermplaatje. 2nd[DRAW] is het teken menu. In een grafiekenscherm (of ander scherm) kun je daarmee punten, lijnen en tekst over het vorige scherm heen tekenen (of schrijven).
-8-
1:ClrDraw veegt het ingetekende gedeelte uit. 2:Line(A,B,C,D) tekent een lijn van (A,B) naar (C,D) 0:Text(R,P,"tekst") schrijft tekst op het scherm op rij R, positie P. Daarbij moet je bedenken dat
het scherm uit 62 ´ 94 pixels (beeldschermpuntjes) bestaat, 62 rijen omlaag en 94 posities naar rechts. Laten we als voorbeeld de parabool Y1=X2 nemen en daarin de lijn van (-5,-5) naar (8,3) tekenen met linksboven de tekst "PARABOOL EN LIJN". Dat gaat als volgt. Eerst [ZOOM] 6:ZStandard. Dan 2nd[DRAW]1:ClrDraw. Vervolgens [CLEAR] en 2nd[DRAW] 2 en achter Line( de coördinaten invullen: -5,-5,8,3) [ENTER] en tenslotte [CLEAR] gevolgd door 2nd[DRAW]0:Text(0,0,"PARABOOL EN LIJN") [ENTER]. 2nd[STAT PLOT] Zo kom je in het statistiek tekenscherm, voor de histogrammen en boxplots. We demonstreren dat met de simulatie van 360 worpen met twee dobbelstenen. Eerst worden de Xwaarden 1 t/m 12 in L1 gezet en de 360 worpen in L3. Lijst L2 gaan we straks gebruiken voor de frequenties. Daarvoor moet de dimensie van L2 eerst op 12 gesteld worden, via 12®2nd[LIST]3:dim(L2 ). De logische test sum(L3=2) telt het aantal keren dat de som 2 is en deze frequentie wordt opgeslagen in de lijst L2: sum(L3=2)® L2(2). De volgende actie is sum(L3=3)®L2(3) hetgeen het snelst in te voeren is met 2nd[ENTRY] en verandering van de 2 in een 3. 2nd[ENTRY] herhaalt de laatste invoer en met | 2nd[INS] breng je veranderingen aan. Zie het derde schermpje.
PANORAMA 2nd[TEST]: voor = < > £ ³ and or 2nd[LIST]: voor Seq(formule,variabele,eerste,laatste) 2nd[LIST]<MAT>: voor sum(list) [MATH] 0:Solver: voor oplossen vergelijking [MATH] : voor intPart, round, abs [MATH] : voor de random generator en combinaties nCr 2nd[DISTR]: voor kansverdelingsfuncties normalcdf(Xlinks,Xrechts,m,s) binompdf(n,p,X)
[VARS]: voor variabelen en functies : functies Y1 , Y2 , … 1:Window...: schermvariabelen Xmin, Xmax, ... 7:String…: Str1, Str2, … 2nd[DRAW]: voor tekenen en schrijven over grafieken heen 1:ClrDraw 2:Line(xA,yA,xB,yB) 0:Text(van boven, naar rechts,tekst)
-9-
Het bewerken van een programma De instructies en functies die onmisbaar zijn voor het programmeren zullen we hierna uitgebreid toelichten. Allereerst moet je weten hoe een programma geopend, verlaten, uitgevoerd, bewerkt, onderbroken en weer verwijderd wordt. Ook komt het plakken van programma's en programmadelen aan de orde. Het openen van een nieuw programma. Druk achtereenvolgens op PRGM ENTER (of 1) en vul achter Name= de naam van het nieuwe programma in. De cursor knippert met een Ø, wat betekent dat hij in de ALPHA stand (de groene hoofdletters) staat. Typ bijvoorbeeld: PROBEERA (straks komt er misschien PROBEERB en PROBEERC bij). Een naam heeft maximaal acht karakters en mag niet met een cijfer beginnen (vanaf het tweede karakter mag dat wel, PROBEER1 of PROBEER8 is toegestaan, maar dan moet je de ALPHA schakelaar uitzetten door even op ALPHA te drukken). Als je na de naam op ENTER drukt is het nieuwe programma geopend en kun je beginnen met de eerste instructie. Laten we zeggen dat je eerste opdracht is, het scherm schoon te vegen. Deze opdracht staat in het Input/Output (I/O) menu. Doe PRGM 8 en er verschijnt ClrHome. Je kunt ook zoeken naar die opdracht door in het Input/Output menu zeven keer † te drukken, maar het commando ClrHome komt zo vaak voor (de meeste programma's beginnen er mee), dat je al gauw automatiseert met PRGM~8. Zodra je ENTER typt achter ClrHome, wordt deze eerste opdracht vastgelegd. We gaan even door met ons eerste programmaatje. Een belangrijk commando is "vertoon" (display). Op de tweede regel komt deze opdracht te staan, na PRGM 3:Disp . Hierna willen we de tekst "HALLO" hebben. Zet de letter-schakelaar aan met 2nd[ALPHA] en typ "HALLO" ENTER. Na ENTER wordt de letter-schakelaar automatisch uitgezet. Even kijken of het programma werkt. Het programma verlaten doe je met 2nd[QUIT]. Het uitvoeren ervan is simpel: druk weer PRGM, kijk onder EXEC op de alfabetische lijst programma's, zoek met † naar de naam die je wilt hebben en druk twee keer ENTER. Het bewerken van een bestaand programma. Laten we eens een paar regels veranderen in ons programmaatje. Het Engelse woord edit staat voor bewerken, redigeren: PRGM<EDIT> PROBEERA ENTER brengt ons terug in de programmalijst (de broncode). Stuur de cursor met † naar de tweede regel en zet hem met ~ achter de O van HALLO. Er wordt nog wat tekst ingevoegd (insert) via 2nd[INS] en nu bijvoorbeeld: 2nd[ALPHA] 'JONGENS'EN'MEISJES (het teken ' levert een spatie). Voer je nieuwe tekst in (na ") met ENTER. Even kijken wat er gebeurd is met: 2nd[QUIT] en PRGM PROBEERA ENTER ENTER. Je ziet dat de vertoonde tekst niet op één regel past. Er passen maar 16 tekens op een regel. Dat gaan we verbeteren.
- 10 -
Terug naar de broncode met
~ <EDIT> PROBEERA ENTER. Manoeuvreer de cursor achter de S van JONGENS, druk 2nd[INS] en ALPHA ", gevolgd door ENTER. Het gedeelte 'EN MEISJES staat nu op de volgende regel en de cursor knippert nog steeds in de Insert stand. Na PRGM 3:Disp ALPHA " en DEL (om de spatie te verwijderen) en 2nd[QUIT] gevolgd door PRGM PROBEERA ENTER zie je de gewenste verbetering. PRGM
Om de bewerking van programma's te oefenen creëren we een tweede programma, genaamd PROBEERB, via de commando's: PRGM ENTER PROBEERB. En nu: PRGM 3:Disp "HOE HEET JE" ENTER gevolgd door PRGM 1:Input Str1 ENTER. Hierbij moet opgemerkt worden dat Str1 gemaakt wordt met VARS 7: Str1. Een string is een tekenreeks of woord, een rijtje letters (of cijfers) dus. Met Input Str1 wordt je naam ingevoerd. Ga verder met PRGM 6:Output(8,1,"DAG"), ENTER en PRGM 6: Output(8,5,Str1) ENTER . Met Output(8,1,"DAG") verschijnt het woord DAG op regel 8, positie 1 van het scherm, en daarachter (regel 8, positie 5) wordt Str1 (je naam dus) geplaatst. Eindig met PRGM 8:Pause ENTER en PRGM 8:ClrHome. Je kunt een programma onderbreken door tijdens een pauze op [ON] te drukken. Daarna kun je het programma verlaten met 1:QUIT of bewerken met 2:Goto. Probeer dit nieuwe programmaatje even uit met 2nd[QUIT] en PRGM PROBEERB en je ontdekt de werking van het pause commando: na een druk op de ENTER toets gaat het programma door met de volgende opdracht (ClrHome) zodat het scherm schoongeveegd wordt. Het plakken van programma's is eenvoudig. Je moet daarvoor op 2nd[RCL] drukken. Kijk hoe we het programma PROBEERB aan het programma PROBEERA plakken en dat vervolgens de naam PROBEERC geven. Open via PRGM een nieuw programma met de naam PROBEERC. Na ENTER knippert de cursor op de eerste regel. Doe nu 2nd[RCL] PRGM <EXEC> PROBEERA en 2nd[RCL] PRGM <EXEC> PROBEERB en voer nu het samengestelde programma PROBEERC uit (na 2nd[QUIT] natuurlijk). Hieronder staat de broncode van PROBEERC op een rijtje: ClrHome Disp "HALLO JONGENS" Disp "EN MEISJES" Pause Disp "HOE HEET JE" Input Str1 Output(8,1,"DAG") Output(8,5,Str1) Pause ClrHome
Laat dit programma nog even staan. De programma's PROBEERA en PROBEERB hebben we echter niet meer nodig.
- 11 -
Het verwijderen van die programma's gaat via het memory menu 2nd[MEM] en daarna: 2:Mem Mgmt/Del… (management/delete) 7:Prgm… Zet de cursor voor de namen van de te verwijderen programma's en doe DEL, gevolgd door 2:Yes. Alle instructies zijn terug te vinden onder 2nd[CATALOG]. Typ de eerste letter, ga naar de instructie en doe [ENTER]. Rest ons nog de werking van de knop CLEAR uit te leggen. Met deze knop verwijder je een hele programmaregel. Probeer dat uit in PROBEERC. (PRGM<EDIT>PROBEERC). Je kunt tenslotte daarna het verminkte programma verwijderen met 2nd[MEM] 2: 7: 2:Yes. PANORAMA 2nd[CATALOG]: Alfabetische lijst met commando's [PRGM] : Een nieuw programma starten [PRGM] <EDIT>: Een bestaand programma bewerken [PRGM] : Invoer/Uitvoer Input, Output, Disp, ClrHome 2nd[QUIT]: Programma verlaten [DEL]: Eén teken wissen [CLEAR]: Hele regel wissen 2nd[INS]: Meerdere tekens invoegen [ON]: Lopend programma onderbreken 1:QUIT programma verlaten 2:Goto ga naar laatste pause 2nd[MEM] 2: 7: DEL 2:Yes: Programma verwijderen
Invoer, Uitvoer Onder PRGM staan de verschillende functies voor de in- en uitvoer van gegevens. We kunnen de werking daarvan alleen uitleggen binnen een programma. Open dus een nieuw programma, laten we zeggen onder de naam "A" met PRGMA. Elke instructie moet met ENTER in het geheugen van de GR opgeslagen worden. Dat zullen we voortaan gemakshalve niet meer vermelden. Doe eerst ClrHome (via PRGM8) om met een schoon scherm te beginnen. Laten we om te beginnen eens kijken wat er gebeurt na het commando Input A (via PRGM1:Input). Ga uit het programma met 2nd[QUIT] en voer het programma uit met PRGM A. Er verschijnt een vraagteken met direct daarachter een knipperende cursor. Er wordt kennelijk gewacht op een invoer, voer daarom een getal in, bijvoorbeeld 17 (ENTER). Als je nu na Done de variabele A oproept zie je dat A de waarde 17 gekregen heeft. Terug naar de broncode (met PRGM<EDIT> A, dat zullen we hierna ook niet meer vermelden, dit boekje moet tenslotte leesbaar blijven). Op de derde regel komt nu te staan: Disp A. (Disp staat achter PRGM 3). Verlaat het programma weer en constateer dat de waarde van A (17) uitgevoerd wordt, rechts uitgelijnd. We vervolgen met Input "B IS: ",B (let op de spatie achter de dubbele punt) en op de vijfde Regel Disp "B:",B. Het kortste invoer commando is PRGM 2:Prompt waarmee je direct een naam noemt: na Prompt C komt de vraag C=? op het scherm. Voeg deze programmaregel toe en vo er programma A uit.Het scherm zou er (afhankelijk van de ingevoerde getallen) uit kunnen zien zoals hiernaast.
- 12 -
De uitvoer functie DISP heeft als nadeel dat er twee regels voor gebruikt worden en we moeten op het kleine beeldscherm zo economisch mogelijk met de ruimte omgaan. Met behulp van de functie Output(regel, positie) kunnen we een mooier resultaat bereiken. Veeg je programma A maar even uit door de laatste vijf regels met CLEAR te verwijderen, of door middel van 2nd[MEM] 2 7 DEL en maak het volgende nieuwe programmaatje. ClrHome Disp "HOEVEEL WORPEN?" Prompt N Output(4,1,"N=") Output(4,3,N)
Typische programmeerinstructies Een label is een soort etiket met een naam erop. Die naam mag uit hoogstens twee karakters bestaan. Het cijfer 0 (nul) mag dus ook. Je kunt naar een label verwijzen met een Goto opdracht (of een menu opdracht, daarover straks meer). Open een nieuw programma om dat te demonstreren. Lbl en Goto staan onder PRGM (control). ClrHome 0!T Lbl 0 T+1!T Disp T Goto 0
T is een teller Teller met 1 verhoogd
Hiermee zit je in een nimmer eindigende lus, die slechts verbroken kan worden met de noodknop [ON]. Maar als je vóór de laatste instructie (Goto 0) via 2nd[INS] de voorwaarde If T<5 inlast, stopt het printen na 5 keer. Ook If staat onder PRGM. Vaak worden de laatste twee instructies in één regel weergegeven: If T<5:Goto 0. Maar deze tekst is eigenlijk een afkorting van: If T<5 Then Goto 0 End
De complete If-Then instructie luidt: If-Then-Else-End. End staat ook onder PRGM. Laten we eens wat uitproberen. ClrHome 0!T Lbl 0 T+1!T If T<5 Then Disp T Goto 0 Else Disp "" Disp "STOPPEN MAAR..." Pause ClrHome End
Dit is een lege regel
Het begint al ergens op te lijken! Nog twee instructies resteren. Daar is het overduidelijke PRGMF: STOP dat geen nadere uitleg behoeft en het veelgebruikte commando PRGMC: Menu waar we wel op ingaan. Een menu heeft een kopje (de titel) en verschillende verwijzingen (keuzes) naar met name genoemde labels. De notatie is: Menu("kopje", "keuze1", label1, "keuze2", labeL2,
- 13 -
…)
Een spelletje Het wordt tijd voor een echt programma, het programma RADEN.83P. Lees eerst alles goed door voor je het begint in te typen. De layout op dit papier van de broncode (met de tabs en de spaties) is cosmetisch, het oog wil ook wat. Al die tabs en spaties en toelichtende tekst hoef je (moet je!) niet in het RAM van je rekenmachine invoeren. Bekijk elke regel goed van dit TI-BASIC programma. De bedoeling van al die instructies is, om de GR in hoogstens tien stappen een in gedachten genomen getal onder de 1000 te laten raden. Stel dat je het getal 37 in gedachten had. Iedere gok van de GR (bijvoorbeeld Ik gok op: 500) moet je beantwoorden met groter dan, kleiner dan of gelijk aan. Na in totaal zeven keer kleiner dan en twee keer groter dan is het precies op de tiende gok raak bij het getal 37. Het programma begint met een linkergrens L=1 en een rechtergrens R=999 en geeft als gok het midden M van L en R. Bij het antwoord kleiner dan wordt de rechtergrens R veranderd in M, bij het antwoord groter dan echter wordt de linkergrens L veranderd in M. Daarna wordt voor de volgende gok weer het midden van de nieuwe waarden L en R berekend. Een teller (T) telt het aantal gokken. Als T>10 is, moet er ergens onderweg iets fout gegaan zijn en wordt daarvan melding gedaan. De functie afronden (round) is te vinden onder MATH2. Ga je gang. Let niet op de inspringende labelnamen. Dat is alleen maar een cosmetisch aspect.
RADEN ClrHome Disp "BEDENK EEN GETAL" Disp "VAN MAXIMAAL" Disp "DRIE CIJFERS:" Disp "TUSSEN 1 EN 999" Disp "EN BEANTWOORD DE" Disp "VRAGEN EERLIJK." Output(8,14,"==>") Pause :ClrHome 1üL:999üR: 0üT Lbl 0 If T>10:Goto FT: "FOUTMELDING" round((L+R)/2,0)üM T+1üT Output(1,1,"IK GOK OP:") Output(1,12," ") Output(1,12,M) Output(8,14,"==>") Pause Menu(" IS JOUW GETAL:","GROTER?",1,"KLEINER?",2,"GELIJK?",3) Lbl 1: MüL: Goto 0 Lbl 2: MüR: Goto 0 Lbl 3 ClrHome Output(1,1,"HET GETAL WAS:"):Output(2,6,M) Output(3,1,"GEVONDEN IN") Output(4,1,T):Output(4,4,"STAPPEN") Pause :ClrHome: Stop Lbl FT ClrHome: Disp "JE HEBT GEJOKT !":STOP
Je kunt het programma gemakkelijk zo veranderen, dat in maximaal 13 keer een getal van maximaal vier cijfers wordt geraden. De verklaring voor het in 10 stappen 3 cijfers en in 13 stappen 4 cijfers raden kun je vast wel zelf bedenken. Of niet soms? Denk met halveren aan machten van 2.
- 14 -
De While voorwaarde
: instructies End opdracht Dit commando vermelden we min of meer volledigheidshalve. Hij moet gelezen worden als: Terwijl (beter: zolang) de voorwaarde juist is, herhalen we de instructies erachter. Bij sommige spelletjes is deze instructie handig. Maar bij de wiskundige programma's kan hij meestal gemist worden. Het zelfde geldt voor de REPEAT voorwaarde : instructies End opdracht. Ook dit is een voorbeeld van een lus opdracht (ook wel loop genaamd). Je herhaalt de instructies die erachter staan tot aan de voorwaarde voldaan is, dan ga je verder achter End.
De For statement. Dit is een van de meest gebruikte instructies. De definitie ervan in TI-BASIC luidt: For(variabele, eerste, laatste, stapgrootte). Een stapgrootte van 1 is default, dat wil zeggen dat een stapgrootte van 1 niet aangegeven hoeft te worden. Telkens wordt eerst de waarde van de variabele vastgesteld en als die nog niet aan de laatste waarde toe is, worden de instructies tussen For en End uitgevoerd. Daarna wordt de variabele met de stapgrootte verhoogd en opnieuw vergeleken met de laatste waarde. For(X,1,5,2): Disp X: End drukt de getallen 1, 3 en 5 af. Na End heeft X de waarde 7 gekregen. Probeer het volgende programmaatje. ClrHome For(X,1,5,2) Disp X End Output(8,1,"LAATSTE X:") Output(8,13,X) Pause ClrHome
Je kunt For statements ook nesten, in elkaar laten grijpen als een nest schalen. Daarbij maken we gebruik van het cosmetische principe: wat op papier staat moet er overzichtelijk uitzien, met spaties en tabs. Die spaties en tabs kun je uiteraard niet in je broncode opnemen. Wel kun je daar af en toe een regel overslaan. Nu drie programma's met geneste For statements. In het eerstvolgende programma (A) ziet dat er bijvoorbeeld zo uit: For(R,1,8) For(K,1,16) Output(R,K,"X") End End
Rijen lopen horizontaal, kolommen verticaal. Eerst is rij R=1 en kolomnummer K loopt van 1 tot 16. Op de plek (1,K) wordt een X geplaatst. Dan wordt rij R=2 en kolom K loopt opnieuw van 1 tot 16. Dat gaat door tot en met R=8, de onderste rij. En wat de diagonalen betreft: de oorsprong (1,1) is het hoekpunt linksboven. Een diagonaal die door de oorsprong loopt heeft coördinaten (1,1) (2,2) (3,3) dus van de vorm (R,R). De andere diagonaal (van rechtsboven naar linksonder) heeft coördinaten (8,1) (7,2) (6,3) van het type (R, 9-R) want rijnummer + kolomnummer = 9 De pause in de programma's is opgenomen om de schermpjes rustig te kunnen bekijken.
- 15 -
programma A De eerste buitenste For lus For(R,1,8) zorgt ervoor dat de letters X regel-voor-regel afgedrukt worden, van boven naar beneden; de tweede buitenste lus For(K,4,13) drukt de min-tekens af kolom-voor-kolom, van links naar rechts. Op het laatst worden twee diagonalen stippenrijen getekend. ClrHome For(R,1,8) For(K,1,16) Output(R,K,"X") End End Pause For(K,4,13) For(R,2,7) Output(R,K,"-") End End Pause :ClrHome For(D,1,8) Output(D,D,".") Output(D,D+8,".") Output(D,9-D,".") Output(D,17-D,".") End Pause :ClrHome
Programma B Op het scherm staan 62 keer 94 beeldschermpuntjes (pixels). Eerst worden de rijen van boven naar beneden getekend (met stapgrootte 2, dus wordt er telkens een overgeslagen). Daarna van links naar rechts en tenslotte worden twee diagonalen weggeveegd. De tekeninstructies vind je onder [DRAW]. ClrHome FnOff :AxesOff ClrDraw For(R,0,62,2) For(K,0,94,2) Pxl-On(R,K) End End Pause For(K,1,93,2) For(R,1,61,2) Pxl-On(R,K) End End Pause For(D,0,62) Pxl-Off(D,D) Pxl-Off(D,62-D) End Pause :ClrHome
- 16 -
programma C De getallen worden pagina-voor-pagina afgedrukt, van links naar rechts en daarna van boven naar beneden. Zoals het hoort. ClrHome 0üX For(P,1,4) Output(1,4,"PAGINA") Output(1,11,P) For(R,2,8) For(K,1,13,4) X+1üX Output(R,K,X) End End Pause ClrHome End
Schermutselingen Soms lijkt het scherm (de display) een beetje te klein. Anders gezegd, er passen wat weinig letters en cijfers (karakters) op. Met de Output-instructie, Output(rij, kolom, ”tekst” of waarde), kun je maximaal 8 rijen met elk 16 karakters karakters op het scherm krijgen, dus 8 ´ 16 = 128. Via de Text-instructie, Text(rij, kolom, ”tekst”) die in het DRAW-menu te vinden is, is het mogelijk om het aantal rijen tot 10 en het aantal karakters per regel tot 23 op te voeren, zodat je met 10 ´ 23 = 230 bijna het dubbele aantal karakters haalt. Het scherm is opgebouwd uit 62 ´ 94 pixels (beeldschermpunten - eigenlijk zijn het vierkantjes). Hieronder is het scherm gevuld met getallen van drie cijfers opgebouwd met beide instructies.
De letter X, met de Text-instructie, is opgebouwd uit 9 pixels: (0,0) ®
(4,0) ®
¬ (4,2)
De positie van een pixel wordt met coördinaten (A,B) weergegeven, met als oorsprong (0,0) het punt linksboven. Het punt op het scherm rechtsonder krijgt de coördinaten (62,94). De eerste coördinaat A geeft het aantal pixels van bovenaf en de tweede coördinaat B hoeveel pixels je naar rechts bent gegaan.
- 17 -
De venstervariabelen zijn altijd bekend. Hoe vind je het verband tussen de pixelcoördinaten en de venstercoördinaten? Linksboven pixel (A, B)=(0, 0) komt overeen met coördinaten en X=Xmin en Y=Ymax, dus: (0, 0) Û (Xmin, Ymax). Rechtsonder pixel (A,B)=(62, 94) komt overeen met X=Xmax en Y=Ymin, dus: (62, 94) Û (Xmax, Ymin) Ymax, A=0
Y, A Ymin, A=62 Xmin B=0
Waaruit blijkt dat
X B
Xmax B=94
X - X min B-0 B Y max - Y 0- A A en = = = = X max - X min 94 - 0 94 Y max - Y min 0 - 62 62
zodat de gezochte omrekensleutel de volgende is:
A = 62 ´
Y max - Y Y max - Y min
B = 94 ´
X - X min X max - X min
2
Stel dat je het punt (3, 9) op de grafiek van y = x wilt markeren. Als het venster gegeven is door 0 £ x £ 5 en 0 £ y £ 16 zijn de pixelcoördinaten van (3, 9) volgens de omrekeningssleutel gelijk aan (27, 56). Voor het centrum van een letter moet je A-3 en B-1 doen, dus: ClrDraw:Text(24,55,"+"):Text(24,60,"(3,9)").
- 18 -
Gebruiksvriendelijkheid De informatie-techniek heeft zich de laatste tien jaar razendsnel ontwikkeld. In sommige opzichten misschien wel te snel. Voor handleidingen, laat staan de vertaling daarvan, is nauwelijks tijd meer. Veel moderne software is bijna honderd procent design, toeters en bellen. Erg mooi maar een goede uitleg voor het gebruik schiet er vaak bij in. Men gaat er nogal eens vanuit dat de gebruiker, in het wilde weg proberend, er zonder gebruiksaanwijzing ook wel uitkomt. En, erger nog, soms lijkt het wel of ook het programmeren via trial and error tot stand is gekomen. Als deze schoenmaker zich even tot de eigen leest beperkt en kijkt naar hetgeen op het terrein van TI83 basic programma's op internet wordt aangeboden dan valt op hoe weinig van die programma's van een goede uitleg voorzien zijn. Wij zullen proberen ons aan een aantal regels te houden. o o o o o o
o
Een programma moet altijd een intro hebben met een uitleg over hetgeen volgt. De broncode moet leesbaar zijn, iedere gebruiker moet in kunnen breken om veranderingen aan te brengen. In de eerste regels van het programma moet rekening gehouden worden met vorige hinderlijke instellingen: de vensterinstelling, de functies die er nog in staan, een STATplot, enzovoorts. Er moet een afsluiting zijn waarin de standaardinstellingen zoveel mogelijk hersteld worden. Als de gebruiker een fout maakt bij de invoer, moet er in principe een foutmelding komen. De Goto statement is de zwakste schakel in alle BASIC programma's. Niet alleen jij, maar ook de microprocessor zoekt zich wezenloos naar alle labels en verwijzingen. Wees dus zuinig met dit soort tijdrovende instructies. Gebruik als het even mogelijk is de menu functie. Sommige programma's verlopen traag, dat komt door de beperkingen in processorsnelheid en geheugenruimte. Vaak is met eenvoudige programmeermiddelen aanzienlijke tijdwinst te boeken.
Systematisch programmeren Het opsporen van fouten (debugging) tijdens de opbouw van je programma kan ondersteund worden door een handig gebruik van het Pause commando. Zie het volgende voorbeeld. We willen het scherm vullen met de cijfers 0 t/m 9 zodanig, dat er diagonaalsgewijze patronen van gelijke cijfers ontstaan. Zie het plaatje. De eerste en laatste regels van het programma zullen duidelijk zijn. Af en toe gaan we een regel invoegen of verwijderen. De programmaregels zouden daarvoor eigenlijk genummerd moeten zijn. Vandaar dat we (op papier! niet in de broncode) de regels nummeren (zoals in het oude BASIC) en daarbij de R voor rij, de K voor kolom en de X voor de cijfers 0 t/m 9 gebruiken. De regelnummers moet je niet intypen. Voeg in als eerste regel bijvoorbeeld 5!X en zie hoe het scherm zich vult met vijven. 10 20 30 40 80 90 100
5!X ClrHome For(R,1,8) For(K,1,16) Output(R,K,X) End End
Gaat het te snel? Je kunt het afdruktempo vertragen met de tussengevoegde regel: 85
For(P,1,50):End
Dat is een lege lus die 50 keer wordt doorlopen voor het programma verder gaat.
- 19 -
Nog beter is het programma aan het eind van elke rij even stil te zetten door op het moment dat K=17 is (dus direct achter de voorlaatste End) in te voegen: 95
Pause
Verwijder regel 85 dus maar weer (CLEAR). Inmiddels staat het scherm vol met vijven, dat was niet de bedoeling. Er moet iets komen als: 10 50
-1!X X+1!X
Draai deze tweede poging af. Druk een paar keer op ENTER en je ziet dat het tellen na de 9 gewoon doorgaat met 10, 11 enzovoorts. Maar door de overlap van het eerste cijfer van de twee krijg je een heel vreemd effect. Even nadenken. We hebben inmiddels het volgende programma: 10 20 30 40 50 80 90 95 100
-1!X ClrHome For(R,1,8) For(K,1,16) X+1!X Output(R,K,X) End Pause End
Hoe lossen we het probleem met de doorlopende cijfers op? Weet je wat? Trek 10 af van alle cijfers ³ 10. Of sneller, begin opnieuw met 0, zodra X 10 geworden is. Dat bereik je met de instructie: 60
If X=10: 0!X
Dit blijkt een stap in de goede richting te zijn. Je krijgt netjes de rij 0123456789012345 6789012345678901 2345… Maar helaas, het bedoelde effect met gelijke cijfers in diagonale rijen is er nog niet. Wat is het verband tussen het rijnummer (R) en het cijfer (X) in de eerste kolom? R=1 hoort bij X=0 R=2 hoort bij X=9 R=3 hoort bij X=8 R=4 hoort bij X=7 Afgezien van rij 1 , is telkens X+R=11. Aha! dus X=11-R. Dat is het verband! Dat leidt tot 70
If K=1 and R³2: 11-R!X
Waarmee ons programma klaar is. Nog even de regels 20 en 95 verwijderen: -1!X For(R,1,8) For(K,1,16) X+1!X If X=10: 0!X If K=1 and R³2: 11-R!X Output(R,K,X) End End Pause
De laatste Pause is er om de wat hinderlijk knipogende cursor onschadelijk te maken.
- 20 -
Niet tevreden? We geven een oplossing met één regel minder voor degenen die gezien hebben dat het verschil K-R het plaatscijfer X bepaalt: For(R,1,8) For(K,1,16) K-R!X If X³10:X-10 !X If X<0:X+10!X Output(R,K,X) End End Pause
Wat heeft dit alles met wiskunde te maken? Het gaat over cijfers, rijen en kolommen en het inzicht dat op diagonalen het verschil of de som van het rij- en kolomnummer constant is. En over systematisch foutenonderzoek. En over logische voorwaarden. En over problemen oplossen. Met schoolwiskunde heeft dat alles jammer genoeg weinig te maken. Maar het plezier, een probleem (of een grafische rekenmachine!) de baas te zijn is een universeel genoegen. Wie dat gevoel niet herkent is waarschijnlijk allang gestopt met lezen. Is het makkelijk om een happertje (<) dat streepjes (-) opeet over het scherm te laten wandelen? Ja hoor, je hoeft er alleen maar aan te denken om de plek waar het happertje stond weg te vegen. Daar is geen aparte instructie voor, maar met een spatie "er overheen" kan het ook: For(R,1,8) For(K,1,16) Output(R,K,"-") End End For (R,1,8) For (K,1,16) Output(R,K,"<") For(X,1,50):End Output(R,K," ") End End Pause
Wil je een happertje met slechte conditie vertonen dan kan dat. Verander daartoe in de tweede alinea van het programma de For lus in: For(X,1,5K+10R):End of iets dergelijks.
Het kansspel EVENON Twee spelers (A en B, jij en de TI83/84) kiezen een getal uit {1, 2, 3, 4, 5}, zonder dat getal in eerste instantie bekend te maken. De calculator doet dat random, jij kiest zelf. De bedoeling is een EVEN totaal te krijgen, want dat levert jou (A) een punt op. Als de som ONEVEN is, scoort de TI83/84. Het programma heeft de naam EVENON gekregen.
- 21 -
Ga het spelletje eerst maar eens een flink aantal keren spelen en ontdek gaandeweg dat de kansen op even en oneven niet even groot zijn. Er is dus een strategie te bedenken die op de lange duur winst oplevert. Het maakt dus uit, of speler A met een even {2, 4} dan wel een oneven keuze {1, 3, 5} begint. Je kunt de winstkans in die twee gevallen van te voren berekenen, doe dat maar eens. Een andere, veel gebruikte mogelijkheid is de simulatie van een kansexperiment. Dat is in het programma SIMEVEN gebeurd. Simuleer het spelletje 1000 keer, waarbij je iedere keer opent met EVEN en kijkt wat de conclusie is. EVENON
SIMEVEN
ClrHome: Disp " EVENON" Disp "---------------" Disp "JE SPEELT TEGEN" Disp "DE TI83/84": Disp "" Disp "PROBEER EEN EVEN" Disp "SOM TE KRIJGEN." Output(8,10,"[ENTER]") Pause : ClrHome Disp "KIES EEN GETAL" Disp "UIT {1,2,3,4,5}" Disp "DE TI83 DOET DAT" Disp "OOK, RANDOM.": Disp "" Disp "JE SCOORT ALS DE" Disp "SOM EVEN IS..." Output(8,10,"[ENTER]": Pause 0üE: 0üO: seq(X,X,1,5)üL1
ClrHome: Disp " SIMEVEN" Disp "----------------" Disp "A KIEST UIT" Disp " {2,4}" Disp "B KIEST UIT" Disp " {1,2,3,4,5}" Disp "IS A+B EVEN?" Output(8,10,"[ENTER]") Pause : ClrHome 0üE: 0üO Output(5,1,"TOTAAL") Output(6,1,"EVEN:") Output(7,1,"ONEVEN:") Output(5,13,"PROC")
Lbl 1 ClrHome Input "GETAL? ",A If sum(L1=A)=0:Goto 1 randInt(1,5)üB: A+BüC If fPart(C/2)=0 Then E+1üE Else O+1üO End Output(2,1,"TI83:"): Output(2,8,B) Output(3,1,A): Output(3,2,"+") Output(3,3,B): Output(3,4,"=") Output(3,5,C) Output(5,1,"TOTAAL") Output(6,1,"EVEN:"): Output(6,9,E) Output(7,1,"ONEVEN:"): Output(7,9,O) Output(8,10,"[ENTER]): Pause Goto 1
For(X,1,1000) 2randInt(1,2)üA: randInt(1,5)üB A+BüC If fPart(C/2)=0 Then E+1üE Else O+1üO End Output(3,1,A): Output(3,2,"+") Output(3,3,B): Output(3,4,"=") Output(3,5,C) Output(6,8,E): Output(7,8,O) 100E/(E+O)üP: round(P,1)üP Output(6,13,P) End Output(1,1,"NA 1000 KEER ...")
Na ongeveer anderhalve minuut kreeg ik met SIMEVEN het hiernaast staande schermpje. Nieuwsgierige programmeurs (en nieuwsgierigheid is het begin van alle wetenschap) zullen zich afvragen welke conclusies er te trekken zijn als je de randvoorwaarden van dit simpele spelletje verandert. Wat voor resultaat krijg je bijvoorbeeld als je: · A random laat kiezen uit {2,4,6} en B uit {1,2,3,4,5,6} · A random laat kiezen uit {2,4,6} en B uit {1,2,3,4,5,6,7} · A random laat kiezen uit {1,2,3,4,5} en B uit {1,2,3,4,5}? In het laatste geval is de kans op een even som niet precies 50%, wat je misschien zou denken ... Het is makkelijk zat om deze kleine wijzigingen in de broncode aan te brengen. Je kunt ook een nulletje toevoegen en 10000 keer simuleren, maar dan moet je 15 minuten wachten op antwoord. Ik wens je veel plezier met dit wetenschappelijk onderzoek.
- 22 -