{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "![Logo 1](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech1.jpg)\n", "<div class=\"alert alert-block alert-info\">\n", "<h1> Systemy informatyczne</h1>\n", "<h2> 12. Ocena jakości systemu informatycznego</i>[wykład]</h2> \n", "<h3>Krzysztof Jassem (2022)</h3>\n", "</div>\n", "\n", "![Logo 2](https://git.wmi.amu.edu.pl/AITech/Szablon/raw/branch/master/Logotyp_AITech2.jpg)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 1. Czym jest jakość produktu?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<div class=\"alert alert-block alert-success\">\n", " \n", "<h3>Definicja wg Toma de Marco</h3> \n", " \n", "Jakość produktu to funkcja tego, jak bardzo zmienia on świat na lepsze.\n", "</div>" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<div class=\"alert alert-block alert-success\">\n", " \n", "<h3>Definicja wg Geralda Weinberga</h3> \n", " \n", "Jakość to subiektywnie pojmowana wartość.\n", "</div>" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<div class=\"alert alert-block alert-success\">\n", " \n", "<h3>Definicja wg Josepha Jurana</h3> \n", " \n", "1. Jakość składa się z tych cech produktu, które spełniają potrzeby klientów i dostarczają im satysfakcji. \n", "2. Jakość to brak braków.\n", "</div>" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<div class=\"alert alert-block alert-success\">\n", " \n", "<h3>Definicja wg Armanda Feigenbauma</h3> \n", " \n", "Jakość to coś, co określa tylko i wyłącznie klient - a nie inżynier, dział marketiingu, czy też kierownictwo.\n", "</div>" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<div class=\"alert alert-block alert-success\">\n", " \n", "<h3>Definicja wg Williama Edwardsa Deminga</h3> \n", " \n", "Cała trudność w zdefiniowaniu jakości polega na przełożeniu przyszłych potrzeb użytkownika na wymierne cechy w taki sposób, aby produkt dawał klientowi satysfakcję za akceptowalną cenę.\n", "</div>" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 2. Definicja jakości oprogramowania" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<div class=\"alert alert-info alert-success\">\n", " \n", "<h3>Jakość oprogramowania</h3> \n", " \n", "<b> Jakość oprogramowania </b> to funkcja wypadkowa wartości określonych właściwości oprogramowania.\n", "</div>" ] }, { "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", "<table>\n", " <caption> Jak mierzyć liczbę wierszy w metryce LOC </caption> \n", "<tr> \n", " <td> Decyzja </td> <td> Rekomendacja </td>\n", "</tr>\n", "<tr>\n", " <td> Czy liczyć puste wiersze?</td> <td> NIE </td>\n", "</tr>\n", "<tr>\n", " <td> Czy liczyć komentarze?</td> <td> NIE </td>\n", "</tr>\n", "<tr>\n", " <td> Czy liczyć liczbę wierszy czy liczbę instrukcji?</td> <td> Liczbę wierszy </td>\n", "</tr>\n", "</table>" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "<div class=\"alert alert-info alert-success\">\n", " \n", "<h3>Reguła 30</h3> \n", " \n", "Jeśli element zawiera wiecej niż 30 podelementów, to najprawdopodobniej w działaniu wystąpi jakiś poważny problem.\n", "</div>" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> **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": [ "### 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", "<figure>\n", "<img src=\"obrazy/LOC vs FP.jpg\" alt=\"Tablica produktywności\" width=500px>\n", "<figcaption> Tablica produktywności. Źródło: Adam Roman, \"Testowanie i jakość oprogramowania\" </figcaption> \n", "</figure>\n", "\n", "[Porównaj w Internecie](https://www.qsm.com/resources/function-point-languages-table)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 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", "<figure>\n", "<img src=\"obrazy/Halstead1.png\" alt=\"Liczby tokenów\" width=300px>\n", "<figcaption> Liczby tokenów. Źródło: wikipedia </figcaption> \n", "</figure>\n", "\n", "Na podstawie liczby tokenów można oszacować objętość (wielkość) programu:\n", "\n", "<figure>\n", "<img src=\"obrazy/Halstead2.png\" alt=\"wielkość programu\" width=300px>\n", "<figcaption> Objętość programu. Źródło: wikipedia </figcaption> \n", "</figure>" ] }, { "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", "<figure>\n", "<img src=\"obrazy/Halstead3.png\" alt=\"metryki złożoności Halsteada\" width=100px>\n", "<figcaption> Metryki złożoności Halsteada. Źródło: wikipedia </figcaption> \n", "</figure>" ] }, { "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 c<sub>i</sub> oznacza złożoność cykolomatyczną i-tej metody).\n", "\n", "<img src=\"obrazy/WMC.png\" alt=\"Uśrednione metody na klasę \" width=150px>" ] }, { "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", "<table>\n", " <caption> Wartości metryki dostępności </caption>\n", "<tr> \n", " <td> Miara dostępności </td> <td> Czas niedostępności w roku </td>\n", "</tr>\n", "<tr>\n", " <td> 99,999 </td> <td> 5 minut 20 sekund </td>\n", "</tr>\n", "<tr>\n", " <td> 99,8</td> <td> 17 godzin 30 minut </td>\n", "</tr>\n", "<tr>\n", " <td> 97,5 </td> <td> 219 godzin </td>\n", "</tr>\n", "</table>" ] }, { "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", "<figure>\n", "<img src=\"obrazy/korelacja.png\" alt=\"korelacja Pearsona\" width=600px>\n", " <figcaption>źródło: https://cyrkiel.info/statystyka/korelacja-pearsona/</figcaption>\n", "</figure>" ] }, { "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", "<figure>\n", "<img src=\"obrazy/korelacja właściwości.png\" alt=\"Korelacja między właściwościomi oprogramowania\" width=600px>\n", " <figcaption> Korelacje między właściwościami oprogramowania źródło: opracowanie własne na podstawie: Stephen H. Kan \"Metryki i modele w inżynierii jakości oprogramowania\"</figcaption>\n", "</figure>\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." ] } ], "metadata": { "author": "Krzysztof Jassem", "email": "jassem@amu.edu.pl", "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "lang": "pl", "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.6" }, "subtitle": "12. Ocena jakości systemu informatycznego[wykład]", "title": "Przygotowanie do projektu badawczo-rozwojowego", "year": "2021" }, "nbformat": 4, "nbformat_minor": 4 }