Strona tytułowa
Tytuł: Program "Trener matematyczny" - budowa aplikacji krok po kroku. To pełna, wieloekranowa aplikacja edukacyjna do nauki tabliczki mnożenia.
Tytuł: Program "Trener matematyczny" - budowa aplikacji krok po kroku. To pełna, wieloekranowa aplikacja edukacyjna do nauki tabliczki mnożenia.
Prezentacja czwarta jest zwieńczeniem części praktycznej. Budujemy jeden, kompletny program o realnej użyteczności - trener tabliczki mnożenia z poziomami trudności, pomiarem czasu, punktacją i zapisem najlepszych wyników.
Program wykorzystuje wszystkie wcześniej poznane elementy: wiele ekranów, zmienne, listy, warunki, pętle, procedury, zdarzenia, komponent Clock i bazę TinyDB.
W toku czwartej prezentacji przechodzimy od prostych aplikacji okien pozwalających na zapamiętywanie pojedynczych pojęć do projektu o skali porównywalnej z realnym produktem edukacyjnym. Każdy kolejny slajd odpowiada jednemu etapowi pracy, począwszy od specyfikacji, a skończywszy na instalacji gotowego pakietu. Taka sekwencja przypomina ścieżkę, jaką podąża profesjonalny zespół wytwarzający oprogramowanie mobilne. Z tego powodu warto mieć obok siebie kartkę i rysować własną mapę ekranów w miarę omawiania kolejnych zagadnień. Samodzielne powtórzenie omawianych kroków po wysłuchaniu wykładu utrwala materiał w sposób, którego nie zapewnia samo czytanie. Na końcu prezentacji student powinien dysponować własną, działającą wersją trenera oraz listą pomysłów na jego rozwój.
Plan prezentacji został ułożony według naturalnej kolejności powstawania aplikacji, od ustalenia wymagań po gotowy plik instalacyjny. Dzięki temu student może śledzić cały proces projektowania tak, jak przebiega on w rzeczywistej praktyce programistycznej. Każda pozycja spisu odpowiada jednemu etapowi pracy, co ułatwia późniejsze odszukiwanie potrzebnych fragmentów podczas powtórek.
Taka mapa treści pełni także funkcję kontrolną, pozwala bowiem ocenić, która część aplikacji została już omówiona, a która wciąż pozostała do omówienia. Porządek ten wspiera stopniowe budowanie wiedzy, ponieważ kolejne zagadnienia opierają się na poprzednich. Przykładowo logiki losowania nie da się w pełni zrozumieć bez znajomości zmiennych globalnych.
Warto skojarzyć każdy element planu z konkretnym ekranem aplikacji, od menu przez ustawienia po wyniki. To ćwiczenie wyrabia nawyk myślenia całością projektu, a nie pojedynczym zdarzeniem. Z czasem student dostrzeże, że podobny układ planu można zastosować w każdym własnym projekcie.
Zestaw celów uczenia się pokazuje, że kurs nie ogranicza się do odtwarzania gotowych projektów, lecz wymaga samodzielnego projektowania i rozwiązywania problemów. Ostatni wymieniony cel, dotyczący dodania nowej funkcji, jest szczególnie istotny, bo weryfikuje zrozumienie wzorców, a nie pamięć. Takie podejście odpowiada rzeczywistości zawodowej, w której programista stale rozwija istniejący kod.
Wymienione umiejętności nie są od siebie niezależne, ponieważ budowa interfejsu poprzedza logikę, a logika wymaga danych trwałych. Student, który potrafi świadomie planować, unika charakterystycznego dla początkujących chaosu bloków. Dobry program poznamy po tym, że każda funkcja ma przemyślane miejsce i uzasadnienie.
Efekty uczenia się warto traktować jako listę kontrolną uzupełnianą w trakcie własnej pracy nad projektem. Regularne sprawdzanie, które kompetencje już są utrwalone, pomaga zaplanować kolejne ćwiczenia. Cele te pokrywają się z zadaniami laboratoryjnymi, dzięki czemu teoria i praktyka pozostają spójne.
Sformułowanie celu i zakresu aplikacji przed napisaniem choćby jednego bloku chroni przed wieloma późniejszymi zmianami. Określenie odbiorcy, czynności i warunków pracy pozwala podejmować decyzje projektowe w sposób świadomy. W przypadku trenera mnożenia łatwo wskazać, że aplikacja służy nauce uczniów pracujących na telefonach.
Specyfikacja to także narzędzie komunikacji, dzięki któremu wykładowca, student i ewentualny zamawiający rozumieją to samo przez podane pojęcia. Zapisanie funkcji na kartce lub w dokumencie pozwala dostrzec luki, zanim staną się kosztownymi problemami. Wielu adeptów pomija ten etap, co zwykle objawia się nieczytelnym projektem.
Czytelna specyfikacja ułatwia również podział pracy na etapy i oszacowanie czasu potrzebnego na realizację. Prosta lista oczekiwań wystarcza, aby rozpocząć projektowanie ekranów i struktury danych. W profesjonalnych firmach dokument ten przyjmuje postać formalną, jednak dla celów edukacyjnych wystarczy przejrzysta notatka.
Wymagania funkcjonalne określają dokładnie, jakie czynności musi wykonać program, dlatego stanowią podstawę do budowy ekranów i bloków. Numeracja funkcji, od pierwszej do siódmej, umożliwia odwoływanie się do każdej z nich w rozmowach i dokumentacji. Dzięki temu łatwo sprawdzić, czy wszystkie zadeklarowane zachowania zostały w kodzie zrealizowane.
Zauważmy, że większość funkcji dotyczy pojedynczych zdarzeń i procedur, co po chwili analizy przekłada się wprost na strukturę bloków. Funkcja losowania pary liczb odpowiada osobnej procedurze, a funkcja punktacji kolejnym zmiennym globalnym. Taka zgodność między specyfikacją a kodem to cecha dojrzałego projektowania.
Warto przyjąć zasadę, że każda nowa funkcja trafia najpierw do listy wymagań, a dopiero potem do programu. Pozwala to kontrolować zakres pracy i unikać niekontrolowanego dodawania elementów. W późniejszych etapach kursu student sam będzie tworzył takie listy dla własnych aplikacji.
Wymagania pozafunkcjonalne opisują nie to, co aplikacja ma robić, lecz w jaki sposób ma to robić, przystępnie, szybko i niezawodnie. Ograniczenie rozmiaru pliku źródłowego narzuca racjonalne gospodarowanie materiałami graficznymi i dźwiękowymi. Praca w trybie offline wymaga, aby wszystkie dane były przechowywane lokalnie, na przykład w bazie TinyDB.
Natychmiastowa reakcja na dotyk nie jest przypadkowym postulatem, ponieważ długie przetwarzanie psuje odczucia i zniechęca użytkownika. W prostych aplikacjach tworzonych w App Inventor czas reakcji pozostaje zwykle znakomity, jeżeli unikamy zbędnych obliczeń. Testy wydajnościowe sprowadzają się wtedy do obserwacji zachowania na prawdziwym telefonie.
Odporność na błędne dane wejściowe realizujemy tu przez walidację pustego pola i właściwą konwersję tekstu na liczbę. Czytelny interfejs to również dobór wielkości czcionek i przycisków zgodny z możliwościami ekranu dotykowego. Takie wymagania pozafunkcjonalne przekładają się na jakość odczuwaną codziennie przez odbiorcę.
Podział aplikacji na cztery ekrany wynika wprost z listy funkcji, menu kieruje pracą, trening wykonuje właściwe obliczenia, a wyniki i ustawienia obsługują dane trwałe. Taka struktura sprawia, że każdy ekran ma jedno, jasno określone zadanie. Ułatwia to również testowanie, gdyż błędy można lokalizować w obrębie jednego ekranu.
Warto zwrócić uwagę, że ekran menu nie prowadzi żadnych obliczeń, lecz jedynie przekazuje sterowanie. Ten wzorzec, znany jako ekran centralny, porządkuje całą nawigację. Dzięki niemu dodanie kolejnego ekranu sprowadza się do dołożenia jednego przycisku i jednego przejścia.
Nazwy ekranów odzwierciedlają ich rolę, co sprzyja czytelności projektu zarówno dla autora, jak i dla osoby przeglądającej kod. Rysunek struktury na kartce przed rozpoczęciem pracy w Designerze pozwala uniknąć wielokrotnych przeróbek. Prosty szkic czterech prostokątów i strzałek to często najcenniejsza czynność w całym projekcie.
Nawigacja w App Inventor sprowadza się do dwóch podstawowych operacji, otwarcia kolejnego ekranu i zamknięcia bieżącego. Ekrany pomocnicze wracają do menu metodą close screen, co tworzy prosty, jednokierunkowy przepływ sterowania. Taki model jest łatwy do zrozumienia i nie prowadzi do nieoczekiwanych stanów aplikacji.
Istotne jest, aby nigdy nie zamykać ekranu głównego Screen1, ponieważ pełni on rolę punktu powrotu dla całej aplikacji. W praktyce oznacza to, że przyciski powrotu umieszczamy wyłącznie na ekranach pomocniczych. Regularne przeglądanie diagramu przejść pomaga wykryć przejścia, które mogłyby zostać przeoczone.
Graf przejść warto rozrysować na kartce i porównać z przyciskami umieszczonymi na ekranach. Każdy przycisk powinien mieć jedno przeznaczenie, a każde przejście powinno być odwracalne w naturalny sposób. Błędna nazwa ekranu w metodzie otwierania kolejnego ekranu objawia się zatrzymaniem aplikacji, dlatego precyzja zapisu ma tu duże znaczenie.
Zmienne globalne w App Inventor są ściśle związane z ekranem, na którym je utworzono, dlatego nie istnieje możliwość odczytania ich z poziomu innego ekranu. Do wymiany informacji służą więc jawne przekazywanie wartości przy otwieraniu ekranu oraz wspólna baza danych. Obie techniki mają swoje miejsce i zależnie od sytuacji wybieramy tę właściwą.
Metoda otwierania kolejnego ekranu z wartością wysyła pojedynczą informację, którą nowy ekran odbiera w zdarzeniu uruchamianym przy swoim starcie. Analogicznie można odesłać wynik przy zamykaniu ekranu i odebrać go już po zamknięciu. Takie rozwiązanie sprawdza się, gdy przekazywana informacja jest niewielka i jednorazowa.
Gdy danych jest więcej lub nie znamy z góry ich liczby, wygodniejszy okazuje się zapis do TinyDB, dostępny dla każdego ekranu. Baza działa jak wspólna półka, z której każdy ekran może pobrać potrzebne wartości. Trwałość zapisanych danych stanowi dodatkową zaletę i łączy ten mechanizm z przechowywaniem wyników.
Zanim powstanie jakikolwiek blok, warto ustalić, jakie zmienne będzie przechowywał program i jakiego typu będą ich wartości. W naszym projekcie dane dzielą się naturalnie na trzy grupy, ustawienia, stan bieżącej sesji i trwałe rekordy. Taki podział pozwala przewidzieć, które wartości muszą być wspólne dla ekranów, a które wystarczą wewnątrz jednego z nich.
Zmienne opisujące bieżącą sesję, czyli punktację, liczbę pytań i czas, zmieniają się bardzo często, dlatego trzymamy je w pamięci ekranu treningu. Ustawienie zakresu i rekordy wymagają trwałości, dlatego lądują w bazie TinyDB. Dokonanie takiego rozróżnienia tuż po zapisaniu specyfikacji oszczędza wiele pracy w dalszych etapach.
Nazewnictwo zmiennych warto przemyśleć od początku, ponieważ czytelne nazwy pełnią funkcję dokumentacji. Przyjęty w tym kursie opisowy styl, jak najlepszyWynik czy liczbaPytan, jest zrozumiały bez zaglądania do kodu. Drobna tabela zmiennych, podobna do zamieszczonej na slajdzie, przydaje się w każdym kolejnym projekcie.
Spójny wygląd wszystkich ekranów nie jest kwestią wyłącznie estetyki, lecz wpływa na szybkość obsługi i komfort nauki. Użytkownik przyzwyczaja się do miejsca nagłówka, przycisków i komunikatów, dzięki czemu nie musi na nowo uczyć się struktury każdego ekranu. Ten sam układ okazuje się szczególnie ważny w aplikacji edukacyjnej kierowanej do dzieci.
Wielkość elementów interaktywnych nie podlega modzie, tylko ergonomii, gdyż ekran dotykowy wymaga celów o odpowiedniej powierzchni. Etykiety z komunikatem o wyniku powinny być krótkie, jednoznaczne i umieszczone w stałym miejscu. Proste tło i ograniczona liczba kolorów zmniejszają obciążenie uwagi odbiorcy.
Reguła minimum elementów na ekranie stanowi praktyczną wskazówkę przy projektowaniu w Designerze. Jeżeli na ekranie pojawia się więcej niż sześć składników, warto zastanowić się nad podziałem treści. Redukcja zbędnych elementów jest korzystna dla czytelności i skraca czas potrzebny na opanowanie aplikacji.
Ekran główny pełni rolę wizytówki aplikacji, dlatego jego projekt warto zacząć od nazwy i czytelnego układu przycisków. Trzy przyciski główne prowadzą do trzech obszarów funkcjonalnych, co niemal samo tłumaczy użytkownikowi sposób obsługi. Ustawienie elementów w pionowym układzie sprawdza się w większości sytuacji i jest łatwe do wykonania w Designerze.
Etykieta informacyjna na dole ekranu potwierdza aktualnie wybrany poziom trudności, co pomaga osobie wracającej z ustawień. Wykorzystanie układu poziomego do grupowania przycisków umożliwia nadanie menu pożądanego wyglądu. Drobne elementy, takie jak marginesy i odstępy, warto wyregulować od razu, aby nie robić tego ponownie przy kolejnych krokach.
Warto od razu ustawić właściwość wyśrodkowania elementów, aby menu wyglądało dobrze na różnych rozmiarach ekranu. Przyciski o jednakowej szerokości najlepiej umieścić w jednej kolumnie o ustalonej wielkości. Tak przygotowane menu stanowi punkt wyjścia dla reszty aplikacji.
Obsługa zdarzeń na ekranie menu jest przykładem kodu, w którym każdy przycisk odpowiada za jedno przejście do innego ekranu. Prosty zestaw trzech zdarzeń kliknięcia nie wymaga żadnych zmiennych ani warunków, co pozwala skupić się na nawigacji. Warto zauważyć, że to zazwyczaj pierwsze bloki, które student pisze samodzielnie.
Zdarzenie uruchamiane przy starcie ekranu menu pełni funkcję inicjacyjną i odświeża etykietę poziomu wartością pobraną z bazy danych. Dzięki temu po powrocie z ustawień menu natychmiast pokazuje aktualny wybór. Wykonanie odczytu właśnie w tym zdarzeniu jest zalecane, ponieważ uruchamia się ono przy wejściu na ekran.
Wzorzec ekranu, który wyłącznie nawiguje, ułatwia dalsze rozwijanie aplikacji o kolejne ekrany. Dodanie kolejnego przycisku i jednego zdarzenia nie narusza istniejącej logiki. Taka architektura jest zalecana w projektach edukacyjnych, ponieważ jej zrozumienie nie wymaga analizy skomplikowanych zależności.
Ekran ustawień obsługuje wybór poziomu trudności i zarządzanie historycznymi wynikami, dlatego jest miejscem pracy z danymi trwałymi. Wybór poziomu realizuje lista wyboru, a reset rekordów przycisk z dodatkowym potwierdzeniem. Rozdzielenie tych dwóch funkcji na osobne przyciski zapobiega przypadkowemu usunięciu osiągnięć.
Pojęcie zakresu liczb pojawia się w projekcie w miejscu naturalnym, ponieważ to właśnie ono decyduje o trudności wszystkich pytań. Zapisanie zakresu w bazie danych sprawia, że ustawienie jest trwałe także po zamknięciu aplikacji. Powrót na ekran treningu nie pociąga za sobą utraty wybranych opcji.
Praca z listami wyboru w App Inventor jest intuicyjna, wystarczy uzupełnić właściwość komponentu wartościami rozdzielonymi przecinkami. Zdarzenie uruchamiane po wybraniu pozycji daje dostęp do zapisanej wartości. Takie komponenty zdecydowanie skracają pracę związaną z tworzeniem formularzy ustawień.
Zapisanie wyboru poziomu wymaga połączenia trzech kroków, odczytania zaznaczonej pozycji, przeliczenia jej na liczbę zakresu i zapisania wyniku. Instrukcje warunkowe porównują nazwę poziomu z kolejnymi możliwościami i nadają odpowiednią wartość zmiennej. Takie przekształcanie tekstu na liczbę jest częstym wzorcem w aplikacjach z konfiguracją.
Wybranie wartości domyślnej w metodzie odczytu zabezpiecza program przed sytuacją, gdy użytkownik nigdy nie otworzył ustawień. Dzięki temu ekran treningu zawsze otrzyma poprawną liczbę, nawet po pierwszym uruchomieniu aplikacji. Ta sama zasada wartości domyślnej chroni także przy odczycie rekordu i liczby sesji.
Pojedyncze miejsce zapisu konfiguracji, tutaj zapis pod kluczem zakres, ułatwia dalszą pracę nad kolejnymi opcjami. Wystarczy dodać nowy klucz w bazie, aby rozszerzyć ustawienia bez zmiany pozostałej logiki. Staranny wybór nazw kluczy, czytelnych i spójnych, procentuje w całym cyklu życia projektu.
Operacje usuwające dane są nieodwracalne, dlatego dobra praktyka nakazuje pytać użytkownika o potwierdzenie przed ich wykonaniem. Komponent powiadamiający wyświetla okno dialogowe z komunikatem oraz dwiema reakcjami, zaakceptować lub zrezygnować. Odpowiednia sekwencja bloków realizuje w ten sposób standardowy wzorzec potwierdzenia działania o dużej sile rażenia.
Metoda czyszcząca całą bazę danych czyści wszystkie wartości naraz, co jest wygodne, ale także ryzykowne, gdyż usuwa również ustawienia poziomu. Bezpieczniejszą alternatywą jest nadpisanie wybranych kluczy wartościami domyślnymi. W naszym projekcie oba podejścia mogą być zastosowane, zależnie od tego, jak szeroki zakres resetu zamierzamy wykonać.
Po potwierdzeniu operacji warto poinformować użytkownika o powodzeniu, aby miał pewność, że działanie nastąpiło. Informacja zwrotna może przybrać postać krótkiego komunikatu w etykiecie lub kolejnego okna dialogowego. Zakończenie wizyty na ekranie ustawień powrotem do menu domyka całą interakcję.
Ekran treningu jest sercem aplikacji, ponieważ łączy w sobie generowanie pytań, odbiór odpowiedzi, ocenę i pomiar czasu. Dlatego projekt tego ekranu wymaga największej uwagi, aby wszystkie informacje były widoczne bez przewijania i zbędnego szukania. Kluczowe elementy to duże pytanie, pole wpisywania i dwa przyciski akcji.
Ograniczenie pola odpowiedzi do cyfr właściwością ograniczającą znaki zmniejsza liczbę błędów typowania, choć nie zastępuje pełnej walidacji. Etykiety punktów i czasu umieszczone obok siebie pozwalają szybko orientować się w postępie sesji. Komponent zegara odświeża etykietę czasu w stałych odstępach, dzięki czemu pomiar jest zawsze aktualny.
Rozdzielenie przycisku sprawdzania od przycisku następnego pytania daje uczniowi czas na kontrolę wyniku. Taki układ powoduje, że sesja ma wyraźny rytm, pytanie, odpowiedź, ocena, kolejne pytanie. Projekt ekranu utrwala więc naturalny przebieg całego treningu i czyni aplikację intuicyjną.
Zdarzenie uruchamiane przy wejściu na ekran to idealne miejsce na przygotowanie stanu początkowego sesji. Odczyt zakresu z bazy oraz wyzerowanie zmiennych gwarantują, że każdy trening zaczyna się od czystego stanu. Pominięcie tego kroku prowadzi do przenoszenia wartości między sesjami i trudnych do wykrycia błędów.
Ustawienie interwału zegara na tysiąc milisekund powoduje odliczanie sekund, a tym samym prosty i czytelny pomiar czasu. Przechowywanie licznika sekund w zmiennej, zamiast bezpośredniego odczytu zegara, daje pełną kontrolę nad tym pomiarem. Wspominana wcześniej procedura losowania pytania uruchamiana jest już na starcie ekranu.
W naszym projekcie poziom i licznik są ustawiane na początku każdej sesji, dlatego aplikacja nie opiera się na pamiętaniu poprzedniego stanu. To, czy zdarzenie inicjujące uruchomi się ponownie przy określonym sposobie przejścia, warto sprawdzić empirycznie na emulatorze. Takie sprawdzenie jest dobrym ćwiczeniem z obserwacji działania aplikacji.
Procedura przygotowująca pytanie gromadzi w jednym miejscu wszystkie czynności związane z losowaniem i prezentacją zadania. Taka centralizacja oznacza, że zmiana reguł losowania wymaga edycji tylko jednego fragmentu programu. Wartości losowane są osobno dla każdego czynnika mnożenia według bieżącego zakresu.
Zapisanie iloczynu w zmiennej jeszcze przed pokazaniem pytania umożliwia późniejsze porównanie z odpowiedzią użytkownika. Budowanie treści pytania przez łączenie tekstów daje pełną kontrolę nad jego formatem. Czyszczenie pola odpowiedzi po każdym pytaniu zapobiega pozostawieniu wpisu z poprzedniego zadania.
Ustawienie położenia kursora w pustym polu skraca drogę od pytania do wpisania wyniku. Skoro z procedury korzysta zarówno start sesji, jak i przycisk kolejnego pytania, jej rola jest podwójnie potwierdzona. Rozbicie pracy na małe, nazwane procedury to cecha czytelnego programu.
Sprawdzenie odpowiedzi to moment, w którym program porównuje wpisany tekst z poprawnym wynikiem przechowywanym w zmiennej. Porównanie może dotyczyć tekstu lub liczby, gdyż środowisko potrafi konwertować tekst na liczbę w działaniach. Ta elastyczność niestety bywa źródłem błędów, dlatego konsekwentna konwersja zwiększa pewność działania.
Komunikat zwrotny, zielony przy poprawnej odpowiedzi i czerwony przy błędnej, dostarcza natychmiastowej informacji o wyniku. Dodatkowe podanie prawidłowego wyniku po błędzie służy nauce i utrwala wiedzę. Zwiększenie licznika pytań i punktów musi nastąpić w tym samym miejscu, aby statystyki pozostały spójne.
Rozdzielenie informacji o poprawności od przejścia do kolejnego pytania pozwala uczniowi przeanalizować swoją pomyłkę. Gromadzenie punktów i liczby pytań w zmiennych, a następnie pokazywanie ich w etykiecie, odzwierciedla powszechny wzorzec aktualizacji widoku. Dokładność tej części kodu decyduje o wiarygodności całej punktacji.
Walidacja wejścia to sprawdzenie, czy dane wprowadzone przez użytkownika mają właściwą postać, zanim program podejmie dalsze działania. W naszym projekcie pierwszym kryterium jest niepustość pola, bo porównanie pustego tekstu z liczbą mija się z celem. Pojawia się przy tym informacja dla ucznia, aby wpisać odpowiedź.
Właściwość ograniczająca znaki pola do cyfr zmniejsza liczbę błędów, ale nie gwarantuje poprawności samodzielnie, dlatego walidacja pozostaje konieczna. W przypadku pustej odpowiedzi program powinien przerwać dalsze działanie, aby nie zliczać pustych prób. Dzięki temu licznik pytań odzwierciedla wyłącznie realnie podjęte odpowiedzi.
Kolejność warunków ma znaczenie, najpierw walidacja, potem porównanie z wynikiem, aby nie generować mylących komunikatów. Taki schemat można przenieść do każdej aplikacji z polami tekstowymi, na przykład w quizach lub formularzach. Wykazanie się takim myśleniem jest wysoko cenione przy przeglądach kodu.
Przycisk następnego pytania pełni rolę sterowania cyklem, bo po sprawdzeniu prowadzi do nowego zadania i czyści komunikaty. Powrót pola odpowiedzi do pustego stanu i przywrócenie domyślnego koloru informacji daje użytkownikowi wyraźny znak nowego pytania. Ponowne wywołanie tej samej procedury napędza cały mechanizm sesji.
Zastosowanie ograniczenia liczby pytań, tutaj dziesięciu, wprowadza do aplikacji wymierny cel treningu i umożliwia podsumowanie. Taka granica sprawia, że sesja ma wyraźny początek, środek i koniec, co sprzyja koncentracji ucznia. Warunek liczby pytań staje się naturalnym miejscem sprawdzenia, czy należy zakończyć trening.
Rozdzielenie oceny od przejścia dalej to celowy wybór projektowy, a nie usterka, gdyż daje czas na zapamiętanie poprawnej odpowiedzi. W kontekście nauki taka sekwencja wzmacnia skojarzenie pytania z wynikiem. Ten rytm warto zachować również w późniejszych wariantach aplikacji.
Pomiar czasu w App Inventor opiera się na komponencie zegara oraz zdarzeniu uruchamianym w regularnych odstępach czasu. Przechowywanie czasu w zmiennej sekund i zwiększanie jej o jeden przy każdym nowym zdarzeniu daje prosty licznik sekund. Zatrzymanie liczenia następuje przez zmianę flagi logicznej, a nie przez usunięcie komponentu.
Formatowanie czasu do postaci minut i sekund wymaga dzielenia całkowitego i reszty z dzielenia, które w App Inventor reprezentują odpowiednie bloki arytmetyczne. Dodawanie zera wiodącego pozwala utrzymać stałą długość tekstu, na przykład pięć sekund jako zapis z zerem. Dzięki tym zabiegom odczyt czasu jest przyjazny i przewidywalny.
Osobna procedura odpowiedzialna za przygotowanie napisu czasu sprawia, że logika pomiaru pozostaje oddzielona od prezentacji. Po zakończeniu sesji wartość zmiennej sekund trafia do bazy danych jako element rekordu. Taki podział obowiązków ułatwia modyfikację wyglądu czasu bez ingerowania w sam pomiar.
Ekran wyników prezentuje trwałe dane zgromadzone w bazie danych i dlatego nie przeprowadza żadnych obliczeń własnych. To świadome ograniczenie upraszcza projekt i pozwala oczekiwać, że każdy ekran ma jeden główny obowiązek. Użytkownik przechodzący na ten ekran widzi wyłącznie stan przechowywany w aplikacji.
Wybór trzech kluczowych informacji, rekordu punktowego, najlepszego czasu i liczby sesji, daje zwięzły obraz osiągnięć. Dodanie licznika rozegranych sesji wzbogaca statystyki bez komplikowania interfejsu. Takie minimalne zestawy danych są szczególnie czytelne na małym ekranie telefonu.
Przycisk powrotu domyka nawigację i prowadzi do menu głównego, zachowując przejrzysty przepływ. Umieszczenie danych na ekranie wyników w tych samych miejscach co na ekranie treningu wzmacnia spójność interfejsu. Ekran ten stanowi naturalne podsumowanie całej aktywności aplikacji.
Odczyt wartości z bazy danych to odwrotność zapisu, która przy zachowaniu tego samego klucza zawsze daje spodziewany wynik. Metoda odczytu przyjmuje nazwę klucza i wartość domyślną, używaną wtedy, gdy klucz jeszcze nie istnieje. Dzięki drugiemu argumentowi programy działają poprawnie nawet przed pierwszym zapisem.
Ustawienie domyślnej wartości zera dla rekordu i czasu sprawia, że ekran wyników nigdy nie pokazuje pustych miejsc. Po pierwszej rozegranej sesji w bazie pojawiają się rzeczywiste dane, które zastępują domyślne. Taki mechanizm eliminuje potrzebę oddzielnego sprawdzania, czy jakikolwiek wynik już istnieje.
Odczytanie wszystkich trzech wartości w zdarzeniu inicjującym ekran wyników gwarantuje aktualność prezentowanych danych. Każde otwarcie tego ekranu powoduje świeże pobranie rekordu, czasu i liczby sesji. Ta strategia jest prostsza niż utrzymywanie danych w pamięci przez cały czas działania aplikacji.
Surowa liczba z bazy danych rzadko jest dobrym komunikatem, dlatego wartość rekordu łączy się z opisem słownym. Składanie napisów metodą łączenia fragmentów tekstu pozwala zbudować czytelne zdania zawierające liczby. Taki sposób przygotowania widoku powszechnie występuje w aplikacjach mobilnych.
Podobny zabieg dotyczy czasu, który z liczby sekund zamienia się na zapis w postaci minut i sekund. Podanie liczby sesji bez dodatkowych opisów byłoby dla użytkownika zagadką, dlatego dodajemy stosowny tekst opisowy. Dzięki formatowaniu dane nabierają kontekstu i znaczenia.
Warunek sprawdzający, czy rekord równa się zero, pozwala wyświetlić informację o braku wyników. Użytkownik po raz pierwszy uruchamiający aplikację zobaczy przejrzysty komunikat zamiast pustych liczb. Zaprogramowanie obu wariantów widoku to dobry przykład myślenia o różnych stanach aplikacji.
Zakończenie sesji po dziesiątym pytaniu to moment przejścia z fazy gry do fazy zapisu, dlatego wymaga starannego uporządkowania. Najpierw zatrzymujemy zegar, aby czas nie zmieniał się podczas zapisu wyniku. Następnie porównujemy osiągnięte punkty i czas z danymi przechowywanymi w bazie.
Zasada aktualizacji rekordu opiera się na porównaniu z wartością zapisaną trwale, a nie z wynikiem z pamięci. Mniejszy czas i większa liczba punktów powodują zapis nowych wartości tylko wtedy, gdy rzeczywiście są lepsze. Zwiększenie licznika sesji przy każdym zakończeniu treningu pozwala śledzić całkowitą liczbę gier.
Podsumowanie pokazane użytkownikowi zbiera w jednym miejscu wynik i czas całej sesji. Powrót do menu głównego po zapisaniu danych zamyka cykl nawigacyjny aplikacji. Sekwencja tych operacji bywa dodatkowo zamknięta w osobnej procedurze, co porządkuje kod zakończenia.
Podsumowanie sesji przekazuje użytkownikowi najważniejsze informacje zebrane podczas treningu, punktację i czas wykonania. Taki widok domyka doświadczenie gry i daje uczniowi wartościową informację zwrotną. Dodanie oceny słownej, zależnej od liczby zdobytych punktów, czyni komunikat bardziej motywującym.
Informacja o nowym rekordzie wzmacnia pozytywne emocje i zwiększa zaangażowanie w dalsze treningi. Sformułowanie oceny opisowej, od słabej po znakomitą, można zrealizować kilkoma warunkami kolejno sprawdzanymi. Przekazywanie takiej informacji zaraz po sesji zwiększa szansę, że uczeń zapamięta swoje osiągnięcie.
Dwa przyciski, pozwalające powtórzyć trening lub wrócić do menu, dają użytkownikowi kontrolę nad kolejnym krokiem. Wybranie opcji jest wygodniejsze niż automatyczne zamknięcie ekranu, które zaskakiwałoby użytkownika. Podsumowanie sesji to zatem ważny element zarówno funkcjonalny, jak i motywacyjny.
Zastosowanie jednej zmiennej zakres do opisania trzech poziomów trudności to kolejny przejaw parametryzacji logiki. Gdy zakres przyjmuje wartość pięć, dziesięć lub dwadzieścia, losowanie pytań automatycznie dostosowuje się do ustawienia. Tym samym program nie zawiera trzech kopii tej samej procedury, lecz jedną uniwersalną.
Takie podejście znacznie ułatwia późniejszą modyfikację, bo dodanie kolejnego poziomu sprowadza się do nowej wartości w bazie. Widać tu przewagę dobrze zaprojektowanych danych nad wieloma warunkami opisanymi dla każdego przypadku. Podobną zasadę można zastosować w dowolnym elemencie gry różnicowanym wartością liczbową.
Stała liczba pytań na każdym poziomie utrzymuje porównywalność wyników między różnymi ustawieniami. Dzięki temu uczciwe porównanie rekordu punktowego między poziomami pozostaje możliwe. Takie decyzje projektowe warto uzasadniać i zapisywać już w specyfikacji aplikacji.
Wzbogacenie ekranu wyników o statystyki szczegółowe nadaje aplikacji cechy narzędzia analitycznego. Zliczanie poprawnych i błędnych odpowiedzi wymaga dodatkowych zmiennych aktualizowanych przy każdej ocenie. Te dodatkowe dane odkrywają ścieżkę nauki ucznia i pozwalają mu zobaczyć własne postępy.
Średni czas na pytanie wylicza się z całkowitego czasu sesji i liczby pytań, co stanowi prosty, ale wymowny wskaźnik. Graficzne przedstawienie takich wartości umożliwia między innymi komponent Canvas, na którym rysowane są proste wykresy słupkowe. Pełne omówienie pracy z Canvasem pojawi się w prezentacji piątej.
Ranking kilku ostatnich sesji w formie listy wymaga przechowywania danych w strukturach odpowiednich do naturalnego porządku wyników. Zbiór wyników zapisany w bazie danych można kolejno odczytywać i pokazywać na ekranie. Taki etap pracy przynosi studentowi praktyczne zadanie z zakresu struktur danych.
Kolejność prac nad projektem w App Inventor nie jest kwestią dowolności, lecz konsekwencją natury narzędzi. Ponieważ projekt zaczyna się w Designerze, najpierw powstają ekrany i komponenty, a dopiero później ich zachowanie. Ta sekwencja sprawdza się szczególnie dobrze, gdy nazwy komponentów przemyśleliśmy wcześniej.
Dodanie kolejnych ekranów, z zaprojektowanym wstępnie wyglądem, pozwala widzieć całość projektu, zanim zacznie się praca nad logiką. Opisowe nazwy wszystkich elementów zmniejszają ryzyko pomyłek w oknie bloków. Ukończenie widoku każdego ekranu przed programowaniem skraca czas poszukiwania brakujących komponentów.
Kolejność programowania bloków, ekran po ekranie, odpowiada naturalnemu sposobowi rozumienia aplikacji. Dzięki temu każdy fragment kodu ma swój kontekst i można go testować od razu po napisaniu. Taka metodyka pracy jest zalecana początkującym, ponieważ zapobiega chaosowi i przeoczeniom.
Dyscyplina nazewnicza to inwestycja, która zwraca się przy każdym kolejnym zaglądaniu do projektu. Konsekwentne prefiksy typu btn oznaczają przyciski, a lbl etykiety, dzięki czemu rodzaj komponentu odczytuje się z nazwy. Ta informacja okazuje się bezcenna w często odwiedzanym oknie bloków.
Unikanie polskich znaków i spacji w nazwach to praktyka bezpieczeństwa, bo takie nazwy nie sprawiają problemów w narzędziach. Nazwy krótkie, ale opisowe, takie jak nazwa pola odpowiedzi, zachowują równowagę między czytelnością a zwięzłością. Utrzymanie tej samej konwencji przez wszystkie ekrany czyni projekt spójnym.
Wiara w dobrą pamięć nie wystarcza przy projektach wieloekranowych, dlatego systematyczne nazewnictwo pełni rolę dokumentacji. Gdy do projektu dołącza nowa osoba, spójne nazwy ograniczają czas wdrożenia. Praktyka ta wyrabia dobre nawyki przenoszone na tradycyjne języki programowania.
Zmienne globalne ekranu treningu przechowują cały stan bieżącej sesji, a więc wszystkie informacje, które zmieniają się w trakcie gry. Zgrupowanie ich w jednym miejscu ułatwia przegląd projektu i wykrywanie brakujących czynności. Każda z nich ma jasno określoną rolę i odpowiada na konkretne pytanie o stan programu.
Flaga logiczna kontrolująca zegar oddziela liczenie czasu od reszty logiki, co upraszcza zrozumienie przepływu. Utworzenie zmiennych dokładnie tam, gdzie są używane, ogranicza przypadkowe odwołania do nieistniejących wartości. Przemyślane nazwy zmiennych pełnią rolę krótkich opisów tego, co program w danej chwili przechowuje.
Wszystkie te zmienne są tworzone na ekranie treningu, co odzwierciedla regułę lokalizowania stanu przy jego wykorzystaniu. Dzięki temu ekran menu nie posiada zbędnych danych, a ekran wyników czyta wyłącznie z bazy. Porządek zmiennych jest widoczny od razu, co ułatwia pracę nad kolejnymi wersjami aplikacji.
Wewnątrz procedury przygotowującej pytanie wykonują się instrukcje tworzące jedno kompletne zadanie od początku do końca. Losowanie kolejnych czynników za pomocą osobnych bloków losowych daje każdej parze równe szanse wystąpienia. Obliczenie iloczynu zaraz po wylosowaniu zapewnia zapamiętanie właściwego wyniku.
Budowanie napisu pytania z łączenia kilku fragmentów, w tym symbolu mnożenia, pokazuje praktyczne zastosowanie operacji sklejania tekstu. Wyczyszczenie pola wpisywania i informacji po poprzednim zadaniu pozostawia interfejs w jednoznacznym stanie. Taki pełny zestaw instrukcji tworzy czytelny, samodzielny fragment logiki.
Wywołanie tej samej procedury z dwóch miejsc, startu ekranu i przycisku kolejnego pytania, eliminuje powielanie kodu. Dzięki temu ewentualna zmiana w jednej regule losowania działa wszędzie od razu. Ten przykład dobrze tłumaczy sens wydzielania powtarzalnych fragmentów do osobnych procedur.
Wyodrębnienie procedury oceniającej odpowiedź przenosi skomplikowaną sekwencję warunków do jednego, czytelnego miejsca. Odczytanie wpisanego tekstu, porównanie z wynikiem i aktualizacja komunikatów pozostają w pełni kontrolowane. Przycisk sprawdzający wywołuje wtedy zaledwie jedno wywołanie tej procedury.
Przepis odpowiedzialny za komunikaty, kolor i punktację łączy w sobie czynności z kilku obszarów projektu. Zwiększenie liczby pytań po każdej ocenie utrzymuje porządek w statystykach sesji. Dzięki wydzieleniu tej logiki sprawdzenie odpowiedzi pozostaje tożsame z jednym, prostym działaniem.
Stosowanie procedur bez argumentów sprawdza się, gdy wszystkie potrzebne dane są dostępne jako zmienne globalne. Modyfikacja reakcji na poprawną odpowiedź wymaga wtedy dotknięcia tylko jednego fragmentu kodu. Ten zabieg pokazuje, jak niewielkim kosztem utrzymać wysoką czytelność programu.
Procedura aktualizująca etykietę punktów gromadzi całą logikę przygotowania napisu informującego o postępie sesji. Składanie tekstu z wyników cząstkowych i napisów opisowych daje w efekcie przejrzysty komunikat. Dzięki temu wartość punktów i liczba pytań są zawsze pokazywane w tej samej formie.
Koncentracja formatowania w jednym miejscu zapobiega rozbieżnościom między różnymi fragmentami kodu. Każda zmiana wyglądu komunikatu wymaga edycji tylko pojedynczego bloku. Takie oddzielenie obliczeń od prezentacji stanowi fundament czytelnej architektury aplikacji.
Wywołanie tej procedury po każdej odpowiedzi utrzymuje etykietę w stanie zgodnym z bieżącymi zmiennymi. Jest to prosty przykład wzorca odświeżania widoku w jednym miejscu. Nawet tak drobna procedura uczy cennego nawyku organizowania kodu.
Zamiana liczby sekund na zapis minut i sekund wymaga dwóch operacji arytmetycznych, dzielenia i reszty z dzielenia. Blok odrzucający część ułamkową daje pełne minuty, a reszta z dzielenia przez sześćdziesiąt daje pozostałe sekundy. Takie liczenie bezwarunkowo mieści się w zwykłych możliwościach App Inventor.
Dodanie zera wiodącego do wartości mniejszych od dziesięciu pozwala zachować stałą szerokość zapisu czasu. Blok łączenia tekstów scala minuty, dwukropek i sekundy w finalny napis. Dzięki tym zabiegom czytanie czasu przez ucznia nie wymaga żadnego wysiłku interpretacyjnego.
Przekazywanie liczby sekund jako argumentu czyni procedurę uniwersalną i gotową do ponownego użycia. Przykład osiemdziesięciu trzech sekund, zamienianych na zapis minut i sekund, dobrze ilustruje zasadę działania. Wielokrotne korzystanie z tej procedury w różnych miejscach jedynie potwierdza jej wartość.
Procedura zapisu wyniku porządkuje wszystkie operacje na danych trwałych wykonywane po zakończeniu sesji. Odczyt aktualnego rekordu z bazy poprzedza porównanie, co pozwala ustalić, czy wynik rzeczywiście uległ zmianie na lepsze. Taki schemat zapobiega nadpisaniu dobrego wyniku słabszym rezultatem.
Analogiczne porównanie dla najlepszego czasu wymaga odwołania się do wartości trwale przechowywanej, a nie do bieżącej zmiennej. Zwiększenie licznika sesji wykonuje się przy każdym ukończeniu treningu, niezależnie od wyniku. Umieszczenie tych czynności w jednej procedurze czyni cały proces kontrolowanym i łatwym do zweryfikowania.
Skoro wszystkie operacje na bazie znalazły się w jednym miejscu, czytelność kodu wyraźnie rośnie. Dodanie kolejnego rodzaju rekordu oznacza zaprogramowanie pojedynczej dodatkowej operacji. Ta koncentracja odpowiedzialności stanowi przykład zasady pojedynczej odpowiedzialności przeniesionej na poziom bloków.
Losowanie w programie trenera opiera się na bloku liczby losowej, który najczęściej występuje jako narzędzie zdarzenia losowego. Użycie zmiennej zakres zamiast wartości wpisanej na sztywno sprawia, że jeden blok obsługuje wszystkie poziomy. Wystarczy zmiana jednej wartości w bazie, aby przedziały losowania natychmiast dostosowały się do nowego ustawienia.
Losowanie obu czynników niezależnie zapewnia równomierny rozkład wszystkich par w obrębie danego zakresu. Dzięki temu uczeń nie napotyka systematycznego powtarzania tych samych zadań. W razie potrzeby można dodatkowo sprawdzać, czy wylosowana para nie powtarza się zbyt często.
Ta technika losowania stanowi dobrą podstawę do dalszych ćwiczeń z przypadkowością w aplikacjach. Zachowanie polegające na losowaniu w obrębie wybranego zakresu pojawia się także w grach, quizach i symulacjach. Zapamiętanie tego wzorca przyda się w kolejnych modułach kursu.
Rozumienie typów danych, tekstu i liczby, jest w App Inventor warunkiem poprawnego działania porównań. Wartość pobrana z pola tekstowego zawsze ma postać łańcucha znaków, nawet gdy zawiera same cyfry. W działaniach arytmetycznych środowisko automatycznie interpretuje taki napis jako liczbę.
Porównanie tekstu z liczbą bywa przewidywalne, ale dla bezpieczeństwa zaleca się jawne operowanie wartościami liczbowymi. Dostępny blok porównujący teksty umożliwia jasne sprecyzowanie, jakiego rodzaju porównanie wykonujemy. Uwaga na zbędne spacje i znaki spoza cyfr chroni przed błędami trudnymi do wykrycia.
Świadome zarządzanie typami danych to cecha dojrzalszego programisty i warto ją wyrobić od początku nauki. Uświadomienie sobie, co dokładnie przechowuje każda zmienna, uchroni przed wieloma błędami logicznymi. Ten nawyk przydaje się w każdym języku programowania, nie tylko w środowiskach blokowych.
Komunikaty zwrotne to element interfejsu, który decyduje o tym, czy użytkownik rozumie, co robi aplikacja. Kolory, zielony i czerwony, są rozpoznawane niemal instynktownie i natychmiast informują o rodzaju wyniku. Krótkie komunikaty słowne, takie jak Dobrze lub Błędnie, wzmacniają ten sygnał dodatkowym potwierdzeniem.
Zmiana koloru etykiety przez właściwość odpowiadającą za barwę tekstu to prosta czynność o dużym znaczeniu wizualnym. Dodanie poprawnej odpowiedzi do komunikatu po błędzie zamienia informację zwrotną w lekcję. Taki podwójny sygnał, kolor i słowo, jest cenny zwłaszcza podczas nauki.
Sposób komunikacji z użytkownikiem powinien być spójny w całej aplikacji, od komunikatów o błędach po potwierdzenia działań. Ustalony wcześniej zestaw krótkich sformułowań ułatwia utrzymanie tej spójności. Dobrze dobrane komunikaty podnoszą jakość aplikacji bez żadnych zmian w samej logice.
Seria pytań może być zorganizowana na dwa sposoby, przez zdarzenia napędzane kliknięciami albo przez pętlę wykonującą powtórzenia. W aplikacji interaktywnej naturalnym wyborem jest wariant zdarzeniowy, w którym uczeń sam wyznacza tempo odpowiedzi. Pętla natomiast doskonale sprawdza się do masowego przygotowania danych, na przykład budowania całej listy zadań w jednym przebiegu.
Licznik pytań i warunek zakończenia razem tworzą mechanizm, którego działanie jest w pełni przewidywalne. W wersji zdarzeniowej licznik wzrasta przy każdej ocenie odpowiedzi, a następnie warunek decyduje o zakończeniu sesji. Taka kombinacja jest prostsza do zrozumienia niż zagnieżdżona pętla, dlatego trafia do wersji wprowadzającej.
Zapamiętanie obu wzorców, pętli i licznika, ułatwia dobór właściwego narzędzia do konkretnego zadania. W projektach takich jak quizy i gry pętle porządkują przygotowanie zadań. Świadomy wybór oznacza, że student nie kopiuje schematów na ślepo, lecz rozumie ich przeznaczenie.
Wariant oparty na liście pytań różni się od losowania tym, że zadania pochodzą z przygotowanego wcześniej zbioru. Lista przechowuje pytania, których kolejność może być określona przez użytkownika albo wymieszana spontanicznie. Dzięki temu aplikacja potrafi prezentować wybrane treści w kontrolowany sposób.
Utrzymanie dwóch list, pytań i poprawnych odpowiedzi, wymaga przestrzegania zasady zgodności ich długości i kolejności. Odwołanie do pozycji o tym samym indeksie zapewnia poprawne skojarzenie pytania z odpowiedzią. W App Inventor pozycje listy numerujemy od jedynki, co warto zapamiętać podczas pracy z tymi strukturami.
Losowa kolejność realizuje się przez przetasowanie zawartości listy, a ponieważ takie operacje trzeba zamanifestować samodzielnie, pojawia się tu okazja do ćwiczenia struktur danych. Takie rozwiązanie przygotowuje grunt pod quizy omawiane w prezentacji trzeciej. Praca z listami łączy w sobie elementy logiki, porządkowania i zarządzania danymi.
Baza danych TinyDB działa na zasadzie słownika, w którym każda informacja ma swój klucz i przypisaną mu wartość. Taki model od razu podpowiada, jak nazwać składowane dane, na przykład rekord, czas albo liczbę sesji. Czytelne klucze sprawiają, że odczyt wartości w dowolnym ekranie jest niemal oczywisty.
Przechowywanie ustawień, takich jak wybrany poziom trudności, w jednej wspólnej bazie usuwa problem różnych zmiennych ekranów. Podstawowe operacje ograniczają się do zapisu i odczytu, wywoływanych osobnymi metodami. Taka prostota czyni TinyDB doskonałym narzędziem do nauki trwałego przechowywania danych.
Wybór wartości domyślnej w odczycie chroni program przed błędami związanymi z pierwszą sesją. Należy pamiętać, że dane pozostają na urządzeniu i nie są przenoszone między instalacjami. To ograniczenie należy uwzględnić, planując funkcje wymagające współdzielenia osiągnięć między urządzeniami.
Logika ustanawiania nowego rekordu sprowadza się do poprawnego porównania osiągniętych punktów z wartością zapisaną wcześniej w bazie. Porównanie powinno dotyczyć trwałego odczytu, a nie zmiennej bieżącej sesji, co jest częstym źródłem pomyłek. Zapis nowego wyniku wykonujemy wyłącznie po spełnieniu odpowiedniego warunku.
Osobna flaga informuje pozostałe części programu, że sesja zakończyła się rekordem, co pozwala pokazać to użytkownikowi. Ustawienie tej flagi dokładnie po zapisie daje spójny obraz sytuacji. Najlepszy czas aktualizuje się według identycznej reguły z przeciwnym kierunkiem porównania.
Włączenie tej logiki do procedury zapisu wyniku utrzymuje całą obsługę rekordów w jednym miejscu. Dzięki temu testy tej funkcji dotyczą tylko pojedynczego fragmentu aplikacji. Powtarzalne, dobrze zorganizowane porównania są podstawą niezawodnych statystyk.
Zarządzanie danymi trwałymi obejmuje nie tylko zapis i odczyt, lecz także świadome ich usuwanie i wykonywanie kopii bezpieczeństwa. Metoda czyszcząca całą bazę jest wygodna, ale czyści wszystkie wartości jednocześnie, co wymaga ostrożności. Alternatywą pozostaje nadpisywanie wybranych kluczy wartościami domyślnymi.
Zasada niemal każdej destrukcyjnej operacji zakłada wcześniejsze potwierdzenie przez użytkownika, realizowane oknem dialogowym. Komponent powiadamiający umożliwia pokazanie pytania i obsługę odpowiedzi potwierdzającej lub przeczącej. W ten sposób aplikacja chroni dane przed przypadkowym skasowaniem.
Trwałość zapisanych danych, przetrwanie zamknięcia i ponownego uruchomienia aplikacji, jest główną zaletą bazy TinyDB. Do tworzenia kopii całego projektu służy eksport pliku źródłowego, obejmujący wszystkie zasoby i bloki. Łączenie regularnych eksportów z bezpiecznym czyszczeniem danych pozwala rozwijać projekt bez obaw o utratę pracy.
Plan testów przeczesuje aplikację w zaplanowany sposób, zaczynając od najważniejszych ścieżek i kończąc na przypadkach brzegowych. Każdy scenariusz opisuje konkretną sytuację i oczekiwany rezultat, co ułatwia wykrycie odstępstw. Takie podejście przypomina profesjonalne testy regresji prowadzone w zespołach wytwarzających oprogramowanie.
Przypadki brzegowe, takie jak puste pole albo pierwsze uruchomienie bez jakichkolwiek danych, najczęściej ujawniają ukryte wady. Dlatego warto przygotować testy osobno dla poprawnej drogi i dla drogi błędnej. Odtworzenie opisanego w teście kroku pozwala wiarygodnie ocenić, czy problem faktycznie występuje.
Testowanie na prawdziwym telefonie różni się od sprawdzenia w emulatorze, bo tylko urządzenie fizyczne wiernie odtwarza odczucia interakcji. Wieloetapowy plan, od punktów po restart aplikacji, obejmuje wszystkie kluczowe funkcje trenera. Doświadczenie pokazuje, że systematyczne testy skracają czas doprowadzenia aplikacji do stanu gotowego.
Większość błędów w projektach początkujących wynika z niedokładności nazw, pominiętych inicjalizacji albo błędnego porównania typów. Niezgodna nazwa ekranu w przejściu natychmiast przerywa działanie aplikacji, dlatego warto porównywać zapisy co do znaku. Każdy z tych błędów pozostaje co do zasady łatwy do naprawienia, jeśli tylko zostanie zauważony.
Porównywanie tekstu z liczbą bez konwersji prowadzi czasem do wyników sprzecznych z oczekiwaniami, dlatego przyjmujemy jedną metodę dla całego projektu. Nadużywanie zapisu rekordu, gdy nowy wynik jest gorszy, wymaga poprawnego warunku porównującego z trwałym odczytem. Brak walidacji pustego pola objawia się nieprawdziwymi statystykami sesji.
Tabela objawów, przyczyn i proponowanych postępowań ułatwia powrót do programu po dłuższej przerwie. Systematyczne rozpoznawanie wzorców błędów wyrabia u studenta praktyczne doświadczenie. Po pewnym czasie budowa kolejnej aplikacji staje się szybsza, bo znane pułapki omija się automatycznie.
Porządek w projekcie blokowym to odpowiednik czytelnego kodu źródłowego, ułatwiający jego przegląd i utrzymanie. Grupowanie powiązanych bloków oraz zwijanie nieużywanych fragmentów skraca czas orientacji w przestrzeni roboczej. Komentarze dołączane do procedur i ważnych warunków pełnią rolę notatek dla przyszłego czytelnika.
Plecak w App Inventor umożliwia przenoszenie sprawdzonych bloków między ekranami i projektami, co przyspiesza pracę. Powtarzalne fragmenty przenoszone w ten sposób zachowują tę samą, dobrą jakość. To narzędzie szczególnie przydaje się przy budowaniu zbliżonych funkcji w kolejnych aplikacjach.
Regularny eksport pliku źródłowego chroni przed utratą pracy i ułatwia wracanie do wcześniejszych wersji. Spójne nazewnictwo oraz podział na procedury pozwalają rozwijać aplikację bez lęku przed zepsuciem istniejących fragmentów. Te praktyki przenoszą się naturalnie na tradycyjne środowiska programistyczne.
Zbudowanie instalacyjnego pliku kończy drogę od projektu do urządzenia i pozwala na realne korzystanie z aplikacji. W menu Build znajduje się opcja tworzenia pakietu dla Androida, po której aplikacja zaczyna być kompilowana w chmurze. Po pewnym czasie pojawia się gotowy plik albo adres umożliwiający pobranie i instalację.
Przenoszenie aplikacji na telefon może odbywać się przewodem, przez przesłanie pliku albo przez kod QR wyświetlany w przeglądarce. Włączenie instalacji z nieznanych źródeł to standardowy krok wymagany przy instalacji spoza sklepu. Po uruchomieniu aplikacji na prawdziwym urządzeniu jej działanie można ocenić w realnych warunkach.
Warto pamiętać o limicie rozmiaru pliku źródłowego, który narzuca oszczędne gospodarowanie zasobami graficznymi. Kompresja obrazów i ograniczenie liczby dodatkowych plików pomagają zmieścić się w dozwolonym zakresie. Przygotowanie ikony i ekranu startowego w odpowiednich rozmiarach poprawia odbiór profesjonalnej aplikacji.
Lista pomysłów na dalszy rozwój pokazuje, jak wiele wariantów gry można zbudować na istniejącej konstrukcji. Dodanie działań innych niż mnożenie wymaga rozszerzenia logiki pytań i przechowywania wybranego trybu. Rozszerzenie o tryb czasowy zmienia cel rozgrywki, co prowadzi do przebudowy warunków zakończenia sesji.
Poziomy trudności zwiększane automatycznie uzależniają zakres losowania od osiągnięć użytkownika, co wzbogaca motywację. Dźwięki przy odpowiedziach realizuje komponent odtwarzający nagrane wcześniej pliki. Wysyłanie wyników na serwer wymaga komponentu sieciowego i wiedzy o komunikacji między aplikacją a usługą.
Każda nowa funkcja to okazja do ponownego użycia wzorców zdarzeń, procedur i danych trwałych. Taka praktyka utrwala poznane mechanizmy bez konieczności ucznia się nowego materiału od podstaw. Stopniowe dodawanie kolejnych ćwiczeń przygotowuje grunt pod większe projekty omawiane w dalszej części kursu.
Podsumowanie prezentacji sprowadza się do kilku trwałych zasad, które student powinien wynieść z tego wykładu. Planowanie specyfikacji i ekranów przed pisaniem kodu okazuje się najważniejszą inwestycją czasu. Ten sam porządek myślowy stosuje się przy każdym kolejnym projekcie aplikacji mobilnej.
Trwałość danych między sesjami osiągnięto dzięki bazie TinyDB, która jest wspólnym magazynem dla wszystkich ekranów. Zdarzenia, warunki i losowość, połączone w całość, budują mechaniczną grę trenera. Umiejętne łączenie tych elementów odróżnia proste scenki od pełnowartościowych aplikacji.
Testowanie zarówno dróg poprawnych, jak i przypadków brzegowych nadaje programowi potrzebną niezawodność. Powstały trener stanowi wzorzec architektury, do jakiego student może wracać przy budowie własnych pomysłów. Przeniesienie tych zależności na nowy projekt jest głównym sprawdzianem kompetencji.
Odpowiedzi zebrane w tym zestawieniu pokazują, że każdy mechanizm omawiany na wykładzie znajduje swoje miejsce w kodzie. Umiejętność samodzielnego sformułowania takiej odpowiedzi jest bardziej wartościowa niż zapamiętanie jej na pamięć. Równie ważne jak same odpowiedzi jest to, czy uczeń rozumie, dlaczego zaproponowane rozwiązanie działa.
Pytania kontrolne zostały dobrane tak, aby obejmowały wszystkie etapy budowy aplikacji, od wymiany danych po zatrzymanie zegara. Powtórzenie odpowiedzi na głos albo w formie pisemnej utrwala pojęcia znacznie lepiej niż samo czytanie. Wartość każdego pytania rośnie, gdy student potrafi podać także przykład z własnego projektu.
Zadanie końcowe, dodanie trybu dzielenia z osobnym rekordem, sprawdza umiejętność przenoszenia wzorców na nowy obszar. Wymaga ono odtworzenia znanych kroków, zapisu nowego klucza w bazie oraz utrzymania spójnego interfejsu. Wykonanie go samodzielnie jest najlepszym dowodem opanowania materiału z całej prezentacji.
Zadania praktyczne tworzą ścieżkę od odtworzenia gotowego programu do samodzielnego wprowadzania zmian. Najpierw warto wykonać wierną kopię trenera, aby przejść całą drogę budowy i nabrać płynności w pracy. Takie ćwiczenie buduje zaufanie do własnych umiejętności przed przystąpieniem do modyfikacji.
Dodanie czwartego poziomu pokazuje praktyczne skutki parametryzacji, bo wystarczy nowa wartość zakresu i pozycja na liście. Podobnie prosto realizuje się dodanie dźwięku, które opiera się na znajomości jednego komponentu. Stopniowe modyfikacje pozwalają zauważyć, jak niewiele zmian wymaga wzbogacanie dobrze zaprojektowanej aplikacji.
Ekran z rankingiem kilku ostatnich sesji wymaga zastosowania list przechowywanych w bazie danych. Zmiana wyglądu, kolorów, czcionek i obrazka tła, uczy dbałości o warstwę wizualną. Układ zadań, od najprostszego do najtrudniejszego, pozwala każdemu studentowi pracować we własnym tempie.
Zakończenie prezentacji przypomina, że powstał kompletny, działający program wieloekranowy, a nie tylko zestaw pojedynczych przykładów. Umiejętność scalania poznanych mechanizmów w jedną aplikację jest celem całego czwartego modułu. Zbudowany trener może posłużyć jako baza do eksperymentów i własnych pomysłów.
Materiały kursowe, obok prezentowanych wykładów, zawierają szczegółowe instrukcje, do których warto wracać podczas pracy. Serwis App Inventor udostępnia aplikację w chmurze i pozwala kontynuować projekt na dowolnym urządzeniu. Samodzielne przeglądanie dokumentacji i forów wsparcia rozwija nawyk uczenia się poza salą wykładową.
W następnej prezentacji zajmiemy się czujnikami, multimediami i grami, co otworzy kolejny obszar możliwości. Zbudowane dotąd kompetencje będą stanowić solidną podstawę dla tych nowych tematów. Zachęcam do zachowania tego projektu i rozwijania go w miarę przybywania nowych umiejętności.