diff options
Diffstat (limited to 'it-it')
-rw-r--r-- | it-it/c++-it.html.markdown | 283 | ||||
-rw-r--r-- | it-it/python-it.html.markdown | 199 |
2 files changed, 435 insertions, 47 deletions
diff --git a/it-it/c++-it.html.markdown b/it-it/c++-it.html.markdown index 92ebc165..4af30176 100644 --- a/it-it/c++-it.html.markdown +++ b/it-it/c++-it.html.markdown @@ -8,6 +8,7 @@ contributors: - ["Connor Waters", "http://github.com/connorwaters"] translators: - ["Robert Margelli", "http://github.com/sinkswim/"] + - ["Tommaso Pifferi", "http://github.com/neslinesli93/"] lang: it-it --- @@ -151,7 +152,7 @@ namespace Primo { namespace Secondo { void foo() { - printf("Questa è Secondo::foo\n") + printf("Questa è Secondo::foo\n"); } } @@ -805,6 +806,94 @@ void faiQualcosaConUnFile(const std::string& nomefile) // sono tutti automaticamente distrutti con i loro contenuti quando escono dalla visibilità. // - I mutex usano lock_guard e unique_lock +// I contenitori che utilizzano chiavi non-primitive (classi personalizzate) +// richiedono la funzione di confronto nell'oggetto stesso, o tramite un puntatore a funzione. +// Le chiavi primitive hanno funzioni di confronto già definite, ma puoi sovrascriverle. +class Foo { +public: + int j; + Foo(int a) : j(a) {} +}; +struct funzioneDiConfronto { + bool operator()(const Foo& a, const Foo& b) const { + return a.j < b.j; + } +}; +// Questo non è permesso, anche se qualche compilatore potrebbe non dare problemi +//std::map<Foo, int> fooMap; +std::map<Foo, int, funzioneDiConfronto> fooMap; +fooMap[Foo(1)] = 1; +fooMap.find(Foo(1)); -- vero + +/////////////////////////////////////// +// Espressioni Lambda (C++11 e superiori) +/////////////////////////////////////// + +// Le espressioni lambda (più semplicemente "lambda") sono utilizzate +// per definire una funzione anonima nel punto in cui viene invocata, o +// dove viene passata come argomento ad una funzione + +// Ad esempio, consideriamo l'ordinamento di un vettore costituito da una +// coppia di interi, utilizzando il secondo elemento per confrontare +vector<pair<int, int> > tester; +tester.push_back(make_pair(3, 6)); +tester.push_back(make_pair(1, 9)); +tester.push_back(make_pair(5, 0)); + +// Passiamo una lambda come terzo argomento alla funzione di ordinamento +// `sort` è contenuta nell'header <algorithm> +sort(tester.begin(), tester.end(), [](const pair<int, int>& lhs, const pair<int, int>& rhs) { + return lhs.second < rhs.second; +}); + +// Nota bene la sintassi utilizzata nelle lambda: +// [] serve per "catturare" le variabili. +// La "Lista di Cattura" definisce tutte le variabili esterne che devono essere disponibili +// all'interno della funzione, e in che modo. +// La lista può contenere: +// 1. un valore: [x] +// 2. un riferimento: [&x] +// 3. qualunque variabile nello scope corrente, per riferimento [&] +// 4. qualunque variabile nello scope corrente, per valore [=] +// Esempio: + +vector<int> id_cani; +// numero_cani = 3; +for(int i = 0; i < 3; i++) { + id_cani.push_back(i); +} + +int pesi[3] = {30, 50, 10}; + +// Mettiamo che vuoi ordinare id_cani in base al peso dei cani +// Alla fine, id_cani sarà: [2, 0, 1] + +// Le lambda vengono in aiuto + +sort(id_cani.begin(), id_cani.end(), [&pesi](const int &lhs, const int &rhs) { + return pesi[lhs] < pesi[rhs]; +}); +// Nota come abbiamo catturato "pesi" per riferimento nell'esempio. +// Altre informazioni sulle lambda in C++: http://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11 + +/////////////////////////////// +// Ciclo For semplificato(C++11 e superiori) +/////////////////////////////// + +// Puoi usare un ciclo for per iterare su un tipo di dato contenitore +int arr[] = {1, 10, 3}; + +for(int elem: arr) { + cout << elem << endl; +} + +// Puoi usare "auto" senza preoccuparti del tipo degli elementi nel contenitore +// Ad esempio: + +for(auto elem: arr) { + // Fai qualcosa con `elem` +} + /////////////////////// // Roba divertente ////////////////////// @@ -855,20 +944,188 @@ Foo f1; f1 = f2; -// Come deallocare realmente le risorse all'interno di un vettore: -class Foo { ... }; -vector<Foo> v; -for (int i = 0; i < 10; ++i) - v.push_back(Foo()); +/////////////////////////////////////// +// Tuple (C++11 e superiori) +/////////////////////////////////////// + +#include<tuple> + +// Concettualmente le tuple sono simili alle strutture del C, ma invece di avere +// i membri rappresentati con dei nomi, l'accesso agli elementi avviene tramite +// il loro ordine all'interno della tupla. + +// Cominciamo costruendo una tupla. +// Inserire i valori in una tupla +auto prima = make_tuple(10, 'A'); +const int maxN = 1e9; +const int maxL = 15; +auto seconda = make_tuple(maxN, maxL); + +// Vediamo gli elementi contenuti nella tupla "prima" +cout << get<0>(prima) << " " << get<1>(prima) << "\n"; // stampa : 10 A + +// Vediamo gli elementi contenuti nella tupla "seconda" +cout << get<0>(seconda) << " " << get<1>(seconda) << "\n"; // stampa: 1000000000 15 + +// Estrarre i valori dalla tupla, salvandoli nelle variabili +int primo_intero; +char primo_char; +tie(primo_intero, primo_char) = prima; +cout << primo_intero << " " << primo_char << "\n"; // stampa : 10 A + +// E' possibile creare tuple anche in questo modo +tuple<int, char, double> terza(11, 'A', 3.14141); + +// tuple_size ritorna il numero di elementi in una tupla (come constexpr) +cout << tuple_size<decltype(terza)>::value << "\n"; // stampa: 3 + +// tuple_cat concatena gli elementi di tutte le tuple, nell'esatto ordine +// in cui sono posizionati all'interno delle tuple stesse +auto tupla_concatenata = tuple_cat(prima, seconda, terza); +// tupla_concatenata diventa = (10, 'A', 1e9, 15, 11, 'A' ,3.14141) + +cout << get<0>(tupla_concatenata) << "\n"; // stampa: 10 +cout << get<3>(tupla_concatenata) << "\n"; // stampa: 15 +cout << get<5>(tupla_concatenata) << "\n"; // stampa: 'A' + + +///////////////////// +// Contenitori +///////////////////// + +// I Contenitori della "Standard Template Library", ovvero la libreria standard +// dei template contenuti nel C++, sono template predefiniti. +// I Contenitori si occupano di come allocare lo spazio per gli elementi contenuti, +// e forniscono funzioni per accedervi e manipolarli + +// Vediamo alcuni tipi di contenitori: + +// Vector (array dinamici/vettori) +// Permettono di definire un vettore, o una lista di oggetti, a runtime +#include<vector> +vector<Tipo_Dato> nome_vettore; // usato per inizializzare un vettore +cin >> val; +nome_vettore.push_back(val); // inserisce il valore di "val" nel vettore + +// Per iterare in un vettore, abbiamo due possibilità: +// Ciclo normale +for(int i=0; i<nome_vettore.size(); i++) +// Cicla dall'indice zero fino all'ultimo + +// Iteratore +vector<Tipo_Dato>::iterator it; // inizializza l'iteratore per il vettore +for(it=nome_vettore.begin(); it!=nome_vettore.end();++it) +// Nota che adesso non cicla più sugli indici, ma direttamente sugli elementi! + +// Per accedere agli elementi del vettore +// Operatore [] +var = nome_vettore[indice]; // Assegna a "var" il valore del vettore all'indice dato + + +// Set (insiemi) +// Gli insiemi sono contenitori che memorizzano elementi secondo uno specifico ordine. +// Gli insiemi vengono per lo più utilizzati per memorizzare valori unici, secondo +// un ordine, senza scrivere ulteriore codice. + +#include<set> +set<int> insieme; // Inizializza un insieme di interi +insieme.insert(30); // Inserisce il valore 30 nell'insieme +insieme.insert(10); // Inserisce il valore 10 nell'insieme +insieme.insert(20); // Inserisce il valore 20 nell'insieme +insieme.insert(30); // Inserisce il valore 30 nell'insieme +// Gli elementi dell'insieme sono: +// 10 20 30 + +// Per cancellare un elemento +insieme.erase(20); // Cancella l'elemento con valore 20 +// L'insieme contiene adesso: 10 30 + +// Per iterare su un insieme, usiamo gli iteratori +set<int>::iterator it; +for(it=insieme.begin();it<insieme.end();it++) { + cout << *it << endl; +} +// Stampa: +// 10 +// 30 + +// Per svuotare il contenitore usiamo il metodo "clear" +insieme.clear(); +cout << insieme.size(); +// Stampa: 0 + +// Nota: per permettere elementi duplicati, possiamo usare "multiset" + +// Map (mappa/tabella di hash) +// Le mappe servono per memorizzare un elemento, detto chiave, a cui viene +// associato un valore, il tutto secondo uno specifico ordine. + +#include<map> +map<char, int> mia_mappa; // Inizializza una mappa che usa i char come chiave, e gli interi come valore + +mia_mappa.insert(pair<char,int>('A',1)); +// Inserisce il valore 1 per la chiave A +mia_mappa.insert(pair<char,int>('Z',26)); +// Inserisce il valore 26 per la chiave Z + +// Per iterare +map<char,int>::iterator it; +for (it=mia_mappa.begin(); it!=mia_mappa.end(); ++it) + std::cout << it->first << "->" << it->second << '\n'; +// Stampa: +// A->1 +// Z->26 + +// Per trovare il valore corrispondente ad una data chiave +it = mia_mappa.find('Z'); +cout << it->second; +// Stampa: 26 + + +/////////////////////////////////// +// Operatori logici e bitwise(bit-a-bit) +////////////////////////////////// + +// La maggior parte di questi operatori in C++ sono gli stessi degli altri linguaggi + +// Operatori logici + +// Il C++ usa la "Short-circuit evaluation" per le espressioni booleane. Cosa significa? +// In pratica, in una condizione con due argomenti, il secondo viene considerato solo se +// il primo non basta a determinate il valore finale dell'espresione. + +true && false // Effettua il **and logico** e ritorna falso +true || false // Effettua il **or logico** e ritorna vero +! true // Effettua il **not logico** e ritorna falso + +// Invece di usare i simboli, si possono usare le keyword equivalenti +true and false // Effettua il **and logico** e ritorna falso +true or false // Effettua il **or logico** e ritorna vero +not true // Effettua il **not logico** e ritorna falso + +// Operatori bitwise(bit-a-bit) + +// **<<** Operatore di Shift a Sinistra +// << sposta i bit a sinistra +4 << 1 // Sposta a sinistra di 1 i bit di 4, ottenendo 8 +// x << n in pratica realizza x * 2^n + + +// **>>** Operatore di Shift a Destra +// >> sposta i bit a destra +4 >> 1 // Sposta a destra di 1 i bit di 4, ottenendo 2 +// x >> n in pratica realizza x / 2^n -// La riga seguente riduce la dimensione di v a 0, ma il distruttore non -// viene chiamato e dunque le risorse non sono deallocate! -v.empty(); -v.push_back(Foo()); // Il nuovo valore viene copiato nel primo Foo che abbiamo inserito +~4 // Effettua il NOT bit-a-bit +4 | 3 // Effettua il OR bit-a-bit +4 & 3 // Effettua il AND bit-a-bit +4 ^ 3 // Effettua il XOR bit-a-bit -// Distrugge realmente tutti i valori dentro v. Vedi la sezione riguardante gli -// oggetti temporanei per capire come mai funziona così. -v.swap(vector<Foo>()); +// Le keyword equivalenti sono +compl 4 // Effettua il NOT bit-a-bit +4 bitor 3 // Effettua il OR bit-a-bit +4 bitand 3 // Effettua il AND bit-a-bit +4 xor 3 // Effettua il XOR bit-a-bit ``` Letture consigliate: diff --git a/it-it/python-it.html.markdown b/it-it/python-it.html.markdown index 3a4099e7..71f6dc1c 100644 --- a/it-it/python-it.html.markdown +++ b/it-it/python-it.html.markdown @@ -4,9 +4,11 @@ contributors: - ["Louie Dinh", "http://ldinh.ca"] - ["Amin Bandali", "http://aminbandali.com"] - ["Andre Polykanine", "https://github.com/Oire"] + - ["evuez", "http://github.com/evuez"] filename: learnpython.py 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 @@ -15,8 +17,15 @@ pseudocodice eseguibile. Feedback sono altamente apprezzati! Potete contattarmi su [@louiedinh](http://twitter.com/louiedinh) oppure [at] [google's email service] -Nota: Questo articolo è valido solamente per Python 2.7, ma dovrebbe andar bene anche per -Python 2.x. Per Python 3.x, dai un'occhiata a [Python 3 tutorial](http://learnxinyminutes.com/docs/python3/). +Nota: questo articolo è riferito a Python 2.7 in modo specifico, ma dovrebbe andar +bene anche per Python 2.x. Python 2.7 sta raggiungendo il "fine vita", ovvero non sarà +più supportato nel 2020. Quindi è consigliato imparare Python utilizzando Python 3. +Per maggiori informazioni su Python 3.x, dai un'occhiata al [tutorial di Python 3](http://learnxinyminutes.com/docs/python3/). + +E' possibile anche scrivere codice compatibile sia con Python 2.7 che con Python 3.x, +utilizzando [il modulo `__future__`](https://docs.python.org/2/library/__future__.html) di Python. +Il modulo `__future__` permette di scrivere codice in Python 3, che può essere eseguito +utilizzando Python 2: cosa aspetti a vedere il tutorial di Python 3? ```python @@ -54,6 +63,12 @@ Python 2.x. Per Python 3.x, dai un'occhiata a [Python 3 tutorial](http://learnxi -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 @@ -112,11 +127,19 @@ not False # => True # Una stringa può essere considerata come una lista di caratteri "Questa è una stringa"[0] # => 'Q' -# % può essere usato per formattare le stringhe, in questo modo: -"%s possono essere %s" % ("le stringhe", "interpolate") +# 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") @@ -132,9 +155,17 @@ 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. - -# None, 0, e stringhe/liste vuote sono tutte considerate a False. -# Tutti gli altri valori sono True + +# 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 @@ -144,7 +175,13 @@ bool("") # => False #################################################### # Python ha una funzione di stampa -print "Sono Python. Piacere di conoscerti!" +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 @@ -155,6 +192,7 @@ una_variabile # => 5 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 @@ -207,6 +245,17 @@ li + altra_li # => [1, 2, 3, 4, 5, 6] # 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 @@ -227,8 +276,9 @@ tup[:2] # => (1, 2) # 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 -d, e, f = 4, 5, 6 +g = 4, 5, 6 # => (4, 5, 6) # Guarda come è facile scambiare due valori e, d = d, e # d è ora 5 ed e è ora 4 @@ -250,6 +300,9 @@ filled_dict.keys() # => ["tre", "due", "uno"] 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 @@ -298,6 +351,15 @@ 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 @@ -405,7 +467,7 @@ aggiungi(y=6, x=5) # Le parole chiave come argomenti possono arrivare in ogni # Puoi definire funzioni che accettano un numero variabile di argomenti posizionali -# che verranno interpretati come tuple se non usi il * +# che verranno interpretati come tuple usando il * def varargs(*args): return args @@ -413,7 +475,7 @@ 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 se non usi ** +# come argomento, che saranno interpretati come un dizionario usando ** def keyword_args(**kwargs): return kwargs @@ -449,19 +511,19 @@ def pass_all_the_args(*args, **kwargs): # Funzioni Scope x = 5 -def setX(num): +def set_x(num): # La variabile locale x non è uguale alla variabile globale x x = num # => 43 print x # => 43 -def setGlobalX(num): +def set_global_x(num): global x print x # => 5 x = num # la variabile globable x è ora 6 print x # => 6 -setX(43) -setGlobalX(6) +set_x(43) +set_global_x(6) # Python ha funzioni di prima classe def create_adder(x): @@ -474,15 +536,22 @@ 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 @@ -502,6 +571,9 @@ class Human(object): # 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) @@ -517,6 +589,21 @@ class Human(object): 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") @@ -536,6 +623,16 @@ 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 @@ -570,34 +667,67 @@ math.sqrt == m.sqrt == sqrt # => True 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 #################################################### -# I generatori ti aiutano a fare codice pigro +# 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 -# Un generatore crea valori al volo. -# Invece di generare e ritornare tutti i valori in una volta ne crea uno in ciascuna -# iterazione. Ciò significa che i valori più grandi di 15 non saranno considerati in -# double_numbers. -# Nota xrange è un generatore che fa la stessa cosa di range. -# Creare una lista 1-900000000 occuperebbe molto tempo e spazio. -# xrange crea un oggetto generatore xrange invece di creare l'intera lista -# come fa range. -# Usiamo un underscore finale nel nome delle variabile quando vogliamo usare un nome -# che normalmente colliderebbe con una parola chiave di python -xrange_ = xrange(1, 900000000) - -# raddoppierà tutti i numeri fino a che result >=30 non sarà trovato -for i in double_numbers(xrange_): - print i - if i >= 30: +# 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 @@ -605,7 +735,6 @@ for i in double_numbers(xrange_): # ritornato from functools import wraps - def beg(target_function): @wraps(target_function) def wrapper(*args, **kwargs): @@ -634,11 +763,13 @@ print say(say_please=True) # Puoi comprarmi una birra? Per favore! Sono povero * [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.6/) +* [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 |