| af Niels Hallenberg | sidst rettet 21. februar, 2001 |
randomRange til generering af tilfældige tal. Opgave B
indeholder som noget nyt ekstraopgaver. Det er opgaver, som man ikke
forventes at løse. Hvis man løser dem, så har man større mulighed for
at opnå 100 point i sættet, idet alle point tælles sammen - man kan
dog maksimalt få 100 point i alt.
Bemærk, at slides 5-2 til 5-9 er vigtige for opgaverne nedenfor.
Opgaver:
toppings en liste med
elementerne Ost, Oliven,
Kylling og Skinke.
set toppings [ ... ]
Du skal bagefter kunne skrive følgende i fortolkeren:
% set toppings Ost Oliven Kylling Skinke
puts,
længden af listen toppings på skærmen, dvs. tallet fire.
Du skal anvende kommandoen% puts [ ... ] 4
llength.
puts) element nummer 2
i listen toppings på skærmen.
Du skal anvende kommandoen% puts [ ... ] Kylling
lindex.
Kødstykker til
listen toppings.
Du skal anvende kommandoen% ... Ost Oliven Kylling Skinke Kødstykker
lappend.
mk_ulist, som tager en liste af
strenge som argument og returnerer (med return) HTML-kode
for en ikke-ordnet liste (HTML tag <ul>). Kroppen af
proceduren skal indeholde et kald til kommandoen foreach,
som bruges til at gennemløbe en liste. Følgende skabelon kan anvendes:
proc mk_ulist { xs } {
set res "<ul>\n";
foreach ... ... {
append res ... ... ...
}
append res "</ul>\n";
return $res;
}
Her er et eksempel på kald af proceduren:
% mk_ulist $toppings <ul> <li>Ost <li>Oliven <li>Kylling <li>Skinke <li>Kødstykker </ul>
mk_mailto, som tager en email som
argument og returnerer en <a href="mailto:..." ... >
tag. Følgende skabelon kan anvendes:
proc mk_mailto {email} {
return "...";
}
Her er et eksempel på kald af proceduren:
% mk_mailto nh@it-c.dk <a href="mailto:nh@it-c.dk"> nh@it-c.dk </a>
mk_email_ulist, som tager en liste
af emailadresser som argument og returnerer (med return)
HTML-kode for en ikke-ordnet liste af emailadresser (HTML tag
<ul>). Hver emailadresse skal forekomme i
HTML-koden som et mailto anker, dvs. du kan med fordel
gøre brug af procedureren mk_mailto ovenfor. Brug
kommandoen lsort
til at sikre at emailadresserne bliver listet i alfabetisk
rækkefølge. Følgende skabelon kan anvendes:
proc mk_email_ulist { xs } {
set xs_sorted [lsort ...];
set res "<ul>\n";
foreach ... ... {
append res [...] "\n";
}
append res "</ul>\n";
return $res;
}
Her er et eksempel på et kald af mk_email_ulist:
Bemærk at emailadressen% mk_email_ulist [list "lise@itu.dk" "kenneth@itu.dk"] <ul> <li><a href="mailto:kenneth@itu.dk"> kenneth@itu.dk </a> <li><a href="mailto:lise@itu.dk"> lise@itu.dk </a> </ul>
kenneth@itu.dk listes før
emailadressen lise@itu.dk.
/web/login/www/oevelse4/opgaveA.tcl på hug.it.edu.
Du skal lave en web-service til stemmeoptælling. Web-servicen skal
have to knapper mærket "Bush" og "Gore" og til højre for hver af
knapperne information om antallet af stemmer afgivet til de to
kandidater. Antallet af stemmer skal også være skjult for brugeren,
dvs. med et inddatafelt input af type
hidden.
Det hele skal programmeres i en fil kaldet
election.tcl. Besvarelsen ligger meget tæt op af
eksemplet taeller2.tcl gennemgået til den fjerde
forelæsning. Nedenfor ser du henholdsvis en skabelon til din
besvarelse og et skærmdump af den vejledende løsning:
proc home_page { title body } { ... }
proc form_update { bush gore } {
return "<center><h2>Election</h2>
<form method=post action=election.tcl>
<input type=hidden name=bush value=\" ... \">
<input type=hidden name=gore value=\" ... \">
<input type=submit name=submit value=Bush><b> ... </b><p>
<input type=submit name=submit value=Gore><b> ... </b>
</form>
</center>"
}
set_form_variables 0
if {[info exists ...] &&
[info exists ... ]} {
if {[info exists ... ] && [string compare ... "..."] == 0} {
incr ...
} else {
incr ...
}
} else {
set bush 49820518
set gore 50158094
}
ns_return 200 text/html [home_page "Election" [form_update $bush $gore]]
|
|
index.html side på hug.it.edu.Nedenfor følger to del-opgaver, som er ekstra. Det vil sige, at du behøver ikke at lave dem. Hvis du laver dem, så har du mulighed for at score 100 point selvom at du laver fejl i de obligatoriske opgaver. Hver ekstraopgave tæller 10 point, og du kan maksimalt få 100 point for hele sættet.
election.tcl
således at der centreret under knappen "Gore" skrives en af de fem
mulige tekster (dog er tallet 10 tilfældigt valgt):
Du kan f.eks. anvende en procedure status efter denne
skabelon:
proc status { bush gore } {
if { $bush - $gore == 1 } {
return "Bush fører med 1 stemme"
} elseif { $bush - $gore > 1 } {
...
} elseif { ... } {
...
} elseif { ... } {
...
} else {
...
}
}
Procedureren status skal da kaldes inde fra procedureren
form_update.
election.tcl,
et søjlediagram med to liggende søjler der viser de forholdsmæssige
stemmetal for Bush og Gore. Placer søjlerne under knapperne som vist
nedenfor. Skaler søjlerne så søjlen for den førende kandidat udfylder
90% af skærmbredden (hvis begge kandidater har nul stemmer skal der
ikke vises noget). Denne ekstraopgave ligger tæt op af
histogrameksemplet histogram2.tcl fra forelæsning 5.
Du kan f.eks. anvende en procedure soejler efter denne
skabelon:
proc soejler { bush gore } {
if { $bush < $gore } {
set max ...
} else {
...
}
# Hvis max er nul, så vil vi slet ikke tegne nogen søjler.
if {$max == 0} {
return ""
}
set w_bush [expr int($bush * 90.0 / $max)] ; # Vi regner først med kommatal og
set w_gore [expr int( ... )] ; # afrunder til heltal med int.
return "<table width=$w_bush%>
<tr><td bgcolor=red width=$w_bush%>Bush: $bush</td></tr>
</table>
<table width=$w_gore%>
<tr><td bgcolor=red width=$w_gore%>Gore: $gore</td></tr>
</table>\n"
}
Procedureren soejler skal da kaldes inde fra procedureren
form_update.
Din opgave er at lave et spil ``Gæt et tal'', som skal køre på din
webserver på hug.it.edu. Spillet
skal implementeres i filen
/web/login/www/oevelse4/gaet_et_tal.tcl.
Ideen med spillet er, at webserveren bestemmer et tal mellem 0 og 100
(med randomRange kommandoen) som brugeren skal
gætte. Hver gang brugeren indtaster et gæt i et formfelt, giver
webserveren brugeren besked om hvorvidt gættet er for stort, for
lille eller rigtigt. I tilfælde af at gættet er rigtigt skal
brugeren lykønskes og have muligheden for at starte et nyt spil. Hvis
derimod det gættede tal er for lille eller for stort skal brugeren
have mulighed for et nyt gæt.
Spillet kan passende gøre brug af følgende tre procedurer, som placeres
øverst i filen /web/login/www/oevelse4/gaet_et_tal.tcl:
proc home_page { title body } {
return "
<html>
<head>
<title>$title</title>
</head>
<body>
$body
<hr>
<a href=\"mailto:login@itu.dk\">login@itu.dk</a>
</body>
</html>"
}
proc my_return_page { title body } {
ns_return 200 text/html [home_page $title $body]
}
proc indtast_gaet_form { tal } {
return "
<form method=post action=gaet_et_tal.tcl>
<input type=hidden name=tilfaeldigt_tal value=$tal>
Indtast dit gæt:<p>
<input type=text name=gaet size=7>
<input type=submit value=Gæt>
</form>"
}
Den første procedure kender vi fra forelæsningerne. Den anden
procedure my_return_page tager som argumenter en titel og
en krop og returnerer en HTML-side med titlen og kroppen indsat. Husk
at ændre emailadressen i my_return_page proceduren. Den
tredje procedure indtast_gaet_form tager et tal som
argument og returnerer HTML-kode for en form til indtastning af et
gæt. Når brugeren ``submitter'' formen, sendes gættet og indholdet af
den skjulte formvariabel tilfaeldigt_tal til siden
gaet_et_tal.tcl som form-argumenter.
Her er en skitse over hvorledes resten af filen
/web/login/www/oevelse4/gaet_et_tal.tcl kan se ud:
# Sæt variablerne `gaet´ og `tilfaeldigt_tal´. Hvis variablen
# `tilfaeldigt_tal´ ikke er sat, da genereres et nyt tilfældigt
# tal og en introduktionsside til spillet "Gæt et tal" vises
# til brugeren
set_form_variables 0
if {![info exists tilfaeldigt_tal]} {
# Variablen `tilfaeldigt_tal´ er ikke sat! Generer tilfældigt
# tal (med randomRange) og returner en HTML-introduktionsside
# med en form til indtastning af et gæt.
...
} elseif {![info exists gaet] || [string compare $gaet ""] == 0} {
# Variablen `gaet` mangler, så vi spørger igen uden at
# generere et nyt tilfældigt tal.
...
} elseif {$gaet > $tilfaeldigt_tal} {
# Returner en HTML-side med en form til indtastning af et nyt
# gæt og en besked om at gættet var for stort.
...
} elseif {$gaet < $tilfaeldigt_tal} {
# Returner en HTML-side med en form til indtastning af et nyt
# gæt og en besked om at gættet var for lille.
...
} else {
# Returner en HTML-side med en lykønskning og et link til et
# nyt spil.
...
}
Din opgave er altså at udfylde ovenstående skelet med relevante kald
til my_return_page proceduren.
Indsæt et link til spillet fra din index.html side på hug.it.edu.
Her følger tre skærmdumps af den vejledende løsning: