Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
Codificatore - Versione 1.1

Codificatore

Sommario | Admin | Forum | Bugs | Todo | Files

Avatar
AldoBaldo (Member)
Expert


Messaggi: 345
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 22:38
Sabato, 07/02/2015
Dopo tanto penare son finalmente riuscito ad arrivare in fondo alla riorganizzazione del codice del mio "Codificatore". Come l'altra volta apprezzerei e prenderei in seria considerazione i suggerimenti delle anime pie che volessero darmene.

Sperando di fare cosa gradita a chi mi ha GIA' consigliato, ci tengo a riassumere in che modo i contributi che ho ricevuto mi hanno spinto a modificare il programma. E' un po' una "lenzuolata" di testo, per cui capirei se la saltaste a pie' pari.

Ho riorganizzato il “Codificatore” secondo alcuni dei suggerimenti che gentilmente avete voluto darmi. Altri suggerimenti li ho considerati, ma mi han dato l’idea di non essere particolarmente vantaggiosi: chi me li ha dati mi tiri pure pubblicamente le orecchie se ritiene che io abbia preso una cantonata agendo così.

“Utilizzare un po' gli oggetti” (marco_) – fatto! Ora la parte “operativa” del codificatore è implementata nella forma della classe CDF.

“Evitare variabili globali” (marco_) – fatto, almeno in parte. Le uniche variabili globali residue sono alcuni handle a elementi di interfaccia e un buffer di char.

“Evitare funzioni con nomi eccessivamente lunghi” (marco_) – per il momento ho preferito conservare i nomi lunghi perché in fase di sviluppo m’aiuta ad orientarmi meglio.

“Mischiare codice dipendente dal SO con l'algoritmo è orribile” (TheDarkJuster) – non succede più! La classe CDF usa solo funzioni e tipi standard.

“Evitare problemi con malloc/free” (marco_) – fatto! Ho completamente “raschiato via” ogni chiamata a malloc() e a free(), sostituendole con new.

“Usare std::string anzichè char*” (TheDarkJuster) – Ho controllato nella documentazione della libreria standard le funzionalità apportate dalla classe stringa. Devo dire che nel contesto di un programmino tanto semplice m’è sembrato inopportuno “caricare” una botta di codice del genere per usare giusto un paio di quelle funzionalità. Ho preferito mantenere la più classica gestione tipo array del C. Ho fatto lo stesso ragionamento per la classe vector – come sparare ai passeri con un cannone, nel caso del mio piccolo codificatore.

“Non serve specificare il tipo delle eccezioni lanciate dai metodi” (TheDarkJuster) – Fatto! Avevo inserito quella caratteristica più che altro perché volevo che un eventuale utilizzatore della classe CDF potesse essere immediatamente al corrente delle eccezioni lanciate senza avere dubbi. In effetti, credo proprio che lo stesso scopo di ottenga anche con la soluzione attuale: dei semplici commenti nel file header cdf.h.

“Personalmente ti sconsiglio di gestire i file direttamente in quella classe” (TheDarkJuster) – Fatto! La classe “lavora” esclusivamente su stringhe di caratteri.

“Normalmente i metodi e le proprietà pubbliche si scrivono con le iniziali maiuscole (ecc.)” (Roby94). Ci ho pensato parecchio, ma ho deciso di rimandare per la stessa ragione per la quale ho mantenuto i nomi lunghi: siccome mi sono abituato così, mi resta più semplice ricordare le cose e ragionarci su con un metodo che mi è ormai famigliare. Una volta finito tutto è probabile ch’io segua gli standard che mi consigli.

“Lasciare che sia la classe a decidere se codificare o decodificare non mi sembra un ottima idea” (Roby94) – fatto e non fatto al tempo stesso. La classe ha un’unica funzione elabora(), ma questa opera in codifica o in decodifica a seconda del tipo di dato che è stato passato in fase di inizializzazione/aggiornamento. Se è stata passata una stringa classificata come testo in chiaro, elabora() agisce come una funzione di codifica; se è stata passata una stringa classificata come testo in codice, elabora() agisce come una funzione di decodifica. Del resto, non avrebbe senso tentare di decodificare un testo già in chiaro, così come non avrebbe senso tentare di codificare un testo già in codice. Sta al chiamante specificare che tipo di testo sta fornendo alla classe. La classe, dal canto suo, marca come “testo in chiaro” il testo risultante da una decodifica, e come “testo codificato” quello risultante da una codifica. C’è, insomma, un minimo di automatismo che a me sembra piuttosto razionale.


Ma cosa vuoi che ne sappia? Io ci gioco, col codice, mica ci lavoro!
PM Quote
Avatar
AldoBaldo (Member)
Expert


Messaggi: 345
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 22:41
Sabato, 07/02/2015
Una cosa che mi sarebbe davvero utile è una funzione di estrazione a sorte che estragga tra valori che possono eccedere il classico 32767 di RAND_MAX. Già avevo proposto un codice chiedendo se fosse affidabile, ma purtroppo non è stato preso in considerazione. Chi si sente di darmi una conferma o una smentita circa l'affidabilità d'una funzione tipo questa?

Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <limits.h>
  4. #include <time.h>
  5.  
  6.  
  7. /*******************************************************************************
  8.    FUNZIONE rand_ul() - 28 gennaio 2015
  9.  
  10.    prototipo:
  11.        unsigned long rand_ul( unsigned long max );
  12.  
  13.    La funzione rand_ul() estrae a sorte un valore unsigned long compreso tra
  14.    0 e max, con max avente valore massimo ULONG_MAX.
  15.  
  16.    Si presuppone che il tipo unsigned long sia costituito da 32 bit e che la
  17.    funzione di libreria standard rand() restituisca valori compresi tra 0 e
  18.    32767.
  19. *******************************************************************************/
  20.  
  21. unsigned long rand_ul( unsigned long max ) {
  22.     return ((((unsigned long)rand())<<17)+(((unsigned long)rand())<<2)+rand()%4)%max;
  23. }
  24.  
  25.  
  26. /*******************************************************************************
  27.    Un semplice main() di esempio.
  28. *******************************************************************************/
  29.  
  30. int main() {
  31.     int i, n, c;
  32.  
  33.     n = 0;
  34.     srand( time(NULL) );
  35.  
  36.     while( 1 ) {
  37.         for( i=1; (i%11); ++i )
  38.             printf( "\n estrazione #%04d = %10lu", ++n, rand_ul(ULONG_MAX) );
  39.  
  40.         printf( "\n\n   Continuo? " );
  41.         if( (c=getchar()) == 'n' ) break;
  42.  
  43.         while( c!='\n' && c!=EOF )
  44.             c = getchar();
  45.     }
  46.  
  47.     return 0;
  48. }


Ultima modifica effettuata da AldoBaldo il 07/02/2015 alle 22:42


Ma cosa vuoi che ne sappia? Io ci gioco, col codice, mica ci lavoro!
PM Quote
Avatar
TheDarkJuster (Member)
Guru^2


Messaggi: 1455
Iscritto: 27/09/2013

Segnala al moderatore
Postato alle 0:26
Domenica, 08/02/2015
Il  consigliavo di usare String e vector per essere conformi il più possibile agli standard c++11 e perché è più immediata la comprensione dell'algoritmo dove si usa la classe string e la classe vector, ovviamente questo secondo il mio parere. L'utilizzo di uno shift per superare il limite imposto dal rand è la mogliore tecnica. Io, come forse ti ho detto non sopporto le winapi e vedere variabili globali che sono tipi di Dati definiti nelle winapi mi fa venire i brividi, ma questo è del tutto personale, quindi non tenerne conto.

PM Quote
Avatar
AldoBaldo (Member)
Expert


Messaggi: 345
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 1:16
Domenica, 08/02/2015
Ma... i tipi caratteristici di Win32 li ho tolti tutti dalla classe CDF! Ora sono "confinati" ai file riferiti all'interfaccia, la parte "operativa" ne è ormai libera.


Ma cosa vuoi che ne sappia? Io ci gioco, col codice, mica ci lavoro!
PM Quote
Avatar
TheDarkJuster (Member)
Guru^2


Messaggi: 1455
Iscritto: 27/09/2013

Segnala al moderatore
Postato alle 12:22
Domenica, 08/02/2015
E hai fatto bene. Non ho detto niente contro il lavoro che hai fatto, è fatto bene.

PM Quote
Avatar
AldoBaldo (Member)
Expert


Messaggi: 345
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 20:42
Domenica, 08/02/2015
Nella prossima versione ho in mente di fare tre cose:

1. usare una finestra di dialogo anziché una finestra standard per l'interfaccia (completato proprio quest'oggi)
2. eliminare tutte le variabili globali (completato proprio quest'oggi)
3. eliminare il ricorso a un file temporaneo, da sostituire con un buffer dinamico, per la preparazione dell'output del programma (da fare)

Dal momento che la settimana entrante dovrò accompagnare una visita d'istruzione scolastica penso che se ne riparlerà la settimana successiva.


Ma cosa vuoi che ne sappia? Io ci gioco, col codice, mica ci lavoro!
PM Quote
Avatar
TheDarkJuster (Member)
Guru^2


Messaggi: 1455
Iscritto: 27/09/2013

Segnala al moderatore
Postato alle 22:51
Domenica, 08/02/2015
Testo quotato

Postato originariamente da AldoBaldo:
eliminare il ricorso a un file temporaneo, da sostituire con un buffer dinamico, per la preparazione dell'output del programma (da fare)



Molto importante! Meno riferimento a API del sistema operativo o dipendente da esso ci sono nei programmi/librerie meglio è! E poi usare la RAM è più veloce che usare un file, e questo velocizzerà l'algoritmo.

Ultima modifica effettuata da TheDarkJuster il 08/02/2015 alle 23:04
PM Quote