Octave w obliczeniach: struktury (1)

>> S = struct('LP',1,'KLIENT','Adam Kowalski','PESEL','89113034509','TOWAR','Jabłka', ...   
              'LICZBA',10,'CENA',2.30,'WARTOSC',23.00,'PR_LOJAL','PRAWDA')
S =
  scalar structure containing the fields:
    LP = 1
    KLIENT = Adam Kowalski
    PESEL = 89113034509
    TOWAR = Jabłka
    LICZBA = 10
    CENA = 2.3000
    WARTOSC = 23
    PR_LOJAL = PRAWDA

>> size(S)
ans =
   1   1

Proszę zwrócić uwagę na charakterystyczny dla Octave’a zapis par argumentów funkcji struct: ’nazwa_argumentu’, wartość_argumentu. I po przecinku kolejna para. Nazwa_argumentu musi być tekstem (obejmujące apostrofy), wartość_argumentu – tylko jeśli też jest tekstem. Tutaj argumentami są nazwy pól, które będą tworzyły strukturę każdego rekordu zmiennej S. Wartości argumentów to zawartości odpowiednich komórek arkusza kalkulacyjnego. Zwróćmy też uwagę na rozmiar struktury (zmienna S): 1 x 1. To oznacza jeden rekord danych. Dodajmy teraz drugi wiersz. Koniecznie musimy poinformować Octave’a, że nową zawartość musi dopisać do zmiennej S (czyli wpisać ją w drugim rekordzie struktury). Gdybyśmy tego nie zrobili, po prostu nadpisalibyśmy dotychczasową zawartość struktury:

>> S(2)= struct('LP',2,'KLIENT','Anna Chrapkowska','PESEL','45123106593','TOWAR','Twaróg', ... 
                 'LICZBA',2,'CENA',2.30,'WARTOSC',23.00,'PR_LOJAL','PRAWDA')
S =
  1x2 struct array containing the fields:
    LP
    KLIENT
    PESEL
    TOWAR
    LICZBA
    CENA
    WARTOSC
    PR_LOJAL

>> size(S)
ans =
   1   2

Ponieważ zmienna S zawiera teraz więcej niż jeden rekord (spójrz na wynik polecenia size(S)), pokazywana jest tylko struktura rekordów (nazwy pól). Aby zobaczyć zawartość wybranych rekordów należy wskazać Octave’owi, o który rekord nam chodzi:

>> S(2)
ans =
  scalar structure containing the fields:
    LP = 2
    KLIENT = Anna Chrapkowska
    PESEL = 45123106593
    TOWAR = Twaróg
    LICZBA = 2
    CENA = 2.3000
    WARTOSC = 23
    PR_LOJAL = PRAWDA

I tak kolejno, wiersz po wierszu, moglibyśmy odtwarzać dane z prezentowanego fragmentu arkusza. Czy można to jakoś zautomatyzować? Można. Dane z arkusza zostały wyeksportowane do pliku .csv (proszę pamiętać, by ustawić stronę kodową UTF-8), plik został zaimportowany w Octave’ie do zmiennej typu komórka i zawartość tej zmiennej posłużyła do stworzenia struktury, zawierającej komplet danych z prezentowanego arkusza. Popatrzmy:

% Najpierw zawartość pliku .csv

>> type plik5.csv
LP,KLIENT,PESEL,TOWAR,LICZBA,CENA,WARTOSC,PR_LOJAL
1,Adam Kowalski,89113034509,Jabłka,10,2.30,23.00,PRAWDA
2,Anna Chrapkowska,45123106593,Twaróg,2,4.50,9.00,PRAWDA
3,Jarosław Witek,19032405678,Tort,1,120.00,120.00,FAŁSZ
4,Małgorzata Dudek,64022887123,Okulary,1,800.00,800.00,PRAWDA


% Teraz import pliku do tablicy komórek

>> pkg load io
>> C=csv2cell('plik5.csv')
C =
{
  [1,1] = LP
  [2,1] = 1
  [3,1] = 2
  [4,1] = 3
  [5,1] = 4
  [1,2] = KLIENT
  [2,2] = Adam Kowalski
  [3,2] = Anna Chrapkowska
  [4,2] = Jarosław Witek
  [5,2] = Małgorzata Dudek
  [1,3] = PESEL
  [2,3] = 8.9113e+10
  [3,3] = 4.5123e+10
  [4,3] = 1.9032e+10
  [5,3] = 6.4023e+10
  [1,4] = TOWAR
  [2,4] = Jabłka
  [3,4] = Twaróg
  [4,4] = Tort
  [5,4] = Okulary
  [1,5] = LICZBA
  [2,5] = 10
  [3,5] = 2
  [4,5] = 1
  [5,5] = 1
  [1,6] = CENA
  [2,6] = 2.3000
  [3,6] = 4.5000
  [4,6] = 120
  [5,6] = 800
  [1,7] = WARTOSC
  [2,7] = 23
  [3,7] = 9
  [4,7] = 120
  [5,7] = 800
  [1,8] = PR_LOJAL
  [2,8] = PRAWDA
  [3,8] = PRAWDA
  [4,8] = FAŁSZ
  [5,8] = PRAWDA
}

% Zauważmy, że plik .csv zawierał nagłówek danych i w związku z tym pierwszy wiersz tablicy komórek zawiera ten nagłówek:

C(1,:) =
{
  [1,1] = LP
  [1,2] = KLIENT
  [1,3] = PESEL
  [1,4] = TOWAR
  [1,5] = LICZBA
  [1,6] = CENA
  [1,7] = WARTOSC
  [1,8] = PR_LOJAL
}

% Następnym krokiem jest import zmiennej C - tablicy komórek i zamiana jej zawartości w strukturę. Funkcja 
% cell2struct, realizująca ten proces, wymaga w tej sytuacji podania trzech argumentów: 
% - pierwszy - C(2:end,:) to zakres zmiennej C, zawierający dane (cała zmienna bez pierwszego wiersza, zawierającego 
%   nagłówki danych);
% - drugi - C(1,:) to pierwszy wiersz zmiennej C, czyli właśnie nagłówki danych. Zostaną one użyte jako nazwy pól 
%   tworzonej struktury;
% - trzeci - liczba 2 to drugi wymiar tablicy komórek (kolumny), informujący funkcję cell2struct, że ma wykorzystać 
%   kolumny wiersza nr 1, by znaleźć nazwy dla pól tworzonej struktury.

>> S=cell2struct(C(2:end,:),C(1,:),2)
   S =
   4x1 struct array containing the fields:
    LP
    KLIENT
    PESEL
    TOWAR
    LICZBA
    CENA
    WARTOSC
    PR_LOJAL

Skoro mamy strukturę z kilkoma rekordami danych (liczbę rekordów pokazuje nam wynik polecenia tworzącego strukturę), obejrzyjmy jej zawartość. Pierwszy sposób już wypróbowaliśmy: nazwa zmiennej z numerem rekordu w roli indeksu, np. S(3) – zawartość trzeciego rekordu zmiennej S. I – oczywiście – wynik, który przedstawi nam Octave zawsze możemy przypisać do nowej zmiennej, tworząc nową strukturę, zawierającą wybrany przez nas zestaw rekordów (np. S2 = S(3)).

>> S(3)
ans =

  scalar structure containing the fields:

    LP = 3
    KLIENT = Jarosław Witek
    PESEL = 1.9032e+10          % Niepokojąco wygląda ten PESEL, prawda? Naprawimy to za chwilę
    TOWAR = Tort
    LICZBA = 1
    CENA = 120
    WARTOSC = 120
    PR_LOJAL = FAŁSZ

Możemy też oglądać przekrój zawartości wybranego pola całej struktury, albo tylko jej wybranych rekordów.

>> S.KLIENT
ans = Adam Kowalski
ans = Anna Chrapkowska
ans = Jarosław Witek
ans = Małgorzata Dudek


>> S(1).KLIENT
ans = Adam Kowalski


>> S(1:2).KLIENT
ans = Adam Kowalski
ans = Anna Chrapkowska


>> S([1 3]).KLIENT
ans = Adam Kowalski
ans = Jarosław Witek

I na koniec jeszcze: co z tym PESELEM? Ponieważ składa się z samych cyfr, został zinterpretowany podczas importu z pliku .csv jako liczba i teraz wyświetlany jest w postaci wykładniczej. Zamienimy go na tekst, aby był wyświetlany popranie. Aby nie komplikować opowieści o strukturach nie użyjemy do tej zamiany żadnej pętli – po prostu naprawimy każdy rekord danych oddzielnie. Do zamiany liczby na tekst użyjemy funkcji o nazwie num2str, która zamieni liczbę na tekst, wyglądający dokładnie tak jak liczba.

% Stan wejściowy: PESEL jest liczbą wyświetlaną w postaci wykładniczej

>> S.PESEL
ans = 8.9113e+10
ans = 4.5123e+10
ans = 1.9032e+10
ans = 6.4023e+10

% Zmiana liczby na tekst w polu PESEL każdego rekordu (średnik na końcu polecenia zapobiega wyświetleniu wyniku 
% polecenia w oknie poleceń)

>> S(1).PESEL=num2str(S(1).PESEL);
>> S(2).PESEL=num2str(S(2).PESEL);
>> S(3).PESEL=num2str(S(3).PESEL);
>> S(4).PESEL=num2str(S(4).PESEL);

% Rezultat

>> S.PESEL
ans = 89113034509
ans = 45123106593
ans = 19032405678
ans = 64022887123

Tyle na dzisiaj. Pozostałe informacje o strukturach w którymś kolejnym wpisie. :))

Podobne wpisy