Lo pseudocodice per la scrittura di algoritmi: un metodo efficace anche nella didattica per le disabilità visive

Tempo di lettura: 11 minuti

Oggi vi parlo di algoritmi e pseudocodice, in un ottica un po’ diversa dal solito. Ho conosciuto questi termini durante gli studi tecnici come perito informatico, capendone le potenzialità come utente ipovedente. Ne riconosco l’efficacia ancora oggi da non vedente e rilancio dichiarando che per una persona con disabilità visiva, la tecnica della scrittura di pseudocodice è assolutamente efficace, rappresentando comunque una metodologia usata spesso anche da sviluppatori normodotati. Quindi non è un metodo esclusivo, ma una tecnica nata per tutti che nello specifico ci è molto utile.

Una definizione di algoritmo

Un algoritmo è una serie di istruzioni ordinate e ben definite che descrivono come risolvere un determinato problema o compiere una determinata operazione. In altre parole, un algoritmo è un metodo sistematico per risolvere un problema, composto da una sequenza di passi logici che, se eseguiti correttamente, risolveranno il problema o compiranno l’operazione richiesta.
Un algoritmo è considerato efficace se risolve il problema in modo efficiente, ovvero utilizzando il minor numero di risorse possibile, come tempo di calcolo, memoria o spazio di archiviazione. Gli algoritmi vengono spesso analizzati in termini di complessità computazionale, che descrive quanto sia efficiente un algoritmo in base alla dimensione del problema da risolvere.
Nel campo informatico e in particolare nel mondo della programmazione, la definizione di algoritmo ci è utile per la risoluzione di varie tipologie di problemi. Infatti, i passi necessari alla risoluzione logica di un dato problema, possono essere convertiti in una sequenza di istruzioni elementari, ordinate, non ambigue e finite.
La capacità di definire tali passi e la conoscenza approfondita degli stessi è chiamato “pensiero computazionale”.
In una fase successiva, tali istruzioni, saranno convertite utilizzando la sintassi del linguaggio di programmazione scelto in fase di progettazione.
Gli algoritmi possono essere utilizzati in molti campi, dalla matematica alla scienza dei dati, dall’informatica alla fisica, e così via.

Un esempio preso dalla vita reale

Potrei proporvi un esempio che appartiene strettamente al mondo della matematica, ma preferisco parlarvi di qualcosa di manuale che fa parte, quasi certamente, della nostra quotidianità. Infatti, ogni giorno, quando compiamo azioni o attività, inconsciamente, utilizziamo degli algoritmi per portarle a termine, tramite una metodologia a noi nota, quella secondo noi più adatta per raggiungere il risultato finale.
Avete mai pensato ai passi necessari e ordinati per preparare una tazza di caffè con una moka?
Seppur con delle piccole variazioni, potremmo ipotizzare i seguenti passi:

  1. prendo la moka;
  2. la svito ;
  3. lavo la moka sotto l’acqua corrente;
  4. riempio il serbatoio dell’acqua in base a quanto voglio intenso il caffè;
  5. inserisco il filtro che conterrà il caffè;
  6. prendo il barattolo del caffè macinato;
  7. con un cucchiaino, riempio il filtro tanto quanto basta per avere un caffè più o meno forte;
  8. avvito la moka;
  9. ripongo la moka chiusa sul fornello ancora spento;
  10. accendo il fuoco e regolo la fiamma;
  11. attendo che il caffè sia pronto;
  12. spengo il fuoco;
  13. prendo una tazza;
  14. verso il caffè nella tazza;
  15. ripongo la moka.

Se ci siamo chiesti il motivo per cui sappiamo preparare un caffè, una risposta possibile è che l’esperienza nel prepararlo, magari ogni mattina per colazione, ci ha fatto migliorare nei passi necessari, moderando la quantità di caffè, lo prepariamo per soddisfare meglio i nostri gusti, mettendo più o meno acqua, ne gestiamo l’intensità. Naturalmente, il nostro risultato finale è il caffè stesso, del quale sappiamo indicare un indice di gradimento ed in base ad esso, la prossima volta, cercheremo di migliorarlo.
Ci capiterà spesso di avere definito una soluzione che crediamo ottimale, per poi accorgerci che ciò che avevamo dedotto era assolutamente migliorabile. Il bello è che potremo migliorare il nostro algoritmo, rendendolo più funzionale, questa prende il nome di fase di ottimizzazione.

Lo pseudocodice

Lo pseudocodice (o pseudocodifica) è una modalità testuale per la rappresentazione di un algoritmo. Tale linguaggio intermedio, non rispetta degli standard definiti da enti preposti e rappresenta il passo precedente alla scrittura vera e propria delle istruzioni in un linguaggio macchina. Anche lo pseudocodice, come i linguaggi veri e propri, deve rispettare una sintassi e delle regole che proveremo a definire.
Quando si raggiunge una certa esperienza nel campo della programmazione, lo pseudocodice torna utile per prendere appunti sulla logica che dovrà avere una certa porzione di codice, è un modo di scrivere universale, chiaro e utile anche ad altri sviluppatori con cui si condivide il lavoro.

Un primo semplice esempio

Senza darvi altre indicazioni teoriche, proviamo a scrivere l’algoritmo che determina se un numero è pari o dispari, tramite il seguente pseudocodice:

  1. INIZIO
  2. Scrivi: “Inserisci un numero naturale n”
  3. Leggi n dall’utente
  4. Se n%2 è = 0 (se il resto della divisione per 2 è 0) ALLORA:
    1. Scrivi: “Il numero è pari”
  5. Altrimenti:
    1. Scrivi: “Il numero è dispari”
  6. FINE SE
  7. FINE

Prestate attenzione al comando “LEGGI n”, infatti esso introduce un concetto fondamentale, quello di variabile. L’elemento n è un contenitore di un certo dato, tale contenitore rimane immutato fino a che non diamo un comando che ne alteri il contenuto. L’abbiamo chiamato n, ma lo potevamo anche chiamare diversamente, ad esempio numero o x, siamo noi a decidere questi nomi.
Come potete vedere, questo linguaggio è più rigoroso rispetto a quello utilizzato per l’algoritmo per la preparazione del caffè. Vengono di certo rispettate delle regole e viene utilizzata una specifica sintassi.
Questa metodologia testuale,è assolutamente accessibile ed utilizzabile da non vedenti e ipovedenti. Si integra in modo ottimale con il lettore di schermo,perchè la sintassi la si può scrivere in un qualsiasi editor di testo e non presenta alcun riferimento grafico.
L’unico passaggio necessario richiesto, è quello di pensare a step, quando si affronta la risoluzione di un problema. Molti di noi già lo fa, senza rendersene conto.
Posso suggerire di iniziare con l’aprire il Blocco Note o un qualsiasi editor di testo e iniziare a elencare i passi necessari alla risoluzione del dato problema. Scriveteli in un linguaggio non formale, ma descrittivo.
Successivamente, accertatevi che gli step siano ordinati in senso logico e non preoccupatevi di eventuali step ripetuti, infatti vedremo come “riciclare” degli step già definiti, in modo da normalizzare il flusso del nostro algoritmo.
Se sono invece presenti passaggi che contengono più operazioni, bisogna cercare di separarli, creando così più step, in modo che sia più semplice convertirli in linguaggio macchina.
Fatto ciò, si può passare alla fase di conversione nel linguaggio di pseudocodifica e solo successivamente convertiremo il tutto nel linguaggio di programmazione scelto.

Alcuni concetti base per comprendere meglio: variabile, costrutto, condizione e operatori logici

In programmazione, una variabile è un contenitore dove viene memorizzato un valore o un insieme di valori. Le variabili vengono utilizzate per memorizzare temporaneamente informazioni all’interno del programma, in modo da poterle richiamare e manipolare in modo efficiente. Per capire meglio, puoi immaginare una scatola dove puoi mettere oggetti diversi. In una variabile possiamo inserire un valore numerico, una parola, un elenco di numeri o di parole o qualsiasi altro tipo di informazione.
Per esempio, supponiamo che ti chieda di scrivere un programma che calcola l’area di un cerchio. La formula per il calcolo dell’area richiede di utilizzare il valore del raggio del cerchio. Quindi, definiresti una variabile chiamata “raggio” e gli attribuiresti il valore numerico del raggio. Successivamente, utilizzando la variabile “raggio” nel tuo calcolo, sarebbe facile trovare l’area del cerchio.
In sostanza, una variabile è un modo per salvare una informazione all’interno di un programma in modo da poterla richiamare e manipolare in futuro.
Cambiando argomento, il costrutto è un blocco di codice che serve per eseguire una specifica operazione o una serie di azioni. Si possono immaginare i costrutti come “mattoni” di base che vengono utilizzati per creare programmi complessi. Ad esempio, un costrutto comune è il ciclo, che permette di eseguire ripetutamente una serie di istruzioni senza doverle ripetere manualmente.
Le condizioni sono il metodo per testare se una specifica relazione tra le variabili è vera o falsa. Ad esempio, si può testare se un numero è pari o dispari, o se due variabili sono uguali o diverse. Le condizioni sono spesso utilizzate con gli operatori logici.
Gli operatori logici sono utilizzati per combinare le condizioni. Ci sono tre operatori logici principali: il “not” (not), che inverte una condizione da vera a falsa e viceversa, l’ “and” (e), che restituisce vero solo se entrambe le condizioni sono vere, e l’ “or” (o), che restituisce vero se almeno una delle condizioni è vera.
Ad esempio, in pseudocodice si potrebbe creare un costrutto di controllo di flusso “if” (se) che verifica se un numero è maggiore o uguale a 10. In caso affermativo, verranno eseguite una serie di istruzioni altrimenti le istruzioni verranno saltate.

Definiamo un nostro standard

Nel definire un nostro standard, dobbiamo sempre tenere conto delle istruzioni che un linguaggio di programmazione ci mette a disposizione. Non dobbiamo inoltre dimenticare che un algoritmo, rappresentato tramite lo pseudocodice, dovrebbe poter essere tradotto in qualsiasi linguaggio di programmazione e non solo in quello che vogliamo utilizzare

Definiamo il seguente standard e utilizziamolo per i nostri algoritmi:

  • INIZIO : punto di inizio del nostro algoritmo;
  • FINE : termine del nostro algoritmo;
  • SCRIVI “stringa” o variabile : output, leggibile dall’utente;
  • LEGGI variabile : input inserito dall’utente;
  • VARIABILE = valore, espressione o procedura : assegna un valore ad una data variabile. Tale valore può essere fisso, come un numero o una stringa, oppure può derivare da un’espressione o dall’esecuzione di una procedura. Ciò che definiamo a destra dell’uguale, verrà assegnato al contenitore a sinistra dell’uguale;
  • + : operatore aritmetico di somma;
  • – : operatore aritmetico di sottrazione;
  • * : operatore aritmetico di prodotto;
  • / : operatore aritmetico di divisione;
  • // : operatore aritmetico di divisione per ottenere solo la parte intera;
  • % : operatore per avere il modulo tra due numeri, cioè il resto della divisione tra i due numeri;
  • = : operatore aritmetico usato per assegnare un risultato o un valore;
  • ! : simbolo usato per negare un valore o condizione. Da scrivere prima del valore, condizione o espressione da negare;
  • != : operatore utilizzato per indicare che un valore o condizione è diversa da qualcos’altro;
  • == : operatore usato nelle condizioni per indicare una uguaglianza in un confronto;
  • < o > : simbolo di minore e maggiore, usati per confrontare i valori nelle condizioni dei vari costrutti condizionali o cicli condizionati;
  • e : usata come una congiunzione, si utilizza per unire più condizioni, indicando così che devono essere entrambe soddisfatte per validare la condizione;
  • o : utilizzata come oppure, indica che tra due condizioni, basta che ne sia valida una per validare il confronto;
  • Se (condizione) ALLORA {istruzione1} ALTRIMENTI {istruzione2} FINE SE : questa sintassi rappresenta un controllo condizionale, di certo uno dei più utilizzati per definire la logica di un algoritmo. Questo tipo di istruzioni possono essere annidate per aumentare la complessità dei controlli sulle condizioni. Ad esempio, si può inserire un ulteriore SE all’interno del ramo ALTRIMENTI, creando così una serie annidata di controlli condizionali;
  • FINCHÉ (condizione) RIPETI {istruzioni} FINE FINCHÉ : fino a che una data condizione è verificata, ripeti le istruzioni. Questa sintassi definisce ciò che è chiamato ciclo condizionato;
  • RIPETI {istruzioni} FINCHÉ (condizione) FINE RIPETI : ripeti le istruzioni fino a che una data condizione è verificata. Anche questa sintassi esprime il concetto di ciclo condizionato, con la differenza che le istruzioni vengono eseguite almeno una volta per poi ripetersi se la condizione è ancora soddisfatta;
  • INTERROMPI RIPETI o INTERROMPI FINCHÉ : termina il ciclo improvvisamente sulla base di una data condizione. Da usare con cautela, dato che è sempre meglio progettare un ciclo in modo che termini a fine iterazioni e non bruscamente. Nonostante ciò, ci sono alcuni casi, in cui può essere utile e funzionale interromperlo prima;
  • NOME_PROCEDURA(possibili_parametri) {istruzioni}RITORNO (eventuale_valore_di_ritorno) FINE PROCEDURA: una procedura (sinonimo di metodo o funzione)contiene una porzione di codice, solitamente riutilizzabile ed invocabile nel flusso dell’algoritmo. Una procedura può ricevere dei parametri quando invocata e può ritornare al chiamante un valore.
  • RICHIAMA NOME_PROCEDURA(possibili_parametri) : invoca una data procedura, richiamandola per nome, utile anche per il riuso di porzioni di codice ripetute. A livello teorico si rimanda al concetto di ricorsione;

Queste sono le istruzioni principali. Potremmo anche decidere di tradurre queste parole chiave in lingua inglese, come preferiamo, ciò ci aiuterà anche poi nel passaggio ad un vero e proprio linguaggio di programmazione, dato che le key word dei linguaggi più usati sono proprio in lingua inglese. Non dimentichiamo che nello scrivere la nostra pseudocodifica, è consigliabile anteporre ad ogni istruzione un numero che ne indichi l’ordinamento, proprio come descritto nell’esempio per l’individuazione dei numeri pari e dispari. Numerare le istruzioni, soprattutto all’inizio, ci serve per capire la struttura dell’algoritmo, soprattutto quando ci troviamo ad utilizzare la sintassi per i costrutti condizionali o i cicli. Rispettando questa convenzione, ci abitueremo anche al fatto che gli editor per programmare ci indicano sempre a quale riga del codice ci troviamo, scopriremo che avere questa informazione è molto importante. In combinazione alla numerazione, possiamo incolonnare la pseudocodifica, utilizzando i rientri di riga, tecnica che prende il nome di indentazione del codice, solitamente si utilizzano le tabulazioni, tasto “tab”. Così sarà semplice ed intuitivo incolonnare i blocchi di istruzione sotto al costrutto di appartenenza. Con il tempo, se usiamo le indentazioni, potremo omettere le parentesi graffe. Man mano che miglioriamo e facciamo pratica, arriveremo a un punto in cui non useremo più la numerazione delle righe e le parentesi graffe, ma lavoreremo solo con l’indentazione. Ricordiamo che il numero di riga è sempre indicato dai programmi di scrittura del codice, per questo diventerà superfluo scriverlo noi ogni volta.

Cenni sulle procedure

Una procedura, un metodo o una funzione rappresentano una porzione di codice che esegue un’operazione specifica racchiusa in un blocco di istruzioni.
Le procedure sono molto utili nella programmazione, poiché permettono di eseguire un blocco di codice più volte, senza doverlo usare ripetutamente ogni volta che lo si deve eseguire. Inoltre, una procedura può accedere a variabili e dati che sono stati definiti fuori di essa, spesso passati come parametri all’inizio dell’esecuzione.
In generale, l’uso delle procedure, dei metodi o delle funzioni è importante per organizzare il codice in un modo sorvegliato e mantenibile, specialmente per programmi di grandi dimensioni che contengono molte funzioni e dati.
Un esempio pratico di funzione potrebbe essere una semplice funzione che, passati due numeri, restituisce il loro prodotto.
In pseudocodice, la funzione potrebbe essere descritta in questo modo:

  1. PROCEDURA_CALCOLA_PRODOTTO(num1, num2)
    1. prodotto = num1 * num2
    2. RITORNO prodotto
  2. FINE PROCEDURA

Questa funzione può essere chiamata in qualsiasi momento e le sue istruzioni saranno eseguite.

In conclusione

Potremmo definire una pseudocodifica più dettagliata e rigorosa, ma secondo me, con questi costrutti di base, possiamo scrivere con chiarezza tutti gli algoritmi di cui avremo bisogno.
Se capiamo questo approccio, avremo ben chiara la logica dell’algoritmo e tradurre il tutto in un linguaggio macchina sarà semplice.
Questa metodologia è anche molto comoda per testare in modo rapido la logica del nostro flusso di istruzioni. Infatti possiamo prevedere diversi casi in cui cambiando i valori dati in ingresso avremo diversi risultati finali che dovranno rispettare le condizioni del nostro algoritmo. Se questi test dovessero fallire, sarebbe inutile concentrarsi nello scrivere il codice macchina, varrebbe la pena prima dedicarsi alla stesura di uno pseudocodice funzionante.

Abbiamo visto cosa si intende per algoritmo e come lo si converte in uno pseudocodice ben definito. Il passo successivo che rimane da compiere è la traduzione dello stesso in un linguaggio di programmazione. Non ho inventato io questi metodi, ho semplicemente preso spunto dal mio vissuto e penso che questa metodologia, applicata alla disabilità visiva, possa aiutare per ottenere ottimi risultati nella risoluzione di qualsiasi tipo di problema. Molto di ciò che le persone normodotate fanno con la vista, noi lo dobbiamo fare con la mente, dobbiamo avere dei pensieri ben ordinati, ridotti ai minimi termini, la logica del flusso di un listato di codice deve essere disegnata nella nostra mente ed io utilizzo questo metodo semplice e potente.

Materiale e esercizi proposti

  • provare a riscrivere l’algoritmo della moka con la pseudocodifica. Immaginatelo come un flusso in cui vengono date delle istruzioni all’utente tramite il comando “SCRIVI” e vengono inseriti dall’utente ingredienti tramite “LEGGI”;
  • scrivere una seconda versione dell’algoritmo della moka, implementando delle situazioni particolari. Ad esempio l’assenza di caffè, senza il quale non potremmo preparare la bevanda. In questo modo potrete utilizzare il costrutto condizionale “SE …”. Potete inventare voi delle nuove situazioni da gestire e controllare;
  • progettare una calcolatrice per effettuare le 4 operazioni fondamentali (addizione, sottrazione, moltiplicazione e divisione). È un progetto apparentemente semplice, ma presenta delle piccole insidie dovute alle proprietà fondamentali di queste potenti operazioni. Supponiamo che i numeri inseriti in input siano interi positivi >= 0 (l’insieme dei numeri naturali). Progettate voi liberamente la logica, le fasi di input e output e tutti i controlli da effettuare sui numeri inseriti e sulla fattibilità delle operazioni;
  • Scrivi un programma in pseudocodifica che generi un numero casuale compreso tra 1 e 100 e chieda all’utente di indovinare il numero. Ipotizza di creare quindi una funzione che genera un numero casuale, possiamo ipotizzare di chiamarla random.
    L’utente ha a disposizione un massimo di 10 tentativi per indovinare il numero. Il programma deve fornire un feedback all’utente indicando se il numero inserito è troppo alto o troppo basso rispetto al numero generato. Se l’utente indovina il numero, il programma deve terminare e fornire un messaggio di congratulazioni. Se l’utente esaurisce i tentativi senza indovinare il numero, il programma deve terminare e fornire il numero segreto. Potremmo anche ipotizzare di fare scegliere il livello di difficoltà del gioco, da 1 a 3, più il livello è alto e meno saranno i tentativi possibili;
  • Implementazione di algoritmi materiale online libero su Wiki Books: una volta fatta pratica nell’analisi di un problema e capiti i concetti per la stesura di uno pseudocodice, potrete procedere nell’analizzare gli algoritmi proposti, progettandoli e scrivendoli a modo vostro e confrontando le soluzioni proposte. Consiglio di iniziare con l’algoritmo per l’elevazione a potenza e con l’algoritmo di Euclide. Man mano che si andrà avanti con gli studi, si riusciranno a risolvere anche quelli più complessi.

Sostieni questo blog con una donazione

Se ti piace ciò che faccio e lo trovi utile, fai una donazione con Paypal oppure usa SatisPay.

Grazie per il tuo supporto!

Pubblicato da

Alessandro Albano

Analista programmatore, formatore e tiflologo.

2 commenti su “Lo pseudocodice per la scrittura di algoritmi: un metodo efficace anche nella didattica per le disabilità visive”

I commenti sono chiusi.