mercoledì 31 dicembre 2014

Modern C++ - Gli Array

Ben ritornati sulle pagine del corso su Modern C++. A questo link trovate come sempre l'indice di tutte le precedenti lezioni.

Dopo aver giocato, seppur in modo rapido, con le variabili di tipo numerico, oggi vi delizio con un altro argomento: gli array numerici.

In C++, a differenza di altri linguaggi di programmazione, quali PHP, Python o Javascript, un array è una collezione di dati dello stesso tipo. Una sequenza puó esser, ad esempio, solamente di tipo int oppure double oppure di un altro tipo ben definito.

Un array può esser monodimensionale (noto anche come vettore) oppure multidimensionale (es., una matrice) e puó avere dimensione fissa, ovvero un numero predefinito di elementi, oppure a dimensione dinamica.

In Modern C++ si preferisce utilizzare strutture giá definite nella Standard Library, in modo da evitare errori di ogni genere e al fine di ottenere ottime prestazioni. infatti, è caldamente consigliato l'uso di std::vector, poiché permette di definire una sequenza di dati a dimensione dinamica, ma è anche possibile inizializzare tale struttura con una dimensione predefinita.
Tale struttura puó esser utilizzata includendo l'header apposito, mediante la direttiva #include <vector> e si puó utilizzare nel seguente modo:
#include 

std::vector<int> array;                  //array di tipo int, vuoto
std::vector<double> array_double;        //array di tipo double, vuoto
std::vector<double> array_double_2(10);  //array di 10 elementi di tipo double, inizializzati con 0.0
std::vector<double> array_double_2(10, 2.5);  //array di 10 elementi di tipo double, inizializzati con 2.5
Vector è una struttura altamente efficiente, che permette l'espansione o dimensione dello stesso array, senza badare ad allocare/deallocare manualmente la memoria.

E`possibile creare quindi un array vuoto oppure un array contenente valori predefiniti. Ma come possiamo giocare con essi?

Ecco di seguito un esempio di listato C++:
Come potete notare,ho incluso l'header <vector> e ho dischiarato alcuni array monodimensionali: un array di integer e 4 array di tipo double, ciascuno creato in modo differente.
Al fine di accedere singolarmente agli elementi di un array, occorre scorrere all'interno di essi. In C++ è possibile farlo in 2 modi: nel nuovo modo, utilizzando i cicli range-based, oppure nel modo classico, C-style, utilizzando il ciclo index-based. Nel primo caso, non si utilizza una variabile indice per accedere all'elemento, bensí si estrare una copia dell'elemento stesso (vedremo come sará possibile utilizzarne il riferimento, nei prossimi post) e si puó lavorare sulla copia. Nel secondo caso, si utilizza un indice che permette di accedere agli elementi singolarmente; la variabile indice vá incrementata di volta in volta per scorrere il vettore in sequenza, controllandone il valore, che deve esser minore della dimensione del vettore. Infatti, in C++, un vettore ha elementi con indici che vanno da 0 a N-1, dove N è il numero di elementi.
Nel caso di array_double_2, avente 10 elementi, gli indici vanno da 0 a 9.

Indice per scorrere un vettore di 10 elementi


Le due diverse applicazioni le notate alle righe 12 e 42.

Vector mette a disposizione alcune interessanti funzioni: push_back(), che permette di inserire in coda un nuovo elemento nel vettore; pop_back(), che permette di rimuove l'ultimo elemento del vettore; size(), che riporta la dimensione del vettore (da non confondere con il giá visto sizeof, il quale riporta la dimensione del vettore in byte.

E' possibile inoltre copiare i valori di un vettore in un secondo vettore: per vettori di piccole dimensioni, questa operazione risulta efficiente, mentre per dimensioni maggiori, puó esser estremamente svantaggiosa. Vedremo nei prossimi post come è possibile risolvere questo problema.

L'output del codice parla da solo:
Output di DemoApp2
E gli array multidimensionali? Possono esser creati nel seguente modo:


std::vector<std::vector<int>> array;  //array di array di tipo int, vuoto


Alla prossima e buon 2015 :)

Clear per Python [Brevi Esercizi]

Salve!

Oggi parliamo del comando clear, della sua funzione, ma non in Bash, in Python.

La funzione di clear è quella di pulire la finestra del terminale. In Python non esiste, ecco.

Bisogna importare un modulo, os, per poterla avere. Il problema si pone soprattutto all'interno degli script, sopratutto in presenza di cicli iterativi infiniti, chissà se si può dire così.. ma a me piace questa definizione, perciò non la cambio.

Dicevo che il problema si pone soprattutto all'interno di uno script, se invece lanciamo comandi in una shell python e vogliamo pulire la finestra del terminale, basta la combinazione di tasti Ctrl+L, che funziona anche in bash. Pare non funzioni su Windows, ma il problema non mi tange mica, uso solo linux, e da svariati anni.

Facciamo un esempio concreto. Costruiamo un semplice script che ci aggiorni dell'ora ogni secondo.
#!/usr/bin/python
# -*- coding: utf-8 -*-

import time
while True:
   print time.strftime("%H:%M:%S", time.localtime(time.time()));
   time.sleep(1);
Capirete subito, una volta eseguito lo script, che il comando clear diventa necessario.


Per aggiungerlo, basta importare il modulo os e costruire una funzione. Almeno io faccio così.

Fatte le dovute aggiunte, avremo il seguente codice:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import time, os

def clearScreen():
 os.system("clear")

while True:
   print time.strftime("%H:%M:%S", time.localtime(time.time()));
   time.sleep(1);
   clearScreen()
In questo modo non vedremo più l'elenco interminabile delle ore, dei minuti e dei secondi.


Alla prossima e buon anno!

martedì 30 dicembre 2014

Decodifichiamo codici QR con Python [Brevi Esercizi]

Salve!

In un precedente post, abbiamo visto come creare un codice QR con Python, oggi vediamo come decodificarlo.

Anzitutto installiamo il seguente pacchetto

$ sudo apt-get install python-qrtools

Create un documento di testo nella cartella Documenti, chiamatelo DecQR.py e incollateci il codice di cui sotto; nella stessa cartella salvate anche il codice QR da decodificare.

Poi dal terminale spostatevi nella directory Documenti

$ cd Documenti

rendete eseguibile lo script

$ chmod +x DecQR.py

e lanciatelo

$ ./DecQR.py

Lo script è interettivo, infatti vi chiederà il nome esatto del codice QR da decodificare. L'output sarà stampato nella stessa finestra del terminale.

#!/usr/bin/python
# -*- coding: utf-8 -*-

from qrtools import QR
print
#Digitiamo il nome del codice QR da decodificare
Nome_Codice_QR = raw_input("Digita il nome del codice QR da decodificare? ")
#Viene impostato il nome
myCode = QR(filename = Nome_Codice_QR)
#decodifica
if myCode.decode():
  print
  print "Output:"
  print myCode.data
  print

L'indice della rubrica "Brevi Esercizi" lo trovate qui

Alla prossima! ;)

venerdì 26 dicembre 2014

La tombola parlante

Nella tombola, un giocatore con ruolo di croupier ha a disposizione un tabellone sul quale sono riportati tutti i numeri da 1 a 90, e un sacchetto riempito con pezzi numerati. Il suo compito consiste nell'estrarre i pezzi in modo casuale, e annunciare agli altri giocatori il numero uscito.

Bene, lo script, appena abbozzato, non fa altro che estrarre i numeri in modo casuale e annunciarli. Per continuare con l'estrazione bisogna premere Invio, per uscire dallo script, Ctrl+C.

Installiamo alcune dipendenze:

$ sudo apt-get install toilet espeak sox

Create un documento di testo nella cartella Documenti, chiamatelo croupier.sh e incollateci il codice di cui sotto.

Poi dal terminale spostatevi nella directory Documenti

$ cd Documenti

rendete eseguibile lo script

$ chmod +x croupier.sh

e lanciatelo

$ ./croupier.sh

#!/bin/bash
#Bit3Lux
#tombola.sh

function numero(){
espeak -p 50 -s 180 --stdout -v it+f5 | play -t wav - \
overdrive 10 
}
a=`for i in {1..90}; do echo $i; done | shuf`
clear
for i in $a 
do
     toilet -f smmono12 $i  && echo $i | numero 
    echo -e "\v" "Premere invio per continuare, Ctrl+C per uscire dallo script"
    read
    echo ""
    clear
done
exit 0

Alla prossima!

mercoledì 24 dicembre 2014

Modern C++ - Prime operazioni con le variabili

Ben ritornati su queste del corso di Modern C++. Spero che il post su CMake non vi abbia particolarmente stravolto.

Oggi vedremo nel dettaglio come giocare con le variabili e le operazioni matematiche di base.

In C++, classicamente, una variabile si definisce nel seguente modo:

tipo_di_dato nome_variabile;

dove tipo_di_dato puó essere uno dei tipi built-in oppure custom (ovvero da noi definito) oppure, novitá assoluta introdotta da C++11, puó essere dedotto in automatico dal compilatore, per mezzo della parola chiave auto.

I tipi di dato built-in base piú utilizzati in C++ sono:
  • char per caratteri singoli (numeri da 0 a 9, una lettera, un segno)
  • int per valori interi
  • float per valori in virgola mobile a singola precisione
  • double per valori in virgola mobile a doppia precisione
A partire da questi questi 4 tipi di dato, sono poi definiti altri tipi custom, per migliorare la leggibilitá del codice sorgente o per creare dei nomi piú intuitivi, a seconda del progetto che si sta sviluppando. Vedremo nelle prossime lezioni, dopo aver parlato di strutture e classi, come creare tipi di dato custom.

Prima di tutto, occorre abilitare GCC per la compilazione di codice C++11: aprite il file project_props.cmake contenuto nella cartella CMakeModules ed incollate il seguente contenuto:
In questo modo, potremo sfruttare alcune interessanti novitá del Modern C++.
Ho preparato per voi un esempio modificato di DemoApp1, il cui listato è il seguente:
Potete notare la sezione dei commenti, delimitata da /* e */. Questi caratteri delimitatori permettono al compilatore di considerare la sezione di testo compresa tra essi come commenti multilinea, ovvero che si estendono su piú linee di codice. In contrasto a questi delimitatori, abbiamo poi il doppio slash // che identifica un commento semplice, ovvero tutti i caratteri successivi a questo simbolo è trattato come commento, fino al termine della riga corrente.

Ho importato la libreria cmath che contiene, tra le svariate funzioni matematiche quali coseno, seno, tangente, radice quadrata, anche la definizione di numeri complessi. Nel listato, come potete notare, utilizzo std::sqrt() e std::pow() per calcolare la radice quadrata e la potenza di un numero.

Nel nostro main(), vedete l'utilizzo di una variabile: in essa viene salvato tipicamente un valore, numerico o letterale, a seconda del tipo di dato specificato tra quelli sopra descritti.

Al rigo 10 vedete la dichiarazione di una variabile, chiamata var_a, che assume valore 3*3, ovvero 9. Questa è la dichiarazione in C++ classico, identica a quanto avviene in C. Una alternativa a questa forma puó essere la seguente:
int var_a(3*3);

Al rigo 11, invece, trovate un nuovo concetto di dichiarazione di variabile, inizializzata con il valore tra parentesi graffe {}, simile a quanto si puó vedere per linguaggi come Python e Javascript, per inizializzare array di elementi. Vedremo come anche in Modern C++ è possibile fare la medesima cosa.
La differenza tra la dichiarazione al rigo 10 e la dichiarazione al rigo 11 sta nel controllo sul tipo di dato effettuato con la seconda modalitá. Il compilatore effettua controlli ed avvisa, mediante warnings, se ci sono problemi con la conversione o inizializzazione di variabili, mentre nel primo caso ció non avviene e la conversione avviene implicitamente.
E´ sempre meglio preferire l'inizializzazione mediante {} ove possibile, poiché è sintatticamente piú corretta.

Al rigo 12, potete vedere come è possibile effettuare piú operazioni: C++ eseguirá le operazioni per precedenza, se non vi sono specificate le parentesi tonde, ovvero, ad esempio, 45.2/3.8*12 è diverso da 45.2/(3.8*12).

E' possibile inizializzare una variabile con un valore numerico o letterale, oppure con il valore di un'altra variabile: infatti, al rigo 15 notate come venga inizializzata var_c con il valore di var_b.

Al rigo 16 viene eseguita la stessa cosa, ma in questo caso, anziché specificare il tipo di dato di var_d, lasciamo al compilatore la libertá di utilizzare il tipo di dato piú appropriato, mediante la parola chiave auto. Questa parola chiave ci permette di alleggerire di molto la leggibilitá e la complessitá del codice, sapendo che il compilatore fará la scelta giusta per quanto riguarda il tipo di dato. Unica accortezza, è sconsigliato utilizzare le {} per inizializzare una variabile, poichè nessuna conversione di dato è implicata (poichè il tipo di dato sará scelto in automatico), ma è preferibile sempre il simbolo =.

Al rigo 23 viene effettuata la conversione esplicita, da double ad int e in questo caso, al compilatore viene un piccolo attacco di panico:
Il Compilatore è allarmato
Perchè avviene questo? Il tipo di dato double utilizza 8 byte per rappresentare un numero in virgola mobile con mantissa ed esponente: è detto a doppia precisione, in contrasto a float, che utilizza solamente 4 byte. Il tipo di dato int usa anch'esso (in generale, ma non sempre) 4 byte per rappresentare peró numeri interi. In questo caso, la conversione double->int fa perdere di precisione (perdiamo i valori decimali, idem per float->int) e quindi si ottiene questo warning. Se provate ad utilizzare il simbolo per inizializzare var_c, vedrete che il compilatore non visualizzerá alcun warning, perchè la conversione avviene implicitamente, agendo alle vostre spalle. Si racconta che in missioni critiche in cui il linguaggio C e il linguaggio C++ siano stati usati senza accorgimenti sulle conversioni di dato e abbiano causato notevoli danni.

Al rigo 23, invece, avviene la conversione da char ad int. In questo caso, non riceviamo alcun warning: char utilizza 1 byte mentre int ne usa 4, quindi non ci sono perdite di precisione, anzi si utilizza fin troppo spazio. Ció che accade invece è la conversione del simbolo letterale nel corrispondente valore numerico in formato ASCII, poichè int tratta solo valori numerici interi non letterali.

Infine, notate l'uso di std::sqrt() e di std::pow(), specificando il numero ed utilizzando auto per definire automaticamente il tipo di dato.

Eseguendo il programma, si ottiene il seguente output:

Output del codice sorgente proposto
Per gli amanti del rischio, la divisione per 0 permette di ottenere effetti indesiderati:

Dividendo per 0 si ottengono effetti particolari
Alla prossima e Buone Feste :-)

P.S. L'indice del corso Modern C++ lo potete trovare qui

Pillole di OpenSource #1

  • Il LubitProject, da non molto tempo, si avvale anche di uno spazio su Google+, dove si possono postare dubbi, richiesta di aiuto, suggerimenti, intorno a lubit e ad alcuni linguaggi di programmazione: Bash, Python, Awk, C++. Gruppo di discussione del progetto Lubit Linux

  • Da un po' di tempo, Michele Adduci sta curando sul blog il corso di Modern C++. Alcune raccomandazioni: Anzitutto vi invito a seguire il corso, il cui indice lo trovate qui; vi invito inoltre a rispondere al questionario che trovate alla fine di ogni lezione. Il questionario è di estrema importanza perchè permette a Michele di "tarare" il corso secondo le vostre esigenze, per quello che è possibile, ovvio. 



  • Stanco di sentire parlare i giornalisti, quasi tutti, male degli hackers, l'altro giorno, su facebook, ho cercato di darne una definizione: "L'hacker è colui che vuole vedere dentro alle cose, ma anche dentro se stesso.
    L'hacker è colui che sa di sapere poco nonostante la sua preparazione eccellente, perchè il sapere, quello vero, non ti veste, ma ti toglie i vestiti.
    L'hacker, quello vero, ha perennemente freddo. E i suoi spazi sono alternativamente ampi. Anzi, l'hacker ha una visione alternativa della vita, non per scelta, ma per vocazione.
    L'hacker nasce con una missione, e ci vuole tempo perchè sintonizzi la sua vita a queste aspirazioni che lo trascendono.
    L'hacker sovente fissa il vuoto, perchè, proprio nel vuoto, vede proiettato il suo progetto.
    L'hacker non è un criminale e, spesso, non è neanche un informatico. E siccome i suoi spazi sono diversamente ampi, tutti i suoi sforzi sono tesi ad aggirare o superare creativamente le limitazioni che gli vengono imposte nel suo campo." Voi che ne pensate?

  • Vi segnalo un interessante articolo di Fiorentino Sarro dell'HLCS. Di Fiorentino apprezzo la grinta, lo stile e i contenuti dei suoi articoli. In sintesi, di lui apprezzo tutto. :) Hacklab X – Anno 1, Numero 9

  •  Per il 9 gennaio 2015 è prevista l'uscita di Lubit 4 - 64 bit
 


Auguri di Buon Natale a tutti! ;)


venerdì 19 dicembre 2014

Modern C++ - Lavorare con CMake

Ben ritornati a questo nostro appuntamento con il Modern C++. Fin qui, a dir il vero, abbiamo considerato pochissimo C++, soffermandoci soprattutto sui tools che ruotano intorno ad esso.

Il filo conduttore di questo corso è quello di imparare a sviluppare un progetto partendo dalle fondamenta, utilizzando un approccio bottom-up.

Nella precedente puntata, abbiamo visto come la direttiva #include consenta di importare un header file all'interno di un altro file.
Pensiamo per un momento ad un ipotetica idea di progetto: ad esempio una calcolatrice, oppure un editor di testo sulla falsa riga di gedit oppure di un gioco. Nel caso di un gioco, si ha a che fare con diversi componenti: i personaggi del gioco, la mappa, i suoni, i nemici; possiamo chiamare questi componenti moduli, che potrebbero essere definiti una volta ed essere riutilizzati per differenti progetti (ricordate, uno dei principi fondamentali di ogni linguaggio orientato agli oggetti come il C++ è il DRY - Don't Repeat Yourself, non ripetere ciò che hai giá fatto).

E' possibile automatizzare il processo di gestione dei moduli e delle applicazioni grazie ad un corretto setup di CMake.
L'idea base è la seguente:

Fig. 1 - Esempio di Applicazioni modulari
Immaginate di avere alcuni moduli fondamentali (come in figura 1, i moduli 3 e 4), dai quali dipendono a loro volta altri moduli. A partire da questa struttura di moduli, è possibile poi costruire svariate applicazioni (pensiamo a differenti applicazioni con grafica diversa, piattaforma di riferimento diversa).
In C++, questi moduli saranno chiamati librerie, poichè al loro interno conterranno le definizioni di funzioni che verranno utilizzate dalle applicazioni finali come se fossero dei libri di ricette culinarie già pronte.

Al fine di realizzare questa automatizzazione con CMake, occorre creare una struttura simile alla seguente:
Fig. 2 - Creazione di una struttura di progetto
Come potete osservare dalla Fig. 2, occorre definire una directory principale, tipicamente con il nome del progetto, in questo caso ModernCpp, e successivamente occorre definire le seguenti 3 subdirectories:
  • Applications, contenente a sua volta tante directories quante sono le applicazioni che vogliamo realizzare,
  • Modules, contenente i moduli che vogliamo sviluppare
  • CMakeModules, che raccoglierá specifici files *.cmake utili per gestire le dipendenze con altre librerie di terze parti (ad esempio, Qt) e proprietá di progetto (eventuali flags per il compilatore, informazioni su come generare un progetto redistribuibile)
Inoltre, abbiamo il bisogno di definire tanti file CMakeLists.txt quante sono le macro-aree di lavoro: un file CMakeLists.txt generale, che conterrà i riferimenti ai CMakeLists.txt delle directory Modules ed Applications, i quali file CMakeLists.txt conterranno a loro volta riferimento ai file di configurazione dei singoli moduli o delle singole applicazioni.

Analizziamo con ordine i singoli file CMakeLists.txt, al fine di capire meglio come funziona questo setup.

CMakeLists.txt principale

Il file CMakeLists.txt principale è organizzato come segue:
A differenza del primo file CMakeLists.txt visto in precedenza, questa volta il file è stato realizzato manualmente.
Le linee 1-13 definiscono la versione minima di CMake installata, il nome del progetto, "ModernCpp", il tipo di linguaggio utilizzato è C++ (identificato con CXX) e definiamo alcune variabili, contenenti le informazioni sulla versione del nostro progetto, ad esempio v. 0.1.0 (siamo solo agli inizi!).
Al rigo 16, importiamo un file di configurazione di progetto (per il momento vuoto) ed infine definiamo un prefisso per il nome dei nostri moduli e le directories da esplorare per ulteriori file CMakeLists.txt.

CMakeLists.txt Modules/

Poiché siamo ancora agli inizi, i nostri moduli sono ancora privi di funzionalitá.
Il file CMakeLists.txt della directory Modules per il momento è molto semplice ed ha il seguente contenuto:
semplicemente stiamo definendo le sottodirectory in cui cercare altri file CMakeLists.txt.
I singoli CMakeLists.txt dei sottomoduli non sono qui riportarti, poichè privi di funzionalitá (non contengono alcun codice C++).

CMakeLists.txt Applications/

Il file CMakeLists.txt contenuto nella directory Applications è simile a quello della directory Modules:
mentre è interessante notare il contenuto delle singole DemoApp definite.

CMakeLists.txt Applications/DemoApp1 (2 o 3)

Il file CMakeLists.txt della singola applicazione è un po' piú complesso dei precedenti. Nelle prime linee, definiamo il nome della applicazione, utilizzando come prefisso, il nome specificato nel file CMakeLists.txt della root directory del progetto e diamo ancora istruzioni sul tipo di progetto, ovvero di considerare il codice sorgente come codice C++.
Le linee 6-9 consentono di sopprimere warnings causati dalla versione 3.0 e superiore di CMake, che compaiono con l'integrazione di alcune dipendenze. Per il momento, è possibile ignorarle.
Le linee 15 e 16 consentono di considerare le sottodirectories include/ e src/ come percorsi in cui cercare gli header files e i source files dell'applicazione in questione, da poter utilizzare successivamente con la direttiva #include. Questi sono interpretati come percorsi relativi al file CMakeLists.txt corrente e non relativi a quelli contenuti in altre directories.
Le linee 18 e 19 invece si occupano di cercare ricorsivamente tutti i file che hanno estensione *.h, contenuti nella directory include, e di salvarli nella variabile ${APPLICATION_NAME}_HEADERS (simil cosa avviene per i file *.cpp in src/).
La linea 25 si occupa di generare l'eseguibile partendo dai file specificati nelle variabili ${APPLICATION_NAME}_HEADERS e ${APPLICATION_NAME}_SOURCES, oltre al file main.cpp.
Infine, la linea 31 si occupa di collegare (linkare) eventuali librerie al nostro eseguibile. Per il momento, il comando non esegue alcuna operazione, dato che non abbiamo definito queste librerie.

Test del nostro Progetto

Su GitHub ho creato un repository che verrá aggiornato lezione dopo lezione con i contenuti attuali del corso. Qui potete esaminare tutti i file specificati.
Ad esempio, ho definito nelle varie cartelle DemoApp1, 2 o 3 il seguente file main.cpp:
simile a quello proposto nella prima lezione.

A questo punto, possiamo generare il nostro progetto!
Se volete risparmiarvi la fatica di creare i file singolarmente, potete utilizzare il codice da me giá scritto (preferirei che vi cimentiate voi personalmente) nel seguente modo:
mkdir -p ~/Projects
cd ~/Projects
git clone https://github.com/blackibiza/ModernCpp.git && cd ModernCpp
mkdir -p build && cd build
cmake ..
make
CMake configura quindi il progetto all'interno della cartella build/, utilizzando il file CMakeLists.txt specificato (in questo caso, la directory-padre, specificando i ".." dopo il comando cmake).
All'interno della cartella build, quindi, ci saranno i file di configurazione, tra cui i Makefile delle nostre DemoApp.
Per eseguire le applicazioni, potete eseguire i seguenti comandi:

./Applications/DemoApp1/modcpp_demoapp_one
oppure
./Applications/DemoApp2/modcpp_demoapp_two
oppure
./Applications/DemoApp3/modcpp_demoapp_three
ottenendo 3 risultati diversi:
Fig. 3 - Tre applicazioni, tre risultati diversi, un solo build step.


Oggi abbiamo appreso come organizzare quindi un progetto con CMake, organizzando al meglio le risorse (i file), divise in moduli riutilizzabili ed in applicazioni finali. Sulla base di questa struttura organizzativa andremo a costruire un esempio progettuale che dimostrerá l'utilitá finale di questa impostazione.
Come sempre, esistono differenti metodi di approcciarsi al problema e quella proposta è solo una delle tante possibili soluzioni, che personalmente utilizzo, ma ciò non vuol dire che sia la soluzione finale a tutti i mali. Ogni progetto ha le sue caratteristiche, i suoi scopi, le sue piattaforme a cui si riferisce.
Se tra i lettori ci sono altri sviluppatori con esperienza, mi piacerebbe conoscere altre possibili soluzioni da voi implementate e, perchè no, discuterne qui sul blog di Lubit.

So di iniziare ad esser noioso con questi questionari, ma sono uno degli strumenti di feedback, dopo i commenti ai singoli post, con i quali posso cercar di migliorare la qualitá dell'offerta proposta.
Qui trovate il form da compilare: il tempo a voi richiesto è sempre inferiore ai 30 secondi :)

E`stato attivato anche un gruppo di supporto su Google+: qui potete esporre le vostre domande o i vostri dubbi e cercheró di rispondervi quanto prima possibile. Su Blogger, sfortunatamente, non ci sono notifiche e-mail per i commenti, almeno non come co-autore.

Alla prossima!

martedì 16 dicembre 2014

Modern C++ - Il primo progetto

Nel post precedente abbiamo focalizzato l'attenzione sul setup dei tool di sviluppo e di supporto che andremo ad utilizzare durante questo corso.

Era d'obbligo mostrare inizialmente un po' di codice sorgente C++ al fine di testare il funzionamento dell'ambiente di sviluppo sulla propria macchina.
Da oggi, invece, si inizia seriamente con il linguaggio di programmazione e con CMake per la configurazione dei progetti.

Listato C++

 

Il progetto generato automaticamente da QtCreator, come abbiamo visto, è risultato il seguente:
Questo piccolo programma scrive il testo "Hello World" nel terminale e poi si chiude.
Come viene realizzato questo? Per prima cosa, fondamentale per ogni progetto e/o linguaggio di programmazione, è la riusabilitá. Costanti (ad esempio, il valore di Pi greco) e funzioni vengono definite in file, denominati header files, che vengono importati successivamente. Questi files generalmente hanno estensione *.h, *.hpp, *.hxx (la scelta è a discrezione dello sviluppatore), ma in C++ esistono header files built-in che non richiedono una estensione esplicita.
Ad un header file, spesso ma non sempre (vedremo il perché in futuro), è associato un source file, con estensione *.cpp, *.cxx, che contiene l'implementazione delle definizioni contenute nell'header file associato.

Linea 1

Notiamo l'importazione dell'header <iostream> per mezzo della parola chiave #include.
Questa parola chiave invoca il preprocessore, un programma che si occupa di svolgere alcuni step prima che venga attivato il processo di compilazione del programma (ovvero la conversione da linguaggio C++ a linguaggio macchina). In questo caso, la direttiva
#include <iostream>

invoca il preprocessore che si occupa di cercare il file iostream ed importarne le definizioni (le funzioni e/o le costanti) in esso contenute.
In C++, le funzioni che lavorano con la gestione degli stream (vedremo nelle successive lezioni cosa significa) sono definite in questo particolare file e tra le quali troviamo cout ed endl, scritte al rigo 7 del nostro codice sorgente.
Se provate ad eliminare quindi il rigo 1 e provate ad eseguire la compilazione, vedrete che QtCreator genererá un errore relativo alla mancata definizione di queste due funzioni.

Linea 3

In C++ è possibile specificare un namespace. Un namespace serve a raccogliere, sotto un identico nome, funzioni, classi, variabili, in modo univoco, evitando fraintendimenti con altre dichiarazioni che potrebbero avere lo stesso nome e che quindi creerebbero un conflitto.
Ad esempio, cout in realtá è definito come std::cout (notare doppi ":"), ovvero si sta utilizzando la "funzione  cout del namespace std". La regola generale è quella di poter estendere un namespace con nuove funzioni, ma è proibito avere due funzioni con lo stesso nome e numero di argomenti all'interno dello stesso.
Se, per alcuni motivi, utilizzassimo librerie di terze parti che abbiano a loro volta una implementazione della funzione cout, allora il namespace costituirebbe un fattore discriminante,  permettendo di usare sia
std::cout << "Hello World" << std::endl;
sia, ad esempio, con namespace mio::,
mio::cout << "Hello World" << mio::endl;
Nel caso di questo primo programma, al fine di evitare di scrivere continuamente il prefisso std:: per ogni funzione, si puó utilizzare il comando
using namespace std; 
ovvero diciamo al compilatore di apporre in automatico il prefisso std:: a tutte le funzioni contenute in <iostream> che stiamo utilizzando.

Linea 5

Il punto di ingresso (o entry point) di ogni programma in C o C++ è la funzione main().  Questa funzione è la prima ad essere eseguita e contiene a sua volta chiamate a funzioni oppure ad operazioni da eseguire.
Una volta completate queste operazioni, allora la funzione main termina e il programma viene chiuso, riportando uno stato, che rappresenta il successo o l'insuccesso dello stesso programma. Lo stato viene indicato con un numero intero, dato che con la dichiarazione:
int main()
stiamo definendo una funzione main con zero argomenti (le parentesi sono vuote) e che restituisce come risultato un numero intero (int è un tipo di dato che sta per integer/intero).
Non è possibile scrivere un programma C/C++ senza la funzione main.

Linea 7

Come già accennato in precedenza, cout ed endl hanno a che fare con gli stream di dati. In particolare, cout consente di scrivere sullo stream uscita (di default, la riga di comando) il valore specificato dopo il simbolo "<<", in questo caso "Hello World", mentre endl si occupa di terminare la riga di testo e andare a capo (ovvero si esegue il CRLF).
Pertanto, questa linea puó esser tradotta in italiano come segue: "sullo stream di uscita (la riga di comando in questo caso), scrivi 'Hello World' e vai a capo".
In contrasto a cout, esiste cin, che consente invece di leggere un valore di input e salvarlo in una variabile. Vedremo come utilizzare gli stream in successivi post.

Linea 8

Come menzionato nella discussione relativa alla linea 5, la funzione main è prossima a terminare, riportando un valore integer come risulato finale dell'esecuzione. Poichè è andato tutto a buon fine, riportiamo il varole 0, che indica il successo dell'esecuzione. In caso di errori (come vedremo in seguito), possiamo definire stati che aiutano a segnalare i problemi che si verificano durante la normale esecuzione di un programma.

File CMake

Fin qui abbiamo descritto il significato del codice sorgente C++, ma QtCreator ha creato anche un altro file, il file CMakeLists.txt, che permette di configurare il nostro progetto utilizzando il tool CMake.
In questo caso, il file risulta molto semplice da comprendere: stiamo generando un progetto chiamato FirstProject (linea 1), che richiede come versione minima di CMake installata la 2.8 (linea 2).
La linea 3 permette di includere nel progetto tutti i file sorgente presenti nell'attuale directory in cui il file CMakeLists.txt è presente:
aux_source_directory(. SRC_LIST) 
permette di salvare nella variabile SRC_LIST tutti i file con estensione nota (*.h, *.cpp, ecc.), nel nostro caso solamente il file main.cpp.
Infine, la linea 4 si occupa di definire il programma eseguibile, con nome FirstProject, come è stato definito nella linea 1, utilizzando come sorgente i file contenuti nella variabile SRC_LIST, ovvero solo main.cpp.

CMake, a seconda della piattaforma e del compilatore rilevato, genera i file di progetto, definendo quindi i file di progetto, eventuali librerie di terze parti, eventuali configurazioni specifiche (flag per il compilatore, generazione di file *.deb, *.zip, *.msi) in base alle necessitá. Di pari passo con i problemi che affronteremo in C++, vedremo come configurare i file CMakeLists.txt (ce ne possono essere uno per ogni subdirectory), in modo da crearci un mini-framework che ci permetterá di utilizzare tutti i file che scriveremo per nuovi ed interessanti progetti.

Per oggi concludiamo qui e vi chiedo nuovamente un piccolo contributo di tempo per la compilazione del seguente questionario. Inoltre, se avete dubbi, opinioni, suggerimenti, potete contattarmi attraverso Google+, Twitter oppure via email.

A presto!

venerdì 12 dicembre 2014

Modern C++ - I tools di sviluppo

Ben ritornati sulle pagine del corso di Modern C++ sul blog di Luigi Bit3Lux.

Nella puntata precedente ho spiegato un po' di cosa si tratterá in questo corso e ho accennato al linguaggio in sé. Non volendo risultare monotono, preferisco affrontare gli aspetti teorici man mano che tocchiamo con mano gli strumenti e il codice sorgente dei programmi che andremo a scrivere.


Ovviamente, per gli esigenti e gli assetati di conoscenza, metteró a disposizione una serie di link a risorse utili, principalmente in inglese, per via della maggiore qualitá e poiché spesso alcune traduzioni risultano fuorvianti in alcuni testi.

Riporto nuovamente qui il sistema operativo di riferimento utilizzato: Lubit Linux Eagle 4.0. Qualsiasi distribuzione Linux derivata da Debian o Ubuntu va comunque bene. Gli utenti ArchLinux, Fedora o Gentoo possono seguire le guide nei rispettivi wiki su come installare gli strumenti necessari. Il nome dei tools rimane esattamente lo stesso.

Gli Strumenti di lavoro

Oggi ci occuperemo di configurare la nostra fiammante macchina con i tools di sviluppo che andremo ad usare per queste prime puntate: il compilatore, un IDE (ambíente di sviluppo), un gestore di progetti ed un tool per la gestione del codice.
Quali e cosa sono esattamente questi tools?

Compilatore

Il compilatore è un programma (o un set di programmi) che converte istruzioni C++ in istruzioni in linguaggio macchina, generando il cosídetto codice oggetto. Questo codice oggetto viene generato col fine di creare ció che poi diventa il prodotto finale, il programma eseguibile. L'argomento compilatore è molto vasto e prometto di dedicarci un post specifico solo su di esso. Per il momento, consideratelo come una scatola nera che produce risultati toccabili con mano. Nel nostro caso, utilizzeremo il compilatore piú usato al mondo: GNU GCC.

IDE (Integrated Development Environment)

L'IDE è un ambiente di lavoro che permette di gestire progetti e codice sorgente in modo semplice ed efficace: in genere, integra un editor di testo, una collezione di tools per compilare il codice (quindi il compilatore viene utilizzato/integrato dall'IDE) e trovare problemi nei programmi che realizziamo. Un IDE definisce un progetto (Linux style) o soluzione (Windows style), una collezione di file che includono i parametri per la generazione di file eseguibili, percorsi di librerie esterne, ecc.
Qui la scelta è molto variegata, in dipendenza dei gusti personali. Poiché il nostro corso prevede anche l'utilizzo di Qt, pertanto il nostro IDE di riferimento sará QtCreator.

Gestore di Progetti

Quando si ha a che fare con librerie di terze parti, progetti complessi o progetti cross-platform (ovvero, che funzionano anche su altri sistemi operativi/piattaforme), occorre ottimizzare i tempi e ridurre gli errori introdotti dal fattore umano (es., immettiamo percorsi di directory inesistenti, alcuni valori non sono esatti, ecc.). In soccorso arriva il gestore di progetti, che permette di definire una configurazione dei progetti, generando in semplici passi i file di progetto dell'IDE di riferimento. Ad esempio, se utilizziamo QtCreator, il gestore di progetto sará in grado di generare i file per questo IDE. Se utilizziamo Microosft Visual Studio su Windows, esso sará in grado di generare le soluzioni.
Il gestore di progetti must-have è CMake. CMake permette di generare quindi file di progetto, ma anche di generare progetti redistribuibili, ovvero eseguibili su altri computer, diversi dal nostro.

Gestore del Codice Sorgente

Quante vi è capitato di effettuare modifiche ad un file e magari aver cancellato accidentalmente alcune parti utili? Come fare a recuperarli? Come fare a collaborare con altre persone sugli stessi file, mantenendo una certa coerenza ed integritá tra le farie modifiche apportate? La risposta è nei gestori di codice sorgente, o versioning tool (tool per il controllo di versione). Anche in questo caso la scelta è variegata, ma in questo corso utilizzeremo il tool che usa anche il papá di Linux, il nostro amatissimo Linus, che è tra l'altro l'ideatore del tool stesso, git. Esistono anche vari servizi web che offrono la possibilitá di effettuare un backup online del nostro codice e di condividerlo con altri sviluppatori, come ad esempio GitHub e BitBucket.

Installazione dei tool

E' il momento di passare all'atto pratico. Avviate il terminale della vostra distribuzione ed eseguite i seguenti comandi (richiede i permessi di root):


sudo apt-get update && sudo apt-get dist-upgrade -y 
sudo apt-get install build-essential cmake git qtcreator -y

Il risultato a schermo sará il seguente:


Installazione delle dipendenze
Il sistema vi chiederá di installare alcune dipendenze, necessarie al funzionamento dei tools richiesti. Una volta completato il processo (ci metterá un po' a seconda della vostra connessione), sarete pronti per scrivere il vostro primo programma in C++!

Primo Programma con QtCreator

Di seguito vi allego gli screenshot dei passaggi effettuati per la creazione di un progetto basilare con QtCreator. Innanzitutto va aggiornato il menu di Lubit, al fine di trovare poi il collegamento a QtCreator:


Lanciamo quindi QtCreator e realizziamo il nostro primo progetto!

Creazione di un nuovo progetto

Creazione di un nuovo progetto - Non-Qt Project (non usiamo Qt adesso), C++ CMake

Definiamo una directory di destinazione dei nostri file

QtCreator ci chiede in quale directory compilare il codice (creare l'eseguibile)

QtCreator ci chiede se utilizzare un versioning tool: nessuno per adesso

Ecco il nostro codice C++, generato in automatico da QtCreator (con la scritta "Hello World")

Ecco il nostro file CMake generato in automatico da QtCreator
Cliccando sul tasto Play, il codice viene compilato ed eseguito. Se porvate a cliccare su "Application Output", troverete il messaggio "Hello World".
Se tutto va a buon fine, vuol dire che QtCreator, GCC e CMake funzionano perfettamente!
Per oggi è tutto, ci vediamo presto, per parlare della struttura di un programma C++, in cui analizzeremo linea per linea il nostro primo progetto (creato automaticamente da QtCreator come test) e definiremo una struttura organizzativa per i nostri futuri progetti, da arricchire successivamente con CMake.

Come ultima cosa, vi chiedo di partecipare al seguente questionario (della durata di meno di 30 secondi) circa gli argomenti trattati. Vi ringrazio anticipatamente per il tempo da voi dedicatomi.

A presto e buon weekend!



Modern C++ - Prefazione

Benvenuta/o e grazie per esser giunta/o qui sulle pagine di The Secrets of Ubuntu / Lubit Blog.
Da oggi inizia una serie di appuntamenti, a cadenza settimanale (o almeno ci provo), grazie anche a Luigi Bit3Lux per avermi accolto nel suo blog, su uno dei linguaggi di programmazione piú discussi ed importanti nella storia dell'informatica, ovvero C++.
Questo linguaggio, considerato di origini oserei dire "preistoriche", vista la sua data di nascita (1979 - "C with Classes", 1983 - ridenominato ufficialmente in "C++"), nato dalla geniale mente di Bjarne Stroustrup e basato sull'ancora piú vetusto C (1969-1973 - Dennis Ritchie), è alla base di tutto ció  che utilizziamo in ambito informatico oggigiorno: sistemi operativi, software di grafica, giochi, smartphones, internet of things, siti web (ad esempio, anche Facebook utilizza C++ ) ed è il precursore di linguaggi moderni e considerati piú alla moda (es. Python, Java, Ruby, Go).

Perché insistere con C++ se ci sono linguaggi piú moderni? Una delle tante possibili risposte è la seguente: C++ (insieme a C) risulta ancora oggi uno dei linguaggi di programmazione orientato alle prestazioni e all'efficienza del software creato. Il kernel Linux basicamente è sviluppato in C, ma è possibile utilizzare anche alcune strutture/metodologie di C++: non si esclude che in futuro possa esser riscritto interamente in C++. Inoltre, C++ è uno standard de facto (la standardizzazione è avvenuta nel 1998).
Certamente, il linguaggio in sé, proprio come i linguaggi naturali, si è evoluto nel tempo e il 2011 ha segnato una data importante nella storia, poiché un nuovo standard, denominato C++11, è stato rilasciato e con esso si sono aggiunte tantissime novitá che hanno non solo portato piú funzionalitá, ma consentono allo sviluppatore di scrivere codice piú performante e piú semplice, quasi sulla falsa riga dei linguaggi moderni. Sulla base di questo fondamentale aggiornamento, costato anni di lavoro, uno degli autori piú conosciuti del settore, Scott Meyers, ha coniato il termine Modern C++, adottato ormai da quasi la totalitá della community per riferirsi a questo nuovo modo di approcciarsi al linguaggio.
Nel 2014 è stato rilasciato un nuovo aggiornamento, definito C++14, non ancora supportato dagli strumenti di sviluppo allo stato attuale. Pertanto, come riferimento per questo corso, si utilizzerá C++11, supportato ampiamente da strumenti di sviluppo aggiornati per tutti i sistemi operativi (Windows, Linux, MacOS X).

Compito di questa serie di appuntamenti è quella di avvicinare neofiti alla programmazione in Modern C++ e magari fornire una rinfrescata a chi giá conosce il linguaggio. Il corso non è focalizzato esclusivamente sul puro e duro linguaggio in sè, ma su uno degli esistenti ecosistemi che guidano alla creazione di progetti piú o meno complessi: impareremo ad usare tools e librerie quali CMake, git, Qt5 e (se c'è tempo e spazio) OpenCV.

Non sará argomento del corso l'installazione del sistema operativo. Il sistema operativo di riferimento sará Lubit Eagle 4.0, ma una qualsiasi distribuzione derivata da Ubuntu va benissimo.

Poiché molte delle risorse e librerie propongono nomi e documentazione prettamente in inglese, si suggerisce una conoscenza basilare della lingua inglese.

Detto questo, mi farebbe piacere comunque ricevere feedback e magari idee su progetti da presentare e sviluppare insieme; volta per volta vi chiederó di compilare un piccolo questionario (tempo di compilazione: meno di 30 secondi) circa la comprensione, la qualitá del corso, idee future.

Alla prossima puntata :-)



Emulare i suoni di una macchina da scrivere su lubit

Salve!

Vabbè, stamattina sono un po' nostalgico. Stanotte mi sono ricordato quando nel 1987 feci un corso di dattilografia. Allora usavo una Olivetti come macchina da scrivere, questa...
Ora vi dico come fare per emularne i suoni su lubit.

Anzitutto installiamo il pacchetto python-xlib

$ sudo apt-get install python-xlib

Scarichiamo lo script in python da github

$ wget -O keypress.tar.gz https://github.com/chrelad/keypress/tarball/master

decoprimpiamo l'archivio .tar.gz ed estraiamone i file.

$ tar -xfz keypress.tar.gz

Spostiamoci nella cartella contenente lo script in python

$ cd chrelad*

rendiamo eseguibile lo script

$ chmod +x keypress.py

Eseguiamo lo script

$ ./keypress.py

Ora possiamo ridurre ad icona la finestra del terminale e iniziare a scrivere qualcosa ;)

Per uscire dallo script, massimizzate la finestra del terminale e premete la combinazione di tasti Ctrl+C

Ah, una cosa, una volta eseguito lo script, ovunque scriviate, writer, browser, editor, etc, avrete i suoni della vecchia olivetti. ;)

Alla prossima!

lunedì 8 dicembre 2014

Come trovare i file senza estensione con il comando Find [Brevi Esercizi]

Salve!

L'esercizio di oggi è il seguente: In una sottocartella, già contenente immagini e scripts, creiamo 7 file di testo senza estensione. Poi, attraverso il comando find, cerchiamoli e, infine, aggiungiamo ad essi l'estensione .txt.

In Documenti ho creato la cartella Test. Entriamoci dentro.

$ cd Documenti/Test

Creiamo i sette file di testo senza estensione

$ touch {a..g}
$ ls

Ora cerchiamo questi file

$ find  -type f ! -name "*.*"

Per aggiungere l'estensione utilizziamo anche rename.

$ find  -type f ! -name "*.*" | rename 's/$/\.txt/'



Importante. C'è da fare una piccola precisazione: Non lanciare mai il comando di cui sopra direttamente nella home dell'utente, ma solo nelle sottocartelle. Questo perchè nella home ci possono essere file di configurazioni che devono essere senza estensione.

Verifichiamo il risultato

$ ls


Alla prossima!

L'indice della rubrica "Brevi Esercizi" lo trovate qui.

domenica 7 dicembre 2014

Mettiamo alla prova le nostre password.

Salve!

Poniamo il caso che mi stia scervellando per creare una password sicura, o che voglia testare una password che sto già usando, in questi casi, o altri analoghi, mi può tornare utile un tool semplice semplice, cracklib-check.

Anzitutto installiamolo

$ sudo apt-get install cracklib-runtime

Ora facciamo un po' di prove.

Supponiamo che voglia impostare come password la classica sequenza "1234567"

$ echo "1234567" | cracklib-check


Altri esempi:





Un altro modo di usare cracklib-check è quello di scrivere il suo nome nel terminale e premere invio, a questo punto bisogna digitare la password, che si vuole provare, e aspettare il responso. Questo secondo metodo evita di digitare, ogni volta, la riga di comando con la nuova password da testare.

cracklib-check


Ad essere proprio sincero, l'utilità di questo tool non è proprio eccezionale. Serve, tuttavia, ad escludere alcune possibilità che potrebbero rivelarsi "dannose" per i nostri account.

Alla prossima.

mercoledì 3 dicembre 2014

Creiamo codici QR con Python

Salve!

L'esercizio di oggi consiste in un semplice script in Python che crea codici QR.

Lo script ci chiede il testo da inserire nel codice QR e il nome dello stesso.

Anzitutto dobbiamo scaricare un pacchetto:

$ sudo apt-get install python-pygooglechart

Di seguito il corpo dello script

#!/usr/bin/python
# -*- coding: utf-8 -*-

# importiamo QRChart
from pygooglechart import QRChart

# Dimensioni codice QR
Codice = QRChart(140, 140)

#Creiamo una variabile che contenga il testo del nostro codice QR
Contenuto_Codice_QR = raw_input ("Scrivi il contenuto del codice QR: ")

# Aggiungi il testo
Codice.add_data(Contenuto_Codice_QR)

# correzione degli errori con un margine di 0 pixel
Codice.set_ec('H', 0)

#Diamo un nome al nostro codice QR
Nome_Codice_QR = raw_input("Che nome vuoi dare al codice QR? ")

# Il codice viene salvato nella dir in cui si trova lo script
Codice.download(Nome_Codice_QR)

Salviamo lo script in un file di testo e nominiamolo creacodQR.py

Posto che lo avete salvato nella cartella Documenti

$ cd Documenti

Rendiamolo eseguibile

$ chmod +x creacodQR.py

infine eseguiamolo

$ ./creacodQR.py


Il codice che "sforna" è il seguente:


Per leggerlo ho scaricato un app sul mio Nexus, che si chiama QR Code Reader.

Alla prossima!

lunedì 1 dicembre 2014

Come "falsare" la data di modifica di un file di testo [Brevi Esercizi]

L'esercizio di oggi risponde a questa esigenza, non voglio far sapere al mio coinquilino (che tra l'altro non esiste) quando ho modificato un file di testo.

Poniamo che nella mia cartella Documenti abbia un file di testo modificato il primo dicembre 2014, voglio indurre il mio coinquilino (lo so, non è giusto, ma è pur sempre un esercizio) a credere che il file non sia stato modificato da molto tempo.


Esageriamo, lo induciamo a credere che il file non sia stato modificato dal lontano 9 novembre 1989 (data ufficiale della caduta del muro di Berlino)


L'operazione è semplicissima, basta usare il comando touch con qualche sua opzione:

Il file in questione si chiama, nel mio caso, programma_novembre.txt e si trova nella directory Documenti.

$ cd Documenti

$ touch -m -t 198911091525.30 programma_novembre.txt

In pratica, dopo l'opzione -t, ho scritto prima l'anno (1989), poi il mese (11), poi il giorno (09), infine l'ora con minuti e secondi (15.25:30), tutto attaccato.

Alla prossima ;)

Ah, dimenticavo, l'indice della rubrica "Brevi Esercizi" lo trovate qui.

Niente è come appare.... non dimentichiamocelo mai!