Imparare a programmare partendo da zero Numeri Come nasce un programma? Dalla necessità di risolvere un problema. Non un problema qualunque, però, ma un problema riguardante dei dati; perché un computer, infatti, per quanto potente possa essere, sarà sempre e comunque solo un calcolatore. Il simulatore di volo più realistico, l'ultima versione di Fifa 2036, il più complesso dei programmi di grafica, tutti quanti non fanno altro che manipolare numeri. Sta al progammatore attribuire uno specifico significato a quei numeri. E qui entrate in scena voi. Per poter scrivere un programma, bisogna seguire questi passi: -individuare il problema da risolvvere -analizzare il problema -scomporlo in sotto-problemi più ssemplici, a loro volta da scomporre e riscomporre successivamente, fino a ridursi a tantissimi, piccolissimi, semplicissimi problemi, rappresentati da operazioni tra numeri -escogitare un modo per mettere neella memoria del computer questi numeri -insegnare al computer a risolveree ognuno di quei singoli problemi -ordinare al computer di mostrare il risultato finale Tutto questo perché a un computer non importa se deve fare tantissime operazioni (è il suo mestiere...), gli importa solo che le operazioni siano semplici: per un computer sarà semplicissimo prendere un miliardo di numeri, dividerli tutti per due, e stamparli sullo schermo, mentre noi ci metteremmo una vita. Mentre per noi sarà semplicissimo riconoscere la faccia di un nstro amico su una foto, ma provate a "dire" al vostro PC di fare altrettanto: DOVE glielo dite? In una fessura del monitor? :-) COME glielo dite? Scrivete con la tastiera "Chi è questo tizio?" E lui come fa a vedere la foto? Col monitor?!? Con uno scanner? E come diciamo al computer di leggere e interpretare la foto che è nello scanner?!? Niente da fare. Ci vuole UN PROGRAMMA. Proviamo a scriverlo, questo programma. Non pretenderemo di insegnare al PC a riconoscere una persona da una foto (migliaia di provetti programmatori cercano di insegnarglielo da anni, ma ancora con scarsi risultati, nonostante quanto si vede nei film); ci limiteremo a insegnargli a riconoscere se una figura è un quadrato oppure no. Abbiamo dunque identificato il problema: riconoscere se una figura è un quadrato. Ora analizziamolo: -un quadrato è un poligono, ossia una figura formata da linee che uniscono dei punti; -il quadrato ha, in particolare, 44 linee che uniscono 4 punti; -ancora più in particolare, le 4 llinee hanno la stessa lunghezza; -una lunghezza può essere espressaa sotto forma di numero: CI SIAMO! Siamo riusciti a tradurre il nostro problema grafico in un problema di numeri! Bene, e adesso? Il nostro programma dovrà essere usato da un utente; questi fornirà al programma dei dati (INPUT), e si aspetterà dei risultati (OUTPUT). INPUT: come vogliamo inserire i nostri dati? Graficamente (disegnando un poligono), o numericamente (scrivendo le coordinate dei vertici)? "Graficamente", direte voi, è più semplice. Perfetto: è più semplice PER L'UTENTE, ma di conseguenza più complicato PER VOI CHE PROGRAMMATE. Delle due l'una, non ci sono altre possibilità: il computer è solo un velocissimo imbecille che sa solo fare bene i conti, per cui "qualcuno" deve abbassarsi al suo livello e "parlare per numeri". Normalmente se ne occupa il programmatore, cosicché l'utente ignorante deve solo cliccare qualche pulsante per ottenere i risultati voluti; ma, nel caso che stiamo trattando voi, gli ignoranti... be', siete voi, che ancora IGNORATE come si fa a programmare, per cui lasciamo un po' di lavoro da fare anche all'utente finale, che dovrà inserire a mano le coordinate: per voi sarà più semplice scrivere il programma. Come immetterà l'utente i dati nel programma? Scrivendo dei numeri. Dove? Dentro delle caselle di testo. Quante saranno queste caselle? Quattro? Troppo facile, così il programma dovrebbe solo calcolare quanto sono lunghi i lati... Predisponiamo allora 6 caselle. Siccome il programma che scriveremo sarà molto elementare, dovremo però fargli dare per scontato almeno alcuni dati: ad esempio, le coordinate che inseriremo saranno dei vari vertici presi in senso orario, anziché a caso; così il programma non dovrà controllare quali vertici sono più vicini tra loro, se per sbaglio tre vertici sono allineati, ecc. Il programma saprà cioè a priori che i dati inseriti si riferiscono a un poligono "normale" (regolare o no, lo calcolerà lui), cioè senza righe che si incrociano, o vertici sovrapposti. Non sapendo a priori di quanti vertici è dotato il poligono, come farà il programma a sapere quando l'utente ha finito di inserire i dati? Certo NON quando tutte le caselle sono piene (sennò avremmo sempre un esagono). Prepareremo allora un pulsante, che l'utente premerà quando vorrà avviare l'elaborazione. Ok, e il risultato? Dove lo scriviamo? Dentro a un'etichetta, che inizialmente conterrà la scritta "[non calcolato]". Una volta premuto il tasto, essa verrà sostituita con "quadrato" se è il caso, altrimenti.... sta a noi decidere se visualizzare un semplice "non è un quadrato", oppure "triangolo", "pentagono" ecc..., nel qual caso però dovremo insegnare al programma anche a riconoscere altri poligoni. Perfetto, ora abbiamo tutto: il problema è analizzato e scomposto, sappiamo come riconoscere un quadrato (il procedimento usato da un programma per fare una cosa è detto, genericamente, algoritmo), abbiamo la nostra interfaccia (l'insieme di caselle di testo, pulsanti e etichette, che ci permette di inserire dati e vedere i risultati): non ci resta che implementare il nostro algoritmo, cioè scrivere un programma che faccia quello che abbiamo progettato. Lo faremo usando il linguaggio wxBasic. Come si fa a scrivere un programma? Si prende un editor di testi, e si scrivono le istruzioni che lo compongono. Poi si fa elaborare questo elenco di istruzioni, chiamato codice sorgente, a un programma, che tradurrà a sua volta il nostro sorgente facendolo diventare un programma. Quindi: il codice sorgente viene "trasformato" in un programma. Ma perché? Perché, come detto all'inizio, il computer capisce solo i numeri, mentre noi scriveremo il nostro programma usando parole: bisognerà che qualcuno traduca queste parole in numeri che il computer possa capire. Questo "traduttore" è un programma che IMPLEMEMTA un linguaggio: un linguaggio che può essere il C, il Pascal, il Basic, il Perl, quello che volete, ma sempre e comunque basato su parole: il "traduttore" leggerà il nostro sorgente, riconoscerà le parole del linguaggio che abbiamo scelto, e le trasformerà in numeri comprensibili dal computer. Dovremo quindi stare attenti a "dare in pasto" a un "traduttore" un sorgente scritto nel giusto linguaggio: inutile passare un sorgente BASIC a un "traduttore" Pascal, vedrebbe soltanto errori, ovviamente! Parlando più propriamente: non si dice, in realtà, "traduttore"; possiamo avere interpreti o compilatori. Non ci addentreremo in spiegazioni complicate: qui basti sapere che il BASIC è un linguaggio interpretato, quindi chiameremo wxBasic "interprete" (anche se non è esattissimo, perché wxBasic si basa su bytecode). Tra parentesi, BASIC è una sigla che sta per Beginner's All Purpose Symbolic Instruction Code, ossia Codice a istruzioni simboliche adatto a tutti gli scopi, per principianti. Fatto apposta per voi, dunque. ;-) Per ottenere il nostro programma a partire dal sorgente in wxBasic, quindi, dovremo passare al nostro interprete il sorgente, il quale avrà estensione WXB , per convenzione. Come si fa? O si scrive da linea di comando wxbasic nomesorgente.wxb oppure si trascina col mouse il sorgente sull'eseguibile wxbasic.exe . In entrambi i casi, trattandosi di un interprete, il programma risultante (i numeri equivalenti alle parole che noi avevamo scritto) non verrà scritto in un file, ma solo conservato in memoria, e cancellato al termine dell'esecuzione. E però possibile ottenere anche un programma stand-alone, che cioè "funziona da solo", senza dover ogni volta passare il sorgente a wxbasic. Per farlo, si usa il programma BIND che trovate insieme a wxbasic, o in versione migliorata sul mio sito (http://www.geocities.com/lcassioli/wxbasic/). (Nel caso si usasse invece un compilatore come il C o il Pascal, si otterrebbe direttamente un file eseguibile.) Per evitare di dover usare un editor di testi per scrivere, e dover poi passare il sorgente all'interprete/compilatore, spesso i programmatori usano gli IDE (Integrated Development Environment, ambienti di sviluppo integrati): si tratta di editor di testi "evoluti", che alla semplice pressione di un pulsante passano il sorgente all'interprete/compilatore, ed eseguono il programma risultante. Comodissimo ma... wxBasic non ha un suo IDE: ce ne sono diversi in giro per la rete, più o meno stabili. Io personalmente uso l'editor di testi ConTEXT opportunamente configurato (vedi mio sito). Bene, questo è tutto: ora sapete tutto quello che c'è da sapere per scrivere il vostro programma sui quadrati. Non vi resta che studiarvi il listato commentato, copiarlo nel vostro editor di testi preferito, provarlo, modificarlo, aggiustarlo, storpiarlo, ecc. ecc..., finché non diverrete padroni di wxBasic. Happy Programming, Luca Cassioli cassioli@iol.it ---------------- Programma per quadrati; ritagliarlo e incollarlo in un file vuoto, salvare in un file con estensione WXB, ed eseguire con wxBasic 'Programma didattico per il riconoscimento dei poligoni 'Linguaggio: wxBasic - Autore: Luca Cassioli - Anno: 2004 '********** ' NOTA '********** 'Qualunque linguaggio di programmazione è dotato di ALMENO una '(ma spesso 2 o 3) istruzione di COMMENTO: qualunque cosa segua 'questa istruzione, viene IGNORATO dall'interprete/compilatore, 'e serve solo al programmatore per descrivere il funzionamento 'del programma. In wxBasic, il "comando" è un semplice APOSTROFO, //ma si può anche usare il simbolo "//", come in questa riga, oppure rem mettere la parola REM (REMark=commento) all'inizio '---------- INIZIO INTERFACCIA GRAFICA ----------- '"Nothing" indica il "controllo-padre" da cui l'oggetto-finestra 'dipende: ogni oggetto deve avere un oggetto-padre, da cui dipende, 'chiamato genericamente "parent" (genitore, in inglese). 'Nelle versioni precedenti di wxBasio, al posto di "Nothing" si 'usava "Null!. 'La finestra non ha identificatore (-1), ha titolo "Poligoni", 'e' posizionata alle coordinate (10,10) dello schermo, e' larga '320 pixel e alta 200, ha il titolo (caption) visibile (attributo wxCAPTION) 'e il menu di sistema è visibile (attributo wxSYSTEM_MENU) . frame=new wxFrame(Null,-1,"Poligoni",wxPoint(10,10),wxSize(320,200),wxCAPTION|wxSYSTEM_MENU) 'Il pannello che fa da sfondo (e da "padre") a tutti i 'successivi controlli ha per "parent" la finestra 'principale. Senza parametri, la occupera' per intero. panel=new wxPanel(frame,-1) 'Definiamo le 4 coppie di caselle di testo (wxTextCtrl) che 'conterranno le coordinate dei vertici. 'Ognuna di esse conterra' PER DEFAULT (cioè come valore standard, 'definito PRIMA di qualsiasi intervento dell'utente sul programma) 'il valore -1. vert1x=new wxTextCtrl(panel,-1,"-1",wxPoint(10,10),wxSize(40,20)) vert1y=new wxTextCtrl(panel,-1,"-1",wxPoint(60,10),wxSize(40,20)) vert2x=new wxTextCtrl(panel,-1,"-1",wxPoint(10,40),wxSize(40,20)) vert2y=new wxTextCtrl(panel,-1,"-1",wxPoint(60,40),wxSize(40,20)) vert3x=new wxTextCtrl(panel,-1,"-1",wxPoint(10,70),wxSize(40,20)) vert3y=new wxTextCtrl(panel,-1,"-1",wxPoint(60,70),wxSize(40,20)) 'Nella casella successiva non mettiamo nessun valore al 'momento della creazione, ma lo facciamo con una 'istruzione successiva (tanto per capire come funziona). vert4x=new wxTextCtrl(panel,-1,"",wxPoint(10,100),wxSize(40,20)) vert4y=new wxTextCtrl(panel,-1,"",wxPoint(60,100),wxSize(40,20)) vert4x.SetLabel("-1") vert4y.SetLabel("-1") 'Definiamo il pulsante che fa eseguire l'elaborazione pulsante=new wxButton(panel,-1,"ELABORA!",wxPoint(200,50),wxSize(80,80)) 'Mostriamo la finestra frame.Show(True) '---------- FINE INTERFACCIA GRAFICA ---------- '----- PROGRAMMA ----- 'La procedura "vai" viene eseguita quando si preme il pulsante: 'questo perche' il pulsante e' COLLEGATO alla procedura tramite 'il comando CONNECT alla fine del programma. sub vai( event ) 'Il valore contenuto in una casella di testo e' di tipo STRINGA, 'cioè è un TESTO: possiamo trasformarlo in un NUMERO con la 'funzione VAL() . Per estrarre il valore dalla casella, usiamo 'il METODO GetLineText(0) dell'OGGETTO di tipo wxTextCtrl . 'Notare che con i ":" (due punti) si possono concatenare più istruzioni 'sulla stessa riga. x1=val(vert1x.GetLineText(0)) : y1=val(vert1y.GetLineText(0)) x2=val(vert2x.GetLineText(0)) : y2=val(vert2y.GetLineText(0)) x3=val(vert3x.GetLineText(0)) : y3=val(vert3y.GetLineText(0)) x4=val(vert4x.GetLineText(0)) : y4=val(vert4y.GetLineText(0)) 'Ora abbiamo in x1, y1 eccetera le coordinate dei vari vertici. 'Come si calcola la lunghezza di un lato compreso tra due vertici? 'Con la FORMULA MATEMATICA della distanza tra due punti: in linguaggio '"umano" si direbbe pressappoco così: 'distanza = 'radice_quadrata_di ( ' (differenza_coordinate_x al quadrato) + (differenza_coordinate_y al quadrato) ' ) 'In wxBasic, la radice quadrata si indica con sqr(), e il quadrato di 'un numero X si scrive X^2 , perciò, se le coordinate dei due vertici 'sono nelle variabili x1, y1 e x2, y2, abbiamo: ' distanza=sqr((x1-x2)^2+(y1-y2)^2 ) 'Nel nostro programma scriveremo quindi: lato1=sqr((x1-x2)^2+(y1-y2)^2) lato2=sqr((x2-x3)^2+(y2-y3)^2) lato3=sqr((x3-x4)^2+(y3-y4)^2) lato4=sqr((x4-x1)^2+(y4-y1)^2) '(Inserire qui sotto l'istruzione print lato1,lato2,lato3,lato4 'se si vuole vedere quanto valgono i lati.) 'Per essere un quadrato, deve avere i 4 lati uguali: mostriamo 'un altro messaggio: if (lato1=lato2) and (lato2=lato3) and (lato3=lato4) then wxMessageBox("Il poligono è un quadrato!") end if 'Il blocco di istruzioni sopra è molto particolare, perché mostra l'uso 'degli OPERATORI LOGICI (AND, OR, NOT): 'Il blocco IF fa visualizzare il messaggio solo se e' vero che lato1=lato2 'E che lato2=lato3 E che lato3=lato4 , cioè se le tre condizioni sono TUTTE 'vere. IN TEORIA, usando wxBasic si poteva scrivere anche 'if lato1=lato2=lato3=lato4 eccetera , 'MA non tutti i linguaggi, in genere, permettono questa forma, quindi 'è meglio non abituarsi ad usarla. end sub 'Per finire, colleghiamo l'interfaccia al programma, con l'istruzione 'CONNECT che segue: connect (pulsante,wxEVT_COMMAND_BUTTON_CLICKED,"vai")