Nei prossimi due esempi confronto i software sulle possibilità di leggere file con formati personalizzati. Come ho già accennato non è un'analisi sistematica: sono casi che mi sono capitati tra le mani e che ho voluto provare a risolvere con i tre software.
l primo esempio è il seguente. Ho un file di testo che contiene dei valori esadecimali che rappresentano dei campioni di forme d'onda da inviare a due DAC, N campioni per ciascun DAC. Devo fare dei controlli su questi valori per cui li voglio caricare su uno qualunque dei programmi che ho a disposizione e convertirli in formato numerico.
Il formato del file, di cui vi allego un esempio, è il seguente: il file è organizzato per linee di 64 caratteri; ogni codice è rappresentato da 4 cifre esadecimali e i campioni per i due DAC sono alternati; l'ultima linea contiene degli zeri che devono essere ignorati, ciò che conta è il numero totale di campioni per canale. I valori dei campioni di ciascun DAC devono venire memorizzati in due vettori separati.
Per la lettura da file, sia Octave che Scilab hanno delle funzioni
C-like e la scrittura del codice è piuttosto semplice. I codici risultanti sono praticamente identici a parte i nomi delle funzioni.
Octave:
- Codice: Seleziona tutto
N = 628;
fd = fopen('samples.txt', 'r');
D = fscanf(fd, '%4x', 2*N);
fclose(fd);
D1 = D(1:2:end);
D2 = D(2:2:end);
Scilab:
- Codice: Seleziona tutto
N = 628;
fd = mopen('samples.txt', 'r');
D = mfscanf(2*N, fd, '%4x');
mclose(fd);
D1 = D(1:2:$);
D2 = D(2:2:$);
Mathematica mi ha dato più filo da torcere: è un mostro per ricchezza di funzioni, ma per chi è abituato ad un certo tipo di linguaggi, non è sempre intuitivo. Non sono quindi sicuro che il risultato ottenuto sia il migliore possibile, ma conto su
PietroBaima per le rifiniture
- Codice: Seleziona tutto
Chunk[s_, n_] := StringCases[s, Repeated[_, {n}]];
nSamples = 628;
hexData = Flatten[Chunk[ReadList["samples.txt", String], 4]];
intData = Map[FromDigits[#, 16] &, hexData];
Subscript[samples, 1] = Take[intData, {1, 2*nSamples - 1, 2}];
Subscript[samples, 2] = Take[intData, {2, 2*nSamples, 2}];
Questo codice richiede forse qualche commento in più. La funzione
Chunks suddivide una stringa in blocchi di
n caratteri. Non è mia, ma l'ho presa da
StackExchange. Viene usata nella riga
- Codice: Seleziona tutto
hexData = Flatten[Chunk[ReadList["samples.txt", String], 4]];
per suddividere ogni riga letta (attraverso
ReadList) in blocchi di 4 caratteri. Poiché per ogni riga
Chunk genera una sottolista, c'è bisogno della funzione
Flatten per generare un'unica lista contenente le stringhe di codici esadecimali.
La riga
- Codice: Seleziona tutto
intData = Map[FromDigits[#, 16] &, hexData];
applica ad ogni elemento della lista generata precedentemente la funzione
FromDigits che converte da stringa, interpretata come sequenza di cifre esadecimali, a numero. I numeri così ottenuti sono immagazzinati nella lista
intData. Le due istruzioni successive suddividono tale lista in due sottoliste, contenenti i codici pari e dispari.
Insomma, in questo caso, per immediatezza d'uso, giudicherei vincenti Octave e Scilab. Se poi qualcuno dei valenti pythonisti volesse cimentarsi anche con questo esercizio...
