Creare un simulatore di consegne con math, datetime e random

by theArchitect
SHARE
Creare un simulatore di consegne con math, datetime e random
© Guida-HTML5.it

Introduzione

Le librerie standard math, datetime e random sono utili per costruire piccoli programmi realistici senza installare pacchetti esterni. In questo tutorial realizzeremo un simulatore di consegne per un negozio online.

Il programma dovrà:

  • generare ordini casuali;
  • calcolare la distanza tra magazzino e cliente;
  • stimare il tempo di consegna in base alla distanza;
  • aggiungere un piccolo ritardo casuale dovuto al traffico;
  • calcolare il costo della spedizione;
  • determinare la data e l’ora previste per la consegna.

Questo esempio è utile perché combina tre categorie di operazioni molto comuni: calcoli matematici, gestione di date e orari e simulazione di eventi imprevedibili.

Codice completo

import math
import random
from datetime import datetime, timedelta


# Dati di esempio relativi a possibili clienti
clienti = [
    {"nome": "Azienda Alfa", "x": 4, "y": 7},
    {"nome": "Studio Beta", "x": 10, "y": 3},
    {"nome": "Negozio Gamma", "x": 6, "y": 12},
    {"nome": "Ufficio Delta", "x": 15, "y": 8},
    {"nome": "Laboratorio Epsilon", "x": 2, "y": 14}
]

# Coordinate del magazzino
magazzino_x = 0
magazzino_y = 0

# Seleziona casualmente un cliente
cliente = random.choice(clienti)

# Calcolo della distanza euclidea dal magazzino
differenza_x = cliente["x"] - magazzino_x
differenza_y = cliente["y"] - magazzino_y

distanza = math.sqrt(
    differenza_x ** 2 + differenza_y ** 2
)

# Arrotondamento della distanza a due cifre decimali
distanza = round(distanza, 2)

# Velocità media del corriere in chilometri all´ora
velocita_media = 30

# Tempo di viaggio in ore
tempo_viaggio_ore = distanza / velocita_media

# Conversione delle ore in minuti, arrotondando per eccesso
tempo_viaggio_minuti = math.ceil(tempo_viaggio_ore * 60)

# Ritardo casuale causato dal traffico o da altri imprevisti
ritardo = random.randint(0, 20)

# Tempo totale previsto
tempo_totale_minuti = tempo_viaggio_minuti + ritardo

# Calcolo del costo: tariffa fissa più costo al chilometro
tariffa_fissa = 4.50
costo_per_km = 0.85

costo_spedizione = tariffa_fissa + distanza * costo_per_km
costo_spedizione = round(costo_spedizione, 2)

# Data e ora attuali
ora_partenza = datetime.now()

# Calcolo dell´orario previsto per la consegna
ora_consegna = ora_partenza + timedelta(minutes=tempo_totale_minuti)

# Classificazione della consegna
if distanza <= 5:
    zona = "zona vicina"
elif distanza <= 12:
    zona = "zona intermedia"
else:
    zona = "zona lontana"

# Stampa del riepilogo
print("=== RIEPILOGO CONSEGNA ===")
print(f"Cliente: {cliente[´nome´]}")
print(f"Zona: {zona}")
print(f"Distanza: {distanza} km")
print(f"Tempo di viaggio: {tempo_viaggio_minuti} minuti")
print(f"Ritardo stimato: {ritardo} minuti")
print(f"Tempo totale previsto: {tempo_totale_minuti} minuti")
print(f"Costo spedizione: {costo_spedizione:.2f} euro")
print(f"Partenza: {ora_partenza.strftime(´%d/%m/%Y %H:%M´)}")
print(f"Consegna prevista: {ora_consegna.strftime(´%d/%m/%Y %H:%M´)}")

Spiegazione

Generare dati casuali con random

La funzione random.choice() seleziona un elemento casuale da una lista. Nel nostro caso viene scelto un cliente tra quelli disponibili:

cliente = random.choice(clienti)

Per il ritardo utilizziamo invece random.randint(0, 20). Questa funzione restituisce un numero intero casuale compreso tra il primo e il secondo valore, inclusi. Il ritardo può quindi variare da zero a venti minuti.

In un’applicazione reale questa casualità potrebbe rappresentare traffico, difficoltà di parcheggio o tempi variabili di preparazione dell’ordine. Durante i test, però, è spesso utile ottenere sempre gli stessi risultati. A questo scopo si può impostare un seme:

random.seed(10)

Inserendo questa istruzione all’inizio del programma, le scelte casuali saranno riproducibili.

Calcolare la distanza con math

Il magazzino e i clienti sono rappresentati da coordinate su un piano. Per calcolare la distanza utilizziamo la formula della distanza euclidea:

distanza = √((x₂ - x₁)² + (y₂ - y₁)²)

La funzione math.sqrt() calcola la radice quadrata. L’operatore ** serve invece per elevare un valore a una potenza:

distanza = math.sqrt(differenza_x ** 2 + differenza_y ** 2)

Usiamo poi math.ceil() per arrotondare il tempo di viaggio per eccesso. Se la consegna richiede 18,2 minuti, il programma considera 19 minuti. In questo modo non sottostimiamo la durata del viaggio.

Gestire date e orari con datetime

datetime.now() restituisce la data e l’ora correnti. Per aggiungere una durata utilizziamo timedelta:

ora_consegna = ora_partenza + timedelta(minutes=tempo_totale_minuti)

Questa soluzione è preferibile alla manipolazione manuale di ore e minuti, perché gestisce correttamente il passaggio da un’ora al giorno successivo, dai minuti alle ore e così via.

Il metodo strftime() formatta la data in una forma leggibile. Il codice %d/%m/%Y %H:%M significa, rispettivamente, giorno, mese, anno, ora e minuti.

Calcolare il costo della spedizione

Il prezzo è composto da una tariffa fissa e da una parte variabile proporzionale alla distanza:

costo_spedizione = tariffa_fissa + distanza * costo_per_km

La funzione round() limita il risultato a due cifre decimali, adatte alla rappresentazione di un importo in euro. Nella stampa usiamo anche :.2f, così il prezzo appare sempre con due decimali, anche quando il valore è intero.

Best practice

  • Usa nomi descrittivi: variabili come tempo_totale_minuti sono più comprensibili di nomi abbreviati come ttm.
  • Separa i dati dalla logica: in un progetto reale i clienti potrebbero essere letti da un file o da un database, invece di essere scritti direttamente nel codice.
  • Arrotonda solo quando serve: durante i calcoli conserva più precisione possibile e arrotonda al momento della visualizzazione o del calcolo finale.
  • Controlla le unità di misura: la velocità è espressa in chilometri orari, mentre la durata finale è convertita in minuti.
  • Rendi riproducibili i test: usa random.seed() quando devi verificare il comportamento del programma.
  • Preferisci timedelta alle operazioni manuali: aggiungere minuti con timedelta evita molti errori nella gestione dell’orario.
  • Dividi il programma in funzioni: in una versione più grande conviene creare funzioni come calcola_distanza(), stima_consegna() e calcola_costo().

Riepilogo

In questo progetto abbiamo usato le librerie standard di Python per simulare una consegna dinamica. math ci ha permesso di calcolare una distanza e di arrotondare il tempo necessario. random ha introdotto variabilità nella scelta del cliente e nel ritardo. datetime ha gestito l’orario di partenza, la durata e la consegna prevista.

La combinazione di queste librerie è particolarmente utile per prototipi, simulatori, applicazioni gestionali e programmi didattici. Anche senza dipendenze esterne è possibile costruire una logica realistica, leggibile e facilmente estendibile.

Approfondisci con risorse ufficiali

SHARE