di Francesco Balena Ecco una bella notizia che mi ha fatto cominciare l'anno nel migliore dei modi.
Microsoft Corp. ha confermato Giuseppe Dimauro e il sottoscritto come gli unici due Regional Director per l'Italia, per gli anni 2008-09. E' una grande soddisfazione far parte di una elite di soli 140 esperti in tutto il mondo - a differenza di altri gruppi come gli MVP, il numero degl RD è "contingentato", tipicamente 1 o 2 per ciascuna nazione e per ciascuno dei 50 stati degli USA. Negli ultimi tempi il Regional Director Program si è arricchito di un sito tutto nostro, che funge anche da aggregatore dei blog. Data la qualiltà del materiale che si può trovare, è quasi meglio di una rivista tecnica.
di Giuseppe DimauroSilverlight
in primis, ma anche le anteprime di Visual Studio 2008 e Windows server 2008, sono
solo alcune delle novità che promettono un inverno più caldo di questa torrida estate italiana.
Un aspetto trascurato, ma che non
può lasciarci indifferenti, è che molte di queste novità hanno avuto un
contributo da rappresentanti del Bel Paese. Sviluppatori, program
manager, tester, evangelisti, ognuno di questi ruoli è rappresentato anche da
italiani illustri come Vittorio Bertocci, Marco Ottaviani, il caro Aldo Donetti e
molti altri. Vi segnalo una iniziativa da non perdere legata al nuovo tag center di Channel9: Italia9. Vittorio Bertocci, si prodigherà in una serie di interviste, rigorosamente in italiano, in giro per il campus di Redmond parlandoci direttamente nella nostra lingua. Grande !!! Altre interviste saranno disponibili nei prossimi mesi; in linea è già disponibile la prima, fatta a Marco Ottaviani, devlead per le Performance nel Connected Framework team (Windows Communication Foundation, Windows Workflow), nella quale Marco ci mostra qualche errore tipico in cui si può incorrere quando si cerca di misurare le performance di WCF e ci svela quali strumenti utilizza nel suo mestiere.
Che dire, un plauso a Vittorio e a tutti quelli che stanno sostenendo questa straordinaria inziativa
oltre ad un in bocca al lupo per il prosieguo del
lavoro a tutti i nostri connazionali oltreoceano dei quali essere orgogliosi.
di Francesco Balena

Sembra siano state scattate nella Silicon Valley e stanno diventando la barzelletta tra molti anti-Microsoft-tiani. Le potete trovare a questo indirizzo.
Ovviamente, il problema non è nella tecnologia ma in quanto bene (o male, in questo caso) la si usa. Quanto costava controllare meglio gli errori o redirezionarli su una pagina più "carina"? Sicuramente meno della brutta figura che la ditta di mobili svedese (e non Microsoft) sta facendo.
di Francesco Balena
Ecco un post che ha poco a che fare con la tecnologia e molto a che fare con il lavoro.
Il nostro amico Eugenio Lamesa, il migliore esperto che abbiamo in Italia di Mail Marketing nonchè la mente dietro il programma/sito SalesWare (a cui sono orgoglioso di aver contribuito come consulente) ha da poco inaugurato il sito TuaPensione.it, dedicato a chi entro il 30 giugno deve decidere cosa fare del proprio TFR.
Tra le tante iniziative Eugenio ha preparato una whitepaper che spiega in modo chiaro e sintetico i dettagli della nuova leggere e come prendere la decisione più giusta e conveniente. Non solo le informazioni sono più chiare e dirette di quelle che ho potuto leggere su alcuni giornali, ma sono anche depurate dai possibili "conflitto di interessi" che abbondano anche in questo settore. Da qualche giorno su sito c'è anche un interessante calcolatore online, che permette di confrontare le varie opzioni. TuaPensione.it è assolutamente no-profit (non ci sono neanche i banner di Google!), come lo è MenoStato.it, l'altro sito a cui Eugenio lavora con passione da qualche anno.
di Francesco BalenaLeggendo questo post sono arrivato a "Myths about the developing world", un video che merita di essere visto, per almeno tre motivi:
1) sfata alcuni luoghi comuni su quello che noi europei pensiamo del mondo in via di sviluppo 2) avanza alcune proposte su come utilizzare e linkare meglio i database contenenti dati statistici ma soprattutto 3) mostra come utilizzare una grafica eccezionale per supportare idee e concetti.
Dategli una occhiata, sono 20 minuti spesi bene.
di Francesco BalenaFinalmente noi Regional Director abbiamo un magazine online tutto nostro! Abbiamo aspettato un po', ma il risultato è davvero di prim'ordine, come potete vedere voi stessi.
The Region è un magazine composto principalmente aggregando i blog dei vari RD, ma la cosa interessante è si ottiene molto più della somma di 140 feeds, perchè esistono alcuni redattori che si preoccupano di mettere online solo i post significativi, evitando doppioni, post di carattere personale oppure smaccatamente commerciale. Non solo: gli articoli sono suddivisi per categorie, quindi potete anche leggere solo quelli che riguardano le tecnologie che vi interessano maggiormente.
Ci sono anche le pagine personali, con informazioni, foto, ultimi post, ecc. Ecco ad esempio la mia home page su The Region (Francesco Balena) e quella di Giuseppe Dimauro, dove il mio socio abbraccia uno dei super-monitor 16:9 che abbelliscono l'ufficio.
di Marco BellinasoIn questo periodo sono occupato quasi settimanalmente con lo Starting Innovation Tour, un ciclo di conferenze gratuite organizzate da Microsoft nelle principali città italiane per mostrare a sviluppatori e partner le principali novità di Vista e Office 2007. Dopo Catania, Napoli, Bologna, Bari e Roma, questa settimana tocca a Padova, poi Milano, Firenze e Torino. A mio parere la conferenza è davvero un'ottima occasione per chi non ha ancora visto con i propri occhi (o toccato con mano, con preferite) le nuove major release dei due prodotti principali di MS. Io mi occuperò delle sessioni su Office, ovvero:
- Sviluppo con Office 2007 Client Side: come sfruttare il nuovo formato XML dei documenti per modificare o creare nuovi documenti senza avere Office installato - da applicazioni desktop o web - nonchè una panoramica sulla creazione di add-in, Action Pane e ribbon custom.
- Windows SharePoint Services 3.0: nuove funzionalità per le liste e document library (cestino, supporto per versioning esteso, supporto RSS,...), nuovi template (blog e wiki tanto per essere moderni, ma altro ancora), utilizzo masterpage a-là ASP.NET 2.0, webpart, utilizzo workflow built-in o utilizzo del nuovo SharePoint Designer per la definizione dei propri flussi.
- Office SharePoint Portal 2007: Excel Services (il motore di calcolo di Excel direttamente sul server + rendering via browser + esposizione del motore tramite web service!), Forms Services (praticamente le form InfoPath via browser!) e Business Data Catalog (indicizzazione e visualizzzione di record presi da un qualunque database o fonte di accesso ai dati esterna)
Insomma, mi sembra ci sia un bel po' di roba da vedere Per non parlare delle bellissime e impressionanti demo grafiche fatte con WPF per Vista! Dai, ci vediamo ad una delle prossime tappe allora...
di Francesco BalenaChe ne dite di questo messaggio di errore in Windows 2000?
Message: Your Password Must Be at Least 18770 Characters and Cannot Repeat Any of Your Previous 30689 Passwords
Sembra una barzellatta ma non lo è. E' "solo" un bug... però vorrei vedere la faccia di un utente che si trova a leggere questo messaggio Trovate tutti i dettagli qui.
di Francesco BalenaRiprendo un po’ a scrivere sul blog, approfittando di una mattina oziosa di vacanza. Lo spunto me lo offrono un paio di commenti al mio post precedente, che oramai data un mese e mezzo fa. (Forse tra qualche settimana vi svelerò a cosa ho lavorato in tutto questo tempo...)
Ogni tanto su questo blog e sui vari forum qualcuno si lamenta che i libri tecnici in italiano costano troppo, e si avanzano spesso ipotesi sulla presunta ingordigia degli editori italiani. Il ragionamento è che se un libro in originale costa, supponiamo, 50$ dovrebbe costare l’equivalente anche in italiano, ossia circa 40 euro, anzichè 50 o 60 euro come spesso accade.
Anche se suggestivo, questo ragionamento è un po’ troppo semplicistico e non tiene conto di quello che accade quando un editore italiano decide di tradurre un libro dall’inglese. Io non voglio fare il “difensore d’ufficio” di aziende come Mondadori o Apogeo, che proprio non hanno bisogno di qualcuno come me che le difenda, però credo sia giusto sgombrare il campo da tutta una serie di falsi miti, che evidentemente derivano dalla scarsa conoscenza dei meccanismi editoriali. Visto che lavore con case editrici da oltre vent’anni dovrei avere qualcosa di interessante da raccontare.
Prima di cominciare, ci tengo a precisare che questa “difesa d’ufficio” degli editori italiani per me è persino controproducente. Se devo dirla tutta, a me farebbe molto più comodo che i miei lettori comprassero direttamente i libri in inglese, per un semplice motivo: io ho un contratto con Microsoft Press e non con l’editore che traduce in italiano i miei libri (Mondadori, nella fattispecie), e per contratto il guadagno sulle copie in inglese è quasi doppio di quello sulle copie tradotte in altre lingue, italiano incluso. In altre parole: convincervi a comprare i libri in italiano va persino contro i miei interessi.
Allora, ragioniamo per assurdo e supponiamo che un editore italiano decida di tradurre un libro tecnico dall'inglese e di venderlo allo stesso prezzo dell'originale. Vediamo come se la caverebbe questo editore con evidenti tendenze suicide...
Il primo costo da sostenere sono i diritti di traduzione. Non ho modo di sapere a quanto ammontano questi diritti, ma di certo non sono irrisori. A titolo puramente di esempio, diciamo che per un libro di medio successo potrebbero essere sugli 6-8 mila euro. La cifra esatta dipende anche dal numero di copie vendute, e comunque questi dati non sono pubblici, quindi la mia è una stima ipotetica ma tutto sommato realistica.
A questo punto scatta il processo di traduzione. I costi di traduzione per un libro di 700 pagine costa non sono meno di 7-8mila euro, o anche più se si tratta di un argomento specialistico. Occorre poi correggere e impaginare le bozze, e sommando questi costi di editing ai costi di traduzione arriviamo a 10-12mila euro, solo per avere i file PDF pronti per la stampa.
I costi per la stampa sono quelli che pesano maggiormente in percentuale per le tirature piccole come quelle italiane. Quanto sono piccole le tirature in Italia? Non posso darvi i numeri esatti delle vendite dei miei libri, che non sarebbero indicativi per un discorso generale in quanto “viziati” dal fatto che io sono un autore italiano con un buon grado di visibilità in patria, però posso fornire qualche numero su cui riflettere.
Un libro di programmazione “mediamente di successo” vende nel mercato mondiale 25-30mila copie, e questo mercato comprende gli USA, il Canada, il Regno Unito e tutti gli altri paesi anglofoni, più tutti i paesi in cui comunque i libri tecnici non sono tradotti (ad esempio, i paesi scandinavi e i paesi dell’Europa dell’Est). È facile vedere che parliamo di un bacino di utenza almeno 20 volte maggiore di quello italiano. Anche abbondando, potremmo dire che la traduzione dello stesso libro “mediamente di successo” non dovrebbe vendere in Italia più di 2-3mila copie.
In realtà la situazione è persino peggiore di quanto ho descritto, poichè molti sviluppatori italiani preferiscono comunque comprare i libri in lingua originale, sia perchè non hanno errori di traduzione sia perchè sono disponibili alcuni mesi prima delle traduzioni. Una stima più attendibile è quindi non oltre le duemila copie per un libro di medio successo. Molti si stupiscono di questi volumi così piccoli, ma tenete presente che stiamo parlando di una nicchia molto specialistica: ad esempio, un libro su Windows o Office vende tipicamente molto più di tanto, anche perchè la maggior parte degli utenti finali proprio non ne vuole sapere di comprare i libri in lingua originale.
I costi di stampa per singola copia aumentano se il numero di copie stampate diminuisce, anche se non in modo proporzionale. Per una tiratura 10-15 volte inferiore i costi di stampa sono sicuramente almeno tre volte superiori. Davvero non conosco le cifre reali, ma mi stupirei se la stampa e la rilegatura di un libro di 700 pagine con una tiratura di 2mila copie e una copertina in cartoncino e a colori possa costare meno di 8-10 euro per copia. Occorre considerare, infatti, è che se anche un libro di successo venderà qualche migliaia di copie nel lungo periodo, inizialmente si stampano un numero inferiore di copie, per vedere come va in libreria e anche per ridurre i costi di magazzino (o forse credete che lo spazio in un magazzino sia gratuito?). Purtroppo, tirature inferiori significano costi per copia superiori, quindi 8-10 euro non è una stima irragionevole. Forse esagero, forse no. Se avessi tempo farei qualche indagine presso una tipografia, ma sono in vacanza e ho altro di meglio a cui pensare. E comunque non credo che qualche euro in meno cambierebbe la sostanza del ragionamento.
A questo punto il libro può essere spedito dalla tipografia al distributore, o meglio i distributori disseminati nelle varie regioni. Per fortuna questi costi di spedizione assommano a qualche frazione di euro per ciascuna copia, per cui possiamo trascurarli in questa analisi di massima.
Ovviamente, non tutti i 40 euro del prezzo di copertina vanno nelle casse dell’editore, perchè occorre considerare il guadagno delle librerie e dei distributori. Negli USA all’editore va il 52% del prezzo di copertina. In Italia non so bene, ma è ipotizzabile una percentuale simile. Allora siamo pronti a tirare le somme.
- 2000 copie a 40 euro l’una fanno 80mila euro lordi
- Il 52% di questa cifra lorda va all’editore, quindi 41.600 euro.
- Togliamo 8mila euro per i diritti di traduzione, e arriviamo a 33.600 euro.
- Sottraendo i costi di traduzione e impaginazione arriviamo a 21.600 euro.
- Ipotizzando 8 euro per la stampa di una copia, arriviamo a 16mila euro di costi di stampa, il che porta il margine per l’editore a circa 8.000 euro.
Per guadagnare questi 8.000 euro, l’editore deve mettere in moto un meccanismo complesso che richiede la presenza di numerose figure di alto profilo professionale, tra cui, i consulenti che decidono quali libri tradurre, gli uffici legali che stilano i contratti, i manager che tengono i contatti con la casa editrice americana, ecc. Oltre agli stipendi di queste persone, occorre considerare i costi della struttura e tutto il resto. Non ho neanche una vaga idea dell’ammontare di questi costi, ma di sicuro non sono trascurabili.
Quando il libro è finalmente stampato occorre provvedere alla sua distribuzione e alla promozione. Come forse potete immaginare, la pubblicità sulle riviste non viene regalata, e anche semplicemente gestire un sito e mandare una newsletter ha dei costi. Ma il costo principale è quello del personale umano, ad esempio gli agenti di vendita. Questi signori (di solito ve ne è uno per regione) girano costantemente per tutte le librerie della penisola, proponendo le novità e raccogliendo gli ordini per i libri che devono essere ancora stampati. Se queste persone non esistessero, nelle librerie trovereste soltanto i libri di Dan Brown, Grisham, e pochi altri, perchè pochi librai capiscono la differenza tra SQL Server e Paint, tanto per fare un esempio.
Attenzione, però, perchè i costi per l’editore non sono terminati. Infatti, i libri tecnici sono soggetti a veloce obsolescenza, quindi tutte le librerie prendono i libri tecnici in conto vendita, il che significa che in qualsiasi momento possono restituire all’editore le copie invendute. Il reso può essere richiesto anche dopo uno o due anni, e questo pesa come una spada di Damocle sui conti economici. Basta un reso del 20% per azzerare o quasi il margine che abbiamo ipotizzato per il nostro editore, perchè al mancato guadagno occorre considerare i costi di spedizione, i costi del macero e dello smaltimento. (Persino buttare via i libri costa...)
Se il 20% di reso vi sembra una stima esageratamente alta, considerate che la maggior parte delle riviste tecniche ha un reso in edicola intorno al 35-40 percento. (...e questo spiega perchè tutte le riviste inisitono così tanto per fare abbonare i loro lettori.) Del resto, basta andare in una qualsiasi libreria e contare il numero di copie impolverate di libri su Access 2000 o Visual Basic 6 per capire che si tratta di stime assolutamente ragionevoli.
Ancora: tenete presente che tutto il discorso fatto finora si riferisce a un libro “mediamente di successo”. In realtà, la stragrande maggioranza dei libri tecnici in inglese vende molto meno di quelle 30mila copie ipotizzate inizialmente, in particolare i libri su tecnologie di nicchia come SharePoint o BizTalk. Ad esempio, un libro su VB o C# “generico” vende anche il doppio di un libro su ASP.NET, che a sua volta vende due-tre volte più di un libro su Windows Forms o quattro-cinque volte più di un libro su ADO.NET.
Ultima considerazione: il nostro libro di esempio non ha un CD-ROM a corredo. Infatti, con un CD i costi salirebbero notevolmente, non solo per la creazione del CD vero e proprio ma anche per il fatto che i CD tendono a rompersi durante il trasporto o persino l’esposizione in libreria. Se un lettore trova un CD rotto o illeggibile, chiede il rimborso all’editore (e non al tipografo, al libraio o al trasportatore, che spesso sono i reali responsabili). La spedizione di un CD praticamente azzera il guadagno per quella particolare copia del libro. Per questi motivi, la presenza di un CD può fare levitare il prezzo di copertina anche di 4-5 euro, visto che occorre considerare il margine del 52% e dei libri restituiti destinati al macero.
Siamo arrivati alla fine del mio ragionamento, che è forzatamente approssimativo perchè si basa su alcuni dati non noti e di cui posso solo stimare il valore. Ma se vi armate di una calcolatrice, vedrete che anche diminuendo l’impatto di qualche voce dubbia – ad esempio i costi di traduzione e di stampa – la sostanza del ragionamento non cambia di molto.
La morale è semplice: i libri tecnici in italiano tradotti dall’inglese non potranno mai costare quanto le versioni originali. Forse nel futuro alcuni costi potranno essere eliminati o ridotti fortemente – ad esempio se si diffondesse il print on demand e si procedesse con la stampa di singole copie a costi bassissimi solo quando un acquirente prenota la sua copia via Internet – ma fino a quando le librerie rimarranno il principale mezzo di diffusione dei libri tecnici questa regola continuerà a valere. Quindi, o vi rassegnate a spedere qualche euro di più per le copie in italiano o vi decidete a imparare l’inglese, che sarebbe una decisione che avrebbe un impatto positivo per molti aspetti ben più importanti 
NOTA: Ho volutamente trascurato la possibilità di evitare i costi di stampa e saltare tutti i livelli della distribuzione pubblicando degli e-book scaricabili da Internet. Purtroppo, gli e-book hanno la simpatica (per il lettore) ma fastidiosa (per l’autore) caratteristica di essere facilmente duplicabili e scambiabili con gli amici e colleghi. Microsoft Press mi ha chiesto in passato di pubblicare degli e-book, ma mi sono sempre rifiutato, come si sono rifiutati praticamente tutti gli autori di una certa rilevanza. Forse le cose cambierebbero se esistesse un meccanismo anti-duplicazione sicuro e che allo stesso tempo non complichi la vita ai legittimi acquirenti, ma per il momento le cose stanno in questo modo, quindi gli e-book non sono una alternativa plausibile.
Se avete osservazioni da fare ma soprattutto se pensate che il ragionamento abbia qualche falla, fatevi sotto con i commenti.
di Francesco BalenaPurtroppo non riesco a stare dietro ai vari commenti a questo blog, e ogni tanto me ne perdo qualcuno davvero interessante. In particolare, non avevo letto subito quello di Pasquale Esposito a un mio post di fine Aprile. In quel post parlavo di una mia DLL per VB6 e chiudevo chiedendo ai lettori VB6 quando si sarebbero decisi a passare a .NET. Pasquale ha risposto con un commento lungo e esauriente, di cui riporto qui i pezzi salienti:
Ci chiedi quand'è che ci decidiamo a migrare a VB.NET. Vedi, io sono rimasto profondamente deluso dal passaggio al byte code operato dalla Microsoft. Da circa dieci anni produco software shareware che distribuisco su Internet o nei CD allegati a riviste di informatica (ultima pubblicazione: Soluzione Bilancio 1.0 recensito a pag. 97 di PC Magazine di maggio 2006). Ho provato a tastare il terreno distribuendo qualche piccolo applicativo in .NET e mi sono subito reso conto che i tempi non sono affatto maturi per passare a questa tecnologia, almeno per chi utilizza la metodologia shareware come canale di distribuzione. Lo affermo per almeno due motivi:
1) Non è per niente facile chiedere ad un utente che non ha il Framework installato sulla propria macchina di scaricarlo da Internet solo per far funzionare la propria applicazione: per chi non ha una connessione ADSL sognificherebbe effettuare un download di qualche ora. Inoltre, anche chi ha installato il SP2 di WinXP, non è detto che abbia scelto di includere il Framework. Conclusione: molto probabilmente, l'utente in questione sceglierà di rinunciare all'applicativo in .NET e cercherà qualcos'altro di meno problematico. In poche parole, il "DLL Hell" di VB6 ha lasciato il posto al ".NET Framework Hell" di VB.NET.
2) Programmare in byte code significa produrre software estremamente vulnerabile, non solo dal punto di vista del cracking ma perfino da quello del reverse-engineering. Basta pochissima esperienza per entrare in possesso del codice sorgente altrui ed è necessario ricorrere a buoni obfuscator di terze parti per proteggere le proprie applicazioni. Questi strumenti non soltanto sono alquanto costosi ma molto spesso fanno uso di codice nativo (anziché di byte code), rendendo la piattaforma .NET non più autosufficiente. Conclusione: non ritengo che programmare in byte code sia conveniente per chi produce shareware. Al contrario, un applicativo in VB6 può essere crackato soltanto da esperti e in nessun caso è possibile ottenere i sorgenti. Il byte code, quindi, non è adatto a fini commerciali. Molti programmatori VB6 non lo hanno mai preso in considerazione, altrimenti sarebbero passati a Java già molto tempo fa.
.....
L'unico motivo che mi potrebbe far pensare alla migrazione a VB.NET è il timore che, dopo Windows Vista, Microsoft possa abbandonare strategicamente la tecnologia COM a 32 bit. Spero davvero che ciò non accada perché ciò significherebbe costringere la gente a buttare via tutto il software attualmente in commercio. Insomma, VB6 è senz'altro lo strumento che utilizzerò nei prossimi 4-5 anni dato che i runtime di base saranno ancora presenti in Windows Vista (lo stesso Microsoft Anti-Spyware è stato progettato in VB6), dopodiché potrò considerare l'ipotesi di effettuare la migrazione.
.....
La richiesta che vorrei rivolgerti è questa: VB6 non è morto. E non è neanche obsoleto. Molti programmatori si g uadagnano da vivere con VB6 e vorrebbero che tu ti occupassi ancora di questo strumento. Come hai reso il tuo MsgHookX nuovamente disponibile online, così dovresti fare con tutta la tua produzione che riguarda VB6. Anzi, dovresti creare ancora per l'ambiente VB6. Infine, se puoi, riferisci alla Microsoft che esiste ancora un esercito di programmatori VB6 che sarebbe pronto ad acquistare una nuova versione unmanaged del suo strumento di sviluppo. Dal punto di vista commerciale, sarebbe senz'altro una mossa vincente!
Io trovo che l’opinione di Pasquale sia fondata, nel senso che se io facessi il suo lavoro (vendere shareware) potrei avere dei problemi a passare armi e bagagli a .NET. Pero’ ci sono alcune considerazioni da fare.
*) Le dimensioni del runtime: La stesso problema se lo ponevano i programmatori shareware 10 anni fa, quando confrontavano il runtime di VB6 con i piccoli eseguibili scritti in C. Ma allora c'è da chiedersi: perchè gli shareware-isti che lavorano in VB hanno avuto spesso più successo di quelli che lavorano in altri linguaggi come C ? La risposta, a mio avviso, è che scrivere un programma in VB richiedeva una frazione del tempo necessario a scriverlo in C quindi a parità di impegno è possibile creare programmi più potenti e ricchi di funzioni. (solo il Delphi può competere con VB quanto a produttività ) Forse non altrettanto veloci di quelli scritti in C, ma sufficientemente veloci per la maggior parte dei compiti.
Rapportiamo questa esperienza ad oggi: i 20M circa del framework sono circa 15 volte più grandi del runtime di VB6, pero' è anche vero che ADSL è almeno 15 volte più veloce del dialup, quindi la proporzione regge. Anzi, se i vostri clienti hanno la fibra ottica, neanche se ne accorgono. Insomma, chi tanti anni fa ha fatto la scelta di passare a VB infischiandosene delle dimensioni del runtime ha avuto ragione. Secondo me, lo stesso accade a chi oggi decide di passare a VB.NET
Certo, non tutti gli utenti hanno la ADSL, ma il ragionamento che farei io se fossi un autore shareware è: quanto mi interessano davvero questi utenti? i clienti migliori per il software e per i servizi sono le aziende e il power-user, e quelli l'ADSL ce l'hanno sempre. Se qualcuno non ha i 20€ al mese per pagare la connettività, difficilmente pagherebbe per i miei programmi. Gli unici che non rientrano in questo mio ragionamento sono le aziende e gli utenti che spenderebbero volentieri questi soldi, ma purtroppo non sono serviti da ADSL. Pero' oggettivamente si tratta di casi che diventeranno sempre più rari, e penso che in 2-3 anni saranno impossibili da trovare. (A parte il fatto che uno si puo' collegare a internet anche con una scheda UMTS...)
Allora, la domanda da porsi è: se sono un autore di software (shareware o non), vale la pena davvero continuare ad usare uno strumento che era eccezionale 10 anni fa ma adesso è decisamente superato? In questi anni io credo di avere dimostrato di saper fare davvero di tutto con il "vecchio Visual Basic", eppure oggi quando devo tornare a scrivere codice con VB6 mi sento un impedito. Non si tratta solo del linguaggio, ma anche dell'IDE e degli strumenti a corredo. Dopo pochi mesi con il VB.NET ero già molto più produttivo che in VB6 (che avevo usato per 10 anni). Oggi che conosco bene il .NET Framework credo di essere, mediamente, almeno tre volte più veloce. Ovvero scrivo un programma in un terzo del tempo che ci mettevo prima. Io vendo programmi principalmente ad aziende, ma anche se facessi shareware mi porre la stessa domanda: vale la pena rinunciare a questa enorme produttività per raggiungere qualche utente in più, che probabilmente non comprerebbe comunque il mio software?
*) Anche se il .NET Framework è ben pesante, non è strettamente necessario distribuirlo tutto con le proprie applicazioni. In teoria una applicazione WinForm ha bisogno di circa un terzo dell'intero framework. Anche se non mi sono mai interessato più di tanto alla questione, ho letto che ci sono dei programmi che sono in grado di comprire un eseguibile .NET e tutte e sole le librerie che utilizza , senza cioè richiedere una installazione completa del framework. Se le dimensioni del runtime fossero davvero un problema, proverei a fare qualche ricerca più approfondita su questi prodotti.
*) come lo stesso Pasquale fa notare, lo shareware si puo' diffondere anche con mezzi che non siano Internet, ad es. sui CD allegati alle riviste. Pero' è un dato di fatto che ci sono sempre meno riviste che allegano i CD, proprio perchè la maggior parte degli utenti ha una linea veloce e preferisce scaricare dalla Rete per essere sicuri di avere la versione più recente. Ad esempio, Microsoft Press, Mondadori e altri publisher importanti non allegano più i CD ai propri libri (a meno che il contenuto non superi i 30-40M) e loro prendono queste decisioni solo dopo analisi di mercato fatte per bene.
*) se fossi un programmatore VB6, a rendere ancora più semplice e più netta la mia decisione di passare a .NET c'è la considerazione che tutto quello che scrivo oggi con VB6 dovrà forzatamente essere buttato via tra qualche anno, vuoi perchè Microsoft non supporterà più VB, vuoi perchè i programmi e i controlli ActiveX potrebbero non funzionare bene con le prossime versioni di Windows. E' giusto fare pressione su Microsoft per evitare che cio' avvenga, ma le probabilità di fare rimangiare le loro decisioni sono prossime allo zero. Quindi è un piccolo "suicidio professionale" puntare tutto su questa speranza e nel frattempo fare finta che il mondo sia quello di dieci anni fa. Se consigliassi a qualcuno di continuare a scrivere codice VB6 sarei un vero incosciente.
*) Il discorso sul byte code: E' innegabile che un programma che possa essere decompilato facilmente pone dei seri problemi. Purtroppo .NET non offre una netta risposta a questo problema, ma solo mezze soluzioni (tipo installare sul server come servizio o sito asp.net). Quando Microsoft lanciò le prime beta di .NET cinque anni fa, questo aspetto mi sembrava davvero fondamentale, in grado addirittura di rallentare la diffusione del nuovo linguaggio.
Le cose sono andate diversamente, per fortuna. C'è da tenere presente che il problema del reverse-engineering è molto sentito da tutti i programmatori, non solo quelli che vendono shareware. Se uno mette sul mercato uno shareware e qualcuno ne fa il reverse engineering, è molto facile dimostrare che il nuovo programma è un clone. Basta decompilarli entrambi e mostrare a tutto il mondo il risultato, sottolineando che il proprio programma è stato messo sul mercato prima del clone. Certo non è efficace quanto una azione legale (che pure è possibile, ma costosa) ma nel mondo di Internet è sufficiente per perdere la reputazione. Certo, uno puo' fare il reverse engineering e poi modificare il codice, ma è facile mettere delle "trappole" in giro per il sorgente, ossia delle istruzioni che non fanno nulla e che chi ha clonato il programma non saprebbe giustificare. Per togliere queste trappole uno si deve studiare meglio tutto il sorgente, ma allora il lavoro del copiatore si complica.
A parte queste considerazioni, c'è da sottolineare il fatto che questo problema è sempre esistito nel mondo dello sviluppo software. Molti linguaggi che in passato hanno avuto successo erano dei byte-code decompilabili: ad esempio dBASE, il Clipper (spacciato come compilatore), Java, e lo stesso Visual Basic fino alla versione 4.0. E anche se il linguaggio era compilato, resta il fatto che i tracciati dei record e le tabelle dei database - ovvero un aspetto fondamentale delle applicazioni gestionali - sono sempre stati visibili e interpretabili. Se vuoi capire come funziona un gestionale, la prima cosa da fare è vedere come sono strutturate le sue tabelle del DB.
Insomma, non sto dicendo che il problema non esiste: sto dicendo che è meno serio di quello che molti programmatori credono.
Termino il post rispondendo direttamente a Pasquale: hai ragione a dire che VB6 non è morto. Ci sono moltissimi programmatori che ancora lo usano e il mio libro su VB6 continua a vendere abbastanza bene, addirittura meglio di alcuni libri su VB.NET (non dei miei libri su VB.NET, per fortuna! )
Pero' hai (molto) torto a dire che NON è obsoleto. Non si tratta di "rinnegare" il passato e soprattutto non dobbiamo parlare di VB come di un cagnolino a cui ci siamo affezionati, che non si vuole rottamare per ragioni sentimentali (ho letto anche interventi di questo tenore sui vari forum....). Quando è nato era eccezionale e per anni io ho campato (e bene!) con questo prodotto, ma se lo confronti con VB.NET (e con l'IDE di Visual Studio 2005) ti accorgi che il Visual Basic 6 è davvero morto e sepolto.
Ecco perchè non ho firmato alcuna petizione pro-VB6 e perchè sto facendo di tutto per convincere gli sviluppatori VB6 a passare il prima possibile a .NET: quando cominci a lavorare con la programmazione ad oggetti "vera", con gli attributi e reflection, i controlli di Windows Forms, le applicazioni ASP.NET e tutto il resto, il Visual Basic 6 ti sembra tanto ma tanto lontano.
NOTA: anche se non sviluppo più sotto VB6, forse cercando sul mio disco rigido troverei qualche cosa interessante che non ho ancora pubblicato. In tal caso sarà un piacere metterla a disposizione di tutti su questo sito. L'ho fatto per anni e posso continuare a farlo anche ora...
di Francesco Balena
Come preannunciavo qualche tempo fa, Code Architects sta partecipando al Progetto SAMP, ovvero Stage @ Microsoft Partner. In pratica, offriamo formazione a laurendi e neo-laureati di Scienze dell'Informazione dell'Università di Bari (e solo di Bari...) e li teniamo poi con noi per 4-6 mesi a lavorare su un progetto reale. E ci sono anche altre aziende del territorio che prenderanno altri stagisti. Lo scopo della iniziativa è davvero meritorio, in quanto si tratta di agevolare l'ingresso nel mondo del lavoro degli studenti e contemporaneamente dare alle aziende la possibilità di entrare in contatto con gli studenti più brillanti, che potranno poi essere assunti in pianta stabile.
Durante lo stage gli studenti lavoreranno a un progetto "reale". Non conosco quelle delle altre aziende coinvolte, ma gli stagisti che lavoreranno con noi ci daranno una mano a sviluppare un framework applicativo e un altro progetto che per il momento è top secret.
Il primo corso su C# e il .NET Framework - che come ho detto è riservato a laureandi e neo-laureati dell'Università di Bari - comincia il 26 giugno e verrà tenuto dal sottoscriitto. Se avete i requisiti e volete partecipare, mandate il prima possibile un vostro curriculum al seguente indirizzo email: jobs - chiocciola - codearchitects - punto - com (lo scrivo così per evitare un po' di spam), lasciando ovviamente un recapito email e telefonico. I tempi sono stretti e i posti sono limitati, quindi affrettatevi.
di Francesco BalenaPer anni gli americani ci hanno inflitto (e afflitto con) una serie infinita di programmi per il baseball, di cui sinceramente a noi italiani non ce ne potrebbe frega' de meno. Questa volta si fanno perdonare con una piccolo programmino per seguire la propria squadra del cuore durante il campionato del mondo. Non l'ho ancora installato, ma dalla descrizione si direbbe ben fatto, è localizzato in oltre una dozzina di lingue, può funzionare come RSS reader, e altre cosucce ancora. Lo potete scaricare da questa pagina.
di Francesco BalenaEcco delle informazioni sulla parte logistica del TechEd che hanno girato nel forum privato dei Regional Director. Ora abbiamo avuto il permesso "formale" di renderle pubbliche. Il tutto tradotto per quelli di voi che sono refrattari all'inglese non-tecnico.
1,250,000 pezzi di "Mikes & Ikes" saranno consumati durante la settimana del Tech Ed 2006 18,750 libbre di insalata saranno preparate e offerte 83,700 pezzi di gelato, frutta di stagione e barrette di yogurt sono state già ordinate 60,000 uova saranno consumate dagli iscritti durante la prima colazione (sono pari a 4,800 dozzine di cartoni di uova) Saranno necessari 4 camion con rimorchio per trasportare le 150,000 bottiglie d'acqua consumate durante la conferenza La quantità totale di frutta ordinata riempiranno 3/4 di un rimorchio di grandi dimensioni 1.6 milioni di once di caffe saranno versate e consumate (è una stima molto prudente) Più di 50,000 libbre di carboidrati saranno consumati durante il Tech*Ed (alla faccia della dieta Atkins, che predica il basso consumo di carboidrati) 1,500 tovaglie saranno apparecchiate e sparecchiate in ogni giorno (7,500 per l'intera settimana) Si prevede che durante l'evento saranno consumente non meno di 2,000 barrette digestive anti-acido.
MIca male, eh? 
di Francesco BalenaUPDATE: dopo aver messo online questo articolo ho modificato leggermente la libreria CAPermutations, e il link ora punta alla versione aggiornata. Tutto quanto scritto nel post originario resta valido, eccetto che i metodi in override restituiscono un enumerativo anzichè un booleano.
Nel primo e nel secondo post di questa serie ho introdotto la libreria CAPermutations e ho mostrato come sia in grado di risolvere alcuni problemi combinatori classici, tipo la generazione di anagrammi e il problema delle regine e amazzoni. In questo articolo mostrerò alcune altre feature molto interessanti di questa libreria e le userò per realizzare un semplice - ma potente e super-efficiente - programma per lo sviluppo di sistemi Totocalcio.
Prima di tutto un veloce ripasso. Come ho mostrato nei precedenti esempi, il costruttore della classe Permutations riceve in input i seguenti argomenti, tutti opzionali eccetto il primo: 1. l’array degli elementi da permutare 2. il numero di elementi che dovranno apparire nella permutazione 3. un enumerativo che indica se desideriamo listare le permutazioni o le combinazioni degli elementi 4. il numero massimo di occorrenze di ciascun elemento 5. l’indirizzo di un metodo di filtro
Ecco ad esempio il codice che permette di generare tutte le parole di cinque lettere e contenenti esclusivamente i caratteri A-G, dove ciascun carattere non può comparire più di due volte:
char [] elements = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' }; Permutations<char> perms = new Permutations<char>(elements, 5, PermutationKind.Permutations, 2); foreach ( char[] chars in perms ) Console.WriteLine( new string(chars));
In aggiunta ai dati che si passano al costruttore, è però possibile impostare numerosi altri campi della classe dopo averla istanziata. In particolare, la classe espone gli array MinOccurrences e MaxOccurrences, che permettono di impostare il numero minimo e massimo di occorrenze di ciascun elemento nel risultato finale. Per default, tutti gli elementi del vettore MinOccurrences sono impostati a zero e tutti gli elementi di MaxOccurrences sono uguali al valore del 4° argomento passato al costruttore – il che di fatto significa che non imponiamo alcun vincolo specifico al numero di occorrenze - ma dopo aver creato una istanza di Permutations è possibile modificare questi array per imporre delle condizioni particolari.
Ad esempio, possiamo affinare il codice precedente specificando che i caratteri ‘A’ e ‘E’ devono essere sempre presenti e anzi possono comparire fino a tre volte, mentre il carattere ‘B’ può comparire al massimo una volta:
char [] elements = { 'A', 'B', 'C', 'D', 'E', 'F', 'G' }; Permutations<char> perms = new Permutations<char>(elements, 5, PermutationKind.Permutations, 2);
perms.MinOccurrences[0] = 1; // 0 = index of char 'A' in the elements array
perms.MaxOccurrences[0] = 3; perms.MaxOccurrences[1] = 1; // 1 = index of char 'B' in the elements array
perms.MinOccurrences[4] = 1; // 4 = index of char 'E' in the elements array
perms.MaxOccurrences[4] = 3; foreach ( char[] chars in perms ) Console.WriteLine( new string(chars));
L’oggetto Permutation espone anche il vettore MaxConsecutiveOccurrences, che indica per ciascun elemento quante occorrenze consecutive possono trovarsi nel risultato. Quindi ad ad esempio possiamo scartare AABCD ma accettare ABACD usando questo codice:
// aggiungere a tutti i vincoli precedenti...
perms.MaxConsecutiveOccurrences = new int[] {1, 1, 1, 1, 1, 1, 1}; foreach ( char[] chars in perms ) Console.WriteLine( new string(chars));
A cosa può servire impostare il numero massimo di occorrenze consecutive? Ad esempio, se i caratteri A-G rappresentano altrettante città, l’output del codice precedente rappresente tutti i percorsi possibili che potete seguire per visitarne alcune di esse (massimo 5), ripassando se necessario fino a tre volte per A oppure E, oppure fino a due volte per tutte le altre città eccetto B. Visto che le permutazioni rappresentano un tratto di viaggio, occorre scartare le tratte che cominciano e terminano nella stessa città, cosa che si fa appunto impostando pari a 1 il valore di MaxConsecutiveOccurrences per tutti gli elementi.
Così formulato, l’esempio può sembrare poco realistico, ma nel settore dei problemi combinatoriali imporre un limite massimo alle occorrenze consecutive può essere molto utile. Ad esempio, nella stesura di un orario scolastico di solito si impone che un professore non possa occupare la stessa aula per più di due ore oppure che gli alunni di una determinata classe non possano occupare un laboratorio per più di un numero stabilito di ore. Vedremo anche tra un attimo che i vettori MinOccurrences, MaxOccurrences, e MaxConsecutiveOccurrences saranno molto utili nella preparazione di un programma per lo sviluppo dei sistemi di totocalcio.
Una feature molto potente della classe Permutations è la possibilità di indicare esattamente quali elementi si possono trovare in determinate posizioni del risultato. Tornando a considerare l’esempio precedente, potremmo voler imporre che il nostro viaggio tra le città A-G possa cominciare e terminare solo dalle città A, D e E, perchè sono le uniche che sono servite da un aereoporto. Una possibile soluzione al problema è di impostare un metodo di callback che scarta tutte le permutazioni che non soddisfano questa condizione, ma è molto più facile agire sul campo ValidIndices della classe Permutations. Questo campo è un vettore di vettori di tipo T (dove T è il tipo parametro della classe generica Permutations), quindi occorre modificare l’elemento con indice 0 (che contiene gli indici validi che può assumere l’elemento nella prima posizione del risultato) e l’elemento 4 (che contiene gli indici validi che può assumere il quinto e ultimo elemento del risultato).
// aggiungere a tutti i vincoli precedenti... // // indica che il primo e ultimo elemento della soluzione // deve essere scelto tra A,D,E, che nel vettore elements // si trovano agli indici 0,3,4
perms.ValidIndices[0] = new int[] { 0, 3, 4 }; perms.ValidIndices[4] = new int[] { 0, 3, 4 }; foreach ( char[] chars in perms ) Console.WriteLine( new string(chars));
Passiamo ora ad una applicazione pratica “seria”, benchè dedicata al gioco del Totocalcio. Attualmente il Totocalcio non è più un gioco molto popolare, ma quelli di voi con più di vent’anni si ricorderanno sicuramente la rivoluzione che il personal computer portò nel mondo degli scommettitori “professionali”. Improvvisamente era possibile impostare, sviluppare e ridurre un sistema di Totocalcio comodamente a casa propria, e magari stampare pure le schedine su una apposita stampante. Ricordo numerose software house che negli anni ’80 avevano a catalogo programmi di questo tipo, e per molti sviluppatori questo tipo di software ha rappresentato una grande fonte di reddito.
Certo, resta valida la ovvia considerazione che se un programmatore trovasse davvero la “sistema perfetto” per azzeccare il 13 (anzi il 14, visto che da qualche anno si gioca su 14 partite...) allora potrebbe fare molti più soldi giocando il sistema perfetto egli stesso, piuttosto che vendere il software. Ma questo è un dettaglio: quello che è importante in questa sede è che lo sviluppo di sistemi di Totocalcio (ma anche di altri giochi simili, come il Totip e il TotoGol) rappresenta un irresistibile banco di prova per chi si diletta di calcolo combinatorio.
La figura seguente mostra la videata principale (nonchè l’unica ) del programma per lo sviluppo di sistemi Totocalcio che potete scaricare in sorgente da questo link: SistemaTotocalcio.zip (55.56 KB). Il file contiene anche la nuova versione della libreria CAPermutations (che è stata finalmente arricchita dai commenti XML dei vari metodi e campi) e delle altre demo già mostrate dei post precedenti. Ricordo che la libreria è usabile liberamente nei propri programmi freeware e no-profit ma potete contattarmi se volete utilizzarla in altri contesti.
Un breve disclaimer prima di continuare: spero sia chiaro che la mia intenzione non è di creare un programma professionale per lo sviluppo di sistemi, anche perchè ce ne sono di ottimi in giro. Il mio unico obiettivo è di mostrare come risolvere il problema combinatorio legato a questo gioco utilizzando la libreria CAPermutations.

Come vedete, il programma permette di impostare il pronostico sulle 14 partite, e una serie di vincoli, tra cui il numero minimo, massimo e massimo consecutivo dei tre segni.
Lo scommettitore dovrebbe impostare i 14 pronostici indicando come primo simbolo (il simbolo principale) il risultato più probabile; come secondo simbolo un risultato prevedibile ma non quanto il simbolo principale; come terzo simbolo quello che lo scommettitore considera una vera e propria sorpresa. Agendo sui controlli nel gruppo “Varianti e sorprese” lo scommettitore può dosare in un certo senso il grado di “imprevedibilità” su cui vuole puntare. È evidente, ad esempio, che se impostando un valore alto come numero minimo di varianti o di sorprese, si ottiene di ridurre notevolmente il numero di colonne dello sviluppo (e quindi la probabilità di vincere) ma in compenso si punta ai risultati meno prevedibili e quindi che potenzialmente potrebbero dare una vincita più alta della media.
Vediamo ora una breve descrizione di come funziona il programma dietro le quinte. Lo sviluppo di un sistema di Totocalcio si riduce in un certo senso a creare tutte le permutazioni dei simboli 1, 2, e X. Per comodità, internamente il programma non permuta questi caratteri ma più semplicemente le cifre 0 (corrispondente al segno ’1’), 1 (corrispondente al ’2’) e 2 (corrispondente al simbolo ’X). Il programma non deve creare davvero tutte le permutazioni delle triple ‘12X’, ma solo le permutazioni che rispondono ai pronostici delle partite, cosa che il codice fa assegnando valori adeguati agli elementi del vettore ValidIndices. Ad esempio, per specificare che per la quarta partita i simboli validi sono sono 1 e X (vedi figura) il codice esegue qualcosa del genere:
perms.ValidIndices[3] = new int[] { 0, 2 };
mentre per la quinta partita (il cui pronostico è ‘1X2’) il codice è il seguente:
perms.ValidIndices[3] = new int[] { 0, 2, 1 };
(notate quindi che è anche possibile impostare sequenze di indici non crescenti).
Grazie alla presenza dei campi ValidIndices, MinOccurrences, MaxOccurrences, e MaxConsecutiveOccurrences, la maggior parte dei vincoli legati allo sviluppo del sistema sono di fatto implementati dalla classe Permutations. Gli unici vincoli che la classe base non risolve sono quello sul numero minimo e massimo di segni principali, varianti, e sorprese, ma anche questi vincoli si implementano facilmente.
Infatti, la classe Permutations espone il vettore Indices, che per ciascuna partita indica la posizione in ValidIndices del simbolo inserito nella soluzione. Quindi contare quante varianti sono presenti nella soluzione corrente significa contare – nel metodo di filtro - quanti elementi pari a 1 sono presenti nel vettore Indices. E contare quante sorprese vi sono corrisponde a contare gli elementi del vettore pari a 2.
Se a questo punto non riuscite più a seguire la mia descrizione non vi preoccupate: il problema non è affatto banale e la cosa migliore da fare è studiare il sorgente della classe SistemaTotocalcio. Questa classe eredita da Permutations<int> e aggiunge un paio di vettori che conservano il valore minimo e massimo di segni principali, varianti e sorprese:
public class SistemaTotocalcio : Permutations<int>
{ const int NumPartite = 14; // valori usati per il filtro del sistema public int[] MinVarianti = new int[3]; public int[] MaxVarianti = new int[3];
// questo è il numero di varianti (privato, perchè usato solo dal filtro) // varianti[0] sono le principali, varianti[1] le varianti, varianti[2] le sorprese private int[] Varianti = new int[3];
// il costruttore non ha argomenti public SistemaTotocalcio() : base( new int[] { 0, 1, 2}, NumPartite, PermutationKind.Permutations, NumPartite) { // imposta il valore max di varianti (modificabile in seguito dal client) for ( int i = 0; i <= 2; i++ ) this.MaxVarianti[i] = NumPartite;
// tutti gli altri array sono correttamente inizializzati }
// ... (continua)....
Quando parte il computo delle permutazioni – ovvero delle colonne generate dallo sviluppo del sistema – occorre inizializzare il vettore Varianti, che viene usato poi dal filtro. Questo si ottiene facendo l’override del metodo OnInitialize, che è chiamato al momento opportuno dalla classe Permutations. Questo metodo deve restituire PermutationResult.Proceed se i dati in input sono OK, oppure PermutationResult.Cancel se vi è un problema e l'enumerazione non deve neanche partire:
// override del metodo per validare i dati e // inizializzare i valori usati dal filtro
protected override PermutationResult OnInitialize()
{ // inizializza l'array Varianti e indica che si può proseguire this.Varianti = new int[3]; return PermutationResult.Proceed
}
Poichè la classe SistemaTotocalcio eredita da Permutations, per filtrare le permutazioni man mano che vengono generate non si usa un metodo di callback, ma si deve fare l’override del metodo protetto OnNewPermutation. Come ho spiegato sopra, il controllo sul numero minimo, massimo e massimo consecutivo dei segni lo fa la classe base Permutations, quindi nel filtro dobbiamo solo controllare il valore minimo e massimo dei segni principali, delle varianti e delle sorprese.
// il filtro, sotto forma di override
protected override PermutationResult OnNewPermutation(int[] colonna, int partita) { // questo è l'indice usato per questa partita (0=princ, 1=variante, 2=sorpresa) int index = base.Indices[partita]; // esci se vi sono già troppe varianti di questo tipo if ( Varianti[index] >= MaxVarianti[index] ) return PermutationResult.Backtrack;
// aggiornal il contatore delle varianti di questo tipo Varianti[index]++; // restituisci false se il numero di varianti è minore del minimo // e non potrebbe diventare mai pari o maggiore del // minimo perchè non ci sono sufficienti partite da analizzare int rimaste = 13 - partita; if ( Varianti[0] + rimaste < MinVarianti[0] || Varianti[1] + rimaste < MinVarianti[1] || Varianti[2] + rimaste < MinVarianti[2] ) { // ripristina il valore precedente prima di restituire false Varianti[index]--; return PermutationResult.Backtrack; }
// restituisci di procedere se tutti i vincoli sono soddisfatti return PermutationResult.Proceed; }
Ricordo che il filtro viene chiamato ogni volta che la classe base prova a mettere un simbolo per la partita N-esima nel risultato (ossia nel vettore colonna), scegliendolo però tra i simboli validi specificati in ValidIndices[partita]. Invece di ricalcolare il numero di segni principali, varianti e sorprese ad ogni chiamata del metodo OnNewPermutations, la classe SistemaTotocalcio tiene traccia di questi valori nel vettore Varianti, dove Varianti[0] è il numero dei segni principali, Varianti[1] delle varianti, e Varianti[2] delle soprese.
Per mantenere sempre aggiornato questo vettore è necessario che i suoi elementi siano aggiornato in fase di backtracking, ovvero quando la classe base “toglie” un simbolo sistemato precedentemente. La classe SistemaTotocalcio implementa il backtracking facendo l’override del metodo protetto OnBacktrack:
// backtracking protected override PermutationResult OnBacktrack(int[] colonna, int partita) { // questo è l'indice usato per questa partita (0=princ, 1=variante, 2=sorpresa) int index = base.Indices[partita]; // ripristina il contatori di Varianti ed esci Varianti[index]--; return PermutationResult.Backtrack; } } // fine della classe SistemaTotocalcio
In definitiva, grazie alla classe Permutations è stato possibile risolvere un problema combinatorio davvero complesso con appena una ventina di istruzioni eseguibili!
La cosa a mio avviso davvero notevole è che, nonostante il fatto che la classe Permutations sia molto generica e sia in grado di risolvere problemi combinatori anche molto differenti tra loro, le prestazioni che si ottengono sono eccezionali. Sul mio desktop, un Pentium D a 2.80GHz, le 4.782.969 colonne di un sistema integrale di 14 triple senza alcun vincolo viene sviluppato interamente in meno di un secondo! Ed ovviamente, più vincoli imponiamo più veloce è lo sviluppo, perchè l'albero delle permutazioni viene "potato" prima di arrivare ad analizzare la 14-esima colonna. La figura mostra ad esempio un sistema 6 triple e 6 doppie con qualche vincolo che sviluppa 701 colonne in soli 2 millisecondi!
Nei fatti il programma è così veloce che una opzione del menu Sistema permette di attivare il ricalcolo automatico, un po’ come in Excel: ogni volta che modificate un pronostico o un vincolo, il programma è in grado di ricalcolare il sistema che ne risulta, ed eventualmente mostrarne le prime N colonne. Se avete un computer veloce non vi accorgerete neanche del ritardo.
Il mio primo programma per lo sviluppo dei sistema era scritto in assembly Z80, girava su Sinclair ZX Spectrum e generava circa 700 colonne al secondo. E ci vollero un paio di settimane, per il debug e il fine tuning, per arrivare a quel risultato che per i tempi era di tutto rispetto.
Al confronto, questa versione è implementata in un linguaggio di alto livello, ha richiesto mezz'ora per l'algoritmo vero e proprio (è stato più faticoso creare l'interfaccia utente) eppure è oltre settemila volte più veloce. Certo, un Pentium D non si può paragonare a uno Z80, ma un parte del merito è proprio nelle tecniche di potatura che ho affinato in questi anni e che ho cablato nella classe Permutations.
di Francesco BalenaSe vi interessa vedere (o far vedere ai vostri clienti) cosa i cattivi hacker possono fare con la sql injection insieme al disassembly dei programmi .NET, date una occhiata a questo video: http://www.rockyh.net/AssemblyHijacking/AssemblyHijacking.html. E dopo esservi un po' spaventati (e aver fatto spaventare i vostri clienti) ricordatevi sempre non solo di usare oggetti Command parametrici (che riducono praticamente a zero i rischi di injection), di ridurre i privilegi sotto cui gira l'applicazione asp.net, ma anche di marcare sempre con strong name tutti i vostri assembly, incluso quelli che - apparentemente - gireranno solo e soltanto sulla vostra macchina.
di Francesco BalenaUPDATE: dopo aver messo online questo articolo ho modificato leggermente la libreria CAPermutations, e il link ora punta alla versione aggiornata. Tutto quanto scritto nel post originario resta valido, eccetto che il metodo di callback restituisce un enumerativo anzichè un booleano.
Nel mio precedente post ho introdotto la nuova libreria CAPermutations, a cui sto lavorando nel tempo libero. In questi giorni ho potenziato la libreria e modificato leggermente la sintassi del costruttore. Nel post originale trovate una piccola nota sulle differenze rispetto alla versione originale.
In questo articolo descriverò invece la feature più potente della libreria CAPermutations, ovvero la possibilità di impostare dei criteri di selezione delle varie permutazioni. In pratica, è possibile fornire alla libreria l'indirizzo di un metodo di callback: questo metodo viene chiamato mentre viene generata una nuova permutazione, e quindi il programma client ha la possibilità di scartare le permutazioni che non interessano. La cosa interessante è che la routine di callback viene chiamata non soltanto quando la permutazione è stata completata, ma anche durante le fasi intermedie. Supponiamo ad esempio di voler calcolare le permutazioni dei numeri 1-9 ma con la condizione che il numero N non si trovi in posizione N-esima. Ovviamente possiamo generare le 9! permutazioni dei numeri in questione e poi scartare quelli che non soddisfano la condizione, ma il metodo di callback permette di accellerare notevolmente i tempi di elaborazione: infatti non ha senso provare per poi scartare i milioni di permutazioni che presentano la cifra 1 al primo posto, ma è molto più efficiente dire "non farlo!" nel momento il cui la classe Permutations prova a generare la prima permutazione errata, dicendole in pratica di saltare tutte le permutazioni di quel tipo.
Ecco un programma Visual Basic che risolve il problema delle permutazioni di questo tipo:
Sub GeneratePermutations() ' generate permutations of digits 1-5 Dim elements() As Integer = {1, 2, 3, 4, 5} Dim permutations As New Permutations(Of Integer)(elements, 5, PermutationKind.Permutations, 1, AddressOf PermutationFilter) For Each perm() As Integer In permutations Dim sb As New System.Text.StringBuilder For Each n As Integer In perm sb.Append(n) Next Console.WriteLine(sb.ToString) Next End Sub
Private Function PermutationFilter(ByVal permutation() As Integer, ByVal level As Integer, ByVal backtracking As Boolean) As PermutationResult ' this is the element just added Dim number As Integer = permutation(level) ' backtrack if the element is equal to its position If number <> (level + 1) Then Return PermutationResult.Proceed Else Return PermutationResult.Backtrack End Function
La procedura di callback, detta anche procedura di filtro, accetta tre argomenti e restituisce un enumerativo PermutationResult. Il primo argomento è il vettore che rappresenta la permutazione che è stata costruita fino a quel momento; il secondo argomento rappresenta il livello di costruzione della permutazione, ovvero l'indice zero-based dell'elemento che è stato appena aggiunto prima di chiamare il metodo di callback. Il terzo argomento è False se la permutazione è stata costruita, True se siamo in fase di backtrack (vedi dopo). Il metodo deve restituire il valore PermutationResult.Proceed se la permutazione può essere accettata, PermutationResult.Backtrack se deve essere scartata. Vi sono altri possibili valori di ritorno, ma li vedremo meglio in altri articoli di questa serie.
La possibilità di effettuare backtracking, ovvero di tornare indietro sui suoi passi se il metodo di callback restituisce PermutationResult.Backtrack, aumenta enormemente il potenziale della libreria e le permette di risolvere problemi combinatoriali molto complessi. Ecco ad esempio una classe che risolve il famoso problema delle regine, ovvero come sistemare N regine su una scacchiera N*N in modo che non si diano scacco a vicenda. Si tratta di un classico problema combinatorio su cui, prima dell'avvento dei computer, si sono arrovellati dei geni come Gauss e altri famosi matematici. Per una introduzione molto sintetica al problema, date una occhiata a questa pagina oppure googlate per "queens' problem" (virgolette incluse).
Questo problema corrisponde a trovare una permutazione dei numeri 1-N, dove ogni elemento P(n) della permutazione rappresenta la colonna in cui posizionare la regina della riga N. Il solo fatto di richiedere permutazioni delle cifre 1-N (dove ogni elemento della permutazioni può apparire una sola volta) assicura che le regine si trovino su colonne oltre che su righe separate. Di fatto quindi, il metodo di callback deve soltanto tenere traccia di quali diagonali (principali e secondarie, ovvero quelle in direzione NO-SE e quelle in direzione NE-SO) sono occupate dalle regine poste sulla scacchiera fino a quel momento. Ecco il codice C# di una classe che calcola tutte le soluzioni del problema, con N qualsiasi:
using System; using System.Collections; using System.Collections.Generic;
namespace CodeArchitects { public class Queens : IEnumerable { // input fields public readonly int Side; // fields used by the filter method bool[] mainDiags; bool[] secDiags;
// the constructor
public Queens(int side) { this.Side = side; }
// the enumerator method delegates to the enumerator of the Permutations class
public IEnumerator GetEnumerator() { Permutations<int> permutations = CreatePermutationObject(); return permutations.GetEnumerator(); }
// helper method that initializes and returns a Permutations object to be used for enumerating squares
private Permutations<int> CreatePermutationObject() { // init the permutation vector with numbers in the range 1-N int[] numbers = new int[Side]; for ( int i = 0; i < Side; i++ ) numbers[i] = i; // init the fields used by the filter method mainDiags = new bool[Side * 2 + 1]; secDiags = new bool[Side * 2 + 1]; // create and return the Permutations object return new Permutations<int>(numbers, Side, PermutationKind.Permutations, 1, Filter); }
// the filter method is invoked when a new queen is added to or removed from the chessboard
PermutationResult Filter(int[] columns, int row, bool backtracking) { // this is the column of the queen just added at row int col = columns[row]; // these are the diagonals used by this queen int mainDiag = row - col + Side; int secDiag = row + col; // if backtracking, updates values and return if ( backtracking ) { mainDiags[mainDiag] = false; secDiags[secDiag] = false; return PermutationResult.Backtrack; }
// check whether the diagonals are already taken by another queen if ( mainDiags[mainDiag] || secDiags[secDiag] ) return PermutationResult.Backtrack;
// ( ... add here code for the amazons' problem)
// if we get here, mark the diagonals as "taken" mainDiags[mainDiag] = true; secDiags[secDiag] = true; // signal that new permutation is ok return PermutationResult.Proceed; } } }
Poichè la procedura di filtro deve gestire gli array di booleani mainDiags e secDiags (che contengono true se la diagonale corrispondente è stata già occupata), la stessa routine deve anche rimettere i valori a false quando - in fase di backtracking - la regina viene rimossa da quella posizione per tentare un'altra strada. Ecco allora che si spiegano le seguenti istruzioni :
// if backtracking, updates values and return if ( backtracking ) { mainDiags[mainDiag] = false; secDiags[secDiag] = false; return PermutationResult.Backtrack; }
Con qualche piccola aggiunta alla procedura di callback è anche possibile risolvere il problema delle amazzoni (o delle super-regine) dove una amazzone è una regina con super-poteri che è anche in grado di muoversi come un cavallo. Queste sono le sole righe che occorre aggiungere nel punto segnato da un commento nel listato della classe:
// additional tests for the amazons' problem if ( Kind == ProblemKind.Amazons ) { // check the cells in previous row if ( row > 0 && ( columns[row - 1] == col - 2 || columns[row - 1] == col + 2 ) ) return PermutationResult.Backtrack; // check cells two rows above if ( row > 1 && ( columns[row - 2] == col - 1 || columns[row - 2] == col + 1 ) ) return PermutationResult.Backtrack; }
Ho preparato un programma che permette di risolvere il problema delle regine e delle amazzoni con N compreso tra 4 e 20. In aggiunta alle feature appena descritte, il programma è anche in grado di scartare le riflessioni e le rotazioni, per ottenere quelle che si definiscono le soluzioni base del problema. Grazie alla classe Permutations, con una manciata di istruzioni è stato possibile risolvere un problema combinatorio davvero complesso. E il tutto in modo super-efficiente: sul mio computer il problema delle regine di ordine 12 è risolto in circa 1.5 secondi, per trovare tutte le 1787 soluzioni base.
Questo è il link al sorgente del programma delle regine e amazzoni, che contiene anche la versione aggiornata della libreria CAPermutations e del programma per generare anagrammi: QueensProblem.zip (37.25 KB) 
di Francesco BalenaUPDATE: dopo aver messo online questo articolo ho modificato leggermente la libreria CAPermutations, e il link ora punta alla versione aggiornata. Tutto quanto scritto nel post originario resta valido, eccetto che il terzo argomento da passare al costruttore è ora un enumerativo anzichè un booleano.
Da quando ho potuto mettere le mani su un computer sono sempre stato affascinato dai problemi combinatoriali. In prima approssimazione, un problema combinatoriale prevede la scelta di una (o più) permutazioni o combinazioni di N elementi in modo da soddisfare alcuni vincoli. E' facile intuire che molti problemi si risolvono solo grazie a tecniche combinatoriali:
- La generazione di tutti gli anagrammi di una parola richiede la generazione di tutte le permutazioni possibili dei suoi caratteri, per poi scegliere tra le parole ottenute quelle di senso compiuto
- Un programma per generare sistemi di Totocalcio, Lotto, Totip e simili richiedono la generazione di tutte le colonne possibili, da cui vengono poi scelte quelle che soddisfano alcuni requisiti (tipo numero minimo e massimo di segni, ecc.)
- Un programma per determinare l'orario scolastico, oppure più in generale, per stabilire turni di lavoro richiede di generare tutte le possibili assegnazioni (persona,turno) per poi scegliere quelle che soddisfano i vincoli impostati dall'utente
- Molti problemi matematici si basano sulla generazione di tutte le possibili permutazioni o combinazioni di N elementi, ad esempio la generazione degli quadrati magici di ordine N oppure la risoluzione del famoso problema delle regine (ovvero: come sistemare N regine su una scacchiera N*N in modo che nessuna dia scacco ad un'altra)
- Lo stesso vale per molti giochi di tipo enigmistico, come ad esempio il Sodoku oppure le parole crociate.
- Il problema dello zaino: abbiamo N oggetti di peso o ingombro differenti da trasportare in uno zaino che ha una capacità (come peso o volume) massima pari a un certo valore: quali oggetti scegliere in modo che la capacità dello zaino sia sfruttata al massimo, in modo cioè che la somma dei volumi o dei pesi degli oggetti scelti sia la più vicina possibile (ma non superiore) alla capacità dello zaino? Se pensate che invece di uno zaino avete a che fare con un container, vedete che il problema ha delle implicazioni pratiche non indifferenti
- Il modo migliore per tagliare sagome bidimensionali da una superficie piana si determina provando i diversi modi di combinare le varie sagome in modo da minimizzare il materiale non utilizzato (si pensi ad esempio al problema di tagliare in modo ottimale le pelli di una sedia o un divano a partire dal pellame a disposizione ed evitando i punti in cui il pellame non è utilizzabile o presenta imperfezioni)
- Il percorso ottimale per andare dalla località A alla località B in trenoo aereo può essere risolto combinando i vari percorsi intermedi, in modo da ridurre la distanza complessiva, il costo complessivo dei biglietti, il numero delle coincidenze aeree o ferroviarie, oppure ancora il tempo speso aspettando tali coincidenze. (Pensate ad esempio a come prenotate un viaggio con Expedia.)
- La generazione di permutazioni e combinazioni è anche alla base di numerose tecniche di "attacco" per scardinare alcuni sistemi di sicurezza. Ad esempio, i programmi che tentano di trovare le password per un sito funzionano combinando le parole in un dizionario che contiene le parole e nomi propri più comuni.
Potrei continuare con altri esempi, ma credo che sia chiaro il fatto che le tecniche combinatorie possono essere utili in moltissimi casi. Per saperne di più, non dovete fare altro che gogglare un po' su termini come "permutations" o "combinations" e scoprirete un sacco di cose interessanti. (La ricerca per "permutations" restituisce circa 10 milioni di hit, quella per "combinations" oltre 137 milioni!).
In questi anni ho scritto numerosi programmi che richiedevano la generazione di permutazioni o combinazioni di elementi simili. Forse il primo programma di questo tipo è stato un generatore di sistemi per il totocalcio che girava su Sinclair Spectrum. Uno dei più recenti è stato il Sodoku Solver che risolve automaticamente gli schemi di Sodoku più complessi in qualche frazione di secondo, direttamente dal vostro broswer. Nei vent'anni intercorsi tra questi due programmi, ho usato tecniche combinatoriali per ottimizzare la soluzione di alcuni problemi come quelli citati sopra.
Una delle cose più intriganti di un problema combinatoriale è il fatto che anche problemi abbastanza semplici richiedono spesso soluzioni complesse dal punto di vista computazionale, e soprattutto richiedono tanto tempo di CPU a meno di non ottimizzare al meglio l'algoritmo. Le possibili permutazioni di 10 oggetti distinti è pari al fattoriale di 10, ovvero 1*2*3*4*5*6*7*8*9*10 = 3.628.800. Disporre i numeri 1-16 su una griglia 4x4 per vedere quali combinazioni generano un quadrato magico (ossia un quadrato in cui la somma lungo le righe, colonne, e diagonali è costante) richiede l'analisi di 20mila miliardi di posizioni, e cosi' via. Per riuscire a risolvere questi problemi in tempi accettabili si richiede spesso di ottimizzare il codice al massimo e di trovare delle tecniche di "potatura" in modo da poter scartare interi gruppi di soluzioni prima di doverle analizzare una a una. Anche in questo modo, la risoluzione di un quadrato magico di ordine 5 può richiedere alcuni giorni anche sulle CPU più performanti. Per avere una idea di quante varianti vi siano per questi problemi combinatoriali, date una occhiata al sito The Combinatorial Object Server.
Ogni problema combinatoriale è una storia a sè stante, nel senso che il codice per trovare le soluzioni di uno schema di Sodoku è molto diverso dal codice per generare l'orario scolastico ottimale o per trovare il tragitto aereo migliore. D'altra parte, queste applicazioni hanno anche molti tratti in comune. In particolare, la parte che genera le varie permutazioni o combinazioni di elementi è spesso simile. Non uguale, ma simile. Quello che cambia in ciascun caso sono le routine che controllano se una combinazione è valida o meno, oppure le funzioni che procedono alla "potatura" degli alberi delle soluzioni. Alla fine ho pensato: perchè non estrapolare l'algoritmo di generazione delle combinazioni in modo da poterlo riutilizzare in occasioni differenti? Il risultato è la libreria CAPermutations, ovvero l'oggetto di questo articolo e di alcuni altri post che seguiranno.
La libreria in questione contiene solo una classe, Permutations, che però già in questa prima versione è in grado di risolvere la maggior parte dei problemi citati in precedenza. Per i problemi non particolarmente complessi, utilizzare questa libreria è davvero semplice: si crea una istanza della classe e si passa al costruttore un vettore contenente tutti gli elementi da permutare, poi si entra in un ciclo For Each che permette di enumerare tutte le possibili permutazioni. La classe Permutations usa i generics, in modo da accettare e restituire un array tipizzato contenente gli elementi che devono essere (o che sono stati) combinati:
' generate all the permutation of the characters A,B,C,D Dim elements() As Char = {"A"c, "B"c, "C"c, "D"c} Dim perms As New Permutations(Of Char)(elements) For Each chars() As Char In perms ' create and display the string obtained by concatenating the characters in the result Console.Write(New String(chars) & ", ") Next
Il codice C# è altrettanto semplice:
// generate all the permutation of the characters A,B,C,D char elements[] = {"A"c, "B"c, "C"c, "D"c}; Permutations<Char> permutations = New Permutations<Char>(elements); foreach ( char[] chars in perms ) { // create and display the string obtained by concatenating the characters in the result Console.Write(new string(chars) + ", "); }
Ecco il risultato che appare nella finestra di console, ovvero tutte le possibili permutazioni degli N elementi forniti in input:
ABCD, ABDC, ACBD, ACDB, ADBC, ADCB, BACD, BADC, BCAD, BCDA, BDAC, BDCA, CABD, CADB, CBAD, CBDA, CDAB, CDBA, DABC, DACB, DBAC, DBCA, DCAB, DCBA,
Invece di un loop For Each potete anche usare il metodo GetAllPermutations, che restituisce in un colpo solo tutte le pemutazioni. Poichè ogni permutazione è un vettore di tipo T (dove T è definito al momento di istanziare la classe generica Permutations), allora il risultato di questo metodo è un jagged array di tipo T, ovvero un vettore dove ciascun elemento è a sua volta un vettore di tipo T.
' VB Dim results()() As Char = perms.GetAllPermutations()
// C# char[][] results = perms.GetAllPermutations();
La classe Permutations è anche in grado di determinare le permutazioni di un gruppo di K elementi presi dall'insieme di N elementi forniti in input, con K <= N . Per ottenere tali permutazioni basta passare al costruttore un secondo argomento, pari al numero K di elementi che devono apparire nel risultato:
' generate all the permutation of two characters chosen from the charaters A,B,C,D Dim elements() As Char = {"A"c, "B"c, "C"c, "D"c} Dim perms As New Permutations(Of Char)(elements, 2) ' .... for each loop as before
Ecco il risultato generato dal ciclo:
AB, AC, AD, BA, BC, BD, CA, CB, CD, DA, DB, DC,
La classe Permutations permette di risolvere una numerosa classe di problemi combinatori e statistici. Ad esempio, se A,B,C,D rappresentano 4 città, l'insieme delle permutazioni rappresentano tutti i possibili percorsi che uniscono le città e che non ripassano mai da una città: un programma può facilmente analizzare questi percorsi per trovare quello che richiede meno tempo o ha un costo minore. Se invece gli elementi rappresentano possibili azioni - ad esempio, l'azione di sistemare una pedina su una determinata casella delle scacchiera - allora l'insieme delle permutazioni permette di stabilire quale sequenza di azioni tra quelle possibili permettono di ottenere il risultato migliore (ad esempio, vincere una partita di tris). E' importante notare che il risultato non conterrà due elementi uguali, il che è corretto perchè non vogliamo visitare due volte la stessa città e non possiamo sistemare due pedine nella stessa casella.
La classe Permutations permette anche di generare le combinazioni di K oggetti presi da un universo di N oggetti, come al solito con K <= N. L'unica differenza tra permutazioni e combinazioni è che con queste ultime l'ordine è ininfluente, quindi ad esempio la soluzione ABC è considerata equivalente a ACB, BAC, BCA, CAB, e CBA perchè quello che conta sono gli elementi che compaiono nel risultato e non il loro ordine. Le combinazioni permettono di risolvere tipi di problemi differenti da quelli visti finora. Per esempio, le combinazioni degli elementi {Giuseppe,Francesco,Marco,Piero,Gianni,MariaTeresa} con K=2 potrebbero servire per generare il calendario della prima serie di partite di un torneo di tennis a cui partecipano sei membri del team di Code Architects, in modo che ciascuna persona si batta una volta contro tutte le altre. In questo caso occorre usare le combinazioni perchè non occorre disputare la partita Francesco-Giuseppe se si è già giocata la partita Giuseppe-Francesco. (In altre parole, l'ordine degli elementi è ininfluente.)
Per generare combinazioni anzichè permutazioni, è sufficiente passare un valore enumerativo PermutationKind come terzo argomento al costruttore della classe Permutations. Ecco ad esempio come generare le partite del torneo:
Dim elements() As String = {"Giuseppe", "Francesco", "Marco", "Piero", "Gianni", "MariaTeresa"} Dim perms As New Permutations(Of String)(elements, 2, PermutationKind.Combinatio ) ' anzichè PermutationKind.Permutations For Each elem() As String In perms ' each element in the result is an array with two elements Console.WriteLine("{0} - {1}", elem(0), elem(1)) Next
Ed ecco il risultato che appare nella console window.
Giuseppe - Francesco Giuseppe - Marco Giuseppe - Piero Giuseppe - Gianni Giuseppe - MariaTeresa Francesco - Marco Francesco - Piero Francesco - Gianni Francesco - MariaTeresa Marco - Piero Marco - Gianni Marco - MariaTeresa Piero - Gianni Piero - MariaTeresa Gianni - MariaTeresa
Fin quì niente di particolarmente eccitante, visto che è facile ottenere lo stesso risultato con qualche ciclo innestato di C# o VB, soprattutto se i valori di K e N sono costanti. Con K o N variabili occorre prevedere degli array che gestiscono gli indici dei vari loop, ma è un codice alla portata di tutti.
Le cose cominciano a diventare interessanti quando l'insieme degli elementi contiene elementi uguali, che non possono quindi essere considerati distinti quando si generano le permutazioni o le combinazioni. L'esempio classico è la generazione di anagrammi: il numero totale di anagrammi della parola "case" è 23, dato dal numero di pemutazioni possibili di 4 lettere (=1*2*3*4) meno uno per evitare di conteggiare la parola originale. D'altra parte, il numero di anagrammi della parola "casa" è soltanto 11, perchè la parola originale contiene due lettere uguali e quindi il numero di permutazioni distinte che è possibile creare è pari a 12, non 24. Questo particolare inizia a complicare non poco la struttura di un programma C# o VB che risolve il problema specifico, ma la classe Permutations rimuove automaticamente le ripetizioni dal risultato:

Ecco il codice nell'evento Click nel pulsante "Show anagrams" del programma demo:
' prepare to generate all permutations of all the characters in the word Dim chars() As Char = txtWords.Text.ToCharArray() Dim permutations As New Permutations(Of Char)(chars) lstAnagrams.Items.Clear() For Each chrs() As Char In permutations Dim anagram As String = New String(chrs) ' don't include the original word in the result If anagram <> txtWords.Text Then lstAnagrams.Items.Add(anagram) Next lblMessage.Text = String.Format("Found {0} anagrams", lstAnagrams.Items.Count)
Come ho fatto notare prima, nella maggior parte dei casi quando chiediamo le permutazioni o combinazioni di un gruppo di elementi non vogliamo che lo stesso elemento compaia più volte. Ad esempio, se un elemento rappresenta la posizione di una regina posta sulla scacchiera, l'elemento non puo' comparire più di una volta perchè una casella non puo' contenere più pezzi. Altri problemi combinatori però non hanno questa limitazione. Se ad esempio stiamo calcolando tutte le possibili permutazioni di due dadi, dovremo includere anche i risultati in cui vi sia un doppio uno, un doppio due, ecc. Per ottenere questo risultato occorre specificare un valore maggiore di 1 come quarto argomento del costruttore della classe Permutations:
' get all the possible permutations of two dice Dim elements() As Integer = {1, 2, 3, 4, 5, 6} ' we pass 2 as fourth argument because we accept that the same value can appear twice Dim perms As New Permutations(Of Integer)(elements, 2, PermutationKind.Permutations , 2) For Each dice() As Integer In perms Console.WriteLine("{0} {1}", dice(0), dice(1)) Next
In una prima versione della libreria avevo usato un booleano per indicare se le ripetizioni erano ammesse o meno, ma usare un intero ha il vantaggio di permettere una maggiore flessibilità. Ad esempio, è possibile generare tutte le permutazioni di tre dadi in cui lo stesso valore compare al massimo due volte:
Dim perms As New Permutations(Of Integer)(elements, 3, PermutationKind.Permutations, 2)
Queste prime note dpvrebbero essere sufficienti per cominciare a utilizzare la libreria CAPermutations, ma le sue possibilità sono di gran lunga superiori e fornirò qualche altro esempio nei prossimi giorni, man mano che ne creo. Nel frattempo, potete scaricare la libreria e il piccolo programma demo visibile nella figura da questo link: PermutationsDemo1.zip (23.15 KB)
Una ultima, importante nota: questa versione della libreria CAPermutations è disponibile come DLL compilata e può essere usata esclusivamente nei programmi freeware o no-profit. Se avete dubbi su questa forma di licenza o se avete la necessità di utilizzarla in applicazioni commerciali, contattatemi via email.
di Francesco BalenaMsgHookX è una DLL ActiveX che permette ai programmatori VB6 di eseguire un subclassing intra-applicazione sicuro ed efficiente, ossia di intercettare qualsiasi messaggio che Windows invia a un controllo o finestra della applicazione corrente. Scrissi questa DLL diversi anni fa, ai tempi del VB5, e l'ho utilizzata in alcuni libri e articoli usciti nel frattempo. Questa DLL era disponibile sul vecchio sito VB2TheMax, ma non è sopravvissuta quando il sito è diventato .NET-2-The-Max e decidemmo di scartare tutti i contenuti relativi al vecchio VB6.
Beh, se devo giudicare dalle tante mail che continuo a ricevere dai lettori, si direbbe che gli sviluppatori VB6 continuano a voler subclassare i loro controlli e le loro finestre. Per questa ragione ho deciso di rendere MsgHookX nuovamente disponibile, sul sito americano a questo URL. Ecco un breve sommario di quello che la DLL è in grado di fare:
- subclassing sicuro: può essere usata nella IDE e in break mode, senza rischiare alcun crash di sistema.
- fornisce gli eventi BeforeMessage e AfterMessage, per una programmazione semplice di tipo event-driven
- è anche in grado di notificare l'arrivo dei messaggi attraverso l'interfaccia secondaria IMsgHookEvents, per fornire prestazioni migliore e un debugging più facile (in alcuni casi gli eventi sono inibiti nella IDE di VB6)
- alta flessibilità: potete decidere di chiamare la window procedure originale dall'evento/metodo BeforeMessage e opzionalmente di annullare l'elaborazione di default del messaggio. Potete anche visualizzare e modificare il valore che il messaggio sta per restituire al sistema operativo.
- La type library della DLL include la definizione di oltre 300 costante simboliche, che definiscono i messaggi Windows più comuni, in modo da non dover ricorrere all'API Viewer per includere le definizioni nella proprie applicazioni.
Ora la mia domanda è: ma quando, quando, quando vi deciderete a passare a .NET ? 
di Francesco BalenaSono appena tornato dal weekend pasquale, e trovo nella mia mailbox una lettera del mio amico Massimiliano Turazzini, che forse qualcuno di voi ricorderà come contributing editor di Visual Basic Journal, la rivista che ho fondato e che dirigo oramai da una decina d'anni. L'azienda di Massimiliano sta cercando uno sviluppatore con un profilo ben preciso, quindi passo la parola a lui....
Trilance è una società composta di persone giovani e dinamiche. Ci occupiamo principalmente di software dedicato alle società dei mercati dell'energia elettrica e del gas sviluppando soluzioni di CRM, di Sales Force Automation e di gestione dei flussi dati di misura.
La persona che cerchiamo è uno sviluppatore con almeno 5 anni di esperienza in ambiente Windows, che conosce e padroneggia le più aggiornate tecnologie Microsoft. Nel corso della propria attività deve aver lavorato in progetti complessi con Clienti medio-grandi, ha portato a termine progetti seguendone l'analisi, l'implementazione e le varianti in corso d'opera. Deve avere esperienza nella conduzione di un progetto: è a conoscenza dei meccanismi per la gestione delle risorse a disposizione e il rispetto dei tempi assegnati. Ha maturato una personale sensibilità alla conduzione dei progetti e al loro controllo durante la fase di implementazione, ed è in grado di rapportare sul loro stato di avanzamento, proponendo soluzioni ai problemi che via via si trova ad affrontare. Ha inoltre maturato la giusta sensibilità per approcciare al Cliente e alla pluralità di soggetti coinvolti in un progetto, e conosce le problematiche della nascita di un prodotto, è in grado di sviluppare soluzioni che raggiungano tale standard. E' curioso, si interessa delle problematiche che riguardano il proprio lavoro, è predisposto all'autoaggiornamento e alla condivisione del know-how.
Requisiti Tecnici: ottima conoscenza del funzionamento di un database relzionale, in particolare SQL Server. Ottima conoscenza di uno dei due seguenti linguaggi di programmazione: Vb.Net, C# Comprovata esperienza in almeno 2 dei seguenti ambiti: soluzioni windows, web, smart client, programmazione lato server, middleware.
La nostra sede di lavoro è a Verona. Inquadramento e retribuzione saranno valutati assieme al candidato in funzione delle rispettive esigenze.
Per maggiori informazioni, su questa e altre occasioni di lavoro, vedere qui e qui.
di Francesco BalenaPer la prima volta da quando esiste questo blog ho "latitato" per oltre due settimane. Non è mai successo prima e (spero) non accadrà mai più. Diciamo però che l'assenza è più che giustificata, a causa sia della grande attività di questi giorni sia delle novità che bollono nella pentola di Code Architects. Ecco un piccolo riassunto di quello che è successo nel frattempo...
Il 23 marzo ho tenuto il mio keynote speech alla conferenza su Visual Basic 2005 tenuta nell'auditorium della sede Microsoft a Milano. E' stato un grande onore, visto che gli speaker della giornata erano niente meno che Jay Roxe (product manager di Visual Studio) e Tyler Whitney (Visual Basic Technology Lead), che insieme a Alexander Holy hanno intrattenuto il numeroso pubblico sulle novità di VB2005 e di Visual Studio Tools for Office. Dal mio punto di vista la parte più interessante dell'incontro è stato l'intervallo di pranzo come pure tutta la mattina del giorno successivo, durante il quale ho potuto scambiare le mie idee su Visual Basic con le persone che probabilmente hanno la maggiore influenza sul team di Visual Studio.
|
Nei giorni 3 e 4 aprile (ovvero ieri e avantieri) io e Giuseppe Dimauro siamo stati ospiti del Microsoft Architects Bootcamp, tenuto nella splendida cornice del Castello di Casiglio (vicino al lago di Como), dove insieme a una decina di altri fortunati abbiamo approfondito alcune tematiche legate ai temi della Service Oriented Architecture (SOA), con tanto di esercizi di gruppo e scambio di opinioni con esperti del settore. Anche senza contare il paio di ore dedicato alla degustazione dei vini, è stata una esperienza molto bella (e molto divertente). |
Nel frattempo, i ritmi in Code Architects stanno accelerando a velocità vertiginose. Abbiamo assunto alcuni nuovi sviluppatori, ed è necessario organizzare il lavoro che sembra non finire mai. (Per fortuna! ) Ci sono nuove commesse con banche e società di assicurazioni, e tutti sembrano avere una fretta pazzesca, come è ovvio. Stiamo anche organizzandoci per aprire una sede più vicino a Bari, in modo da essere più vicini all'aereoporto e ad alcuni nostri clienti.
|
Come se non bastasse, nel frattempo Code Architects ha aderito al programma S@MP (Stage at Microsoft Campus, http://www.progettosamp.it/), una bellissima e meritoria iniziativa di Microsoft che incoraggia le aziende a ospitare laureandi per stage e altro. Al momento siamo l'unica azienda del territorio (Bari e provincia) che ha i requisiti richiesti da Microsoft per farlo, quindi sarà un bello sforzo ma anche una bella esperienza. |
Poi ovviamente ci sono alcuni progetti software su cui stiamo lavorando, ma di quelli ne parlerò in qualche altro post. Per il momento è tutto...
di Francesco Balena
|
Ottime notizie dagli USA per Giuseppe Dimauro e il sottoscritto.
Il libro Practical Guidelines and Best Practices for Visual Basic and Visual C# Developers ha vinto un Excellence Award dalla Society of Technical Communication, un prestigioso ente che ogni anno individua i migliori libri, articoli, siti, e courseware nell'ambito della editoria tecnica internazionale. Non solo l'editoria che riguarda la programmazione o i computer, ma l'editoria tecnica in generale. Infatti, tra i premiati ci sono solo una decina pubblicazioni che hanno a che fare con il software. Il nostro è l'unico libro di Microsoft Press ad aver vinto il premio, quindi abbiamo di che essere soddisfatti. 
E' un riconoscimento davvero importante, e mi fa particolarmente piacere perchè si tratta del primo (e unico) libro che ho scritto al di fuori della serie "Programming Visual Basic" e di un libro con una impostazione molto originale, la prima e attualmente l'unica raccolta organica di guideline per sviluppatori .NET in circolazione.
Una nota a margine:
La soddisfazione è ancora maggiore se penso al fatto che questo è stato l'unico mio libro ad avere avuto una recensione davvero negativo, sul blog di un farneticante Alex Papadimoulis, che ha pure postato le sue stupidaggini su Amazon. (Se vi interessa la storia, trovate le mie risposte su Amazon.) E approfitto della occasione per ringraziare Stefano Demiliani, Luca Minudel, Adrian Florea, e Andrea Adami, che hanno dedicato qualche minuto del loro tempo per sottolineare la faziosità di quelle affermazioni.
La cosa simpatica è che alcuni lettori mi hanno scritto (e lo hanno dichiarato su Amazon) per farmi sapere di essere stati spinti all'acquisto del libro proprio dalla recensione negativa del nostro Alex. Per fortuna non tutti scambiano per "autorevolezza" la furia compulsiva con cui alcuni blogger senza curriculum degni di nota inondano la rete delle loro opinioni. |
di Francesco BalenaSaprete sicuramente che Microsoft ha deciso di rendere noti i sorgenti di Windows, a organizzazioni selezionate che offrano le necessarie garanzie di riservatezza. Se ne volete sapere di più, leggete questo articolo su Repubblica online di Vittorio Zambardino. Proprio leggendo tale articolo ho pensato che l'importanza data dal mondo dei media all'annuncio è decisamente sproporzionata, quindi mi sono deciso a scrivere all'autore, il quale ha pubblicato la mia lettera nel suo blog.
Se avete qualcosa da dire sull'articolo, lasciate un commento sul blog di Zambardino. Se invece avete dei commenti sulla mia opinione, lasciate un commento in *questo* blog, altrimenti non lo leggerei mai e non potrei rispondere.
di Francesco Balena
 |
Nel mio precedente post annunciavo il lancio ufficiale di dotnet2themax.com, la versione in lingua inglese di questo sito e spiegavo che in linea di massima i due siti avrebbero ospitato molti articoli ma non sarebbero stati uno la traduzione dell'altro. In particolare, il sito punto-com ospiterà la home page dei nostri libri e dei nostri prodotti.
Per inaugurare in bellezza, la prima cosa che ho messo online è la lista di 700+ best practice per applicazioni .NET. Si tratta di un documento Word di oltre 30 pagine che riassume di tutte le regole contenuto nel libro cho ho scritto insieme a Giuseppe Dimauro, ovvero Practical Guidelines and Best Practices for Microsoft Visual Basic .NET and Visual C# Developers. Il documento è formattato come una checklist, in modo da poter "spuntare" i vari elementi quando si esegue il code review di un progetto particolarmente complesso. Noi lo usiamo regolarmente per i progetti interni e spero che lo troviate anche voi utile. Se poi lo troverete davvero utile, potete sempre comprare il libro per trovare esempi e tutto il resto. 
Oltre alla lista delle guideline, sul nuovo sito americano è disponibile il codice sorgente degli esempi del libro e ben tre capitoli del libro: il capitolo 6, "Types", il capitolo 23, "Memory Usage", e il capitolo 31, "Serviced Components." I capitoli sono in formato PDF e pronti ad essere stampati. E' la prima volta che questo materiale è disponibile online.
Sul sito sono disponibili altri capitoli mai apparsi prima online, tratti dal mio Programming Microsoft Visual Basic .NET 2003, ovvero il capitolo 18, "Windows Forms Custom Controls.", il capitolo 12, "Regular Expressions", e il capitolo 21, "ADO.NET in Disconnected Mode" che era già disponibile sul sito MSPress. Si tratta di oltre 100 pagine di reference che continua ad essere valido anche per VB2005 e .NET 2.0, in particolare nel caso delle regular expression.
NOTA: Per accedere a questi contenuti occorre registrarsi, con nome e email, e iscriversi alla newsletter del sito. Se poi volete davvero farci un piccolo regalo, dedicato un paio di minuti per rispondere alle domande del nostro questionario, che ci permette di capire davvero qual è il nostro pubblico. Noi in compenso vi promettiamo solennemente (e ovviamente) che non faremo mai spamming e che useremo la newsletter (che ha una cadenza mensile) solo per comunicare nuove iniziative e prodotti che vi possono davvero interessare. |
di Francesco Balena
Chi legge i miei libri e i mieiarticoli da qualche anno conosce sicuramente il mio primo sito, VB2TheMax, che lanciai nel '99 insieme a Giuseppe Dimauro, Dino Esposito e tanti altri "bravi guaglioni". VB2themax diventò in poco tempo uno dei siti sul VB più visitati al mondo e il gruppo iniziale si arricchì di nuovi collaboratori, come Marco Bellinaso, Alberto Falossi e Enrico Sabbadin, che da lì hanno intrapreso bella carriere come articolisti su riviste italiane e americane, scrittori di libri, e speaker a conferenze. In questi anni il sito ha subito una serie di vicissitudini, anche legali, e quando qualcuno mi chiede cosa è successo mi tocca raccontare una storia un po' lunga, quindi ho pensato di riassumere qui tutta la vicenda.
All'inizio il sito era "ospite" di DevX, che ci offriva l'hosting e in cambio si prendevano i proventi della pubblicità. A un certo punto, verso la fine del 2003, l'accordo con DevX terminò. Poco male, perchè si fecero subito avanti quelli di Fawcette Technical Publications, ovvero gli editori di Visual Studio Magazine. Il problema fu che DevX - che è un acerrimo concorrente di FTP - ci ingiunse di eliminare immediatamente tutto il materiale (prevalentemente su VB6) che avevamo prodotto negli anni precedenti. Il contratto a tale riguardo era decisamente poco chiaro e forse l'avremmo spuntata in tribunale, ma la cosa avrebbe potuto costarci più di 100mila dollari, quindi decidemmo di esaudire la loro richiesta, anche considerato il fatto che oramai il nostro focus si stava spostando su .NET. Visto che dovevamo puntare su .NET decidemmo di riscrivere tutta l'architettura su ASP.NET, e il nostro Marco Bellinaso ha fatto un lavoro eccezionale, un vero e proprio CMS dedicato alla memorizzazione di knowledge item per programmatori. Per sottolineare il cambiamento inaugurammo anche il nuovo dominio www.dotnet2themax.com.
Dopo un inizio un po' difficoltoso il sito aveva cominciato a riprendersi, ma comunque non siamo mai riusciti a "ingranare" davvero e a trovare un ritmo giusto nella collaborazione con Fawcette. Io lavoro con loro da oltre dieci anni e sono tutti molto in gamba, ma in generale un sito deve essere molto più agile di un magazine cartaceo. Quando si ha una idea si deve poterla implementare e metterla online in pochi giorni o ore. Questo non era possibile farlo continuando ad essere sotto un publisher, con un bel po' di burocrazia interna. Anche semplicemente per aprire un blog c'erano problemi quasi insormontabili!
Cosi' qualche mese fa abbiamo deciso di chiudere l'accordo con Fawcette e di riprenderci la nostra libertà. Marco ha semplificandolo di molto l'infrasfruttura, e rendendo il sito più usabile e molto simile a dotnet2themax.it. Siamo partiti in sordina fine ottobre, in modo da poter fare un po' di rodaggio, e ora siamo finalmente pronti per il lancio, anzi il rilancio. Sul nuovo sito troverete un bel po' di materiale inedito, nonchè il blog inglese mio e di Marco.
La nostra intenzione è di continuare a gestire entrambi i siti, dotnet2themax.it (in italiano) e dotnet2themax.com (in inglese). Sul primo continueremo a fare "community", con blog e iniziative di carattere nazionale, sul secondo parleremo di argomenti di più ampio respiro e ospiteremo le home page dei nostri libri in inglese e dei nostri tool per sviluppatori. Io penso di mantenere i due blog in parallelo e di postare contemporaneamente gli stessi articoli, ma ci potranno anche essere contenuti che per mancanza di tempo non riuscirò a tradurre dall'italiano in inglese o vicevera. Ci sono anche dei contenuti inediti, ma di quelli parlerò in un altro post.
Come al solito, se avete commenti o suggerimenti non fatevi pregare. Vanno anche bene dei semplici incoraggiamenti... 
di Francesco BalenaSiamo sempre in cerca di bravi sviluppatori che siano anche molto motivati a perfezionarsi e specializzarsi in tecnologie Microsoft, incluso SQL Server, SharePoint, e BizTalk. Lavoriamo come consulenti per banche, ministeri, e grandi aziende come Telecom, Consip, e la stessa Microsoft Italia. Scriviamo applicazioni di classe enterprise che supportano anche diecimila utenti e sviluppiamo anche tools ad-hoc per developers. Di sicuro non ci annoiamo. 
Se vi interessa lavorare o collaborare con Code Architects e partecipate alla WPC, fatevi vedere al nostro banchetto e portate con voi il vostro curriculum.
di Enrico SabbadinTelefona una signora in ufficio e dice: nel programma c'è una cosa che non funziona, il punto che c'è nel tastierino numerico che uso per inserire gli importi delle fatture non si comporta come un "separatore di decimali ma di migliaia" (non dice così evidentemente ma è per farvi capire il concetto con poche parole). Beh, dico io, è chiaro, in italiano il punto del tastierino numerico è il separatore delle migliaia .. se vuole può modificare le impostazioni del programma (che non è windows regional settings aware) affinchè consideri il punto come separatore dei decimali (e la virgola delle migliaia) .. no dice la signora .. se faccio così poi le cifre mi sono mostrate con il punto come separatore dei decimali .. io voglio che le cifre siano mostrate come sono adesso .. quel che voglio è che il tasto sul tastierino numerico dove c'è il punto in realtà "scriva" virgola..
cavoli penso io :) allora non è così facile .. considerando che non ho accesso al codice del programma .. voi come suggerite di fare ? Io una soluzione che mi pare piuttosto efficace l'ho trovata , ma non sono sicuro che sia quella migliore. Qualche suggerimento ? .. a breve la mia soluzione.
di Enrico SabbadinHo finito di leggere un libro che mi ha consigliato Eugenio LaMesa “Alla ricerca della stupidità: 20 anni di disastri hi-tech”. Molto bello, lo consiglio a tutti. Una delle cose che mi ha più colpito è stata l’intervista ad un certo Joel Spolsky che è stato tra l’altro Program Manager di Excel ed altre cosette del genere. Vi riporto la parte dell’intervista che mi ha fatto molto pensare, mi ha colpito come un fulmine a ciel sereno. SoftwareMarketSolution: Joel qual è il più grande errore che possa fare un’azienda produttrice di software? Joel Spolsky: Decidere di riscrivere da zero il codice di un prodotto basandosi sulla solita teoria che tutto quel codice è un casino, è tendenzialemente bacato ed è ingestibile e che, di conseguenza, va completamente ripensato e riscritto. SMS: Uh, e cosa c’è di sbagliato in questo ? JS: Perchè non è quasi mai vero ... Secondo me questo accade perchè è molto più difficile leggere il codice piuttosto che scriverlo. Un programmatore arriverà sul punto di piangere per una funzione che secondo lui è un casino. Si tratta di una funzione molto semplice per aprire una finestra, ma per qualche motivo c’è bisogno di due pagine di codice, di tutte quelle parentesi e freccette delle quali nessuno capisce niente, per farla funzionare. OK TE LO DICO IO A COSA SERVE TUTTA QUELLA ROBA. Si tratta di bug-fixing. Un pezzo serve per risolvere un baco che tizio ha individuato quando ha provato a installare il prodotto su un computer che non aveva IE. Un altro pezzo serve a fixare un baco che capita quando il sistema non ha sufficiente memoria. Un altro pezzo serve per fixare un baco che capita quando il file si trova sul floppy disc e l’utente lo tira fuori per errore metre il file è ancora aperto. Tutte queste cose sono certamente orribili a vedersi ma fanno si che il codice possa funzionare anche su windows 95. Se decidi di buttare quella funzione e di riscriverla da zero, butti via tutta quest’esperienza, anni di lavoro.
Mio commento : Come si può fare frenare i programmatori dalla continua tentazione di riscrivere il codice di altri? Come si può fare evitare che i capi progetto tecnici vadano dal management a dire che bisogna riscrivere tutto il prodotto? COMMENTATE IL CODICE !!! così chi lo vedrà capirà perchè ci sono quelle venti righe un pò contorte invece che quella singola riga che sembra essere sufficiente (che poi a volte capita anche che chi legge il vostro codice e non ne capisce niente siete sempre voi qualche mese dopo). Ogni mattina prima di cominciare a programmare ripetete come un mantra per tre volte “devo commentare il mio codice, devo commentare il mio codice, devo commentare il mio codice”.
Enrico Sabbadin
di Francesco BalenaOggi riflettevo sul fatto che ho cominciato la mia carriera di speaker a conferenze per programmatori esattamente 10 anni fa, il 27 ottobre 1995 al VB Forum organizzato da Edizioni Infomedia e la rivista Visual Basic Journal, che avevo da poco fondato. Come tutte le prime volte, ero super-emozionato, parlavo troppo velocemente, avevo un volume discontinuo, non sapevo dove tenere le mani, ecc. Dopo dieci anni sono sicuramente migliorato un bel po' (ma ho ancora margini per migliorare!) e credo di poter passare qualche consiglio a chi comincia solo ora.
In questo post, però, non mi preme offrire una lista di consigli per diventare un bravo oratore e mi limiterò invece a dare qualche spunto di riflessione su come preparare al meglio le demo con Visual Studio. Ci sono tante piccole cose che è possibile fare in questo campo e che relativamente pochi speaker fanno. Inoltre, si tratta di piccoli consigli che possono essere utili anche a coloro che conducono corsi di programmazione in aula, che sono certamente un numero maggiore di coloro che hanno la fortuna di salire su un palco a parlare davanti a centinaia di persone.
Avevo preparato questa lista qualche anno fa, ad uso e consume del team di Code Architects, che oramai sono speaker collaudati e non ne hanno più bisogno. La lista è divisa in due parti: la prima dedicata alla fase di preparazione della sessione, la seconda con consigli su come condurre le demo durante la sessione.
Prima della sessione
Impostare font leggibili per l'editor di codice Non tutti gli spettatori siedono in prima file o hanno la vista delle aquile. È preferibile impostare la dimensione del font ad almeno 14-16 punti. Per aumentare la quantità di codice visibile sullo schermo si puo' utilizzare un font proporzionale, ad esempio Arial Black.
Modificare il colore del testo selezionato Di default Visual Studio mostra il testo selezionato con caratteri bianchi su sfondo blu scuro, ma il risultato è molto poco leggibile durante le presentazioni. È molto meglio mantenere il colore nero per il testo e usare un colore chiaro (ad esempio ciano) per lo sfondo.
Mantenere i colori di default A parte le modifiche indicate nei punti precedenti, evitare di modificare i colori di default usati da Visual Studio. La stragrande maggioranza degli sviluppatori si aspetta che i breakpoint siano marcati in rosso, l'istruzione attualmente in esecuzione dovrebbe essere in giallo, e così via. E' anche opportuno usare lo schema di default per i colori di Windows, quello con la barra dei titoli in blu (o al massimo il Silver, quello con la barra dei titoli in grigio).
Usare font più grandi per l'interfaccia utente Nel creare una applicazione Windows Form o Web Form, utilizzare un font più grande del solito per i vari elementi della interfaccia utente, sia nelle applicazioni demo preparate in anticipo, sia per quelle create al volo. È sufficiente ricordare di modificare il font del form subito dopo averlo creato, in modo che tutti i controlli sul form si adattino alla nuova dimensione.
Lunghezza delle righe di codice Negli esempi di codice che si intende mostrare durante la sessione è opportuno spezzare le righe ad una lunghezza tale da non rendere necessario l'uso della scrollbar orizzontale per mostrare il testo nascosto dal bordo destro.
Larghezza della tabulazione Un modo semplice per aumentare la quantità di testo visibile sullo schermo è impostare la larghezza di tabulazione a 3 o persino 2 caratteri, soprattutto se usate loop e strutture indentate di tre o quattro livelli.
Contrassegnare i punti di interesse nel codice Non c'è nulla di più penoso che vedere uno speaker alla ricerca affannosa dei pezzi di codice che intende mostrare al pubblico. Per rintracciare velocemente i punti di interesse basta marcarli nel codice con un commento speciale riconosciuto dalla finestra Task List. Ecco come fare. Per prima cosa, usare la pagina Task List della finestra Tools-Options di Visual Studio per definire un comment token personalizzato di nome SHOW e con priorità low. A questo punto è sufficiente marcare il codice con commenti opportuni, usando opzionalmente un numero dopo il commento per indicare l'ordine con cui i vari punti devono essere mostrati, ad es. // SHOW: 1. Il costruttore della classe A questo punto si possono visualizzare questi commenti speciali scegliendo il comando All dal sottomenu Show Tasks del menu contestuale della finestra Task List. Cliccando sull'intestazione della colonna Description si raggruppando tutti i commenti di tipo SHOW e li si ordina in base al numero progressivo. (Se ci sono più di 9 punti, usare numeri a due cifre, ad es. 01, 02, ecc.). Se si clicca sulla intestazione della colonne File, i commenti ritornano ad essere ordinati per posizione.
Per ritrovare velocemente punti nel codice che non sono segnalati da commenti, potete anche usare dei bookmark. Questi bookmark possono apparire nella finestra Task List se usate il comando Add Task List bookmark dal sottomenu Bookmarks del menu Edit, corrispondente alla combinazione Ctrl+K, Ctrl+H.
Stile uniforme del codice Usare uno stile il più standard possibile per il codice usato nelle demo preparate in anticipo: rispettare le indentazioni, commentare ogni blocco di righe, usare nomi significativi per campi, proprietà, e metodi, e così via.
Aggiungere un file Readme.txt al progetto Tutti i progetti demo di una certa complessità dovrebbero essere accompagnate da un file di testo che contiene le istruzioni per il setup. Se questo file è aggiunto al progetto in questione sarà visualizzato nella finestra del Solution Explorer e quindi sarà più facilmente notato quando i partecipanti installeranno gli esempi sul proprio computer. Se non vi fidate della vostra memoria, stampate il contenuto di questo file e tenetelo accanto alla tastiera, per essere sicuri di non omettere alcun passo importante.
Controllate le demo alla risoluzione 1024x768 Ecco un errore fin troppo frequente: tutte le demo sono preparate per la risoluzione che usate durante lo sviluppo (spesso 1280x1024 o superiori) e poi l'interfaccia utente funziona male alla risoluzione usata durante la sessione, che non supera mai 1024x768. Quindi accertatevi che tutte le vostre demo funzionino a questa risoluzione. Se vi sembra un grande sacrificio, pensate che fino a non molti anni fa la maggior parte dei proiettori che si trovavano anche nei migliori centri congressi supportava al massimo 800x600.
Scorciatorie nel menu Tools Aggiungere al menu Tools i comandi per richiamare le utility che usate più frequentemente durante le demo, ad esempio • lanciare ILDASM per dissassemblare l'eseguibile corrente • lanciare GACUTIL per registrare l'assembly corrente nella GAC • aprire il Window Explorer nella cartella del progetto. (In VS2005 questo comando esiste già, basta fare click con il tasto destro sulla tab nella parte superiore dell'editor di codice.) • lanciare il prompt di Visual Studio .NET nella cartella contenente gli eseguibili, in modo da poter poi lanciare con facilità gli altri tool di .NET
Macro e toolbar custom per altre azioni comuni E' buona norma preparare delle macro per le azioni comuni che prendono più tempo, ad esempio per creare una proprietà con tanto di blocco get/set oppure per attivare e disattivare i numeri di riga. Queste macro si possono richiamare dal Macro Explorer o meglio ancora mediante una toolbar custom costruita per l'occasione. Una toolbar del genere può essere utile anche per richiamare alcuni comandi di Visual Studio che sono annidati in menù particolarmente profondi o che corrispondono a modifiche delle impostazioni della dialog Tools-Options. Se usate Visual Studio 2005, non dimenticate delle expansions.
Durante le demo
Operazioni di editing mediante mouse e menu di contesto Usate preferibilmente il mouse per invocare un comando invece della combinazione di tasti che corrisponde al comando. In questo modo gli spettatori possono rendersi conto di quello che sta avvenendo, senza dover tirare a indovinare quali tasti state premendo. Questo suggerimento vale anche per i comuni comandi di editing come Copy, Cut, Paste, Delete, ecc. Se non usate il mouse, almeno dichiarate a voce quello che state facendo in ogni momento.
Evidenziare la posizione del mouse Attivare l'opzione "Show location of pointer when I press the CTRL key" che si trova nella pagina Pointer Options della dialog box con le proprietà del mouse (raggiungibile da Control Panel). In questo modo è possibile attirare l'attenzione degli spettatori sulla posizione del mouse semplicemente premendo il tasto Control.
Editor a pieno schermo Quando si analizza un pezzo di codice istruzione per istruzione, è opportuno usare la modalità full-screen dell'editor di Visual Studio .NET, attivabile e disattivabile con la combinazione Shift+Alt+Enter, in modo da massimizzare l'area a disposizione e ridurre la necessità di eseguire lo scrolling orizzontale per mostrare le righe troppo lunghe.
Evitare lo scrolling orizzontale Come indicato in precedenza, è opportuno che le istruzioni nelle demo non siano tanto lunghe da richiedere l'uso della scrollbar orizzontale per mostrare il testo nascosto. Un sistema alternativo consiste nell'attivare e disattivare velocemente il line wrapping delle righe con la combinazione di tasti Ctrl+R, Ctrl+R. (Oppure Ctrl+E, Ctrl+W in Visual Studio 2005.) Visual Studio viene anche fornito con le macro predefinite TurnOnWordWrap e TurnOffWordWrap che modificano questa impostazione per tutti i linguaggi supportati.
Outlining del codice Utilizzare le capacità di outlining di Visual Studio per collassare ed espandere le single classi e i singoli metodi, in modo da poter attirare l'attenzione degli spettatori sulle porzioni di codici realmente importanti. E' anche opportuno usare la direttiva #region per creare porzioni di codice che possono essere facilmente collassate, ad esempio l'insieme dei metodi che implementano una interfaccia.
Numeri di riga Se accettate che gli spettatori possano fare delle domande sul codice che state mostrando, attivate la visualizzazione dei numeri di riga in modo da metterli in grado di indicare velocemente a quale porzione del codice si riferiscono. Visto che questa opzione si attiva dalla dialog Tools-Options, conviene creare una macro e assegnarvi una shortcut. Visual Studio viene fornito con le macro TurnOnLineNumbers e TurnOffLineNumbers che attivano e disattivano questa feature per tutti i linguaggi supportati.
Confrontare due porzioni di codice Se occorre mostrare due porzioni di codice allo stesso tempo, ad esempio per permettere di apprezzare piccole differenze, si dovrebbe dividere a metà la finestra dell'editor. Ci sono due modi di farlo, a seconda che il codice si trova nello stesso file sorgente oppure in due file differenti. Nel primo caso, si divide in due la finestra dell'editor trascinando verso il basso il piccolo rettangolino grigio che si trova immediatamente sopra la scrollbar verticale. Nel secondo caso è invece necessario creare un nuovo Tab Group orizzontale (cliccare con il tasto destro su una delle tab mostrate nella parte alta della finestra dell'editor) e accertarsi che i due file in questione appartengono a due gruppi distinti (se non lo sono, basta eseguire il drag-and-drop di una linguetta su un altro gruppo).
Navigazione veloce nel codice Usate tutti i mezzi e i comandi che Visual Studio mette a disposizione per muoversi velocemente nel codice. Eccone alcuni, non tutti noti come meriterebbero: • Evidenziare il nome di una variabile, metodo, o classe e premere F12 per saltare alla definizione della classe • navigare direttamente alla definizione di una classe o metodo mediante l'Object Browser o il Class Viewer • premere il tasto Ctrl+- (meno) per tornare alla posizione precedente (questa la sanno in pochi!!! ) • creare uno o più bookmark per poi rintracciarli velocemente mediante la finestra Bookmarks. • usare il comando Find per cercare velocemente tutte le occorrenze delle variabili, invocazioni a metodi, ecc.
Porzioni di codice pre-confezionate Scrivere codice "al volo" durante la sessione è molto efficace e dà agli spettatori l'impressione che lo speaker padroneggia davvero la materia, ma se si tratta di scrivere più di 4-5 righe di codice molti tendono a distrarsi e a confondersi, anche perché di solito scrivendo codice in questo modo non si aggiungono i commenti necessari. All'altro lato dello spettro vi sono le applicazioni demo preparate in anticipo e complete e funzionanti, che però di solito non mettono in evidenza il ragionamento che ha seguito lo sviluppatore per arrivare al risultato finale. Ecco alcune soluzioni "intermedie": • Scrivete in precedenza il codice nel programma ma commentatelo, in modo da poterlo poi "scommentare" velocemente con Ctrl+K, Ctrl+U. • Scrivete in precedenza il codice nel programma, ma usate una direttiva #if false per non farlo eseguire; se invece della costante false usate una variabile di compilazione, questo meccanismo permette di attivare o nascondere più pezzi di codice con una modifica in un unico punto del codice (oppure nelle proprietà di progetto). • Per le porzioni di codice di una certa dimensione, preparate un file di testo contenenti le varie porzioni di codice, caricatelo in Notepad, e durante la sessione usate il copia-e-incolla per inserire tali pezzi di codice in determinati punti del listato. • Come sopra, ma prima della sessione copiate i pezzi di codice sulla Toolbox di VS come frammenti di testo, da dove potete riprenderli mediante un semplice drag-and-drop • Usate un qualsiasi code librarian per conservare i frammenti di codice che vi interessano, ad esempio la versione freeware di CodeBox (www.dotnet2themax.com/codebox). • Se la sessione verte su Visual Studio 2005, potete preparare delle porzioni di codice e inserirle con il comando Insert Snippet.
L'utility Magnifier Se volete attirare l'attenzione su alcuni particoli della interfaccia utente del vostro programma (o di Visual Studio, o di un altro programma qualsiasi), usate l'utility Magnifier (che trovate nel menu Accessibility del menu Accessories di Windows). Su Internet trovate una marea di utility simili e anche più potenti.
ATTENZIONE AL TEMPO CHE PASSA !!! L'ultimo consiglio è in realtà il più importante: ricordatevi di indossare l'orologio e soprattutto di guardarlo in continuazione. Non c'è nulla di peggio di vedere uno speaker che si affanna per finire le sue slide in tempo, perchè ha indugiato troppo all'inizio o ha accettato troppe domande dal pubblico. Se il vostro orologio ha un allarme, impostatelo a 15 minuti prima della fine della sessione. Se avete un palmare, usate l'allarme del palmare. Se non avete un palmare, portatevi una sveglia sul palco, oppure usate una qualsiasi utility sul computer che emetta un beep.
Se non trovate una di queste utility su Internet o non sapete scriverne una, mi chiedo che ci fate su un palco di una conferenza per programmatori Ma anche in quel caso, almeno chiedete a un amico in prima file di tossire violentemente quando si accorge che state per "sforare" ....
Sono sicuro che molti di voi hanno qualcosa da aggiungere a questo elenco, sia perchè hanno avuto modo di parlare in pubblico sia perchè hanno visto altri speaker NON fare qualcosa che avrebbero dovuto fare (o fare qualcosa che NON avrebbero dovuto fare, il che è lo stesso). Se ne avete voglia, lasciate pure un commento e aggiornerò l'elenco.
di Francesco Balena
|
Sono stati tre giorni di fuoco e domenica sera sono crollato a dormire alle 10 sul divano. Ma ne è valsa la pena, perchè il Code Architects Retreat 2005 è stato un successone. Per tutto il weekend il Team CA si è aggirato in quel di Ostuni (BR) in un pile color crema con tanto di logo. Sembravamo una squadra di calcio in libera uscita, e anche quanto a goliardia l'atmosfera era quella. Alle tre di notte ancora non si riusciva a prendere sonno per via delle risate che echeggiavano nelle varie stanza. (Quanto alla modella qui sulla destra, non farò il suo nome ma come indizio posso dire che l'ho sposata qualche anno fa )
Due giorni zeppi di sessioni tecniche: applicazioni distribuite, tecniche avanzate con i web service, design e disaccoppiamento di business logic e UI, coding guidelines e best practices. Il tutto a cura del team ma anche di alcuni cari amici che sono venuti a farci visita per l'occasione, come Eugenio La Mesa di Salesware, che ci ha insegnato a valorizzare al meglio i nostri servizi e prodotti. Oppure Francesco Albano, che ha spiegato come Code Architects possa funzionare come una piccola (molto piccola!) Microsoft.
Insomma, il cibo per la mente non è mancato, ma anche quanto a cibo tout court il weekend è stato una serie di piacevoli scoperte, soprattutto per i non pugliesi: orecchiettte con le cime di rapa, monachelle al cioccolato, angus cotto sulla pietra ollare, "bombette" di carne al formaggio, tarallini alle olive, cozze ripiene, frittura di moscardini, e un polpo alla brace cotto davanti a noi in riva al mare in una giornata super-soleggiata. Per non parlare della cassata e dei babà al rhum della pasticceria siciliana all'angolo, meta di ripetuti pellegrinaggi durante le pause tra le sessioni.
Se le cose continueranno ad andare bene, il nostro obiettivo è di fare almeno un ritiro all'anno. Se invece le cose andranno molto bene, uno dei prossimi ritiri lo faremo a Ibiza o alle Seychelles |
di Francesco BalenaPer una volta tanto non è un blog tecnico ma personale, o meglio, aziendale. Oggi comincia la seconda edizione del Code Architects Retreat, l'incontro di tutto il team di CA sparso nella penisola. .
Ci riuniremo in una villa nella bellissima Ostuni, per un tour de force di sessioni tecniche, per mettere tutti al corrente delle novità in azienda (che tra un po' rendemo pubbliche sul sito), per fare brainstorming collettivo su nuove iniziative, prodotti e servizi, ma soprattutto per stare insieme in una atmosfera rilassata e anche un pizzico goliardica. Ho consigliato a tutti di portarsi il costume da bagno, anche se le previsioni non sono esattamente favorevoli.
Organizzare un weekend per una quindicina di persone non è proprio uno scherzo. Nè sanno qualcosa Christian, Maria Teresa e Adriana, che hanno badato alla logistica dell'evento. Prenotazioni e biglietti per persone che arrivano da Milano, Torino, Bologna, e Perugia, prenotazioni al ristorante, trasferimenti a/da Ostuni, grandi pulizie, computer, proiettori, schermi, cavetti, latte, biscotti, merendine, marmellate, acqua minerale, bibite varie, piatti, stoviglie, biancheria, lenzuola, e tanto altro che non mi viene in mente. Io mi sono limitato alla sola agenda tecnica delle sessioni, e in confronto è stata una passeggiata. 
di Francesco BalenaCome probabilmente già sapete, sono disponibili sul sito Microsoft le prime specifiche delle future versioni di Visual Basic e di Visual C#. La chiave di quasi tutte le nuove feature è il progetto Linq, che oramai è ampiamente dibattuto in articoli, blog, sessioni alla PDC e persino video, come se dovesse essere rilasciato la prossima settimana. Per dirla davvero in due righe, Linq permetterà di integrare meglio i linguaggi tradizionali con linguaggi db-oriented tipo SQL, e offrirà una sintassi standard per eseguire query su collection di oggetti e tabelle di database in modo molto simile.
Quasi tutte le nuove feature del linguaggio, ad esempio gli anonymous types e la dichiarazione implicita delle variabili (che è necessaria per supportare gli anonymous types), sono una conseguenza indiretta dell'adozione di Linq. Quando scrivo una istruzione Linq come Dim result = Select Name,Population From Country In Countries Where Country.Population < 1000000, il valore restituito in result è una collection di tipi anonimi che "derivano" (ma non nel senso dell'editarietà) dalla classe Country ma hanno solo i campi Name e Population. In quanto anonimi, questi tipi non hanno evidentemente un nome e quindi non li posso usare nella clausola As per dichiarare la variabile result. L'adozione di Linq ha portato anche alla necessità di estendere le classi "al volo" mediante extension methods e a offrire un supporto più esteso al late binding. Anche l'introduzione delle dynamic interfaces va nella stessa direzione.
Forse perchè quest'anno (come l'anno scorso, del resto) NON sono andato alla PDC, ma non mi sento contagiato da questa grande euforia. Per una serie di motivi che proverò a sintetizzare. Prima di continuare, però un piccolo ringraziamento a Dino per un suo post che mi ha dato la voglia di scrivere questa paginetta.
Prima di tutto, dopo anni che ci hanno spiegato (e in cui noi "esperti" abbiamo tentato di spiegarlo ai programmatori/lettori) che occorre scrivere codice strong-typed, improvvisamente c'è questa virata verso i linguaggi dinamici. Quando era il VB a incoraggiare il late binding erano tutti a dargli addosso, urlando che era una vergogna che un linguaggio moderno supportasse queste sconcezze. Oggi improvvisamente la parola late binding non è più un tabù, e anzi persino il C# ne sarà contagiato. Ovviamente, il late binding di VB9 e C#3 è ben più robusto quello che si aveva in VB6 (e si puo' tuttora avere in VB.NET) usando variabili Variant e Object, ma è comunque vero che le chiamate agli estension method e alle dynamic interfaces saranno molto meno performanti del solito. Senza contare il fatto che le dichiarazione implicite dei tipi renderà il codice meno leggibile di quello che è ora. Considerando che molti programmatori VB non si sono ancora abituati a Option Explicit, non lo considero certo un progresso.
La seconda considerazione, anche più importante, è che in realtà non mi pare che l'introduzione di Linq (e delle feature accessorie che porta in dote) serva a risolvere una esigenza realmente sentita tra gli sviluppatori. Da anni si scrivono applicazioni super-complesse usando i linguaggi tipo SQL per manipolare i dati e i linguaggi "tradizionali" come VB e C# per tutto il resto. Il problema non è nella sintassi con cui si accede ai dati, lo è nel fatto che è difficile mappare un paradigma "a oggetti" basato su relazioni uno-a-uno e uno-a-molti (le collection) in memoria con una memorizzazione in un db relazionale. Sarebbe bello avere un unico linguaggio per entrambi i compiti, ma almeno con i database relazionali forse questa fusione è semplicemente impossibile. Non mi pare che Linq risolva questi problemi.
La dimostrazione indiretta che questa convivenza è molto difficile è data dal fallimento del progetto ObjectSpaces, sulle cui versioni alfa si sono sprecati fiumi di inchiostro e ore e ore di sessioni alla conferenze varie. Ricordo le mie discussioni con amici e colleghi alla PDC 2003, ero quasi l'unico ad avere riserve mentali su quella meravigliosa tecnologia del futuro, proprio per i motivi sopra detti. Si è visto come è andata a finire.
Per fortuna, insieme alle feature appena descritte, il VB è stato espanso anche per colmare le (pochissime) differenze esistenti con il C# 2.0, ad esempio il supporto nativo per i nullable type e il rilassamento dei delegate. Non aggiungeranno gli iterators, almeno al momento, e anche il supporto per i metodi anonimi non è sicuro. D'altra parte i tipi nullable in .NET 2.0 sono praticamente inutili e gli iterator servono a un programmatore su mille. I metodo anonimi - o meglio, le lamba functions come dovrebbero chiamati - sono decisamente più interessanti, ma sono anche una pericolosi, soprattutto quando li si usa per registrare "al volo" dei gestori di eventi che non possono mai essere de-registrati. In mano a programmatori meno che accorti saranno soprattutto in grado di fare proliferare i bug.
Insomma, mi sembra che i linguaggi più diffusi nel mondo Windows stiano andando in una direzione molto accademica e molto poco pratica. Io non sono un esperto di linguaggi di programmazione, ma mi scontro quasi quotidianamente contro qualche limite del linguaggio VB o C# (intendo i limiti che non si possono superare semplicemente scrivendo una libreria esterna). Ad es. manca la possibilità di compilare al volo e aggiungere metodi e proprietà a una classe (e non solo nuove classi, come si può fare mediante Reflection.Emit). Se fosse possibile implementare una interfaccia in una classe già esistente (e già compilata in una DLL), potrei rendere serializable, remotizzabile o disposable una classe che non lo è. Le partial class di VS2005 non aiutano in questo caso e dagli esempi che ho visto neanche le dynamic interfaces di VB9 e C#3 saranno in grado di farlo.
Un'altra feature che sarebbe utile è l'aggiunta al volo di attributi a una classe o a un suo membro, il che permetterebbe ad esempio di variare il livello transazionale di un ServicedComponent o di decidere esattamente quali membri serializzare. Mi piacerebbe anche che il mio linguaggio includesse un valutatore di espressioni che sappia interpretare una stringa contenente operatori, chiamate a metodi e soprattutto variabili definite nel programma. (Quello è un tipo di late-binding che accetterei volentieri.) Oppure un meccanismo built-in per intercettare tutte le chiamate ai membri di una classe già compilata, una specie di oggetto proxy universale. Visto che sto sognando ad occhi aperti, gradirei tanto anche un meccanismo che permetta di influire sul processo di JIT-compilation e qualche hint per l'ottimizzazione del codice. Anche i generics dovrebbero essere resi più potenti di quel che sono oggi. (Ho scritto a proposito di questi limiti in questo post e in questo post). E perchè non la possibilità di scrivere codice IL inline?
Per il momento niente di tutto questo. Accontentiamoci di Linq e aspettiamo la prossima PDC 
di Francesco BalenaQuasi per caso oggi ho scoperto questo sito che è una vera miniera d'oro. Si tratta di How-to-Select Guides (http://www.howtoselectguides.com) e contiene una serie di guide professionali (e l'enfasi è davvero meritata) che spiegano come scegliere un tool di sviluppo di un certo tipo. I documenti non si limitano a descrivere i vari prodotti esistenti, ma spiegano anche quali sono le feature più importanti in quel particolare settore (data grid, charting, report) e mettono poi a confronto i prodotti specifici. Guardate ad esempio a colpo d'occhio come sono confrontate le librerie per generare PDF.
Oggi ho letto per intero la loro guida agli obfuscator ed è fatta benissimo. Non per niente, tutte le guide in questione sono scritte da autori professionisti come Mike Gunderloy e Don Kiely, che hanno una reputazione da difendere e non scrivono fesserie. Tanto per dirne una, spiegano anche quando non usare un prodotto del genere e includono anche prodotti freeware quando ve ne sono.
Oltre alla guida sugli offuscatori, attualmente sono disponibili solo la guida ai vari tipi di licenza di Visual Studio e e la succitata guida alle librerie PDF. Però sono già in preparazione molte altre guide. Un ulteriore conferma della serietà con cui è fatto il sito è che per ciascuna delle future guide è menzionata la data in cui sarà disponibile, e fino ad ora sembra che le deadline passate sono state rispettate. Ci sono anche dei forum pubblici, quindi i lettori e le case produttrici hanno la possibilità di rettificare quanto scritto.
Il sito è una idea di Mike Schinkel, il fondatore di XTras, una nota azienda che distribuisce tool per programmatori. Eppure non ci sono pubblicità di Xtras sul sito, e ho notato che sono recensiti anche molti prodotti che non sono nel catalogo di Xtras. Quando si dice che la classe non è acqua Spero che abbia il successo che si merita!
di Francesco BalenaIl nostro Sodoku online continua ad andare molto forte, a giudicare dal traffico che sta generando e dal fatto che, se provate a fare una ricerca su Google.it per la parola sodoku è sempre al primo posto o comunque tra le prime posizioni. Ma la cosa più gratificante, per quanto mi riguarda, è che in molti hanno deciso di scaricare il sorgente del programma Win32, per studiarselo. Ad occhio e croce a tutt'oggi il programma è stato scaricato da alcune migliaia di persone.
Qualcuno dei più intrepidi ha anche deciso di modificarlo per i propri scopi. Ad esempio, Roberto Giacomelli lo ha riscritto in C# modificando l'algoritmo per usare la ricorsione (leggete il suo post sull'argomento). Michele Ciboddo ha invece lasciato il programma in VB ma lo ha migliorato risolvendo un bug e soprattutto estendendolo alle griglie 16x16. Ecco un frammento della sua mail:
Per cercare di capire meglio il codice del SodokuSolver, ho provato a modificarlo aumentando le celle. Sono passato da 9x9 a 16x16 con sezioni di 4x4. In pratica è un sodoku esadecimale (le cifre ammesse vanno da 1 a G invece che da 0 a F). Il gioco funziona anche in questa modalità anche se ho dovuto abbassare a 20000 il terzo parametro del metodo FindSolutions per non impallare il computer. Quando ci sono troppe soluzioni l’occupazione della ram va alle stelle. Ho notato che il programma (anche l’originale) segnala “nessuna soluzione” quando lo schema ha una sola soluzione possibile. Nelle spiegazioni comunque la soluzione viene riportata. Ho risolto passando 0 come secondo parametro di FindSolutions invece di 1.
Ecco qui il sorgente modificato e il nuovo eseguibile: SodokuSolver16x16.zip (351.71 KB)
Ho anche corretto in bug nella mia versione originale, che può essere scaricata da questa pagina.
di Francesco BalenaOggi sul Corriere ho trovato un articolo davvero interessante, riguardante il sito www.lulu.com.
In breve, questi signori di Lulu hanno avuto una idea davvero geniale: sono degli editori (molto poco tradizionali) che non pongono alcuna barriera a chi vuole diventare un autore di libri (ma non solo libri), neanche barriere di tipo economico. Ecco come funziona il processo:
1) un autore spedisce un documento word e decide come deve essere la copertina, la rilegatura, ecc. 2) mentre l’autore aspetta al browser, loro creano in automatico il PDF e calcolano i costi vivi di stampa 3) quando l’autore conosce il costo, può decidere il margine e quindi il costo di copertina, oppure può decidere di venderlo solo in formato elettronico 4) il libro diventa quindi parte del catalogo di Lulu, che lo può vendere sul suo sito ma può anche venderlo tramite altre librerie che glielo richiedono, incluso librerie online come Amazon 5) a differenza di quello che fanno tanti piccoli editori locali, NON CI SONO COSTI DI SETUP nè ordini minimi di un certo numero di copie: la stampa avviene infatti on-demand. I costi di stampa sono pero' ridotti se si ordinano un certo numero di pezzi. 6) i ricavi vengono divisi in questo modo : 80% all’autore, 20% a Lulu
La divisione delle royalties è davvero notevole, se si pensa che un autore "medio" (ossia che non fa di cognome Grisham o King) non riesce a spuntare più del 12-15% del margine, che poi normalmente è l'8-10% del prezzo di copertina.
Non sto (ovviamente) pensando di scrivere il mio prossimo manuale su .NET con un editore come Lulu, nè penso che qualche altro autore affermato sceglierà mai questo editore per i propri libri, perchè non dà l'autorevolezza di un libro Microsoft Press o Addison Wesley. Però l'iniziativa è davvero molto interessante ed è indicativa di come Internet sta modificando il mondo dell'editoria tradizionale.
E comunque, anche un autore "di professione" potrebbe trovare utile questo meccanismo almeno in un paio di casi: a) per scrivere un libriccino di poche pagine che nessun grande editore ci vuole comprare b) per rendere disponibile al pubblico un "instant book" in pochi giorni, senza aspettare i 3-4 mesi richiesti dal solito iter necessario con editori normali.
Ovviamente, tutto questo discorso ha un senso per chi scrive in inglese, perchè farsi spedire i libri dall'america costa molto più che stamparseli uno per uno a casa con una inkjet. Però, se siete italiani e scrivete in inglese, un editore/rivenditore come Lula offre un vantaggio notevole: se volete vendere un libro o un CD autoprodotto dall’italia al pubblico americano, i costi di spedizione sono talmente alti che nessun americano lo comprerà mai. Se però lo vendete tramite Lula, i costi di spedizioni sono acccettabili, e inoltre non avete le rogne di dover stampare, masterizzzare, ecc.
di Francesco BalenaMi ha scritto mio amico Marco de Salvo, coautore di alcuni libri per Mondadori - tra cui Windows XP Service Pack 2 alla massima potenza e Dal DVD al CD con un click, di cui ho avuto l'onore di scrivere la prefazione. Marco mi segnala una nuova sezione del suo sito, dedicata alle prove di gadgets hardware non facilmente trovabili (e non solo accessori per computer).
La nuova sezione non è troppo estesa ma cresce velocemente. Vale la pena dare una occhiata al SoundBag, un trasduttore sonore che può trasformare i vostri tavoli e finestre in altoparlanti (ottimo se alloggiate in albergo e vi secca portarvi dietro una coppia delle vostre Bose preferite) e dello X-zylo, un cilindro ruotante di plastica che può volare anche per 200 metri. Per uno come me che è cresciuto a colpi di freesbee è una vera tentazione 
di Francesco BalenaUn paio di settimane fa annunciavo in questo post la pubblicazione di una applicazione ASP.NET in grado di risolvere un qualsiasi schema di Sodoku, mediante un semplice algoritmo di backtracking. Da allora ho ricevuto un buon numero di richieste di pubblicare il sorgente, quindi appena ho avuto un oretta libera ho ripulito il codice per renderlo presentabile e ho aggiunto un po' di commenti. Ho anche creato una applicazione Windows Forms con una interfaccia utente più che decorosa, che ha tutte le feature della versione online e in più la possibilità di salvare e ricaricare degli schemi di Sodoku.
Potete scaricare l'intero progetto VB.NET 2003 da questo link, oppure solo l'eseguibile Windows da quest'altro link. Con il sorgente troverete un piccolo articolo in formato Word che spiega come funziona l'algoritmo.
Potete redistribuire sia il codice che l'eseguibile a chi volete, purchè non modificate il logo della azienda e il testo di copyright. Se usate il codice in un vostro programma, per piacere menzionate l'origine del codice e inserite un link a questo post.
Buon divertimento con il Sodoku! Per quanto mi riguarda, dopo aver scritto un programma che risolve il gioco in una frazione di secondo, buona parte dell'interesse si è dissolto. Niente a che vedere con le parole crociate senza schema della cara vecchia Settimana Enigmistica... fossi mai riuscito a completarne una! 
UPDATE: Michele Giboddo mi ha segnalato un bug nel programma, che segnala erroneamente "nessuna soluzione" quando invece lo schema ha esattamente una soluzione. Per maggiori informazioni leggete questo post. I link al sorgente ed eseguibile in questa pagina puntano già alla versione corretta.
di Francesco BalenaVolete la versione corta o la versione lunga di questo post? Se conoscete già il gioco del Sodoku, potete optare per la versione corta e saltare a questa pagina: www.dotnet2themax.it/sodoku/default.aspx. Altrimenti continuate a leggere.
È probabile che molti di voi conoscano il gioco del Sodoku o abbiano già provato a risolvere uno dei problemi che appaiono ogni giorno su La Repubblica o Il Corriere della Sera. Se invece non ne avete mai sentito parlare, potete leggere le regole e trovare qualche problema di esempio in questa pagina.
Riassumendo, si tratta di un gioco di abilità e pazienza, basato su una griglia di 81 caselle, suddivisa in 9 righe, 9 colonne e 9 sottosezioni di 3x3. Le regole del gioco sono semplicissime: ogni casella può contenere una cifra da 1 a 9, e ogni riga, colonna o sottosezione deve contenere tutte le cifre 1-9, senza alcuna cifra mancante o ripetizione. Un problema di Sodoku consiste in una griglia riempita solo parzialmente, dove il risolutore deve ovviamente riempire le celle vuote in modo che le regole siano rispettate. A seconda del numero e del contenuto delle celle riempite inizialmente il gioco può avere una sola soluzione, oppure più d'una. Ecco ad esempio l'unica soluzione del gioco apparso sulla Repubblica del 25 Giugno:
+---+---+---+ |635|247|189| |817|935|624| |294|186|537| +---+---+---+ |352|869|471| |971|524|863| |468|371|952| +---+---+---+ |749|653|218| |583|412|796| |126|798|345| +---+---+---+
Il gioco del Sodoku ha spopolato in Giappone, ma anche nel resto del mondo sembra che stia partendo una vera e propria mania del Sodoku, paragonabile forse a quella che anni fa impazzava per il Cubo di Rubik. Sul sito del Corriere è anche disponibile un forum per gli appassionati di Sodoku e recentemente è anche dovuto intervenire il grande Stefano Bartezzaghi per chiarire qualche aspetto del gioco relativo alla unicità delle risposte.
Devo essere sincero: nonostante tutta questa febbre collettiva, non credo che il Sodoku sia poi così interessante. Alla fine si tratta di stabilire una strategia per provare le varie mosse a disposizione nelle celle e continuare così fino a quando non si cade in contraddizione (non vi sono valori disponibili per una cella) oppure si trova una soluzione. Insomma, alla fine tutti i problemi Sodoku si assomigliano e cambia solo il tempo necessario per risolverli. Non mi stupisce che il gioco stia conoscendo un periodo fortunato proprio in estate, quando la gente non sa bene cosa fare sotto l'ombrellone 
Facevo queste riflessioni, mentre mi prendevo una pausa dopo aver completato il capitolo 15 del mio librone su Visual Basic 2005. Un programma per risolvere uno schema di Sodoku non è difficile da scrivere: basta applicare le solite tecniche di esplorazione di un albero di soluzioni e di backtracking quando si arriva a una contraddizione. Questo dovrebbe provare tra l'altro che non sono richieste particolari doti di intuizione o esperienza: insomma, niente di paragonabile non dico a dama e scacchi, ma neanche semplicemente a un solitario con le carte.
Per farla breve, mi sono armato di Visual Basic 2003 e dopo un paio di ore avevo il mio bel Sodoku Solver funzionante! Non è stato neanche necessario ricorrere a chissà quali tecniche di ottimizzazione, dato che sul mio Pentium 4 il programma risolve un problema con oltre 100mila soluzioni (e le elenca tutte!) in meno di una decina di secondi! Il passo successivo è stato creare una versione Web, che possa essere giocabile da chiunque senza dover installare tutto il .NET Framework. La potete trovare su questo sito a questo indirizzo: www.dotnet2themax.it/sodoku/default.aspx.
La cosa interessante è che il programma mostra non soltanto le soluzioni ma descrive anche la strategia adottata per arrivare al risultato. In questo modo il programma può funzionare anche come strumento didattico per insegnare a risolvere il Sodoku con carta e penna. Sulla pagina troverete anche qualche problema di esempio. Si può usare il programma anche per creare nuovi problemi: basta inserire un po' di celle a casaccio e cliccare sul pulsante "Risolvi", aggiungendo caselle fino a quando non si arriva ad una soluzione unica, oppure svuotandone qualcuna se il programma indica che lo schema corrente non porta ad alcuna soluzione.
La strategia che applica il programma è così semplice da poter essere riassunta in poche righe, almeno per chi è pratico degli algoritmi di backtracking:
- Partendo dalla griglia corrente, si riempiono tutte le caselle obbligate, dove una "casella obbligata" è quella per cui non esistono alternative in quanto vi è solo una cifra nell'intervallo 1-9 che NON appare nella riga, colonna e sottosezione a cui la cella appartiene.
- Si esplorano tutte le celle libere, tenendo traccia di quante mosse alternative vi sono per ciascuna di esse.
- Si sceglie la cella con il numero minimo di alternative (di solito vi sono molte celle con due sole alternative) e si ipotizza di assegnare la prima di queste alternative alla cella. Quando questo accade si dice che si sta passando al livello di ipotesi successivo (N+1), si ottiene un nuovo schema e si ripete il ciclo dal passo 1.
- se l'ipotesi corrente porta a una contraddizione, ossia porta a una situazione in cui non vi è alcuna alternativa valida per una delle celle libere, allora evidentemente l'ipotesi al livello corrente non è corretta: occorre tornare al livello precedente (N-1) e provare un'altra mossa per la cella scelta al passo 3.
OK, questo è tutto. Se siete interessati ad altri dettagli sul gioco o del mio programma , lasciate pure un commento.
di Alberto FalossiIl fenomeno dei blog sta prendendo sempre più piede.
Altro che diario personale, i blog stanno diventando veri e propri strumenti marketing! Non è un caso che grandi società come Microsoft, Sun, Ford abbiano più o meno frettolosamente aperto un blog, per favorire ulteriormente il contatto con le community. In effetti, stanno iniziando ad essere pubblicati dei libri (come quello di Scoble) che analizzano i blog dal punto di vista business.
Eppure il pubblico non sa ancora cos'è un blog. I tecnici forse, ma la massa no. E' evidente che manca ancora... che cosa?
Circa un anno fa, in occasione del Whidbey and Security Day di Firenze, ero a pranzo con Daniele e Cristian e qualcuno fece la stessa domanda. Allora i blog erano "molto di nicchia" e una buona parte dei tecnici ancora non li conosceva.
La mia risposta fu: "I blog si diffonderanno quando Microsoft metterà un RSS Aggregator in Outlook". Poter gestire i feed con gli strumenti di tutti i giorni permette di abbattere le barriere all'adozione. Quando dal browser si clicca su un feed URL, viene aperto Outlook (come quando si clicca su un indirizzo email) che una MessageBox chiede se sottoscriverlo. Quando si preme Send/Receive, i feed vengono aggiornati.
In circolazione ci sono già degli add-on che integrano Outlook: però sono di terze parti e spesso a pagamento. Avere un Outlook Espress (e Outlook 2003) che gestisce di default email, newsgroup e feed sarebbe secondo me l'ideale. Integrazione è la parola chiave. Oggi uso NewzCrawler perchè permette di gestire contemporaneamente RSS e newsgroup.
Non è un caso che Apple, con il suo browser Safari si sia mossa in questa direzione: Safari ha un RSS aggregator integrato, che viene sbandierato come caratteristica più importante nella pagina di overview!
E (finalmente...) anche Microsoft ha annunciato il supporto RSS per Longhorn e IE7 (vedi articolo di WindowsITPro). E non è tutto:
"Longhorn will also support programming APIs that make RSS content available to any application. Today, Microsoft will demonstrate a simple application that connects Microsoft Office Outlook to RSS feeds, providing continuously updated calendar items. It seems likely that the next version of Outlook, which will ship next year as part of Office 12, will support this functionality natively, [...]"
(considerazioni/reazioni all'annuncio raccolte da Scoble)
Non ci resta che vedere se la direzione è quella giusta.
|
|
Feed di Blog2theMax
Cerca nel blog
Archivio
| | Sun | Mon | Tue | Wed | Thu | Fri | Sat | | 28 | 1 | 2 | 3 | 4 | 5 | 6 | | 7 | 8 | 9 | 10 | 11 | 12 | 13 | | 14 | 15 | 16 | 17 | 18 | 19 | 20 | | 21 | 22 | 23 | 24 | 25 | 26 | 27 | | 28 | 29 | 30 | 31 | 1 | 2 | 3 | | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
Categorie
Powered by: newtelligence dasBlog 1.7.5016.2
|