Python Standard Library
Ovviamente l'utilità dei moduli non è solo organizzativa, ma... storica!!! Immaginate se qualcuno avesse raccolto tutte le funzioni più "fighe" scritte in Python e le avesse catalogate in gruppi omogenei; ad esempio le funzioni aritmetiche, le funzioni per le stringhe, le funzioni per data e ora e così via.
Beh... qualcuno lo ha fatto! Ed ha creato la Python Standard Library.
Essa non è nient'altro che una collezione di moduli, inclusi per semplicità in qualunque installazione Python,
che quindi possiamo utilizzare semplicemente scrivendo import nomeModulo
.
Fighissimo!
Elenco qui alcuni fra i moduli più comuni, indicando il nome e una descrizione sommaria:
random
: Generazioni di numeri "pseudo-casuali"math
: Operazioni matematiche comunitime
: Gestione Tempodatetime
: Gestione Data e Orapathlib
: Accesso a file e directoriescsv
: Lettura e Scrittura su file csv
Se questi elencati non vi bastano e siete curiosi su quanti ce ne siano effettivamente, provate a consultare la documentazione ufficiale.
Ancora non vi basta? Bene! Allora sappiate che ci sono altre migliaia di moduli pieni zeppi di funzioni utili per gli incarichi più disparati, già catalogati e liberi di essere utilizzati da chiunque! La differenza con i precedenti è che questi non fanno parte della Python Standard Library, ma sono elencati semplicemente nel Python Package Index.
Ma questa è la storia del prossimo capitolo (Moduli PyPi). Per adesso, guardiamo qualcuno dei moduli standard!
Suggerimento
La documentazione ufficiale (in inglese) di ogni modulo è inserita nel modulo stesso: per ottenerla, dato il modulo "NomeModulo", basta scrivere nell'interprete:
>>> import NomeModulo
>>> dir(NomeModulo)
>>> help(NomeModulo.FunzioneInteressante)
Prova con uno dei moduli elencati sopra!!!
random
Il modulo random
serve per operazioni che richiedono una certa "casualità", anche se il termine corretto sarebbe "pseudocasualità".
Vediamo una carrellata delle funzioni pià interessanti del modulo. Per tutte le altre... ormai dovreste aver capito!!!
Funzione randint
Dato un intervallo (con entrambi gli estremi inclusi) seleziona un numero pseudocasuale al suo interno
Funzione choice
Applicata ad una sequenza generica ritorna un elemento casuale della stessa (utile per le estrazioni)
import random
lista = [ 1, 2, 3, 4, 5]
numero = random.choice(lista) # scegle un elemento della lista (a caso)
print(numero) # scrive.... (boh, ad esempio)... 4
Funzione shuffle
funziona solo con le liste e serve per mescolare la lista passata come parametro. Ovviamente non ritorna valori.
import random
lista = [ 1, 2, 3, 4, 5]
random.shuffle(lista) # mischia la lista
print(lista) # ad esempio: [4, 3, 1, 5, 2]
Non è affatto difficile! Provate a fare i seguenti esercizi aiutandovi anche con la documentazione integrata.
Esercizio 621 (randint)
Riempire una lista con 5 numeri casuali fra 1 e 90 diversi fra loro. Pronta la cartella della tombola!!!
Esercizio 622 (randint)
Generare 5 numeri casuali fra 0 e 1 con 2 cifre esatte dopo la virgola (sugg: genera interi fra 0 e 100, dividi per...)
Esercizio 623 (choice)
Dichiarare una tupla contenenti l'elenco dei cognomi della classe ed estrarne uno con choice. Chi esce sarà interrogato!!!
Esercizio 624 (choice)
Creare una lista contenente i numeri da 1 a 10 ed estrarre un numero con choice. Provvedere successivamente ad eliminare il numero estratto dalla lista e visualizzare la stessa.
Esercizio 625 (shuffle)
Dichiarare una lista contenente l'elenco dei cognomi della classe (in ordine alfabetico) e mischiarla con shuffle. Visualizzare la lista mescolata: quello sarà l'ordine delle interrogazioni!!!
Esercizio 626 (shuffle)
Creare una lista contenente i numeri da 1 a 10 e mescolarla. Visualizzare la lista nel nuovo ordine ottenuto e successivamente riordinarla.
math
Il modulo math
contiene tutte le funzioni matematiche utili per le operazioni su
esponenziali, logaritmi, trigonometria, etc...
# esempi di operazioni varie
import math
math.log(10) # logaritmo in base e di 10
math.cos(math.pi) # coseno di 90 gradi (pi greco radianti)
math.factorial(5) # fattoriale di 5, ovvero 5! = 1 * 2 * 3 * 4 * 5
math.sqrt(12) # radice quadrata di 12
math.gcd(345,678) # Massimo Comun Divisore
math.lcm(345,678) # Minimo Comune Multiplo (da Python 3.9)
ceil/floor/trunc # RTFM
Il modulo math si porta dietro anche una serie di costanti famose:
# variabili (pre)definite in math:
# math.e = 2.718281828459045 (numero di Nepero)
# math.inf = inf (più infinito)
# math.nan = nan (not a number. PS: hai combinato qualcosa)
# math.pi = 3.141592653589793 (pi greco)
Esercizio 631 (sqrt)
Scrivere una funzione che calcola le soluzioni dell'equazione di
secondo grado Ax^2 + Bx + C = 0
.
In particolare la funzione prende come parametri i coefficienti A, B, C dell'equazione e restituisce la lista delle soluzioni reali della stessa.
La lista può contenere 0, 1, 2 soluzioni (anche coincidenti) a seconda dei casi.
Esercizio 632 (sqrt, floor)
Scrivere una funzione per calcolare la radice quadrata intera di un
numero. La radice quadrata intera di un numero x è il più grande intero
n tale che n * n <= x
.
Provate a scrivere questa funzione con l'aiuto del modulo math (facile) e provate a scriverne una analoga senza (un po' più complicato)
Esercizio 633 (gcd , lcm)
Scrivere una funzione che prende numeratore e denominatore di una frazione e ritorna una tupla di 2 valori contenenti numeratore e denominatore ridotti ai minimi termini. Ad esempio, la funzione riduci(15,6) ritorna la tupla (5,2).
Esercizio 634 (gcd , lcm)
In una piazza si trova il capolinea di tre linee di tram: A, B, e C. Il tram A parte ogni TOT_A minuti, il tram B ogni TOT_B minuti, il tram C ogni TOT_C minuti. Ogni quanti minuti i 3 tram si ritrovano al capolinea insieme? Implementare la funzione calcolaMinuti(TOT_A, TOT_B, TOT_C) che ritorna il numero di minuti che bisogna aspettare per avere di nuovo i 3 tram insieme al capolinea.
time
Il modulo time
in Python gestisce l'interazione con il temporizzatore del computer in cui esso viene
eseguito ed è dunque in grado di effettuare operazioni collegate al tempo, come:
- aspettare per un lasso di tempo
- controllare l'orario corrente
- formattare l'orario in base alle sue componenti.
Vediamo alcuni esempi:
Funzione sleep
Serve per mettere in stand-by lo script Python per un certo numero di secondi (vale anche la virgola!!!)
Funzione time
Questa funzione ritorna il numero di secondi trascorsi da Epoch
(noi diremmo... dalla notte dei tempi)!
In realtà, epoch
non è altro che January 1, 1970, 00:00:00 UTC
import time
# il numero di secondi trascorsi da Epoch
seconds = time.time()
print("Seconds since epoch:", seconds)
Partendo da questa, abbiamo varie possibilità per la formattazione e la gestione di questo tempo:
Funzioni *time
In questo caso mi viene più semplice presentare alcune delle funzioni di tempo con qualche esempio:
import time
seconds = time.time()
# ctime:
# prende i secondi trascorsi e ritorna una stringa
local_time = time.ctime(seconds)
print("Local time:", local_time)
# Scrive: Local time: Wed Dec 28 08:16:19 2022
# localtime:
# prende i secondi trascorsi e ritorna struct_time, una tupla contenente le informazioni
# sul tempo: anno, mese, giorno, ore, minuti, secondi, nome del giorno, giorno dell'anno, bisestile
res = time.localtime(seconds)
print("result:", res)
# Scrive: result: time.struct_time(tm_year=2022, tm_mon=12, tm_mday=28, tm_hour=8, tm_min=8, tm_sec=53, tm_wday=2, tm_yday=362, tm_isdst=0)
# mktime:
# prende una tupla di tipo struct_time e ritorna il numero di secondi passati da Epoch per quella data
time_tuple = (2022, 12, 28, 8, 44, 4, 4, 362, 0)
seconds = time.mktime(time_tuple)
print(seconds)
# Scrive: 1672217044.0
# asctime:
# prende una tupla di tipo struct_time e ritorna una stringa che la rappresenta
res = time.asctime(time_tuple)
print(res)
# Scrive: Fri Dec 28 08:44:04 2022
Esercizio 641
Visualizza l'ora corrente in ORE:MINUTI:SECONDI (sugg: visualizza i giusti campi della tupla di tempo)
Esercizio 642
Chiedi all'utente un numero grande a piacere e calcola se è primo. Dopo aver risposto alla domanda visualizza quanto tempo il tuo programma ha impiegato a calcolarlo.
Esercizio 643
Calcola quanti secondi sono trascorsi dal 1 gennaio di quest'anno a oggi.
datetime
Il modulo datetime
contiene le funzioni per la manipolazione di data e ora. Contiene 4
classi diverse a cui si accede con l'operatore PUNTO (.):
- la classe Date per la gestione della data, con giorno, mese ed anno;
- la classe Time per la gestione dell'orario, con ore, minuti, secondi e microsecondi;
- la classe DateTime per la gestione di Data e Ora: praticamente è la classe unione delle due precedenti;
- la classe TimeDelta per il calcolo delle differenze di tempo.
Vediamo alcuni esempi per chiarire i concetti espressi.
import datetime
# nell'ordine: anno, mese, giorno
scopertaAmerica = datetime.date(1492, 10, 12)
# nell'ordine: ore, minuti, secondi
oraDellaPausa = datetime.time(16, 40, 00)
# nell'ordine: anno, mese, giorno, ore, minuti, secondi
uomoSullaLuna = datetime.datetime(1969, 7, 20, 20, 18, 00)
# con le variabili nominali: giorni, secondi, microsecondi, millisecondi, minuti, ore, settimane.
# (i campi con valore 0 possono essere omessi)
fra3giornie2ore = datetime.timedelta(days=3, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=2, weeks=0)
Successivamente vedremo uno o due esempi che coinvolgono la classe TimeDelta
.
Per visualizzare informazioni sulle classi in oggetto ricordatevi di utilizzare le funzioni dir() e help():
Una delle cose più semplici da fare con queste classi è ottenere ora e data correnti:
# Per la classe Date, possiamo ottenere il giorno odierno
oggi = datetime.date.today() # vale 2019-05-23
# La classe Time NON ha un metodo per l'ora corrente.
# Dobbiamo usare la classe DateTime
adesso = datetime.datetime.now() # vale 2019-05-23 19:26:03.478039
Una volta impostata una data o un'ora è possibile accedere ai valori dei campi che la caratterizzano:
print("Anno: ", adesso.year)
print("Mese: ", adesso.month)
print("Giorno: ", adesso.day)
print("Ore: ", adesso.hour)
print("Minuti: ", adesso.minute)
print("Secondi: ", adesso.second)
L'accesso ai valori dei campi che caratterizzano una variabile
di tipoDate
,DateTime
,Time
è sempre in sola lettura.
Questo significa che possiamo visualizzare i valori come fatto qui sopra, ma non possiamo utilizzare questi campi per modificare una data. Per essere completamente espliciti, non è possibile fare operazioni tipo le seguenti:
dataAcaso = datetime.datetime(2022, 6, 4, 13, 0, 0)
dataAcaso.year = 2020 # ERRORE
dataAcaso.hour = 12 # ERRORE. (capito? Non si può...)
Le date non sono fatte per essere modificate. Invece di cambiarne una... create un'altra variabile!
Per visualizzare date, ore o data con ora a piacimento, tutte e tre le classi mettono a disposizione la funzione strftime()
che prende
l'oggetto Data (o Ora, o Data e Ora) e ritorna una stringa personalizzata, secondo i seguenti parametri (ho messo solo i
principali...):
Parametro | Descrizione | Esempio |
---|---|---|
%a | Giorno della settimana (breve) | Wed |
%A | Giorno della settimana | Wednesday |
%w | Giorno della settimana come numero: 0 è Domenica | 3 |
%d | Giorno del mese: 01-31 | 31 |
%b | Nome del mese (breve) | Dec |
%B | Nome del mese | December |
%m | Mese come numero: 01-12 | 12 |
%y | Anno (breve, 2 cifre) | 18 |
%Y | Anno | 2018 |
%H | Ore: 00-23 | 17 |
%M | Minuti: 00-59 | 41 |
%S | Secondi: 00-59 | 08 |
%% | Per visualizzare % | % |
Qualche esempio è meglio di molte spiegazioni:
>>> adesso = datetime.datetime.now()
>>> print( adesso.strftime("%d-%m-%Y") )
23-05-2019
>>> print( adesso.strftime("Sono le %H:%M") )
Sono le 19:26
>>> print( adesso.strftime("%A") )
Thursday
È facile capire che in ogni tipologia di dato potete usare solo i parametri relativi ad esso: ovvero con un oggetto date, i parametri relativi ad ore, minuti o secondi non vanno bene, mentre con un oggetto time non vanno quelli sul giorno, il mese, etc... su un oggetto datetime funzionano tutti!!!
Differenze di tempo (TimeDelta)
Ok, domanda a bruciapelo. Da quanto tempo l'uomo è andato sulla Luna? Da quanti anni? Da quanti giorni??
Le differenze di tempo sono materia per la classe TimeDelta; un elemento
della classe stessa si ottiene facendo una differenza tra due elementi
di tipo DateTime o Date (non Time... attenti! E dello stesso tipo... attentissimi!! datetime - datetime
, oppure date - date
)
Le differenze di tempo si fanno banalmente con il segno meno:
Ok... in giorni è quello. Ma... in anni? Settimane? Ore? Minuti? Secondi?
In questo caso occorre fare un po' di calcoli: si fa la differenza fra 2 date (o 2 datetime, NON due time), si utilizza la
funzione total_seconds()
che ritorna i secondi totali e poi si fa qualche divisione...
diff = adesso - uomoSullaLuna
secondiTotali = int(diff.total_seconds()) # int() per arrotondare...
minutiTotali = secondiTotali // 60
oreTotali = minutiTotali // 60
giorniTotali = oreTotali // 24
settimaneTotali = giorniTotali // 7
anniTotali = giorniTotali // 365 # più o meno...
Come la differenza fra due date
(o due datetime
) risulta in un oggetto timedelta
, così la somma fra una date
e un timedelta risulta una data:
oggi = datetime.date.today()
duegiorni = datetime.timedelta(days=2)
dopodomani = oggi + duegiorni
print(dopodomani, type(dopodomani)) # vedremo un oggetto datetime.date con la data di dopodomani
Prendiamo confidenza con il modulo datetime
grazie ad un po' di esercizi
Esercizio 651 (now)
Visualizzare la data e l'ora corrente, scrivendo la frase "Oggi è il GG/MM/AAAA e sono le ore HH:MM"
Esercizio 652 (...)
Data l'ora di adesso e inserito dall'utente l'ora di fine lezione calcolare il numero di minuti mancanti.
Esercizio 653 (tuple, weekday)
Chiedere all'utente di inserire la data di nascita e visualizzare il giorno della settimana in cui è nato.
Esercizio 654 (...)
Chiedere all'utente di inserire due numeri per giorno e mese dell'anno corrente e calcolare quante settimane sono passate dall'inizio dell'anno a quella data.