Skillbook Logo
foto profilo

Categoria: Tutorials


Excel delle meraviglie Lezione 10 - Analisi statistica di una popolazione di dati

Gino Visciano | Skill Factory - 06/04/2021 00:33:27 | in Tutorials

In questa lezione utilizzerete le principali funzioni statistiche o di database di Excel per analizzare  una popolazione di dati  di un sito che vende prodotti online.

Prima d'iniziare è importante dare una definizione di statistica.

Che cos'è la statistica
La statistica è lo strumento che permette di trasformare le informazioni, organizzate sotto forma di dati, in conoscenza.

La conoscenza dei dati può essere quantitativa oppure qualitativa. Una ricerca quantitativa richiede una grossa quantità di dati, per ottenere  informazioni  oggettive sulla cosa che si sta analizzando.

L’analisi qualitativa è una ricerca mirata, che permette di individuare una serie di sfumature di un determinato comportamento o evento che non potrebbero essere colte con un’analisi quantitativa.

La statistica è importante perché ci permette di valutare ciò che osserviamo e di prendere decisioni, è descrittiva se si limita a descrivere i fenomeni attraverso indici e grafici, è inferenziale se si avvale di metodi probabilistici, per trarre conclusioni generali a partire dall'esame di un campione.

La statistica inferenziale  non ci dice mai se una cosa è vera o falsa, ma ci permette di determinare la probabilità per stabilire se una cosa può essere vera o falsa.

Principali funzioni di Excel per fare statistica

In Excel per fare statistica potete utilizzare le funzioni statistiche e di database, per ottenere l'elenco completo di queste funzioni cliccate sull'icona fx e  selezionate le  categorie   statistiche   oppure database, come mostra l'immagine seguente:

 

Obiettivo della nostra analisi statistica 

La nostra analisi statistica prevede lo studio della popolazione di dati inserita nel foglio Excel  "Prodotti acquistati online":

i dati sono stati estratti da un sito e-commerce che vende prodotti online. L'obiettivo è quello di capire quali e quanti prodotti sono stati venduti e l'età media dei clienti, sia per sesso, sia per fasce di età

L'attività di analisi verrà gestita attraverso diversi livelli di approfondimento, per ottenere informazioni sempre più dettagliate.

Per calcolare l'età media dei clienti, in base al livello di dettaglio, utilizzerete sia la media aritmetica, sia la media ponderata, di seguito trovate le informazioni che vi servono per capire come calcolare questi due tipi di misure.

Media aritmetica
La media aritmetica serve per sintetizzare una distribuzione di valori attraverso un numero che ne rappresenta la sintesi, quindi si può considerare un indicatore di sintesi di una distribuzione di valori.  

Per calcolare la media aritmetica di n numeri, si applica la formula seguente:

Xm=(X1+X2+X3+...+Xn)/n

in Excel potete usare la funzione:

=media(intervallo_di_valori)

Per capire quanto è affidabile la media aritmetica, dovete calcolare o la varianza oppure la deviazione standard.

Varianza e deviazione standard
La varianza si calcola con la formula seguente:

Varianza=(X1-Xm)^2+(X2-Xm)^2+(X3-Xm)^2+...+(Xn-Xm)^2

in Excel potete usare la funzione:

=var(intervallo_di_valori)

Questa formula permette di misurare la variabilità di una distribuzione di dati.

Giacché la varianza, per evitare i valori negativi, è espressa al quadrato, per indicare l'affidabilità della media conviene usare  la deviazione standardscarto quadratico medio, che corrisponde alla radice quadrata della varianza e quindi è una grandezza della stessa dimensione della media aritmeticain Excel potete usare la funzione:

=dev.st(intervallo_di_valori)

Media ponderata o pesata
Per calcolare la media ponderata servono le seguenti informazioni:
1) le osservazioni o classi;
2) i pesi;
3) la numerosità totale.

Facciamo un esempio:
per calcolare la media ponderata delle età dei clienti che hanno acquistato un particolare prodotto online, dovete prima di tutto indicare le classi di età (osservazioni) a cui siete interessati:
18-25
26-35
36-50
51-65

Successivamente, per ogni classe (osservazioni), dovete calcolare il numero di clienti che hanno acquistato un prodotto online (pesi):

18-25   10
26-35   15
36-50   10
51-65     5

Infine, il rapporto tra i clienti di ogni classe ed i clienti totali (numerosità totale), vi permette di calcolare la media ponderata distribuita par ogni classe:

18-25   10     25%                 (10/40)*100
26-35   15     37,5%              (15/40)*100
36-50   10     25%                 (10/40)*100
51-65     5     12,5%              (5/40)*100
---------------------------------
Totale 40    100%

Le classi permettono anche di calcolare l'età media per ogni intervallo di età scelto, per ottenere questo risultato dovete calcolare il valore centrale delle classi, come indicato nell'esempio seguente:

(25+18)/2=21,5
(35+26)/2=30,5
(50+36)/2=43
(65+51)/2=58

A questo punto potete iniziare ad analizzare la popolazione dei dati del sito e-commerce.

 

Analisi della popolazione di dati  del sito e-commerce (primo livello)
In questo primo livello analizzerete la popolazione di dati disponibile per conoscere: la quantità di prodotti venduti, l'età media, l'età minima e l'età massima dei clienti.
Per ottenere queste informazioni dovete utilizzare le seguenti funzioni di Excel:

=CONTA.VALORI('Prodotti acquistati online'!$A$2:$A$1001)
=MEDIA(
'Prodotti acquistati online'!$B$2:$B$1001)
=MIN(
'Prodotti acquistati online'!$B$2:$B$1001)
=MAX(
'Prodotti acquistati online'!$B$2:$B$1001)

Per indicare il livello di affidabilità dell'età media dei clienti che acquistano i prodotti online, dovete calcolare la deviazione standard, utilizzando la funzione di Excel:
DEV.ST(
'Prodotti acquistati online'!$B$2:$B$1001)

Di seguito la tabella con i dati richiesti:

 

La deviazione standard è molto alta, quindi l'età media dei clienti che acquistano prodotti online non è sicuramente soggetta a grosse variazioni, nell'intervallo di età tra i 18 ed i 65 anni.

 

Analisi della popolazione di dati  del sito e-commerce (secondo livello)
Per proseguire con un'analisi più approfondita dei dati disponibili, dovete conoscere prima quali sono i prodotti venduti. Per ottenere questo risultato dovete estrarre i prodotti venduti dalla popolazione di dati ed eliminare i duplicati, eseguendo le operazioni seguenti:

1) Nel foglio in cui è presente la popolazione di dati che state analizzando, copiate ed incollate  in E1 e in G1 il titolo della colonna prodotto e nella cella E2 inserite un asterisco per indicare che volete estrarre dall'elenco tutti i prodotti, come mostra l'immagine seguente:

Successivamente selezionate Dati, filtri avanzate e compilate la scheda filtro avanzato come indicato nell'immagine seguente:

Cliccando sul pulsante ok, otterrete l'elenco dei prodotti venduti, senza duplicati.

A questo punto potete calcolare: la quantità venduta, l'età media dei clienti, la deviazione standard, l'età minima e l'età massima di ogni singolo prodotto, utilizzando le funzioni seguenti:

=CONTA.SE('Prodotti acquistati online'!$A$2:$A$1001;Statistiche!A14)
=CONTA.SE('Prodotti acquistati online'!$A$2:$A$1001;Statistiche!A15)
=CONTA.SE('Prodotti acquistati online'!$A$2:$A$1001;Statistiche!A16)
=MEDIA.SE('Prodotti acquistati online'!A2:A1001;Statistiche!A14;'Prodotti acquistati online'!B2:B1001)
=MEDIA.SE('Prodotti acquistati online'!A2:A1001;Statistiche!A15;'Prodotti acquistati online'!B2:B1001)
=MEDIA.SE('Prodotti acquistati online'!A2:A1001;Statistiche!A17;'Prodotti acquistati online'!B2:B1001)
=DB.DEV.ST(db;'Prodotti acquistati online'!$B$1;Criteri!A2:A3)
=DB.DEV.ST(db;'Prodotti acquistati online'!$B$1;Criteri!A4:A5)
=DB.DEV.ST(db;'Prodotti acquistati online'!$B$1;Criteri!A6:A7)
=DB.MIN(db;'Prodotti acquistati online'!$B$1;Criteri!$A$2:$A$3)
=DB.MIN(db;'Prodotti acquistati online'!$B$1;Criteri!$A$8:$A$9)
=DB.MIN(db;'Prodotti acquistati online'!$B$1;Criteri!$A$10:$A$11)
=DB.MAX(db;'Prodotti acquistati online'!$B$1;Criteri!$A$2:$A$3)
=DB.MAX(db;'Prodotti acquistati online'!$B$1;Criteri!$A$8:$A$9)
=DB.MAX(db;'Prodotti acquistati online'!$B$1;Criteri!$A$10:$A$11)

 

L'immagine seguente mostra l'area dei criteri utilizzati nelle funzioni DB:

L'immagine seguente mostra la tabella ed i grafici con i risultati dei calcoli:

Per creare i grafici, basta selezionare con il mouse la colonna prodotti da A13:A16, e successivamente, tenendo premuto il tasto ctrl, selezionate la colonna con i dati da associare al grafico. Con la selezione attiva, cliccate sul menu inserisci e scegliete il tipo di grafico da creare, come mostra l'immagine seguente:

 

Analisi della popolazione di dati  del sito e-commerce (terzo livello)
Adesso potete dettagliare ulteriormente i dati del livello precedente, introducendo una nuova variabile di selezione, il sesso

Per ottenere questo risultato dovete usare le funzioni seguenti:

Maschi
=DB.CONTA.VALORI(db;'Prodotti acquistati online'!$A$1;Criteri!A2:B4)
=DB.CONTA.VALORI(db;'Prodotti acquistati online'!$A$1;Criteri!A6:B7)
=DB.CONTA.VALORI(db;'Prodotti acquistati online'!$A$1;Criteri!A10:B11)
=DB.MEDIA(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$2:$B$3)
=DB.MEDIA(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$6:$B$7)
=DB.MEDIA(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$10:$B$11)
=DB.DEV.ST(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$2:$B$3)
=DB.DEV.ST(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$6:$B$7)
=DB.DEV.ST(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$10:$B$11)
=DB.MIN(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$2:$B$3)
=DB.MIN(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$6:$B$7)
=DB.MIN(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$10:$B$11)
=DB.MAX(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$2:$B$3)
=DB.MAX(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$6:$B$7)
=DB.MAX(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$10:$B$11)

Femmine
=DB.CONTA.VALORI(db;'Prodotti acquistati online'!$A$1;Criteri!A4:B5)
=DB.CONTA.VALORI(db;'Prodotti acquistati online'!$A$1;Criteri!A8:B9)
=DB.CONTA.VALORI(db;'Prodotti acquistati online'!$A$1;Criteri!A12:B13)
=DB.MEDIA(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$4:$B$5)
=DB.MEDIA(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$8:$B$9)
=DB.MEDIA(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$12:$B$13)
=DB.DEV.ST(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$4:$B$5)
=DB.DEV.ST(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$8:$B$9)
=DB.DEV.ST(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$12:$B$13)
=DB.MIN(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$4:$B$5)
=DB.MIN(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$8:$B$9)
=DB.MIN(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$12:$B$13)
=DB.MAX(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$4:$B$5)
=DB.MAX(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$8:$B$9)
=DB.MAX(statistiche.xlsx!db;'Prodotti acquistati online'!$B$1;Criteri!$A$12:$B$13)

L'immagine seguente mostra l'area dei criteri utilizzati nelle funzioni:

L'immagine seguente mostra le tabelle ed i grafici con i risultati dei calcoli:


Come creare istogrammi che permettono di confrontare due serie di dati
Per creare un istogramma che permette di confrontare due serie di dati, cliccate su inserisci e selezionate un grafico di tipo istogramma.

Successivamente selezionate il grafico aggiunto al foglio di lavoro, premete il pulsante destro del mouse e quando appare il menu selezionate il comando Seleziona dati ... 

Nella scheda seleziona origine dati rimuovete eventuali informazioni presenti e cliccate sul pulsante aggiungi, per selezionare la prima serie di dati.

Selezionate il nome da assegnare alla prima serie, poi selezionate i valori corrispondenti ed infine confermate con ok

Ripetete le stesse operazioni per aggiungere la seconda serie.

Per completare, cliccate sul pulsante modifica, e selezionate le etichette da associare alle serie di dati.

Per visualizzare le etichette dati sulle barre del grafico, selezionate un gruppo di barre, premete il pulsante destro del mouse e dal menu selezionate il comando Aggiungi etichette dati.  

 

Analisi della popolazione di dati  del sito e-commerce (quarto livello)

In quest'ultimo livello di analisi utilizzerete le classi di età, per calcolare la media poderata dei prodotti acquistati per fasce d'età. L'analisi verrà fatta per ogni singolo prodotto in modo da avere la maggiore quantità d'informazioni possibili, come mostrano le tabelle dell'immagine seguente. 
 
 
Per filtrare i dati per contare i prodotti venduti e calcolare l'età media e la deviazione standard per fasce d'età e sesso, potete utilizzare le stesse funzioni db usate nei livelli precedenti, in questo caso però nei criteri di selezione dovete aggiungere anche gli intervalli di età da filtrare, come mostra l'immagine seguente.
 
Ad esempio per contare i prodotti A venduti e calcolare l'età media e la deviazione standard dei clienti maschi di età compresa tra i 18 e 25 anni, dovete usare le funzioni seguenti:
=DB.CONTA.VALORI(db;'Prodotti acquistati online'!$A$1;Criteri!$A$16:$D$17)
=DB.MEDIA(db;'Prodotti acquistati online'!$B$1;Criteri!$A$16:$D$17)
=DB.DEV.ST(db;'Prodotti acquistati online'!$B$1;Criteri!$A$16:$D$17)
 
Per il calcolo della media ponderata, relativamente ai tipi di prodotti venduti, alle fasce di età ed al sesso, seguite l'esempio seguente che vi permette di calcolare la percentuale di prodotti di tipo A,  venduti ai clienti maschi, appartenenti alla fascia di età 18-25 anni
 
=B93/$B$98*100
 
 
Come calcolare il centro di una classe
 
Si definisce centro di una classe il punto medio di un intervallo di valori, l'esempio seguente vi mostra come potete calcolare il centro delle classi delle fasce d'età dei clienti che hanno acquistato prodotti dal sito e-commerce.
 
 
Nella prossima lezione continueremo con la statistica e vedremo come analizzare la popolazione di dati del sito e-commerce utilizzando le tabelle di pivot.

Per il download del file excel analisi_dati_sito_ecommerce.xlsx clicca qui.

<< Lezione precedente | Vai alla prima lezione


T U T O R I A L S    S U G G E R I T I


EDUCATIONAL GAMING BOOK (EGB) "H2O"

Nell'era dello SMART LEARNING e di PYTHON i libri non si scrivono, ma si sviluppano, in questo modo chi studia, può sperimentare ed apprendere contemporaneamente; un libro con queste caratteristiche lo possiamo definire un  Educational Gaming Book (EGB).

"H2Oè un EGB che descrive tutte le caratteristiche dell'acqua, la sostanza formata da molecole di H2O, che attraverso il suo ciclo di vita garantisce la sopravvivenza di tutti gli esseri viventi del Pianeta

L'obiettivo dell'EGB è quello di far conoscere ai giovani le proprietà dell'acqua, sotto molti aspetti uniche, per sensibilizzarli a salvaguardare un bene comune raro, indispensabile per la vita


Per il DOWNLOAD di "H2Oclicca qui.


 

Share Button

La geometria della tartaruga: "I Quadrilateri" - Lezione 2

Gino Visciano | Skill Factory - 20/03/2021 18:51:05 | in Tutorials

 

Benvenuti alla seconda lezione di INFORMATEMATICA, l'argomento di questa nuova lezione sono i quadrilateri. Con l'aiuto della tartaruga Pitagora imparerete a disegnare quadrati, rombi, rettangoli e trapezi e a calcolare le loro principali informazioni geometriche

Per iniziare dovete creare il pannello di controllo dove inserire le informazioni che servono alla tartaruga  Pitagora per disegnare il tipo di quadrilatero scelto.

 

COME CREARE IL PANNELLO DI CONTROLLO PER DISEGNARE I QUATRILATERI

Per creare un'interfaccia grafica con Python dovete importare la libreria Tkinter con il comando seguente:

import tkinter as tk

Potete utilizzare l'alias tk per usare tutti i widget e le funzioni contenute all'interno di questa potente libreria grafica.

widget più utilizzati sono: LabelEntry,  Radiobutton,  Checkbutton,  Spinbox,  Listbox,  Button.

Per creare il pannello di controllo che servirà per disegnare i quadrilateri, utilizzeremo i seguenti widgetLabel, Spinbox, Checkbutton, Button.

Potete creare la finestra che conterrà i widget con il comando seguente:

 root = tk.Tk()

Ad esempio, il codice Python seguente vi permette di creare una finestra, larga 320 pixel ed alta 360 pixel, di disattivare il suo ridimensionamento ed impostare il titolo che apparirà in alto a sinistra:

root = tk.Tk()
root.geometry("320x360")
root.resizable(False,False)
root.title("Quadrilateri")

COME AGGIUNGERE I WIDGET ALLA FINESTRA TKINTER

Dopo la creazione della finestra tkinter, per aggiungere i widget che servono, li dovete prima creare e poi successivamente con le funzioni pack() oppure grid() li potete collegare.

La funzione pack() dispone i componenti in modo sequenziale, dall'alto verso il basso, permettendo di allinearli in alto, in basso, a sinistra e a destra, aggiungendo l'argomento side, come mostra l'esempio seguente:

root = Tk()
root.geometry('250x150')
button1 = Button(text="Left")
button1.pack(side = LEFT)
button2 = Button(text="Top")
button2.pack(side = TOP)
button3 = Button(text="Right")
button3.pack(side = RIGHT)
button4 = Button(text="Bottom")
button4.pack(side = BOTTOM)
root.mainloop()

La funzione grid() permette di disporre i componenti all'interno di una griglia, indicando la loro posizione attraverso la riga e la colonna.

L'esempio seguente mostra come potete aggiungere alla finestra root alcuni dei widget che vi servono:

root = tk.Tk()
root.geometry("320x360")
root.resizable(False,False)
root.title("Quadrilateri")

varTipo=tk.StringVar(root)
colore=tk.StringVar(root)
chkbt=tk.IntVar(root)
lbl_tipo=tk.Label(root,text="Tipo quadrilatero")
tipo=tk.Spinbox(root, values=["Quadrato", "Rombo", "Rettangolo", "Trapezio"], textvariable=
varTipo, command=lambda: abilita_disabilita_controlli_pannello_quadrilateri(controlli_a,controlli_b), state="readonly")
lbl_colore=tk.Label(root,text="Colore del quadrilatero")

colore=tk.Spinbox(root,values=("None", "Blue", "Red", "Orange", "Green", "Yellow", "Violet", "Fuchsia", "Pink", "Deepskyblue", "Aqua", "Lightgreen", "Gold", "Peru", "Black", "Gray", "White"], textvariable=
colore, state="readonly")
...

disegna = tk.Button(root, width=19, text ="Disegna",
command = lambda:disegna_quadrilatero(varTipo.get(), int(rotazione.get()), int(lato_A.get()), int(lato_B.get()),colore.get(), int(sezione.get()), chkbt.get()))
coord_diag = tk.Checkbutton(root, text='Coordinate e diagonale',variable=chkbt,onvalue=1,offvalue=0)
...

lbl_tipo.grid(row=0,column=0)
tipo.grid(row=1,column=0)
lbl_colore.grid(row=2,column=0)
colore.grid(row=3,column=0)
disegna.grid(row=12,column=0)
coord_diag.grid(row=13,column=0)
...
root.mainloop()

Il comando root.mainloop() visualizza il  pannello di controllo è si mette in ascolto degli eventi prodotti dagli utenti che usano l'interfaccia grafica.

Principalmente le azioni di un utente che sono associate ad un evento sono due: il click del mouse su un pulsante ed il cambiamento del contenuto di un widget, entrambi gli eventi possono essere associati all'esecuzione di una funzione con l'opzione command, come mostra il codice seguente:

disegna = tk.Button(root, width=19, text ="Disegna", command = lambda:disegna_quadrilatero(tipo.get(),int(rotazione.get()),int(lato_A.get()),int(lato_B.get()),colore.get(),int(sezione.get()),chkbt.get())),

quando l'utente clicca sul button disegna viene eseguita la funzione disegna_quadrilatero(...).
 

COME GESTIRE I VALORI ASSEGNATI AI WIDGET

Per gestire i valori contenuti nei widget di tipo input come ad esempio: Entry,  Radiobutton,  Checkbutton,  Spinbox,  Listbox, dovete associare il componente ad una variabile attraverso le opzioni textvariable o variable, come mostrano gli esempi seguenti:

Esempio 1

varTipo=tk.StringVar(root)
tipo=tk.Spinbox(root, values=["Quadrato", "Rombo", "Rettangolo", "Trapezio"], textvariable=varTipocommand=lambda: abilita_disabilita_controlli_pannello_quadrilateri(controlli_a,controlli_b), state="readonly")

Esempio 2

chkbt=tk.IntVar(root)
coord_diag = tk.Checkbutton(root, text='Coordinate e diagonale',variable=chkbt,onvalue=1,offvalue=0)

Le variabili varTipo e chkbt attraverso le opzioni textvariable e variable sono state associate ai widget  tipo e coord_diag, in questo modo attraverso le due variabili potete leggere o assegnare un valore ai due componenti.

Per assegnare o leggere il valore di una variabile  associata ad un widget dovete utilizzare le funzioni: set(valore) e get():

print(chkbt.get())
varTipo.set("Quadrato")

COME ELIMINARE UN WIDGET DA  UNA FINESTRA TKINTER

Per eliminare un widget da una finestra Tkinter,  dovete utilizzare la funzione pack_forget() se il componente è stato collegato con la funzione pack(), altrimenti dovete usare la funzione grid_forget(), come mostra l'esempio seguente:

tipo.grid_forget()
disegna.grid_forget()

Per eliminare velocemente tutti  i  widget di una finestra, potete aggiungere i loro indirizzi ad una lista ed utilizzare un ciclo for per eliminarli tutti con le funzioni grid_forget() oppure  pack_forget(), come mostra la funzione seguente:

#Elimina controlli pannello quadrilateri
def elimina_controlli_pannello_quadrilateri(controlli_a,controlli_b):
    for i in range(len(controlli_a)):
        controlli_a[i].grid_forget()
    for i in range(len(controlli_b)):
        controlli_b[i].grid_forget()

Le liste controlli_a e controlli_b contengono i riferimenti a tutti i widget del pannello di controllo usato per gestire i quadrilateri:

lbl_tipo.grid(row=0,column=0)
controlli_a.append(lbl_tipo)
tipo.grid(row=1,column=0)
controlli_a.append(tipo)
lbl_colore.grid(row=2,column=0)
controlli_a.append(lbl_colore)
colore.grid(row=3,column=0)
controlli_a.append(colore)
lbl_sezione.grid(row=4,column=0)
controlli_a.append(lbl_sezione)
sezione.grid(row=5,column=0)
controlli_a.append(sezione)
lbl_lato_A.grid(row=6,column=0)
controlli_a.append(lbl_lato_A)
lato_A.grid(row=7,column=0)
controlli_a.append(lato_A)

LA GEOMETRIA DEL QUADRATO E DEL ROMBO
Il quadrato ed il rombo hanno le stesse caratteristiche geometriche, l'unica differenza è che il rombo ha un angolo di rotazione iniziale di 45 gradi.
Per disegnare entrambe le figure basta un solo lato:



La diagonale di queste due figure geometriche si può calcolare applicando il teorema di pitagora.

 

Il codice Python seguente mostra come calcolare la diagonale, il perimetro e l'area, sia del quadrato, sia del rombo:

#Importare la libreria math
import math

#Diagonale
d=round(math.sqrt(math.pow(lato_A,2)+math.pow(lato_A,2)),3)

#Perimetro
p=lato_A*4

#Area
a=math.pow(lato_A,2)

Il codice Python seguente mostra come aggiornare i dati dei widget, nel pannello di controllo:

#Visualizzazione delle informazioni geometriche calcolate nel pannello di controllo
perimetro.config(text=str(p))
area.config(text=str(a))
diagonale.config(text=str(d))

L'angolo alfa adiacente al vertice A, come mostra l'immagine, misura 90°:

quindi la somma degli angoli interni del quadrato e del rombo corrisponde 360°.

#Angolo adiacente al vertice A
val_angolo_A=90
#Calcolo della somma degli angoli interni del quadrato e del rombo
val_angoli_somma=4*val_angolo_A
#Visualizzazione delle informazioni geometriche calcolate nel pannello di controllo
angolo_A.config(text=str(val_angolo_A))
angoli_somma.config(text=str(val_angoli_somma))

 

LA GEOMETRIA DEL RETTTANGOLO

Per disegnare un rettangolo occorrono due lati di lunghezza diversa, vi suggerisco di fare in modo che il lato_A sia quello minore ed il lato_B quello maggiore:

Anche in questo caso per calcolare la diagonale del rettangolo si può usare il teorema di pitagora.

Il codice Python seguente mostra come calcolare la diagonale, il perimetro e l'area, del rettangolo:

#Importare la libreria math
import math

#Diagonale
d=round(math.sqrt(math.pow(lato_A,2)+math.pow(lato_B,2)),3)
#Perimetro
p=(lato_A*2)+(lato_B*2)
#Area
a=lato_A*lato_B
#Visualizzazione delle informazioni geometriche calcolate nel pannello di controllo
perimetro.config(text=str(p))
area.config(text=str(a))
diagonale.config(text=str(d))


Anche nel rettangolo, l'angolo alfa adiacente al vertice misura 90°:

quindi la somma degli angoli interni del quadrato e del rombo corrisponde 360°.

#Angolo adiacente al vertice A
val_angolo_A=90
#Calcolo della somma degli angoli interni del rettangolo
val_angoli_somma=4*val_angolo_A
#Visualizzazione delle informazioni geometriche calcolate nel pannello di controllo
angolo_A.config(text=str(val_angolo_A))
angolo_B.config(text=str(val_angolo_B))
angoli_somma.config(text=str(val_angoli_somma))

 

LA GEOMETRIA DEL TRAPEZIO

Anche per disegnare un trapezio occorrono due lati di lunghezza diversa, vi suggerisco sempre di fare in modo che il lato_A sia quello minore ed il lato_B quello maggiore:

 

Il trapezio disegnato dalla tartaruga Pitagora è di tipo isoscele, con due lati obliqui uguali, come mostra l'immagine seguente:

L'altezza BH corrisponde al lato_A, mentre la base HD del triangolo rettangolo bhd corrisponde al lato_A + AH, dove:

AH=(lato_B-lato_A)/2.

Per calcolare la diagonale del trapezio dovete applicare il teorema di pitagora ai cateti BH che corrisponde al lato_A e HD che corrisponde a lato_A+(lato_B-lato_A)/2, come mostra il codice Python seguente:

#Importare la libreria math
import math

#Diagonale
d=round(math.sqrt(math.pow(lato_A,2)+math.pow(lato_A+(lato_B-lato_A)/2,2)),3)

Per calcolare il perimetro del trapezio dovete prima calcolare la dimensione di uno dei lati obliqui, come mostra la formula seguente:

Il codice Python seguente vi permette di calcolare il perimetro del trapezio:

#Calcolo del lato obliquo
lo=round(math.sqrt(math.pow(lato_A,2)+math.pow((lato_B-lato_A)/2,2)),3)

#Perimetro
p=(lo*2)+lato_A+lato_B

Per calcolare l'area del trapezio dovete applicare la formula seguente:


ll codice Python seguente mostra come calcolare l'area del trapezio:

#Area
a=((lato_A+lato_B)*lato_A)/2

Nel trapezio l'angolo alfa adiacente al vertice A è minore di 90° (acutangolo)perché i lati sono obliqui, ma la somma degli angoli interni continua ad essere uguale a 360°.

Per calcolare l'angolo alfa adiacente al vertice dovete procedere come segue:

1) calcolare il seno dell'angolo alfa applicando la formula:

sin=lato_A/lato_Obliquo.

2) successivamente applicando la funzione inversa arcoseno si può ricavare la misura dell'angolo alfa in radianti.

3) per convertire i radianti in gradi applicare la funzione math.degrees(...).

Il codice Python seguente mostra come ottenere la misura espressa in gradi dell'angolo alfa, adiacente ad A:

#Angolo adiacente al vertice A
val_angolo_A=round(math.degrees(math.asin(lato_A/lo)),2)

L'angolo beta, adiacente al vertice B è maggiore di 90° (ottusangolo), per calcolarlo dovete fare due considerazioni:

1) il triangolo ABH è rettangolo, quindi l'angolo corrispondente al vertice H è di 90°.

2) la somma degli angoli interni di un triangolo è uguale a 180°.

Quindi l'angolo beta può essere calcolato come segue:

Angolo_ABH=(180-angolo_alfa-90)

Angolo beta=Angolo_ABH+90=180-angolo_alfa-90+90=180-angolo_alfa.

Il codice Python seguente mostra come ottenere la misura espressa in gradi dell'angolo alfa e dell'angolo beta, in modo da calcolare la somma degli angoli interni del trapezio:

val_angolo_A=round(math.degrees(math.asin(lato_A/lo)),2)
val_angolo_B=round(180-val_angolo_A,2)
val_angoli_somma=2*val_angolo_A+2*val_angolo_B

Usate  il codice Python seguente per aggiornare le label della finestra dei quadrilateri: 

perimetro.config(text=str(p))
area.config(text=str(a))
diagonale.config(text=str(d))
lato_obliquo.config(text=str(lo))
angolo_A.config(text=str(val_angolo_A))
angolo_B.config(text=str(val_angolo_B))
angoli_somma.config(text=str(val_angoli_somma))

COME DISEGNARE I QUADRILATERI
Per disegnare il quadrilatero scelto dovete prima posizionare la tartaruga Pitagora al centro della sezione del piano cartesiano scelta, la struttura condizionale seguente permette di impostare le coordinate richieste:

#Disegna il quadrilatero al centro del piano cartesiano
if sezione==0:
    cx=0
    cy=0

#Disegna il quadrilatero in alto a sinistra del piano cartesiano
elif sezione==1:
    cx=-150
    cy=150

#Disegna il quadrilatero in alto a destra del piano cartesiano
elif sezione==2:
    cx=150
    cy=150

#Disegna il quadrilatero in basso a sinistra del piano cartesiano
elif sezione==3:
    cx=-150
    cy=-150

#Disegna il quadrilatero in basso a destra del piano cartesiano
else:
   cx=150
   cy=-150

Il codice Python seguente permette di posizionare e ruotare la tartaruga Pitagora, prima che inizia a disegnare il quadrilatero:

turtle.goto(cx,cy)
turtle.setheading(270)
turtle.right(rotazione)

Il valore della variabile rotazione, se diverso da zero, permette di ruotare il quadrilatero del numero di gradi indicato, come mostra l'immagine seguente:

Nell'immagine lo stesso quadrato è stato disegnato più volte aggiungendo ogni volta una differenza di rotazione di 15°.

Nel codice Python allegato a questa lezione,  nelle funzioni seguenti trovate il codice per disegnare i quadrilateri:

1) def disegna_quadrato_rombo(rotazione,lato_A,colore,sezione,coord_diag)
2) def disegna_rettangolo(rotazione,lato_A,lato_B,colore,sezione,coord_diag)
3) def disegna_trapezio(rotazione,lato_A,lato_B,colore,sezione,coord_diag).


COME DISEGNARE LE DIAGONALI  E LE LETTERE DEI VERTICI

Per indicare alla tartaruga Pitagora di disegnare anche la diagonale e le lettere dei vertici dei quadrilateri, dovete selezionare il checbutton coordinate e diagonale.

Per memorizzare le posizioni necessarie per disegnare la diagonale e le lettere dei vertici dei quadrilateri, dovete creare un vettore di oggetti, del tipo seguente:

#Classe per memorizzare le coordinate delle figure geometriche
class MemorizzaCoordinate:
    def __init__(self):
        self.coordinate = []
    def aggiungi(self,coordinata):
        self.coordinate.append(coordinata)
    def estrai(self):
        posizione=self.coordinate[0]
        del self.coordinate[0]
        return posizione
    def resetta(self):
        self.coordinate.clear()

 

 L'esempio seguente mostra come utilizzare la classe per memorizzare le posizioni necessarie e disegnare la diagonale e le lettere:

def disegna_rettangolo(rotazione,lato_A,lato_B,colore,sezione,coord_diag):
    coordinateDiagonale=MemorizzaCoordinate()
    coordinateLettere=MemorizzaCoordinate()

...
for x in range(2):
      turtle.right(angoloRotazione)
      coordinateLettere.aggiungi(turtle.pos())
      turtle.forward(lato_A)
      coordinateDiagonale.aggiungi(turtle.pos())
      coordinateLettere.aggiungi(turtle.pos())
      turtle.right(angoloRotazione)
      turtle.forward(lato_B)
      if colore!="None":
         turtle.color(colore)
         turtle.end_fill()
      if coord_diag==1:
         disegna_diagonale_lettere(cx,cy,coordinateDiagonale,coordinateLettere)

 

COME INSTALLARE ED ESEGUIRE L'APPLICAZIONE PITAGORA (VERSIONE 2)

Per eseguire l'applicazione Pitagora sul vostro computer,  la dovete prima scaricare cliccando qui.

Dopo il download del file pitagora_v2.zip che contiene i file: pitagora_v2.py e tartaruga.png, sul disco c: create la cartella pitagora, ed estraete all'interno i due file.

Per eseguire l'applicazione, da prompt scrivete il comando: python pitagora_v2.py,  come mostra l'immagine seguente:


COME INSTALLARE PYTHON

Se non avete installato Python seguite i passaggi seguenti:
1) collegatevi al sito: https://www.python.org;
2) fate il download del file d'installazione;


3) Successivamente per installare Python, eseguite il file python-x.x.x.exe, dove x.x.x. è la versione che state installando;
4) Durante l'installazione non dimenticate di spuntare la selezione:

altrimenti Python si avvierà solo partendo dalla cartella dove verrà installato.

 


<< Lezione precedente


Per far parte della nostra community registrati su www.skillbook.it.


T U T O R I A L S    S U G G E R I T I


EDUCATIONAL GAMING BOOK (EGB) "H2O"

Nell'era dello SMART LEARNING e di PYTHON i libri non si scrivono, ma si sviluppano, in questo modo chi studia, può sperimentare ed apprendere contemporaneamente; un libro con queste caratteristiche lo possiamo definire un  Educational Gaming Book (EGB).

"H2Oè un EGB che descrive tutte le caratteristiche dell'acqua, la sostanza formata da molecole di H2O, che attraverso il suo ciclo di vita garantisce la sopravvivenza di tutti gli esseri viventi del Pianeta

L'obiettivo dell'EGB è quello di far conoscere ai giovani le proprietà dell'acqua, sotto molti aspetti uniche, per sensibilizzarli a salvaguardare un bene comune raro, indispensabile per la vita


Per il DOWNLOAD di "H2Oclicca qui.

Share Button

La geometria della tartaruga Pitagora: "Il piano cartesiano" - Lezione 1

Gino Visciano | Skill Factory - 16/01/2021 01:17:46 | in Tutorials

Benvenuti alla prima lezione di INFORMATEMATICA, l'obiettivo di questa prima attività è quello d'introdurre il significato di geometria e di piano cartesiano.

Per spiegare questi due concetti astratti ci faremo aiutare da Pitagora, la tartaruga esperta di geometria che vi farà scoprire il mondo dei punti e delle figure geometriche.

Pitagora è una tartaruga che può essere programmata con il linguaggio Python che fa tutto quello che gli insegnate, per queste attività gli abbiamo spiegato la geometria analitica o geometria cartesiana, la scienza matematica che permette di misurare le figure geometriche disegnate su un piano cartesiano.

La parola geometria nasce dalla composizione di due parole geo="terra" e metria="misura" e significa "misurazione della terra", la possiamo definire la scienza matematica che studia la disposizione dei punti nello spazio che formano le figure.

Lo spazio è l'ambiente che vi circonda in cui si trovano tutte le cose che vedete e con cui vi relazionate tutti i giorni. 

Poiché lo spazio che ci circonda è troppo grande, al punto di sembrare infinito, in geometria per misurare le cose si usa uno spazio molto più piccolo: il "piano cartesiano".

Un piano cartesiano lo potete immaginare come una parte di spazio delimitata, di forma quadrata o rettangolare, divisa in quattro parti da due assi perpendicolari (ortogonali), che contiene i punti e le figure da misurare.

Il  nome cartesiano è riferito al  matematico francese Cartesio, nel 1637 fu uno dei primi ad utilizzarlo  per effettuare misure geometriche. 

L'asse verticale, indicato con la lettera Y, si chiama asse delle ordinate, mentre quello orizzontale, indicato con la lettera X, si chiama asse delle ascisse.

Il punto in cui i due assi s'incontrano (intersezione), si chiama origine e si indica con la lettera O.

I valori dell'asse delle ascisse X a sinistra dell'origine O sono negativi (-), quelli a destra invece sono positivi (+).

I valori dell'asse delle ordinate Y al di sopra dell'origine O sono positivi (+), quelli al di sotto invece sono negativi (-).

Per indicare la posizione di qualunque punto nel piano dovete usare sempre una coordinata X ed una Y, come indicato nell'immagine seguente:

Le coordinate che indicano l'origine O  sono (X=0, Y=0).

In questa prima versione la tartaruga Pitagora è stata programmata per indicare le coordinate X ed Y dei punti del piano su cui cliccate usando il puntatore  del mouse, come indica l'immagine seguente:

Per usare il programma dovete installare l'interprete Python, per il download del programma d'installazione cliccate qui.

Per leggere, modificare ed eseguire il programma pitagora_v1.py, vi suggerisco di usare l'IDE (Integrated Development Environment) Visual Studio Code, per il download del programma d'installazione cliccate qui.

Per maggiori informazioni su Python e Visual Studio Code, cliccate qui per scaricare la guida.

 

COME PROGRAMMARE LA TARTARUGA PITAGORA

1) Per utilizzare la tartaruga Pitagora in un programma Python, dovete importare il modulo turtle con il comando:

import turtle

2) Con i comandi seguenti potete impostare la  forma della tartaruga, il colore, le dimensioni e la velocità di spostamento:

turtle.shape("turtle")
turtle.color("green")
turtle.shapesize(stretch_wid=2, stretch_len=2, outline=None)
turtle.speed(3)

3) Per impostare la dimensione della tartaruga potete anche usare il comando:

turtle.turtlesize(2)

4) Le forme di tartarughe possono essere le seguenti: "arrow", "turtle", "circle", "square", "triangle", "classic".

5) Per nascondere la tartaruga Pitagora usate il comando:

turtle.hideturtle()

6) Per mostrare la tartaruga Pitagora usate il comando:

turtle.showturtle()

7) La tartaruga Pitagora può ruotare sia in senso orario, sia in senso antiorario, ad esempio:

# Ruota la tartaruga di 60° in senso orario
turtle.rigth(60)

# Ruota la tartaruga di 60° in senso antiorario
turtle.left(60)

Il comando seguente vi permette d'impostare la direzione iniziale della tartaruga Pitagora:

turtle.setheading(90)

8) La tartaruga Pitagora quando si muove sul piano può disegnare, i comandi seguenti vi permettono di impostare lo stato della penna:

# Non disegna
turtle.penup()

# Disegna
turtle.pendown()

# Imposta il colore della penna
turtle.pencolor("black")

# Imposta lo spessore della punta della penna
turtle.pensize(10)

Nell'esempio seguente la tartaruga Pitagora disegna un segmento di colore rosso:

import turtle
turtle.shape("turtle")
turtle.turtlesize(2)
turtle.left(60)
turtle.pencolor("red")
turtle.pensize(5)

# Sposta la tartaruga Pitagora in avanti alla posizione 100
turtle.forward(100)
# Si mette in ascolto per verificare se l'utente esegue operazioni
turtle.mainloop()

9) I comandi seguenti permettono di muovere la tartaruga Pitagora:

# Sposta la tartaruga in avanti della distanza indicata
turtle.forward(100)

# Sposta la tartaruga indietro della distanza indicata
turtle.back(50)

# Sposta la tartaruga alle coordinate X,Y indicate
turtle.goto(-100,50)

# Sposta la tartaruga a caso nella posizione (X=0, Y=0)
turtle.home()

10) La tartaruga Pitagora, può scrivere nella posizione del piano in cui si trova, con il comando seguente:

turtle.write('La geometria della tartaruga Pitagora',align='center',font=("Garamond", 12, "normal"))

Le informazioni che dovete fornire al comando sono le seguenti:

a) Testo da scrivere
b) Tipo di allineamento: "center", "left", "right"
c) Tipo di carattere di stampa, ad esempio: "Ariale"
d) Dimensione del testo
e) Aspetto: "normal", "italic", "bold"

11) Per disegnare un punto nella posizione del piano in cui si trova la tartaruga Pitagora, usare il comando:

turtle.dot(10,colore)

12) Per associare una funzione Python al  click del mouse usare il comando seguente:

# Esegue la funzione evento_mouse_click quando si clicca con il mouse
turtle.onscreenclick(evento_mouse_click)

13) Per associare una funzione Python ad un tasto premuto usare il comando seguente:

turtle.onkey(undo,"space")
# Ascolta quando viene premuto lo spazio ed esegue la funzione undo

turtle.listen()

COME VISUALIZZARE O COPIARE IL CODICE PYTHON DEL PROGRAMMA PITAGORA

Per visualizzare o copiare il codice Python del programma PITAGORAcliccate qui
Dopo la visualizzazione del codice Python, lo potete selezionare e copiare.
Se incollate il codice Python copiato in un nuovo file creato con Visual Studio Code lo potete salvare con il nome python_v1.py ed eseguire.

 

COME FARE IL DOWNLOAD DEL PROGRAMMA PITAGORA

1) Per eseguire il programma PITAGORA vi serve il file  pitagora_v1.py, per fare il download cliccate qui;
2) Dopo il download estrate dallo zip il file pitagora_v1.py;

 

COME ESEGUIRE IL PROGRAMMA PITAGORA

1) Se state lavorando con Windows  aprite esplora risorse, portatevi sotto la cartella dove si trova il file pitagora_v1.py ed eseguitelo con il doppio click;  
2) Per eseguire il programma da prompt dei comandi, portatevi sotto la cartella dove si trova il file pitagora_v1.py ed scrivete il comando:

python pitagora_v1.py

3) Per eseguire il programma da Visual Studio Code, aprite il file pitagora_v1.py premete il tasto desto del mouse e selezionate il comando Run Python File in Terminal:

 

 

COME DISEGNARE I PUNTI SUL PIANO CARTESIANO

Dopo l'avvio del programma, per disegnare i punti sul piano cartesiano, cliccate con il mouse in un punto qualsiasi, la tartaruga Pitagora disegnarà il punto e le sue coordinate nella posizione indicata.

Arrivederci alla prossima lezione!


Lezione successiva >> 


Per far parte della nostra community registrati su www.skillbook.it.


T U T O R I A L S    S U G G E R I T I


EDUCATIONAL GAMING BOOK (EGB) "H2O"

Nell'era dello SMART LEARNING e di PYTHON i libri non si scrivono, ma si sviluppano, in questo modo chi studia, può sperimentare ed apprendere contemporaneamente; un libro con queste caratteristiche lo possiamo definire un  Educational Gaming Book (EGB).

"H2Oè un EGB che descrive tutte le caratteristiche dell'acqua, la sostanza formata da molecole di H2O, che attraverso il suo ciclo di vita garantisce la sopravvivenza di tutti gli esseri viventi del Pianeta

L'obiettivo dell'EGB è quello di far conoscere ai giovani le proprietà dell'acqua, sotto molti aspetti uniche, per sensibilizzarli a salvaguardare un bene comune raro, indispensabile per la vita


Per il DOWNLOAD di "H2Oclicca qui.

Share Button

Competenze per programmare

Gino Visciano | Skill Factory - 28/11/2020 19:47:49 | in Tutorials

La PLAYLIST "Competenze per programmare" è  una raccolta di lezioni pubblicate sul canale YOUTUBE  "Skill Factory channel"  rivolte ai giovani che devono acquisire le competenze fondamentali  per imparare a programmare.  Clicca qui per accedere alla PLAYLIST.

La PLAYLIST , di volta in volta, si arricchirà di nuove lezioni con nuovi contenuti che vi permetteranno di conoscere i linguaggi di programmazione più utilizzati dai programmatori che lavorono nelle aziende IT.

Per ricevere in tempo reale le notifiche delle nuove lezioni pubblicate, cliccate sul pulsante seguente per iscrivervi al canale.  Attenzione durante l'iscrizione non dimenticate di cliccare sulla campanella per richiedere l'invio delle notifiche dei video pubblicati.

In questa pagina verranno pubblicati tutti i programmi sviluppati durante le lezioni in modo da poterli scaricare e provare.
(Per motivi di sicurezza i programmi hanno tutti l'estensione txt, per poterli eseguire li dovete salvare e rinominare con l'estensione giusta.)


RISORSE PALYLIST "COMPETENZE PER PROGRAMMARE"

Contatore JavaScript
Contatore Python
Semaforo JavaScript
Semaforo bis JavaScript
Semaforo Python
Intervalli JavaScript
Condizioni JavaScript
Condizioni Python
Cicli nidificati JavaScript
Cicli nidificati Python
Vettore JavaScript
Vettore Python
Matrice JavaScript
Matrice Python
Tabellina JavaScript
Tabellina Python
Laboratorio_uno JavaScript
Laboratorio_uno Python

Laboratorio_due JavaScript
Laboratorio_due Python

 

Share Button

TypeScript - Lezione 7: Paradigma Object Oriented (seconda parte)

Gino Visciano | Skill Factory - 07/08/2020 22:54:12 | in Tutorials

Nella lezione precedente abbiamo introdotto il "Paradigma Object Oriented", descrivendo le seguenti proprietà di programmazione:

1) Incapsulamento;
2) Ereditarietà;
3) Polimorfismo dei metodi.

In questa lezione completiamo le proprietà di programmazione parlando di "Polimorfismo degli oggetti", la proprietà che ci permette di sfruttare le potenzialità offerte dall'Upcasting, successivamente vediamo le proprietà architetturali per creare applicazioni riusabili , scalabili e manutenibili.  

POLIMORFISMO DEGLI OGGETTI

Gli oggetti sono Polimorfi se sono simili, due oggetti possono diventare simili per ereditarietà oppure se implementano la stessa interfaccia.

Il Diagramma di classe seguente descrive un esempio di polimorfismo per erditarietà:

La classe Dirigente è la più specializzata, perché contiene maggiori responsabilità e caratteristiche, quindi è più dettagliata, mentre la classe Object è la più generica.

Tutti gli oggetti istanziati con uno dei tipi indicati nel diagramma sono simili, perché appartengono alla stessa gerarchia di ereditarietà.

Quando gli oggetti sono simili è possibile applicare l'upcasting, che permette di  assegnare ad una variabile di tipo  più generico il riferimento di un oggetto più dettagliato, come mostra l'esempio seguente:

var persona:Persona; // Variabile più generica di tipo Persona
persona=new Dipendente() // Upcasting. Il riferimento dell'oggetto di tipo Dipendente, più dettagliato, viene assegnato ad una variabile più generica di tpo Persona

L'Upcasting è utile  perché con questa tecnica è possibile passare alla stesso metodo oggetti di tipo diverso, purché simili tra loro, come mostra l'esempio seguente:

Esempio 1

 
class Persona{
    private id:number;
    private nome:string;
    private cognome:string;
    private dataDiNascita:Date;
    private luogoDiNascita:string;
    private sesso:string;
    public setId(id:number):void{
        this.id=id;
    }
    public getId():number{
        return this.id;
    }
    public setNome(nome:string):void{
        this.nome=nome;
    }
    public getNome():string{
        return this.nome;
    }
    public setCognome(cognome:string):void{
        this.cognome=cognome;
    }
    public getCognome(){
        return this.cognome;
    }
    public setDataDiNascita(dataDiNascita:Date):void{
        this.dataDiNascita=dataDiNascita;
    }
    public getDataDiNascita():Date{
        return this.dataDiNascita;
    }
    public setLuogDiNascita(luogoDiNascita:string):void{
        this.luogoDiNascita=luogoDiNascita;
    }
    public getLuogoDiNascita():string{
        return this.luogoDiNascita;
    }
    public setSesso(sesso:string):void{
        this.sesso=sesso;
    }
    public getSesso():string{
        return this.sesso;
    }
    public toString():string{
        let optionsIntl.DateTimeFormatOptions = {
            day: "numeric"month: "numeric"year: "numeric"
        };
 
           return this.id+","+this.nome+","+this.cognome+","+this.dataDiNascita.toLocaleDateString("en-GB"options)+","+this.luogoDiNascita+","+this.sesso;
    }
    public equals(obj:Object):boolean{
        if (this.toString()!=obj.toString()){
            return false;
        }
        return true;
    }
        // Sovraccarico del costruttore
        public constructor();
        public constructor(id:number,nome:string,cognome:string,dataDinascita:Date,luogoDiNascita:string,sesso:string);
        public constructor(id?:number,nome?:string,cognome?:string,dataDinascita?:Date,luogoDiNascita?:string,sesso?:string){
            this.id=id;
            this.nome=nome;
            this.cognome=cognome;
            this.dataDiNascita=dataDinascita;
            this.luogoDiNascita=luogoDiNascita;
            this.sesso=sesso;
        }    
}
 
class Dipendente extends Persona {
    private ruolo:string;
    private stipendio:number;
    public setRuolo(ruolo:string):void{
        this.ruolo=ruolo;
    }
    public getRuolo():string{
        return this.ruolo;
    }
    public setStipendio(stipendio:number):void{
        this.stipendio=stipendio;
    }
    public getStipendio():number{
        return this.stipendio;
    }
    public toString():string{
        return super.toString()+","+this.ruolo+","+this.stipendio;
    }
    public equals(obj:Object):boolean{
        if (this.toString()!=obj.toString()){
            return false;
        }
        return true;
    }
            // Sovraccarico del costruttore
            public constructor();
            public constructor(id:number,nome:string,cognome:string,dataDinascita:Date,luogoDiNascita:string,sesso:string,ruolo:string,stipendo:number);
            public constructor(id?:number,nome?:string,cognome?:string,dataDinascita?:Date,luogoDiNascita?:string,sesso?:string,ruolo?:string,stipendo?:number){
                super(id,nome,cognome,dataDinascita,luogoDiNascita,sesso); 
                this.ruolo=ruolo;
                this.stipendio=stipendo;
            }      
}
class Vista {
public stampa(persona:Persona){
    console.log(persona.toString())
    }    
public stampaScheda(persona:Persona){
    let optionsIntl.DateTimeFormatOptions = {
        day: "numeric"month: "numeric"year: "numeric"
    };
    console.log("Id:"+persona.getId());
    console.log("Nome:"+persona.getNome());
    console.log("Cognome:"+persona.getCognome());
    console.log("Data di nascita:"+persona.getDataDiNascita().toLocaleDateString("en-GB"options));
    console.log("Luogo di nascita:"+persona.getLuogoDiNascita());
    console.log("Sesso:"+persona.getSesso());
    // Se la variabile persona è un riferimento di tipo dipendente visualizza anche ruolo e stipendio
    if(persona instanceof Dipendente){
        console.log("Ruolo:"+persona.getRuolo());
        console.log("Stipendio:"+persona.getStipendio());
    }
    }
}
// Istanza di un oggetto di tipo Vista (view), per stampare gli oggetti simili di tipo Persona e Dipendente (model) 
var vista=new Vista();
// Istanzio due oggetti di tipo Persona (model)
var personaUno=new Persona();
var personaDue=new Persona(2,"Carla","Verdi",new Date("10/05/1992"),"Milano","F");
// Istanzio due oggetti di tipo Dipendente (model)
var dipendenteUno=new Dipendente();
var dipendenteDue=new Dipendente(4,"Paolo","Formisano",new Date("09/02/1970"),"Potenza","M","Commerciale",1800.00);
personaUno.setId(1);
personaUno.setNome("Roberta");
personaUno.setCognome("Bianchi");
personaUno.setDataDiNascita(new Date("09/07/2000"));
personaUno.setLuogDiNascita("Firenze");
personaUno.setSesso("F");
dipendenteUno.setId(3);
dipendenteUno.setNome("Michele");
dipendenteUno.setCognome("Rossi");
dipendenteUno.setDataDiNascita(new Date("08/03/1980"));
dipendenteUno.setLuogDiNascita("Torino");
dipendenteUno.setSesso("M");
dipendenteUno.setRuolo("Project Managaer");
dipendenteUno.setStipendio(1500.00);
console.log("------ Persone stampa orizzontale ------")
vista.stampa(personaUno);
console.log("---------------------------------------")
vista.stampa(personaDue);
console.log("\n------ Dipendenti stampa orizzontale ------")
vista.stampa(dipendenteUno);
console.log("--------------------------------------")
vista.stampa(dipendenteDue);
console.log("\n------ Persone stampa scheda ------")
vista.stampaScheda(personaUno);
console.log("--------------------------------")
vista.stampaScheda(personaDue);
console.log("\n------ Dipendenti stampa scheda ------")
vista.stampaScheda(dipendenteUno);
console.log("--------------------------------")
vista.stampaScheda(dipendenteDue);
 
---------------------------------------------------------------------------------------

------ Persone stampa orizzontale ------
1,Roberta,Bianchi,9/7/2000,Firenze,F
---------------------------------------
2,Carla,Verdi,10/5/1992,Milano,F

------ Dipendenti stampa orizzontale ------
3,Michele,Rossi,8/3/1980,Torino,M,Project Managaer,1500
--------------------------------------
4,Paolo,Formisano,9/2/1970,Potenza,M,Commerciale,1800

------ Persone stampa scheda ------
Id:1
Nome:Roberta
Cognome:Bianchi
Data di nascita:9/7/2000
Luogo di nascita:Firenze
Sesso:F
--------------------------------
Id:2
Nome:Carla
Cognome:Verdi
Data di nascita:10/5/1992
Luogo di nascita:Milano
Sesso:F

------ Dipendenti stampa scheda ------
Id:3
Nome:Michele
Cognome:Rossi
Data di nascita:8/3/1980
Luogo di nascita:Torino
Sesso:M
Ruolo:Project Managaer
Stipendio:1500
--------------------------------
Id:4
Nome:Paolo
Cognome:Formisano
Data di nascita:9/2/1970
Luogo di nascita:Potenza
Sesso:M
Ruolo:Commerciale
Stipendio:1800

 

 

Gli oggetti possono diventare simili, anche se implementano la stessa interfaccia, iDiagramma di classe seguente descrive un esempio di polimorfismo per interfaccia:
 

In questo caso l'Upcasting si può applicare utilizzando come tipo l'interfaccia, come mostra l'esempio seguente:

var cerchio:IFiguraGeometrica;
var rettangolo:IFiguraGeometrica;
cerchio=new Cerchio();
rettangolo=new Rettangolo(); 

Esempio 2

//geometria.ts
interface IFiguraGeometrica{
    getTipoFigura():string;
    getPerimetro():number;
    getArea():number;
}
 
class Cerchio implements IFiguraGeometrica{
    public constructor(private raggio:number){}
    public getTipoFigura():string{
        return "Cerchio";
    }
    public getPerimetro(): number {
        return 2*Math.PI*this.raggio;
    }
    public getArea(): number {
        return Math.pow(this.raggio,2)*Math.PI;
    }
}
 
class Quadrato implements IFiguraGeometrica{
    public constructor(private latoA:number){}
    public getTipoFigura():string{
        return "Quadrato";
    }
    public getPerimetro(): number {
        return 4*this.latoA;
    }
    public getArea(): number {
        return Math.pow(this.latoA,2);
    }
}
 
class Rettangolo implements IFiguraGeometrica{
    public constructor(private latoA:number,private latoB:number){}
    public getTipoFigura():string{
        return "Rettangolo";
    }
    public getPerimetro(): number {
        return (2*this.latoA)+(2*this.latoB);
    }
    public getArea(): number {
        return this.latoA*this.latoB;
    }
}
 
class Triangolo implements IFiguraGeometrica{
    public constructor(private latoA:number,private latoB:number,private latoC:number){}
    public getTipoFigura():string{
        return "Triangolo";
    }
    public getPerimetro(): number {
        return this.latoA+this.latoB+this.latoC;
    }
    public getArea(): number {
        let sp=this.getPerimetro()/2;
        let area=Math.sqrt(sp*(sp-this.latoA)*(sp-this.latoB)*(sp-this.latoC))
        return area;
    }
}
class Geometria {
    private figureGeometriche:IFiguraGeometrica[]=[]
    public add(figuraGeometrica:IFiguraGeometrica):void{
        this.figureGeometriche.push(figuraGeometrica);
    }
    public stampa(){
        this.figureGeometriche.forEach(figuraGeometrica =>{
            console.log("Tipo figura:"+figuraGeometrica.getTipoFigura());
            console.log("Perimetro  :"+figuraGeometrica.getPerimetro());
            console.log("Area       :"+figuraGeometrica.getArea());
        })
    }
}
class Main{
public static main():void{
    var cerchio:IFiguraGeometrica=new Cerchio(10);
    var quadrato:IFiguraGeometrica=new Quadrato(20);
    var rettangolo:IFiguraGeometrica=new Rettangolo(10,20);
    var triangolo:IFiguraGeometrica=new Triangolo(5,10,10);
    var geometria:Geometria=new Geometria();
    geometria.add(cerchio);
    geometria.add(quadrato);
    geometria.add(rettangolo);
    geometria.add(triangolo);
    geometria.stampa();
}    
}    
//Main
Main.main();
-----------------------------------------------------------------------

Tipo figura:Cerchio
Perimetro  :62.83185307179586
Area       :314.1592653589793
Tipo figura:Quadrato
Perimetro  :80
Area       :400
Tipo figura:Rettangolo
Perimetro  :60
Area       :200
Tipo figura:Triangolo
Perimetro  :25
Area       :24.206145913796355
 

 

PROPRIETA' ARCHITETTURALI DEL PARADIGMA OBJECT ORIENTED

Le proprietà Architetturali del paradigma object oriented caratterizzano l'organizzazione strutturale di un'applicazione software
Le proprietà architetturali incidono sulla qualità  delle applicazioni, come ad esempio le prestazioni, la scalabilità, la disponibilità la 
riusabilità e la modificabilità.

COESIONE

Le classi sono Coese se sono disegnate per offrire una soluzione specifica, come ad esempio avviene per i servizi che mettono a disposizione funzioni che  risolvono problemi di un particolare dominio applicativo.

Il pattern MVC (Model View Controller), favorisce il disegno di classi coese,  perché permette di distinguere le classi in base al ruolo che devono avere all'interno dell'applicazione.

Se più classi hanno responsabilità (metodi) e caratteristiche (attributi) comuni, probabilmente bisogna creare una nuova classe che le contiene tutte.

Un bravo programmatore ad oggetti, quando sviluppa un'applicazione, rispetta sempre questa regola:

"Metti il codice dove gli altri si aspettano di trovarlo" .

Le classi di tipo model sono coese, perché tutti i loro metodi interni servono per gestire gli attributi privati, non accessibili ai metodi di altre classi. 

 
class Persona{
    private id:number;
    private nome:string;
    private cognome:string;
    private dataDiNascita:Date;
    private luogoDiNascita:string;
    private sesso:string;
    public setId(id:number):void{
        this.id=id;
    }
    public getId():number{
        return this.id;
    }
    public setNome(nome:string):void{
        this.nome=nome;
    }
    public getNome():string{
        return this.nome;
    }
    public setCognome(cognome:string):void{
        this.cognome=cognome;
    }
    public getCognome(){
        return this.cognome;
    }
    public setDataDiNascita(dataDiNascita:Date):void{
        this.dataDiNascita=dataDiNascita;
    }
    public getDataDiNascita():Date{
        return this.dataDiNascita;
    }
    public setLuogDiNascita(luogoDiNascita:string):void{
        this.luogoDiNascita=luogoDiNascita;
    }
    public getLuogoDiNascita():string{
        return this.luogoDiNascita;
    }
    public setSesso(sesso:string):void{
        this.sesso=sesso;
    }
    public getSesso():string{
        return this.sesso;
    }
    public toString():string{
        let optionsIntl.DateTimeFormatOptions = {
            day: "numeric"month: "numeric"year: "numeric"
        };
 
           return this.id+","+this.nome+","+this.cognome+","+this.dataDiNascita.toLocaleDateString("en-GB"options)+","+this.luogoDiNascita+","+this.sesso;
    }
    public equals(obj:Object):boolean{
        if (this.toString()!=obj.toString()){
            return false;
        }
        return true;
    }
        // Sovraccarico del costruttore
        public constructor();
        public constructor(id:number,nome:string,cognome:string,dataDinascita:Date,luogoDiNascita:string,sesso:string);
        public constructor(id?:number,nome?:string,cognome?:string,dataDinascita?:Date,luogoDiNascita?:string,sesso?:string){
            this.id=id;
            this.nome=nome;
            this.cognome=cognome;
            this.dataDiNascita=dataDinascita;
            this.luogoDiNascita=luogoDiNascita;
            this.sesso=sesso;
        }    
}
 

Un altro esempio di classi coese, sono quelle di tipo CRUD, specializzate per gestire la persistenza delle classi di tipo model.

Una classe CRUD può essere considerata un servizio.

 
 
interface IPersonaCRUD{
    inserisci(persona:Persona):boolean;
    modifica(indice:number,persona:Persona):boolean;
    cancella(indice:number):boolean;
    leggi(indice:number):Persona;
    leggi():Persona[];
}
 
export class PersonaCRUD implements IPersonaCRUD{
    private persone:Persona[];
    inserisci(personaPersona): boolean {
       this.persone.push(persona);
       return true;
    }
    modifica(indice:numberpersonaPersona): boolean {
        this.persone[indice]=persona;
        return true;
    }
    cancella(indicenumber): boolean {
        this.persone.splice(indice,1);
        return true;  
    }
    // Overload (polimorfismo dei metodi)
    leggi(indicenumber): Persona;
    leggi(): Persona[];
    leggi(indice?: number): Persona | Persona[] {
        if (arguments.length==1){
            return this.persone[indice];
        } else{
        return this.persone;
        }
    }
 
}
 

Anche la classe di utilità Math è coesa, perché contiene tutte le funzionalità richieste per gestire operazioni di matematica, di seguito elenchiamo quelle più importanti:

// matematica.ts
class OperazioniMatematiche{
    public static main():void{
        var numeri:number[]=[10,30,20,5,40];
        console.log("Pi greco:"+Math.PI);
        console.log("Arrotonda per eccesso:"+Math.ceil(Math.PI));
        console.log("Arrotonda per difetto:"+Math.round(Math.PI));
        console.log("Valore assoluto di -10:"+Math.abs(-10));
        console.log("Potenza di 5^2:"+Math.pow(5,2));
        console.log("Radice quadrata di 25:"+Math.sqrt(25));
        console.log("Valore massimo di :"+numeri+" -> "+Math.max(10,30,20,5,40));
        console.log("Valore minimo di :"+numeri+" -> "+Math.min(10,30,20,5,40));
        console.log("Valore casuale da 1 a 100:"+Math.ceil(Math.random()*100));
    }
}
OperazioniMatematiche.main();
-----------------------------------------------------------------------------------
Pi greco:3.141592653589793
Arrotonda per eccesso:4
Arrotonda per difetto:3
Valore assoluto di -10:10
Potenza di 5^2:25
Radice quadrata di 25:5
Valore massimo di :10,30,20,5,40 -> 40
Valore minimo di :10,30,20,5,40 -> 5
Valore casuale da 1 a 100:63
 

DISACCOPPIAMENTO

Per Accoppiamento s'intendono i legami (relazioni di dipendenza)  esistenti tra classi diverse della stessa applicazione.
Minore è il livello di accoppiamento tra le classi e maggiore è la manutenibilità del software, perché oltre a favorire la leggibilità del codice, eventuali modifiche ad una classe hanno basse ripercussioni sulle altre classi.

Si crea un accoppiamento forte tra due classi tutte le volte che un metodo di una classe Client, istanzia un oggetto per usare i metodi oppure gli attributi pubblici di una classe Server, come mostra il diagramma seguente:

 L'accoppiamento è debole se il metodo della classe Client riceve come argomento il riferimento della classe Server senza istanziare un oggetto di tipo Server

Esempio 3

Una classe Persona ha un attributo di tipo Indirizzo, composto dal nome della strada, il cap, la città e la provincia.
Per creare l'attributo di tipo Indirizzo nella classe Persona utilizziamo la classe seguente:

 
//indirizzo.ts
export class Indirizzo {
    private nomeStrada:string;
    private cap:string;
    private citta:string
    private provincia:string;
    public getNomeStrada():string{
        return this.nomeStrada;
    }
    public setNome(nomeStrada:string):void{
        this.nomeStrada=nomeStrada;
    }
    public getCap():string{
        return this.cap;
    }
    public setCap(cap:string):void{
        this.cap=cap;
    }
    public getCitta():string{
        return this.citta;
    }
    public setCitta(citta:string):void{
        this.citta=citta;
    }    
    public getProvincia():string{
        return this.provincia;
    }
    public setProvincia(provincia:string):void{
        this.provincia=provincia;
    }    
    public toString():string{
        return this.nomeStrada+","+this.cap+","+this.citta+","+this.provincia;
    }
    public constructor();
    public constructor(nomeStrada:string,cap:string,citta:string,provincia:string);
    public constructor(nomeStrada?:string,cap?:string,citta?:string,provincia?:string){
        this.nomeStrada=nomeStrada;
        this.cap=cap;
        this.citta=citta;
        this.provincia=provincia;    
    }
}
 

 

In questo esempio per creare l'attributo di tipo Indirizzo nella classe Persona, stiamo creando un accoppiamento tra la due classi.

A seconda di come viene impostato il metodo setIndirizzo ed il costruttore della classe Persona, l'accoppiamento diventa alto (forte) oppure basso (debole).

A) Accoppiamento alto

 
//persona_con_indirizzo_accoppiamento_alto.ts
import {Indirizzofrom './indirizzo'
export class Persona{
    private id:number;
    private nome:string;
    private cognome:string;
    private dataDiNascita:Date;
    private luogoDiNascita:string;
    private sesso:string;
    private codiceFiscale:string;
    private indirizzo:Indirizzo=new Indirizzo();
    public setId(id:number):void{
        this.id=id;
    }
    public getId():number{
        return this.id;
    }
    public setNome(nome:string):void{
        this.nome=nome;
    }
    public getNome():string{
        return this.nome;
    }
    public setCognome(cognome:string):void{
        this.cognome=cognome;
    }
    public getCognome(){
        return this.cognome;
    }
    public setDataDiNascita(dataDiNascita:Date):void{
        this.dataDiNascita=dataDiNascita;
    }
    public getDataDiNascita():Date{
        return this.dataDiNascita;
    }
    public setLuogDiNascita(luogoDiNascita:string):void{
        this.luogoDiNascita=luogoDiNascita;
    }
    public getluogoDiNascita():string{
        return this.luogoDiNascita;
    }
    public setSesso(sesso:string):void{
        this.sesso=sesso;
    }
    public getSesso():string{
        return this.sesso;
    }
    public getCodiceFiscale():string{
        return this.codiceFiscale;
    }
    public setCodiceFiscale(codiceFiscale:string):void{
        this.sesso=codiceFiscale;
    }
    public setIndirizzo(nomeStrada:string,cap:string,citta:string,provincia:string){
        this.indirizzo.setNomeStrada(nomeStrada);
        this.indirizzo.setCap(cap);
        this.indirizzo.setCitta(citta);
        this.indirizzo.setProvincia(provincia);
    }
    public getIndirizzo():Indirizzo{
           return this.indirizzo;
    }
    public toString():string{
        let optionsIntl.DateTimeFormatOptions = {
            day: "numeric"month: "numeric"year: "numeric"
        };
 
           return this.id+","+this.nome+","+this.cognome+","+this.dataDiNascita.toLocaleDateString("en-GB"options)+","+this.luogoDiNascita+","+this.sesso+","+this.codiceFiscale+","+this.indirizzo;
    }
    public equals(obj:Object):boolean{
        if (this.toString()!=obj.toString()){
            return false;
        }
        return true;
    }
        // Sovraccarico del costruttore
        public constructor();
        public constructor(id:number,nome:string,cognome:string,dataDinascita:Date,luogoDiNascita:string,sesso:string,codiceFiscale:string,nomeStrada:string,cap:string,citta:string,provincia:string);
        public constructor(id?:number,nome?:string,cognome?:string,dataDinascita?:Date,luogoDiNascita?:string,sesso?:string,codiceFiscale?:string,nomeStrada?:string,cap?:string,citta?:string,provincia?:string){
            if(arguments.length>0){
                this.id=id;
                this.nome=nome;
                this.cognome=cognome;
                this.dataDiNascita=dataDinascita;
                this.luogoDiNascita=luogoDiNascita;
                this.sesso=sesso;
                this.codiceFiscale=codiceFiscale;
                this.indirizzo.setNomeStrada(nomeStrada);
                this.indirizzo.setCap(cap);
                this.indirizzo.setCitta(citta);
                this.indirizzo.setProvincia(provincia);
                    }
        }    
}
 

In questo caso l'accoppiamento tra la classe Persona e la classe Indirizzo è alto, perché se si modificano gli attributi della classe Indirizzo, necessariamente bisogna modificare anche gli argomenti del metodo setIndirizzo ed del costruttore della classe Persona. 

private indirizzo:Indirizzo=new Indirizzo(); 
...
    public setIndirizzo(nomeStrada:string,cap:string,citta:string,provincia:string){
        this.indirizzo.setNomeStrada(nomeStrada);
        this.indirizzo.setCap(cap);
        this.indirizzo.setCitta(citta);
        this.indirizzo.setProvincia(provincia);
    }
...
public constructor(id?:number,nome?:string,cognome?:string,dataDinascita?:Date,luogoDiNascita?:string,sesso?:string,codiceFiscale?:string,nomeStrada?:string,cap?:string,citta?:string,provincia?:string){
            if(arguments.length>0){
                this.id=id;
                this.nome=nome;
                this.cognome=cognome;
                this.dataDiNascita=dataDinascita;
                this.luogoDiNascita=luogoDiNascita;
                this.sesso=sesso;
                this.codiceFiscale=codiceFiscale;
                this.indirizzo.setNomeStrada(nomeStrada);
                this.indirizzo.setCap(cap);
                this.indirizzo.setCitta(citta);
                this.indirizzo.setProvincia(provincia);
                    }
}    

 

B) Accoppiamento basso

 
//persona_con_indirizzo_accoppiamento_basso.ts
import {Indirizzofrom './indirizzo'
export class Persona{
    private id:number;
    private nome:string;
    private cognome:string;
    private dataDiNascita:Date;
    private luogoDiNascita:string;
    private sesso:string;
    private codiceFiscale:string;
    private indirizzo:Indirizzo;
    public setId(id:number):void{
        this.id=id;
    }
    public getId():number{
        return this.id;
    }
    public setNome(nome:string):void{
        this.nome=nome;
    }
    public getNome():string{
        return this.nome;
    }
    public setCognome(cognome:string):void{
        this.cognome=cognome;
    }
    public getCognome(){
        return this.cognome;
    }
    public setDataDiNascita(dataDiNascita:Date):void{
        this.dataDiNascita=dataDiNascita;
    }
    public getDataDiNascita():Date{
        return this.dataDiNascita;
    }
    public setLuogDiNascita(luogoDiNascita:string):void{
        this.luogoDiNascita=luogoDiNascita;
    }
    public getluogoDiNascita():string{
        return this.luogoDiNascita;
    }
    public setSesso(sesso:string):void{
        this.sesso=sesso;
    }
    public getSesso():string{
        return this.sesso;
    }
    public getCodiceFiscale():string{
        return this.codiceFiscale;
    }
    public setCodiceFiscale(codiceFiscale:string):void{
        this.sesso=codiceFiscale;
    }
    public setIndirizzo(indirizzo:Indirizzo){
        this.indirizzo=indirizzo;
    }
    public getIndirizzo():Indirizzo{
           return this.indirizzo;
    }
    public toString():string{
        let optionsIntl.DateTimeFormatOptions = {
            day: "numeric"month: "numeric"year: "numeric"
        };
 
           return this.id+","+this.nome+","+this.cognome+","+this.dataDiNascita.toLocaleDateString("en-GB"options)+","+this.luogoDiNascita+","+this.sesso+","+this.codiceFiscale+","+this.indirizzo;
    }
    public equals(obj:Object):boolean{
        if (this.toString()!=obj.toString()){
            return false;
        }
        return true;
    }
        // Sovraccarico del costruttore
        public constructor();
        public constructor(id:number,nome:string,cognome:string,dataDinascita:Date,luogoDiNascita:string,sesso:string,codiceFiscale:string,indirizzo:Indirizzo);
        public constructor(id?:number,nome?:string,cognome?:string,dataDinascita?:Date,luogoDiNascita?:string,sesso?:string,codiceFiscale?:string,indirizzo?:Indirizzo){
            if(arguments.length>0){
                this.id=id;
                this.nome=nome;
                this.cognome=cognome;
                this.dataDiNascita=dataDinascita;
                this.luogoDiNascita=luogoDiNascita;
                this.sesso=sesso;
                this.codiceFiscale=codiceFiscale;
                this.indirizzo=indirizzo;
            }
        }    
}
 

  

In questo caso l'accoppiamento tra la classe Persona e la classe Indirizzo è basso perché se si modificano gli attributi della classe Indirizzo, non bisogna modificare gli argomenti del metodo setIndirizzo e del costruttore della classe Persona, poiché contengono semplicemente il riferimento della classe indirizzo.

private indirizzo:Indirizzo;
...
    public setIndirizzo(indirizzo;Indirizzo){
        this.indirizzo=indirizzo;
    }
...
public constructor(id?:number,nome?:string,cognome?:string,dataDinascita?:Date,luogoDiNascita?:string,sesso?:string,codiceFiscale?:string,indirizzo?:Indirizzo){
            if(arguments.length>0){
                this.id=id;
                this.nome=nome;
                this.cognome=cognome;
                this.dataDiNascita=dataDinascita;
                this.luogoDiNascita=luogoDiNascita;
                this.sesso=sesso;
                this.codiceFiscale=codiceFiscale;
                this.indirizzo=indirizzo;
                    }
}    

DIPENDECY INJECTION

La Dipendency Injection è una particolare forma del pattern Inversion Of Control (IoC), che rende una classe indipendente dell'inizializzazione delle proprie dipendenze.
Questa caratteristica riduce il livello di accoppiamento tra le classi ed aumenta la manutenibilità dell'applicazione.

In parole semplici, con la Dipendency Injection i metodi oppure i costruttori di una classe non istanziano gli oggetti con il comando new, ma ricevono direttamente i loro riferimento come argomento passato dal contesto applicativo.

Nella programmazione tradizionale è lo sviluppatore che si occupa di tutte le operazioni di creazione, inizializzazione ed invocazione dei metodi degli oggetti, l'IoC invece inverte il control flow facendo in modo che non sia più lo sviluppatore a doversi preoccupare di questi aspetti, ma il framework, che reagendo a qualche “stimolo” se ne occuperà per suo conto.

Se sviluppate con Java il framework più usato è SPRING, se sviluppate con TypeScript il più usato è ANGULAR.

 

Nella prossima lezione vedremo come manipolare gli elementi del DOM delle pagine  HTML.


<< Lezione precedente | Vai alla prima lezione


T U T O R I A L S    S U G G E R I T I


EDUCATIONAL GAMING BOOK (EGB) "H2O"

Nell'era dello SMART LEARNING e di PYTHON i libri non si scrivono, ma si sviluppano, in questo modo chi studia, può sperimentare ed apprendere contemporaneamente; un libro con queste caratteristiche lo possiamo definire un  Educational Gaming Book (EGB).

"H2Oè un EGB che descrive tutte le caratteristiche dell'acqua, la sostanza formata da molecole di H2O, che attraverso il suo ciclo di vita garantisce la sopravvivenza di tutti gli esseri viventi del Pianeta

L'obiettivo dell'EGB è quello di far conoscere ai giovani le proprietà dell'acqua, sotto molti aspetti uniche, per sensibilizzarli a salvaguardare un bene comune raro, indispensabile per la vita


Per il DOWNLOAD di "H2Oclicca qui.

Share Button
TOP