Wybór między formalnym a zwinnym

https://aie24.pl/

Tradycyjne metody testowania, w których testowanie jest odrębną fazą cyklu życia oprogramowania, obejmującą wstępnie zdefiniowane kroki, najlepiej sprawdzają się, gdy wymagania są precyzyjne, takie jak pisanie oprogramowania dla samolotów, statków kosmicznych lub IRS. W przypadku takich krytycznych dla misji aplikacji programistycznych należy utworzyć i przestrzegać formalnego planu testów, który określa, kto, co, gdzie, kiedy i jak w fazie testowania. Większość dzisiejszych prac nad rozwojem oprogramowania odbywa się zgodnie z metodologią zwinną, w której rozwój oprogramowania i testowanie są wykonywane iteracyjnie, a nie jako liniowy proces krok po kroku. W zwinnym rozwoju oprogramowania plan testów koncentruje się na ciągłym testowaniu. Uznając, że wymagania się zmieniają i że żaden plan nie jest idealny, zwinne testowanie kładzie nacisk na elastyczność i adaptowalność w procesie testowania. Celem zwinnego planu testów jest przetestowanie oprogramowania w celu upewnienia się, że spełnia ono potrzeby użytkowników końcowych, zgodnie ze specyfikacją w historiach użytkowników i kryteriach akceptacji.  To, czy plan testów jest formalnym dokumentem, czy planem zwinnym, zależy od rodzaju tworzonego oprogramowania i metodologii rozwoju oprogramowania stosowanej przez pracodawcę.

Testowanie kodu

https://aie24.pl/

Spośród wszystkich zadań programistycznych, w których może pomóc sztuczna inteligencja, testowanie jest prawdopodobnie  najbezpieczniejsze. Dzieje się tak, ponieważ uruchomienie testu nie wpływa na kod ani projekt oprogramowania — sprawdza jedynie, czy oprogramowanie działa zgodnie z projektem. Pisanie testów z pomocą sztucznej inteligencji nie zawsze jest jednak niezawodne. Jak dowiesz się z tego rozdziału, jakość testów i porad dotyczących testowania, które otrzymasz od sztucznej inteligencji, zależy od Twoich podpowiedzi dla modelu sztucznej inteligencji i od tego, jak dobrze wiesz, które zadania są lepiej obsługiwane przez ludzi. Automatyzacja testów to proces używania oprogramowania oddzielnie od testowanego oprogramowania w celu kontrolowania uruchamiania testów. Przed latami 80. większość testów oprogramowania była wykonywana przez testerów, czyli osoby, które używały oprogramowania, aby potwierdzić, że działa. Pod koniec lat 80. testerzy używali narzędzi do rejestrowania swoich interakcji z oprogramowaniem i odtwarzania testu w dowolnym momencie. Proces ten był znany jako testowanie nagrywania i odtwarzania. Trzecia poważna zmiana w testowaniu nastąpiła w latach 90., kiedy większość testów stała się oparta na skryptach. Zamiast testować oprogramowanie za jego pomocą, testerzy zaczęli automatyzować zadania testowe, pisząc skrypty przy użyciu języków programowania. W rezultacie testowanie stało się bardziej elastyczne, ale także bardziej techniczne, wymagając umiejętności programistów oprogramowania, a nie testerów oprogramowania. Począwszy od lat 2010. zaczęły pojawiać się narzędzia AI wspomagające testowanie oprogramowania. Testowanie z pomocą AI może ułatwić testowanie i pisanie testów, co ponownie pozwoli osobom niebędącym programistami uczestniczyć w procesie (oraz programistom, oczywiście).

Unikanie przedwczesnej optymalizacji

https://aie24.pl/

Najlepszym momentem na optymalizację kodu jest moment, gdy go piszesz. Jednak nie zawsze jest to możliwe. W miarę pisania oprogramowania i zmian wymagań, nieefektywności i zły kod mają tendencję do wkradania się. Zobacz rozdział 6, aby dowiedzieć się o typach problemów (znanych również jako zapachy kodu), które mogą występować w kodzie źródłowym, z których wiele może negatywnie wpływać na wydajność. Zanim zoptymalizujesz kod pod kątem wydajności, zdecyduj, czy optymalizacja jest warta zachodu. Jeśli program działa poprawnie i zidentyfikujesz refaktoryzację, która mogłaby go przyspieszyć, zachowaj ostrożność, aby uniknąć tego, co programiści nazywają „przedwczesną optymalizacją”. Wybitny informatyk Donald Knuth, autor The Art of Computer Programming, słynnie oświadczył, że „Przedwczesna optymalizacja jest źródłem wszelkiego zła”. (Ktoś inny powiedział: „Zdania absolutne są źródłem wszelkiego zła”). Knuth miał na myśli, że programiści powinni uważać, aby nie martwić się o wydajność bardziej niż to konieczne. Oszczędzanie kilku mikrosekund w procesie kosztem wielu godzin pracy i potencjalne wprowadzanie nowych błędów nie jest warte wysiłku — zwłaszcza, że ​​szybsze procesory prawdopodobnie spowodują bardziej znaczącą poprawę wydajności w krótkim czasie i bez dodatkowej pracy programistycznej. Jednak jeśli użytkownicy Twojej aplikacji zgłaszają niską wydajność lub inne niedociągnięcia w oprogramowaniu, optymalizacja w celu rozwiązania tego problemu powinna być Twoim najwyższym priorytetem.

Uzyskiwanie sugestii dotyczących optymalizacji kodu

https://aie24.pl/

Źle zoptymalizowany kod działa poprawnie, ale nie jest wydajny, nie działa dobrze lub zgodnie z oczekiwaniami. Prawie cały kod można ulepszyć. Możesz chcieć zoptymalizować kod, aby działał szybciej, poprawić jego jakość lub aby działał w ramach ograniczeń sprzętu lub innych czynników środowiskowych. Python jest jednym z najczęściej używanych języków programowania i jest szczególnie popularny i przydatny podczas pracy z uczeniem maszynowym. Jednak Python jest notorycznie powolny w porównaniu z innymi językami programowania. Gdy połączysz powolność Pythona z wymaganiami przetwarzania i pamięci zadań uczenia maszynowego, wynikiem może być program, którego uruchomienie zajmuje bardzo dużo czasu i monopolizuje zasoby komputera podczas działania. Jednak powolność działania programu nie jest tylko winą języka, kompilatora i podstawowego sprzętu. Decyzje podejmowane podczas kodowania mogą w większym stopniu wpłynąć na wydajność programu. Identyfikacja możliwości poprawy wydajności wymaga czasu i doświadczenia. Optymalizacja kodu zaczyna się od profilowania, czyli techniki wykrywającej, ile czasu zajmuje uruchomienie każdej funkcji w programie i jak często jest wykonywana. Profilowanie powie Ci, które obszary Twojego programu wymagają optymalizacji. Narzędzie, które wykonuje profilowanie, nazywa się profilerem. Łącząc pracę tradycyjnego profilera z sugestiami od czatbota AI, możesz dowiedzieć się, jaki kod działa wolno i uzyskać sugestie dotyczące możliwych ulepszeń.

<-TU

Uzyskiwanie sugestii dotyczących optymalizacji kodu

Scalene to profiler procesora, procesora graficznego i pamięci dla Pythona, który profiluje kod i oferuje proponowane optymalizacje oparte na AI. Zainstalowałem i uruchomiłem Scalene na macOS. Wersja Scalene na Windows nie obsługuje wszystkich tych samych funkcji, co wersja na Linuxa lub macOS w momencie pisania tego tekstu. Zanim zainstalujesz Scalene, musisz zainstalować i skonfigurować Pythona. Ponieważ Scalene wykorzystuje modele OpenAI, musisz również mieć konto OpenAI z dodatnim saldem, aby korzystać z funkcji AI. Aby dowiedzieć się, jak uzyskać konto OpenAI i klucz API, zobacz rozdział 4. Następnie wykonaj następujące kroki, aby zainstalować Scalene i przetestować go:

  1. Odwiedź repozytorium GitHub dla Scalene na https://github.com/plasmaumass/scalene, aby dowiedzieć się więcej.
  2. W systemie macOS, Linux lub Windows Subsystem for Linux (WSL2) użyj następującego polecenia pip, aby zainstalować pakiet Scalene:

pip install -U scalene

  1. Sklonuj repozytorium Scalene GitHub do wygodnego miejsca na swoim komputerze, wprowadzając następujące polecenie w oknie terminala:

git clone https://github.com/plasma-umass/scalene

Repozytorium GitHub zawiera katalog plików Python, których użyjemy do przetestowania Scalene.

  1. Otwórz repozytorium Scalene GitHub w VS Code.
  2. W panelu Rozszerzenia w VS Code znajdź i zainstaluj rozszerzenie Scalene VS Code, jak pokazano na rysunku

  1. Otwórz test/testme.py w VS Code. Ten program nie robi niczego użytecznego, ale możemy go użyć do zademonstrowania, co potrafi Scalene.
  2. Naciśnij Command+Shift+P (macOS) lub Ctrl+Shift+P (Windows), aby otworzyć paletę poleceń VS Code.
  3. Wpisz Scalene w palecie poleceń, aż zobaczysz polecenie Scalene:

AI-Powered Profiling. . . Kliknij to polecenie, aby je uruchomić.

W VS Code pojawia się komunikat informujący, że Scalene profiluje kod. Po zakończeniu w VS Code otwiera się raport, jak pokazano na rysunku

  1. Przejrzyj raport.Na moim komputerze program działał 10,646 sekund i używał maksymalnie 20,536 MB pamięci. Zwróć uwagę na wiersze kodu z ikoną błyskawicy lub fajerwerków po lewej stronie. Ikona fajerwerków oznacza, że ​​Scalene zaproponował optymalizacje dla tego wiersza lub regionu kodu; kliknij ikonę, aby wyświetlić optymalizacje. Ikona błyskawicy powoduje, że Scalene proponuje optymalizacje dla wierszy kodu, dla których pierwotnie nie znalazł optymalizacji, lub próbuje wygenerować inny kod dla wierszy, dla których zaproponował optymalizację.

10. Aby wprowadzić klucz API OpenAI do Scalene, kliknij łącze Opcje zaawansowane (pod logo Scalene u góry raportu Scalene), jak pokazano na rysunku.

  1. W polu wprowadzania w obszarze opcji zaawansowanych wklej klucz API OpenAI, a następnie zamknij opcje zaawansowane, klikając ponownie łącze Opcje zaawansowane.

12. Kliknij ikonę fajerwerków w raporcie Scalene’a. Po chwili proponowana optymalizacja pojawi się poniżej linii oznaczonej ikoną fajerwerków, jak pokazano na rysunku

Pozostaw kartę zawierającą oryginalny raport otwartą, aby móc porównać go z nowym raportem.

  1. Przejrzyj proponowaną optymalizację. Jeśli chcesz zobaczyć inną propozycję, kliknij ponownie ikonę fajerwerków.

14. Gdy znajdziesz optymalizację, która ma dla Ciebie sens, zaimplementuj ją w swoim kodzie i ponownie uruchom Scalene. Nowy raport pojawi się w nowej karcie w VS Code, jak pokazano na rysunku

  1. Jeśli Twój pierwszy raport jest nadal otwarty, porównaj oba raporty, aby dowiedzieć się, czy wdrożenie optymalizacji poprawiło wydajność programu.

Plik testme.py został zaprojektowany tak, aby był jak najmniej wydajny, aby zademonstrować Scalene. Jednak optymalizując tylko pierwszą funkcję, udało mi się zmniejszyć pamięć do 0 MB i czas wykonania o około 4,5 sekundy.

Weryfikacja przetłumaczonego kodu

https://aie24.pl/

Tłumaczenie kodu z jednego języka na drugi i weryfikacja, czy przetłumaczony kod działa, to dopiero początek procesu zapewniania dokładności tłumaczenia. Zwłaszcza jeśli przetłumaczyłeś kod za pomocą asystenta AI, nowy kod musi przejść przez wiele kolejnych kroków, zanim będziesz mógł go wdrożyć. Powinieneś traktować przetłumaczony kod tak samo, jak świeżo napisany kod. Proces weryfikacji przetłumaczonej aplikacji obejmuje następujące kroki:

»»Zrozumienie kodu źródłowego: poświęć czas na pełne zrozumienie kodu źródłowego przetłumaczonej aplikacji, a także kodu oryginalnego, zanim przejdziesz do kolejnych kroków. Narzędzia chatbotów AI mogą pomóc Ci lepiej zrozumieć kod.

»»Test: tłumaczenie mogło wprowadzić nowe błędy do Twojego programu. Weź testy napisane dla oryginalnego kodu i dostosuj je do nowego kodu. AI może być pomocna w tłumaczeniu testów dla nowego kodu.

»»Przeprowadź przeglądy kodu: Przeprowadź przeglądy kodu, najlepiej z pomocą innego programisty, a także asystenta AI.

»»Przeprowadź statyczną analizę kodu: Użyj lintera z nowym kodem, aby sprawdzić potencjalne problemy ze składnią, formatowaniem i stylem.

»»Wyjście odniesienia krzyżowego: Zapewnij obu wersjom aplikacji to samo wejście i sprawdź, czy generują identyczne wyjście dla zadań przetwarzania danych lub obliczeń.

»»Dokument: Sprawdź dokumentację i komentarze w nowym kodzie, aby zweryfikować, czy są nadal dokładne, i zaktualizuj je w razie potrzeby.

»»Przeprowadź przegląd bezpieczeństwa: Różne języki i środowiska wykonawcze mają różne luki w zabezpieczeniach. Na przykład obawy dotyczące bezpieczeństwa związane z aplikacją internetową są bardzo różne od obaw związanych z aplikacją na Androida lub iOS. Z tego powodu należy przeprowadzić przegląd bezpieczeństwa przetłumaczonego kodu. Narzędzie takie jak Snyk może być pomocne w przeprowadzeniu tego przeglądu.

Narzędzia i procesy wykorzystywane do weryfikacji przetłumaczonego kodu są takie same jak te używane do pisania i optymalizacji kodu oryginalnego.

Tłumaczenie całego programu przy użyciu GPT-4

https://aie24.pl/

GPT-4 jest znacznie większy i bardziej zdolny do wykonywania trudniejszych zadań niż model Copilot. Aby zobaczyć, jak GPT-4 poradzi sobie ze złożonym tłumaczeniem, użyłem OpenAI Playground do utworzenia asystenta tłumaczenia kodu. Dałem modelowi następujący monit systemowy:

Jesteś ekspertem w programowaniu JavaScript. Przetłumacz mój kod z aplikacji internetowej na aplikację mobilną napisaną w React Native.

Aplikacja internetowa, którą napisałem, aby przetestować mojego nowego asystenta tłumaczeń, używa pojedynczego komponentu React, który daje użytkownikowi pole wprowadzania, w którym może wpisać nazwę użytkownika GitHub, jak pokazano na rysunku .

Gdy użytkownik kliknie łącze Pobierz repozytoria, aplikacja używa interfejsu API GitHub do pobrania i wyświetlenia listy repozytoriów GitHub użytkownika. W OpenAI Playground wkleiłem kod pojedynczego komponentu aplikacji, a także kod do renderowania go w monit użytkownika. Wybrałem model GPT-4 i ustawiłem temperaturę na 0,5, aby model preferował dokładniejsze przewidywania nad kreatywnością. Aby mieć pewność, że odpowiedź nie zostanie odcięta, ustawiłem maksymalną długość na znacznie wyższą wartość, niż się spodziewałem. Mój monit i ustawienia pokazano na rysunku .

Przesłałem monit i otrzymałem przekonwertowany komponent, który skopiowałem i wkleiłem do szablonu React Native i uruchomiłem. Poza drobnym problemem ze stylem na iOS, działał on idealnie zarówno na urządzeniach z systemem iOS, jak i Android, jak pokazano na rysunku

Eksploracja strategii tłumaczeniowych

https://aie24.pl/

Aby zobaczyć, jak dobrze duże modele językowe radzą sobie z tłumaczeniem między językami programowania, zacznijmy od prostej funkcji JavaScript:

// converts an array to an HTML unordered list

function makeUnorderedList(array) {

let listItems = array.map(element => {

return `<li>${element}</li>`;

});

return `<ul>${listItems.join(“)}</ul>`;

}Nie ma nic skomplikowanego w tej funkcji. Gdy podasz jej tablicę, konwertuje ona tablicę na wypunktowaną listę HTML. Rysunek  pokazuje funkcję makeUn orderedList() w akcji.

Możesz użyć Copilot Chat do tłumaczenia kodu z jednego języka na inny. Gdy plik zawierający tylko funkcję makeUnordinateList() jest otwarty w VS Code, podaj Copilot Chat następujący monit:

przetłumacz tę funkcję na język Python.

Tłumaczenie Copilota jest następujące:

def make_unordered_list(array):

list_items = [f”<li>{element}</li>” for element in array]

return f”<ul>{“.join(list_items)}</ul>”

To rozwiązanie wydaje się w porządku. Aby je przetestować, wprowadź je do Google Colab i uruchom funkcję. Wynik, który pokazano na rysunku , jest taki, jakiego się spodziewałem.

Copilot wykonał świetną robotę, konwertując prostą funkcję między dwoma popularnymi językami programowania. Teraz zobaczmy, jak poradzi sobie z tłumaczeniem na mniej popularny język, konwertując wersję Pythona funkcji na język programowania Nim. Nim to statycznie typowany kompilowany język programowania, który łączy najlepsze cechy innych języków programowania, takich jak Python, Lisp i Ada. Przetłumaczona funkcja wygląda następująco:

import strutils

proc makeUnorderedList(array: seq[string]): string =

var listItems = “”

for element in array:

listItems = listItems & “<li>” & element & “</li>”

return “<ul>” & listItems & “</ul>”

Nie znam Nima (jeszcze), ale na pierwszy rzut oka ten wynik wydaje się rozsądny. Poprosiłem Copilota o przykład użycia tej funkcji, a on podał przykład i powiedział, jaki będzie wynik, jak pokazano na rysunku

Aby sprawdzić, czy kod Nim Copilota działa i generuje oczekiwane dane wyjściowe, skopiuj przykładowy kod do Nim Playground na stronie https://play.nim-lang. org/. Dane wyjściowe były dokładnie takie, jak podał Copilot, jak pokazano na rysunku

Chociaż ten prosty przykład generuje poprawne wyniki, nie wiem, czy jest to najlepszy sposób na napisanie tej funkcji w Nim. Chyba że po prostu eksperymentujesz, nie proś asystenta AI o konwersję kodu na język, którego nie znasz. Przejście z JavaScript do Nim wydawało się sukcesem. Teraz chcę się dowiedzieć, czy Copilot może pomóc w czymś, do czego mam codzienne zastosowanie: konwersji JavaScript do TypeScript. Niestety, przy pierwszej próbie Copilot odniósł tylko częściowy sukces:

converts an array to an HTML unordered list

function makeUnorderedList(array: any[]) {

let listItems = array.map((element) => {

return `<li>${element}</li>`;

});

return `<ul>${listItems.join(“)}</ul>`;

}

Widzę dwa problemy z tym kodem:

»»Komentarz nie jest oznaczony jako komentarz.

»»Parametr akceptowany przez makeUn orderedList() jest adnotowany jako będący typu any[].

Ponieważ oryginalna funkcja nie określa, jaki typ danych powinny mieć elementy tablicy, to tłumaczenie jest technicznie poprawne. Jednak programista użyłby bardziej szczegółowego typu. Poprosiłem Copilota o ponowne wykonanie tłumaczenia i tym razem wynik był lepszy, ale nadal nie był poprawny:

converts an array to an HTML unordered list

function makeUnorderedList(array: string[]): string {

let listItems: string[] = array.map((element) => {

return `<li>${element}</li>`;

});

return `<ul>${listItems.join(“)}</ul>`;

}

W tym tłumaczeniu komentarz nadal nie jest oznaczony jako komentarz, a adnotacje typu dla wartości zwracanej z funkcji i dla listItems są zbędne. Ponownie spróbowałem tłumaczenia i otrzymałem niemal idealny wynik, z wyjątkiem tego, że komentarz został usunięty:

function makeUnorderedList(array: string[]) {

let listItems = array.map((element) => {

return `<li>${element}</li>`;

});

return `<ul>${listItems.join(“)}</ul>`;

}

Prawdopodobnie Copilot będzie radził sobie z prostymi tłumaczeniami znacznie lepiej, gdy przeczytasz ten tekst, zwłaszcza jeśli używany przez niego model zostanie ulepszony. Jednak ten eksperyment pokazuje, że nie można ani nie jest mądre ufać tłumaczeniom AI, jeśli nie znasz języka docelowego.

Przygotowanie kodu do tłumaczenia

https://aie24.pl/

Jeśli tłumaczysz kod między dwiema bibliotekami lub frameworkami, ale używasz tego samego języka bazowego (np. tłumaczysz aplikację internetową napisaną przy użyciu Angulara na taką, która używa Reacta), szanse na uzyskanie dobrych wyników są znacznie większe niż w przypadku tłumaczenia między językami programowania. W obu przypadkach możesz jednak wykonać kilka czynności przed tłumaczeniem, aby proces przebiegał płynniej. Większość kroków przygotowania kodu do tłumaczenia to po prostu dobre praktyki kodowania:

»»Utwórz kopię zapasową oryginalnego kodu. Najważniejszym krokiem jest upewnienie się, że zawsze możesz powrócić do oryginalnego języka — albo zmodyfikować podejście do tłumaczenia wspomaganego przez sztuczną inteligencję, albo ręcznie obsłużyć przynajmniej jego część.

»»Dokładnie skomentuj i udokumentuj swój kod. Asystent AI może wykorzystać Twoje komentarze i dokumentację do zinterpretowania celu kodu.

»»Wyczyść i przebuduj kod. Usuń niepotrzebny lub powtarzający się kod i uprość złożone części kodu tak bardzo, jak to możliwe.

»»Zapewnij spójny styl kodowania. Użyj lintera i formatera kodu, aby upewnić się, że Twój kod ma spójne konwencje nazewnictwa, wcięcia i rozmieszczenie nawiasów.

»»Używaj opisowych nazw zmiennych i funkcji. Opisowe nazwy mogą pomóc AI lepiej zrozumieć strukturę i cel Twojego kodu.

»»Zajmij się cechami specyficznymi dla języka. Podczas tłumaczenia między językami programowania powszechnym dużym problemem jest to, że cechy i konwencje używane w jednym języku nie są obecne w drugim języku. Ograniczenie korzystania z tych funkcji lub po prostu świadomość korzystania z nich przez program pomoże Ci zidentyfikować i naprawić problemy z przetłumaczonym kodem.

»»Modularyzuj swój kod. Dzieląc swój kod na małe i modułowe komponenty, pomagasz sztucznej inteligencji w bardziej wydajnym tłumaczeniu kodu. Jeśli Twój kod jest napisany jako zbiór niezależnych modułów, umożliwia to również tłumaczenie kodu źródłowego w mniejszych fragmentach, co może poprawić dokładność i uprościć rozwiązywanie problemów.

Tłumaczenie kodu na inne języki

https://aie24.pl/

Najczęstszą formą tłumaczenia kodu jest kompilacja, w której natywny kod napisany przez programistów jest tłumaczony na kod maszynowy, który może być uruchomiony przez procesor. Kompilacja jest koniecznym i niezawodnym procesem. Tłumaczenie kodu z jednego języka programowania wysokiego poziomu na inny jest jednak procesem obarczonym niebezpieczeństwem. Jeśli robisz to z niewłaściwego powodu (np. myśląc, że nowy język jest fajniejszy od starego), możesz skończyć z czasochłonnym projektem, który nie zapewnia żadnych korzyści użytkownikom oprogramowania lub, co gorsza, zapewnia mniej funkcji niż oryginalny kod. (Czy brzmi to tak, jakbym miał doświadczenie w takich scenariuszach?) Istnieją dobre powody tłumaczenia kodu między językami wysokiego poziomu. Najczęstszym powodem jest to, że sprzęt lub system operacyjny wymagany przez oprogramowanie nie ma kompilatora dla bieżącego języka programowania. Na przykład, jeśli chcesz, aby aplikacja internetowa (napisana w HTML, CSS i JavaScript) działała natywnie na urządzeniu mobilnym, musisz ją przetłumaczyć. Albo jeśli masz starszą aplikację zbudowaną przy użyciu przestarzałego języka programowania, którego chcesz używać na nowoczesnym sprzęcie, prawdopodobnie będziesz musiał przetłumaczyć aplikację.