mercoledì 30 aprile 2008

Gigetto: servizio pubblico o semplice spesa pubblica?

Le obliteratrici continuamente inceppate.
Le emettitrici automatiche sempre fuori uso (ma almneo ora c'è un foglio che recita più o meno Fuori Servizio - La Direzione).
I monitor per gli orari montati doppi in ogni stazione, anche quelle più piccole, distrutti a sassate.

Ma è realmente un servizio pubblico o semplicemente una spesa pubblica?

martedì 29 aprile 2008

Google Earth e le impostazioni del proxy

Google Earth legge le impostazioni di rete di Microsoft Windows per connettersi ai server di ricerca, e di conseguenza occorre anzitutto verificare che queste siano corrette e che utilizzino il gateway e il proxy server corretti.

Se il proxy è di tipo Linux, allora potrebbe rendersi necessario abilitare il forwarding verso la porta 80 del dominio google.com.

giovedì 24 aprile 2008

WebCalendar: bloccare gli inserimenti degli appuntamenti oltre una certa data

Utilizzo il comodo e bello WebCalendar, un calendario web semplice e potente che si appoggia ad un database SQL (io uso PostgreSQL) per memorizzare gli eventi e la profilazione utente.
Mi è stato chiesto di fare una modifica affinché il calendario non permettesse più l'inserimento di eventi oltre una data prefissata, e non avendo trovato nessuna funzionalità allo scopo, ho deciso di modificare il codice sorgente.
Premetto che non so assolutamente nulla di PHP (codice con il quale il calendario è implementato).
La prima idea che mi è venuta in mente è stata quella di modificare i file relativi alla visualizzazione del calendario (es. week.php e day.php) affinché disabilitassero i link per le date superiori a quelle di fine attività. Ovviamente questa non è una buona idea per due motivi:
  • occorre inserire gli stessi controlli in più file e, soprattutto, ricordarsi di abilitare tali controlli per ogni nuova vista;
  • la data di visualizzazione viene passata come parametro get agli script, e quindi un utente malizioso potrebbe comunque riuscire ad avere accesso al calendario in una data successiva quella di fine attività.
Ho quindi deciso di mettere mano al file che consente l'editazione (e la memorizzazione) di un appuntamento: edit_entry.php. In questo file ho inserito il seguente controllo subito prima della visualizzazione del form di editazione:


// Controllo che la data di fine calendario non sia superata
$endDate = "20080430";
if( $cal_date > $endDate ){
echo "Data di fine attivita' superata";
$can_edit = 0;
}


La variabile $endDate viene inizializzata al valore di fine attività, nel formato YYYYMMDD, mentre la variabile $cal_date contiene la data con la quale è stata richiamata la form di editazione. A questo punto il controllo fra le due variabili di cui sopra verifica se lasciare il form abilitato o disabilitarlo ($can_edit = 0) e stampare un messaggio di warning per l'utente.

mercoledì 23 aprile 2008

Rimuovere le andate a capo da un file Excel tramite OpenOffice

A volte capita che un file excel contenga delle celle magari importate da altri software con dei caratteri di andata a capo ('\n' o peggio ancora '\r\n'). Rimuoverli è spesso molto complesso, e la loro permanenza potrebbe pregiudicare l'utilizzo delle celle come input per importazioni di dati (ad esempio tramite file CSV). Fortunatamente OpenOffice consente di risolvere il problema eliminando i caratteri di andata a capo mediante una sostituzione di espressione regolare.

E' necessario aprire il file in OpenOffice, selezionare dal menù Edit la voce Find and Replace e dalla finestra di dialogo che si apre abilitare il match su espressioni regolari avendo cura di sostituire '\n' con '\n' stesso. In questo modo OpenOffice sostituisce le andate a capo nascoste rimuovendole. Successivamente è possibile fare la stessa cosa per gli altri tipi di caratteri che si vogliono eliminare.

Inserire dei padding nei campi di testo

PostgreSQL mette a disposizione una funzione molto comoda, lpad, che consente data una stringa e una lunghezza cui questa deve essere formattata, di tagliare (o allungare) la stringa inserendo un eventuale padding specificato. Questo è molto utile quando si vuole uniformare la lunghezza di alcuni codici che sono stati inseriti in modo eterogeneo. Ad esempio, avendo una serie di codici come:

cod01
08cod02

e volendo uniformare il tutto affinché i due codici abbiano il prefisso 08 e siano della stessa lunghezza, è possibile utilizzare lpad specificando come padding '08' e la lunghezza di 7 caratteri:

lpad('cod01', 7, '08') = 08cod01


A questo punto, ipotizzando di avere una tabella padding che contiene la lunghezza con cui uniformare i codici, e quindi di voler prendere da questa tabella la lunghezza dei codici si può usare un semplice comando (da utilizzare eventualmente in transazione). Ad esempio avendo il padding e la tabella delle stringhe da modificare come segue:

luca=# select * from padding;
tipo | lunghezza
------+-----------
1 | 10
2 | 20
3 | 30
(3 rows)

luca=# select * from stringhe;
stringa_src | stringa_dest
-------------+--------------
Luca |
ciao |
(2 rows)


è possibile dare il seguente update per inserire il padding nelle stringhe:

luca=# update stringhe set stringa_dest =
lpad( stringa_src, (select lunghezza from padding where tipo=2), '0')
where stringa_src = 'ciao';

UPDATE 1
luca=# select * from stringhe;
stringa_src | stringa_dest
-------------+----------------------
Luca |
ciao | 0000000000000000ciao
(2 rows)

Come si può notare è stato inserito un padding di 10 caratteri 0 (10 è stato selezionato dal tipo di padding 1) nella stringa ciao.



Importazioni di dati da file CSV

Il client psql consente di importare dei dati da file CSV in modo molto comodo e veloce.
Si supponga di voler caricare due campi da un file CSV, ad esempio un codice e una descrizione, in una tabella articoli(codice, descrizione), sarà usare il comando copy per ottenere l'importazione:

\copy articoli(codice,descrizione) from articoli.csv with delimiter ';'

Il precedente comando copia le righe del file CSV, direttamente nei record della tabella, considerando che i valori siano separati dal ';' e che i record siano distinti da una andata a capo.

Una implementazione di cercaVert in Perl

In questo articolo presento un semplice script Perl che realizza la funzione cercaVert di Excel operando su un file CSV. L'idea è quella di fornire allo script un file CSV specificandogli di cercare i valori di una colonna in un'altra, e di riportare in un file di uscita i valori che trovano riscontro fra le due colonne.
In altre parole, se il file CSV contiene i seguenti dati di esempio:

luca;marco;maschio;
marco;lucia;femmina;
simone;luca;maschio;


e si specifica di cercare i valori della seconda colonna nella prima, allora si avrà match sui valori marco (riportato nella prima riga, seconda colonna - seconda riga, prima colonna) e luca (riportato nella terza riga, seconda colonna - prima riga, prima colonna), ottenendo in uscita il file:

marco;1;
luca;1;


dove la prima colonna rappresenta il valore cercato e la seconda il numero di occorrenze di tale valore nella prima colonna.

Il funzionamento dello script è abbastanza semplice: oltre al file CSV da analizzare vengono passati come argomenti i numeri delle colonne sulle quali fare match, partendo da 1 per la prima colonna a sinistra. Il programma legge riga per riga il file CSV memorizzando in un hash (occurences) il valore cercato e il relativo numero di occorrenze, che al momento risulta pari a zero. Allo stesso tempo, viene memorizzato in un array (domain) la lista dei valori in cui cercare. In altre parole, se si vuole controllare la colonna 2 sulla colonna 1, allora occurences conterrà tutti i valori della colonna 2, mentre domain i valori della colonna 1. Terminata la lettura del file, e quindi con le due origini dati in memoria, viene fatto un ciclo su tutti i valori memorizzati nell'hash e li si confronta con tutti i valori (che possono essere duplicati) del dominio in cui cercare, incrementando le eventuali occorrenze. Infine si riportano sul file di uscita le chiavi e il numero di occorrenze trovate.

#!/usr/bin/perl

# Programma che emula la funzione cercavert di excel: ricerca un campo di una colonna di un file CSV
# in un'altra colonna.
#
# Argomenti dello script:
# $ARGV[0] = nome del file CSV da leggere (deve essere
# formattato con separatori ';'
# $ARGV[1] = numero della colonna da cui prendere i codici
# $ARGV[2] = numero della colonna in cui cercare i codici
#
# Ad esempio:
#
# cercaVert.pl file.csv 2 1
#
# ricerca i codici della colonna 2 nella colonna 1 del file file.csv


# * Copyright (C) Luca Ferrari 2008
# *
# * This program is free software: you can redistribute it and/or modify
# * it under the terms of the GNU General Public License as published by
# * the Free Software Foundation, either version 3 of the License, or
# * (at your option) any later version.
# *
# * This program is distributed in the hope that it will be useful,
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# * GNU General Public License for more details.
# *
# * You should have received a copy of the GNU General Public License
# * along with this program. If not, see .



# controllo numero argomenti
if( $#ARGV < 3 ){
print "\nUtilizzo: $0 \n";
exit(0);
}


# apro il file da cui leggere e su cui scrivere
open(FILE_CSV, "<$ARGV[0]") || die("\nImpossibile aprire il file $ARGV[0]\n$!\n");
open(FILE_OUT,">$ARGV[3]") || die("\nImpossibile aprire il file $ARGV[3]\n$!\n");
print FILE_OUT "Valore ricercato (colonna $ARGV[1]); numero di occorrenze trovate nella colonna $ARGV[2];\n";
$SRC_COLUMN = $ARGV[1] - 1;
$DST_COLUMN = $ARGV[2] - 1;
print "\nRicerco le occorrenze dei valori della colonna $DST_COLUMN nella colonna $SRC_COLUMN del file $ARGV[0]...\n";


# leggo il file una volta, estrando la colonna sorgente e
# costruisco un hash che contiene tutte le occorrenze trovate, e un
# array che contiene tutti i valori in cui cercare successivamente
$occurences = {};
@domain = ();

while( $line = ){
@parts = split(";", $line);

$srcValue = $parts[ $SRC_COLUMN ];
$dstValue = $parts[ $DST_COLUMN ];

# memorizzo il valore nell'hash
$occurences->{ $srcValue } = 0;

# aggiungo il valore in cui cercare nell'array
$domain[ ++$#domain ] = $dstValue;
} # fine del ciclo while


close(FILE_CSV);

print "\nInizio ricerca fra $#domain valori...\n";
@domain = sort(@domain);
$counter = 0;

foreach $chiave (sort(keys(%$occurences))){
foreach $valore (@domain){
if( $valore eq $chiave ){
$occurences->{$chiave} += 1;
$counter ++;
}
}
}

print "\nTrovati $counter valori uguali...";

# produco in uscita il risultato
foreach $chiave (sort(keys(%$occurences))){
if( defined($occurences->{$chiave}) && $occurences->{$chiave} > 0 ){
print FILE_OUT "\n$chiave;" . $occurences->{$chiave};
}
}


print "\nfinito\n";

Lo script è piuttosto semplice, e l'utilizzo di un hash e di un array consente di tenere solo i valori non duplicati da cercare contro un dominio di valori che possono essere duplicati. Va notato che, tenendo le fonti dati in memoria, in caso di file CSV molto grandi questo script tenderà a consumare notevoli risorse.

martedì 22 aprile 2008

Un piccolo tributo a JPUG


JPUG è l'acronimo di Japan PostgreSQL User Group, ed è il gruppo nazionale giapponese di utenti PostgreSQL, della quale ho conosciuto due simpatici e molto qualificati esponenti (Hiroshi Saito e Ishikawa Toshiyuki) al PGDay 2007. Mi era avanzato qualche adesivo del loro gruppo, e così ho deciso di attaccarli ai flettenti superiori dell'arco. Mostro qui il risultato.



Sui miei flettenti Hoyt ho attaccato un adesivo quadrato, mentre sugli Sky-Beiter, essendo a profilo più sottile, ho attaccato un adesivo tondo. Speriamo che mi porti fortuna!











Un piccolo tributo sentimentale

Ho attaccato alcune lettere adesive in ordine sparso sui miei flettenti dell'arco. Il nome che ne è risultato è quello della mia ragazza. E' un piccolo tributo e ringraziamento per avermi incitato (e incitarmi ancora) a riprendere a tirare, e anche per sopportarmi quando faccio tardi per allenarmi o quando spargo il materiale per casa.....GRAZIE!




P.S.
non me ne voglia il mio amico Andrea, al quale avevo chiesto di autografarmi i flettenti quando vinse gli assoluti targa compound....

giovedì 17 aprile 2008

L'importanza delle chiavi esterne

Mi sono trovato a lavorare su un database PostgreSQL progettato da altre persone, e purtroppo ho notato come questo non implementava nessun meccanismo di foreign key. Ovviamente questo non è per via di PostgreSQL, che anzi supporta in modo eccellente i vincoli di integrità referenziali.

Perché è importante implementare i vincoli di integrità referenziale? Diciamo che in linea di massima, se la propria applicazione (PHP, Java, C, ...) implementa bene la logica di gestione dei dati, allora le foreign key non sono strettamente necessarie. Almeno a prima vista. Ebbene si, perché non bisogna scordarsi che un RDBMS è un sistema a se stante, un motore per la gestione dei dati che può essere interrogato e usato anche senza un applicativo (o addirittura da applicativi differenti). Ecco allora che se si accede alla base di dati tramite l'interfaccia del proprio RDBMS, o tramite un applicativo implementato male, si rischia di incappare in incoerenza dei dati, cancellazioni sbagliate e distruzione dei dati stessi.

Le foreign key, come pure i vincoli di tipo check e altri simili, sono importantissimi perché consentono di mantenere la base di dati coerente indipendentemente dal modo in cui i dati stessi sono acceduti. Un RDBMS è uno strumento potentissimo in questo, le sue caratteristiche devono essere sfruttate a pieno, specialmente su sistemi di produzione.

mercoledì 16 aprile 2008

Il paradosso dell'arciere

Ho trovato un video molto interessante che mostra il paradosso dell'arciere, ossia la flessione della freccia in uscita dall'arco. Un altro classico video è quello con il campione olimpico Jay Barrs, per non parlare delle frecce che impattano il bersaglio. Tutti video molto belli e utili (almeno per comprendere un po' meglio la meccanica dell'arco).

martedì 15 aprile 2008

Frecce re-impennate!


Ieri sera ho reimpennato le ultime frecce rimaste, delle ACE 470 molto rovinate. Siccome sono convinto che queste frecce non siano giuste per me, e avendo avuto sempre le Sping-Wing molto rovinate su di esse, ho deciso di montare delle Easton Diamond bianche. Sicuramente queste alette renderanno la freccia più rigida ancora, ma almeno non dovrò reimpennare le frecce in continuazione!
Come cocche ho rispolverato le vecchie Beiter normali, togliendo le in-out poiché ne avevo solo di colore blu scuro, molto difficili da vedere a lunga distanza.

lunedì 14 aprile 2008

Migrare i bookmarks di Konqueror

Il web browser Konqueror salva i suoi bookmark in un file XML che risulta molto semplice da migrare (o da backuppare) su una nuova installazione, inclusa quella che viene con il nuovo KDE 4 (che installa i file nella directory ~/.kde4).

Per disporre dei bookmark nel nuovo KDE 4 è sufficiente impartire il seguente comando:

cp ~/.kde/share/apps/konqueror/bookmarks.xml ~/.kde4/share/apps/konqueror

e riavviare l'istanza di konqueror destinazione.

giovedì 10 aprile 2008

Riordinamento delle celle di un file CSV

Quando si esportano/importano dati con file CSV può essere comodo rigirare le celle di una medesima riga ordinandole. Il riordinamento ovviamente ha senso se le celle rappresentano la stessa caratteristica, ossia appartengono alle stessa categoria (es. attributi di classificazione). Il seguente script è un semplice esempio di come ottenere il riordinamento di un file CSV:

#!/usr/bin/perl

# Script per ordinare la riga di un file csv. Accetta in ingresso il file di uscita e stampa su
# STDOUT le righe riordinate.

# * Copyright (C) Luca Ferrari 2008
# *
# * This program is free software: you can redistribute it and/or modify
# * it under the terms of the GNU General Public License as published by
# * the Free Software Foundation, either version 3 of the License, or
# * (at your option) any later version.
# *
# * This program is distributed in the hope that it will be useful,
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# * GNU General Public License for more details.
# *
# * You should have received a copy of the GNU General Public License
# * along with this program. If not, see .


$INPUT_FIELD_SEPARATOR = ";";

open(FILE_IN, "<$ARGV[0]") || die("\nImpossibile aprire il file di input $ARGV[0]\n$!\n");

while( $line = ){
$line =~ s/\r\n//;
$line =~ s/\n//;
@parts = split(";", $line);


foreach $element (sort (@parts)){
print "$element;";
}

print "\n";
}



Come si può notare lo script è molto semplice: come primo argomento viene specificato il file CSV da leggere, e ogni riga viene riportata ordinata su standard output (quindi è necessaria la redirezione per l'utilizzo). Da notare che vengono utilizzate due espressioni regolari per la cancellazione dei caratteri di andata a capo; questo è dovuto ad un problema di chomp qualora il file di origine sia stato generato da un computer Microsoft Windows. In questo caso, infatti ogni riga viene terminata da una sequena \r\n, della quale chomp rimuove solo l'ultimo \n. Ne consegue che rimane un ritorno di carrello (\r) che produce sovrascritture dei campi di uscita. La prima espressione regolare verrà utilizzata nel caso di file di origine prodotti da Microsoft Windows, mentre la seconda nel caso di un file prodotto su piattaforma Unix.

Aggiustamento automatico dell'ora di un server Ubuntu

Ho sempre usato ntpdate per la sincronizzazione dell'ora dei server, e Ubuntu fornisce il pacchetto nei suoi repository ufficiali. Una rapida occhiata a /etc/ntp.conf mi ha mostrato un file di configurazione corretto, tuttavia la sincronizzazione dell'orologio non funziona di default. Infatti è necessario inserire l'aggiornamento fra i task giornalieri, ad esempio con i comandi:

echo "sudo ntpdate ntp.ubuntu.com" > /etc/cron.daily/ntpdate
chmod 755 /etc/cron.daily/ntpdate

Mi domanda come mai Ubuntu, che fornisce pacchetti preconfigurati in modo eccellente, non abbia sistemato questo piccolo dettaglio per fare in modo che la sincronizzazione venisse abilitata in automatico.

mercoledì 9 aprile 2008

Samba: connection denied due to security descriptor.

Se il server Samba ha un livello di sicurezza ad utente (security = user) e si sta cercando di impostare una share pubblica (guest ok = yes), l'errore in oggetto può verificarsi se l'utente con il quale si accede (guest) ha dei problemi sul server. Occorre verificare le seguenti cose:
  • verificare che nel file smb.conf siano attive le opzioni
map to guest = Bad User
guest account = guest.samba

(essendo guest.samba l'utente scelto come guest per le connessioni SMB anonime, solitamente tale utente è guest)
  • aggiungere l'utente guest (anche se quello inserito come guest account ha uno username differente) alla lista di utenti Samba, mettendolo senza password:
smbpasswd -n -a guest

A questo punto la connessione al server Samba in forma anonima dovrebbe essere possibile.

smbldap_tools: un problema nella definizione dei gruppi

Usando gli smbldap_tools su una Ubuntu 7.1 mi sono trovato nell'impossibilità di gestire i gruppi (e conseguentemente gli utenti); l'errore riportato era sempre del tipo

No suche object at /usr/share/perl5/smbldap_tools.pm line 406.

Il problema ho verificato essere nella stringa usata per la ricerca della categoria gruppi nell'albero LDAP. In sostanza lo script ricerca un gruppo con etichetta Groups, quando invece il gruppo è stato posizionato (dagli stessi tools di Ubuntu) con etichetta Group. E' sufficiente allora forzare il gruppo manualmente nello script (sicuramente esistono soluzioni più eleganti, ma non ho avuto il tempo di cercarle) come segue:

$config{groupsdn}=~s/Groups/Group/;

per far funzionare correttamente i tools.

Frecce usurate

Come già anticipato in un precedente articolo le mie frecce sono ormai molto usurate. Si tratta di ACE 470 (almeno credo, visto che non si riesce nemmeno a leggere la marcatura), con alette sping wind ormai mangiate in ogni modo, come mostrano le foto.




Volevo reimpennarle ieri sera, ma non avevo a portata di mano l'impennatore e addirittura la colla si era completamente seccata (questo sottolinea da quanto tempo non le impenni!). Parlo di colla e impennatore perché sono intenzionato a montare le poche alette Easton Diamond che mi sono rimaste al posto delle Sping Wing. La scelta di una aletta di gomma è dettata fondamentalmente dalla loro resistenza agli urti rispetto alle Sping Wing. Infatti, essendo queste frecce palesemente sbagliate per il mio arco, non credo ci siano molte possibilità di farle volare bene (almeno alle corte distanze), e quindi invece che consumare Sping Wing credo sia meglio montare alette di gomma.


Le punte al momento sono delle L-5, che potrei anche cambiare con delle break-off da 125 grani, anche se la loro lunghezza mi porterebbe il clicker fuori dalla prolunga che attualmente monto.


Una nota positiva per le cocche Beiter In-Ot, che effettivamente hanno protetto una freccia da una rottura. Chiaramente queste cocche non possono fare miracoli, ma offrono una leggere protezione maggiore. Tuttavia ora ho esaurito la mia scorta di cocche, quindi probabilmente monterò quelle poche cocche tradizionali (sempre Beiter) rimaste. Anche perché la scelta del colore blu, seppur gradevole, non permette di vedere le frecce a lunga distanza.

lunedì 7 aprile 2008

Rimozione dei caratteri di andata a capo in un campo testo

Mi sono trovato a lavorare con un database ove risiedevano dei dati importati manualmente tramite un altro programma. Una tabella in particolare aveva un campo di tipo text che inglobava, al suo interno, anche dei caratteri di andata a capo (nello specifico \r\n). Questo rappresentava un problema quando si cercava di fare un'estrazione (ad esempio CSV) poiché il numero delle righe prodotte e il loro contenuto veniva sfalsato.

Fortunamente PostgreSQL mette a disposizione una comoda funzione, che consente di cambiare una stringa esatta di testo in un'altra, restituendo quest'ultima. In questo modo è possibile allora eseguire un semplice update della tabella per rimuovere i caratteri di andata a capo.

Supponendo che la tabella in questione si chiami varie e che la colonna contentente il testo da pulire sia note allora la seguente query risolve il problema:

update varie set note = replace(note, E'\r\n', ' ');

Da notare l'uso della E per indicare che la stringa che segue contiene dei caratteri sottoposti ad escaping. Ovviamente è bene fare comunque un backup della tabella prima della modifica!

venerdì 4 aprile 2008

Movimenti non troppo lineari....

Ho trovato su youtube questo video che mostra tre arcieri coreani al tiro....beh i primi due non mi sembrano avere quei movimenti lineari solitamente presenti in altri connazionali! In particolare il primo effettua questa serie di "onde" durante la trazione, mentre il secondo tende a sbracciare e ha un rilascio non troppo pulito...

mercoledì 2 aprile 2008

Maniaci del Natale

Ok, non è stagione, ma solo oggi ho caricato un breve filmato dove, a parte le sfocature, si può vedere l'impianto luminoso che io e mio padre montiamo regolarmente ogni anno per Natale.


Ogni anno resto un po' intristito dal fatto che, almeno nel quartiere, nessuno si preoccupa di abbellire la propria casa con decorazioni natalizie. E' anche questo un modo per festeggiare.

Gigetto: il treno dove anche le informazioni sono optional!

Anche questa mattina ci sono stati dei problemi nel trasporto pubblico Gigetto, il treno che collega Modena e Sassuolo. Arrivato alla stazione di Casinalbo alle 7.55 (quando il treno per Sassuolo è previsto alle 7.58) mi sono visto arrivare davanti un treno diretto a Modena. Io ed un altra persona abbiamo chiesto spiegazioni al controllore di tale treno, il quale ci ha risposto che di li a poco il treno per Sassuolo sarebbe regolarmente passato. Abbiamo quindi atteso qualche minuto speranzosi, anche se titubanti.

Qualche minuto dopo le 8 invece il nuovo tabellone luminoso che segnala i prossimi treni in arrivo ha cancellato, senza fornire alcuna spiegazione, il treno delle 7.58. Sono stato quindi costretto a prendere l'auto e recarmi in ufficio con quella.

Mi piacerebbe molto sapere come pensa la provincia di tenere in piedi (e magari far fruttare) un servizio di trasporto pubblico così scalcinato da non riuscire nemmeno a fornire le informazioni base ai viaggiatori.

Faccio inoltre notare ai vari capostazione che l'installazione dei nuovi pannelli luminosi con la schedulazione dei treni non fornisce loro alcun diritto di cancellare i treni senza fornire spiegazione. E' impensabile che i viaggiatori debbano rimanere con il naso all'insù tenendo d'occhio il tabellone fino a quando il loro treno non è arrivato.

La situazione è a mio avviso ridicola.