Ideen med nyhedslisten er, at personer, som er tilmeldt listen, automatisk får tilsendt emails, når IT-C annoncerer nyheder. Dette kan eksempelvis være stillingsopslag, nye uddannelser og Buzz Talks. Når personer tilmelder sig listen, vælger de, hvilke typer af informationer de er interesserede i, f.eks. uddannelser og Buzz Talks. Udsendelse af emails sker ved, at en medarbejder ved IT-C går ind på en administrationsside, hvori emailen indtastes og sendes.
Indgangssiden indeholder tre formularer (HTML-tag <form
...>) svarende til de tre kasser: "Tilmelding", "Kontrol" og
"Afmelding". Siden giver mulighed for, at personer kan
<form method=post action=nl_kontrol.tcl>
...
</form>
Kassen med teksten "Kontrol" er ikke en del af formularen.Der er ingen skjulte formvariable i formularen.
Formularen indeholder to form-elementer:
<input>) til email, hvor
form variablen navngives email.
<form method=post action=nl_tilmeld.tcl>
...
</form>
Den sorte ramme er ikke en del af formularen.Der er ingen skjulte formvariable i formularen.
Formularen indeholder følgende fem form-elementer:
name.
phone.
email.
info. Værdierne af hver knap sættes til henholdsvis 1
for Uddannelser, 2 for Stillinger, 3 for Forskning og 4 for Buzz
Talks. Man skal kunne klikke (vælge) flere knapper samtidigt.
nl_return_page, som returnerer HTML-koden, der omgiver
formularerne på indgangssiden. Procedureren tager to argumenter
title og body. Indgangssiden kan genereres
ved at kalde nl_return_page med title sat
lig "IT-højskolens nyhedstjeneste" og body sat lig de tre
formularer (jvf. billedet med indgangssiden vist ovenfor):
proc nl_return_page { title body } {
ns_return 200 text/html "
<html>
##A##
</html>"
}
Der er følgende krav til siden:
title) til venstre og linket (href)
www.it-c.dk til højre (dvs. for at generere indgangssiden
skal title sættes lig "IT-højskolens
nyhedstjeneste"). Bjælken implementeres ved en tabel med rød
baggrundsfarve og to kolonner, der henholdsvis er venstre- og
højrestillet.
body indsættes under den øverste røde
bjælke.
info@it-c.dk skal være et
email-link.
Du skal opskrive kode for programpunktet ##A##.
nl_user - indeholder data om de tilmeldte personer
nl_info - indeholder de mulige informationstyper,
dvs. Buzz Talk, Forskning, Stillinger og Uddannelser
nl_user_info - indeholder informationstyper knyttet
til de tilmeldte personer
nl_user have 1
eller flere informationstyper i tabellen nl_user_info.
Udover de tre tabeller anvendes en Oracle sekvens til at generere
unikke numre: nl_user_seq.
Tabellen nl_info og Oracle sekvensen til generering
af unikke numre er oprettet ved følgende SQL kommandoer:
create sequence nl_user_seq start with 5;
create table nl_info (
info_id integer primary key,
info_name varchar(40) unique not null
);
Følgende SQL insert kommandoer kan efterfølgende antages
at være udført:
insert into nl_info (info_id, info_name) values (1,'Uddannelser'); insert into nl_info (info_id, info_name) values (2,'Stillinger'); insert into nl_info (info_id, info_name) values (3,'Forskning'); insert into nl_info (info_id, info_name) values (4,'Buzz Talks');
select kommando:
select info_id, info_name from nl_info order by info_name;
nl_user. Tabellen skal have fem felter (kolonner):
user_id - unikt heltal til at identificere en
person (primary key)
name - tekstfelt med plads til 200 tegn. Dette felt
må ikke være tomt.
phone - telefonnummer, med plads til 50 tegn, som
gerne må være tomt.
email - email, med plads til 200 tegn, som nyheder
sendes til. Dette felt må ikke være tomt. Derudover skal hver email
være unik, dvs. der må ikke forekomme to ens emails i tabellen.
create_date - datoen for tilmelding til listen (brug Oracles
date datatype). Feltet må ikke være tomt.
nl_user_info. Tabellen skal have to felter:
user_id - reference til tabellen nl_user
info_id - reference til tabellen nl_info
nl_user: navn "Anders And", telefon "34 32 56 43" og
email "anders@andeby.dk". Sæt user_id lig 1 og
create_date lig dagsdato.
Skriv en SQL kommando som knytter personen Anders And (med
user_id lig 1) til informationstypen Buzz Talks
(info_id lig 4).
info_id lig 1).
Følgende kolonner skal indgå i resultatet: name,
email, info_name, user_id og
info_id.
Rækkerne ønskes sorteret stigende efter email.
Vink: SQL kommandoen skal hente data fra de tre tabeller
nl_user, nl_user_info og
nl_info.
Kolonnerne i resultatet skal være name og
count (dvs. antallet af personer tilmeldt den pågældende
informationstype). Resultatet skal være sorteret stigende efter
kolonnen name.
SQL kommandoen kan eksempelvis returnere:
COUNT NAME
---------- -----------
2 Buzz Talks
3 Forskning
3 Stillinger
3 Uddannelser
Der er to personer, som har tilmeldt sig Buzz Talks osv.
Vink: SQL kommandoen skal hente data fra de to tabeller
nl_info og nl_user_info og desuden benytte
SQL's group by konstruktion.
gen_info_buttons).
Indholdet af tabellen nl_info er som i opgave 2.1.
proc gen_info_buttons { db group_name } {
set query "select info_id, name from nl_info order by name"
set selection [ns_db select $db $query]
set res "<blockquote>\n"
while {[ns_db getrow $db $selection]} {
set_variables_after_query
append res "<input type=checkbox name=$group_name
value=\"$info_id\"> $name<br>\n"
}
append res "</blockquote>\n"
return $res
}
set db [ns_db gethandle]
gen_info_buttons $db "info"
Bemærk: Hvis du ikke har løst opgave 2.1, så skal du kigge på
insert-kommandoerne lige før opgave 2.1.
counts
set counts [list 2 3 2 3]Hvad er resultatet af at udføre Tcl-koden nedenfor (dvs. hvad returnerer kaldet til
calc_sum).
proc calc_sum { counts } {
set sum 0.0
foreach i $counts {
set sum [expr $sum + $i]
}
return $sum
}
calc_sum $counts
Du skal angive resultatet med 1 decimal.
counts fra opgave 3.2 samt
listen names:
set names [list "Buzz Talks" "Forskning" "Stillinger" "Uddannelser"]Du skal skrive en procedure
calc_pct, som givet listerne
counts og names som argument returnerer
følgende HTML-kode (der må gerne være et vilkårligt antal decimaler
før %-tegnet):
<ul>
<li><b>Buzz Talks</b>: 2(20.00%)
<li><b>Forskning</b>: 3(30.00%)
<li><b>Stillinger</b>: 2(20.00%)
<li><b>Uddannelser</b>: 3(30.00%)
</ul>
Det første element i listen counts (2) er antallet af
tilmeldinger til første informationstype i listen names
(Buzz Talks) osv.For hver informationstype angives i procent antallet af tilmeldinger ud af samtlige tilmeldinger; eksempelvis er 2 ud af i alt 10 tilmeldinger 20.00% (2 / 10 * 100 = 20.00).
Du kan anvende følgende skabelon:
proc calc_pct { counts names } {
set sum [calc_sum $counts]
set infos "<ul>\n"
for {set i 0} {$i < [llength $counts]} {incr i} {
append infos "<li><b>[lindex $names $i]</b>: "
##A##
}
append infos "</ul>\n"
return $infos
}
Du skal opskrive kode for programpunktet ##A##.
Hvilke af følgende fem strenge matches af det regulære udtryk ovenfor:^[1-9][0-9]*$
4
4301
014
4a4
0
- (bindestreg).Følgende strenge er gyldige telefonnumre:
3255 6892
52-565987
03 765 545
45 45 45 32 - 402
+45 32 45 43 22
34 32 45 32 lok. 304
GoFedEx
Vink: Der er ikke nogen øvre grænse på længden af et telefonnummer.
nl_tilmeld.tcl, som
tilmelder en ny person til nyhedslisten.
Formvariablene name, phone,
email og info modtages fra
tilmeldingsformularen på indgangssiden.
Proceduren set_form_var_as_list returnerer en liste med
de informationstyper, som brugeren har valgt på indgangssiden. Hvis
informationstyperne Buzz Talks og Uddannelser er valgt, så returneres
listen (svarende til info_id i tabellen
nl_info):
[list 4 1]Vi har simplificeret opgaven ved ikke at checke formvariable; vi checker dog, at der mindst er valgt en informationstype.
# expecting form variables: name, phone, email and info (a list)
set_the_usual_form_variables
set_form_var_as_list info
if {[llength $info] == 0} {
nl_return_page "Tilmelding" "Du skal angive mindst en informationstype
før du kan tilmeldes."
exit
}
set db [ns_db gethandle]
# Generate fresh user_id
set user_id [database_to_tcl_string ##A##]
set insert_sql "insert into nl_user ##B##"
if {[catch { ns_db dml $db $insert_sql } errmsg]} {
# the insert went wrong; assume it is because the
# email is already in the user table
nl_return_page "Tilmelding" "Vi kan ikke registrere din tilmelding
idet den indtastede email allerede er registreret."
} else {
foreach info_id $info {
set insert_sql ##C##
ns_db dml $db $insert_sql
}
nl_return_page "Tilmelding" "Tak for din tilmelding."
}
Opgaven består i at opskrive kode for programpunkterne
##A##, ##B## og ##C## i
skabelonen ovenfor.
nl_kontrol.tcl, som viser registreret information om
allerede tilmeldte personer.
Formvariablen email modtages fra kontrolformularen på
indgangssiden. Vi har simplificeret opgaven ved ikke at checke
formvariablen.
# expecting form variable: email
set_the_usual_form_variables
set db [ns_db gethandle]
set query "select user_id, name, phone, create_date from nl_user
where nl_user.email = '$QQemail'"
set selection [ns_db 0or1row $db $query]
set body ""
if { $selection == "" } {
nl_return_page "Kontrol" "Den indtastede email er ikke
registreret i nyhedstjenesten."
} else {
set_variables_after_query
append body "
<b>$name</b> er registreret den $create_date med <p>
email: <b>$email</b>, <p>
telefon: <b>$phone</b> og følgende informationstyper:<p>
<ul>\n"
set query "select nl_info.info_name from nl_user_info, nl_info
where nl_user_info.info_id = nl_info.info_id
and nl_user_info.user_id = '$user_id'
order by nl_info.info_name"
##A##
append body "</ul>"
nl_return_page "Kontrol" "$body"
}
Du skal opskrive kode for programpunktet ##A##, som skal
tilføje HTML-kode til variablen body, således at
body også indeholder en "bullet"-liste (tag
<ul>) med de informationstyper som brugeren er
tilmeldt.
Vink: Kommandoen ns_db 0or1row udfører
SQL-forespørgslen (query) og returnerer enten 0 eller 1
række. Da email er unik, så kan der højst returneres 1
række. Hvis der returneres 0 rækker, så er selection lig
den tomme streng ("").
nl_afmeld.tcl, som
sletter en person fra databasen.
Formvariablen email modtages fra afmeldingsformularen på
indgangssiden. Vi simplificerer opgaven ved ikke at checke
formvariablen.
# expecting form variable: email set_the_usual_form_variables set db [ns_db gethandle] set query "select user_id from nl_user where email = '$QQemail'" ##A##Du skal opskrive kode for programpunktet
##A##, som skal
se, om personen findes i tabellen nl_user. Hvis dette
ikke er tilfældet, returneres en fejl side (med
nl_return_page, Opgave 1.3), ellers slettes personen fra
tabellen nl_user og nl_user_info og der
returneres en side med information om, at personen er slettet (med
nl_return_page).
Vink: Til at finde ud af om personen allerede findes i
nl_user, kan du f.eks. anvende Tcl kommandoerne
database_to_tcl_string og catch.
nl_stat.tcl.
Der overføres ikke nogen formvariable til nl_stat.tcl.
proc calc_sum { counts } {
-- Som vist i opgave 3.2
}
proc calc_pct { counts names } {
-- Dit svar i opgave 3.3
}
set query "-- Dit svar i opgave 2.5"
set db [ns_db gethandle]
set selection [ns_db select $db $query]
##A##
nl_return_page "Statistik" "
Af de registrerede person på nyhedslisten fordeler interessen sig således:
<blockquote>
[calc_pct $counts $names]
</blockquote>"
Du skal opskrive kode for programpunktet ##A##, som går
ud på at opbygge to lister: counts og names
svarende til listerne i opgave 3.3.
Vink: Du skal anvende en løkke (Tcl kommandoerne
for eller while) samt Tcl kommandoen
lappend.
nl_send.tcl, som givet en
informationstype og indhold af en email, sender emailen til alle personer
på nyhedslisten, som er tilknyttet informationstypen.
Filen nl_send.tcl modtager formvariablene
info, subject, content og
sender.
Vi simplificerer opgaven ved ikke at checke formvariablene samt antager, at der kun modtages en informationstype.
# Expect form variables: sender, subject, content and info
set_the_usual_form_variables
set query "-- Dit svar på opgave 2.4 med info_id = 1
-- erstattet af info_id = '$info_id'";
##A##
Du skal opskrive kode til programpunktet ##A##, der med
Tcl-kommandoen qmail (eller ns_sendmail)
sender en email til de personer, som forespørgslen returnerer.Der skal returneres en side til brugeren, som viser navn og email på dem, der er sendt en email til.