Skillbook Logo
foto profilo

Tutte le categorie


Cassa Integrazione: per molti dipendenti, oltre al danno, la beffa ...

Gino Visciano | Skill Factory - 05/08/2020 17:24:52 | in Home

E' ormai noto a tutti che, nonostante le rassicurazioni dell'INPS e le promesse del governo, molti dipendenti in cassa integrazione devono ancora ricevere parte dei soldi dei mesi di marzo ed aprile e  quasi nessuno ha ricevuto i soldi dei mesi di maggio e giugno.

Ma purtroppo i  disagi non sembrano finire qui!

Alcuni dipendenti in cassa integrazione ci hanno segnalato che per qualche ingiustificato e scellerato motivo, l'INPS non sta versando i soldi della cassa integrazione sul conto corrente bancario indicato nella domanda di cassa integrazione, questo nonostante sia stato fornito un IBAN valido, ma sta inviando un mandato di pagamento che li obbliga a ritirare i soldi presso gli sportelli delle Poste Italiane

Questa cosa è molto grave, perché per ritirare i propri soldi, bisogna fare lunghe file, anche di alcune ore, che inevitabilmente provocano  assembramenti ed aumentano  il rischio di contrarre il COVID, proprio quello che si voleva evitare chiudendo le aziende ed introducendo l'uso dello smart-working.

Ma c'è dell'altro ...

Qualcuno ci ha anche raccontato che per motivi di antiriciclaggio, per ritirare i propri soldi è stato costretto, per fortuna gratuitamente, ad aprire un libretto postale, su cui depositare i soldi, per poi poterli ritirare successivamente allo sportello oppure attraverso la carta BMT.

Sicuramente dietro a tutto questo disagio esisterà una spiegazione logica, soprattutto in un periodo di emergenza come quello che stiamo vivendo, ma nell'era digitale, dove tutto può essere fatto a distanza, è difficile credere che sia solo inefficienza, probabilmente ci sono anche altri interessi di tipo commerciale.

Share Button

TypeScript - Lezione 6: Paradigma Object Oriented (prima parte)

Gino Visciano | Skill Factory - 28/07/2020 23:29:50 | in Tutorials

Il paradigma Object Oriented prevede che le applicazioni siano  composte da un insieme di componenti, chiamti oggetti oppure istanze, che collaborano tra loro per svolgere un lavoro o risolvere un problema.

Il Diagramma di collaborazione seguente mostra un esempio di applicazione Object Oriented.

 

Tutte le applicazioni si possono assemblare utilizzando tre tipi di oggetti: 

- I MODEL sono oggetti che contengono i dati di un entità, corrispondono ai record delle tabelle, permettono di memorizzare temporaneamente i dati in memoria;
- Le 
VIEW sono oggetti oppure viste,  come ad esempio le pagine htmlpermettono la visualizzazione oppure l'inserimento di informazioni;
- I 
CONTROLLER  sono oggetti che hanno il compito di gestire un flusso logico applicativo, all'interno della stessa applicazione ci possono essere anche più CONTROLLER.

L'immagine seguente mostra un diagramma di classe che descrive una classe  che contiene gli attributi di una Persona.

Con una classe di questo tipo è possibile istanziare oggetti di tipo MODEL.

L'immagine seguente mostra il mockup di una pagina.html che permette di inserire i dati che verranno memorizzati in un oggetto di tipo Persona:

L'immagine seguente mostra un diagramma di classe con la classe GestionePersone di tipo CONTROLLER che, attraverso il metodo main, implementa la logica necessaria per gestire oggetti di tipo Persona: 

 

COLLABORAZIONE TRA COMPONENTI

Quando si lavora con un linguaggio ad oggetti bisogna ricordare alcune regole importanti per permettere la collaborazione (comunicazione) tra i componenti dell'applicazione:

1) Una classe diventa un componente (oggetto) quando s'istanzia, solo in questo caso è possibile usare gli attributi ed i metodi pubblici, come mostra il codice TypeScript seguente:

Persona personaUno = new Persona();
Persona personaDue = new Persona();
personaUno.setNome("Pippo");
personaUno.setCognome("Rossi");
personaUno.setEta(35);
personaDue.setNome("Carla");
personaDue.setCognome("Verdi");
personaDue.setEta(30);

L'immagine seguete mostra prima il Diagramma di Classe che descrive la classe Persona, di seguito attraverso un Diagramma ad Oggetti vengono descritti gli stati delle istanze (oggetti) dei due compenenti di tipo MODEL  creati usando la classe Persona.

I due componenti istanziati sono stati allocati in memoria e gli indirizzi (riferimenti) memorizzati nelle variabili personaUno e personaDue di tipo Persona.

2) Gli attributi ed i metodi  pubblici di una classe si definiscono Interfaccia. I componenti possono collaborare (comunicare) tra loro solo attraverso l'interfaccia.  

Ad esempio l'interfaccia della classe Persona è composta solo dai metodi:

public setNome(nome:string):void;
public setCognome(cognome:string):void;
public setEta(eta:number):void;
public getNome():string;
public getCognome():string;
public getEta():int;

perché gli attributi sono tutti privati e non possono essere visibili agli altri componenti.

3) Un componente che usa gli attributi ed i metodi pubblici (interfaccia) di un altro componenete ha il ruolo di Client, l'altro ha il ruolo di Server

L'immagine seguente mostra la classe Prima, di tipo Client, perché attraverso i metodi stampaDivisione() e stampaValore(), utilizza l'attributo valore ed il metodo divisione(...) della classe Seconda, che ha il ruolo di Server.

I metodi di una classe Client per usare gli attributi ed i metodi pubblici (interfaccia) di una classe Server devono istanziarla, come mostra l'esempio seguente:

Esempio 1

 
// prima.ts classe Client
import {Secondafrom './seconda'
export class Prima{
    public stampaDivisione():void{
        //Istanza classe Server
        var seconda:Seconda =new Seconda();
        console.log("Divisione 10/5="+seconda.divisione(10,5));
    }
    public stampaValore():void{
        //Istanza classe Server
        var seconda:Seconda =new Seconda();
        console.log("valore="+seconda.valore);
    }
}
 

 

 
// seconda.ts classe Server
export class Seconda{
    //Interfaccia classe Server perché entrambi gli elementi sono pubblici
    public valore:number=10;
    public divisione(dividendo:number,divisore:number):number{
        return dividendo/divisore;
    }
}
 

 

 
import {Primafrom './prima'
//Istanza classe Prima perché per poter usare 
//i suoi elementi pubblici deve diventare un componente 
var prima:Prima=new Prima();
prima.stampaDivisione();
prima.stampaValore();
 

 

Tra la classe Client Prima e la classe Server Seconda esiste una dipendenza, perché entrambi i metodi stampaDivisione() e stampaValore() di classe Prima istanziano un componente di tipo Seconda.

Quando esiste una dipendenza le classi si dicono accoppiate


PROPRIETA' DEL PARADIGMA OBJECT ORIENTED

Il paradigma Object Oriented prevede tre proprietà di programmazione e due architetturali.

Proprietà di programmazione:

1) Incapsulamento
2) Ereditarietà
3) Polimorfismo

Il Polimorfismo può essere diviso in:

1) Polimorfismo dei metodi: Overload ed Override
2) Polimorfismo degli oggetti, che si può ottenere per ereditarietà oppure per interfaccia.

Le proprietà di programmazione permettono di sviluppare le classi ed impostare le loro caratteristiche ed il loro comportamento

Proprietà architetturali:

1) Coesione
2) Disaccoppiamento

Le proprietà architetturali permettono d'impostare la struttura e l'organizzazione delle applicazioni ad oggetti, per migliorarne le funzionalità e la qualità

 

PROPRIETA' DI PROGRAMMAZIONE DEL PARADIGMA OBJECT ORIENTED

Le proprietà descritte di seguito sono disponibili unicamente nei linguaggio orientatti agli oggetti (Object Oriented),  come ad esempio: C++, C#, Java, TypeScript e Python.

INCAPSULAMENTO

L'incapsulamento, attraverso i modificatori di accesso,  permette di regolare la visibilità e quindi l'utilizzo degli elementi di una classe:

- Attributi
- Metodi
- Costruttori

da parte dei metodi di altre classi.

I modificatori di accesso disponbili in TypeScript sono:

- public         (+, notazione UML)
- private        (-, notazione UML)
- protected  (#, notazione UML)

a)  un elemento è public è visibile a tutti i metodi sia della classe a cui appartiene, sia ai metodi di altre classi.
b)  un elemento è private è visibile solo a tutti i metodi della classe a cui appartiene, ma non è visibile ai metodi di altre classi.
c)  un elemento è protected è visibile solo a tutti i metodi della classe a cui appartiene ed a quelli delle classi che ereditano la classe che contiene l'elemento protected, ma non è visibile ai metodi di altre classi.

 


Esempio 2

 
// incapsulamento.rs
class Test{
public a:number=10;
private b:number=20;
protected c:number=30;
}
class TestA{
public eseguiTest(){
     // Verifica incapsulamento per istanza (dipendenza)
     var test:Test=new Test();
     console.log("a="+test.a+" (public)")
     console.log("b=non visibile (private)");
     console.log("c=non visibile (protected)");
}
}
class TestB extends Test{
    public eseguiTest(){
         // Verifica incapsulamento per ereditarietà
         console.log("a="+this.a+" (public)")
         console.log("b=non visibile (private)");
         console.log("c="+this.c+" (protected)");
    }
    }
 
// Controller
class Main{
    public static main(){
        var testA:TestA=new TestA();
        var testB:TestB=new TestB();
        console.log("----- Test incapsulamento per dipendenza -----")
        testA.eseguiTest();
        console.log("----- Test incapsulamento per ereditarietà -----")
        testB.eseguiTest();
    }
}
 
//main
Main.main();
 
----------------------------------------------------------------------------
----- Test incapsulamento per dipendenza -----
a=10 (public)
b=non visibile (private)
c=non visibile (protected)
----- Test incapsulamento per ereditarietà -----
a=10 (public)
b=non visibile (private)
c=30 (protected)
 

 

EREDITARIETA'

L'Ereditarietà è una tecnica di riuso del codice, questa proprietà permette di creare una nuova classe, ereditando tutti gli elementi public e protected di un'altra classe, chiamata classe padre.
La classe figlia o derivata può contenere nuovi elementi che permettono di specializzare la classe Padre ereditata

L'Ereditarietà è quasi sempre singola, ovvero una classe figlia può ereditare una sola classe per volta, l'unico linguaggio che permette l'ereditarietà multipla è il C++.

 

EREDITARIETA': REGOLA DEL COSTRUTTORE PARAMETRIZZATO

In caso di ereditarietà, se nella classe padre è presente un costruttore parametrizzato, i suoi argomenti devono essere alimentati dal costruttore della classe figlia, con il metodo super(...), come mostra l'immagine seguente:
 

 

POLIMORFISMO DEI METODI

- OVERLOAD

L'Overload è la proprietà dell'Object Oriented che permette di usare nella stessa classe metodi con lo stesso nome, ma firma diversa.

La firma di un metodo è composta dal nome del metodo più i tipi degli argomenti passati, come mostra l'immagine seguente:

Nella stessa classe possono essere presenti più costruttori con lo stesso nome grazie all'overload, come mostra l'esempio seguente:

Persona() // Costruttore dei default
Persona(nome:string,cognome:string,eta:int) // Costruttore parametrizzato

Firma 1=Persona
Firma 2=Persona+string+string+int

Esempio 3

L'esempio seguente mostra la classe Colori con tre metodi con lo stesso nome, ma firma diversa:
1) colora+string, questo metodo fornisce in output il nome del colore fornito in input come argomento;
2) colora+number, questo metodo fornisce in output il colore corrispondente al progressivo numerico fornito in input come argomento;
3) colora+number+number+number, questo metodo fornisce in output il codice esadecimale del colore corrispondente al codice R,G,B (RED=decimale,GREEN=decimale,BLUE=decimale) fornito in input come argomento.
 

Attenzione in TypeScript l'overload si gestisce con una funzione con argomenti opzionali e l'uso d'interfacce che permettono di definire le firme consentite, come mostra il codice seguente:

 
class Colori {
    public colora(valoreUno:string):string;
    public colora(valoreUno:number):string;
    public colora(valoreUno:number,valoreDue:number,valoreTre:number):string;
    public colora(valoreUno:string | number,valoreDue?:number,valoreTre?:number):string{
    if(arguments.length==3){
        return  "#"+valoreUno.toString(16)+valoreDue.toString(16)+valoreTre.toString(16);
    } else{
        if (typeof valoreUno=="number") {
            switch(valoreUno){
                case 1:
                    return "rosso";
                    break;
                case 2:
                    return "verde";
                    break;
                case 3:
                    return "bianco";
                    break;
                default:
                    return "nero";
                    break;
            }
 
        } else{
            return valoreUno;
        }   
    }
  }
// Controller
class Main{
    public static main():void{
var colori:Colori=new Colori();
console.log(colori.colora("rosso"));
console.log(colori.colora(2));
console.log(colori.colora(200,100,255));
    }
}
// main
Main.main();
 
 
--------------------------------------------------
rosso
verde
#c864ff
 

 

- OVERRIDE

L'Override è la seconda proprietà del polimorfismo dei metodi, serve per cambiare il comportamento di un metodo ereditato dalla classe Padre, come mostra l'esempio seguente:

Esempio 4

Se la classe ChiSeiSeconda eredita la classe ChiSeiPrima, il comportamento del metodo toString() è lo stesso, sia per un oggetto di tipo ChiSeiPrima, sia per un oggetto di tipo ChiSeiSeconda.

 
class ChiSeiPrima {
    public toString():string{
           return "Sono la classe ChiSeiPrima!" ;
    }
}
class ChiSeiSeconda extends ChiSeiPrima{
}
// Controller
class Main{
    public static main():void{
        var chiSeiPrima=new ChiSeiPrima();
        var chiSeiSeconda=new ChiSeiSeconda();
        console.log(chiSeiPrima.toString());
        console.log(chiSeiSeconda.toString());
    }
}
// main
Main.main();
 
------------------------------------------
Sono la classe ChiSeiPrima!
Sono la classe ChiSeiPrima!
 

 

Esempio 5

Se sovrascrivete (override) il metodo  toString() nella classe ChiSeiSeconda, allora il comportamento del metodo sarà diveso se l'oggetto è di tipo ChiSeiPrima oppure di tipo ChiSeiSeconda.

 
class ChiSeiPrima {
    public toString():string{
           return "Sono la classe ChiSeiPrima!" ;
    }
}
class ChiSeiSeconda extends ChiSeiPrima{
    //Override
    public toString():string{
        return "Sono la classe ChiSeiSeconda!" ;
 }
}
// Controller
class Main{
    public static main():void{
        var chiSeiPrima=new ChiSeiPrima();
        var chiSeiSeconda=new ChiSeiSeconda();
        console.log(chiSeiPrima.toString());
        console.log(chiSeiSeconda.toString());
    }
}
 
----------------------------------------------
Sono la classe ChiSeiPrima!
Sono la classe ChiSeiSeconda!
 
 

 

- OVERRIDE: OPERATORE SUPER

Quando si sovrascrive (override) un metodo in una classe figlia, per poter utilizzare lo stesso metodo della classe Padre, dovete usare l'operatore super

Ricordate che quando istanziate un oggetto utilizzando una classe, l'operatore this diventerà il riferimento dell'oggetto creato, mentre super diventerà il riferimento dell'oggetto padre. 

 
class ChiSeiPrima {
    public toString():string{
           return "Sono la classe ChiSeiPrima!" ;
    }
}
class ChiSeiSeconda extends ChiSeiPrima{
    //Override
    public toString():string{
        return super.toString()+", Sono la classe ChiSeiSeconda!" ;
 }
}
// main
var chiSeiPrima=new ChiSeiPrima();
var chiSeiSeconda=new ChiSeiSeconda();
console.log(chiSeiPrima.toString());
console.log(chiSeiSeconda.toString());
 
-----------------------------------------------
Sono la classe ChiSeiPrima!
Sono la classe ChiSeiPrima!, Sono la classe ChiSeiSeconda!
 

 

Continua nella prossima lezione dove vedremo il Polimorfismo degli oggetti e le proprietà architetturali del paradigma Object Oriented.


<< Lezione precedente           Lezione successiva >> | 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

Non Siamo un'Academy! Siamo una grande community di programmatori Junior ...

Gino Visciano | Skill Factory - 15/07/2020 16:57:14 | in Home

Nell'era dello Storytelling raccontare una storia di successo è gratificante, soprattutto in un momento in cui occorrono certezze,  per superare le difficoltà che stiamo vivendo a causa dell'emergenza COVID.

Quando nel 2011 abbiamo avviato la società "Skill Factory", non pensavamo che a breve saremo diventati una grande "Community di programmatori junior".

Oggi, grazie al nostro lavoro, oltre 2000 giovani hanno avuto la possibilità di accedere a percorsi gratuiti, chiamati skill factory ed entrare nel mondo del lavoro presso uno dei nostri Job partner IT, con un contratto di apprendistato.

Una skill factory è un percorso progettato ad hoc per creare tutte le competenze che servono ad un programmatore e facilitare il percorso richiesto per entrare nel mondo del lavoro. 

Escluso il periodo di tirocinio formativo, un percorso di skill factory ha una durata di 320/480 ore ed  ha una percentuale di successo del 60/70%.  

I destinatari sono giovani disoccupati di età compresa tra i 22 ed i 29 anni, diplomati oppure laureati, in cerca di prima occupazione oppure persone che hanno bisogno di riqualificarsi, perché sono alla ricerca di nuove opportunità di lavoro. 

Non siamo un'ACADEMY! 

La Skill Factory non è un’Academy aziendale, ma un’azienda di specializzazione informatica, dove conoscenza ed esperienza si combinano per creare le figure tecniche più richieste dai nostri partner che basano il proprio successo sull’innovazione tecnologica e digitale

Attraverso la piattaforma www.skillbook.it,  collaboriamo con tutti gli utenti dell'nostra community a cui offriamo i seguenti servizi:

- Informazione;
- Formazione;
- Aggiornamento;
- Certificazione delle competenze;
- Consulenza e Supporto.

 

  
 


Tutto quello che ti serve per diventare programmatore te lo insegniamo noi!
Vuoi partecipare ad una "Skill Factory"? Invia il tuo CV a recruiting@skillfactory.it, ti contatteremo per verificare se hai i prerequisiti richiesti.
Non cerchiamo talenti o esperti d'Informatica, ma giovani serivolenterosi ed audaci, che vogliono mettersi in gioco per raggiungere un obiettivo professionale.   


Sei un programmatore esperto?
Pensi che la tua esperienza possa essere utile agli utenti della nostra community?
Cosa aspetti, conttattaci!  Puoi diventare un nostro "Competence partner" ed aiutarci a formare i nostri ragazzi che partecipano alle "skill factory" ...

mail: recruiting@skillfactory.it 


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


Iscriverti al nostro canale YOUTUBE! 

Per iscriverti al nostro canale devi essere in possesso di un account Google, se non hai ancora un account clicca qui.

Se sei già in possesso di un account Google, prosegui nel modo seguente:

1) Collegati al tuo account Gmail
2) Vai sul sito ufficiale di YouTube
3) Cliccare su Accedi
4) Inserisci user e password del tuo account Google
5) Clicca sul pulsante seguente:

6) Per iscriverti clicca sul pulsante indicato

7) Non dimenticare di attivare le notifiche

 


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

TypeScript - Lezione 5: Classi ed Oggetti

Gino Visciano | Skill Factory - 10/07/2020 17:52:46 | in Tutorials

TypeScript pur essendo un linguaggio usato per sviluppare applicazioni lato Front-end, è un linguaggio Object Oriented, quindi è importante conoscere i concetti di Classe ed Oggetto.

Una Classe definisce un tipo di oggetto, in pratica è il codice sorgente dell'oggetto che verrà creato in meomria. L'operazione che trasforma il codice  sorgente della classe in oggetto si chiama istanza

L'esempio seguente mostra come si può istanziare in memoria un oggetto di nome persona usando la classe Persona:

Persona persona=new Persona();

1) Persona  è la classe, rappresenta il tipo di oggetto;
2) persona variabile che contiene l'indirizzo (riferimento)  dell'oggetto istanziato con il comando new;
3) Persona() costruttore, metodo usato per inizializzare l'oggetto creato.  

Istanziare significa creare in memoria con il comando new un oggetto, usando come modello la classe. L'indirzzo dove viene allocato l'oggetto, viene assegnato alla variabile dell'istanza, come ad esempio  persona

In fase di progettazione il linguaggio UML (Unified Modeling Language) è molto utile per disegnare un tipo di classe che poi potra essere scritta con qualunque linguaggio di programmazione object oriented (orientato agli oggetti).

L'esempio seguente mostra il diagramma di classe della classe Persona:

Le Classi  possono contenere i seguenti elementi:

attributi
metodi
costruttori

Per convenzione i nomi delle Classi iniziano sempre con la lettera maiuscola e se sono composti da più parole, anche le altre parole devono iniziare con la lettera maiuscola.

ATTRIBUTI
Gli attributi sono variabili della classe, per questo motivo sono anche chiamate  variabili d'istana, sono le proprietà che si usano per memorizzare i dati che appartengono all'oggetto.

Gli attributi  se sono pubblici (+ simbolo UML) possono anche essere usati dai metodi di altre classi, altrimenti se sono privati (- simbolo UML  possono essere usati solo dai metodi della stessa classe.

Se un attributo è protected (# simbolo UML) , in caso di ereditarietà è visibile anche ai metodi della classe figlia.


METODI
metodi sono funzioni contenute nelle classi, le azioni dei metodi determinano il comportamento degli oggetti.

Nei linguaggi di programmazione ad oggetti, la logica applicativa (istruzioni), può essere implementata solo all'interno dei metodi.

 

 

metodi se sono pubblici   (+ simbolo UML)  possono essere eseguiti anche dai metodi di altre classi, se sono privati  (- simbolo UML) possono essere eseguiti solo dai metodi della stessa classe.

Se un metodo è protected (# simbolo UML) , in caso di ereditarietà è visibile anche ai metodi della classe figlia.

Per convenzione i  metodi che hanno il nome che inizia con i prefissi get e set si usano per assegnare o leggere i valori degli attributi privati dell'oggetto a cui appartengono. 

Ad esempio,  dato che gli  attributi della classe  Persona sono privati, per gestirli dovete usare i seguenti metodi pubblici:

setNome
getNome
setCognome
getCognome
setEta
getEta 

COSTRUTTORI
I costruttori sono metodi speciali usati  per istanziare gli oggetti e per inizializzare gli attributi.

Persona persona=new Persona();

Persona() => costruttore.

Per creare un costruttore inTypeScript  dovete implementare un metodo che si chiama constructor senza indicare il tipo restituito

In una classe deve esistere sempre almeno un costruttore senza argomenti, chiamato costruttore di default, come mostra l'esempio seguente:

public constructor(){}

Se necessario il costruttore di default può anche essere usato per inizializzare gli attributi dell'oggetto creato, come mostra l'esempio seguente:
 
public constructor(){
            this.id=1;
            this.nome="Marco";
            this.cognome="Rossi";
            this.dataDiNascita="05/10/1990";
            this.luogoDiNascita="Milano";
            this.sesso="Maschio";
            this.codiceFiscale="mrcrss90r05l268f";
}

Un costruttore con argomenti si chiama costruttore parametrizzato, a differenza di quello di default, permette di passare i valori per inizializzare l'oggetto durante l'istanza, come mostra l'esempio  seguente:

Persona persona=new Persona(1,'Paolo','Rossi','10/02/1991','Milano','Maschio','pllrss91a02l234f');

L'esempio seguente mostra come si crea un costruttore parametrizzato:

public constructor(id:number,nome:string,cognome:string,dataDinascita:Date,luogoDiNascita:string,sesso:string,codiceFiscale:string){
            this.id=id;
            this.nome=nome;
            this.cognome=cognome;
            this.dataDiNascita=dataDinascita;
            this.luogoDiNascita=luogoDiNascita;
            this.sesso=sesso;
            this.codiceFiscale=codiceFiscale;

Esempio 1

L'esempio seguente mostra come creare una classe Persona con gli attributi privati ed i metodi set e get pubblici.
La parola chiave export indica che la classe può essere importata anche in un altro modulo con il comando import.


export class Persona{
    private id:number;
    private nome:string;
    private cognome:string;
    private dataDiNascita:Date;
    private luogoDiNascita:string;
    private sesso:string;
    private codiceFiscale: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 getCodiceFiscale():string{
        return this.codiceFiscale;
    }
    public setCodiceFiscale(codiceFiscale:string):void{
        this.sesso=codiceFiscale;
    }
    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;
    }
    public equals(obj:Object):boolean{
        if (this.toString()!=obj.toString()){
            return false;
        }
        return true;
    }
        // Sovraccarico del costruttore (Overload)
        public constructor();
        public constructor(id:number,nome:string,cognome:string,dataDinascita:Date,
                           luogoDiNascita:string,
                           sesso:string,codiceFiscale:string);
        public constructor(id?:number,nome?:string,cognome?:string,dataDinascita?:Date,
                           luogoDiNascita?:string,sesso?:string,codiceFiscale?: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;
            }
 
        }    
}
 

 

SOVRACCARICO DEL COSTRUTTORE  IN TYPESCRIPT (OVERLOAD)

L' overload è la proprietà dei linguaggi di programmazione ad oggetti che permettere l'implementazione nella stessa classe di metodi con lo stesso nome, ma firma diversa. 

Si definisce firma il nome di un metodo più i tipi degli argomenti passati in input. 

Ad esempio, le firme dei costruttori della classe Persona, sono le seguenti:

1) constructor
2) constructor, number, string, string,  Date, string, string, string

In TypeScript l'overlad si può applicare usando una funzione con argomenti opzionali che in base al numero di argomenti passati in input assume un comportamento diverso.
Per conoscere quali e quanti argomenti vengono passati ad una funzione con argomenti opzionali potete usare l'interfaccia arguments.
Per definire le firme consentite per eseguire la funzione con argomenti opzionali, dovete indicare le  interfacce corrispondenti, come mostra l'esempio seguente:

// Interfaccia che definisce la firma del costruttore di default
public constructor();
// Interfaccia che definisce la firma del costruttore parametrizzato
public constructor(id:number,nome:string,cognome:string,dataDinascita:Date,luogoDiNascita:string,sesso:string,codiceFiscale:string); 
// Funzione con argomenti opzionali, il punto indicativo "?" rende il parametro facoltativo
public constructor(id?:number,nome?:string,cognome?:string,dataDinascita?:Date,luogoDiNascita?:string,sesso?:string,codiceFiscale?: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;
            }
}

Esempio 2

L'esempio seguente utilizza la classe Persona, creata nell'esempio precedente, per gestire un array di persone.

L'inserimento dei dati avviene attraverso il Form seguente che permette di aggiungere una persona all'array, con il pulsante "Salva" e visualizzare l'elenco di tutte le persone inserite con il pulsante "Elenco".


 

Per ottenere il Form dovete utilizzare il codice HTML seguente:

 
<!--gui_persona.html-->
<html>
<head>
    <script lang="JavaScript" src="persone.js"></script>
</head>
<body>
<table>
<form>
<tr><th>PERSONA</th><th></th></tr>
<tr><td>Nome:</td><td><input type="text" id="nome" value=""></td></tr>
<tr><td>Cognome:</td><td><input type="text" id="cognome" value=""></td></tr>
<tr><td>Data di nascita:</td><td><input type="text" id="data" value=""></td></tr>
<tr><td>Luogo di nascita:</td><td><input type="text" id="luogo" value=""></td></tr>
<tr><td>Sesso:</td><td><input type="text" id="sesso" value=""></td></tr>
<tr><td>Codice Fiscale:</td><td><input type="text" id="cf" value=""></td></tr>
<tr><td></td><td><input type="button" onclick="salva();" value="Salva"> 
<input type="button" onclick="addElenco();" value="Elenco"> <input type="reset" 
       value="reset"></td></tr>
</form>
</table>
--- Elenco Persone ---
<div id="elenco"></div>
</body>
</html>
 


Il tag <script lang="JavaScript" src="persone.js"></script> permette d'importare il modulo JavaScript, risultato della compilazione con tsc del codice TypeScript seguente:


// persone.ts
import {Personafrom "./persona";
 
var persone:Persona[]=[];  //var persone:Persona[]=[]
var id:number=0;
 
// Funzione associata al metodo onclick del pulsante Salva
function salva():void{
    var nome:string=(<HTMLInputElement>document.getElementById("nome")).value;
    var cognome:string=(<HTMLInputElement>document.getElementById("cognome")).value;
    var strData:string=(<HTMLInputElement>document.getElementById("data")).value;
    var luogo:string=(<HTMLInputElement>document.getElementById("luogo")).value;
    var sesso:string=(<HTMLInputElement>document.getElementById("sesso")).value;
    var cf:string=(<HTMLInputElement>document.getElementById("cf")).value;
    var data:Date=new Date(strData);
    id++;
    persone.push(new Persona(id,nome,cognome,data,luogo,sesso,cf));
 }
 
 
// Funzione associata al metodo onclick del pulsante Elenco
 function addElenco() { 
    // crea un nuovo elemento div
    // gli assegna un contenuto
    var currentDiv = document.getElementById("elenco");  
    persone.forEach((persona:Persona)=>{
     // aggiungi il nodo di testo al div appena creato
    var newDiv = document.createElement("div"); 
     newDiv.style.color="blue";
     newDiv.style.fontSize="20";
     var newContent = document.createTextNode(persona.toString()); 
     newDiv.appendChild(newContent);  
     document.body.insertBefore (newDivcurrentDiv); 
     })
   // aggiungi l'elemento appena creato e il suo contenuto nel DOM
 }
 


L'immagine seguente mostra il Form con l'elenco delle persone inserite: 

INTERFACCE

In TypeScript un'interfaccia può essere usata sia per definire un tipo di dato multivalore che serve ad esempio per creare un oggetto JSON, sia per definire  l'elenco dei metodi astratti da implementare in una classe. In questa lezione ci occuperemo delle interfacce che contengono metodi astratti.

Per comprendere come utilizzare un'interfaccia che contiene metodi astratti, facciamo l'esempio di una classe CRUD che usa come repository array di tipo Persona.
Come è nota la classe per svolgere il proprio compito deve garantire le seguenti operazioni:

1) Inserimento (Create);
2) Lettura (Read), di una o tutte le persone memorizzare nel repository;
3) Modifica (Update);
4) Cancellazione (Delete). 

L'esempio seguente mostra come utilizza un'interfaccia come modello per implementare in una classe che deve svolgere le operazioni previste dal CRUD.

Esempio 3

 
//personacrud.ts
import {Personafrom './persona'
 
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;
        }
    }
 
}
 

 

CLASSI ASTRATTE

Nella programmazione ad oggetti una classe astratta è un pattern, perché serve per implementare una soluzione applicativa.
Le classi astratte permettono d'implementare metodi che usano il risultato di uno o più metodi astratti, di cui non ne conosciamo ancora il comportamento.
Naturalmente le classi astratte non possono istanziare oggetti, perché contengono sia metodi implementati, sia metodi astratti e quindi devono necessariamente essere ereditate.
La classe figlia verrà utilizzata per implementare il comportamento dei metodi astratti della classe padre

Esempio 4  

//geometria_astratta.ts
//Classe astratta che può essere solo ereditata
abstract class FiguraGeometrica{
    // Attributo di tipo privato, visibile solo nell'oggetto, globalmente.
    private tipoFigura:string;
    public getInfoFigura():string[]{
        var infoFigura:string[]=[];
        infoFigura.push("Tipo figura:"+this.tipoFigura);
        // Uso il risultato dei metodi astratti
        // che verranno implementati nella classe figlia 
        infoFigura.push(this.getCaratteristiche());
        infoFigura.push("Perimetro  :"+this.getPerimetro());
        infoFigura.push("Area       :"+this.getArea());
        return infoFigura;
    }
    getTipoFigura():string{
        return this.tipoFigura;
    }
    // metodi astratti
    abstract getCaratteristiche():string;
    abstract getPerimetro():number;
    abstract getArea():number;
    // Costruttore alimentato dalla classe figlia
    // viene utilizzato per indicare il tipo di figura geometrica
    public constructor(tipoFigura:string){
        this.tipoFigura=tipoFigura;
    }
}
 
class Cerchio extends FiguraGeometrica{
    // Attraverso il costruttore assegno all'attributo raggio il suo valore
    public constructor(private raggio:number){
        // Il metodo super esegue il costruttore del padre
        // e gli passa il valore "Cerchio"
        super("Cerchio");
    }
    // Implemento i metodi astratti ereditati
    public getCaratteristiche():string{
        return "Raggio     :"+this.raggio;
    }
    public getPerimetro(): number {
        return 2*Math.PI*this.raggio;
    }
    public getArea(): number {
        return Math.pow(this.raggio,2)*Math.PI;
    }
}
 
class Quadrato extends FiguraGeometrica{
    // Attraverso il costruttore assegno all'attributo latoA il suo valore   
    public constructor(private latoA:number){
        // Il metodo super esegue il costruttore del padre
        // e gli passa il valore "Cerchio"
        super("Quadrato");
    }
    // Implemento i metodi astratti ereditati
    public getCaratteristiche():string{
        return "Lato       :"+this.latoA;
    }
    public getPerimetro(): number {
        return 4*this.latoA;
    }
    public getArea(): number {
        return Math.pow(this.latoA,2);
    }
}
 
class Rettangolo extends FiguraGeometrica{
    // Attraverso il costruttore assegno agli attributi 
    // latoA e latoB i loro valori   
    public constructor(private latoA:number,private latoB:number){
        // Il metodo super esegue il costruttore del padre
        // e gli passa il valore "Cerchio"
        super("Rettangolo");
    }
    // Implemento i metodi astratti ereditati
    public getCaratteristiche():string{
        return "Lati       :"+this.latoA+", "+this.latoB;
    }
    public getPerimetro(): number {
        return (2*this.latoA)+(2*this.latoB);
    }
    public getArea(): number {
        return this.latoA*this.latoB;
    }
}
 
class Triangolo extends FiguraGeometrica{
    // Attraverso il costruttore assegno agli attributi 
    // latoA, latoB e latoC i loro valori   
    public constructor(private latoA:number,private latoB:number,private latoC:number){
        // Il metodo super esegue il costruttore del padre
        // e gli passa il valore "Cerchio"
        super("Triangolo");
    }
    // Implemento i metodi astratti ereditati
    public getCaratteristiche():string{
        return "Lati       :"+this.latoA+", "+this.latoB+", "+this.latoC;
    }
    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 {
    /* Dichiaro un array di tipo FiguraGeometrica che 
    può contenere cerchi,quadrati, rettangoli e triangoli (Upcasting).  
    Questo è possibile solo perché le classi cerchio,quadrato,
    rettangolo e triangolo sono diventate simili, perché hanno ereditato tutte
    la classe FiguraGeometrica (Polimorfismo degli oggetti)*/
    private figureGeometriche:FiguraGeometrica[]=[]
    // Il metodo add grazie all'Upcasting può ricevere anche 
    // riferimenti di oggetti di tipo cerchio,quadrato, rettangolo e triangolo.
    public add(figuraGeometrica:FiguraGeometrica):void{
        this.figureGeometriche.push(figuraGeometrica);
    }
    public stampa(){
        this.figureGeometriche.forEach(figuraGeometrica =>
            figuraGeometrica.getInfoFigura().forEach(info => console.log(info)))
    }
}
class Main{
public static main():void{
    var cerchio:FiguraGeometrica=new Cerchio(10);
    var quadrato:FiguraGeometrica=new Quadrato(20);
    var rettangolo:FiguraGeometrica=new Rettangolo(10,20);
    var triangolo:FiguraGeometrica=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
Raggio     :10
Perimetro  :62.83185307179586
Area       :314.1592653589793
Tipo figura:Quadrato
Lato       :20
Perimetro  :80
Area       :400
Tipo figura:Rettangolo
Lati       :10, 20
Perimetro  :60
Area       :200
Tipo figura:Triangolo
Lati       :5, 10, 10
Perimetro  :25
Area       :24.206145913796355
 

 

CLASSI SINGLETON

Nella programmazione ad oggetti una classe singleton è un pattern, perché serve per implementare una soluzione applicativa.
Le classi singleton permettono d'istanziare una sola ricorrenza di un oggetto per evitare duplicati.
Di solito le classi singleton si usano per creare i repository, array che memorizzano oggetti. 

Esempio 5  

 
//singleton.ts
interface IRepository{
    inserisci(obj:Object):boolean;
    modifica(indice:number,obj:Object):boolean;
    cancella(indice:number):boolean;
    leggi(indice:number):Object;
    leggi():Object[];
}
 
export class Repository implements IRepository{
    // Poiché questa classe non può essere istanziata
    // la variabile che deve contenere il riferimento del singolo
    // oggetto istanziato deve istanziarsi da sola con l'operatore static
    private static instance:Repository=null;
    private repository:Object[]=[];
    // Poiché questa classe non può essere istanziata, il metodo 
    // getRepository() che istanzia l'unica ricorrenza dell'oggetto 
    // di tipo Repository deve istanziarsi da solo con l'operatore static
    public static getRepository():Repository{
        // Se instance è null viene istanziato l'oggetto di tipo Repository
        // altrimento l'oggetto già esiste e viene restituito il suo riferimento 
        if(this.instance==null){
            //Il costruttore può essere eseguito anche se privato
            //perché getRepository() è un metodo della classe
            this.instance=new Repository(); 
        }
        return this.instance;
    }
    inserisci(objObject): boolean {
       this.repository.push(obj);
       return true;
    }
    modifica(indice:numberobjObject): boolean {
        this.repository[indice]=obj;
        return true;
    }
    cancella(indicenumber): boolean {
        this.repository.splice(indice,1);
        return true;  
    }
    // Overload (polimorfismo dei metodi)
    leggi(indicenumber): Object;
    leggi(): Object[];
    leggi(indice?: number): Object | Object[] {
        if (arguments.length==1){
            return this.repository[indice];
        } else{
        return this.repository;
        }
    }
    // Il costruttore di una classe singleton è privato
    // per non permettere d'istanziare oggetti
    private constructor(){}
}
 
// Model utente
class Utente{
    public constructor(private id:number,private nome:string,
                       private cognome:string,eta:number,private sesso:boolean){}
}
 
// Classe Controller
class Main{
    public static main(){
        var utentiUno=Repository.getRepository();
        var utentiDue=Repository.getRepository();
        utentiUno.inserisci(new Utente(1,"Mara","Rossi",30,true));
        utentiUno.inserisci(new Utente(2,"Roberta","Verdi",25,true));
        utentiUno.inserisci(new Utente(3,"Carlo","Bianchi",50,false));
        utentiDue.inserisci(new Utente(4,"Ugo","Rossini",20,false));
        utentiDue.inserisci(new Utente(5,"Raffaele","Palomba",25,false));
        utentiDue.inserisci(new Utente(6,"Corrado","Belvedere",50,false));
        console.log("---------- Prima istanza di Repository ----------");
        utentiUno.leggi().forEach(utente => console.log(utente));
        console.log("---------- Seconda istanza di Repository ----------");
        utentiDue.leggi().forEach(utente => console.log(utente));
    }
}
 
// main
Main.main();
 
------------------------------------------------------------------------------------
---------- Prima istanza di Repository ----------
Utente { id: 1, nome: 'Mara', cognome: 'Rossi', sesso: true }
Utente { id: 2, nome: 'Roberta', cognome: 'Verdi', sesso: true }
Utente { id: 3, nome: 'Carlo', cognome: 'Bianchi', sesso: false }
Utente { id: 4, nome: 'Ugo', cognome: 'Rossini', sesso: false }
Utente { id: 5, nome: 'Raffaele', cognome: 'Palomba', sesso: false }
Utente { id: 6, nome: 'Corrado', cognome: 'Belvedere', sesso: false }
---------- Seconda istanza di Repository ----------
Utente { id: 1, nome: 'Mara', cognome: 'Rossi', sesso: true }
Utente { id: 2, nome: 'Roberta', cognome: 'Verdi', sesso: true }
Utente { id: 3, nome: 'Carlo', cognome: 'Bianchi', sesso: false }
Utente { id: 4, nome: 'Ugo', cognome: 'Rossini', sesso: false }
Utente { id: 5, nome: 'Raffaele', cognome: 'Palomba', sesso: false }
Utente { id: 6, nome: 'Corrado', cognome: 'Belvedere', sesso: false }
 

 

Nella prossima lezione approfondiamo il paradigma Object Oriented.


<< Lezione precedente           Lezione successiva >> | 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

TypeScript - Lezione 4: Tipi di Funzioni

Gino Visciano | Skill Factory - 03/07/2020 16:33:54 | in Tutorials

In questa lezione vedremo tutti i tipi di funzioni che si possono utilizzare in TypeScript.

Per creare una funzione in  TypeScript dovete utilizzare la sintassi seguente:

function nomeFunzione(elenco argomenti):tipoValoreRestituito {
     // Codice funzione
}

Se la funzione si comporta come una procedura , perché non restituisce nessun valore, come tipoValoreRestituito  dovete usare il tipo void.

Ad esempio la funzione contaFinoADieci è di tipo void, perché è una procedura che visualizza un numero da 1 fino a 10:


function contaFinoADieci():void {
    for(let x:number=1;x<=10;x++){
        console.log(x);
    }
}
// Esegue contaFinoADieci
contaFinoADieci();
 

La parola chiave let indica che la variabile x può essere usata solo nel blocco for, al di fuori del blocco for non è visibile. Per usare la x anche al di fuori del blocco for dovete usare la parola chiave var

Anche la funzione contaFinoAMax è una procedura, ma attraverso l'argomento max permette di visualizzare un numero da 1 ad un valore predefinito.


function contaFinoAMax(max:number):void {
    for(let x:number=1;x<=max;x++){
        console.log(x);
    }
}
// Esegue contaFinoAMax e conta fino a 20
contaFinoAMax(20);
 

Quando la funzione  restituisce un valore attraverso il comando return, il  tipoValoreRestituito deve essere dello stesso tipo, come mostra l'esempio seguente:


function divisione(dividendo:numberdivisore:number):number {
    var risultato:number;
    risultato=dividendo/divisore;
    return risultato;
}
 

 

DIFFERENZA TRA FUNZIONI CON PASSAGGIO PER VALORE E PASSAGGIO PER RIFERIMENTO

Le funzioni sono task di programmazione che eseguono operazioni specifiche quando vengono eseguite.

Se necessario possono ricevere argomenti in input e restituire un argomento come output, naturalmente se non sono di tipo  void.  

L'immagine seguente mostra il comportamento di una funzione che riceve n argomenti in ingresso (input)  e ne restituisce uno in uscita (output).

Block box significa che se una funzione riceve in input gli  stessi argomenti, fornisce sempre lo stesso risultato come output.

Gli argomenti delle funzioni, sia in input, sia in output, possono essere passati per valore oppure per riferimento

Quando passate un argomento per valore state passando il contenuto di una variabile

Quando il passaggio avviene per riferimento state passando l'indirizzo di un array oppure di un oggetto in cui sono contenuti i valori.

Questa differenza è molto importante perché  se il passaggio degli argomenti avviene per valore, utilizzate una copia dei valori originali, mentre se il passaggio degli argomenti avviene per riferimento, attraverso l'indirizzo lavorate direttamente  con i valori degli array o degli oggetti originali. 

L'immagine seguente descrive un esempio di passaggio per valore, in questo caso gli argomenti della funzione divisione ricevono una copia del contenuto delle variabili dividendo e divisore.

L'immagine seguente descrive un esempio di passaggio per riferimento, in questo caso l'argomento della funzione calcolaQuadrato riceve una copia del riferimento (indirizzo) dell'array di interi numeri, attraverso il riferimento può modificare direttamente il contenuto dell'array.

Esempio 1

L'esempio seguente mostra che il passaggio per valore permette di copiare il contenuto della variabile originale nella variabile indicata come argomento. Modificando il contenuto della variabile indicata come argomento della funzione, il contenuto della variabile originale non cambia: 


// passaggio_per_valore.ts
function modificaValore(copiaDiA:number){
    console.log("Funzione modificaValore, valore passato:"+copiaDiA);
    //Modifico copiaDiA;
    copiaDiA=20;
    console.log("Funzione modificaValore, valore modificato:"+copiaDiA);
}
 
//Modulo
var a:number=10;
console.log("Modulo, valore passato alla funzione modificaValore:"+a);
modificaValore(a)
console.log("Modulo, valore dopo l'esecuzione della funzione modificaValore:"+a);
------------------------------------------------------------------------------------
Modulo, valore passato alla funzione modificaValore:10
Funzione modificaValore, valore passato:10
Funzione modificaValore, valore modificato:20
Modulo, valore dopo l'esecuzione della funzione modificaValore:10
 

Con il passaggio per valore, per modificare  il contenuto della variabile originale dovete usare il comando return, come mostra l'esempio seguente:

Esempio 2

 
// passaggio_per_valore_bis.ts
function modificaValore(copiaDiA:number):number{
    console.log("Funzione modificaValore, valore passato:"+copiaDiA);
    //Modifico copiaDiA;
    copiaDiA=20;
    console.log("Funzione modificaValore, valore modificato:"+copiaDiA);
    return copiaDiA;
}
 
//Modulo
var a:number=10;
console.log("Modulo, valore passato alla funzione modificaValore:"+a);
a=modificaValore(a)
console.log("Modulo, valore dopo l'esecuzione della funzione modificaValore:"+a);
------------------------------------------------------------------------------------
Modulo, valore passato alla funzione modificaValore:10
Funzione modificaValore, valore passato:10
Funzione modificaValore, valore modificato:20
Modulo, valore dopo l'esecuzione della funzione modificaValore:20
 

Esempio 3

L'esempio seguente mostra che il passaggio per riferimento permette di copiare l'indirizzo di un array o di un oggetto nella variabile indicata come argomento. Attraverso il riferimento è possibile modificare direttamente il valore della variabile originale: 

 
 
// passaggio_per_riferimento.ts
function modificaValore(rifObjJson:{a:number}){
    console.log("Funzione modificaValore, valore passato:"+rifObjJson.a);
    //Modifico copiaDiA;
    rifObjJson.a=20;
    console.log("Funzione modificaValore, valore modificato:"+rifObjJson.a);
}
 
//Modulo
//Dichiarazione di una variabile in cui memorizzare il riferimento di 
//un oggetto di tipo Json
var objJson:{a:number};
//Creazione di un oggetto di tipo Json assegnando il valore 10 all'attributo a 
objJson={a:10}; 
console.log("Modulo, valore passato alla funzione modificaValore:"+objJson.a);
//Passo alla funzione il riferimento (indirizzo) dell'oggetto objJson.
modificaValore(objJson);
console.log("Modulo, valore dopo l'esecuzione della funzione modificaValore:"+objJson.a);
-----------------------------------------------------------------------------------------
Modulo, valore passato alla funzione modificaValore:10
Funzione modificaValore, valore passato:10
Funzione modificaValore, valore modificato:20
Modulo, valore dopo l'esecuzione della funzione modificaValore:20
 

 

FUNZIONI ANONIME

In TypeScript le funzioni possono essere passate  come argomenti ad altre funzioni, utilizzando il loro riferimento

In questo caso non passate un'informazione, ma un comportamento.

Una funzione che riceve in input il riferimento di una funzione viene chiamata funzione superiore.  

Le funzioni anonime sono funzioni che non hanno un nome e possono essere eseguite attraverso il loro riferimento.

Questo tipo di funzione può anche essere passata come argomento ad funzione superiore.

 L'esempio seguente mostra come si crea ed esegue una funzione anonima, utilizzando il metodo log che in questo caso è la funzione superiore.

 
var rifPerimetro=function (latoA:number,latoB:number,latoC:number):number {
    return latoA+latoB+latoC;
}
console.log(rifPerimetro(10,15,20));
----------------------------------------------------------------------------
45
 

 

FUNZIONI LAMBDA

Le funzioni lambda sono particolari tipi di funzioni anonime, quindi anch'esse possono essere passate  come argomenti alle funzione superiori.

La sintassi per creare le funzioni lambda è leggermente diversa da quella usata per le funzioni anonime, perché al posto della parola chiave function si usa l'operatore freccia "=>", come mostra l'esempio seguente:


var rifPerimetro=(latoA:number,latoB:number,latoC:number):number => {
    return latoA+latoB+latoC;
}
console.log(rifPerimetro(10,15,20));
---------------------------------------------------------------------------------------
45

Attenzione, le funzioni lambda e le funzioni anonime, se sono composte da una sola riga di comando, possono essere implementate senza usare le parentesi graffe e senza indicare il return, come mostra l'esempio seguente:


var rifPerimetro=(latoA:number,latoB:number,latoC:number):number => latoA+latoB+latoC;
console.log(rifPerimetro(10,15,20));
---------------------------------------------------------------------------------------
45
 

 

FUNZIONI RICORSIVE

In TypeScript le funzioni sono ricorsive, cioè possono chiamare se stesse. Questa caratteristica è molto importante perché la ricorsività permette di simulare il comportamento di un ciclo while al contrario. 

Per capire l'utilità della ricorsività delle funzioni facciamo alcuni  esempi.

Esempio 4

Visualizzare il contenuto di una array d'interi partendo dall'ultimo valore al primo.

A) Soluzione utilizzando un while.

//inverti_interi.ts
var interi:number[]=[2,10,25,8,80,30,70,5,15,90];
var indice:number=interi.length-1;
while(indice>=0){
    console.log(interi[indice]);
    indice--;
}
-----------------------------------------------------
90
15
5
70
30
80
8
25
10
2

B) Soluzione utilizzando una funzione ricorsiva.

 
//inverti_interi_ricorsivo.ts
function inverti_interi(indice:number){
  if(indice<interi.length-1){
      inverti_interi(indice+1);
   }
   console.log(indice+","+interi[indice]);
}
 
// main
var interi:number[]=[2,10,25,8,80,30,70,5,15,90];
inverti_interi(0);
-------------------------------------------------------
9,90
8,15
7,5
6,70
5,30
4,80
3,8
2,25
1,10
0,2
 

Esempio 5

Calcolare il fattoriale di un numero intero N.
Il fattoriale di un numero intero N è dato dal prodotto di tutti i valori compresi tra 1 ad N, ad esempio il fattoriale di 3 = 1 * 2 * 3 = 6.

 

A) Soluzione utilizzando un while.

 
//fattoriale_while.ts
function fattoriale(numero:number):number{
var totale=1;
while(numero>1){
    totale*=numero;
    numero--;
}
return totale;
}
// main
console.log(fattoriale(5));
-------------------------------------------------
120
 

B) Soluzione utilizzando una funzione ricorsiva.

 
//fattoriale.ts
function fattoriale(numero:number):number{
    if(numero>1){
        numero*=fattoriale(numero-1);
    }else {
        return 1;
    }
    return numero;
}
 
// main
console.log(fattoriale(5));
-------------------------------------------------
120
 

Attenzione, per convenzione, il fattoriale di 0 = 1.

 
//fattoriale.ts
function fattoriale(numero:number):number{
    if(numero>1){
        numero*=fattoriale(numero-1);
    }else {
        return 1;
    }
    return numero;
}
// main
console.log(fattoriale(0));
-------------------------------------------------
1
 
 

 

FUNZIONI CON ARGOMENTI OPZIONALI

In TypeScript si possono creare funzioni con argomenti opzionali, per rendere l'argomento di una funzione opzionale basta inserire un "?" dopo il nome dell'argomento, come mostra l'esempio seguente:

function infoFiguraGeometrica(tipoFigura:string, valoreUno:number,valoreDue?:number,valoreTre?:number){...} 

La dichiarazione della funzione  infoFiguraGeometrica  indica che gli argomenti tipoFigura:stringvaloreUno:number, sono obbligatori e gli argomenti valoreDue?:number,valoreTre?:number sono opzionali.

L'attributo length dell'interfaccia arguments permette do conoscere il numero di argomenti passati ad una funzione con argomenti opzionali. 

Esempio 6

 
// opzionali_01.ts
function infoFiguraGeometrica(tipoFigura:stringvaloreUno:number,valoreDue?:number,valoreTre?:number):void{
var scelta:number=arguments.length;
var perimetro:number,area:number;
// Controllo se tipoFigura è corretto altrimenti controllo se i valori sono maggiori
// di zero
// Scelta=5 imposta il default che corrisponde ad un errore
if(tipoFigura.toLowerCase()!="cerchio" && tipoFigura.toLowerCase()!="quadrato" && 
   tipoFigura.toLowerCase()!="rettangolo" && tipoFigura.toLowerCase()!="triangolo"){
       scelta=5;
}else if(arguments.length==2 && valoreUno<=0){
    scelta=5;
}else if(arguments.length==3 && (valoreUno<=0 || valoreDue<=0)){
    scelta=5
}else if(arguments.length==4 && (valoreUno<=0 || valoreDue<=0 || valoreTre<=0)){
    scelta=5
}
//Controllo se i lati del triangolo sono coerenti altrimenti imposto la scelta=5
if(scelta!=5 && arguments.length==4){
    if(valoreUno>=valoreDue+valoreTre || valoreUno<=valoreDue-valoreTre){
        scelta=5;
    } else if(valoreDue>=valoreUno+valoreTre || valoreDue<=valoreUno-valoreTre){
        scelta=5;
    } else if(valoreTre>=valoreDue+valoreUno || valoreTre<=valoreDue-valoreUno){
        scelta=5;
    } 
}
 
switch(scelta){
    case 2:
        if(tipoFigura.toLowerCase()=="cerchio"){
            perimetro=2*Math.PI*valoreUno;
            area=Math.pow(valoreUno,2)*Math.PI;
            console.log("Tipo figura:"+tipoFigura);
            console.log("Raggio     :"+valoreUno);
            console.log("Perimetro  :"+perimetro);
            console.log("Area       :"+area);
        }   else{
            perimetro=4*valoreUno;
            area=Math.pow(valoreUno,2);
            console.log("Tipo figura:"+tipoFigura);
            console.log("Lato       :"+valoreUno);
            console.log("Perimetro  :"+perimetro);
            console.log("Area       :"+area);
        }
        break;
    case 3:
        perimetro=(2*valoreUno)+(2*valoreDue);
        area=valoreUno*valoreDue;
        console.log("Tipo figura:"+tipoFigura);
        console.log("Lati       :"+valoreUno,valoreDue);
        console.log("Perimetro  :"+perimetro);
        console.log("Area       :"+area);
    break;
    case 4:
        perimetro=valoreUno+valoreDue+valoreTre;
        let sp=perimetro/2;
        area=Math.sqrt(sp*(sp-valoreUno)*(sp-valoreDue)*(sp-valoreTre));
        console.log("Tipo figura:"+tipoFigura);
        console.log("Lati       :"+valoreUno,valoreDue,valoreTre);
        console.log("Perimetro  :"+perimetro);
        console.log("Area       :"+area);
        break;
        default:
            console.log("Errore: Gli argomenti forniti alla funzione non sono esatti")
    } 
}
// main
console.log("----- Gestione Figure Geometriche -----");
infoFiguraGeometrica("Cerchio",10);
console.log("---------------------------------------");
infoFiguraGeometrica("Quadrato",20);
console.log("---------------------------------------");
infoFiguraGeometrica("Rettangolo",10,5);
console.log("---------------------------------------");
infoFiguraGeometrica("Triangolo",10,20,20);


----------------------------------------------------------------------

Tipo figura:Cerchio
Raggio     :10
Perimetro  :62.83185307179586
Area       :314.1592653589793
---------------------------------------
Tipo figura:Quadrato
Lato       :20
Perimetro  :80
Area       :400
---------------------------------------
Tipo figura:Rettangolo
Lati       :10 5
Perimetro  :30
Area       :50
---------------------------------------
Tipo figura:Triangolo
Lati       :10 20 20
Perimetro  :50
Area       :96.82458365518542

 

Un argomento opzionale a cui non viene passato nulla contiene il valore undefined, come mostra l'esempio seguente:

 
//opzionali_02.ts
function infoArgomenti(a?:number,b?:number){
    console.log("Argomenti:"+arguments.length)
    if(a==undefined && b==undefined){
      console.log("Non hai fornito argomenti");
      console.log("a=" +a);
      console.log("b=" +b);
  } else if (b==undefined){
        console.log("Hai fornito un solo argomento");
        console.log("a=" +a);
        console.log("b=" +b);
    } else{
        console.log("Hai fornito due argomenti");
        console.log("a=" +a);
        console.log("b=" +b);
    }
}
// main
infoArgomenti();
infoArgomenti(10);
infoArgomenti(10,20);
 
---------------------------------------------------------
Argomenti:0
Non hai fornito argomenti
a=undefined
b=undefined
Argomenti:1
Hai fornito due argomenti
a=10
b=undefined
Argomenti:2
Hai fornito due argomenti
a=10
b=20
 

 

Per passare ad una funzione con argomenti opzionali, gli argomenti richiesti, utilizzando i nomi degli argomenti,  dovete usare un'interfaccia e passare gli argomenti alla funzione con la notazione JSON, come mostra l'esempio seguente:

 
//opzionali_03.ts
interface Parametri{
    a?:number;
    b?:number;
}
function infoArgomenti(parametri:Parametri){
    if(parametri.a==undefined && parametri.b==undefined){
      console.log("Non hai fornito argomenti {}");
      console.log("a=" +parametri.a);
      console.log("b=" +parametri.b);
  } else if (parametri.a==undefined){
        console.log("Hai fornito un solo l'argomento a {b:20}");
        console.log("a=" +parametri.a);
        console.log("b=" +parametri.b);
    }else if (parametri.b==undefined){
        console.log("Hai fornito un solo l'argomento b {a:10}");
        console.log("a=" +parametri.a);
        console.log("b=" +parametri.b);
    } else{
        console.log("Hai fornito due argomenti {a:10,b:20}");
        console.log("a=" +parametri.a);
        console.log("b=" +parametri.b);
    }
}
// main
infoArgomenti({});
infoArgomenti({a:10});
infoArgomenti({b:20});
infoArgomenti({a:10,b:20});

---------------------------------------------------------------------
Non hai fornito argomenti {}
a=undefined
b=undefined
Hai fornito un solo l'argomento b {a:10}
a=10
b=undefined
Hai fornito un solo l'argomento a {b:20}
a=undefined
b=20
Hai fornito due argomenti {a:10,b:20}
a=10
b=20

 

 

FUNZIONI CON ARGOMENTI REST

In TypeScript un altro modo per creare funzioni con argomenti opzionali  è quello di utilizzare l'operatore "..." chiamato REST.  L'argomento preceduto dall'operatore REST diventa un array che contiene i valori di tutti gli argomenti passati, come mostrano gli esempi seguenti:

Esempio 7 

// opzionali_01_rest.ts
function infoFiguraGeometrica(tipoFigura:string, ...valori:number[]):void{
var scelta:number=valori.length;
var perimetro:number,area:number;
// Controllo se tipoFigura è corretto altrimenti controllo se i valori sono 
// maggiori di zero
// Scelta=5 imposta il default che corrisponde ad un errore
if(tipoFigura.toLowerCase()!="cerchio" && tipoFigura.toLowerCase()!="quadrato" && 
   tipoFigura.toLowerCase()!="rettangolo" && tipoFigura.toLowerCase()!="triangolo"){
       scelta=5;
}else if(valori.length==1 && valori[0]<=0){
    scelta=5;
}else if(valori.length==2 && (valori[0]<=0 || valori[1]<=0)){
    scelta=5
}else if(valori.length==3 && (valori[0]<=0 || valori[1]<=0 || valori[2]<=0)){
    scelta=5
}
//Controllo se i lati del triangolo sono coerenti altrimenti imposto la scelta=5
if(scelta!=5 && arguments.length==4){
    if(valori[0]>=valori[1]+valori[2] || valori[0]<=valori[1]-valori[2]){
        scelta=5;
    } else if(valori[1]>=valori[0]+valori[2] || valori[1]<=valori[0]-valori[2]){
        scelta=5;
    } else if(valori[2]>=valori[1]+valori[0] || valori[2]<=valori[1]-valori[0]){
        scelta=5;
    } 
}
 
switch(scelta){
    case 2:
        if(tipoFigura.toLowerCase()=="cerchio"){
            perimetro=2*Math.PI*valori[0];
            area=Math.pow(valori[0],2)*Math.PI;
            console.log("Tipo figura:"+tipoFigura);
            console.log("Raggio     :"+valori[0]);
            console.log("Perimetro  :"+perimetro);
            console.log("Area       :"+area);
        }   else{
            perimetro=4*valori[0];
            area=Math.pow(valori[0],2);
            console.log("Tipo figura:"+tipoFigura);
            console.log("Lato       :"+valori[0]);
            console.log("Perimetro  :"+perimetro);
            console.log("Area       :"+area);
        }
        break;
    case 3:
        perimetro=(2*valori[0])+(2*valori[1]);
        area=valori[0]*valori[1];
        console.log("Tipo figura:"+tipoFigura);
        console.log("Lati       :"+valori[0],valori[1]);
        console.log("Perimetro  :"+perimetro);
        console.log("Area       :"+area);
    break;
    case 4:
        perimetro=valori[0]+valori[1]+valori[2];
        let sp=perimetro/2;
        area=Math.sqrt(sp*(sp-valori[0])*(sp-valori[1])*(sp-valori[2]));
        console.log("Tipo figura:"+tipoFigura);
        console.log("Lati       :"+valori[0],valori[1],valori[2]);
        console.log("Perimetro  :"+perimetro);
        console.log("Area       :"+area);
        break;
        default:
            console.log("Errore: Gli argomenti forniti alla funzione non sono esatti")
    } 
}
// main
console.log("----- Gestione Figure Geometriche -----");
infoFiguraGeometrica("Cerchio",10);
console.log("---------------------------------------");
infoFiguraGeometrica("Quadrato",20);
console.log("---------------------------------------");
infoFiguraGeometrica("Rettangolo",10,5);
console.log("---------------------------------------");
infoFiguraGeometrica("Triangolo",10,20,20);

----------------------------------------------------------------------

Tipo figura:Cerchio
Raggio     :10
Perimetro  :62.83185307179586
Area       :314.1592653589793
---------------------------------------
Tipo figura:Quadrato
Lato       :20
Perimetro  :80
Area       :400
---------------------------------------
Tipo figura:Rettangolo
Lati       :10 5
Perimetro  :30
Area       :50
---------------------------------------
Tipo figura:Triangolo
Lati       :10 20 20
Perimetro  :50
Area       :96.82458365518542

 

Esempio 8

 
//rest.ts
class Persona{
    nome:string;
    cognome:string;
    luogoDiNascita:string;
    dataDiNascita:Date;
    sesso:boolean;
    toString():string{
        var gg:number=this.dataDiNascita.getDate(); 
        var mm:number=this.dataDiNascita.getMonth()+1;
        var aaaa:number=this.dataDiNascita.getFullYear();
        var dataValore=gg+"/"+mm+"/"+aaaa;
        var sessoValore:string="";
        if(this.sesso){
            sessoValore="Maschio";
        } else{
            sessoValore="Femmina"
        }
         return this.nome+","+this.cognome+","+this.luogoDiNascita+","+dataValore
                +","+sessoValore;
    }
    constructor(){} // In questo caso il costruttore non contiene codice d'inizializzazione
}
 
function infoArgomentiRest(...parametri:any[]){
    parametri.forEach(parametro =>{
        if(typeof parametro=="number"){
          console.log("number:"+parametro);
        }else if(typeof parametro=="string"){
            console.log("string:"+parametro);
        }else if(typeof parametro=="boolean"){
            console.log("boolean:"+parametro);            
        }else {
            console.log(typeof parametro+":"+parametro);
        }
    })
}
// main
var personaUno:Persona=new Persona();
personaUno.nome="Mario";
personaUno.cognome="Rossi";
personaUno.luogoDiNascita="Milano";
personaUno.dataDiNascita=new Date("12/5/1990");
personaUno.sesso=true;
infoArgomentiRest(10,10.5,"Rossi",true,personaUno);
 
-----------------------------------------------------------------
number:10
number:10.5
string:Rossi
boolean:true
object:Mario,Rossi,Milano,5/12/1990,Maschio
 
 

Nella prossima lezione iniziamo a parlare di Object Oriented in TypeScript, introducendo le Classi e gli Oggetti.


<< Lezione precedente           Lezione successiva >> | 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