π
<-
Chat plein-écran
[^]

UnderBasic 2

Assembleur, Axe, C/C++, ICE...

UnderBasic 2

Message non lude Clément.7 » 17 Sep 2016, 21:20

Bonjour à tous !
Il y a un an, presque jour pour jour, naissait le projet UnderBasic (à deux jours près, zut ! ;))

Ce projet avait pour but de permettre de programmer en Basic de manière plus simple tout en ayant plus de fonctionnalités à disposition, telles que les fonctions, les blocs, les alias et les routines (vous pouvez regarder la doc pour voir ce qu'on pouvait faire avec ce langage). Cependant, il lui manquait une fonction cruciale, à savoir un type checker.

Show/Hide spoilerAfficher/Masquer le spoiler
Il s'agit d'un petit programme qui permet de savoir que 2 + cos(5 / "Hello") n'est pas valide mais que 2 + L1 / 2 * [A](0, 2] correspond à un nombre. Le compilateur utilisé pour UnderBasic n'était pas codé de manière à permettre une telle implémentation, et j'ai fini par jeter l'éponge.


Aujourd'hui, je vous annonce une nouvelle version de ce langage, bien plus robuste et puissante que la première version ! En plus de ce programme qui est - comme vous vous en doutez - implémenté, beaucoup de choses ont changé, des choses qui étaient problématiques et faisaient de l'UnderBasic un langage trop peu structuré pour être vraiment intéressant.

I - Présentation du langage

L'UnderBasic est un langage de programmation qui est converti en TI-Basic. En d'autres termes, vous créez un programme en UnderBasic, vous le collez dans l'éditeur, et un magnifique code TI-Basic apparaît :o !

Avant de commencer, voici un petit aperçu des fonctions qu'on peut créer en UnderBasic :

Show/Hide spoilerAfficher/Masquer le spoiler
Code: Tout sélectionner
function direBonjour(nom) {
  afficher "Bonjour, " + nom + " !"
  afficher "Comment ça va ?"
}

direBonjour "Michel"
direBonjour "Jean-Pierre"

saisir "Votre nom ?", nom
direBonjour nom


Code: Tout sélectionner
Disp "Bonjour, Michel !"
Disp "Comment ça va ?"
Disp "Bonjour, Michel !"
Disp "Comment ça va ?"
Disp "Bonjour, Jean-Pierre !"
Disp "Comment ça va ?"
Input "Votre nom ?", Str0
Disp "Bonjour, " + Str0 + " !"
Disp "Comment ça va ?"


L'intérêt de ce langage est de permettre de programmer des programmes qui fonctionnent sur les calculatrices TI-z80 (TI-82 Stats.fr, TI-83+, TI-83+.fr, TI-84+, TI-84+ SE, TI-83 Premium CE, TI-84 Premium CE et TI-84 CSE, plus quelques autres vieux modèles comme la TI-81 je pense), tout en créant des programmes plus simplement et de manière plus lisible, en utilisant des fonctionnalités dont ne disposent pas ces calculatrices.
Vous pourrez par exemple programmer en utilisant des fonctions intégralement traduites en français (afficher, saisir, effacer...) et une grande liberté de syntaxe (que nous verrons un peu après).
Si vous avez besoin d'effectuer une grosse série de calculs sur plusieurs valeurs à plusieurs endroits dans votre code, vous allez devoir recopier ce morceau de code à chaque fois, ce qui va prendre de la place. À chaque fois que vous voudrez modifier ces calculs, vous devrez modifier chaque partie du code, ce qui est contraignant. Ici, pas de problème !

Les fonctions

Les fonctions permettent d'exécuter un code de manière répétée. Dans notre exemple, cela donnerait ceci :

Code: Tout sélectionner
fonction grosCalculs(a, b, c) {
  a * b / cos( tan( arcsin( 2 / stdDev(L1, L2) ) ) ) / sin( 2 * tan( a / L1[3] ) )
  Ans + 2 * cos( Ans * a / c )
}

grosCalculs(2, 3, 5)
# beaucoup de code ici
grosCalculs(7, 2, 8)


En TI-Basic, vous auriez dû écrire :

Code: Tout sélectionner
2*3/cos(tan(arcsin(2/stdDev(L1,L2))))/sin(2*tan(2/L1[3]))
Ans+2*cos(Ans*2/5)
# Beaucoup de code ici
7*2/cos(tan(arcsin(2/stdDev(L1,L2))))/sin(2*tan(7/L1[3]))
Ans+2*cos(Ans*7/8)


Ça fait peur, hein :troll: ?

Les variables

Bon, on va pas se mentir, les variables ça sert. Un peu.
En TI-Basic on a accès à A, B, L1, [A], Z, PI, e, i, X...
Il n'est pas pratique du tout d'écrire avec ces noms-là sur un ordinateur.
D'autre part, l'UnderBasic est, à l'instar du TI-Basic, un langage dit typé, c'est-à-dire que vous ne pouvez pas mettre une chaîne de caractère dans une variable faite pour recevoir un nombre. Ainsi, "Hello"->A ne fonctionne pas en TI-Basic.

Pour pouvoir utiliser des variables, on va donc utiliser des noms. age correspondra à A, nom à Str1, etc.
Dans l'ancienne version d'UnderBasic, on faisait comme ça :

Code: Tout sélectionner
nom is Str1
ou bien encore
Code: Tout sélectionner
#alias nom : Str1


Nom seulement ce n'était pas très pratique mais en plus il y avait plein de bugs, si vous écriviez ensuite print "Salut, mon nom est Michel !" votre ligne était transformée en print "Salut, mon Str1 est Michel !", ce qui est nettement moins sexy.

Voici comment on déclare des variables en UnderBasic :

Code: Tout sélectionner


Voilà. C'est simple non ? Si c'est allé trop vite pour vous, je vous le refais :

Censuré pour cause de répétition totalement inutile

En UnderBasic, on n'a pas besoin de déclarer les variables. Plus exactement, vous pouvez les déclarer, mais ce n'est pas obligatoire. Ainsi, on distingue trois types d'utilisation :

1 - Déclaration à la volée
Code: Tout sélectionner
# Pas de déclaration ici
saisir "Votre nom ?", nom


Comme le compilateur sait que la fonction "saisir" prend comme second argument une variable de chaîne de caractères (eh oui, j'ai dû recopier tout le catalogue de la TI à la main en ajoutant les types, ça fait beaucoup de fonctions), il va "deviner" que "nom" est une variable contenant une chaîne de caractères. Problème, elle n'est pas définie... Du coup, il va la créer !
Mais comme la TI n'a pas de variable nommée "nom", il va l'associer à une variable TI-Basic, et il choisira en premier lieu Str0, puis Str1, puis Str2...

Et quand il arrive à Str9... Il est bloqué, et une erreur survient. Comme la TI n'a que 10 variable pouvant contenir des chaînes, il ne peut pas en faire apparaître (malheureusement :p).

2 - Déclaration implicite

Code: Tout sélectionner
let nom
saisir "Votre nom ?", nom


Cette forme de déclaration permet de déclarer votre variable avant de l'utiliser. Cela vous permet de savoir quelle variable vous utilisez dans votre code, sans vous retrouver à relire tout votre code de 800 lignes pour vous en souvenir...
Là, le compilateur sait que la variable "nom" existe, il n'a plus qu'à deviner son type.

3 - Déclaration explicite

Le problème des deux formes précédentes, c'est que l'on ne se souvient pas forcément de quelle variable contient quoi, et surtout vous pouvez vous retrouvez avec des illogicités dans votre code, par exemple un endroit ou vous y assigner un nombre et un autre où, en ayant oublié cela, vous assignez une chaîne de caractères. Pas bien grave, me direz-vous. C'est vrai, mais c'est toujours mieux de ne pas faire d'erreur ;).
Pour cela, on utilise des déclarations dites typées, c'est-à-dire que l'on indique quel est le type de la variable :

Code: Tout sélectionner
string nom
nom = "Michel"


Voilà, c'est tout bête. Les types disponibles sont "string" "number" "list" "matrix" "yvar" "picture" "gdb" (qui seront par la suit également disponibles en français), respectivement une chaîne de caractères, un nombre, une liste une matrice, une fonction (2X+1), une image (Pic1) et un groupe de données graphiques (GDB1).

II - Les fonctions et les blocs

Pour les fonctions et les blocs... Beh ça n'a pas changé en fait :p. C'est toujours comme dans la première version, à l'exception près que vous pouvez ou non exiger un type pour l'argument qui est passé en paramètre. C'est tout !
Les directives changeront également (#define, #alias, #ifdef...) mais j'en reparlerais, pour l'instant ce n'est même pas encore implémenté.

Allez, une dernière bonne petite fonction bien compliquée pour finir ? (je précise que les #ifdef, #match etc. ne sont pas des commentaires) :

Code: Tout sélectionner
function centrer(string str, number [y]) {
  # ifdef y
  # ifmatch str string~
  :precalc number x = 8 - Math.round($scope.str.length / 2);
  output y, ${x}, str
  # elseif
  output y, 8 - round(length(str) / 2), str
  # endif
  # elseif
  # ifmatch str string~
  :precalc string spaces = " ".repeat(Math.round(7 - $scope.str.length / 2))
  print "${spaces | unquote}${str}"
  # elseif
  # error Impossible d'afficher la variable sans en connaître la ligne
  # endif
}


Code: Tout sélectionner
# Exemples d'utilisation :
# Afficher sur la ligne suivante un magnifique "Bouquet" centré
center("Bouquet")
# Afficher Str0 au centre de la ligne 2
center(Str0, 2)


Code: Tout sélectionner
Disp "     Michel"
Output(2,8-round(length(Str0)/2),Str0)


:o :p
Si si c'est vraiment possible de faire ça en UnderBasic. J'ai dit qu'on pouvait faire beaucoup de choses, non ;) ?

Bonne soirée à tous !

P.S. : Vous pouvez aussi consulter le dépôt GitHub.
Toujours plus loin, toujours plus haut, toujours plus geek !
Créateur du projet Haskier : Jouer ! Sujet sur OpenClassrooms
Programmez en UnderBasic ! https://tiplanet.org/forum/viewtopic.php?t=19009&p=207260
Avatar de l’utilisateur
Clément.7
Niveau 11: LV (Légende Vivante)
Niveau 11: LV (Légende Vivante)
Prochain niv.: 29.5%
 
Messages: 348
Inscription: 12 Juin 2013, 15:02
Localisation: Près de Nantes
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: IUT Informatique en 2017-2019
GitHub: ClementNerma

Re: UnderBasic 2

Message non lude Adriweb » 17 Sep 2016, 22:42

J'avais vu le repo GitHub, mais franchement en voyant tes exemples et explications ici, c'est nettement plus impressionnant que ce que je l'imaginais. Très sympa, cette v2 :)
Mes félicitations, et bonne chance pour la suite.

Je te conseille de faire une page de doc avec le maximum d'exemples, du plus simple au plus complexe, histoire d'augmenter la popularité de ton langage, il n'y a rien de mieux que d'apprendre par l'exemple je trouve :P Et puis ça complètera la doc existante (et bien fournie), c'est bien.
J'imagine que le must serait de montrer un vrai projet genre un jeu ?

Je vais voir si je peux rapidement m'occuper des bindings JS pour tivars_lib_cpp histoire de pouvoir (pour de bon) faire exporter le code TI-Basic généré en 8xp, ca te sera, je pense, utile...
(Ca tombe bien, j'étais en train de bosser dessus aujourd'hui pour améliorer des choses)
Image

MyCalcs: Help the community's calculator documentations by filling out your calculators info!
MyCalcs: Aidez la communauté à documenter les calculatrices en donnant des infos sur vos calculatrices !
Inspired-Lua.org: All about TI-Nspire Lua programming (tutorials, wiki/docs...)
Avatar de l’utilisateur
AdriwebAdmin
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Prochain niv.: 80.2%
 
Messages: 14613
Images: 1218
Inscription: 01 Juin 2007, 00:00
Localisation: France
Genre: Homme
Calculatrice(s):
MyCalcs profile
Twitter/X: adriweb
GitHub: adriweb

Re: UnderBasic 2

Message non lude Wistaro » 17 Sep 2016, 23:13

Excellent travail.
Et en js en plus, je savais même pas que c'était possible de faire ce genre de truc.
C'est vrai que c'est plus intéressants de faire travailler le client plutôt que le serveur comme je peux le faire en php. Tu me donnes envie de me remettre au JS (enfin plutôt me mettre, mes connaissances dans ce langage sont très limitée voire inexistantes. Je n'accordais que très peu d'attention à ce langage qui, pour moi, servait simplement à afficher des pop-up et des trucs épileptiques sur les vieux site des années 2000.
Trêve de blabla.

Ça va être utile ton programme. Même si..
Je ne vois pas vraiment l'intérêt de passer d'une syntaxe simple à une.syntaxe plus complexe pour finalement obtenir le même résultat. Mais bon.
Nouveau sur le site, Anonymous ? Avant de poster sur le chat et sur le forum, n'oublie pas de lire les règles. En cas de problème, tu peux m'envoyer un message, je réponds rapidement.

Liens utiles:
Image
Découvre mes programmes et mon site!
Avatar de l’utilisateur
WistaroSuper Modo
Niveau 15: CC (Chevalier des Calculatrices)
Niveau 15: CC (Chevalier des Calculatrices)
Prochain niv.: 88%
 
Messages: 3158
Images: 37
Inscription: 25 Fév 2013, 16:21
Localisation: Toulouse
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: Ingénieur en électronique
YouTube: Wistaro
Twitter/X: Wistaro
GitHub: Wistaro

Re: UnderBasic 2

Message non lude Lionel Debroux » 18 Sep 2016, 08:37

En effet, ça semble être du bon travail, Clément.7 :)
Ce genre de projets est très formateur, et je t'encourage donc à les poursuivre si tu souhaites devenir développeur professionnel, comme un certain nombre de membres anciens et actuels de la communauté.
Et Adriweb a raison, il faut un maximum d'exemples et une bonne doc.

Wistaro: on peut en effet faire beaucoup mieux que ce que tu cites avec le JS, que ce soit côté client ou côté serveur (Node.js) :)
Mais ne faisons pas dérailler le sujet.
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Avatar de l’utilisateur
Lionel DebrouxSuper Modo
Niveau 14: CI (Calculateur de l'Infini)
Niveau 14: CI (Calculateur de l'Infini)
Prochain niv.: 11.2%
 
Messages: 6859
Inscription: 23 Déc 2009, 00:00
Localisation: France
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: -
GitHub: debrouxl

Re: UnderBasic 2

Message non lude Clément.7 » 18 Sep 2016, 08:50

@Wistaro : La syntaxe est de prime d'abord plus complexe, mais au final c'est plus simple de coder en UnderBasic qu'en TI-Basic. On a accès à des noms de variables à plusieurs caractères, là où sur TI on se limite à A, B, Str0... On peut utiliser des fonctions pour répéter du code, utiliser les blocs et les routines dont je parlerais plus tard pour utiliser de gros codes dans les jeux.

@Adriweb : J'ai créé l'UnderBasic à la base pour créer des jeux en fait. Donc oui, ça sera tout à fait possible. J'avais même commencé à développer des structures de jeux, une fois que le compilateur sera terminé il sera possible de faire ce que je n'arrivais pas à faire en TI-Basic : Un RPG avec plusieurs maps, complètes, des combats, et surtout réaliser - enfin - mon projet RPG Maker que j'avais abandonné à cause de sa trop grande complexité. Un moteur qui permettrait de coder des RPG sur TI directement, sans passer par un PC, tout en customisant les personnages, les monstres, les dialogues, avec des sortes de mini cut-scenes, des événements sur la map, etc.
Bref, une fois que j'aurais terminé le compilateur je mettrais en ligne une doc' complète avec des exemples, pourquoi pas si j'en ai le courage un tuto sur OpenClassrooms (mais j'en doute).
Il y aura de toutes manières des exemples de code fournis avec le compilateur, les premiers affichant un simple texte ou calculant les premiers termes de la suite de Fibonacci, les derniers pour montrer l'utilisation des directives conditionnelles qui permettent, comme je l'ai montré dans mon premier post, de réaliser des fonctions qui ne généreront pas le même code suivant les paramètres qu'on leur donne.

Merci à tous pour votre soutien :D
Toujours plus loin, toujours plus haut, toujours plus geek !
Créateur du projet Haskier : Jouer ! Sujet sur OpenClassrooms
Programmez en UnderBasic ! https://tiplanet.org/forum/viewtopic.php?t=19009&p=207260
Avatar de l’utilisateur
Clément.7
Niveau 11: LV (Légende Vivante)
Niveau 11: LV (Légende Vivante)
Prochain niv.: 29.5%
 
Messages: 348
Inscription: 12 Juin 2013, 15:02
Localisation: Près de Nantes
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: IUT Informatique en 2017-2019
GitHub: ClementNerma

Re: UnderBasic 2

Message non lude Clément.7 » 01 Oct 2016, 11:07

Il y avait plein de bugs dans le support des expressions écrites dans le compilateur, par exemple :

Code: Tout sélectionner
sub("0123456789", iPart(10 * fPart(nbr * 10 ^ ( -x ))) + 1, 1) + answer


Ne fonctionnait pas. J'ai ajouté tout à l'heure un nouveau parser après deux semaines de développement (c'est pour ça que le projet semblait "arrêté" sur GitHub, pour ceux qui suivraient le dépôt). Maintenant tout fonctionne, il ne me reste plus que quelques petites choses à régler et le compilateur sera totalement utilisable ;)

La liste des choses à faire :

  • Renommer les fonctions (il y a des fonctions dont le nom les rend inutilisables, par exemple la fonction ShadeX² lèvera une erreur de syntaxe) quasiment terminé
  • Faire un fichier de traduction française (pour les messages d'erreur du compilateur, et pour les noms de fonction, "print" deviendra "afficher", etc.) avancé à 75 %
  • Ajouter des bibliothèques d'utilitaires (par exemple la fonction "replaceChar" permet de remplacer un caractère dans une chaîne) avancé à 75 %
  • Créer la bibliothèque RPG (pour... bah... créer des RPG :p) avancé à 50 %
  • Rédiger un tutoriel avancé à 25 %
  • Ajouter le support de fonctions écrites par l'utilisateur (à faire)
  • Ajouter le support des directives (à faire)
Toujours plus loin, toujours plus haut, toujours plus geek !
Créateur du projet Haskier : Jouer ! Sujet sur OpenClassrooms
Programmez en UnderBasic ! https://tiplanet.org/forum/viewtopic.php?t=19009&p=207260
Avatar de l’utilisateur
Clément.7
Niveau 11: LV (Légende Vivante)
Niveau 11: LV (Légende Vivante)
Prochain niv.: 29.5%
 
Messages: 348
Inscription: 12 Juin 2013, 15:02
Localisation: Près de Nantes
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: IUT Informatique en 2017-2019
GitHub: ClementNerma

Re: UnderBasic 2

Message non lude Ti64CLi++ » 08 Oct 2016, 15:29

Bonne chance,
Et si tu as besoin d'aide, n'hésite pas ;)
Image
Avatar de l’utilisateur
Ti64CLi++Modo
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Prochain niv.: 32.3%
 
Messages: 3441
Images: 75
Inscription: 04 Juil 2014, 14:40
Localisation: Clermont-Ferrand 63
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: ENS Rennes
GitHub: Ti64CLi

Re: UnderBasic 2

Message non lude Clément.7 » 08 Oct 2016, 20:23

Pour le coup ça ira, déjà j'ai jamais fait de projet en équipe, et ensuite j'y arrive tout seul (pour l'instant ^^). Le plus dur ç'a vraiment été le parser qui vérifie que 2 + 5 * abs(2) c'est un nombre et que "Salut" * 2 c'est pas valide, mais que 2 * L1 ça marche, plus la vérification des arguments pour chaque commande.

D'ailleurs il reste encore un ou deux bugs je crois, je vais corriger ça d'ici les prochains jours. Le plus bête à vrai dire, c'est que j'ai reçu une nSpire hier et que je ne vais plus trop utiliser ma TI-83+ (mais promis je continue le projet, de toutes façons le TI-Basic z80 est 100x meilleur que celui sur TI-Nspire :p)
Toujours plus loin, toujours plus haut, toujours plus geek !
Créateur du projet Haskier : Jouer ! Sujet sur OpenClassrooms
Programmez en UnderBasic ! https://tiplanet.org/forum/viewtopic.php?t=19009&p=207260
Avatar de l’utilisateur
Clément.7
Niveau 11: LV (Légende Vivante)
Niveau 11: LV (Légende Vivante)
Prochain niv.: 29.5%
 
Messages: 348
Inscription: 12 Juin 2013, 15:02
Localisation: Près de Nantes
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: IUT Informatique en 2017-2019
GitHub: ClementNerma

Re: UnderBasic 2

Message non lude Hamza.S » 08 Oct 2016, 20:48

Clément.7 a écrit:mais promis je continue le projet, de toutes façons le TI-Basic z80 est 100x meilleur que celui sur TI-Nspire :p

tu te bases sur quoi?
côté graphique il n'y a rien mais côté calculs et fonctions de la calculatrice, les z80 sont nulles
Image
Avatar de l’utilisateur
Hamza.SAdmin
Niveau 17: GM (Grand Maître des calculatrices)
Niveau 17: GM (Grand Maître des calculatrices)
Prochain niv.: 28.5%
 
Messages: 4463
Images: 18
Inscription: 07 Nov 2014, 00:43
Genre: Homme
Calculatrice(s):
MyCalcs profile

Re: UnderBasic 2

Message non lude Adriweb » 08 Oct 2016, 20:54

Le TI-Basic des Nspire a simplement un objectif différent de celui des z80 (Nspire: maths/science uniquement, et c'est pas mal, c'est même le meilleur Basic pour ça, de loin ; z80: un peu de tout, mais assez limité, c'est très bien pour apprendre à coder) - on peut donc pas vraiment comparer.
Et par défaut, côté Nspire, la puissance de la machine, contrairement à celle des z80, lui permet d'avoir du Lua, ce qui en gros comble les trous de son TI-Basic. Sur z80, on a bien de l'ASM mais ça reste largement plus bas niveau (et donc beaucoup moins accessible à du monde) que du Lua.
Image

MyCalcs: Help the community's calculator documentations by filling out your calculators info!
MyCalcs: Aidez la communauté à documenter les calculatrices en donnant des infos sur vos calculatrices !
Inspired-Lua.org: All about TI-Nspire Lua programming (tutorials, wiki/docs...)
Avatar de l’utilisateur
AdriwebAdmin
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Prochain niv.: 80.2%
 
Messages: 14613
Images: 1218
Inscription: 01 Juin 2007, 00:00
Localisation: France
Genre: Homme
Calculatrice(s):
MyCalcs profile
Twitter/X: adriweb
GitHub: adriweb

Suivante

Retourner vers Langages alternatifs

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 6 invités

-
Rechercher
-
Social TI-Planet
-
Sujets à la une
Comparaisons des meilleurs prix pour acheter sa calculatrice !
Aidez la communauté à documenter les révisions matérielles en listant vos calculatrices graphiques !
Phi NumWorks jailbreak
123
-
Faire un don / Premium
Pour plus de concours, de lots, de tests, nous aider à payer le serveur et les domaines...
Faire un don
Découvrez les avantages d'un compte donateur !
JoinRejoignez the donors and/or premium!les donateurs et/ou premium !


Partenaires et pub
Notre partenaire Jarrety Calculatrices à acheter chez Calcuso
-
Stats.
1462 utilisateurs:
>1440 invités
>17 membres
>5 robots
Record simultané (sur 6 mois):
6892 utilisateurs (le 07/06/2017)
-
Autres sites intéressants
Texas Instruments Education
Global | France
 (English / Français)
Banque de programmes TI
ticalc.org
 (English)
La communauté TI-82
tout82.free.fr
 (Français)