Moduli

Nell'apprendimento di Python, abbiamo usato funzioni predefinite come print(), input(), type(), ecc. Python possiede un gran numero di funzioni, e non tutte sono direttamente accessibili da un nuovo script Python. Invece, sono conservate in file separati chiamati moduli. Per utilizzare queste funzioni, dobbiamo importare il modulo che le contiene. Questo si fa usando l'istruzione import. Vediamo un esempio:
import math           # Importazione del modulo math

print(math.pi)        # Accesso alla costante pi dal modulo math
print(math.sqrt(16))  # Accesso alla funzione radice quadrata dal modulo math
Questo programma stamperà il valore di pi (3.141592653589793) e la radice quadrata di 16 (4.0).
Possiamo anche importare specifici attributi o funzioni da un modulo usando l'istruzione from...import:
from math import pi, sqrt  # Importazione solo di pi e sqrt dal modulo math

print(pi)                  # Possiamo usare pi direttamente senza anteporre il nome del modulo
print(sqrt(16))            # Allo stesso modo, possiamo usare sqrt direttamente
L'output del programma sarà lo stesso del precedente.
A volte i moduli hanno nomi lunghi, e digitare l'intero nome ogni volta che vogliamo usare una funzione può essere laborioso. Per evitare ciò, possiamo usare la parola chiave as per assegnare un nome diverso (alias) al modulo.
import math as m   # Importazione del modulo math e rinominazione come m

print(m.pi)        # Ora possiamo usare l'alias breve
print(m.sqrt(16))  # Usare la funzione sqrt utilizzando l'alias
L'output sarà anche 3.141592653589793 e 4.0, proprio come prima.
In conclusione, i moduli in Python sono come cassette degli attrezzi che contengono funzioni e variabili predefinite che possiamo importare e usare nei nostri programmi. Aiutano a organizzare il codice e a renderlo più efficiente.
Come Funzionano i Moduli Dietro le Quinte
Quando si importa un modulo, Python esegue alcune operazioni dietro le quinte che potrebbero non essere immediatamente evidenti. Ecco una panoramica di ciò che accade quando si utilizza l'istruzione import:
  1. Ricerca del Modulo: Python innanzitutto cerca il modulo controllando le posizioni specificate nella sua lista sys.path. Questa lista include la directory corrente, la directory dei pacchetti Python integrati, e qualsiasi percorso specificato nella variabile d'ambiente PYTHONPATH. Se Python trova il modulo, procede ai passaggi successivi. In caso contrario, lancia un'eccezione ModuleNotFoundError.
  1. Inizializzazione del Modulo: Una volta individuato il file del modulo, Python crea un nuovo oggetto modulo (types.ModuleType). Poi carica il contenuto del modulo in questo nuovo oggetto, eseguendo tutto il codice di primo livello nel file del modulo. Questo include definizioni di funzioni, classi, variabili, e l'esecuzione del codice di inizializzazione.
  1. Caching del Modulo: Dopo l'inizializzazione, il modulo viene messo in cache in sys.modules (un dizionario). Questo passaggio garantisce che quando lo stesso modulo viene importato nuovamente nello script (o da altri script), Python non ha bisogno di localizzare e inizializzare di nuovo il modulo. Invece, può usare la versione in cache. La chiave in questo dizionario è il nome del modulo, e il valore è l'oggetto modulo.
  1. Aggiunta del Modulo allo Spazio dei Nomi dell'Importatore: Infine, Python aggiunge il nome del modulo allo spazio dei nomi dello script o del modulo che lo ha importato. Il nome si riferisce all'oggetto modulo, così si possono accedere alle funzioni e variabili del modulo utilizzando la notazione con il punto.
Illustriamo questo con un po' di codice:
import sys
import math

print(sys.path)       # Il percorso dove Python cerca i moduli
print(sys.modules)    # I moduli in cache
print(math.sqrt(16))  # Accesso a una funzione dal modulo math
sys.path stampa una lista di directory dove Python cerca i moduli. sys.modules stampa un dizionario di nomi di moduli (chiavi) e i rispettivi oggetti modulo (valori).

Sfida: Numeri Casuali

Nel mondo della crittografia, i numeri casuali svolgono un ruolo incredibilmente cruciale. Gli algoritmi crittografici spesso si basano sulla generazione di una sequenza di numeri casuali per mantenere sicuri i dati.
In questa sfida, il tuo compito è simulare un semplice generatore di numeri casuali che ci aiuterà a comprendere la casualità in una forma più tangibile. Python include un modulo integrato chiamato random che ha varie funzioni per generare numeri casuali. Ti viene chiesto di usare questo modulo per generare una lista di n numeri interi casuali tra due numeri dati a e b. La casualità, tuttavia, non deve essere veramente casuale - dobbiamo fissare il seme a 42 per la ripetibilità dell'esperimento. Puoi usare la funzione seed() per fissare il seme e randint() per generare un numero casuale.
La prima riga dell'input contiene tre numeri interi separati da uno spazio: n, a e b. I numeri a e b determinano l'intervallo (inclusivo) dal quale devono essere scelti i numeri casuali, e n determina quanti di tali numeri devi generare.
Il programma dovrebbe stampare n numeri casuali separati da uno spazio, generati nell'intervallo [a, b], fissando il seme casuale a 42.
Input
Output
10 1 100
82 15 4 95 36 32 29 18 95 14
5 1 5
1 1 3 2 2
3 10 20
20 11 10
Nota: Poiché impostiamo il seme casuale a 42, la sequenza dell'output dovrebbe restare la stessa attraverso molteplici esecuzioni del programma. Questa è una caratteristica che sfruttiamo in fase di test, debugging e in altri scenari dove è necessario un output deterministico.
 

Constraints

Time limit: 2 seconds

Memory limit: 512 MB

Output limit: 1 MB

To check your solution you need to sign in
Sign in to continue