Blocs personnalisés: Guide de style

Au fil des ans, les équipes de Blockly et Blockly Games ont appris de nombreuses leçons applicables à ceux qui développent de nouveaux blocs. Voici un exemple un ensemble d'erreurs que nous avons commises ou d'erreurs fréquemment commises par d'autres.

Ce sont des leçons générales que nous avons apprises en utilisant le style visuel et peuvent ne pas s'appliquer à tous les cas d'utilisation ou conceptions. Il existe d'autres solutions. C'est non une liste exhaustive des problèmes que les utilisateurs peuvent rencontrer et comment les éviter de l'IA générative. Chaque cas est un peu différent et a ses propres compromis.

1. Expressions conditionnelles ou boucles

Les blocs les plus difficiles pour les nouveaux utilisateurs sont les conditions et les boucles. Beaucoup dans les environnements basés sur des blocs regroupent ces deux blocages dans le même , les deux blocs ayant la même forme et la même couleur. Cela génère souvent de la frustration, car les nouveaux utilisateurs confondent les deux blocs. Blockly recommande de déplacer les conditions et les boucles dans des "logiques" distinctes et Boucles catégories, chacune avec une couleur différente. Cela montre clairement que ce sont des idées distinctes qui se comportent différemment, malgré des formes similaires.

Recommandation: Séparez les conditions et les boucles.

2. Listes basées sur une seule liste

Les programmeurs débutants réagissent mal lorsqu'ils rencontrent des listes basées sur zéro pour la première en temps réel. Par conséquent, Blockly suit l'exemple de Lua et Lambda Moo en créant des listes et l'indexation des chaînes.

Pour des utilisations plus avancées de Blockly, les listes basées sur zéro sont prises en charge pour passer au texte plus facilement. Pour un public plus jeune ou plus débutant une indexation unique est toujours recommandée.

Recommandation: Le premier chiffre correspond au chiffre 1.

3. Entrées utilisateur

Vous pouvez obtenir un paramètre de trois façons auprès de l'utilisateur. Une liste déroulante est le le plus restrictif, et convient aux tutoriels et exercices simples. Un champ de saisie offre plus de liberté et convient à des activités plus créatives. Un bloc "value" (généralement avec un bloc fantôme) permet de calculer une valeur (par exemple, un générateur aléatoire) au lieu d'être simplement une valeur statique.

Recommandation: Choisissez un mode de saisie adapté à vos utilisateurs.

4. Images de blocs en direct

La documentation des blocs doit inclure des images des blocs auxquels elle fait référence auxquelles vous souhaitez vous connecter. Il est facile de faire des captures d'écran. Mais s'il existe 50 images de ce type est traduite en 50 langues, et soudain,l'une d'entre elles gère 2 500 langues des images statiques. Ensuite, le jeu de couleurs change,et 2 500 images doivent être mises à jour. encore une fois.

Pour nous échapper de ce cauchemar de maintenance, Blockly Games a remplacé toutes les captures d'écran montrant des instances de Blockly s'exécutant en mode lecture seule. Résultat est identique à une image, mais leur actualisation est garantie. Lecture seule a rendu possible l'internationalisation.

Recommandation: Si plusieurs langues sont disponibles, utilisez le mode lecture seule.

5. Votre autre gauche

Commentaires d'enfants aux États-Unis (même s'il est intéressant de noter que ceux-ci ne proviennent pas d'autres pays) a révélé une confusion généreuse entre la gauche et la droite. Ce problème a été résolu grâce au l'ajout de flèches. Si la direction est relative (pour un avatar, par exemple), la le style de flèche est important. A → Flèche droite ou flèche de rotation ↱ manque de confusion lorsque l'avatar est tourné dans la direction opposée. Le plus utile est l'icône circulaire ⟳ flèche, même dans les cas où l'angle de rotation est inférieur à ce qu'indique la flèche.

Recommandation: Dans la mesure du possible, ajoutez des icônes Unicode au texte.

6. Blocs de haut niveau

Dans la mesure du possible, une approche de haut niveau doit être adoptée, même si elle réduit les performances d'exécution ou la flexibilité. Prenons l'expression Apps Script suivante:

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

Dans un mappage 1:1 qui préserve toutes les capacités potentielles, les éléments serait construite à partir de quatre blocs. Mais Blockly vise un niveau plus élevé et fournirait un bloc qui encapsule l'expression entière. L'objectif est pour optimiser les 95% de cas, même si cela complique les 5% restants. Blockly n'a pas vocation à remplacer les langues textuelles. vise à aider les utilisateurs à surmonter la phase d'apprentissage initiale pour qu'ils puissent utiliser dans les langues basées sur le texte.

Recommandation: Ne convertissez pas aveuglément l'intégralité de votre API en blocs.

7. Valeurs renvoyées facultatives

De nombreuses fonctions de la programmation textuelle effectuent une action, puis renvoient une valeur. Cette valeur renvoyée peut ou non être utilisée. Par exemple, l'attribut fonction pop(). Pop peut être appelé pour obtenir et supprimer le dernier élément, ou il peut être appelé pour supprimer uniquement le dernier élément avec la valeur renvoyée d'être ignorés.

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

Les langages basés sur des blocs ne sont généralement pas efficaces pour ignorer une valeur renvoyée. A le bloc "value" doit se connecter à quelque chose qui accepte la valeur. Il y a plusieurs stratégies pour résoudre ce problème.

a) Contournez le problème. La plupart des langages basés sur des blocs conçoivent pour éviter ces cas de figure. Par exemple, Scratch ne comporte aucun bloc contenant les effets secondaires et une valeur renvoyée.

b) Fournissez deux blocs. Si l’espace dans la boîte à outils n’est pas un problème, un simple est de fournir deux de chaque type de bloc, un avec et un sans valeur renvoyée. L'inconvénient est que cela peut entraîner une confusion avec de nombreux blocs presque identiques.

c) Modifier un bloc. Utilisez un menu déroulant, une case à cocher ou une autre commande à l'utilisateur de choisir s'il y a une valeur renvoyée ou non. Le bloc puis change de forme en fonction de ses options. Par exemple, vous pouvez visible dans le bloc d'accès à la liste de Blockly.

d) Consommationr la valeur. La première version d'App Inventor a créé un pipe spécial qui consomme n'importe quelle valeur connectée. Les utilisateurs n'ont pas compris le concept et la deuxième version d'App Inventor a supprimé le bloc du tuyau et à la place recommandait aux utilisateurs d'attribuer simplement la valeur à une variable non autorisée.

Recommandation: Chaque stratégie a ses avantages et ses inconvénients. Choisissez celle qui convient vos utilisateurs.

8. Blocs de croissance

Certains blocs peuvent nécessiter un nombre variable d'entrées. Exemples : bloc d'addition qui additionne un ensemble arbitraire de nombres, ou un opérateur if/elseif/else avec un ensemble arbitraire de clauses elseif ou un constructeur de liste avec un nombre arbitraire d'éléments initialisés. Il existe plusieurs stratégies, chacun avec ses avantages et ses inconvénients.

a) L'approche la plus simple consiste à faire en sorte que l'utilisateur compose le bloc à partir de blocs. Par exemple, vous ajouteriez trois nombres, en imbriquant deux nombres à deux des blocs supplémentaires. Autre exemple : vous ne fournissez que les blocs if/else, et en faisant en sorte que l'utilisateur les imbrique pour créer des conditions elseif.

L'avantage de cette approche est sa simplicité initiale (à la fois pour l'utilisateur et le développeur). L'inconvénient est que lorsqu'un grand nombre d'imbrications, le code devient très fastidieux et difficile pour l'utilisateur à lire et à gérer.

b) Une autre solution consiste à développer le bloc de façon dynamique afin qu'il y en ait toujours entrée libre à la fin. De même, le bloc supprime la dernière entrée s'il existe deux entrées libres à la fin. C'est l'approche que la première version App Inventor utilisé.

Les utilisateurs d'App Inventor n'aiment pas les blocs qui s'agrandissent automatiquement pendant quelques temps de raisons. Tout d'abord, il y avait toujours une entrée libre et le programme n'a jamais été "complete" (terminé). Deuxièmement, l'insertion d'un élément au milieu de la pile était frustrant, car cela impliquait de déconnecter tous les éléments sous la modification et les reconnecter. Cela dit, si l'ordre n'est pas important et que les utilisateurs peuvent à l'aise avec les trous dans leur programme, c’est une option très pratique.

c) Pour résoudre le problème des trous, certains développeurs ajoutent des boutons +/- aux blocs ajouter ou supprimer manuellement des entrées. Roberta utilise deux boutons de ce type pour ajouter ou supprimez les entrées en partant du bas. Les autres développeurs ajoutent deux boutons à chacun ligne afin que l'insertion et la suppression à partir du milieu de la pile adapté. D’autres ajoutent deux boutons haut/bas à chaque ligne afin que l’ordre des la pile peut être adaptée.

Cette stratégie est un éventail d'options allant de seulement deux boutons par bloc, jusqu'à quatre boutons par rangée. À une extrémité, il y a le risque que les utilisateurs ne puissent pas pour effectuer les actions dont il a besoin, à l'autre extrémité de l'UI est tellement remplie de de boutons qui ressemblent au pont du vaisseau spatial Enterprise.

d) L'approche la plus flexible consiste à ajouter une bulle de mutateur au bloc. Ce est représentée par un bouton unique qui ouvre une boîte de dialogue de configuration . Les éléments peuvent être ajoutés, supprimés ou réorganisés à votre guise.

L'inconvénient de cette approche est que les mutateurs ne sont pas intuitifs pour les utilisateurs novices. L'introduction de mutateurs nécessite une certaine forme d'instruction. Les applications par blocs ciblant les jeunes enfants ne doivent pas utiliser de mutateurs. Une fois apprises, elles sont inestimables pour les utilisateurs expérimentés.

Recommandation: Chaque stratégie a ses avantages et ses inconvénients. Choisissez celle qui convient vos utilisateurs.

9. Génération de code propre

Les utilisateurs de l'option Advanced Blockly doivent pouvoir consulter le code généré (JavaScript, Python, PHP, Lua, Dart, etc.) et reconnaissent immédiatement le programme qu'ils ont écrit. Des efforts supplémentaires sont donc nécessaires pour conserver ce code généré automatiquement et lisibles. Parenthèses excessives de parenthèses, variables numériques, espaces blancs écrasés et les modèles de code détaillés empêchent tous de produire du code élégant. Le code généré doit inclure des commentaires et doit être conforme au Guides de style Google

Recommandation: Soyez fier du code généré. Montrez-le à l'utilisateur.

10. Dépendance linguistique

L'un des effets secondaires du désir de code propre est que le comportement de Blockly est défini en grande partie en termes de comportement du langage compilé de manière croisée. Les plus langage de sortie courant est JavaScript, mais si Blockly devait effectuer une compilation croisée dans une autre langue, aucune tentative déraisonnable de préserver un comportement exact dans les deux langues. Par exemple, en JavaScript, un champ vide la chaîne est "false", alors que pour Lua, c'est "true". Définir un seul modèle de pour que le code de Blockly s'exécute quelle que soit la langue cible entraînant des problèmes de gestion du code qui semblent provenir du compilateur GWT.

Recommandation: Blockly n'est pas une langue, autorisez la langue existante à sur le comportement.