Opdracht | Programma | Data |
Memory Based Learner | learner/classifier | instances: features, classe; frequentielijst: classe, frequentie |
Overhoringsprogramma | programma | paren: Engels, Nederlands |
Parser | parser | grammatikaregels: linker, rechter kant |
Galgje | programma | woord, welke letters al geraden |
Ten eerste betekent dit bijvoorbeeld dat de grammatikaregels niet als
Scheme-functies van de parser geïmplementeerd zijn, maar ergens in een
lijst zitten.
Maar ten tweede moet ook het precieze formaat van die lijstelementen
niet uitmaken. Zo kan ik de regel S -> NP VP uitdrukken als ( S NP VP
) of ( NP VP S ) of ( ( NP VP ) . S ). Al naar gelang
waarvoor ik kies zouden in mijn parserprogramma uitdrukkingen als (car
regel) of (car (reverse regel)) of (cdr regel) opduiken,
als ik de linker kant van de regel (de S) bedoel. Dit is niet alleen onoverzichtelijk,
maar ook erg onhandig als ik later besluit om van formaat te wisselen,
want dan moet ik die uitdrukkingen op alle plaatsen vervangen. Beter is
het om in dit geval een aparte functie "linker_kant" te maken, die als
input een regel krijgt, en als output de linker kant levert. Alleen deze
functie hoeft te "weten" hoe het formaat van die regels nou precies is.
En alleen deze functie hoef ik dus aan te passen als ik van formaat wissel.
Overal elders blijft gewoon (linker_kant regel) staan. Dit
is data abstractie in een notedop.
Nog verder doorgevoerd wordt deze gedachte in object-georienteerd programmeren,
waar elke regel samen met de functie "linker_kant" een apart object vormt,
en de linker kant van de regel alleen via deze objectsfunctie toegankelijk
is. Maar Scheme is niet object-georienteerd.
(define my-eof #!eof) ; gambit (define my-file "stud.txt") ; gambit ; (define my-eof eof) ; pcscheme ; (define my-file "C:/terug/stud.txt") ; pcscheme ;;;;;;;;;;;;;;;;;;; initialisatie ;;;;;;;;;;;; (define sb (lambda () (define poort (open-input-file my-file) ) (studbeheer-r (lees_lijst '() poort)) (close-input-port poort) ) ) (define lees_lijst (lambda (lijst poort) (define woord (read poort)) (if (equal? my-eof woord) lijst (lees_lijst (cons woord lijst) poort)))) ;;;;;;;;;;;;;;;;;;; hoofdprogramma ;;;;;;;;;;;; (define studbeheer-r (lambda (ls) (display "Wilt u student t)oevoegen,") (newline) (display "op a)chternaam sorteren,") (newline) (display "l)ijst afprinten") (newline) (display "gemiddelde p)unten berekenen of") (newline) (display "s)toppen") (newline) (display "(toets t,a,l,p of s)") (newline) (let ((keuze (read))) (if (equal? keuze 's) (begin (display "Tot ziens") (newline) ) (begin ; de "else" (newline) (cond ((equal? keuze 't) (set! ls (cons (nieuwe-stud) ls))) ((equal? keuze 'a) (set! ls (sorteer ls))) ((equal? keuze 'l) (druk-af ls)) ((equal? keuze 'p) (middel-punten 0 0 ls)) (else (display "Verkeerde letter!")) ) (newline) (studbeheer-r ls) ) ) ) ) ) ;;;;;;;;;;;;;; hulpprogramma's ;;;;;;;;;;;;; (define nieuwe-stud (lambda () (display "Voornaam (als string!): ") (let ((voornaam (read))) (display "Achternaam (als string!): ") (let ((achternaam (read))) (display "Nummer: ") (let ((nummer (read))) (display "Punten: ") (let ((punten (read))) (make-stud voornaam achternaam nummer punten) ) ) ) ) ) )
(define sorteer (lambda (ls) (if (null? ls) '() (begin (set! ls (alpha-first ls)) (cons (car ls) (sorteer (cdr ls)) ) ) ) ) ) (define alpha-first (lambda (ls) (if (equal? 1 (length ls)) ls (let ((rest (alpha-first (cdr ls)))) (if (string (achternaam (car ls)) (achternaam (car rest))) (cons (car ls) rest) (cons (car rest) (cons (car ls) (cdr rest) ) ) ) ) ) ) ) (define druk-af (lambda (ls) (if (not (null? ls)) (begin (display-stud (car ls)) (druk-af (cdr ls)) ) ) ) ) (define display-stud (lambda (stud) (display (voornaam stud)) (display " ") (display (achternaam stud)) (display " ") (display (nummer stud)) (display " ") (display (punten stud)) (newline) ) ) (define middel-punten (lambda (aantal som ls) (if (null? ls) (begin (display "Gemiddeld ") (display (/ som aantal)) (display " punten") (newline) ) (middel-punten (+ 1 aantal) (+ (punten (car ls)) som) (cdr ls) ) ) ) ) ;;;;;;;;;;;;;; data abstractie ;;;;;;;;;;;;;; ;;; constructor (define make-stud (lambda (voornaam achternaam nummer punten) (list (list voornaam achternaam) nummer punten) ) ) ;;; toegangsfuncties (define voornaam (lambda (stud) (caar stud) ) ) (define achternaam (lambda (stud) (cadar stud) ) ) (define nummer (lambda (stud) (cadr stud) ) ) (define punten (lambda (stud) (caddr stud) ) )
( ( "Jacqueline" "Dake" ) 1 393) ( ( "Ashra" "Sugito" ) 2 575) ( ( "Jan" "Van Gerwen" ) 3 303) ( ( "Emiel" "Maarschalkerweerd" ) 4 676)met een file zoals dit werkt:
( "Jacqueline" "Dake" 1 393) ( "Ashra" "Sugito" 2 575) ( "Jan" "Van Gerwen" 3 303) ( "Emiel" "Maarschalkerweerd" 4 676)NB: Voor het gemak hebben we het boven zo geregeld dat het formaat in het file hetzelfde is als het interne dataformaat in het programma. Dit hoeft helemaal niet, en wordt ook vaak niet zo gedaan. Dus er zijn twee oplossingen mogelijk voor de opdracht (maar een is genoeg).