Post Image

Automatizzare i turni di reperibilità in Python: guida al codice passo dopo passo

Nel primo articolo, Automatizza la gestione dei turni in ufficio: il potere di uno script Python, abbiamo visto come automatizzare la gestione della reperibilità in ufficio, eliminando gli errori manuali grazie a uno script Python. Ora è il momento di entrare nel dettaglio e analizzare il codice alla base di questa soluzione, per capire come funziona passo dopo passo. Scopriremo insieme le scelte tecniche, le librerie utilizzate e le logiche implementate per rendere il processo semplice, efficace e soprattutto affidabile.

Gestione degli argomenti di input: una guida semplice per iniziare

Quando si crea uno script Python pensato per essere usato da chiunque, è fondamentale permettere all’utente di fornire delle informazioni precise, chiamate argomenti di input, che guidano il funzionamento del programma. Nel nostro caso, lo script per la gestione automatizzata della reperibilità in ufficio ha bisogno di alcune informazioni essenziali per poter lavorare correttamente: la data di inizio del periodo, la data di fine, il numero di gruppi tra cui distribuire la reperibilità e il gruppo da cui partire.

Questi dati non sono opzionali, ma obbligatori, perché senza di essi lo script non saprebbe come calcolare e organizzare i turni. È quindi importante strutturare il nostro codice in modo che sappia accettare e riconoscere questi parametri dall’utente, segnalando chiaramente eventuali mancanze o errori.

Come gestire gli argomenti con argparse

Per fare questo, Python ci mette a disposizione un modulo molto utile chiamato argparse. Questo modulo permette di definire in modo semplice quali argomenti lo script deve aspettarsi e come interpretarli. Nel nostro script, definiamo quattro argomenti fondamentali: begin_date (data di inizio), end_date (data di fine), group_number (numero di gruppi) e group_begin (gruppo di partenza).

Ecco un esempio concreto di come impostiamo questi argomenti nel codice:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
    "-b",
    "--begin-date",
    help="Interval begin date: format date as YYYY-MM-DD.",
    required=True
)
parser.add_argument(
    "-e",
    "--end-date",
    help="Interval end date: format date as YYYY-MM-DD.",
    required=True
)
parser.add_argument(
    "-n",
    "--group-number",
    help="Number of groups to assign",
    required=True
)
parser.add_argument(
    "-s",
    "--group-begin",
    help="Number of group to assign on first day",
    required=True
)
args = parser.parse_args()

Perché questi argomenti sono importanti

Dichiarare gli argomenti come required=True significa che chiunque voglia eseguire lo script deve necessariamente fornire questi quattro valori. Se uno di questi manca, Python si preoccuperà di avvisare l’utente con un messaggio chiaro, evitando che lo script continui a girare con dati incompleti o errati. Questo approccio è fondamentale per mantenere alta la precisione e la correttezza dell’elaborazione, due aspetti chiave quando si parla di gestione automatizzata.

Cosa succede quando si esegue lo script senza parametri

Se proviamo a lanciare il nostro script senza inserire alcun argomento, il sistema risponderà così:

python main.py

# usage: main.py [-h] -b BEGIN_DATE -e END_DATE -n GROUP_NUMBER -s GROUP_BEGIN
# main.py: error: the following arguments are required: -b/--begin-date, -e/--end-date, -n/--group-number, -s/--group-begin

Questo messaggio, sebbene possa sembrare tecnico, è in realtà molto utile: indica esattamente quali parametri sono mancanti e come inserirli correttamente. È quindi un primo filtro che protegge lo script da input errati o incompleti.

Esempio di utilizzo corretto

Quando invece forniamo i dati nel modo giusto, ad esempio con il comando:

python turni_reperibilita.py -b 2021-10-01 -e 2021-12-31 -n 6 -s 2

lo script riconosce i parametri e può procedere senza generare errori, pronto a eseguire tutte le operazioni successive per organizzare la reperibilità in modo automatico.

Conversione dei dati per il processamento

Una volta ottenuti gli argomenti dall’utente, dobbiamo prepararli per l’uso vero e proprio all’interno del nostro script. Le date, fornite come stringhe in formato testo, vanno trasformate in oggetti di tipo data, così da poter fare con loro tutte le operazioni necessarie, come confronti o calcoli. Allo stesso modo, i numeri di gruppo, forniti come testo, devono essere convertiti in numeri interi.

Questo processo di conversione è fondamentale per la corretta esecuzione del programma e si realizza con il seguente codice:

import datetime

start_date = datetime.datetime.strptime(args.begin_date, "%Y-%m-%d")
end_date = datetime.datetime.strptime(args.end_date, "%Y-%m-%d")
number_of_groups = int(args.group_number)
start_group = int(args.group_begin)

Qui usiamo la funzione strptime per trasformare la stringa della data nel formato YYYY-MM-DD in un oggetto datetime, facilmente gestibile dal codice. Per i numeri, invece, usiamo la funzione int() per convertirli da stringhe a interi.


Questa fase iniziale di gestione degli argomenti di input rappresenta un passaggio fondamentale per qualsiasi script che deve interagire con l’utente o con sistemi esterni. Grazie all’uso del modulo argparse, il nostro script di gestione automatizzata della reperibilità in ufficio diventa molto più robusto, chiaro e facile da utilizzare anche per chi si avvicina per la prima volta al tema della programmazione in Python.

Comprendere come leggere e trasformare i dati di input è il primo passo per creare un software che sia affidabile e flessibile. Nei prossimi paragrafi continueremo a scoprire insieme come questi dati vengono usati per costruire un calendario di reperibilità preciso e senza errori.

Definizione della classe Turni: il cuore della gestione automatizzata dei turni di reperibilità

Per poter organizzare in modo efficace la gestione dei turni di reperibilità nei vari gruppi di lavoro, abbiamo deciso di strutturare il nostro codice all’interno di una classe chiamata Turni. Questa scelta non è casuale: utilizzare una classe ci permette di mantenere tutto ordinato, chiaro e facilmente manutenibile, soprattutto quando il codice cresce o diventa più complesso.

Cos’è una classe e perché serve nel nostro script

Per chi non ha familiarità con la programmazione orientata agli oggetti, una classe può essere vista come un “contenitore” che raggruppa dati e funzioni (metodi) legate a uno stesso concetto. In questo caso, la classe Turni racchiude tutto ciò che serve per gestire l’assegnazione dei turni di reperibilità ai vari gruppi.

La gestione dei turni è la funzionalità principale del nostro script, quindi è naturale che tutta la logica operativa venga organizzata in questa classe. Questo approccio rende il codice più leggibile e permette di riutilizzare facilmente le funzionalità in diversi contesti, senza dover riscrivere nulla.

Come si usa la classe Turni

Il programma che utilizza la nostra classe è molto semplice e chiaro. Prima di tutto creiamo un’istanza della classe, cioè un oggetto che rappresenta l’insieme dei turni, specificando quanti gruppi dobbiamo gestire. Poi carichiamo i dati, indicando l’intervallo temporale e il gruppo da cui partire, e infine scriviamo il risultato su file in formato JSON, così da poterlo leggere e usare facilmente anche al di fuori di Python.

Il codice è il seguente:

turni = Turni(number_of_groups)
turni.load(start_date, end_date, start_group)
turni.to_json()

Da questo breve esempio si capisce subito che i metodi principali che useremo sono due: load, che serve per creare e popolare la struttura dati con i turni assegnati, e to_json, che consente di salvare il risultato in un file leggibile.

Il metodo load: assegnare i giorni ai gruppi con logica e precisione

Il cuore del nostro script si trova nel metodo load. È qui che avviene la vera magia della gestione automatizzata dei turni: il metodo prende in input la data di inizio e la data di fine dell’intervallo da gestire, insieme al gruppo da cui iniziare ad assegnare i giorni.

Il codice è semplice, ma efficace:

def load(self, start_date, end_date, start_group):
    while start_date <= end_date:
        if not self._has_date_key(start_group, start_date):
            self._add_date_key(start_group, start_date)
        self._add_day(start_group, start_date)
        start_date = self._get_next_date(start_date)
        start_group = self._get_next_group(start_group)

Cosa succede qui? Il ciclo while continua a girare finché la data di partenza non supera quella di fine. Per ogni giorno, controlliamo se nel nostro dizionario esiste già una chiave per il mese e l’anno di quel giorno nel gruppo corrente. Se non c’è, la creiamo. Poi aggiungiamo il giorno stesso alla lista dei giorni di quel gruppo. Infine, passiamo al giorno successivo e al gruppo successivo, così da distribuire i turni in modo ordinato e ciclico.

Capire i metodi privati: come la classe organizza internamente i dati

La classe Turni utilizza anche dei metodi privati, cioè funzioni che lavorano “dietro le quinte” per aiutare load a svolgere il suo compito. Questi metodi hanno nomi che iniziano con un underscore _, a indicare che sono destinati all’uso interno della classe.

Ecco una breve spiegazione di come funzionano:

  • _has_date_key verifica se il gruppo corrente ha già una chiave corrispondente al mese e anno del giorno da assegnare. Questo aiuta a organizzare i turni in base a mesi, facilitando una struttura ordinata.

  • _add_date_key crea una nuova chiave nel dizionario del gruppo, utilizzando la stringa formattata dell’anno e mese (ad esempio “2025-05”), e la associa a una lista vuota che conterrà i giorni.

  • _add_day aggiunge il numero del giorno alla lista associata al mese nel gruppo corrispondente.

  • _get_date_key si occupa di trasformare una data in una stringa nel formato “anno-mese”, fondamentale per raggruppare i giorni.

  • _get_next_date calcola la data successiva, spostandosi di un giorno in avanti.

  • _get_next_group gestisce il passaggio ciclico tra i gruppi, assicurandosi che dopo l’ultimo gruppo si ricominci da capo.

Questi piccoli pezzi di codice lavorano insieme per assicurare che i dati vengano organizzati in modo coerente, chiaro e facilmente accessibile.

Il metodo to_json: salvare i turni in un formato leggibile e versatile

Una volta che abbiamo assegnato tutti i giorni ai vari gruppi, il passo successivo è salvare questo risultato in un file. Il formato JSON è perfetto per questo scopo perché è semplice da leggere sia per gli umani che per i programmi, ed è largamente supportato da molti software.

Il metodo to_json permette di scrivere la struttura dati che abbiamo costruito all’interno di un file, il cui percorso può essere deciso dall’utente, ma che ha anche un valore di default. Ecco come funziona:

def to_json(self, target_path='/tmp/turni.json'):
    fh = open(target_path, 'w')
    fh.write(json.dumps(self.turni))
    fh.close()

Il metodo apre il file indicato in modalità scrittura, trasforma il dizionario dei turni in una stringa JSON e la salva sul disco. In questo modo, possiamo facilmente condividere il risultato, importarlo in altri programmi o conservarlo per usi futuri.

Perché questa struttura rende lo script potente e affidabile

La combinazione di questi metodi e la loro organizzazione in una classe dedicata rendono il nostro script di gestione automatizzata dei turni di reperibilità estremamente flessibile e scalabile. La chiave del successo è infatti riuscire a mantenere tutto il codice pulito e modulare, così da poter intervenire facilmente per aggiungere nuove funzionalità o risolvere problemi senza rischiare di rompere ciò che già funziona.

Grazie a questa struttura, anche chi si avvicina per la prima volta al concetto di automazione e programmazione potrà capire come funziona il flusso, partendo da una definizione semplice e chiara di cosa fa ogni parte del codice.


In sintesi, la definizione della classe Turni e dei suoi metodi rappresenta il cuore pulsante del nostro sistema di assegnazione automatica dei turni di reperibilità. Con questa organizzazione, il processo diventa semplice da gestire, comprensibile da chiunque e soprattutto affidabile. Nei prossimi paragrafi approfondiremo ulteriormente come utilizzare questi strumenti per ottimizzare la gestione in ufficio, riducendo al minimo gli errori e risparmiando tempo prezioso.

Conclusioni: un approccio moderno ed efficace alla gestione dei turni

Automatizzare la gestione dei turni di reperibilità in ufficio non è solo una questione di risparmio di tempo, ma anche di precisione, affidabilità e riduzione degli errori. Come abbiamo visto, grazie a Python e a una struttura ben progettata come la classe Turni, è possibile ottenere un sistema semplice da usare ma estremamente potente.

Attraverso l’uso del modulo argparse, lo script è in grado di interagire con l’utente in modo chiaro e sicuro, richiedendo solo i dati essenziali per partire. Grazie poi alla logica implementata nel metodo load e all’organizzazione modulare dei metodi interni, possiamo generare turni equamente distribuiti e strutturati in modo ordinato, mese per mese, gruppo per gruppo.

Infine, la possibilità di esportare i risultati in formato JSON rende questo strumento estremamente flessibile: possiamo integrarlo in altri software, condividerlo con i colleghi o archiviarlo per consultazioni future. È una soluzione che si adatta facilmente a diverse esigenze lavorative, e che può essere estesa o modificata nel tempo con relativa semplicità.

Questo tipo di approccio rappresenta un ottimo esempio di come l’automazione intelligente possa trasformare anche le attività più ripetitive in processi snelli e affidabili. Con un piccolo sforzo iniziale, è possibile creare strumenti che fanno la differenza ogni giorno in termini di organizzazione ed efficienza.

Perché con Python, organizzare la reperibilità in ufficio non è mai stato così semplice.