Posted by Dibi Store
Wed, 26 Dec 2007 16:34:00 GMT
In effetti a volte vorremmo un metodo che si comportasse a prescindere se il primo parametro è maggiore o minore del secondo. Di cosa sto parlando?
In ruby possiamo iterare in un range di numeri con gli utilissimi metodi upto() e downto(). C'è un piccolo problema: come fare se no sappiamo a prescindere se il primo numero sarà più grande?
class Integer
def to(limit,&blk)
send(limit>self ? :upto : :downto, limit, &blk)
end
end
Figo no? i crediti vanno a sepp2k nel canale irc di ruby-lang.
Posted in ruby | no comments | no trackbacks
Posted by Dibi Store
Wed, 26 Dec 2007 16:31:00 GMT
Lo pseudocodice è una particolare tecnica che ci aiuta nella scrittura di un codice migliore, più efficente e in un tempo minore. Lo pseudocodice può non è un codice eseguibile direttamente da un computer, bensì ci aiuta nel tradurre l'algoritmo (o procedura) nel nostro linguaggio preferito. Oggi dimostretrò come questo, unito alla tecnica top down possa aiutarci in molte occasioni.
Enunciazione del problema
Il nostro obiettivo sarà quello di stampare il fattoriale dei numeri da 1 a 5 in formato tabellare, usando come linguaggio il C. A scopo didattico non verrà utilizzata nessuna libreria per effettuare il calcolo. Il fattoriale di un numero x, non è altro che il prodotto di se stesso per tutti i numeri in ordine decresente a partire da se stesso fino a 1. Per esempio il fattoriale di 5 é: 5! = 5 * 4 * 3 * 2 * 1. Anche se può sembrare a prima lista banale, il programma presenta molte caratteristiche che risaltano i vantaggi dell'uso dello pseudocodice e della tecnica top down.
risultato finale:
1 1
2 2
3 6
4 24
5 120
La tecnica top down prevede che si parta da un unica dichiarazione dell'obiettivo su una riga (o poche al massimo), che però descriva sempre completamente l'algoritmo. Potremmo quindi iniziare scrivendo questo pseudocodice:
Stampa in formato tabellare il prodotto dei numeri da 1 a 5.
Ovviamente questo codice è ben lontano dal poter essere convertito in codice reale, per qui andremo man mano ad estenderlo. In particolare ragionando sul problema è chiaro che avremo bisogno di alcune variabili e di qualche iterazione:
inizializzare le variabili
Per ogni numero da 1 a 5
stampa il fattoriale di ogni numero
Le cose cominciano ad essere interessanti, infatti notate che abbiamo dapprima inserito una nuova istruzione per l'inizializzazione delle variabili, e annunciato un ciclo che itera su tutti i numeri. Per quanto banale questo comincia già a creare una certa struttura al nostro codice e a chiarire un po le idee. Infine notate gli spazi e le indentazioni che rendono più leggibile lo pseudocodice.
Ragionando per un momento sul problema, ci viene chiaro che avremmo bisogno di 3 variabili, una sarà l'iteratore principale che useremo nel primo ciclo, che per comodità chiameremo number, di una variabile secondaria che chiamerermo i che servirà per un secondo ciclo (dobbiamo costruire un iterazione per calcolare il fattoriale), e infine una variabile sum che conterrà il prodotto delle iterazioni del secondo ciclo. Non preoccupatevi se non capite subito il mio ragionamento, in quanto l'obiettivo non è capire il significato del codice ma imparare a usare le due tecniche che ho presentato:
inizializzare variabili number, i e sum
Per ogni numero da 1 a 5(usa number come variabile di controllo)
stampa il numero corrente seguito da un segno di tabulazione
assegna a sum un valore uguale a number
per ogni numero in ordine decrescente da number a 1(usa i come variabile di controllo)
moltiplica sum per i
stampa sum
Questo codice non sarà difficile da convertire in un linguaggio come il C:
#include "stdio.h"
int main ()
{
int number, y, sum;
for(number = 1; number <= 5; ++number)
{
printf("%d\t", number );
sum = number;
for ( y = number; y > 1; --y)
sum *= y - 1;
printf("%d\n", sum );
} /* for */
return 0;
}
Che produrrà il risultato desiderato:
dibistore:4 oskar$ gcc esercizio3.c
dibistore:4 oskar$ ./a.out
1 1
2 2
3 6
4 24
5 120
dibistore:4 oskar$
Conclusioni
Avete imparato le tecniche base per scrivere un buon pseudocodice e avete sperimentato la tecnica top down. Sono sicuro che potranno tornarvi molto utili, specialmente quando un problema sembra contorto. Vi consiglio di esercitarvi un pò con queste tecniche, cercando magari un pò di documentazione online. Uno dei vantaggi più grandi a mio parere dello pseudocodice è che ora sarà estremamente semplice riscrivere lo stesso codice in un altro linguaggio, per esempio ruby:
(1..5).each do |number|
printf("#{number}\t")
sum = number
number.downto(2) {|y| sum *= y - 1 }
printf("#{sum}\n")
end
Posted in metodologie | Tags agile | no comments | no trackbacks
Posted by Dibi Store
Tue, 25 Dec 2007 08:00:00 GMT
Auguri di BUON NATALE a tutti!
Vi ho fatto anche la canzoncina :D
Posted in news | no comments | no trackbacks
Posted by Dibi Store
Sat, 22 Dec 2007 10:27:00 GMT
Git è uno strumento che permette di tenere traccia delle versioni di sviluppo (e non solo) dei nostri files, in parole povere è un ottimo sostituto di svn.
Git è molto utile in quanto permette di tenere traccia dei nostri lavori in locale, senza quindi la necessità di un repository online, e sta avendo molti consensi da parte della community, in particolare, potete trovare un ottimo screencast nel sito peepcode.
In questo tutorial partirò dall' installazione di git, alla configurazione ed infine ad un esempio d'uso, che comunque vi consiglio di prendere in seria considerazione, ossia di tenere sempre una versione di rails a disposizione, completa di tutti i plugin che usiamo sempre, e ovviamente i nostri files di configurazione, come tra l'altro suggerito nel nuovo libro advanced rails recipes.
Installazione di GIT
Potete installare git direttamente da sorgente, scaricandolo direttamente dal sito ufficiale, oppure con il vostro packet manager preferito (in base alla vostra distribuzione).
In questo esempio mostrerò il semplice comando da eseguire nel caso abbiate a disposizione mac ports:
sudo port install git-core
Configurazione
La configurazione base di Git è semplice, di default vi basterà indicare il vostro nome e il vostro indirizzo email, in modo che possa essere visualizzato nel repository, comunque le configurazione potrete poi vederle nel file ~/.gitconfig
git config --global user.name "Del Ben Oscar"
git config --global user.email 'my@email.com'
Creiamo il progetto rails
Questo è semplice e dovreste già saperlo fare, comunque ora creerò un progetto rails, rinominerò il file config/database.yml in config/database.example.yml, rimuoverò i logs, i files temp e public/index.html:
rails rails
cd rails
mv config/database{,.example}.yml
rm log/*
rake tmp:clear
rm public/index.html
Pronti con Git!
Ora viene il bello, con il semplice comando git init, creeremo i files necessari per git, in pratica una directory .git contenente alcuni files interessanti, che siete liberi (anzi consiglio) di guardare, invece cosa molto utile è creare nella root del progetto il file .gitignore, in qui potremmo scrivere tutti i files che git dovrà ignorare:
touch .gitignore
Io ho aggiunto *.log ad esempio, ma nei vostri progetti aggiungete pure se necessario i files di database e informazioni che non devono essere contenuti nella versione salvata nel repository.
Ora siamo pronti al primo commit (nel nostro repository locale), quindi con il prossimo comando, prima aggiungerò tutti i files (dobbiamo dire a git cosa includere) e poi eseguirò il commit:
git add .
git commit -m "Primo commit rails"
Ora è vostro compito aggiungere tutti quei plugin e files (anche javascript, css, ecc) che usate comunemente in tutte le vostre applicazioni, come titolo di esempio mostro come aggiungere il plugin will paginate:
./script/plugin install svn://errtheblog.com/svn/plugins/will_paginate
git status
git add vendor/
git commit -m "Aggiunto plugin will paginate"
Il comando git status vi dice che i files dovete aggiungerli a git, se volete salvarli nel repository ovviamente. Molto simile il comando git rm vi permette di rimuovere files se necessario ovviamente. Ripete l'operazione per tutti i plugins, files ecc che vi servono
La potenza dei branch
Qualunque persona che segua un progetto di qualsiasi dimensione, è abituato ad utilizzare almeno 2 versioni, una di sviluppo, e una di produzione. Ovviamente per fare cio, vengono solitamente tenute due directory separate, con git invece, abbiamo a disposizione una nuova feauture chiamata brench. In questo modo potremo usare piu versioni contemporaneamente, per vedere la versione che state usando, digitate semplicemente git brench. Per darvi un idea di cosa potete fare, create un nuovo branch con il comando:
git checkout test
Ora create un file qualsiasi dentro l'applicazione, salvatelo e aggiungetelo con il comando git add /path/to/file. Ovviamente committate, e poi tornate al branch master (quello creato di default), con il comando:
git checkout master
Magnifico! Il file non c'è più! Questo significa che avete a disposizione 2 ambienti completamente separati, e potete spostarvi da un all'altro quando volete. Vi starete domandando cosa accade se aggiungete un pezzo di codice in un file esistente nell'altro branch, provate pure! Inutile dire che potete poi aggiornare l'altro branch con le modifiche che nel frattempo avete fatto, in questo caso il comando è git rebase nome_branch, ma questo è già un concetto più avanzato (seppur semplice).
Conclusione
Ora sarete in grado di creare una copia della vostra applicazione in qualsiasi momento semplicemente con il comando git clone rails path/to/new/app. Ovviamente potrete nel corso del tempo modificare la vostra versione di rails in base alle vostre esigenze.
Posted in metodologie | Tags git | 2 comments | no trackbacks
Posted by Dibi Store
Fri, 07 Dec 2007 18:42:00 GMT
Rak è una nuova gemma (scritta in ruby) che permette di effettuare alcune utili funzioni di ricerca. Molte volte è in grado di sostituire senza problemi il classico grep. Cio che più mi ha stupito usando rak, è l'utilità quando devo cercare dove viene ripetuta una data sringa di testo (o regular expression) all'interno di una directory. Infatti ipotizzano di trovarmi dentro la directory desiderata, mi basterà lanciare il comando rak 'my string' e automaticamente parsera i files restituendo un ricco output con sintassi colorata! Meglio di cosi!
Documentazione
Enjoy
Posted in ruby | Tags rak | no comments | no trackbacks
Posted by Dibi Store
Fri, 07 Dec 2007 15:20:00 GMT
Sarà l'ennesimo post, oggi ne parlano tutti, è finalmente giunto il rilascio di rails2.0. Bhe non provo nemmeno ad agiornarela mia release oggi, perchè immagino ci sia un traffico pazzesco, e rischio di rimanere a metà con l'installazione, anche se io personalmente gia da mesi ho una versione stabile della gemma e una di sviluppo, comunque fate voi, ma ne vale veramente a pena :)
Posted in ruby on rails | Tags rails20 | no comments | no trackbacks
Posted by Dibi Store
Fri, 07 Dec 2007 08:57:00 GMT
Visto chè tra un pò uscirà la nuova versione di ruby (la 1.9), ho pensato che sarebbe interessante pubblicare alcuni test che ho fatto per vedere la differenza di velocità nell' interpretazione tra le due versioni. Gli esperimenti sono stati fatti con pezzetti di codice usati comunemente, siete liberi di postare nei commenti anche i vostri esperimenti, che poi potranno essere integrati nel post.
####################
def hash
{"Key1" => "val1", "Key2" => "val2", :key3 => 'val3'}
end
def read_hash
string = ""
hash.each {|k,v| string << "#{k} is #{v}\n" }
end
ruby 1.8
user system total real
first 9.720000 0.010000 9.730000 ( 9.725511)
ruby 1.9
user system total real
first 11.190000 0.020000 11.210000 ( 11.198272)
####################
def string_with_scan
"Questo è un test semplice di scansione".scan(/./) { |x| x }
end
ruby 1.8
user system total real
first 6.500000 0.010000 6.510000 ( 6.505941)
ruby 1.9
user system total real
first 5.850000 0.010000 5.860000 ( 5.868308)
####################
def mega_sum
( 78 * 15 ) / 34 * 23 - (34 * 567)
end
ruby 1.8
user system total real
first 0.910000 0.000000 0.910000 ( 0.915802)
ruby 1.9
user system total real
first 0.310000 0.000000 0.310000 ( 0.327869)
####################
def with_tr
"àòèùàòèùàòèàìììì".tr('àèìòù','aeiou')
end
ruby 1.8
user system total real
first 1.580000 0.000000 1.580000 ( 1.589578)
ruby 1.9
user system total real
first 1.810000 0.010000 1.820000 ( 1.819424)
Considerazioni finali
Sicuramente questo post verrà aggiornato, magari integrando qualche regular expression come test, e altri metodi usati frequentemente
A mio parere ruby è migliorato molto per quanto riguarda la gestione dei numeri, i calcoli e family, ma ha perso qualcosina nelle operazioni con le stringhe, sperò che con la release definitiva prevista prima di natale ci sia qualche miglioramento in questo senso, ma comunque resta il fatto che sono stati fatti importantissimi miglioramenti che gioveranno di sicuro a questo fantastico linguaggio.
Posted in ruby | no comments | no trackbacks
Posted by Dibi Store
Fri, 07 Dec 2007 08:25:00 GMT
Ieri, io e dei colleghi, mentre lavoravamo per zooppa, ci siamo imbattuti in un problema insolito, ossia utilizzando il browser safari, non riuscivamo ad effettuare l'upload di files in formato flv. In pratica l'applicazione in rails ci dava come parametro nella richiesta post direttamente una parte del binario (so che non è il binario, ma per capirci :D ), anzichè il nome del file (come nel resto degli altri browser usati).
In pratica, io e Alberto (un collega), abbiamo provato ad analizzare il traffico di rete, e le risposte che venivano fornite eseguendo l'upload,e ci siamo accorti che proprio nel browser safari non veniva riconosciuto correttamente il mime-type, e al contrario degli altri browser che solitamente in questo caso restituiscono una risposta application/octet-stream, safari non restituisce nulla (sarebbe una cosa da aggiungere in un prossimo futuro al browser della mela). Smanettando quà e la, Alberto ha trovato un pezzetto di codice nella classe Cgi e nel modulo QueryExtension di Ruby che definisce cosa fare quando non viene restituito un mime-type dal browser. Di seguito il pezzetto di codice originale:
content_type = ($1 or "")
In pratica li viene detto semplicemente che se non viene specificato il content-type dal browser (è attraverso il browser che effettuiamo la richiesta), ci mettiamo al suo posto una stringa vuota! Questo però in qualche modo a rails o a file_column non piace, e quindi noi abbiamo sostituito quella stringa con il mime-type desiderato ( application/octet-stream ). Ovviamente se anche voi vi state trovando in una soluzione simile, avrete sicuramente pensato che non è necessario andare a modificare direttamente il sorgente della classe originale, vi basterà semplicemente ridefinire il metodo dove volete, noi ad esempio abbiamo creato un file apposito posizionato all'interno della directory '/config', e lo abbiamo poi richiamato con require dal file environment.rb. E' inutile che posti direttamente il file modificato in quanto cambia solo quella riga, potete comunque contattarmi per problemi simili. I crediti per la soluzione vanno per la maggior parte ad Alberto e a wireshark (programmino per il traffico di rete).
Posted in ruby | Tags safari | no comments | no trackbacks
Posted by Dibi Store
Sat, 01 Dec 2007 09:11:00 GMT
Oggi ho trovato una risorsa molto utile, che consiglio vivamente a chi vuole fare qualche esercizio di programmazione (non importa particolarmente il linguaggio che usate).
Pubblicherò quindi le soluzioni in una nuova categoria del blog, che chiamerò metodologie, che conterrà spero le soluzioni a buona parte dei quesiti, più molti altri articoli interessanti.
Posted in metodologie | Tags codekata | no comments | no trackbacks