diff options
author | Suzane Sant Ana <tetestonaldo@gmail.com> | 2017-12-31 14:27:06 -0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-31 14:27:06 -0200 |
commit | 42f9329bb3a028d374d6397991ac48b44064741e (patch) | |
tree | 1e75e2b3e122aeb863e3ffa037f6f64c4027fbf8 /it-it | |
parent | e6b77595f2669d66ac7be43c6e6083cbff80a9a7 (diff) | |
parent | 70a36c9bd970b928adde06afb2bd69f6ba8e5d5c (diff) |
Merge pull request #1 from adambard/master
update
Diffstat (limited to 'it-it')
-rw-r--r-- | it-it/bash-it.html.markdown | 374 | ||||
-rw-r--r-- | it-it/bf-it.html.markdown | 93 | ||||
-rw-r--r-- | it-it/brainfuck-it.html.markdown | 101 | ||||
-rw-r--r-- | it-it/c++-it.html.markdown | 1136 | ||||
-rw-r--r-- | it-it/coffeescript-it.html.markdown | 107 | ||||
-rw-r--r-- | it-it/elixir-it.html.markdown | 428 | ||||
-rw-r--r-- | it-it/git-it.html.markdown | 498 | ||||
-rw-r--r-- | it-it/go-it.html.markdown | 453 | ||||
-rw-r--r-- | it-it/html-it.html.markdown | 121 | ||||
-rw-r--r-- | it-it/java-it.html.markdown | 170 | ||||
-rw-r--r-- | it-it/json-it.html.markdown | 70 | ||||
-rw-r--r-- | it-it/logtalk-it.html.markdown | 550 | ||||
-rw-r--r-- | it-it/markdown.html.markdown | 310 | ||||
-rw-r--r-- | it-it/matlab-it.html.markdown | 526 | ||||
-rw-r--r-- | it-it/python-it.html.markdown | 778 | ||||
-rw-r--r-- | it-it/rst-it.html.markdown | 111 | ||||
-rw-r--r-- | it-it/ruby-ecosystem-it.html.markdown | 145 | ||||
-rw-r--r-- | it-it/rust-it.html.markdown | 322 |
18 files changed, 6142 insertions, 151 deletions
diff --git a/it-it/bash-it.html.markdown b/it-it/bash-it.html.markdown new file mode 100644 index 00000000..efc47969 --- /dev/null +++ b/it-it/bash-it.html.markdown @@ -0,0 +1,374 @@ +--- +category: tool +tool: bash +contributors: + - ["Max Yankov", "https://github.com/golergka"] + - ["Darren Lin", "https://github.com/CogBear"] + - ["Alexandre Medeiros", "http://alemedeiros.sdf.org"] + - ["Denis Arh", "https://github.com/darh"] + - ["akirahirose", "https://twitter.com/akirahirose"] + - ["Anton Strömkvist", "http://lutic.org/"] + - ["Rahil Momin", "https://github.com/iamrahil"] + - ["Gregrory Kielian", "https://github.com/gskielian"] + - ["Etan Reisner", "https://github.com/deryni"] + - ["Jonathan Wang", "https://github.com/Jonathansw"] + - ["Leo Rudberg", "https://github.com/LOZORD"] + - ["Betsy Lorton", "https://github.com/schbetsy"] + - ["John Detter", "https://github.com/jdetter"] +filename: LearnBash-it.sh +translators: + - ["Robert Margelli", "http://github.com/sinkswim/"] + - ["Tommaso Pifferi", "http://github.com/neslinesli93/"] +lang: it-it +--- + +Bash è il nome della shell di unix, la quale è stata distribuita anche come shell del sistema oprativo GNU e la shell di default su Linux e Mac OS X. +Quasi tutti gli esempi sottostanti possono fare parte di uno shell script o eseguiti direttamente nella shell. + +[Per saperne di più.](http://www.gnu.org/software/bash/manual/bashref.html) + +```bash +#!/bin/bash +# La prima riga dello script è lo shebang il quale dice al sistema come eseguire +# lo script: http://it.wikipedia.org/wiki/Shabang +# Come avrai già immaginato, i commenti iniziano con #. Lo shebang stesso è un commento. + +# Semplice esempio ciao mondo: +echo Ciao mondo! + +# Ogni comando inizia su una nuova riga, o dopo un punto e virgola: +echo 'Questa è la prima riga'; echo 'Questa è la seconda riga' + +# Per dichiarare una variabile: +Variabile="Una stringa" + +# Ma non così: +Variabile = "Una stringa" +# Bash stabilirà che Variabile è un comando da eseguire e darà un errore +# perchè non esiste. + +# Usare la variabile: +echo $Variabile +echo "$Variabile" +echo '$Variabile' +# Quando usi la variabile stessa - assegnala, esportala, oppure — scrivi +# il suo nome senza $. Se vuoi usare il valore della variabile, devi usare $. +# Nota che ' (singolo apice) non espande le variabili! + +# Espansione dei parametri ${ }: +echo ${Variabile} +# Questo è un esempio semplice dell'espansione dei parametri. +# L'espansione dei parametri prende il valore di una variabile, ed appunto lo "espande" o lo stampa. +# Durante l'espansione il valore o il parametro passato possono essere modificati. +# Sotto ci sono altri esempi che analizzano l'uso dell'espansione dei parametri. + +# Sostituzione di stringhe nelle variabili +echo ${Variabile/Una/A} +# Questo sostituirà la prima occorrenza di "Una" con "La" + +# Sottostringa di una variabile +Lunghezza=7 +echo ${Variabile:0:Lunghezza} +# Questo ritornerà solamente i primi 7 caratteri + +# Valore di default per la variabile +echo ${Foo:-"ValoreDiDefaultSeFooMancaOppureÈVuoto"} +# Questo funziona per null (Foo=), stringa vuota (Foo=""), zero (Foo=0) ritorna 0 +# Nota: viene ritornato il valore di default, il contenuto della variabile pero' non cambia. + +# Espansione delle graffe { } +# Viene usata per generare stringe in modo arbitrario +echo {1..10} +echo {a..z} +# Con questi comandi viene stampato l'intervallo dal valore iniziale al valore finale (i numeri da 1 a 10, le lettere dell'alfabeto) + +# Variabili builtin: +# Ci sono delle variabili builtin molto utili, come +echo "Valore di ritorno dell'ultimo programma eseguito: $?" +echo "PID dello script: $$" +echo "Numero di argomenti: $#" +echo "Argomenti dello script: $@" +echo "Argomenti dello script separati in variabili distinte: $1 $2..." + +# Adesso che sappiamo come stampare a schermo, e come usare le variabili, possiamo andare avanti con le basi di bash! +# Per conoscere la directory su cui siamo posizionati, è sufficiente usare `pwd`. +# `pwd` è l'acronimo di "print working directory", ovvero "stampa la directory corrente". +# Possiamo anche usare la variabile builtin `$PWD`. +# Prova questi due esempi, e vedi che il risultato è lo stesso: +echo "Sono dentro $(pwd)" # esegue `pwd` ed interpola l'output +echo "Sono dentro $PWD" # interpola direttamente la variabile builtin + +# Se c'è troppo testo nel terminale, ottenuto scrivendo comandi oppure eseguendo uno script, il comando `clear` pulisce lo schermo +clear +# Puoi utilizzare anche Ctrl-L al posto di clear + +# Leggere un valore di input: +echo "Come ti chiami?" +read Nome # Nota che non abbiamo dovuto dichiarare una nuova variabile +echo Ciao, $Nome! + +# Classica struttura if: +# usa 'man test' per maggiori informazioni sulle condizionali +if [ $Nome -ne $USER ] +then + echo "Il tuo nome non è lo username" +else + echo "Il tuo nome è lo username" +fi + +# Nota: se $Name è vuoto, la condizione precedente viene interpretata come: +if [ -ne $USER ] +# che genera un errore di sintassi. Quindi il metodo sicuro per usare +# variabili che possono contenere stringhe vuote è il seguente: +if [ "$Name" -ne $USER ] ... +# che viene interpretato come: +if [ "" -ne $USER ] ... +# e dunque funziona correttamente. + +# C'è anche l'esecuzione condizionale +echo "Sempre eseguito" || echo "Eseguito solo se la prima condizione fallisce" +echo "Sempre eseguito" && echo "Eseguito solo se la prima condizione NON fallisce" + +# Per usare && e || con l'if, c'è bisogno di piu' paia di parentesi quadre: +if [ "$Nome" == "Steve" ] && [ "$Eta" -eq 15 ] +then + echo "Questo verrà eseguito se $Nome è Steve E $Eta è 15." +fi + +if [ "$Nome" == "Daniya" ] || [ "$Nome" == "Zach" ] +then + echo "Questo verrà eseguito se $Nome è Daniya O Zach." +fi + +# Le espressioni sono nel seguente formato: +echo $(( 10 + 5 )) + +# A differenza di altri linguaggi di programmazione, bash è una shell - quindi lavora nel contesto +# della cartella corrente. Puoi elencare i file e le cartelle nella cartella +# corrente con il comando ls: +ls + +# Questi comandi hanno opzioni che controllano la loro esecuzione: +ls -l # Elenca tutti i file e le cartelle su una riga separata +ls -t # Ordina i contenuti della cartella in base all'ultima data di modifica (ordine decrescente) +ls -R # Esegue `ls` in modo ricorsivo all'interno di questa cartella e tutte le sottocartelle + +# I risultati del comando precedente possono essere passati al comando successivo come input. +# Il comando grep filtra l'input con il pattern passato. Ecco come possiamo elencare i +# file .txt nella cartella corrente: +ls -l | grep "\.txt" + +# Usa `cat` per stampare il contenuto dei file a schermo: +cat file.txt + +# Possiamo leggere il contenuto di un file e memorizzarlo in una variabile, sempre usando `cat`: +Contenuti=$(cat file.txt) +echo "INIZIO DEL FILE\n$Contenuti\nFINE DEL FILE" + +# Usa `cp` per copiare file o cartelle da un punto all'altro del sistema. +# `cp` crea NUOVE versioni dei file, quindi le modifiche della copia non hanno effetto sull'originale, e viceversa. +# Nota che il file (o la cartella) di destinazione vengono sovrascritte se già esistono! +cp fileSorgente.txt copia.txt +cp -r cartellaSorgente/ destinazione/ # copia ricorsiva + +# Se hai bisogno di trasferire file tra computer, puoi usare `scp` o `sftp`. +# `scp` ha una sintassi simile a `cp`. +# `sftp` invece è più interattivo. + +# Usa `mv` per spostare file o cartella da un punto all'altro del sistema. +# `mv` è simile a `cp`, ma cancella il file(o la cartella) sorgente. +# `mv` è molto utile anche per rinominare i file! +mv s0rg3nt3.txt dst.txt # mi spiace anonymous... + +# Dal momento che bash lavora nel contesto della cartella corrente, potresti voler eseguire il comando dentro a qualche altra cartella. Per fare questo si usa `cd`: +cd ~ # va nella cartella Home +cd .. # va nella cartella "padre" + # (ad esempio da /home/user/Download a /home/user) +cd /home/user/Documenti # entra nella cartella specificata +cd ~/Documenti/.. # siamo sempre nella cartella home... vero? + +# Usa le subshell per lavorare in cartelle diverse contemporaneamente +(echo "All'inizio sono qua: $PWD") && (cd cartella; echo "Adesso invece sono qua: $PWD") +pwd # siamo sempre nella prima cartella + +# Usa `mkdir` per creare nuove cartelle +mkdir nuovaCartella +# Il flag `-p` indica la creazione delle cartelle intermedie, se non esistono. +mkdir nuovaCartella/con/tante/cartelle/intermedie + +# Puoi redirezionare l'input e l'output del comando (stdin, stdout, e stderr). +# Leggi da stdin finchè ^EOF$ e sovrascrivi hello.py con le righe +# comprese tra "EOF": +cat > hello.py << EOF +#!/usr/bin/env python +from __future__ import print_function +import sys +print("#stdout", file=sys.stdout) +print("#stderr", file=sys.stderr) +for line in sys.stdin: + print(line, file=sys.stdout) +EOF + +# Esegui hello.py con diverse redirezioni stdin, stdout, e stderr: +python hello.py < "input.in" +python hello.py > "output.out" +python hello.py 2> "error.err" +python hello.py > "output-and-error.log" 2>&1 +python hello.py > /dev/null 2>&1 +# Lo output error sovrascriverà il file se esiste, +# se invece vuoi appendere usa ">>": +python hello.py >> "output.out" 2>> "error.err" + +# Sovrascrivi output.out, appendi a error.err, e conta le righe: +info bash 'Basic Shell Features' 'Redirections' > output.out 2>> error.err +wc -l output.out error.err + +# Esegui un comando e stampa il suo file descriptor (esempio: /dev/fd/123) +# vedi: man fd +echo <(echo "#ciaomondo") + +# Sovrascrivi output.out con "#helloworld": +cat > output.out <(echo "#helloworld") +echo "#helloworld" > output.out +echo "#helloworld" | cat > output.out +echo "#helloworld" | tee output.out >/dev/null + +# Pulisci i file temporanei verbosamente (aggiungi '-i' per la modalità interattiva) +# Attenzione: il comando `rm` non può essere annullato! +rm -v output.out error.err output-and-error.log +rm -r cartellaTemporanea/ # cancella ricorsivamente + +# I comandi possono essere sostituiti con altri comandi usando $( ): +# Il comando seguente mostra il numero di file e cartelle nella +# cartella corrente. +echo "Ci sono $(ls | wc -l) oggetti qui." + +# Lo stesso puo' essere usato usando backticks `` ma non possono essere innestati - il modo migliore +# è usando $( ). +echo "Ci sono `ls | wc -l` oggetti qui." + +# Bash utilizza uno statemente case che funziona in maniera simile allo switch in Java e C++: +case "$Variabile" in + #Lista di pattern per le condizioni che vuoi soddisfare + 0) echo "C'è uno zero.";; + 1) echo "C'è un uno.";; + *) echo "Non è null.";; +esac + +# I cicli for iterano per ogni argomento fornito: +# I contenuti di $Variabile sono stampati tre volte. +for Variabile in {1..3} +do + echo "$Variabile" +done + +# O scrivilo con il "ciclo for tradizionale": +for ((a=1; a <= 3; a++)) +do + echo $a +done + +# Possono essere usati anche per agire su file.. +# Questo eseguirà il comando 'cat' su file1 e file2 +for Variabile in file1 file2 +do + cat "$Variabile" +done + +# ..o dall'output di un comando +# Questo eseguirà cat sull'output di ls. +for Output in $(ls) +do + cat "$Output" +done + +# while loop: +while [ true ] +do + echo "corpo del loop..." + break +done + +# Puoi anche definire funzioni +# Definizione: +function foo () +{ + echo "Gli argomenti funzionano come gli argomenti dello script: $@" + echo "E: $1 $2..." + echo "Questa è una funzione" + return 0 +} + +# o semplicemente +bar () +{ + echo "Un altro modo per dichiarare funzioni!" + return 0 +} + +# Per chiamare la funzione +foo "Il mio nome è" $Nome + +# Ci sono un sacco di comandi utili che dovresti imparare: +# stampa le ultime 10 righe di file.txt +tail -n 10 file.txt +# stampa le prime 10 righe di file.txt +head -n 10 file.txt +# ordina le righe di file.txt +sort file.txt +# riporta o ometti le righe ripetute, con -d le riporta +uniq -d file.txt +# stampa solamente la prima colonna prima del carattere ',' +cut -d ',' -f 1 file.txt +# sostituisce ogni occorrenza di 'okay' con 'great' in file.txt (compatible con le regex) +sed -i 's/okay/great/g' file.txt +# stampa su stdout tutte le righe di file.txt che soddisfano una certa regex +# L'esempio stampa le righe che iniziano con "foo" e che finiscono con "bar" +grep "^foo.*bar$" file.txt +# passa l'opzione "-c" per stampare invece il numero delle righe che soddisfano la regex +grep -c "^foo.*bar$" file.txt +# Altre opzioni utili possono essere: +grep -r "^foo.*bar$" someDir/ # esegue `grep` ricorsivamente nella cartella +grep -n "^foo.*bar$" file.txt # stampa il numero delle righe del file +grep -rI "^foo.*bar$" someDir/ # esegue `grep` ricorsivamente nella cartella, ignorando i file non testuali +# Esegue la stessa ricerca iniziale, ma filtrando solo le righe che contengono la stringa "baz" +grep "^foo.*bar$" file.txt | grep -v "baz" + +# se vuoi letteralmente cercare la stringa, +# e non la regex, usa fgrep (o grep -F) +fgrep "foobar" file.txt + +# Il comando trap permette di eseguire un comando quando un segnale viene ricevuto dal tuo script. +# In questo esempio, trap eseguirà rm se uno dei tre segnali (SIGHUP, SIGINT o SIGTERM) viene ricevuto. +trap "rm $TEMP_FILE; exit" SIGHUP SIGINT SIGTERM + +# `sudo` viene usato per eseguire comandi come superuser, ovvero come utente che ha maggiori privilegi all'interno del sistema +$NOME1=$(whoami) +$NOME2=$(sudo whoami) +echo "Ero $NOME1, poi sono diventato più potente: $NOME2" + +# Leggi la documentazione dei builtin di bash con il builtin 'help' di bash: +help +help help +help for +help return +help source +help . + +# Leggi la manpage di bash con man +apropos bash +man 1 bash +man bash + +# Leggi la documentazione con info (? per help) +apropos info | grep '^info.*(' +man info +info info +info 5 info + +# Leggi la documentazione di bash: +info bash +info bash 'Bash Features' +info bash 6 +info --apropos bash +``` diff --git a/it-it/bf-it.html.markdown b/it-it/bf-it.html.markdown new file mode 100644 index 00000000..97e5b88e --- /dev/null +++ b/it-it/bf-it.html.markdown @@ -0,0 +1,93 @@ +--- +language: bf +filename: learnbf-it.bf +contributors: + - ["Prajit Ramachandran", "http://prajitr.github.io/"] + - ["Mathias Bynens", "http://mathiasbynens.be/"] +translators: + - ["Ivan Sala", "http://slavni96.github.io/"] + - ["Christian Grasso", "http://chris54721.net"] +lang: it-it +--- + +Brainfuck è un linguaggio di programmazione +[Turing equivalente](https://it.wikipedia.org/wiki/Turing_equivalenza) +estremamente minimale, composto da solo 8 comandi. + +Puoi provarlo nel tuo browser utilizzando +[brainfuck-visualizer](http://fatiherikli.github.io/brainfuck-visualizer/). + +``` + +Qualsiasi carattere diverso da "><+-.,[]" (escludendo gli apici) +viene ignorato. +Branfuck è caratterizzato da un array di 30,000 celle inizializzate a zero +e da un puntatore che punta alla cella corrente. + +Vi sono otto comandi: ++ : Incrementa il valore della cella attuale di uno. +- : Decrementa il valore della cella attuale di uno. +> : Sposta il puntatore sulla cella seguente (sulla destra). +< : Sposta il puntatore sulla cella precendete (sulla sinistra). +. : Stampa il valore ASCII della cella corrente. (es. 65 = 'A') +, : Legge un singolo carattere come input e lo salva nella cella corrente. +[ : Se il valore della cella corrente è zero, prosegue fino alla ] corrispondente. + Altrimenti, passa alla prossima istruzione. +] : Se il valore della cella corrente è zero, passa alla prossima istruzione. + Altrimenti, torna indietro fino alla [ corrispondente. + +[ e ] formano un ciclo while. Ovviamente dovranno essere bilanciati. +(Ad ogni [ dovrà corrispondere una ]) + +Ecco alcuni semplici esempi di programmi scritti in Brainfuck: + +++++++ [ > ++++++++++ < - ] > +++++ . + +Questo programma stampa in output la lettera 'A'. Prima di tutto, incrementa +la cella #1 fino al valore 6. La cella #1 verrà utilizzata per il ciclo. +Poi, entra nel ciclo ([) e si sposta alla cella #2. Incrementa la cella #2 10 +volte, torna alla cella #1, e decrementa quest'ultima. +Il ciclo si ripete 6 volte (la cella #1 viene decrementata 6 volte prima di +raggiungere lo 0, quindi prosegue oltre la corrispondente ]). + +A questo punto, siamo sulla cella #1, che ha valore 0, mentre la cella #2 ha +valore 60. Ci spostiamo sulla cella #2, la incrementiamo per 5 volte, ottenendo +il valore 65, quindi stampiamo il valore della cella #2. +Il valore 65 equivale ad 'A' in ASCII, per cui viene stampato 'A' nel terminale. + + +, [ > + < - ] > . + +Questo programma legge un carattere come input dall'utente, quindi salva il +carattere nella cella #1. Dopodichè entra in un ciclo. Si sposta alla cella #2, +incrementa quest'ultima, torna alla cella #1, e decrementa quest'ultima. +Il ciclo continua fino a quando la cella #1 diventa 0, e quindi la cella #2 +avrà il valore iniziale della cella #1. Infine, visto che ci troviamo sulla +cella #1 alla fine del ciclo, si sposta sulla cella #2 e stampa il valore in +ASCII. + +Gli spazi nel codice sovrastante sono presenti solo a scopo di ottenere +una maggiore leggibilità. Lo stesso programma poteva essere scritto senza spazi: + +,[>+<-]>. + +Proviamo, adesso, a capire cosa fa invece questo programma: + +,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >> + +Il programma legge 2 numeri come input dall'utente, e li moltiplica. + +Innanzitutto, legge in input i due numeri. Poi entra nel ciclo più esterno +basandosi sulla cella #1. Quindi si sposta sulla cella #2, e inizia il ciclo +più interno basandosi sul valore della cella #2, incrementando la cella #3. +Arrivati a questo punto abbiamo un problema: alla fine del ciclo interno +la cella #2 avrà valore 0. Ciò impedirà di eseguire nuovamente il ciclo interno. +Per ovviare a questo problema, incrementiamo anche la cella #4, e copiamo il +valore di quest'ultima nella cella #2. +Il risultato sarà infine contenuto nella cella #3. +``` + +E questo è brainfuck. Non è così difficile, eh? Se vuoi, ora puoi scrivere per +divertimento altri programmi in brainfuck, oppure scrivere un interprete +brainfuck in un altro linguaggio. L'interprete è abbastanza semplice da +implementare, ma se sei veramente masochista, prova ad implementare un interprete brainfuck... in brainfuck. diff --git a/it-it/brainfuck-it.html.markdown b/it-it/brainfuck-it.html.markdown deleted file mode 100644 index 4999d7e6..00000000 --- a/it-it/brainfuck-it.html.markdown +++ /dev/null @@ -1,101 +0,0 @@ ---- - -language: brainfuck -contributors: - - ["Prajit Ramachandran", "http://prajitr.github.io/"] - - ["Mathias Bynens", "http://mathiasbynens.be/"] -translators: - - ["Ivan Sala", "http://slavni96.github.io/"] -lang: it-it - ---- - -Brainfuck è un linguaggio di programmazione estremamente minimale, -ma è ingrado di rappresentare completamente una macchina di turnig, -e sfrutta solo 8 caratteri. -[Per saperne di più](http://it.wikipedia.org/wiki/Brainfuck) - -``` - -Qualsiasi carattere che non sia "><+-.,[]" (escludendo gli apici) -viene ignorato. -Branfuck è caratterizzato da un array (vettore) di 30,000 celle -inizializzare a zero, e un puntatore che punta alla cella corrente. - -Vi sono solo otto comando: -+ : Incrementa il valore della cella attuale di uno. -- : Decrementa il valore della cella attuale di uno. -> : Sposta il puntatore sulla cella seguente (prossima a destra). -< : Sposta il puntatore sulla cella precendete (precedente a sinistra). -. : Stampa il valore in ASCII della cella corrente. (es: 65 = 'A') -, : Legge un singolo carattere come input per la cella corrente. -[ : Se il valore della cella corrente è zero, conclude il ciclo - andando alla sua corrispondente ]. - Altrimenti, passa alla prossima istruzione. -] : Se il valore della cella corrente è zero, passa alla prossima istruzione. - Altrimenti torna indetro fino alla [ corrispondente. - -[ e ] creano un loop (while). Ovviamente dovranno essere bilanciati. -Per ogni [ dovrà corrispondere una ] - -Alcuni semplici esempi di programmi scritti in Brainfuck: - -++++++ [ > ++++++++++ < - ] > +++++ . - -Questo programma stampa in output la lettera 'A'. Priam incrementa -la cella #1 fino a 6, Quindi la cella #1 viene usata per crare un ciclo. -Poi, entra in un loop ([) e si sposta alla cella #2. -Incrementa la cella #2 10 volte, e torna alla cella #1, e la decrementa. -Questo avviene 6 volte (servono che la cella #1 venga decrementata 6 volte -per raggiungere lo 0. Quindi passa alla corrispondente ] e prosegue). - -A questo punto, siamo sulla cella #1, che ha valore 0, -la cella #2 ha valore 60 (6*10). Ci spostiamo sulla cella #2, incrementiamo -per 5 volte, e otteniamo il valore 65, quindi stampaimo il valore della cella -#2 (.). -65 è 'A' in ASCII, quindi alla fine viene stampata 'A'. - - -, [ > + < - ] > . - -Questo programma legge un carattere come input dall'utente, -quindi salva il carattere dentro la cella #1. -In seguito, incominca a ciclare. -Si sposta alla cella #², e increementa il valore della cella (#2). -Quindi torna alla cella #1, e decrementa il valore della cella (#1). -Questo continua fino a quando la cella #²1 diventa 0, e quindi la cella #2 -avrà il valore iniziale della cella #1. -Infine, visto che ci troviamo sulla cella #1 alla fine del ciclo, si sposta -sulla cella #2 e stampa il valore in ASCII. - -Gli spazi nel codice sovrastante, sono presenti solo a scopo di ottenere -una maggiore leggibilità, si poteva anche scrivere senza: - -,[>+<-]>. - -Proviamo, adesso, a capire cosa fa invece questo programma: - -,>,< [ > [ >+ >+ << -] >> [- << + >>] <<< -] >> - -Prende due numeri in input e quindi li moltiplica. - -Prima prende in input i due numeri (,>,<), quindi inizia un cilclo -basandosi sulla cella #1. -Quindi si sposta sulla cella #2, e inizia un altro ciclo condizionato -dal valore della cella #2, incrementando la cella #3. -Arrivati a questo punto abbiamo un problema: alla fine del ciclo interno -la cella #2 ha valore 0. In questo caso, quando il ciclo esterno rifarà -partire il ciclo interno, non funzionerà più perchè la cella #2 ha valore 0. -Per ovviare a questo problema, oltre alla cella 3, incrementiamo anche la cella -#4, e alla fine di ogni ciclo interno copiala il valore della cella #4 -nella cella #2, in modo che il ciclo interno -possa essere eseguito una altra volta. -Alla fine la cella #3 contiene il risultato. -``` - -E questo è brainfuck...Non è difficele, vero? -Per divertimento adesso puoi scrivere i tuoi programmi in brainfuck, -oppure puoi scrivere un interprete brainfuck in un altro linguaggio. -L'interprete è abbastanza semplice da implementare, ma se sei veramente -masochista prova ad implementare un interprete brainfuck in... -brainfuck. diff --git a/it-it/c++-it.html.markdown b/it-it/c++-it.html.markdown new file mode 100644 index 00000000..b4f9c50e --- /dev/null +++ b/it-it/c++-it.html.markdown @@ -0,0 +1,1136 @@ +--- +language: c++ +filename: learncpp-it.cpp +contributors: + - ["Steven Basart", "http://github.com/xksteven"] + - ["Matt Kline", "https://github.com/mrkline"] + - ["Geoff Liu", "http://geoffliu.me"] + - ["Connor Waters", "http://github.com/connorwaters"] +translators: + - ["Robert Margelli", "http://github.com/sinkswim/"] + - ["Tommaso Pifferi", "http://github.com/neslinesli93/"] +lang: it-it +--- + +Il C++ è un linguaggio di programmazione il quale, +[secondo il suo inventore Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote), +è stato progettato per + +- essere un "miglior C" +- supportare l'astrazione dei dati +- supportare la programmazione orientata agli oggetti +- supportare la programmazione generica + +Nonostante la sintassi possa risultare più difficile o complessa di linguaggi più recenti, +è usato in maniera vasta poichè viene compilato in istruzioni macchina che possono +essere eseguite direttamente dal processore ed offre un controllo stretto sull'hardware (come il linguaggio C) +ed allo stesso tempo offre caratteristiche ad alto livello come i generici, le eccezioni, e le classi. +Questa combinazione di velocità e funzionalità rende il C++ +uno dei più utilizzati linguaggi di programmazione. + +```c++ +////////////////// +// Confronto con il C +////////////////// + +// Il C++ è _quasi_ un superset del C e con esso condivide la sintassi di base per +// la dichiarazione di variabili, tipi primitivi, e funzioni. + +// Proprio come nel C, l'inizio del programma è una funzione chiamata +// main con un intero come tipo di ritorno, +// Questo valore serve come stato d'uscita del programma. +// Vedi http://it.wikipedia.org/wiki/Valore_di_uscita per maggiori informazioni. +int main(int argc, char** argv) +{ + // Gli argomenti a linea di comando sono passati tramite argc e argv così come + // avviene in C. + // argc indica il numero di argomenti, + // e argv è un array di stringhe in stile-C (char*) + // che rappresenta gli argomenti. + // Il primo argomento è il nome che è stato assegnato al programma. + // argc e argv possono essere omessi se non hai bisogno di argomenti, + // in questa maniera la funzione avrà int main() come firma. + + // Lo stato di uscita 0 indica successo. + return 0; +} + +// Tuttavia, il C++ varia nei seguenti modi: + +// In C++, i caratteri come letterali sono dei char. +sizeof('c') == sizeof(char) == 1 + +// In C, i caratteri come letterali sono degli interi. +sizeof('c') == sizeof(int) + + +// C++ ha prototipizzazione rigida +void func(); // funziona che non accetta argomenti + +// In C +void func(); // funzione che può accettare un qualsiasi numero di argomenti + +// Usa nullptr invece di NULL in C++ +int* ip = nullptr; + +// Gli header C standard sono disponibili in C++, +// ma sono prefissati con "c" e non hanno il suffisso ".h". +#include <cstdio> + +int main() +{ + printf("Ciao, mondo!\n"); + return 0; +} + +/////////////////////////////// +// Overloading per le funzioni +////////////////////////////// + +// Il C++ supporta l'overloading per le funzioni +// sia dato che ogni funzione accetta parametri diversi. + +void print(char const* myString) +{ + printf("Stringa %s\n", myString); +} + +void print(int myInt) +{ + printf("Il mio int è %d", myInt); +} + +int main() +{ + print("Ciao"); // Viene chiamata void print(const char*) + print(15); // Viene chiamata void print(int) +} + +//////////////////////// +// Argomenti di default +/////////////////////// + +// Puoi fornire argomenti di default per una funzione +// se non sono forniti dal chiamante. + +void faiQualcosaConInteri(int a = 1, int b = 4) +{ + // fai qualcosa con gli interi qui +} + +int main() +{ + faiQualcosaConInteri(); // a = 1, b = 4 + faiQualcosaConInteri(20); // a = 20, b = 4 + faiQualcosaConInteri(20, 5); // a = 20, b = 5 +} + +// Gli argomenti di default devono essere alla fine della lista degli argomenti. + +void dichiarazioneInvalida(int a = 1, int b) // Errore! +{ +} + + +///////////// +// Namespaces +///////////// + +// I namespaces forniscono visibilità separata per dichiarazioni di variabili, funzioni, +// ed altro. +// I namespaces possono essere annidati. + +namespace Primo { + namespace Annidato { + void foo() + { + printf("Questa è Primo::Annidato::foo\n"); + } + } // fine di namespace Annidato +} // fine di namespace Primo + +namespace Secondo { + void foo() + { + printf("Questa è Secondo::foo\n"); + } +} + +void foo() +{ + printf("Questa è foo globale\n"); +} + +int main() +{ + // Include tutti i simboli del namespace Secondo nello scope attuale. + // Osserva che chiamare semplicemente foo() non va più bene perché è ambiguo: + // bisogna specificare se vogliamo chiamare foo definita nel namespace Secondo + // o foo definita nel livello principale del programma. + + using namespace Secondo; + + Secondo::foo(); // stampa "Questa è Secondo::foo" + Primo::Annidato::foo(); // stampa "Questa è Primo::Annidato::foo" + ::foo(); // stampa "Questa è foo globale" +} + +/////////////// +// Input/Output +/////////////// + +// L'input e l'output in C++ utilizza gli streams +// cin, cout, e cerr i quali rappresentano stdin, stdout, e stderr. +// << è l'operatore di inserzione >> è l'operatore di estrazione. + +#include <iostream> // Include gli streams di I/O + +using namespace std; // Gli streams sono nel namespace std (libreria standard) + +int main() +{ + int myInt; + + // Stampa su stdout (o terminalee/schermo) + cout << "Inserisci il tuo numero preferito:\n"; + // Prende l'input + cin >> myInt; + + // cout può anche essere formattato + cout << "Il tuo numero preferito è " << myInt << "\n"; + // stampa "Il tuo numero preferito è <myInt>" + + cerr << "Usato per messaggi di errore"; +} + +//////////// +// Stringhe +/////////// + +// Le stringhe in C++ sono oggetti ed hanno molte funzioni membro +#include <string> + +using namespace std; // Anche le stringhe sono contenute nel namespace std (libreria standard) + +string myString = "Ciao"; +string myOtherString = " Mondo"; + +// + è usato per la concatenazione. +cout << myString + myOtherString; // "Ciao Mondo" + +cout << myString + " Bella"; // "Ciao Bella" + +// le stringhe in C++ possono essere modificate. +myString.append(" Mario"); +cout << myString; // "Ciao Mario" + + +/////////////// +// Riferimenti +////////////// + +// Oltre ai puntatori come quelli in C, +// il C++ ha i _riferimenti_. +// Questi non sono tipi puntatori che non possono essere riassegnati una volta settati +// e non possono essere null. +// Inoltre, essi hanno la stessa sintassi della variabile stessa: +// * non è necessario per la dereferenziazione e +// & ("indirizzo di") non è usato per l'assegnamento. + +using namespace std; + +string foo = "Io sono foo"; +string bar = "Io sono bar"; + + +string& fooRef = foo; // Questo crea un riferimento a foo. +fooRef += ". Ciao!"; // Modifica foo attraverso il riferimento +cout << fooRef; // Stampa "Io sono foo. Ciao!" + +// Non riassegna "fooRef". Questo è come scrivere "foo = bar", e +// foo == "Io sono bar" +// dopo questa riga. +cout << &fooRef << endl; // Stampa l'indirizzo di foo +fooRef = bar; +cout << &fooRef << endl; // Stampa lo stesso l'indirizzo di foo +cout << fooRef; // Stampa "Io sono bar" + +// L'indirizzo di fooRef rimane lo stesso, ovvero si riferisce ancora a foo. + + +const string& barRef = bar; // Crea un riferimento const a bar. +// Come in C, i valori const (i puntatori e i riferimenti) non possono essere modificati. +barRef += ". Ciao!"; // Errore, i riferimenti const non possono essere modificati. + +// Facciamo un piccolo excursus: prima di approfondire ancora i riferimenti, è necessario +// introdurre il concetto di oggetto temporaneo. Supponiamo di avere il seguente codice: +string tempObjectFun() { ... } +string retVal = tempObjectFun(); + +// Nella seconda riga si ha che: +// - un oggetto di tipo stringa viene ritornato da tempObjectFun +// - viene costruita una nuova stringa, utilizzando l'oggetto ritornato come +// argomento per il costruttore +// - l'oggetto ritornato da tempObjectFun viene distrutto +// L'oggetto ritornato da tempObjectFun viene detto oggetto temporaneo. +// Un oggetto temporaneo viene creato quando una funzione ritorna un oggetto, e viene +// distrutto quando l'espressione che lo racchiude termina la sua esecuzione - questo +// comportamento viene definito dallo standard, ma i compilatori possono modificarlo +// a piacere. Cerca su google "return value optimization" se vuoi approfondire. +// Dunque nel seguente codice: +foo(bar(tempObjectFun())) + +// dando per scontato che foo e bar esistano, l'oggetto ritornato da tempObjectFun +// è passato a bar ed è distrutto prima dell'invocazione di foo. + +// Tornando ai riferimenti, c'è un'eccezione a quanto appena detto. +// Infatti un oggetto temporaneo "viene distrutto quando l'espressione +// che lo racchiude termina la sua esecuzione", tranne quando è legato ad un +// riferimento di tipo const. In tal caso la sua vita viene estesa per tutto +// lo scope attuale: + +void constReferenceTempObjectFun() { + // constRef riceve l'oggetto temporaneo, che non viene distrutto fino + // alla fine di questa funzione. + const string& constRef = tempObjectFun(); + ... +} + +// Un altro tipo di riferimento introdotto nel C++11 è specifico per gli +// oggetti temporanei. Non puoi dichiarare una variabile di quel tipo, ma +// ha la precedenza nella risoluzione degli overload: + +void someFun(string& s) { ... } // Riferimento normale +void someFun(string&& s) { ... } // Riferimento ad un oggetto temporaneo + +string foo; +someFun(foo); // Chiama la versione con il riferimento normale +someFun(tempObjectFun()); // Chiama la versione con il riferimento temporaneo + +// Ad esempio potrai vedere questi due costruttori per std::basic_string: +basic_string(const basic_string& other); +basic_string(basic_string&& other); + +// L'idea è che se noi costruiamo una nuova stringa a partire da un oggetto temporaneo +// (che in ogni caso verrà distrutto), possiamo avere un costruttore più efficiente +// che in un certo senso "recupera" parti di quella stringa temporanea. +// Ci si riferisce a questo concetto come "move semantics". + +///////////////////// +// Enum +///////////////////// + +// Gli enum sono un modo per assegnare un valore ad una costante, e sono +// principalmente usati per rendere il codice più leggibile. +enum ETipiMacchine +{ + AlfaRomeo, + Ferrari, + SUV, + Panda +}; + +ETipiMacchine GetPreferredCarType() +{ + return ETipiMacchine::Ferrari; +} + +// Dal C++11 in poi c'è un modo molto semplice per assegnare un tipo ad un enum, +// che può essere utile per la serializzazione dei dati o per convertire gli enum +// tra il tipo desiderato e le rispettive costanti. +enum ETipiMacchine : uint8_t +{ + AlfaRomeo, // 0 + Ferrari, // 1 + SUV = 254, // 254 + Ibrida // 255 +}; + +void WriteByteToFile(uint8_t InputValue) +{ + // Serializza InputValue in un file +} + +void WritePreferredCarTypeToFile(ETipiMacchine InputCarType) +{ + // L'enum viene implicitamente convertito ad un uint8_t poiché + // è stato dichiarato come tale + WriteByteToFile(InputCarType); +} + +// D'altro canto potresti voler evitare che un enum venga accidentalmente convertito +// in un intero o in un altro tipo, quindi è possibile create una classe enum che +// impedisce la conversione implicita. +enum class ETipiMacchine : uint8_t +{ + AlfaRomeo, // 0 + Ferrari, // 1 + SUV = 254, // 254 + Ibrida // 255 +}; + +void WriteByteToFile(uint8_t InputValue) +{ + // Serializza InputValue in un file +} + +void WritePreferredCarTypeToFile(ETipiMacchine InputCarType) +{ + // Il compilatore darà errore anche se ETipiMacchine è un uint8_t: questo + // perchè abbiamo dichiarato l'enum come "enum class"! + WriteByteToFile(InputCarType); +} + +////////////////////////////////////////////////// +// Classi e programmazione orientata agli oggetti +///////////////////////////////////////////////// + +// Primo esempio delle classi +#include <iostream> + +// Dichiara una classe. +// Le classi sono in genere dichiara in un header file (.h o .hpp). +class Cane { + // Variabili e funzioni membro sono private di default. + std::string nome; + int peso; + +// Tutti i membri dopo questo sono pubblici (public) +// finchè "private:" o "protected:" non compaiono. +public: + + // Costruttore di default + Cane(); + + // Dichiarazioni di funzioni membro (le implentazioni sono a seguito) + // Nota che stiamo usando std::string invece di porre + // using namespace std; + // sopra. + // Mai usare uno statement "using namespace" in uno header. + void impostaNome(const std::string& nomeCane); + + void impostaPeso(int pesoCane); + + // Le funzioni che non modificano lo stato dell'oggetto + // dovrebbero essere marcate come const. + // Questo permette di chiamarle con un riferimento const all'oggetto. + // Inoltre, nota che le funzioni devono essere dichiarate espliciamente come _virtual_ + // per essere sovrascritte in classi derivate. + // Le funzioni non sono virtual di default per motivi di performance. + virtual void print() const; + + // Le funzioni possono essere definite anche all'interno del corpo della classe. + // Le funzioni definite in questo modo sono automaticamente inline. + void abbaia() const { std::cout << nome << " abbaia!\n"; } + + // Assieme con i costruttori, il C++ fornisce i distruttori. + // Questi sono chiamati quando un oggetto è rimosso o esce dalla visibilità. + // Questo permette paradigmi potenti come il RAII + // (vedi sotto) + // I distruttori devono essere virtual per permettere a classi di essere + // derivate da questa; altrimenti, il distruttore della classe derivata + // non viene chiamato se l'oggetto viene distrutto tramite un riferimento alla + // classe da cui ha ereditato o tramite un puntatore. + virtual ~Dog(); + +}; // Un punto e virgola deve seguire la definizione della funzione + +// Le funzioni membro di una classe sono generalmente implementate in files .cpp . +Cane::Cane() +{ + std::cout << "Un cane è stato costruito\n"; +} + +// Gli oggetti (ad esempio le stringhe) devono essere passati per riferimento +// se li stai modificando o come riferimento const altrimenti. +void Cane::impostaNome(const std::string& nomeCane) +{ + nome = nomeCane; +} + +void Cane::impostaPeso(int pesoCane) +{ + peso = pesoCane; +} + +// Notare che "virtual" è solamente necessario nelle dichiarazioni, non nelle definizioni. +void Cane::print() const +{ + std::cout << "Il cane è " << nome << " e pesa " << peso << "kg\n"; +} + +Cane::~Cane() +{ + std::cout << "Ciao ciao " << nome << "\n"; +} + +int main() { + Cane myDog; // stampa "Un cane è stato costruito" + myDog.impostaNome("Barkley"); + myDog.impostaPeso(10); + myDog.print(); // stampa "Il cane è Barkley e pesa 10 kg" + return 0; +} // stampa "Ciao ciao Barkley" + +// Ereditarietà: + +// Questa classe eredita tutto ciò che è public e protected dalla classe Cane, +// ma anche ciò che privato: tuttavia non potrà accedere direttamente a membri/metodi +// privati se non c'è un metodo pubblico o privato che permetta di farlo. +class MioCane : public Cane { + + void impostaProprietario(const std::string& proprietarioCane); + + // Sovrascrivi il comportamento della funzione print per tutti i MioCane. Vedi + // http://it.wikipedia.org/wiki/Polimorfismo_%28informatica%29 + // per una introduzione più generale se non sei familiare con + // il polimorfismo. + // La parola chiave override è opzionale ma fa sì che tu stia effettivamente + // sovrascrivendo il metodo nella classe base. + void print() const override; + +private: + std::string proprietario; +}; + +// Nel frattempo, nel file .cpp corrispondente: + +void MioCane::impostaProprietario(const std::string& proprietarioCane) +{ + proprietario = proprietarioCane; +} + +void MioCane::print() const +{ + Cane::print(); // Chiama la funzione print nella classe base Cane + std::cout << "Il cane è di " << proprietario << "\n"; + // stampa "Il cane è <nome> e pesa <peso>" + // "Il cane è di <proprietario>" +} + +/////////////////////////////////////////////////// +// Inizializzazione ed Overloading degli Operatori +////////////////////////////////////////////////// + +// In C++ puoi sovrascrivere il comportamento di operatori come +, -, *, /, ecc... +// Questo è possibile definendo una funzione che viene chiamata +// ogniqualvolta l'operatore è usato. + +#include <iostream> +using namespace std; + +class Punto { +public: + // Così si assegna alle variabili membro un valore di default. + double x = 0; + double y = 0; + + // Definisce un costruttore di default che non fa nulla + // ma inizializza il Punto ai valori di default (0, 0) + Punto() { }; + + // La sintassi seguente è nota come lista di inizializzazione + // ed è il modo appropriato di inizializzare i valori membro della classe + Punto (double a, double b) : + x(a), + y(b) + { /* Non fa nulla eccetto inizializzare i valori */ } + + // Sovrascrivi l'operatore +. + Punto operator+(const Punto& rhs) const; + + // Sovrascrivi l'operatore += + Punto& operator+=(const Punto& rhs); + + // Avrebbe senso aggiungere gli operatori - e -=, + // ma li saltiamo per rendere la guida più breve. +}; + +Punto Punto::operator+(const Punto& rhs) const +{ + // Crea un nuovo punto come somma di questo e di rhs. + return Punto(x + rhs.x, y + rhs.y); +} + +Punto& Punto::operator+=(const Punto& rhs) +{ + x += rhs.x; + y += rhs.y; + return *this; +} + +int main () { + Punto su (0,1); + Punto destro (1,0); + // Questo chiama l'operatore + di Punto + // Il Punto su chiama la funzione + con destro come argomento + Punto risultato = su + destro; + // Stampa "Risultato è spostato in (1,1)" + cout << "Risultato è spostato (" << risultato.x << ',' << risultato.y << ")\n"; + return 0; +} + +///////////////// +// Templates +//////////////// + +// Generalmente i templates in C++ sono utilizzati per programmazione generica, anche se +// sono molto più potenti dei costrutti generici in altri linguaggi. Inoltre, +// supportano specializzazione esplicita e parziale, classi in stile funzionale, +// e sono anche complete per Turing. + +// Iniziamo con il tipo di programmazione generica con cui forse sei familiare. Per +// definire una classe o una funzione che prende un parametro di un dato tipo: +template<class T> +class Box { +public: + // In questa classe, T può essere usato come qualsiasi tipo. + void inserisci(const T&) { ... } +}; + +// Durante la compilazione, il compilatore in effetti genera copie di ogni template +// con i parametri sostituiti, e così la definizione completa della classe deve essere +// presente ad ogni invocazione. Questo è il motivo per cui vedrai le classi template definite +// interamente in header files. + +// Per instanziare una classe template sullo stack: +Box<int> intBox; + +// e puoi usarla come aspettato: +intBox.inserisci(123); + +//Puoi, ovviamente, innestare i templates: +Box<Box<int> > boxOfBox; +boxOfBox.inserisci(intBox); + +// Fino al C++11, devi porre uno spazio tra le due '>', altrimenti '>>' +// viene visto come l'operatore di shift destro. + +// Qualche volta vedrai +// template<typename T> +// invece. La parole chiavi 'class' e 'typename' sono _generalmente_ +// intercambiabili in questo caso. Per una spiegazione completa, vedi +// http://en.wikipedia.org/wiki/Typename +// (si, quella parola chiave ha una sua pagina di Wikipedia propria). + +// Similmente, una funzione template: +template<class T> +void abbaiaTreVolte(const T& input) +{ + input.abbaia(); + input.abbaia(); + input.abbaia(); +} + +// Nota che niente è specificato relativamente al tipo di parametri. Il compilatore +// genererà e poi verificherà il tipo di ogni invocazione del template, così che +// la funzione di cui sopra funzione con ogni tipo 'T' che ha const 'abbaia' come metodo! + +Cane fluffy; +fluffy.impostaNome("Fluffy") +abbaiaTreVolte(fluffy); // Stampa "Fluffy abbaia" tre volte. + +// I parametri template non devono essere classi: +template<int Y> +void stampaMessaggio() { + cout << "Impara il C++ in " << Y << " minuti!" << endl; +} + +// E poi esplicitamente specializzare i template per avere codice più efficiente. Ovviamente, +// la maggior parte delle casistiche reali non sono così triviali. +// Notare che avrai comunque bisogna di dichiarare la funzione (o classe) come un template +// anche se hai esplicitamente specificato tutti i parametri. +template<> +void stampaMessaggio<10>() { + cout << "Impara il C++ più velocemente in soli 10 minuti!" << endl; +} + +printMessage<20>(); // Stampa "impara il C++ in 20 minuti!" +printMessage<10>(); // Stampa "Impara il C++ più velocemente in soli 10 minuti!" + +//////////////////////////// +// Gestione delle eccezioni +/////////////////////////// + +// La libreria standard fornisce un paio di tipi d'eccezioni +// (vedi http://en.cppreference.com/w/cpp/error/exception) +// ma ogni tipo può essere lanciato come eccezione +#include <exception> +#include <stdexcept> + +// Tutte le eccezioni lanciate all'interno del blocco _try_ possono essere catturate dai successivi +// handlers _catch_. +try { + // Non allocare eccezioni nello heap usando _new_. + throw std::runtime_error("C'è stato un problema."); +} + +// Cattura le eccezioni come riferimenti const se sono oggetti +catch (const std::exception& ex) +{ + std::cout << ex.what(); +} + +// Cattura ogni eccezioni non catturata dal blocco _catch_ precedente +catch (...) +{ + std::cout << "Catturata un'eccezione sconosciuta"; + throw; // Rilancia l'eccezione +} + +/////// +// RAII +/////// + +// RAII sta per "Resource Allocation Is Initialization". +// Spesso viene considerato come il più potente paradigma in C++. +// È un concetto semplice: un costruttore di un oggetto +// acquisisce le risorse di tale oggetto ed il distruttore le rilascia. + +// Per comprendere come questo sia vantaggioso, +// consideriamo una funzione che usa un gestore di file in C: +void faiQualcosaConUnFile(const char* nomefile) +{ + // Per cominciare, assumiamo che niente possa fallire. + + FILE* fh = fopen(nomefile, "r"); // Apri il file in modalità lettura. + + faiQualcosaConIlFile(fh); + faiQualcosAltroConEsso(fh); + + fclose(fh); // Chiudi il gestore di file. +} + +// Sfortunatamente, le cose vengono complicate dalla gestione degli errori. +// Supponiamo che fopen fallisca, e che faiQualcosaConUnFile e +// faiQualcosAltroConEsso ritornano codici d'errore se falliscono. +// (Le eccezioni sono la maniera preferita per gestire i fallimenti, +// ma alcuni programmatori, specialmente quelli con un passato in C, +// non sono d'accordo con l'utilità delle eccezioni). +// Adesso dobbiamo verificare che ogni chiamata per eventuali fallimenti e chiudere il gestore di file +// se un problema è avvenuto. +bool faiQualcosaConUnFile(const char* nomefile) +{ + FILE* fh = fopen(nomefile, "r"); // Apre il file in modalità lettura + if (fh == nullptr) // Il puntatore restituito è null in caso di fallimento. + return false; // Riporta il fallimento al chiamante. + + // Assumiamo che ogni funzione ritorni false se ha fallito + if (!faiQualcosaConIlFile(fh)) { + fclose(fh); // Chiude il gestore di file così che non sprechi memoria. + return false; // Propaga l'errore. + } + if (!faiQualcosAltroConEsso(fh)) { + fclose(fh); // Chiude il gestore di file così che non sprechi memoria. + return false; // Propaga l'errore. + } + + fclose(fh); // Chiudi il gestore di file così che non sprechi memoria. + return true; // Indica successo +} + +// I programmatori C in genere puliscono questa procedura usando goto: +bool faiQualcosaConUnFile(const char* nomefile) +{ + FILE* fh = fopen(nomefile, "r"); + if (fh == nullptr) + return false; + + if (!faiQualcosaConIlFile(fh)) + goto fallimento; + + if (!faiQualcosAltroConEsso(fh)) + goto fallimento; + + fclose(fh); // Chiude il file + return true; // Indica successo + +fallimento: + fclose(fh); + return false; // Propaga l'errore +} + +// Se le funzioni indicano errori usando le eccezioni, +// le cose sono un pò più pulite, ma sono sempre sub-ottimali. +void faiQualcosaConUnFile(const char* nomefile) +{ + FILE* fh = fopen(nomefile, "r"); // Apre il file in modalità lettura + if (fh == nullptr) + throw std::runtime_error("Errore nell'apertura del file."); + + try { + faiQualcosaConIlFile(fh); + faiQualcosAltroConEsso(fh); + } + catch (...) { + fclose(fh); // Fai sì che il file venga chiuso se si ha un errore. + throw; // Poi rilancia l'eccezione. + } + + fclose(fh); // Chiudi il file + // Tutto è andato bene +} + +// Confronta questo con l'utilizzo della classe C++ file stream (fstream) +// fstream usa i distruttori per chiudere il file. +// Come detto sopra, i distruttori sono automaticamente chiamati +// ogniqualvolta un oggetto esce dalla visibilità. +void faiQualcosaConUnFile(const std::string& nomefile) +{ + // ifstream è l'abbreviazione di input file stream + std::ifstream fh(nomefile); // Apre il file + + // Fai qualcosa con il file + faiQualcosaConIlFile(fh); + faiQualcosAltroConEsso(fh); + +} // Il file viene chiuso automaticamente chiuso qui dal distruttore + +// Questo ha vantaggi _enormi_: +// 1. Può succedere di tutto ma +// la risorsa (in questo caso il file handler) verrà ripulito. +// Una volta che scrivi il distruttore correttamente, +// È _impossibile_ scordarsi di chiudere l'handler e sprecare memoria. +// 2. Nota che il codice è molto più pulito. +// Il distruttore gestisce la chiusura del file dietro le scene +// senza che tu debba preoccupartene. +// 3. Il codice è sicuro da eccezioni. +// Una eccezione può essere lanciata in qualunque punto nella funzione e la ripulitura +// avverrà lo stesso. + +// Tutto il codice C++ idiomatico usa RAII in maniera vasta su tutte le risorse. +// Esempi aggiuntivi includono +// - Utilizzo della memoria con unique_ptr e shared_ptr +// - I contenitori - la lista della libreria standard, +// vettori (i.e. array auto-aggiustati), mappe hash, e così via +// sono tutti automaticamente distrutti con i loro contenuti quando escono dalla visibilità. +// - I mutex usano lock_guard e unique_lock + +// I contenitori che utilizzano chiavi non-primitive (classi personalizzate) +// richiedono la funzione di confronto nell'oggetto stesso, o tramite un puntatore a funzione. +// Le chiavi primitive hanno funzioni di confronto già definite, ma puoi sovrascriverle. +class Foo { +public: + int j; + Foo(int a) : j(a) {} +}; +struct funzioneDiConfronto { + bool operator()(const Foo& a, const Foo& b) const { + return a.j < b.j; + } +}; +// Questo non è permesso, anche se qualche compilatore potrebbe non dare problemi +//std::map<Foo, int> fooMap; +std::map<Foo, int, funzioneDiConfronto> fooMap; +fooMap[Foo(1)] = 1; +fooMap.find(Foo(1)); -- vero + +/////////////////////////////////////// +// Espressioni Lambda (C++11 e superiori) +/////////////////////////////////////// + +// Le espressioni lambda (più semplicemente "lambda") sono utilizzate +// per definire una funzione anonima nel punto in cui viene invocata, o +// dove viene passata come argomento ad una funzione + +// Ad esempio, consideriamo l'ordinamento di un vettore costituito da una +// coppia di interi, utilizzando il secondo elemento per confrontare +vector<pair<int, int> > tester; +tester.push_back(make_pair(3, 6)); +tester.push_back(make_pair(1, 9)); +tester.push_back(make_pair(5, 0)); + +// Passiamo una lambda come terzo argomento alla funzione di ordinamento +// `sort` è contenuta nell'header <algorithm> +sort(tester.begin(), tester.end(), [](const pair<int, int>& lhs, const pair<int, int>& rhs) { + return lhs.second < rhs.second; +}); + +// Nota bene la sintassi utilizzata nelle lambda: +// [] serve per "catturare" le variabili. +// La "Lista di Cattura" definisce tutte le variabili esterne che devono essere disponibili +// all'interno della funzione, e in che modo. +// La lista può contenere: +// 1. un valore: [x] +// 2. un riferimento: [&x] +// 3. qualunque variabile nello scope corrente, per riferimento [&] +// 4. qualunque variabile nello scope corrente, per valore [=] +// Esempio: + +vector<int> id_cani; +// numero_cani = 3; +for(int i = 0; i < 3; i++) { + id_cani.push_back(i); +} + +int pesi[3] = {30, 50, 10}; + +// Mettiamo che vuoi ordinare id_cani in base al peso dei cani +// Alla fine, id_cani sarà: [2, 0, 1] + +// Le lambda vengono in aiuto + +sort(id_cani.begin(), id_cani.end(), [&pesi](const int &lhs, const int &rhs) { + return pesi[lhs] < pesi[rhs]; +}); +// Nota come abbiamo catturato "pesi" per riferimento nell'esempio. +// Altre informazioni sulle lambda in C++: http://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11 + +/////////////////////////////// +// Ciclo For semplificato(C++11 e superiori) +/////////////////////////////// + +// Puoi usare un ciclo for per iterare su un tipo di dato contenitore +int arr[] = {1, 10, 3}; + +for(int elem: arr) { + cout << elem << endl; +} + +// Puoi usare "auto" senza preoccuparti del tipo degli elementi nel contenitore +// Ad esempio: + +for(auto elem: arr) { + // Fai qualcosa con `elem` +} + +/////////////////////// +// Roba divertente +////////////////////// + +// Aspetti del C++ che potrebbero sbalordire i nuovi arrivati (e anche qualche veterano). +// Questa sezione è, sfortunatamente, selvaggiamente incompleta; il C++ è uno dei linguaggi +// più facili con cui puoi spararti da solo nel piede. + +// Puoi sovrascrivere metodi privati! +class Foo { + virtual void bar(); +}; +class FooSub : public Foo { + virtual void bar(); // Sovrascrive Foo::bar! +}; + + +// 0 == false == NULL (la maggior parte delle volte)! +bool* pt = new bool; +*pt = 0; // Setta il valore puntato da 'pt' come falso. +pt = 0; // Setta 'pt' al puntatore null. Entrambe le righe vengono compilate senza warnings. + +// nullptr dovrebbe risolvere alcune di quei problemi: +int* pt2 = new int; +*pt2 = nullptr; // Non compila +pt2 = nullptr; // Setta pt2 a null. + +// C'è un'eccezione per i bool. +// Questo permette di testare un puntatore a null con if(!ptr), ma +// come conseguenza non puoi assegnare nullptr a un bool direttamente! +*pt = nullptr; // Questo compila, anche se '*pt' è un bool! + + +// '=' != '=' != '='! +// Chiama Foo::Foo(const Foo&) o qualche variante (vedi "move semantics") +// del costruttore di copia. +Foo f2; +Foo f1 = f2; + +// Chiama Foo::Foo(const Foo&) o qualche variante, ma solo copie di 'Foo' che fanno parte di +// 'fooSub'. Ogni altro membro di 'fooSub' viene scartato. Questo comportamento +// orribile viene chiamato "object slicing." +FooSub fooSub; +Foo f1 = fooSub; + +// Chiama Foo::operator=(Foo&) o una sua variante. +Foo f1; +f1 = f2; + + +/////////////////////////////////////// +// Tuple (C++11 e superiori) +/////////////////////////////////////// + +#include<tuple> + +// Concettualmente le tuple sono simili alle strutture del C, ma invece di avere +// i membri rappresentati con dei nomi, l'accesso agli elementi avviene tramite +// il loro ordine all'interno della tupla. + +// Cominciamo costruendo una tupla. +// Inserire i valori in una tupla +auto prima = make_tuple(10, 'A'); +const int maxN = 1e9; +const int maxL = 15; +auto seconda = make_tuple(maxN, maxL); + +// Vediamo gli elementi contenuti nella tupla "prima" +cout << get<0>(prima) << " " << get<1>(prima) << "\n"; // stampa : 10 A + +// Vediamo gli elementi contenuti nella tupla "seconda" +cout << get<0>(seconda) << " " << get<1>(seconda) << "\n"; // stampa: 1000000000 15 + +// Estrarre i valori dalla tupla, salvandoli nelle variabili +int primo_intero; +char primo_char; +tie(primo_intero, primo_char) = prima; +cout << primo_intero << " " << primo_char << "\n"; // stampa : 10 A + +// E' possibile creare tuple anche in questo modo +tuple<int, char, double> terza(11, 'A', 3.14141); + +// tuple_size ritorna il numero di elementi in una tupla (come constexpr) +cout << tuple_size<decltype(terza)>::value << "\n"; // stampa: 3 + +// tuple_cat concatena gli elementi di tutte le tuple, nell'esatto ordine +// in cui sono posizionati all'interno delle tuple stesse +auto tupla_concatenata = tuple_cat(prima, seconda, terza); +// tupla_concatenata diventa = (10, 'A', 1e9, 15, 11, 'A' ,3.14141) + +cout << get<0>(tupla_concatenata) << "\n"; // stampa: 10 +cout << get<3>(tupla_concatenata) << "\n"; // stampa: 15 +cout << get<5>(tupla_concatenata) << "\n"; // stampa: 'A' + + +///////////////////// +// Contenitori +///////////////////// + +// I Contenitori della "Standard Template Library", ovvero la libreria standard +// dei template contenuti nel C++, sono template predefiniti. +// I Contenitori si occupano di come allocare lo spazio per gli elementi contenuti, +// e forniscono funzioni per accedervi e manipolarli + +// Vediamo alcuni tipi di contenitori: + +// Vector (array dinamici/vettori) +// Permettono di definire un vettore, o una lista di oggetti, a runtime +#include<vector> +vector<Tipo_Dato> nome_vettore; // usato per inizializzare un vettore +cin >> val; +nome_vettore.push_back(val); // inserisce il valore di "val" nel vettore + +// Per iterare in un vettore, abbiamo due possibilità: +// Ciclo normale +for(int i=0; i<nome_vettore.size(); i++) +// Cicla dall'indice zero fino all'ultimo + +// Iteratore +vector<Tipo_Dato>::iterator it; // inizializza l'iteratore per il vettore +for(it=nome_vettore.begin(); it!=nome_vettore.end();++it) +// Nota che adesso non cicla più sugli indici, ma direttamente sugli elementi! + +// Per accedere agli elementi del vettore +// Operatore [] +var = nome_vettore[indice]; // Assegna a "var" il valore del vettore all'indice dato + + +// Set (insiemi) +// Gli insiemi sono contenitori che memorizzano elementi secondo uno specifico ordine. +// Gli insiemi vengono per lo più utilizzati per memorizzare valori unici, secondo +// un ordine, senza scrivere ulteriore codice. + +#include<set> +set<int> insieme; // Inizializza un insieme di interi +insieme.insert(30); // Inserisce il valore 30 nell'insieme +insieme.insert(10); // Inserisce il valore 10 nell'insieme +insieme.insert(20); // Inserisce il valore 20 nell'insieme +insieme.insert(30); // Inserisce il valore 30 nell'insieme +// Gli elementi dell'insieme sono: +// 10 20 30 + +// Per cancellare un elemento +insieme.erase(20); // Cancella l'elemento con valore 20 +// L'insieme contiene adesso: 10 30 + +// Per iterare su un insieme, usiamo gli iteratori +set<int>::iterator it; +for(it=insieme.begin();it<insieme.end();it++) { + cout << *it << endl; +} +// Stampa: +// 10 +// 30 + +// Per svuotare il contenitore usiamo il metodo "clear" +insieme.clear(); +cout << insieme.size(); +// Stampa: 0 + +// Nota: per permettere elementi duplicati, possiamo usare "multiset" + +// Map (mappa/tabella di hash) +// Le mappe servono per memorizzare un elemento, detto chiave, a cui viene +// associato un valore, il tutto secondo uno specifico ordine. + +#include<map> +map<char, int> mia_mappa; // Inizializza una mappa che usa i char come chiave, e gli interi come valore + +mia_mappa.insert(pair<char,int>('A',1)); +// Inserisce il valore 1 per la chiave A +mia_mappa.insert(pair<char,int>('Z',26)); +// Inserisce il valore 26 per la chiave Z + +// Per iterare +map<char,int>::iterator it; +for (it=mia_mappa.begin(); it!=mia_mappa.end(); ++it) + std::cout << it->first << "->" << it->second << '\n'; +// Stampa: +// A->1 +// Z->26 + +// Per trovare il valore corrispondente ad una data chiave +it = mia_mappa.find('Z'); +cout << it->second; +// Stampa: 26 + + +/////////////////////////////////// +// Operatori logici e bitwise(bit-a-bit) +////////////////////////////////// + +// La maggior parte di questi operatori in C++ sono gli stessi degli altri linguaggi + +// Operatori logici + +// Il C++ usa la "Short-circuit evaluation" per le espressioni booleane. Cosa significa? +// In pratica, in una condizione con due argomenti, il secondo viene considerato solo se +// il primo non basta a determinate il valore finale dell'espresione. + +true && false // Effettua il **and logico** e ritorna falso +true || false // Effettua il **or logico** e ritorna vero +! true // Effettua il **not logico** e ritorna falso + +// Invece di usare i simboli, si possono usare le keyword equivalenti +true and false // Effettua il **and logico** e ritorna falso +true or false // Effettua il **or logico** e ritorna vero +not true // Effettua il **not logico** e ritorna falso + +// Operatori bitwise(bit-a-bit) + +// **<<** Operatore di Shift a Sinistra +// << sposta i bit a sinistra +4 << 1 // Sposta a sinistra di 1 i bit di 4, ottenendo 8 +// x << n in pratica realizza x * 2^n + + +// **>>** Operatore di Shift a Destra +// >> sposta i bit a destra +4 >> 1 // Sposta a destra di 1 i bit di 4, ottenendo 2 +// x >> n in pratica realizza x / 2^n + +~4 // Effettua il NOT bit-a-bit +4 | 3 // Effettua il OR bit-a-bit +4 & 3 // Effettua il AND bit-a-bit +4 ^ 3 // Effettua il XOR bit-a-bit + +// Le keyword equivalenti sono +compl 4 // Effettua il NOT bit-a-bit +4 bitor 3 // Effettua il OR bit-a-bit +4 bitand 3 // Effettua il AND bit-a-bit +4 xor 3 // Effettua il XOR bit-a-bit + +``` +Letture consigliate: + +Un riferimento aggiornato del linguaggio può essere trovato qui +<http://cppreference.com/w/cpp> + +Risorse addizionali possono essere trovate qui <http://cplusplus.com> diff --git a/it-it/coffeescript-it.html.markdown b/it-it/coffeescript-it.html.markdown new file mode 100644 index 00000000..d30ba819 --- /dev/null +++ b/it-it/coffeescript-it.html.markdown @@ -0,0 +1,107 @@ +--- +language: coffeescript +contributors: + - ["Luca 'Kino' Maroni", "http://github.com/kino90"] + - ["Tenor Biel", "http://github.com/L8D"] + - ["Xavier Yao", "http://github.com/xavieryao"] +filename: coffeescript-it.coffee +lang: it-it +--- + +CoffeeScript è un piccolo linguaggio che compila direttamente nell'equivalente +JavaScript, non c'è nessuna interpretazione a runtime. Come possibile +successore di Javascript, CoffeeScript fa il suo meglio per restituire +un codice leggibile, ben stampato e performante in ogni ambiente JavaScript. + +Guarda anche [il sito di CoffeeScript](http://coffeescript.org/), che ha una +guida completa a CoffeeScript. + +```coffeescript +# CoffeeScript è un linguaggio hipster. +# Segue le mode di alcuni linguaggi moderni. +# Quindi i commenti sono come quelli di Ruby e Python, usano il cancelletto. + +### +I blocchi di commenti sono definiti con tre cancelletti, che vengono tradotti +direttamente in `/*` e `*/` nel codice JavaScript risultante. + +Prima di continuare devi conoscere la maggior parte +delle semantiche JavaScript. +### + +# Assegnamento: +numero = 42 #=> var numero = 42; +contrario = true #=> var contrario = true; + +# Condizioni: +numero = -42 if contrario #=> if(contrario) { numero = -42; } + +# Funzioni: +quadrato = (x) -> x * x #=> var quadrato = function(x) { return x * x; } + +riempi = (contenitore, liquido = "caffè") -> + "Sto riempiendo #{contenitore} con #{liquido}..." +#=>var riempi; +# +#riempi = function(contenitore, liquido) { +# if (liquido == null) { +# liquido = "caffè"; +# } +# return "Sto riempiendo " + contenitore + " con " + liquido + "..."; +#}; + +# Intervalli: +lista = [1..5] #=> var lista = [1, 2, 3, 4, 5]; + +# Oggetti: +matematica = + radice: Math.sqrt + quadrato: quadrato + cubo: (x) -> x * quadrato x +#=> var matematica = { +# "radice": Math.sqrt, +# "quadrato": quadrato, +# "cubo": function(x) { return x * quadrato(x); } +# } + +# Splats: +gara = (vincitore, partecipanti...) -> + print vincitore, partecipanti +#=>gara = function() { +# var partecipanti, vincitore; +# vincitore = arguments[0], partecipanti = 2 <= arguments.length ? __slice.call(arguments, 1) : []; +# return print(vincitore, partecipanti); +# }; + +# Esistenza: +alert "Lo sapevo!" if elvis? +#=> if(typeof elvis !== "undefined" && elvis !== null) { alert("Lo sapevo!"); } + +# Comprensione degli Array: +cubi = (matematica.cubo num for num in lista) +#=>cubi = (function() { +# var _i, _len, _results; +# _results = []; +# for (_i = 0, _len = lista.length; _i < _len; _i++) { +# num = lista[_i]; +# _results.push(matematica.cubo(num)); +# } +# return _results; +# })(); + +cibi = ['broccoli', 'spinaci', 'cioccolato'] +mangia cibo for cibo in cibi when cibo isnt 'cioccolato' +#=>cibi = ['broccoli', 'spinaci', 'cioccolato']; +# +#for (_k = 0, _len2 = cibi.length; _k < _len2; _k++) { +# cibo = cibi[_k]; +# if (cibo !== 'cioccolato') { +# mangia(cibo); +# } +#} +``` + +## Altre risorse + +- [Smooth CoffeeScript](http://autotelicum.github.io/Smooth-CoffeeScript/) +- [CoffeeScript Ristretto](https://leanpub.com/coffeescript-ristretto/read) diff --git a/it-it/elixir-it.html.markdown b/it-it/elixir-it.html.markdown new file mode 100644 index 00000000..60301b1a --- /dev/null +++ b/it-it/elixir-it.html.markdown @@ -0,0 +1,428 @@ +--- +language: elixir +contributors: + - ["Luca 'Kino' Maroni", "https://github.com/kino90"] + - ["Joao Marques", "http://github.com/mrshankly"] + - ["Dzianis Dashkevich", "https://github.com/dskecse"] +translators: + - ["Tommaso Pifferi","http://github.com/neslinesli93"] +filename: learnelixir-it.ex +lang: it-it +--- + +Elixir è un linguaggio funzionale moderno, costruito sulla VM Erlang. +È totalmente compatibile con Erlang, ma con una sintassi più standard +e molte altre funzionalità. + +```elixir + +# I commenti su una riga iniziano con un cancelletto. + +# Non esistono commenti multilinea, +# ma puoi concatenare più commenti. + +# Per usare la shell di elixir usa il comando `iex`. +# Compila i tuoi moduli con il comando `elixirc`. + +# Entrambi i comandi dovrebbero già essere nel tuo PATH se hai installato +# elixir correttamente. + +## --------------------------- +## -- Tipi di base +## --------------------------- + +# Numeri +3 # intero (Integer) +0x1F # intero +3.0 # decimale (Float) + +# Atomi, che sono literals, una costante con un nome. Iniziano con `:`. +:ciao # atomo (Atom) + +# Tuple che sono salvate in celle di memoria contigue. +{1,2,3} # tupla (Tuple) + +# Possiamo accedere ad un elemento di una tupla con la funzione `elem`: +elem({1, 2, 3}, 0) #=> 1 + +# Liste, che sono implementate come liste concatenate (o linked list). +[1,2,3] # lista (List) + +# Possiamo accedere alla testa (head) e alla coda (tail) delle liste così: +[testa | coda] = [1,2,3] +testa #=> 1 +coda #=> [2,3] + +# In Elixir, proprio come in Erlang, il simbolo `=` denota pattern matching e +# non un assegnamento. +# +# Questo significa che la parte sinistra (pattern) viene confrontata alla +# parte destra. +# +# Questo spiega il funzionamento dell'esempio dell'accesso alla lista di prima. + +# Un pattern match darà errore quando le parti non combaciano, ad esempio se +# le tuple hanno dimensione differente. +# {a, b, c} = {1, 2} #=> ** (MatchError) no match of right hand side value: {1,2} + +# Ci sono anche i binari +<<1,2,3>> # binari (Binary) + +# Stringhe e liste di caratteri +"ciao" # stringa (String) +'ciao' # lista di caratteri (List) + +# Stringhe multilinea +""" +Sono una stringa +multi-linea. +""" +#=> "Sono una stringa\nmulti-linea.\n" + +# Le stringhe sono tutte codificate in UTF-8: +"cìaò" +#=> "cìaò" + +# le stringhe in realtà sono dei binari, e le liste di caratteri sono liste. +<<?a, ?b, ?c>> #=> "abc" +[?a, ?b, ?c] #=> 'abc' + +# `?a` in elixir restituisce il valore ASCII della lettera `a` +?a #=> 97 + +# Per concatenare liste si usa `++`, per binari si usa `<>` +[1,2,3] ++ [4,5] #=> [1,2,3,4,5] +'ciao ' ++ 'mondo' #=> 'ciao mondo' + +<<1,2,3>> <> <<4,5>> #=> <<1,2,3,4,5>> +"ciao " <> "mondo" #=> "ciao mondo" + +# Gli intervalli sono rappresentati come `inizio..fine` (estremi inclusi) +1..10 #=> 1..10 (Range) +minore..maggiore = 1..10 # Puoi fare pattern matching anche sugli intervalli +[minore, maggiore] #=> [1, 10] + +## --------------------------- +## -- Operatori +## --------------------------- + +# Un po' di matematica +1 + 1 #=> 2 +10 - 5 #=> 5 +5 * 2 #=> 10 +10 / 2 #=> 5.0 + +# In elixir l'operatore `/` restituisce sempre un decimale. + +# Per fare una divisione intera si usa `div` +div(10, 2) #=> 5 + +# Per ottenere il resto di una divisione si usa `rem` +rem(10, 3) #=> 1 + +# Ci sono anche gli operatori booleani: `or`, `and` e `not`. +# Questi operatori si aspettano un booleano come primo argomento. +true and true #=> true +false or true #=> true +# 1 and true #=> ** (ArgumentError) argument error + +# Elixir fornisce anche `||`, `&&` e `!` che accettano argomenti +# di qualsiasi tipo. +# Tutti i valori tranne `false` e `nil` saranno valutati come true. +1 || true #=> 1 +false && 1 #=> false +nil && 20 #=> nil +!true #=> false + +# Per i confronti abbiamo: `==`, `!=`, `===`, `!==`, `<=`, `>=`, `<` e `>` +1 == 1 #=> true +1 != 1 #=> false +1 < 2 #=> true + +# `===` e `!==` sono più rigidi quando si confrontano interi e decimali: +1 == 1.0 #=> true +1 === 1.0 #=> false + +# Possiamo anche confrontare tipi di dato diversi: +1 < :ciao #=> true + +# L'ordine generale è definito sotto: +# numeri < atomi < riferimenti < funzioni < porte < pid < tuple < liste +# < stringhe di bit + +# Per citare Joe Armstrong su questo: "L'ordine non è importante, +# ma è importante che sia definito un ordine." + +## --------------------------- +## -- Controllo di flusso +## --------------------------- + +# espressione `se` (`if`) +if false do + "Questo non si vedrà mai" +else + "Questo sì" +end + +# c'è anche un `se non` (`unless`) +unless true do + "Questo non si vedrà mai" +else + "Questo sì" +end + +# Ti ricordi il pattern matching? +# Moltre strutture di controllo di flusso in elixir si basano su di esso. + +# `case` ci permette di confrontare un valore a diversi pattern: +case {:uno, :due} do + {:quattro, :cinque} -> + "Questo non farà match" + {:uno, x} -> + "Questo farà match e binderà `x` a `:due`" + _ -> + "Questo farà match con qualsiasi valore" +end + +# Solitamente si usa `_` se non si ha bisogno di utilizzare un valore. +# Ad esempio, se ci serve solo la testa di una lista: +[testa | _] = [1,2,3] +testa #=> 1 + +# Per aumentare la leggibilità possiamo usarlo in questo modo: +[testa | _coda] = [:a, :b, :c] +testa #=> :a + +# `cond` ci permette di verificare più condizioni allo stesso momento. +# Usa `cond` invece di innestare più espressioni `if`. +cond do + 1 + 1 == 3 -> + "Questa stringa non si vedrà mai" + 2 * 5 == 12 -> + "Nemmeno questa" + 1 + 2 == 3 -> + "Questa sì!" +end + +# È pratica comune mettere l'ultima condizione a `true`, che farà sempre match +cond do + 1 + 1 == 3 -> + "Questa stringa non si vedrà mai" + 2 * 5 == 12 -> + "Nemmeno questa" + true -> + "Questa sì! (essenzialmente funziona come un else)" +end + +# `try/catch` si usa per gestire i valori lanciati (throw), +# Supporta anche una clausola `after` che è invocata in ogni caso. +try do + throw(:ciao) +catch + message -> "Ho ricevuto #{message}." +after + IO.puts("Io sono la clausola 'after'.") +end +#=> Io sono la clausola 'after' +# "Ho ricevuto :ciao" + +## --------------------------- +## -- Moduli e Funzioni +## --------------------------- + +# Funzioni anonime (notare il punto) +quadrato = fn(x) -> x * x end +quadrato.(5) #=> 25 + +# Accettano anche guardie e condizioni multiple. +# le guardie ti permettono di perfezionare il tuo pattern matching, +# sono indicate dalla parola chiave `when`: +f = fn + x, y when x > 0 -> x + y + x, y -> x * y +end + +f.(1, 3) #=> 4 +f.(-1, 3) #=> -3 + +# Elixir fornisce anche molte funzioni, disponibili nello scope corrente. +is_number(10) #=> true +is_list("ciao") #=> false +elem({1,2,3}, 0) #=> 1 + +# Puoi raggruppare delle funzioni all'interno di un modulo. +# All'interno di un modulo usa `def` per definire le tue funzioni. +defmodule Matematica do + def somma(a, b) do + a + b + end + + def quadrato(x) do + x * x + end +end + +Matematica.somma(1, 2) #=> 3 +Matematica.quadrato(3) #=> 9 + +# Per compilare il modulo 'Matematica' salvalo come `matematica.ex` e usa +# `elixirc`. +# nel tuo terminale: elixirc matematica.ex + +# All'interno di un modulo possiamo definire le funzioni con `def` e funzioni +# private con `defp`. +# Una funzione definita con `def` è disponibile per essere invocata anche da +# altri moduli, una funziona privata può essere invocata solo localmente. +defmodule MatematicaPrivata do + def somma(a, b) do + esegui_somma(a, b) + end + + defp esegui_somma(a, b) do + a + b + end +end + +MatematicaPrivata.somma(1, 2) #=> 3 +# MatematicaPrivata.esegui_somma(1, 2) #=> ** (UndefinedFunctionError) + +# Anche le dichiarazioni di funzione supportano guardie e condizioni multiple: +defmodule Geometria do + def area({:rettangolo, w, h}) do + w * h + end + + def area({:cerchio, r}) when is_number(r) do + 3.14 * r * r + end +end + +Geometria.area({:rettangolo, 2, 3}) #=> 6 +Geometria.area({:cerchio, 3}) #=> 28.25999999999999801048 +# Geometria.area({:cerchio, "non_un_numero"}) +#=> ** (FunctionClauseError) no function clause matching in Geometria.area/1 + +# A causa dell'immutabilità dei dati, la ricorsione è molto frequente in elixir +defmodule Ricorsione do + def somma_lista([testa | coda], accumulatore) do + somma_lista(coda, accumulatore + testa) + end + + def somma_lista([], accumulatore) do + accumulatore + end +end + +Ricorsione.somma_lista([1,2,3], 0) #=> 6 + +# I moduli di Elixir supportano attributi. Ci sono degli attributi incorporati +# e puoi anche aggiungerne di personalizzati. +defmodule Modulo do + @moduledoc """ + Questo è un attributo incorporato in un modulo di esempio. + """ + + @miei_dati 100 # Questo è un attributo personalizzato . + IO.inspect(@miei_dati) #=> 100 +end + +## --------------------------- +## -- Strutture ed Eccezioni +## --------------------------- + + +# Le Strutture (Structs) sono estensioni alle mappe che portano +# valori di default, garanzia alla compilazione e polimorfismo in Elixir. +defmodule Persona do + defstruct nome: nil, eta: 0, altezza: 0 +end + +luca = %Persona{ nome: "Luca", eta: 24, altezza: 185 } +#=> %Persona{eta: 24, altezza: 185, nome: "Luca"} + +# Legge al valore di 'nome' +luca.nome #=> "Luca" + +# Modifica il valore di eta +luca_invecchiato = %{ luca | eta: 25 } +#=> %Persona{eta: 25, altezza: 185, nome: "Luca"} + +# Il blocco `try` con la parola chiave `rescue` è usato per gestire le eccezioni +try do + raise "un errore" +rescue + RuntimeError -> "Salvato un errore di Runtime" + _error -> "Questo salverà da qualsiasi errore" +end + +# Tutte le eccezioni hanno un messaggio +try do + raise "un errore" +rescue + x in [RuntimeError] -> + x.message +end + +## --------------------------- +## -- Concorrenza +## --------------------------- + +# Elixir si basa sul modello degli attori per la concorrenza. +# Tutto ciò di cui abbiamo bisogno per scrivere programmi concorrenti in elixir +# sono tre primitive: creare processi, inviare messaggi e ricevere messaggi. + +# Per creare un nuovo processo si usa la funzione `spawn`, che riceve una +# funzione come argomento. +f = fn -> 2 * 2 end #=> #Function<erl_eval.20.80484245> +spawn(f) #=> #PID<0.40.0> + +# `spawn` restituisce un pid (identificatore di processo). Puoi usare questo +# pid per inviare messaggi al processo. +# Per passare messaggi si usa l'operatore `send`. +# Perché tutto questo sia utile dobbiamo essere capaci di ricevere messaggi, +# oltre ad inviarli. Questo è realizzabile con `receive`: + +# Il blocco `receive do` viene usato per mettersi in ascolto di messaggi +# ed elaborarli quando vengono ricevuti. Un blocco `receive do` elabora +# un solo messaggio ricevuto: per fare elaborazione multipla di messaggi, +# una funzione con un blocco `receive do` al suo intero dovrà chiamare +# ricorsivamente sé stessa per entrare di nuovo nel blocco `receive do`. +defmodule Geometria do + def calcolo_area do + receive do + {:rettangolo, w, h} -> + IO.puts("Area = #{w * h}") + calcolo_area() + {:cerchio, r} -> + IO.puts("Area = #{3.14 * r * r}") + calcolo_area() + end + end +end + +# Compila il modulo e crea un processo che esegue `calcolo_area` nella shell +pid = spawn(fn -> Geometria.calcolo_area() end) #=> #PID<0.40.0> +# Alternativamente +pid = spawn(Geometria, :calcolo_area, []) + +# Invia un messaggio a `pid` che farà match su un pattern nel blocco in receive +send pid, {:rettangolo, 2, 3} +#=> Area = 6 +# {:rettangolo,2,3} + +send pid, {:cerchio, 2} +#=> Area = 12.56000000000000049738 +# {:cerchio,2} + +# Anche la shell è un processo. Puoi usare `self` per ottenere il pid corrente +self() #=> #PID<0.27.0> +``` + +## Referenze + +* [Getting started guide](http://elixir-lang.org/getting_started/1.html) dalla [pagina web ufficiale di elixir](http://elixir-lang.org) +* [Documentazione Elixir](http://elixir-lang.org/docs/master/) +* ["Programming Elixir"](https://pragprog.com/book/elixir/programming-elixir) di Dave Thomas +* [Elixir Cheat Sheet](http://media.pragprog.com/titles/elixir/ElixirCheat.pdf) +* ["Learn You Some Erlang for Great Good!"](http://learnyousomeerlang.com/) di Fred Hebert +* ["Programming Erlang: Software for a Concurrent World"](https://pragprog.com/book/jaerlang2/programming-erlang) di Joe Armstrong diff --git a/it-it/git-it.html.markdown b/it-it/git-it.html.markdown new file mode 100644 index 00000000..521538a1 --- /dev/null +++ b/it-it/git-it.html.markdown @@ -0,0 +1,498 @@ +--- +category: tool +tool: git +contributors: + - ["Jake Prather", "http://github.com/JakeHP"] + - ["Leo Rudberg" , "http://github.com/LOZORD"] + - ["Betsy Lorton" , "http://github.com/schbetsy"] + - ["Bruno Volcov", "http://github.com/volcov"] +translators: + - ["Christian Grasso", "http://chris54721.net"] +filename: LearnGit-it.txt +lang: it-it +--- + +Git è un sistema di +[controllo versione distribuito](https://it.wikipedia.org/wiki/Controllo_versione_distribuito) +e di gestione del codice sorgente. + +Git esegue una serie di _snapshot_ per salvare lo stato di un progetto, così +facendo può fornirti la possibilità di gestire il tuo codice e di salvarne lo +stato assegnando delle versioni. + +## Basi del controllo versione + +### Cos'è il controllo versione? + +Il controllo versione (_Version Control_ o _Versioning_) è un sistema che +registra le modifiche apportate a uno o più file nel tempo. + +### Controllo versione centralizzato e distribuito + +* Il controllo versione centralizzato si concentra sulla sincronizzazione, il + monitoraggio e il backup dei file. +* Il controllo versione distribuito si concentra sulla condivisione delle + modifiche. Ogni modifica ha un identificatore univoco. +* I sistemi distribuiti non hanno una struttura definita. Si potrebbe creare + ad esempio un sistema centralizzato simile a SVN utilizzando Git. + +[Ulteriori informazioni](http://git-scm.com/book/it/v1/Per-Iniziare-Il-Controllo-di-Versione) + +### Perchè usare Git? + +* Consente di lavorare offline. +* Collaborare con altre persone è semplice! +* Utilizzare i branch (rami di sviluppo) è semplice! +* Git è veloce. +* Git è flessibile. + +## Architettura di Git + +### Repository + +Un insieme di file, cartelle, registrazioni della cronologia e versioni. +Immaginalo come una struttura dati del codice, con la caratteristica che ogni +"elemento" del codice ti fornisce accesso alla sua cronologia delle revisioni, +insieme ad altre cose. + +Un repository comprende la cartella .git e il working tree. + +### Cartella .git (componente del repository) + +La cartella .git contiene tutte le configurazioni, i log, i rami e altro. +[Lista dettagliata](http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html) + +### Working Tree (componente del repository) + +Si tratta semplicemente delle cartelle e dei file presenti nel repository. +Spesso viene indicato come "directory di lavoro" ("working directory"). + +### Index (componente della cartella .git) + +L'Index è l'area di staging di Git. Si tratta di un livello che separa il +working tree dal repository. Ciò fornisce agli sviluppatori più controllo su +cosa viene inviato al repository. + +### Commit + +Un commit è uno snapshot di una serie di modifiche apportate al working tree. +Ad esempio, se hai aggiunto 5 file e ne hai rimossi 2, ciò sarà registrato in +un commit. Il commit può essere pushato (inviato) o meno ad altri repository. + +### Branch (ramo) + +Un branch (ramo) è essenzialmente un puntatore all'ultimo commit che hai +effettuato. Effettuando altri commit, il puntatore verrà automaticamente +aggiornato per puntare all'ultimo commit. + +### Tag + +Un tag è un contrassegno applicato a un punto specifico nella cronologia dei +commit. Di solito i tag vengono utilizzati per contrassegnare le versioni +rilasciate (v1.0, v1.1, etc.). + +### HEAD e head (componenti della cartella .git) + +HEAD (in maiuscolo) è un puntatore che punta al branch corrente. Un repository +può avere solo 1 puntatore HEAD *attivo*. + +head (in minuscolo) è un puntatore che può puntare a qualsiasi commit. Un +repository può avere un numero qualsiasi di puntatori head. + +### Stadi di Git +* _Modified_ - Un file è stato modificato, ma non è ancora stato effettuato + un commit per registrare le modifiche nel database di Git +* _Staged_ - Un file modificato è stato contrassegnato per essere incluso nel + prossimo commit +* _Committed_ - È stato effettuato un commit e le modifiche sono state + registrate nel database di Git + +## Comandi + +### init + +Crea un repository Git vuoto. Le impostazioni e le informazioni del repository +sono salvate nella cartella ".git". + +```bash +$ git init +``` + +### config + +Utilizzato per configurare le impostazioni, sia specifiche del repository, sia +a livello globale. Le impostazioni globali sono salvate in `~/.gitconfig`. + +```bash +$ git config --global user.email "email@example.com" +$ git config --global user.name "Nome utente" +``` + +[Ulteriori informazioni su git config](http://git-scm.com/docs/git-config) + +### help + +Fornisce una documentazione molto dettagliata di ogni comando. + +```bash +# Mostra i comandi più comuni +$ git help + +# Mostra tutti i comandi disponibili +$ git help -a + +# Documentazione di un comando specifico +# git help <nome_comando> +$ git help add +$ git help commit +$ git help init +# oppure git <nome_comando> --help +$ git add --help +$ git commit --help +$ git init --help +``` + +### Ignorare file + +Per impedire intenzionalmente che file privati o temporanei vengano inviati +al repository Git. + +```bash +$ echo "temp/" >> .gitignore +$ echo "privato.txt" >> .gitignore +``` + + +### status + +Mostra le differenza tra lo stato attuale del working tree e l'attuale commit +HEAD. + +```bash +$ git status +``` + +### add + +Aggiunge file alla staging area, ovvero li contrassegna per essere inclusi nel +prossimo commit. Ricorda di aggiungere i nuovi file, altrimenti non saranno +inclusi nei commit! + +```bash +# Aggiunge un file nella directory attuale +$ git add HelloWorld.java + +# Aggiunge un file in una sottocartella +$ git add /path/to/file/HelloWorld.c + +# Il comando supporta le espressioni regolari +$ git add ./*.java + +# Aggiunge tutti i file non ancora contrassegnati +$ git add --all +``` + +Questo comando contrassegna soltanto i file, senza effettuare un commit. + +### branch + +Utilizzato per gestire i branch (rami). Puoi visualizzare, modificare, creare o +eliminare branch utilizzando questo comando. + +```bash +# Visualizza i branch e i remote +$ git branch -a + +# Crea un nuovo branch +$ git branch nuovoBranch + +# Elimina un branch +$ git branch -d nomeBranch + +# Rinomina un branch +$ git branch -m nomeBranch nuovoNomeBranch + +# Permette di modificare la descrizione di un branch +$ git branch nomeBranch --edit-description +``` + +### tag + +Utilizzato per gestire i tag. + +```bash +# Visualizza i tag esistenti +$ git tag +# Crea un nuovo tag +# L'opzione -m consente di specificare una descrizione per il tag. +# Se l'opzione -m non viene aggiunta, Git aprirà un editor per consentire +# l'inserimento del messaggio. +$ git tag -a v2.0 -m 'Versione 2.0' +# Mostra informazioni relative a un tag +# Include informazioni sul creatore del tag, la data di creazione, e il +# messaggio assegnato al tag oltre alle informazioni sul commit. +$ git show v2.0 +``` + +### checkout + +Consente di cambiare branch o ripristinare i file a una revisione specifica. +Tutti i file nel working tree vengono aggiornati per corrispondere alla versione +presente nel branch o nel commit specificato. + +```bash +# Effettua il checkout di un repository - il branch predefinito è 'master' +$ git checkout +# Effettua il checkout di un branch specifico +$ git checkout nomeBranch +# Crea un nuovo branch e ne effettua il checkout +# Equivalente a "git branch <nomeBranch>; git checkout <nomeBranch>" +$ git checkout -b nuovoBranch +``` + +### clone + +Clona, o copia, un repository esistente in una nuova directory. Inoltre, +aggiunge dei branch _remote-tracking_, utilizzati per monitorare i branch +remoti corrispondenti a quelli locali, e consentendo così di inviare le +modifiche al repository remoto. + +```bash +# Clona learnxinyminutes-docs +$ git clone https://github.com/adambard/learnxinyminutes-docs.git +# Clona solo l'ultima revisione di un repository +$ git clone --depth 1 https://github.com/adambard/learnxinyminutes-docs.git +# Clona solo un branch specifico +$ git clone -b master-cn https://github.com/adambard/learnxinyminutes-docs.git --single-branch +``` + +### commit + +Effettua uno _snapshot_ dello stato attuale del working tree e registra le +modifiche in un nuovo commit. Il commit contiene, oltre alle modifiche apportate, +anche l'autore e una descrizione. + +```bash +# Crea un nuovo commit con un messaggio +$ git commit -m "Aggiunta la funzione multiplyNumbers() in HelloWorld.c" + +# Aggiunge (git add) automaticamente i file modificati o eliminati (ESCLUSI +# i nuovi file) e quindi effettua il commit +$ git commit -a -m "Modificato foo.php e rimosso bar.php" + +# Modifica l'ultimo commit (il comando elimina il commit precedente e lo +# sostituisce con uno nuovo) +$ git commit --amend -m "Messaggio corretto" +``` + +### diff + +Mostra la differenza tra un file nel working tree e la sua versione nell'index, +in un branch o ad un commit specifico. + +```bash +# Mostra la differenza tra il working tree e l'index +$ git diff + +# Mostra la differenza tra l'index e il commit più recente +$ git diff --cached + +# Mostra la differenza tra il working tree e un commit specifico +$ git diff <commit> + +# Mostra la differenza tra due commit +$ git diff <commit1> <commit2> +``` + +### grep + +Consente di effettuare una ricerca veloce nel repository. + +```bash +# Cerca "variableName" nei file Java +$ git grep 'variableName' -- '*.java' + +# Cerca una riga contenente "arrayListName" E "add" oppure "remove" +$ git grep -e 'arrayListName' --and \( -e add -e remove \) +``` + +Impostazioni relative a `git grep`: + +```bash +# Mostra il numero delle righe +$ git config --global grep.lineNumber true + +# Rende i risultati più leggibili +$ git config --global alias.g "grep --break --heading --line-number" +``` + +### log + +Mostra la cronologia dei commit inviati al repository. + +```bash +# Mostra tutti i commit +$ git log + +# Mostra ogni commit su una sola riga +$ git log --oneline + +# Mostra solo i commit legati ai merge +$ git log --merges +``` + +### merge + +Effettua un "merge", ovvero unisce le modifiche di un branch in quello attuale. + +```bash +# Unisce il branch specificato a quello attuale +$ git merge nomeBranch + +# Genera un commit in ogni caso dopo aver eseguito il merge +$ git merge --no-ff nomeBranch +``` + +### mv + +Rinomina o sposta un file. + +```bash +# Rinomina un file +$ git mv HelloWorld.c HelloNewWorld.c + +# Sposta un file +$ git mv HelloWorld.c ./new/path/HelloWorld.c + +# Forza l'esecuzione del comando +# Se un file "nuovoNomeFile" esiste già nella directory, verrà sovrascritto +$ git mv -f nomeFile nuovoNomeFile +``` + +### pull + +Aggiorna il repository effettuando il merge delle nuove modifiche. + +```bash +# Aggiorna il branch attuale dal remote "origin" +$ git pull + +# Di default, git pull aggiorna il branch attuale effettuando il merge +# delle nuove modifiche presenti nel branch remote-tracking corrispondente +$ git pull + +# Aggiorna le modifiche dal branch remoto, quindi effettua il rebase dei commit +# nel branch locale +# Equivalente a: "git pull <remote> <branch>; git rebase <branch>" +$ git pull origin master --rebase +``` + +### push + +Invia ed effettua il merge delle modifiche da un branch locale ad uno remoto. + +```bash +# Invia ed effettua il merge delle modifiche dal branch "master" +# al remote "origin". +# git push <remote> <branch> +$ git push origin master + +# Di default, git push invia ed effettua il merge delle modifiche +# dal branch attuale al branch remote-tracking corrispondente +$ git push + +# Per collegare il branch attuale ad uno remoto, basta aggiungere l'opzione -u +$ git push -u origin master +``` + +### stash + +Salva lo stato attuale del working tree in una lista di modifiche non ancora +inviate al repository con un commit che possono essere applicate nuovamente +in seguito. + +Questo comando può essere utile se, ad esempio, mentre stai effettuando delle +modifiche non ancora completate, hai bisogno di aggiornare il repository locale +con `git pull`. Poichè non hai ancora effettuato il commit di tutte le modifiche, +non sarà possibile effettuare il pull. Tuttavia, puoi utilizzare `git stash` per +salvare temporaneamente le modifiche e applicarle in seguito. + +```bash +$ git stash +``` + +Ora puoi effettuare il pull: + +```bash +$ git pull +``` + +A questo punto, come già suggerito dall'output del comando `git stash`, puoi +applicare le modifiche: + +```bash +$ git stash apply +``` + +Infine puoi controllare che tutto sia andato bene: + +```bash +$ git status +``` + +Puoi visualizzare gli accantonamenti che hai effettuato finora utilizzando: + +```bash +$ git stash list +``` + +### rebase (attenzione) + +Applica le modifiche effettuate su un branch su un altro branch. +*Non effettuare il rebase di commit che hai già inviato a un repository pubblico!* + +```bash +# Effettua il rebase di experimentBranch in master +$ git rebase master experimentBranch +``` + +[Ulteriori informazioni](https://git-scm.com/book/it/v1/Diramazioni-in-Git-Rifondazione) + +### reset (attenzione) + +Effettua il reset del commit HEAD attuale ad uno stato specifico. +Questo comando consente di annullare `merge`, `pull`, `commit`, `add` e altro. +Tuttavia, può essere pericoloso se non si sa cosa si sta facendo. + +```bash +# Effettua il reset della staging area (annullando le aggiunte e le rimozioni +# di file dal repository, senza modificare il working tree) +$ git reset + +# Effettua il reset completo della staging area, ovvero annulla qualsiasi +# modifica al repository eliminando definitivamente anche tutte le modifiche +# ai file non inviate e ripristinando il working tree +$ git reset --hard + +# Effettua il reset del branch attuale al commit specificato (lasciando il +# working tree intatto) +$ git reset 31f2bb1 + +# Effettua il reset completo del branch attuale al commit specificato, +# eliminando qualsiasi modifica non inviata +$ git reset --hard 31f2bb1 +``` + +### rm + +Consente di rimuovere un file dal working tree e dal repository. +Per eliminare un file solo dal working tree ma non dal repository, è invece +necessario utilizzare `/bin/rm`. + +```bash +# Elimina un file nella directory attuale +$ git rm HelloWorld.c + +# Elimina un file da una sottocartella +$ git rm /pather/to/the/file/HelloWorld.c +``` diff --git a/it-it/go-it.html.markdown b/it-it/go-it.html.markdown new file mode 100644 index 00000000..e49ccd79 --- /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 include un'ottima libreria standard e ha una community entusiasta. + +```go +// Commento su riga singola +/* Commento + su riga multipla */ + +// In cima ad 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 restituisce due valori. + somma, prod := imparaMoltepliciValoriRestituiti(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 restituire (molteplici!) valori. +In questo esempio, x e y sono gli argomenti, mentre somma e prod sono i valori restituiti. +Da notare il fatto che x e somma vengono dichiarati come interi. +*/ +func imparaMoltepliciValoriRestituiti(x, y int) (somma, prod int) { + return x + y, x * y // Restituisce 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 +può 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 restituiti da una funzione. +// Assegnare un nome al tipo di dato restituito 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 restituire. +func imparaValoriRestituitiConNome(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 commettere errori a causa di puntatori nulli, ma non puoi +// incrementare un puntatore direttamente. +func imparaLaMemoria() (p, q *int) { + // I valori restituiti (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 i loop in Go, ma ha varie forme. + for { // Ciclo infinito. + break // Scherzavo. + continue // Non si arriva qua. + } + + // Puoi usare range per iterare lungo un vettore, slice, stringa, mappa o canale. + // range restituisce 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 restituito è 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 restituisce 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 abbia termine. + 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/html-it.html.markdown b/it-it/html-it.html.markdown new file mode 100644 index 00000000..471019a1 --- /dev/null +++ b/it-it/html-it.html.markdown @@ -0,0 +1,121 @@ +--- +language: html +filename: learnhtml-it.html +contributors: + - ["Christophe THOMAS", "https://github.com/WinChris"] +translators: + - ["Ale46", "http://github.com/Ale46/"] +lang: it-it +--- + +HTML sta per HyperText Markup Language (linguaggio a marcatori per ipertesti). +È un linguaggio che consente di scrivere pagine web per il world wide web. +È un linguaggio di markup, che permette di scrivere pagine web usando del codice che indica come il testo ed i dati devono essere mostrati. +Infatti, i files html sono semplici file di testo. +Cos'è il markup? È un metodo per organizzare i dati della pagina circondandoli con tag di apertura e tag di chiusura. +Questo markup serve a dare significato al testo che racchiude. +Come altri linguaggi di programmazione, HTML ha molte versioni. Qui discuteremo di HTML5. + +**NOTA :** Puoi testare i differenti tags ed elementi man mano che prosegui nel tutorial in un sito come [codepen](http://codepen.io/pen/) per vedere i loro effetti, capire come lavorano e familiarizzare con il linguaggio. +Questo articolo riguarda principalmente la sintassi HTML ed alcuni suggerimenti utili. + + +```html +<!-- I commenti sono racchiusi come in questa riga! --> + +<!-- #################### I Tags #################### --> + +<!-- Ecco un esempio di file HTML che andremo ad analizzare. --> + +<!doctype html> + <html> + <head> + <title>Il mio sito</title> + </head> + <body> + <h1>Ciao, mondo!</h1> + <a href = "http://codepen.io/anon/pen/xwjLbZ">Vieni a vedere ciò che mostra</a> + <p>Questo è un paragrafo.</p> + <p>Questo è un altro paragrafo.</p> + <ul> + <li>Questo è un elemento di un elenco non numerato (elenco puntato)</li> + <li>Questo è un altro elemento</li> + <li>E questo è l'ultimo elemento dell'elenco</li> + </ul> + </body> + </html> + +<!-- Un file HTML inizia sempre indicando al browser che la pagina è HTML. --> +<!doctype html> + +<!-- Dopo questo, inizia aprendo un tag <html>. --> +<html> + +<!-- che sarà chiuso alla fine del file con </html>. --> +</html> + +<!-- Nulla dovrebbe apparire dopo questo tag finale. --> + +<!-- All'interno (tra i tag di apertura e chiusura <html> </html>) troviamo: --> + +<!-- Un'intestazione definita da <head> (deve essere chiusa con </head>). --> +<!-- L'intestazione contiene alcune descrizioni e informazioni aggiuntive non visualizzate; questi sono i metadati. --> + +<head> + <title>Il mio sito</title> <!-- Il tag <title> indica al browser il titolo da mostrare nella barra del titolo della finestra del browser e nel nome della scheda. --> +</head> + +<!-- Dopo la sezione <head>, troviamo il tag - <body> --> +<!-- Fino a questo punto, niente di ciò che abbiamo descritto verrà visualizzato nella finestra del browser. --> +<!-- Dobbiamo riempire il corpo con il contenuto da visualizzare. --> + +<body> + <h1>Ciao, mondo!</h1> <!-- Il tag h1 crea un titolo. --> + <!-- Ci sono anche sottotitoli a <h1> dal più importante (h2) al più preciso (h6). --> + <a href = "http://codepen.io/anon/pen/xwjLbZ">Vieni a vedere ciò che mostra</a> <!-- un collegamento ipertestuale all'URL fornito dall'attributo href="" --> + <p>Questo è un paragrafo.</p> <!-- Il tag <p> ci permette di includere del testo nella pagina html. --> + <p>Questo è un altro paragrafo.</p> + <ul> <!-- Il tag <ul> crea un elenco puntato. --> + <!-- Per avere un elenco numerato, invece, usiamo <ol> che restituisce 1. per il primo elemento, 2. per il secondo, etc. --> + <li>Questo è un elemento in un elenco non elencato (elenco puntato)</li> + <li>Questo è un altro elemento</li> + <li>E questo è l'ultimo elemento dell'elenco</li> + </ul> +</body> + +<!-- E questo è tutto, creare un file HTML può essere molto semplice. --> + +<!-- Ma è possibile aggiungere molti altri tipi di tag HTML. --> + +<!-- Per inserire un'immagine. --> +<img src="http://i.imgur.com/XWG0O.gif"/> <!-- La fonte dell'immagine viene indicata usando l'attributo src="" --> +<!-- La fonte può essere un URL o persino un percorso di un file sul tuo computer. --> + +<!-- È anche possibile creare una tabella. --> + +<table> <!-- Apriamo un elemento <table>. --> + <tr> <!-- <tr> ci permette di creare una riga. --> + <th>Prima intestazione</th> <!-- <th> ci permette di dare un titolo ad una colonna della tabella. --> + <th>Seconda intestazione</th> + </tr> + <tr> + <td>prima riga, prima colonna</td> <!-- <td> ci permette di creare una cella della tabella. --> + <td>prima riga, seconda colonna</td> + </tr> + <tr> + <td>seconda riga, prima colonna</td> + <td>seconda riga, seconda colonna</td> + </tr> +</table> + +``` + +## Uso + +HTML è scritto in files che finiscono con `.html`. + +## Per saperne di più + +* [wikipedia](https://it.wikipedia.org/wiki/HTML) +* [HTML tutorial](https://developer.mozilla.org/it/docs/Web/HTML) +* [W3School](http://www.w3schools.com/html/html_intro.asp) diff --git a/it-it/java-it.html.markdown b/it-it/java-it.html.markdown index 6eabd61f..54602cff 100644 --- a/it-it/java-it.html.markdown +++ b/it-it/java-it.html.markdown @@ -6,6 +6,7 @@ contributors: - ["Madison Dickson", "http://github.com/mix3d"] translators: - ["Ivan Sala","http://github.com/slavni96"] + - ["Tommaso Pifferi","http://github.com/neslinesli93"] lang: it-it --- @@ -31,9 +32,9 @@ import java.security.*; // Ogni file .java contiene una classe pubblica, con lo stesso nome del file public class LearnJava { - // Un programma deve avere un metodo main come punto di partenza - // Ma si possono creare anche file senza main, che però per essere usati - // devono essere richiamati da altri file. + // Un programma deve avere un metodo main come punto di partenza. + // Tuttavia si possono creare anche file senza main, che però + // per essere usati devono essere richiamati da altri file. public static void main (String[] args) { // Per stampare a schermo si usa System.out.println @@ -47,88 +48,157 @@ public class LearnJava { System.out.print("Ciao "); System.out.print("Mondo "); + // Per stampare del testo formattato, si puo' usare System.out.printf + System.out.printf("pi greco = %.5f", Math.PI); // => pi greco = 3.14159 /////////////////////////////////////// - // Tipi e Variabili + // Variabili /////////////////////////////////////// - // Si dichiara una variabile usando <tipo> <nome> - // Byte - variabile intera da 8 bit con segno + + /* + * Dichiarazione delle Variabili + */ + // Per dichiarare una variabile basta fare <tipoDato> <nomeVariabile> + int fooInt; + // Per dichiarare piu' di una variabile dello lo stesso tipo si usa: + // <tipoDato> <nomeVariabile1>, <nomeVariabile2>, <nomeVariabile3> + int fooInt1, fooInt2, fooInt3; + + /* + * Inizializzazione delle Variabili + */ + + // Per inizializzare una variabile si usa + // <tipoDato> <nomeVariabile> = <valore> + int fooInt = 1; + // Per inizializzare piu' di una variabile dello lo stesso tipo + // si usa <tipoDato> <nomeVariabile1>, <nomeVariabile2>, <nomeVariabile3> = <valore> + int fooInt1, fooInt2, fooInt3; + fooInt1 = fooInt2 = fooInt3 = 1; + + /* + * Tipi di Variabili + */ + // Byte - intero con segno a 8 bit (in complemento a 2) // (-128 <= byte <= 127) byte fooByte = 100; - // Short - variabile intera da 18 bit con segno + // Short - intero con segno a 16 bit (in complemento a 2) // (-32,768 <= short <= 32,767) short fooShort = 10000; - // Integer - variabile intera da 32 bit con segno + // Integer - intero con segno a 32 bit (in complemento a 2) // (-2,147,483,648 <= int <= 2,147,483,647) int fooInt = 1; - // Long - variabile da 64 bit intera con segno + // Long - intero con segno a 64 bit (in complemento a 2) // (-9,223,372,036,854,775,808 <= long <= 9,223,372,036,854,775,807) long fooLong = 100000L; - // L viene usato per specificare che il valore dalla variabile - // e' di tipo "Long", qualsiasi variabile che non viene contrassegnata - // e' trattata di base come un intero. + // L viene usato per indicare che il valore e' di tipo Long; + // altrimenti il valore viene considerato come intero. - // Nota: Java non dispone di variabili senza segno + // Nota: Java non dispone di interi senza segno. - // Float - variabile piu' precisa, con virgola [numeri reali] - // di grandezza 32 bit + // Float - Numero in virgola mobile a 32 bit con precisione singola (IEEE 754) + // 2^-149 <= float <= (2-2^-23) * 2^127 float fooFloat = 234.5f; - // f e' usato per specificare che la variabile e'' di tipo "float" - // altrimenti di default viene trattata come un "dobule" + // f o F indicano the la variabile e' di tipo float; + // altrimenti il valore viene considerato come double. - // Double - ancora piu' precisione la si puo' ottenere con una variabile - // Double, con granzezza di 64 bit. + // Double - Numero in virgola mobile a 64 bit con precisione doppia (IEEE 754) + // 2^-1074 <= x <= (2-2^-52) * 2^1023 double fooDouble = 123.4; - // Boolean - vero & falso + // Boolean - Puo' assumere il valore vero (true) o falso (false) boolean fooBoolean = true; boolean barBoolean = false; - // Char - un singolo carattere con grandezza 16 bit + // Char - Un singolo carattere Unicode a 16-bit char fooChar = 'A'; - // final - Costanti, non possono essere riassegnate ad un altro oggetto - final int ORE_LAVORATIVE_DI_UNA_SETTIMANA = 9001; - - // String - Stringhe, array di caratteri - String fooString = "Ecco una stringa!"; - - // \n e' un carattere speciale che permette di andare a capo. - String barString = "Andare a capo?\nNessun problema!"; - // \t e' un carattere speciale che permette di aggiungere un 'Tab' - String bazString = "Vuoi inserire tab?\tNessun problema"; + // Le variabili precedute da final possono essere inizializzate una volta sola, + final int HOURS_I_WORK_PER_WEEK = 9001; + // pero' e' possibile dichiararle e poi inizializzarle in un secondo momento. + final double E; + E = 2.71828; + + + // BigInteger - Interi a precisione arbitraria + // + // BigInteger e' un tipo di dato che permette ai programmatori di + // gestire interi piu' grandi di 64 bit. Internamente, le variabili + // di tipo BigInteger vengono memorizzate come un vettore di byte e + // vengono manipolate usando funzioni dentro la classe BigInteger. + // + // Una variabile di tipo BigInteger puo' essere inizializzata usando + // un array di byte oppure una stringa. + + BigInteger fooBigInteger = new BigDecimal(fooByteArray); + + // BigDecimal - Numero con segno, immutabile, a precisione arbitraria + // + // Una variabile di tipo BigDecimal e' composta da due parti: un intero + // a precisione arbitraria detto 'non scalato', e un intero a 32 bit + // che rappresenta la 'scala', ovvero la potenza di 10 con cui + // moltiplicare l'intero non scalato. + // + // I BigDecimal permettono un controllo completo sull'arrotondamento + // dei numeri. Essi sono molto usati in ambito finanziario, nella + // gestione delle valute, e in ogni altro posto in cui serve + // precisione esatta. + // + // Le variabili di tipo BigDecimal possono essere inizializzate con un + // int, long, double o String, oppure con un intero non scalato + // (di tipo BigInteger) e una scala (int). + + BigDecimal fooBigDecimal = new BigDecimal(fooBigInteger, fooInt); + + + + // Stringhe + String fooString = "Questa e' la mia stringa!"; + + // \n e' un carattere di escape che rappresenta l'andare a capo + String barString = "Stampare su una nuova riga?\nNessun problema!"; + // \t e' un carattere di escape che aggiunge un tab + String bazString = "Vuoi aggiungere un tab?\tNessun problema!"; System.out.println(fooString); System.out.println(barString); System.out.println(bazString); - // Vettori [array] - //La lunghezza del vettore deve essere decisa quando viene istanziato - //Si puo' dichiarare come segue: - //<tipodato> [] <nomevariabile> = new <tipodato>[<grandezza vettore>]; - //<tipodato> <nomevariabile>[] = new <tipodato>[<grandezza vettore>]; - int [] intArray = new int[10]; - String [] stringArray = new String[1]; - boolean boolArray [] = new boolean[100]; - - // Un altro modo per dichiarare & inizializzare un vettore - int [] y = {9000, 1000, 1337}; - String nomi [] = {"Andrea", "Bob", "Pippo", "Susan"}; + // Vettori + // La dimensione di un array deve essere decisa in fase di + // istanziazione. Per dichiarare un array si puo' fare in due modi: + // <tipoDato>[] <nomeVariabile> = new <tipoDato>[<dimensioneArray>]; + // <tipoDato> <nomeVariabile>[] = new <tipoDato>[<dimensioneArray>]; + int[] intArray = new int[10]; + String[] stringArray = new String[1]; + boolean boolArray[] = new boolean[100]; + + // Un altro modo per dichiarare ed insieme inizializzare un vettore. + int[] y = {9000, 1000, 1337}; + String names[] = {"Gianni", "Anna", "Luca", "Cristina"}; boolean bools[] = new boolean[] {true, false, false}; - - // I vettori vengono indicizzati a parire dallo 0 + + // Per accedere ad un elemento di un vettore System.out.println("intArray @ 0: " + intArray[0]); - // e' possibile un accesso diretto ad un elemento + // I vettori non sono immutabili (ma la loro dimensione si!) + // e gli indici partono da 0. intArray[1] = 1; System.out.println("intArray @ 1: " + intArray[1]); // => 1 - // Altro da vedere: - // Liste di array - come i vettori ma piu' funzionali - // e la loro grandezza puo' variare in corso di esecuzione - // Liste concatenate di memoria + // Ci sono altri tipo di dato interessanti. + // ArrayList - Simili ai vettori, pero' offrono altre funzionalita', + // e la loro dimensione puo' essere modificata. + // LinkedList - Si tratta di una lista linkata doppia, e come tale + // implementa tutte le operazioni del caso. + // Map - Un insieme di oggetti che fa corrispondere delle chiavi + // a dei valori. Non permette l'inserimento di chiavi uguali. + // HashMap - Questa classe usa una tabella di hash per implementare + // l'interfaccia di tipo Map. Questo permette di effettuare + // operazioni basilari, come inserimento e cancellazione, + // in tempo costante anche su insiemi molto grandi. /////////////////////////////////////// // Operatori diff --git a/it-it/json-it.html.markdown b/it-it/json-it.html.markdown new file mode 100644 index 00000000..e1e16c42 --- /dev/null +++ b/it-it/json-it.html.markdown @@ -0,0 +1,70 @@ +--- +language: json +filename: learnjson-it.json +contributors: + - ["Anna Harren", "https://github.com/iirelu"] + - ["Marco Scannadinari", "https://github.com/marcoms"] + - ["himanshu", "https://github.com/himanshu81494"] +translators: + - ["Robert Margelli", "http://github.com/sinkswim/"] + - ["Christian Grasso", "http://chris54721.net"] +lang: it-it +--- + +JSON è un formato per l'interscambio di dati estremamente semplice, per cui questo sarà +con molta probabilità il più semplice Learn X in Y Minutes. + +Nella sua forma più pura JSON non ha commenti, ma molti parser accettano +commenti in stile C (//, /\* \*/). Per lo scopo prefissato, tuttavia, tutto sarà +100% JSON valido. Fortunatamente, si spiega da sè. + +I tipi supportati da JSON comprendono: numeri, stringhe, boolean, array, oggetti e null. +I browser supportati sono: Firefox (Mozilla) 3.5+, Internet Explorer 8+, Google Chrome, +Opera 10+, Safari 4+. +I file JSON sono salvati nel formato ".json". Il MIME type per documenti JSON è +"application/json". Gli svantaggi del JSON includono l'assenza di una definizione dei tipi +e di una sorta di [DTD](https://it.wikipedia.org/wiki/Document_Type_Definition). + +```json +{ + "chiave": "valore", + + "chiavi": "devono sempre essere racchiuse tra doppi apici", + "numeri": 0, + "stringhe": "Ciaø, møndø. Tutti i caratteri Unicode sono permessi, insieme all'\"escaping\".", + "ha booleani?": true, + "il nulla": null, + + "numero grande": 1.2e+100, + + "oggetti": { + "commento": "La maggior parte della tua struttura viene dagli oggetti.", + + "array": [0, 1, 2, 3, "Gli array possono contenere qualsiasi cosa.", 5], + + "un altro oggetto": { + "commento": "Queste cose possono essere annidate, molto utile." + } + }, + + "sciocchezze": [ + { + "sorgenti di potassio": ["banane"] + }, + [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, "neo"], + [0, 0, 0, 1] + ] + ], + + "stile alternativo": { + "commento": "Guarda qua!" + , "posizione della virgola": "non conta - se è prima della chiave successiva, allora è valida" + , "un altro commento": "che bello" + }, + + "è stato molto breve": "Ed hai finito. Adesso sai tutto cio che JSON ha da offrire." +} +``` diff --git a/it-it/logtalk-it.html.markdown b/it-it/logtalk-it.html.markdown new file mode 100644 index 00000000..7f1e9eeb --- /dev/null +++ b/it-it/logtalk-it.html.markdown @@ -0,0 +1,550 @@ +--- +language: Logtalk +filename: learnlogtalk-it.lgt +contributors: + - ["Paulo Moura", "http://github.com/pmoura"] +translators: + - ["Ugo Chirico", "https://github.com/ugochirico"] +lang: it-it +--- + +Logtalk è un linguaggio di programmazione logica orientata agli oggetti che estende il linguaggio Prolog con le moderne tecniche di Object-Oriented Programming quali incapsulamento, ereditarietà e riutilizzo del codice, senza compromettere le caratteristiche di programmazione dichiarativa del Prolog. Logtalk è implementato in codice altamente portabile e utilizza i più moderni standard di conformità del Prolog rispetto al compilatore backend. + +Per mantenere una dimensione ragionevole, questo tutorial presuppone necessariamente che il lettore abbia una conoscenza del linguaggio Prolog ed è inoltre focalizzato esclusivamente sulla descrizione delle caratteristiche object-oriented di Logtalk. + +# Sintassi + +Logtalk utilizza la sintassi standard del linguaggio Prolog con l'aggiunta di un paio di operatori e di alcune direttive per una curva di apprendimento morbida e per assicurare ampia portabilità. Una conseguenza importante è che il codice Prolog può essere facilmente incapsulato in oggetti con poche o nessuna modifica. Inoltre, Logtalk può interpretare come oggetti Logtalk, in modo trasparente, la maggior parte dei moduli Prolog già esistenti. + +I principali operatori sono: + +* `::/2` - per inviare un messaggio ad un oggetto +* `::/1` - per inviare un messaggio a se stesso _self_ (cioè all'oggetto che riceverà il messaggio) +* `^^/1` - _super_ per chiamare un predicato ereditato o importato + +Alcune delle più importanti entità e direttive saranno introdotte nelle sezioni successive. + +# Entità e Ruoli + +Logtalk tratta gli oggetti, i protocolli e le categorie come entità di prima classe. I rapporti tra le entità definiscono i _patterns of code reuse_ ossia i modelli di riutilizzo del codice e i _roles_ ossia i ruoli svolti da tali entità. Ad esempio, quando un oggetto istanzia un altro oggetto, il primo oggetto assume il ruolo di istanza e il secondo oggetto assume il ruolo di classe. Una relazione di tipo _extends_ tra due oggetti implica che entrambi gli oggetti svolgano il ruolo di prototipi, in cui uno di loro estende l'altro, che diventa quindi suo prototipo padre. + +# Definizione di un oggetto + +Un oggetto incapsula le dichiarazioni e le definizioni dei predicati. Gli oggetti possono essere creati in modo dinamico, ma di solito sono dichiarati come statici e definiti nel codice sorgente. Un singolo file sorgente può contenere un qualsiasi numero di definizioni di entità. Ecco un semplice oggetto `list` che definisce un membro pubblico `member/2`: + +```logtalk +:- object(list). + + :- public(member/2). + member(Head, [Head| _]). + member(Head, [_| Tail]) :- + member(Head, Tail). + +:- end_object. +``` + +# Compilazione dei file sorgenti + +Supponendo che il codice di cui sopra per l'oggetto `list` venga salvato in un file` list.lgt`, esso può essere compilato e caricato utilizzando il predicato predefiniti `logtalk_load/1` o la sua abbreviazione `{}/1`, con il percorso del file come argomento (l'estensione può essere omessa): + +```logtalk +?- {list}. +yes +``` + +# Inviare un messaggio ad un oggetto + +L'operatore infisso `::/2` è usato per inviare messaggi ad un oggetto. Analogamente al Prolog, è possibile fare backtracking per le soluzioni alternative: + +```logtalk +?- list::member(X, [1,2,3]). +X = 1 ; +X = 2 ; +X = 3 +yes +``` + +Analogamente alla programmazione object-oriented, logtalk consente anche l'Incapsulamento. +Un predicato può essere dichiarata pubblico, protetto o privato. Può anche essere _local_ quando non esiste una direttiva specifica per esso all'interno dello scope. Per esempio: + +```logtalk +:- object(scopes). + + :- private(bar/0). + bar. + + local. + +:- end_object. +``` + +Assumendo che l'oggetto è salvato nel file `scopes.lgt`: + +```logtalk +?- {scopes}. +yes + +?- catch(scopes::bar, Error, true). +Error = error( + permission_error(access, private_predicate, bar/0), + logtalk(scopes::bar, user) +) +yes + +?- catch(scopes::local, Error, true). +Error = error( + existence_error(predicate_declaration, local/0), + logtalk(scopes::local, user) +) +yes +``` + +Quando il predicato in un messaggio non è noto per l'oggetto (il ruolo dell'oggetto determina le procedure di ricerca), si ha un errore. +Per esempio: + +```logtalk +?- catch(scopes::unknown, Error, true). +Error = error( + existence_error(predicate_declaration, unknown/0), + logtalk(scopes::unknown, user) +) +yes +``` + +Un punto fondamentale da capire è che le direttive che specificano il predicato nello scope specificano la semantica di chiamata (_calling_) del predicato, e non la semantica di definizione (_definition_). Ad esempio, se un oggetto ha il ruolo di una classe e dichiara un predicato privato, tale predicato può essere definito nelle sue sottoclassi e nelle istanze * ma * può essere chiamato solo nelle sue istanza (_from_) dalla classe. + +# Definizione e implementazione di un protocollo + +Un Protocollo contiene le dichiarazioni dei predicati che possono essere implementati da un qualsivoglia numero di oggetti e categorie: + +```logtalk +:- protocol(listp). + + :- public(member/2). + +:- end_protocol. + +:- object(list, + implements(listp)). + + member(Head, [Head| _]). + member(Head, [_| Tail]) :- + member(Head, Tail). + +:- end_object. +``` + +Lo scope dei predicati di un protocollo può essere ristretto usando implementazioni protected e private. Ad esempio: + +```logtalk +:- object(stack, + implements(private::listp)). + +:- end_object. +``` + +Difatti, tutte le relazioni tra entità (nella direttiva di apertura di un entità) possono essere definite come public (default), protected, o private. + +# Prototipi + +Un oggetto senza una istanza o senza una relazione di specializzazione con un altro oggetto interpreta il ruolo di prototipo. Un prototipo può estendere un altro oggetto, il suo prototipo genitore. + +```logtalk +% clyde, our prototypical elephant +:- object(clyde). + + :- public(color/1). + color(grey). + + :- public(number_of_legs/1). + number_of_legs(4). + +:- end_object. + +% fred, another elephant, is like clyde, except that he's white +:- object(fred, + extends(clyde)). + + color(white). + +:- end_object. +``` + +Per rispondere ad un messaggio inviato ad un oggetto che ha il ruolo di prototipo, si cerca prima una risposta nel prototipo stesso e se il prototipo non sa rispondere si passa all'eventuale prototipo genitore (se esiste): + +```logtalk +?- fred::number_of_legs(N). +N = 4 +yes + +?- fred::color(C). +C = white +yes +``` + +Un messaggio è valido se il relativo predicato è dichiarato in un oggetto (e se il mittente è nel campo di applicazione), ma fallirà, piuttosto che lanciare un errore, se il predicato non è definito. Questa è chiamata la _closed-world assumption_. Ad esempio, si consideri il seguente oggetto, salvato in un file `foo.lgt`: + +```logtalk +:- object(foo). + + :- public(bar/0). + +:- end_object. +``` + +Caricando il file e cercando di chiamare il predicato `bar/0` questo fallisce come previsto. Si noti che ciò è diverso dal chiamare un predicato sconosciuto _unknown_, che invece genera un errore: + +```logtalk +?- {foo}. +yes + +?- foo::bar. +no + +?- catch(foo::baz, Error, true). +Error = error( + existence_error(predicate_declaration, baz/0), + logtalk(foo::baz, user) +) +yes +``` + +# Classi e istanze + +Per definire gli oggetti nei ruoli di classi e/o istanze, un oggetto deve avere almeno un istanziazione o una relazione di specializzazione con un altro oggetto. Gli oggetti che hanno il ruolo di meta-classi possono essere utilizzati quando abbiamo bisogno di usare una classe come se fosse un'istanza. Il seguente esempio mostra come creare dinamicamente nuovi oggetti in fase di esecuzione: + +```logtalk +% a simple, generic, metaclass defining a new/2 predicate for its instances +:- object(metaclass, + instantiates(metaclass)). + + :- public(new/2). + new(Instance, Clauses) :- + self(Class), + create_object(Instance, [instantiates(Class)], [], Clauses). + +:- end_object. + +% a simple class defining age/1 and name/1 predicate for its instances +:- object(person, + instantiates(metaclass)). + + :- public([ + age/1, name/1 + ]). + + % a default value for age/1 + age(42). + +:- end_object. + +% a static instance of the class person +:- object(john, + instantiates(person)). + + name(john). + age(12). + +:- end_object. +``` + +Nel rispondere ad un messaggio inviato ad un oggetto ha assunto il ruolo di istanza, tal messaggio viene convalidato partendo dalla sua classe e andando a ritroso nella gerarchia, se necessario, fino alle sue superclassi. Supponendo che il messaggio sia valido, allora si cerca una risposta a partire dall'istanza stessa: + +```logtalk +?- person::new(Instance, [name(paulo)]). +Instance = o1 +yes + +?- o1::name(Name). +Name = paulo +yes + +?- o1::age(Age). +Age = 42 +yes + +?- john::age(Age). +Age = 12 +yes +``` + +# Categorie + +Una categoria è un'unità atomica di codice riutilizzabile. Una categoria è usata per incapsulare una insieme coesivo (_cohesive_) di dichiarazioni e di definizioni di predicato ed è atta ad implementare una singola (_single_) funzionalità che può essere importata in qualsiasi oggetto. Una categoria può quindi essere concepita come il concetto duale di protocollo. Nel seguente esempio, si definiscono prima le categorie che rappresentano i motori di auto e poi si importano tali categorie negli oggetti auto: + +```logtalk +% a protocol describing engine characteristics +:- protocol(carenginep). + + :- public([ + reference/1, + capacity/1, + cylinders/1, + horsepower_rpm/2, + bore_stroke/2, + fuel/1 + ]). + +:- end_protocol. + +% a typical engine defined as a category +:- category(classic, + implements(carenginep)). + + reference('M180.940'). + capacity(2195). + cylinders(6). + horsepower_rpm(94, 4800). + bore_stroke(80, 72.8). + fuel(gasoline). + +:- end_category. + +% a souped up version of the previous engine +:- category(sport, + extends(classic)). + + reference('M180.941'). + horsepower_rpm(HP, RPM) :- + ^^horsepower_rpm(ClassicHP, ClassicRPM), % "super" call + HP is truncate(ClassicHP*1.23), + RPM is truncate(ClassicRPM*0.762). + +:- end_category. + +% with engines (and other components), we may start "assembling" some cars +:- object(sedan, + imports(classic)). + +:- end_object. + +:- object(coupe, + imports(sport)). + +:- end_object. +``` + +Le Categorie sono compilate in modo indipendente e, quindi, consentono l'importazione di oggetti da aggiornare mediante il semplice aggiornamento delle categorie importate, senza richiedere pertanto la ricompilazione dell'oggetto. Le Categorie forniscono anche la _runtime transparency_, cioè il protocollo della categoria si aggiunge al protocollo degli oggetti che importano tale categoria: + +```logtalk +?- sedan::current_predicate(Predicate). +Predicate = reference/1 ; +Predicate = capacity/1 ; +Predicate = cylinders/1 ; +Predicate = horsepower_rpm/2 ; +Predicate = bore_stroke/2 ; +Predicate = fuel/1 +yes +``` + +# Hot patching + +Le categorie possono essere anche usate per modificare gli oggetti al volo (_hot-patch_). Una categoria può aggiungere nuovi predicati ad un oggetto e/o sostituire le definizioni dei predicati dell'oggetto. Ad esempio, si consideri il seguente oggetto: + +```logtalk +:- object(buggy). + + :- public(p/0). + p :- write(foo). + +:- end_object. +``` + +Si supponga che l'oggetto stampi la stringa sbagliata quando riceve il messaggio `p/0`: + +```logtalk +?- {buggy}. +yes + +?- buggy::p. +foo +yes +``` + +Se il codice sorgente dell'oggetto non è disponibile e bisogna correggere l'applicazione che sta eseguendo il codice dell'oggetto, si può semplicemente definire una categoria che corregge il predicato non corretto: + +```logtalk +:- category(patch, + complements(buggy)). + + % fixed p/0 def + p :- write(bar). + +:- end_category. +``` + +Dopo la compilazione e il caricamento della categoria nell'applicazione in esecuzione si ottiene: + +```logtalk +?- {patch}. +yes + +?- buggy::p. +bar +yes +``` + +Poiché l'hot-patching pregiudica forzatamente l'incapsulamento, un apposito flag di compilazione `complementary` può essere impostato (a livello globale o per un singolo oggetto) per consentire, limitare o prevenire l'hot-patching. + +# Oggetti Parametrici e Categorie + +Gli oggetti e le categorie possono essere parametrizzati utilizzando come identificativo un compound-term al posto di un atomo. Oggetti e parametri di una categoria sono variabili logiche _logical variables_ condivise con tutti i predicati incapsulati. Ecco un esempio con cerchi geometrici: + +```logtalk +:- object(circle(_Radius, _Color)). + + :- public([ + area/1, perimeter/1 + ]). + + area(Area) :- + parameter(1, Radius), + Area is pi*Radius*Radius. + + perimeter(Perimeter) :- + parameter(1, Radius), + Perimeter is 2*pi*Radius. + +:- end_object. +``` + +Oggetti parametrici possono essere utilizzati come qualsiasi altro oggetto e di solito forniscono i valori da assegnare ai parametri quando si invia un messaggio: + +```logtalk +?- circle(1.23, blue)::area(Area). +Area = 4.75291 +yes +``` + +Gli oggetti parametrici forniscono anche un modo semplice per associare un insieme di predicati con un semplice predicato Prolog. Fatti Prolog possono essere interpretati come oggetti proxy parametrici ( _parametric object proxies_) quando hanno lo stesso funtore e arietà degli identificatori di oggetti parametrici. Per lavorare con i proxy viene fornita una sintassi maneggevole. Per esempio, si prendano le seguenti clausole per il predicato `circle/2`: + +```logtalk +circle(1.23, blue). +circle(3.71, yellow). +circle(0.39, green). +circle(5.74, black). +circle(8.32, cyan). +``` + +Con queste clausole, si può facilmente calcolare, ad esempio, un elenco con le aree di tutti i cerchi: + +```logtalk +?- findall(Area, {circle(_, _)}::area(Area), Areas). +Areas = [4.75291, 43.2412, 0.477836, 103.508, 217.468] +yes +``` + +In pratica, il costrutto `{Goal}::Message` prova il goal `Goal`, instanziando le variabili interne e inviando un messaggio `Message` al termine risultante. + +# Eventi and monitor + +Logtalk supporta l'_event-driven programming_ mediante la definizione di eventi e di monitor. Un evento è semplicemente l'invio di un messaggio ad un oggetto. Un monitor è un gestore di un evento. L'evento (con l'invio di un messaggio) è un'attività atomica, ed è preceduta da un evento _before_ e da un evento _after_. Il monitor gestisce tali eventi mediante i predicati, `before/3` e `after/3`, che sono chiamati rispettivamente prima e dopo il verificarsi dell'evento. Un monitor può inoltre interrogare, registrare e cancellare un evento nel registro eventi a livello di sistema il quale che associa gli eventi con i monitor. Ad esempio, un semplice tracer per ogni messaggio inviato utilizzando il costrutto `::/2` può essere definito come: + +```logtalk +:- object(tracer, + implements(monitoring)). % built-in protocol for event handlers + + :- initialization(define_events(_, _, _, _, tracer)). + + before(Object, Message, Sender) :- + write('call: '), writeq(Object), write(' <-- '), writeq(Message), + write(' from '), writeq(Sender), nl. + + after(Object, Message, Sender) :- + write('exit: '), writeq(Object), write(' <-- '), writeq(Message), + write(' from '), writeq(Sender), nl. + +:- end_object. +``` + +Supponendo che l'oggetto `tracer` e l'oggetto `list` definito in precedenza siano stati già compilati e caricati, si possono osservare i gestori di eventi in azione durante l'invio di un messaggio: + +```logtalk +?- list::member(X, [1,2,3]). + +call: list <-- member(X, [1,2,3]) from user +exit: list <-- member(1, [1,2,3]) from user +X = 1 ; +exit: list <-- member(2, [1,2,3]) from user +X = 2 ; +exit: list <-- member(3, [1,2,3]) from user +X = 3 +yes +``` + +Gli eventi possono essere impostati e cancellati dinamicamente in fase di esecuzione chiamando i predicati predefiniti `define_events/5` e` abolish_events/5` . + +La programmazione event-driven può essere vista come una forma di _computational reflection_. Si noti però che gli eventi sono generati solo quando si utilizza il costrutto di controllo per l'invio di messaggi `::/2`. + +# Espressioni lambda + +Logtalk supporta anche le espressioni lambda. I parametri della espressioni lambda sono rappresentati mediante una lista con l'operatore infisso `(>>)/2` che collega i parametri alla relativa lambda espressione. Ecco alcuni semplici esempi di che usano i meta-predicati. + + +```logtalk +?- {library(metapredicates_loader)}. +yes + +?- meta::map([X,Y]>>(Y is 2*X), [1,2,3], Ys). +Ys = [2,4,6] +yes +``` + +Logtalk supporta anche il _currying_: + +```logtalk +?- meta::map([X]>>([Y]>>(Y is 2*X)), [1,2,3], Ys). +Ys = [2,4,6] +yes +``` + +Infine, le variabili libere Lambda possono essere espresso usando la sintassi estesa `{Free1, ...}/[Parameter1, ...]>>Lambda`. + +# Macro + +I Termini e goal nel file sorgente possono essere _estesi_ al momento della compilazione specificando una hook ad un oggetto (_hook object_) che definisce le regole di riscrittura dei termini e riscrittura dei quesiti. Ad esempio, si consideri il seguente oggetto semplice, salvato nel file `source.lgt`: + +```logtalk +:- object(source). + + :- public(bar/1). + bar(X) :- foo(X). + + foo(a). foo(b). foo(c). + +:- end_object. +``` + +Si supponga il seguente hook all'oggetto, salvato nel file `my_macros.lgt`, che estende le clausole e chiama il predicato locale `foo/1`: + +```logtalk +:- object(my_macros, + implements(expanding)). % built-in protocol for expanding predicates + + term_expansion(foo(Char), baz(Code)) :- + char_code(Char, Code). % standard built-in predicate + + goal_expansion(foo(X), baz(X)). + +:- end_object. +``` + +Dopo aver caricato il file contenente la macro, si può espandere il nostro file sorgente usando il flag del compilatore `hook`: + +```logtalk +?- logtalk_load(my_macros), logtalk_load(source, [hook(my_macros)]). +yes + +?- source::bar(X). +X = 97 ; +X = 98 ; +X = 99 +true +``` + +La libreria Logtalk fornisce infine il supporto per combinare hook agli oggetti utilizzando diversi modi (ad esempio, definendo una pipeline di espansioni). + + +# Maggiori informazioni + +Visita il [Sito web di Logtalk (en)](http://logtalk.org) per maggiori informazioni. diff --git a/it-it/markdown.html.markdown b/it-it/markdown.html.markdown new file mode 100644 index 00000000..44801747 --- /dev/null +++ b/it-it/markdown.html.markdown @@ -0,0 +1,310 @@ +--- +language: markdown +contributors: + - ["Dan Turkel", "http://danturkel.com/"] + - ["Jacob Ward", "http://github.com/JacobCWard/"] +translators: + - ["Jacopo Andrea Giola", "http://geekpanda.net"] + - ["Ale46", "https://github.com/Ale46"] +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). + +Markdown varia nelle sue implementazioni da un parser all'altro. Questa guida cercherà di chiarire quali caratteristiche esistono a livello globale o quando sono disponibili solo per un determinato parser. + +- [Elementi HTML](#elementi-html) +- [Titoli](#titoli) +- [Stili di testo semplici](#stili-di-testo-semplici) +- [Paragrafi](#paragrafi) +- [Liste](#liste) +- [Estratti di codice](#estratti-di-codice) +- [Linea orizzontale](#linea-orizzontale) +- [Links](#links) +- [Immagini](#immagini) +- [Miscellanea](#miscellanea) + +## Elementi HTML +Markdown è un superset di HTML, quindi ogni file HTML è a sua volta un file Markdown valido. + +```markdown +<!-- 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. --> +``` + +## Titoli + +Potete creare gli elementi HTML da `<h1>` a `<h6>` facilmente, basta che inseriate un egual numero di caratteri cancelletto (#) prima del testo che volete all'interno dell'elemento + +```markdown +# 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 + +```markdown +Questo è un h1 +============== + +Questo è un h2 +-------------- +``` + +## Stili di testo semplici +Il testo può essere stilizzato in corsivo o grassetto usando markdown + +```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: + +```markdown +~~Questo testo è barrato.~~ +``` +## Paragrafi + +```markdown +I paragrafi sono una o più linee di testo adiacenti separate da una o più righe vuote. + +Questo è 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. + +```markdown +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 >. + +```markdown +> 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 + +```markdown +* 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. + +```markdown +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. + +```markdown +1. Primo oggetto +1. Secondo oggetto +1. Terzo oggetto +``` +(Questa lista verrà visualizzata esattamente come quella dell'esempio prima) + +Potete inserire anche sotto liste + +```markdown +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. + +```markdown +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. + +```markdown + Questa è una linea di codice + Come questa +``` + +Potete inoltre inserire un altro tab (o altri quattro spazi) per indentare il vostro codice + +```markdown + my_array.each do |item| + puts item + end +``` + +Codice inline può essere inserito usando il carattere backtick ` + +```markdown +Giovanni non sapeva neppure a cosa servisse la funzione `go_to()`! +``` + +In Github Flavored Markdown, potete inoltre usare una sintassi speciale per il codice +<pre> +<code class="highlight">```ruby +def foobar + puts "Hello world!" +end +```</code></pre> +Se usate questa sintassi, il testo non richiederà di essere indentato, inoltre Github userà l'evidenziazione della sintassi del linguaggio specificato dopo i \`\`\` iniziali + +## Linea orizzontale +Le linee orizzontali (`<hr/>`) sono inserite facilmente usanto tre o più asterischi o trattini, con o senza spazi. + +```markdown +*** +--- +- - - +**************** +``` + +## Links +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 () + +```markdown +[Cliccami!](http://test.com/) +``` + +Potete inoltre aggiungere al link un titolo mettendolo fra doppi apici dopo il link + +```markdown +[Cliccami!](http://test.com/ "Link a Test.com") +``` + +La sintassi funziona anche con i path relativi. + +```markdown +[Vai a musica](/music/). +``` + +Markdown supporta inoltre anche la possibilità di aggiungere i link facendo riferimento ad altri punti del testo. +```markdown +[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!" +``` +l 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. +```markdown +[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! + +```markdown +![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 + +```markdown +![Questo è il testo alternativo.][myimage] + +[myimage]: relative/urls/cool/image.jpg "Se vi serve un titolo, lo mettete qui" +``` +## Miscellanea +### Auto link + +```markdown +<http://testwebsite.com/> è equivalente ad +[http://testwebsite.com/](http://testwebsite.com/) +``` +### Auto link per le email + +```markdown +<foo@bar.com> +``` +### Caratteri di escaping + +```markdown +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. + +```markdown +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: + +```markdown +| Col1 | Col2 | Col3 | +| :------------------- | :------: | -----------------: | +| Allineato a sinistra | Centrato | Allineato a destra | +| blah | blah | blah | +``` +oppure, per lo stesso risultato + +```markdown +Col 1 | Col2 | Col3 +:-- | :-: | --: +È una cosa orrenda | fatela | finire in fretta +``` + +--- +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..8d6d4385 --- /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 elemento +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/) diff --git a/it-it/python-it.html.markdown b/it-it/python-it.html.markdown new file mode 100644 index 00000000..e81d1676 --- /dev/null +++ b/it-it/python-it.html.markdown @@ -0,0 +1,778 @@ +--- +language: python +filename: learnpython-it.py +contributors: + - ["Louie Dinh", "http://ldinh.ca"] + - ["Amin Bandali", "http://aminbandali.com"] + - ["Andre Polykanine", "https://github.com/Oire"] + - ["evuez", "http://github.com/evuez"] +translators: + - ["Ale46", "http://github.com/Ale46/"] + - ["Tommaso Pifferi", "http://github.com/neslinesli93/"] +lang: it-it +--- +Python è stato creato da Guido Van Rossum agli inizi degli anni 90. Oggi è uno dei più popolari +linguaggi esistenti. Mi sono innamorato di Python per la sua chiarezza sintattica. E' sostanzialmente +pseudocodice eseguibile. + +Feedback sono altamente apprezzati! Potete contattarmi su [@louiedinh](http://twitter.com/louiedinh) oppure [at] [google's email service] + +Nota: questo articolo è riferito a Python 2.7 in modo specifico, ma dovrebbe andar +bene anche per Python 2.x. Python 2.7 sta raggiungendo il "fine vita", ovvero non sarà +più supportato nel 2020. Quindi è consigliato imparare Python utilizzando Python 3. +Per maggiori informazioni su Python 3.x, dai un'occhiata al [tutorial di Python 3](http://learnxinyminutes.com/docs/python3/). + +E' possibile anche scrivere codice compatibile sia con Python 2.7 che con Python 3.x, +utilizzando [il modulo `__future__`](https://docs.python.org/2/library/__future__.html) di Python. +Il modulo `__future__` permette di scrivere codice in Python 3, che può essere eseguito +utilizzando Python 2: cosa aspetti a vedere il tutorial di Python 3? + +```python + +# I commenti su una sola linea iniziano con un cancelletto + +""" Più stringhe possono essere scritte + usando tre ", e sono spesso usate + come commenti +""" + +#################################################### +## 1. Tipi di dati primitivi ed Operatori +#################################################### + +# Hai i numeri +3 # => 3 + +# La matematica è quello che vi aspettereste +1 + 1 # => 2 +8 - 1 # => 7 +10 * 2 # => 20 +35 / 5 # => 7 + +# La divisione è un po' complicata. E' una divisione fra interi in cui viene +# restituito in automatico il risultato intero. +5 / 2 # => 2 + +# Per le divisioni con la virgola abbiamo bisogno di parlare delle variabili floats. +2.0 # Questo è un float +11.0 / 4.0 # => 2.75 ahhh...molto meglio + +# Il risultato di una divisione fra interi troncati positivi e negativi +5 // 3 # => 1 +5.0 // 3.0 # => 1.0 # funziona anche per i floats +-5 // 3 # => -2 +-5.0 // 3.0 # => -2.0 + +# E' possibile importare il modulo "division" (vedi la sezione 6 di questa guida, Moduli) +# per effettuare la divisione normale usando solo '/'. +from __future__ import division +11/4 # => 2.75 ...divisione normale +11//4 # => 2 ...divisione troncata + +# Operazione Modulo +7 % 3 # => 1 + +# Elevamento a potenza (x alla y-esima potenza) +2**4 # => 16 + +# Forzare le precedenze con le parentesi +(1 + 3) * 2 # => 8 + +# Operatori Booleani +# Nota "and" e "or" sono case-sensitive +True and False #=> False +False or True #=> True + +# Note sull'uso di operatori Bool con interi +0 and 2 #=> 0 +-5 or 0 #=> -5 +0 == False #=> True +2 == True #=> False +1 == True #=> True + +# nega con not +not True # => False +not False # => True + +# Uguaglianza è == +1 == 1 # => True +2 == 1 # => False + +# Disuguaglianza è != +1 != 1 # => False +2 != 1 # => True + +# Altri confronti +1 < 10 # => True +1 > 10 # => False +2 <= 2 # => True +2 >= 2 # => True + +# I confronti possono essere concatenati! +1 < 2 < 3 # => True +2 < 3 < 2 # => False + +# Le stringhe sono create con " o ' +"Questa è una stringa." +'Anche questa è una stringa.' + +# Anche le stringhe possono essere sommate! +"Ciao " + "mondo!" # => Ciao mondo!" +# Le stringhe possono essere sommate anche senza '+' +"Ciao " "mondo!" # => Ciao mondo!" + +# ... oppure moltiplicate +"Hello" * 3 # => "HelloHelloHello" + +# Una stringa può essere considerata come una lista di caratteri +"Questa è una stringa"[0] # => 'Q' + +# Per sapere la lunghezza di una stringa +len("Questa è una stringa") # => 20 + +# Formattazione delle stringhe con % +# Anche se l'operatore % per le stringe sarà deprecato con Python 3.1, e verrà rimosso +# successivamente, può comunque essere utile sapere come funziona +x = 'mela' +y = 'limone' +z = "La cesta contiene una %s e un %s" % (x,y) + +# Un nuovo modo per fomattare le stringhe è il metodo format. +# Questo metodo è quello consigliato +"{} è un {}".format("Questo", "test") +"{0} possono essere {1}".format("le stringhe", "formattate") +# Puoi usare delle parole chiave se non vuoi contare +"{nome} vuole mangiare {cibo}".format(nome="Bob", cibo="lasagna") + +# None è un oggetto +None # => None + +# Non usare il simbolo di uguaglianza "==" per comparare oggetti a None +# Usa "is" invece +"etc" is None # => False +None is None # => True + +# L'operatore 'is' testa l'identità di un oggetto. Questo non è +# molto utile quando non hai a che fare con valori primitivi, ma lo è +# quando hai a che fare con oggetti. + +# Qualunque oggetto può essere usato nei test booleani +# I seguenti valori sono considerati falsi: +# - None +# - Lo zero, come qualunque tipo numerico (quindi 0, 0L, 0.0, 0.j) +# - Sequenze vuote (come '', (), []) +# - Contenitori vuoti (tipo {}, set()) +# - Istanze di classi definite dall'utente, che soddisfano certi criteri +# vedi: https://docs.python.org/2/reference/datamodel.html#object.__nonzero__ +# +# Tutti gli altri valori sono considerati veri: la funzione bool() usata su di loro, ritorna True. +bool(0) # => False +bool("") # => False + + +#################################################### +## 2. Variabili e Collections +#################################################### + +# Python ha una funzione di stampa +print "Sono Python. Piacere di conoscerti!" # => Sono Python. Piacere di conoscerti! + +# Un modo semplice per ricevere dati in input dalla riga di comando +variabile_stringa_input = raw_input("Inserisci del testo: ") # Ritorna i dati letti come stringa +variabile_input = input("Inserisci del testo: ") # Interpreta i dati letti come codice python +# Attenzione: bisogna stare attenti quando si usa input() +# Nota: In python 3, input() è deprecato, e raw_input() si chiama input() + +# Non c'è bisogno di dichiarare una variabile per assegnarle un valore +una_variabile = 5 # Convenzionalmente si usa caratteri_minuscoli_con_underscores +una_variabile # => 5 + +# Accedendo ad una variabile non precedentemente assegnata genera un'eccezione. +# Dai un'occhiata al Control Flow per imparare di più su come gestire le eccezioni. +un_altra_variabile # Genera un errore di nome + +# if può essere usato come un'espressione +# E' l'equivalente dell'operatore ternario in C +"yahoo!" if 3 > 2 else 2 # => "yahoo!" + +# Liste immagazzinano sequenze +li = [] +# Puoi partire con una lista pre-riempita +altra_li = [4, 5, 6] + +# Aggiungi cose alla fine di una lista con append +li.append(1) # li ora è [1] +li.append(2) # li ora è [1, 2] +li.append(4) # li ora è [1, 2, 4] +li.append(3) # li ora è [1, 2, 4, 3] +# Rimuovi dalla fine della lista con pop +li.pop() # => 3 e li ora è [1, 2, 4] +# Rimettiamolo a posto +li.append(3) # li ora è [1, 2, 4, 3] di nuovo. + +# Accedi ad una lista come faresti con un array +li[0] # => 1 +# Assegna nuovo valore agli indici che sono già stati inizializzati con = +li[0] = 42 +li[0] # => 42 +li[0] = 1 # Nota: è resettato al valore iniziale +# Guarda l'ultimo elemento +li[-1] # => 3 + +# Guardare al di fuori dei limiti è un IndexError +li[4] # Genera IndexError + +# Puoi guardare gli intervalli con la sintassi slice (a fetta). +# (E' un intervallo chiuso/aperto per voi tipi matematici.) +li[1:3] # => [2, 4] +# Ometti l'inizio +li[2:] # => [4, 3] +# Ometti la fine +li[:3] # => [1, 2, 4] +# Seleziona ogni seconda voce +li[::2] # =>[1, 4] +# Copia al contrario della lista +li[::-1] # => [3, 4, 2, 1] +# Usa combinazioni per fare slices avanzate +# li[inizio:fine:passo] + +# Rimuovi arbitrariamente elementi da una lista con "del" +del li[2] # li è ora [1, 2, 3] +# Puoi sommare le liste +li + altra_li # => [1, 2, 3, 4, 5, 6] +# Nota: i valori per li ed altra_li non sono modificati. + +# Concatena liste con "extend()" +li.extend(altra_li) # Ora li è [1, 2, 3, 4, 5, 6] + +# Rimuove la prima occorrenza di un elemento +li.remove(2) # Ora li è [1, 3, 4, 5, 6] +li.remove(2) # Emette un ValueError, poichè 2 non è contenuto nella lista + +# Inserisce un elemento all'indice specificato +li.insert(1, 2) # li è di nuovo [1, 2, 3, 4, 5, 6] + +# Ritorna l'indice della prima occorrenza dell'elemento fornito +li.index(2) # => 1 +li.index(7) # Emette un ValueError, poichè 7 non è contenuto nella lista + +# Controlla l'esistenza di un valore in una lista con "in" +1 in li # => True + +# Esamina la lunghezza con "len()" +len(li) # => 6 + + +# Tuple sono come le liste ma immutabili. +tup = (1, 2, 3) +tup[0] # => 1 +tup[0] = 3 # Genera un TypeError + +# Puoi fare tutte queste cose da lista anche sulle tuple +len(tup) # => 3 +tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6) +tup[:2] # => (1, 2) +2 in tup # => True + +# Puoi scompattare le tuple (o liste) in variabili +a, b, c = (1, 2, 3) # a è ora 1, b è ora 2 and c è ora 3 +d, e, f = 4, 5, 6 # puoi anche omettere le parentesi +# Le tuple sono create di default se non usi le parentesi +g = 4, 5, 6 # => (4, 5, 6) +# Guarda come è facile scambiare due valori +e, d = d, e # d è ora 5 ed e è ora 4 + + +# Dizionari immagazzinano mappature +empty_dict = {} +# Questo è un dizionario pre-riempito +filled_dict = {"uno": 1, "due": 2, "tre": 3} + +# Accedi ai valori con [] +filled_dict["uno"] # => 1 + +# Ottieni tutte le chiavi come una lista con "keys()" +filled_dict.keys() # => ["tre", "due", "uno"] +# Nota - Nei dizionari l'ordine delle chiavi non è garantito. +# Il tuo risultato potrebbe non essere uguale a questo. + +# Ottieni tutt i valori come una lista con "values()" +filled_dict.values() # => [3, 2, 1] +# Nota - Come sopra riguardo l'ordinamento delle chiavi. + +# Ottieni tutte le coppie chiave-valore, sotto forma di lista di tuple, utilizzando "items()" +filled_dicts.items() # => [("uno", 1), ("due", 2), ("tre", 3)] + +# Controlla l'esistenza delle chiavi in un dizionario con "in" +"uno" in filled_dict # => True +1 in filled_dict # => False + +# Cercando una chiave non esistente è un KeyError +filled_dict["quattro"] # KeyError + +# Usa il metodo "get()" per evitare KeyError +filled_dict.get("uno") # => 1 +filled_dict.get("quattro") # => None +# Il metodo get supporta un argomento di default quando il valore è mancante +filled_dict.get("uno", 4) # => 1 +filled_dict.get("quattro", 4) # => 4 +# nota che filled_dict.get("quattro") è ancora => None +# (get non imposta il valore nel dizionario) + +# imposta il valore di una chiave con una sintassi simile alle liste +filled_dict["quattro"] = 4 # ora, filled_dict["quattro"] => 4 + +# "setdefault()" aggiunge al dizionario solo se la chiave data non è presente +filled_dict.setdefault("five", 5) # filled_dict["five"] è impostato a 5 +filled_dict.setdefault("five", 6) # filled_dict["five"] è ancora 5 + + +# Sets immagazzina ... sets (che sono come le liste, ma non possono contenere doppioni) +empty_set = set() +# Inizializza un "set()" con un po' di valori +some_set = set([1, 2, 2, 3, 4]) # some_set è ora set([1, 2, 3, 4]) + +# l'ordine non è garantito, anche se a volta può sembrare ordinato +another_set = set([4, 3, 2, 2, 1]) # another_set è ora set([1, 2, 3, 4]) + +# Da Python 2.7, {} può essere usato per dichiarare un set +filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4} + +# Aggiungere elementi ad un set +filled_set.add(5) # filled_set è ora {1, 2, 3, 4, 5} + +# Fai intersezioni su un set con & +other_set = {3, 4, 5, 6} +filled_set & other_set # => {3, 4, 5} + +# Fai unioni su set con | +filled_set | other_set # => {1, 2, 3, 4, 5, 6} + +# Fai differenze su set con - +{1, 2, 3, 4} - {2, 3, 5} # => {1, 4} + +# Effettua la differenza simmetrica con ^ +{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5} + +# Controlla se il set a sinistra contiene quello a destra +{1, 2} >= {1, 2, 3} # => False + +# Controlla se il set a sinistra è un sottoinsieme di quello a destra +{1, 2} <= {1, 2, 3} # => True + +# Controlla l'esistenza in un set con in +2 in filled_set # => True +10 in filled_set # => False + + +#################################################### +## 3. Control Flow +#################################################### + +# Dichiariamo una variabile +some_var = 5 + +# Questo è un controllo if. L'indentazione è molto importante in python! +# stampa "some_var è più piccola di 10" +if some_var > 10: + print "some_var è decisamente più grande di 10." +elif some_var < 10: # Questa clausola elif è opzionale. + print "some_var è più piccola di 10." +else: # Anche questo è opzionale. + print "some_var è precisamente 10." + + +""" +I cicli for iterano sulle liste +stampa: + cane è un mammifero + gatto è un mammifero + topo è un mammifero +""" +for animale in ["cane", "gatto", "topo"]: + # Puoi usare {0} per interpolare le stringhe formattate. (Vedi di seguito.) + print "{0} è un mammifero".format(animale) + +""" +"range(numero)" restituisce una lista di numeri +da zero al numero dato +stampa: + 0 + 1 + 2 + 3 +""" +for i in range(4): + print i + +""" +"range(lower, upper)" restituisce una lista di numeri +dal più piccolo (lower) al più grande (upper) +stampa: + 4 + 5 + 6 + 7 +""" +for i in range(4, 8): + print i + +""" +I cicli while vengono eseguiti finchè una condizione viene a mancare +stampa: + 0 + 1 + 2 + 3 +""" +x = 0 +while x < 4: + print x + x += 1 # Forma compatta per x = x + 1 + +# Gestisci le eccezioni con un blocco try/except + +# Funziona da Python 2.6 in su: +try: + # Usa "raise" per generare un errore + raise IndexError("Questo è un errore di indice") +except IndexError as e: + pass # Pass è solo una non-operazione. Solitamente vorrai fare un recupero. +except (TypeError, NameError): + pass # Eccezioni multiple possono essere gestite tutte insieme, se necessario. +else: # Clausola opzionale al blocco try/except. Deve seguire tutti i blocchi except + print "Tutto ok!" # Viene eseguita solo se il codice dentro try non genera eccezioni +finally: # Eseguito sempre + print "Possiamo liberare risorse qui" + +# Invece di try/finally per liberare risorse puoi usare il metodo with +with open("myfile.txt") as f: + for line in f: + print line + +#################################################### +## 4. Funzioni +#################################################### + +# Usa "def" per creare nuove funzioni +def aggiungi(x, y): + print "x è {0} e y è {1}".format(x, y) + return x + y # Restituisce valori con il metodo return + +# Chiamare funzioni con parametri +aggiungi(5, 6) # => stampa "x è 5 e y è 6" e restituisce 11 + +# Un altro modo per chiamare funzioni è con parole chiave come argomenti +aggiungi(y=6, x=5) # Le parole chiave come argomenti possono arrivare in ogni ordine. + + +# Puoi definire funzioni che accettano un numero variabile di argomenti posizionali +# che verranno interpretati come tuple usando il * +def varargs(*args): + return args + +varargs(1, 2, 3) # => (1, 2, 3) + + +# Puoi definire funzioni che accettano un numero variabile di parole chiave +# come argomento, che saranno interpretati come un dizionario usando ** +def keyword_args(**kwargs): + return kwargs + +# Chiamiamola per vedere cosa succede +keyword_args(big="foot", loch="ness") # => {"big": "foot", "loch": "ness"} + + +# Puoi farle entrambi in una volta, se ti va +def all_the_args(*args, **kwargs): + print args + print kwargs +""" +all_the_args(1, 2, a=3, b=4) stampa: + (1, 2) + {"a": 3, "b": 4} +""" + +# Quando chiami funzioni, puoi fare l'opposto di args/kwargs! +# Usa * per sviluppare gli argomenti posizionale ed usa ** per espandere gli argomenti parola chiave +args = (1, 2, 3, 4) +kwargs = {"a": 3, "b": 4} +all_the_args(*args) # equivalente a foo(1, 2, 3, 4) +all_the_args(**kwargs) # equivalente a foo(a=3, b=4) +all_the_args(*args, **kwargs) # equivalente a foo(1, 2, 3, 4, a=3, b=4) + +# puoi passare args e kwargs insieme alle altre funzioni che accettano args/kwargs +# sviluppandoli, rispettivamente, con * e ** +def pass_all_the_args(*args, **kwargs): + all_the_args(*args, **kwargs) + print varargs(*args) + print keyword_args(**kwargs) + +# Funzioni Scope +x = 5 + +def set_x(num): + # La variabile locale x non è uguale alla variabile globale x + x = num # => 43 + print x # => 43 + +def set_global_x(num): + global x + print x # => 5 + x = num # la variabile globable x è ora 6 + print x # => 6 + +set_x(43) +set_global_x(6) + +# Python ha funzioni di prima classe +def create_adder(x): + def adder(y): + return x + y + return adder + +add_10 = create_adder(10) +add_10(3) # => 13 + +# Ci sono anche funzioni anonime +(lambda x: x > 2)(3) # => True +(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5 + +# Esse sono incluse in funzioni di alto livello +map(add_10, [1, 2, 3]) # => [11, 12, 13] +map(max, [1, 2, 3], [4, 2, 1]) # => [4, 2, 3] + +filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7] + +# Possiamo usare la comprensione delle liste per mappe e filtri +[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13] +[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7] + +# Puoi fare anche la comprensione di set e dizionari +{x for x in 'abcddeef' if x in 'abc'} # => {'d', 'e', 'f'} +{x: x**2 for x in range(5)} # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} + + +#################################################### +## 5. Classi +#################################################### + +# Usiamo una sottoclasse da un oggetto per avere una classe. +class Human(object): + + # Un attributo della classe. E' condiviso da tutte le istanze delle classe + species = "H. sapiens" + + # Costruttore base, richiamato quando la classe viene inizializzata. + # Si noti che il doppio leading e gli underscore finali denotano oggetti + # o attributi che sono usati da python ma che vivono nello spazio dei nome controllato + # dall'utente. Non dovresti usare nomi di questo genere. + def __init__(self, name): + # Assegna l'argomento all'attributo name dell'istanza + self.name = name + + # Inizializza una proprietà + self.age = 0 + + # Un metodo dell'istanza. Tutti i metodi prendo "self" come primo argomento + def say(self, msg): + return "{0}: {1}".format(self.name, msg) + + # Un metodo della classe è condiviso fra tutte le istanze + # Sono chiamate con la classe chiamante come primo argomento + @classmethod + def get_species(cls): + return cls.species + + # Un metodo statico è chiamato senza una classe od una istanza di riferimento + @staticmethod + def grunt(): + return "*grunt*" + + # Una proprietà è come un metodo getter. + # Trasforma il metodo age() in un attributo in sola lettura, che ha lo stesso nome + @property + def age(self): + return self._age + + # Questo metodo permette di modificare la proprietà + @age.setter + def age(self, age): + self._age = age + + # Questo metodo permette di cancellare la proprietà + @age.deleter + def age(self): + del self._age + +# Instanziare una classe +i = Human(name="Ian") +print i.say("hi") # stampa "Ian: hi" + +j = Human("Joel") +print j.say("hello") # stampa "Joel: hello" + +# Chiamare metodi della classe +i.get_species() # => "H. sapiens" + +# Cambiare l'attributo condiviso +Human.species = "H. neanderthalensis" +i.get_species() # => "H. neanderthalensis" +j.get_species() # => "H. neanderthalensis" + +# Chiamare il metodo condiviso +Human.grunt() # => "*grunt*" + +# Aggiorna la proprietà +i.age = 42 + +# Ritorna il valore della proprietà +i.age # => 42 + +# Cancella la proprietà +del i.age +i.age # => Emette un AttributeError + + +#################################################### +## 6. Moduli +#################################################### + +# Puoi importare moduli +import math +print math.sqrt(16) # => 4 + +# Puoi ottenere specifiche funzione da un modulo +from math import ceil, floor +print ceil(3.7) # => 4.0 +print floor(3.7) # => 3.0 + +# Puoi importare tutte le funzioni da un modulo +# Attenzione: questo non è raccomandato +from math import * + +# Puoi abbreviare i nomi dei moduli +import math as m +math.sqrt(16) == m.sqrt(16) # => True +# puoi anche verificare che le funzioni sono equivalenti +from math import sqrt +math.sqrt == m.sqrt == sqrt # => True + +# I moduli di Python sono normali file python. Ne puoi +# scrivere di tuoi ed importarli. Il nome del modulo +# è lo stesso del nome del file. + +# Potete scoprire quali funzioni e attributi +# definiscono un modulo +import math +dir(math) + +# Se nella cartella corrente hai uno script chiamato math.py, +# Python caricherà quello invece del modulo math. +# Questo succede perchè la cartella corrente ha priorità +# sulle librerie standard di Python + + +#################################################### +## 7. Avanzate +#################################################### + +# Generatori +# Un generatore appunto "genera" valori solo quando vengono richiesti, +# invece di memorizzarli tutti subito fin dall'inizio + +# Il metodo seguente (che NON è un generatore) raddoppia tutti i valori e li memorizza +# dentro `double_arr`. Se gli oggetti iterabili sono grandi, il vettore risultato +# potrebbe diventare enorme! +def double_numbers(iterable): + double_arr = [] + for i in iterable: + double_arr.append(i + i) + +# Eseguendo il seguente codice, noi andiamo a raddoppiare prima tutti i valori, e poi +# li ritorniamo tutti e andiamo a controllare la condizione +for value in double_numbers(range(1000000)): # `test_senza_generatore` + print value + if value > 5: + break + +# Invece, potremmo usare un generatore per "generare" il valore raddoppiato non +# appena viene richiesto +def double_numbers_generator(iterable): + for i in iterable: + yield i + i + +# Utilizzando lo stesso test di prima, stavolta però con un generatore, ci permette +# di iterare sui valori e raddoppiarli uno alla volta, non appena vengono richiesti dalla +# logica del programma. Per questo, non appena troviamo un valore > 5, usciamo dal ciclo senza +# bisogno di raddoppiare la maggior parte dei valori del range (MOLTO PIU VELOCE!) +for value in double_numbers_generator(xrange(1000000)): # `test_generatore` + print value + if value > 5: + break + +# Nota: hai notato l'uso di `range` in `test_senza_generatore` e `xrange` in `test_generatore`? +# Proprio come `double_numbers_generator` è la versione col generatore di `double_numbers` +# Abbiamo `xrange` come versione col generatore di `range` +# `range` ritorna un array di 1000000 elementi +# `xrange` invece genera 1000000 valori quando lo richiediamo/iteriamo su di essi + +# Allo stesso modo della comprensione delle liste, puoi creare la comprensione +# dei generatori. +values = (-x for x in [1,2,3,4,5]) +for x in values: + print(x) # stampa -1 -2 -3 -4 -5 + +# Puoi anche fare il cast diretto di una comprensione di generatori ad una lista. +values = (-x for x in [1,2,3,4,5]) +gen_to_list = list(values) +print(gen_to_list) # => [-1, -2, -3, -4, -5] + + +# Decoratori +# in questo esempio beg include say +# Beg chiamerà say. Se say_please è True allora cambierà il messaggio +# ritornato +from functools import wraps + +def beg(target_function): + @wraps(target_function) + def wrapper(*args, **kwargs): + msg, say_please = target_function(*args, **kwargs) + if say_please: + return "{} {}".format(msg, "Per favore! Sono povero :(") + return msg + + return wrapper + + +@beg +def say(say_please=False): + msg = "Puoi comprarmi una birra?" + return msg, say_please + + +print say() # Puoi comprarmi una birra? +print say(say_please=True) # Puoi comprarmi una birra? Per favore! Sono povero :( +``` + +## Pronto per qualcosa di più? + +### Gratis Online + +* [Automate the Boring Stuff with Python](https://automatetheboringstuff.com) +* [Learn Python The Hard Way](http://learnpythonthehardway.org/book/) +* [Dive Into Python](http://www.diveintopython.net/) +* [The Official Docs](http://docs.python.org/2/) +* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/) +* [Python Module of the Week](http://pymotw.com/2/) +* [A Crash Course in Python for Scientists](http://nbviewer.ipython.org/5920182) +* [First Steps With Python](https://realpython.com/learn/python-first-steps/) +* [LearnPython](http://www.learnpython.org/) +* [Fullstack Python](https://www.fullstackpython.com/) + +### Libri cartacei + +* [Programming Python](http://www.amazon.com/gp/product/0596158106/ref=as_li_qf_sp_asin_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596158106&linkCode=as2&tag=homebits04-20) +* [Dive Into Python](http://www.amazon.com/gp/product/1441413022/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=1441413022&linkCode=as2&tag=homebits04-20) +* [Python Essential Reference](http://www.amazon.com/gp/product/0672329786/ref=as_li_tf_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0672329786&linkCode=as2&tag=homebits04-20) diff --git a/it-it/rst-it.html.markdown b/it-it/rst-it.html.markdown new file mode 100644 index 00000000..a834e899 --- /dev/null +++ b/it-it/rst-it.html.markdown @@ -0,0 +1,111 @@ +--- +language: restructured text (RST) +filename: restructuredtext-it.rst +contributors: + - ["DamienVGN", "https://github.com/martin-damien"] + - ["Andre Polykanine", "https://github.com/Oire"] +translators: + - ["Ale46", "https://github.com/Ale46"] + - ["Chris54721", "https://chris54721.net"] +lang: it-it +--- + +RST (Restructured Text) è un formato di file inizialmente creato dalla comunità Python +per la documentazione (per questo motivo appartiene a Docutils). + +I file RST sono semplici file di testo con una sintassi leggera (in confronto all'HTML). + +## Installazione + +Per usare Restructured Text, sarà necessario installare [Python](http://www.python.org) ed il pacchetto `docutils`. + +`docutils` può essere installato da riga di comando: + +```bash +$ easy_install docutils +``` + +Oppure, se hai `pip` installato sul tuo sistema: + +```bash +$ pip install docutils +``` + + +## Sintassi del file + +Ecco un semplice esempio della sintassi RST: + +``` +.. Le righe che iniziano con due punti sono comandi speciali. Ma se non è possibile trovare alcun comando, la riga viene considerata come un commento + +=============================================================================== +I titoli principali sono scritti utilizzando caratteri di uguale, sopra e sotto +=============================================================================== + +Si noti che devono esserci tanti caratteri di uguale quanti caratteri del titolo. + +Anche i titoli normali usano caratteri di uguale, ma solo sotto +=============================================================== + +I sottotitoli usano i trattini +------------------------------ + +E i sotto-sottotitoli le tildi +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Puoi inserire il testo in *corsivo* o in **grassetto**, puoi "contrassegnare" il testo come codice con un doppio apice ``: `` print () ``. + +Le liste sono semplici come in Markdown: + +- primo articolo +- Secondo elemento + - Sottoelemento + +oppure + +* Primo elemento +* Secondo elemento + * Sottoelemento + +Le tabelle sono molto semplici da inserire: + +=========== ======== +Stato Capitale +=========== ======== +Francia Parigi +Giappone Tokio +=========== ======== + +Anche le tabelle più complesse possono essere inserite facilmente (colonne e/o righe unite) ma ti suggerisco di leggere la documentazione completa per questo :) + +Esistono diversi modi per creare collegamenti: + +- Aggiungendo un underscore dopo una parola: Github_ e aggiungendo l'URL di destinazione dopo il testo (questo metodo ha il vantaggio di non inserire URL non necessari all'interno del testo leggibile). +- Digitando un URL completo: https://github.com/ (verrà automaticamente convertito in un collegamento) +- Utilizzando una sintassi simile a Markdown: `Github <https://github.com/>`_ . + +.. _Github https://github.com/ + +``` + +## Come usarlo + +RST viene fornito con docutils, che dispone di `rst2html`, per esempio: + +```bash +$ rst2html miofile.rst output.html +``` + +*Nota : In alcuni sistemi il comando potrebbe essere rst2html.py* + +Ma ci sono applicazioni più complesse che utilizzano il formato RST: + +- [Pelican](http://blog.getpelican.com/), un generatore di siti statici +- [Sphinx](http://sphinx-doc.org/), un generatore di documentazione +- e molti altri + + +## Letture + +- [Riferimento ufficiale rapido](http://docutils.sourceforge.net/docs/user/rst/quickref.html) diff --git a/it-it/ruby-ecosystem-it.html.markdown b/it-it/ruby-ecosystem-it.html.markdown new file mode 100644 index 00000000..d745399b --- /dev/null +++ b/it-it/ruby-ecosystem-it.html.markdown @@ -0,0 +1,145 @@ +--- +category: tool +tool: ruby ecosystem +contributors: + - ["Jon Smock", "http://github.com/jonsmock"] + - ["Rafal Chmiel", "http://github.com/rafalchmiel"] +translators: + - ["Cristian Achille", "http://github.com/blackdev1l/"] +lang: it-it +--- + +Generalmente chi usa ruby ha l'esigenza di avere differenti versioni di Ruby +installate, gestire le proprie gemme, e le loro dipendenze. + +## Manager Ruby + +Alcune piattaforme hanno Ruby pre-installato o disponibile come pacchetto. +Molti sviluppatori Ruby non usano questi pacchetti, o se lo fanno, li usano solo +per installare dei manager Ruby, i quali permettono di installare e gestire più +versioni di Ruby in base al progetto su cui si lavora. + +Di seguito i più famosi manager Ruby: + +* [RVM](https://rvm.io/) - Installa e permette di utilizzare diverse versioni di + Ruby. RVM Ha anche il concetto di gemsets i quali isolano completamente l'ambiente di sviluppo del progetto. +* [ruby-build](https://github.com/sstephenson/ruby-build) - Installa solamente + multiple versioni di ruby. Usa questo se vuoi maggior controllo sull'installazione di Ruby. +* [rbenv](https://github.com/sstephenson/rbenv) - + Permette solo la scelta di quale versione Ruby utilizzare. Usato insieme a ruby-build. + Utilizza questo per un maggior controllo su quale versione di Ruby utilizzare. +* [chruby](https://github.com/postmodern/chruby) - + Permette solo la scelta di quale Ruby utilizzare, simile a rbenv. + +## Ruby Versions + +Ruby fu creato da Yukihiro "Matz" Matsumoto, il [BDFL](https://en.wikipedia.org/wiki/Benevolent_Dictator_for_Life), +(acronimo inglese che sta per "Benevolo dittatore a vita") , seppur +ultimamente non è più del tutto vera; l'implementazione di Ruby +è detta MRI (Matz' Reference Implementation), e dunque quando si legge di una +versione Ruby, essa si riferisce sempre al rilascio di una MRI + +Le tre maggiori versioni di Ruby in uso sono: + +* 2.0.0 - Rilasciata nel febbraio 2013. La maggior parte delle librerie e + framework supportano la 2.0.0 +* 1.9.3 - Rilasciata nel ottobre 2011. QUesta è la versione che molti + svluppatori usano, il supporto è + [concluso](https://www.ruby-lang.org/en/news/2015/02/23/support-for-ruby-1-9-3-has-ended/) +* 1.8.7 - Il supporto per Ruby 1.8.7 è + [concluso](http://www.ruby-lang.org/en/news/2013/06/30/we-retire-1-8-7/). + +I cambiamenti tra la 1.8.7 a la 1.9.x sono maggiori di quelli tra la 1.9.3 a la +2.0.0. Per esempio, nella 1.9 vengono introdotti encodings e bytecode VM. +Esistono ancora dei progetti basati sulla 1.8.7, ma stanno diventando una +minoranza man mano che la community si trasferisce alle versioni 1.92 e +1.9.3 + +## Ruby Implementations + +L'ecosistema Ruby gode di molte implementazioni differenti di Ruby, ognuna con +particolari punti di forza, da chiarire che ogni implementazione è scritta con +un linguaggio diverso, ma esse *sono tutte Ruby*. Ogni implementazione ha +feature extra ma tutte esse possono eseguire file ruby. Per esempio, JRuby è +scritto in Java, ma non devi conoscere java per usarlo. + +Implementazioni mature e compatibili: + +* [MRI](https://github.com/ruby/ruby) - Scritto in C, Questa è l'implementazione + standard di Ruby, per definizione è 100% compatibile (con se stessa). Tutte le + altre implemetazioni mantengono la compatibilità con MRI + (vedere [RubySpec](#rubyspec) sotto). +* [JRuby](http://jruby.org/) - Scritto in Java e Ruby, Questa implementazione è + molto veloce e robusta, la forza di JRuby consiste nell'interoperabilità + tra JVM/Java, permettendo l'utilizzo di struemnti Java già esistenti, progetti + e linguaggi +* [Rubinius](http://rubini.us/) - Scritto principalmente in Ruby con un + c++ bytecode VM, molto matura e veloce, permette alcune feature riguardo VM. + +Mediamente mature e compatibili: + +* [Maglev](http://maglev.github.io/) - Sviluppata sui Gemstone, è una Smalltalk +VM, Smalltalk è degli strumenti molto utili, e questo progetto cerca di portare +questi strumenti nello sviluppo Ruby. +* [RubyMotion](http://www.rubymotion.com/) - Porta ruby nello sviluppo iOS. + +Poco mature e compatibili: + +* [Topaz](http://topazruby.com/) - Scritto in RPython (usando PyPy come + toolchain) Topaz è un progetto ancora giovane e non compatibile, ha le + possibilità di diventare una implementazione Ruby molto performante +* [IronRuby](http://ironruby.net/) - Scritto in C# e prendendo di mira la + piattaforma .NET, lo sviluppo sembra fermo da quando Microsoft ha rimosso il + suo supporto. + +Le implementazioni Ruby possono avere una propria versione, ma hanno sempre come +target una specifica versione di MRI. Molte implementazioni hanno l'abilità di +selezionare una versione specifica di MRI. + +##RubySpec + +La maggior parte delle implementazioni Ruby dipendono pesantemente su +[RubySpec](http://rubyspec.org/). Ruby non ha una specifica ufficiale, quindi la +community ha scritto una specifica eseguibile in Ruby per testare la compatibilità +con MRI. + +## RubyGems + +[RubyGems](http://rubygems.org/) è un package manager gestito dalla communtiy +per Ruby. Rubygems viene installato con Ruby, quindi non c'è bisogno di +scaricarlo separatamente. + +I pacchetti Ruby sono chiamate "gemme", e possono essere hostate dalla community +su RubyGems.org . Ogni gemma contiene il codice sorgente e del metadata, tra cui +la versione, le dipendenze, autor* e licenz*. + +## Bundler + +[Bundler](http://bundler.io/) è un risolvitore di dipendenze, Esso usa il Gemfile +di un progetto per cercare le dipendenze, dopo di che ottiene le dipendenze delle +dipendenze ricorsivamente, Questo procedimento viene eseguito finchè tutte le +dipendenze sono state risolte e scaricate, o si fermerà se un conflitto verrà +trovato. + +Bundler genererà un error se troverà dipendenze in conflitto, Per esempio, +se la gemma A richiede la versione 3 o maggiore della gemma Z, ma la gemma B +richiede la versione 2, Bundler ti notificherà del conflitto. Questo diventa +di aiuto nel momento in cui si hanno molte gemme nel progetto, il che porta a +un grande grafo di dipendenza da risolvere. + +# Testing + +Il testing è un pezzo fondamentale della cultura Ruby, Ruby viene installato con +il proprio testing framework chiamato minitest (O TestUnit per ruby 1.8.x). +Esistono molte librerie con obiettivi differenti + +* [TestUnit](http://ruby-doc.org/stdlib-1.8.7/libdoc/test/unit/rdoc/Test/Unit.html) - Testing frameowrk rilasciato insieme a Ruby 1.8.x +* [minitest](http://ruby-doc.org/stdlib-2.0.0/libdoc/minitest/rdoc/MiniTest.html) - Testing frameowrk rilasciato insieme a Ruby 1.9/2.0 +* [RSpec](http://rspec.info/) - Un testing framework che si concentra nella chiarezza +* [Cucumber](http://cukes.info/) - Un BDD testing framework che estrapola testo formattato in Gherkin + +## Sii cordiale + +La community Ruby è orgogliosa di essere una communtiy aperta, accogliente e +variegata. Matz stesso è estremamente amichevole, e la generosità degli sviluppatori +Ruby è fantastica. diff --git a/it-it/rust-it.html.markdown b/it-it/rust-it.html.markdown new file mode 100644 index 00000000..6b379f93 --- /dev/null +++ b/it-it/rust-it.html.markdown @@ -0,0 +1,322 @@ +--- +language: rust +contributors: + - ["Carlo Milanesi", "http://github.com/carlomilanesi"] +lang: it-it +filename: rust-it.html.markdown +--- + +Rust è un linguaggio di programmazione sviluppato da Mozilla Research. +Rust combina il controllo a basso livello sulle prestazioni con alcune comodità +ad alto livello e stringenti garanzie di sicurezza. + +Rust raggiunge questi obiettivi senza richiedere la garbage collection né una grossa +libreria di supporto run-time, rendendo così possibile l'uso di librerie scritte in Rust +come rimpiazzo di librerie scritte in C. + +La prima versione pubblica di Rust, la 0.1, è stata rilasciata nel gennaio 2012, e per 3 anni +lo sviluppo è proceduto così rapidamente che l'utilizzo delle versioni +stabili veniva scoraggiato, e piuttosto si consigliava di utilizzare le versioni notturne +(nightly build). + +Il 15 maggio 2015, la versione 1.0 di Rust è stata rilasciata con la garanzia +che nelle successive versioni 1.x non ci sarebbero state modifiche che avrebbero reso +incompatibile il codice scritto per tale versione. +Nelle nightly build sono attualmente disponibili migliorie al tempo di compilazione +e ad altri aspetti del compilatore. Rust ha adottato un modello di rilascio a scaglioni +con rilasci regolari ogni sei settimane. Per esempio, la versione 1.1 beta è stata resa +disponibile contestualmente al rilascio della versione stabile 1.0. + +Sebbene Rust sia un linguaggio di livello relativamente basso, Rust ha alcuni concetti +di programmazione funzionale che solitamente si trovano solo nei linguaggi di livello più alto. +Ciò rende Rust non solo veloce, ma anche facile ed comodo da usare. + +```rust +// I commenti che stanno su una sola riga sono fatti così... +/* ...mentre così sono fatti +i commenti che richiedono +più righe */ + +/////////////////// +// 1. Fondamenti // +/////////////////// + +// Funzioni +// `i32` è il tipo per gli interi a 32-bit con segno +fn add2(x: i32, y: i32) -> i32 { + // return implicito (senza punto-e-virgola) + x + y +} + +// Funzione "main" +fn main() { + // Numeri // + + // Binding (ossia "variabili") immutabili + let x: i32 = 1; + + // Suffissi intero/virgola mobile + let y: i32 = 13i32; + let f: f64 = 1.3f64; + + // Inferenza di tipo + // La maggior parte delle volte, il compilatore Rust può inferire + // di quale tipo sia l'espressione usata per inizializzare un binding, + // e quindi non è necessario specificare esplicitamente il tipo. + // In tutto questo tutorial, i tipi vengono specificati esplicitamente in molti posti, + // ma solo a scopo dimostrativo. La maggior parte delle volte se ne potrebbe + // fare a meno, grazie all'inferenza di tipo. + let implicito_x = 1; + let implicito_f = 1.3; + + // Aritmetica + let somma = x + y + 13; + + // Variabile mutevole + let mut mutevole = 1; + mutevole = 4; + mutevole += 2; + + // Stringhe // + + // Letterali di stringa + let x: &str = "Ciao mondo!"; + + // Stampa + println!("{} {}", f, x); // 1.3 Ciao mondo! + + // Una `String` – una stringa allocata nello heap + let s: String = "Ciao mondo".to_string(); + + // Uno slice (fetta) di stringa – una vista immutabile + // all'interno di un'altra stringa. + // Uno slice è una coppia immutabile di puntatori al buffer contenuto + // nella stringa - non contiene dei caratteri, solo dei puntatori a + // un buffer statico o a un buffer contenuto in un altro oggetto (in questo caso, `s`) + let s_slice: &str = &s; + + println!("{} - {}", s, s_slice); // Ciao mondo - Ciao mondo + + // Vettori/array // + + // Un array di lunghezza fissa + let quattro_int: [i32; 4] = [1, 2, 3, 4]; + + // Un array dinamico (vettore) + let mut vettore: Vec<i32> = vec![1, 2, 3, 4]; + vettore.push(5); + + // Uno slice – una vista immutabile all'interno di un vettore o di un array + // E' molto simile a uno slice di stringa, ma per i vettori + let slice: &[i32] = &vettore; + + // Usa `{:?}` per stampare qualcosa a scopo di debugging + println!("{:?} {:?}", vettore, slice); // [1, 2, 3, 4, 5] [1, 2, 3, 4, 5] + + // Tuple // + + // Una tupla è un insieme ordinato di dimensione fissa di valori aventi tipi eventualmente diversi + let x: (i32, &str, f64) = (1, "ciao", 3.4); + + // Il `let` che destruttura + let (a, b, c) = x; + println!("{} {} {}", a, b, c); // 1 ciao 3.4 + + // Indicizzazione + println!("{}", x.1); // ciao + + ///////////// + // 2. Tipi // + ///////////// + + // Strutture + struct Point { + x: i32, + y: i32, + } + + let origine: Punto = Punto { x: 0, y: 0 }; + + // Ana struct con campi senza nome, chiamata ‘tuple struct’ + struct Punto2(i32, i32); + + let origine2 = Punto2(0, 0); + + // Enum basilare, analoga a quelle del linguaggio C + enum Direzione { + Sinistra, + Destra, + Su, + Giu, + } + + let su = Direzione::Su; + + // Enum con campi + enum OpzionaleI32 { + UnI32(i32), + Niente, + } + + let due: OpzionaleI32 = OpzionaleI32::UnI32(2); + let niente = OpzionaleI32::Niente; + + // Generici // + + struct Foo<T> { bar: T } + + // Questo è definito nella libreria standard come `Option` + enum Opzionale<T> { + QualcheValore(T), + NessunValore, + } + + // Metodi // + + impl<T> Foo<T> { + // I metodi di oggetto prendono un parametro `self` esplicito + fn get_bar(self) -> T { + self.bar + } + } + + let a_foo = Foo { bar: 1 }; + println!("{}", a_foo.get_bar()); // 1 + + // I trait (tratti), noti come "interfacce" o "mixin" in altri linguaggi + + trait Maneggiamento<T> { + fn maneggia(self) -> Option<T>; + } + + impl<T> Maneggiamento<T> for Foo<T> { + fn maneggia(self) -> Option<T> { + Some(self.bar) + } + } + + let altro_foo = Foo { bar: 1 }; + println!("{:?}", altro_foo.maneggia()); // Some(1) + + ///////////////////////// + // 3. Pattern matching // + ///////////////////////// + + let foo = OpzionaleI32::UnI32(1); + match foo { + OpzionaleI32::UnI32(n) => println!("E' un i32: {}", n), + OpzionaleI32::Niente => println!("Non vale niente!"), + } + + // Pattern matching avanzato + struct FooBar { x: i32, y: OpzionaleI32 } + let bar = FooBar { x: 15, y: OpzionaleI32::UnI32(32) }; + + match bar { + FooBar { x: 0, y: OpzionaleI32::UnI32(0) } => + println!("I numeri valgono zero!"), + FooBar { x: n, y: OpzionaleI32::UnI32(m) } if n == m => + println!("I numeri sono identici"), + FooBar { x: n, y: OpzionaleI32::UnI32(m) } => + println!("Numeri diversi: {} {}", n, m), + FooBar { x: _, y: OpzionaleI32::Niente } => + println!("Il secondo numbero non vale niente!"), + } + + /////////////////////////////////////////// + // 4. Flusso di controllo (Control flow) // + /////////////////////////////////////////// + + // Ciclo/iterazione con `for` + let array = [1, 2, 3]; + for i in array.iter() { + println!("{}", i); + } + + // Range + for i in 0u32..10 { + print!("{} ", i); + } + println!(""); + // Stampa `0 1 2 3 4 5 6 7 8 9 ` + + // `if` + if 1 == 1 { + println!("La matematica funziona!"); + } else { + println!("Oh no..."); + } + + // `if` come espressione + let value = if true { + "bene" + } else { + "male" + }; + + // Ciclo `while` + while 1 == 1 { + println!("L'universo sta funzionando regolarmente."); + } + + // Ciclo infinito + loop { + println!("Ciao!"); + } + + ///////////////////////////////////////////////// + // 5. La sicurezza della memoria e i puntatori // + ///////////////////////////////////////////////// + + // Puntatore posseduto (owned) – solamente una cosa sola per volta può ‘possedere’ questo puntatore + // Ciò significa che quando il `Box` abbandona il suo scope, verrà automaticamente deallocato in sicurezza. + let mut mio: Box<i32> = Box::new(3); + *mio = 5; // dereference + // Qui, `adesso_e_mio` acquisisce la proprietà di `mio`. In altre parole, `mio` viene spostato. + let mut adesso_e_mio = mio; + *adesso_e_mio += 2; + + println!("{}", adesso_e_mio); // 7 + // println!("{}", mio); // questo non compilerebbe perché `adesso_e_mio` adesso possiede il puntatore + + // Riferimento (reference) – un puntatore immutabile che si riferisce ad altri dati + // Quando un riferimento viene preso a un valore, diciamo che quel valore + // è stato ‘preso in prestito’ (borrowed). + // Mentre un valore è preso in prestito immutabilmente, non può venire mutato né spostato. + // Un prestito dura fino alla fine dello scope in cui è stato creato. + let mut var = 4; + var = 3; + let ref_var: &i32 = &var; + + println!("{}", var); // Diversamente da `mio`, `var` può ancora essere usato + println!("{}", *ref_var); + // var = 5; // questo non compilerebbe, perché `var` è stato preso in prestito + // *ref_var = 6; // neanche questo, perché `ref_var` è un riferimento immutabile + + // Riferimento immutabile + // Mentre un valore è preso in presto mutevolmente, non può essere acceduto in nessun modo. + let mut var2 = 4; + let ref_var2: &mut i32 = &mut var2; + *ref_var2 += 2; // '*' serve a puntare al binding var2, preso in presto mutevolmente + + println!("{}", *ref_var2); // 6 + // var2 non compilerebbe. ref_var2 è di tipo &mut i32, e quindi + // immagazzina un riferimento a un i32, e non il valore stesso. + // var2 = 2; // questo non compilerebbe, perché `var2` è stato preso in prestito +} +``` + +## Ulteriori letture + +C'è molto di più in Rust — questi sono solo i fondamenti di Rust, che servono a capire +le cose più importanti. + +Purtroppo c'è pochissima documentazione in italiano, tra cui: +(https://www.mozillaitalia.org/home/2015/05/30/primi-passi-con-rust/) + +Però ce n'è parecchia in inglese. Per saperne di più, leggi [The Rust Programming +Language](http://doc.rust-lang.org/book/index.html) e tieni d'occhio l'area di interesse di Reddit (subreddit) +[/r/rust](http://reddit.com/r/rust). + +Puoi anche provare a programmare in varie versioni di Rust usando il compilatore online al sito ufficiale +[Rust playpen](http://play.rust-lang.org). |