ToolsQuesto non è un messaggio. E’ un annuncio. Un inserzione.

Avevo intensione di scrivere un plasmoide per le notifiche di nuove wave su Google Wave. Ma prima di questo volevo fare una sorta di libreria di accesso in Python. Il problema è che è più complicato del previsto e non ho esperienza in interazioni con web-application via software. Quindi se qualcuno fosse disponibile mi contatti pure che proviamo a cercare una soluzione.

Alla prossima.

 

PodioHo preparato un PDF con la dimostrazione del lower bound per algoritmi di ordinamento. Può contenere ancora qualche svista ma dovrebbe essere piuttosto corretto e fornire, a chi vuole, una dimostrazione semplificata del perché non può esistere un algoritmo di ordinamento con complessità inferiore a O(n log(n)).

SCARICA

 

3dLo so. Sono discorsi pro-flame che hanno stancato tutti. Anche me. Ma a quanto pare qualcuno non ha capito a fondo la differenza fra le due librerie e crede che OpenGL sia il solito fratello sfigato delle DirectX che mamma microsoft ci offre con tanto spirito di carità.

Non starò a tediarvi con “è meglio X perché” o “quanto fa schifo Y”. Vi sparerò di seguito qualche dato preso da libri attendibili e non trarrò conclusioni. Queste spettano a voi.

Per prima cosa va puntualizzato che comparare OpenGL con le DirectX è come comparare KDE con OpenSolaris. Le OpenGL infatti sono puramente librerie 3D mentre le DirectX offrono anche funzionalità collegate al mondo dei videogame quali

DirectDraw – Libreria per la grafica 2D
Direct3D – Libreria per la grafica 3D
DirectSound – Libreria per la riproduzione e la manipolazione di effetti sonori
DirectInput- Libreria per la gestione dell’Input (tastiera, mouse, joystick etc.)
DirectShow – Libreria per la riproduzione di file video
DirectPlay – Libreria per il networking

Per OpenGL invece dobbiamo accoppiare librerie specifiche separate e librerie ausiliarie come GLUT e simili. Le comparazioni fra OpenGL e DirectX, quindi, le farò solamente rispetto a Direct3D.

Iniziamo con una tabella che comparativa delle features

Feature: OpenGL Direct3D
Vertex Blending N/A Yes
Multiple Operating Systems Yes No
Extension Mechanism Yes Yes
Development Multiple member Board Microsoft
Thorough Specification Yes No
Two-sided lighting Yes No
Volume Textures Yes No
Hardware independent Z-buffers Yes No
Accumulation buffers Yes No
Full-screen Antialiasing Yes Yes
Motion Blur Yes Yes
Depth of field Yes Yes
Stereo Rendering Yes No
Point-size/line-width attributes Yes No
Picking Yes No
Parametric curves and surfaces Yes No
Cache geometry Display Lists Vertex Buffers
System emulation Hardware not present Let app determine
Interface Procedure calls COM
Updates Yearly Yearly
Source Code Sample SDK Implementation

Da notare il supporto allo Stereo Rendering che serve a creare video 3D compatibili con gli occhialetti tanto di moda nell’ultimo periodo. :D Ora non so se questa tabella è aggiornatissima ma è comunque indicativa.

Altra questione. Le DirectX hanno un accesso diretto all’hardware su Windows mentre le OpenGL si devono arrangiare con le WGL. Questo influisce negativamente sulle OpenGL su Windows ed è uno dei motivi per cui per i giochi windows si preferiscono le DirectX. Il motivo di questa discriminazione è nella chiusura del codice di Windows, ovviamente. Inoltre, astutamente, le funzionalità di accesso all’hardware (driver) e quelle di API sono inseparabili. Ciò significa che un programma che sfrutta OpenGL non può appoggiarsi a DirectX per avere una via preferenziale verso la scheda video, infatti tale via è utilizzabile solamente se il canale viene aperto dalle API Direct3D.

Inoltre le prestazioni fra Direct3D e OpenGL sono del tutto comparabili. A seconda dei test prevale una o prevale l’altra. Quindi siamo in totale parità.

Infine la semplicità di programmazione pende a favore delle OpenGL. Per prima cosa perché sono scelte universalmente come libreria didattica e in secondo luogo perché sfrutta la semplice interfaccia a “chiamata di funzione” a differenza dell’uso di COM per DirectX.

Non dico che la tecnologia COM sia peggio della chiamata di funzione. Ma sicuramente richiede un approccio diverso e quindi una curva di apprendimento più ripida rispetto al sistema “standard” usato da C/C++ e che quindi tutti conoscono già.

Quasi dimenticavo di aggiungere che le OpenGL sono disponibili ovunque, per qualunque architettura e dispositivo, mentre le DirectX sono vincolate a Microsoft.

Ci sarebbe altro da dire ma poi diventerei noiso. Penso che queste cose servano a fare un po di chiarezza.

 

NuvoleDiciamocelo chiaramente, volenti o nolenti, adesso o fra qualche anno, ci troveremo sempre più costretti all’uso di sistemi di cloud computing. I sistemi cloud hanno notevoli vantaggi, primo fra i tanti quello di avere a disposizione ovunque lo stesso set di applicazioni, pronte e configurate, e i propri documenti.

Per chi viaggia molto o fa spesso uso di portatili queste caratteristiche sono la manna.

Ma il cloud porta con se anche oscuri presagi: per prima cosa ha il difetto di centralizzare in pochi server le informazioni e i dati di migliaia o milioni di utenti ma soprattutto quella di non garantire alcune libertà riguardo ai software.

Il problema delle web application è proprio questo. Sono quasi totalmente proprietarie e, anche se esistessero web application a codice aperto, non potrei modificarle a mio piacimento perché queste applicazioni girano solamente sul server remoto!

Allora ho cercato di vedere se può esistere qualcosa che mantenga i vantaggi del cloud ma ne minimizzi i rischi legati alle libertà fondamentali. Una sorta di plasma computing in cui la struttura di rete è talmente rarefatta in cui ognuno gestisce se stesso e nel contempo tutto è collegato a tutto. Dopotutto ormai qualunque PC di media potenza può gestire un piccolo server domestico.

Mi è venuto in mente di sfruttare (lato server) cose come SSH e il suo protocollo per X (che permette di aprire programmi remoti come se girassero in locale) aggiungendo loro la possibilità di formare cluster (ovvero la possibilità di “fondere” all’occorrenza due o più server facendone sembrare uno e quindi condividere dati e applicazioni).

Vabbè, probabilmente sono solo fandonie, ma il senso è chiaro. Il Cloud rischia di distruggere la mia idea di Open Source relegandola solamente agli strati più bassi di un sistema operativo (vedi Chrome OS) e se la cosa rischia di avere troppo successo la comunità Open deve essere pronta a reagire.

 

ChromeQuesta sera alle 19:00 Google mostrerà a noi comuni mortali il suo nuovo S.O. in anteprima mondiale.

Si può assistere all’evento su questo link.

Ovviamente, nonostante Chrome OS sia basato su Linux, il sito richiede il plugin di MediaPlayer o di RealPlayer per poter essere visto…. vabbè… a questo rimedia VLC.

La curiosità c’è per quello che sembra l’ennesimo piccolo passo verso una imposizione nel mercato dei sistemi operativi (prima il browser Chrome, poi Wave ed ora questo…). Ma i benefici che avrà il mondo GNU/Linux da Chrome OS sembrano ancora poco sicuri.

Potrebbe essere una piccola svolta come potrebbe essere l’ennesima delusione.

Per il momento non serve a nulla arrovellarci il cervello, aspettiamo le 19.

 

Google WaveHo avuto modo di provare più a fondo questo tool, di avere una discreta corrispondenza con alcuni sviluppatori e con gente più informata sugli sviluppi futuri del progetto.

Prima cosa che ho scoperto è che gli inviti sono sospesi fino a quando non si svuota un po la coda degli inviti pendenti. Quindi per il momento sto a secco. Secondo ho testato Wave grazie alle wave pubbliche (accessibili scrivendo with:public nella ricerca).

Dopo aver giocherellato qualche giorno mi sono fatto un idea migliore di cosa sia Wave, delle sue possibilità e di quali sono gli sviluppi più vicini.

Innanzitutto dobbiamo mettere in chiaro che uno dei ruoli di Wave è quello di soppiantare le email. E su questo io spero molto perché, diciamocelo chiaramente, le email fanno schifo: invase di spam e vincolate alla loro staticità (molto fuori tempo se paragonato alla sempre più crescente dinamicità dei contenuti web).

Questo obbiettivo non tanto nascosto è palesato anche dall’interfaccia che richiama molto quella di una web mail con la casella inbox, archivio, cestino e la possibilità di incasellare i messaggi in cartelle personalizzate (come si fa con Gmail).

Ma Wave pare essere ancora di più: il dinamismo dei contenuti permette di sostituire anche i vari sistemi di messaggistica istantanea e la permanenza degli stessi, di sostituire vari tool di collaborazione.

A dettare i tempi di questi obbiettivi sono proprio le funzioni che sono in procinto di essere inserite in Wave come l’integrazione con Gmail/Gtalk e la possibilità di esportare una Wave nei Google Documents.

A penalizzare il tutto, attualmente, è la smisurata lentezza dell’applicazione quando si trova di fronte a Wave di grosse dimensioni. Questo penso sia l’effetto di un uso “particolare” di alcune funzioni di HTML+CSS+Javascript, cosa che spiegherebbe il tentativo di Google di inserire nello standard HTML5 alcune proprie personali modifiche nonché il tentativo di trovare un alternativa al protocollo HTML/TCP.

Inoltre il sistema pare ancora molto incompleto e penso che il suo pieno potenziale arriverà successivamente alla pubblicazione del servizio. (Anche il primo GMail era una web-mail piuttosto lacunosa e poco gradevole).

Quindi io credo che ne vedremo delle belle ma dovremo aspettare ancora parecchio.

 

DoppioLa maggior parte dell’opera non consiste nel vedere se una cosa smetterà di funzionare bensì nel pensare a cosa fare quando quella cosa smetterà sicuramente di funzionare.

Questa cosa è presente anche nell’informatica e nelle telecomunicazioni: ad esempio non possiamo garantire che le trasmissioni attraverso un canale siano perfettamente prive di errori, anzi, gli errori sono sempre dannatamente frequenti se paragonati alla quantità di dati che attraversano la rete e alla precisione che ci aspettiamo in uscita.

Scarichiamo solitamente file di un paio di mega, circa 2 milioni di byte che corrispondono a 16 milioni di bit. Anche solo un errore su 100.000 bit inviati (una percentuale di errore dello 0.001%) si ripercuoterebbe nel file per 160 volte e sappiamo che, specialmente in file eseguibili, basta anche un solo bit fuori posto per mandare all’aria l’intera applicazione.

Il metodo più utilizzato per ovviare al problema è senza dubbio la ridondanza ovvero la ripetizione delle informazioni nella speranza che, anche nel caso in cui un pacchetto di informazioni venga danneggiato da un errore di trasferimento, il ricevente abbia sempre a disposizione una “copia di riserva” da cui recuperare l’informazione.

La ridondanza viene solitamente applicata su più livelli e nella pila protocollare ci sono almeno 2-3 meccanismi di ridondanza più un meccanismo di “rinvio”. Quindi possiamo dire che nel traffico di rete l’informazione utile è meno della metà del totale dei bit in transito.

Al livello più basso il meccanismo di codifica più basso e semplice che possiamo immaginare è quello di duplicare brutalmente l’informazione: se dobbiamo inviare la sequenza di bit 011010 invieremo, per sicurezza, 000111111000111000. In questo modo anche se abbiamo un errore all’interno della tripletta di bit sapremo sempre qual’era il messaggio originale. Infatti se riceviamo la tripletta 010 sappiamo che in realtà la tripletta originale era 000 e non 111 per il semplice fatto che la probabilità di un errore è molto più alta che la probabilità di due errori nella stessa tripletta! Ovviamente non abbiamo la garanzia assoluta ed è per questo che ci sono meccanismi di ridondanza anche ad alto livello.

Ma perché abbiamo messo triplette invece di coppie? Semplicemente perché la tripletta ci permette di eseguire sia la rilevazione che il recupero dell’errore. Supponendo infatti di inviare coppie quali 00 o 11 alla presenza di un errore, mettiamo 01, non possiamo distinguere se ci sia stato un errore nel primo bit (e quindi l’originale era 11) oppure l’errore fosse del secondo bit (e quindi l’originale era 00). In questo caso possiamo solamente rilevare l’errore ma non possiamo recuperarlo.

Questo fatto è indicato dalla distanza di Hamming la quale indica il numero di “errori” necessari per convertire una stringa di bit in un altra. Il primo codice che abbiamo usato ha una distanza fra i suoi elementi (ovvero fra 000 e 111) di 3. Il sistema quindi sceglierà, in caso di errore, la stringa che dista di meno da quella ricevuta. Nel nostro esempio la stringa 010 dista 1 da 000 e dista 2 da 111. Scegliendo quella a distanza minore scegliamo proprio 000.

Notiamo quindi che scegliere un codice che abbia distanza di Hamming dispari fra i propri elementi garantisce sempre il recupero dell’errore perché il sistema ha sempre una parola di codice più vicina di un altra. Una distanza di Hamming pari fra le parole invece presenta sempre, seppure improbabili, delle stringhe ricevute che distano in egual misura da due parole distinte. In questo caso il sistema è solo in grado di rilevare l’errore e non di correggerlo.

Ma la ridondanza non viene solamente utilizzata per rilevare e correggere errori. Anche le prestazioni di un programma possono beneficiarne. Supponiamo ad esempio una classe Triangolo che mantiene al suo interno informazioni sui tre angoli interni dello stesso. Notiamo subito che potremmo operare in due modi: creare tre attributi che mantengono i tre angoli, oppure mantenere solo 2 angoli e ricavare il 3° tramite una funzione. Se scegliamo di inserire il terzo angolo inseriamo una ridondanza. Se abbiamo un triangolo con due angoli di 45°sappiamo automaticamente che il terzo dovrà essere di 90°. Facendo così risparmieremo sì spazio ma renderemo la classe triangolo più onerosa dal punto di vista della CPU.

Questa cosa è sempre vera, anche nel caso della rilevazione dell’errore. Quando scegliamo di utilizzare la ridondanza scegliamo di sacrificare lo spazio per guadagnare tempo. E’ questa la grande coperta dell’informatica: dobbiamo sempre saper scegliere se il sacrificio di spazio dia guadagni in tempo significativi o, viceversa, se risparmiare spazio non faccia perdere troppo tempo.

E’ un concetto sottile ma essenziale per progettare sistemi ad alta efficenza e soprattutto adatti all’ambiente che vogliamo utilizzare.

 

Google WaveIeri notte tornando a casa mi sono ritrovato l’invito di Google per la nuova e misteriosa piattaforma Wave. Richiesi l’invito perché attratto dal video dimostrativo ebbi l’idea di integrare alcune funzioni su KDE appoggiandomi ad alcune api di Wave che Google mise a disposizione fin dall’inizio.

Ora posso iniziare questo progetto. O meglio… potrei… dato il mio sovraccarico di impegni. :D

Comunque sia. Per ora Wave è una scatola piuttosto inutile. Non per suoi demeriti ma semplicemente perché per ora non ho contatti! xD E a che serve una potente interfaccia di comunicazione se non c’è nessuno con cui comunicare?

Se mai mi daranno qualche invito e troverò qualche contatto, magari potrei capirci qualcosa di più e fare qualcosa di utile!

 

Pacchetto DebDato che spesso mi capita di dover programmare in Python e dato che non ho voglia di stare ogni volta che modifico un sorgente a ricrearmi tutto il .deb. Ho deciso di automatizzare la cosa con uno script. E’ uno script grezzo e perfezionabile, ma fa magnificamente il suo lavoro. Lo pubblico sperando che possa essere utile a qualcuno, ovviamente una volta che l’avete modificato per le vostre esigenze.

#! /bin/bash

version="0.2.0-1"

mkdir nomeprogramma_${version}_all
cd nomeprogramma_${version}_all
mkdir DEBIAN
mkdir usr
cd DEBIAN

# GENERATE CONTROL FILE
echo "Package: nomeprogramma" >> control
echo "Version: ${version}" >> control
echo "Section: video" >> control
echo "Priority: optional" >> control
echo "Architecture: all" >> control
echo "Depends: python, python-qt4" >> control
echo "Installed-Size: 309" >> control
echo "Maintainer: Nome Cognome <email@gmail.com&>" >> control
echo "Description: Bla bla bla" >> control

cd ..
cd usr
mkdir bin
mkdir share
cd bin

# GENERATE START FILE
echo "#!/bin/bash" >> nomeprogramma
echo "cd /usr/share/nomeprogramma" >> nomeprogramma
echo "env python -O main.py" >> nomeprogramma

chmod +x nomeprogramma

cd ..
cd share

mkdir applications
mkdir doc
mkdir nomeprogramma

# GENERATE DESKTOP FILE
cd applications
echo "[Desktop Entry]" >> nomeprogramma.desktop
echo "Version=${version}" >> nomeprogramma.desktop
echo "Name=Nome Programma" >> nomeprogramma.desktop
echo "Comment=Bla bla" >> nomeprogramma.desktop
echo "Type=Application" >> nomeprogramma.desktop
echo "Comment[it_IT]=Bla bla" >> nomeprogramma.desktop
echo "Exec=/usr/bin/nomeprogramma" >> nomeprogramma.desktop
echo "Icon=/usr/share/prova/img/nomeprogramma.png" >> nomeprogramma.desktop
echo "Terminal=false" >> nomeprogramma.desktop
echo "Categories=Multimedia;QT;" >> nomeprogramma.desktop
cd ..

cd ..
cd ..
cd ..

# COPY COMPILED FILE
cp -r -v ./src/* ./nomeprogramma_${version}_all/usr/share/nomeprogramma/ #Questa parte copia tutti i sorgenti del vostro programma python.
cd ./nomeprogramma_${version}_all/usr/share/nomeprogramma/

# CLEAN NOT USEFUL FILES
#Cancella i file non necessari all'esecuzione.
find -name '*.ui' -exec rm -v {} \;
find -name '*.*~' -exec rm -v {} \;
rm Makefile

cd ..
cd ..
cd ..
cd ..

#  MAKE DEB
dpkg -b ./nomeprogramma_${version}_all

# REMOVE TEMP DIRECTORY
rm -r ./nomeprogramma_${version}_all

Ovviamente in nomeprogramma dovete inserire il nome del vostro programma. Ancora meglio sarebbe metterlo in una variabile e usare una variabile, così potete riutilizzarlo per più programmi. A me non andava di farlo e ve lo beccate così com’è :D

Inoltre la copia dei file dovete rivederla perché io assumo che nella cartella in cui c’è questo script esista una cartella src che contiene i sorgenti (in pratica assumo che usiate una convenzione che uso io xD). Ma è solo una riga, si cambia facilmente.

Spero vi sia utile. :)

 

Golden gene in DNA Se state pensando ad orrori tipo cani a due teste oppure ad un esercito di super-soldatigeneticamente modificati siete completamente fuoristrada. In informatica, e in particolare nell’intelligenza artificiale, per programmazione genetica si intende una metodologia di programmazione automatizzata ispirata dall’evoluzione biologica. Ma cosa significa? La selezione naturale si basa sulla sopravvivenza e la capacità di un essere vivente di avere capacità migliori rispetto ad un altro se sottoposto ad alcune pressioni naturali quali le caratteristiche dell’ambiente e la presenza di particolari predatori. Com’è possibile quindi trasportare tutto questo a livello di programmazione?

Ovviamente le parti in gioco sono diverse ma analoghe. Il codice genetico di un animale diventa semplicemente il codice di un particolare programma o funzione e la selezione naturale si riduce ad “avere le caratteristiche migliori”.

Così semplice? Almeno grossolanamente si. Ma se andiamo ad analizzare attentamente questi due aspetti possiamo trovarci di fronte a problematiche più sottili. Ad esmpio: come si può portare il codice di un programma ad assomigliare ad un codice genetico?

La risposta è altrettanto apparentemente semplice. Ci sono alcune caratteristiche che un programma, o meglio la sua rappresentazione, deve rispettare. Innanzitutto il programma deve poter essere “riprodotto” secondo una riproduzione sessuata, ovvero tramite crossover. Inoltre tale codice deve essere sottoposto a mutazioni casuali.

Spiegare come possano avvenire queste due cose su un programma o un algoritmo è qualcosa di piuttosto complesso che non ho la pretesa di poter spiegare qui. Forse lo farò un in qualche articolo separato. Sappiate però che l’approccio più semplice è quello di utilizzare  una struttura ad albero per rappresentare i programmi e simulare crossover e mutazioni come scambi e variazioni di sotto-alberi scelti casualmente all”interno del programma.

La cosa da fare, una volta che sappiamo come rappresentare i programmi, è di generare una popolazione iniziale. L’algoritmo procede in linea di massima così:

  • Viene generata casualmente una popolazione di programmi iniziale.
  • Vengono fatti funzionare tutti questi programmi e vengono raccolti i risultati.
  • I risultati vengono valutati con una funzione di FITNESS.
  • Il programma che ottiene il maggior punteggio di fitness passa immutato alla seconda generazione e inoltre viene utilizzato per “riprodurre” una nuova generazione di programmi usando crossover e mutazioni.
  • Si torna al punto due e così via finché non viene estrapolato un programma sufficentemente valido.

La funzione di fitness è una funzione che prende in ingresso il codice genetico di un programma, lo avvia e confronta il risultato con il risultato “ideale”. Il concetto di risultato ideale è piuttosto complesso: molto spesso, infatti, non abbiamo chiara l’idea di quale sia il risultato ideale. Ma anche questo, da solo, potrebbe essere argomento di un libro. Il concetto di fondo della funzione di fitness rimane comunque valida.

Come vedete sia i termini che il procedimento ricorda molto quello che avviene in natura. Un interessante esempio di proto-programmazione genetica è narrata infatti anche nel libro di Richard Dawkins L’orologiaio cieco del 1989 in cui questo processo di selezione “informatica” viene usato dall’autore per mostrare la potenza della selezione cumulativa.

L’argomento è, onestamente, uno dei miei prefetiti e da tempo cerco di perfezionare un ambiente di programmazione genetica in Python chiamato Galapagos e spero con questo articolo di aver incuriosito qualcuno riguardo questa fascinosa metodologia di programmazione. Mi spiace parlarne così frettolosamente ma lo spazio è quello che è.

Vi lascio perciò un link nel quale potete approfondire l’argomento (in attesa che ci pensi io ;) )

http://www.genetic-programming.org/

© 2008-2012 SlashCode Suffusion theme by Sayontan Sinha