Vai al contenuto

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 comuni
  • time: Gestione Tempo
  • datetime: Gestione Data e Ora
  • pathlib: Accesso a file e directories
  • csv: 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

import random

# estrae un numero pseudocasuale fra 1 e 90
n = random.randint(1, 90)


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!!!)

import time

print("Lo scrive subito")
time.sleep(2.5)
print("Lo scrive dopo 2 secondi e mezzo!!")


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 tipo Date , 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)

>>> print(adesso - uomoSullaLuna)
18205 days, 12:42:12.510824

Le differenze di tempo si fanno banalmente con il segno meno:

diff = adesso - uomoSullaLuna
print(diff.days) # scrive 18205 (int)

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.