Skip to content

fdemusso/ProgettoLaboratorio

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

226 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Sistema Gestione Spedizioni

Versione documento: 1.2 — luglio 2025

Questo documento descrive in dettaglio l'architettura, le scelte progettuali e l'uso del Sistema Gestione Spedizioni sviluppato in linguaggio C. È pensato per i membri del team di sviluppo: vuole essere allo stesso tempo tecnico e facile da consultare.


Novità della versione 1.2 (luglio 2025)

  • Funzioni complete documentate: aggiunta sezione dettagliata con tutte le funzioni disponibili nel sistema, organizzate per modulo
  • Algoritmo Bin Packing: aggiunta la funzione di pianificazione del caricamento dei camion usando l'algoritmo Worst-Fit
  • Validazioni avanzate: migliorate le funzioni di validazione con controlli più rigorosi
  • Gestione memoria ottimizzata: migliorata la gestione dell'ownership e della memoria

Indice


1. Obiettivi del progetto

  1. Gestire l'intero ciclo di vita di una spedizione (creazione, modifica, ricerca, cancellazione, salvataggio/caricamento da file, ordinamento, pianificazione carico).
  2. Garantire affidabilità tramite validazione degli input e programmazione difensiva.
  3. Mantenere manutenibilità con una struttura modulare e uso di ADT (Abstract Data Type).
  4. Offrire un'interfaccia CLI cross-platform (Windows / Unix) completamente in standard C99, senza dipendenze esterne.

2. Struttura delle directory

ProgettoLaboratorio/
├── Headers/      # Header pubblici dei moduli
├── Source/       # Implementazioni (.c)
├── bin/          # Eseguibili generati dal Makefile/Code::Blocks
├── obj/          # File oggetto intermedi
├── dati.txt      # File CSV di esempio per il caricamento
└── README.md     # Questo documento

Perché due cartelle Headers/ e Source/?

  • Separazione delle responsabilità: chi include un header ottiene solo l'API pubblica, mentre l'implementazione resta nascosta.
  • Facilità di compilazione: il Makefile e il progetto Code::Blocks aggiungono entrambe le cartelle al include path, evitando prefix lunghi nei #include.

3. Principi di progettazione adottati

Principio Applicazione nel codice
Modularità Ogni concetto (Persona, Spedizione, Lista, I/O, Validazione…) ha un modulo dedicato.
ADT & Information Hiding Strutture definite come puntatori opachi (typedef struct X *X) nei .h; i campi reali sono nel .c.
Programmazione difensiva Il modulo validate centralizza tutte le verifiche (stringhe, date, pesi, CAP, ecc.).
Responsabilità chiara Ogni funzione fa una cosa e la documentazione Doxygen spiega pre/post-condizioni.
Error Handling esplicito Le funzioni restituiscono bool / int per indicare successo/fallimento; l'UI (io_utils) mostra l'errore all'utente.
Portabilità Solo librerie standard C; uso di ClearScreen() che rileva il sistema operativo a runtime.

4. Panoramica dei moduli

Modulo Scopo principale Dettagli notevoli
io_utils Gestione input/output dell'utente Funzioni di prompt con validazione immediata; lunghezze costanti centralizzate.
person ADT Person (mittente/destinatario) Setter/Getters safe-string, responsabilità di ownership ben documentata.
shipment ADT Shipment Enum ParcelType, multi-level printing (PrintShipment vs PrintShipmentTable).
list Lista semplicemente concatenata di Shipment Inserimento in testa, ricerca per codice, serializzazione CSV, ordinamento tramite MergeSort.
validate Programmazione difensiva Funzioni IsValidXYZ riusate da tutti gli altri moduli.
operation Layer "business logic" Incapsula le operazioni del menu, mantiene UI separata dal model.
main Punto di ingresso Loop menu, delega tutta la logica ai moduli precedenti, gestione ciclo di vita della lista.
shipment_cmp Funzioni di confronto Comparatori multipli per l'ordinamento delle spedizioni.

Ownership e gestione memoria

  • Il chiamante che crea un oggetto (es. CreatePerson) ne cede l'ownership ai contenitori (Shipment, List).
  • Le funzioni Destroy* propagano la distruzione (es. DestroyShipment distrugge anche sender/recipient).
  • Questo pattern evita leak e facilita il riuso delle strutture.

5. Funzioni complete del sistema

5.1 Modulo io_utils - Gestione Input/Output

Funzioni di Input

  • ReadString(const char *prompt, char *buffer, int size) - Legge una stringa da stdin
  • ReadInt(const char *prompt, int *out) - Legge un intero da stdin
  • ReadFloat(const char *prompt, float *out) - Legge un numero in virgola mobile
  • ReadDate(const char *prompt, struct tm *out) - Legge una data (giorno, mese, anno)
  • ReadType(ParcelType *out) - Legge il tipo di pacco
  • ReadPerson(const char *ruolo, Person *out) - Legge tutti i campi di una persona
  • ReadArrivalDate(const char *prompt, struct tm *arrival, struct tm departure) - Legge data di arrivo ≥ partenza

Funzioni di Output

  • PrintMenu() - Stampa il menu principale del programma
  • PrintMessage(const char *msg) - Stampa un messaggio generico
  • PrintSectionHeader(const char *title) - Stampa un'intestazione di sezione
  • ClearScreen() - Pulisce lo schermo in modo portabile
  • WaitEnter() - Pausa l'esecuzione finché l'utente non preme invio

5.2 Modulo person - Gestione Persone

Costruttori e Distruttori

  • CreatePerson(const char *name, const char *surname, const char *address, const char *city, const char *cap, const char *phone) - Crea un nuovo oggetto Person
  • DestroyPerson(Person p) - Dealloca un oggetto Person

Getter e Setter

  • GetName(Person p) / SetName(Person p, const char *name) - Nome
  • GetSurname(Person p) / SetSurname(Person p, const char *surname) - Cognome
  • GetAddress(Person p) / SetAddress(Person p, const char *address) - Indirizzo
  • GetCity(Person p) / SetCity(Person p, const char *city) - Città
  • GetCap(Person p) / SetCap(Person p, const char *cap) - CAP
  • GetPhone(Person p) / SetPhone(Person p, const char *phone) - Telefono

Output

  • PrintPerson(Person p, FILE *out) - Stampa una persona su uno stream

5.3 Modulo shipment - Gestione Spedizioni

Costruttori e Distruttori

  • CreateShipment(const char *code, ParcelType type, float weight, struct tm departure, struct tm arrival, Person sender, Person recipient) - Crea una nuova spedizione
  • DestroyShipment(Shipment s) - Dealloca una spedizione e le persone collegate

Generazione Codici

  • GenerateShipmentCode(char *code_out, const char *prefix) - Genera un nuovo codice spedizione unico

Getter e Setter

  • GetCode(Shipment s) / SetCode(Shipment s, const char *code) - Codice spedizione
  • GetType(Shipment s) / SetType(Shipment s, ParcelType type) - Tipo di pacco
  • GetWeight(Shipment s) / SetWeight(Shipment s, float weight) - Peso
  • GetDepartureDate(Shipment s) / SetDepartureDate(Shipment s, struct tm departure) - Data partenza
  • GetArrivalDate(Shipment s) / SetArrivalDate(Shipment s, struct tm arrival) - Data arrivo
  • GetSender(Shipment s) / SetSender(Shipment s, Person sender) - Mittente
  • GetRecipient(Shipment s) / SetRecipient(Shipment s, Person recipient) - Destinatario

Output e Utility

  • PrintShipment(Shipment s, FILE *out) - Stampa dettagli completi della spedizione
  • PrintShipmentTable(Shipment s, FILE *out) - Stampa la spedizione in formato tabellare
  • ParcelTypeToString(ParcelType t) - Converte un ParcelType in stringa leggibile

5.4 Modulo list - Gestione Lista Spedizioni

Costruttori e Distruttori

  • CreateList() - Crea una lista vuota di spedizioni
  • DestroyList(List l) - Dealloca completamente la lista e tutte le spedizioni

Operazioni CRUD

  • InsertShipment(List l, Shipment s) - Inserisce una nuova spedizione in testa
  • DeleteShipment(List l, const char *code) - Rimuove la spedizione con il codice specificato
  • FindShipment(List l, const char *code) - Ricerca una spedizione per codice

Output

  • PrintList(List l, FILE *out) - Stampa tutte le spedizioni con dettagli completi
  • PrintListTable(List l, FILE *out) - Stampa le spedizioni in formato tabellare

Persistenza

  • SaveListToFile(List l, const char *filename) - Salva l'intera lista su file CSV
  • LoadListFromFile(const char *filename) - Carica una lista da file

Ordinamento e Utility

  • SortList(List l, int (*cmp)(Shipment, Shipment)) - Ordina la lista con MergeSort
  • IsListEmpty(List l) - Verifica se la lista è vuota
  • CountShipments(List l) - Conta le spedizioni nella lista
  • ForEachShipment(List l, void (*callback)(Shipment)) - Esegue una callback per ogni spedizione
  • GenerateShipmentCodeWithList(List l, char *code_out, const char *prefix) - Genera codice unico usando la lista

5.5 Modulo validate - Programmazione Difensiva

Validazione Stringhe

  • IsValidCap(const char *cap) - Verifica la validità di un CAP italiano
  • IsValidPhone(const char *telefono) - Verifica la validità di un numero di telefono
  • IsValidName(const char *nome) - Controlla se un nome è valido
  • IsValidSurname(const char *cognome) - Controlla se un cognome è valido
  • IsValidCode(const char *codice) - Verifica se un codice spedizione rispetta il formato
  • IsValidCity(const char *citta) - Controlla la correttezza di una città

Validazione Numeri

  • IsValidWeight(float peso) - Valida il peso del pacco

Validazione Date

  • IsValidDate(struct tm data) - Controlla la correttezza di una data
  • IsDepartureBeforeOrEqualArrival(struct tm departure, struct tm arrival) - Verifica che partenza ≤ arrivo

Validazione ADT

  • IsValidPerson(Person p) - Esegue controlli di consistenza su un oggetto Person
  • IsValidShipment(Shipment s) - Esegue controlli di consistenza su un oggetto Shipment
  • IsDelivered(Shipment s) - Verifica se una spedizione è già stata consegnata

5.6 Modulo operations - Business Logic

Operazioni CRUD

  • InsertShipmentOperation(List lista) - Inserisce una nuova spedizione
  • EditShipmentOperation(List lista) - Modifica una spedizione esistente
  • DeleteShipmentOperation(List lista) - Elimina una spedizione

Operazioni di Ricerca

  • SearchShipmentOperation(List lista) - Cerca una spedizione per codice
  • ViewAllShipmentsOperation(List lista) - Visualizza tutte le spedizioni

Operazioni di Ordinamento

  • SortShipmentsOperation(List lista) - Ordina le spedizioni secondo diversi criteri

Operazioni su File

  • SaveToFileOperation(List lista) - Salva la lista su file
  • LoadFromFileOperation(List *lista) - Carica la lista da file

Operazioni di Bin Packing

  • BinPackingOperation(List lista) - Pianifica il caricamento dei camion con Worst-Fit

5.7 Modulo shipment_cmp - Funzioni di Confronto

Comparatori per Ordinamento

  • CompareShipmentByCode(Shipment a, Shipment b) - Per codice (alfabetico)
  • CompareShipmentByWeight(Shipment a, Shipment b) - Per peso (crescente)
  • CompareShipmentByWeightDesc(Shipment a, Shipment b) - Per peso (decrescente)
  • CompareShipmentByType(Shipment a, Shipment b) - Per tipo di pacco
  • CompareShipmentByDepartureDate(Shipment a, Shipment b) - Per data partenza
  • CompareShipmentByArrivalDate(Shipment a, Shipment b) - Per data arrivo
  • CompareShipmentBySenderName(Shipment a, Shipment b) - Per nome mittente
  • CompareShipmentByRecipientName(Shipment a, Shipment b) - Per nome destinatario
  • CompareShipmentBySenderCity(Shipment a, Shipment b) - Per città mittente
  • CompareShipmentByRecipientCity(Shipment a, Shipment b) - Per città destinatario

6. Flusso di esecuzione (runtime)

flowchart TD
    Start([Avvio programma]) --> Init[List = CreateList()]
    Init --> Menu{PrintMenu() \n e scelta utente}
    Menu -->|1| Op1[InsertShipmentOperation]
    Menu -->|2| Op2[EditShipmentOperation]
    Menu -->|3| Op3[SearchShipmentOperation]
    Menu -->|4| Op4[ViewAllShipmentsOperation]
    Menu -->|5| Op5[SortShipmentsOperation]
    Menu -->|6| Op6[DeleteShipmentOperation]
    Menu -->|7| Op7[SaveToFileOperation]
    Menu -->|8| Op8[LoadFromFileOperation]
    Menu -->|9| Op9[BinPackingOperation]
    Menu -->|0| End[DestroyList & Exit]
    subgraph Persistenza
        Op7 --> File[(CSV File)]
        Op8 -->|sostituisce lista| List
    end
Loading

Nota: la scelta del formato CSV semplifica l'import/export e consente apertura rapida in Excel o LibreOffice.


7. Scelte implementative chiave

  1. Ordinamento MergeSort → la lista delle spedizioni può essere ordinata secondo criteri multipli selezionabili dall'utente, grazie a comparatori modulari e all'algoritmo MergeSort su lista collegata.
  2. Algoritmo Bin Packing → pianificazione ottimale del caricamento dei camion usando l'algoritmo Worst-Fit per massimizzare l'utilizzo dello spazio.
  3. Enum ParcelType → leggibile (LETTERA, PICCOLO, …) + conversione ParcelTypeToString per l'output.
  4. Codice spedizione univoco → funzione GenerateShipmentCode ispeziona la lista e aggiunge un progressivo a sei cifre al prefisso.
  5. Serializzazione/Deserializzazione → tutte le funzioni I/O sono in list.c per tenere lontano il parsing dalla UI.
  6. Standard C99 → miglior for-declaration e funzioni <stdbool.h> senza rinunciare alla portabilità.
  7. Doxygen → ogni modulo include tag @file, @brief, parametri, @return; si può generare la documentazione HTML con:
    doxygen Doxyfile

8. Compilazione e sviluppo

8.1 Makefile

# Compilazione debug
make

# Pulizia
make clean

Il target predefinito compila con -Wall -Wextra -g -std=c99.

8.2 Code::Blocks

  • Progetto aggiornato in ProgettoLaboratorio.cbp.
  • Due build targets: Debug (con -g) e Release (con -O2 -s).

8.3 Strumenti consigliati

  • Compilatore: gcc ≥ 9 o clang ≥ 11.
  • Analisi statica: clang-tidy, cppcheck.
  • Test Valgrind: valgrind --leak-check=full ./bin/programma.exe.

9. Linee guida di codifica

  • Snake_case per funzioni (create_person sarebbe C-like, qui usiamo CreatePerson).
  • Costanti ALL_CAPS e suffisso _LEN per lunghezze.
  • Commenti Doxygen in italiano brevi ma completi.
  • Ogni modulo esporta solo il necessario; le funzioni static restano nel .c.

10. Roadmap e miglioramenti futuri

  1. Unit test con Unity o CMock (i test legacy sono stati rimossi nella refactor ma vanno ripristinati).
  2. Log su file con livelli (INFO/WARN/ERROR) per audit.
  3. Interfaccia grafica (GTK/Qt) mantenendo intatta la business logic.
  4. Internationalization (i18n): separare stringhe UI in file risorsa.
  5. Algoritmi di ottimizzazione avanzati per il bin packing (First-Fit Decreasing, Best-Fit).

11. Contatti

Ruolo Nome Email
Maintainer Flavio De Musso flavio@example.com
Developer Giuseppe Di Cosola giuseppe@example.com
Developer Gabriele Farigu gabriele@example.com

Buon hacking!

About

Un sistema completo per la gestione di spedizioni sviluppato in C puro, progettato per scopi didattici e professionali. Il programma implementa un'architettura modulare con gestione CRUD delle spedizioni, ricerca avanzata e persistenza dati.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors