Skip to content

Découvrir Linotte 3 en dix minutes

cpc6128 edited this page Feb 9, 2022 · 64 revisions

Dix minutes pour découvrir les bases

📣 Remarques


  • Ce document présente rapidement quelques fonctionnalités du langage Linotte.
  • Ce n'est pas un tutoriel pour apprendre à programmer.

🔔 Prérequis


🎬 Présentation


Linotte est un langage de programmation très simple à prendre en main. Ces principales caractéristiques sont :

  • programmation fonctionnelle
  • programmation orientée objet
  • programmation graphique et événementielle
  • programmation web dynamique

🎓 Des applications puissantes


Malgré sa simplicité apparente, le langage peut produire des programmes complexes.

🐒 Premier pas


affiche "Bonjour !"

En 1 ligne, nous avons écrit un premier programme qui peut être directement exécuté dans l'atelier Linotte.

🔦 Exemple avec une variable


La notion de variables en Linotte s'exprime à travers la notion d'acteurs. Un acteur est caractérisé par un nom, un rôle (un type) et une valeur.

prénom prend "Nicolas"
affiche "Bonjour, " + prénom

Cet exemple créé l'acteur prénom typé texte et contiendra la valeur "Nicolas". Si vous l'essayez dans l'Atelier, vous obtiendrez à l'affichage : Bonjour, Nicolas

🔦 Des types simples


Le langage propose seulement 5 types qui sont : texte, nombre, drapeau, casier, espèce

Nous verrons à travers les exemples comment les utiliser.

🔈 Interaction avec l'utilisateur

Le verbe Demander interroge l'utilisateur :

prénom est un texte
affiche "Quel est ton prénom ?"
demande prénom
affiche "Bonjour, " + prénom

Le verbe Questionner peut être également utilisé :

prénom est un texte
questionne prénom sur "Quel est ton prénom ?"
affiche "Bonjour, " + prénom

🔦 Fonctions mathématiques


Les fonctions disponibles sont :

  • Carré d'un nombre : carré x
  • Cosinus : cos x
  • Sinus : sin x
  • Fonction exponentielle : exp x
  • Logarithme décimal: log x
  • Logarithme naturel: logn x
  • Valeur absolue : abs x
  • Racine carrée : racine x
  • Arrondi : arrondi x
  • Cube d'un nombre : cube x
  • Puissance : x puiss n
  • Modulo : x mod n
  • Et logique : x et n
  • Ou logique : x ou n
  • Xou logique : x xou n
  • Tangente : tan x
  • Arc cosinus : acos x
  • Arc sin : asin x
  • Arc tangente : atan x
  • Hasard : hasard x

Exemple simple :

affiche carré 4
affiche 2 puiss 4
affiche vrai ou faux
affiche (2 puiss 23 + 5 * 6 - 1) / 3

Exemple plus complexe :

durée est un nombre
e est un nombre
demande e
tant que e != 1
	durée prend durée + 1
	si (e mod 2) = 0, e prend e / 2
	sinon e prend e * 3 + 1
ferme
affiche durée

🔦 Les conditions


Le langage propose les conditions suivantes :

  • si 1 = 1 affiche "vrai"
  • si 1 != 1 affiche "faux"
  • si 2 > 1 affiche "vrai"
  • si 1 < 2 affiche "vrai"
  • si 1 >= 1 affiche "vrai"
  • si 2 <= 2 affiche "vrai"
  • si ?.collision(?) affiche "vrai" (à utiliser avec des objets graphiques)
  • si vrai affiche "vrai"
  • si "a" contient "banane" affiche "vrai"

Les conditions peuvent s'utiliser simplement sur une ligne :

si (2 * 2) = (2 + 2) affiche "j'ai raison !"
si (3 * 3) > (3 + 3) affiche "j'ai encore raison !"

On peut utiliser les blocs :

si (1 * 1) != (1 * 1)
	affiche "j'ai dit :"
	attends 500 millisecondes
	affiche "tu as tort !"
ferme

La clause Sinon peut également être utilisée :

si (1 * 1) != (1 * 1)
	affiche "j'ai dit :"
	attends 500 millisecondes
	affiche "tu as tort !"
ferme
sinon
	affiche "j'ai dit :"
	attends 500 millisecondes
	affiche "j'ai toujours raison !"
ferme

🔦 Les fonctions et paramètres


Il est parfois utile de découper un programme en plusieurs fonctions :

// Exemple inspiré du manuel utilisateur du CPC 6128 (page 32)
efface tableau
affiche dame("")
affiche "Noire dans le gris du soir,"
affiche dame("")
affiche "Grise dans le noir. 
"
affiche nuage(",")
affiche "Il fait noir comme dans un four,"
affiche nuage(".")
affiche "Tiens le petit jour. 
"
affiche dame(",")
affiche "Rose dans les rayons bleus,"
affiche dame(" :")
affiche "Debout, paresseux. 

Paul Verlaine."

dame : suffix
	retourne "Dame souris trotte" + suffix

nuage : suffix
	retourne "Un nuage passe" + suffix
  • Les blocs

Les blocs sont des structures internes à une fonction. On peut les utiliser dans des conditions ou les boucles. Un bloc termine avec le verbe fermer.

capitale est un texte
tant que capitale != "Paris"
	affiche "Quelle est la capitale de la France ?"
	demande capitale
ferme
affiche "Bravo, tu es trop fort !"

🔦 La récursivité


Implémenter des algorithmes récursifs en Linotte est possible. Le meilleur exemple... la suite de Fibonacci :

n est un nombre
affiche "Entrez un nombre :"
demande n
affiche fibo(n)

fibo : n
	si n < 2 retourne n
	sinon retourne fibo(n-1) + fibo(n-2)

🔂 Les boucles


Les boucles, briques essentielles lors de l'élaboration d'algorithme sont présentes sous différentes formes dans le langage Linotte.

La forme la plus usuelle est "pour n de a à b ... " :

notes est un casier de nombres
prénoms est un casier de textes valant "Pierre", "Jacques", "Hugo"
b est un nombre
pour b de 0 à 2
	ajoute question( prénoms{b} ) dans notes
ferme
pour b de 0 à 2
	affiche "La note de " + prénoms{b} + " est " + notes{b}
ferme

question : prénom
	valeur est un nombre
	affiche "Quelle est la note de " + prénom + " ?"
	demande valeur
	retourne valeur

La forme "tant que condition ... " est également disponible :

notes est un casier de nombres
prénoms est un casier de textes valant "Pierre", "Jacques", "Hugo"
b est un nombre
tant que b < 3
	ajoute question( prénoms{b} ) dans notes
	b prend b + 1
ferme
tant que b > 0
	b prend b - 1
	affiche "La note de " + prénoms{b} + " est " + notes{b}
ferme

question : prénom
	valeur est un nombre
	affiche "Quelle est la note de " + prénom + " ?"
	demande valeur
	retourne valeur

🍭 Un peu de sucre ?


Quelques raccourcis très utiles sont proposés.

  • Raccourci pour le verbe Afficher :
"Bonjour" !
  • Raccourci pour le verbe Demander :
prénom est un texte
prénom ?
"Bonjour, " + prénom !
  • Raccourci pour le verbe Prendre :
prénom prend "Jules"
prénom = "Jules"
  • Forcer l'Atelier à demander des valeurs :

Si la première commande d'un programme est une fonction avec des paramètres, automatiquement, l'Atelier va demander à l'utilisateur les valeurs des paramètres. Si la dernière commande est le verbe retourner, l'Atelier affiche la valeur sur le tableau.

fibo : n
	si n < 2 retourne n
	sinon retourne fibo(n-1) + fibo(n-2)

L'exécution de ce programme va produire cet affichage :

Quelle est la valeur de l'acteur 'n' ? 20      
6765
  • Interpolation de chaîne :
prénom prend "Amandine"
affiche "Bonjour, {prénom} !"
  • Regrouper plusieurs actions identiques en une ligne :

Au lieu d'écrire :

prénom est un texte
nom est un texte
demande prénom
demande nom
affiche "Je vous présente : "
affiche prénom
affiche nom

L'utilisation de l'esperluette compacte le livre ainsi :

prénom & nom est un texte
demande prénom & nom
affiche "Je vous présente : " & prénom & nom
  • Regrouper plusieurs actions différentes en une ligne :
prénom & nom est un texte
demande prénom ; affiche prénom
demande nom ; affiche nom
  • Syntaxe simplifiée pour écrire des casiers :

Forme normale :

animaux est un casier de textes valant "Koala", "Panda", "Kangourou"
pour chaque animaux affiche joker

Et la forme simplifiée :

pour chaque {"Koala", "Panda", "Kangourou"} affiche joker

Le joker est un acteur particulier car celui-ci est alimenté par Linotte dés que l'on utilise la forme simple des boucles : "pour chaque X ". Dans cet exemple, à chaque itération, il prend une valeur successive du casier "animaux".

  • Inférence de types : L'interprète Linotte détermine automatique le rôle d'un acteur s'il n'est pas précisé.
prénom prend "Amandine" // nous avons supprimé "est un texte"
âge prend 1 
affiche "Bonjour, {prénom} a {âge*12} mois !"
  • Le verbe fermer :

Le verbe fermer ferme peut être remplacé par le symbole §

si heure < 12
	affiche "Nous sommes le matin"
§
sinon
	affiche "Nous sommes l'après-midi"
§	

🏁 Attraper les erreurs


Nous sommes tous un peu des têtes de linotte... Une erreur est vite arrivée dans l'élaboration d'un algorithme. Pour s'en protéger, et surtout, pour mieux comprendre l'origine du problème, on entoure son algorithme du bloc Essayer. Celui-ci permet au développeur de procéder à son l'analyse et à sa correction :

/* Algorithme farfelu */
valeur prend 10
essaie
	tant que valeur > 0
		valeur temporaire prend valeur - 1
		si (valeur / valeur temporaire) > 0
			affiche "Je peux continuer"
			valeur prend valeur - 1
		ferme
		sinon valeur prend valeur - 2
	ferme
ferme
sinon affiche "Pfff, une erreur dans ton algorithme lorsque valeur=" + valeur

Et si l'erreur est vraiment insaisissable, utilisons les grands moyens : le débogage.

/* Algorithme farfelu */
débogue
valeur prend 10
tant que valeur > 0
	valeur temporaire prend valeur - 1
	si (valeur / valeur temporaire) > 0
		affiche "Je peux continuer"
		valeur prend valeur - 1
	ferme
	sinon valeur prend valeur - 2
ferme

On avance dans l'algorithme en cliquant sur le bouton "Pas à pas" de l'Atelier.

🔦 Parallélisation des traitements


Linotte est une tête bien faite ! Ce n'est pas une tâche mais plusieurs qu'elle est capable de traiter en même temps ! Pas besoin de longues explications car c'est très simple à mettre en place. Au lieu d'utiliser le verbe Parcourir, on utilise le verbe Appeler :

appelle alarme
appelle pièces
attends 10 secondes
affiche "Don Salluste : Gouzi, gouzi, gouzi !"
observe pièces
affiche "Don Salluste : Il en manque une !!"

alarme :
	attends 8 secondes
	affiche "Blaze : C'est l'hoooor, il est l'hoooor, Monsignoooor !"
	attends 8 secondes
	affiche "Blaze : Il est l'hoooor de se réveiller, il est huit hoooor !"
	reviens

pièces :
	pour chaque 10
		attends 1 seconde
		affiche "[clic clic !]"
		attends 1 seconde
		affiche "[clac ding !]"
	ferme
	reviens

Le verbe Observer attend que la tâche "pièces" soit terminée. Ce programme va produire ce texte :

[clic clic !]
[clac ding !]
[clic clic !]
[clac ding !]
[clic clic !]
[clac ding !]
[clic clic !]
Blaze : C'est l'hoooor, il est l'hoooor, Monsignoooor !
[clac ding !]
[clic clic !]
Don Salluste : Gouzi, gouzi, gouzi !
[clac ding !]
[clic clic !]
[clac ding !]
[clic clic !]
[clac ding !]
[clic clic !]
Blaze : Il est l'hoooor de se réveiller, il est huit hoooor !
[clac ding !]
[clic clic !]
[clac ding !]
[clic clic !]
[clac ding !]
Don Salluste : Il en manque une !!

🔦 Méthode ou fonction ?


Verbe parcourir

todo

🔦 Les fonctions internes


todo

code :
	chaine prend "bonjour la TERRE et les terriens !"
	affiche chaine.inverser()
	affiche chaine.minuscule()
	affiche chaine.majuscule()
	affiche chaine.minuscule().remplacer("terr", "lun").majuscule()
	affiche chaine.taille()
	affiche chaine.position(0,"terr")
	affiche chaine.position(0,"lun")
	affiche chaine.position(13,"terr")
	affiche chaine.extraire(0,7)
	affiche chaine.capitaliser()
	affiche chaine.mélanger()
! sneirret sel te ERRET al ruojnob
bonjour la terre et les terriens !
BONJOUR LA TERRE ET LES TERRIENS !
BONJOUR LA LUNE ET LES LUNIENS !
34
11
-1
24
bonjour
Bonjour La Terre Et Les Terriens !
tnralsR Eueo rEnR!ejso beltei   rT

🔦 Les espèces


L'exemple suivant introduit un nouveau type de variable : les espèces. Celles-ci peuvent contenir une ou plusieurs caractéristiques (ou attributs) :

espèces
	patte est un nombre
	famille & repas & nom est un texte
	espèce animal contient patte, famille, repas, nom

principal :
	chat est un animal, patte prend 4, nom prend "chat", famille prend "félin", repas prend "souris"
	chien est un animal, patte prend 4, nom prend "chien", famille prend "canidé", repas prend "os"
	affiche détail(chat)
	affiche détail(chien)

détail : bébête
	retourne "Le " + nom de bébête + " de la famille des " + famille de bébête + "s" + " mange des " + repas de bébête

L'exécution de cet exemple affiche sur le tableau de l'Atelier les lignes suivantes :

Le chat de la famille des félins mange des souris
Le chien de la famille des canidés mange des os

🔦 L'héritage


Le langage Linotte propose des espèces qui ont des capacités graphiques : elles peuvent s'afficher sur la toile. Voici le graffiti dont le rôle est d'afficher du texte ; Linotte propose également le cercle, le rectangle, l'image, le praxinoscope. La liste complète est disponible dans le tutoriel du langage.

Chaque espèce contient ces attributs spécifiques tels que : la taille, la couleur, la transparence, etc. Ces attributs sont définis par le langage et sont modifiables par le programmeur.

Regardons cet exemple simple affichant un nuage de points :

champs est une toile, couleur prend "jaune mimosa"
pour chaque couleurs, semer(joker)

semer : nom
	fleur est un point
	couleur@fleur prend nom
	taille@fleur prend 10
	déplace fleur vers hasard(600) et hasard(600)
	retourne fleur

Exécutez ce programme dans l'atelier et admirez le résultat !

Remarque sucrée : avez-vous remarqué dans le programme ci-dessus que l'on peut écrire couleur de fleur ainsi couleur@fleur ?

Toutes les couleurs connues du langage s'affichent aléatoirement. Ce tableau est beau mais presque inutile ! Ce que l'on souhaite : c'est afficher le nom de la couleur dés que l'on passe la souris sur un des points colorés.

Pour cela, nous allons créer l'espèce fleur qui héritera du point et qui contiendra un nouvel attribut : nom. Il portera le nom de la couleur.

espèces
	nom est un texte
	espèce fleur hérite de point et contient nom

principal :
	champs est une toile, couleur prend "jaune mimosa"
	fleurs est un casier de fleur
	message_fleur est un graffiti,  x prend 114, y prend 539, couleur prend "noir", texte prend "Déplace la souris sur les fleurs !", position prend 1, taille prend 10
	pointeur est un point, couleur prend "blanc"
        //projette champs & message_fleur & pointeur
	pour chaque couleurs ajoute semer(joker) dans fleurs
	tant que vrai
		déplace pointeur vers sourisx et sourisy
		pour chaque fleurs
			si pointeur.collision(joker)
				texte@message_fleur prend nom@joker
			ferme
		ferme
		temporise // Bloc le programme et attend que la souris de l'utilisateur bouge
	ferme

semer : nom
	fleur est une fleur
	couleur@fleur & nom@fleur prend nom
	taille@fleur prend 20
	déplace fleur vers hasard(600) et hasard(600)
	retourne fleur

Vous êtes enfin prêt pour admirer, puis réviser vos couleurs !

🔦 Les évènements


L'interaction avec les éléments graphiques est facilitée par l'association d'un traitement à une action effectuée par l'utilisateur.

Dans l'exemple suivant, une action sera exécutée à la fin d'un glisser-déposer sur un des deux objets centre ou boule :

centre est un cercle,  x prend 311, y prend 285, couleur prend "rouge", plein prend "oui", rayon prend 50
boule est un rectangle,  largeur prend 40, hauteur prend 20, couleur prend "noir", plein prend "oui"
salle est une toile, couleur prend "blanc"

fais réagir boule & centre à "glisser-déposer" pour changement
tant que vrai temporise // boucle infinie

changement : // ce n'est pas une fonction mais une méthode (aucune valeur doit être retounée)
	si boule.collision(centre)
		couleur@centre prend "jaune"
	ferme
	sinon couleur@centre prend "rouge"
	reviens

D'autres types d'évènements peuvent être utilisés : souris entrante, souris sortante, clic souris, double clic souris et clic droit souris.

🔦 Les prototypes


Tels des Legos, les espèces sont des objets modifiables : on peut les enrichir pour y ajouter des nouveaux attributs et même, des fonctions.

Dans l'exemple suivant, on associe la fonctionne présentation à l'espèce Marjordome.

espèces
	espèce marjordome hérite de entité // entité est une espèce vide

principal :
	messager est un marjordome
	nom prend "Jules"
	attache nom à messager
	attache présentation à messager
	affiche messager.présentation()

présentation : // Implicitement, le paramètre moi est créé.
	retourne "Je suis votre serviteur {nom@moi}."

Et sur le tableau, s'affiche :

Je suis votre serviteur Jules.

🔦 Le clonage


Linotte supporte nativement le clonage (duplication d'un objet à l'identique). Celui-ci est effectué en préfixant la variable du symbole dièse :

espèces
	énergie prend 1000
	espèce stormtrooper hérite de entité et contient énergie

principal :
	prototype est un stormtrooper, énergie prend 1000
	armée est un casier de stormtrooper
	soldat est un nombre
	attache attaquer à prototype
	// On clone le prototype 100 fois pour constituer notre armée :
	de 0 à 99, ajoute #prototype dans armée
	affiche "àààà l'attaaaqueeee !"
	pour soldat de 0 à 99 affiche "Le stormtrooper va effectuer une attaque de " + (armée{soldat}.attaquer()) + " points !"

attaquer :
	retourne hasard(1000) + énergie@moi

Sur le tableau, s'affiche 100 fois :

Le stormtrooper va effectuer une attaque de 1125 points !

Remarque : pour cloner un objet, au lieu d'utiliser le symbole #, vous pouvez utiliser la fonction clone() : ajoute clone(prototype) dans armée

🔦 Programmation d'IHM


Et pour le plaisir, voici un exemple de création d'IHM en quelques lignes :

form est un formulaire, titre prend "Première question", largeur prend 400, hauteur prend 260
bouton1 est un bouton, texte prend "Blanc", x prend 30, y prend 60
bouton2 est un bouton, texte prend "Noir", x prend 100, y prend 60
étiquette1 est un étiquette, texte prend "Quelle est la couleur du cheval blanc d'Henri 4 ?", x prend 30, y prend 30
étiquette2 est un étiquette, texte prend "", x prend 30, y prend 100

ajoute bouton1 & bouton2 dans form // On ajoute les éléments de l'IHM à notre fenêtre "form"
ajoute étiquette1 & étiquette2 dans form

fais réagir bouton2 à "clic souris" pour réponse fausse
fais réagir bouton1 à "souris entrante" pour bouger bouton
fais réagir bouton1 à "clic souris" pour bouger bouton

tant que vrai temporise

réponse fausse : bouton // Objet qui reçoit l'action. Ici, le bouton "Noir"
	texte de étiquette2 prend "Tu es bien trop mauvais pour continuer le test !"
	reviens

bouger bouton : bouton // Objet qui reçoit l'action. Ici, le bouton "Blanc"
	x de bouton prend hasard(320) + 30
	y de bouton prend hasard(220) + 30
	reviens

Testez cet exemple dans l'Atelier et répondez bien ! 😜