Innanzitutto premettiamo che il metodo visto si può applicare alle righe di un testo, come alle parole, alle lettere, ai puntini che compongono un'immagine, a qualsiasi cosa.
I siti come Dropbox, Google, Mega, offrono di ospitare i vostri file e, ogni volta che aggiornate un file, di mantenere le versioni precedenti. Per risparmiare spazio, invece di avere più copie di file con piccole differenza, mantengono nei loro archivi solo un file e le successive differenze.
Anche nei formati video digitali, ogni 5 fotogrammi, abbiamo i dati di un fotogramma intero e solo le differenze per i successivi 4 fotogrammi; sempre per ridurre spazio.
Trovare le differenza ci serve anche in biologia e medicina, per capire cosa è effettivamente cambiato in un DNA, da una specie ad un'altra, o una lunga molecola organica come si è modificata.
Nel campo dell'informatica, si possono mandare solo i DIFF di un programma, e i programmi di patch, applicheranno solo le modifiche; in questo modo non c'è bisogno di inviare tutto il programma.
Ora vediamo di creare un programma che ci faccia vedere le differenze fra sue testi, molto usato in informatica.
Ci basterà sfruttare il codice mostrato nell'altro post, aggiungendo il solo il modo di colorare il testo.
Otterremo un programma simile a questo:
Nelle due colonne in basso a destra abbiamo i due testi affiancati con le righe eliminate in rosso e quelle aggiunte in verde. Chiamando questi due campi rispettivamente: VersAdiff e VersBdiff, il codice per ottenere il testo colorato è il seguente:
on mouseUp #trasformiamo i testi in array, dove ogni riga è un elemento dell'array put the text field "versA" into tOldSource put the text field "versB" into tNewSource split tOldSource using return split tNewSource using return #cerchiamo di capire di quanti elementi, cioè righe, è fatto ogni array #extents mostra una serie di righe con due numeri, il numero minimo e il massimo per ogni dimensione dell'array #qui la dimensione è 1 put item 2 of the extents of tOldSource into tOldLineCount put item 2 of the extents of tNewSource into tNewLineCount #calcoliamo le varie sequenze con il massimo testo in comune (LCSL) put CalculateLCSLengths(tOldSource, tNewSource, tOldLineCount, tNewLineCount) into LCLS #e adesso calcoliamo il DIFF lock screen put empty into field "VersAdiff" put empty into field "VersBdiff" DetermineDiff LCLS, tOldSource, tNewSource, tOldLineCount, tNewLineCount DetermineDiff2 LCLS, tOldSource, tNewSource, tOldLineCount, tNewLineCount unlock screenend mouseUp
function CalculateLCSLengths tOldSource, tNewSource, tOldLineCount, tNewLineCount #costruiamo la tabella per il calcolo LCSL #la riga 0 è tutti 0 repeat with tRow = 0 to tOldLineCount put 0 into pLCSLength[tRow,0] end repeat #la colonna 0 è tutti 0 repeat with tCol = 0 to tNewLineCount put 0 into pLCSLength[0,tCol] end repeat #ora calcoliamo le altre varie celle della matrice LCLS repeat with tRow = 1 to tOldLineCount repeat with tCol = 1 to tNewLineCount put tOldSource[tRow] into tOldLine put tNewSource[tCol] into tNewLine if tOldLine = tNewLine then put pLCSLength[tRow - 1,tCol - 1] + 1 into pLCSLength[tRow,tCol] else put max(pLCSLength[tRow - 1,tCol],pLCSLength[tRow,tCol - 1]) into pLCSLength[tRow,tCol] end if end repeat end repeat #finito return pLCSLengthend CalculateLCSLengths
#abbiamo un messaggio che chiama se stesso parecchie volte#qui usiamo le @ per risparmiare meomoria ed evitare troppe copie della stessa variabile, però stiamo attenti a non modificarle!on DetermineDiff @pLCSLength, @pOldSource, @pNewSource, pRow, pCol put pOldSource[pRow] into tOldLine #la riga nel file originale put pNewSource[pCol] into tNewLine #la riga nella nuova versione if pRow > 0 and pCol > 0 and tOldLine = tNewLine then #sono uguali, andiamo alla cella in alto a sinistra rispetto all'attuale nel LCLS DetermineDiff pLCSLength, pOldSource, pNewSource, pRow - 1, pCol - 1 put the htmltext of field versAdiff into temp set the htmltext of field VersAdiff to ( temp & prow & "	" & tOldLine ) else if pCol > 0 and (pRow = 0 or pLCSLength[pRow,pCol - 1] >= pLCSLength[pRow - 1, pCol]) then ##caso la cella a sinistra è maggiore o uguale di quella sopra #è stata aggiunta una riga, moviamoci a sinistra nella tabella LCLS DetermineDiff pLCSLength, pOldSource, pNewSource, pRow, pCol - 1 #set the text of field uscita to (field uscita & prow& "+" & tab & tNewLine & return ) else if pRow > 0 and (pCol = 0 or pLCSLength[pRow,pCol - 1] < pLCSLength[pRow - 1, pCol]) then ##caso la cella a sinistra è minore di quella sopra #è stata rimossa una riga, saliamo di una riga nella tabella LCLS DetermineDiff pLCSLength, pOldSource, pNewSource, pRow - 1, pCol put the htmltext of field VersAdiff into temp set the htmltext of field VersAdiff to (temp &"<font bgcolor=red>" & prow & "	" & tOldLine & "</font>" ) end ifend DetermineDiff
#abbiamo un messaggio che chiama se stesso parecchie volte#qui usiamo le @ per risparmiare meomoria ed evitare troppe copie della stessa variabile, però stiamo attenti a non modificarle!on DetermineDiff2 @pLCSLength, @pOldSource, @pNewSource, pRow, pCol put pOldSource[pRow] into tOldLine #la riga nel file originale put pNewSource[pCol] into tNewLine #la riga nella nuova versione if pRow > 0 and pCol > 0 and tOldLine = tNewLine then #sono uguali, andiamo alla cella in alto a sinistra rispetto all'attuale nel LCLS DetermineDiff2 pLCSLength, pOldSource, pNewSource, pRow - 1, pCol - 1 put the htmltext of field versBdiff into temp set the htmltext of field VersBdiff to ( temp & prow & "	" & tOldLine ) else if pCol > 0 and (pRow = 0 or pLCSLength[pRow,pCol - 1] >= pLCSLength[pRow - 1, pCol]) then ##caso la cella a sinistra è maggiore o uguale di quella sopra #è stata aggiunta una riga, moviamoci a sinistra nella tabella LCLS DetermineDiff2 pLCSLength, pOldSource, pNewSource, pRow, pCol - 1 put the htmltext of field VersBdiff into temp set the htmltext of field VersBdiff to (temp & "<font bgcolor=green>" & prow & "	" & tNewLine & "</font>") else if pRow > 0 and (pCol = 0 or pLCSLength[pRow,pCol - 1] < pLCSLength[pRow - 1, pCol]) then ##caso la cella a sinistra è minore di quella sopra #è stata rimossa una riga, saliamo di una riga nella tabella LCLS DetermineDiff2 pLCSLength, pOldSource, pNewSource, pRow - 1, pCol end ifend DetermineDiff2
Possiamo renderlo graficamente più professionale facendo in modo che muovendo un solo scroller, tutte i due testi scorrano contemporaneamente, mostrando sempre proporzionalmente la stesse parti. Ci basterà levare lo scroll verticale dal campo VersAdiff, e mettere nel secondo campo (VersBdiff) il seguente codice:
on scrollbardrag tdrag put the formattedheight of me into myh put the formattedheight of field versAdiff into ah put tdrag / myh into perc put round(perc * ah) into ah2 set the vscroll of field "VersADiff" to ah2end scrollbardragarrivati a questo punto, affiancandoli bene avremo il risultato voluto.
Il programma è scaricabile da qui: diff.livecode
Questo tipo di analisi, tipica dell'informatica, è applicabile a qualunque campo. Voi dove l'applichereste?

Nessun commento:
Posta un commento