[Tuto] Les flags

Espace contenant des tutoriels divers concernant AutoIt.
Règles du forum
.

Tutoriel "La programmation avec Autoit" : https://openclassrooms.com/fr/courses/1 ... vec-autoit
Répondre
Avatar du membre
Iste
Modérateur
Modérateur
Messages : 1870
Enregistré le : jeu. 04 déc. 2008 14:21
Localisation : 76
Status : Hors ligne

[Tuto] Les flags

#1

Message par Iste » mar. 16 août 2011 17:27

Salutations,

Voici un tutoriel complet sur ce que sont les flags, leurs différences avec d'autre paramètres, comment les utiliser et comment les mettre en place.

I. Les bases sur les fonctions et les paramètres.
II. Qu'es-ce que les flags et comment les utiliser ?
III. Comment mettre en place un système de flags dans une de ses fonctions ?

Ceci n'est pas un tuto technique, mais pratique, pour qu'un maximum de personnes puisse le comprendre et l'appliquer.
Signez ici

Avatar du membre
Iste
Modérateur
Modérateur
Messages : 1870
Enregistré le : jeu. 04 déc. 2008 14:21
Localisation : 76
Status : Hors ligne

Re: [Tuto] Les flags

#2

Message par Iste » mar. 16 août 2011 17:27

I. Les bases sur les fonctions et les paramètres.

Une fonction est un bout de code que l'on va appeler dans un autre.
Par exemple, la fonction native d'Autoit (à savoir, une fonction qui existe directement dans l'interpréteur Autoit) la fonction ConsoleWrite(). Cette fonction permet d’écrire du texte dans la console.
Pour savoir ce que l'on veut écrire, ConsoleWrite() utilise un paramètre. Il s'agit d'une variable que l'on passe a la fonction par cette syntaxe :

Code : Tout sélectionner

ConsoleWrite($var)
Noter qu'on peut également passer une expression littéral :

Code : Tout sélectionner

ConsoleWrite("mon texte")
Une fonction renvoi une variable. Par exemple :

Code : Tout sélectionner

$var = Abs(-5)
:!: Par définition, une fonction est appelée, avec ou sans paramètres, et renvoi une valeur, sans agir sur le reste de l'application. Tant que l'on exploite pas le retour de la fonction, celle ci est sans impacte pour le reste du code. Il existe toute foi des fonctions qui agissent sans que le retour n'ai besoin d’être utilisé. On parle alors de procédures. ConsoleWrite() en est une, comme beaucoup d'autre fonctions en Autoit.

Nous allons maintenant nous pencher sur une fonction définie par nos soin. Pour cela, nous allons prendre un exemple simple de fonction que l'on va faire évoluer durant ce tuto : la fonction bonjour()
Pour notre exemple, nous travaillerons sur un code capable d'écrire dans la console "Bonjour mon_pseudo". Il s'agit donc d'une procédure, vous l'aurez comprit.

La syntaxe pour définir nous même une fonction est la suivante :

Code : Tout sélectionner

Func nom_fonction()
    Return $var
EndFunc
:!: Le Return est facultatif. Mais dans le cadre d'une procédure, il est de bonne pratique de retourner une information sur la bonne réussite ou non de la fonction. En Autoit, on possède aussi pour les erreurs la macro @error.

Voici un premier jet pour notre fonction bonjour()

Code : Tout sélectionner

Func bonjour()
    ConsoleWrite("Bonjour Iste")
EndFunc
Cette fonction écrira "Bonjour Iste" dans la console à son appel.
Voici le code de test que l'on utilisera tout le long de ce tuto en enrichissant la fonction bonjour()

Code : Tout sélectionner

bonjour()

Func bonjour()
    ConsoleWrite("Bonjour Iste")
EndFunc
Exécutez le, vous verrez bien écrit "Bonjour Iste" entre le blabla habituel d'autoit dans la console
Image

Maintenant, comme c'est pas bien pratique de devoir modifier la fonction à chaque changement de pseudo, nous allons passer en paramètre le nom à afficher.

Code : Tout sélectionner

Func bonjour($pseudo)
    ConsoleWrite("Bonjour " & $pseudo)
EndFunc
:!: Le " & $pseudo" c'est de la concaténation de chaine. Je vous laisse aller vous renseigner dessus si besoin car ce n'est pas le sujet ici.

Un paramètre est donc la valeur d'une variable qui est passée a la fonction dans une autre pour qu'elle puisse travailler avec. On peut avoir plusieurs paramètres. Les paramètres on pour scope (portée) la fonction (voir un tuto sur les scope si besoin).

Maintenant que notre fonction prend maintenant une variable en paramètres, nous pouvons l'appeler grâce à ce code

Code : Tout sélectionner

bonjour("Roger")
La valeur de "Roger" sera copiée dans $pseudo.

Poussons un peu plus loin cette histoire de paramètre. Nous pouvons déjà le rendre optionnel en lui donnant une valeur par défaut avec cette syntaxe :

Code : Tout sélectionner

Func bonjour($pseudo = "anonyme")
La fonction peut maintenant être appelée avec ou sans paramètre :

Code : Tout sélectionner

bonjour("Roger")
bonjour()
:!: Les paramètres optionnels doivent être les derniers !

Si vous voulez savoir dans votre fonction si l'utilisateur à envoyé "anonyme" ou rien, vous pouvez utiliser le mot clef Default en valeur par défaut. Exemple :

Code : Tout sélectionner

Func bonjour($param = Default)
    If $param = Default Then
        $pseudo = "anonyme"
    Else
        $pseudo = $param
    EndIf

    ConsoleWrite("Bonjour " & $pseudo)
    If $param = Default Then MsgBox(0, '', "Ce n'est pas bien de ne pas donner son nom !")

EndFunc
En testant If $param = Default, on peut savoir si l'utilisateur a ou non envoyé le paramètre.

Nous pouvons aussi mettre le paramètres en Const comme toutes variables :

Code : Tout sélectionner

Func bonjour(Const $param = Default)
Je vous le recommande fortement. Cela permet de ne jamais perdre la valeur passée en paramètre durant la fonction. Si vous avez besoin de la modifier, faites le dans une nouvelle variable. Ne cherchez pas à avoir un code "léger" à tout prix.

Enfin, nous pouvons aussi marquer le paramètre ByRef

Code : Tout sélectionner

Func bonjour(ByRef Const $param)
Un paramètre ByRef ne copiera pas le code, mais la référence de la variable. Ainsi, un paramètre ByRef si il est modifié dans la fonction modifiera la valeur de la variable passée en paramètre. Cela peut être utilisé, entre autre, pour éviter la duplication de variables lourdes comme des gros tableaux.
:!: Un paramètre ByRef doit obligatoirement être une variable. Vous ne pouvez donc pas passer de valeurs littérales ou encore les rendre optionnels.

Voici pour les bases sur les fonctions et leur paramètres.
Je saute volontairement de nombreux aspects liés aux fonctions comme le retour ou les udf pour nous concentrer sur l'essentiel.
Signez ici

Avatar du membre
Iste
Modérateur
Modérateur
Messages : 1870
Enregistré le : jeu. 04 déc. 2008 14:21
Localisation : 76
Status : Hors ligne

Re: [Tuto] Les flags

#3

Message par Iste » mar. 16 août 2011 17:27

II. Qu'es-ce que les flags et comment les utiliser ?

Dans certain cas, on aime mettre dans une fonction un ou plusieurs booléen pour laisser des choix supplémentaires à l'utilisateur. Reprenons notre fonction bonjour(). J'aimerai maintenant ajouter la possibilité d'ajouter un retour a la ligne après le Bonjour. Pour cela, je rajoute un paramètre optionnel :
► Afficher le texte
Maintenant, imaginons qu'en plus, j'aimerai remplacer le "Bonjour" par "Bonsoir"
► Afficher le texte
Enfin, rajoutons la possibilité de jouer un "bip" avant l'affichage :
► Afficher le texte
Voila.
Maintenant, a quoi ressemblerai un appel pour juste le bip ?

Code : Tout sélectionner

bonjour("Iste", False, False, True)
Et oui, car il faut mettre tout les paramètres optionnels qui se trouve avant celui voulu. Si ce n'est pas bien grave ici, imaginez tout ces paramètres pour le style de GuiCreate() !

C'est là que les flags entre en jeu.

L'idée est de pouvoir passer plein de booléen optionnels facilement, et en plus, en une seule variable !

Comment cela est-ce possible ?

Très simple, un nombre, par exemple, 446 s'écrit en binaire par une liste de 1 et de 0. Je ne vais pas vous faire de cours de binaire, car encore une foi ce n'est pas le sujet. Mais donc, revoilà notre 446 en binaire : 1 1011 1110
L'idée du flag est de dire que chacun de ses 1 et 0 sont des booléens.
La on a donc, en partant des unités, False True True True True True False True True.
C'est bine plus simple d’écrire 446 hein ? ^^

Sur notre fonction bonjour(), nous allons donc, après le nom, mettre un paramètre flag. Ce flag vaudra au maximum 111. L'unité sera pour le paramètres $crlf, la dizaine pour $bonsoir et la centaine pour $bip.
L'on peut donc appeler la fonction avec le flag ayant pour valeur binaire 1, 10, 100 ou une combinaison 101, 110 011 ou encore 111. On peut aussi envoyer 0.
L'addition en binaire est aussi simple qu'en décimal, donc 10 + 100 = 110

Maintenant que vous avez compris ce qu’était un flag, nous allons voir comment les utiliser :

Déjà, convertissons nos bit en décimal 111 vaut 7. Pourquoi ?
Car en binaire, le 1er bit vaut 1, le second vaut 2, puis 4, puis 8 etc. Encore une fois, ce n'est pas un cours sur le binaire.
Pour notre fonction bonjours($pseudo, $flag), si je veux avoir uniquement le crlf, j'écris bonjours($pseudo, 1), pour avoir uniquement le bonsoir bonjours($pseudo, 2) et pour le bip bonjours($pseudo, 4).
Pour une combinaison je peux simplement les additionner bonjours($pseudo, 1 + 2 + 4)

Mais bon... comme ce n'est pas forcément facile de savoir quel bit correspond a quoi, il est de bonne pratique de définir des constantes plus explicite :

Code : Tout sélectionner

Global Const $FLAG_CRLF = 1
Global Const $FLAG_BONSOIR = 2
Global Const $FLAG_BIP = 4

bonjour("Iste", $FLAG_CRLF + $FLAG_BONSOIR + $FLAG_BIP)
:!: Dans ce cas j'utilise l'addition, mais certaine constantes de flags peuvent en contenir plusieurs ! Exemple

Code : Tout sélectionner

Global Const $FLAG_BONSOIR_BIP = 6
Il faudra donc combiner les flag à l'aide d'un OU (voir BitOR() en Autoit)

Voila, vous savez maintenant ce qu'est un flag et comment l'utiliser. Nous allons donc passez de l'autre coté du miroir pour comprendre comment la fonction l'utilise.
Signez ici

Avatar du membre
Iste
Modérateur
Modérateur
Messages : 1870
Enregistré le : jeu. 04 déc. 2008 14:21
Localisation : 76
Status : Hors ligne

Re: [Tuto] Les flags

#4

Message par Iste » mar. 16 août 2011 17:28

III. Comment mettre en place un système de flags dans une de ses fonctions ?

Du coté de la fonction, on va recevoir un paramètre $flag qui sera un nombre. Par exemple, 446. Il faudra donc le décomposer en binaire pour savoir quel bit sont sur 1 ou sur 0.
Pour cela c'est une fois de plus très simple, on va appliquer un masque sur notre combinaison de flags.
On va devoir utiliser le ET logique. Petit rappel
0 AND 0 = 0
0 AND 1 = 0
1 AND 0 = 0
1 AND 1 = 1

Pour notre 446, si l'on applique le masque binaire 100 avec un ET, cela nous donne :
1 AND 0 = 0
1 AND 0 = 0
0 AND 0 = 0
1 AND 0 = 0
1 AND 0 = 0
1 AND 0 = 0
1 AND 1 = 1
1 AND 0 = 0
0 AND 0 = 0

Ce qu'il faut comprendre : Quand on test une combinaison de flag avec un masque, si le résultat est le même que le masque, alors tout les bit voulu sont sur 1.
Soit

Code : Tout sélectionner

If BitAND($flag, $FLAG_BIP) = $FLAG_BIP Then Beep()
Voici la notre fonction bonjour() modifiée pour l'occasion :

Code : Tout sélectionner

Global Const $FLAG_CRLF = 1
Global Const $FLAG_BONSOIR = 2
Global Const $FLAG_BIP = 4

bonjour("Iste", $FLAG_CRLF + $FLAG_BONSOIR + $FLAG_BIP)

Func bonjour(Const $param = Default, Const $flag = 0)
    If $param = Default Then
        $pseudo = "anonyme"
    Else
        $pseudo = $param
    EndIf

    If $param = Default Then MsgBox(0, '', "Ce n'est pas bien de ne pas donner son nom !")

    If BitAND($flag, $FLAG_BIP) = $FLAG_BIP Then Beep()

    If BitAND($flag, $FLAG_BONSOIR) = $FLAG_BONSOIR Then
        ConsoleWrite("Bonsoir ")
    Else
        ConsoleWrite("Bonjour ")
    EndIf

    ConsoleWrite($pseudo)

    If BitAND($flag, $FLAG_CRLF) = $FLAG_CRLF Then
        ConsoleWrite(@CRLF)
    EndIf

EndFunc
Voila, vous savez maintenant comment mettre en place un système de flag dans vos fonctions !
Signez ici

Avatar du membre
Tlem
Site Admin
Site Admin
Messages : 11421
Enregistré le : ven. 20 juil. 2007 20:00
Localisation : Bordeaux
Status : Hors ligne

Re: [Tuto] Les flags

#5

Message par Tlem » dim. 28 juin 2015 12:59

Vous trouverez un autre tutoriel avec plus de détails ici : Les Fonctions et les Flags

.
Thierry

Rechercher sur le forum ----- Les règles du forum
Le "ça ne marche pas" est une conséquence commune découlant de beaucoup trop de raisons potentielles ...

Une idée ne peut pas appartenir à quelqu'un. (Albert Jacquard) tiré du documentaire "Copié n'est pas volé".

Répondre