diff options
Diffstat (limited to 'it-it')
-rw-r--r-- | it-it/go-it.html.markdown | 453 | ||||
-rw-r--r-- | it-it/markdown.html.markdown | 244 | ||||
-rw-r--r-- | it-it/matlab-it.html.markdown | 526 |
3 files changed, 1223 insertions, 0 deletions
diff --git a/it-it/go-it.html.markdown b/it-it/go-it.html.markdown new file mode 100644 index 00000000..e005f2dc --- /dev/null +++ b/it-it/go-it.html.markdown @@ -0,0 +1,453 @@ +--- +name: Go +language: Go +filename: learngo-it.go +contributors: + - ["Sonia Keys", "https://github.com/soniakeys"] + - ["Christopher Bess", "https://github.com/cbess"] + - ["Jesse Johnson", "https://github.com/holocronweaver"] + - ["Quint Guvernator", "https://github.com/qguv"] + - ["Jose Donizetti", "https://github.com/josedonizetti"] + - ["Alexej Friesen", "https://github.com/heyalexej"] + - ["Clayton Walker", "https://github.com/cwalk"] +translators: + - ["Tommaso Pifferi","http://github.com/neslinesli93"] +lang: it-it +--- + +Go è stato creato per avere tra le mani uno strumento in grado di arrivare +al punto, nel modo più veloce ed efficiente possibile. Non è all'ultima +moda tra i linguaggi di programmazione, ma è una delle migliori soluzioni +per risolvere in maniera efficace i problemi di tutti i giorni. + +Go presenta alcuni concetti già presenti nei linguaggi imperativi con +tipizzazione statica. Compila velocemente ed esegue altrettanto veloce. +Aggiunge la concorrenza in maniera diretta e semplice da capire, per far +forza sulle CPU multi-core di oggigiorno. Presenta caratteristiche utili +per la programmazione in larga scala. + +Go comes with a great standard library and an enthusiastic community. + +```go +// Commento su riga singola +/* Commento + su riga multipla */ + +// In cima a ogni file è necessario specificare il package. +// Main è un package speciale che identifica un eseguibile anziché una libreria. +package main + +// Con import sono dichiarate tutte le librerie a cui si fa riferimento +// all'interno del file. +import ( + "fmt" // Un package nella libreria standard di Go. + "io/ioutil" // Implementa alcune funzioni di utility per l'I/O. + m "math" // Libreria matematica, con alias locale m + "net/http" // Sì, un web server! + "strconv" // Package per la conversione di stringhe. +) + +// Una definizione di funzione. Il main è speciale: è il punto di ingresso +// per il programma. Amalo o odialo, ma Go usa le parentesi graffe. +func main() { + // Println stampa una riga a schermo. + // Questa funzione è all'interno del package fmt. + fmt.Println("Ciao mondo!") + + // Chiama un'altra funzione all'interno di questo package. + oltreIlCiaoMondo() +} + +// Le funzioni ricevono i parametri all'interno di parentesi tonde. +// Se la funzione non riceve parametri, vanno comunque messe le parentesi (vuote). +func oltreIlCiaoMondo() { + var x int // Dichiarazione di una variabile. Ricordati di dichiarare sempre le variabili prima di usarle! + x = 3 // Assegnazione di una variabile. + // E' possibile la dichiarazione "rapida" := per inferire il tipo, dichiarare e assegnare contemporaneamente. + y := 4 + // Una funzione che ritorna due valori. + somma, prod := imparaMoltepliciValoriDiRitorno(x, y) + fmt.Println("somma:", somma, "prodotto:", prod) // Semplice output. + imparaTipi() // < y minuti, devi imparare ancora! +} + +/* <- commento su righe multiple +Le funzioni possono avere parametri e ritornare (molteplici!) valori. +Qua, x e y sono gli argomenti, mentre somma e prod sono i valori ritornati. +Da notare il fatto che x e somma vengono dichiarati come interi. +*/ +func imparaMoltepliciValoriDiRitorno(x, y int) (somma, prod int) { + return x + y, x * y // Ritorna due valori. +} + +// Ecco alcuni tipi presenti in Go +func imparaTipi() { + // La dichiarazione rapida di solito fa il suo lavoro. + str := "Impara il Go!" // Tipo stringa. + + s2 := `Una stringa letterale +puo' includere andata a capo.` // Sempre di tipo stringa. + + // Stringa letterale non ASCII. I sorgenti Go sono in UTF-8. + g := 'Σ' // Il tipo runa, alias per int32, è costituito da un code point unicode. + + f := 3.14195 // float64, un numero in virgola mobile a 64-bit (IEEE-754) + + c := 3 + 4i // complex128, rappresentato internamente con due float64. + + // Inizializzare le variabili con var. + var u uint = 7 // Senza segno, ma la dimensione dipende dall'implementazione (come l'int) + var pi float32 = 22. / 7 + + // Sintassi per la conversione. + n := byte('\n') // Il tipo byte è un alias per uint8. + + // I vettori hanno dimensione fissa, stabilita durante la compilazione. + var a4 [4]int // Un vettore di 4 interi, tutti inizializzati a 0. + a3 := [...]int{3, 1, 5} // Un vettore inizializzato con una dimensione fissa pari a 3, i cui elementi sono 3, 1 e 5. + + // Gli slice hanno dimensione variabile. Vettori e slice hanno pro e contro, + // ma generalmente si tende a usare più spesso gli slice. + s3 := []int{4, 5, 9} // La differenza con a3 è che qua non ci sono i 3 punti all'interno delle parentesi quadre. + s4 := make([]int, 4) // Alloca uno slice di 4 interi, tutti inizializzati a 0. + var d2 [][]float64 // Semplice dichiarazione, non vengono fatte allocazioni. + bs := []byte("uno slice") // Sintassi per la conversione. + + // Poiché gli slice sono dinamici, è possibile aggiungere elementi + // quando è necessario. Per farlo, si usa la funzione append(). Il primo + // argomento è lo slice a cui stiamo aggiungendo elementi. Di solito + // lo slice viene aggiornato, senza fare una copia, come nell'esempio: + s := []int{1, 2, 3} // Il risultato è uno slice di dimensione 3. + s = append(s, 4, 5, 6) // Aggiunge 3 elementi: lo slice ha dimensione 6. + fmt.Println(s) // Lo slice aggiornato è [1 2 3 4 5 6] + // Per aggiungere un altro slice, invece che elencare gli elementi uno ad + // uno, è possibile passare alla funzione append un riferimento ad uno + // slice, oppure uno slice letterale: in questo caso si usano i tre punti, + // dopo lo slice, a significare "prendi ciascun elemento dello slice": + s = append(s, []int{7, 8, 9}...) // Il secondo argomento è uno slice letterale. + fmt.Println(s) // Lo slice aggiornato è [1 2 3 4 5 6 7 8 9] + + p, q := imparaLaMemoria() // Dichiara due puntatori a intero: p e q. + fmt.Println(*p, *q) // * dereferenzia un puntatore. Questo stampa due interi. + + // Una variabile di tipo map è un vettore associativo di dimensione variabile, + // e funzionano come le tabelle di hash o i dizionari in altri linguaggi. + m := map[string]int{"tre": 3, "quattro": 4} + m["uno"] = 1 + + // Le variabili dichiarate e non usate sono un errore in Go. + // L'underscore permette di "usare" una variabile, scartandone il valore. + _, _, _, _, _, _, _, _, _, _ = str, s2, g, f, u, pi, n, a3, s4, bs + // Stampare a schermo ovviamente significa usare una variabile. + fmt.Println(s, c, a4, s3, d2, m) + + imparaControlloDiFlusso() // Torniamo in carreggiata. +} + +// In Go è possibile associare dei nomi ai valori di ritorno di una funzione. +// Assegnare un nome al tipo di dato ritornato permette di fare return in vari +// punti all'interno del corpo della funzione, ma anche di usare return senza +// specificare in modo esplicito che cosa ritornare. +func imparaValoriDiRitornoConNome(x, y int) (z int) { + z = x * y + return // z è implicito, perchè compare nella definizione di funzione. +} + +// Go è dotato di garbage collection. Ha i puntatori, ma non l'aritmetica dei +// puntatori. Puoi fare errori coi puntatori a nil, ma non puoi direttamente +// incrementare un puntatore. +func imparaLaMemoria() (p, q *int) { + // I valori di ritorno (con nome) p e q sono puntatori a int. + p = new(int) // La funzione new si occupa di allocare memoria. + // L'int allocato viene inizializzato a 0, dunque p non è più nil. + s := make([]int, 20) // Alloca 20 int come un singolo blocco di memoria. + s[3] = 7 // Ne assegna uno. + r := -2 // Dichiara un'altra variabile locale + return &s[3], &r // & "prende" l'indirizzo di un oggetto. +} + +func calcoloCostoso() float64 { + return m.Exp(10) +} + +func imparaControlloDiFlusso() { + // L'istruzione if richiede parentesi graffe per il corpo, mentre non ha + // bisogno di parentesi tonde per la condizione. + if true { + fmt.Println("te l'ho detto") + } + // Eseguendo "go fmt" da riga di comando, il codice viene formattato + // in maniera standard. + if false { + // :( + } else { + // :D + } + // L'istruzione switch serve ad evitare tanti if messi in cascata. + x := 42.0 + switch x { + case 0: + case 1: + case 42: + // Quando è soddisfatta la condizione all'interno di un case, il + // programma esce dal switch senza che siano specificate istruzioni + // di tipo "break". In Go infatti di default non è presente il + // cosiddetto "fall through" all'interno dell'istruzione switch. + // Tuttavia, il linguaggio mette a disposizione la parola chiave + // fallthrough per permettere, in casi particolari, questo comportamento. + case 43: + // Non si arriva qua. + default: + // Il caso di default è opzionale. + } + // Come l'if, anche il for non usa parentesi tonde per la condizione. + // Le variabili dichiarate all'interno di if/for sono locali al loro scope. + for x := 0; x < 3; x++ { // ++ è un'istruzione! + fmt.Println("ciclo numero", x) + } + // x == 42 qua. + + // Il for è l'unica istruzione per ciclare in Go, ma ha varie forme. + for { // Ciclo infinito. + break // Scherzavo. + continue // Non si arriva qua. + } + + // Puoi usare range per ciclare su un vettore, slice, stringa, mappa o canale. + // range ritorna uno (per i canali) o due valori (vettore, slice, stringa, mappa). + for chiave, valore := range map[string]int{"uno": 1, "due": 2, "tre": 3} { + // per ogni coppia dentro la mappa, stampa chiave e valore + fmt.Printf("chiave=%s, valore=%d\n", chiave, valore) + } + + // Come nel for, := dentro la condizione dell'if è usato per dichiarare + // e assegnare y, poi testare se y > x. + if y := calcoloCostoso(); y > x { + x = y + } + // Le funzioni letterali sono closure. + xGrande := func() bool { + return x > 10000 // Si riferisce a x dichiarata sopra al switch (vedi sopra). + } + fmt.Println("xGrande:", xGrande()) // true (abbiamo assegnato e^10 a x). + x = 1.3e3 // Adesso x == 1300 + fmt.Println("xGrande:", xGrande()) // false ora. + + // Inoltre le funzioni letterali possono essere definite e chiamate + // inline, col ruolo di parametri di funzione, a patto che: + // a) la funzione letterale venga chiamata subito (), + // b) il valore ritornato è in accordo con il tipo dell'argomento. + fmt.Println("Somma e raddoppia due numeri: ", + func(a, b int) int { + return (a + b) * 2 + }(10, 2)) // Chiamata con argomenti 10 e 2 + // => Somma e raddoppia due numeri: 24 + + // Quando ti servirà, lo amerai. + goto amore +amore: + + imparaFabbricaDiFunzioni() // Una funzione che ritorna un'altra funzione è divertente! + imparaDefer() // Un tour veloce di una parola chiave importante. + imparaInterfacce() // Arriva la roba buona! +} + +func imparaFabbricaDiFunzioni() { + // Questi due blocchi di istruzioni sono equivalenti, ma il secondo è più semplice da capire. + fmt.Println(fabbricaDiFrasi("estate")("Una bella giornata", "giornata!")) + + d := fabbricaDiFrasi("estate") + fmt.Println(d("Una bella", "giornata!")) + fmt.Println(d("Un pigro", "pomeriggio!")) +} + +// I decoratori sono comuni in alcuni linguaggi. Si può fare lo stesso in Go +// con le funzioni letterali che accettano argomenti. +func fabbricaDiFrasi(miaStringa string) func(prima, dopo string) string { + return func(prima, dopo string) string { + return fmt.Sprintf("%s %s %s", prima, miaStringa, dopo) // Nuova stringa + } +} + +func imparaDefer() (ok bool) { + // Le istruzioni dette "deferred" (rinviate) sono eseguite + // appena prima che la funzione ritorni. + defer fmt.Println("le istruzioni 'deferred' sono eseguite in ordine inverso (LIFO).") + defer fmt.Println("\nQuesta riga viene stampata per prima perché") + // defer viene usato di solito per chiudere un file, così la funzione che + // chiude il file viene messa vicino a quella che lo apre. + return true +} + +// Definisce Stringer come un'interfaccia con un metodo, String. +type Stringer interface { + String() string +} + +// Definisce coppia come una struct con due campi interi, chiamati x e y. +type coppia struct { + x, y int +} + +// Definisce un metodo sul tipo coppia, che adesso implementa Stringer. +func (p coppia) String() string { // p viene definito "ricevente" + // Sprintf è un'altra funzione del package ftm. + // La notazione con il punto serve per richiamare i campi di p. + return fmt.Sprintf("(%d, %d)", p.x, p.y) +} + +func imparaInterfacce() { + // Brace syntax is a "struct literal". It evaluates to an initialized + // struct. The := syntax declares and initializes p to this struct. + // Le parentesi graffe sono usate per le cosiddette "struct letterali". + // Con :=, p viene dichiarata e inizializzata a questa struct. + p := coppia{3, 4} + fmt.Println(p.String()) // Chiama il metodo String di p, che è di tipo coppia. + var i Stringer // Dichiara i come interfaccia Stringer. + i = p // Valido perchè coppia implementa Stringer. + // Chiama il metodo String di i, che è di tipo Stringer. Output uguale a sopra. + fmt.Println(i.String()) + + // Functions in the fmt package call the String method to ask an object + // for a printable representation of itself. + // Le funzioni dentro al package fmt chiamano il metodo String per + // chiedere ad un oggetto una rappresentazione in stringhe di sé stesso. + fmt.Println(p) // Output uguale a sopra. Println chiama il metodo String. + fmt.Println(i) // Output uguale a sopra. + + imparaParametriVariadici("grande", "imparando", "qua!") +} + +// Le funzioni possono avere parametri variadici (ovvero di lunghezza variabile). +func imparaParametriVariadici(mieStringhe ...interface{}) { + // Cicla su ogni valore variadico. + // L'underscore serve a ignorare l'indice del vettore. + for _, param := range mieStringhe { + fmt.Println("parametro:", param) + } + + // Passa un valore variadico come parametro variadico. + fmt.Println("parametri:", fmt.Sprintln(mieStringhe...)) + + imparaGestioneErrori() +} + +func imparaGestioneErrori() { + // La sintassi ", ok" è usata per indicare se qualcosa ha funzionato o no. + m := map[int]string{3: "tre", 4: "quattro"} + if x, ok := m[1]; !ok { // ok sarà false perchè 1 non è dentro la mappa. + fmt.Println("qua non c'è nessuno!") + } else { + fmt.Print(x) // x sarebbe il valore che corrisponde alla chiave 1, se fosse nella mappa. + } + // Un errore non riporta soltanto "ok" ma è più specifico riguardo al problema. + if _, err := strconv.Atoi("non_intero"); err != nil { // _ scarta il valore + // stampa 'strconv.ParseInt: parsing "non_intero": invalid syntax' + fmt.Println(err) + } + // Approfondiremo le interfacce un'altra volta. Nel frattempo, + imparaConcorrenza() +} + +// c è un canale, un oggetto per comunicare in modo concorrente e sicuro. +func inc(i int, c chan int) { + c <- i + 1 // <- è l'operatore di "invio" quando un canale sta a sinistra. +} + +// Useremo inc per incrementare alcuni numeri in modo concorrente. +func imparaConcorrenza() { + // Stessa funzione usata prima per creare uno slice. Make alloca e + // inizializza slice, mappe e canali. + c := make(chan int) + // Lancia tre goroutine. I numeri saranno incrementati in modo concorrente, + // forse in parallelo se la macchina lo supporta. Tutti e tre inviano dati + // sullo stesso canale. + go inc(0, c) // go è un'istruzione che avvia una goroutine. + go inc(10, c) + go inc(-805, c) + // Legge tre risultati dal canale e li stampa a schermo. + // Non si conosce a priori l'ordine in cui i risultati arriveranno! + fmt.Println(<-c, <-c, <-c) // <- è l'operatore di "ricevuta" quando + // un canale sta a destra. + + cs := make(chan string) // Un altro canale, gestisce le stringhe. + ccs := make(chan chan string) // Un canale che gestisce canali di stringhe. + go func() { c <- 84 }() // Lancia una goroutine, solo per inviare un valore. + go func() { cs <- "parolina" }() // Stessa cosa ma per cs. + // select è simile a switch, ma ogni case riguarda un'operazione su un + // canale. Seleziona, in modo random, uno tra i canali che sono pronti + // a comunicare. + select { + case i := <-c: // Il valore ricevuto può essere assegnato a una variabile, + fmt.Printf("E' un %T", i) + case <-cs: // oppure il valore ricevuto può essere scartato. + fmt.Println("E' una stringa.") + case <-ccs: // Canale vuoto, non pronto per comunicare. + fmt.Println("Non succede niente.") + } + // A questo punto un valore è stato preso da c o cs. Una delle tue goroutine + // cominciate sopra ha completato l'esecuzione, l'altra rimarrà bloccata. + + imparaProgrammazioneWeb() // Se lo fa Go, lo puoi fare anche tu. +} + +// Una funzione all'interno del package http avvia un webserver. +func imparaProgrammazioneWeb() { + + // Il primo parametro di ListenAndServe è l'indirizzo TCP su cui ascoltare. + // Il secondo parametro è un'interfaccia, precisamente http.Handler. + go func() { + err := http.ListenAndServe(":8080", coppia{}) + fmt.Println(err) // Non ignorare gli errori. + }() + + richiediServer() +} + +// Per rendere coppia un http.Handler basta implementare il metodo ServeHTTP. +func (p coppia) ServeHTTP(w http.ResponseWriter, r *http.Request) { + // Il server fornisce dati con un metodo di http.ResponseWriter. + w.Write([]byte("Hai imparato Go in Y minuti!")) +} + +func richiediServer() { + risposta, err := http.Get("http://localhost:8080") + fmt.Println(err) + defer risposta.Body.Close() + corpo, err := ioutil.ReadAll(risposta.Body) + fmt.Printf("\nIl webserver dice: `%s`", string(corpo)) +} +``` + +## Letture consigliate + +La risorsa più importante per imparare il Go è il [sito ufficiale di Go](http://golang.org/). +Qui puoi seguire i tutorial, scrivere codice in modo interattivo, e leggere tutti i dettagli. +Oltre al tour, [la documentazione](https://golang.org/doc/) contiene informazioni su +come scrivere ottimo codice in Go, documentazione sui package e sui comandi, e +la cronologia delle release. + +Anche il documento che definisce il linguaggio è un'ottima lettura. E' semplice +da leggere e incredibilmente corto (rispetto ad altri documenti riguardanti +la creazione di linguaggi). + +Puoi giocare con il codice visto finora nel [Go playground](https://play.golang.org/p/Am120Xe7qf). +Prova a cambiarlo e ad eseguirlo dal browser! +Osserva che puoi usare [https://play.golang.org](https://play.golang.org) come +una [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) per scrivere +codice all'interno del browser, senza neanche installare Go! + +Una lettura importante per capire Go in modo più profondo è il [codice +sorgente della libreria standard](http://golang.org/src/pkg/). Infatti è +molto ben documentato e costituisce quanto più chiaro e conciso ci sia riguardo +gli idiomi e le buone pratiche del Go. Inoltre, clickando sul nome di una +funzione [nella documentazione](http://golang.org/pkg/) compare il relativo +codice sorgente! + +Un'altra ottima risorsa per imparare è [Go by example](https://gobyexample.com/). + +Go Mobile aggiunge il supporto per lo sviluppo mobile (Android e iOS). +In questo modo è possibile scrivere un'app mobile nativa in Go, oppure +una libreria che contiene binding da un package scritto in Go, e che può +essere richiamata da Java(Android) e Objective-C(iOS). Visita la pagina di +[Go Mobile](https://github.com/golang/go/wiki/Mobile) per maggiori informazioni. diff --git a/it-it/markdown.html.markdown b/it-it/markdown.html.markdown new file mode 100644 index 00000000..b006dbb4 --- /dev/null +++ b/it-it/markdown.html.markdown @@ -0,0 +1,244 @@ +--- +language: markdown +contributors: + - ["Dan Turkel", "http://danturkel.com/"] +translators: + - ["Jacopo Andrea Giola", "http://geekpanda.net"] +filename: markdown-it.md +lang: it-it +--- + +Markdown è stato creato da John Gruber nel 2004. Il suo scopo è quello di essere una sintassi facile da leggere e scrivere, e che può essere convertita in HTML (ad oggi anche in molti altri formati). + +Mandate tutto il feedback che volete! / Sentitevi liberi di forkare o di mandare pull request! + + +```markdown +<!-- Markdown è un superset di HTML, quindi ogni file HTML è a sua volta un file Markdown valido. Questo significa che possiamo usare elementi di HTML in Markdown, come per esempio i commenti, e questi non saranno modificati dal parser di Markdown. State attenti però, se inserite un elemento HTML nel vostro file Markdown, non potrete usare la sua sintassi all'interno del contenuto dell'elemento. --> + +<!-- L'implementazione di Markdown inoltre cambia da parser a parser. In questa guida cercheremo di indicare quando una feature è universale e quando sono specifiche ad un certo parser. --> + +<!-- Titoli --> +<!-- Potete creare gli elementi HTML da <h1> ad <h6> facilmente, basta che inseriate un egual numero di caratteri cancelletto (#) prima del testo che volete all'interno dell'elemento --> +# Questo è un <h1> +## Questo è un <h2> +### Questo è un <h3> +#### Questo è un <h4> +##### Questo è un <h5> +###### Questo è un <h6> + +<!-- Markdown inoltre fornisce due alternative per indicare gli elementi h1 e h2 --> +Questo è un h1 +============== + +Questo è un h2 +-------------- + +<!-- Stili di testo semplici --> +<!-- Il testo può essere stilizzato in corsivo o grassetto usando markdown --> + +*Questo testo è in corsivo.* +_Come pure questo._ + +**Questo testo è in grassetto.** +__Come pure questo.__ + +***Questo testo è stilizzato in entrabmi i modi.*** +**_Come questo!_** +*__E questo!__* + +<!-- In Github Flavored Markdown, che è utilizzato per renderizzare i file markdown su +Github, è presente anche lo stile barrato --> + +~~Questo testo è barrato.~~ + +<!-- I paragrafi sono uno o più linee di testo addiacenti separate da una o più righe vuote. --> + +Qeusto è un paragrafo. Sto scrivendo in un paragrafo, non è divertente? + +Ora sono nel paragrafo 2. +Anche questa linea è nel paragrafo 2! + + +Qui siamo nel paragrafo 3! + +<!-- Se volete inserire l'elemento HTML <br />, potete terminare la linea con due o più spazi e poi iniziare un nuovo paragrafo. --> + +Questa frase finisce con due spazi (evidenziatemi per vederli). + +C'è un <br /> sopra di me! + +<!-- Le citazioni sono semplici da inserire, basta usare il carattere >. --> + +> Questa è una citazione. Potete +> mandare a capo manualmente le linee e inserire un `>` prima di ognuna, oppure potete usare una sola linea e lasciare che vada a capo automaticamente. +> Non c'è alcuna differenza, basta che iniziate ogni riga con `>`. + +> Potete utilizzare anche più di un livello +>> di indentazione! +> Quanto è comodo? + +<!-- Liste --> +<!-- Le liste non ordinate possono essere inserite usando gli asterischi, il simbolo più o dei trattini --> + +* Oggetto +* Oggetto +* Altro oggetto + +oppure + ++ Oggetto ++ Oggetto ++ Un altro oggetto + +oppure + +- Oggetto +- Oggetto +- Un ultimo oggetto + +<!-- Le liste ordinate invece, sono inserite con un numero seguito da un punto. --> + +1. Primo oggetto +2. Secondo oggetto +3. Terzo oggetto + +<!-- Non dovete nemmeno mettere i numeri nell'ordine giusto, markdown li visualizzerà comunque nell'ordine corretto, anche se potrebbe non essere una buona idea. --> + +1. Primo oggetto +1. Secondo oggetto +1. Terzo oggetto +<!-- (Questa lista verrà visualizzata esattamente come quella dell'esempio prima) --> + +<!-- Potete inserire anche sotto liste --> + +1. Primo oggetto +2. Secondo oggetto +3. Terzo oggetto + * Sotto-oggetto + * Sotto-oggetto +4. Quarto oggetto + +<!-- Sono presenti anche le task list. In questo modo è possibile creare checkbox in HTML. --> + +I box senza la 'x' sono checkbox HTML ancora da completare. +- [ ] Primo task da completare. +- [ ] Secondo task che deve essere completato. +Il box subito sotto è una checkbox HTML spuntata. +- [x] Questo task è stato completato. + +<!-- Estratti di codice --> +<!-- Potete inserire un estratto di codice (che utilizza l'elemento <code>) indentando una linea con quattro spazi oppure con un carattere tab --> + + Questa è una linea di codice + Come questa + +<!-- Potete inoltre inserire un altro tab (o altri quattro spazi) per indentare il vostro codice --> + + my_array.each do |item| + puts item + end + +<!-- Codice inline può essere inserito usando il carattere backtick ` --> + +Giovanni non sapeva neppure a cosa servisse la funzione `go_to()`! + +<!-- In Github Flavored Markdown, potete inoltre usare una sintassi speciale per il codice --> + +\`\`\`ruby <!-- In realtà dovete rimuovere i backslash, usate solo ```ruby ! --> +def foobar + puts "Hello world!" +end +\`\`\` <!-- Anche qui, niente backslash, solamente ``` --> + +<!-- Se usate questa sintassi, il testo non richiederà di essere indentanto, inoltre Github userà la syntax highlighting del linguaggio specificato dopo i ``` iniziali --> + +<!-- Linea orizzontale (<hr />) --> +<!-- Le linee orizzontali sono inserite facilemtne usanto tre o più asterischi o trattini senza spazi consecutivi e senza spazi. --> + +*** +--- +- - - +**************** + +<!-- Link --> +<!-- Una delle funzionalità migliori di markdown è la facilità con cui si possono inserire i link. Mettete il testo da visualizzare fra parentesi quadre [] seguite dall'url messo fra parentesi tonde () --> + +[Cliccami!](http://test.com/) + +<!-- Potete inoltre aggiungere al link un titolo mettendolo fra doppie apici dopo il link --> + +[Cliccami!](http://test.com/ "Link a Test.com") + +<!-- La sintassi funziona anche i path relativi. --> + +[Vai a musica](/music/). + +<!-- Markdown supporta inoltre anche la possibilità di aggiungere i link facendo riferimento ad altri punti del testo --> + +[Apri questo link][link1] per più informazioni! +[Guarda anche questo link][foobar] se ti va. + +[link1]: http://test.com/ "Bello!" +[foobar]: http://foobar.biz/ "Va bene!" + +<!-- Il titolo può anche essere inserito in apici singoli o in parentesi, oppure omesso interamente. Il riferimento può essere inserito in un punto qualsiasi del vostro documento e l'identificativo del riferimento può essere lungo a piacere a patto che sia univoco. --> + +<!-- Esiste anche un "identificativo implicito" che vi permette di usare il testo del link come id --> + +[Questo][] è un link. + +[Questo]: http://thisisalink.com/ + +<!-- Ma non è comunemente usato. --> + +<!-- Immagini --> +<!-- Le immagini sono inserite come i link ma con un punto esclamativo inserito prima delle parentesi quadre! --> + +![Qeusto è il testo alternativo per l'immagine](http://imgur.com/myimage.jpg "Il titolo opzionale") + +<!-- E la modalità a riferimento funziona esattamente come ci si aspetta --> + +![Questo è il testo alternativo.][myimage] + +[myimage]: relative/urls/cool/image.jpg "Se vi serve un titolo, lo mettete qui" + +<!-- Miscellanea --> +<!-- Auto link --> + +<http://testwebsite.com/> è equivalente ad +[http://testwebsite.com/](http://testwebsite.com/) + +<!-- Auto link per le email --> + +<foo@bar.com> + +<!-- Caratteri di escaping --> + +Voglio inserire *questo testo circondato da asterischi* ma non voglio che venga renderizzato in corsivo, quindi lo inserirò così: \*questo testo è circondato da asterischi\*. + +<!-- Combinazioni di tasti --> +<!-- In Github Flavored Markdown, potete utilizzare il tag <kbd> per raffigurare i tasti della tastiera --> + +Il tuo computer è crashato? Prova a premere +<kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Canc</kbd> + +<!-- Tabelle --> +<!-- Le tabelle sono disponibili solo in Github Flavored Markdown e sono leggeremente complesse, ma se proprio volete inserirle fate come segue: --> + +| Col1 | Col2 | Col3 | +| :------------------- | :------: | -----------------: | +| Allineato a sinistra | Centrato | Allineato a destra | +| blah | blah | blah | + +<!-- oppure, per lo stesso risultato --> + +Col 1 | Col2 | Col3 +:-- | :-: | --: +È una cosa orrenda | fatela | finire in fretta + +<!-- Finito! --> + +``` + +Per altre informazioni, leggete il post ufficiale di John Gruber sulla sintassi [qui](http://daringfireball.net/projects/markdown/syntax) e il magnifico cheatsheet di Adam Pritchard [qui](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet). diff --git a/it-it/matlab-it.html.markdown b/it-it/matlab-it.html.markdown new file mode 100644 index 00000000..aeb42658 --- /dev/null +++ b/it-it/matlab-it.html.markdown @@ -0,0 +1,526 @@ +--- +language: Matlab +contributors: + - ["mendozao", "http://github.com/mendozao"] + - ["jamesscottbrown", "http://jamesscottbrown.com"] + - ["Colton Kohnke", "http://github.com/voltnor"] +translators: + - ["Samuele Gallerani", "http://github.com/fontealpina"] +lang: it-it +filename: matlab-it.md +--- + +MATLAB sta per MATrix LABoratory ed è un potente linguaggio per il calcolo numerico comunemente usato in ingegneria e matematica. + +```matlab +% I commenti iniziano con il segno percentuale. + +%{ +I commenti multilinea +assomigliano a +qualcosa +del genere +%} + +% i comandi possono essere spezzati su più linee, usando '...': + a = 1 + 2 + ... + + 4 + +% i comandi possono essere passati al sistema operativo +!ping google.com + +who % Mostra tutte le variabili in memoria +whos % Mostra tutte le variabili in memoria, con i loro tipi +clear % Cancella tutte le tue variabili dalla memoria +clear('A') % Cancella una particolare variabile +openvar('A') % Apre la variabile in un editor di variabile + +clc % Cancella il contenuto della Command Window +diary % Attiva il log della Command Window su file +ctrl-c % Interrompe il calcolo corrente + +edit('myfunction.m') % Apre la funzione/script nell'editor +type('myfunction.m') % Stampa il codice della funzione/script sulla Command Window + +profile on % Attiva la profilazione del codice +profile off % Disattiva la profilazione del codice +profile viewer % Apre il profilatore + +help comando % Mostra la documentazione di comando sulla Command Window +doc comando % Mostra la documentazione di comando sulla Help Window +lookfor comando % Cerca comando nella prima linea di commento di tutte le funzioni +lookfor comando -all % Cerca comando in tutte le funzioni + + +% Formattazione dell'output +format short % 4 decimali in un numero float +format long % 15 decimali +format bank % Solo due cifre decimali - per calcoli finaziari +fprintf('text') % Stampa "text" a terminale +disp('text') % Stampa "text" a terminale + +% Variabili ed espressioni +miaVariabile = 4 % Il pannello Workspace mostra la nuova variabile creata +miaVariabile = 4; % Il punto e virgola evita che l'output venga stampato sulla Command Window +4 + 6 % ans = 10 +8 * myVariable % ans = 32 +2 ^ 3 % ans = 8 +a = 2; b = 3; +c = exp(a)*sin(pi/2) % c = 7.3891 + +% La chiamata di funzioni può essere fatta in due modi differenti: +% Sintassi standard di una funzione: +load('myFile.mat', 'y') % argomenti tra parentesi, separati da virgole +% Sintassi di tipo comando: +load myFile.mat y % Non ci sono parentesi e gli argometi sono separati da spazi +% Notare la mancanza di apici nella sintassi di tipo comando: gli input sono sempre passati come +% testo letterale - non è possibile passare valori di variabili. Inoltre non può ricevere output: +[V,D] = eig(A); % Questa non ha una forma equivalente con una sintassi di tipo comando +[~,D] = eig(A); % Se si vuole solo D e non V + + + +% Operatori logici +1 > 5 % ans = 0 +10 >= 10 % ans = 1 +3 ~= 4 % Not equal to -> ans = 1 +3 == 3 % equal to -> ans = 1 +3 > 1 && 4 > 1 % AND -> ans = 1 +3 > 1 || 4 > 1 % OR -> ans = 1 +~1 % NOT -> ans = 0 + +% Gli operatori logici possono essere applicati alle matrici: +A > 5 +% Per ogni elemento, se la condizione è vera, quell'elemento vale 1 nella matrice risultante +A( A > 5 ) +% Restituisce un vettore contenente gli elementi in A per cui la condizione è vera + +% Stringhe +a = 'MyString' +length(a) % ans = 8 +a(2) % ans = y +[a,a] % ans = MyStringMyString + + +% Celle +a = {'one', 'two', 'three'} +a(1) % ans = 'one' - ritorna una cella +char(a(1)) % ans = one - ritorna una stringa + +% Strutture +A.b = {'one','two'}; +A.c = [1 2]; +A.d.e = false; + +% Vettori +x = [4 32 53 7 1] +x(2) % ans = 32, gli indici in Matlab iniziano da 1, non da 0 +x(2:3) % ans = 32 53 +x(2:end) % ans = 32 53 7 1 + +x = [4; 32; 53; 7; 1] % Vettore colonna + +x = [1:10] % x = 1 2 3 4 5 6 7 8 9 10 + +% Matrici +A = [1 2 3; 4 5 6; 7 8 9] +% Le righe sono separate da punto e virgola, mentre gli elementi sono separati da spazi +% A = + +% 1 2 3 +% 4 5 6 +% 7 8 9 + +A(2,3) % ans = 6, A(row, column) +A(6) % ans = 8 +% (implicitamente concatena le colonne in un vettore, e quindi gli indici sono riferiti al vettore) + + +A(2,3) = 42 % Aggiorna riga 2 colonna 3 con 42 +% A = + +% 1 2 3 +% 4 5 42 +% 7 8 9 + +A(2:3,2:3) % Crea una nuova matrice a partire da quella precedente +%ans = + +% 5 42 +% 8 9 + +A(:,1) % Tutte le righe nella colonna 1 +%ans = + +% 1 +% 4 +% 7 + +A(1,:) % Tutte le colonne in riga 1 +%ans = + +% 1 2 3 + +[A ; A] % Concatenazione di matrici (verticalmente) +%ans = + +% 1 2 3 +% 4 5 42 +% 7 8 9 +% 1 2 3 +% 4 5 42 +% 7 8 9 + +% è equivalente a +vertcat(A,A); + + +[A , A] % Concatenazione di matrici (orrizontalmente) + +%ans = + +% 1 2 3 1 2 3 +% 4 5 42 4 5 42 +% 7 8 9 7 8 9 + +% è equivalente a +horzcat(A,A); + + +A(:, [3 1 2]) % Ripristina le colonne della matrice originale +%ans = + +% 3 1 2 +% 42 4 5 +% 9 7 8 + +size(A) % ans = 3 3 + +A(1, :) =[] % Rimuove la prima riga della matrice +A(:, 1) =[] % Rimuove la prima colonna della matrice + +transpose(A) % Traspone la matrice, equivale a: +A one +ctranspose(A) % Trasposizione hermitiana della matrice +% (ovvero il complesso coniugato di ogni elemento della matrice trasposta) + + + + +% Aritmetica Elemento per Elemento vs. Artimetica Matriciale +% Gli operatori aritmetici da soli agliscono sull'intera matrice. Quando sono preceduti +% da un punto, allora agiscono su ogni elemento. Per esempio: +A * B % Moltiplicazione matriciale +A .* B % Moltiplica ogni elemento di A per il corrispondente elemento di B + +% Ci sono diverse coppie di funzioni, in cui una agisce su ogni elemento, e +% l'altra (il cui nome termina con m) agisce sull'intera matrice. +exp(A) % Calcola l'esponenziale di ogni elemento +expm(A) % Calcola la matrice esponenziale +sqrt(A) % Calcola la radice quadrata di ogni elementotake the square root of each element +sqrtm(A) % Trova la matrice di cui A nè è la matrice quadrata + + +% Plot di grafici +x = 0:.10:2*pi; % Crea un vettore che inizia a 0 e termina 2*pi con incrementi di .1 +y = sin(x); +plot(x,y) +xlabel('x axis') +ylabel('y axis') +title('Plot of y = sin(x)') +axis([0 2*pi -1 1]) % x range da 0 a 2*pi, y range da -1 a 1 + +plot(x,y1,'-',x,y2,'--',x,y3,':') % Per stampare più funzioni in unico plot +legend('Line 1 label', 'Line 2 label') % Aggiunge un etichetta con il nome delle curve + +% Metodo alternativo per stampare funzioni multiple in un unico plot. +% mentre 'hold' è on, i comandi sono aggiunti al grafico esistene invece di sostituirlo +plot(x, y) +hold on +plot(x, z) +hold off + +loglog(x, y) % Un plot di tipo log-log +semilogx(x, y) % Un plot con asse x logaritmico +semilogy(x, y) % Un plot con asse y logaritmico + +fplot (@(x) x^2, [2,5]) % Stampa la funzione x^2 da x=2 a x=5 + +grid on % Mostra la griglia, disattivare con 'grid off' +axis square % Rende quadrata la regione individuata dagli assi +axis equal % Iposta l'aspetto del grafico in modo che le unità degli assi siano le stesse + +scatter(x, y); % Scatter-plot +hist(x); % Istogramma + +z = sin(x); +plot3(x,y,z); % Stampa una linea 3D + +pcolor(A) % Heat-map di una matrice: stampa una griglia di rettangoli, colorati in base al valore +contour(A) % Contour plot di una matrice +mesh(A) % Stampa come una superfice di mesh + +h = figure % Crea un nuovo oggetto figura, con handle f +figure(h) % Rende la figura corrispondente al handle h la figura corrente +close(h) % Chiude la figura con handle h +close all % Chiude tutte le figure +close % Chiude la figura corrente + +shg % Riutilizza una finestra grafica già esistente, o se necessario ne crea una nuova +clf clear % Pulisce la figura corrente, e resetta le proprietà della figura + +% Le proprietà possono essere impostate e modificate attraverso l'handle della figura. +% Si può salvare l'handle della figura quando viene creata. +% La funzione gcf restituisce un handle alla figura attuale. +h = plot(x, y); % Si può salvare un handle della figura quando viene creata +set(h, 'Color', 'r') +% 'y' yellow; 'm' magenta, 'c' cyan, 'r' red, 'g' green, 'b' blue, 'w' white, 'k' black +set(h, 'LineStyle', '--') + % '--' linea continua, '---' tratteggiata, ':' puntini, '-.' trattino-punto, 'none' nessuna linea +get(h, 'LineStyle') + + +% La funzione gca restituisce un handle degli assi della figura corrente +set(gca, 'XDir', 'reverse'); % Inverte la direzione dell'asse x + +% Per creare una figura che contiene diverse sottofigure, usare subplot +subplot(2,3,1); % Seleziona la prima posizione in una griglia 2 per 3 di sottofigure +plot(x1); title('First Plot') % Stampa qualcosa in questa posizione +subplot(2,3,2); % Seleziona la seconda posizione nella griglia +plot(x2); title('Second Plot') % Stampa qualcosa in questa posizione + + +% Per usare funzioni o script, devono essere nel tuo path o nella directory corrente +path % Mostra il path corrente +addpath /path/to/dir % Aggiunge al path +rmpath /path/to/dir % Rimuove dal path +cd /path/to/move/into % Cambia directory + + +% Le variabili possono essere salvate in file .mat +save('myFileName.mat') % Salva le variabili nel tuo Workspace +load('myFileName.mat') % Carica variabili salvate nel tuo Workspace + +% M-file Scripts +% I file di script sono file esterni che contengono una sequenza di istruzioni. +% Permettono di evitare di scrivere ripetutamente lo stesso codice nella Command Window +% Hanno estensione .m + +% M-file Functions +% Come gli script, hanno la stessa estensione .m +% Ma possono accettare argomenti di input e restituire un output. +% Inoltre, hanno un proprio workspace (differente scope delle variabili). +% Il nome della funzione dovrebbe coincidere con il nome del file (quindi salva questo esempio come double_input.m). +% 'help double_input.m' restituisce i commenti sotto alla linea iniziale della funzione +function output = double_input(x) + %double_input(x) restituisce il doppio del valore di x + output = 2*x; +end +double_input(6) % ans = 12 + + +% Si possono anche avere sottofunzioni e funzioni annidate. +% Le sottofunzioni sono nello stesso file della funzione primaria, e possono solo essere +% chiamate da funzioni nello stesso file. Le funzioni annidate sono definite dentro ad altre +% funzioni, e hanno accesso ad entrambi i workspace. + +% Se si vuole creare una funzione senza creare un nuovo file si può usare una +% funzione anonima. Utile quando si vuole definire rapidamente una funzione da passare ad +% un'altra funzione (es. stampa con fplot, valutare un integrale indefinito +% con quad, trovare le radici con fzenzro, o trovare il minimo con fminsearch). +% Esempio che restituisce il quadrato del proprio input, assegnato all'handle sqr: +sqr = @(x) x.^2; +sqr(10) % ans = 100 +doc function_handle % scopri di più + +% Input dell'utente +a = input('Enter the value: ') + +% Ferma l'esecuzione del file e cede il controllo alla tastiera: l'utente può esaminare +% o cambiare variabili. Digita 'return' per continuare l'esecuzione, o 'dbquit' per uscire +keyboard + +% Importarare dati (anche xlsread/importdata/imread per excel/CSV/image file) +fopen(filename) + +% Output +disp(a) % Stampa il valore della variabile a +disp('Hello World') % Stampa una stringa +fprintf % Stampa sulla Command Window con più controllo + +% Istruzioni condizionali (le parentesi sono opzionali, ma un buon stile) +if (a > 15) + disp('Maggiore di 15') +elseif (a == 23) + disp('a è 23') +else + disp('nessuna condizione verificata') +end + +% Cicli +% NB. Ciclare su elementi di vettori/matrici è lento! +% Dove possibile, usa funzioni che agiscono sull'intero vettore/matrice +for k = 1:5 + disp(k) +end + +k = 0; +while (k < 5) + k = k + 1; +end + +% Misurare la durata dell'esecuzione del codice: 'toc' stampa il tempo trascorso da quando 'tic' è stato chiamato +tic +A = rand(1000); +A*A*A*A*A*A*A; +toc + +% Connessione a un Database MySQL +dbname = 'database_name'; +username = 'root'; +password = 'root'; +driver = 'com.mysql.jdbc.Driver'; +dburl = ['jdbc:mysql://localhost:8889/' dbname]; +javaclasspath('mysql-connector-java-5.1.xx-bin.jar'); +% xx dipende dalla versione, download disponibile all'indirizzo http://dev.mysql.com/downloads/connector/j/ +conn = database(dbname, username, password, driver, dburl); +sql = ['SELECT * from table_name where id = 22'] % Esempio istruzione sql +a = fetch(conn, sql) % conterra i tuoi dati + + +% Funzioni matematiche comuni +sin(x) +cos(x) +tan(x) +asin(x) +acos(x) +atan(x) +exp(x) +sqrt(x) +log(x) +log10(x) +abs(x) +min(x) +max(x) +ceil(x) +floor(x) +round(x) +rem(x) +rand % Numeri pseudocasuali uniformemente distribuiti +randi % Numeri interi pseudocasuali uniformemente distrubuiti +randn % Numeri pseudocasuali distrbuiti normalmente + +% Costanti comuni +pi +NaN +inf + +% Risolvere equazioni matriciali +% Gli operatori \ e / sono equivalenti alle funzioni mldivide e mrdivide +x=A\b % Risolve Ax=b. Più veloce e più accurato numericamente rispetto ad usare inv(A)*b. +x=b/A % Risolve xA=b + +inv(A) % Calcola la matrice inversa +pinv(A) % Calcola la matrice pseudo-inversa + +% Funzioni comuni su matrici +zeros(m,n) % Matrice m x n di zeri +ones(m,n) % Matrice m x n di uni +diag(A) % Estrae gli elementi della diagonale della matrice A +diag(x) % Costruisce una matrice con elementi diagonali uguali agli elementi di x, e zero negli altri elementi +eye(m,n) % Matrice identità +linspace(x1, x2, n) % Ritorna n punti equamente distanziati, con minimo x1 e massimo x2 +inv(A) % Matrice inversa di A +det(A) % Determinante di A +eig(A) % Autovalori e autovettori di A +trace(A) % Traccia della matrice - equivalente a sum(diag(A)) +isempty(A) % Verifica se l'array è vuoto +all(A) % Verifica se tutti gli elementi sono nonzero o veri +any(A) % Verifica se almento un elemento è nonzero o vero +isequal(A, B) % Verifica l'uguaglianza di due array +numel(A) % Numero di elementi nella matrice +triu(x) % Ritorna la parte triangolare superiore di x +tril(x) % Ritorna la parte triangolare inferiore di x +cross(A,B) % Ritorna il prodotto vettoriale dei vettori A e B +dot(A,B) % Ritorna il prodotto scalare di due vettori (devono avere la stessa lunghezza) +transpose(A) % Ritorna la trasposta di A +fliplr(A) % Capovolge la matrice da sinistra a destra +flipud(A) % Capovolge la matrice da sopra a sotto + +% Fattorizzazione delle matrici +[L, U, P] = lu(A) % Decomposizione LU: PA = LU, L è il triangolo inferiore, U è il triangolo superiore, P è la matrice di permutazione +[P, D] = eig(A) % Auto-decomposizione: AP = PD, le colonne di P sono autovettori e gli elementi sulle diagonali di D sono autovalori +[U,S,V] = svd(X) % SVD: XV = US, U e V sono matrici unitarie, S ha gli elementi della diagonale non negativi in ordine decrescente + +% Funzioni comuni su vettori +max % elemento più grande +min % elemento più piccolo +length % lunghezza del vettore +sort % ordina in modo crescente +sum % somma degli elementi +prod % prodotto degli elementi +mode % valore moda +median % valore mediano +mean % valore medio +std % deviazione standard +perms(x) % lista tutte le permutazioni di elementi di x + + +% Classi +% Matlab supporta la programmazione orientata agli oggetti. +% La classe deve essere messa in un file con lo stesso nome della classe e estensione .m +% Per iniziare, creiamo una semplice classe per memorizzare waypoint GPS +% Inizio WaypointClass.m +classdef WaypointClass % Il nome della classe. + properties % Le proprietà della classe funzionano come Strutture + latitude + longitude + end + methods + % Questo metodo che ha lo stesso nome della classe è il costruttore + function obj = WaypointClass(lat, lon) + obj.latitude = lat; + obj.longitude = lon; + end + + % Altre funzioni che usano l'oggetto Waypoint + function r = multiplyLatBy(obj, n) + r = n*[obj.latitude]; + end + + % Se si vuole aggiungere due oggetti Waypoint insieme senza chiamare + % una funzione speciale si può sovradefinire una funzione aritmetica di Matlab come questa: + function r = plus(o1,o2) + r = WaypointClass([o1.latitude] +[o2.latitude], ... + [o1.longitude]+[o2.longitude]); + end + end +end +% End WaypointClass.m + +% Si può creare un oggetto della classe usando un costruttore +a = WaypointClass(45.0, 45.0) + +% Le proprietà della classe si comportano esattamente come una Struttura Matlab. +a.latitude = 70.0 +a.longitude = 25.0 + +% I metodi possono essere chiamati allo stesso modo delle funzioni +ans = multiplyLatBy(a,3) + +% Il metodo può anche essere chiamato usando una notazione con punto. In questo caso, l'oggetto +% non necessita di essere passato al metodo. +ans = a.multiplyLatBy(a,1/3) + +% Le funzioni Matlab possono essere sovradefinite per gestire oggetti. +% Nel metodo sopra, è stato sovradefinito come Matlab gestisce +% l'addizione di due oggetti Waypoint. +b = WaypointClass(15.0, 32.0) +c = a + b + +``` + +## Di più su Matlab + +* Sito ufficiale [http://http://www.mathworks.com/products/matlab/](http://www.mathworks.com/products/matlab/) +* Forum ufficiale di MATLAB: [http://www.mathworks.com/matlabcentral/answers/](http://www.mathworks.com/matlabcentral/answers/) |