Introduzione
Le librerie standard di Python offrono strumenti semplici ma potentissimi per risolvere problemi concreti senza installare pacchetti esterni. In questo tutorial vedremo un caso d’uso molto pratico: costruire una piccola simulazione di prenotazione dinamica, utile come base per sistemi di booking, preventivazione o pianificazione automatica.
L’idea è questa: partendo da una data di partenza, generiamo una serie di slot disponibili nei giorni successivi, calcoliamo un prezzo finale con regole matematiche e introduciamo una componente casuale controllata per simulare disponibilità variabile o sconti temporanei. Per farlo useremo tre librerie standard fondamentali:
- math per arrotondamenti e calcoli numerici più affidabili;
- datetime per gestire date e orari in modo corretto;
- random per introdurre casualità simulata, ma riproducibile.
Questo approccio è utile in molti contesti reali: prenotazione di sale, appuntamenti, noleggi, servizi online, gestione di slot temporali e simulazioni di domanda.
Codice completo
from datetime import datetime, timedelta
import math
import random
def genera_slot_prenotazione(data_inizio, giorni, slot_al_giorno=3):
"""
Genera slot di prenotazione nei giorni successivi a una data iniziale.
Ogni slot ha:
- data e ora
- disponibilità casuale
- prezzo calcolato in base al giorno e alla fascia oraria
"""
slot = []
# Fasce orarie predefinite
orari = [9, 13, 17]
for giorno in range(giorni):
data_corrente = data_inizio + timedelta(days=giorno)
for ora in orari[:slot_al_giorno]:
data_slot = data_corrente.replace(hour=ora, minute=0, second=0, microsecond=0)
# Simuliamo una disponibilità casuale
disponibile = random.choice([True, True, False]) # più probabile che sia disponibile
# Prezzo base
prezzo_base = 50.0
# Aumento per i giorni più lontani: +2% per ogni giorno
aumento_giorni = 1 + (giorno * 0.02)
# Maggiorazione serale
if ora >= 17:
aumento_orario = 1.15
elif ora >= 13:
aumento_orario = 1.05
else:
aumento_orario = 1.0
prezzo_lordo = prezzo_base * aumento_giorni * aumento_orario
# Sconto casuale del 10% in alcuni casi
sconto = 0.90 if random.random() < 0.25 else 1.0
prezzo_finale = prezzo_lordo * sconto
# Arrotondiamo sempre a 2 decimali con math
prezzo_finale = math.ceil(prezzo_finale * 100) / 100
slot.append({
"data": data_slot,
"disponibile": disponibile,
"prezzo": prezzo_finale
})
return slot
def mostra_slot(slot):
"""
Stampa gli slot in modo leggibile.
"""
for elemento in slot:
data_formattata = elemento["data"].strftime("%d/%m/%Y %H:%M")
stato = "DISPONIBILE" if elemento["disponibile"] else "NON DISPONIBILE"
prezzo = f"{elemento[´prezzo´]:.2f} €"
print(f"{data_formattata} | {stato} | {prezzo}")
def trova_slot_economici(slot, massimo=55.0):
"""
Filtra gli slot con prezzo inferiore o uguale a una soglia.
"""
return [
s for s in slot
if s["disponibile"] and s["prezzo"] <= massimo
]
def main():
# Impostiamo un seed per rendere la simulazione riproducibile
random.seed(42)
# Data di partenza: oggi alle 9:00
oggi = datetime.now().replace(hour=9, minute=0, second=0, microsecond=0)
# Generiamo 5 giorni di slot
slot = genera_slot_prenotazione(oggi, giorni=5, slot_al_giorno=3)
print("=== TUTTI GLI SLOT ===")
mostra_slot(slot)
print("n=== SLOT ECONOMICI E DISPONIBILI (<= 55.00 €) ===")
economici = trova_slot_economici(slot, massimo=55.0)
mostra_slot(economici)
# Calcolo statistico semplice sul prezzo medio degli slot disponibili
prezzi_disponibili = [s["prezzo"] for s in slot if s["disponibile"]]
if prezzi_disponibili:
media = sum(prezzi_disponibili) / len(prezzi_disponibili)
media = math.ceil(media * 100) / 100
print(f"nPrezzo medio degli slot disponibili: {media:.2f} €")
else:
print("nNessuno slot disponibile.")
if __name__ == "__main__":
main() Spiegazione
1. Gestione delle date con datetime
La libreria datetime è lo strumento standard per lavorare con date e orari. Nel nostro esempio la usiamo in due modi principali:
- datetime.now() per ottenere il momento corrente;
- timedelta(days=giorno) per spostare la data di uno o più giorni in avanti.
La riga data_inizio + timedelta(days=giorno) è molto utile perché evita calcoli manuali con numeri di giorno e mese, che diventano rapidamente complessi e soggetti a errori.
2. Formattazione e sostituzione dell’orario
Con replace() impostiamo un orario preciso su una data già esistente. Questo è perfetto per creare slot come 9:00, 13:00 e 17:00 senza dover costruire ogni volta un oggetto data da zero.
Per mostrare la data all’utente usiamo strftime("%d/%m/%Y %H:%M"), che converte il valore datetime in una stringa leggibile.
3. Casualità controllata con random
La libreria random serve a simulare variabilità realistica. Nel codice:
- random.choice([True, True, False]) rende la disponibilità più probabile del non disponibile;
- random.random() genera un numero tra 0 e 1, utile per decidere se applicare uno sconto casuale;
- random.seed(42) rende il comportamento ripetibile, fondamentale nei test e nei tutorial.
Usare un seed è una best practice quando vuoi verificare sempre gli stessi risultati durante lo sviluppo.
4. Calcolo del prezzo con math
La libreria math entra in gioco per gestire il prezzo finale. Nel nostro esempio:
- partiamo da un prezzo base;
- lo aumentiamo del 2% per ogni giorno successivo;
- applichiamo una maggiorazione in base alla fascia oraria;
- eventualmente applichiamo uno sconto casuale.
Infine usiamo math.ceil(prezzo_finale * 100) / 100 per arrotondare sempre per eccesso a due decimali. Questo approccio è utile quando vuoi evitare prezzi con troppi decimali o arrotondamenti “troppo favorevoli” al cliente in contesti di business.
5. Filtraggio degli slot utili
La funzione trova_slot_economici() restituisce solo gli slot disponibili con prezzo inferiore a una soglia. È un esempio molto comune di filtro applicato a dati strutturati. In un sistema reale potresti usare questa logica per mostrare al cliente solo le opzioni più convenienti o per ordinare i risultati in base al budget.
Best practice
- Usa seed durante i test: se il tuo codice contiene casualità, impostare
random.seed()aiuta a ottenere risultati prevedibili. - Separa logica e presentazione: genera i dati in una funzione e stampali in un’altra. Il codice diventa più leggibile e riutilizzabile.
- Lavora con oggetti datetime, non con stringhe: converti in stringa solo alla fine, quando devi mostrare il risultato.
- Arrotonda in modo esplicito: nei calcoli economici evita di lasciare valori con molti decimali.
- Usa strutture dati chiare: dizionari e liste sono ottimi per rappresentare slot, prezzi e stato di disponibilità.
- Documenta le funzioni: i docstring nel codice aiutano te e altri sviluppatori a capire subito lo scopo di ogni blocco.
Riepilogo
In questo tutorial abbiamo visto come combinare math, datetime e random per costruire una simulazione di prenotazione dinamica, realistica e facilmente estendibile. Abbiamo usato:
- datetime per creare e formattare slot temporali;
- random per simulare disponibilità e sconti variabili;
- math per calcolare e arrotondare il prezzo finale.
Questo esempio è piccolo, ma rappresenta bene un flusso tipico di molte applicazioni reali: generazione dati, trasformazione, filtro e presentazione. Una volta compreso questo schema, potrai adattarlo facilmente a calendari, sistemi di prenotazione, preventivi automatici o simulazioni di disponibilità.
Approfondisci con risorse ufficiali
- math - documentazione ufficiale Python: https://docs.python.org/3/library/math.html
- datetime - documentazione ufficiale Python: https://docs.python.org/3/library/datetime.html
- random - documentazione ufficiale Python: https://docs.python.org/3/library/random.html
- PEP 8 - guida allo stile del codice Python: https://peps.python.org/pep-0008/
