Docsity
Docsity

Prepara i tuoi esami
Prepara i tuoi esami

Studia grazie alle numerose risorse presenti su Docsity


Ottieni i punti per scaricare
Ottieni i punti per scaricare

Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium


Guide e consigli
Guide e consigli


Dispensa di informatica completa e statistica, Dispense di Elementi di Informatica

cos'è l'informatica, complessità computazionale, esercizi su algoritmi e basi di programmazione. cos'è la statistica, basi di statistica, esercizi e problemi spiegati.

Tipologia: Dispense

2019/2020

In vendita dal 22/10/2020

GaiaNives
GaiaNives 🇮🇹

4.6

(17)

12 documenti

1 / 20

Toggle sidebar

Questa pagina non è visibile nell’anteprima

Non perderti parti importanti!

bg1
GAIA STUCCHI [email protected]
INFORMATICA 8 CFU
Lezione 1
L’INFORMATICA è una
scienza
che si occupa del trattamento dell’
informazione
mediante l’utilizzo di procedure
automatizzabili
.
Come sono fatti i “computer”?
I computer sono macchine elettroniche programmabili ciò significa che avendo in
ingresso un programma e dei fati, un computer produce risultati secondo il
procedimento di trasformazione descritto dal programma. Queste macchine sono
composte da varie parti tra cui la scheda madre, una piastra di circuito stampato a più
livelli composta a sua volta da circuiti. Il TRANSISTOR è l’elemento base di un
circuito (chip legge di moore), ogni transistor può essere visto come un microscopico
interruttore capace di assumere uno stato aperto o chiuso (acceso o spento, …). Ogni
transistor implementa un PORTA LOGICA che realizza una determinata operazione
tra variabili booleane (un insieme di porte logiche connesse fra di loro costituisce una
rete logica, che svolge un determinato «calcolo» sui valori delle variabili che riceve in
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14

Anteprima parziale del testo

Scarica Dispensa di informatica completa e statistica e più Dispense in PDF di Elementi di Informatica solo su Docsity!

INFORMATICA – 8 CFU

Lezione 1

L’INFORMATICA è una scienza che si occupa del trattamento dell’ informazione

mediante l’utilizzo di procedure automatizzabili.

Come sono fatti i “computer”? I computer sono macchine elettroniche programmabili ciò significa che avendo in ingresso un programma e dei fati, un computer produce risultati secondo il procedimento di trasformazione descritto dal programma. Queste macchine sono composte da varie parti tra cui la scheda madre, una piastra di circuito stampato a più livelli composta a sua volta da circuiti. Il TRANSISTOR è l’elemento base di un circuito (chip → legge di moore), ogni transistor può essere visto come un microscopico interruttore capace di assumere uno stato aperto o chiuso (acceso o spento, …). Ogni transistor implementa un PORTA LOGICA che realizza una determinata operazione tra variabili booleane (un insieme di porte logiche connesse fra di loro costituisce una rete logica, che svolge un determinato «calcolo» sui valori delle variabili che riceve in

input, e restituisce un valore in output → 0 (false) o 1 (true). Esistono diverse porte logiche:

  • AND (“prodotto logico”): 1 solo se entrambe 1, altrimenti 0
  • OR (“somma logica”): 1 se almeno una 1, altrimenti 0
  • NOT (“negazione logica”): output è l’opposto del valore di input Vedi ex. 1 e 2 HARDWARE: parte fisica del computer costituita da un insieme di circuiti e da vari dispositivi. Architettura di Von Neumann Tutti i computer sono composti da tre (cinque) parti:
  1. PERIFERICHE: sono vari dispositivi che permettono la comunicazione tra il computer e l’ambiente esterno (anche l’utente) a. Periferiche di INPUT b. Periferiche di OUTPUT c. Periferiche di INPUT - OUTPUT
  2. CPU (processore): parte del computer dedicata all’elaborazione dei dati, esegue istruzioni (sequenze di 0 e 1, ex. ADD 4000, 2000: i numeri sono gli indirizzi di memoria, non i valori!!!) deterministiche ed elementari, ed è costituita da a. CU (unità di controllo): dirige il processo di esecuzione delle istruzioni b. ALU (unità aritmetico-logica): elaboratore di calcoli c. Alcuni registri di memoria di appoggio (ex. Program Counter, registro dove vengono memorizzate il numero delle istruzioni da eseguire, il PC viene incrementato automaticamente quando finisce di interpretare un’istruzione per passare all’esecuzione di quella successiva)

Il CICLO MACCHINA è espresso dai seguenti passi:

  1. Fetch istruzione:
  2. Decodifica istruzione
  3. Fetch dati
  4. Esecuzione istruzione
  5. Restituzione risultato

Tipi di LINGUAGGIO:

  • Linguaggio macchina: è un linguaggio comprensibile al processore (a quello specifico che si sta utilizzando) in cui sono scritte le istruzioni da eseguire e quindi i programmi, in sequenze di 0 e 1 lunga otto caratteri. Quindi per scrivere in linguaggio macchina al posto dei codici mnemonici bisogna utilizzare (digitare) la sequenza di cifre binarie corrispondenti
  • Linguaggio Assembly: è un linguaggio “primitivo”, composto da parole e numeri (codici mnemonici associati alle istruzioni macchina) invece che bit o un Assembler è un programma che analizza le istruzioni del programma scritte in parole e le sostituisce con i corrispondenti binari, e quando ha assemblato tutti i bit dell'istruzione li salva nel file oggetto binario e passa alla riga successiva
  • Linguaggi di programmazione ad alto livello: o sono indipendenti dal processore su cui andranno ad essere eseguiti i codici macchina corrispondenti o permette di specificare istruzioni in forma più semplici per l’uomo, è infatti composto da istruzioni più complesse rispetto alle istruzioni elementari eseguite dal processore ▪ ogni istruzione ha una sintassi precisa (= forma con cui l’istruzione viene espressa) e una semantica precisa (= significato dell’istruzione stessa), quindi l’esecutore riconoscendo un’istruzione in base alla sintassi effettua l’azione corrispondente alla semantica. o prima di essere eseguiti il compilatore trasforma (traduce) ogni istruzione di un programma di alto livello in una o più istruzioni elementari. Una variante del compilatore è l’interprete, programma che compie una traduzione simultanea con l’esecuzione di ciascuna istruzione.

➔ Da base 10 a base 2 Conversione di 13 10 13 / 2 → quoziente = 6, resto = 1 6 / 2 → quoziente = 3, resto = 0 3 / 2 → quoziente = 1, resto = 1 1 / 2 → quoziente = 0, resto = 1 STOP! Leggiamo ora i valori dei resti: il primo resto corrisponde all’ultimo bit, così via fino l’ultimo resto che corrisponde al primo bit → Quindi: 1310 = 1101 2 Rappresentazione dei caratteri e dei testi senza formattazione: Ad ogni carattere (lettere e altri simboli che sono parte di un testo, come i segni di punteggiatura, lo spazio, etc) è possibile associare un numero in rappresentazione binaria. Per esempio, a quale numero è associata la lettera «a»? Si può scegliere un numero qualsiasi, a patto che poi tutti usino sempre questo numero per «a». Cioè, si decide una codifica sulla quale tutti concordano. Esistono diverse codifiche:

  • ASCII: rappresentazione a 7 bit, ma negli anni sessanta ci si rende conto che che il codice a 7 bit non bastava, perchè non poteva rappresentare lingue con caratteri diversi dall'inglese quindi si passa alla seconda codifica di questo elenco
  • ASCII esteso: estensione della ASCII, è una rappresentazione a 8 bit che comprende tutti i simboli (caratteri) di tutte le lingue. (questa nuova sequenza di otto bit viene chiamata byte)
  • Unicode: originariamente strutturata in 6bit ma poi estesa a 32bit (= 4 byte) per carattere. Questa codifica comprende tutte le lingue del mondo e anche i simboli matematici, chimici, etc. La formattazione è l’aggiunta di informazioni su come deve essere mostrato il testo, un testo non formattato si rappresenta come una serie di caratteri codificati uno dopo l’altro. Lo spazio necessario per memorizzare le informazioni (testo non formattato) come “ciao ciao” dipende dalla codifica utilizzata:
  • ASCII estero → 9 byte totali
  • Unicode → 36 byte totali Rappresentazione dei testi con formattazione Definiamo un carattere speciale (→ ad esempio “$”), quello che segue il carattere scelto ($) indica come deve essere formattato il testo Ex: “ciao ciao” potrebbe essere codificato come:
  • ciao $IniziaSottolineato ciao $FineSottolineato
  • che a sua volta può essere memorizzato come normale testo in codifica ASCII

Quindi basta accordarsi sulle marcature da utilizzare, e per il resto si usa la codifica dei caratteri tipo ASCII o Unicode Lo spazio necessario per memorizzare il testo formattato è lo stesso spazio occupato dal testo non formattato più lo spazio per codificare le marcature (che dipende dal tipo di marcature utilizzate, ma occupa poco spazio) Vedi esercizi lez2 slide 47- 48 Rappresentazione dell’informazione multimediale: L’immagine digitale è una rappresentazione di un’immagine (bidimensionale) tramite un’opportuna serie di valori (Ad esempio, immagine bitmap: i valori formano una matrice di punti, ogni punto (=pixel) indica le caratteristiche dell’immagine da rappresentare) I PIXEL (= picture element) sono puntini di luce colorata, disposti su una griglia per formare lo schermo di un computer (il numero di bit necessari per rappresentare un pixel viene chiamato profondità del colore). I metodi di codifica del colore sono basati soprattutto sulla percezione umana, infatti l’occhio umano distingue colori compresi tra 0.4 e 0.8 μm di lunghezza d’onda, chiamato campo del visibile. Nella nostra percezione del colore, un gran numero di colori può essere rappresentato come somma di tre colori primari Per digitalizzare i colori si è pensato di rappresentarli come combinazioni di tre colori Red Green Blue → RGB, quindi ciascun pixel è composto dalla somma tre luci colorate. Attivando una luce per volta è possibile visualizzare i tre colori (più il nero e il bianco) e usando diverse intensità, quantità, delle tre luci si possono ottenere tutti i colori. La dimensione di un’immagine è data dal numero di pixel di cui l’immagine è composta, moltiplicato per lo spazio necessario per memorizzare ogni pixel. È, però, possibile modificare l’informazione in modo che occupi meno spazio, ciò significa comprimere un’informazione. La compressione, quindi, è la modifica della rappresentazione in modo da usare meno bit per la memorizzazione o la trasmissione delle informazioni. Esistono due tipologie di compressione:

  • Compressione lossless (=senza perdita): dall’informazione compressa si può tornare all’originale senza perdita di dati
  • Compressione lossy (=con perdita): L’informazione viene compressa maggiormente, ma non è possibile riottenere l’originale (completa)

algoritmo come azioni (verbi), quindi non con la sintassi specifica di qualche linguaggio di programmazione, che ha come scopo la comprensibilità e leggibilità del codice. Vedi esercizi lez3, slide da 20 a 31 + da 37 a 47 Dato un problema è possibile definire più algoritmi per trovare una soluzione, è importante ricordare che algoritmi differenti possono risolvere lo stesso problema in modo diverso, quindi in tempi diversi. In linea generale, si può dire che tra diversi algoritmi si sceglie quello che, a parità di

memoria occupata, calcola più velocemente la soluzione, ma di quale tempo stiamo

parlando?? Il TEMPO DI CALCOLO non è un tempo fisico (misurato in secondi), ma un tempo determinato dal numero di istruzioni eseguite, dato un certo input. La COMPLESSITÀ COMPUTAZIONALE di un algoritmo è quindi indipendente dalla sua implementazione o dal computer sul quale viene eseguito ma è basata solo sul tempo di calcolo di quel algoritmo. Confrontando le diverse complessità di diversi algoritmi si può allora scegliere quello più efficiente.

  • Complessità costante O(1)
  • Complessità lineare O(n)
  • Complessità quadratica O(n^2 )
  • Complessità polinomiale O(nk)
  • Complessità esponenziale O(an) Un algoritmo è efficiente se:
  • La sua complessità è costante oppure lineare
  • La sua complessità è polinomiale per valori bassi di k, quindi al più quadratica Un algoritmo è inefficiente se la sua complessità è esponenziale, ciò non vuol dire che l'algoritmo sia sbagliato, ma solo che il tempo di esecuzione è inaccettabile. Vengono definiti problemi facili quelli per cui esistono algoritmi efficienti, vengono invece definiti problemi intrattabili quei problemi che non possono essere risolti mediante nessun algoritmo efficiente. Esistono anche i problemi NP-completi (intrinsecamente difficili per dimostrazione matematica) che corrispondono a quei problemi per i quali non sono stati trovati algoritmi efficienti ma, allo stesso tempo, non c’è certezza che tali algoritmi non esistano. Vedi appunti quaderno → macchina di Turing Vedi lez3pt3 slide da 20 a 55 → NB

PROGRAMMAZIONE STRUTTURATA:

è una metodologia usata per la stesura dei programmi, ha infatti come scopo limitare la complessità della struttura del controllo dei comandi. Si basa su tre strutture di controllo fondamentali (con ognuna una sintassi e una semantica specifica) che guidano l’rodine di esecuzione delle istruzioni di un algoritmo:

  1. Sequenza: le istruzioni di un programma sono eseguite nell’ordine in cui compaiono
  2. Selezione (if-then-else): permette di scegliere, in base alla veridicità di una condizione, l’esecuzione di un blocco di istruzioni fra due possibili (quindi, le operazioni sono alternative e mutualmente esclusive, e verranno eseguite o meno a seconda della veridicità della condizione posta) - Sintassi: - Semantica: se la condizione è verificata si esegue istruzione1, altrimenti viene eseguita istruzione
  3. Iterazione (ciclo): permette di ripetere l’esecuzione di un blocco di istruzioni per un certo numero di volte o in base al valore di una data condizione. o “For”: - Sintassi: - Semantica: l’istruzione viene eseguita una volta dopo l’altra per il numero di volte prestabilito (a priori) o “Repeat until”: - Sintassi: - Semantica: l’istruzione viene sempre eseguita almeno una volta (perché la condizione è posta e valutata alla fine del blocco di istruzioni) e se la condizione risulta falsa l’istruzione viene eseguita nuovamente; l’iterazione termina quando la condizione risulta vera o “While do”: - Sintassi: - Semantica: l’istruzione viene eseguita diverse volte fino a quando la condizione (posta a priori) risulta falsa, allora termina Vedi esercizi lez3pt2 slide da 25 a 29 + esercizi lezione

BASI DI DATI

Le banche dati biologiche possono essere classificate a seconda del tipo di “struttura” usata per gestire i dati:

  • bd basate su DBMS standard
  • bd basate sul DBMS chiamato ACEDB
  • bd supportate da OPM insieme a un DBMS relazionale o a oggetti
  • bd implementate come collezione di “flat-file” (un flat-file = è un file di testo txt non formattato, contenente informazioni che non presentano alcun tipo di relazione strutturata, e contengono una sorta di etichetta per ogni informazione) [Si definisce DBMS il sistema (strato software di base) di gestione del database. Il DBMS si colloca tra i programmi applicativi e i file e si occupa di gestire e manipolari i dati di un database, inserendoli e quindi definendoli e archiviandoli, o prelevarli nella base di dati.] L’utente di una banca dati generalmente non è consapevole del modo in cui la banca dati è implementata, e “vede” solo i servizi che la banca dati fornisce e i dati reperiti tramite un’opportuna ricerca o analisi. In un database è possibile rappresentare qualunque ENTITÀ (= oggetti principali su cui vengono raccolte le informazioni; vengono definite attraverso un nome dato dal creatore del db) che sia rappresentabile su un computer. Ogni singolo oggetto descritto dall'entità viene detto ISTANZA. Per rappresentare un’entità, si identificano le sue caratteristiche, dette ATTRIBUTI. Gli attributi hanno un nome che caratterizza la natura dell’informazione e un dominio (insieme di tutti i possibili valori che un attributo può avere) che definisce il tipo di valori che possono essere assunti per quell’attributo. Il dominio è un metadato, cioè ogni tipo di informazione usata per descrivere un'altra informazione, invece i dati sono gli specifici valori inseriti per gli attributi. Perciò, i metadati specificano il tipo di dati contenuti nel database, ma non i dati stessi. Unicità delle entità → due entità possono avere lo stesso valore per uno o più attributi ma se hanno lo stesso valore per TUTTI gli attributi allora sono la stessa entità. In pratica NON possono esistere nel database due entità con gli stessi valore per tutti gli attributi, ossia deve esistere almeno un insieme di attributi i cui valori non sono ripetuti in due entità diverse, ognuno di questi insiemi identifica univocamente un’entità, dunque ci permettere di distinguere entità diverse.

Tipologie di CHIAVI: Un insieme di attributi che identifica in modo univoco un’entità è detto chiave CANDIDATA. Tra tutte le chiavi candidate, ne viene scelta una che svolge il ruolo di chiave PRIMARIA. La chiave primaria è appunto è la chiave candidata che il computer e l'utente usano di comune accordo per localizzare le entità durante le operazioni sul database. Inoltre l'utilizzo della chiave primaria (→ chiave esterna) permette di risolvere i problemi relativi alla ridondanza dei dati che sono:

  • spreco di spazio di memorizzazione
  • inconsistenza dei dati Una chiave ESTERNA è un insieme di attributi di una tabella che fa riferimento alla chiave primaria di un’altra entità. La chiave esterna permette di reperire le informazioni da un’entità ad un’altra in modo coerente, senza dover replicare tutte le informazioni di una tabella in altre tabelle. Una RELAZIONE tra entità (tabelle) è una corrispondenza tra gli attributi di una tabella e gli attributi di un’altra tabella. Una relazione rappresenta un'associazione tra una o più entità. Un database RELAZIONALE descrive appunto le relazioni tra diversi tipi di dati, permettendo al software di rispondere alle interrogazioni formulate dagli utenti sul suo contenuto. Il diagramma «entità-relazione» è uno schema usato per rappresentare le entità (con i loro attributi) e le loro relazioni.

Lezione 5

La BIOINFORMATICA è la scienza che si occupa della soluzione di problemi biologici, sfruttando gli strumenti e le teorie dell’informatica La bioinformatica è nata con lo scopo di fornire metodi automatici per l’analisi di sequenze di DNA e di proteine:

  • Sviluppo di database di dati biologici
  • Enorme impulso dal Progetto Genoma Umano (sequenziamento di genomi su larga scala) Le discipline “–omiche” (ex. genomica, trascrittomica, proteomica, glicomica, etc) sono discipline molecolari che si occupano dello studio su larga scala degli elementi di una cellula e delle loro funzionalità, integrando l’uso di metodi sperimentali e computazionali. Spesso si accoppiano diverse discipline “-omiche”, così da conoscere vari sistemi nelle sue diverse parti e funzioni. Oggi si usa spesso anche il termine Biologia Computazionale come sinonimo di bioinformatica, ma la bioinformatica è più un modo di classificare e analizzare, invece dietro la biologia computazionale c’è più modellistica. Dall’informatica alla biologia Vedi alcuni problemi della biologia lez5 slide da 10 a 12 Ogni molecola può essere descritta come una sequenza di simboli, quindi ci si dimentica della sua struttura tridimensionale, delle sue proprietà e si guarda solo a quali simboli la costituiscono (ex. RNA è una sequenza con 4 simboli: A,C,G, U).

** Problema di allineamento (somiglianza) di due sequenze Come si fa a sapere se due sequenze sono simili, e quanto sono simili?

  1. Si confrontano i simboli di una sequenza con i simboli dell’altra sequenza, allineando cioè ogni simbolo della prima sequenza con un simbolo dell’altra a. Se le due sequenze sono della stessa lunghezza vedi pt. 2 b. Se le due sequenze non sono lunghe uguali non è possibile allineare tutti i simboli di una sequenza con i simboli dell’altra, quindi si usa un simbolo speciale chiamato GAP che si denota con “ – “, e che può essere inserito in qualsiasi punto della sequenza (con l’eccezione dell’allineamento gap con gap)
  2. Si dà un buon punteggio a tutte le coppie a. di simboli uguali (es. A con A, T con T, C con C, G con G) → MATCH + b. di simboli diversi (es. A con T, A con C, A con G, …) → MISMATCH - 1 c. di simbolo e gap → - 2 In questo modo è possibile quantificare quanto sono simili due sequenze, infatti più alta è la somma dei punteggi di tutte le coppie che si confrontano, più saranno simili le due sequenze. Se bisognerebbe ogni volta costruire tutti gli allineamenti, valutare il punteggio di ognuno, e poi scegliere l’allineamento con il valore più alto ci vorrebbe un tempo lunghissimo. Quindi si è pensato di dividere il problema in sottoproblemi, risolvere ogni sottoproblema, e quindi trovare la soluzione finale (del problema intero) rimettendo insieme le soluzioni parziali (dei sottoproblemi); questa tecnica di risoluzione viene chiamata PROGRAMMAZIONE DINAMICA. In pratica, si costruisce l’allineamento migliore in modo progressivo, partendo dai simboli iniziali delle due sequenze e a mano a mano che si «allunga» l’allineamento fra le parti di sequenze non ancora allineate, si sceglie sempre la soluzione migliore fra quelle possibili precedentemente valutati (valutando e memorizzando i punteggi parziali dei “nuovi” tre allineamenti possibili, che poi andranno a sommarsi con i punteggi degli allineamenti precedentemente considerati, il totale migliore sarà poi scelto). Così per costruzione, l’allineamento completo sarà quindi il migliore allineamento.

[I problemi di ottimizzazione sono quei problemi che richiedono di determinare la soluzione (fra un insieme di possibili soluzioni) che minimizza o massimizza (cioè ottimizza) una funzione specificata. Anche questi problemi possono essere oggettivamente difficili e in questo caso vengono definiti NP-hard. Per cercare di risolvere un problema di ottimizzazione (ad es. il protein folding per la previsione di una struttura proteica), anziché modificare iterativamente una sola soluzione candidata, potremmo utilizzare un insieme di potenziali soluzioni. Potremmo anche far collaborare le soluzioni tra loro, in modo che esplorino al meglio l’insieme di tutte le possibili soluzioni al problema.] **Problema di Protein Folding Il problema di Protein Folding consiste nel prevedere la struttura nativa di una proteina, usando come dato in input la sequenza primaria dei suoi aminoacidi. Data la sequenza iniziale, esiste un numero esponenziale di possibili strutture tridimensionali, la struttura nativa migliore è quella che minimizza il valore di “energia libera” associato alla struttura. È un problema di ottimizzazione NP- hard, infatti tutti gli algoritmi che si possono definire per risolvere questo problema avranno tempi (fisici) di calcolo lunghissimi e quindi non favorevoli. Anche in questo caso si possono utilizzare delle tecniche euristiche per avvicinarsi alla soluzione. **Problema di Docking Molecolare Il problema di docking molecolare (la cui principale applicazione è lo sviluppo e progettazione di farmaci → drug design) consiste nel determinare se e come due molecole interagiscono fra loro, qual è la geometria del complesso da esse formato e qual è il complesso migliore tra diversi. Anche in questo caso, l’interazione migliore viene definita tramite un’opportuna funzione di energia che stima l’affinità di legame fra le due molecole.

Questo problema è anch’esso un problema difficile, infatti non esistono algoritmi efficienti in grado di trovare la soluzione ottimale (e in un tempo accettabile) ma è possibile applicare tecniche euristiche. Il risultato ottenuto dall’analisi computazionale dovrà essere sottoposta a successive (e numerose) analisi sperimentali e cliniche. Studiare un processo cellulare sul computer ha numerosi vantaggi: o Riduzione dei costi e del numero di esperimenti di laboratorio o Il tempo (fisico) di calcolo è generalmente inferiore al tempo necessario per un esperimento o Si possono testare diverse ipotesi e condizioni, senza pericolo di danneggiare o uccidere le cellule o Si possono integrare processi distinti e studiarne le o reciproche interazioni → studio del sistema globale Dalla biologia all’informatica Gli algoritmi genetici sono tecniche euristiche basate su due fenomeni che avvengono in natura: la riproduzione sessuata e la selezione naturale. Gli algoritmi genetici permettono di risolvere numerosi problemi di ottimizzazione. In pratica, invece che “provare” tutte le soluzioni possibili, si lavora solo su un numero molto ridotto di soluzioni, e si fanno “evolvere” le soluzioni per trovare soluzioni che siano sempre migliori delle precedenti. In questo modo, molti problemi possono essere risolti da un processo iterativo che imita l’evoluzione naturale nella ricerca della soluzione migliore. Da ricordare il fatto che comunque la bioinformatica, la biologia computazionale, systems biology e synthetic biology sono aree di ricerca multidisciplinari in cui si lavora in gruppi di ricerca eterogenei ed è fondamentale capirsi, ma ciò non vuol dire che sia sempre facile.