Successione di Fibonacci con RIMIRO

Nella conclusione del precedente articolo, dedicato alla presentazione di una prima bozza della versione alfa del progetto RIMIRO, ci eravamo ripromessi di studiare come rendere operativo un generico grafo.

Ci sono volute diverse ore di programmazione con FreeBASIC, ma alla fine l’obiettivo è stato raggiunto:

Ora l’ambiente di sviluppo visuale RIMIRO permette sia di descrivere una generica base dati che l’algoritmo che opera su questa.

Per mettere alla prova RIMIRO si è lavorato sul calcolo della Successione di Fibonacci.

L’immagine in copertina a questo articolo non è una “semplice immagine”, ma l’immagine è il vero e proprio programma.

Ecco quindi cos’è un programma realizzato con RIMIRO:

Un grafo che contiene tutto: base dati, algoritmo e descrizione dell’idea operante concepita dal programmatore.

A questo punto non ci resta che lavorare su due fronti:

  1. Continuare a sviluppare RIMIRO correggendo eventuali errori, aggiungendo funzionalità ed ottimizzando il codice e le prestazioni.
  2. Cominciare a scrivere una Guida a RIMIRO sulla falsariga della Guida al FreeBASIC.

Bene. Un altro piccolo passo è stato fatto. 🙂

RIMIRO: versione alfa

Nell’articolo Cos’è RIMIRO? avevamo definito una prima struttura schematica delle procedure di base della versione alfa del progetto.

Il nostro Modello (comportamento o logica del programma) prevedeva:

  • creazione, attivazione/disattivazione ed eliminazione di un nodo
  • creazione ed eliminazione di un arco
  • spostamento di un nodo
  • salvataggio/caricamento di un grafo

A distanza di quasi tre mesi il codice è pronto.

Ovviamente il programma manca ancora della parte operativa: ovvero non è ancora in grado di eseguire alcun algoritmo.

Quello che però già possiamo fare è creare e modificare un generico grafo come quello più sotto.

Guida ai comandi disponibili

Nel prossimo articolo ragioneremo su come rendere operativo il grafo.

Cos’è RIMIRO?

Scopo

L’articolo Grafi, diagrammi di flusso e database si concludeva proponendo i seguenti due obiettivi:

  1. Sviluppare una applicazione per la rappresentazione grafica sia di una generica base di dati che degli algoritmi. Una rappresentazione che metta insieme l’arte (colori e figure) e la scienza (concetti e idee), e che sia inoltre operativa: ovvero che si possano eseguire gli algoritmi sulla base dati.
  2. Che questa applicazione non si limiti ad essere un altro modo per fare programmazione visuale, ma che sia una educazione pratica del pensiero.

Nello stesso articolo si assegnava al progetto il nome RIMIRO.

Metodo di lavoro

Il metodo di lavoro che seguiremo si articolerà su tre aspetti:

Strumenti di lavoro

Gli strumenti di lavoro principali saranno:

Progettazione top-down di RIMIRO

Struttura schematica delle procedure e sotto-procedure della versione alfa del progetto RIMIRO.

  • Modello (comportamento o logica del programma)
    • Procedure interne:
      • creazione, attivazione/disattivazione ed eliminazione di un nodo
      • creazione ed eliminazione di un arco
      • spostamento di un nodo
      • salvataggio/caricamento di un grafo
    • Notifica (Modello -> Controllo):
      • grafo aggiornato
  • Vista (interazione con l’utente)
    • Azioni utente (Utente -> Vista -> Controllo):
      • crea, attiva/disattiva ed elimina un nodo
      • crea ed elimina un arco
      • sposta un nodo
      • salva/carica un grafo
    • Aggiornamento (Vista -> Utente):
      • visualizzazione del grafo aggiornato
  • Controllo (interlavoro interno)
    • Gestione eventi (programmazione a eventi):
      • Aggiornamento (Controllo -> Modello):
        • chiama la procedura specifica in base a:
          • informazioni del mouse
          • tasto della tastiera premuto
      • Aggiornamento (Controllo -> Vista):
        • passa il grafo aggiornato
Di Wdror-wsu-ap and Regis Frey – Opera propria, Pubblico dominio, Collegamento

Nel prossimo articolo cominceremo a sviluppare passo passo il codice FreeBASIC delle varie procedure e sotto-procedure. 🙂

Grafi, diagrammi di flusso e database

Scopo di questo articolo è quello di riflettere sul concetto di grafo, sulla relazione che i grafi hanno con i diagrammi di flusso (flow chart) e con le basi di dati (database), infine sul cominciare ad immaginare una nuova modalità di rappresentazione grafica degli algoritmi e delle basi di dati: una modalità che sia al tempo stesso descrittiva e operativa.

Cosa sono i grafi

In estrema sintesi un grafo è un insieme di punti che possono essere collegati tra loro.

Tra le tante possibili definizioni, in questo articolo chiameremo i punti con il termine nodi e i collegamenti con quello di archi.

Identificando un generico grafo con la lettera maiuscola G, l’insieme dei nodi con la lettera maiuscola N e l’insieme degli archi con la lettera maiuscola A, avremo la formula:

G(N,A)

Cosa possiamo rappresentare con un grafo?

Dalla definizione data, è facile immaginare che un grafo può rappresentare molte strutture reali o astratte, per esempio:

Codice sorgente

  • i nodi potrebbero identificare le singole istruzioni di un programma informatico;
  • gli archi potrebbero identificare la sequenza delle istruzioni descrivendo quindi tutte le possibili diramazioni.

Questo esempio ci suggerisce che il classico diagramma di flusso (flow chart) può essere assimilabile ad un grafo.

È utile ricordare che il paradigma della programmazione strutturata fa largo uso dei diagrammi di flusso per rappresentare i suoi tre elementi fondamentali:

Base di dati (database)

  • i nodi potrebbero identificare i singoli concetti;
  • gli archi potrebbero identificare le relazioni tra i concetti e definirne la tipologia e la direzione.

Tipologie dei grafi

Si possono avere diverse tipologie di grafi in base ad alcune caratteristiche dei nodi o degli archi.

Grafo orientato

Se gli archi che collegano i vari nodi hanno un verso di percorrenza, allora il grafo si dice orientato, altrimenti viene definito non orientato.

Data questa definizione è facile capire che un diagramma di flusso rientra tra i grafi orientati, così come una base di dati a grafo dove la tipologia di relazione tra due concetti esprime anche una direzione.

Nomenclatura

Nei grafi orientati i vari elementi prendono le seguenti definizioni:

nodo di partenza (i): coda (o predecessore di j)
nodo di arrivo (j): testa (o successore di i)

Grafo e multigrafo

Se in un grafo vi è la presenza di almeno due nodi collegati tra loro da più archi, allora il grafo prende il nome di multigrafo.

Il diagramma di flusso è quindi un grafo orientato completo.

Una base di dati a grafo può essere sia un grafo che un multigrafo orientato completo.

L’indicazione completo ci informa che non vi sono nodi isolati: ovvero privi di un arco di collegamento con altri nodi.

Rappresentazione di un grafo con un linguaggio di programmazione

Esistono diverse possibilità per rappresentare un grafo attraverso un qualsiasi linguaggio di programmazione.

Una di queste è la lista di adiacenza.

Lista di adiacenza

Per costruire una lista di adiacenza che rappresenti un generico grafo, possiamo sfruttare due costrutti tipici della maggior parte dei linguaggi di programmazione:

E adesso? Che si fa?

Adesso è arrivato il momento di mettersi al lavoro per cercare di tradurre in codice FreeBASIC le idee che abbiamo raccolto sin qui.

Abbiamo di fronte a noi due obiettivi molto difficili:

  1. Sviluppare una applicazione per la rappresentazione grafica sia di una generica base di dati che degli algoritmi. Una rappresentazione che metta insieme l’arte (colori e figure) e la scienza (concetti e idee), e che sia inoltre operativa: ovvero che si possano eseguire gli algoritmi sulla base dati.
  2. Che questa applicazione non si limiti ad essere un altro modo per fare programmazione visuale, ma che sia una educazione pratica del pensiero.

Ogni progetto ha bisogno di un nome. Eccolo: RIMIRO. 🙂

Come possiamo far fare qualcosa al computer sulla base di una serie di concetti interconnessi?

Nel precedente articolo abbiamo identificato i due soli elementi che riteniamo debbano essere necessari e sufficienti per permetterci di programmare con i concetti.

I due elementi sono: i concetti e le connessioni tra loro.

Siccome nell’Informatica, come anche in tanti altri campi, bisogna evitare di reinventare la ruota, se riflettiamo in maniera approfondita sull’idea di una rete di concetti interconnessi, arriviamo, prima o poi, a toccare il concetto di grafo.

Concentriamoci ora sulla definizione semplificata di grafo:

Un grafo è un insieme di elementi detti nodi che possono essere collegati fra loro da linee chiamate archi.

Ma allora, se equipariamo i nostri concetti ai nodi e le nostre connessioni agli archi, siamo forse sulla buona strada per tradurre in codice informatico la nostra rete di concetti interconnessi.

Nel prossimo articolo approfondiremo la relazione tra i grafi, i diagrammi di flusso e i database.

Come possiamo far entrare in relazione più concetti?

Nei due precedenti articoli abbiamo riflettuto sulla possibilità di fare coding con i concetti e poi abbiamo iniziato a vedere come definire un concetto nel nostro codice.

Adesso dobbiamo tentare di dare una risposta a questa domanda:

Come possiamo far entrare in relazione più concetti?

Per farlo dobbiamo chiarirci le idee su cosa intendiamo per relazione.

Domandiamoci quindi:

Cos’è una relazione?

Nel Vocabolario Treccani troviamo, tra le varie definizioni, questa:

Connessione o corrispondenza che intercorre, in modo essenziale o accidentale, tra due o più enti (oggetti e fatti, situazioni e attività, persone e gruppi, istituzioni e categorie, fenomeni, grandezze, valori, ecc.).

Una relazione è quindi una connessione tra due o più enti: quindi tra due o più concetti.

Proviamo allora a riformulare la nostra prima domanda in questo modo:

Come possiamo creare una rete di concetti interconnessi?

Interconnessione concettuale

Se proviamo ad immaginare una rete di concetti interconnessi, è probabile che tra le immagini che si formano nella nostra fantasia ci sia quella di una ragnatela.

Ecco allora che potremmo identificare i fili com le connessioni e i punti di contatto dei vari fili con i concetti.

E il ragno? Che ruolo potremmo dare al ragno?

Il ragno sarà il nostro pensare che pazientemente deve tessere la tela che unisce i vari concetti.

Ma la similitudine con la ragnatela può spingersi oltre. Domandiamoci: chi è la preda?

La preda è l’obiettivo del pensare.

La preda che viene intrappolata nella tela dei nostri concetti interconnessi non è altro che l’idea. Un’idea che si illumina nella mente del programmatore mentre con il suo pensare connette i concetti.

Un esempio pratico

''
''esempio di connessione tra tre concetti
''

''definiamo il tipo di dato "concetto*"
type concetto
  id_1 as integer ''identificativo del concetto
  etichetta as string
  id_2 as integer ''identificativo del concetto connesso
end type
''dimensioniamo e creiamo il vettore dei concetti
''del tipo di dato "concetto"
dim vettore_concetti(1 to 3) as concetto

''**********

''valorizziamo i membri dei diversi concetti
vettore_concetti(1).id_1 = 1
vettore_concetti(1).etichetta = "pioppo"
vettore_concetti(1).id_2 = 2
vettore_concetti(2).id_1 = 2
vettore_concetti(2).etichetta = "albero"
vettore_concetti(2).id_2 = 3
vettore_concetti(3).id_1 = 3
vettore_concetti(3).etichetta = "pianta"
vettore_concetti(3).id_2 = 0

''**********

''esplora tutte le connessioni che si diramano dal primo concetto
''presente nel vettore dei concetti e stampa a video tutti i
''concetti interconnessi
cls
dim as integer id_1, id_2
id_1 = vettore_concetti(1).id_1
id_2 = vettore_concetti(1).id_2

print vettore_concetti(id_1).etichetta;

do until id_2 = 0

  print " ---> " & vettore_concetti(id_2).etichetta;

  id_1 = vettore_concetti(id_2).id_1
  id_2 = vettore_concetti(id_2).id_2

loop

Nel prossimo articolo affronteremo il terzo quesito:

Come possiamo far fare qualcosa al computer sulla base di una serie di concetti interconnessi?

Come possiamo definire un concetto nel nostro codice?

Ci eravamo lasciati nel precedente articolo dicendo che se vogliamo esplorare la possibilità di fare coding con i concetti, dobbiamo risolvere tre problemi, il primo dei quali è legato proprio alla domanda scelta come titolo per questo articolo:

Come possiamo definire un concetto nel nostro codice?

Sempre nell’articolo già citato abbiamo definito il concetto* di concetto** in questo modo:

Un concetto può essere visto come una etichetta che rimanda ad una entità reale o astratta.

In questo senso l’etichetta concetto* potrebbe rimandare all’entità astratta “cerchio” (concetto**) che a sua volta potrebbe rimandare all’entità reale “ruota avente raggio di 22cm”.

Proviamo a partire con le nostre riflessioni proprio dalla definizione che abbiamo dato.

Innanzitutto suddividiamola nelle sue parti costitutive per verificare se possiamo tradurle in codice:

  • un concetto è identificato da una etichetta;
  • un concetto rimanda ad una entità reale o astratta.

Concentriamoci per il momento sulla sola prima frase e facciamo entrare nel flusso dei nostri pensieri anche gli argomenti trattati nella nostra Guida al FreeBASIC. Sappiamo che uno dei sinonimi del verbo identificare è far coincidere. Facendo ora un parallelo con quanto abbiamo imparato studiando il FreeBASIC, ci dovrebbe venire in mente l’articolo dedicato alla dichiarazione delle variabili: ad una variabile, infatti, coincide uno spazio in memoria. In altri termini, all’etichetta scelta come nome della variabile corrisponderà un certo valore: quindi una certa informazione.

Tenendo a mente questa idea e passando alla seconda frase, il rimando ad entità reali o astratte porta il nostro pensiero al tema più specifico della dichiarazione di un tipo di dato definito ad hoc che possa rappresentare queste entità.

Attenzione! Nell’ambito dell’informatica, rappresentare una qualsiasi cosa significa, in ultima analisi, costruire un modello.

Le nostre riflessioni ci hanno quindi per ora condotto ad un altro concetto, quello di modellizzazione.

Il processo di modellizzazione avviene attraverso l’interazione tra l’atto dell’osservazione e l’atto del pensare. Questa interazione permette di creare un modello, cioè una classe generica (concetto**) che rappresenta una certa entità astratta che a sua volta rappresenta idealmente una entità reale o astratta (cioè il cosiddetto oggetto o istanza della classe).

Esprimendo il problema in questi termini ci sembra di giungere come logica conseguenza al paradigma della programmazione orientata agli oggetti.

Ma allora questo ipotetico nuovo paradigma di programmazione per concetti che andiamo vagheggiando non è altro, in realtà, che l’arcinoto paradigma di programmazione ad oggetti?

Apparentemente sembrerebbe di sì, ma cè un aspetto che facilmente può sfuggire ad una prima analisi.

Proviamo ad approfondire la questione dicendo quanto segue:

Nella programmazione per concetti non si vogliono creare dei modelli, ovvero delle classi al fine di istanziarle per ottenere degli oggetti con cui lavorare, ma si vuole rimanere al solo livello concettuale del tipo (type), e solo con questo lavorare. Non si creano quindi delle classi e non si istanziano oggetti.

Si abbandona quindi l’idea della rappresentazione: ovvero la creazione arbitraria e soggettiva di un modello (concetto**), nella convinzione che il modello non potrà mai essere la realtà.

Si persegue invece l’idea dello sviluppo dinamico di una rete di concetti* interconnessi.

Nel nuovo paradigma di programmazione per concetti che andiamo definendo il ruolo fondamentale spetta alla riflessione del programmatore: sarà il suo pensare riflessivo che creerà dinamicamente le connessioni concettuali che sveleranno l’idea che di volta in volta informa una determinata realtà.

Un esempio pratico

''definiamo il tipo di dato "concetto*"
type concetto
  id as integer ''identificativo del concetto
  etichetta as string
end type

''dimensioniamo e creiamo il vettore dei concetti
''del tipo di dato "concetto"
dim vettore_concetti(1 to 2) as concetto

''valorizziamo i membri dei diversi concetti
vettore_concetti(1).id = 1
vettore_concetti(1).etichetta = "albero"
vettore_concetti(2).id = 2
vettore_concetti(2).etichetta = "pioppo"

Bene. Possiamo per oggi fermarci qui.

Nel prossimo articolo affronteremo il secondo quesito:

Come possiamo far entrare in relazione più concetti?

Fare coding con i concetti

Proviamo a domandarci: è possibile fare coding con i concetti?

Ma cos’è un concetto?

Un concetto può essere visto come una etichetta che rimanda ad una entità reale o astratta. Un esempio del primo tipo potrebbe essere il concetto di “albero” riferito al pioppo che vedo fuori dalla finestra di casa mia, il secondo tipo potrebbe essere ancora una volta il concetto di “albero”, questa volta però inteso come astrazione per indicare genericamente le piante legnose perenni.

Il concetto però, di per sé, risulta statico: se dico all’improvviso al mio vicino la parola “albero”, è probabile che lui si volti e mi guardi con aria interrogativa senza sapere che pensare. Fare coding significa invece creare qualcosa in grado di fare qualcos’altro: quindi un qualcosa di dinamico.

Dobbiamo allora domandarci: come possiamo mettere in moto un concetto? Se è vero che un concetto, preso da solo, ci appare come una entità statica, allora è forse probabile che ci occorra qualcos’altro per renderlo attivo. Ma cosa?

Stiamo attenti. Concentriamoci un attimo su questo punto…

Ebbene, qualsiasi sia quest’altra entità che andiamo cercando, sarà pure essa stessa esprimibile attraverso un concetto!

Ma allora sarà sufficiente accostare ad un concetto un secondo concetto per renderlo attivo?

Facciamo una prova: prendiamo il concetto di “numero” e il concetto di “pace”. Immaginiamo di accostarli… non accade nulla.

Facciamo allora una seconda prova: prendiamo sempre il concetto di “numero” e accostiamogli il concetto di “parità”.

Ecco che in questo caso nella nostra mente accade qualcosa, come una piccola scintilla: i due concetti si collegano; tra loro si stabilisce una relazione, nasce una immagine, una idea.

I due concetti, sino a quel momento inerti, entrano in una relazione generativa e nella nostra mente vi è un’esplosione di numeri pari che danzano davanti ai nostri occhi.

Che sia questa una possibile via per fare coding con i concetti?

Se vogliamo provare a percorrere questa via, appare evidente che abbiamo di fronte a noi 3 problemi da risolvere:

  1. Come possiamo definire un concetto nel nostro codice?
  2. Come possiamo far entrare in relazione più concetti?
  3. Come possiamo far fare qualcosa al computer sulla base di una serie di concetti interconnessi?

Rispondere a questi tre quesiti sarà oggetto dei prossimi articoli. 🙂

Immaginare un modo nuovo di fare coding

Premessa

Questo articolo non vuole inserirsi nel dibattito se sia corretto o meno avvicinare i bambini al coding, ovvero alla programmazione informatica, durante la scuola primaria con l’obiettivo di sviluppare in loro il pensiero computazionale già nei primi dieci anni di vita.

Anzi, personalmente ho firmato la petizione ai responsabili dell’istruzione nell’UE e negli Stati membri per concedere il diritto ad asili nido, scuole materne e scuole elementari di essere liberi dallo schermo, nella convinzione che ogni cosa deve essere fatta a suo tempo.

Il pensiero computazionale è un processo mentale per la creazione di un algoritmo, ovvero di una sequenza finita di passi elementari (istruzioni), traducibili poi in un linguaggio di programmazione (codice sorgente) in grado di permettere ad un computer di risolvere un problema.

Sull’introduzione delle competenze digitali nella scuola si visiti il sito web del MIUR (Ministero dell’Istruzione dell’Università e della Ricerca) dedicato al Piano Nazionale Scuola Digitale.

Si veda inoltre il progetto CS Unplugged che intende avvicinare i bambini al mondo del coding senza utilizzare direttamente il computer.

Come adulti, però, dobbiamo sentirci liberi di esplorare la possibilità, se esiste, di fare coding antroposoficamente così come esiste per esempio un modo antroposofico di educare (pedagogia Waldorf), di coltivare (agricoltura biodinamica) o di curare (medicina antroposofica).

Scopo

Lo scopo è quello di provare a gettare uno sguardo non meramente utilitaristico sul mondo dell’Informatica.

Per intraprendere questo percorso di ricerca ci si ispira alla concezione filosofica dell’Idealismo oggettivo così come è stata veicolata dall’Antroposofia.

Coding e creatività

Non c’è dubbio che nella programmazione informatica la creatività giochi un ruolo fondamentale.

Non basta infatti conoscere un linguaggio di programmazione per risolvere un dato problema, e molto spesso non basta neanche una disciplinata capacità di analisi unita alla conoscenza della natura del problema che si sta affrontando. Tutte cose, ovviamente, indispensabili.

Quando ci si trova bloccati, quando sembra che non ci sia più una via d’uscita, ecco che una illuminazione, un guizzo della fantasia, una fulminea intuizione, ci fanno scorgere finalmente la soluzione, e soltanto allora possiamo tornare a mettere mano al codice sorgente scrivendo o correggendo il nostro algoritmo.

Quando il pensiero concepisce un algoritmo efficace ed efficiente, lo si descrive spesso come una soluzione elegante, e non è raro sentire accostare a questa soluzione il concetto di bellezza.

Tutto questo ha a che fare con l’ampio tema relativo alla risoluzione dei problemi, il cosiddetto problem solving, che, per inciso, riguarda tutti noi, sia che si stia lavorando nell’ambito informatico, sia che si debba semplicemente decidere come organizzarsi per andare a fare la spesa.

Possiamo quindi dire che il pensiero computazionale, oltre ad essere una facoltà umana di uso generalizzato e quotidiano, è strettamente legato al pensiero creativo.

Arte e Antroposofia

Nell’ambito dell’Antroposofia l’arte riveste un ruolo fondamentale, tanto che si parla di arti antroposofiche.

Se Rudolf Steiner, il fondatore dell’Antroposofia, ha ritenuto che l’intera esperienza umana dovesse venire informata dalla conoscenza spirituale, tanto da influenzare anche la musica, il canto, la poesia, la scultura, la pittura, la danza (euritmia) e persino l’architettura (architettura organica), allora dobbiamo domandarci:

Come possiamo pensare che un’attività umana, oggi così diffusa, come la programmazione informatica, che abbiamo visto essere così legata anche al concetto di creatività, possa rimanere esclusa dalla visione antroposofica?

Come cultori dell’Antroposofia, è forse arrivato il momento di rivolgere la nostra attenzione anche al mondo legato alla programmazione informatica, senza preconcetti, forti anche del fatto che il software è la parte immateriale di questo mondo, la parte più legata al pensiero immaginativo.

“L’informazione è informazione, non materia o energia.” Norbert Wiener

Per cominciare a farlo, si pensi al fenomeno dell’arte digitale o, per esempio, al linguaggio di programmazione Processing che, tra le altre cose, permette di sviluppare opere d’arte generativa.

“[…] ci stiamo avvicinando sempre più all’epoca della composizione consapevole, razionale. Presto il pittore sarà orgoglioso di spiegare che le sue opere sono costruite.” Wassily Kandinsky, Lo spirituale nell’arte

Fare coding antroposoficamente

Se vogliamo provare a mettere in dialogo il mondo dell’Antroposofia con quello del coding occorre forse immaginare nuove applicazioni che siano capaci di toccare lo spirito di chi le usa, e magari spingersi oltre dando vita ad un nuovo paradigma di programmazione che permetta allo spirito dell’autore (il programmatore) di esprimersi.

Un primo possibile passo…

Chi si avvicina all’Antroposofia scopre molto presto l’importanza che in essa riveste il mondo dei colori e delle figure geometriche, unito al mondo dei concetti e delle idee.

Forse un primo passo potrebbe proprio essere quello di riflettere su come utilizzare i colori e le figure geometriche per creare software antroposofico.

Un piccolo primo esempio: come generare immagini in stile Mondrian.

Ma poi, provando a spingersi oltre, occorrerebbe esplorare la possibilità di creare un nuovo paradigma di programmazione.

Mi rendo conto che tutto questo possa apparire come estremamente vago e privo di solide basi, ma si tratta per adesso soltanto di una intuizione su cui magari cominciare a riflettere e lavorare.