Pagine

lunedì 21 marzo 2016

Programmazione web lato client (4 parte a)

Per gli studenti della Ia e Ib Itis Volta Frosinone: questa volta vi lancio in acque profonde!

Al solito, per comodità, dal momento che l'interfaccia del programma non occupa molto spazio sullo schermo, l'ho inserito anche in questa pagina utilizzando un tag "iframe".


Il programma crea, premendo il tasto "Tabellina", una tabella pitagorica di 15 righe e 15 colonne. Il tasto "Clear" la cancella. Nulla di sensazionale, ma è un pretesto per insegnarvi il DOM.

Il DOM (Document Object Model) viene creato dal browser quando la pagina html viene caricata. Potete pensare al DOM come a uno schema della pagina, costruito dal browser mentre la carica. In pratica il browser "prende appunti" e memorizza al suo interno uno schema in cui ogni tag è rappresentato da un pallino (nodo), e i tag che si trovano al suo interno sono altri nodi che vengono chiamati "childnodes" (nodi-figlio). Per capirci, prendiamo in esame la pagina html dell'esempio, che riporto qui sotto:

<!DOCTYPE html>
<html>

   <head>
      <link href="cssDoc.css" rel="stylesheet" type="text/css" />
      <script language="javascript" src="jsDoc.js"></script>
   </head>
  <body>
    <button onclick="document.getElementById('demo').appendChild(makeTable(15,15))">Tabellina</button>
    <button onclick="deleteTable()">Clear</button>
    <p align="center" id="demo"></p>
  </body>
</html>


 Lo schema di questa semplicissima pagina è il seguente (a parte la dichiarazione di tipo <!DOCTYPE html>.



Il nodo <html> ha due figli (childNodes): <head> e <body>. A loro volta <head> e <body> hanno rispettivamente 2 (<link> e <script>) e 3 (<button>, <button> e <p>) childNodes. Questo schema, ovviamente memorizzato in formato digitale, è il DOM della pagina.

Per la cronaca, ma ne parleremo più diffusamente in un altro post, osserviamo che ogni nodo (node) può avere degli "attributi". Ad esempio, il nodo <p> ha l'attributo "id", il cui valore è in questo caso "demo".

 I programmatori dei browsers, oltre a fornire la capacità di creare uno schema della pagina, rendono disponibili un set di metodi per manipolare i nodi. Ad esempio, se un nodo ha un attributo "id" (poniamo con il valore "demo") noi possiamo individuarlo (cioè ottenere un riferimento ad essso) e memorizzare tale riferimento in una variabile (se questo ci fa comodo) con l'istruzione:

var x = document.getElementById("demo");

Ora vi presenterò, e spiegherò, alcuni metodi che ho usato per realizzare il programmino oggetto del nostro studio.
  • var tbl= document.createElement("table"); //crea un tag <table>
  • var row= document.createElement("tr");    //crea un tag <tr>
  • var col= document.createElement("td");    //crea un tag <td>
Il metodo createElement("tag") crea un nodo del tipo specificato in "tag". Nel nostro caso, rispettivamente un nodo "table", un nodo "tr" e un nodo "td".

Si noti che il metodo createElement("tag") appartiene all'oggetto document. In altre parole, non posso scrivere solo createElement("tag"), ma devo necessariamente scrivere document.createElement("tag"). Il che significa: crea l'oggetto (il nodo) "tag" utilizzando il metodo createElement("tag") dell'oggetto (nodo) "document".

InZomma: nel DOM i nodi sono degli "oggetti". Dice: ma che è un "oggetto"? Semplice: la mia mano è un "oggetto", e ha il metodo "sganciaUnCeffone", che invocherò se non mi saprete rispondere all'interrogazione. E' più chiaro adesso?

Un "oggetto" può anche avere delle proprietà. Ad esempio, la mia mano ha la proprietà "dimensioni", il cui valore è lievemente superiore al quello della mano di Roma (ossia l'"oggetto" alunno di cognome "Roma").

 Dopo aver creato un nodo occorre assegnargli un papà (se preferite: genitore 1). Se, ad esempio, vogliamo che il noto "table" abbia come papà (sia figlio di) il nodo "p" con l'"id" di valore "demo", possiamo scrivere:

var tbl= document.createElement("table");
var demo = document.getElementById("demo");
demo.appendChild(tbl);

Naturalmente, siccome la "table" che abbiamo creato non ha (ancora) righe e colonne, non vedremo una beneamata fava. Per vedere qualcosa dovremo aggiungere almeno una riga con almeno una colonna. Cosicché il codice diventa:

var tbl= document.createElement("table");
var row= document.createElement("tr");
tbl.appendChild(row);
var col= document.createElement("td");
row.appendChild(col);

var demo = document.getElementById("demo");
demo.appendChild(tbl);

A questo punto vedremo... la solita beneamata fava! Già, perché abbiamo una tabella, con una riga e una colonna (una cella), ma dentro non c'è scritto niente. Cosa volete metterci nell'unica cella della tabella? Un testo? Va bene. Allora aggiungiamo al codice precedente:

var t = document.createTextNode("il prof è completamente pazzo");
col.appendChild(t);


 e il gioco è fatto. Volete di meglio? Ci volete mettere un'immagine? E allora scriviamo:

var myImg=document.createElement("img");
myImg.setAttribute("src", "http://www.w3schools.com/js/pic_htmltree.gif");
demo.appendChild(myImg);


Il codice completo (con il javascript, in grassetto, inserito direttamente nella pagina html) è il seguente:

<!DOCTYPE html>
<html>
<body>
<button id="myBtn" onclick="myFunction()">Cliccami</button>
<button id="clearBtn" onclick="document.getElementById('demo').innerHTML='';">Clear</button>
<script>
function myFunction() {
var demo = document.getElementById("demo");
if(demo.innerHTML!=""){return(null);}
var myImg=document.createElement("img");
myImg.setAttribute("src", "http://www.w3schools.com/js/pic_htmltree.gif");
demo.appendChild(myImg);
}
</script>
<p id="demo"></p>
</body>
</html>

Il risultato è questo:


Il minimo che vi chiedo, per ora, è di scegliere un'immagine migliore. Conoscete le mie preferenze, non deludetemi.

Conclusioni


Siete affogati? Non credo proprio. In classe vi spiegherò meglio, con il poco tempo che abbiamo e tutti i limiti della situation. Un giorno capirete perché la scuola pubblica è ridotta come sapete, e spero che farete qualcosa per rimediare. Quando le cose cambieranno io sarò sotto terra: pensate anche a me il giorno della vittoria.

giovedì 3 marzo 2016

Programmazione web lato client (3)

Oggi realizzeremo un semplice gioco, il tris. Al solito eccovi il link al source code e alla pagina web.
Per comodità, dal momento che l'interfaccia del gioco non occupa molto spazio sullo schermo, l'ho inserito anche in questa pagina, utilizzando un tag "iframe".


Nell'"head", oltre ai soliti riferimenti ai files esterni per il css e il codice javascript:

<link href="cssDoc.css" rel="stylesheet" type="text/css" />
<script language="javascript" src="jsDoc.js"></script>

troviamo una terza linea di codice:

<script>var j=1;</script>

il cui uso sarà spiegato nel seguito. Questo, infine, è il codice html che disegna la tabella e inserisce il pulsante per ricominciare il gioco.

<table align="center" border="1">
<tr>
<td class="riquadro" onclick="j=gulp(this,j)"></td>
<td class="riquadro" onclick="j=gulp(this,j)"></td>
<td class="riquadro" onclick="j=gulp(this,j)"></td>
</tr>
<tr>
<td class="riquadro" onclick="j=gulp(this,j)"></td>
<td class="riquadro" onclick="j=gulp(this,j)"></td>
<td class="riquadro" onclick="j=gulp(this,j)"></td>
</tr>
<tr>
<td class="riquadro" onclick="j=gulp(this,j)"></td>
<td class="riquadro" onclick="j=gulp(this,j)"></td>
<td class="riquadro" onclick="j=gulp(this,j)"></td>
</tr>
<tr><td id="comandi" colspan="3">
<input type="button" onclick="restartAll();" value="Ricomincia">
</td></tr>
</table> 

Ci sono 9 celle, ognuna delle quali ha un attributo "class" (che specifica la classe css "riquadro") e un attributo onclick. Quando si passa il cursore su una delle celle, esso prende la forma di una manina. Cliccando sulla cella si richiama in esecuzione la funzione javascript "gulp" con la seguente sintassi:

j=gulp(this,j)

Ovvero si impone che il valore della variabile "j", inizializzata nell'intestazione (<script>var j=1;</script>) sia aggiornato dal valore di ritorno della funzione "gulp". A quest'ultima vengono passati "this" e il valore di "j" al momento del click. Come già sapete, la parola chiave "this" indica l'elemento su cui si è fatto click, in questo caso una delle 9 celle della tabella. Esaminiamo ora il codice della funzione gulp.

function gulp(t,j)
{if (t.innerHTML=="")
{
if(j==1){
t.innerHTML="<img src='homer.jpg'>";
}
else
{
t.innerHTML="<img src='roger.gif'>";
}
j=-j;
}
return(j)
}

La logica implementata dal codice è la seguente: se la cella è vuota, allora se j vale 1 si inserisce l'immagine "homer.jpg", altrimenti si inserisce l'immagine "roger.gif". Al termine si cambia segno a "j" e lo si restituisce come valore di ritorno della funzione. Così facendo, ogni volta che si clicca su una cella vuota vi si inserisce  una delle due immagini, a seconda che "j" sia 1 o -1, e lo si cambia di segno. Ovviamente, se la cella su cui si è cliccato non è vuota (perché contiene già una delle due immagini) non succede nulla.

Il pulsante "Ricomincia" reinizializza il gioco eseguendo il codice della funzione "restartAll":

function restartAll()
{
var tdList=document.getElementsByTagName("td");
for (i = 0; i < tdList.length; i++) { 
if (tdList[i].id=="")
     {tdList[i].innerHTML="";}
}
}

Si ottiene un riferimento alla lista delle 9+1 celle presenti sulla pagina (le 9 su cui si clicca più quella che ospita il pulsante) e gli si assegna il nome "tdList". Il resto del codice sarà di facile interpretazione dopo che avremo parlato in classe di liste (o variabili con indice) e di cicli for. Per il momento vi basti una descrizione generica di quello che fa il frammento di codice: eliminare il contenuto di tutte le celle della table ad eccezione di quella che ospita il pulsante, riconosciuta grazie all'attributo "id" il cui valore è "comandi" (si veda il codice html).

domenica 21 febbraio 2016

Programmazione web lato client (2)

Salve ragasciuoli, eccomi qua a spiegarvi il secondo esercizio...

Anche in questo caso abbiamo tre files: un html, un css e un js. Il riferimento al css e al js è nell'intestazione del file html:

<link href="cssDoc.css" rel="stylesheet" type="text/css" />
<script language="javascript" src="jsDoc.js"></script>

Abbiamo una table con un certo numero di immagini di automobili prese da Internet. Al centro della table c'è un'immagine più grande delle altre. Cliccando su una qualsiasi delle immagini più piccole che la circondano, questa prende il posto dell'immagine grande, e quest'ultima si posiziona al posto di quella piccola. L'effetto è scenografico, ma il codice necessario è veramente poco: quattro istruzioni.

Per prima cosa occorre assegnare un id all'immagine centrale. La scelta è stata quella di assegnargli il valore id="trg". Ciò fatto, abbiamo assegnato (ad ognuna delle immagini piccole) un gestore all'evento onclick, con la seguente sintassi:

<img class="manina" onclick="swapImg(this)" src="quello che ve pare"/>

Non mi soffermo sulla classe css "manina" perché so che non ne avete bisogno. Andiamo al sodo, cioè alla sintassi onclick="swapImg(this)". Già sapete che questo significa che, cliccando sull'immagine, viene chiamata in esecuzione la funzione swapImg alla quale viene passato il parametro "this". Sapete anche che "this" in italiano significa "questo" (e nella nobile lingua ciociara "chisse").

Ma "chisse" che? In questo caso "this" significa l'intero tag:

<img class="manina" onclick="swapImg(this)" src="quello che ve pare"/>

Ora guardiamo il codice della funzione swapImg, alla quale viene passato il parametro "chisse"... oops scusate, volevo dire "this".

function swapImg(p)
{
var x=p.src;
var trg=document.getElementById("trg")
p.src=trg.src;
trg.src=x;
}

La function accetta il parametro "p" (ma avremmo potuto chiamarlo come ci pare, salvo il divieto di usare "parole riservate"). Ovvio che se chiamiamo "p" il parametro, da ciò segue che, nel corso dell'esecuzione della function esso avrà il valore che gli è stato passato, vale a dire l'intero tag:

<img class="manina" onclick="swapImg(this)" src="quello che ve pare"/>

Quindi, nell'ambito dell'esecuzione della function swapImg, accade che "this" venga chiamato "p".

Perché non ho chiamato, anche nella function, il parametro con la parola "this"? Perché l'ho rinominato "p"? Semplice: perché "this" è una parola riservata, e dunque deve e può essere usata solo ed esclusivamente secondo le regole del linguaggio, e non come serve a noi. Claro? Casomai ve lo rispiego in laboratorio.

Ora, se "p" è tutto il tag, e questo ha degli attributi, che nel caso in esame sono:
  • class
  • onclick
  • src
noi possiamo leggerne il valore con l'istruzione: p.<nome_attributo>

Per cui, se vogliamo sapere qual è il valore dell'attributo "src" e assegnarlo alla variabile "x" possiamo scrivere:

var x=p.src;

Dunque, eseguita questa istruzione, nella variabile "x" è memorizzato il valore di "src" dell'immagine su cui abbiamo cliccato. L'istruzione successiva:

var trg=document.getElementById("trg")

assegna alla variabile "trg" il contenuto del tag "img" relativo all'immagine centrale (quella grande). In questo caso, siccome "trg" non è una parola riservata, per pura comodità (cioè fare una scelta che ci aiuta a ricordare che dde sse tratta) abbiamo usato come nome di variabile lo stesso nome dell'id nella pagina html. 

Vi siete persi? No problem, su questi dettagli torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo, torneremo....

A questo punto, con l'istruzione:

p.src=trg.src;

assegniamo all'attributo "src" dell'immagine su cui abbiamo cliccato (che è il tag il cui id è "this") il valore dell'attributo "src" dell'immagine centrale (quella grande). Se ci fermassimo qui, il risultato sarebbe:
  • immagine su cui abbiamo cliccato: compare l'immagine centrale
  • immagine centrale: resta quello che c'era
Non ci resta, quindi, che mettere nell'immagine centrale quella su cui abbiamo cliccato. Lo facciamo con l'ultima istruzione:

trg.src=x;

Cioè assegniamo all'immagine centrale (il cui riferimento è "trg", come risultato dell'istruzione var trg=document.getElementById("trg")) un nuovo valore per l'attributo "src", che avevamo precedentemente prelevato e salvato nella variabile "x".

Due parole sullo swap


Ho assegnato alla function il nome "swapImage" in onore al fatto che nel gergo informatico il termine "swap" indica lo scambio di valori tra due variabili. Son Diego e vi spiego:

se x="pippo" e y="pluto", fare lo swap tra x e y significa che, dopo l'istruzione, si ha x="pluto" e y=pippo".

Vi ho anche spiegato, con un esempio "alcolico", in cosa consista lo swap. Lo ripeto. Immaginate di fare i camerieri in un locale e di dover portare a un tavolo un bicchiere di vino e uno di birra, ma che per errore avete messo il vino nel bicchiere della birra e la birra in quello del vino. Il caposala vi becca e vi ingiunge di rimediare. Che fare? Ovviamente avete bisogno di un terzo bicchiere: prima mettete il vino in questo bicchiere, poi versate la birra nel bicchiere giusto, poi travasate il vino dal terzo bicchiere in quello giusto per il vino.

Chiaro? Ricordatevi sempre, cari ragasciuoli, che molto spesso ciò che appare difficile è, in realtà, molto banale. Si tratta solo di imparare i rudimenti di un nuovo linguaggio.

Alla proxy (chiara allusione al fatto che prima o poi dovrete sapere cos'è un proxy).

sabato 13 febbraio 2016

Programmazione web lato client

Ho preparato un piccolo esempio per introdurre i miei studenti ai fondamentali della programmazione web lato client. L'esempio consta di tre files: il file htmlDoc.html, il file cssDoc.css e il file jsDoc.js, tutti nella stessa cartella.
Il sorgente di htmlDoc.html è il seguente:

<!DOCTYPE html>
<html>
<head>
<link href="cssDoc.css" rel="stylesheet" type="text/css" />
<script language="javascript" src="jsDoc.js"></script>
</head>
<body>
<p>Lorem ipsum dolor sit amet, nec molestie lacus elit nunc lacinia. Fermentum consequat nec, nunc orci, et amet vitae accumsan et, sit amet quam porttitor. Metus interdum vitae nulla id mi, a vehicula, cum et. Vero justo dictum, vivamus euismod neque mi pede pulvinar blandit, ad et nec quis vel molestie, mattis ultricies lorem dapibus volutpat non. Eget sem nec scelerisque vehicula hac.</p>
<p>
Ornare et vel dictum dictum et, quis mauris tempus accumsan. Sed ligula, est integer justo viverra. Lacus porttitor blandit ac, sit in rerum sodales urna. Urna amet malesuada feugiat sed eu sodales, integer quae aenean pellentesque eget vulputate est, pretium cupiditate, praesent taciti sapien. Tristique sodales leo urna, aliquet consectetuer fermentum sit. In neque gravida ac nunc, interdum orci bibendum convallis lobortis ac nec, vitae nibh nulla sodales mi justo nulla, sed sit vestibulum. Vestibulum eget morbi dolor. Et quis massa ultricies et eros est, vel id. Fringilla curabitur non orci duis erat commodo. Amet mauris nulla dui imperdiet, pede elit semper dui.</p>
<p>
Nunc suspendisse vehicula ipsum. A turpis mollis nulla nunc nunc. Libero facilisis fermentum vel at, viverra duis dolor orci pede lacinia tempore, mauris a justo proin in tincidunt, euismod nibh egestas. Tempus eleifend sit, vel placerat lacus est, sed suspendisse ut, aliquam arcu neque a. Duis eu nec suscipit eros accumsan. Consectetuer maecenas sed ac velit etiam, ante eget mattis sapien vitae vivamus, est faucibus vestibulum wisi, commodo purus congue nunc velit nec nec, ante ligula quis orci sed consequatur potenti. Vivamus libero, dis consequat donec mattis diam vestibulum, dis nunc pellentesque, metus augue mollis nisl, sed adipiscing faucibus curabitur non pede ut. Sit at a suscipit sed quis, tincidunt metus tellus, id risus massa vehicula, quis in ut dis sollicitudin turpis sem, vitae egestas tortor. Ut lacinia pulvinar pulvinar in, quis elit elit eu sed, nulla lorem placerat tempor pellentesque in, ullamcorper urna. Ut dictum vel fusce eros lectus, justo nulla cum ligula eros quis vel, arcu ullamcorper, torquent pulvinar fringilla turpis fringilla dolor. Fermentum leo augue natoque, fringilla vestibulum quis. Quis eleifend eget est vestibulum.</p>
<p>
Vel mauris mattis sit id, eget diam urna dui vestibulum sed, eu vulputate in mi et sit laoreet. Turpis ullamcorper quis sapien semper et tortor, auctor non elit fringilla, montes pellentesque viverra condimentum volutpat risus, diam tincidunt, lorem quam. Porta pede duis sed massa. Neque sit vehicula porta nec cras tortor, sed lobortis donec mi odio faucibus, mollis neque proin pretium ut, nonummy nostra tellus placerat adipiscing vel. Ultrices leo, lorem sem cursus mauris.</p>

<select id="paragrafo">

  <option value="">Scegli un paragrafo</option>
  <option value="0">Paragrafo 1</option>
  <option value="1">Paragrafo 2</option>
  <option value="2">Paragrafo 3</option>
  <option value="3">Paragrafo 4</option>
</select>

<select id="styling">

  <option value="">Scegli uno stile</option>
  <option value="pace">Pace</option>
  <option value="viulenza">Viulenza</option>
  <option value="sconvolten">Sconvolten</option>
  <option value="delicatessen">Delicatessen</option>
</select>

<button type="button" onclick="changePar()">Applica</button> 

<button type="button" onclick="resetPar()">Resetta</button>

</body>

</html>

Si noti l'uso di testo Lorem ipsum.

Nell'intestazione sono referenziati i due files cssDoc.css e jsDoc.js:

<link href="cssDoc.css" rel="stylesheet" type="text/css" />
<script language="javascript" src="jsDoc.js"></script>

Il codice di cssDoc.css è il seguente:

body
{
margin-left: 15px;
margin-right:15px;
padding:0;
height:100%;
font-family: Verdana;
font-size: 20px;


p

{
margin-left:35px;
margin-right:35px;
}

.pace{color: blue;background-color: yellow }

.viulenza{color: red;background-color: black }
.sconvolten{color: white;background-color: black }
.delicatessen{color: blue;background-color: red }

In particolare si notino le tre dichiarazioni di classe css: .pace, .viulenza, .sconvolten e .delicatessen.

Tali stili non sono usati al primo caricamento della pagina. Lo saranno quando, dopo aver scelto un singolo paragrafo e lo stile da applicare, premeremo sul pulsante "Applica". La pressione del pulsante "Reset" riporterà la pagina nella condizione iniziale.

Il file javascript che "fa il lavoro" è il seguente:

function changePar()
{
var par=document.getElementById("paragrafo").value;
var stile=document.getElementById("styling").value;
var pList = document.getElementsByTagName("p");

pList[par].className=stile;

}

function resetPar(){

var pList = document.getElementsByTagName("p");

for (i = 0; i < pList.length; i++) {

pList[i].className="";
}

paragrafo.selectedIndex=0;

styling.selectedIndex=0;

}


Esso consta di due funzioni, changePar() e resetPar(), che vengono eseguite quando si premono, rispettivamente, i pulsanti "Applica" e "Reset".

Gi studenti sono invitati a copiare i sorgenti e ad eseguire il codice. Ciò fatto, possono provare a introdurre qualche modifica, ad esempio al file css. I più bravi potranno intervenire sul codice javascript per ulteriori modifiche al comportamento della pagina.

Non appena possibile realizzerò un filmato nel quale approfondirò gli aspetti più concettuali dell'esempio e, più in generale, della programmazione web lato client. Have fun guys.

domenica 25 ottobre 2015

La modulazione analogica angolare (di frequenza e di fase)

Link correlati:

1) SVILUPPO IN SERIE DI FOURIER
2) SVILUPPO IN SERIE DI FOURIER
3) MODULAZIONE DI FREQUENZA (FM)

Nella modulazione angolare l'argomento di una portante sinusoidale viene variato in funzione dell'ampiezza di un segnale modulante. Si ricorda che la frequenza della portante è sempre molto maggiore della frequenza della modulante.

Chiariamo subito cos'è l'argomento della portante sinusoidale. Esso è il valore istantaneo f(t)=2p·fp·t sul quale si calcola la funzione coseno (o seno) che descrive la portante.

Indichiamo con il pedice "p" le grandezze riferite alla portante e con il pedice "m" quelle riferite alla modulante. Se fp è la frequenza della portante, e fm quella della modulante (supposta per semplicità essere un segnale sinusoidale, con fp>>fm) allora modulare l'argomento della portante (supposta per semplicità di ampiezza unitaria):

Vp(t)=cos(2p·fp·t)

significa variare l'argomento della funzione coseno, f(t)=2·p·fp·t in funzione dell'ampiezza della modulante, oltre che del tempo. In altre parole, nella formula precedente la fp diventa:

f(t)= fp + Df·cos(2p·fm·t)

In tal modo l'espressione della portante modulata diventa:

V(t)=cos{2p·[fp + Df·cos(2p·fm·t)]·t}

Ovvero:

V(t)=cos[2p·fp·t + 2p·Df·t·cos(2p·fm·t)]

Ricordando che la pulsazione w può essere scritta come: w=2p·f e quindi 2p·Df=Dw

V(t)=cos[wp·t + Dw·t·cos(wm·t)]

Si definisce indice di modulazione il rapporto: mf=Dw/wm

Quando l'indice di modulazione è minore di 1 si parla di modulazione di frequenza in banda stretta, altrimenti si ha modulazione in banda larga e in ricezione è più difficile separare la modulante dalla portante. Nella modulazione in banda larga l'analisi spettrale diventa molto più complessa, sebbene le prestazioni complessive dei sistemi di trasmissione siano nettamente migliori.

L'analisi in frequenza del segnale modulato

L'analisi in frequenza, nel caso della modulazione angolare, è più complessa rispetto alla modulazione di ampiezza. Essa può essere affrontata con i teoremi della trigonometria solo quando il segnale modulante è anch'esso sinusoidale e l'indice di modulazione è minore di 1, ma per un generico segnale modulante e soprattutto con indice di modulazione maggiore di 1 si deve far ricorso a strumenti di matematica un po' più complessi. Nella figura sottostante è riportato lo spettro di un singolo segnale sinusoidale modulato in frequenza con indice di modulazione minore di 1:



La larghezza di banda può essere calcolata, con buona approssimazione, usando la formula di Carson:

Bfm=2·fm·(mf+1)=2·(Df+fm)

La formula di Carson è valida con buona approssimazione anche per un segnale generico. In tal caso si deve considerare la massima frequenza contenuta in esso.

Per capire in che modo si esegue l'analisi spettrale quando il segnale modulante non è una singola sinusoide, cioè nelle situazioni reali, è necessario ricordare il teorema di Fourier. Il teorema di Fourier afferma che un qualsiasi segnale periodico, sotto alcune condizioni matematiche (sempre verificate per i segnali fisici), può essere ottenuto mediante la somma di un termine costante e di infinite funzioni sinusoidali, le cui frequenze sono multipli interi di quella del segnale (ovvero le cui pulsazioni sono multipli interi di quella del segnale). Indicando con w0 = 2p·f0 la pulsazione di un segnale periodico v(t), di qualsiasi forma, a frequenza f0, il teorema ha la seguente espressione matematica, definita sviluppo in serie di Fourier:



I coefficienti di questa formula possono essere calcolati con metodi che non sono alla portata di studenti del 4° Itis. Soprassediamo a ciò e osserviamo un dettaglio importante: la formula precedente è valida per un segnale generico che sia però periodico, con frequenza che abbiamo indicato con f0. Cosa accade quando il segnale non è periodico, come è nelle situazioni reali? Ebbene, anche in questo caso è possibile scomporlo in una somma di infinite armoniche, infinitamente vicine le une alle altre. I calcoli per affrontare questa situazione sono ancora più complessi, per cui ci limiteremo a descrivere sommariamente il caso della modulazione in frequenza in banda larga di un generico segnale periodico, con frequenza fondamentale f0.

Si può dimostrare che le ampiezze delle armoniche che costituiscono il segnale modulato dipendono dall'indice di modulazione e dall'andamento di particolari funzioni, dette di Bessel.



Nella figura sono riportate le funzioni di Bessel, ordinate con un indice che parte da 0. In ascisse è riportato l'indice di modulazione.  Supponiamo che l'indice di modulazione sia pari a 3. Le ampiezze delle armoniche che compongono il segnale modulato in frequenza in banda larga sono date dai valori (in modulo) delle intersezioni della retta verticale in corrispondenza dell'indice di modulazione pari a 3 con gli andamenti delle funzioni di Bessel. Calcoli analoghi possono essere eseguiti per i valori delle fasi.

Le funzioni di Bessel

Una esposizione delle funzioni di Bessel esula dagli scopi di questo corso. Tuttavia possiamo divertirci a graficarle usando una tabella elettronica. La sintassi per calcolare il valore di una funzione di Bessel di ordine n (=0,1,2,3,4....) nel punto x è: =BESSEL.J(x;n). Buon divertimento.

martedì 19 maggio 2015

La tabella ASCII (parte I - il problema della codifica)

Premessa


Ragazzi, oggi parliamo della tabella ASCII. Cominciamo dalle cose semplici: la tabella ASCII fa corrispondere una combinazione di bit ad ogni carattere tipografico. L'acronimo ASCII sta per American Standard Code for Information Interchange.

Se seguite questo link alla voce di wikipedia dedicata all'ASCII, e quest'altro relativo allo standard che lo ha sostituito, l'UTF-8, trovate molte informazioni tecniche di grande importanza. Devo tuttavia ricordarvi che l'informatica è una disciplina particolare che richiede la conoscenza di una grandissima quantità di concetti come linguaggi, standard, architetture, sistemi operativi, nonché dispositivi hardware e molto altro, ragion per cui è necessario non solo operare qualche scelta che limiti il campo di interesse, ma anche organizzare il percorso di apprendimento in modo da non disperdere eccessivamente le proprie risorse intellettuali e di tempo, nel vano tentativo di approfondire ogni argomento in dettaglio.

La strategia che ogni buon informatico adotta è quella di:
  • avere un quadro concettuale (dicasi: concettuale) completo di tutte le tecnologie in gioco
  • apprendere ad un livello sufficiente una parte di esse
  • approfondire, di volta in volta, quelle che sono necessarie per svolgere un determinato compito
Poiché queste note sono indirizzate a studenti del primo anno di informatica di un istituto tecnico, i quali sono del tutto all'oscuro delle più semplici nozioni che non siano quelle di pigiare su uno smartphone, siamo obbligati a fare il primo passo muovendoci quasi esclusivamente sul piano dei concetti di base e trascurando gli approfondimenti, come ad esempio un'esposizione dettagliata delle soluzioni adottate nello standard UTF-8 rispetto all'ASCII classico.

Il problema della codifica


La parola "codifica" è uno dei termini usati dagli informatici, e in generale da chi si occupa di tecnologia e scienza, per indicare i termini di un accordo. Altre parole molto usate sono "standard" e "protocollo". In generale la parola "codifica" è usata dagli informatici e dagli elettronici per indicare un tipo di accordo relativo al funzionamento di base di un computer, ad esempio quale combinazione di bit usare per indicare un determinato colore, oppure quale livello di tensione elettrica usare per indicare un bit posto a 1 o a 0. Il termine "standard" è più frequentemente usato per indicare un accordo relativo alle architetture dei sistemi, mentre il il termine "protocollo" è quello preferito dagli ingegneri che si occupano di telecomunicazioni (protocolli di comunicazione), come pure dai medici per indicare procedure terapeutiche (protocolli di cura), dai diplomatici per indicare un cerimoniale nei rapporti tra Stati, e altro ancora.

Nel caso della tabella ASCII si parla di "codifica ASCII" perché si tratta di un accordo, ormai condiviso a livello mondiale, in base al quale si è stabilito di indicare ogni lettera dell'alfabeto, e ogni segno di punteggiatura (più qualcos'altro di cui diremo) con una ben precisa combinazione di bit. Ad esempio, in ASCII la parola "ciao" è indicata con la seguente combinazione di 32 bit, 8 per ogni carattere:

01100011 01101001 01100001 01101111
      c                i               a               o

In realtà, all'inizio la tabella ASCII usava 7 bit per ogni carattere, ma in seguito si è passati ad 8, ed oggi se ne usano 16 o 32. Ma di ciò parleremo più avanti. Prima è necessario parlare in generale del concetto di "codifica" (o standard, o protocollo, o termini simili).

Adottare una codifica significa stabilire un accordo sul significato di un segnale. Ciò presuppone l'esistenza di almeno due soggetti dotati di capacità intellettive: dalle più semplici, possedute anche dagli animali, a quelle più evolute che caratterizzano l'uomo. Un gesto, o un suono, sono esempi di segnali elementari. Quando il significato di un gesto, o di un suono, è condiviso da almeno due soggetti dotati di intelletto, allora siamo di fronte a un "codice", o "codifica". Possiamo dunque affermare che l'esistenza di un codice è indice della presenza di una qualche capacità intellettiva, cioè di coscienza.

Tuttavia c'è un problema: la distanza spazio-temporale. Se io voglio che l'informazione (il significato) associato a un gesto o a un suono duri nel tempo, oppure possa essere trasferita a distanza, devo ricorrere a un espediente: associare quel gesto o quel suono a un simbolo. Devo, cioè, imparare a scrivere. Per far ciò ho bisogno di un alfabeto, ovvero di un certo numero di simboli che rappresentino i segnali affinché, invece di trasferire questi nello spazio-tempo, cosa impossibile, io possa trasferire i simboli.

L'umanità ha adottato, nel corso della storia, due soluzioni diverse. La prima, più semplice da concepire ma meno efficiente, consiste nell'associare a ogni concetto un simbolo. Questa soluzione è più semplice perché, in un certo senso, "salta il segnale", codificando direttamente il messaggio con l'uso di uno o più simboli. Ad esempio: ho paura, dunque emetto un grido, ma, invece di "codificare il grido" (cioè il segnale), codifico direttamente l'idea di paura, con un disegno o un segno stilizzato. La soluzione alternativa, codificare il segnale che, a sua volta, "codifica" il concetto, sebbene apparentemente più complessa, alla fine è talmente più efficiente da risultare la più semplice.

Usando il primo metodo, si potrebbe usare un mucchietto di sassi, opportunamente disposti secondo le regole dell'alfabeto condiviso dalla tribù, per indicare una situazione di pericolo piuttosto che la presenza di un sentiero. Le più antiche forme di scrittura si sono conformate a questa impostazione, utilizzando disegni tracciati su una superficie (scrittura pittografica). Con il passare del tempo i disegni divennero segni stilizzati, che avevano il vantaggio di rendere meno equivocabile il loro significato.

A destra è riportato un esempio di simboli (ideogrammi) usati nell'alfabeto cinese e il metodo seguito per comporli al fine di esprimere concetti più complessi a partire da quelli più semplici. Nella seconda riga, ad esempio, con un simbolo, due simboli o tre si indica rispettivamente un albero, un bosco o una foresta. Gli ideogrammi riportati dal dizionario della lingua cinese moderna sono in totale 56000, sebbene sia sufficiente la conoscenza di circa 3500 segni per comprendere mediamente il 90% di un testo. Molte civiltà, oltre quella cinese, hanno adottato un metodo di scrittura ideografico. Si pensi, ad esempio, alle civiltà della valle dell'Indo.

La scrittura degli antichi egizi è un'evoluzione del metodo ideografico. Accanto ai segni ideografici, infatti, gli antichi egizi ne introdussero altri che indicavano suoni semplici (fonemi) e suoni composti (sillabe). I geroglifici egizi (dal greco ἱερογλυφικός - hieroglyphikós - che significa "segno sacro inciso") utilizzavano 24 segni di base i quali, combinati in modo diverso secondo regole anche complesse, conducevano a un totale di quasi 7000 segni diversi. Per approfondire potete visionare questo lavoro, svolto dai ragazzi della IV-D dell'Istituto Commerciale Santorre di Santarosa di Savigliano (Cuneo).

Il secondo metodo che gli uomini hanno sviluppato per scrivere consiste nell'associare un simbolo ad ogni suono elementare presente in una lingua. Questo è il metodo fonetico, lo stesso che avete appreso in prima elementare: in questo caso si codifica il segnale sonoro (la parola) che è associato al concetto che si intende trasferire nello spazio-tempo. La complessità, apparentemente, aumenta, perché si ha bisogno di una doppia codifica (concetto => suono => simbolo) ma alla fine l'efficienza è molto maggiore.

Si ritiene che il metodo fonetico si sia sviluppato, a partire dalla metà del secondo millennio a.c., come evoluzione dei geroglifici usati dagli egiziani e dagli abitanti della Mesopotamia (coincidente in gran parte con l'odierno Iraq).

Poiché presumo che le maestre e i maestri che vi hanno insegnato a leggere e scrivere abbiano fatto un buon lavoro, non perderò tempo per spiegarvi come funziona il metodo di scrittura fonetica. Tuttavia vi è un aspetto del metodo fonetico che è molto interessante, perché ha attinenza con la tabella ASCII; per essere più precisi con l'evoluzione di questa codifica da 7/8 bit per carattere fino ai 16/32 oggi utilizzati nella codifica UTF-8. 

L'alfabeto fonetico internazionale (IPA)


Vedete ragazzi, quando voi eravate alle elementari le maestre e i maestri vi hanno insegnato, per prima cosa, i simboli fonetici che rappresentano i suoni elementari della lingua italiana. I suoni elementari sono chiamati "fonemi", mentre i simboli usati per rappresentarli sono i "grafemi".

Vi è però un problema. Prendiamo il fonema rappresentato dal grafema "c", presente ad esempio nella parola "cane". Lo stesso fonema (suono) è presente però anche nella parola "chiesa", ma in questo caso è rappresentato da una coppia di grafemi, la "c" seguita dalla "h". A complicare le cose c'è il fatto che le lingue si evolvono, per cui oggi in italiano si usa anche il grafema "k" per indicare parole ormai accolte nel dizionario italiano, ad esempio "killer", che certamente nessuno di voi si sogna di scrivere "chiller"; anche perché un "chiller" è un tipo di frigorifero.

I linguisti, cioè coloro che studiano professionalmente i linguaggi scritti e parlati da tutte le civiltà di tutti i tempi, a un certo punto hanno sentito l'esigenza di un metodo universale, ovvero non legato a una lingua particolare, per denotare tutti i suoni presenti in tutte le lingue di tutti i tempi. Da questa esigenza è nato l'alfabeto fonetico internazionale (International Phonetic Alphabet - IPA), che è un sistema convenzionale di notazione standardizzata di carattere universale, poiché consente la codifica articolatoria dei suoni di tutte le lingue del mondo.

Avete sicuramente incontrato esempi di scrittura fonetica IPA, sfogliando un dizionario. Ad esempio, la pronuncia della parola "summertime" (estate) in IPA si scrive così:  /ˈsʌm.ə.taɪm/. Il suo suono è questo

Se avete la curiosità di approfondire l'IPA vi suggerisco, per incominciare, questi due video YT: