diff --git a/Organizacja + oceny prezentacji koncepcji projektów.ipynb b/Organizacja + oceny prezentacji koncepcji projektów.ipynb index c21102b..1e3a517 100644 --- a/Organizacja + oceny prezentacji koncepcji projektów.ipynb +++ b/Organizacja + oceny prezentacji koncepcji projektów.ipynb @@ -159,7 +159,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.7.6" + "version": "3.8.5" } }, "nbformat": 4, diff --git a/materiały na PPB (wykład)/.ipynb_checkpoints/12_ocena_jakości_systemu-checkpoint.ipynb b/materiały na PPB (wykład)/.ipynb_checkpoints/12_ocena_jakości_systemu-checkpoint.ipynb index 3210b7b..b17444c 100644 --- a/materiały na PPB (wykład)/.ipynb_checkpoints/12_ocena_jakości_systemu-checkpoint.ipynb +++ b/materiały na PPB (wykład)/.ipynb_checkpoints/12_ocena_jakości_systemu-checkpoint.ipynb @@ -18,7 +18,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Czym jest jakość produktu?" + "# 1. Czym jest jakość produktu?" ] }, { @@ -41,7 +41,7 @@ " \n", "

Definicja wg Geralda Weinberga

\n", " \n", - "Jakość to subiektywnie pojmowana wartość dla kogoś.\n", + "Jakość to subiektywnie pojmowana wartość.\n", "" ] }, @@ -86,7 +86,76 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Definicja jakości oprogramowania" + "# 2. Definicja jakości oprogramowania" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + " \n", + "

Jakość oprogramowania

\n", + " \n", + " Jakość oprogramowania to funkcja wypadkowa wartości określonych właściwości oprogramowania.\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2.1. Proces określania jakości oprogramowania\n", + "Proces określenia jakości oprogramowania składa się z dwóch etapów:\n", + "1. Zdefiniowanie funkcji jakości oprogramowania:\n", + "\n", + " > 1. Określ właściwości istotne dla danego typu oprogramowania (np. rozmiar, funkcjonalność, użyteczności, dostępność).\n", + " > 2. Dla każdej włąsciwości zdefiniuj zakres wartości liczbowych lub kategorii, określających, w jakim stopniu spełnia ona oczekiwania użytkowników.\n", + " > 3. Zdefiniuj jakość oprogramowania jako funkcję wartości poszczególnych właściwości: \n", + " > **Quality = q(wartości właściwości)**\n", + " \n", + "2. Ocena jakości oprogramowania\n", + " > 1. Wyznacz wartości poszczególnych cech oprogramowania.\n", + " > 2. Oblicz jakość oprogramowania za pomocą zdefiniowanej funkcji *Quality*." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 3. Jakość kodu źródłowego\n", + "Cechy kodu żródłowego:\n", + " * rozmiar,\n", + " * złożoność" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3.1. Metryki rozmiaru kodu źródłowego\n", + "\n", + "### 3.1.1. Liczba wierszy (LOC - Lines of Code)\n", + "LOC mierzy **liczbę wierszy** w metodzie, klasie lub całej aplikacji.\n", + "\n", + "W obliczaniu LOC trzeba podjąć kilka nieoczywistych decyzji.\n", + "\n", + "Przykłady:\n", + "\n", + "\n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + "\n", + " \n", + "\n", + "\n", + " \n", + "\n", + "
Decyzja Rekomendacja
Czy liczyć puste wiersze? NIE
Czy liczyć komentarze? NIE
Czy liczyć liczbę wierszy czy liczbę instrukcji? Liczbę wierszy
" ] }, { @@ -95,9 +164,9 @@ "source": [ "
\n", " \n", - "

Jakość oprogramowania

\n", + "

Reguła 30

\n", " \n", - "Jakość oprogramowania to funkcja cech oprogramowania, które spełniają oczekiwania użytkownika: znane i przewidywane.\n", + "Jeśli element zawiera wiecej niż 30 podelementów, to najprawdopodobniej w działaniu wystąpi jakiś poważny problem.\n", "
" ] }, @@ -105,35 +174,412 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Jakość kodu źródłowego\n", - "### Metryki oceny rozmiaru kodu źródłowego\n", - "### Metryki oceny złożoności kodu źródłowego" + "> **Methods** should not have more than an average of 30 code lines (not counting line spaces and comments). \n", + "> **A class** should contain an average of less than 30 methods, resulting in up to 900 lines of code. \n", + "> **A package** shouldn’t contain more than 30 classes, thus comprising up to 27,000 code lines. \n", + "> **Subsystems** with more than 30 packages should be avoided. Such a subsystem would count up to 900 classes with up to 810,000 lines of code. \n", + "> **A system** with 30 subsystems would thus possess 27,000 classes and 24.3 million code lines. \n", + "[Przeczytaj w Internecie](https://dzone.com/articles/rule-30-%E2%80%93-when-method-class-or)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Cechy oprogramowania wpływające na ocenę jakości\n", - "### Funkcjonalność\n", - "### Niezawodność\n", - "### Użyteczność\n", - "### Wydajność\n", - "### Łatwość konserwacji\n", - "### Przenośność\n", - "### Dostępność\n", - "### Bezpieczeństwo\n", - "### Kompatybilność" + "### 3.1.2. Punkty funkcyjne\n", + "\n", + "**Punkty Funkcyjne** - metryka, która wyznacza liczbę funkcjonalności dostarczaną przez system.\n", + "\n", + "**Współczynnik produktywności języka programowania**: ile (średnio) linii kodu potrzeba do zakodowania jednego punktu funkcyjnego? \n", + "\n", + "Wartość kodu w punktach funkcyjnych wyznacza się, dzieląc wartośćLOC przez współczynnik produktywności.\n", + "\n", + "**Tablica produktywności języków programowania**\n", + " \"Tablica\n", + " źródło: Adam Roman, \"Testowanie i jakość oprogramowania\"\n", + "\n", + "[Porównaj w Internecie](https://www.qsm.com/resources/function-point-languages-table)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Schematy oceny jakości\n", - "### CUPRIMDSO\n", - "### FURPS\n", - "### CUPRIMDA" + "### 3.1.3. Liczba tokenów - metryka Halsteada\n", + "\n", + "Metryka Halsteada wyznacza objętość (wielkość) kodu na podstawie liczby unikatowych tokenów.\n", + "Wyróżniane są dwa typy tokenów:\n", + " * operatory (funkcje, słowa kluczowe itp.),\n", + " * operandy (zmienne, stałe, wartości).\n", + " \n", + "Wartości metryk Halsteada (w przeciwieństwie do LOC) nie zależą od długości przyjętego nazewnictwa.\n", + "\n", + "\"Liczby\n", + "źródło: Wikipedia\n", + "\n", + "Na podstawie liczby tokenów można oszacować objętość (wielkość) programu:\n", + "\n", + "\"wielkość\n", + "źrodło: Wikipedia" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3.2. Metryki oceny złożoności kodu źródłowego " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.2.1. Metryki złożoności Halsteada\n", + "Złożoność programu szacowana jest pod kilkoma aspektami - na podstawie liczby tokenów:\n", + " * D: trudność implementacji,\n", + " * L: poziom programu (im wyższy tym program jest mniej podatny na błędy),\n", + " * E: wysiłek implementacji,\n", + " * T: czas implementacji\n", + " * B: liczba błędów.\n", + "\"metryki\n", + "żródło: Wikipedia" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.2.2. Złożoność cyklomatyczna\n", + "**Złożoność cyklomatyczna** określa liczbę niezależnych ścieżek przebiegu programu. \n", + "\n", + "Jeśli program reprezentowany jest w postaci schematu blokowego (grafu), to:\n", + "\n", + "> CC = e - n + 2 * p \n", + "> e – liczba krawędzi grafu \n", + "> n – liczba węzłów grafu \n", + "> p – liczba składowych grafu \n", + "\n", + "Złożoność cykolmatyczną można łatwo wyliczyć na podstawie wzoru:\n", + "\n", + "> CC = d + 1, gdzie d oznacza liczbę węzłów decyzyjnych, np. instrukcji: \n", + "> * if \n", + "> * while \n", + "> * for \n", + "> * case" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.2.3. Uśrednione metody na klasę (Weighted Methods per Class - WMC)\n", + "\n", + "Metryka uwzględnia zarówno liczbę metod w klasie, jak i ich złożoność cyklomatyczną: (n oznacza liczbę metod w klasie, a ci oznacza złożoność cykolomatyczną i-tej metody).\n", + "\n", + "\"Uśrednione" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.2.4. Odpowiedzialność klasy (Response for a Class - RFC)\n", + "\n", + "Metryka RFC oznacza całkowitą liczbę metod, które mogą być potencjalnie wywołane w odpowiedzi na komunikat odebrany przez obiekt klasy. \n", + "\n", + "Wysoka wartość RFC oznacza większą funkcjonalność, ale zarazem i wyższą złożoność." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 4. Właściwości produktu wpływające na ocenę jakości oprogramowania" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4.1. Przydatność funkcjonalna (Functional Suitability - F)\n", + "**Przydatność funkcjonalna** określa stopień, w jakim program dostarcza oczekiwane funkcjonalności.\n", + "\n", + "Wartość przydatności funkcjonalnej można wyznaczyć podczas testowania:\n", + "\n", + "> **M = 1 - A/B**\n", + "> * A = funkcjonalności problemowe \n", + "> * B = wszystkie testowane funkcjonalności" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4.2. Niezawodność\n", + "\n", + "**Niezawodność** określa prawdopodobieństwo, że wykonanie operacji przez program będzie bezbłędne.\n", + "\n", + "Wartość niezawodności można wyznaczyć podczas testowania:\n", + "\n", + "> **M = A/B** \n", + "> * A = liczba testów ukończonych pomyślnie, \n", + "> * B = liczba wszystkich testów" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4.3. Użyteczność (Usability - U)\n", + "\n", + "**Użyteczność** określa łatwość użytkowania.\n", + "\n", + "Wartość użyteczności można wyznaczyć podczas testów użyteczności:\n", + "\n", + "> **M = A/B**\n", + "> * A = liczba funkcjonalności odkryta przez użytkownika, \n", + "> * B = liczba wszystkich funkcjonalości." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4.4. Wydajność (Performance Efficiency)\n", + "**Wydajność** określa liczbę wykonanych operacji w odniesieniu do czasu i zużytych zasobów.\n", + "\n", + "Przykładowe metryki pomiaru wydajności:\n", + "\n", + "> * Czas odpowiedzi: **M = T1 (end) - T2 (start)** \n", + "> * Czas postoju: **M = T1 (waiting time) / T2 (total time)**\n", + "> * Przepustowość = Liczba zadań wykonanych w jednostce czasu \n", + "> * Zużycie pamięci (w bajtach) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4.5. Łatwość konserwacji (Maintainability - M)\n", + "**Łatwość konserwacji** to łatwość, z jaką program jest utrzymywany w celu:\n", + " * poprawiania błędów,\n", + " * wprowadzania nowych funkcji.\n", + "\n", + "Przykładowa metryka: Ile czasu zajmuje średnio naprawienie błędu?\n", + "\n", + "> **M = SUM(czas naprawy) / N** \n", + "> * N oznacza liczbę napraw" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4.6. Przenośność (Portability - P)\n", + "**Przenośność** to Łatwość przenoszenia systemu pomiędzy różnymi środowiskami platformami / systemami operacyjnymi. \n", + "\n", + "Przykładowe metryki:\n", + " * łatwość adaptacji\n", + " > **M = T** \n", + " > * T oznacza czas adaptacji do nowego środowiska\n", + "\n", + " * łatwość instalacji: \n", + " > **M = A / B**\n", + " > * A = przypadki pomyślnej instalacji \n", + " > * B = wszystkie przypadki instalacji " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4.7. Dostępność (Availibility - A)\n", + "**Dostępność** to czas, w którym program zobowiązany jest odpowiadać zgodnie z oczekiwaniami.\n", + "\n", + "* Metryka:\n", + "\n", + "> **M = A / B**\n", + "> * A = Czas dostępności \n", + "> * B = Czas całkowity \n", + "\n", + "* Przykładowe wartości metryki dostępności:\n", + "\n", + "\n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + "\n", + " \n", + "\n", + "\n", + " \n", + "\n", + "
Miara dostępności Czas niedostępności w roku
99,999 5 minut 20 sekund
99,8 17 godzin 30 minut
97,5 219 godzin
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4.8. Kompatybilność (Compatibility)\n", + "**Kompatybilność** to możliwość współpracowania z systemami zewnętrznymi." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4.9. Bezpieczeństwo (Security - S)\n", + "**Bezpieczeństwo** to możliwość chronienia danych przetwarzanych przez aplikację.\n", + "\n", + "* Przykładowa metryka:\n", + "\n", + "> **M = A / B** \n", + "> * A = Liczba przetestowanych funkcji programu uznanych jako bezpieczne\n", + "> * B = Liczba wszystkich przetestowanych funkcji " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 5. Schematy oceny jakości\n", + "\n", + "Aby ocenić jakość oprogramowania należy wybrać właściwości oprogramowania, które wchodzą w skład oceny. Służą do tego **schematy oceny jakości**.\n", + "\n", + "## 5.1. CUMPRIMDSO (schamat wprowadzony przez IBM)\n", + "* Capability (odpowiednik przydatności funkcjonalnej)\n", + "* Usability (użyteczność)\n", + "* Performance – wydajność\n", + "* Reliability – niezawodność\n", + "* Installability – łatwość instalacji\n", + "* Maintainibility – łatwość utrzymania (pielęgnowalność)\n", + "* Documentation – dokumentacja\n", + "* Service – serwis\n", + "* Overall - ocena ogólna\n", + "\n", + "## 5.2. CUMPRIMDA\n", + "* Capability (odpowiednik przydatności funkcjonalnej)\n", + "* Usability (użyteczność)\n", + "* Performance – wydajność\n", + "* Reliability – niezawodność\n", + "* Installability – łatwość instalacji\n", + "* Maintainibility – łatwość utrzymania (pielęgnowalność)\n", + "* Documentation – dokumentacja\n", + "* Availibility - dostępność\n", + "\n", + "## 5.3. FURPS (schemat wprowadzony przez Hewlett-Packard)\n", + "* Functionality\n", + "* Usability\n", + "* Reliability\n", + "* Performance\n", + "* Supportability – łatwość wspierania" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 6. Funkcja oceny jakości oprogramowania" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6.1. Pojęcie korelacji\n", + "\n", + "**Korelacja** to miara zależności pomiędzy dwoma zmiennymi (cechami).\n", + "\n", + "Korelacja przyjmuje wartości z przedziału [-1, 1]. \n", + "* korealacja > 0 → korelacja dodatnia\n", + " * gdy wartości jednej cechy rosną, to drugiej również rosną.\n", + "* r < 0 → korelacja ujemna\n", + " * gdy wartości jednej cechy rosną, to drugiej maleją i odwrotnie\n", + "* r = 0 → korelacja zerowa\n", + " * brak związku między cechami.\n", + " \n", + "Przykłady korelacji: \n", + "\n", + "\"korelacja\n", + "źródło: https://cyrkiel.info/statystyka/korelacja-pearsona/" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6.2. Korelacja między właściwościami oprogramowania\n", + "Korelację między poszczególnymi właściwościami oprogramowania obrazuje tabela:\n", + "\n", + "\"Korelacja\n", + "źródło: opracowanie własne na podstawie: Stephen H. Kan \"Metryki i modele w inżynierii jakości oprogramowania\"\n", + "\n", + "Tabela wskazuje, że polepszenie jednej cechy oprogramowania (np. przydatności funkcjonalnej) może pogorszyć inną cechę (np. wydajność), bo cechy te są ujemnie skorelowane." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6.3. Waga właściwości oprogramowania\n", + "Istotność poszczególnych właściwości oprogramowania zależy od typu programu.\n", + "\n", + "Stephen H. Kan (\"Metryki i modele w inżynierii jakości oprogramowania\") podaje, że dla metryki UPRIMDA najbardziej odpowiednie kolejności właściwości są następujące: \n", + "* RUIPMDA\n", + "* RUAIMPD" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6.4. Wzór na ocenę jakości oprogramowania\n", + "\n", + "Procedura opracowania wzoru na ocenę jakości oprogramowania odpowiedniego dla danego typu programu:\n", + "\n", + "> 1. Wybierz schemat (np. FURPS) \n", + "> \n", + "> 2. Zdefiniuj typ funkcji (np. funkcja liniowa) \n", + "> **Quality = a + b*F + c*U +d*R + e*P + f*S** \n", + "> \n", + "> 3. Zdefiniuj współczynniki tak, by korelacja z oceną ludzką była jak najwyższa." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Przykładowy proces dostrajania współczynników jakości\n", + "\n", + "> 1. Zorganizuj grupę użytkowników (co najmniej 5 osób). \n", + "> 2. Zbierz od użytkowników oceny poszczególnych właściwości oprogramowania. \n", + "> 3. Zbierz od użytkowników oceny ogólne jakości. \n", + "> 4. Określ heurystycznie wartości współczynników we wzorze na ocenę ogolną. \n", + "> 5. Oblicz współczynnik korelacji między:\n", + "> * ocenami ogólnymi jakości podanymi przez użytkowników, \n", + "> * ocenami ogólnymi jakości wyznaczonymi przez wzór na oceną ogólną na podstawie ocen cząstkowych użytkownikow.\n", + "> 6. Jeśli korelacja jest niska, to powróć do punktu 4." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Podsumowanie\n", + " * Istnieje wiele definicji jakości programowania.\n", + " * Na wykładzie zdefiniowano jakość jako funkcję poszczególnych właściwości oprogramowania.\n", + "\n", + "* Istnieją metryki oceny **kodu źrodłowego**. \n", + " * Na ich podstawie można ocenić jakość kodu.\n", + " \n", + " * Jakość oprogramowania można oceniać również z punktu widzenia klienta. \n", + " * Stosowane są różne schematy oceny, które biorą pod uwagę różne właściwości oprogramowania.\n", + " \n", + " * Ocenę ogólną oprogramowania (z punktu widzenia klienta) można zdefiniować jako **funkcję liniową** ocen poszczególnych właściwości." ] } ], diff --git a/materiały na PPB (wykład)/10_wybrane_zagadnienia_użyteczności.ipynb b/materiały na PPB (wykład)/10_wybrane_zagadnienia_użyteczności.ipynb index 012ae54..f035cb6 100644 --- a/materiały na PPB (wykład)/10_wybrane_zagadnienia_użyteczności.ipynb +++ b/materiały na PPB (wykład)/10_wybrane_zagadnienia_użyteczności.ipynb @@ -492,13 +492,6 @@ "Ten etap raportu można zakończyć wykresami." ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, { "attachments": {}, "cell_type": "markdown", diff --git a/materiały na PPB (wykład)/12_ocena_jakości_systemu.ipynb b/materiały na PPB (wykład)/12_ocena_jakości_systemu.ipynb index 3210b7b..b17444c 100644 --- a/materiały na PPB (wykład)/12_ocena_jakości_systemu.ipynb +++ b/materiały na PPB (wykład)/12_ocena_jakości_systemu.ipynb @@ -18,7 +18,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Czym jest jakość produktu?" + "# 1. Czym jest jakość produktu?" ] }, { @@ -41,7 +41,7 @@ " \n", "

Definicja wg Geralda Weinberga

\n", " \n", - "Jakość to subiektywnie pojmowana wartość dla kogoś.\n", + "Jakość to subiektywnie pojmowana wartość.\n", "" ] }, @@ -86,7 +86,76 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Definicja jakości oprogramowania" + "# 2. Definicja jakości oprogramowania" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "
\n", + " \n", + "

Jakość oprogramowania

\n", + " \n", + " Jakość oprogramowania to funkcja wypadkowa wartości określonych właściwości oprogramowania.\n", + "
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2.1. Proces określania jakości oprogramowania\n", + "Proces określenia jakości oprogramowania składa się z dwóch etapów:\n", + "1. Zdefiniowanie funkcji jakości oprogramowania:\n", + "\n", + " > 1. Określ właściwości istotne dla danego typu oprogramowania (np. rozmiar, funkcjonalność, użyteczności, dostępność).\n", + " > 2. Dla każdej włąsciwości zdefiniuj zakres wartości liczbowych lub kategorii, określających, w jakim stopniu spełnia ona oczekiwania użytkowników.\n", + " > 3. Zdefiniuj jakość oprogramowania jako funkcję wartości poszczególnych właściwości: \n", + " > **Quality = q(wartości właściwości)**\n", + " \n", + "2. Ocena jakości oprogramowania\n", + " > 1. Wyznacz wartości poszczególnych cech oprogramowania.\n", + " > 2. Oblicz jakość oprogramowania za pomocą zdefiniowanej funkcji *Quality*." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 3. Jakość kodu źródłowego\n", + "Cechy kodu żródłowego:\n", + " * rozmiar,\n", + " * złożoność" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3.1. Metryki rozmiaru kodu źródłowego\n", + "\n", + "### 3.1.1. Liczba wierszy (LOC - Lines of Code)\n", + "LOC mierzy **liczbę wierszy** w metodzie, klasie lub całej aplikacji.\n", + "\n", + "W obliczaniu LOC trzeba podjąć kilka nieoczywistych decyzji.\n", + "\n", + "Przykłady:\n", + "\n", + "\n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + "\n", + " \n", + "\n", + "\n", + " \n", + "\n", + "
Decyzja Rekomendacja
Czy liczyć puste wiersze? NIE
Czy liczyć komentarze? NIE
Czy liczyć liczbę wierszy czy liczbę instrukcji? Liczbę wierszy
" ] }, { @@ -95,9 +164,9 @@ "source": [ "
\n", " \n", - "

Jakość oprogramowania

\n", + "

Reguła 30

\n", " \n", - "Jakość oprogramowania to funkcja cech oprogramowania, które spełniają oczekiwania użytkownika: znane i przewidywane.\n", + "Jeśli element zawiera wiecej niż 30 podelementów, to najprawdopodobniej w działaniu wystąpi jakiś poważny problem.\n", "
" ] }, @@ -105,35 +174,412 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "## Jakość kodu źródłowego\n", - "### Metryki oceny rozmiaru kodu źródłowego\n", - "### Metryki oceny złożoności kodu źródłowego" + "> **Methods** should not have more than an average of 30 code lines (not counting line spaces and comments). \n", + "> **A class** should contain an average of less than 30 methods, resulting in up to 900 lines of code. \n", + "> **A package** shouldn’t contain more than 30 classes, thus comprising up to 27,000 code lines. \n", + "> **Subsystems** with more than 30 packages should be avoided. Such a subsystem would count up to 900 classes with up to 810,000 lines of code. \n", + "> **A system** with 30 subsystems would thus possess 27,000 classes and 24.3 million code lines. \n", + "[Przeczytaj w Internecie](https://dzone.com/articles/rule-30-%E2%80%93-when-method-class-or)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Cechy oprogramowania wpływające na ocenę jakości\n", - "### Funkcjonalność\n", - "### Niezawodność\n", - "### Użyteczność\n", - "### Wydajność\n", - "### Łatwość konserwacji\n", - "### Przenośność\n", - "### Dostępność\n", - "### Bezpieczeństwo\n", - "### Kompatybilność" + "### 3.1.2. Punkty funkcyjne\n", + "\n", + "**Punkty Funkcyjne** - metryka, która wyznacza liczbę funkcjonalności dostarczaną przez system.\n", + "\n", + "**Współczynnik produktywności języka programowania**: ile (średnio) linii kodu potrzeba do zakodowania jednego punktu funkcyjnego? \n", + "\n", + "Wartość kodu w punktach funkcyjnych wyznacza się, dzieląc wartośćLOC przez współczynnik produktywności.\n", + "\n", + "**Tablica produktywności języków programowania**\n", + " \"Tablica\n", + " źródło: Adam Roman, \"Testowanie i jakość oprogramowania\"\n", + "\n", + "[Porównaj w Internecie](https://www.qsm.com/resources/function-point-languages-table)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "## Schematy oceny jakości\n", - "### CUPRIMDSO\n", - "### FURPS\n", - "### CUPRIMDA" + "### 3.1.3. Liczba tokenów - metryka Halsteada\n", + "\n", + "Metryka Halsteada wyznacza objętość (wielkość) kodu na podstawie liczby unikatowych tokenów.\n", + "Wyróżniane są dwa typy tokenów:\n", + " * operatory (funkcje, słowa kluczowe itp.),\n", + " * operandy (zmienne, stałe, wartości).\n", + " \n", + "Wartości metryk Halsteada (w przeciwieństwie do LOC) nie zależą od długości przyjętego nazewnictwa.\n", + "\n", + "\"Liczby\n", + "źródło: Wikipedia\n", + "\n", + "Na podstawie liczby tokenów można oszacować objętość (wielkość) programu:\n", + "\n", + "\"wielkość\n", + "źrodło: Wikipedia" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3.2. Metryki oceny złożoności kodu źródłowego " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.2.1. Metryki złożoności Halsteada\n", + "Złożoność programu szacowana jest pod kilkoma aspektami - na podstawie liczby tokenów:\n", + " * D: trudność implementacji,\n", + " * L: poziom programu (im wyższy tym program jest mniej podatny na błędy),\n", + " * E: wysiłek implementacji,\n", + " * T: czas implementacji\n", + " * B: liczba błędów.\n", + "\"metryki\n", + "żródło: Wikipedia" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.2.2. Złożoność cyklomatyczna\n", + "**Złożoność cyklomatyczna** określa liczbę niezależnych ścieżek przebiegu programu. \n", + "\n", + "Jeśli program reprezentowany jest w postaci schematu blokowego (grafu), to:\n", + "\n", + "> CC = e - n + 2 * p \n", + "> e – liczba krawędzi grafu \n", + "> n – liczba węzłów grafu \n", + "> p – liczba składowych grafu \n", + "\n", + "Złożoność cykolmatyczną można łatwo wyliczyć na podstawie wzoru:\n", + "\n", + "> CC = d + 1, gdzie d oznacza liczbę węzłów decyzyjnych, np. instrukcji: \n", + "> * if \n", + "> * while \n", + "> * for \n", + "> * case" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.2.3. Uśrednione metody na klasę (Weighted Methods per Class - WMC)\n", + "\n", + "Metryka uwzględnia zarówno liczbę metod w klasie, jak i ich złożoność cyklomatyczną: (n oznacza liczbę metod w klasie, a ci oznacza złożoność cykolomatyczną i-tej metody).\n", + "\n", + "\"Uśrednione" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 3.2.4. Odpowiedzialność klasy (Response for a Class - RFC)\n", + "\n", + "Metryka RFC oznacza całkowitą liczbę metod, które mogą być potencjalnie wywołane w odpowiedzi na komunikat odebrany przez obiekt klasy. \n", + "\n", + "Wysoka wartość RFC oznacza większą funkcjonalność, ale zarazem i wyższą złożoność." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 4. Właściwości produktu wpływające na ocenę jakości oprogramowania" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4.1. Przydatność funkcjonalna (Functional Suitability - F)\n", + "**Przydatność funkcjonalna** określa stopień, w jakim program dostarcza oczekiwane funkcjonalności.\n", + "\n", + "Wartość przydatności funkcjonalnej można wyznaczyć podczas testowania:\n", + "\n", + "> **M = 1 - A/B**\n", + "> * A = funkcjonalności problemowe \n", + "> * B = wszystkie testowane funkcjonalności" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4.2. Niezawodność\n", + "\n", + "**Niezawodność** określa prawdopodobieństwo, że wykonanie operacji przez program będzie bezbłędne.\n", + "\n", + "Wartość niezawodności można wyznaczyć podczas testowania:\n", + "\n", + "> **M = A/B** \n", + "> * A = liczba testów ukończonych pomyślnie, \n", + "> * B = liczba wszystkich testów" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4.3. Użyteczność (Usability - U)\n", + "\n", + "**Użyteczność** określa łatwość użytkowania.\n", + "\n", + "Wartość użyteczności można wyznaczyć podczas testów użyteczności:\n", + "\n", + "> **M = A/B**\n", + "> * A = liczba funkcjonalności odkryta przez użytkownika, \n", + "> * B = liczba wszystkich funkcjonalości." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4.4. Wydajność (Performance Efficiency)\n", + "**Wydajność** określa liczbę wykonanych operacji w odniesieniu do czasu i zużytych zasobów.\n", + "\n", + "Przykładowe metryki pomiaru wydajności:\n", + "\n", + "> * Czas odpowiedzi: **M = T1 (end) - T2 (start)** \n", + "> * Czas postoju: **M = T1 (waiting time) / T2 (total time)**\n", + "> * Przepustowość = Liczba zadań wykonanych w jednostce czasu \n", + "> * Zużycie pamięci (w bajtach) " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4.5. Łatwość konserwacji (Maintainability - M)\n", + "**Łatwość konserwacji** to łatwość, z jaką program jest utrzymywany w celu:\n", + " * poprawiania błędów,\n", + " * wprowadzania nowych funkcji.\n", + "\n", + "Przykładowa metryka: Ile czasu zajmuje średnio naprawienie błędu?\n", + "\n", + "> **M = SUM(czas naprawy) / N** \n", + "> * N oznacza liczbę napraw" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4.6. Przenośność (Portability - P)\n", + "**Przenośność** to Łatwość przenoszenia systemu pomiędzy różnymi środowiskami platformami / systemami operacyjnymi. \n", + "\n", + "Przykładowe metryki:\n", + " * łatwość adaptacji\n", + " > **M = T** \n", + " > * T oznacza czas adaptacji do nowego środowiska\n", + "\n", + " * łatwość instalacji: \n", + " > **M = A / B**\n", + " > * A = przypadki pomyślnej instalacji \n", + " > * B = wszystkie przypadki instalacji " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4.7. Dostępność (Availibility - A)\n", + "**Dostępność** to czas, w którym program zobowiązany jest odpowiadać zgodnie z oczekiwaniami.\n", + "\n", + "* Metryka:\n", + "\n", + "> **M = A / B**\n", + "> * A = Czas dostępności \n", + "> * B = Czas całkowity \n", + "\n", + "* Przykładowe wartości metryki dostępności:\n", + "\n", + "\n", + " \n", + " \n", + "\n", + "\n", + " \n", + "\n", + "\n", + " \n", + "\n", + "\n", + " \n", + "\n", + "
Miara dostępności Czas niedostępności w roku
99,999 5 minut 20 sekund
99,8 17 godzin 30 minut
97,5 219 godzin
" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4.8. Kompatybilność (Compatibility)\n", + "**Kompatybilność** to możliwość współpracowania z systemami zewnętrznymi." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4.9. Bezpieczeństwo (Security - S)\n", + "**Bezpieczeństwo** to możliwość chronienia danych przetwarzanych przez aplikację.\n", + "\n", + "* Przykładowa metryka:\n", + "\n", + "> **M = A / B** \n", + "> * A = Liczba przetestowanych funkcji programu uznanych jako bezpieczne\n", + "> * B = Liczba wszystkich przetestowanych funkcji " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 5. Schematy oceny jakości\n", + "\n", + "Aby ocenić jakość oprogramowania należy wybrać właściwości oprogramowania, które wchodzą w skład oceny. Służą do tego **schematy oceny jakości**.\n", + "\n", + "## 5.1. CUMPRIMDSO (schamat wprowadzony przez IBM)\n", + "* Capability (odpowiednik przydatności funkcjonalnej)\n", + "* Usability (użyteczność)\n", + "* Performance – wydajność\n", + "* Reliability – niezawodność\n", + "* Installability – łatwość instalacji\n", + "* Maintainibility – łatwość utrzymania (pielęgnowalność)\n", + "* Documentation – dokumentacja\n", + "* Service – serwis\n", + "* Overall - ocena ogólna\n", + "\n", + "## 5.2. CUMPRIMDA\n", + "* Capability (odpowiednik przydatności funkcjonalnej)\n", + "* Usability (użyteczność)\n", + "* Performance – wydajność\n", + "* Reliability – niezawodność\n", + "* Installability – łatwość instalacji\n", + "* Maintainibility – łatwość utrzymania (pielęgnowalność)\n", + "* Documentation – dokumentacja\n", + "* Availibility - dostępność\n", + "\n", + "## 5.3. FURPS (schemat wprowadzony przez Hewlett-Packard)\n", + "* Functionality\n", + "* Usability\n", + "* Reliability\n", + "* Performance\n", + "* Supportability – łatwość wspierania" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 6. Funkcja oceny jakości oprogramowania" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6.1. Pojęcie korelacji\n", + "\n", + "**Korelacja** to miara zależności pomiędzy dwoma zmiennymi (cechami).\n", + "\n", + "Korelacja przyjmuje wartości z przedziału [-1, 1]. \n", + "* korealacja > 0 → korelacja dodatnia\n", + " * gdy wartości jednej cechy rosną, to drugiej również rosną.\n", + "* r < 0 → korelacja ujemna\n", + " * gdy wartości jednej cechy rosną, to drugiej maleją i odwrotnie\n", + "* r = 0 → korelacja zerowa\n", + " * brak związku między cechami.\n", + " \n", + "Przykłady korelacji: \n", + "\n", + "\"korelacja\n", + "źródło: https://cyrkiel.info/statystyka/korelacja-pearsona/" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6.2. Korelacja między właściwościami oprogramowania\n", + "Korelację między poszczególnymi właściwościami oprogramowania obrazuje tabela:\n", + "\n", + "\"Korelacja\n", + "źródło: opracowanie własne na podstawie: Stephen H. Kan \"Metryki i modele w inżynierii jakości oprogramowania\"\n", + "\n", + "Tabela wskazuje, że polepszenie jednej cechy oprogramowania (np. przydatności funkcjonalnej) może pogorszyć inną cechę (np. wydajność), bo cechy te są ujemnie skorelowane." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6.3. Waga właściwości oprogramowania\n", + "Istotność poszczególnych właściwości oprogramowania zależy od typu programu.\n", + "\n", + "Stephen H. Kan (\"Metryki i modele w inżynierii jakości oprogramowania\") podaje, że dla metryki UPRIMDA najbardziej odpowiednie kolejności właściwości są następujące: \n", + "* RUIPMDA\n", + "* RUAIMPD" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6.4. Wzór na ocenę jakości oprogramowania\n", + "\n", + "Procedura opracowania wzoru na ocenę jakości oprogramowania odpowiedniego dla danego typu programu:\n", + "\n", + "> 1. Wybierz schemat (np. FURPS) \n", + "> \n", + "> 2. Zdefiniuj typ funkcji (np. funkcja liniowa) \n", + "> **Quality = a + b*F + c*U +d*R + e*P + f*S** \n", + "> \n", + "> 3. Zdefiniuj współczynniki tak, by korelacja z oceną ludzką była jak najwyższa." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Przykładowy proces dostrajania współczynników jakości\n", + "\n", + "> 1. Zorganizuj grupę użytkowników (co najmniej 5 osób). \n", + "> 2. Zbierz od użytkowników oceny poszczególnych właściwości oprogramowania. \n", + "> 3. Zbierz od użytkowników oceny ogólne jakości. \n", + "> 4. Określ heurystycznie wartości współczynników we wzorze na ocenę ogolną. \n", + "> 5. Oblicz współczynnik korelacji między:\n", + "> * ocenami ogólnymi jakości podanymi przez użytkowników, \n", + "> * ocenami ogólnymi jakości wyznaczonymi przez wzór na oceną ogólną na podstawie ocen cząstkowych użytkownikow.\n", + "> 6. Jeśli korelacja jest niska, to powróć do punktu 4." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Podsumowanie\n", + " * Istnieje wiele definicji jakości programowania.\n", + " * Na wykładzie zdefiniowano jakość jako funkcję poszczególnych właściwości oprogramowania.\n", + "\n", + "* Istnieją metryki oceny **kodu źrodłowego**. \n", + " * Na ich podstawie można ocenić jakość kodu.\n", + " \n", + " * Jakość oprogramowania można oceniać również z punktu widzenia klienta. \n", + " * Stosowane są różne schematy oceny, które biorą pod uwagę różne właściwości oprogramowania.\n", + " \n", + " * Ocenę ogólną oprogramowania (z punktu widzenia klienta) można zdefiniować jako **funkcję liniową** ocen poszczególnych właściwości." ] } ], diff --git a/materiały na PPB (wykład)/obrazy/Halstead1.png b/materiały na PPB (wykład)/obrazy/Halstead1.png new file mode 100644 index 0000000..d47c8de Binary files /dev/null and b/materiały na PPB (wykład)/obrazy/Halstead1.png differ diff --git a/materiały na PPB (wykład)/obrazy/Halstead2.png b/materiały na PPB (wykład)/obrazy/Halstead2.png new file mode 100644 index 0000000..26b33e9 Binary files /dev/null and b/materiały na PPB (wykład)/obrazy/Halstead2.png differ diff --git a/materiały na PPB (wykład)/obrazy/Halstead3.png b/materiały na PPB (wykład)/obrazy/Halstead3.png new file mode 100644 index 0000000..a283ed2 Binary files /dev/null and b/materiały na PPB (wykład)/obrazy/Halstead3.png differ diff --git a/materiały na PPB (wykład)/obrazy/LOC vs FP.jpg b/materiały na PPB (wykład)/obrazy/LOC vs FP.jpg new file mode 100644 index 0000000..985cc03 Binary files /dev/null and b/materiały na PPB (wykład)/obrazy/LOC vs FP.jpg differ diff --git a/materiały na PPB (wykład)/obrazy/WMC.png b/materiały na PPB (wykład)/obrazy/WMC.png new file mode 100644 index 0000000..6fe54a4 Binary files /dev/null and b/materiały na PPB (wykład)/obrazy/WMC.png differ diff --git a/materiały na PPB (wykład)/obrazy/korelacja właściwości.png b/materiały na PPB (wykład)/obrazy/korelacja właściwości.png new file mode 100644 index 0000000..3ec8a5e Binary files /dev/null and b/materiały na PPB (wykład)/obrazy/korelacja właściwości.png differ diff --git a/materiały na PPB (wykład)/obrazy/korelacja.png b/materiały na PPB (wykład)/obrazy/korelacja.png new file mode 100644 index 0000000..ae1fa0b Binary files /dev/null and b/materiały na PPB (wykład)/obrazy/korelacja.png differ diff --git a/materiały na PPB (wykład)/obrazy/wypadkowa.png b/materiały na PPB (wykład)/obrazy/wypadkowa.png new file mode 100644 index 0000000..bbc3696 Binary files /dev/null and b/materiały na PPB (wykład)/obrazy/wypadkowa.png differ