4. Specyfikacja wymagań
4.3. Wymagania niefunkcjonalne
W podrozdziale wyszczególniono wymagania niefunkcjonalne sformułowane dla opracowywanego oprogramowania.
1. Kompatybilność.
Konwencje architektoniczne, nazewnicze oraz sposób formatowania kodu źródłowego powinny być zachowane w zgodzie z regułami przyjętymi podczas powstawania systemu.
2. Przenośność.
Program powinien dać się skompilować na większości współczesnych platform sprzętowosystemowych. Wymaganym minimum są komputery działające pod kontrolą systemów operacyjnych Linux oraz Windows.
3. Łatwość użycia.
Aplikacja powinna udostępniać prosty i intuicyjny interfejs użytkownika, umożliwiający szybkie i wygodne korzystanie z funkcji programu.
4. Technologia.
Rozszerzenia programu powinny być przygotowane z wykorzystaniem dostępnych, darmowych rozwiązań informatycznych.
Ponadto zaleca się użycie jak największej liczby technologii wybranych podczas implementacji pierwotnej wersji systemu.
W tej części pracy scharakteryzowana została architektura systemu KTDA. Znajduje się tutaj opis pierwotnego sposobu organizacji kodu źródłowego oraz analiza przyjętego rozwiązania. Następnie w rozdziale zawarto esencjonalny portret architektury trójwarstwowej, skupiający się na zaletach takiej kompozycji. Ostatni fragment rozdziału stanowi raport z przeprowadzonej reorganizacji struktury programu.
5.1. Początkowa struktura programu
System KTDA w założeniu został skonstruowany z dwóch warstw:
algorytmicznej oraz warstwy składającej się na interfejs użytkownika.
Interfejs korzysta z warstwy algorytmicznej udostępniając w ten sposób użytkownikowi zaimplementowane funkcje.
Sama wartswa algorytmiczna została podzielona na pakiety zawierające moduły programu o zbieżnym zastosowaniu. Wspomniane pakiety aplikacji to: jak i rzeczywiste wartości atrybutów. Opisywany moduł jest także odpowiedzialny za obsługę odczytu i zapisu plików różnych formatów.
2. Pakiet "ep".
Pakiet ep został skonstruowany w celu przechowywania modelu wyłaniających wzorców oraz metod ich przetwarzania. Znajdują się tutaj implementacje algorytmów odkrywania wyłaniających wzorców oraz klasyfikacji za ich pomocą.
3. Pakiet "cred".
Kolejnym pakietem jest pakiet cred. Mieści się w nim moduł związany z analizą wiarygodności. Umieszczono tu algorytmy wyznaczania współczynników wiarygodności. Ponadto zaimplementowano tu również generatory syntetycznych zbiorów danych używanych podczas doświadczeń z analizą wiarygodności danych.
4. Pakiet "other".
Ostatnim z pakietów jest pakiet other. Znalazły w nim swoje miejsce moduły niezwiązane bezpośrednio z wcześniej wymienionymi pojęciami. Występują tu natomiast deklaracje metod wykorzystywanych przez pozostałe pakiety. Do opracowanych modułów m.in. należą:
generator punktów o wielowymiarowym rozkładzie normalnym, dodatkowe funkcje obsługi macierzy czy moduł zaawansowanego zarządzania pamięcią.
O ile taka organizacja kodu źródłowego wydaje się przejrzysta i zrozumiała, to po głębszej analizie udaje się dostrzec jej niedoskonałości. Przede wszystkim brak wyraźnej separacji pomiędzy składowaniem danych, a ich przetwarzaniem. Dodatkowo, wyżej wspomniana warstwa interfejsu użytkownika również nie jest niezależną całością i w wielu miejscach przenika się z innymi wartstwami systemu.
Ostatnim niedociągnięciem jest występowanie w kodzie źródłowym plików niepowiązanych z żadnym z zaprojektowanych pakietów.
W dalszej części rozdziału ukazano, jakimi środkami poradzono sobie ze wspomnianymi trudnościami oraz co było istotą refaktoryzacji.
5.2. Architektura trójwarstwowa
Architektura trójwarstwowa jest wzorcem architektonicznym typu klientserwer, gdzie interfejs użytkownika (warstwa prezentacji), przetwarzanie danych (warstwa logiki aplikacji) oraz składowanie danych (warstwa danych) są implementowane w postaci odrębnych modułów.
Takie rozplanowanie architektury systemu umożliwia niezależną wymianę dowolnej warstwy, chociażby w odpowiedzi na zaistniałe zmiany technologiczne.
System KTDA nie jest oprogramowaniem, w którym zachodzi potrzeba aż tak zasadniczej hermetyzacji. W gruncie rzeczy jest to aplikacja okienkowa przeznaczona do eksploatacji tylko przez jednego użytkownika, na pojedynczej maszynie. Nie ma również konieczności tworzenia skomplikowanej warstwy dostępu do danych, gdyż wszelkie operacje zachodzą przy wykorzystaniu dostępnej pamięci. Można natomiast skorzystać z popularnego wzorca projektowego MVC (ang. ModelViewController), który w pewnym sensie odpowiada architekturze trójwarstwowej, jednak dotyczy wyłącznie implementacji interfejsu użytkownika.
Wzorzec ModelWidokKontroler dzieli aplikację na trzy współzależne części, oddzielając w ten sposób wewnętrzną reprezentację danych od zasad rządzących ich przetwarzaniem, a także od sposobu w jaki są one prezentowane użytkownikowi.
W modelu zawarta jest reprezentacja dziedziny problemu, uchwycona przez stworzony system. To tutaj zapisane są zasady dotyczące zachowania aplikacji oraz sposób zarządania danymi.
Widok stanowi warstwę, która odpowiada za prezentację danej części modelu użytkownikowi. Możliwym jest stworzenie tzw.
podwidoków, umożliwiających przedstawienie tej samej informacji w różnych ujęciach.
Na ostatnią część wzorca składa się kontroler, o którym możemy myśleć jak o buforze pomiędzy modelem, a widokiem. Do jego naczelnych zadań bowiem należy przyjmowanie żądań od użytkownika, skutujących odświeżaniem widoku tudzież aktualizacją modelu.
Rysunek 5.1. Diagram ilustrujący przepływ sterowania w architekturze MVC.
5.3. Wprowadzone zmiany
Główną zmianą architektoniczą w strukturze systemu było wydzielenie warstawy prezentacji programu. Do realizacji tego celu utworzony został nowy pakiet view. W pakiecie zebrano wszystkie klasy (dotychaczas rozrzucone w wielu miejscach kodu źródłowego) odpowiedzialne za wygląd aplikacji. Zabieg ten umożliwił uporządkowanie źródeł programu, co również ułatwiło nawigację po plikach podczas pracy nad rozbudową systemu.
Rysunek 5.2. Docelowy wygląd drzewa katalogów mieszczących kod źródłowy systemu.
Bezsprzeczną zaletą tego rozwiązania jest zysk w postaci zwiększonej elastyczności oprogramowania. W przypadku chęci zmiany biblioteki do tworzenia graficznego interfejsu użytkownika lub środowiska graficznego jednym pakietem wymagającym zmiany jest pakiet view. Logika aplikacji i model danych są odporne na modyfikacje poczynione w tym kierunku.
Niniejszy rozdział przedstawia szereg decyzji podjętych podczas rozbudowy systemu KTDA. Problemy oraz metody rozwiązania zostały przedstawione w sposób chronologiczny, zgodnie z kolejnością przedsięwziętych działań.
6.1. Uruchomienie programu
Pierwszym krokiem rozpoczynającym pracę nad implementacją było uruchomienie programu. To z pozoru zdawać by się mogło trywialne zadanie ujawniło początkowe trudności, a tym samym wyznaczyło inicjalny etap pracy. Zważając na liczność bibliotek użytych w pierwotnej wersji programu oraz upływ czasu, błędy pojawiające się podczas kompilacji nie dziwią.
Biblioteka wxWidgets użyta do stworzenia graficznego interfejsu użytkownika na przestrzeni lat kilkakrotnie się zmieniała. Intuicyjnym rozwiązaniem wydawać by się mogło skorzystanie z wersji biblioteki użytej podczas pierwszego wydania systemu KTDA. Niemniej jednak nie jest to rozwiązanie satysfakcjonujące. Autor rozszerzenia programu zdecydował się na wykorzystanie najnowszej wersji biblioteki, tj. wxWidgets 3.0.
Do realizacji tego celu konieczne było przeprowadzenie refaktoryzacji kodu źródłowego w miejscach, w których stosowana była wyżej wymieniona biblioteka. Posiłkując się wykazem zmian dostarczonym przez projektantów biblioteki oraz komunikatami o błędach sygnalizowanymi przez kompilator udało się z powodzeniem uaktualnić oprogramowanie, tak aby korzystało z biblioteki w wersji 3.0.
Refaktoryzacja swoim zakresem obejmowała m.in. zmiany nazw wewnętrznych zmiennych stosowanych przez bibliotekę, zmiany
w obsłudze napisów i zmiennych tekstowych, jak i poprawienie konfiguracji zarządzania wątkami.
Rysunek 6.1. Okno główne programu pod kontrolą systemu Kubuntu 15.04.
6.2. Zmiana generatora liczb pseudolosowych
W pracy [1] autor wymienia bibliotekę R250, jako narzędzie którego użył do generacji liczb pseudolosowych. Zaznacza również, że jest to wersja własnoręcznie poprawiona. W źródłach programu jedynym śladem po rzeczonej bibliotece są dyrektywy:
#include <random>
oraz wybrane, na nowo przepisane klasy biblioteki.
Ostatecznie nie udało się odnaleźć teraźniejszej wersji biblioteki R250, którą można by było dołączyć do programu za pomocą pojedynczej, prostej dyrektywy jak nakreślono to wyżej.
Podczas dalszych poszukiwań natrafiono na witrynę [9], na której znajduje się dostępna do pobrania implementacja generatora R250 w postaci archiwum zawierającego pliki źródłowe. Implementacja została napisana w języku C++.
Po porównaniu znalezionego kodu źródłowego, z kodem stanowiącym poprawki wprowadzone przez pierwszego autora systemu zauważono, że nazwy klas i metod są ze sobą zbieżne. Stanowiło to pierwszy trop, a zarazem przełom w poszukiwaniu biblioteki R250. Po skrupulatnej analizie i serii eksperymentów udało się uruchomić aplikację z działającym generatorem liczb pseudolosowych R250.
Autor poczuł się zaintrygowany problemem generowania liczb pseudolosowych, więc postanowił bliżej przyjrzeć się temu zagadnieniu.
Po przestudiowaniu tematu okazało się, że obecnie generator R250 znacznie ustępuje swoim konkurentom. Jego niezaprzeczalnym atutem jest szybkość działania, jednakże oferowana jakość losowości pozostawia wiele do życzenia. Podjęto decyzję o reimplementacji części systemu odpowiedzialnej za generowanie liczb pseudolosowych.
Wraz z nowym standardem języka C++, C++11, światło dzienne ujrzała nowa biblioteka dostarczająca narzędzia do generacji liczb pseudolosowych. Zaimplementowano w niej szereg wiodących algorytmów w tej dziedzinie. Będąc wyposażonym w kompilator obsługujący standard języka C++11 projektant jest gotowy do skorzystania z biblioteki. Poprzez dołączenie dyrektywy:
#include <random>
w pliku źródłowym, dostępne stają się wszystkie klasy zawarte w bibliotece.
Autor przeprowadził kompletną refaktoryzację kodu źródłowego usuwając generator R250 i zastępując go doskonalszym odpowiednikiem dostarczonym wraz z nową specyfikacją języka.
6.3. Dodanie nowych funkcji
Ostatnim etapem pracy było dodanie brakujących funkcji programu. Ta część nie sprawiła większych problemów. W tym stadium rozwoju autor biegle poruszał się po kodzie źródłowym aplikacji. Kolejne funkcje były dodawane cyklicznie do momentu spełnienia założonych wymagań funkcjonalnych.
W bieżącym rozdziale znajduje się opis najważniejszych narzędzi użytych podczas implementacji nowych funkcjonalności systemu.
Podczas wyboru technologii głównymi kryteriami były: wygoda użytkowania, uniwersalność oraz dostępność na rynku wolnego oprogramowania. Wszystkie technologie i narzędzia zostały opisane w kontekście ich pochodzenia, popularności oraz warunków licencyjnych.
7.1. Code::Blocks
W każdym większym projekcie informatycznym, nieodzownym staje się skorzystanie z zintegrowanego środowiska programistycznego (ang. integrated development environment, IDE). Code::Blocks jest darmowym, wieloplatformowym środowiskiem wspierającym m.in. język C++, który został wykorzystany do budowy systemu oraz do napisania samego środowiska. Tym, co zaważyło na wyborze omawianego środowiska był fakt, że do jego implementacji wykorzystano wieloplatformową bibliotekę wxWidgets, która jest szeroko stosowana w implementacji systemu KTDA. Środowisko Code::Blocks udostępnia najlepsze wsparcie do projektowania aplikacji wykorzystujących tę bibliotekę.
Podczas pracy nad rozszerzeniem programu użyto wersji Code::Blocks 13.12.
Program Code::Blocks jest dystrybuowany na licencji GNU GPL v3.0.
Rysunek 7.1. Ekran powitalny środowiska Code::Blocks w wersji 13.12.
7.2. Git
Tematem niniejszej pracy jest rozbudowa istniejącego systemu.
Podczas realizacji tego zadania pożądanym było dysponowanie działającą wersją oprogramowania, na każdym etapie rozwoju projektu.
W spełnieniu tego wymagania pomocne okazało się skorzystanie z systemu kontroli wersji (ang. version control system, VCS) Git.
Narzędzia użyto w celu rejestracji oraz śledzenia zmian w kodzie źródłowym. Dzięki temu zabiegowi możliwe stało się cofnięcie do dowolnego miejsca w historii rozbudowy aplikacji w przypadku wystąpienia regresji. Log wprowadzanych poprawek był przechowywany w prywatnym repozytorium przez cały czas trwania prac nad projektem.
System Git jest dystrybuowany na licencji GNU GPL v2.0.
Rysunek 7.2. Logo projektu Git.
7.3. Biblioteka wxWidgets
W pierwotnej wersji programu autor zdecydował się na wykorzystanie biblioteki wxWidgets. wxWidgets jest biblioteką klas języka C++ przeznaczoną do tworzenia graficznego interfejsu użytkownika aplikacji. Biblioteka udostępnia jednolity, łatwy w użyciu interfejs do budowy oprogramowania przeznaczonego do uruchamiania na różnych platformach, co stanowi jej główną zaletę.
Biblioteka do dziś jest aktywnie rozwijana. Na przestrzeni lat przeszła szereg zmian i usprawnień. Podczas rozbudowy systemu KTDA postanowiono skorzystać z jej najnowszej wersji, tj. wxWidgets 3.0.
W konsekwencji należało przebudować kod źródłowy, pozbywając się z niego przestarzałych funkcji, klas czy zmienionych nazw zmiennych i zastąpić je aktualnymi odpowiednikami. W niektórych przypadkach konieczne były zmiany w architekturze programu. Stanowiło to zasadniczą część pracy.
Biblioteka wxWidgets jest dystrybuowana na licencji wxWindows, która w zasadniczej części została oparta na licencji LGPL.
Rysunek 7.3. Logo biblioteki wxWidgets.
7.4. Biblioteka Newmat
Newmat jest biblioteką języka C++ udostępniającą użytkownikom podstawowe operacje na macierzach. Biblioteka kładzie główny nacisk na operacje stosowane w obliczeniach statystycznych.
W pracy korzysta się z wersji biblioteki Newmat10.
W bieżącym rozdziale zaprezentowano przykłady użycia systemu.
Zademonstrowane funkcje wybrano pod kątem ukazania możliwości oprogramowania w jak najszerszym zakresie. Przede wszystkim skupiono się na nowo powstałych funkcjach.
Przykład 8.1. Obliczenie współczynników wiarygodności dla wygenerowanego zbioru danych „RP”.
Procedurę rozpoczynamy od uruchomienia programu, a następnie wygenerowaniu specjalnego zbioru danych „RP”. W tym celu z widocznego menu kontekstowego wybieramy kolejno opcje:
Plik Utwórz zbiór danych RP→
Po wybraniu tej opcji pojawia się okno dialogowe, w którym należy zadać parametry aktualnie generowanego zbioru:
Rysunek 8.1. Okno wyboru parametrów generowanego zbioru danych.
Zatwierdzając wybór w głównym oknie programu powinien pojawić się obiekt reprezentujący wygenerowany zbiór:
Rysunek 8.2. Utworzenie obiektu zbioru danych.
Wygenerowany zbiór możemy przejrzeć. W tym celu prawym przyciskiem myszy należy kliknąć interesujący nas zbiór danych, a następnie wybrać opcję Widok. Naszym oczom ukaże się nowe okno zawierające tabelę, w której każdy rekord odpowiada innemu obiektowi, a także komplet histogramów obrazujących rozkład wartości poszczególnych atrybutów.
Warto również zauważyć, że wraz z generacją zbioru danych automatycznie został utworzony system decyzyjny z domyślnym atrybutem decyzyjnym. Jeśli potrzebujemy utworzyć system decyzyjny bazujący na innym atrybucie, to w tym celu należy klikając prawym przyciskiem myszy na zbiorze danych wybrać opcję Utwórz system decyzyjny, a następnie w oknie dialogowym wybrać właściwy atrybut decyzyjny.
Rysunek 8.3. Okno przeglądu zbioru danych.
Kolejnym krokiem procedury jest odkrycie w systemie decyzyjnym wyłaniających wzorców. Dokonać tego możemy na trzy sposoby:
odkrywanie wyłaniających wzorców z użyciem drzewa decyzyjnego;
odkrywanie wyłaniających wzorców z użyciem maksymalnych częstych zbiorów;
załadowanie uprzednio odkrytych wyłaniających wzorców z pliku ARFF.
W przykładzie skorzystamy z pierwszej możliwości. Klikając prawym przyciskiem myszy na systemie decyzyjnym wybieramy:
Odkryj wyłaniające wzorce Algorytm drzewa decyzyjnego→
Po tej czynności system wyświetli okno dialogowe służące do nastawy parametrów algorytmu:
Rysunek 8.4. Okno wyboru parametrów algorytmu odkrywania wyłaniających wzorców.
Zatwierdzając wybór przyciskiem OK program wykona operację odkrywania wyłaniających wzorców. Po jej zakończeniu do głównego okna programu dodany zostaje obiekt reprezentujący odkryte wyłaniające wzorce:
Rysunek 8.5. Utworzenie obiektu wyłaniających wzorców.
W następnym kroku utworzymy klasyfikator CAEP.
Oprogramowanie umożliwia podjęcie decyzji, czy chcemy zbudować klasyfikator na podstawie wszystkich wyłonionych wzorców, czy tylko na kilku wybranych. Wykorzystamy drugą możliwość.
Klikając prawym przyciskiem myszy na obiekcie reprezentującym wyłaniające wzorce wybieramy opcję Utwórz klasyfikator CAEP bazując na wybranych wzorcach. System wyświetla okno dialogowe z możliwością wyboru wzorców użytych w dalszym procesie analizy:
Rysunek 8.6. Okno wyboru wyłaniających wzorców wykorzystanych w dalszym procesie analizy.
Po wyborze i jego zatwierdzeniu w głównym oknie programu pojawia się nowo utworzony obiekt wyrażający klasyfikator CAEP.
Mając do dyspozycji klasyfikator możemy przystąpić do finalnego etapu procedury, tj. obliczenia współczynników wiarygodności. W tym celu klikając prawym przyciskiem myszy na obiekcie klasyfikatora wybieramy opcję Użyj do obliczenia współczynników wiarygodności.
Wyświetlone zostaje kolejne okno dialogowe, w którym wybieramy system decyzyjny, który zostanie poddany przetwarzaniu:
Rysunek 8.7. Okno wyboru systemu decyzyjnego poddanego analizie.
Zatwierdzając decyzję współczynniki wiarygodności dla danego systemu decyzyjnego zostają wyznaczone, co w systemie objawia się ukazaniem kolejnego obiektu:
Rysunek 8.8. Utworzenie obiektu zbierającego wyznaczone współczynniki wiarygodności.
System umożliwia także przejrzenie wyników działania procedury w przejrzystej formie tabelarycznej. Aby skorzystać z tej możliwości należy, klikając prawym przyciskiem myszy na obiekcie reprezentującym współczynniki wiarygodności, wybrać opcję Widok.
Wyświetlone zostaje okno zawierające wszelkie dane o badanych obiektach:
Rysunek 8.9. Okno przeglądu wyników analizy.
W ramach niniejszej pracy dyplomowej z powodzeniem zrealizowano rozbudowę systemu KTDA. Spełnione zostały wszystkie wymogi zawarte w specyfikacji wymagań.
Modernizacja już istniejącego systemu wymaga przyjęcia odpowiedniego rygoru pracy. Ze względu na fakt, że system KTDA jest oprogramowaniem dedykowanym, przed przystąpieniem do właściwych działań autor zapoznał się z dziedziną problemu. W obrębie tych działań znalazło się przyswojenie podstawowych pojęć z zakresu eksploracji danych, procesu analizy wiarygodności danych, wyłaniających wzorców oraz współczynników wiarygodności. Zrozumienie przytoczonych zagadnień umożliwiło dokładną analizę wymagań stawianych rozbudowywanemu systemowi.
Po przyswojeniu wiedzy dziedzinowej nadszedł czas na wybór narzędzi i technologii stosowanych do rozwiązania zadania.
Zdecydowano się użyć większości bibliotek, którymi posłużono się w inicjalnej wersji projektu. Z racji tego, że były to propozycje nieznane autorowi, należało poświęcić czas na zapoznanie się z nimi.
Zdecydowanie najbardziej czasochłonnym etapem okazała się analiza architektury systemu. Ponadto autor musiał przyzwyczaić się do konwencji stosowanych przez swojego poprzednika, co również stanowiło pewne wyzwanie.
Po rzetelnym przygotowaniu teoretycznym przystąpiono do właściwej pracy nad kodem źródłowym aplikacji oraz wprowadzaniem nowych funkcjonalności systemu. Wraz z upływem czasu autor coraz lepiej orientował się w organizacji kodu źródłowego oraz bieglej posługiwał się wykorzystywanymi narzędziami. Poskutkowało to tym, że implementacje kolejnych funkcji pojawiały się w krótszych odstępach czasu.
Ostatecznie udało się zrealizować wszystkie założone cele pracy.
System KTDA został wyposażony w nowe, praktyczne funkcje, elastyczną architekturę, aktualne wersje bibliotek oraz nie sprawia żadnych trudności podczas uruchamiania na współczesnych maszynach.
1. Krzysztof Tomaszewski „Analiza wiarygodności danych z wykorzystaniem wyłaniających wzorców”, praca dyplomowa magisterska, Politechnika Warszawska, Wydział Elektroniki i Technik Informacyjnych, Instytut Informatyki, Warszawa, 2005 2. Andrzej Dominik „Analiza danych z zastosowaniem teorii zbiorów
przybliżonych”, praca dyplomowa magisterska, Politechnika Warszawska, Wydział Elektroniki i Technik Informacyjnych, Instytut Informatyki, Warszawa, 2004
3. Mariusz Walkiewicz „Ocena wiarygodności danych”, praca dyplomowa magisterska, Politechnika Warszawska, Wydział Elektroniki i Technik Informacyjnych, Instytut Informatyki, Warszawa, 2004
4. Zdzisław Pawlak „Rough sets – Basic notions”, ICS PAS Reports, Warszawa, 1981
5. Zdzisław Pawlak „Systemy informacyjne podstawy teoretyczne”, WNT, Warszawa, 1983
6. Guozhu Dong, Jinyan Li „Efficient Mining of Emerging Patterns:
Discovering Trends and Differences”, Proceedings of the SIGKDD (5th ACM International Conference on Knowledge Discovery and Data Mining), 1999
7. Mosche Lichman, UCI Machine Learning Repository, Irvine, CA:
University of California, School of Information and Computer Science, 2013, http://archive.ics.uci.edu/ml
11. Projekt Code::Blocks,
http://www.codeblocks.org/
12. Projekt Git,
https://gitscm.com/
13. Biblioteka wxWidgets,
https://www.wxwidgets.org/
14. Biblioteka Newmat,
http://www.robertnz.net/nm_intro.htm