Workshop UGISS ad Alessandria


Oggi ad Alessandria si è svolto il workshop UGISS [ http://www.ugiss.org/Content/Event/Workshop-UGISS-R2-Alessandria.aspx ]. Vorrei ringraziare tutti gli speaker per la loro disponibilità e competenza: Davide Mauri, Gianluca Hotz, Andrea Benedetti, Marco Russo e Alberto Ferrari. Professionisti davvero eccezionali che hanno reso possibile la realizzazione di un evento in una sede (Università) e luogo (Alessandria) insoliti.

Un grazie anche ai partecipanti che sono accorsi numerosi.

author: Daniele Mantovani | posted @ venerdì 15 gennaio 2010 23.08 | Feedback (0)

"Subclassing" attraverso l'overload di cast implicito


Si immagini di voler creare una versione specializzata di cookie MyCookie.

La scelta più intuitiva è quella di scrivere una classe MyCookie che eredita da System.Web.HttpCookie

public class MyCookie : System.Web.HttpCookie
{
    // ...
}

 

per poi usarla in questo modo

MyCookie cookie = new MyCookie();
Response.Cookies.Add(cookie);

 

Purtroppo HttpCookie è sealed e quindi non estendibile.

Volendo preservare la precedente sintassi, è tuttavia possibile creare una sorta di "subclassing" facendo l'overload dell'operatore di cast implicito da MyCookie a HttpCookie. Questo consente di utilizzare MyCookie laddove è richiesta una istanza di HttpCookie.

public class MyCookie 
{
    public static implicit operator HttpCookie(MyCookie cookie)
    {
        return new HttpCookie(...);
    }
}

 

author: Daniele Mantovani | posted @ martedì 7 aprile 2009 23.13 | Feedback (1)

Brahma


Brahma è una interessante libreria open-source, scritta per .Net 3.5, il cui scopo è quello di fornire un modello di programmazione astratto per fare calcolo parallelo.
Implementa un modello a provider che la rende aperta verso diversi "processori" per il calcolo.
Di suo offre un provider che sfrutta, tramite DirectX, la GPU.

author: Daniele Mantovani | posted @ venerdì 24 ottobre 2008 23.42 | Feedback (0)

La notte dei ricercatori (Università del Piemonte Orientale)


La notte dei ricercatori

author: Daniele Mantovani | posted @ domenica 21 settembre 2008 17.29 | Feedback (1)

Real World Functional Programming


Vorrei segnalare un libro che sto leggendo nei ritagli di tempo: Real World Functional Programming.
Non è ancora completo ma i primi capitoli sono già disponibili (a pagamento) in formato elettronico. E' un libro interessante e con un taglio originale. Tratta dello stile di programmazione funzionale, argomento che sta acquistando importanza per diverse ragioni (vedi LINQ, PLINQ, PFX, ...).

author: Daniele Mantovani | posted @ mercoledì 3 settembre 2008 18.35 | Feedback (0)

How I got Started in Software Development


Rispondo anche io all'invito di Gianluca...

A quale età hai cominciato a programmare?

A 12 anni nell'ormai lontano 1985.

Come hai cominciato a programmare?

Le mie prime esperienze con la programmazione coincidono con i primi contatti con il computer. Nel 1985, i miei genitori mi regalarono un corso di informatica con computer annesso (la marca del computer in dotazione era "Laser", computer dei quali non ho più sentito parlare). Il mio interesse iniziale è stato, come per molti, la curiosità verso i videogame. Nel corso mi furono insegnati i rudimenti di BASIC con il quale cominciai a fare i primi esperimenti, o per meglio dire, improvvisazioni. Siccome era complesso inventare dei programmi, ho preferito imparare copiando dei listati da riviste che in quel periodo spopolavano (chi ricorda il mitico "List"?!).

Qual’è stato il tuo primo linguaggio di programmazione?

BASIC.

Qual’è stato il primo programma vero che hai scritto?

Non ne sono certo ma credo che il primo programma "vero" fosse un semplice videogame, nel quale un personaggio costruito a - puzzle di - caratteri doveva rincorrere un oggetto in movimento nel tentativo di acchipparlo.

Quali linguaggi hai usato da quando hai cominciato a programmare?

In ordine temporale:

BASIC, Turbo Pascal, Assembler Z80, Assembler Motorola 68000, C, Basic di Microsoft Access 2.0, Lisp/Scheme, Prolog, ML, C++, Visual Basic 5 e 6, VBScript, JavaScript, C#

Quando è stato il tuo primo vero lavoro da programmatore?

Nel 1994, insiemi ad alcuni amici e compagni di Università, ricevemmo l'incarico di sviluppare un'applicazione per la gestione delle attività (chi fa che cosa, per quanto tempo, quando, ...) del personale interno all'azienda committente. L'applicazione continuò ad essere utilizzata fino al 1999.

Con il senno di poi, rifaresti lo stesso il programmatore? Ricominceresti a programmare?

Probabilmente sì visto che l'informatica è sempre stata la mia passione principale. Ho però un po' di rammarico per le altre passioni che ho un po' accantonato: la matematica e la fisica.

Se ci fosse una cosa che hai imparato nella tua carriera e che vorresti dire ai giovani programmatori, cosa diresti?

Lavorate con passione. Non accontentatevi: continuate a dedicare tempo all'apprendimento e siate sempre alla ricerca di un lavoro stimolante. Lavorate con umiltà: c'è sempre qualcuno che ha qualcosa da insegnarvi. Se potete trasmettere qualcosa di appreso a qualcuno, fatelo: trasparenza, comunicazione e sincerità sono doti essenziali.

Qual’è la cosa più divertente che hai programmato?

Probabilmente all'Università nel corso di linguaggi formali: un compilatore, per una variante del Pascal, che doveva produrre codice macchina da far girare su un simulatore di un processore simil Z80.

Adesso è l’ora di taggare qualcun’altro...

Davide Senatore

Cristian Bressan

Marco Minerva

Fulvio Canepari

Nicolò Carandini

Stefan Demetz

author: Daniele Mantovani | posted @ martedì 15 luglio 2008 23.13 | Feedback (0)

Custom DropDownList simile a ListViewSelector in SharePoint


La toolbar, presente di norma su tutte le liste SharePoint (quindi anche le Document Library), mostra una DropDownList che permette di selezionare la vista da applicare:

ListViewSelector

Comportamento e aspetto grafico di questa DropDownList sono implementati nel controllo Microsoft.SharePoint.WebControls.ListViewSelector.
Questo controllo è riutilizzabile se si vuole permettere la selezione di una vista di una lista.
E se invece si volesse semplicemente imitarne l'aspetto grafico?
Curiosando un po' è possibile notare qual è l'HTML generato:

<table border="0" cellpadding="0" cellspacing="0">
<tr>
    <td nowrap="nowrap" onmouseout="this.className='ms-viewselector'" class="ms-toolbar ms-viewselector" id="SomeID">
        <span style="display: none;">
            <menu compactmode="true" id="SomeID_Menu" type="ServerMenu">
                <ie:menuitem _moz-userdefined="" menugroupid="100" text="One" onmenuclick="alert('One');" type="option" />
                <ie:menuitem _moz-userdefined="" menugroupid="300" text="Two" onmenuclick="alert('Two');" type="option" />
                <ie:menuitem _moz-userdefined="" menugroupid="400" text="Three" onmenuclick="alert('Three');" iconsrc="/_layouts/images/modifyview.gif" type="option" />
                <ie:menuitem _moz-userdefined="" menugroupid="400" text="Four" onmenuclick="alert('Four');" iconsrc="/_layouts/images/createview.gif" type="option" />
            </menu>
        </span>
        <span title="Open Menu">
            <div nowrap="nowrap" oncontextmenu="this.click(); return false;" foa="MMU_GetMenuFromClientId('SomeID_Anchor')" onclick="MMU_Open(byid('SomeID_Menu'), MMU_GetMenuFromClientId('SomeID_Anchor'),event,true, 'SomeID', 0);" hoverinactive="ms-viewselector" hoveractive="ms-viewselectorhover" onmouseover="MMU_PopMenuIfShowing(this);MMU_EcbTableMouseOverOut(this, true)" class="ms-viewselector">
                <a serverclientid="SomeID_Anchor" menutokenvalues="MENUCLIENTID=SomeID_Anchor,TEMPLATECLIENTID=SomeID_Menu" oncontextmenu="this.click(); return false;" onclick="javascript:return false;" onkeydown="MMU_EcbLinkOnKeyDown(byid('SomeID_Menu'), MMU_GetMenuFromClientId('SomeID_Anchor'), event);" onfocus="MMU_EcbLinkOnFocusBlur(byid('SomeID_Menu'), this, true);" style="cursor: pointer; white-space: nowrap;" href="#" accesskey="W" id="SomeID_Anchor">
                    All Documents
                    <img border="0" alt="Use SHIFT+ENTER to open the menu (new window)." src="/_layouts/images/blank.gif" />
                </a>
                <img align="absbottom" alt="" src="/_layouts/images/blank.gif" />
            </div>
        </span>
    </td>
</tr>
</table>

In particolare è possibile notare come sia sufficiente aggiungere elementi del tipo

<ie:menuitem _moz-userdefined="" menugroupid="100" text="One" onmenuclick="alert('One');" type="option" />

per avere ulteriori scelte nella DropDownList.
onmenuclick permette di definire il codice JavaScript da eseguire quando si sceglie quel particolare elemento.
text definisce il testo dei singoli item.
menugroupid permette di raggruppare più elementi (quelli che hanno pari valore di menugroupid).
E' inoltre possibile visualizzare, a fianco di ciascun item, una immagine.
A questo punto il gioco è fatto: basta implementare un proprio WebControl in grado di produrre codice HTML simile a quello mostrato.

author: Daniele Mantovani | posted @ giovedì 22 maggio 2008 1.06 | Feedback (0)

Parallel C#


La diffusione dei processori multi-core, anzi many-core, offre nuove opportunità a tutti gli sviluppatori e non più soltanto ad una élite di persone operanti in settori di nicchia (calcolo scientifico, ...).
Per sfruttare in modo efficace queste opportunità è necessario un nuovo grado di astrazione nei linguaggi e paradigmi di programmazione: operare con i concetti quali concorrenza, sincronizzazione, ... ad alto livello senza doversi preoccupare di "dettagli" di basso livello (lock, semafori, ...).

Le problematiche non sono di facile soluzione. Questo ha dato origine ad una serie di filoni di ricerca, alla cui base spesso ci sono scelte piuttosto differenti.
In questo panorama Microsoft si pone con un atteggiamento che, a mio avviso, cerca di equilibrare aspetti innovativi di ricerca con una buona dose di pragmatismo. A tal proposito si può ad esempio dare un'occhiata alle cosiddette PFX (Parallel Extensions to the .Net Framework 3.5), PLINQ, ... Questi lavori tentano, almeno al momento, di catturare le peculiarità del calcolo parallelo sotto forma di librerie di codice.
Ci sono altri progetti, di cui "Parallel C#" è sicuramente un esemplare interessante, che invece si ripropongono di estendere i linguaggi di programmazione stessi al fine di incorporare le astrazioni del caso.

author: Daniele Mantovani | posted @ martedì 13 maggio 2008 23.31 | Feedback (10)

Paginazione dei risultati di una query


Il problema di dover paginare i risultati di una query a SQL Server (ma più in generale ad un qualunque DBMS) ricorre spesso, specialmente nelle applicazioni distribuite dove è fondamentale ridurre al minimo la quantità di dati trasportati sul canale.
SQL Server 2005 offre alcuni operatori SQL che permettono di costruire uno "schema" per tradurre una qualunque query nella equivalente versione che restituisce la sola pagina di dati voluta.
Supponiamo ad es. di voler paginare i dati della seguente query (Northwind):

SELECT *
FROM Customers
ORDER BY CustomerID ASC

Isoliamo la clausola ORDER BY dal resto della query ottenendo quindi qualcosa del tipo

SELECT *
FROM (
    SELECT
        *,
        ROW_NUMBER() OVER (ORDER BY CustomerID ASC) AS [_RowNum]

    FROM Customers
    ) AS T
WHERE [_RowNum] BETWEEN @Min AND @Max
ORDER BY [_RowNum] ASC

I colori mostrano le parti della query SQL prima e dopo la trasformazione. I parametri @Min e @Max devono essere sostituiti rispettivamente con l'indice del primo record e dell'ultimo record della pagina desiderata.
Lo schema indicato, con alcune limitazioni (ad es. è obbligatorio specificare esplicitamente la clausola ORDER BY), permette di trasformare una query complessa a piacere nell'equivalente paginabile. Detto questo, è possibile costruire una stored procedure che, facendo uso degli statement SQL dinamici, permette di paginare i risultati di una qualunque query:

CREATE PROCEDURE [dbo].[spQuery]
    @Sql NVARCHAR(MAX) = N'',
    @OrderBy NVARCHAR(MAX) = N'',
    @PageNumber INT = 1 OUT,
    @PageSize INT = 0,
    @NoRecordCount SMALLINT = 0,
    @RecordCount INT = 0 OUT
AS
    DECLARE @SqlString NVARCHAR(MAX)
    DECLARE @PageCount INT
    DECLARE @Min INT
    DECLARE @Max INT
    DECLARE @RowNum INT

    SET @Sql = LTRIM(RTRIM(ISNULL(@Sql, N'')))
    IF @Sql = N''
        RETURN 1 -- Missed Sql.

    SET @OrderBy = LTRIM(RTRIM(ISNULL(@OrderBy, N'')))
    IF @OrderBy = N''
        RETURN 2 -- Missed OrderBy.

    IF @PageNumber <= 0
        SET @PageNumber = 1

-- Vengono contati i record.
    SET @RecordCount = -1
    IF @NoRecordCount = 0
        BEGIN
            SET @SqlString = N'SELECT @RecordCount = COUNT(*) FROM (' + @Sql + N') AS T'
            EXEC sp_executesql @SqlString, N'@RecordCount int out', @RecordCount OUT
        END

-- Se occorre contare i record...
    IF @PageSize = 0
        BEGIN
            SET @PageCount = 1
            SET @PageNumber = 1
        END
    ELSE
        BEGIN
            IF @RecordCount < 0
                BEGIN
                    SET @PageCount = 0
                END
            ELSE
                BEGIN
                    SET @PageCount = CEILING(CAST(@RecordCount AS FLOAT) / CAST(@PageSize AS FLOAT))

        -- @PageNumber = 0  => ultima pagina
        -- @PageNumber = N  => N-esima pagina o ultima se @PageNumber > @PageCount
        -- @PageNumber = -N => @PageNumber = @PageCount - N (penultima, ...)
        -- Se alla fine @PageNumber < 0 => @PageNumber = @PageCount
                    IF @PageNumber <= 0
                        OR @PageNumber > @PageCount
                        SET @PageNumber = @PageCount - @PageNumber
                    IF @PageNumber <= 0
                        SET @PageNumber = @PageCount
                END
        END

    -- Deve essere rimpiazzata solo la prima occorrenza di SELECT ... => SELECT ROW_NUMBER() OVER (...) AS [_RowNum]
    IF @PageSize > 0 AND @NoRecordCount <> 0
        SET @SqlString = N'SELECT TOP ' + CAST((@PageNumber * @PageSize) AS NVARCHAR(MAX)) + N' * '
    ELSE
        SET @SqlString = N'SELECT * '

    SET @SqlString = @SqlString +
        N'FROM (' +
        N'SELECT ROW_NUMBER() OVER (ORDER BY ' + @OrderBy + N') AS [_RowNum],' + SUBSTRING(@Sql, 7, LEN(@Sql) - 6) +
        N') AS T'

    IF @PageSize > 0
        BEGIN
            SET @Min = @PageSize * ( @PageNumber - 1 ) + 1
            SET @Max = @Min + @PageSize - 1
            SET @SqlString = @SqlString + N' WHERE [_RowNum] BETWEEN @Min AND @Max'
        END

    SET @SqlString = @SqlString + N' ORDER BY [_RowNum] ASC'

    EXEC sp_executesql @SqlString, N'@Min int, @Max int', @Min = @Min, @Max = @Max

    RETURN 0 -- No error.

Esempio di invocazione:

DECLARE @RC INT

EXEC dbo.spQuery
    N'SELECT * FROM Customers',    -- Query SQL a meno della clausola ORDER BY principale
    N'CustomerID ASC',             -- Clausola ORDER BY principale
    1,                             -- Numero di pagina voluto (pagina 1 di ...)
    3,                             -- Numero di record per pagina (3 record per pagina)
    0,                             -- Mi interessa avere il conteggio dei record totali (senza paginazione)
    @RC OUT                        -- Numero di record totali

author: Daniele Mantovani | posted @ martedì 25 marzo 2008 23.55 | Feedback (0)

SharePoint, ListView Control e Toolbar


SharePoint offre il controllo ListView (namespace controllo Microsoft.SharePoint.WebControls) che è possibile utilizzare per renderizzare una qualunque SPList all'interno di una pagina, di una Web Part custom, ... Es:

SPList list = SPContext.Current.Web.Lists["Company documents"];
ListView lv = new ListView();
lv.ListId = list.ID.ToString();
lv.ViewId = list.DefaultView.ID.ToString();
Controls.Add(lv);



Se l'utilizzo di ListView è semplice e intuitivo, è invece meno banale capire qual è il controllo da utilizzare per renderizzare la toolbar della SPList.



Il seguente frammento di codice illustra il funzionamento di ViewToolbar, il controllo che renderizza appunto la toolbar:

SPList list = SPContext.Current.Web.Lists["Company documents"];

ViewToolBar toolbar = new ViewToolBar();
SPContext context = SPContext.GetContext(this.Context, list.DefaultView.ID, list.ID, SPContext.Current.Web);
toolbar.RenderContext = context;
Controls.Add(toolbar);

author: Daniele Mantovani | posted @ venerdì 14 marzo 2008 0.22 | Feedback (5)