summaryrefslogtreecommitdiffhomepage
path: root/it-it
diff options
context:
space:
mode:
Diffstat (limited to 'it-it')
-rw-r--r--it-it/asciidoc-it.html.markdown2
-rw-r--r--it-it/bash-it.html.markdown23
-rw-r--r--it-it/c++-it.html.markdown2
-rw-r--r--it-it/elixir-it.html.markdown70
-rw-r--r--it-it/go-it.html.markdown16
-rw-r--r--it-it/javascript-it.html.markdown2
-rw-r--r--it-it/markdown.html.markdown27
-rw-r--r--it-it/matlab-it.html.markdown16
-rw-r--r--it-it/php-composer-it.html.markdown193
-rw-r--r--it-it/pyqt-it.html.markdown8
-rw-r--r--it-it/python-it.html.markdown952
-rw-r--r--it-it/python3-it.html.markdown1016
-rw-r--r--it-it/pythonlegacy-it.html.markdown778
-rw-r--r--it-it/qt-it.html.markdown2
-rw-r--r--it-it/rst-it.html.markdown6
-rw-r--r--it-it/ruby-it.html.markdown2
-rw-r--r--it-it/rust-it.html.markdown4
-rw-r--r--it-it/solidity.html.markdown1069
-rw-r--r--it-it/sql-it.html.markdown112
-rw-r--r--it-it/toml-it.html.markdown552
-rw-r--r--it-it/zfs-it.html.markdown361
21 files changed, 3492 insertions, 1721 deletions
diff --git a/it-it/asciidoc-it.html.markdown b/it-it/asciidoc-it.html.markdown
index 47a57349..eaa2372b 100644
--- a/it-it/asciidoc-it.html.markdown
+++ b/it-it/asciidoc-it.html.markdown
@@ -6,7 +6,7 @@ contributors:
translators:
- ["Ale46", "https://github.com/ale46"]
lang: it-it
-filename: asciidoc-it.md
+filename: asciidoc-it.adoc
---
AsciiDoc è un linguaggio di markup simile a Markdown e può essere usato per qualsiasi cosa, dai libri ai blog. Creato nel 2002 da Stuart Rackman, questo linguaggio è semplice ma permette un buon numero di personalizzazioni.
diff --git a/it-it/bash-it.html.markdown b/it-it/bash-it.html.markdown
index efc47969..dd55b84c 100644
--- a/it-it/bash-it.html.markdown
+++ b/it-it/bash-it.html.markdown
@@ -22,7 +22,7 @@ translators:
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.
+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 macOS.
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)
@@ -63,7 +63,7 @@ echo ${Variabile}
# Sotto ci sono altri esempi che analizzano l'uso dell'espansione dei parametri.
# Sostituzione di stringhe nelle variabili
-echo ${Variabile/Una/A}
+echo ${Variabile/Una/La}
# Questo sostituirà la prima occorrenza di "Una" con "La"
# Sottostringa di una variabile
@@ -140,6 +140,25 @@ then
echo "Questo verrà eseguito se $Nome è Daniya O Zach."
fi
+# C'è anche l'operatore `=~`, che serve per confrontare una stringa con un'espressione regolare:
+Email=me@example.com
+if [[ "$Email" =~ [a-z]+@[a-z]{2,}\.(com|net|org) ]]
+then
+ echo "Email valida!"
+fi
+# L'operatore =~ funziona solo dentro alle doppie parentesi quadre [[ ]],
+# che hanno un comportamento leggermente diverso rispetto alle singole [ ].
+# Se vuoi approfondire, visita questo link (in inglese):
+# http://www.gnu.org/software/bash/manual/bashref.html#Conditional-Constructs
+
+# Usando `alias`, puoi definire nuovi comandi o modificare quelli già esistenti.
+# Ad esempio, così puoi ridefinire il comando ping per inviare solo 5 pacchetti
+alias ping='ping -c 5'
+# "Scavalca" l'alias e usa il comando vero, utilizzando il backslash
+\ping 192.168.1.1
+# Stampa la lista di tutti gli alias
+alias -p
+
# Le espressioni sono nel seguente formato:
echo $(( 10 + 5 ))
diff --git a/it-it/c++-it.html.markdown b/it-it/c++-it.html.markdown
index 449aebfb..a8e0c7b5 100644
--- a/it-it/c++-it.html.markdown
+++ b/it-it/c++-it.html.markdown
@@ -1,5 +1,5 @@
---
-language: c++
+language: C++
filename: learncpp-it.cpp
contributors:
- ["Steven Basart", "http://github.com/xksteven"]
diff --git a/it-it/elixir-it.html.markdown b/it-it/elixir-it.html.markdown
index 60301b1a..ce3e4535 100644
--- a/it-it/elixir-it.html.markdown
+++ b/it-it/elixir-it.html.markdown
@@ -1,5 +1,5 @@
---
-language: elixir
+language: Elixir
contributors:
- ["Luca 'Kino' Maroni", "https://github.com/kino90"]
- ["Joao Marques", "http://github.com/mrshankly"]
@@ -21,11 +21,11 @@ e molte altre funzionalità.
# Non esistono commenti multilinea,
# ma puoi concatenare più commenti.
-# Per usare la shell di elixir usa il comando `iex`.
+# 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.
+# Entrambi i comandi dovrebbero già essere nel tuo PATH se hai installato
+# Elixir correttamente.
## ---------------------------
## -- Tipi di base
@@ -65,7 +65,7 @@ coda #=> [2,3]
# 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
+# Ci sono anche i binari
<<1,2,3>> # binari (Binary)
# Stringhe e liste di caratteri
@@ -80,14 +80,14 @@ multi-linea.
#=> "Sono una stringa\nmulti-linea.\n"
# Le stringhe sono tutte codificate in UTF-8:
-"cìaò"
+"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` in Elixir restituisce il valore ASCII della lettera `a`
?a #=> 97
# Per concatenare liste si usa `++`, per binari si usa `<>`
@@ -112,7 +112,7 @@ minore..maggiore = 1..10 # Puoi fare pattern matching anche sugli intervalli
5 * 2 #=> 10
10 / 2 #=> 5.0
-# In elixir l'operatore `/` restituisce sempre un decimale.
+# In Elixir l'operatore `/` restituisce sempre un decimale.
# Per fare una divisione intera si usa `div`
div(10, 2) #=> 5
@@ -124,10 +124,11 @@ rem(10, 3) #=> 1
# Questi operatori si aspettano un booleano come primo argomento.
true and true #=> true
false or true #=> true
-# 1 and true #=> ** (ArgumentError) argument error
+# 1 and true
+#=> ** (BadBooleanError) expected a boolean on left-side of "and", got: 1
# Elixir fornisce anche `||`, `&&` e `!` che accettano argomenti
-# di qualsiasi tipo.
+# di qualsiasi tipo.
# Tutti i valori tranne `false` e `nil` saranno valutati come true.
1 || true #=> 1
false && 1 #=> false
@@ -147,7 +148,7 @@ nil && 20 #=> nil
1 < :ciao #=> true
# L'ordine generale è definito sotto:
-# numeri < atomi < riferimenti < funzioni < porte < pid < tuple < liste
+# numeri < atomi < riferimenti < funzioni < porte < pid < tuple < liste
# < stringhe di bit
# Per citare Joe Armstrong su questo: "L'ordine non è importante,
@@ -171,8 +172,8 @@ else
"Questo sì"
end
-# Ti ricordi il pattern matching?
-# Moltre strutture di controllo di flusso in elixir si basano su di esso.
+# 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
@@ -214,7 +215,7 @@ cond do
"Questa sì! (essenzialmente funziona come un else)"
end
-# `try/catch` si usa per gestire i valori lanciati (throw),
+# `try/catch` si usa per gestire i valori lanciati (throw),
# Supporta anche una clausola `after` che è invocata in ogni caso.
try do
throw(:ciao)
@@ -235,7 +236,7 @@ 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,
+# 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
@@ -265,13 +266,13 @@ end
Matematica.somma(1, 2) #=> 3
Matematica.quadrato(3) #=> 9
-# Per compilare il modulo 'Matematica' salvalo come `matematica.ex` e usa
+# 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
+# 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
@@ -286,7 +287,11 @@ end
MatematicaPrivata.somma(1, 2) #=> 3
# MatematicaPrivata.esegui_somma(1, 2) #=> ** (UndefinedFunctionError)
-# Anche le dichiarazioni di funzione supportano guardie e condizioni multiple:
+# Anche le dichiarazioni di funzione supportano guardie e condizioni multiple.
+# Quando viene chiamata una funzione dichiarata con più match, solo la prima
+# che matcha viene effettivamente invocata.
+# Ad esempio: chiamando area({:cerchio, 3}) vedrà invocata la seconda definizione
+# di area mostrata sotto, non la prima:
defmodule Geometria do
def area({:rettangolo, w, h}) do
w * h
@@ -302,7 +307,7 @@ 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
+# 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)
@@ -322,16 +327,25 @@ defmodule Modulo do
Questo è un attributo incorporato in un modulo di esempio.
"""
- @miei_dati 100 # Questo è un attributo personalizzato .
+ @miei_dati 100 # Questo è un attributo personalizzato.
IO.inspect(@miei_dati) #=> 100
end
+# L'operatore pipe |> permette di passare l'output di una espressione
+# come primo parametro di una funzione.
+# Questo facilita operazioni quali pipeline di operazioni, composizione di
+# funzioni, ecc.
+Range.new(1,10)
+|> Enum.map(fn x -> x * x end)
+|> Enum.filter(fn x -> rem(x, 2) == 0 end)
+#=> [4, 16, 36, 64, 100]
+
## ---------------------------
## -- Strutture ed Eccezioni
## ---------------------------
-# Le Strutture (Structs) sono estensioni alle mappe che portano
+# 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
@@ -367,8 +381,8 @@ end
## -- Concorrenza
## ---------------------------
-# Elixir si basa sul modello degli attori per la concorrenza.
-# Tutto ciò di cui abbiamo bisogno per scrivere programmi concorrenti in elixir
+# 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
@@ -379,12 +393,12 @@ 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,
+# 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,
+# 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
@@ -405,7 +419,7 @@ 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
+# 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}
@@ -420,8 +434,8 @@ 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/)
+* [Getting started guide](http://elixir-lang.org/getting_started/1.html) dalla [pagina web ufficiale di Elixir](http://elixir-lang.org)
+* [Documentazione Elixir](https://elixir-lang.org/docs.html)
* ["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
diff --git a/it-it/go-it.html.markdown b/it-it/go-it.html.markdown
index 797f6b0b..6f974c91 100644
--- a/it-it/go-it.html.markdown
+++ b/it-it/go-it.html.markdown
@@ -34,7 +34,7 @@ Go include un'ottima libreria standard e ha una community entusiasta.
su riga multipla */
// In cima ad ogni file è necessario specificare il package.
-// Main è un package speciale che identifica un eseguibile anziché una libreria.
+// 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
@@ -91,7 +91,7 @@ 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)
+ f := 3.14159 // float64, un numero in virgola mobile a 64-bit (IEEE-754)
c := 3 + 4i // complex128, rappresentato internamente con due float64.
@@ -422,9 +422,9 @@ func richiediServer() {
## Letture consigliate
-La risorsa più importante per imparare il Go è il [sito ufficiale di Go](http://golang.org/).
+La risorsa più importante per imparare il Go è il [sito ufficiale di Go](https://go.dev/).
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
+Oltre al tour, [la documentazione](https://go.dev/doc/) contiene informazioni su
come scrivere ottimo codice in Go, documentazione sui package e sui comandi, e
la cronologia delle release.
@@ -432,17 +432,17 @@ 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).
+Puoi giocare con il codice visto finora nel [Go playground](https://go.dev/play/p/Am120Xe7qf).
Prova a cambiarlo e ad eseguirlo dal browser!
-Osserva che puoi usare [https://play.golang.org](https://play.golang.org) come
+Osserva che puoi usare [https://go.dev/play/](https://go.dev/play/) 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 è
+sorgente della libreria standard](https://go.dev/src/). 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
+funzione [nella documentazione](https://go.dev/pkg/) compare il relativo
codice sorgente!
Un'altra ottima risorsa per imparare è [Go by example](https://gobyexample.com/).
diff --git a/it-it/javascript-it.html.markdown b/it-it/javascript-it.html.markdown
index 68bf6287..1d776535 100644
--- a/it-it/javascript-it.html.markdown
+++ b/it-it/javascript-it.html.markdown
@@ -1,7 +1,7 @@
---
language: javascript
contributors:
- - ["Adam Brenecki", "http://adam.brenecki.id.au"]
+ - ["Leigh Brenecki", "https://leigh.net.au"]
- ["Ariel Krakowski", "http://www.learneroo.com"]
translators:
- ["vinniec", "https://github.com/vinniec"]
diff --git a/it-it/markdown.html.markdown b/it-it/markdown.html.markdown
index b0a123f1..609d3bb7 100644
--- a/it-it/markdown.html.markdown
+++ b/it-it/markdown.html.markdown
@@ -72,7 +72,7 @@ __Come pure questo.__
*__E questo!__*
```
-In Github Flavored Markdown, che è utilizzato per renderizzare i file markdown su Github, è presente anche lo stile barrato:
+In GitHub Flavored Markdown, che è utilizzato per renderizzare i file markdown su GitHub, è presente anche lo stile barrato:
```md
~~Questo testo è barrato.~~
@@ -183,7 +183,7 @@ Potete inoltre inserire un altro tab (o altri quattro spazi) per indentare il vo
```md
my_array.each do |item|
- puts item
+ puts item
end
```
@@ -193,14 +193,17 @@ Codice inline può essere inserito usando il carattere backtick `
Giovanni non sapeva neppure a cosa servisse la funzione `go_to()`!
```
-In Github Flavored Markdown, potete inoltre usare una sintassi speciale per il codice
-<pre>
-<code class="highlight">&#x60;&#x60;&#x60;ruby
+In GitHub Flavored Markdown, potete inoltre usare una sintassi speciale per il codice
+
+````md
+```ruby
def foobar
- puts "Hello world!"
+ puts "Hello world!"
end
-&#x60;&#x60;&#x60;</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
+```
+````
+
+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.
@@ -253,7 +256,7 @@ Ma non è comunemente usato.
Le immagini sono inserite come i link ma con un punto esclamativo inserito prima delle parentesi quadre!
```md
-![Qeusto è il testo alternativo per l'immagine](http://imgur.com/myimage.jpg "Il titolo opzionale")
+![Questo è 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
@@ -282,7 +285,7 @@ Voglio inserire *questo testo circondato da asterischi* ma non voglio che venga
```
### Combinazioni di tasti
-In Github Flavored Markdown, potete utilizzare il tag `<kbd>` per raffigurare i tasti della tastiera.
+In GitHub Flavored Markdown, potete utilizzare il tag `<kbd>` per raffigurare i tasti della tastiera.
```md
Il tuo computer è crashato? Prova a premere
@@ -290,7 +293,7 @@ Il tuo computer è crashato? Prova a premere
```
### Tabelle
-Le tabelle sono disponibili solo in Github Flavored Markdown e sono leggeremente complesse, ma se proprio volete inserirle fate come segue:
+Le tabelle sono disponibili solo in GitHub Flavored Markdown e sono leggeremente complesse, ma se proprio volete inserirle fate come segue:
```md
| Col1 | Col2 | Col3 |
@@ -307,4 +310,4 @@ Col 1 | Col2 | Col3
```
---
-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).
+Per altre informazioni, leggete il post ufficiale di John Gruber sulla sintassi [qui](https://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
index 38be8848..2668815f 100644
--- a/it-it/matlab-it.html.markdown
+++ b/it-it/matlab-it.html.markdown
@@ -1,5 +1,5 @@
---
-language: Matlab
+language: MATLAB
contributors:
- ["mendozao", "http://github.com/mendozao"]
- ["jamesscottbrown", "http://jamesscottbrown.com"]
@@ -114,7 +114,7 @@ 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) % 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
@@ -466,7 +466,7 @@ perms(x) % lista tutte le permutazioni di elementi di x
% Classi
-% Matlab supporta la programmazione orientata agli oggetti.
+% 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
@@ -488,7 +488,7 @@ classdef WaypointClass % Il nome della classe.
end
% Se si vuole aggiungere due oggetti Waypoint insieme senza chiamare
- % una funzione speciale si può sovradefinire una funzione aritmetica di Matlab come questa:
+ % 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]);
@@ -500,7 +500,7 @@ end
% 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.
+% Le proprietà della classe si comportano esattamente come una Struttura MATLAB.
a.latitude = 70.0
a.longitude = 25.0
@@ -511,15 +511,15 @@ ans = multiplyLatBy(a,3)
% 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
+% 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
+## 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/php-composer-it.html.markdown b/it-it/php-composer-it.html.markdown
new file mode 100644
index 00000000..509ec336
--- /dev/null
+++ b/it-it/php-composer-it.html.markdown
@@ -0,0 +1,193 @@
+---
+category: tool
+tool: composer
+contributors:
+ - ["Brett Taylor", "https://github.com/glutnix"]
+translator:
+ - ["Agostino Fiscale", "https://github.com/agostinofiscale"]
+lang: it-it
+filename: LearnComposer-it.sh
+---
+
+[Composer](https://getcomposer.org/) è uno strumento che ti aiuta a gestire le
+dipendenze in PHP. Ti permette di dichiarare le librerie utilizzate dal tuo
+progetto e di installarle/aggiornarle per te.
+
+# Installazione
+
+```sh
+# Se installi l'eseguibile in una cartella...
+curl -sS https://getcomposer.org/installer | php
+# ...dovrai utilizzare questo approccio, invocando Composer in questo modo:
+php composer.phar about
+
+# Se installi l'eseguibile nella directory ~/bin/composer
+# Nota: assicurati che ~/bin si trovi nella variabile di ambiente PATH
+curl -sS https://getcomposer.org/installer | php -- --install-dir=~/bin --filename=composer
+```
+
+Gli utenti Windows possono seguire le istruzioni per [installarlo su Windows](https://getcomposer.org/doc/00-intro.md#installation-windows).
+
+## Assicuriamoci che il tutto abbia funzionato correttamente
+
+```sh
+# Controlla la versione e la lista delle opzioni disponibili
+composer
+
+# Ottieni ulteriori informazioni riguardanti le opzioni
+composer help require
+
+# Controlla se Composer ha tutto il necessario per funzionare come si deve
+# e se è aggiornato correttamente all'ultima versione disponibile.
+composer diagnose
+composer diag # alias
+
+# Aggiorna Composer all'ultima versione disponibile
+composer self-update
+composer self # alias
+```
+
+# Cominciamo ad usare Composer
+
+Composer memorizza le dipendenze necessarie nel file `composer.json`.
+Puoi editare questo file manualmente, ma è meglio che lasci che Composer se ne
+occupi per te.
+
+```sh
+# Crea un nuovo progetto nella cartella attuale
+composer init
+# ti verranno chieste delle domande interrative riguardanti il tuo progetto.
+# Puoi evitare di rispondere almeno che tu non stia sviluppando altri progetti
+# che che possano dipendere da questo.
+
+# Se il file composer.json esiste già, scarichera' le dipendenze necessarie
+composer install
+
+# Scarica le dipendenze necessarie per l'ambiente di produzione
+composer install --no-dev
+
+# Aggiunge una dipendenza per l'ambiente di produzione
+composer require guzzlehttp/guzzle
+# automaticamente selezionera' l'ultima versione, la scarichera' e la aggiungera'
+# come dipendenza nell'apposito campo del file composer.json.
+
+composer require guzzlehttp/guzzle:6.0.*
+# scarichera' l'ultima versione disponibile corrispondente al pattern (es. 6.0.2)
+# e lo aggiungera' come dipendenza nell'apposito campo del file composer.json.
+
+composer require --dev phpunit/phpunit:~4.5.0
+# aggiungera' la dipendenza nell'ambiente di sviluppo utilizzando l'ultima versione
+# disponibile nel range >=4.5.0 e < 4.6.0.
+
+composer require-dev phpunit/phpunit:^4.5.0
+# aggiungera' la dipendenza nell'ambiente di sviluppo utilizzando l'ultima versione
+# disponibile nel range >=4.5.0 and < 5.0.
+
+# Per ulteriori dettagli riguardo le versioni, vedi [la documentazione di Composer sulle versioni](https://getcomposer.org/doc/articles/versions.md) per ulteriori dettagli
+
+# Per vedere quali pacchetti sono installabili e quali sono gia' stati installati
+composer show
+
+# Per vedere solo quali pacchetti sono gia' stati installati
+composer show --installed
+
+# Per trovare una dipendenza con 'mailgun' nel suo nome o nella descrizione.
+composer search mailgun
+```
+
+[Packagist.org](https://packagist.org/) è il repository principale per i pacchetti
+di Composer. Cerca qui pacchetti di terze-parti utili per il tuo progetto.
+
+## `composer.json` vs `composer.lock`
+
+Il file `composer.json` memorizza la versione che si preferisce per ogni dipendenza,
+insieme ad altre informazioni.
+
+Il file `composer.lock` memorizza quale versione è stata scaricata per ogni
+dipendenza. Non editare mai questo file.
+
+Se includi il file `composer.lock` nella tua repository git, ogni sviluppatore
+andra' a installare la versione attualmente utilizzata dal tuo progetto per
+ogni dipendenza. Anche quando una nuova versione è stata rilasciata, Composer
+andra' a installare la versione registrata nel file lock.
+
+```sh
+# Se vuoi aggiornare tutte le dipendenze all'ultima versione che corrisponde al pattern descritto
+composer update
+
+# Se vuoi scaricare l'ultima versione di una particolare dipendenza:
+composer update phpunit/phpunit
+
+# Se vuoi cambiare la versione di una una dipendenza, potresti dover rimuovere
+# quello attualmente selezionato, per poi richiedere quello corretto successivamente,
+# attraverso i seguenti comandi:
+composer remove --dev phpunit/phpunit
+composer require --dev phpunit/phpunit:^5.0
+
+```
+
+## Autoloader
+
+Composer crea una classe autoloader che puoi richiamare nella tua applicazione.
+Puoi creare instanze delle classi tramite il loro namespace.
+
+```php
+require __DIR__ . '/vendor/autoload.php';
+
+$mailgun = new Mailgun\Mailgun("key");
+```
+
+### PSR-4 Autoloader
+
+Puoi aggiungere i tuoi namespace all'autoloader.
+
+Nel file `composer.json`, aggiungi il campo "autoload":
+
+```json
+{
+ "autoload": {
+ "psr-4": {"Acme\\": "src/"}
+ }
+}
+```
+Questo dira' all'autoloader di controllare ogni risorsa che corrisponde al
+namespace `\Acme\` all'interno della cartella `src`.
+
+In alternativa puoi usare [PSR-0, una Classmap o una lista di file da includere](https://getcomposer.org/doc/04-schema.md#autoload).
+Inoltre e' possibile anche utilizzare `autoload-dev` dedicato all'ambiente di sviluppo.
+
+Quando aggiungi o modifichi una chiave, dovrai ricompilare l'autoload attraverso:
+
+```sh
+composer dump-autoload
+composer dump # alias
+
+# Ottimizza i pacchetti PSR0 e PSR4 per essere caricati anche con le classmap.
+# Sara' lento, ma migliorera' le performance in produzione.
+composer dump-autoload --optimize --no-dev
+```
+
+# La cache di Composer
+
+```sh
+# Composer utilizzera i pacchetti scaricati anche per i progetti futuri. Per evitare che accada:
+composer clear-cache
+```
+
+# Problemi?
+
+```sh
+composer diagnose
+composer self-update
+composer clear-cache
+```
+
+## Argomenti che non sono stati (ancora) discussi in questo tutorial
+
+* Creare e distribuire pacchetti personali su Packagist.org o altrove
+* Pre- e post- script hooks: eseguire operazioni quando vengono eseguiti degli eventi
+
+### References
+
+* [Composer - Dependency Manager for PHP](https://getcomposer.org/)
+* [Packagist.org](https://packagist.org/)
diff --git a/it-it/pyqt-it.html.markdown b/it-it/pyqt-it.html.markdown
index 7238dd7b..7b5a98c2 100644
--- a/it-it/pyqt-it.html.markdown
+++ b/it-it/pyqt-it.html.markdown
@@ -14,12 +14,12 @@ lang: it-it
Questo è un adattamento sull'introduzione di C ++ a QT di [Aleksey Kholovchuk] (https://github.com/vortexxx192
), alcuni degli esempi di codice dovrebbero avere la stessa funzionalità
-che avrebbero se fossero fatte usando pyqt!
+che avrebbero se fossero fatte usando pyqt!
```python
import sys
from PyQt4 import QtGui
-
+
def window():
# Crea un oggetto applicazione
app = QtGui.QApplication(sys.argv)
@@ -47,7 +47,7 @@ if __name__ == '__main__':
Per ottenere alcune delle funzionalità più avanzate in **pyqt**, dobbiamo iniziare a cercare di creare elementi aggiuntivi.
Qui mostriamo come creare una finestra popup di dialogo, utile per chiedere all'utente di confermare una decisione o fornire informazioni
-```Python
+```python
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
@@ -66,7 +66,7 @@ def window():
w.setWindowTitle("PyQt Dialog")
w.show()
sys.exit(app.exec_())
-
+
# Questa funzione dovrebbe creare una finestra di dialogo con un pulsante
# che aspetta di essere cliccato e quindi esce dal programma
def showdialog():
diff --git a/it-it/python-it.html.markdown b/it-it/python-it.html.markdown
index 794e7a70..de7bb0ed 100644
--- a/it-it/python-it.html.markdown
+++ b/it-it/python-it.html.markdown
@@ -1,98 +1,89 @@
---
-language: python
+language: Python
filename: learnpython-it.py
contributors:
- - ["Louie Dinh", "http://ldinh.ca"]
- - ["Amin Bandali", "http://aminbandali.com"]
+ - ["Louie Dinh", "http://pythonpracticeprojects.com"]
+ - ["Steven Basart", "http://github.com/xksteven"]
- ["Andre Polykanine", "https://github.com/Oire"]
+ - ["Zachary Ferguson", "http://github.com/zfergus2"]
- ["evuez", "http://github.com/evuez"]
+ - ["Rommel Martinez", "https://ebzzry.io"]
translators:
+ - ["Draio", "http://github.com/Draio/"]
- ["Ale46", "http://github.com/Ale46/"]
- ["Tommaso Pifferi", "http://github.com/neslinesli93/"]
-lang: it-it
+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]
+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.
-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/).
+Feedback sono altamente apprezzati! Potete contattarmi su [@louiedinh](http://twitter.com/louiedinh) oppure [at] [google's email service]
-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?
+Nota: Questo articolo è riferito a Python 3 in modo specifico. Se volete avete la necessità di utilizzare Python 2.7 potete consultarla [qui](https://learnxinyminutes.com/docs/it-it/python-it/)
```python
# I commenti su una sola linea iniziano con un cancelletto
+
""" Più stringhe possono essere scritte
usando tre ", e sono spesso usate
- come commenti
+ come documentazione
"""
####################################################
## 1. Tipi di dati primitivi ed Operatori
####################################################
-# Hai i numeri
+# Ci sono i numeri
3 # => 3
# La matematica è quello che vi aspettereste
-1 + 1 # => 2
-8 - 1 # => 7
+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
+35 / 5 # => 7.0
-# 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
+# Risultato della divisione intera troncata sia in positivo che in negativo
+5 // 3 # => 1
+5.0 // 3.0 # => 1.0 # works on floats too
+-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
+# Il risultato di una divisione è sempre un numero decimale (float)
+10.0 / 3 # => 3.3333333333333335
# Operazione Modulo
-7 % 3 # => 1
+7 % 3 # => 1
# Elevamento a potenza (x alla y-esima potenza)
-2**4 # => 16
+2**3 # => 8
# Forzare le precedenze con le parentesi
(1 + 3) * 2 # => 8
+# I valori booleani sono primitive del linguaggio (nota la maiuscola)
+True
+False
+
+# nega con not
+not True # => False
+not False # => True
+
# Operatori Booleani
# Nota "and" e "or" sono case-sensitive
-True and False #=> False
-False or True #=> True
+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
+# False è 0 e True è 1
+# Non confonderti tra bool(ints) e le operazioni bitwise and/or (&,|)
+0 and 2 # => 0
+-5 or 0 # => -5
+0 == False # => True
+2 == True # => False
+1 == True # => True
+-5 != False != True #=> True
# Uguaglianza è ==
1 == 1 # => True
@@ -112,37 +103,46 @@ not False # => True
1 < 2 < 3 # => True
2 < 3 < 2 # => False
+# ('is' vs. '==')
+# 'is' controlla se due variabili si riferiscono allo stesso oggetto
+# '==' controlla se gli oggetti puntati hanno lo stesso valore.
+a = [1, 2, 3, 4] # a punta ad una nuova lista [1, 2, 3, 4]
+b = a # b punta a ciò a cui punta a
+b is a # => True, a e b puntano allo stesso oggeto
+b == a # => True, gli oggetti di a e b sono uguali
+b = [1, 2, 3, 4] # b punta ad una nuova lista [1, 2, 3, 4]
+b is a # => False, a e b non puntano allo stesso oggetto
+b == a # => True, gli oggetti di a e b sono uguali
+
# 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"
+# Anche le stringhe possono essere sommate! Ma cerca di non farlo.
+"Hello " + "world!" # => "Hello world!"
+# Le stringhe (ma non le variabili contenenti stringhe) possono essere
+# sommate anche senza '+'
+"Hello " "world!" # => "Hello world!"
# Una stringa può essere considerata come una lista di caratteri
"Questa è una stringa"[0] # => 'Q'
-# Per sapere la lunghezza di una stringa
+# Puoi conoscere 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)
+# .format può essere usato per formattare le stringhe, in questo modo:
+"{} possono essere {}".format("Le stringhe", "interpolate") # => "Le stringhe possono essere interpolate"
+
+# Puoi ripetere gli argomenti di formattazione per risparmiare un po' di codice
+"{0} be nimble, {0} be quick, {0} jump over the {1}".format("Jack", "candle stick")
+# => "Jack be nimble, Jack be quick, Jack jump over the candle stick"
-# 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")
+# Puoi usare dei nomi se non vuoi contare gli argomenti
+"{nome} vuole mangiare {cibo}".format(nome="Bob", cibo="le lasagne") # => "Bob vuole mangiare le lasagne"
+
+# Se il tuo codice Python 3 necessita di eseguire codice Python 2.x puoi ancora
+# utilizzare il vecchio stile di formattazione:
+"%s possono essere %s nel %s modo" % ("Le stringhe", "interpolate", "vecchio") # => "Le stringhe possono essere interpolate nel vecchio modo"
# None è un oggetto
None # => None
@@ -150,57 +150,54 @@ 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
+None is None # => True
+# None, 0, e stringhe/liste/dizionari/tuple vuoti vengono considerati
+# falsi (False). Tutti gli altri valori sono considerati veri (True).
+bool(0) # => False
+bool("") # => False
+bool([]) # => False
+bool({}) # => False
+bool(()) # => False
####################################################
## 2. Variabili e Collections
####################################################
-# Python ha una funzione di stampa
-print "Sono Python. Piacere di conoscerti!" # => Sono Python. Piacere di conoscerti!
+# Python ha una funzione per scrivere (sul tuo schermo)
+print("Sono Python. Piacere di conoscerti!") # => Sono Python. Piacere di conoscerti!
+
+# Di default la funzione print() scrive e va a capo aggiungendo un carattere
+# newline alla fine della stringa. È possibile utilizzare l'argomento opzionale
+# end per cambiare quest'ultimo carattere aggiunto.
+print("Hello, World", end="!") # => Hello, World!
# 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()
+variabile_stringa_input = input("Inserisci del testo: ") # Restituisce i dati letti come stringa
+# Nota: Nelle precedenti vesioni di Python, il metodo input()
+# era chiamato raw_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
+# Come convenzione, per i nomi delle variabili, si utilizzano i caratteri
+# minuscoli separati, se necessario, da underscore
+some_var = 5
+some_var # => 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
+# Dai un'occhiata al Control Flow per imparare di più su come gestire
+# le eccezioni.
+some_unknown_var # Genera un errore di nome
# if può essere usato come un'espressione
-# E' l'equivalente dell'operatore ternario in C
+# È l'equivalente dell'operatore ternario in C
"yahoo!" if 3 > 2 else 2 # => "yahoo!"
-# Liste immagazzinano sequenze
+# Le liste immagazzinano sequenze
li = []
# Puoi partire con una lista pre-riempita
-altra_li = [4, 5, 6]
+other_li = [4, 5, 6]
-# Aggiungi cose alla fine di una lista con append
+# Aggiungere 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]
@@ -212,14 +209,10 @@ 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
+# Guardare al di fuori dei limiti genera un IndexError
li[4] # Genera IndexError
# Puoi guardare gli intervalli con la sintassi slice (a fetta).
@@ -236,14 +229,11 @@ li[::-1] # => [3, 4, 2, 1]
# Usa combinazioni per fare slices avanzate
# li[inizio:fine:passo]
+# Crea una copia (one layer deep copy) usando la sintassi slices
+li2 = li[:] # => li2 = [1, 2, 4, 3] ma (li2 is li) risulterà falso.
+
# 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]
@@ -252,10 +242,17 @@ 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
+ 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
+# Puoi sommare le liste
+# Nota: i valori per li e per other_li non vengono modificati.
+li + other_li # => [1, 2, 3, 4, 5, 6]
+
+# Concatena le liste con "extend()"
+li.extend(other_li) # Adesso li è [1, 2, 3, 4, 5, 6]
+
# Controlla l'esistenza di un valore in una lista con "in"
1 in li # => True
@@ -263,93 +260,112 @@ li.index(7) # Emette un ValueError, poichè 7 non è contenuto nella lista
len(li) # => 6
-# Tuple sono come le liste ma immutabili.
+# Le tuple sono come le liste ma immutabili.
tup = (1, 2, 3)
-tup[0] # => 1
+tup[0] # => 1
tup[0] = 3 # Genera un TypeError
+# Note that a tuple of length one has to have a comma after the last element but
+# tuples of other lengths, even zero, do not.
+type((1)) # => <class 'int'>
+type((1,)) # => <class 'tuple'>
+type(()) # => <class 'tuple'>
+
# 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
+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
+a, b, c = (1, 2, 3) # a è ora 1, b è ora 2 e 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
-
+e, d = d, e # d è ora 5 ed e è ora 4
-# Dizionari immagazzinano mappature
-empty_dict = {}
-# Questo è un dizionario pre-riempito
+# I dizionari memorizzano insiemi di dati indicizzati da nomi arbitrari (chiavi)
+empty_dict= {}
+# Questo è un dizionario pre-caricato
filled_dict = {"uno": 1, "due": 2, "tre": 3}
-# Accedi ai valori con []
+# Nota: le chiavi dei dizionari devono essere di tipo immutabile. Questo per
+# assicurare che le chiavi possano essere convertite in calori hash costanti
+# per un risposta più veloce.
+invalid_dict = {[1,2,3]: "123"} # => Emette un TypeError: unhashable type: 'list'
+valid_dict = {(1,2,3):[1,2,3]} # I valori, invece, possono essere di qualunque tipo
+
+# Accedi ai valori indicando la chiave tra []
filled_dict["uno"] # => 1
-# Ottieni tutte le chiavi come una lista con "keys()"
-filled_dict.keys() # => ["tre", "due", "uno"]
+# Puoi ottenere tutte le chiavi di un dizionario con "keys()"
+# (come oggetto iterabile). Per averle in formato lista è necessario
+# utilizzare list().
# Nota - Nei dizionari l'ordine delle chiavi non è garantito.
# Il tuo risultato potrebbe non essere uguale a questo.
+list(filled_dict.keys()) # => ["tre", "due", "uno"]
-# 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)]
+# Puoi ottenere tutti i valori di un dizionario con "values()"
+# (come oggetto iterabile).
+# Anche in questo caso, er averle in formato lista, è necessario utilizzare list()
+# Anche in questo caso, come per le chiavi, l'ordine non è garantito
+list(filled_dict.values()) # => [3, 2, 1]
# Controlla l'esistenza delle chiavi in un dizionario con "in"
"uno" in filled_dict # => True
-1 in filled_dict # => False
+1 in filled_dict # => False
-# Cercando una chiave non esistente è un KeyError
+# Cercando una chiave non esistente genera un KeyError
filled_dict["quattro"] # KeyError
# Usa il metodo "get()" per evitare KeyError
-filled_dict.get("uno") # => 1
-filled_dict.get("quattro") # => None
+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
+# "setdefault()" inserisce un valore per una chiave in un dizionario
+# solo se la chiave data non è già presente
+filled_dict.setdefault("cinque", 5) # filled_dict["cinque"] viene impostato a 5
+filled_dict.setdefault("cinque", 6) # filled_dict["cinque"] rimane 5
+# Aggiungere una coppia chiave->valore a un dizionario
+filled_dict.update({"quattro":4}) # => {"uno": 1, "due": 2, "tre": 3, "quattro": 4}
+filled_dict["quattro"] = 4 # un altro modo pe aggiungere a un dizionario
-# 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])
+# Rimuovi una chiave da un dizionario con del
+del filled_dict["uno"] # Rimuove la chiave "uno" dal dizionario
-# 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 3.5 puoi anche usare ulteriori opzioni di spacchettamento
+{'a': 1, **{'b': 2}} # => {'a': 1, 'b': 2}
+{'a': 1, **{'a': 2}} # => {'a': 2}
-# Da Python 2.7, {} può essere usato per dichiarare un set
-filled_set = {1, 2, 2, 3, 4} # => {1, 2, 3, 4}
+# I set sono come le liste ma non possono contenere doppioni
+empty_set = set()
+# Inizializza un "set()" con un dei valori. Sì, sembra un dizionario.
+some_set = {1, 1, 2, 2, 3, 4} # set_nuovo è {1, 2, 3, 4}
+
+# Come le chiavi di un dizionario, gli elementi di un set devono essere
+# di tipo immutabile
+invalid_set = {[1], 1} # => Genera un "TypeError: unhashable type: 'list'""
+valid_set = {(1,), 1}
-# Aggiungere elementi ad un set
-filled_set.add(5) # filled_set è ora {1, 2, 3, 4, 5}
+# Aggiungere uno o più elementi ad un set
+some_set.add(5) # some_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}
+some_set & other_set # => {3, 4, 5}
# Fai unioni su set con |
-filled_set | other_set # => {1, 2, 3, 4, 5, 6}
+some_set | other_set # => {1, 2, 3, 4, 5, 6}
# Fai differenze su set con -
-{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
+{1, 2, 3, 4} - {2, 3, 5} # => {1, 4}
# Effettua la differenza simmetrica con ^
{1, 2, 3, 4} ^ {2, 3, 5} # => {1, 4, 5}
@@ -361,65 +377,77 @@ filled_set | other_set # => {1, 2, 3, 4, 5, 6}
{1, 2} <= {1, 2, 3} # => True
# Controlla l'esistenza in un set con in
-2 in filled_set # => True
-10 in filled_set # => False
+2 in some_set # => True
+10 in some_set # => False
+
####################################################
-## 3. Control Flow
+## 3. Control Flow e oggetti Iterabili
####################################################
-# Dichiariamo una variabile
+# Dichiariamo una variabile
some_var = 5
# Questo è un controllo if. L'indentazione è molto importante in python!
-# stampa "some_var è più piccola di 10"
+# Come convenzione si utilizzano quattro spazi, non la tabulazione.
+# Il seguente codice stampa "some_var è minore 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."
-
+ print("some_var è maggiore di 10")
+elif some_var < 10: # La clausolo elif è opzionale
+ print("some_var è minore di 10")
+else: # Anche else è opzionale
+ print("some_var è 10.")
"""
-I cicli for iterano sulle liste
-stampa:
+I cicli for iterano sulle liste, cioè ripetono un codice per ogni elemento
+di una lista.
+Il seguente codice scriverà:
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)
+ # Puoi usare format() per interpolare le stringhe formattate.
+ print("{} è un mammifero".format(animale))
"""
-"range(numero)" restituisce una lista di numeri
-da zero al numero dato
-stampa:
+"range(numero)" restituisce una lista di numeri da zero al numero dato
+Il seguente codice scriverà:
0
1
2
3
"""
for i in range(4):
- print i
+ print(i)
"""
-"range(lower, upper)" restituisce una lista di numeri
-dal più piccolo (lower) al più grande (upper)
-stampa:
+"range(lower, upper)" restituisce una lista di numeri dal più piccolo (lower)
+al più grande (upper).
+Il seguente codice scriverà:
4
5
6
7
"""
for i in range(4, 8):
- print i
+ print(i)
"""
+"range(lower, upper, step)" rrestituisce una lista di numeri dal più piccolo
+(lower) al più grande (upper), incrementando del valore step.
+Se step non è indicato, avrà come valore di default 1.
+Il seguente codice scriverà:
+ 4
+ 6
+"""
+for i in range(4, 8, 2):
+ print(i)
+"""
+
I cicli while vengono eseguiti finchè una condizione viene a mancare
-stampa:
+Il seguente codice scriverà:
0
1
2
@@ -427,28 +455,62 @@ stampa:
"""
x = 0
while x < 4:
- print x
+ 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:
+# Gestione delle eccezioni con un blocco try/except
try:
# Usa "raise" per generare un errore
- raise IndexError("Questo è un errore di indice")
+ raise IndexError("Questo è un IndexError")
except IndexError as e:
- pass # Pass è solo una non-operazione. Solitamente vorrai fare un recupero.
+ pass # Pass è solo una non-operazione. Solitamente vorrai rimediare all'errore.
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
+else: # Clausola opzionale al blocco try/except. Deve essere dopo 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"
+ print("Possiamo liberare risorse qui")
-# Invece di try/finally per liberare risorse puoi usare il metodo with
+# Se ti serve solo un try/finally, per liberare risorse, puoi usare il metodo with
with open("myfile.txt") as f:
for line in f:
- print line
+ print(line)
+
+# In Python qualunque oggetto in grado di essere trattato come una
+# sequenza è definito un oggetto Iterable (itarabile).
+# L'oggetto restituito da una funzione range è un iterabile.
+
+filled_dict = {"uno": 1, "due": 2, "tre": 3}
+our_iterable = filled_dict.keys()
+print(our_iterable) # => dict_keys(['uno', 'due', 'tre']).
+# Questo è un oggetto che implementa la nostra interfaccia Iterable.
+
+# È possibile utilizzarlo con i loop:
+for i in our_iterable:
+ print(i) # Scrive uno, due, tre
+
+# Tuttavia non possiamo recuperarne i valori tramite indice.
+our_iterable[1] # Genera un TypeError
+
+# Un oggetto iterabile è in grado di generare un iteratore
+our_iterator = iter(our_iterable)
+
+# L'iteratore è un oggetto che ricorda il suo stato mentro lo si "attraversa"
+# Possiamo accedere al successivo elemento con "next()".
+next(our_iterator) # => "uno"
+
+# Mantiene il suo stato mentro eseguiamo l'iterazione
+next(our_iterator) # => "due"
+next(our_iterator) # => "tre"
+
+# Dopo che un iteratore ha restituito tutti i suoi dati, genera
+# un'eccezione StopIteration
+next(our_iterator) # Raises StopIteration
+
+# Puoi prendere tutti gli elementi di un iteratore utilizzando list().
+list(filled_dict.keys()) # => Returns ["one", "two", "three"]
+
+
####################################################
## 4. Funzioni
@@ -456,23 +518,20 @@ with open("myfile.txt") as f:
# 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
+ print("x è {} e y è {}".format(x, y)) // Scrive i valori formattati in una stringa
+ return x + y # Restituisce la somma dei valori con il metodo return
# Chiamare funzioni con parametri
-aggiungi(5, 6) # => stampa "x è 5 e y è 6" e restituisce 11
+aggiungi(5, 6) # => scrive "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.
+aggiungi(y=6, x=5) # In questo modo non è necessario rispettare l'ordine degli argomenti
-
-# Puoi definire funzioni che accettano un numero variabile di argomenti posizionali
-# che verranno interpretati come tuple usando il *
+# Puoi definire funzioni che accettano un numero non definito di argomenti
def varargs(*args):
return args
-varargs(1, 2, 3) # => (1, 2, 3)
-
+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 **
@@ -485,8 +544,8 @@ 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
+ print(args)
+ print(kwargs)
"""
all_the_args(1, 2, a=3, b=4) stampa:
(1, 2)
@@ -494,38 +553,44 @@ all_the_args(1, 2, a=3, b=4) stampa:
"""
# Quando chiami funzioni, puoi fare l'opposto di args/kwargs!
-# Usa * per sviluppare gli argomenti posizionale ed usa ** per espandere gli argomenti parola chiave
+# 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
+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)
+
+
+# Restituire valori multipli (with tuple assignments)
+def swap(x, y):
+ return y, x # Restituisce valori multipli come tupla senza parentesi
+ # (Nota: le parentesi sono state escluse ma possono essere messe)
+
+x = 1
+y = 2
+x, y = swap(x, y) # => x = 2, y = 1
+# (x, y) = swap(x,y) # Le parentesi sono state escluse ma possono essere incluse.
+
+# Funzioni - Visibilità delle variabili (variable scope)
x = 5
def set_x(num):
- # La variabile locale x non è uguale alla variabile globale x
- x = num # => 43
- print x # => 43
+ # La variabile locale x non è la 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
+ 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
+
+# Python ha "first class functions"
def create_adder(x):
def adder(y):
return x + y
@@ -535,204 +600,381 @@ 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
+(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]
+# È possibile creare "mappe" e "filtri"
+list(map(add_10, [1, 2, 3])) # => [11, 12, 13]
+list(map(max, [1, 2, 3], [4, 2, 1])) # => [4, 2, 3]
-filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7]
+list(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]
+# Possiamo usare le "list comprehensions" per mappe e filtri
+# Le "list comprehensions" memorizzano l'output come una lista che può essere
+# di per sé una lista annidata
+[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 for x in 'abcddeef' if x not 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
+## 5. Modules
+####################################################
+
+# Puoi importare moduli
+import math
+print(math.sqrt(16)) # => 4.0
+
+# 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
+
+
+# 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
+# sono definiti in 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
+
+# Se hai uno script Python chiamato math.py nella stessa
+# cartella del tua script, Python caricherà quello al posto del
+# comune modulo math.
+# Questo accade perché la cartella locale ha la priorità
+# sulle librerie built-in di Python.
+
+
+####################################################
+## 6. Classes
####################################################
-# Usiamo una sottoclasse da un oggetto per avere una classe.
-class Human(object):
+# Usiamo l'istruzione "class" per creare una classe
+class Human:
- # Un attributo della classe. E' condiviso da tutte le istanze delle classe
+ # Un attributo della classe. E' condiviso tra 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.
+ # Si noti che i doppi underscore iniziali e finali denotano gli oggetti o
+ # attributi utilizzati da Python ma che vivono nel namespace controllato
+ # dall'utente
+ # Metodi, oggetti o attributi come: __init__, __str__, __repr__, etc. sono
+ # chiamati metodi speciali (o talvolta chiamati "dunder methods").
+ # Non dovresti inventare tali nomi da solo.
+
def __init__(self, name):
# Assegna l'argomento all'attributo name dell'istanza
self.name = name
# Inizializza una proprietà
- self.age = 0
+ 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)
+ print("{name}: {message}".format(name=self.name, message=msg))
+
+ # Un altro metodo dell'istanza
+ def sing(self):
+ return 'yo... yo... microphone check... one two... one two...'
# Un metodo della classe è condiviso fra tutte le istanze
- # Sono chiamate con la classe chiamante come primo argomento
+ # Sono chiamati 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
+ # Un metodo statico è chiamato senza classe o 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
+ # Una property è come un metodo getter.
+ # Trasforma il metodo age() in un attributo in sola lettura, che ha
+ # lo stesso nome
+ # In Python non c'è bisogno di scrivere futili getter e setter.
@property
def age(self):
return self._age
- # Questo metodo permette di modificare la proprietà
+ # Questo metodo permette di modificare una property
@age.setter
def age(self, age):
self._age = age
- # Questo metodo permette di cancellare la proprietà
+ # Questo metodo permette di cancellare una property
@age.deleter
def age(self):
del self._age
-# Instanziare una classe
-i = Human(name="Ian")
-print i.say("hi") # stampa "Ian: hi"
+# Quando l'interprete Python legge un sorgente esegue tutto il suo codice.
+# Questo controllo su __name__ assicura che questo blocco di codice venga
+# eseguito solo quando questo modulo è il programma principale.
+
+if __name__ == '__main__':
+ # Crea un'istanza della classe
+ i = Human(name="Ian")
+ i.say("hi") # "Ian: hi"
+ j = Human("Joel")
+ j.say("hello") # "Joel: hello"
+ # i e j sono istanze del tipo Human, o in altre parole sono oggetti Human
+
+ # Chiama un metodo della classe
+ i.say(i.get_species()) # "Ian: H. sapiens"
+ # Cambia l'attributo condiviso
+ Human.species = "H. neanderthalensis"
+ i.say(i.get_species()) # => "Ian: H. neanderthalensis"
+ j.say(j.get_species()) # => "Joel: H. neanderthalensis"
+
+ # Chiama un metodo statico
+ print(Human.grunt()) # => "*grunt*"
+
+ # Non è possibile chiamare il metodo statico con l'istanza dell'oggetto
+ # poiché i.grunt() metterà automaticamente "self" (l'oggetto i)
+ # come argomento
+ print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given
+
+ # Aggiorna la property (age) di questa istanza
+ i.age = 42
+ # Leggi la property
+ i.say(i.age) # => "Ian: 42"
+ j.say(j.age) # => "Joel: 0"
+ # Cancella la property
+ del i.age
+ i.age # => questo genererà un AttributeError
-j = Human("Joel")
-print j.say("hello") # stampa "Joel: hello"
-# Chiamare metodi della classe
-i.get_species() # => "H. sapiens"
+####################################################
+## 6.1 Ereditarietà (Inheritance)
+####################################################
-# Cambiare l'attributo condiviso
-Human.species = "H. neanderthalensis"
-i.get_species() # => "H. neanderthalensis"
-j.get_species() # => "H. neanderthalensis"
+# L'ereditarietà consente di definire nuove classi figlio che ereditano metodi e
+# variabili dalla loro classe genitore.
-# Chiamare il metodo condiviso
-Human.grunt() # => "*grunt*"
+# Usando la classe Human definita sopra come classe base o genitore, possiamo
+# definire una classe figlia, Superhero, che erediterà le variabili di classe
+# come "species", "name" e "age", così come i metodi, come "sing" e "grunt",
+# dalla classe Human, ma potrà anche avere le sue proprietà uniche.
-# Aggiorna la proprietà
-i.age = 42
+# Per importare le funzioni da altri file usa il seguente formato
+# from "nomefile-senza-estensione" import "funzione-o-classe"
-# Ritorna il valore della proprietà
-i.age # => 42
+from human import Human
-# Cancella la proprietà
-del i.age
-i.age # => Emette un AttributeError
+# Specificare le classi genitore come parametri della definizione della classe
+class Superhero(Human):
+ # Se la classe figlio deve ereditare tutte le definizioni del genitore
+ # senza alcuna modifica, puoi semplicemente usare la parola chiave "pass"
+ # (e nient'altro)
-####################################################
-## 6. Moduli
-####################################################
+ #Le classi figlio possono sovrascrivere gli attributi dei loro genitori
+ species = 'Superhuman'
-# Puoi importare moduli
-import math
-print math.sqrt(16) # => 4.0
+ # Le classi figlie ereditano automaticamente il costruttore della classe
+ # genitore, inclusi i suoi argomenti, ma possono anche definire ulteriori
+ # argomenti o definizioni e sovrascrivere i suoi metodi (compreso il
+ # costruttore della classe).
+ # Questo costruttore eredita l'argomento "nome" dalla classe "Human" e
+ # aggiunge gli argomenti "superpowers" e "movie":
-# Puoi ottenere specifiche funzione da un modulo
-from math import ceil, floor
-print ceil(3.7) # => 4.0
-print floor(3.7) # => 3.0
+ def __init__(self, name, movie=False,
+ superpowers=["super strength", "bulletproofing"]):
-# Puoi importare tutte le funzioni da un modulo
-# Attenzione: questo non è raccomandato
-from math import *
+ # aggiungi ulteriori attributi della classe
+ self.fictional = True
+ self.movie = movie
+ self.superpowers = superpowers
-# 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
+ # La funzione "super" ti consente di accedere ai metodi della classe
+ # genitore che sono stati sovrascritti dalla classe figlia,
+ # in questo caso il metodo __init__.
+ # Il seguente codice esegue il costruttore della classe genitore:
+ super().__init__(name)
-# 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.
+ # Sovrascrivere il metodo "sing"
+ def sing(self):
+ return 'Dun, dun, DUN!'
-# Potete scoprire quali funzioni e attributi
-# definiscono un modulo
-import math
-dir(math)
+ # Aggiungi un ulteriore metodo dell'istanza
+ def boast(self):
+ for power in self.superpowers:
+ print("I wield the power of {pow}!".format(pow=power))
-# 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
+if __name__ == '__main__':
+ sup = Superhero(name="Tick")
+
+ # Controllo del tipo di istanza
+ if isinstance(sup, Human):
+ print('I am human')
+ if type(sup) is Superhero:
+ print('I am a superhero')
+
+ # Ottieni il "Method Resolution search Order" usato sia da getattr ()
+ # che da super (). Questo attributo è dinamico e può essere aggiornato
+ print(Superhero.__mro__) # => (<class '__main__.Superhero'>,
+ # => <class 'human.Human'>, <class 'object'>)
+
+ # Esegui il metodo principale ma utilizza il proprio attributo di classe
+ print(sup.get_species()) # => Superhuman
+
+ # Esegui un metodo che è stato sovrascritto
+ print(sup.sing()) # => Dun, dun, DUN!
+
+ # Esegui un metodo di Human
+ sup.say('Spoon') # => Tick: Spoon
+
+ # Esegui un metodo che esiste solo in Superhero
+ sup.boast() # => I wield the power of super strength!
+ # => I wield the power of bulletproofing!
+
+ # Attributo di classe ereditato
+ sup.age = 31
+ print(sup.age) # => 31
+
+ # Attributo che esiste solo in Superhero
+ print('Am I Oscar eligible? ' + str(sup.movie))
####################################################
-## 7. Avanzate
+## 6.2 Ereditarietà multipla
####################################################
-# Generatori
-# Un generatore appunto "genera" valori solo quando vengono richiesti,
-# invece di memorizzarli tutti subito fin dall'inizio
+# Un'altra definizione di classe
+# bat.py
+class Bat:
-# 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)
+ species = 'Baty'
-# 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
+ def __init__(self, can_fly=True):
+ self.fly = can_fly
+
+ # Questa classe ha anche un metodo "say"
+ def say(self, msg):
+ msg = '... ... ...'
+ return msg
+
+ # E anche un suo metodo personale
+ def sonar(self):
+ return '))) ... ((('
+
+if __name__ == '__main__':
+ b = Bat()
+ print(b.say('hello'))
+ print(b.fly)
+
+# Definizione di classe che eredita da Superhero e Bat
+# superhero.py
+from superhero import Superhero
+from bat import Bat
+
+# Definisci Batman come classe figlia che eredita sia da Superhero che da Bat
+class Batman(Superhero, Bat):
+
+ def __init__(self, *args, **kwargs):
+ # In genere per ereditare gli attributi devi chiamare super:
+ # super(Batman, self).__init__(*args, **kwargs)
+ # Ma qui abbiamo a che fare con l'ereditarietà multipla, e super()
+ # funziona solo con la successiva classe nell'elenco MRO.
+ # Quindi, invece, chiamiamo esplicitamente __init__ per tutti gli
+ # antenati. L'uso di *args e **kwargs consente di passare in modo
+ # pulito gli argomenti, con ciascun genitore che "sbuccia un
+ # livello della cipolla".
+ Superhero.__init__(self, 'anonymous', movie=True,
+ superpowers=['Wealthy'], *args, **kwargs)
+ Bat.__init__(self, *args, can_fly=False, **kwargs)
+ # sovrascrivere il valore per l'attributo name
+ self.name = 'Sad Affleck'
-# Invece, potremmo usare un generatore per "generare" il valore raddoppiato non
-# appena viene richiesto
-def double_numbers_generator(iterable):
+ def sing(self):
+ return 'nan nan nan nan nan batman!'
+
+
+if __name__ == '__main__':
+ sup = Batman()
+
+ # Ottieni il "Method Resolution search Order" utilizzato da getattr() e super().
+ # Questo attributo è dinamico e può essere aggiornato
+ print(Batman.__mro__) # => (<class '__main__.Batman'>,
+ # => <class 'superhero.Superhero'>,
+ # => <class 'human.Human'>,
+ # => <class 'bat.Bat'>, <class 'object'>)
+
+ # Esegui il metodo del genitore ma utilizza il proprio attributo di classe
+ print(sup.get_species()) # => Superhuman
+
+ # Esegui un metodo che è stato sovrascritto
+ print(sup.sing()) # => nan nan nan nan nan batman!
+
+ # Esegui un metodo da Human, perché l'ordine di ereditarietà è importante
+ sup.say('I agree') # => Sad Affleck: I agree
+
+ # Esegui un metodo che esiste solo nel 2o antenato
+ print(sup.sonar()) # => ))) ... (((
+
+ # Attributo di classe ereditato
+ sup.age = 100
+ print(sup.age) # => 100
+
+ # Attributo ereditato dal secondo antenato il cui valore predefinito
+ # è stato ignorato.
+ print('Can I fly? ' + str(sup.fly)) # => Can I fly? False
+
+
+
+####################################################
+## 7. Advanced
+####################################################
+
+# I generatori ti aiutano a creare codice pigro (lazy code).
+# Codice che darà un risultato solo quando sarà "valutato"
+def double_numbers(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:
+# I generatori sono efficienti in termini di memoria perché caricano
+# solo i dati necessari per elaborare il valore successivo nell'iterabile.
+# Ciò consente loro di eseguire operazioni su intervalli di valori
+# altrimenti proibitivi.
+# NOTA: `range` sostituisce` xrange` in Python 3.
+for i in double_numbers(range(1, 900000000)): # `range` is a generator.
+ print(i)
+ if i >= 30:
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.
+# Proprio come è possibile creare una "list comprehension", è possibile
+# creare anche delle "generator comprehensions".
values = (-x for x in [1,2,3,4,5])
for x in values:
- print(x) # stampa -1 -2 -3 -4 -5
+ print(x) # prints -1 -2 -3 -4 -5 to console/terminal
-# Puoi anche fare il cast diretto di una comprensione di generatori ad una lista.
+# Puoi anche trasmettere una "generator comprehensions" direttamente
+# ad un elenco.
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
+# In questo esempio "beg" avvolge/wrappa "say".
+# Se say_please è True, cambierà il messaggio restituito.
from functools import wraps
def beg(target_function):
@@ -752,8 +994,8 @@ def say(say_please=False):
return msg, say_please
-print say() # Puoi comprarmi una birra?
-print say(say_please=True) # Puoi comprarmi una birra? Per favore! Sono povero :(
+print(say()) # Puoi comprarmi una birra?
+print(say(say_please=True)) # Puoi comprarmi una birra? Per favore! Sono povero :(
```
## Pronto per qualcosa di più?
@@ -761,18 +1003,14 @@ print say(say_please=True) # Puoi comprarmi una birra? Per favore! Sono povero
### 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/)
+* [Ideas for Python Projects](http://pythonpracticeprojects.com)
+* [The Official Docs](http://docs.python.org/3/)
* [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)
+* [Python Course](http://www.python-course.eu/index.php)
* [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)
+* [A curated list of awesome Python frameworks, libraries and software](https://github.com/vinta/awesome-python)
+* [30 Python Language Features and Tricks You May Not Know About](http://sahandsaba.com/thirty-python-language-features-and-tricks-you-may-not-know.html)
+* [Official Style Guide for Python](https://www.python.org/dev/peps/pep-0008/)
+* [Python 3 Computer Science Circles](http://cscircles.cemc.uwaterloo.ca/)
+* [Dive Into Python 3](http://www.diveintopython3.net/index.html)
+* [A Crash Course in Python for Scientists](http://nbviewer.jupyter.org/gist/anonymous/5924718)
diff --git a/it-it/python3-it.html.markdown b/it-it/python3-it.html.markdown
deleted file mode 100644
index 04f78cff..00000000
--- a/it-it/python3-it.html.markdown
+++ /dev/null
@@ -1,1016 +0,0 @@
----
-language: python3
-filename: learnpython3-it.py
-contributors:
- - ["Louie Dinh", "http://pythonpracticeprojects.com"]
- - ["Steven Basart", "http://github.com/xksteven"]
- - ["Andre Polykanine", "https://github.com/Oire"]
- - ["Zachary Ferguson", "http://github.com/zfergus2"]
- - ["evuez", "http://github.com/evuez"]
- - ["Rommel Martinez", "https://ebzzry.io"]
-translators:
- - ["Draio", "http://github.com/Draio/"]
- - ["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 3 in modo specifico. Se volete avete la necessità di utilizzare Python 2.7 potete consultarla [qui](https://learnxinyminutes.com/docs/it-it/python-it/)
-
-```python
-
-# I commenti su una sola linea iniziano con un cancelletto
-
-
-""" Più stringhe possono essere scritte
- usando tre ", e sono spesso usate
- come documentazione
-"""
-
-####################################################
-## 1. Tipi di dati primitivi ed Operatori
-####################################################
-
-# Ci sono i numeri
-3 # => 3
-
-# La matematica è quello che vi aspettereste
-1 + 1 # => 2
-8 - 1 # => 7
-10 * 2 # => 20
-35 / 5 # => 7.0
-
-# Risultato della divisione intera troncata sia in positivo che in negativo
-5 // 3 # => 1
-5.0 // 3.0 # => 1.0 # works on floats too
--5 // 3 # => -2
--5.0 // 3.0 # => -2.0
-
-# Il risultato di una divisione è sempre un numero decimale (float)
-10.0 / 3 # => 3.3333333333333335
-
-# Operazione Modulo
-7 % 3 # => 1
-
-# Elevamento a potenza (x alla y-esima potenza)
-2**3 # => 8
-
-# Forzare le precedenze con le parentesi
-(1 + 3) * 2 # => 8
-
-# I valori booleani sono primitive del linguaggio (nota la maiuscola)
-True
-False
-
-# nega con not
-not True # => False
-not False # => True
-
-# 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
-# False è 0 e True è 1
-# Non confonderti tra bool(ints) e le operazioni bitwise and/or (&,|)
-0 and 2 # => 0
--5 or 0 # => -5
-0 == False # => True
-2 == True # => False
-1 == True # => True
--5 != False != True #=> 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
-
-# ('is' vs. '==')
-# 'is' controlla se due variabili si riferiscono allo stesso oggetto
-# '==' controlla se gli oggetti puntati hanno lo stesso valore.
-a = [1, 2, 3, 4] # a punta ad una nuova lista [1, 2, 3, 4]
-b = a # b punta a ciò a cui punta a
-b is a # => True, a e b puntano allo stesso oggeto
-b == a # => True, gli oggetti di a e b sono uguali
-b = [1, 2, 3, 4] # b punta ad una nuova lista [1, 2, 3, 4]
-b is a # => False, a e b non puntano allo stesso oggetto
-b == a # => True, gli oggetti di a e b sono uguali
-
-# Le stringhe sono create con " o '
-"Questa è una stringa."
-'Anche questa è una stringa.'
-
-# Anche le stringhe possono essere sommate! Ma cerca di non farlo.
-"Hello " + "world!" # => "Hello world!"
-# Le stringhe (ma non le variabili contenenti stringhe) possono essere
-# sommate anche senza '+'
-"Hello " "world!" # => "Hello world!"
-
-# Una stringa può essere considerata come una lista di caratteri
-"Questa è una stringa"[0] # => 'Q'
-
-# Puoi conoscere la lunghezza di una stringa
-len("Questa è una stringa") # => 20
-
-# .format può essere usato per formattare le stringhe, in questo modo:
-"{} possono essere {}".format("Le stringhe", "interpolate") # => "Le stringhe possono essere interpolate"
-
-# Puoi ripetere gli argomenti di formattazione per risparmiare un po' di codice
-"{0} be nimble, {0} be quick, {0} jump over the {1}".format("Jack", "candle stick")
-# => "Jack be nimble, Jack be quick, Jack jump over the candle stick"
-
-# Puoi usare dei nomi se non vuoi contare gli argomenti
-"{nome} vuole mangiare {cibo}".format(nome="Bob", cibo="le lasagne") # => "Bob vuole mangiare le lasagne"
-
-# Se il tuo codice Python 3 necessita di eseguire codice Python 2.x puoi ancora
-# utilizzare il vecchio stile di formattazione:
-"%s possono essere %s nel %s modo" % ("Le stringhe", "interpolate", "vecchio") # => "Le stringhe possono essere interpolate nel vecchio modo"
-
-# 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
-
-# None, 0, e stringhe/liste/dizionari/tuple vuoti vengono considerati
-# falsi (False). Tutti gli altri valori sono considerati veri (True).
-bool(0) # => False
-bool("") # => False
-bool([]) # => False
-bool({}) # => False
-bool(()) # => False
-
-####################################################
-## 2. Variabili e Collections
-####################################################
-
-# Python ha una funzione per scrivere (sul tuo schermo)
-print("Sono Python. Piacere di conoscerti!") # => Sono Python. Piacere di conoscerti!
-
-# Di default la funzione print() scrive e va a capo aggiungendo un carattere
-# newline alla fine della stringa. È possibile utilizzare l'argomento opzionale
-# end per cambiare quest'ultimo carattere aggiunto.
-print("Hello, World", end="!") # => Hello, World!
-
-# Un modo semplice per ricevere dati in input dalla riga di comando
-variabile_stringa_input = input("Inserisci del testo: ") # Restituisce i dati letti come stringa
-# Nota: Nelle precedenti vesioni di Python, il metodo input()
-# era chiamato raw_input()
-
-# Non c'è bisogno di dichiarare una variabile per assegnarle un valore
-# Come convenzione, per i nomi delle variabili, si utilizzano i caratteri
-# minuscoli separati, se necessario, da underscore
-some_var = 5
-some_var # => 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.
-some_unknown_var # Genera un errore di nome
-
-# if può essere usato come un'espressione
-# È l'equivalente dell'operatore ternario in C
-"yahoo!" if 3 > 2 else 2 # => "yahoo!"
-
-# Le liste immagazzinano sequenze
-li = []
-# Puoi partire con una lista pre-riempita
-other_li = [4, 5, 6]
-
-# Aggiungere 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
-# Guarda l'ultimo elemento
-li[-1] # => 3
-
-# Guardare al di fuori dei limiti genera 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]
-
-# Crea una copia (one layer deep copy) usando la sintassi slices
-li2 = li[:] # => li2 = [1, 2, 4, 3] ma (li2 is li) risulterà falso.
-
-# Rimuovi arbitrariamente elementi da una lista con "del"
-del li[2] # li è ora [1, 2, 3]
-
-# 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
-
-# Puoi sommare le liste
-# Nota: i valori per li e per other_li non vengono modificati.
-li + other_li # => [1, 2, 3, 4, 5, 6]
-
-# Concatena le liste con "extend()"
-li.extend(other_li) # Adesso li è [1, 2, 3, 4, 5, 6]
-
-# Controlla l'esistenza di un valore in una lista con "in"
-1 in li # => True
-
-# Esamina la lunghezza con "len()"
-len(li) # => 6
-
-
-# Le tuple sono come le liste ma immutabili.
-tup = (1, 2, 3)
-tup[0] # => 1
-tup[0] = 3 # Genera un TypeError
-
-# Note that a tuple of length one has to have a comma after the last element but
-# tuples of other lengths, even zero, do not.
-type((1)) # => <class 'int'>
-type((1,)) # => <class 'tuple'>
-type(()) # => <class 'tuple'>
-
-# 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 e 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
-
-# I dizionari memorizzano insiemi di dati indicizzati da nomi arbitrari (chiavi)
-empty_dict= {}
-# Questo è un dizionario pre-caricato
-filled_dict = {"uno": 1, "due": 2, "tre": 3}
-
-# Nota: le chiavi dei dizionari devono essere di tipo immutabile. Questo per
-# assicurare che le chiavi possano essere convertite in calori hash costanti
-# per un risposta più veloce.
-invalid_dict = {[1,2,3]: "123"} # => Emette un TypeError: unhashable type: 'list'
-valid_dict = {(1,2,3):[1,2,3]} # I valori, invece, possono essere di qualunque tipo
-
-# Accedi ai valori indicando la chiave tra []
-filled_dict["uno"] # => 1
-
-# Puoi ottenere tutte le chiavi di un dizionario con "keys()"
-# (come oggetto iterabile). Per averle in formato lista è necessario
-# utilizzare list().
-# Nota - Nei dizionari l'ordine delle chiavi non è garantito.
-# Il tuo risultato potrebbe non essere uguale a questo.
-list(filled_dict.keys()) # => ["tre", "due", "uno"]
-
-
-# Puoi ottenere tutti i valori di un dizionario con "values()"
-# (come oggetto iterabile).
-# Anche in questo caso, er averle in formato lista, è necessario utilizzare list()
-# Anche in questo caso, come per le chiavi, l'ordine non è garantito
-list(filled_dict.values()) # => [3, 2, 1]
-
-# 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 genera 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
-
-
-# "setdefault()" inserisce un valore per una chiave in un dizionario
-# solo se la chiave data non è già presente
-filled_dict.setdefault("cinque", 5) # filled_dict["cinque"] viene impostato a 5
-filled_dict.setdefault("cinque", 6) # filled_dict["cinque"] rimane 5
-
-# Aggiungere una coppia chiave->valore a un dizionario
-filled_dict.update({"quattro":4}) # => {"uno": 1, "due": 2, "tre": 3, "quattro": 4}
-filled_dict["quattro"] = 4 # un altro modo pe aggiungere a un dizionario
-
-# Rimuovi una chiave da un dizionario con del
-del filled_dict["uno"] # Rimuove la chiave "uno" dal dizionario
-
-# Da Python 3.5 puoi anche usare ulteriori opzioni di spacchettamento
-{'a': 1, **{'b': 2}} # => {'a': 1, 'b': 2}
-{'a': 1, **{'a': 2}} # => {'a': 2}
-
-# I set sono come le liste ma non possono contenere doppioni
-empty_set = set()
-# Inizializza un "set()" con un dei valori. Sì, sembra un dizionario.
-some_set = {1, 1, 2, 2, 3, 4} # set_nuovo è {1, 2, 3, 4}
-
-# Come le chiavi di un dizionario, gli elementi di un set devono essere
-# di tipo immutabile
-invalid_set = {[1], 1} # => Genera un "TypeError: unhashable type: 'list'""
-valid_set = {(1,), 1}
-
-# Aggiungere uno o più elementi ad un set
-some_set.add(5) # some_set ora è {1, 2, 3, 4, 5}
-
-# Fai intersezioni su un set con &
-other_set = {3, 4, 5, 6}
-some_set & other_set # => {3, 4, 5}
-
-# Fai unioni su set con |
-some_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 some_set # => True
-10 in some_set # => False
-
-
-
-####################################################
-## 3. Control Flow e oggetti Iterabili
-####################################################
-
-# Dichiariamo una variabile
-some_var = 5
-
-# Questo è un controllo if. L'indentazione è molto importante in python!
-# Come convenzione si utilizzano quattro spazi, non la tabulazione.
-# Il seguente codice stampa "some_var è minore di 10"
-if some_var > 10:
- print("some_var è maggiore di 10")
-elif some_var < 10: # La clausolo elif è opzionale
- print("some_var è minore di 10")
-else: # Anche else è opzionale
- print("some_var è 10.")
-
-"""
-I cicli for iterano sulle liste, cioè ripetono un codice per ogni elemento
-di una lista.
-Il seguente codice scriverà:
- cane è un mammifero
- gatto è un mammifero
- topo è un mammifero
-"""
-for animale in ["cane", "gatto", "topo"]:
- # Puoi usare format() per interpolare le stringhe formattate.
- print("{} è un mammifero".format(animale))
-
-"""
-"range(numero)" restituisce una lista di numeri da zero al numero dato
-Il seguente codice scriverà:
- 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).
-Il seguente codice scriverà:
- 4
- 5
- 6
- 7
-"""
-for i in range(4, 8):
- print(i)
-
-"""
-"range(lower, upper, step)" rrestituisce una lista di numeri dal più piccolo
-(lower) al più grande (upper), incrementando del valore step.
-Se step non è indicato, avrà come valore di default 1.
-Il seguente codice scriverà:
- 4
- 6
-"""
-for i in range(4, 8, 2):
- print(i)
-"""
-
-I cicli while vengono eseguiti finchè una condizione viene a mancare
-Il seguente codice scriverà:
- 0
- 1
- 2
- 3
-"""
-x = 0
-while x < 4:
- print(x)
- x += 1 # Forma compatta per x = x + 1
-
-# Gestione delle eccezioni con un blocco try/except
-try:
- # Usa "raise" per generare un errore
- raise IndexError("Questo è un IndexError")
-except IndexError as e:
- pass # Pass è solo una non-operazione. Solitamente vorrai rimediare all'errore.
-except (TypeError, NameError):
- pass # Eccezioni multiple possono essere gestite tutte insieme, se necessario.
-else: # Clausola opzionale al blocco try/except. Deve essere dopo 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")
-
-# Se ti serve solo un try/finally, per liberare risorse, puoi usare il metodo with
-with open("myfile.txt") as f:
- for line in f:
- print(line)
-
-# In Python qualunque oggetto in grado di essere trattato come una
-# sequenza è definito un oggetto Iterable (itarabile).
-# L'oggetto restituito da una funzione range è un iterabile.
-
-filled_dict = {"uno": 1, "due": 2, "tre": 3}
-our_iterable = filled_dict.keys()
-print(our_iterable) # => dict_keys(['uno', 'due', 'tre']).
-# Questo è un oggetto che implementa la nostra interfaccia Iterable.
-
-# È possibile utilizzarlo con i loop:
-for i in our_iterable:
- print(i) # Scrive uno, due, tre
-
-# Tuttavia non possiamo recuperarne i valori tramite indice.
-our_iterable[1] # Genera un TypeError
-
-# Un oggetto iterabile è in grado di generare un iteratore
-our_iterator = iter(our_iterable)
-
-# L'iteratore è un oggetto che ricorda il suo stato mentro lo si "attraversa"
-# Possiamo accedere al successivo elemento con "next()".
-next(our_iterator) # => "uno"
-
-# Mantiene il suo stato mentro eseguiamo l'iterazione
-next(our_iterator) # => "due"
-next(our_iterator) # => "tre"
-
-# Dopo che un iteratore ha restituito tutti i suoi dati, genera
-# un'eccezione StopIteration
-next(our_iterator) # Raises StopIteration
-
-# Puoi prendere tutti gli elementi di un iteratore utilizzando list().
-list(filled_dict.keys()) # => Returns ["one", "two", "three"]
-
-
-
-####################################################
-## 4. Funzioni
-####################################################
-
-# Usa "def" per creare nuove funzioni
-def aggiungi(x, y):
- print("x è {} e y è {}".format(x, y)) // Scrive i valori formattati in una stringa
- return x + y # Restituisce la somma dei valori con il metodo return
-
-# Chiamare funzioni con parametri
-aggiungi(5, 6) # => scrive "x è 5 e y è 6" e restituisce 11
-
-# Un altro modo per chiamare funzioni è con parole chiave come argomenti
-aggiungi(y=6, x=5) # In questo modo non è necessario rispettare l'ordine degli argomenti
-
-# Puoi definire funzioni che accettano un numero non definito di argomenti
-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)
-
-
-# Restituire valori multipli (with tuple assignments)
-def swap(x, y):
- return y, x # Restituisce valori multipli come tupla senza parentesi
- # (Nota: le parentesi sono state escluse ma possono essere messe)
-
-x = 1
-y = 2
-x, y = swap(x, y) # => x = 2, y = 1
-# (x, y) = swap(x,y) # Le parentesi sono state escluse ma possono essere incluse.
-
-# Funzioni - Visibilità delle variabili (variable scope)
-x = 5
-
-def set_x(num):
- # La variabile locale x non è la 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 "first class functions"
-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
-
-# È possibile creare "mappe" e "filtri"
-list(map(add_10, [1, 2, 3])) # => [11, 12, 13]
-list(map(max, [1, 2, 3], [4, 2, 1])) # => [4, 2, 3]
-
-list(filter(lambda x: x > 5, [3, 4, 5, 6, 7])) # => [6, 7]
-
-# Possiamo usare le "list comprehensions" per mappe e filtri
-# Le "list comprehensions" memorizzano l'output come una lista che può essere
-# di per sé una lista annidata
-[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 not in 'abc'} # => {'d', 'e', 'f'}
-{x: x**2 for x in range(5)} # => {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
-
-
-####################################################
-## 5. Modules
-####################################################
-
-# Puoi importare moduli
-import math
-print(math.sqrt(16)) # => 4.0
-
-# 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
-
-
-# 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
-# sono definiti in 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
-
-# Se hai uno script Python chiamato math.py nella stessa
-# cartella del tua script, Python caricherà quello al posto del
-# comune modulo math.
-# Questo accade perché la cartella locale ha la priorità
-# sulle librerie built-in di Python.
-
-
-####################################################
-## 6. Classes
-####################################################
-
-# Usiamo l'istruzione "class" per creare una classe
-class Human:
-
- # Un attributo della classe. E' condiviso tra tutte le istanze delle classe
- species = "H. sapiens"
-
- # Si noti che i doppi underscore iniziali e finali denotano gli oggetti o
- # attributi utilizzati da Python ma che vivono nel namespace controllato
- # dall'utente
- # Metodi, oggetti o attributi come: __init__, __str__, __repr__, etc. sono
- # chiamati metodi speciali (o talvolta chiamati "dunder methods").
- # Non dovresti inventare tali nomi da solo.
-
- 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):
- print("{name}: {message}".format(name=self.name, message=msg))
-
- # Un altro metodo dell'istanza
- def sing(self):
- return 'yo... yo... microphone check... one two... one two...'
-
- # Un metodo della classe è condiviso fra tutte le istanze
- # Sono chiamati con la classe chiamante come primo argomento
- @classmethod
- def get_species(cls):
- return cls.species
-
- # Un metodo statico è chiamato senza classe o istanza di riferimento
- @staticmethod
- def grunt():
- return "*grunt*"
-
- # Una property è come un metodo getter.
- # Trasforma il metodo age() in un attributo in sola lettura, che ha
- # lo stesso nome
- # In Python non c'è bisogno di scrivere futili getter e setter.
- @property
- def age(self):
- return self._age
-
- # Questo metodo permette di modificare una property
- @age.setter
- def age(self, age):
- self._age = age
-
- # Questo metodo permette di cancellare una property
- @age.deleter
- def age(self):
- del self._age
-
-# Quando l'interprete Python legge un sorgente esegue tutto il suo codice.
-# Questo controllo su __name__ assicura che questo blocco di codice venga
-# eseguito solo quando questo modulo è il programma principale.
-
-if __name__ == '__main__':
- # Crea un'istanza della classe
- i = Human(name="Ian")
- i.say("hi") # "Ian: hi"
- j = Human("Joel")
- j.say("hello") # "Joel: hello"
- # i e j sono istanze del tipo Human, o in altre parole sono oggetti Human
-
- # Chiama un metodo della classe
- i.say(i.get_species()) # "Ian: H. sapiens"
- # Cambia l'attributo condiviso
- Human.species = "H. neanderthalensis"
- i.say(i.get_species()) # => "Ian: H. neanderthalensis"
- j.say(j.get_species()) # => "Joel: H. neanderthalensis"
-
- # Chiama un metodo statico
- print(Human.grunt()) # => "*grunt*"
-
- # Non è possibile chiamare il metodo statico con l'istanza dell'oggetto
- # poiché i.grunt() metterà automaticamente "self" (l'oggetto i)
- # come argomento
- print(i.grunt()) # => TypeError: grunt() takes 0 positional arguments but 1 was given
-
- # Aggiorna la property (age) di questa istanza
- i.age = 42
- # Leggi la property
- i.say(i.age) # => "Ian: 42"
- j.say(j.age) # => "Joel: 0"
- # Cancella la property
- del i.age
- i.age # => questo genererà un AttributeError
-
-
-####################################################
-## 6.1 Ereditarietà (Inheritance)
-####################################################
-
-# L'ereditarietà consente di definire nuove classi figlio che ereditano metodi e
-# variabili dalla loro classe genitore.
-
-# Usando la classe Human definita sopra come classe base o genitore, possiamo
-# definire una classe figlia, Superhero, che erediterà le variabili di classe
-# come "species", "name" e "age", così come i metodi, come "sing" e "grunt",
-# dalla classe Human, ma potrà anche avere le sue proprietà uniche.
-
-# Per importare le funzioni da altri file usa il seguente formato
-# from "nomefile-senza-estensione" import "funzione-o-classe"
-
-from human import Human
-
-# Specificare le classi genitore come parametri della definizione della classe
-class Superhero(Human):
-
- # Se la classe figlio deve ereditare tutte le definizioni del genitore
- # senza alcuna modifica, puoi semplicemente usare la parola chiave "pass"
- # (e nient'altro)
-
- #Le classi figlio possono sovrascrivere gli attributi dei loro genitori
- species = 'Superhuman'
-
- # Le classi figlie ereditano automaticamente il costruttore della classe
- # genitore, inclusi i suoi argomenti, ma possono anche definire ulteriori
- # argomenti o definizioni e sovrascrivere i suoi metodi (compreso il
- # costruttore della classe).
- # Questo costruttore eredita l'argomento "nome" dalla classe "Human" e
- # aggiunge gli argomenti "superpowers" e "movie":
-
- def __init__(self, name, movie=False,
- superpowers=["super strength", "bulletproofing"]):
-
- # aggiungi ulteriori attributi della classe
- self.fictional = True
- self.movie = movie
- self.superpowers = superpowers
-
- # La funzione "super" ti consente di accedere ai metodi della classe
- # genitore che sono stati sovrascritti dalla classe figlia,
- # in questo caso il metodo __init__.
- # Il seguente codice esegue il costruttore della classe genitore:
- super().__init__(name)
-
- # Sovrascrivere il metodo "sing"
- def sing(self):
- return 'Dun, dun, DUN!'
-
- # Aggiungi un ulteriore metodo dell'istanza
- def boast(self):
- for power in self.superpowers:
- print("I wield the power of {pow}!".format(pow=power))
-
-
-if __name__ == '__main__':
- sup = Superhero(name="Tick")
-
- # Controllo del tipo di istanza
- if isinstance(sup, Human):
- print('I am human')
- if type(sup) is Superhero:
- print('I am a superhero')
-
- # Ottieni il "Method Resolution search Order" usato sia da getattr ()
- # che da super (). Questo attributo è dinamico e può essere aggiornato
- print(Superhero.__mro__) # => (<class '__main__.Superhero'>,
- # => <class 'human.Human'>, <class 'object'>)
-
- # Esegui il metodo principale ma utilizza il proprio attributo di classe
- print(sup.get_species()) # => Superhuman
-
- # Esegui un metodo che è stato sovrascritto
- print(sup.sing()) # => Dun, dun, DUN!
-
- # Esegui un metodo di Human
- sup.say('Spoon') # => Tick: Spoon
-
- # Esegui un metodo che esiste solo in Superhero
- sup.boast() # => I wield the power of super strength!
- # => I wield the power of bulletproofing!
-
- # Attributo di classe ereditato
- sup.age = 31
- print(sup.age) # => 31
-
- # Attributo che esiste solo in Superhero
- print('Am I Oscar eligible? ' + str(sup.movie))
-
-####################################################
-## 6.2 Ereditarietà multipla
-####################################################
-
-# Un'altra definizione di classe
-# bat.py
-class Bat:
-
- species = 'Baty'
-
- def __init__(self, can_fly=True):
- self.fly = can_fly
-
- # Questa classe ha anche un metodo "say"
- def say(self, msg):
- msg = '... ... ...'
- return msg
-
- # E anche un suo metodo personale
- def sonar(self):
- return '))) ... ((('
-
-if __name__ == '__main__':
- b = Bat()
- print(b.say('hello'))
- print(b.fly)
-
-# Definizione di classe che eredita da Superhero e Bat
-# superhero.py
-from superhero import Superhero
-from bat import Bat
-
-# Definisci Batman come classe figlia che eredita sia da Superhero che da Bat
-class Batman(Superhero, Bat):
-
- def __init__(self, *args, **kwargs):
- # In genere per ereditare gli attributi devi chiamare super:
- # super(Batman, self).__init__(*args, **kwargs)
- # Ma qui abbiamo a che fare con l'ereditarietà multipla, e super()
- # funziona solo con la successiva classe nell'elenco MRO.
- # Quindi, invece, chiamiamo esplicitamente __init__ per tutti gli
- # antenati. L'uso di *args e **kwargs consente di passare in modo
- # pulito gli argomenti, con ciascun genitore che "sbuccia un
- # livello della cipolla".
- Superhero.__init__(self, 'anonymous', movie=True,
- superpowers=['Wealthy'], *args, **kwargs)
- Bat.__init__(self, *args, can_fly=False, **kwargs)
- # sovrascrivere il valore per l'attributo name
- self.name = 'Sad Affleck'
-
- def sing(self):
- return 'nan nan nan nan nan batman!'
-
-
-if __name__ == '__main__':
- sup = Batman()
-
- # Ottieni il "Method Resolution search Order" utilizzato da getattr() e super().
- # Questo attributo è dinamico e può essere aggiornato
- print(Batman.__mro__) # => (<class '__main__.Batman'>,
- # => <class 'superhero.Superhero'>,
- # => <class 'human.Human'>,
- # => <class 'bat.Bat'>, <class 'object'>)
-
- # Esegui il metodo del genitore ma utilizza il proprio attributo di classe
- print(sup.get_species()) # => Superhuman
-
- # Esegui un metodo che è stato sovrascritto
- print(sup.sing()) # => nan nan nan nan nan batman!
-
- # Esegui un metodo da Human, perché l'ordine di ereditarietà è importante
- sup.say('I agree') # => Sad Affleck: I agree
-
- # Esegui un metodo che esiste solo nel 2o antenato
- print(sup.sonar()) # => ))) ... (((
-
- # Attributo di classe ereditato
- sup.age = 100
- print(sup.age) # => 100
-
- # Attributo ereditato dal secondo antenato il cui valore predefinito
- # è stato ignorato.
- print('Can I fly? ' + str(sup.fly)) # => Can I fly? False
-
-
-
-####################################################
-## 7. Advanced
-####################################################
-
-# I generatori ti aiutano a creare codice pigro (lazy code).
-# Codice che darà un risultato solo quando sarà "valutato"
-def double_numbers(iterable):
- for i in iterable:
- yield i + i
-
-# I generatori sono efficienti in termini di memoria perché caricano
-# solo i dati necessari per elaborare il valore successivo nell'iterabile.
-# Ciò consente loro di eseguire operazioni su intervalli di valori
-# altrimenti proibitivi.
-# NOTA: `range` sostituisce` xrange` in Python 3.
-for i in double_numbers(range(1, 900000000)): # `range` is a generator.
- print(i)
- if i >= 30:
- break
-
-# Proprio come è possibile creare una "list comprehension", è possibile
-# creare anche delle "generator comprehensions".
-values = (-x for x in [1,2,3,4,5])
-for x in values:
- print(x) # prints -1 -2 -3 -4 -5 to console/terminal
-
-# Puoi anche trasmettere una "generator comprehensions" direttamente
-# ad un elenco.
-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" avvolge/wrappa "say".
-# Se say_please è True, cambierà il messaggio restituito.
-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)
-* [Ideas for Python Projects](http://pythonpracticeprojects.com)
-* [The Official Docs](http://docs.python.org/3/)
-* [Hitchhiker's Guide to Python](http://docs.python-guide.org/en/latest/)
-* [Python Course](http://www.python-course.eu/index.php)
-* [First Steps With Python](https://realpython.com/learn/python-first-steps/)
-* [A curated list of awesome Python frameworks, libraries and software](https://github.com/vinta/awesome-python)
-* [30 Python Language Features and Tricks You May Not Know About](http://sahandsaba.com/thirty-python-language-features-and-tricks-you-may-not-know.html)
-* [Official Style Guide for Python](https://www.python.org/dev/peps/pep-0008/)
-* [Python 3 Computer Science Circles](http://cscircles.cemc.uwaterloo.ca/)
-* [Dive Into Python 3](http://www.diveintopython3.net/index.html)
-* [A Crash Course in Python for Scientists](http://nbviewer.jupyter.org/gist/anonymous/5924718)
diff --git a/it-it/pythonlegacy-it.html.markdown b/it-it/pythonlegacy-it.html.markdown
new file mode 100644
index 00000000..4c8b2a17
--- /dev/null
+++ b/it-it/pythonlegacy-it.html.markdown
@@ -0,0 +1,778 @@
+---
+language: Python 2 (legacy)
+filename: learnpythonlegacy-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/python/).
+
+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.0
+
+# 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/qt-it.html.markdown b/it-it/qt-it.html.markdown
index d7469f67..ef829493 100644
--- a/it-it/qt-it.html.markdown
+++ b/it-it/qt-it.html.markdown
@@ -1,7 +1,7 @@
---
category: tool
tool: Qt Framework
-language: c++
+language: C++
filename: learnqt-it.cpp
contributors:
- ["Aleksey Kholovchuk", "https://github.com/vortexxx192"]
diff --git a/it-it/rst-it.html.markdown b/it-it/rst-it.html.markdown
index a834e899..3885cbd8 100644
--- a/it-it/rst-it.html.markdown
+++ b/it-it/rst-it.html.markdown
@@ -81,11 +81,11 @@ Anche le tabelle più complesse possono essere inserite facilmente (colonne e/o
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).
+- 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/>`_ .
+- Utilizzando una sintassi simile a Markdown: `GitHub <https://github.com/>`_ .
-.. _Github https://github.com/
+.. _GitHub https://github.com/
```
diff --git a/it-it/ruby-it.html.markdown b/it-it/ruby-it.html.markdown
index 295bf28a..1f466cce 100644
--- a/it-it/ruby-it.html.markdown
+++ b/it-it/ruby-it.html.markdown
@@ -650,4 +650,4 @@ Something.new.qux #=> 'qux'
- [Ruby from other languages](https://www.ruby-lang.org/en/documentation/ruby-from-other-languages/)
- [Programming Ruby](http://www.amazon.com/Programming-Ruby-1-9-2-0-Programmers/dp/1937785491/) - Una passata [edizione libera](http://ruby-doc.com/docs/ProgrammingRuby/) è disponibile online.
- [Ruby Style Guide](https://github.com/bbatsov/ruby-style-guide) - A community-driven Ruby coding style guide.
-- [Try Ruby](http://tryruby.org) - Imparare le basi del linguaggio di programmazion Ruby, interattivamente nel browser.
+- [Try Ruby](https://try.ruby-lang.org/) - Imparare le basi del linguaggio di programmazion Ruby, interattivamente nel browser.
diff --git a/it-it/rust-it.html.markdown b/it-it/rust-it.html.markdown
index e4b7c33f..acb8b8ba 100644
--- a/it-it/rust-it.html.markdown
+++ b/it-it/rust-it.html.markdown
@@ -1,5 +1,5 @@
---
-language: rust
+language: Rust
contributors:
- ["Carlo Milanesi", "http://github.com/carlomilanesi"]
lang: it-it
@@ -229,7 +229,7 @@ fn main() {
// Ciclo/iterazione con `for`
let array = [1, 2, 3];
- for i in array.iter() {
+ for i in array {
println!("{}", i);
}
diff --git a/it-it/solidity.html.markdown b/it-it/solidity.html.markdown
new file mode 100644
index 00000000..be747e68
--- /dev/null
+++ b/it-it/solidity.html.markdown
@@ -0,0 +1,1069 @@
+---
+language: Solidity
+filename: learnSolidity-it.sol
+contributors:
+ - ["Nemil Dalal", "https://www.nemil.com"]
+ - ["Joseph Chow", ""]
+ - ["Bhoomtawath Plinsut", "https://github.com/varshard"]
+ - ["Shooter", "https://github.com/liushooter"]
+ - ["Patrick Collins", "https://gist.github.com/PatrickAlphaC"]
+translators:
+ - ["Al", "http://github.com/al-ias"]
+lang: it-it
+---
+
+Solidity permette di programmare su [Ethereum](https://www.ethereum.org/), una
+macchina virtuale basata sulla blockchain che consente la creazione e
+l'esecuzione degli smart contract senza che sia richiesta centralizzazione o
+fiducia negli attori coinvolti.
+
+Solidity è un linguaggio di programmazione di contratti tipizzato staticamente e
+ha molte cose in comune con Javascript e C. Come per gli oggetti nella
+programmazione ad oggetti, ogni contratto contiene variabili di stato, funzioni
+e tipi di dato semplici. Tra le funzionalità specifiche dei contratti troviamo
+le clausole (guardie) dei modifier, gli event notifier per i listener, e le
+variabili globali custom.
+
+Come esempi di contratti su Ethereum troviamo sistemi di crowdfunding, voto,
+[finanza decentralizzata](https://defipulse.com/) e aste al buio.
+
+Compiere errori nel codice Solidity può portare a rischi e costi alti, quindi
+bisogna fare attenzione a testare e rilasciare le modifiche lentamente. A
+CAUSA DEI CONTINUI CAMBIAMENTI DI ETHEREUM È IMPROBABILE CHE QUESTO DOCUMENTO
+RESTI AGGIORNATO, QUINDI COSNIGLIAMO DI SEGUIRE LA CHAT ROOM DI SOLIDITY E IL
+BLOG DI ETHEREUM PER TENERSI AGGIORNATI. TUTTO IL CODICE QUI PRESENTE E' FORNITO
+COSÌ COM'È, CON ANNESSI RISCHI SOSTANZIALI DI ERRORI O PATTERN DI PROGRAMMAZIONE
+DEPRECATI.
+
+A differenza di altri linguaggi, potresti aver bisogno di usare pattern di
+pausing, deprecation e throttling usage per ridurre il rischio. Questo documento
+tratta principalmene la sintassi e quindi esclude molti design pattern in voga.
+
+Visto che Solidity e Ethereum sono in continuo sviluppo, le funzionalità
+sperimentali o beta sono evidenziate e soggette a cambiamenti. Ogni Pull Request
+è ben accetta.
+
+
+# Lavorare con Remix e Metamask
+
+Uno dei modi più semplici di scrivere, distribuire e testare il codice Solidity
+è usare :
+
+1. [L'ambiente di sviluppo online Remix](https://remix.ethereum.org/)
+2. [Il wallet Metamask](https://metamask.io/).
+
+Per cominciare, [scarichiamo l'estesione per browser di Metamask](https://metamask.io/).
+
+Una volta installata, potremo iniziare ad usare Remix. Il codice seguente è
+pre-inizializzato, ma prima di addentrarci, diamo un'occhiata a qualche
+trucchetto per iniziare ad usare Remix. Carica tutto il necessario [clickando su questo link](https://remix.ethereum.org/#version=soljson-v0.6.6+commit.6c089d02.js&optimize=false&evmVersion=null&gist=f490c0d51141dd0515244db40bbd0c17&runs=200).
+
+1. Scegli il compilatore per Solidity
+
+![Solidity-in-remix](../images/solidity/remix-solidity.png)
+
+2. Apri il file che si caricherà su quel link
+
+![Solidity-choose-file](../images/solidity/remix-choose-file.png)
+
+3. Compila il file
+
+![Solidity-compile](../images/solidity/remix-compile.png)
+
+4. Fai il deploy
+
+![Solidity-deploy](../images/solidity/remix-deploy.png)
+
+5. Smanetta con i contratti
+
+![Solidity-deploy](../images/solidity/remix-interact.png)
+
+Hai distribuito il tuo primo contratto! Congratulazioni!
+
+Potrai testarlo e smanettare con le funzioni già definite. Dai un'occhiata ai
+commenti per scoprire cosa fanno.
+
+
+## Lavorare su una testnet
+
+Distribuire e testare su una testnet è il modo più accurato per mettere alla
+prova i tuoi smart contract in Solidity. Per farlo procuriamoci prima degli ETH
+di test dalla testnet Kovan.
+
+[Entra in questo Gitter Channel](https://gitter.im/kovan-testnet/faucet) e
+scrivici l'indirizzo del tuo wallet Metamask.
+
+Sul tuo Metamask, dovrai cambiare la testnet in `Kovan`.
+
+![Solidity-in-remix](../images/solidity/metamask-kovan.png)
+
+Riceverai degli Ethereum di test gratuiti. Abbiamo bisogno di Ethereum per
+distribuire degli smart contract su una testnet.
+
+Nell'esempio precedente non avevamo usato una testnet, ma avevamo distribuito
+su un ambiente virtuale fittizio. Quando si lavora su una testnet, possiamo
+davvero monitorare e interagire con i nostri contratti in maniera persistente.
+
+Per distribuire su una testnet, allo step `#4 Fai il deploy`, cambia
+l'`environment` selezionato in `injected web3`. In questo modo verrà usato
+come network su cui fare il deploy qualsiasi network selezionato sul tuo
+Metamask.
+
+![Solidity-in-remix](../images/solidity/remix-testnet.png)
+
+Per ora continua a usare la `Javascript VM` a meno che non ti sia detto di
+cambiarla. Quando distribuisci su una testnet, Metamask aprirà un pop up che
+ti chiederà di "confermare" la transazione. Premi `yes` e dopo un certo lasso
+di tempo, ti apparirà la stessa interfaccia per il contratto nella parte
+inferiore dello schermo.
+
+
+```javascript
+// Iniziamo con un semplice contratto su una Banca
+// Permette di depositare, prelevare e fare l'estratto conto
+
+// simple_bank.sol (nota l'estensione .sol)
+/* **** INIZIO DELL'ESEMPIO **** */
+
+// Dichiara la versione del compilatore per il file sorgente
+pragma solidity ^0.6.6;
+
+// Inizia con il commento Natspec (i tre slash)
+// viene usato per la documentazione - e per i dati descrittivi per gli elementi
+// dell'interfaccia utente / azioni
+
+/// @title SimpleBank
+/// @author nemild
+
+/* 'contract' somiglia a 'class' in altri linguaggi (ha variabili di classe,
+ereditarietà, etc.) */
+contract SimpleBank { // CapWords
+ // Dichiariamo le variabili di stato fuori dalle funzioni, persisteranno
+ // durante tutta la vita del contratto
+
+ // i dizionari mappano gli indirizzi con i saldi
+ // fai sempre attenzione agli overflow attack che sfruttano i numeri
+ mapping (address => uint) private balances;
+
+ // "private" significa che che altri contratti non possono leggere i
+ // saldi ma le informazioni restano visibili ad altri attori sulla blockchain
+
+ address public owner;
+ // 'public' lo rende leggibile dall'esterno (ma non modificabile) dagli
+ // utenti e dai contratti
+
+ // Gli 'event' pubblicano le azioni in modo che siano ascoltabili da
+ // listener esterni
+ event LogDepositMade(address accountAddress, uint amount);
+
+ // I 'constructor' possono ricevere uno o più parametri; Si può
+ // dichiarare un solo costruttore
+ constructor() public {
+ // 'msg' fornisce i dettagli sul messaggio che è stato mandato al contratto
+ // 'msg.sender' è chi invoca il contratto (l'indirizzo di chi lo crea)
+ owner = msg.sender;
+ }
+
+ /// @notice Deposita ether nella banca
+ /// @return Il saldo dell'utente dopo che è stato effettualto il deposito
+ function deposit() public payable returns (uint) {
+ // Usiamo 'require' per testare gli input dell'utente, 'assert' per gli
+ // invarianti interni. Qui ci assicuriamo di non avere a che fare con
+ // un overflow
+ require((balances[msg.sender] + msg.value) >= balances[msg.sender]);
+
+ balances[msg.sender] += msg.value;
+ // Non servono "this." o "self." con le variabili di stato
+ // Tutti i valori iniziali delle variabili sono impostati automaticamente
+ // al valore di default per quel tipo di dato
+
+ emit LogDepositMade(msg.sender, msg.value); // Fa scattare l'evento
+
+ return balances[msg.sender];
+ }
+
+ /// @notice Preleva ether dalla banca
+ /// @dev Non restituisce gli ether inviati in eccesso
+ /// @param withdrawAmount L'importo che si vuole ritirare
+ /// @return remainingBal
+ function withdraw(uint withdrawAmount) public returns (uint remainingBal) {
+ require(withdrawAmount <= balances[msg.sender]);
+
+ // Notiamo come per prima cosa scaliamo i soldi dal saldo, prima di
+ // invarli. Ogni .transfer/.send in questo contratto può chiamare una
+ // funzione esterna. Questa cosa potrebbe permettere a chi invoca la
+ // funzione di richiedere un importo maggiore del suo saldo usando
+ // una chiamata ricorsiva. Miriamo ad aggiornare lo stato prima che sia
+ // chiamata una funzione esterna, incluse .transfer/.send
+ balances[msg.sender] -= withdrawAmount;
+
+ // Qui lancia automaticamente un errore se fallisce, il che implica
+ // che il saldo (non più aggiornato) viene ripristinato a prima della
+ // transazione
+ msg.sender.transfer(withdrawAmount);
+
+ return balances[msg.sender];
+ }
+
+ /// @notice Recupera il saldo
+ /// @return Il saldo dell'utente
+ // 'view' (ex: constant) impedisce alle funzioni di modificare lo stato
+ // delle variabili; consente alle le funzioni di essere disponibili in
+ // locale/fuori dalla blockchain
+ function balance() view public returns (uint) {
+ return balances[msg.sender];
+ }
+}
+// ** FINE DELL'ESEMPIO **
+
+
+// Passiamo alle basi di Solidity
+
+// 1. TIPI DI DATO E I LORO METODI
+// uint viene usato per gli importi in valuta (non ci sono double o float)
+// e per le date (in unix time)
+uint x;
+
+// int di 256 bit, non possono essere modificati dopo l'istanziazione
+int constant a = 8;
+int256 constant a = 8; // stesso effetto della riga prima, qui viene
+// dichiarato esplicitamente che è di 256 bit
+uint constant VERSION_ID = 0x123A1; // Una costante esadecimale
+// con 'constant', il compilatore rimpiazza ogni occorrenza con il valore
+
+// Tutte le variabili di stato (quelle fuori da una funzione)
+// sono 'interne' di default e accessibili SOLO dall'interno del contratto
+// e da tutti contratti che le ereditano
+// Bisogna usare esplicitamente 'public' per consentire l'accesso dai contratti
+// esterni
+int256 public a = 8;
+
+// Per int e uint possiamo esplicitamente assegnare una dimensione tra 8 e 256
+// es. int8, int16, int24
+uint8 b;
+int64 c;
+uint248 e;
+
+// Attenzione a non andare in overflow e a proteggersi dagli attacchi che lo fanno
+// Ad esempio per quanto rigrada l'addizione, conviene fare:
+uint256 c = a + b;
+assert(c >= a); // 'assert' testa gli invarianti interni; require viene usato
+// per gli input
+// Per altri esempi di problemi comuni con le operazioni aritmentiche, dai una
+// occhiata alla Zeppelin's SafeMath library
+// https://github.com/OpenZeppelin/zeppelin-solidity/blob/master/contracts/math/SafeMath.sol
+
+
+// Non ci sono funzioni random built-in, puoi ottenere un numero pseudo-casuale
+// hashando l'ultimo blockhash, o ottenere un numero realmente casuale usando
+// qualcosa come Chainlink VRF.
+// https://docs.chain.link/docs/get-a-random-number
+
+// Conversione di tipo
+int x = int(b);
+
+bool b = true; // oppure 'var b = true;' per l'inferenza di tipo
+
+// Indirizzi - contengono indirizzi Ethereum di 20 byte/160 bit
+// Non sono consentite operazioni aritmetiche
+address public owner;
+
+// Tipi di account:
+// Contract account: l'indirizzo viene impostato quando lo si crea (funzione con
+// l'indirzzo di chi lo crea, il numero della transazione inviata)
+// External Account: (persona/enitità esterna): l'indirizzo viene creato dalla
+// chiave pubblica
+
+// Aggiungi il campo 'public' per indicare che è pubblico/accessibile dall'esterno
+// un getter viene creato automaticamente, ma NON un setter
+
+// Si possono mandare ether a tutti gli indirizzi
+owner.transfer(SOME_BALANCE); // fallisce e, in tal caso, ripristina
+// lo stato precedente
+
+// Possiamo anche usare la funzione di livello più basso .send, che restituisce
+// false se fallisce
+if (owner.send) {} // RICORDA: metti la send in un 'if' dato che gli indirizzi
+// usati nei contratti hanno delle funzioni, che vengono eseguite quando viene
+// fatta una send, che possono fallire.
+// Inoltre fai attenzione a scalare i saldi PRIMA di provare a fare una send,
+// dato il rischio di chiamate riscorsive che potrebbero prosciugare il contratto
+
+// Possiamo controllare il saldo
+owner.balance; // il saldo del propietario (utente o contratto)
+
+
+// I Byte sono disposibili in dimensioni da 1 a 32
+byte a; // 'byte' è la stessa cosa di 'bytes1'
+bytes2 b;
+bytes32 c;
+
+// Byte con dimensione dinamica
+bytes m; // Un array particolare, la stessa cosa dell'array 'byte[]' (ma scritto stringato)
+// È più dispendioso di byte1-byte32, che di solito sono preferibili
+
+// come bytes, ma non permette di accedere alla lunghezza o all'indice (per ora)
+string n = "hello"; // salvato in UTF8, nota i doppi apici, non singoli
+// le utility function per le stringhe saranno aggiunte in futuro
+// sono preferibili bytes32/bytes, dato che UTF8 occupa più memoria
+
+// Inferenza di tipo
+// 'var' fa inferenza di tipo a seconda del primo assegnamento,
+// non può essere usata tra i parametri di una funzione
+var a = true;
+// da usare con cautela, può inferire un tipo errato
+// es. un int8 quando un contatore dev'essere un int16
+
+// var può essere usata per assegnare una funzione ad una variabile
+function a(uint x) returns (uint) {
+ return x * 2;
+}
+var f = a;
+f(22); // chiamata
+
+// di default, tutte le variabili sono impostate a 0 durante l'istanziazione
+
+
+// Delete può essere chiamato sulla maggior parte dei valori
+// (NON distrugge il valore, ma lo setta a 0, il valore did default)
+uint x = 5;
+
+
+// Destructuring/Tuple
+(x, y) = (2, 7); // assegna/scambia più valori
+
+
+// 2. STRUTTURE DATI
+// Array
+bytes32[5] nicknames; // array statico
+bytes32[] names; // array dinamico
+uint newLength = names.push("John"); // aggiungere un elemento restituisce
+// la nuova dimensione dell'array
+// Dimesione
+names.length; // ottenere la dimensione
+names.length = 1; // la dimensione può essere assegnata (solo per gli array nello storage)
+
+// array multidimensionali
+uint[][5] x; // array con 5 array dinamici (ordine opposto rispetto ad
+// altri linguaggi)
+
+// Dizionari (da un tipo qualsiasi a un tipo qualsiasi)
+mapping (string => uint) public balances;
+balances["charles"] = 1;
+// il risultato balances["ada"] è 0, tutte le chiavi non settate
+// restituiscono zero
+// 'public' permette che si possa fare questo da un altro contratto:
+contractName.balances("charles"); // restituisce 1
+// 'public' ha creato getter (ma non un setter), come il seguente:
+function balances(string _account) returns (uint balance) {
+ return balances[_account];
+}
+
+// Mapping annidati
+mapping (address => mapping (address => uint)) public custodians;
+
+// Fare una delete
+delete balances["John"];
+delete balances; // assegna 0 a tutti gli elementi
+
+// Diversamente da altri linguaggi NON si può iterare tra gli elementi di un
+// mapping senza conoscere le chiavi - ma si può costruire una struttura dati a monte
+// che lo faccia
+
+// Strutture dati
+struct Bank {
+ address owner;
+ uint balance;
+}
+Bank b = Bank({
+ owner: msg.sender,
+ balance: 5
+});
+// oppure
+Bank c = Bank(msg.sender, 5);
+
+c.balance = 5; // imposta ad un nuovo valore
+delete b;
+// reimposta, imposta tutte le variabili della struttura a 0, tranne i mapping
+
+// Enumerazioni
+enum State { Created, Locked, Inactive }; // di solito si usano per gli automi a stati finiti
+State public state; // Dichiara una variabile da un enum
+state = State.Created;
+// Le enum possono essere convertite esplicitamente in int
+uint createdState = uint(State.Created); // 0
+
+// Data location: Memory vs. storage vs. calldata - tutti i tipi complessi
+// (array, struct) hanno una data location
+// 'memory' non è persistente, 'storage' sì
+// Il default è 'storage' per varibili locali e di stato;
+// 'memory' per i parametri delle funzioni
+// Lo stack può contenere poche varaibili locali
+
+// Per la maggior parte dei tipi, si può impostare esplicitamente
+// quale data location usare
+
+
+// 3. Operatori semplici
+// Ci sono operatori logici, a bit e aritmetici
+// Potenza: **
+// Or esclusivo: ^
+// Negazione bitwise: ~
+
+
+// 4. Variabili globali degne di nota
+// ** this **
+this; // indirizzo del contratto
+// di solito si usa per trasferire altrove il saldo rimanente
+// al termine della vita del contratto
+this.balance;
+this.someFunction(); // invoca una funzione esterna tramite chiamata,
+// non attraverso un salto interno
+
+// ** msg - Il messaggio corrente ricevuto dal contratto **
+msg.sender; // indirizzo di chi ha inviato msg
+msg.value; // l'importo di ether forniti a questo contratto espresso in "wei",
+// la funzione dovrebbe essere marcata come "payable"
+msg.data; // in bytes, tutti gli argomenti del messaggio
+msg.gas; // 'gas' restante
+
+// ** tx - Questa transazione **
+tx.origin; // l'indirizzo di chi ha avviato questa transazione
+tx.gasprice; // il prezzo del "gas" per la transazione
+
+// ** block - Informazioni sul blocco attuale **
+now; // ora corrente (approssimatamente), alias di block.timestamp (in Unix time)
+// Da notare come può essere manipolata dai miner, quindi da usare con cautela
+
+block.number; // numero del blocco attuale
+block.difficulty; // difficulty del blocco attuale
+block.blockhash(1); // restituisce un bytes32, funziona solo per i 256 blocchi
+// più recenti
+block.gasLimit();
+
+// ** storage - Memoria persistente (in hash) **
+storage['abc'] = 'def'; // mappa da parole di 256 bit a parole di 256 bit
+
+
+// 4. FUNZIONI E ALTRO
+// A. Funzioni
+// Una semplice funzione
+function increment(uint x) returns (uint) {
+ x += 1;
+ return x;
+}
+
+// Le funzioni possono restituire molti valori,
+// e visto che i valori di ritorno vengono dichiarati prima
+// non è richiesta un'instruzione return esplicita
+function increment(uint x, uint y) returns (uint x, uint y) {
+ x += 1;
+ y += 1;
+}
+// Chiama la funzione di cui sopra
+uint (a,b) = increment(1,1);
+
+// 'view' (un alias di 'constant')
+// indica che la funzione non cambia / non può cambiare le variabili persistenti
+// Le funzioni definite con view vengono eseguite localmente, non sulla blockchain
+// N.B. la keyword constant sarà presto deprecata
+uint y = 1;
+
+function increment(uint x) view returns (uint x) {
+ x += 1;
+ y += 1; // questa riga fallirebbe
+ // y è una variabile di stato, e non può essere cambiata in una funzione di view
+}
+
+// 'pure' è più restrittivo di 'view' o 'constant', e non
+// permette nemmeno di leggere le varaibili di stato
+// In realtà è più complicato, per approfondire su
+// view/pure:
+// http://solidity.readthedocs.io/en/develop/contracts.html#view-functions
+
+// Modificatori di visibilità per le funzioni
+// Possono essere messi vicino a 'view' e includono:
+// public - visibile esternamente e internamente (di default per function)
+// external - visible solo esternamente (comprese le chiamate fatte con this.)
+// private - visibile solo dal contratto attuale
+// internal - visibile solo dal contratto attuale, e da quelli che ne derivano
+
+// Di solito è una buona idea marcare esplicitamente ogni funzione
+
+// Le funzioni sono hoisted e si può assegnare una funzione ad una variabile
+function a() {
+ var z = b;
+ b();
+}
+
+function b() {
+
+}
+
+// Tutte le funzioni che ricevono ether devono essere dichiarate come 'payable'
+function depositEther() public payable {
+ balances[msg.sender] += msg.value;
+}
+
+
+// I cicli sono da preferire alla ricorsione
+// (la profondità massima dello stack è 1024)
+// Inoltre, non impostare dei loop senza limiti,
+// perchè potresti raggiungere il limite per il gas
+
+// B. Eventi
+// Gli eventi notificano a terze parti; è facile ispezionare e
+// accedere agli eventi al di fuori della blockchain (con client leggeri);
+// Tipicamente si dichiarano dopo i parametri del contratto
+
+// Tipicamente, sono capitalized - si usa Log come prefisso per esplicitarli
+// meglio ed evitare che si confondano con una chiamata a funzione
+
+// Dichiarazione
+event LogSent(address indexed from, address indexed to, uint amount);
+// Da notare le prime lettere maiuscole
+
+// Chiamata
+LogSent(from, to, amount);
+
+/**
+
+Una terza parte esterna (entità o contratto), può osservare usando
+la libreria Javascript Web3:
+
+// Quel che se segue è codice Javascript, non Solidity
+Coin.LogSent().watch({}, '', function(error, result) {
+ if (!error) {
+ console.log("Trasferimento valuta: " + result.args.amount +
+ " la valuta è stata mandata da " + result.args.from +
+ " a " + result.args.to + ".");
+ console.log("I saldi ora sono:\n" +
+ "Mittente: " + Coin.balances.call(result.args.from) +
+ "Destinatario: " + Coin.balances.call(result.args.to));
+ }
+}
+**/
+
+// È prassi che un contratto dipenda da un altro (es. che dipenda
+// dai tassi di cambio forniti da un altro contratto)
+
+// C. Modifier
+// I modifier validano gli input per conto dele funzioni verificando ad esempio
+// il saldo minimo o l'autenticazione dell'utente;
+// sono simili alle calusole di guardia di altri linguaggi
+
+// '_' (underscore) viene spesso posizionato nell'ultima riga del body, e indica
+// che la funzione chiamata dev'essere posizionata lì
+modifier onlyAfter(uint _time) { require (now >= _time); _; }
+modifier onlyOwner { require(msg.sender == owner) _; }
+// usate comunemente negli automi a stati finiti
+modifier onlyIfStateA (State currState) { require(currState == State.A) _; }
+
+// Si dichiarano appena dopo la definizione di una funzione
+function changeOwner(newOwner)
+onlyAfter(someTime)
+onlyOwner()
+onlyIfState(State.A)
+{
+ owner = newOwner;
+}
+
+// L'underscore può essere messo prima della fine del body,
+// ma un'istruzione di ritorno esplicita lo salterebbe,
+// quindi è da usare con cautela
+modifier checkValue(uint amount) {
+ _;
+ if (msg.value > amount) {
+ uint amountToRefund = amount - msg.value;
+ msg.sender.transfer(amountToRefund);
+ }
+}
+
+
+// 6. ISTRUZIONI CONDIZIONALI E CICLI
+
+// Troviamo tutte le istruzioni condizionali di base - incluse if/else, for,
+// while, break, continue e return - ma non c'è lo switch
+
+// La sintassi è la stessa di javascript, ma non esiste la conversione di tipo
+// in booleano dai non booleani (bisogna usare gli operatori logici per
+// ottenere il valore boolean)
+
+// Bisogna stare attenti i loop che iterano in base al comportamento
+// dell'utente, dato che i contratti hanno un tetto massimo di gas
+// per blocco di codice e falliranno se lo superano
+// Ad esempio:
+for(uint x = 0; x < refundAddressList.length; x++) {
+ refundAddressList[x].transfer(SOME_AMOUNT);
+}
+
+// Ci sono due errori nel codice precedente:
+// 1. Un fallimento su una transfer impedisce al loop di completare tutti
+// i cicli, bloccando dei soldi;
+// 2. Questo loop potrebbe essere arbitrariamente lungo (si basa sul numero
+// degli utenti che hanno diritto al rimborso), quindi potrebbe fallire sempre
+// se supera il tetto massimo di gas per blocco;
+// Come soluzione, si permette agli utenti di prelevare
+// individualmente dal loro subaccount e segnare il rimborso come riscosso
+// Ad es. preferire pull payments ai push payment
+
+
+// 7. OGGETTI/CONTRATTI
+
+// A. Invocare un contratto esterno
+contract InfoFeed {
+ function info() payable returns (uint ret) { return 42; }
+}
+
+contract Consumer {
+ InfoFeed feed; // punta ad un contratto sulla blockchain
+
+ // Imposta il feed sull'istanza del contratto esistente
+ function setFeed(address addr) {
+ // fare attenzione alla conversione di tipo automatica;
+ // il costruttore non viene invocato
+ feed = InfoFeed(addr);
+ }
+
+ // Imposta il feed ad una nuova istanza del contratto
+ function createNewFeed() {
+ feed = new InfoFeed(); // viene creata una nuova istanza;
+ // viene invocato il costruttore
+ }
+
+ function callFeed() {
+ // le parentesi finali invocano il contratto, opzionalmente si può
+ // specificare un importo custom di ether o di gas
+ feed.info.value(10).gas(800)();
+ }
+}
+
+// B. ereditarietà
+
+// Conta l'ordine, l'ultimo contratto ereditato (es. 'def') può andare
+// in overriding su parti dei contratti precedentemente ereditati
+contract MyContract is abc, def("a custom argument to def") {
+
+// Funzione in overriding
+ function z() {
+ if (msg.sender == owner) {
+ def.z(); // invoca la funzione overridden da def
+ super.z(); // chiama la funzione overridden del padre
+ }
+ }
+}
+
+// Funzioni astratte
+function someAbstractFunction(uint x);
+// non possono essere compilate, vengono usate nei contratti base/astratti
+// e poi verranno implementate
+
+// C. Import
+
+import "filename";
+import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol";
+
+
+// 8. ALTRE KEYWORD
+
+// A. Selfdestruct
+// autodistrugge il contratto corrente, inviando i fondi ad un indirizzo
+// (di solito il creatore)
+selfdestruct(SOME_ADDRESS);
+
+// rimuove il codice e quanto in memoria dal blocco corrente e da tutti i blocchi futuri
+// aiuta ad alleggerire i client, ma le informazioni precedenti continueranno
+// a persistere sulla blockchain
+
+// È un pattern comune, permette al proprietario di terminare il contratto
+// e ricevere i fondi rimasti
+function remove() {
+ if(msg.sender == creator) { // Solo il creatore del contratto può farlo
+ selfdestruct(creator); // Cessa l'attività del contratto, trasferisce i fondi
+ }
+}
+
+// Si potrebbe voler disattivare il contratto manualmente, anzichè usare una
+// selfdestruct (gli ether inviati ad un contratto dopo una selfdestruct
+// vengono persi)
+
+
+// 9. NOTE SUL DESIGN DEI CONTRATTI
+
+// A. Offruscamento
+// Tutte le variabili sono pubblicamente visibili sulla blockchain, quindi
+// qualsiasi informazione privata ha bisogno di essere offruscata (es. hash con una
+// chiave segreta)
+
+// Passi: 1. Impegnarsi pagare una certa cifra, 2. Rivelare l'impegno preso
+keccak256("una_puntata_d_asta", "un segreto"); // impegno
+
+// in futuro, l'invocazione della funzione rivelatrice del contratto
+// mostrerà la puntata con il segreto che produce lo SHA3
+reveal(100, "ilMioSegreto");
+
+// B. Ottimizzazione della memoria (storage)
+// Scrivere dati sulla blockchain può essere costoso visto che vengono
+// conservati per sempre; siamo incoraggati ad usare la memoria in maniera
+// scaltra (un giorno la compilazione migliorerà, ma per ora è vantaggioso
+// pianificare le strutture dati da usare - e conservarne il minimo possibile
+// sulla blockchain)
+
+// I costi per conservare cose come array multidimensionali sono spesso alti
+// (costa conservare dati - non dichiarare variabili parzialmente vuote)
+
+// C. Accesso ai dati sulla blockchain
+// Non si può impedire alle persone o ai computer di leggere il contenuto
+// o lo stato delle transazioni
+
+// Anche se 'private' non permette agli altri *contratti* di leggere alcune
+// informazioni direttamente, qualsiasi altro attore può leggerle
+// sulla blockchain
+
+// Tutti i dati, dall'inizio, vegono conservati sulla blockchain e
+// tutti possono accedere alle informazioni passate e ai cambiamenti futuri
+
+// D. Oracle e dati esterni
+// Gli oracle consentono di interagire con i tuoi smart contract
+// al di fuori della blockchain.
+// Vengono usati per ricevere informazioni dal mondo reale, mandare
+// richieste post al mondo reale o vice versa.
+
+// Anche le implementazioni che sfruttano l'ora vengono fatte attraverso
+// gli oracle, visto che i contratti devono essere chiamati direttamente e
+// non possono fare una "subscribe" a un certo orario.
+// Data la decentralizzazione degli smart contract, vorrai ricevere informazioni
+// in maniera decentralizzata, altrimenti rischi di ricreare l'accentramento
+// che la progettazione degli smart contract si prefigge di prevenire.
+
+// Il modo migliore di ottenere e usare dati decentralizzati già pronti
+// è attraverso i Chainlink Data Feeds
+// https://docs.chain.link/docs/get-the-latest-price
+// Possiamo fare riferimento a certe informazioni della blockchain
+// che sono già state aggregate da più fonti e ridistribuite on-chain,
+// usandole come "banche dati" di fonti di informazione.
+
+// Puoi vedere altri esempi che effettuano chiamate alle API qui:
+// https://docs.chain.link/docs/make-a-http-get-request
+
+// E ovviamente puoi costruire la tua rete di orace, ma assicurati di sapere
+// quant'è accentrata o decentralizzata la tua applicazione.
+
+// Mettere su una rete di oracle per conto tuo
+
+// E. Cron Job
+// I contratti devono essere chiamati manualmente per gestire lo scheduling
+// in base all'orario; si può creare un codice esterno che li pinghi reglarmente
+// oppure fornire degli incentivi (ether) a qualcun'altro che lo faccia
+
+// F. Pattern Observer
+// Un pattern observer permette di iscriversi come osservatore e
+// registrare una funzione che verrà chiamata dall'oracle
+// (N.B. l'oracolo paga perchè sia eseguita quest'azione)
+// Ci sono alcune somoglianze nella registrazione con Pub/sub
+
+// Questo è un contratto astratto che importano sia il client che il server
+// Il client dovrebbe implementarlo
+contract SomeOracleCallback {
+ function oracleCallback(int _value, uint _time, bytes32 info) external;
+}
+
+contract SomeOracle {
+ SomeOracleCallback[] callbacks; // array di tutti gli osservatori iscritti
+
+ // Osservatori iscritti
+ function addSubscriber(SomeOracleCallback a) {
+ callbacks.push(a);
+ }
+
+ function notify(value, time, info) private {
+ for(uint i = 0;i < callbacks.length; i++) {
+ // tutti gli osservatori iscritti dovranno implementare la oracleCallback
+ callbacks[i].oracleCallback(value, time, info);
+ }
+ }
+
+ function doSomething() public {
+ // Codice che fa qualcosa
+
+ // Notifica a tutti gli iscritti
+ notify(_value, _time, _info);
+ }
+}
+
+// Il contratto client può aggiungersi agli iscritti (con addSubscriber)
+// del contratto SomeOracle, importando SomeOracleCallback
+
+// G. Automi a stati finiti
+// vedi l'esempio sotto che usa enum per lo stato e il modifier inState
+```
+
+Prova l'esempio completo qui sotto [usando remix e la `Javascript VM`](https://remix.ethereum.org/#version=soljson-v0.6.6+commit.6c089d02.js&optimize=false&evmVersion=null&gist=3d12cd503dcedfcdd715ef61f786be0b&runs=200)
+
+```javascript
+// *** ESEMPIO: Un esempio di crowdfunding (molto simile a Kickstarter) ***
+// ** START EXAMPLE **
+
+// CrowdFunder.sol
+pragma solidity ^0.6.6;
+
+/// @title CrowdFunder
+/// @author nemild
+contract CrowdFunder {
+ // Variabili impostate alla creazione dal creatore
+ address public creator;
+ address payable public fundRecipient; // il creatore può essere diverso
+ // da chi riceve i fondi, che dev'essere payable
+ uint public minimumToRaise; // è richiesto per chiedere il finanziamento,
+ // altrimenti tutti ricevono un rimborso
+ string campaignUrl;
+ byte version = "1";
+
+ // Strutture dati
+ enum State {
+ Fundraising,
+ ExpiredRefund,
+ Successful
+ }
+ struct Contribution {
+ uint amount;
+ address payable contributor;
+ }
+
+ // Variabili di stato
+ State public state = State.Fundraising; // inizializzato alla creazione
+ uint public totalRaised;
+ uint public raiseBy;
+ uint public completeAt;
+ Contribution[] contributions;
+
+ event LogFundingReceived(address addr, uint amount, uint currentTotal);
+ event LogWinnerPaid(address winnerAddress);
+
+ modifier inState(State _state) {
+ require(state == _state);
+ _;
+ }
+
+ modifier isCreator() {
+ require(msg.sender == creator);
+ _;
+ }
+
+ // Aspetta 24 settimane dopo l'ultimo cambio di stato prima di consentire
+ // che in contratto venga distrutto
+ modifier atEndOfLifecycle() {
+ require(((state == State.ExpiredRefund || state == State.Successful) &&
+ completeAt + 24 weeks < now));
+ _;
+ }
+
+ function crowdFund(
+ uint timeInHoursForFundraising,
+ string memory _campaignUrl,
+ address payable _fundRecipient,
+ uint _minimumToRaise)
+ public
+ {
+ creator = msg.sender;
+ fundRecipient = _fundRecipient;
+ campaignUrl = _campaignUrl;
+ minimumToRaise = _minimumToRaise;
+ raiseBy = now + (timeInHoursForFundraising * 1 hours);
+ }
+
+ function contribute()
+ public
+ payable
+ inState(State.Fundraising)
+ returns(uint256 id)
+ {
+ contributions.push(
+ Contribution({
+ amount: msg.value,
+ contributor: msg.sender
+ }) // usiamo un array per iterare
+ );
+ totalRaised += msg.value;
+
+ emit LogFundingReceived(msg.sender, msg.value, totalRaised);
+
+ checkIfFundingCompleteOrExpired();
+ return contributions.length - 1; // restituisce l'id
+ }
+
+ function checkIfFundingCompleteOrExpired()
+ public
+ {
+ if (totalRaised > minimumToRaise) {
+ state = State.Successful;
+ payOut();
+
+ // qui si può incentivare chi ha provocato il cambiamento di stato
+ } else if ( now > raiseBy ) {
+ state = State.ExpiredRefund; // ora i finanziatori possono avere
+ // il rimborso chiamando getRefund(id)
+ }
+ completeAt = now;
+ }
+
+ function payOut()
+ public
+ inState(State.Successful)
+ {
+ fundRecipient.transfer(address(this).balance);
+ LogWinnerPaid(fundRecipient);
+ }
+
+ function getRefund(uint256 id)
+ inState(State.ExpiredRefund)
+ public
+ returns(bool)
+ {
+ require(contributions.length > id && id >= 0 && contributions[id].amount != 0 );
+
+ uint256 amountToRefund = contributions[id].amount;
+ contributions[id].amount = 0;
+
+ contributions[id].contributor.transfer(amountToRefund);
+
+ return true;
+ }
+
+ function removeContract()
+ public
+ isCreator()
+ atEndOfLifecycle()
+ {
+ selfdestruct(msg.sender);
+ // il creatore riceve tutti i fondi che non sono stati riscossi
+ }
+}
+// ** END EXAMPLE **
+
+```
+
+Qualche altra funzionalità.
+
+```javascript
+// 10. ATRE FUNZIONALITA' NATIVE
+
+// Unità di valuta
+// La valuta viene definita partendo dai wei, l'unità più piccola di Ether
+uint minAmount = 1 wei;
+uint a = 1 finney; // 1 ether == 1000 finney
+// Per altre unità, vedi: http://ether.fund/tool/converter
+
+// Unità temporali
+1 == 1 second
+1 minutes == 60 seconds
+
+// Le unità temporali si possono moltiplicare, visto che non vegono salvate
+// nelle variabili
+uint x = 5;
+(x * 1 days); // 5 giorni
+
+// Attenzione ad usare l'operatore di uguaglianza con i secondi/anni bisestili
+// (sono da preferire maggiore/minore di)
+
+// Crittografia
+// Tutte le stringhe che vengono passate vengono concatenate prima di
+// calcolare l'hash
+sha3("ab", "cd");
+ripemd160("abc");
+sha256("def");
+
+
+// 11.SICUREZZA
+
+// I bug possono essere disastrosi per i contratti Ethereum e anche
+// i pattern comuni di Solidity potrebbero riverlarsi degli antipattern
+
+// Dai un'occhiata ai link sulla sicurezza alla fine di questo documento
+
+
+// 12. FUNZIONI DI BASSO LIVELLO
+// call - è di basso livello, non viene usata spesso, perchè non è type safe
+successBoolean = someContractAddress.call('function_name', 'arg1', 'arg2');
+
+// callcode - Il codice all'indirizzo target viene eseguito *contestualmente*
+// alla chiamata del contratto
+// fornisce le stesse funzionalità di una libreria
+someContractAddress.callcode('function_name');
+
+
+// 13. NOTE SULLO STILE
+// Basate sulla guida allo stile PEP8 di Python
+// Guida completa allo stile: http://solidity.readthedocs.io/en/develop/style-guide.html
+
+// Riassunto veloce:
+// 4 spazi per l'indentazione
+// Due righe per separare la dichiarazione dei contratti
+// (e altre dichirazioni top level)
+// Evitare spazi ai lati interni delle parentesi tonde
+// Si possono omettere le parentesi graffe per statement monolinea (if, for, etc)
+// L'else dovrebbe essere posizionato su una riga a se
+
+// 14. COMMENTI NATSPEC
+// usati per la documentazione, commenti e UI esterne
+
+// Natspec dei contratti - sempre sopra la definizione del contratto
+/// @title Titolo del contratto
+/// @author Nome dell'autore
+
+// Natspec delle funzioni
+/// @notice informazioni su quel che fa la funzione; mostrate quando la funzione viene eseguita
+/// @dev Documentazione della funzione per sviluppatori
+
+// Natspec dei parametri/valori di ritorno delle funzioni
+/// @param someParam Una descrizione di quel che fa il parametro
+/// @return Descrizione del valore di ritorno
+```
+
+## Risorse Aggiuntive
+- [Documentazione di Solidity](https://solidity.readthedocs.org/en/latest/)
+- [Tutorial Chainlink per Principianti](https://docs.chain.link/docs/beginners-tutorial)
+- [Best Practice per Smart Contract](https://github.com/ConsenSys/smart-contract-best-practices)
+- [Superblocks Lab - Ambiente di sviluppo su browser per Solidity](https://lab.superblocks.com/)
+- [EthFiddle - Il JsFiddle di Solidity](https://ethfiddle.com/)
+- [Solidity Editor su Browser](https://remix.ethereum.org/)
+- [Chat Room Gitter su Solidity](https://gitter.im/ethereum/solidity)
+- [Stategie di Progettazione Modulare per Contratti Ethereum](https://docs.erisindustries.com/tutorials/solidity/)
+- [Documentazione Chainlink](https://docs.chain.link/docs/getting-started)
+
+## Framework di Sviluppo per Smart Contract
+- [Hardhat](https://hardhat.org/)
+- [Brownie](https://github.com/eth-brownie/brownie)
+- [Truffle](https://www.trufflesuite.com/)
+
+## Librerie importanti
+- [Zeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts): Librerie che offrono pattern comuni (crowdfuding, safemath, ecc)
+- [Chainlink](https://github.com/smartcontractkit/chainlink): Codice che permette di interagire con dati esterni
+
+## Contratti di esempio
+- [Dapp Bin](https://github.com/ethereum/dapp-bin)
+- [Esempi Defi](https://github.com/PatrickAlphaC/chainlink_defi)
+- [Solidity per Contratti a Piccoli Passi](https://github.com/fivedogit/solidity-baby-steps/tree/master/contracts)
+- [Contratti ConsenSys](https://github.com/ConsenSys/dapp-store-contracts)
+- [Lo stato delle Dapp](http://dapps.ethercasts.com/)
+
+## Sicurezza
+- [Pensando Alla Sicurezza Degli Smart Contract](https://blog.ethereum.org/2016/06/19/thinking-smart-contract-security/)
+- [Sicurezza Degli Smart Contract](https://blog.ethereum.org/2016/06/10/smart-contract-security/)
+- [Blog Distribuito di Hacking](http://hackingdistributed.com/)
+
+## Stile
+- [Guida allo Stile di Solidity](http://solidity.readthedocs.io/en/latest/style-guide.html): La guida allo stile di Ethereum deriva in gran parte dalla guida allo stile [PEP 8](https://www.python.org/dev/peps/pep-0008/) di Python.
+
+## Editor
+- [Remix](https://remix.ethereum.org/)
+- [Emacs Modalità Solidity](https://github.com/ethereum/emacs-solidity)
+- [Vim Solidity](https://github.com/tomlion/vim-solidity)
+- Snippet per gli Editor ([Ultisnips format](https://gist.github.com/nemild/98343ce6b16b747788bc))
+
+## Cose da fare in futuro
+- Nuove keyword: protected, inheritable
+- Lista dei design pattern comuni (throttling, RNG, upgrade di versione)
+-Anti patterns comuni sulla sicurezza
+
+Sentiti libero di mandare una pull request con qualsiasi modifica - o scrivi una mail a nemild -/at-/ gmail
diff --git a/it-it/sql-it.html.markdown b/it-it/sql-it.html.markdown
new file mode 100644
index 00000000..7db2eec1
--- /dev/null
+++ b/it-it/sql-it.html.markdown
@@ -0,0 +1,112 @@
+---
+language: SQL
+filename: learnsql-it.sql
+contributors:
+ - ["Bob DuCharme", "http://bobdc.com/"]
+translators:
+ - ["Christian Grasso", "https://grasso.io"]
+lang: it-it
+---
+
+Structured Query Language (SQL) è un linguaggio standard ISO per la creazione e la gestione
+di database organizzati in un insieme di tabelle. Le diverse implementazioni aggiungono
+spesso le proprie estensioni al linguaggio base ([confronto tra le diverse implementazioni](http://troels.arvin.dk/db/rdbms/))
+
+Le diverse implementazioni forniscono inoltre un prompt per inserire in modo interattivo i comandi
+o eseguire il contenuto di uno script.
+
+I comandi di seguito lavorano sul [database di esempio MySQL](https://dev.mysql.com/doc/employee/en/)
+disponibile su [GitHub](https://github.com/datacharmer/test_db). I file .sql contengono liste di comandi
+simili a quelli mostrati di seguito, che creano e riempiono delle tabelle con dati di un'azienda fittizia.
+Il comando per eseguire questi script può variare in base all'implementazione in uso.
+
+
+```sql
+-- I commenti iniziano con due trattini. Ogni comando va terminato con il punto e virgola
+
+-- SQL è case-insensitive per quanto riguarda i comandi; in genere si
+-- preferisce scriverli in maiuscolo per distinguerli dai nomi di
+-- database, tabelle e colonne
+
+-- Crea ed elimina un database. I nomi di database e tabelle sono case-sensitive
+CREATE DATABASE someDatabase;
+DROP DATABASE someDatabase;
+
+-- Lista dei database disponibili
+SHOW DATABASES;
+
+-- Attiva uno specifico database
+USE employees;
+
+-- Seleziona tutte le righe e le colonne dalla tabella departments
+SELECT * FROM departments;
+
+-- Seleziona tutte le righe della tabella departments,
+-- ma solo le colonne dept_no e dept_name.
+-- È possibile suddividere i comandi su più righe.
+SELECT dept_no,
+ dept_name FROM departments;
+
+-- Seleziona solo le prime 5 righe della tabella departments.
+SELECT * FROM departments LIMIT 5;
+
+-- Ottiene la colonna dept_name della tabella departments
+-- solo per le righe il cui valore di dept_name contiene 'en'.
+SELECT dept_name FROM departments WHERE dept_name LIKE '%en%';
+
+-- Ottiene tutte le colonne della tabella departments
+-- solo per le righe che hanno un dept_name formato da una 'S'
+-- seguita esattamente da altri 4 caratteri
+SELECT * FROM departments WHERE dept_name LIKE 'S____';
+
+-- Seleziona i valori di title dalla tabella titles eliminando i duplicati
+SELECT DISTINCT title FROM titles;
+
+-- Come sopra, ma i valori sono ordinati alfabeticamente
+SELECT DISTINCT title FROM titles ORDER BY title;
+
+-- Mostra il numero di righe della tabella departments
+SELECT COUNT(*) FROM departments;
+
+-- Mostra il numero di righe della tabella departments
+-- il cui valore di dept_name contiene 'en'.
+SELECT COUNT(*) FROM departments WHERE dept_name LIKE '%en%';
+
+-- Un JOIN tra più tabelle: la tabella titles contiene gli
+-- incarichi lavorativi associati ad un certo numero di impiegato.
+-- Con il JOIN utilizziamo il numero di impiegato per ottenere
+-- le informazioni ad esso associate nella tabella employees.
+-- (Inoltre selezioniamo solo le prime 10 righe)
+
+SELECT employees.first_name, employees.last_name,
+ titles.title, titles.from_date, titles.to_date
+FROM titles INNER JOIN employees ON
+ employees.emp_no = titles.emp_no LIMIT 10;
+
+-- Mostra tutte le tabelle di tutti i database.
+-- Spesso le implementazioni forniscono degli shortcut per questo comando
+SELECT * FROM INFORMATION_SCHEMA.TABLES
+WHERE TABLE_TYPE='BASE TABLE';
+
+-- Crea una tabella tablename1, con due colonne, per il database in uso.
+-- Per le colonne specifichiamo il tipo di dato (stringa di max 20 caratteri)
+CREATE TABLE tablename1 (fname VARCHAR(20), lname VARCHAR(20));
+
+-- Inserisce una riga nella tabella tablename1. I valori devono essere
+-- appropriati per la definizione della tabella
+INSERT INTO tablename1 VALUES('Richard','Mutt');
+
+-- In tablename1, modifica il valore di fname a 'John'
+-- in tutte le righe che hanno come lname 'Mutt'.
+UPDATE tablename1 SET fname='John' WHERE lname='Mutt';
+
+-- Elimina tutte le righe di tablename1
+-- il cui lname inizia per 'M'.
+DELETE FROM tablename1 WHERE lname like 'M%';
+
+-- Elimina tutte le righe della tabella tablename1
+DELETE FROM tablename1;
+
+-- Elimina la tabella tablename1
+DROP TABLE tablename1;
+```
diff --git a/it-it/toml-it.html.markdown b/it-it/toml-it.html.markdown
index 99082048..beb63096 100644
--- a/it-it/toml-it.html.markdown
+++ b/it-it/toml-it.html.markdown
@@ -1,276 +1,276 @@
----
-language: toml
-filename: learntoml-it.toml
-contributors:
- - ["Alois de Gouvello", "https://github.com/aloisdg"]
-translators:
- - ["Christian Grasso", "https://grasso.io"]
-lang: it-it
----
-
-TOML è l'acronimo di _Tom's Obvious, Minimal Language_. È un linguaggio per la
-serializzazione di dati, progettato per i file di configurazione.
-
-È un'alternativa a linguaggi come YAML e JSON, che punta ad essere più leggibile
-per le persone. Allo stesso tempo, TOML può essere utilizzato in modo abbastanza
-semplice nella maggior parte dei linguaggi di programmazione, in quanto è
-progettato per essere tradotto senza ambiguità in una hash table.
-
-Tieni presente che TOML è ancora in fase di sviluppo, e la sua specifica non è
-ancora stabile. Questo documento utilizza TOML 0.4.0.
-
-```toml
-# I commenti in TOML sono fatti così.
-
-################
-# TIPI SCALARI #
-################
-
-# Il nostro oggetto root (corrispondente all'intero documento) sarà una mappa,
-# anche chiamata dizionario, hash o oggetto in altri linguaggi.
-
-# La key, il simbolo di uguale e il valore devono trovarsi sulla stessa riga,
-# eccetto per alcuni tipi di valori.
-key = "value"
-stringa = "ciao"
-numero = 42
-float = 3.14
-boolean = true
-data = 1979-05-27T07:32:00-08:00
-notazScientifica = 1e+12
-"puoi utilizzare le virgolette per la key" = true # Puoi usare " oppure '
-"la key può contenere" = "lettere, numeri, underscore e trattini"
-
-############
-# Stringhe #
-############
-
-# Le stringhe possono contenere solo caratteri UTF-8 validi.
-# Possiamo effettuare l'escape dei caratteri, e alcuni hanno delle sequenze
-# di escape compatte. Ad esempio, \t corrisponde al TAB.
-stringaSemplice = "Racchiusa tra virgolette. \"Usa il backslash per l'escape\"."
-
-stringaMultiriga = """
-Racchiusa da tre virgolette doppie all'inizio e
-alla fine - consente di andare a capo."""
-
-stringaLiteral = 'Virgolette singole. Non consente di effettuare escape.'
-
-stringaMultirigaLiteral = '''
-Racchiusa da tre virgolette singole all'inizio e
-alla fine - consente di andare a capo.
-Anche in questo caso non si può fare escape.
-Il primo ritorno a capo viene eliminato.
- Tutti gli altri spazi aggiuntivi
- vengono mantenuti.
-'''
-
-# Per i dati binari è consigliabile utilizzare Base64 e
-# gestirli manualmente dall'applicazione.
-
-##########
-# Interi #
-##########
-
-## Gli interi possono avere o meno un segno (+, -).
-## Non si possono inserire zero superflui all'inizio.
-## Non è possibile inoltre utilizzare valori numerici
-## non rappresentabili con una sequenza di cifre.
-int1 = +42
-int2 = 0
-int3 = -21
-
-## Puoi utilizzare gli underscore per migliorare la leggibilità.
-## Fai attenzione a non inserirne due di seguito.
-int4 = 5_349_221
-int5 = 1_2_3_4_5 # VALIDO, ma da evitare
-
-#########
-# Float #
-#########
-
-# I float permettono di rappresentare numeri decimali.
-flt1 = 3.1415
-flt2 = -5e6
-flt3 = 6.626E-34
-
-###########
-# Boolean #
-###########
-
-# I valori boolean (true/false) devono essere scritti in minuscolo.
-bool1 = true
-bool2 = false
-
-############
-# Data/ora #
-############
-
-data1 = 1979-05-27T07:32:00Z # Specifica RFC 3339/ISO 8601 (UTC)
-data2 = 1979-05-26T15:32:00+08:00 # RFC 3339/ISO 8601 con offset
-
-######################
-# TIPI DI COLLECTION #
-######################
-
-#########
-# Array #
-#########
-
-array1 = [ 1, 2, 3 ]
-array2 = [ "Le", "virgole", "sono", "delimitatori" ]
-array3 = [ "Non", "unire", "tipi", "diversi" ]
-array4 = [ "tutte", 'le stringhe', """hanno lo stesso""", '''tipo''' ]
-array5 = [
- "Gli spazi vuoti", "sono", "ignorati"
-]
-
-###########
-# Tabelle #
-###########
-
-# Le tabelle (o hash table o dizionari) sono collection di coppie key/value.
-# Iniziano con un nome tra parentesi quadre su una linea separata.
-# Le tabelle vuote (senza alcun valore) sono valide.
-[tabella]
-
-# Tutti i valori che si trovano sotto il nome della tabella
-# appartengono alla tabella stessa (finchè non ne viene creata un'altra).
-# L'ordine di questi valori non è garantito.
-[tabella-1]
-key1 = "una stringa"
-key2 = 123
-
-[tabella-2]
-key1 = "un'altra stringa"
-key2 = 456
-
-# Utilizzando i punti è possibile creare delle sottotabelle.
-# Ogni parte suddivisa dai punti segue le regole delle key per il nome.
-[tabella-3."sotto.tabella"]
-key1 = "prova"
-
-# Ecco l'equivalente JSON della tabella precedente:
-# { "tabella-3": { "sotto.tabella": { "key1": "prova" } } }
-
-# Gli spazi non vengono considerati, ma è consigliabile
-# evitare di usare spazi superflui.
-[a.b.c] # consigliato
-[ d.e.f ] # identico a [d.e.f]
-
-# Non c'è bisogno di creare le tabelle superiori per creare una sottotabella.
-# [x] queste
-# [x.y] non
-# [x.y.z] servono
-[x.y.z.w] # per creare questa tabella
-
-# Se non è stata già creata prima, puoi anche creare
-# una tabella superiore più avanti.
-[a.b]
-c = 1
-
-[a]
-d = 2
-
-# Non puoi definire una key o una tabella più di una volta.
-
-# ERRORE
-[a]
-b = 1
-
-[a]
-c = 2
-
-# ERRORE
-[a]
-b = 1
-
-[a.b]
-c = 2
-
-# I nomi delle tabelle non possono essere vuoti.
-[] # NON VALIDO
-[a.] # NON VALIDO
-[a..b] # NON VALIDO
-[.b] # NON VALIDO
-[.] # NON VALIDO
-
-##################
-# Tabelle inline #
-##################
-
-tabelleInline = { racchiuseData = "{ e }", rigaSingola = true }
-punto = { x = 1, y = 2 }
-
-####################
-# Array di tabelle #
-####################
-
-# Un array di tabelle può essere creato utilizzando due parentesi quadre.
-# Tutte le tabelle con questo nome saranno elementi dell'array.
-# Gli elementi vengono inseriti nell'ordine in cui si trovano.
-
-[[prodotti]]
-nome = "array di tabelle"
-sku = 738594937
-tabelleVuoteValide = true
-
-[[prodotti]]
-
-[[prodotti]]
-nome = "un altro item"
-sku = 284758393
-colore = "grigio"
-
-# Puoi anche creare array di tabelle nested. Le sottotabelle con doppie
-# parentesi quadre apparterranno alla tabella più vicina sopra di esse.
-
-[[frutta]]
- nome = "mela"
-
- [frutto.geometria]
- forma = "sferica"
- nota = "Sono una proprietà del frutto"
-
- [[frutto.colore]]
- nome = "rosso"
- nota = "Sono un oggetto di un array dentro mela"
-
- [[frutto.colore]]
- nome = "verde"
- nota = "Sono nello stesso array di rosso"
-
-[[frutta]]
- nome = "banana"
-
- [[frutto.colore]]
- nome = "giallo"
- nota = "Anche io sono un oggetto di un array, ma dentro banana"
-```
-
-Ecco l'equivalente JSON dell'ultima tabella:
-
-```json
-{
- "frutta": [
- {
- "nome": "mela",
- "geometria": { "forma": "sferica", "nota": "..."},
- "colore": [
- { "nome": "rosso", "nota": "..." },
- { "nome": "verde", "nota": "..." }
- ]
- },
- {
- "nome": "banana",
- "colore": [
- { "nome": "giallo", "nota": "..." }
- ]
- }
- ]
-}
-```
-
-### Altre risorse
-
-+ [Repository ufficiale di TOML](https://github.com/toml-lang/toml)
+---
+language: toml
+filename: learntoml-it.toml
+contributors:
+ - ["Alois de Gouvello", "https://github.com/aloisdg"]
+translators:
+ - ["Christian Grasso", "https://grasso.io"]
+lang: it-it
+---
+
+TOML è l'acronimo di _Tom's Obvious, Minimal Language_. È un linguaggio per la
+serializzazione di dati, progettato per i file di configurazione.
+
+È un'alternativa a linguaggi come YAML e JSON, che punta ad essere più leggibile
+per le persone. Allo stesso tempo, TOML può essere utilizzato in modo abbastanza
+semplice nella maggior parte dei linguaggi di programmazione, in quanto è
+progettato per essere tradotto senza ambiguità in una hash table.
+
+Tieni presente che TOML è ancora in fase di sviluppo, e la sua specifica non è
+ancora stabile. Questo documento utilizza TOML 0.4.0.
+
+```toml
+# I commenti in TOML sono fatti così.
+
+################
+# TIPI SCALARI #
+################
+
+# Il nostro oggetto root (corrispondente all'intero documento) sarà una mappa,
+# anche chiamata dizionario, hash o oggetto in altri linguaggi.
+
+# La key, il simbolo di uguale e il valore devono trovarsi sulla stessa riga,
+# eccetto per alcuni tipi di valori.
+key = "value"
+stringa = "ciao"
+numero = 42
+float = 3.14
+boolean = true
+data = 1979-05-27T07:32:00-08:00
+notazScientifica = 1e+12
+"puoi utilizzare le virgolette per la key" = true # Puoi usare " oppure '
+"la key può contenere" = "lettere, numeri, underscore e trattini"
+
+############
+# Stringhe #
+############
+
+# Le stringhe possono contenere solo caratteri UTF-8 validi.
+# Possiamo effettuare l'escape dei caratteri, e alcuni hanno delle sequenze
+# di escape compatte. Ad esempio, \t corrisponde al TAB.
+stringaSemplice = "Racchiusa tra virgolette. \"Usa il backslash per l'escape\"."
+
+stringaMultiriga = """
+Racchiusa da tre virgolette doppie all'inizio e
+alla fine - consente di andare a capo."""
+
+stringaLiteral = 'Virgolette singole. Non consente di effettuare escape.'
+
+stringaMultirigaLiteral = '''
+Racchiusa da tre virgolette singole all'inizio e
+alla fine - consente di andare a capo.
+Anche in questo caso non si può fare escape.
+Il primo ritorno a capo viene eliminato.
+ Tutti gli altri spazi aggiuntivi
+ vengono mantenuti.
+'''
+
+# Per i dati binari è consigliabile utilizzare Base64 e
+# gestirli manualmente dall'applicazione.
+
+##########
+# Interi #
+##########
+
+## Gli interi possono avere o meno un segno (+, -).
+## Non si possono inserire zero superflui all'inizio.
+## Non è possibile inoltre utilizzare valori numerici
+## non rappresentabili con una sequenza di cifre.
+int1 = +42
+int2 = 0
+int3 = -21
+
+## Puoi utilizzare gli underscore per migliorare la leggibilità.
+## Fai attenzione a non inserirne due di seguito.
+int4 = 5_349_221
+int5 = 1_2_3_4_5 # VALIDO, ma da evitare
+
+#########
+# Float #
+#########
+
+# I float permettono di rappresentare numeri decimali.
+flt1 = 3.1415
+flt2 = -5e6
+flt3 = 6.626E-34
+
+###########
+# Boolean #
+###########
+
+# I valori boolean (true/false) devono essere scritti in minuscolo.
+bool1 = true
+bool2 = false
+
+############
+# Data/ora #
+############
+
+data1 = 1979-05-27T07:32:00Z # Specifica RFC 3339/ISO 8601 (UTC)
+data2 = 1979-05-26T15:32:00+08:00 # RFC 3339/ISO 8601 con offset
+
+######################
+# TIPI DI COLLECTION #
+######################
+
+#########
+# Array #
+#########
+
+array1 = [ 1, 2, 3 ]
+array2 = [ "Le", "virgole", "sono", "delimitatori" ]
+array3 = [ "Non", "unire", "tipi", "diversi" ]
+array4 = [ "tutte", 'le stringhe', """hanno lo stesso""", '''tipo''' ]
+array5 = [
+ "Gli spazi vuoti", "sono", "ignorati"
+]
+
+###########
+# Tabelle #
+###########
+
+# Le tabelle (o hash table o dizionari) sono collection di coppie key/value.
+# Iniziano con un nome tra parentesi quadre su una linea separata.
+# Le tabelle vuote (senza alcun valore) sono valide.
+[tabella]
+
+# Tutti i valori che si trovano sotto il nome della tabella
+# appartengono alla tabella stessa (finchè non ne viene creata un'altra).
+# L'ordine di questi valori non è garantito.
+[tabella-1]
+key1 = "una stringa"
+key2 = 123
+
+[tabella-2]
+key1 = "un'altra stringa"
+key2 = 456
+
+# Utilizzando i punti è possibile creare delle sottotabelle.
+# Ogni parte suddivisa dai punti segue le regole delle key per il nome.
+[tabella-3."sotto.tabella"]
+key1 = "prova"
+
+# Ecco l'equivalente JSON della tabella precedente:
+# { "tabella-3": { "sotto.tabella": { "key1": "prova" } } }
+
+# Gli spazi non vengono considerati, ma è consigliabile
+# evitare di usare spazi superflui.
+[a.b.c] # consigliato
+[ d.e.f ] # identico a [d.e.f]
+
+# Non c'è bisogno di creare le tabelle superiori per creare una sottotabella.
+# [x] queste
+# [x.y] non
+# [x.y.z] servono
+[x.y.z.w] # per creare questa tabella
+
+# Se non è stata già creata prima, puoi anche creare
+# una tabella superiore più avanti.
+[a.b]
+c = 1
+
+[a]
+d = 2
+
+# Non puoi definire una key o una tabella più di una volta.
+
+# ERRORE
+[a]
+b = 1
+
+[a]
+c = 2
+
+# ERRORE
+[a]
+b = 1
+
+[a.b]
+c = 2
+
+# I nomi delle tabelle non possono essere vuoti.
+[] # NON VALIDO
+[a.] # NON VALIDO
+[a..b] # NON VALIDO
+[.b] # NON VALIDO
+[.] # NON VALIDO
+
+##################
+# Tabelle inline #
+##################
+
+tabelleInline = { racchiuseData = "{ e }", rigaSingola = true }
+punto = { x = 1, y = 2 }
+
+####################
+# Array di tabelle #
+####################
+
+# Un array di tabelle può essere creato utilizzando due parentesi quadre.
+# Tutte le tabelle con questo nome saranno elementi dell'array.
+# Gli elementi vengono inseriti nell'ordine in cui si trovano.
+
+[[prodotti]]
+nome = "array di tabelle"
+sku = 738594937
+tabelleVuoteValide = true
+
+[[prodotti]]
+
+[[prodotti]]
+nome = "un altro item"
+sku = 284758393
+colore = "grigio"
+
+# Puoi anche creare array di tabelle nested. Le sottotabelle con doppie
+# parentesi quadre apparterranno alla tabella più vicina sopra di esse.
+
+[[frutta]]
+ nome = "mela"
+
+ [frutto.geometria]
+ forma = "sferica"
+ nota = "Sono una proprietà del frutto"
+
+ [[frutto.colore]]
+ nome = "rosso"
+ nota = "Sono un oggetto di un array dentro mela"
+
+ [[frutto.colore]]
+ nome = "verde"
+ nota = "Sono nello stesso array di rosso"
+
+[[frutta]]
+ nome = "banana"
+
+ [[frutto.colore]]
+ nome = "giallo"
+ nota = "Anche io sono un oggetto di un array, ma dentro banana"
+```
+
+Ecco l'equivalente JSON dell'ultima tabella:
+
+```json
+{
+ "frutta": [
+ {
+ "nome": "mela",
+ "geometria": { "forma": "sferica", "nota": "..."},
+ "colore": [
+ { "nome": "rosso", "nota": "..." },
+ { "nome": "verde", "nota": "..." }
+ ]
+ },
+ {
+ "nome": "banana",
+ "colore": [
+ { "nome": "giallo", "nota": "..." }
+ ]
+ }
+ ]
+}
+```
+
+### Altre risorse
+
++ [Repository ufficiale di TOML](https://github.com/toml-lang/toml)
diff --git a/it-it/zfs-it.html.markdown b/it-it/zfs-it.html.markdown
new file mode 100644
index 00000000..c1307e67
--- /dev/null
+++ b/it-it/zfs-it.html.markdown
@@ -0,0 +1,361 @@
+---
+category: tool
+tool: zfs
+contributors:
+ - ["sarlalian", "http://github.com/sarlalian"]
+translators:
+ - ["Christian Grasso","https://grasso.io"]
+filename: LearnZfs-it.txt
+lang: it-it
+---
+
+
+[ZFS](http://open-zfs.org/wiki/Main_Page) è un sistema di storage che combina file system
+tradizionali e volume manager in un unico strumento. ZFS utilizza della terminologia
+specifica, diversa da quella usata da altri sistemi di storage, ma le sue funzioni lo
+rendono un ottimo tool per gli amministratori di sistema.
+
+
+## Concetti base di ZFS
+
+### Virtual Device
+
+Un VDEV è simile a un dispositivo gestito da una scheda RAID. Esistono diversi tipi di
+VDEV che offrono diversi vantaggi, tra cui ridondanza e velocità. In generale,
+i VDEV offrono una maggiore affidabilità rispetto alle schede RAID. Si sconsiglia di
+utilizzare ZFS insieme a RAID, poichè ZFS è fatto per gestire direttamente i dischi fisici.
+
+Tipi di VDEV:
+
+* stripe (disco singolo, senza ridondanza)
+* mirror (mirror su più dischi)
+* raidz
+ * raidz1 (parity a 1 disco, simile a RAID 5)
+ * raidz2 (parity a 2 dischi, simile a RAID 6)
+ * raidz3 (parity a 3 dischi)
+* disk
+* file (non consigliato in production poichè aggiunge un ulteriore filesystem)
+
+I dati vengono distribuiti tra tutti i VDEV presenti nella Storage Pool, per cui un maggior
+numero di VDEV aumenta le operazioni al secondo (IOPS).
+
+### Storage Pool
+
+Le Storage Pool di ZFS sono un'astrazione del livello inferiore (VDEV) e consentono di
+separare il filesystem visibile agli utenti dal layout reale dei dischi.
+
+### Dataset
+
+I dataset sono simili ai filesystem tradizionali, ma con molte più funzioni che rendono
+vantaggioso l'utilizzo di ZFS. I dataset supportano il [Copy on Write](https://en.wikipedia.org/wiki/Copy-on-write)
+gli snapshot, la gestione delle quota, compressione e deduplicazione.
+
+
+### Limiti
+
+Una directory può contenere fino a 2^48 file, ognuno dei quali di 16 exabyte.
+Una storage pool può contenere fino a 256 zettabyte (2^78), e può essere distribuita
+tra 2^64 dispositivi. Un singolo host può avere fino a 2^64 storage pool.
+
+
+## Comandi
+
+### Storage Pool
+
+Azioni:
+
+* List (lista delle pool)
+* Status (stato)
+* Destroy (rimozione)
+* Get/Set (lettura/modifica proprietà)
+
+Lista delle zpool
+
+```bash
+# Crea una zpool raidz
+$ zpool create bucket raidz1 gpt/zfs0 gpt/zfs1 gpt/zfs2
+
+# Lista delle zpool
+$ zpool list
+NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
+zroot 141G 106G 35.2G - 43% 75% 1.00x ONLINE -
+
+# Informazioni dettagliate su una zpool
+$ zpool list -v zroot
+NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
+zroot 141G 106G 35.2G - 43% 75% 1.00x ONLINE -
+ gptid/c92a5ccf-a5bb-11e4-a77d-001b2172c655 141G 106G 35.2G - 43% 75%
+```
+
+Stato delle zpool
+
+```bash
+# Informazioni sullo stato delle zpool
+$ zpool status
+ pool: zroot
+ state: ONLINE
+ scan: scrub repaired 0 in 2h51m with 0 errors on Thu Oct 1 07:08:31 2015
+config:
+
+ NAME STATE READ WRITE CKSUM
+ zroot ONLINE 0 0 0
+ gptid/c92a5ccf-a5bb-11e4-a77d-001b2172c655 ONLINE 0 0 0
+
+errors: No known data errors
+
+# "Scrubbing" (correzione degli errori)
+$ zpool scrub zroot
+$ zpool status -v zroot
+ pool: zroot
+ state: ONLINE
+ scan: scrub in progress since Thu Oct 15 16:59:14 2015
+ 39.1M scanned out of 106G at 1.45M/s, 20h47m to go
+ 0 repaired, 0.04% done
+config:
+
+ NAME STATE READ WRITE CKSUM
+ zroot ONLINE 0 0 0
+ gptid/c92a5ccf-a5bb-11e4-a77d-001b2172c655 ONLINE 0 0 0
+
+errors: No known data errors
+```
+
+Proprietà delle zpool
+
+```bash
+
+# Proprietà di una zpool (gestite dal sistema o dall'utente)
+$ zpool get all zroot
+NAME PROPERTY VALUE SOURCE
+zroot size 141G -
+zroot capacity 75% -
+zroot altroot - default
+zroot health ONLINE -
+...
+
+# Modifica di una proprietà
+$ zpool set comment="Dati" zroot
+$ zpool get comment
+NAME PROPERTY VALUE SOURCE
+tank comment - default
+zroot comment Dati local
+```
+
+Rimozione di una zpool
+
+```bash
+$ zpool destroy test
+```
+
+
+### Dataset
+
+Azioni:
+
+* Create
+* List
+* Rename
+* Delete
+* Get/Set (proprietà)
+
+Creazione dataset
+
+```bash
+# Crea un dataset
+$ zfs create tank/root/data
+$ mount | grep data
+tank/root/data on /data (zfs, local, nfsv4acls)
+
+# Crea un sottodataset
+$ zfs create tank/root/data/stuff
+$ mount | grep data
+tank/root/data on /data (zfs, local, nfsv4acls)
+tank/root/data/stuff on /data/stuff (zfs, local, nfsv4acls)
+
+
+# Crea un volume
+$ zfs create -V zroot/win_vm
+$ zfs list zroot/win_vm
+NAME USED AVAIL REFER MOUNTPOINT
+tank/win_vm 4.13G 17.9G 64K -
+```
+
+Lista dei dataset
+
+```bash
+# Lista dei dataset
+$ zfs list
+NAME USED AVAIL REFER MOUNTPOINT
+zroot 106G 30.8G 144K none
+zroot/ROOT 18.5G 30.8G 144K none
+zroot/ROOT/10.1 8K 30.8G 9.63G /
+zroot/ROOT/default 18.5G 30.8G 11.2G /
+zroot/backup 5.23G 30.8G 144K none
+zroot/home 288K 30.8G 144K none
+...
+
+# Informazioni su un dataset
+$ zfs list zroot/home
+NAME USED AVAIL REFER MOUNTPOINT
+zroot/home 288K 30.8G 144K none
+
+# Lista degli snapshot
+$ zfs list -t snapshot
+zroot@daily-2015-10-15 0 - 144K -
+zroot/ROOT@daily-2015-10-15 0 - 144K -
+zroot/ROOT/default@daily-2015-10-15 0 - 24.2G -
+zroot/tmp@daily-2015-10-15 124K - 708M -
+zroot/usr@daily-2015-10-15 0 - 144K -
+zroot/home@daily-2015-10-15 0 - 11.9G -
+zroot/var@daily-2015-10-15 704K - 1.42G -
+zroot/var/log@daily-2015-10-15 192K - 828K -
+zroot/var/tmp@daily-2015-10-15 0 - 152K -
+```
+
+Rinominare un dataset
+
+```bash
+$ zfs rename tank/root/home tank/root/old_home
+$ zfs rename tank/root/new_home tank/root/home
+```
+
+Eliminare un dataset
+
+```bash
+# I dataset non possono essere eliminati se hanno degli snapshot
+$ zfs destroy tank/root/home
+```
+
+Lettura/modifica proprietà
+
+```bash
+# Tutte le proprietà di un dataset
+$ zfs get all zroot/usr/home │157 # Create Volume
+NAME PROPERTY VALUE SOURCE │158 $ zfs create -V zroot/win_vm
+zroot/home type filesystem - │159 $ zfs list zroot/win_vm
+zroot/home creation Mon Oct 20 14:44 2014 - │160 NAME USED AVAIL REFER MOUNTPOINT
+zroot/home used 11.9G - │161 tank/win_vm 4.13G 17.9G 64K -
+zroot/home available 94.1G - │162 ```
+zroot/home referenced 11.9G - │163
+zroot/home mounted yes -
+...
+
+# Proprietà specifica
+$ zfs get compression zroot/usr/home
+NAME PROPERTY VALUE SOURCE
+zroot/home compression off default
+
+# Modifica di una proprietà
+$ zfs set compression=gzip-9 mypool/lamb
+
+# Specifiche proprietà per tutti i dataset
+$ zfs list -o name,quota,reservation
+NAME QUOTA RESERV
+zroot none none
+zroot/ROOT none none
+zroot/ROOT/default none none
+zroot/tmp none none
+zroot/usr none none
+zroot/home none none
+zroot/var none none
+...
+```
+
+
+### Snapshot
+
+Gli snapshot sono una delle funzioni più importanti di ZFS:
+
+* Lo spazio occupato è la differenza tra il filesystem e l'ultimo snapshot
+* Il tempo di creazione è di pochi secondi
+* Possono essere ripristinati alla velocità di scrittura del disco
+* Possono essere automatizzati molto semplicemente
+
+Azioni:
+
+* Create
+* Delete
+* Rename
+* Access
+* Send / Receive
+* Clone
+
+
+Creazione di uno snapshot
+
+```bash
+# Crea uno snapshot di un singolo dataset
+zfs snapshot tank/home/sarlalian@now
+
+# Crea uno snapshot di un dataset e dei suoi sottodataset
+$ zfs snapshot -r tank/home@now
+$ zfs list -t snapshot
+NAME USED AVAIL REFER MOUNTPOINT
+tank/home@now 0 - 26K -
+tank/home/sarlalian@now 0 - 259M -
+tank/home/alice@now 0 - 156M -
+tank/home/bob@now 0 - 156M -
+...
+```
+
+Eliminazione di uno snapshot
+
+```bash
+# Elimina uno snapshot
+$ zfs destroy tank/home/sarlalian@now
+
+# Elimina uno snapshot ricorsivamente
+$ zfs destroy -r tank/home/sarlalian@now
+
+```
+
+Rinominare uno snapshot
+
+```bash
+$ zfs rename tank/home/sarlalian@now tank/home/sarlalian@today
+$ zfs rename tank/home/sarlalian@now today
+
+$ zfs rename -r tank/home@now @yesterday
+```
+
+Accedere ad uno snapshot
+
+```bash
+# Utilizzare il comando cd come per una directory
+$ cd /home/.zfs/snapshot/
+```
+
+Invio e ricezione
+
+```bash
+# Backup di uno snapshot su un file
+$ zfs send tank/home/sarlalian@now | gzip > backup_file.gz
+
+# Invia uno snapshot ad un altro dataset
+$ zfs send tank/home/sarlalian@now | zfs recv backups/home/sarlalian
+
+# Invia uno snapshot ad un host remoto
+$ zfs send tank/home/sarlalian@now | ssh root@backup_server 'zfs recv tank/home/sarlalian'
+
+# Invia l'intero dataset e i suoi snapshot ad un host remoto
+$ zfs send -v -R tank/home@now | ssh root@backup_server 'zfs recv tank/home'
+```
+
+Clonare gli snapshot
+
+```bash
+# Clona uno snapshot
+$ zfs clone tank/home/sarlalian@now tank/home/sarlalian_new
+
+# Rende il clone indipendente dallo snapshot originale
+$ zfs promote tank/home/sarlalian_new
+```
+
+### Letture aggiuntive (in inglese)
+
+* [BSDNow's Crash Course on ZFS](http://www.bsdnow.tv/tutorials/zfs)
+* [FreeBSD Handbook on ZFS](https://www.freebsd.org/doc/en_US.ISO8859-1/books/handbook/zfs.html)
+* [BSDNow's Crash Course on ZFS](http://www.bsdnow.tv/tutorials/zfs)
+* [Oracle's Tuning Guide](http://www.oracle.com/technetwork/articles/servers-storage-admin/sto-recommended-zfs-settings-1951715.html)
+* [OpenZFS Tuning Guide](http://open-zfs.org/wiki/Performance_tuning)
+* [FreeBSD ZFS Tuning Guide](https://wiki.freebsd.org/ZFSTuningGuide)