LINUX NELLA DIDATTICA: UN ESEMPIO SIGNIFICATIVO


Siamo giunti al quarto articolo sull'uso di GNU/Linux nella didattica e credo sia opportuno un brevissimo riassunto delle "puntate precedenti": abbiamo iniziato, nel numero 10, con un esame delle motivazioni etiche, pratiche e didattiche di tale scelta; nel numero 12 si è poi presa in esame la politica di questi anni del Ministero della Pubblica Istruzione relativamente all'informatica nelle scuole constatando come il software libero sia stato sostanzialmente ignorato; infine nel numero 13 è stato illustrato l'uso concreto di GNU/Linux e del software libero presso l'I.P.C "F. Besta" di Treviso.”

Anche questo mese ci occupiamo di un caso concreto: il corso finanziato dal Fondo Sociale Europeo (FSE) per tecnici in "Commercio Elettronico" organizzato dalla C.N.A. di Treviso presso l'istituto "Besta " nella scorsa primavera.

Caratteristiche del corso

Il corso era rivolto a non occupati senza esperienze informatiche e prevedeva moduli di: economia, diritto, inglese, sistemi operativi, basi di dati, principi di programmazione, reti di computer, posta elettronica, creazione di pagine WEB.

Sono state utilizzate le due aule con macchine Linux e Open Dos (come terminali) collegate in rete di cui avevamo parlato nelle scorse puntate. Per quanto riguarda il software, nei moduli a carattere informatico, si sono ovviamente utilizzati strumenti della categoria del software libero o open-source: Linux, Postgres, Perl, Sendmail, Pine, Apache, Mozilla, PHP, fra gli altri.

Linux è stato sfruttato, oltre che come piattaforma su cui far girare tutto il resto, anche per l'apprendimento dei concetti di base sui sistemi operativi, usando alcuni dei suoi comandi fondamentali, e per il modulo sulle reti.

Sendmail e Pine sono ovviamente serviti per la posta elettronica ed il Perl per il modulo di principi di programmazione.

Per quanto riguarda la parte pratica del modulo di gestione di basi dati si è utilizzato Postgres, sia con l'interfaccia a carattere psql sia con quella grafica pgaccess.

Infine la creazione e la visualizzazione di pagine WEB è stata possibile grazie ad alcuni degli editor di testo forniti dalle distribuzioni di Linux, al server Apache, a Mozilla e al PHP con il quale si sono realizzati i documenti dinamici.

Gestione del Database dal WEB

Entriamo adesso più nel dettaglio dell'attività svolta nel modulo di creazione di pagine WEB.

Nella prima parte è stato preso in esame il linguaggio HTML e si sono creati documenti sempre più complessi fino ad arrivare all'uso di tabelle, di frame, di immagini mappate.

Inizialmente l'editor usato per la scrittura dei sorgenti HTML è stato il vi, poi affiancato da strumenti più "evoluti" come gedit; volutamente sono stati trascurati i programmi di creazione automatica delle pagine come Composer in quanto non avrebbero favorito un effettivo apprendimento del linguaggio HTML. Per visualizzare le pagine create si sono usati lynx, Mozilla e talvolta anche Opera (unica deroga al software libero).

In seguito siamo passati alle pagine dinamiche con una carrellata sui vari strumenti per la loro gestione. Fra essi si è privilegiato il PHP per la potenza, la relativa immediatezza e semplicità d'uso, la possibilità di costruire agevolmente interfacce con un database. L'obiettivo che ci eravamo prefissi era infatti quello di gestire l'archivio degli ordini, che gli studenti avevano già costruito con psql e pgaccess, attraverso delle pagine WEB.

Nella figura 1 è visibile lo schema del database degli ordini (per chi avesse da obiettare circa la completezza di tale archivio, ricordo che è stato definito a scopo didattico e non per essere usato per applicazioni reali).


Fig.1




In figura 2 si può vedere il primo form per l'inserimento di un ordine; in esso viene proposto l'anno corrente (modificabile) in quanto i primi due byte del codice ordine corrispondono proprio all'anno. Il listato 1 è il sorgente di questa pagina WEB.


Fig.2



Listato 1

<html>

<head>

<title>ordini1.a</title>

<!- viene caricata sempre l'ultima versione della pagina ->

<meta http-equiv="expires" content="0">

</head>

<body bgcolor="#68afcf">

<?php

$anno=date("y"); //preimposta anno = anno corrente

?>

<form action="ordini1a.php" method="get">

<table cellspacing="20" align="center">

<tr> <td align="center" colspan="2"><b><font face="arial" size="6">

<i>Inserimento ordine</i></font></b></tr>

<tr> <td><font face="arial"><i>Anno:</i></font>

<?php // i primi due byte del numero ordine corrispondono all'anno

print ("<td><input type='text' name='anno' size='2'

maxlength='2' value='$anno'>");

?>

</tr><tr>

<td><font face="arial" size="6">

<input type="submit" value="Continua" align="left"></font>

<td><input type="reset" value="Cancella" align="right">

</table>

</form>

<center><a href="index.php"><img src="/immagini/bluhome.gif"></a>

</center></body>

</html>



In figura 3 si vede la successiva maschera per l'inserimento dell'ordine; il numero ordine è assegnato automaticamente con il primo progressivo libero per quell'anno. Nel form vengono richiesti i dati di testata: agente, cliente e data (preimpostata con la data corrente) e i dati di dettaglio per le righe ordine (si è semplificato il tutto imponendo che le righe siano al massimo 5).







Fig.3




Il sorgente corrispondente a questa pagina e quello relativo alla gestione dei dati immessi, sono in listato 2 e listato3. Gli altri sorgenti son visibili nel sito www.linuxdidattica.org.


Listato 2

<html>

<head>

<title>ordini1a.php</title><meta http-equiv="expires" content="0">

</head>

<body bgcolor="#68afcf">

<?php

// connessione al database

$pg_database="stradamordini";

$pg_host="192.168.2.53";

$pg_port="5432";

$pg_user="stradam";

$pg_psw="";

$conn=pg_connect ("dbname=$pg_database host=$pg_host

port=$pg_port user=$pg_user password=$pg_psw");

if (!$conn) {

echo"<p><center><b>Connessione al database non riuscita!</b></center>\n";

exit ();

}

//viene cercato il primo codice libero per l'anno

$query="SELECT num_ordine INTO TEMPORARY TABLE appoggio1

FROM ordini WHERE num_ordine LIKE '$anno%';";

$result = pg_exec($conn, $query);

if (!$result) {

echo ("<p><center><b>La query non è avvenuta</b></center>\n");

pg_close ($conn);

exit ();

}

$query1="SELECT MAX(num_ordine) AS num_ordine FROM appoggio1;";

$result = pg_exec($conn, $query1);

if (!$result) {

echo ("<p><center><b>La query non è avvenuta</b></center>\n");

pg_close ($conn);

exit ();

}

$num_ordine = pg_result($result, 0, "num_ordine");

if ($num_ordine == 0) {

$num_ordine = (string)$anno . str_repeat("0", 4);

}

$num_ordine++;

// form per inserire i dati dell'ordine

$data=date("d/m/Y"); // data preimpostata

print ("<center><h1>Inserimento ordine num.<b>".$num_ordine."</h1></center>\n");

print ("<form action = 'ordini1b.php' method = 'get'>\n");

print ("<input type=\"hidden\" name='num_ordine' value='$num_ordine'>");

print ("<table align=\"center\">\n");

print ("<tr></tr><tr>\n");

print ("<td><font face=\"arial\" size=\"6\">Data:\n");

print ("<td>"."<input type='text' maxlength=\"10\" size=\"10\"

name='data_ordine' value = '$data'></font>\n");

print ("<td><font face=\"arial\" size=\"6\">Cod. agente:\n");

print ("<td>"."<input type='text' maxlength=\"6\" size=\"6\"

name='cod_agente' ></font>\n");

print ("<td><font face=\"arial\" size=\"6\">Cod. cliente:\n");

print ("<td>"."<input type='text' maxlength=\"6\" size=\"6\"

name='cod_cliente'></font>\n");

print ("</tr></table><p>\n");

print ("<table border align=\"center\">");

print ("<tr>\n");

print ("<td><font face=\"arial\" size=\"6\"><b>Articolo</b></font>\n");

print ("<td><font face=\"arial\" size=\"6\"><b>Quant.</b></font>\n");

print ("<td><font face=\"arial\" size=\"6\"><b>Sconto %</b></font>\n");

print ("</tr><tr>\n");

print ("<td><input type = 'text' maxlength=\"6\" size=\"8\" name='a1'>\n");

print ("<td><input type = 'text' maxlength=\"8\" size=\"8\" name='q1'>\n");

print ("<td><input type = 'text' maxlength=\"6\" size=\"8\" name='s1'>\n");

print ("</tr><tr>\n");

print ("<td><input type = 'text' maxlength=\"6\" size=\"8\" name='a2'>\n");

print ("<td><input type = 'text' maxlength=\"8\" size=\"8\" name='q2'>\n");

print ("<td><input type = 'text' maxlength=\"6\" size=\"8\" name='s2'>\n");

print ("</tr><tr>\n");

print ("<td><input type = 'text' maxlength=\"6\" size=\"8\" name='a3'>\n");

print ("<td><input type = 'text' maxlength=\"8\" size=\"8\" name='q3'>\n");

print ("<td><input type = 'text' maxlength=\"6\" size=\"8\" name='s3'>\n");

print ("</tr><tr>\n");

print ("<td><input type = 'text' maxlength=\"6\" size=\"8\" name='a4'>\n");

print ("<td><input type = 'text' maxlength=\"8\" size=\"8\" name='q4'>\n");

print ("<td><input type = 'text' maxlength=\"6\" size=\"8\" name='s4'>\n");

print ("</tr><tr>\n");

print ("<td><input type = 'text' maxlength=\"6\" size=\"8\" name='a5'>\n");

print ("<td><input type = 'text' maxlength=\"8\" size=\"8\" name='q5'>\n");

print ("<td><input type = 'text' maxlength=\"6\" size=\"8\" name='s5'>\n");

print ("</tr><tr>\n");

print ("</table><table align=\"center\">");

print ("<td align=\"center\"><p><br> Vuoi inserire i dati?\n");

print ("<td>"."<input type='submit' value='Sì'>\n");

print ("<td><p><br>&nbsp;\n");

print ("<td>"."<input type='reset' value='Reset'>\n");

print ("</tr></table></font>\n");

print ("</form>\n");

pg_close($conn);

?>

<p><center>

<a href="index.php"><img src="/immagini/bluhome.gif"></a>

</center></body>

</html>



Listato 3

<html>

<head>

<title>ordini1b.php</title><meta http-equiv="expires" content="0">

</head>

<body bgcolor="#68afcf">

<?php

reset($HTTP_GET_VARS);

// connessione al database

include ("inizio.inc");


// Acquisizione variabili provenienti dal form

$i=0;

while (list($keys[$i],$value[$i])=each($HTTP_GET_VARS)){

$i++;

}

$flag=0;

$query = "BEGIN WORK;"; // inizio transazione

$result = pg_exec($conn, $query);

if (!$result) {

echo "<p><center><b>Query di inizio lavoro non avvenuta!</b></center>\n";

pg_close($conn);

exit();

}

//Controlla della validita' della data

list($day, $month, $year)=split('[/.-]', $data_ordine);

if (!checkdate ($month, $day, $year))

{

echo "<p><b><center>Data non valida</b></center>\n";

$flag=1;

}

$data_ordine = $year . "-" . $month . "-" . $day;

//verifica dell'esistenza del codice agente

$query_agente = "SELECT cod_agente from agenti where cod_agente = '$cod_agente';";

$richiesta_agente = pg_exec($conn, $query_agente);

if (!$richiesta_agente){

echo "<p><center><b>Problemi per la ricerca del codice agente</b></center>\n";

$flag=1;

}

$righe_agente = pg_numrows($richiesta_agente);

if ($righe_agente == 0) {

echo "<p><center><b>Il codice agente non esiste</b></center>\n";

$flag=1;

}

//verifica dell'esistenza del codice cliente

$query_cliente = "SELECT cod_client from clientla where cod_client = '$cod_cliente';";

$richiesta_cliente = pg_exec($conn, $query_cliente);

if (!$richiesta_cliente){

echo "<p><center><b>Problemi per la ricerca del codice cliente</b></center>\n";

$flag=1;

}

$righe_cliente = pg_numrows($richiesta_cliente);

if ($righe_cliente == 0) {

echo "<p><center><b>Il codice cliente non esiste</b></center>\n";

$flag=1;

}

//verifica dell'esistenza del codice articolo

for ($i = 4 ; $i < 17; $i=$i+3) {

if (!empty($value[$i])) {

$query_articolo = "SELECT cod_artic from articoli where cod_artic='$value[$i]';";

$richiesta_articolo = pg_exec($conn, $query_articolo);

if (!$richiesta_articolo){

echo "<p><center><b>Problemi in ricerca del codice articolo</b></center>\n";

$flag=1;

}

$righe_articolo = pg_numrows($richiesta_articolo);

if ($righe_articolo == 0) {

echo "<p><center><b>Il codice articolo '$value[$i]' non esiste</b></center>\n";

$flag=1;

}

}

}

if ($flag == 1) {

pg_exec($conn, "ROLLBACK WORK;");

pg_close($conn);

echo "<p><center><b>REGISTRAZIONE NON EFFETTUATA</b>\n";

echo "<p><a href=\"ordini1.php\">ALTRO INSERIMENTO</a></center>\n";

exit();

}

// Inserimento dei dati testata ordine

$query="INSERT INTO ordini VALUES ('$value[0]','$data_ordine','$value[2]','$value[3]');";

$result=pg_exec($conn,$query);

// ciclo di inserimento dei dati delle righe ordine

for ($i = 4; $i <= 15; $i=$i + 3) {

$j = $i + 1;

$k = $j + 1;

if (($value[$i]) and ($value[$j] <> 0)) {

if (!$value[$k]) {

$value[$k] = 0;

}

$query1 = "INSERT INTO voci_ord VALUES ('$value[0]','$value[$i]',$value[$j],$value[$k]);";

$risultato=pg_exec($conn,$query1);


$i2 = $i -3;

if (!$risultato) {

echo "<p><center><b>Registrazione riga ordine $i2 non avvenuta</b></center>\n";

pg_exec($conn, "ROLLBACK WORK;");

pg_close($conn);

exit();

}

}

if (!$result){

echo "<p><center><b>La registrazione non è avvenuta</b></center>\n";

pg_exec($conn, "ROLLBACK WORK;");

pg_close($conn);

exit();

}

}

$query = "COMMIT WORK;";

$result = pg_exec($conn, $query);

echo "<p><center><b>La registrazione è avvenuta</b></center>\n";

if (!$result) {

echo "<p><center><b>Problemi nella registrazione dei dati!</b></center>\n";

}

?>

<p><br>

<center><a href="index.php"><img src="/immagini/bluhome.gif"></a>

<a href="ordini1.php">ALTRO INSERIMENTO</a></center>

</body>

</html>


Conclusioni

Per chi volesse dare un'occhiata a tutta la "procedura" è possibile collegarsi all'indirizzo mail.linuxdidattica.org/~fse. Il lavoro fatto è esclusivamente didattico, senza pretese professionali ed è stato svolto dagli allievi con la sola supervisione mia e di Umberto Zanatta.

Questa esperienza costituisce secondo me un buon esempio di utilizzo del software libero in ambito didattico, perdipiù ad un livello più elevato rispetto ad un normale corso disciplinare di scuola media superiore. A sostegno di questa impressione c'è il fatto che alcuni degli studenti, adesso in stage presso aziende, si stanno cimentando con successo con il WEB dinamico e uno di loro ha installato da zero un server Linux, un WEB server con Apache e sta costruendo delle applicazioni con il PHP per la intranet aziendale.



Fulvio Ferroni