Kommentarer til eksamen V2012 - London OL


Oppgave 3 - Programmering av resultathåndtering

Hva må lages:

Datastruktur:

Nærliggende å lagre alt i en (assosiativ) tabell.

navn: Olsen lengder:
66 70.3 71.4 0 79.2 49.1
lengst: 79.2
navn: Jensen lengder:
76 59.3 72.4 67 69.2 49.1
lengst: 76
... ... ...
navn: Hansen lengder:
32 48 55 52 53 55
lengst: 55

Fordel: Lett å sortere med registreringer.sortOn("lengst") når vi skal lage resultatliste!

Ulempe:søke opp navn når vi skal vise kastlengder, da indexOf() ikke virker på feltnavn i assosiative array.

( Akkurat i dette tilfellet løses dette ved at brukeren indirekte velger indeks for oss når brukeren velger navn i komboboksen,
så i denne oppgaven slipper vi å lage en søkerutine for å finne hvilken indeks som inneholder navnet vi slår opp på.
Ellers måtte vi ha laget omtrent noe slikt:

for(var i:int = 0; i < registreringer.length; i++) {
   var indeks: int = -1;                         //Default ikke funnet
   if(tfNavn.text == registreringer.navn) {
      indeks = i;                       //funnet
      break;                            //hopper ut av for-løkke, unødvendig å gå videre
   }//if
}//for
)

Tabellen deklareres tom:

var registreringer: Array = new Array(); 

Og fylles opp etterhvert med metoden push() når vi registrerer navn.

Kodeskisser til underapplikasjonene:

Jeg viser bare funksjoner som "gjør jobben", ikke oppkobling mot brukergrensesnitt med lytterfunksjoner.
Fordelen med å legge all funksjonalitet i funksjoner og bare kalle funksjoner fra lytterfunksjonene,
er at alt kan testes ut uavhengig av brukergrensesnittet!.

Se testkode helt til slutt!

Registrering av navn:

/*  GUI:                                                                            
       Registrering av deltagere
       Navn:    [ Olsen ]                TextField tfNavn
                  [ OK]                  Button    btnRegNavn
*/
... 
/*   Funksjon som registrerer navn.
     Kalles av lytterfunksjon med:    registrerNavn( tfNavn.text );
*/
function registrerNavn(navn: String): void {
   if( registreringer.length < 7 ) {     // Ikke registrer fler enn 8 deltagere!
      var o: Object = new Object();      // Lager objekt med
      o.navn = navn;                     //     navn
      o.lengder = new Array();           //     lengder
      o.lengst = 0;                      //   og maks-lengde
      registreringer.push(o);
   } else {
      trace("8 finalister allerede registrert!");
   }//if
}// registrerNavn()

 

Registrering av kastlengder for en deltager:

/*  GUI:                                                                            
        Registrering av lengder
        Navn:         [ Jensen  ]       ComboBox   cbNavn
        Ny lengde:    [   77.7  ]       TextField  tfLengde
                         [ OK ]         Button     btnRegLengde
*/
...
/*  Funksjon som registrerer lengde */
function registrerLengde(indeks: int, lengde: Number): void {
   var omgang:   int =    registreringer[indeks].lengder.length;
   if(omgang <6) {
      registreringer[indeks].lengder.push( lengde  );
   } else {
      trace("6 lengder allerede registrert!");
   }//if
}// registrerLengde()

Vis kastlengdene til en deltager:

/*  GUI:                                                                                                        
         Navn:      [ Olsen ]                ComboBox   cbNavn                          
                     [OK]                    Button    btnVisLengder
         Lengder:   [          ]             TextArea  taLengder
                    [          ]
                    [          ]
                    [          ]
*/
...
/*  Funksjon som viser lengdene for en deltager */
function visLengder(indeks: int): String {
   var lengder:  String = "Registrerte lengder for " + registreringer[indeks].navn+":\n";
   for( var omgang:int = 0; omgang < registreringer[indeks].lengder.length ; omgang++ ) {
      lengder = lengder + 
         "Omgang: " + (omgang+1) + "   Lengde: " + registreringer[indeks].lengder[omgang].toFixed(1) + "\n"; 
   }//for
   return lengder;
}//visLengder()

 

Vis resultatliste:

/* GUI:
      Resultatliste vises i TextArea taResultatliste
*/
...
/* Funksjoner som  lager resultatlisten */ 
function sorterRegistreringer(): void {
   for( var i: int = 0; i < registreringer.length; i++) {
      for( var j: int = 0; j < registreringer[i].lengder.length; j++) {
         registreringer[i].lengder.sort(Array.NUMERIC+Array.DESCENDING); // Sorterer lengdetabellen for en deltager
         registreringer[i].lengst=registreringer[i].lengder[0]; // Lengste kast ligger nå sist i lengdetabellen
      }//for j
   }//for i 
   registreringer.sortOn("lengst", Array.NUMERIC+Array.DESCENDING); // Sorterer registreringstabellen på feltet "lengst"
}//sorterRegistreringer()
function lagResultatliste(): String {
   var resultat: String = "Resultatliste:\n";
   for(var i:int = 0; i<registreringer.length; i++){
      resultat = resultat + (i+1) + " " + registreringer[i].navn + "\t\t" + registreringer[i].lengst.toFixed(1) + "\n";
   }//for
   return resultat;
}//lagResultatliste()

Testkode for testing av funksjonene over:

// Registrer noen deltagere:                                    
registrerNavn("Ferkenberg");
registrerNavn("Hattek");
registrerNavn("Woxholt");
registrerNavn("Snytenstrup");
registrerNavn("Sterkesen");
// Registrer noen tilfeldige lengder:
for(i=0;i<registreringer.length;i++) {
   for(j=0;j<6;j++) {
      var lengde: Number = Math.random()*80;
      registrerLengde( i, lengde );
   }//for j (lengder)
}//for i (deltager)
// Skriv ut lengder for alle deltagere:
for(i = 0; i<registreringer.length;i++) {
   trace(visLengder(i));
}//for
// Vis resultatliste:
sorterRegistreringer();
trace( lagResultatliste() );
Dette vil gi omtrent denne utskriften i Output-vinduet:
Registrerte lengder for Ferkenberg:
Omgang: 1   Lengde: 78.0
Omgang: 2   Lengde: 33.9
Omgang: 3   Lengde: 32.4
Omgang: 4   Lengde: 40.0
Omgang: 5   Lengde: 72.0
Omgang: 6   Lengde: 58.5

Registrerte lengder for Hattek:
Omgang: 1   Lengde: 8.0

...
Omgang: 6   Lengde: 77.7

...

Registrerte lengder for Sterkesen:
Omgang: 1   Lengde: 65.0
Omgang: 2   Lengde: 5.2
Omgang: 3   Lengde: 1.5
Omgang: 4   Lengde: 21.1
Omgang: 5   Lengde: 38.1
Omgang: 6   Lengde: 5.6
Resultatliste:
1  Woxholt         79.6
2  Ferkenberg      78.0
3  Snytenstrup     77.7
4  Sterkesen       65.0
5  Hattek          57.6

Kode for å koble funksjonene over til brukergrensesnitt:

/* Komboboks cbNavn:                                                                     
   Fyll ut komboboksen med navn fra tabellen.
   Funksjon fordi den brukes flere steder
*/
function fillComboBox(cb: ComboBox): void {
   for( var i: int = 0; i < registreringer.length; i++ ) {
      var o: Object = new Object();
      o.label = registreringer[i].navn;
      o.data = "";
      cb.addItem(o);
   }//for
}//fillComboBox()
fillComboBox(cbNavn);                     //Bruker funksjonen til å fylle komboboks
/* Lytterfunksjoner (må kobles til knapper som kjører koden) */
function btnRegNavnKlikket(evt: MouseEvent): void {
   registrerNavn( tfNavn.text );
}//btnRegNavnKlikket()
function btnRegLengdeKlikket(evt: MouseEvent): void{
   var lengde: Number = Number( tfLengde.text );
   var indeks: int    = cbNavn.selectedIndex;
   registrerLengde(indeks, lengde );
}//btnRegKlikket()
function btnVisLengderKlikket(evt: MouseEvent): void {
   var indeks: int = cbNavn.selectedIndex;
   var tekst: String = visLengder(indeks);
   taLengder.text = tekst;
}//btnVisLengderKlikket()
function btnVisResultatKlikket(evt: MouseEvent): void {
   sorterRegistreringer();
   var tekst: String = lagResultatliste();
   taResultatliste.text = tekst;
}//btnVisResuyltatKlikket()

Objektorientering:

Kunne lagt all grunnleggende funksjonalitet i en egen klasse med filnavn Resultat.as, omtrent slik:

Resultat
(ingen egenskaper)
registrerNavn(String)
registrerLengde(int,Number)
visLengder(int)
sorterRegistreringer()
lagResultatliste()

I Flash kan vi da bruke klassen slik:

var resultat: Resultat = new Resultat();      // Opprette klassen med konstruktørmetoden                 
...
// Lytterfunksjonene kan bruker klassen slik: (Må angi klassen funksjonene er i med kommanotasjon!)
function btnRegNavnKlikket(evt: MouseEvent): void {
   resultat.registrerNavn( tfNavn.text );
}//btnRegNavnKlikket()
function btnRegLengdeKlikket(evt: MouseEvent): void{
   var lengde: Number = Number( tfLengde.text );
   var indeks: int    = cbNavn.selectedIndex;
   resultat.registrerLengde(indeks, lengde );
}//btnRegKlikket()
function btnVisLengderKlikket(evt: MouseEvent): void {
   var indeks: int = cbNavn.selectedIndex;
   var tekst: String = resultat.visLengder(indeks);
   taLengder.text = tekst;
}//btnVisLengderKlikket()
function btnVisResultatKlikket(evt: MouseEvent): void {
   resultat.sorterRegistreringer();
   var tekst: String = resultat.lagResultatliste();
   taResultatliste.text = tekst;
}//btnVisResuyltatKlikket()

Filen Resultat.as må inneholde:

package {                                                                               
   public class Resultat {
      var registreringer: Array = new Array();
      //constructor:
      public function Resultat() {
         //intet å gjøre
      }//constructor
      public function registrerNavn(navn: String):void {
         ...                 // kode som i eksemplene over!
      }//registrerNavn()
      public function registrerLengde(indeks: int, lengde: Number): void {
         ...
      }//registrerLengde()
      public function visLengder(indeks: int): String {
         ...
      }//visLengder()
      public function sorterRegistreringer(): void {
          ...
      }//sorterRegistreringer()
      public function lagResultatliste():String {
         ...
      }//lagResultatliste()
   }//class Resultat
}//package