Archive pour la catégorie ‘Programmation’

Initiation à la programmation avec Python

Tuesday 13 March 2012

J’ai récemment eu besoin de concevoir un petit programme pour initier des débutants à la programmation, ceci dans le cadre des “journées découvertes” organisées par mon école.

Une introduction à la programmation

Le programme devait respecter les points suivants :

  • Il devait être graphique et interactif, afin de permettre de visualiser instantanement les actions du code ;
  • Il devait utiliser un langage de haut niveau, afin de ne pas avoir besoin d’introduire de concepts “compliqués” ;
  • Il devait être en français afin d’être plus accèssible à tout le monde.

Il a finalement été décidé d’implémenter une version Python du langage LOGO (une tortue qui se déplace à l’écran en suivant des instructions simples).

Python nous a paru un choix évident car c’est un langage de très haut niveau, donc facilement comprehensible par les débutants. Il dispose de plus d’une syntaxe claire et de peu de contraintes de typage.

Le projet

Ce que j’ai réalisé est principalement une interface pour appeler des méthodes graphiques et un “wrapper” qui permet au programmeur de simplement mettre ses instructions dans un fichier sans s’occuper de l’environnement. Un autre avantage de Python ici est de pouvoir lancer le programme avec un interpreteur, et ainsi pouvoir jouer avec le programme de manière interactive.


Les fonctions fournies sont très simples et permettent d’aller en avant, de tourner, de changer la couleur et la taille du pinceau.

Par exemple, il est possible de dessiner un carré avec le code suivant :

for i in range(4):
    avancer(100)
    tourner_gauche(90)

Dessiner une spirale est également assez simple, le code suivant change aussi la couleur :

def spiral():
    angle = 2
    n = 3500

    for i in range(n):
        # calcule une nouvelle couleur
        c = int(i * 255. / n)
        changer_couleur((100, c, 50))

        # trace la ligne et change légerement l'angle
        avancer(2)
        tourner_gauche(angle)
        angle *= 0.9995

spiral()

Toutes ces instructions sont bien sur également disponible en anglais et il est possible de les traduire via un fichier d’alias dans n’importe quelle langue.

Malgré l’apparente simplicité de ce programme il est possible d’apprendre toutes les notions basiques de programmation, des variables à la récursion. Notre programme pour le petit TP (1h30) que nous organisions était le suivant :

  1. Qu’est-ce que la programmation ? Pourquoi programmer ?
  2. Variables
  3. Fonctions
  4. Boucles

Triangles de Sierpinski

Le projet est téléchargeable sur GitHub.

Conclusion

Les étudiants ayant participé à ce TP, bien que n’ayant pas ou peu programmé avant, on rapidement réussi à dessiner des formes plus ou moins complexes à l’écran et ont pour la majorité apprécié l’exercice.

Le combo Python/programmation graphique a plutôt bien fonctionné pour une initiation, en espérant que cela ait donné l’envie à certains d’en apprendre plus sur la programmation.

Sérialisation binaire (C#)

Sunday 23 May 2010

La sérialisation est un moyen simple de convertir des objets afin de pouvoir par exemple les stocker sur le disque dur ou les envoyer via le réseau. Il existe plusieurs formes de sérialisation selon le type de données à stocker et l’usage qu’il doit en être fait, nous allons nous attaquer ici à la sérialisation binaire.

Le but de la manœuvre va donc être de convertir un objet en un flux binaire puis de le stocker dans un fichier. Pour cela rien de très compliqué car C# va s’occuper de tout.

Commençons par créer une classe contenant les informations que nous voulons stocker. Libre à vous d’en changer le contenu, j’ai ici choisi d’y mettre un string et un int mais vous pouvez ajouter n’importe quel type de donnée sérialisable (y compris ceux que vous aurez précédemment créé). Afin de définir la classe comme sérialisable il suffit de rajouter l’attribut [Serializable] dans la déclaration.

[Serializable]
public class Data
{
public string maChaine;
public int reponse;
}

Notre classe étant créée il va maintenant falloir instancier un objet (afin d’avoir des données à sérialiser) puis procéder à la sérialisation. Pour cela C# va nous fournir l’objet Stream qui permettra d’écrire dans un fichier, ainsi que l’objet BinaryFormatter qui va s’occuper de la sérialisation.

// On crée l'objet à sérialiser
Data data = new Data();
data.maChaine = "Hello world!";
data.reponse = 42;

Stream stream = File.Open(path, FileMode.Create);
BinaryFormatter formatter = new BinaryFormatter();

// On sérialise
formatter.Serialize(stream, data);

stream.Close();

Notre objet est maintenant sérialisé et stocké sur le disque dur. La déserialisation va se passer de manière tout aussi simple. Il va nous suffire d’ouvrir le fichier dans un flux et de deserialiser celui-ci.

BinaryFormatter formatter = new BinaryFormatter();
FileStream stream = File.Open(path, FileMode.Open);
Data data = (Data)formatter.Deserialize(stream);

stream.Close();

Notre objet est maintenant déserialisé et se trouve dans data.

Cette méthode est très pratique afin de sauvegarder l’état d’un programme de manière facile et rapide. Et pour ceux qui s’intéressent à XNA, cela peut-être un bon moyen de créer des fichiers de sauvegarde pour vos jeux, les fichier créés n’étant pas lisibles (et donc pas modifiables) par le joueur et permettant de stocker autant d’information que vous le souhaitez tout en les récupérant de manière simple et rapide.

Questions ? remarques ? choses pas claires ?

XNA – Gérer les saisies clavier

Sunday 16 May 2010

Bien que la gestion du clavier avec XNA soit simple pour certaines tâches, elle l’est beaucoup moins pour d’autres. XNA ne propose en effet pas de méthode simple pour récupérer un texte saisi par l’utilisateur.
Nous allons donc voir ici comment gérer de manière rapide les frappes basiques au clavier.

Pour simplifier le tutorial j’ai choisi de gérer uniquement les lettres ainsi que les touches espace et shift. A vous d’ajouter la gestion des autres caractères si vous désirez quelque chose de plus complet.

XNA fournit à tout moment l’état du clavier via la méthode Keyboard.GetState(), pour récupérer la saisie de l’utilisateur la technique va donc consister à comparer l’état actuel du clavier avec l’état précédent. Pour chaque touche pressée nous allons vérifier si elle l’était également à l’état précédent. Si elle ne l’était pas c’est que l’utilisateur vient d’appuyer dessus et il faut donc l’ajouter au texte saisi.

Commençons tout d’abord par créer les champs dont nous aurons besoin. Il nous faudra un tableau de Keys afin de stocker l’état précédent ainsi qu’une string représentant le texte saisi par l’utilisateur :

Keys[] prevPressedKeys;
String text;

En n’oubliant pas d’initialiser la valeur de text dans la méthode Initialize :

text = "";

Et enfin la gestion de la saisie :


KeyboardState keyboardState = Keyboard.GetState();
Keys[] pressedKeys = keyboardState.GetPressedKeys();

bool shiftPressed;

shiftPressed = keyboardState.IsKeyDown(Keys.LeftShift) || keyboardState.IsKeyDown(Keys.RightShift);

if (keyboardState.IsKeyDown(Keys.Space))
text += " ";

foreach (Keys key in pressedKeys)
{
if (!prevPressedKeys.Contains(key))
{
string keyString = key.ToString();

if (keyString.Length == 1)
{
char c = keyString[0];

if (!shiftPressed)
c += (char)('a' - 'A');

text += "" + c;
}
}
}

prevPressedKeys = pressedKeys;

Dans un premier temps on récupère l’état du clavier via la méthode Keyboard.GetState(), à partir de là on va récupérer un tableau contenant les touches pressées ainsi qu’un booléen qui va indiquer si l’une des touche shift est pressée (et donc si on doit écrire en majuscule). C’est à ce moment là qu’on va gérer les caractères spéciaux, ici je gère exclusivement l’espace que je rajoute au texte si la touche est appuyée.

On va ensuite parcourir la liste des touches et pour chaque touche qui n’était pas pressée à l’état précédent on va effectuer un traitement. Cela consiste ici à récupérer le string correspondant et si jamais c’est une lettre on va l’ajouter au texte. A noter que si la touche shift n’est pas appuyée (shiftPressed est à false) on va effectuer un décalage sur le caractère afin de le passer en minuscule.

La dernière consiste à sauvegarder l’état actuel qui servira au prochain appel de la fonction.

A vous de l’améliorer pour avoir une gestion plus complète !

Voila pour ce premier tutoriel, n’hesitez pas à poster vos remarques ou vos question afin que je puisse l’améliorer.