8. AVANCERAD DATABEHANDLING

8.1 READ och DATA

Du har sett hur man tilldelar värden till variabler direkt i program (A = 2), och hur du tilldelar olika värden under tiden programmet körs -- genom INPUT-kommandot.

Det är trots allt många tillfällen när ingen av dessa metoder passar det du vill göra, speciellt om det innehåller en mängd information.

Prova detta korta program:

  10 READ X
  20 PRINT "X ÄR NU :"; X
  30 GOTO 10
  40 DATA 1, 34, 10.5, 16, 234.56

  RUN
  X ÄR NU : 1
  X ÄR NU : 34
  X ÄR NU : 10.5
  X ÄR NU : 16
  X ÄR NU : 234.56
  ?OUT OF DATA  ERROR IN 10
  READY.

På rad 10 läser datorn med hjälp av READ ett värde från DATA-satserna och tilldelar värdet till variabeln X. Varje gång genom programmet läses nästa värde i DATA-satserna och det värdet tilldelas X, varefter X skrives ut med hjälp av PRINT. En pekare i datorn håller ordning på vilket värde som ska läsas nästa gång:

           Pekare
             |
  40 DATA 1, 34, 10.5, 16, 234.56

När alla värden har används och datorn inte finner mer data visas felindikering "OUT OF DATA" eftersom det inte finns mer data att läsa (READ).

Det är viktigt att följa exakt rätt format vid DATAsatser:

  40 DATA 1, 34, 10.5, 16, 234.56
           ↑                     ↑
           |                     |
    Komma separerar         Inget komma
    olika data

Datasatser kan innehålla heltal, decimaltal eller exponentierade tal. Men du kan inte läsa andra variabler, eller ha matematiska uttryck som DATA-satser. Följande är fel:

  40 DATA A, 23/56, 2*5

Du kan emellertid använda en strängvariabel i READ-satsen och sedan placera stränginformation i DATA-satsen. Följande är acceptabelt:

  NEW

  10 FOR X = 1 TO 3
  15 READ A$
  20 PRINT "A$ ÄR NU :"; A$
  30 NEXT
  40 DATA DETTA,ÄR,KUL

  RUN
  A$ ÄR NU :DETTA
  A$ ÄR NU :ÄR
  A$ ÄR NU :KUL
  READY.

Lägg märke till att READ denna gång var placerat inom en FOR... NEXT- slinga. Denna slinga utfördes sedan för att passa antalet data i DATA-satsen. I flera fall vill man ändra antalet data i DATA-satserna varje gång programmet körs. Ett sätt att slippa räkna antalet data i DATA-satserna och ändå undvika 'OUT OF DATA'-felindikering är att placera en "flagga" som sista värde i DATA-satserna. Detta kan vara ett värde som din data aldrig kan anta, såsom ett negativt tal eller ett mycket stort eller mycket litet tal. När det värdet lästs grenar programmet ut till nästa del.

Det finns ett sätt att återanvända samma DATA senare i programmet genom instruktionen RESTORE som återställer datapekaren till början av datalistan. Lägg till rad 50 till det tidigare programmet:

  50 GOTO 10

Du kommer att få, 'OUT OF DATA', felmeddelande eftersom programmet styrs tillbaka till rad 10 för att på nytt läsa data och datapekaren indikerar då att alla data har använts. Lägg nu till:

  45 RESTORE

och kör programmet igen. Datapekaren blir återställd (RESTOREad) och samma data-sats kan läsas på nytt.

8.2 GENOMSNITT

Följande program illustrerar en praktisk användning av READ- och DATA-instruktionen, genom att läsa ett antal värden och beräkna dess medelvärde.

  NEW

   5 T = 0 : CT = 0
  10 READ X
  20 IF X = -1 THEN 50 : REM KONTROLL AV FLAGGA
  25 CT = CT + 1
  30 T= T + X : REM UPPDATERA TOTAL
  40 GOTO 10
  50 PRINT "DET HAR LÄSTS"; CT ;"VÄRDEN"
  60 PRINT "TOTAL = "; T
  70 PRINT "MEDELVÄRDE ="; T/CT
  80 DATA 75, 80, 62, 91, 87, 93, 78, -1

  RUN
  DET HAR LÄSTS 7 VÄRDEN
  TOTAL =  566
  MEDELVÄRDE = 80.8571429

Rad 5 sätter CT, räknaren och T, total till 0. Rad 10 läser ett värde och tilldelar värdet till X. Rad 20 kontrollerar om värdet är vår "FLAGGA" (här -1). Om det lästa värdet är giltiga data ökas CT med 1 och X adderas till total.

När "FLAGGAN" lästs grenar programmet av till rad 50 vilken skriver ut antalet inlästa värden. Rad 60 skriver ut totalvärdet och rad 70 delar totalvärdet med antalet värden för att få medeltalet.

Genom att använda en "FLAGGA" i slutet av DATA-satserna, kan du placera godtyckligt antal data i DATA-satserna. Dessa kan sträcka sig över ett flertal rader utan att du behöver besvära dig med att räkna antalet inskrivna värden.

En variation på READ-instruktionen innebär tilldelning ur samma DATA-rad till olika variabler. Detta medger även blandning av teckensträngar och numeriska variabler. Du kan göra allt detta i följande program som läser (READ) ett namn, några poäng -- exempelvis i bowling -- och skriver ut namn, poäng och medelpoäng:

  NEW

  10 READ N$, A, B, C
  20 PRINT N$;"'S POÄNG VAR:"; A ;" "; B ;" "; C
  30 PRINT "MEDELTALET VAR: ";(A+B+C)/3
  40 PRINT : GOTO 10
  50 DATA ROLF, 190, 185, 165, OVE, 225, 245, 190
  60 DATA KENT, 155, 185, 205, KJELL, 160, 179, 187

  RUN
  ROLF'S POÄNG VAR : 190   185   165
  MEDELTALET VAR:  180

  OVE'S POÄNG VAR: 225   245   190
  MEDELTALET VAR:  220

Datasatserna är uppställda på det sätt som READ-instruktionen förväntar sig informationen- ett namn (en teckensträng), därefter tre numeriska värden. Med andra ord, N$ tilldelas ordet ROLF, A i READ satsen tilldelas 190 och B och C får 185 respektive 165. Därefter repeteras Inläsningen i samma ordning för återstoden av informationen. (Ove och hans poäng, Kent och hans poäng och Kjell och hans poäng).

8.3 INDEXERADE VARIABLER

Tidigare har vi endast använt enkla BASIC-variabler såsom, A, A$ och NU för att representera värden. Dessa var en enkel bokstav följd av en bokstav eller siffra.

Det är tveksamt om du i något av de program du skulle vilja skriva kommer att behöva fler än de kombinationer av bokstäver och siffror som finns tillgängliga. Men du är begränsad på det sätt variabler används i program.

Låt mig nu visa dig på egenskaperna hos indexerade variabler eller fältvariabler:

                               A(1)
                               ↑ ↑
                               | |___ Index
                               |_____ Variabel

Ovanstående uttalas: A indexerat med 1. En indexerad variabel består av en bok. stav följt av ett index inom parenteser. Lägg märke till skillnaden mellan A, A1 och A(1). Alla är unika. Endast A(1) är en fältvariabel.

Fältvariabler såväl som enkla variabler betecknar ett minnesutrymme inne i datorn. Jämför indexerade variabler med lådor att lagra information i på samma sätt som enkla variabler

        +------------------------+
  A(0)  |                        |
        +------------------------+
  A(1)  |                        |
        +------------------------+
  A(2)  |                        |
        +------------------------+
  A(3)  |                        |
        +------------------------+
  A(4)  |                        |
        +------------------------+
Om du skrev:
  10 A(0) = 25:A(3) = 55:A(4) = -45.3
då skulle minnet se ut så här:
        +------------------------+
  A(0)  | 25                     |
        +------------------------+
  A(1)  |                        |
        +------------------------+
  A(2)  |                        |
        +------------------------+
  A(3)  | 55                     |
        +------------------------+
  A(4)  | -45.3                  |
        +------------------------+

En fältvariabel kallas också en matris. I detta fall en endimensionell matris eller en vektor. Senare ska vi berätta om flerdimensionella matriser.

Index kan också vara mer komplexa och innehålla andra variabler eller beräkningar. Följande är acceptabla fältvariabler:

  A(X)  A(X + 1)  A(2 + 1)  A(1*3)

Uttrycken inom parenteserna beräknas enligt reglerna för aritmetiska operationer som vi studerade i kapitel 2.

Nu när vi fått grundreglerna klara, hur kan vi använda fältvariabler? Ett sätt är att lagra en lista med tal som läses in i datorn med INPUT- eller READ-instruktioner.

Låt oss använda fältvariabler för att beräkna medelvärde på ett nytt sätt.

   5 PRINT CHR$(147)
  10 INPUT " ANTAL TAL:"; X
  20 FOR A = 1 TO X
  30 PRINT "SKRIV TALET#"; A ;: INPUT B(A)
  40 NEXT
  50 SU = 0
  60 FOR A = 1 TO X
  70 SU = SU + B(A)
  80 NEXT
  90 PRINT : PRINT "MEDELTAL ="; SU/X

  RUN
  ANTAL TAL:? 5
  SKRIV TALET# 1 ? 125
  SKRIV TALET# 2 ? 167
  SKRIV TALET# 3 ? 189
  SKRIV TALET# 4 ? 167
  SKRIV TALET# 5 ? 158

  MEDELTAL = 161.2

Det finns möjligen enklare sätt att utföra vad vi gjorde men detta program illustrerar väl hur fältvariabler fungerar. Rad 10 frågar hur många variabler som ska behandlas. Denna variabel "X" fungerar som räknare för slingan som läser in talen vilka tilldelas variabeln B. Varje gång datorn arbetar sig genom inläsningsslingan ökas A med ett så att nästa värde tilldelas nästa element A. Exempelvis första gången programmet löper genom loopen är A = 1 varför första värdet tilldelas variabeln B(1). Nästa gång har värdet på A ökat till 2 varför nästa värde tilldelas B(2) och så vidare tills samtliga värden har lästs in. Men nu kommer vi till den stora skillnaden. När värdena en gång lästs in lagras de i en matris, redo att användas för olika ändamål. Tidigare lagrades endast en adderad totalsumma varje gång programmet gick genom INPUT- eller READ-slingan. Detta hindrade oss att gå tillbaka till speciella data utan att läsa in alla informationer på nytt.

På rad 50 till 80 finns en slinga som adderar upp de olika elementen i matrisen för att därefter visa genomsnittet på skärmen. Denna del av programmet visar att alla värden är lagrade i minnet och kan nås om så önskas.

För att visa att alla de olika värden verkligen är separat lagrade i en matris, skriv följande direkt efter att programmet har körts:

  FOR A=1 TO 5 : ? B(A), : NEXT
  125        167        189        167
  158
Skärmen visar dig aktuella värden då innehållet i matrisen skrivs ut.

8.4 DIMENSIONERING

Om du försökte att skriva in fler än tio nummer i det förra exemplet fick du, "DIMENSION ERROR", felmeddelande. Matriser upp till 11 element (index 0 till 10 för en endimensionsmatris) kan användas när man vill, lika enkelt som en vanlig variabel. Matriser med mer än 11 element måste DIMensioneras.

Lägg till denna rad till ditt program:

   5 DIM B(100)

Detta talar om för din dator att du kommer att behöva plats för maximalt 100 element i matrisen B.

Dimensioneringsinstruktioner kan också användas tillsammans med en variabel. Följande rad kan ersätta rad 5, (glöm inte att ta bort rad 5).

  15 DIM B(X)

Detta DIMensionerar matrisen för exakt det antal värden som behövs. Var emellertid försiktig. När en matris en gång är dimensionerad kan den inte ändras i en annan del av programmet. Du kan emellertid ha flera matriser i ett program och dimensionera dem alla på samma rad.

  10 DiM C(20), D(50), E(40)

8.5 SIMULERAT TÄRNINGSKAST

Då programmen blir större hjälper indexerade variabler till att begränsa antalet erforderliga instruktioner och gör programmet enklare att skriva.

En endimensionell matris kan användas, som i nedanstående exempel, för att hålla rätt på hur många gånger en speciell sida kommer upp vid tärningskast:

  1 PRINT CHR$(147):REM SIMULERA TÄRNINGSKAST
  10 INPUT"ANTAL KAST";X
  20 FOR L = 1 TO X
  30 R = INT(6*RND(1))+1
  40 F(R)=F(R)+1
  50 NEXTl
  60 PRINT"SIDA","ANTAL GÅNGER"
  70 FOR C = 1 TO 6 :PRINT C, F(C):NEXT
(Hämta)

Matrisen S, för sida, används för att hålla reda på hur många gånger en speciell sida kommer upp. Exempelvis varje gång en tvåa kommer upp, ökas S(2) med 1. Genom att använda index som numret på den sida som kommer upp, har vi eliminerat behovet av sex andra variabler (en för varje sida) och ett antal instruktioner för att kontrollera vilket nummer som kom upp.

Rad 10 frågar hur många kast du önskar simulera.

Rad 20 sätter upp en slinga för att simulera, (d.v.s. "låtsas" vara en tärning genom att generera ett slumptal från 1 till 6) ett tärningskast och räkna upp rätt variabel beroende på vilken sida som kommer upp.

Efter alla kast är klara skriver rad 60 ut överskriften och rad 70 det antal gånger varje sida kommit upp.

En körning kan se ut så här:

  ANTAL KAST? 1000
  SIDA       ANTAL GÅNGER
   1          174
   2          168
   3          179
   4          156
   5          162
   6          161

Bara som en jämförelse ska vi se hur vi kan skriva programmet utan att använda matriser. Bry dig inte om att skriva in det, men lägg märke till de ytterligare programinstruktioner som erfordras.

  10 INPUT "ANTAL KAST"; X
  20 FOR L = 1 TO X
  30 R = INT(6*RND(1))+1
  40 IF R = 1 THEN F1 = F1 + 1 : NEXT
  41 IF R = 2 THEN F2 = F2 + 1 : NEXT
  42 IF R = 3 THEN F3 = F3 + 1 : NEXT
  43 IF R = 4 THEN F4 = F4 + 1 : NEXT
  44 IF R = 5 THEN F5 = F5 + 1 : NEXT
  45 IF R = 6 THEN F6 = F6 + 1 : NEXT
  60 PRINT "SIDA", "ANTAL GÅNGER"
  70 PRINT 1, F1
  71 PRINT 2, F2
  72 PRINT 3, F3
  73 PRINT 4, F4
  74 PRINT 5, F5
  75 PRINT 6, F6

Programmet har dubblat sin storlek från 8 till 16 rader. I större program kommer, om matriser används, besparingar att bli ännu mer dramatiska.

8.6 TVÅDIMENSIONELLA FÄLT

Tidigare i detta kapitel experimenterade du med endimensionella fält. Denna typ beskrevs som en grupp av efter varandra följande lådor som vardera lagrade ett element i fältet. Hur tror du att ett tvådimensionellt fält ser ut?

Ett två-dimensionellt fält skrivs enligt följande:

                              A(4,6)
                              ↑ ↑ ↑
                              | | |
                              | Index
                              |
                          Fältbeteckning
och kan beskrivas som en tvådimensionell matris i minnet:
             0       1       2       3       4       5       6
         +-------+-------+-------+-------+-------+-------+-------+
    0    |       |       |       |       |       |       |       |
         +-------+-------+-------+-------+-------+-------+-------+
    1    |       |       |       |       |       |       |       |
         +-------+-------+-------+-------+-------+-------+-------+
    2    |       |       |       |       |       |       |       |
         +-------+-------+-------+-------+-------+-------+-------+
    3    |       |       |       |       |       |       |       |
         +-------+-------+-------+-------+-------+-------+-------+
    4    |       |       |       |       |       |       |       |
         +-------+-------+-------+-------+-------+-------+-------+

Indexen kan ses som de motsvarade rad- och kolumnnumren i ovanstående figur där fältens olika element lagras.

                              A(3,4) = 255
                                ↑ ↑
                                | |___ Kolumn
                                |
                               Rad

Om vi tilldelade värdet 255 till A(3,4) kan vi se det som värdet 255 placerades i tredje radens fjärde kolumn i ovanstående figur.

Tvådimensionella fält följer samma regler som vi lärt för de endimensionella fälten:
De måste dimensioneras: DIM A(20,20)
Kan tilldelas data: A(1,1) = 255
Kan tilldela data till andra variabler: AB = A(1,1)
Kan skriva ut värden: PRINT A(1,1)

Om två-dimensionella fält fungerar på samma sätt som endimensionella fält vilka ytterligare fördelar ger då dessa större fält?

Prova detta: Kan du tänka ut ett sätt att använda ett tvådimensionellt fält för att ställa upp svaren på en frågelista för din klubb? Listan innehåller fyra frågor med upp till tre svar på varje fråga. Problemet kan skrivas så här:

FRÅGOR TILL MEDLEMMARNA
1. FÖREDRAR DU FÖRSLAG 1?
_1-JA _2-NEJ _3-VET EJ
... och så vidare.
matrisen för detta problem kan ritas upp på detta sätt:
                                        SVAR

                        JA              NEJ            VET EJ

                +----------------+----------------+----------------+
  FRÅGA 1       |                |                |                |
                +----------------+----------------+----------------+
  FRÅGA 2       |                |                |                |
                +----------------+----------------+----------------+
  FRÅGA 3       |                |                |                |
                +----------------+----------------+----------------+
  FRÅGA 4       |                |                |                |
                +----------------+----------------+----------------+

Själva programmet som utför uppställningen för frågeformuläret kan se ut så här:

  20 PRINT"{clear}":REM CLR/HOME
  30 FOR R = 1 TO 4
  40 PRINT"FRÅGA NR:";R
  50 PRINT"1-JA  2-NEJ  3-VET EJ"
  60 PRINT"VILKET VAR SVARET ?";
  61 GET C:IF C <1 OR C >3 THEN 61
  65 PRINTC:PRINT
  70 A(R,C) = A(R,C) + 1:REM UPPDATERA ELEMENT
  80 NEXT R
  85 PRINT
  90 PRINT"VILL DU SKRIVA YTTERLIGARE SVAR":PRINT"(J/N)";
  100 GETA$:IF A$ = "" THEN 100
  110 IF A$="J" THEN 20
  120 IF A$<> "N"THEN 100
  130 PRINT"{clear}";"TOTALA ANTALET SVAR VAR:":PRINT
  140 PRINT SPC(19);"SVAR":PRINT
  141 PRINT"FRÅGA","JA","NEJ","VET EJ"
  142 PRINT"-----  ----------------------------"
  150 FOR R = 1 TO 4
  160 PRINT R,A(R,1),A(R,2),A(R,3)
  170 NEXT R

  RUN

  FRÅGA NR: 1
  1-JA  2-NEJ  3-VET EJ
  VILKET VAR SVARET ? 1
  FRÅGA NR: 2
  1-JA  2-NEJ  3-VET EJ
  VILKET VAR SVARET ? 1


  och så vidare...


  TOTALA ANTALET SVAR:

  FRÅGA     JA       NEJ       VET EJ
  -----  ----------------------------
   1        4         3        2
   2        4         2        3
   3        6         1        2
   4        5         4        0
(Hämta)

Detta program använder sig av flera av de programmeringsrutiner vi gått igenom tidigare. Även om du inte har någon användning för det aktuella programmet bör du försöka förstå funktionen.

Programmets kärna är ett 4 gånger 3 två-dimensionellt fält, A(4,3). Totala antalet svar för varje möjlig variant av svar lagras i motsvarande fältelement. För att göra det enklare använder vi inte första raden och kolumnen A(0,0) till A(0,4). Kom emellertid ihåg att dessa element alltid finns med när du gör matriser.

I verkligheten, om svaret på fråga 1 är JA, Ökas A(1,1) med 1 -- rad 1 för fråga ett och kolumn 1 för JA-svar. Resten av frågor och svar följer samma monster.

Ett NEJ-svar för fråga 3 skulle alltså addera 1 till elementet A(3,2) och så vidare.

[ ← Föregående | Innehållsförteckning | Nästa → ]
[HTML 4.01]
Peter Krefting / $Date: 2009-10-08 13:34:08 $ / peter@softwolves.pp.se