Uso pratico di math, datetime e random per simulare una prenotazione dinamica

by theArchitect
SHARE
Uso pratico di math, datetime e random per simulare una prenotazione dinamica
© Guida-HTML5.it

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

SHARE