Niestandardowe bloki: przewodnik po stylu

Na przestrzeni lat zespół Blockly i Blockly Games nauczył się wielu rzeczy które dotyczą osób tworzących nowe bloki. Oto zbiór popełnionych przez nas błędów lub błędów często popełnianych przez innych.

Oto ogólne lekcje, których nauczyliśmy się, używając stylu wizualnego Blockly może nie dotyczyć wszystkich przypadków użycia lub projektów. Są też inne rozwiązania. To jest ale nie jest to wyczerpująca lista problemów, które mogą napotkać użytkownicy, oraz sposobów unikania . Każdy przypadek jest trochę inny i wiążą się z nimi różne kompromisy.

1. Warunkowe a pętle

Najtrudniejszym zadaniem dla nowych użytkowników są warunkowe i pętle. Wiele środowiska oparte na blokach grupują oba te bloki w „Elementy sterujące” gdzie obie bryły mają taki sam kształt i ten sam kolor. Często jest to frustrujące, ponieważ nowi użytkownicy mylą te dwa bloki. Blockly zaleca przeniesienie warunków i pętli do osobnej struktury „Logic” oraz „Pętle” kategorie, a każda z nich ma inny kolor. Wyraźnie pokazuje to, są to różne idee, które zachowują się inaczej, chociaż mają podobne kształty.

Zalecenie: oddziel warunki i pętle od siebie.

2. Listy składające się z 1 elementu

Początkujący programiści źle reagują na pierwszą listę, która zawiera listy zerowe. obecnie się znajdujesz. W efekcie Blockly podąża za Luą i Lambda Moo, tworząc listę i indeksowania ciągów znaków.

W bardziej zaawansowanych zastosowaniach Blockly są obsługiwane listy liczone od zera, i ułatwia im przejście na tekst. Dla młodszych i początkujących odbiorców nadal zalecamy indeksowanie pojedynczego.

Zalecenie: pierwsza liczba to pierwsza.

3. Dane wejściowe użytkownika

Parametr można uzyskać od użytkownika na 3 sposoby. Menu to jest najbardziej restrykcyjny i sprawdza się w przypadku prostych samouczków i ćwiczeń. Pole do wprowadzania danych pozwala na większą swobodę i jest dobrym rozwiązaniem dla większej liczby działań twórczych. Blok wartości dane wejściowe (zwykle z blokiem cienia) umożliwiają obliczenie wartości (np. generator losowy), a nie być tylko wartością statyczną.

Zalecenie: wybierz metodę przesyłania odpowiednią dla Twoich użytkowników.

4. Obrazy blokad na żywo

Dokumentacja bloków powinna zawierać obrazy bloków, do których się odnoszą. do. Robienie zrzutów ekranu jest łatwe. Ale jeśli jest 50 takich obrazów, aplikacja została przetłumaczona na 50 języków, a w jednym z nich statycznych obrazów. Schemat kolorów się zmienia i 2500 zdjęć wymaga aktualizacji. ponownie.

Aby wydostać się z tego koszmaru, zastąpiliśmy Blockly Games na wszystkich zrzutach ekranu z instancjami Blockly w trybie tylko do odczytu. Wynik wygląda identycznie jak zdjęcie, ale na pewno jest aktualne. Tylko do odczytu umożliwił internacjonalizację.

Zalecenie: jeśli obsługujesz więcej niż 1 język, użyj trybu „tylko do odczytu”.

5. Twoja druga lewa strona

Opinie od dzieci z USA (choć co ciekawie, nie z innych krajów) ujawniło ogromne dezorientację między lewą a prawą stroną. Rozwiązaliśmy ten problem za pomocą dodawania strzałek. Jeśli kierunek jest względny (na przykład do awatara), styl strzałki jest ważny. A → strzałka prosta lub strzałka obrócenia ↱ – wprowadza w błąd gdy awatar jest skierowany w przeciwną stronę. Najbardziej przydatny jest okrąg ⟳ nawet wtedy, gdy kąt obrócenia jest mniejszy, niż wskazuje strzałka.

Zalecenie: w miarę możliwości uzupełnij tekst ikonami Unicode.

6. Bloki wysokiego poziomu

W miarę możliwości należy podejmować działania wyższego poziomu, nawet jeśli zmniejsza to lub efektywność działania. Weźmy pod uwagę to wyrażenie Apps Script:

SpreadsheetApp.getActiveSheet().getDataRange().getValues()

W ramach mapowania 1:1, które zachowuje wszystkie potencjalne możliwości, powyższe zmiany zostałaby utworzona za pomocą czterech bloków. Blockly dąży jednak do wyższego poziomu i udostępni tylko jeden blok, który obejmuje całe wyrażenie. Celem jest w przypadku 95%, nawet jeśli utrudniłoby to pozostałe 5%. Blockly nie jest zamiennikiem języków opartych na tekście, który ma pomóc użytkownikom przejść przez wstępną krzywą uczenia się i używać języków opartych na tekście.

Zalecenie: nie konwertuj na ślepo całego interfejsu API w bloki.

7. Opcjonalne wartości zwracane

Wiele funkcji w programowaniu tekstowym wykonuje działanie, a potem zwraca wartość. Zwracana wartość może, ale nie musi, zostać użyta. Na przykład: pop(). Pop może być wywoływany, aby pobrać i usunąć ostatni element, lub może być wywoływany tylko do usunięcia ostatniego elementu z zwracaną wartością. są ignorowane.

var last = stack.pop();  // Get and remove last element.
stack.pop();  // Just remove last element.

Języki oparte na blokach zwykle nie nadają się do ignorowania zwracanych wartości. O musi być wpięty w coś, co akceptuje tę wartość. Istnieją kilka strategii radzenia sobie z tym problemem.

a) Omów problem. W większości języków opartych na blokach język projektuje się aby uniknąć takich sytuacji. Na przykład Scratch nie zawiera żadnych bloków, w których zastosowano zarówno skutki uboczne, jak i zwrot z inwestycji.

b) Dostarcz 2 bloki. Jeśli miejsce w narzędziach nie stanowi problemu, możesz rozwiązaniem jest utworzenie dwóch bloków tego typu – jednego bez zwracanej wartości. a to z kolei może być mylące. z wieloma niemal identycznymi blokami.

c) Zmiana jednego bloku. Za pomocą menu, pola wyboru lub innego elementu sterującego, użytkownik decyduje, czy ma zostać zwrócona wartość. Blok zmienia kształt w zależności od dostępnych opcji. Na przykład: widoczne w bloku dostępu do listy Blockly.

d) Zjadaj wartość. W pierwszej wersji App Inventor utworzono specjalną kreskę pionową który zjadł dowolną powiązaną wartość. użytkownicy nie rozumieli, na czym polega koncepcja, druga wersja App Inventor usunęła blok potoku, zaleca się, aby użytkownicy po prostu przypisywali wartość do jednorazowej zmiennej.

Zalecenie: każda strategia ma wady i zalety – wybierz rozwiązanie odpowiednie dla klienta użytkowników.

8. Rosnące bloki

Niektóre blokady mogą wymagać zmiennej liczby danych wejściowych. Przykłady: blok dodawania , który sumuje dowolny zbiór liczb, lub blok if/elseif/else blok z dowolnym zbiorem klauzul otherif lub konstruktorem listy z argumentem dowolną liczbę zainicjowanych elementów. Istnieje kilka strategii, oraz wadami i zaletami każdego z nich.

a) Najprostszym sposobem jest, aby użytkownik składał blok z mniejszych części. bloki. Przykładem może być dodanie 3 liczb przez zagnieżdżenie dwóch dwuliczbowych bloki dodawania. Innym przykładem może być podanie tylko blokad „if/else”, a użytkownik zagnieżdża je, aby utworzyć warunki otherif.

Zaletą tego podejścia jest jego początkowa prostota (zarówno z punktu widzenia użytkowników, dewelopera). Wadą jest to, że w przypadku dużych ilości zagnieżdżania, kod staje się bardzo niewygodny i trudny dla użytkownika. odczytywanie i utrzymywanie.

b) Innym rozwiązaniem jest dynamiczne rozwijanie bryły, tak by zawsze na końcu tekstu. Analogicznie blokada usuwa ostatnie dane wejściowe, jeśli są dwóch bezpłatnych danych wejściowych na końcu. Właśnie takie podejście stosujemy w pierwszej wersji Użyto programu App Inventor.

Użytkownicy App Inventor od pewnego czasu nie lubią bloków, które powiększają się automatycznie z powodów. Po pierwsze, twórcy zawsze mieli dostęp do swobodnych opinii, a program nie 'zakończona”. Po drugie, wstawienie elementu pośrodku stosu i frustrujące, bo wymagało odłączenia wszystkich elementów w dół z powrotem. Jeśli jednak kolejność nie jest istotna, a użytkownicy mogą ale bez problemu poradzili sobie z dziurami w programie, jest to bardzo wygodna opcja.

c) Niektórzy programiści dodają przyciski +/- do bloków, które pozwalają rozwiązać problem z dziurami. ręcznie dodać lub usunąć dane wejściowe. Otwórz Roberta, korzystając z dwóch takich przycisków, lub usuń z dołu elementy wejściowe. Inni deweloperzy dodają po 2 przyciski tak aby wstawianie i usuwanie elementów ze środka stosu uwzględnione w dokumencie. Inne dodają po 2 przyciski w górę/w dół w każdym wierszu, aby zmienić kolejność w jakimś miejscu.

Ta strategia obejmuje wachlarz opcji – od 2 przycisków na blok, do czterech przycisków w rzędzie. Użytkownicy mogą nie być w stanie na wykonanie działań, których potrzebują, natomiast interfejs jest wypełniony wyglądają jak most statku kosmicznego Enterprise.

d) Najbardziej elastycznym sposobem jest dodanie do bloku bąbelków mutatora. Ten jest reprezentowany jako pojedynczy przycisk, który otwiera okno konfiguracji blokować. Elementy można dodawać, usuwać i zmieniać ich kolejność.

Wadą tego podejścia jest to, że mutatory nie są intuicyjne dla początkujących użytkowników. Przedstawienie mutatorów wymaga jakiegoś rodzaju instrukcji. Aplikacje oparte na blokach kierowane do młodszych dzieci nie powinny używać mutatorów. Chociaż już się nauczyli, są bezcenne dla doświadczonych użytkowników.

Zalecenie: każda strategia ma wady i zalety – wybierz rozwiązanie odpowiednie dla klienta użytkowników.

9. Generowanie czystego kodu

Użytkownicy Advanced Blockly powinni mieć możliwość zobaczenia wygenerowanego kodu (JavaScript, Pythona, PHP, Lua, Dart itp.) i od razu rozpoznają napisany przez siebie program. Oznacza to, że trzeba włożyć więcej wysiłku, aby zachować ten kod wygenerowany maszynowo czytelna. zbędnych nawiasów, zmiennych liczbowych, zmiażdżonych odstępów i takie szablony uniemożliwiają wygenerowanie eleganckiego kodu. Wygenerowany kod powinien zawierać komentarze i być zgodny z Przewodniki stylistyczne Google.

Zalecenie: pochwal się wygenerowanym kodem. Pokaż je użytkownikowi.

10. Zależność od języka

Efektem ubocznym chęci posiadania czystego kodu jest to, że zachowanie Blockly są zazwyczaj zdefiniowane w sposobie zachowania danego języka. Najbardziej typowym językiem wyjściowym jest JavaScript, ale jeśli Blockly zmienić język, nie należy podejmować nieuzasadnionych prób zachowania dokładne zachowanie w obu językach. np. w skrypcie JavaScript pusty string ma wartość false (fałsz), podczas gdy w Lua to prawda. Zdefiniowanie jednego wzorca dla wykonania kodu Blockly niezależnie od języka docelowego w efekcie powstaje kod, który wygląda, jakby pochodził z kompilatora GWT.

Zalecenie: Blockly nie jest językiem, zezwól na istniejący język na zachowanie użytkownika.