Visualizzazione post con etichetta Programmazione. Mostra tutti i post
Visualizzazione post con etichetta Programmazione. Mostra tutti i post

venerdì 31 gennaio 2014

Pycharm, l'IDE che fa al caso mio!

Come a molti geek/hax0r/nerd/devs/ecc. piace anche a me senrimi old school utilizzando strumenti rozzi (ma infinitamente leggeri e flessibili) per sviluppare (chi ha nominato vi?). Va detto però che quando il progetto si fa serio, modulare ed esteso bisogna appoggiarsi a strumenti che aiutino a semplificare almeno la gestione dei vari componenti. Su Windows Visual Studio è praticamente il padrone indiscusso del settore IDE. Per quanto riguarda l'offerta open source si hanno molte più scelte ma non sempre i tool soddisfano ogni nostra più piccola esigenza.


Se quando mi trovo a sviluppare applicazioni C++ basate e non sul framework Qt non ho dubbi ed utilizzo QtCreator, nelle varie occasioni in cui ho sviluppato con Python non sono mai stato a mio agio ne con Eclipse, ne con il mastodontico NetBeans e neppure con lo scarno IDLE.

Recentemente ho effettuato la ricerca canonica di chi non sa dove picciare la testa e ho digitato su google "best python ide". Finalmente questa volta Google mi ha dato la risposta che cercavo portandomi sulla pagina che cercavo da anni: http://www.jetbrains.com/pycharm/

PyCharm è un integrated development environment che permette di sviluppare in modo molto agevole in python. Permette la gestione di progetti ed è integrato con i principali tool di versioning (chi ha detto Git?).

Ciò che mi ha colpito principalmente di PyCharm è la velocità con cui permette l'editing del testo. Pur basandosi su una JVM non soffre dei fastidiosissimi lag della gui di cui possono "vantarsi" altri IDE come Eclipse e soprattutto NetBeans. Permette di effettuare debug delle applicazioni in modo molto comodo fornendo uno snapshot dell'applicazione al breakpoint corrente e includendo tutte le informazioni che della VM python.
Utilizzandolo sempre più spesso ho anche potuto apprezzare il supporto al linguaggio C e HTML ed XML in generale.

Sul sito ufficiale viene rilasciato in due versioni: la community edition, che è gratis e che ha funzioni minime per la programmazione in python, e la versione professional che ha un supporto esteso anche ad altri framework e ad altri linguaggi.

Per il mio utilizzo minimo la community edition soddisfa appieno le mie esigenze e consiglio a tutti coloro che vogliono sviluppare in Python ma non hanno ancora trovato lo strumento che fa al caso loro.

E voi quale IDE usate per sviluppare in python?

sabato 29 giugno 2013

Qt: trucco per versionare applicazioni e librerie

Ciao a tutti. Recentemente sono stato impegnato da un piccolo problema durante la finalizzazione di un'applicazione. Il problema da risolvere era creare un widget che riportasse la versione all'utente nella sezione "About". Il mio obiettivo era utilizzare un unico file che contensse la definizione della versione corrente, sia da far comparire nel widget sia per generare le librerie lib*.so.maj.min.patch. La mia soluzione è stata aggirare il compilatore c++ e il sistema di pre-build qmake con un semplice trucco. Per prima cosa riportiamo il file Version.h:
#ifndef VERSION_H_
#define VERSION_H_

#define BUILD_VERSION_NUMBER
#ifdef BUILD_VERSION_NUMBER

#define MY_MAJOR_VERSION 1
#define MY_MINOR_VERSION 2
#define MY_PATCH_VERSION 3

#define OTHER_INTERESTING_DEFINES 0

#else

MY_MAJOR_VERSION = 1
MY_MINOR_VERSION = 2
MY_PATCH_VERSION = 3

#endif

Già da questa porzione di codice si capisce qual'è stato il trucco. Il pre-compilatore esclude le righe che darebbero un errore di compilazione in c++ grazie alla definizione on-the-fly di "BUILD_VERSION_NUMBER". Il sistema di pre-build qmake consente di inserire negli script "Project" commenti se questi sono preceduti dal carattere '#'. A questo punto il file Version.h viene incluso nella classe del widget che, così facendo, potrà utilizzare le define MY_MAYOR_VERSION, MY_MINOR_VERSION, MY_PATCH_VERSION. Successivamente il file Version.h viene incluso anche dal file *.pro che dovrà contenere la seguente porzione di codice:
include ( Version.h )

VER_MAJ      = $${MY_MAJOR_VERSION}
VER_MIN      = $${MY_MINOR_VERSION}
VER_PAT      = $${MY_PATCH_VERSION}
Le variabili VER_MAJ, VER_MIN e VER_PAT vengono poi usate da qmake per numerare le librerie. Chiudo questo breve articolo con una domanda: c'è un modo migliore per fare questo? La mia risposta è: "probabilmente si, ma mi sono divertito molto a trovare questa soluzione!"

giovedì 22 settembre 2011

Ubuntu Developer - Un portale tante idee

Inizio questo mio post dopo un'assenza piuttosto lunga dichiarando subito che quanto stiamo per analizzare non è nulla di incredibilmente nuovo. Recentemente ha attirato la mia attenzione un progetto di ubuntu: Ubuntu Developer Portal.

L'idea che sta alla base di questo nuovo progetto targato Canonical non è niente di innovativo: un portale dove raccogliere app. Soprattutto con l'avvento degli smart phone, questo tipo di "magazzini" è diventato di moda.

 Ciò che contraddistingue questa nuova piattaforma, dalla quale sinceramente mi aspetto molto, è la stretta relazione che ha con uno dei sistemi operativi open source più diffusi. In questo momento il sito propone solo un'anteprima di quello che sarà il servizio ma già abbiamo materiale a sufficenza per un'analisi preliminare. Nella pagina "Create" viene pubblicizzato uno strumento che assiste lo sviluppatore novizio nella creazione e distribuzione di un'applicazione per Ubuntu.

Sono venuto così a conoscenza (ammetto di non averlo mai visto prima) di un tool, Quickly, che permette di creare applicazioni in python con interfaccia grafica il tutto dando alcuni comandi da terminale e con una guida in linea piuttosto utile e ben scritta. Il lato negativo di questo abbassamento del livello di difficoltà sarà sencondo me un ancora maggiore moltiplicarsi di applicazioni che hanno il medesimo scopo. Rimane comunque uno strumento a cui dare un'occhiata nel proprio tempo libero.

 La prima perplessità è l'utilizzo del solo launchpad per l'hosting del codice. Una mossa scontata da parte di Canonical, dalla quale avrei però voluto la possibilità di scegliere altri tipi di controllo di versione, fra cui ovviamente GIT. Questo è ancora un punto a favore del portale GitHub.
 La seconda riguarda la pubblicazione di applicazioni a pagamento. Penso di non essere l'unico a sostenere tramite paypal sviluppatori open source e Canonical in primis per il lavoro svolto, ma quest'opera che tende ad assomigliare ad Apple mi lascia un certo amaro in bocca. Le applicazioni, principalmente scritte in python (e non perchè è un linguaggio che mi è simpatico ma perchè lo stesso Quickly lo propone come linguaggio di sviluppo) con il codice sorgente a disposizione su launchpad, potranno sicuramente essere reimpacchettate e distribuite gratuitamente con tutta la disputa che ne uscirà. Dall'altro lato la possibilità di pubblicare direttamente sull'Ubuntu Software Center sarà perfetta per far conoscere applicazioni utilissime che altrimenti sarebbero rimaste nell'ombra.

 Concludendo: questo portale riprende il concetto di application store e lo lega ad Ubuntu. L'idea è ottima ma gradirei non vedere i soliti autogol che si fa Canonical per imitare Apple. ;)

giovedì 20 gennaio 2011

Java and performance, non è impossibile con gcj

Java è un buon linguaggio. Molto diffuso e ricco di documentazione e librerie.
La Java VM è molto lenta. Molto lenta. Mooooooooolto lenta.
Sono venuto così a contatto con gcj ovvero gcc per Java. Questo compilatore produce un file eseguibile esattamente come per C/C++.

A questo punto viene spontaneo fare un piccolo test di performance. Premetto che il test proposto non ha valenza assoluta.

Compiliamo questa classe.
public class MiaClass
{
public MiaClass()
{
}

public void print()
{
long startTime = System.currentTimeMillis();

callOperationToTime();

long endTime = System.currentTimeMillis();

long totalTime = endTime - startTime;

System.out.println("Time: " + totalTime);
}

private void callOperationToTime()
{
for(int i = 0; i < 10000; i++)
{
System.out.println(" ");
}
}
}

e successivamente richiamiamola da un semplice "main".

public class HelloWorld {

public static void main(String[] args) {
MiaClass c = new MiaClass();
c.print();
}

}


Questo codice compilato con gcj esegue le operazioni in 75ms mentre lanciato con la Java VM i millisecondi salgono a 291.

La mia macchina è un P8400 e Ubuntu 10.04.

mercoledì 21 luglio 2010

Esplorando il kernel Linux: boot

Cominciando il mio viaggio all'interno del kernel Linux mi sono posto una domanda: come fa Linux a partire?

Ho cercato e trovato online un link molto interessante che voglio condividere: LINK

In questo articolo viene dettagliato il processo di boot del kernel linux in tutte le sue fasi.

Questi passi possono essere ritrovati all'interno del codice sorgente. A questo proposito a questo indirizzo è possibile consultare il codice sorgente on-line molto comodamente e poter riferire ogni singola linea di codice tramite il bookmark che si trova sotto il numero.

Buona lettura.

martedì 29 giugno 2010

How to write Spamassassin plugin - part 2

Come promesso eccoci al secondo e ultimo appuntamento di questa serie.
Precisiamo subito che semplici regole possono essere scritte direttamente all'interno dei file di configurazione. All'interno dei plugin vanno messe regole più complesse o che si basano su dati che cambiano frequentemente.

Per prima cosa bisogna ereditare dalla classe base Plugin
package Mail::SpamAssassin::Plugin::MyPlugin;
use Mail::SpamAssassin::Plugin;
use DBI;
our @ISA = qw(Mail::SpamAssassin::Plugin);

sub new {
my ($class, $mailsa) = @_;

# the usual perlobj boilerplate to create a subclass object
$class = ref($class) || $class;
my $self = $class->SUPER::new($mailsa);
bless ($self, $class);

# add rule
$self->register_eval_rule ("check_myplugin_header");

return $self;
}

1;

In questo modo abbiamo registrato la nuova regola già definita all'interno del file di configurazione.

A questo punto bisogna dare corpo alla nuova regola che vogliamo introdurre nel tool.
Nel frammento di codice sopra abbiamo importanto anche le librerie DBI che ci consentono di interrogare il database con un comodo Object Model.

Facciamo un esempio di implementazione di una regola basata su DB.
sub check_myplugin_header
{

my ($self, $pms) = @_;

# Extract desidered informations from mail header
$head = $pms->get('CustomHeader');

$result = 0;
study;

chomp($head);
$head =~ s/;//;

$dbh = DBI->connect("dbi:mysql:spamassassindb","user","pass");


if(!defined $dbh)
{
die "Connessione al database non riuscita: $DBI::errstrn";
}

$query = "SELECT count(accepted_headers) FROM headers WHERE accepted_headers = $head";

# Insert query into database instructions
$sth = $dbh->prepare($query);

# Database query execution
$sth->execute;

$count = $sth->fetchrow();


if($count eq 0)
{
# Report error
$result = 1;
}

# Disconnect from database
$dbh->disconnect();

return $result;
}

Questo frammento di codice è piuttosto semplice e fa una query al db, tramite DBI, dopo aver bonificato la stringa da passare.
Una cosa sicuramente da notare è il paramtro $pms che consente di accedere a tutti gli headers della mail.
Forniamo allora questo messaggio
From god@heaven.com  Thu Jun 17 21:33:41 2010
Return-Path: <god@heaven.com>
X-Original-To: account@post-server
Delivered-To: account@post-server
Received: from post-server (host [127.0.0.1])
by post-server (Postfix) with SMTP id B66E9424F5
for <account@post-server>; Thu, 30 Jun 2010 21:33:20 +0200 (CEST)
CustomHeader:blablabla
Subject:Try this

Simple mail to test my plugin.

a spamassassin e avremo due comportamenti diversi:
  • Se la stringa "blablabla" è contenuta nel database la regola non andrà ad aggiungere i punti definiti nel file di configurazione (2.0 dal post precedente)
  • Se la stringa "blablabla" non è contenuta allora la regola avrà un hit che sommerà 2 punti allo score totale. In questo secondo caso se questo punteggio fa superare la soglia (definita sempre nei vari file di configurazione) allora il messaggio verrà identificato come SPAM!!!


È un argomento piuttosto vasto che richiede tempo per essere assimilato. Questo è solo un input che vuole stimolare interesse. Spero di essere stato chiaro e sono a disposizione per un help in linea, per quanto posso fare.

Have fun ;)

domenica 27 giugno 2010

How to write Spamassassin plugin - part 1

Sono giunto a un buon punto di un progetto per un esame universitario (che verrà pubblicato non appena consegnato) che riguarda un argomento sul quale ho trovato pochissimo materiale.

Si sta parlando della scrittura di un plugin che valuti una regola complessa su un messaggio e-mail, per determinare se si tratta di spam oppure no.

C'è voluto molto tempo per raggiungere qualcosa di funzionante ma ora che ho fra le mani un po' di codice che gira posso scrivere un articolo come questo e colmare la lacuna che il web mi ha mostrato. (I'll translate this article soon for international usage)

Cominciamo con installare tutto quello che serve (a parte una VM con sopra Ubuntu): Documentazione Ubuntu - Mail Server

A questo punto il plugin ha bisogno di due cose:
  1. Un file di configurazione che permetta di richiamare la regola e le assegni un punteggio.
  2. Una classe Perl che implementi l'interfaccia Plugin e che definisca precisamente la regola che si vuole aggiungere a Spamassassin.


In questa prima parte ci concentreremo sul file di configurazione. Nel prossimo articolo parleremo di come scrivere un .pm che interroghi un database per la valutazione di un header.

Il file di configurazione che bisogna comporre va depositato all'interno della directory di sistema /etc/spamassassin.
Possiamo andare a scriverlo direttamente con il seguente comando:
sudo gedit /etc/spamassassin/25_myplugin.cf

All'interno di questo file andiamo a scrivere due cose. La prima è il collegamento della funzione che andremo a definire nella nostra classe. La seconda è lo score che la regola aggiunge alla valutazione se si verifica la condizione definita.
Il contenuto sarà pressochè il seguente:
# Rule load for MyPlugin
header MY_RULE eval:check_myplugin_header()
score MY_RULE 2.0

Per configurare la nostra personalizzazione manca solo un passaggio: bisogna far caricare a Spamassassin il nostro plugin. Va dunque cambiato un qualunque file *.pre. Apriamo quindi:
sudo gedit /etc/spamassassin/v310.pre

In coda a questo file vanno aggiunte le seguenti righe affinchè il nostro plugin venga caricato a successivo riavvio.
# load MyPlugin
loadplugin Mail::SpamAssassin::Plugin::MyPlugin

Conclusa la configurazione è il momento di scrivere il vero e proprio plugin ma sarà argomento del prossimo post.

Stay tuned ;)

Ah, quasi dimenticavo:
sudo /etc/init.d/postfix
sudo /etc/init.d/spamassassin

lunedì 7 giugno 2010

Google I|O: Una fucina di idee!

Ogni anno viene riproposto un evento. No, scusate, ogni anno viene riproposto L'Evento: il Google I|O, dove le menti più brillanti fanno vedere cosa si può fare con le moderne tecnologie a disposizione.



Una cosa in particolare ha catturato la mia attenzione. A questo link è possibile visionare un tech talk di quasi un'ora sul nuovo linguaggio di programmazione (Go-language). Questo talk è tenuto da Russ Cox, papà del linguaggio.

La particolarità di questa presentazione è il fatto che Russ si spinge in dettagli avanzati come la gestione degli oggetti e dei tipi che sicuramente hanno bisogno di chiarimenti da parte di chi ha concepito il linguaggio.

Ma i regali di G. non finiscono qua. Sul blog ufficiale della sezione code di Google è possibile guardare tutti i tech talk fra cui App Engine e Wave.

Buona visione a tutti ;)

domenica 25 aprile 2010

Nefarious-IDE, un primo passo dell'universo Go

A chi è stato molto attento non è per nulla nuovo, ma oramai mi sembra giunto alla maturità sufficiente per essere presentato a tutti.

Nefarious-IDE è un plug-in per Eclipse che ci permette di avere un IDE per il linguaggio GO che fino ad oggi abbiamo editato all'interno di scarni editor.

Il progetto non si può ancora definire avanzato ma quanto meno usabile. Infatti è già presente quasi tutta la parte di highlight della sintassi e permette di compilare i sorgenti scritti.

Ancora nulla sul versante autocompletamento o almeno suggerimenti ma sono sicuro che sia il primo punto sull'agenda dei dev.

Ecco lo stato di avanzamento delle varie parti:
"Current Features for Development Version: 0.0.12.a (Total Dev Time: 40.2 hrs)
- syntax highlighting (90%)
- compile upon save and mark errors within project (60%) (go compiler required)
- preference integration (70%)
- project configuration (65%)
- editor keyboard shortcuts (10%)
- go source to xml translator tool(65%)
"


Sul sito ufficiale del progetto è possibile trovare l'url da inserire direttamente all'interno di Eclipse per scaricare il plug-in e automaticamente installarlo.

Buon divertimento ;)

martedì 9 marzo 2010

wait() in Go, How to?

Stamattina sono stato colto da un dubbio che ha fortunatamente trovato una risposta nella ricchissima mailing list di go-language: http://groups.google.com/group/golang-nuts?pli=1

La domanda che mi sono posto è la seguente: esiste un modo intelligente per aspettare che tutte le go routines abbiano finito la loro esecuzione prima di procedere alla chiusura della funzione main?

Stamattina, come al solito, apro le mail e trovo la seguente discussione.

Subito arrivano alcune risposte come ad esempio:
The standard practice in Go seems to be for goroutines to pass to a
channel so signal their end. For example:

package main

func routine(quit chan int) {
// do stuff
quit <- 1

}

func main() {
routineQuit := make(chan int)
go routine(routineQuit)

<-routineQuit // blocks until quit is written to

}

-Daniel

Ma poi arriva questo link che vi invito caldamente a seguire se siete interessati all'argomento come lo sono io perchè lo spiega in modo molto chiaro: link.

A breve altri approfondimenti.
Buon Go a tutti!

lunedì 1 marzo 2010

State Machine in Go-Language - 1^ parte

Comincia con questo articolo una serie di post che tratta un argomento molto attuale e utile. La vastità del mare nel quale ci apprestiamo a navigare avrebbe bisogno di molte e molte pagine di libro per questo ho deciso di spezzettare in più parti la trattazione.

L'utilizzo di macchine a stati mi sembra importante nella programmazione di sistema, soprattutto quando si parla di servizi.
Cosa succede allora quando le state machine incontrano Go?

Ma partiamo "dall'incomincio": ecco un esempio di macchina a stati semplicissima (e anche un po' inutile) che però fa capire in cosa consistono questi arcani.


Questo concetto è molto comodo quando si programma a oggetti. Come abbiamo visto nello scorso articolo il linguaggio Go possiede gli oggetti.
Creiamo dunque il nostro oggetto intorno allo stato interno che per comodità conterrà solo l'indice dello stato in cui ci troviamo.

type InternalState struct  {
myState int;
}

Se prendiamo come modello quello nella figura sopra lo stato interno InternalState dovrà essere inizializzato, poi passare nello stato 1 e successivamente nello stato 2 prima di terminare.

Componiamo allora in questo modo la funzione che andrà a inizializzare la nostra macchina a stati:
func (state * InternalState) Init (inputValue int)
{
state.myState = inputValue;
}

Avremo poi bisogno di due funzioni per ogni stato, una che effettua operazioni di entry ed exit:
func (state * InternalState) Stato1_Entry ()
{
}

func (state * InternalState) Stato1_Exit ()
{
}

func (state * InternalState) Stato2_Entry ()
{
}

func (state * InternalState) Stato2_Exit ()
{
}



Nel prossimo post vedremo invece come unire tutti i componenti appena creati per far transitare lo stato dell'oggetto da quello iniziale a quello finale passando per gli stati intermedi.

Spero inoltre di aver messo qualche pulce nell'orecchio per approfondire un argomento veramente interessante.

sabato 6 febbraio 2010

OOp in go-lang

Prima di cominciare a parlare dell'argomento di questo post consentitemi di fare un piccolo festeggiamento per il 200esimo post su questo blog. Ultimamente ho rallentato la frequenza di aggiornamenti ma spero di averne incrementato la qualità.

Penso che una caratteristica che ha fatto storcere il naso a molti sia l'assenza della keyword class nel linguaggio Go.
In un primo momento questa illustre assenza potrebbe far pensare all'assenza del concetto di oggetto che invece è molto presente e molto utile.

Ma andiamo in ordine:

1) Definizione di nuovi tipi
Go permette di definire nuovi tipi con la keyword type.
type File struct  {
fileName [] byte; //Name of the file
sizeInByte int; //Size of the file
path [] byte; //Location of the file on hd
}

In questo modo abbiamo associato alla struttura File un nuovo tipo che da ora in avanti avrà gli attributi descritti all'interno.

2) Definizione di nuovi metodi
Creare nuovi metodi che eseguano del codice è molto semplice.
func PrintAll()
{
fmt.Printf("All");
}

3) Associare i metodi ai tipi
A questo punto perchè non provare ad associare il metodo PrintAll al tipo File in modo che stampi tutti gli attributi di File quando viene invocato?
Si deve quindi dire al metodo PrintAll che eseguerà operazioni solo sul tipo File.
func (f * File) PrintAll()
{
fmt.Printf("Filename: %s\n",f.fileName);
fmt.Printf("Size: %d\n",f.sizeInByte);
fmt.Printf("Path: %s\n",f.path);
}

4) Istanziare un nuovo File
In questo modo si potrà dunque istanziare un nuovo oggetto di tipo file e invocarne il suo metodo.
filePtr := new(File); //File *
filePtr.fileName = "Useless.txt";
filePtr.sizeInByte = "1024";
filePtr.path = "$HOME";

//Call File method
filePtr.PrintAll();

------------------------------------------------------

L'argomento è ovviamente molto più esteso ma in questo post volevo dare soltanto un'introduzione all'utilizzo degli oggetti all'interno di Go per i più scettici.
Prossimamente potremo anche parlare di Interfacce lasciando però prima di addentrarci tutti i preconcetti che arrivano da altri tipi di linguaggi poichè Go affronta tali argomenti da un altro punto di vista.

domenica 24 gennaio 2010

Parametri da linea di comando secondo Go

Go-lang è stato pensato per essere il linguaggio definitivo per le applicazioni di sistema.
Una delle cose che più impreziosiscono gli strumenti che (non) tutti i giorni utilizziamo per l'amministrazione del nostro sistema è sicuramente il parco di opzioni e flag che possiamo indicare da linea di comando.

Go-lang permette molto comodamente di dichiarare quali saranno i parametri che ci aspettiamo di ricevere da linea di comando, di che tipo saranno e che cosa comunicare all'operatore per aiutarlo nell'utilizzo del tool.

Vediamo, con un semplice esempio, ciò che Go ci mette a disposizione per rendere la nostra applicazione il più flessibile possibile.

Cominciamo con dichiarare quali flag ci aspetteremo:
//Flags
var file_to_download * string;
var fileType * string;
var configShow * string;
var configEdit * bool;


Successivamente definiamo le keywords con le quali potranno essere attivati i parametri:
/**
*Function used to initialize flags from command line.
*/
func initFlags() int
{
file_to_download = flag.String("d","","Type the name of the file");
fileType = flag.String("t","*","Kind of file you want to download:\n\t*: all\n\tmov: movie\n\tmsc: music");
configShow = flag.String("c","editor","Open the config file into chosen [editor]");
configEdit = flag.Bool("C",false,"Edit parameters of config from inside the program.");
}

Il package flag contiene una funzione di definizione parametro per ogni tipo di comando che desideriamo ricevere. Tutte queste funzioni però hanno tutte la stessa forma. Ricevono infatti tre parametri:

  1. La lettera/Le lettere che identificano il comando;

  2. Il comportamento di default;

  3. Un messaggio da dare all'operatore su come va utilizzato il flag.


Una volta definiti i flag possiamo utilizzare i comandi che arrivano dalla shell all'interno del nostro programma:
/**
*Main function. From here the program starts.
*/
func main()
{

//Initialize flags
initFlags();

flag.Parse(); //Scans the arg list and sets up flags

var fileStr string = "";
var typeStr string = "";
var confStr string = "";
var confMode bool = false;

confStr += *configShow;
confMode = *configEdit;

if(confMode)
{
os.Stdout.WriteString("Config mode\n");
}
else
{
os.Stdout.WriteString("Normal mode\n");
}

if( *file_to_download == "") //Want to download a file
{
fileStr += "errore";
fileStr += Newline;
os.Stdout.WriteString(fileStr);
}
else
{
fileStr += *file_to_download;
fileStr += Newline;
os.Stdout.WriteString(fileStr);
}

typeStr += *fileType;
typeStr += Newline;
os.Stdout.WriteString(typeStr);

//Useless calls
giogolib.LogMessage(def.Debug,"Applicazione partita");
}


Spero di aver mostrato in modo chiaro come Go lang permetta di fornire all'utente che andrà ad utilizzare la nostra applicazione tutti gli strumenti per adattare l'esecuzione del software alle sue esigenze.

domenica 20 dicembre 2009

Go Language - go statement

Il linguaggio Go, sviluppato da Google, mi ha subito affascinato. I programmatori di Google hanno da subito sostenuto che questo linguaggio di sistema sarebbe stato "divertente" da usare.
Non posso far altro che confermare quando dichiarato da big G e in questo video-tutoria cerco di far vedere con un semplice esempio quanto sia facile scrivere codice multithread con Go.



Perdonatemi l'audio che è leggermente "a scatti" ma recordmydesktop ha deciso che oggi lo vuole fare così. Una volta risolti i problemi pubblicherò una versione con l'audio migliore.

Per quanto riguarda un po' di documentazione ecco la specifica del comando "go": Go docs.

Ecco invece il codice dell'esempio per poterlo provare con mano:
package main

import "fmt";

func main()
{
var a int;

a = 10;

go thread1(&a);
}

func thread1(v * int)
{
//do nothing
fmt.Printf("Value %d",*v);
}

mercoledì 11 novembre 2009

Let's GO

Il mio aggregatore di notizie mi vomita tonnellate di news ogni giorno in una pagina dal design minimale (GOOGLE RULEZ).
Oggi però, proprio parlando di Google, mi è saltato all'occhio un trafiletto veramente interessante:

Have you heard about Go? We released a new, experimental systems programming language today. It is open source and we're excited about sharing it with the development community. For more information, check out the Google Open Source blog.

By Robert Griesemer, Rob Pike, Ken Thompson, Ian Taylor, Russ Cox, Jini Kim and Adam Langley - The Go Team


Allora mi sono precipitato sul sito ufficiale: http://golang.org e ho scoperto che è un linguaggio di sistema dinamico come python ma che si compila e ha una velocità di esecuzione come C/C++.
In pratica ora non resta che prendersi i tutorial e cercare di capire che cosa ci ha nascosto mamma Google per tutto questo tempo...

È ora di tuffarsi in un nuovo linguaggio tutto da imparare...

martedì 27 ottobre 2009

Vipera - Python IDE

Devo dire una cosa: NetBeans è molto pesante, così come il "più performante" Eclipse.
Visto che mi sono stancato dei tempi di caricamento ho pensato di scrivermi io stesso un comodo ide molto veloce e leggero che consenta di gestire i progetti e permetta un minimo di autocompletamento e di sintassi evidenziata.

Ecco com'è nato Vipera di cui voglio far vedere le prime immagini del progetto. Il set di icone è un po' rudimentale ma assolutamente chiare.



Il programma è sviluppato in C++ utilizzando le librerie Qt per una massima portabilità ma devo già da ora precisare che sarà ottimizzato per Gnu/Linux.
Spero di poter rilasciare una versione beta molto presto.

sabato 1 agosto 2009

Utilizzo di Qt per i file

Siamo dunque giunti al primo di una serie di articoli che tratteranno le librerie Qt in maniera un po' più seria (e anche il primo articolo da dott. ihihih!!!).

Apriamo il nostro fidato Qt Creator e proviamo a interagire con un file, che potrebbe essere benissimo un file di configurazione o un file di sistema.

Per allenarci creeremo una funzione preso in input un file, una funzione per effettuare le modifiche a una stringa e una tabella hash (int,qstring) passata per puntatore, riempie la tabella con indice e stringa modificata dalla funzione.

Nel nostro caso la funzione di modifica della stringa sarà semplicemente prendere i primi x caratteri.
void parseString( void * str )
{
QString * objStr = (QString * ) str;

*objStr = (*objStr).left( CODE_LEN );
}

Quindi nella nostra funzione fillHashTable andiamo ad aprire e scorrere il file come segue:

1) Creiamo un oggetto di tipo QFile passandogli il path del file da aprire:
    QFile filePtr (file);


2) Creiamo uno stream di dati sul file in sola lettura e cicliamo fino a che non viene raggiunta la fine del file.
    QTextStream stream( &filePtr );
while( !stream.atEnd() )
{
line = stream.readLine();
}


Ora con la linea ottenuta possiamo fare quello che vogliamo. Nell'esempio cerchiamo i token separati dallo spazio e il primo token sarà il numero il secondo la stringa da formattare.

Ecco quindi l'intera funzione:
void fillHashTable( QString file , void(*parser) (void * str), QHash <int , QString> * tb )
{
QHash <int , QString> table;
QFile filePtr (file);
bool fin = false;

if( !filePtr.open(QIODevice::ReadOnly | QIODevice::Text) )
{
cout<<"ERRORE nell'apertura del file"<<endl;
exit( -2 );
}
table.clear();
QTextStream stream( &filePtr );
QString line, tok01 , tok02;
QStringList tokens;

while( !stream.atEnd() || !fin )
{
line = stream.readLine();
if( line == "" )
{
fin = true;
continue;
}

tokens = line.split( " " );
tok01 = tokens[0];
parseString( &tokens[1] );
tok02 = tokens[1];

table.insert( tok01.toInt() , tok02 );
}


filePtr.close();

*tb = table;
}


Si dovrà dunque scrivere un main che semplicemente stampa a console i valori inseriti nella tabella hash.
Importante: l'oggetto QHash appena creato ha già un elemento in posizione 0. Per questo va pulito con il metodo clear. In merito a questo, che per me è un difetto, sto cercando materiale ma per il momento non ho ancora trovato nulla.

Ecco infine il main creato per quest'esempio:
int main(int argc, char *argv[])
{
QHash <int , QString> table;
table.clear();
fillHashTable( "file.txt", parseString, &table );
cout<<"Stampa della hash di dimensione "<<table.size()<<endl;
for( int i = 0; i < table.size() ; i++ )
{
cout<<i<<" : "<<table[i].toStdString()<<endl;
}

return 0;
}


Per ora ho concluso. Buon divertimento con quest'esempio che può ovviamente essere adattato a molte situazioni.

domenica 31 maggio 2009

Disegnare 2d con Qt4

Facciamo una piccola divagazione rispetto alla gestione dei Todo.
Con le Qt è molto semplice anche disegnare in 2D.


Per disegnare una linea o un cerchio come quelli appena mostrati il procedimento è molto semplice.

Cominciamo con il mostrare per intero il codice:
void MainWindow::paintEvent(QPaintEvent * event)
{
QPainter painter( this );
painter.setPen(QColor(255,0,0));
painter.drawLine(QPointF(0,0),QPointF(50,50));
QRectF rect (60,60,100,100);
QPainterPath path (QPointF(100,100));

path.addEllipse(rect);
painter.fillPath(path,QColor(0,255,0));
}


Per prima cosa va fatto l'override del metodo paintEvent() proprio dei widget.

painter.setPen(QColor(255,0,0));
painter.drawLine(QPointF(0,0),QPointF(50,50));

Con queste due semplici linee di codice è molto semplice disegnare e definire anche la formattazione.
Per riempire invece un tondo bisogna creare un QPainterPath, ovvero un insieme di primitive di disegno da disegnare tutte insieme.
Queste semplici istruzioni sono ovviamente utilizzabili ovunque e il metodo paintEvent è reimplementabile in ogni componente per poterne definire lo stile di disegno.

Buon divertimento :)

sabato 16 maggio 2009

NetBeans, la strada verso la 6.7

NetBeans è un IDE completo e molto potente che si basa su tecnologia Java, ma permette di svillupare, praticamente, in tutti i principali linguaggi di programmazione.

Possiamo già scaricare la beta della nuova versione, 6.7, che contiene delle succose novità.
La prima che mi è saltato all'occhio è il supporto alle librerie Qt, che stanno prendendo sempre più campo.

Da questo link è possibile raggiungere la notizia del rilascio e il link per scaricare la beta, per quanto mi riguarda già in download.

lunedì 11 maggio 2009

Laboratorio Programmazione di Rete Open

Oggi è stato completato l'esame di Laboratorio di Programmazione di rete.

Pubblichiamo quindi il codice che è già presente su internet dall'inizio del progetto.
E' possibile quindi scaricarlo, testarlo e utilizzarne il codice.

Se individuate dei problemi potete sempre inserire una "issue" nel pannello delle segnalazioni, ne saremo veramente grati.

Cliccate qui per andare al sito "ufficiale" del progetto.