Catégorie : Projets

Projets

De la musique ? Oui, mais pas que.

Envie d’écouter de la musique avec style ? Le Web regorge de site Internet sans aucune utilité, comme les Cookies Clickers, les sites vierges, ou Parcoursup. Et bien, je peux fièrement annoncer que mon site est l’un d’entre eux, mais ne paniquez pas ! Avec mon site, vous pourrez mettre de la musique (téléchargée au préalable, il faut pas déconner non plus), et l’écouter sereinement, sans crainte. Mais le plus important c’est que vous pourrez écouter votre musique… avec style et bagou.

Ce site, qui est constitué d’une seule et unique page, est constitué de 4 programmes différents, que j’ai intégré a ma page html, et nous allons les détailler un par un.

1 La souris animée

Sur mon site, nous avons une petite boule animée qui suit la souris, avec un temps de retard.Retour ligne automatique
Cette souris est animée grâce a deux petits codes css et javascript, que je me permet d’afficher ici, car il est vraiment petit, et simple a afficher (pour les codes plus long, je prendrais des extraits).

D’abord le Javascript ;

const cursor = document.querySelector('.cursor');
 
document.addEventListener('mousemove', e => {
    cursor.setAttribute('style', 'top:'+(e.pageY - 20)+"px; left:"+(e.pageX - 20)+"px;")
})
 
document.addEventListener('click', ()=>{
    cursor.classList.add('expand');
 
    setTimeout(()=>{
        cursor.classList.remove("expand");
    }, 500);
})

Comme on a dit, le « setTimeout » sert a initialiser le retard du curseur, pour donner cette impression de ralenti. Retour ligne automatique
Le « cursor.setAttribute » place le cercle animée a la pointe du curseur, et pas au milieu, ce qui se passerait si cette commande n’aurait pas été la.

Le CSS :

.cursor {
    width: 40px;
    height: 40px;
    border: 1px dashed white;
    border-radius: 50%;
    position: absolute;
    animation: Anim1 1s infinite alternate;
  pointer-events: none;
}
 
.cursor::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
    width: 5px;
    height: 5px;
    background: crimson;
    border-radius: 50%;
}
 
.expand {
    animation: Anim2 .5s;
    background: crimson;
    border: 1px solid crimson;
}
@keyframes Anim1 {
    from {
        transform: scale(1) rotate(0deg);
    }
    to {
        transform: scale(0.7) rotate(190deg);
    }
}
 
@keyframes Anim2 {
    0%{
        transform: scale(1);
    }
    50%{
        transform: scale(2);
    }
    100%{
        transform: scale(1);
        opacity:0;
    }
}

Le curseur est crée grâce a ".cursor", est le curseur après-clic est crée grâce à ".cursor::before"

L’animation du cercle lorsqu’il est statique est générée ici :

les "@keyframes" s’en occupent, en le faisant tourner, et en le faisant respirer.

Evidemment, pour que la souris fonctionne, il ne faut pas oublier de déclarer la souris dans le html, grâce a cette unique ligne : <div class="cursor"></div>
Bref, la souris est surtout un élément esthétique (comme si il n’y en avait pas assez…), et ne demande pas beaucoup d’analyse, c’est un code relativement simple, ou du moins compréhensible, ce qui n’est clairement pas le cas des codes suivants (bon courage).

2 Le background avec les lignes animées

On parlait d’élément esthétiques, bah en voila un autre.

Ces lignes, qui donnent du dynamisme au site, sont générées uniquement en CSS (sans compter la déclaration dans le HTML).

Le HTML :

<div class="lines">
  <div class="line"></div>
  <div class="line"></div>
  <div class="line"></div>
</div>

On peut remarquer que chaque ligne est indépendantes, ce n’est pas juste un background animé.

Le CSS :

.lines {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 100%;
  margin: auto;
  width: 90vw;
}
.lines .line {
  position: absolute;
  width: 1px;
  height: 100%;
  top: 0;
  left: 50%;
  background: rgba(255, 255, 255, 0.1);
  overflow: hidden;
}
.lines .line::after {
  content: "";
  display: block;
  position: absolute;
  height: 15vh;
  width: 100%;
  top: -50%;
  left: 0;
  background: -webkit-gradient(linear, left top, left bottom, from(rgba(255, 255, 255, 0)), color-stop(75%, #ffffff), to(#ffffff));
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, #ffffff 75%, #ffffff 100%);
  -webkit-animation: run 7s 0s infinite;
          animation: run 7s 0s infinite;
  -webkit-animation-fill-mode: forwards;
          animation-fill-mode: forwards;
  -webkit-animation-timing-function: cubic-bezier(0.4, 0.26, 0, 0.97);
          animation-timing-function: cubic-bezier(0.4, 0.26, 0, 0.97);
}
.lines .line:nth-child(1) {
  margin-left: -25%;
}
.lines .line:nth-child(1)::after {
  -webkit-animation-delay: 2s;
          animation-delay: 2s;
}
.lines .line:nth-child(3) {
  margin-left: 25%;
}
.lines .line:nth-child(3)::after {
  -webkit-animation-delay: 2.5s;
          animation-delay: 2.5s;
}
 
@-webkit-keyframes run {
  0% {
    top: -50%;
  }
  100% {
    top: 110%;
  }
}
 
@keyframes run {
  0% {
    top: -50%;
  }
  100% {
    top: 110%;
  }
}

Ici aussi, l’animation des lignes est juste une histoire de délais : pour que les lignes soit décalées, un délai de 2 seconde est donné a la première ligne, et un délai de 2.5 est donnée a la troisième ligne.

On peut d’ailleurs le voir quand on lance le site : la deuxième ligne, celle qui n’a pas de délai, descend en première, suivi de la première est de la troisième .

Grace a « webkit », le navigateur gère (presque) tout seul les animations, et cela est moins lourd dans le code.

Bref, je ne vais pas tout détailler, mais cet effet apporte tellement au site (sans être ironique pour le coup), quand on lance une musique, on a l’impression que les lignes bougent en rythme.

Passons au programme majeur du site.

3 Le spectre audio + le bouton d’upload

Alors, faisons un point.

Il est hors de question que j’explique le code ligne par ligne, déjà parce que c’est long, et puis j’avoue que je n’y comprend pas grand chose, c’est hors de mes capacités. Je vais expliquer comment marche le bouton, mais je vais très peu parler des spectres audio.

Le bouton est juste un… bouton. SAUF que, il permet d’uploader le mp3, pour, de 1 lancer la musique, et de 2, initialiser le spectre audio.

Ce code Javascript, est ce qui permet au site de récupérer la musique, via le bouton :

input();
                shade.init();
                document.getElementById("input").addEventListener("change", function(e){
                        document.getElementsByClassName('label')[0].innerText = e.target.files[0].name;
                        fileReader = new FileReader();
                        fileReader.readAsArrayBuffer(e.target.files[0]);
                        music.init();
                       
                }.bind(this), false);

Le "input" demande le fichier choisi, et le "getElement" récupère le fichier, pour l’upload dans le site. Le "innerText" permet de donner au bouton le nom du fichier, et le fait de choisir un nouveau fichier, écrase le précédent, comme nous le montre "fileReader = new FileReader() ;".
Enfin, "music.init" lance la musique sur le navigateur.

Pour ce qui est des deux spectres audio, tout ça est contrôlé par de nombreuuuses formules mathématiques, voici un petit exemple du Javascript :

color : function(){
                        var r = [false, Math.floor(Math.random() * shade.data.max)],
                        g = [false, Math.floor(Math.random() * shade.data.max)],
                        b = [false, Math.floor(Math.random() * shade.data.max)];
                        setInterval(function(){
                               
                                if(r[1] === shade.data.max) r[0] = true;
                                if(r[1] === shade.data.min) r[0] = false;
                                if(r[0] === false) r[1]++;
                                if(r[0] === true) r[1]--;
 
                                if(g[1] === shade.data.max) g[0] = true;
                                if(g[1] === shade.data.min) g[0] = false;
                                if(g[0] === false) g[1]++;
                                if(g[0] === true) g[1]--;
 
                                if(b[1] === shade.data.max) b[0] = true;
                                if(b[1] === shade.data.min) b[0] = false;
                                if(b[0] === false) b[1]++;
                                if(b[0] === true) b[1]--;
 
                                for(var i = 0; i <= 1; i++){
                                        colour = 'rgba('+r[1]+','+g[1]+','+b[1]+',0.8)';
                                        ctx[i].fillStyle = colour;
                                        document.getElementsByClassName('label')[0].style.setProperty('border-color', colour,'');

A ce que j’ai compris, ceci sert a régler les couleurs , car oui, les couleurs réagissent aussi a la musique, et ça, c’est quand même plutôt cool.

Les teintes r (rouge), g (vert), et b(bleu), évoluent au rythme des « shades », qui sont a mon avis les variations du spectre audio.

Bref, ce code rajoute quand même au site tout son charme, et arrachera surement un « wow » a vos amis, si vous en avez.

Passons au dernier programme, tout simple, symbole de l’ego surdimensionné du programmeur :

4 La signature du beau développeur

Tout en bas, a droite, nous avons un petit « Made by Robin Metais », animé, et cliquable.

Le CSS :

a{
  color:white;
  font-size:9px;
  text-decoration:none;
  letter-spacing:2px;
  font-family: "Open sans", sans-serif;
  position:fixed;
  z-index:5;
  bottom:10px;
  right:10px;
  transition:all 0.2s 0s ease-in-out;
}
a:hover{
  color:#95afab;
  letter-spacing:3px;
  transition:all 0.2s 0s ease-in-out;
}

la partie « a » est le bouton (car c’est un bouton) d’origine, et le "a:hover" est le bouton lorsqu’il est survolé.

Le Javascript :

var a = document.createElement("a");
a.innerText = "Made by Robin Metais";
a.href="https://www.youtube.com/watch?v=dQw4w9WgXcQ"
a.title = "";
a.target="";
body.insertBefore(a, body.childNodes[0]);

Ici, on définit le texte qui doit être affiché, et ce qui doit se passer quand le bouton est cliqué.
Un mystérieux lien mystique est apparu dans mon fichier Javascript, comment l’enlever ? ( ͡° ͜ʖ ͡°)

Avec ça, je crois que nous avons fait le tour de ce sublime programme !

Etes vous prêt a mettre le « fire » dans vos diners de famille, et enflammer le « dancefloor » ?

Projets

Douglas’s story

Nous vous présentons nos premier projet de nsi. Ce jeu basé sur l’interaction vous fera vivre des moment tordant. Vous pourrez incarner Douglas qui est aussi attachant qu’extravagant. Grâce à nous, vous allez passer les plus belles heures de jeux votre vie !!

Tout d’abord, notre projet consisté à créer un jeu qui mélange humour, stresse et action, nous l’avons nommé : DOUGLA’S STORY.

L’histoire de douglas se passe à notre époque, vous incarnerais donc le rôle de ce personnage très attachant qui mêle singularité et maladresse. Il a 16 ans et est passionné par les jeux vidéos et la musique. Votre mission dans ce jeu si vous l’acceptez sera d’aider Douglas a sortir avec la fille de ses rêves, car il a beau la voir tous les jours dans la cour de récrée, il na jamais réussit à franchir le pas et ne lui a donc jamais adresser la parole, vous devez donc grâce à votre génie l’aider à se rapprocher d’elle et plus si affinité.

Quel est le but du jeu et à quoi sert-il ?

Après multiple brain storming nous avons décidé de créé une histoire à choix multiples, suivant vos choix vous gagnerez ou perdrez des points, vous vous en douter ; plus vous avez de point plus votre objectif se réalisera. Ce principe de choix multiples est fait pour donner envie au joueur de découvrir toutes les fins et toutes les conséquences possibles de leur actes, ce qui est très intéressant pour nous développeur.

Problème rencontré

Le principal problème dans ce code a été le stockage. En effet, nous avons commencé à coder ce jeu uniquement à base de if, elif, else donc la place prise allé être assez importante.
On a donc trouvé un moyen avec l’aide de notre professeur pour réduire la taille du code.
Nous avons compressé les boucles if, elif, else en une seul boucle :

for i in range(7): # 7 phase, 0,1,2,3,4,5,6,7
    if score > 0 :
        clear(15)
        print(annonce1[i])
        input()
        print(annonce2[i])
        print(question[i])
        choixJoueur = int(input("Choix ="))
        choix = choixJoueur + move
        print(concequence[(choix-1)])
        score = score + points[i][(choixJoueur-1)]
        move += 3
        print("score = ", score)
        input()

Le deuxième problème a été d’insérer la conséquence à la suite des questions. Une fois le programme terminé, les conséquences s’appliquent pour tous les choix. C’est à dire que peu importe le choix de réponse, les conséquences étaient toutes les trois visibles. Or nous voulions que chaque réponse est sa conséquence. Nous avons donc réussis à faire cela en utilisant les balises :

concequence = ["1 = tres bon choix \nca commence bien ",
            "2 = c est pas le meilleur \nchoix mais en vrai \nca passe",
            "3 = alors entre nous patoche \nc est le meilleur mais douglas \nne l aime pas du tout",

Et en plus :

choixJoueur = int(input("Choix ="))
        choix = choixJoueur + move
        print(concequence[(choix-1)])
        score = score + points[i][(choixJoueur-1)]
        move += 3

Le troisième problème a été d’aérer le programme pour le rendre plus lisible et facile à décrypter. Il fallait utiliser des balises permettant d’espacer les différents codes :

def clear(saut=1):
    print("\n"*saut)

Conclusion

En conclusion, ce jeu nous a été utile dans notre progression vers un meilleur niveau en python. Nous avons rencontré pas mal de difficulté mais elles ont toutes été résolu évidemment. Nous avons fait de notre mieux et nous sommes donc fiers de notre projet.
Peut-être y aura-t-il une deuxième partie ? A voir par la suite.

Le code pour télécharger le jeu sur votre Numworks et jouer dès maintenant :

Projets

Un compte bancaire à contrôle de solde

Tu as envie de calculer tes recettes, ton solde dans plusieurs monnaies différentes alors ce script Python est fait pour toi. Tu auras accès à tes comptes sécurisés pour faire des crédits, convertir et débiter ton compte. Avec ce compte bancaire à contrôle de solde, tu n’as aucune limite.} }

Présentation du projet

Le projet que nous avons réalisé est un compte bancaire à contrôle de solde. Il permet d’entrer son nom et son mot de passe pour accéder au compte bancaire. Un mot de passe autre que celui enregistré renverra vers une erreur :

Plusieurs menus sont à disposition permettant de déterminer le sexe de l’utilisateur et de choisir parmi plusieurs propositions :

(Cet exemple sera démontré avec 1000 euros de solde)

Choix 1 : Nous choisissons de combien nous voulons créditer : 168 euros

Notre compte se trouve maintenant à 1168 euros

r = int(input("Combien voulez vous créditer? \n"))
        sf = sd + r
        print("Votre solde est de", sf,"euros.")

Grâce à l’addition et aux variables créées précédemment nous pouvons voir le calcul fait :

r = La valeur voulant être créditée

sd = Le solde du compte

sf = Le compte en banque une fois le crédit effectué

sf = sd + r

Choix 2 : Nous choisissons de combien nous voulons débiter : 272 euros

Notre compte se trouve maintenant à 728 euros

Si le compte en banque viendrait à être négatif, il afficherait “Compte à découvert »

dep = int(input("Combien voulez-vous débiter? \n"))
        sf = sd - dep
        if sf < 0:
            print("Votre solde est de", sf,"euros.")
            print("Compte à découvert.")

dep = La valeur voulant être débitée

sd = Le solde du compte avant toute action

sf = Le compte en banque après le débit

sf = sd – dep

Choix 3 : Nous choisissons de convertir notre solde de 1000 euros

Cela nous donne la valeur de notre solde en plusieurs monnaies : en Dollar, en Yen, en Livre sterling et bien sûr en euro.

sf = sd
        print("Votre solde est de", sf*1.18,"$.")
        print("Votre solde est de", sf*124.4,"JPY.")
        print("Votre solde est de", sf*1.10,"GBP.")
        print("Votre solde est de", sf,"euros.")

sf = La monnaie après avoir été convertie

sd = Le solde du compte avant toute action

En conclusion grâce à ce compte en banque vous pourrez créditer, débiter, convertir en toute sécurité. Avec un contrôle de solde n’ayez aucune crainte d’être à découvert.

Lien pour télécharger le script :

https://workshop.numworks.com/python/thomas-vignal01/compte_en_banque

Projets

Entrainement au calcul mental en Python

Ce script génère des additions et multiplications aléatoires et permet de s’entraîner sur le calcul mental.

Projet NSI 1 : Le calcul mental :

Ce projet consiste à créer un programme en python faisant travailler le calcul mental. Nous sommes en 1ère spécialité NSI au lycée Louis Pasteur à l’année 2019/2020.

Introduction : Python :

Python est un langage de programmation interprété. C’est à dire un programme qui exécute les programmes écrits avec un langage informatique. Python est un langage épuré car il possède moins de construction syntaxique que les autres langages. Il est disponible sur tablettes, ordinateurs, ou encore calculatrice.

But et présentation du programme :

Ce programme de calcul mental permet de se perfectionner et de s’entrainer au calcul via différents niveaux adaptés à tout le monde. Il est pratique car il permet d’avoir une correction et un score et de ne pas se préoccuper à trouver des calculs. Ce programme est destiné à tous les niveaux (plus particulièrement aux élèves de seconde qui doivent savoir maîtriser ces notions.).

Ce programme est constitué de 5 niveaux regroupant le calcul d’additions, de soustractions et de multiplication. Chaque niveau est constitué de 20 questions et d’une correction. Ce programme permet aussi à un élève de seconde de s’initier au langage python en l’exécutant et d’essayer de le comprendre grâce à la petite présentation du programme ci-dessous.

Décortication du programme :

Tout d’abord la console nous demande de choisir un niveau dans le menu proposé.

# La fonction menu !
def menu():
    print("Choisis un niveau")
    print("1. Addition niveau 1") 
    print("2. Addition niveau 2")
    print("3. Multiplication niveau 1")
    print("4. Multiplication niveau 2")
    print("5. Final avec toutes les opérations posssibles")
    choix = 0
    while choix==0:
        choix=int(input())
    if choix==1:
        additionniveau1()
    elif choix==2: 
        additionniveau2()
    elif choix==3:
        multiplicationniveau1()
    elif choix==4:
        multiplicationniveau2()
    elif choix==5:
        final()
    elif choix==9:
        print("Au revoir !")
        exit
    else: 
        menu() 
    if choix!=9:
        menu() 

menu()

On peut voir ci-dessus la fonction menu. Grace à « print » un menu va s’afficher. Puis avec la fonction « int(input » l’utilisateur va choisir un niveau grâce à 5 chiffres correspondant aux 5 niveaux. Et avec les conditions « elif et if » notre programme va se reporter au fonction prédéfinies précedemment.

Voici une des fonctions définies :

# Une des 5 fonctions définis !
    print("Niveau1 : Addition avec 1 chiffre")
    nb=1
    score = 0
    while nb<=20:
        aleat1 = random.randint(1, 9)
        aleat2 = random.randint(1, 9)
        print("Combien fait", aleat1, "+",aleat2)
        reponse = int(input("réponse = "))
        nb = nb + 1
        result = (aleat1 + aleat2)
        if reponse==result :
            score = score + 1
        elif reponse!=result :
            score = score + 0
        print("Voici la correction:", result)
    print("Ton score est:", score, "/20")
    if score>=16 :
        print("Bravo tu es experimenté et tu peux passer au niveau 2")
    if score<10 :
        print("C'est pas grave, retente ta chance")
    if score<16 and score>=10:
        print("Tu as un bon niveau mais je te conseille de reessayer. Avant révise un peu.") 

Grace à la fonction random des chiffres et des nombres vont être tirés aléatoirement permettant de générer des calculs aléatoirement.

Ces chiffres et nombres sont 2 variables (aleat1 et aleat2) tirés aléatoirement selon un intervalle de chiffres et nombres selon les niveaux respectifs. Cela va être appliqué au 4 premier niveaux.

Avec « if » qui nous permet d’exécuter le code mais avec des conditions. Si la réponse est juste le +1 va être ajouté au score sinon pas de changement du score. Ce qui fera un résultat final sur 20 grâce à la fonction « while » ; while nous permet de réaliser cette boucle indéfiniment tant que la variable « nb » n’est pas inférieur à 20. Cette boucle va donc se répéter pendant 20 questions.. Aussi à la fin de chaque calcul une correction est proposée encore grâce à « if ». Si le score est supérieur à 16 la compétence est validée, si c’est entre 10 et 15 tu maîtrises moyennement les compétences. Si inférieur à 10 il vaudrait mieux réviser.

# Le script d'une autre fonction !
    print("Niveau5: Final")
    nb=1
    score = 0
    while nb<=20:
        aleat1 = random.randint(1, 15)
        aleat2 = random.randint(1, 15)
        listes = [(aleat1 + aleat2), (aleat1 * aleat2), (aleat1 - aleat2)]
        aleat3 = listes[random.randint(0, 2)]
        if aleat3==(aleat1 + aleat2) :
            print("Combien fait", aleat1, "+", aleat2)
        elif aleat3==(aleat1 * aleat2) :
            print("Combien fait", aleat1, "x", aleat2)
        elif aleat3==(aleat1 - aleat2) :
            print("Combien fait", aleat1, "-", aleat2)
        reponse = int(input("réponse = "))
        nb = nb + 1 
        result = aleat3
        if reponse==result :
            score = score + 1
        elif reponse!=result :
            score = score + 0
        print("Voici la correction:", result)
    print("Ton score est:", score, "/20")
    if score>=16 :
        print("Bravo tu es experimenté et tu maitrise toutes les compétences nécessaires")
    if score<10 :
        print("C'est pas grave, retente ta chance tu vas y arriver. Avant révise un peu.")
    if score<16 and score>=10:
        print("Tu as un bon niveau mais je te conseille de réessayer")

Pour la 5ème fonction nous avons créé une 3ème variable (aleat3) nous permettant de tirer aléatoirement dans une liste prédéfinie (composé des 3 opérations), et grâce encore une fois à la condition « if » pour avoir une opération aléatoire et toujours des chiffres et nombres aléatoires.

Si tu veux t’améliorer en calcul mental clique sur le lien ci-dessous :

Projets

Convertisseur d’unité en python

Plus besoin de convertir des unités de tête ou avec un tableau. Ce programme vous fait le travail à votre place.

Ce projet est un programme réalisé avec python dans le but de convertir un nombre avec une unité de départ dans une unité finale. Il permet de convertir des volumes, des masses, des longueurs et des aires. Ce programme a été développé à l’aide d’omega et est téléchargeable sur la calculatrice Numworks grâce aux liens hypertextes en bas de cet article.

Explication de notre programme

• Tout d’abord nous avons dû assimilés les unités avec les puissances de 10 qui correspondaient.

expo0 = [10**-3, 10**-2, 10**-1, 10**0, 10**1, 10**2, 10**3, 10**-3, 10**0, 10**3, 10**6, 10**9]
unit0 = ["mL", "cL", "dL", "L", "daL", "hL", "kL", "cm3", "dm3", "m3", "dam3", "hm3", "km3"]
 
expo1 =[10**-3, 10**-2, 10**-1, 10**0, 10**1, 10**2, 10**3, 10**5, 10**6]
unit1 =["mg", "cg", "dg", "g", "dag", "hg", "kg", "q", "t"]
 
expo2 = [10**-9,10**-6,10**-3,10**-2,10**-1,10**0,10**1,10**2,10**3]
unit2 = ["nm","micrometre","mm","cm","dm","m","dam","hm","km",]
 
expo3 = [10**-6, 10**-4, 10**-2, 10**0, 10**2, 10**4, 10**6]
unit3 = ["mm2", "cm2", "dm2", "m2", "dam2", "hm2", "km2"]

• On a également créer une petite fonction utile.

Une fonction utile

def clear(nb):
    print("\n"*nb)

Cette fonction permet de sauter le nombre de ligne que l’on veut en écrivant ce nombre entre les parenthèses.

Exemple

clear(2)

• Ensuite, nous avons créé les fonctions permettant de convertir les unités.

Fonction volume, masse, longueur et aire

def volume():
    clear(6)
    print("Vous avez choisi les volumes.")
    clear(2)
    nbr = float(input("Quel nombre voulez vous\nconvertir : "))
    clear(1)
    print("liste des unites : \n0 = mL\t1 = cL\t 2 = dL\n3 = L \t4 = daL\t5 = hL\n6 = kL\t7 = cm3\t8 = dm3\n9 = m3\t10 = dam3  11 = hm3\n12 = km3")
    clear(1)
    unit_d0 = int(input("Quel est l'unite de depart\nde votre nombre : "))
    clear(0)
    unit_a0 = int(input("Quel est l'unite final\nde votre nombre : "))
    convert0 = nbr * expo0[unit_d0] / expo0[unit_a0]
    clear(1)
    print("Le resultat est :\n%.3e"%convert0, unit0[unit_a0])
    clear(0)
    go_menu = float(input("Entrez un nombre pour\nretourner au menu : "))
    if go_menu == 1:
        return menu()
    else:
        return menu()

Explication de la fonction volume ci-dessus

Cette fonction nous demande dans un premier temps, quel nombre nous voulons convertir.

Et dans un second temps, l’unité de départ et l’unité finale du nombre.

Cette fonction nous affiche ensuite le résultat et nous demande d’écrire un nombre au hasard pour retourner au menu (que l’on verra plus tard dans cet article).

def masse():
    clear(6)
    print("Vous avez choisi les masses.")
    clear(2)
    nbr = float(input("Quel nombre voulez vous\nconvertir : "))
    clear(1)
    print("liste des unites : \n0 = mg\t1 = cg\t2 = dg\n3 = g     4 = dag   5 = hg\n6 = kg\t7 = q\t 8 = t")
    clear(1)
    unit_d1 = int(input("Quel est l'unite de depart\nde votre nombre : "))
    clear(1)
    unit_a1 = int(input("Quel est l'unite final\nde votre nombre : "))
    convert1 = nbr * expo1[unit_d1] / expo1[unit_a1]
    clear(1)
    print("Le resultat est :\n%.3e"%convert1, unit1[unit_a1])
    clear(0)
    go_menu = float(input("Entrez un nombre pour\nretourner au menu : "))
    if go_menu == 1:
        return menu()
    else:
        return menu()

La fonction masse ci-dessus

Cette fonction est la même que la fonction volume, mais elle ne convertit pas des volumes mais des masses.

def longueur():
    clear(6)
    print("Vous avez choisi les longueurs.")
    clear(2)
    nbr = float(input("Quel nombre voulez vous\nconvertir : "))
    clear(1)
    print("liste des unites : \n0 = nm\t1 = micrometre\n2 = mm\t3 = cm\t4 = dm\n5 = m     6 = dam   7 = hm\n8 = km")
    clear(1)
    unit_d2 = int(input("Quel est l'unite de depart\nde votre nombre : "))
    clear(0)
    unit_a2 = int(input("Quel est l'unite final\nde votre nombre : "))
    convert2 = nbr * expo2[unit_d2] / expo2[unit_a2]
    clear(1)
    print("Le resultat est :\n%.3e"%convert2, unit2[unit_a2])
    clear(0)
    go_menu = float(input("Entrez un nombre pour\nretourner au menu : "))
    if go_menu == 1:
        return menu()
    else:
        return menu()

La fonction longueur ci-dessus

Cette fonction est la même que la fonction volume et la fonction masse, mais elle ne convertit ni des volumes ni des masses, mais des longueurs.

def aire():
    clear(6)
    print("Vous avez choisi l'aire.")
    clear(2)
    nbr = float(input("Quel nombre voulez vous\nconvertir : "))
    clear(1)
    print("liste des unites : \n0 = mm2\t1 = cm2\t2 = dm2\n3 = m2     4 = dam2   5 = hm2\n6 = km2")
    clear(1)
    unit_d3 = int(input("Quel est l'unite de depart\nde votre nombre : "))
    clear(1)
    unit_a3 = int(input("Quel est l'unite final\nde votre nombre : "))
    convert3 = nbr * expo3[unit_d3] / expo3[unit_a3]
    clear(1)
    print("Le resultat est :\n%.3e"%convert3, unit3[unit_a3])
    clear(0)
    go_menu = float(input("Entrez un nombre pour\nretourner au menu : "))
    if go_menu == 1:
        return menu()
    else:
        return menu()

La fonction aire ci-dessus

Cette fonction est la même que la fonction volume, la fonction masse et la fonction longueur, mais elle ne convertit ni des volumes ni des masses ni des longueurs, mais des aires.

• Et pour finir nous avons créé une fonction menu.

def menu():
    clear(3)
    print("        _______________")
    print("       |               |")
    print("       | CONVERTISSEUR |")
    print("       |    D'UNITE !  |")
    print("       |_______________|")
    print("\n1 - Le volume")
    print("2 - La masse")
    print("3 - La longueur")
    print("4 - L'aire\n")
    choix = int(input("Indiquer votre choix : " ))
 
    if choix == 1:
        volume()
 
    elif choix == 2:
        masse()
 
    elif choix == 3:
        longueur()
 
    elif choix == 4:
        aire()
 
    else:
        return menu()

Explication de la fonction menu ci-dessus

Cette fonction nous propose 4 choix qui sont le volume, la masse, la longueur et l’aire. Ces 4 choix sont respectivement associés aux chiffres 1, 2, 3 et 4 donc si on rentre le chiffre 1, le programme va exécuter la fonction volume. Et si on rentre un nombre différent de 1, 2, 3 et 4 la fonction exécutera encore le menu.

Conclusion

Plus besoin de convertir mentalement ou avec un tableau, ce programme vous fait le travail à votre place ! Vous pouvez le télécharger les liens ci-dessous.

Le programme

ServeurRemarquesLiens hypertextes
Workshop de NumWorksPermet un téléchargement rapide sur la calculatriceconvertisseur d’unité

Projets

Une Histoire de plus ou moins

Lancez vous dans le jeu du plus ou moins, et tenter de battre l’ordinateur en devinant le nombre entre 0 et 1000 auquel il pense en moins de 10 coups ! Ou alors faites lui deviner votre nombre, saura t’il le trouver en moins de 10 coups et quelle stratégie adoptera t’il ?

Lancez vous dans le jeu du plus ou moins et tentez de battre l’ordinateur en devinant le nombre, entre 0 et 1000, auquel il pense en moins de 10 coups ! 
Ou alors, faites lui deviner votre nombre, saura t’il le trouver en moins de 10 coups et quelle stratégie adoptera t’il ?

Ce projet est un programme réalisé sur python recréant le célèbre jeu du plus ou moins. Il vous permettra une fois téléchargé sur votre calculatrice Numworks ou à l’aide d’un IDE de trouver ou de faire deviner un nombre entre 0 et 1000 à l’ordinateur. Ce programme a été developpé sur Pycharm et peut être téléchargeable sur la calculatrice Numworks via les liens hypertextes en bas de l’article.

La Naissance du projet

Dès l’annonce du projet nous voulions partir sur un jeu et surtout travailler sur l’interaction entre l’homme et la machine.

C’est alors que le jeu du plus ou moins nous est apparu comme une idée ni trop simple ni trop compliquée à coder avec une interaction importante.

Le projet était comme un mini défi puisque nous devions incrémenter une sorte de mini “intelligence artificielle”, car en effet dans ce jeu il existe une stratégie qui garantit la victoire.

Les différents modes de jeu

  • UN PREMIER MODE DE JEU

Dans ce mode de jeu, l’ordinateur doit trouver un nombre auquel l’utilisateur pense.

La stratégie consiste à diviser par deux le nombre de possibilités allant de 0 à 999, il suffit donc de proposer 500 comme premier choix, 250 ou 750 en deuxième choix et ainsi de suite… Grâce à cette méthode, l’ordinateur a la certitude de trouver le nombre en moins de dix coups.

Le but étant d’intégrer la stratégie à l’ordinateur comme une sorte de mini « intelligence artificielle” pour que l’ordinateur l’adopte et soit donc sûr de gagner à tous les coups.

victoire = False
min = 0
max = 1000
 
def recherche(min, max):
   scoreordi = 0
   scorejoueur = 0
   global victoire
   while not victoire:
       print("Ton chiffre est il plus grand que",int((min + max) / 2),"?")
       reponse = input()
       if reponse == "+":
           recherche(int((min + max) / 2), max)
       elif reponse == "-":
           recherche(min, int((min + max) / 2))
       elif reponse == "=":
           print("J'ai donc trouvé ton chiffre qui est",int((min + max) / 2))
           victoire = True
           print("Partie terminee")
recherche(min,max)

Voici le rendu du 1er mode de jeu :

  • UN DEUXIEME MODE DE JEU

Le deuxième mode de jeu fut bien plus simple à coder que l’autre car il suffisait de faire un script qui génère un nombre aléatoirement et le faire deviner à l’utilisateur à l’aide de phrases tels que “c’est plus !” ou “c’est moins !” .Nous avons intégré des boucles “if” et “while” en réponse au nombre entré par le joueur.

choix = randint(0, 999)
    nb = int(input())
    if nb < 0:
        print("Votre réponse n'est pas valide")
        sleep(3)
        questionordi()
    elif nb > 999:
        print("Votre réponse n'est pas valide")
        sleep(3)
        questionordi()
    cpt = 0
    scoreordi = 0
    scorejoueur = 0
    while cpt < 9:
        if nb > choix:
            print("C'est moins !")
            nb = int(input())
            if nb < 0:
                print("Votre réponse n'est pas valide")
                sleep(3)
                questionordi()
            elif nb > 999:
                print("Votre réponse n'est pas valide")
                sleep(3)
                questionordi()
            cpt += 1
        elif nb < choix:
            print("C'est plus !")
            nb = int(input())
            if nb < 0:
                print("Votre réponse n'est pas valide")
                sleep(3)
                questionordi()
            elif nb > 999:
                print("Votre réponse n'est pas valide")
                sleep(3)
                questionordi()
            cpt += 1
        else:
            print("Tu as trouve")
            cpt = 10
            scorejoueur = scorejoueur + 1
            print("Score ordinateur :", scoreordi, "\nScore joueur  :", scorejoueur)

Voici le rendu du 2ème mode de jeu :

Une ergonomie pensée pour la calculatrice

Un des autres défis de ce projet fut de traduire notre script pour qu’il puisse coller à l’interface limitée de la Numworks, en effet dans la calculatrice on ne peut pas se permettre de faire une phrase trop longue ou encore de mettre trop de texte. Nous avons alors utilisé des IDE Python tels que Numworks ou Omega pour corriger les bugs d’affichage et mettre en forme notre jeu textuel.

La création d’un menu nous a permis de créer un semblant d’interface graphique afin d’ajouter un peu d’esthétique à notre code.

Voici un aperçu du menu :

Conclusion

Comme vous le savez, le langage python nécessite comme tous les langages une extrême rigueur sans quoi le script est immédiatement obsolète.

C’est pourquoi nous avons dû braver certains problèmes qui empiétaient sur la justesse du code et donc du jeu.

Notre obstacle majeur étant que la boucle « while » dans la définition recherche (Voir le mode de jeu 1), était interminable ! Aussi mais pas des moindre nous avons eu aussi de nombreux soucis d’indentation et de syntaxe.

Après avoir résolu ces problèmes et optimiser notre jeu, nous avions l’impression qu’une couche graphique aiderait à rendre le jeu plus vivant.

Malheureusement, nos faibles connaissances pour les modules tels que turtlekandinsky et tkinter ont fait que notre tentative d’amélioration a échoué. Dès lors, nous avons abandonné l’idée d’offrir une interface graphique au joueur pour uniquement nous concentrer sur le script et le menu, qui servirait en remplacement.

Voici un lien vers nos essais graphiques

En somme, ce projet nous aura permis d’étendre nos connaissances en python ainsi que de réaliser notre premier “jeu” interactif.

Vous retrouverez les liens de notre script dans le tableau ci-dessous et pourrez le télécharger.

Télécharger et tester

ServeurWorkshop de NumWorkstiplanet.orgnsi.xyz
RemarquePermet un téléchargement rapide sur la calculatriceTéléchargement .pyTéléchargement .zip
Liens hypertexteslienNumWorks > Physique > Lien(Bouton en dessous)
Projets

Un Pac-Man sur ta Numworks, en python

Rond comme un ballon, et plus jaune qu’un citron, c’est lui Pac-Man ! Pac-Man débarque sur ta NumWorks ! Aide le à manger toutes les pac-gommes en évitant les fantômes et accumule le plus grand score.

Bon jeu !

URL courte de cet article : nsi.xyz/pacman

Pac-Man débarque sur ta NumWorks !

Aide le à manger toutes les pac-gommes en évitant les fantômes et accumule le plus grand score. Pour cela, tu peux :

  • Manger des pac-gommes (10)
  • Manger des super pac-gommes (50)
  • Manger les fantômes (200, 400, 800, puis 1600)

Si tu manges tout les fantômes a chaque super pac-gommes, tu obtiendras même un bonus de 12000 points !

Bon jeu !

Pac-Man, un sacré projet…

Comme toujours, sur nsi.xyz, on aime raconter l’histoire derrière nos projets.

Celle là commence dans une cuisine. Je commençais à faire à manger quand le patron  m’a envoyé un message concernant un bug sur un de ses projets « un jeu en une soirée » : Treasure

L’idée me plaisait, j’avais envie de faire pareil. Mais quel jeu choisir ?

🤓  Je vais tenter de faire un jeu en une nuit aussi vous m’avez motivé. Une idée ?
🧐 Pacman, tout autre jeu serait trop facile pour toi 😅

Pac-Man, ca paraissait infaisable… Des IA différentes pour chaque fantômes, des collisions, des tableaux et encore des tableaux, tout ça dans 32Ko max !

On est parti !

Première étape : Comment stocker la carte ?

Déjà, posons nous la question suivante : C’est quoi la carte dans Pac-Man ?

La carte, c’est soit :

  • Les chemins : On peut se balader dessus, les fantômes aussi.
  • Les murs : Comme on peut le penser, c’est l’inverse des chemins, on ne peut pas les traverser.

Du coup, on est sauvé ! Le tableau contiendra uniquement des 1 (pour les murs) ou des 0 (pour les chemins). Ainsi, on passe d’un tableau 2D de Booléen à un tableau 1D d’entier.
L’astuce est simple mais efficace : Une ligne de 1 et de 0 peut être convertie en entier grâce au fait que l’ordinateur code les entier en binaire.
En plus de réduire la complexité en espace, ça réduit aussi celle en temps, ce qui est pratique quand on parle d’un jeu tel que Pac-Man sur une calculatrice.

Deuxième étape : Construire la carte

Je commence déjà par choisir une taille pour les cases : 10px.
Sachant que la NumWorks dispose d’un écran de 222 px de haut, je sais que ma carte fera 22 cases de haut.Retour ligne automatique
A l’aide d’un logiciel professionnel et d’une image sur Internet, je crée une image blanche de 18x22px (Pourquoi 18 ? Je ne sais pas) que je commence à colorier de façon à obtenir ceci :

Et cette carte se traduit par le tableau suivant :

bits = 18  # Le nombre de bits pour chaque entiers, ce sera utile plus tard
terrain = (262143,131841,187245,187245,131073,186285,135969,252783,249903,251823,1152,251823,249903,251823,131841,187245,147465,219051,135969,195453,131073,262143)

Encore une fois, on utilise des tuple pour gagner en mémoire.

Maintenant, il ne reste plus qu’a rendre la carte à l’écran.
Et pour ca, on utilise une belle fonction :

def render():
    global terrain
    for l in range(len(terrain)):
        for c in range(bits):
            fill_rect(c*10+140,l*10+1,10,10,colors[0])
            if terrain[l]>>(bits-1-c) & 1:
                for d in ((1,0),(0,1),(-1,0),(0,-1)):
                    if 0 <= l + d[0] <= len(terrain) - 1 and 0 <= c + d[1] <= bits - 1 and not terrain[l + d[0]]>>(bits-1-(c+d[1])) & 1:
                        fill_rect(c*10+140+9*(d[1]==1),l*10+1+9*(d[0]==1),1+9*(d[1]==0),1+9*(d[0]==0),colors[1])

Pour faire simple, cette fonction lit les entier comme s’ils était des tableaux de 1 et de 0. Pour chaque case, elle dessine un carré noir. Si la case est un 1, elle regarde dans les 4 direction possibles, si un 0 s’y trouve, alors elle dessine un mur de ce côté.

En rajoutant une petite fonction pour du pré-rendu que je ne détaillerai pas, on obtiens déjà ceci :

Troisième étape : Ajouter de « la classe » au jeu

Outre l’aspect douteux de ce jeu de mot, il est temps de créer une classe pour Pac-Man et ses amis.
Ainsi née la classe Entity qui contiendra, à elle seule, toutes les méthodes pour le jeu. En effet, si on ne considère pas l’entrée des directions, les fantômes et Pac-Man se déplacent de la même manière sur la carte.

Pour faire court, cette classe contient 4 méthodes :

  • Le constructeur : initialise tout les attributs de l’entité.
  • espace : C’est la méthode qui teste les collision, grâce à elle, les fantômes et Pac-Man ne tournent que sur les intersections sans déborder sur les murs. Et évidemment, ils ne traversent pas non plus les murs.
  • move : C’est la méthode qui fait se déplacer les entités, qui réactualise les pac-gommes et super pac-gommes (j’y viendrai plus tard) et qui gère les collisions Pac-Man / Fantômes et Pac-Man / pac-gommes.
  • ia : Détermine la direction des fantômes.

Attardons-nous sur la méthode ia :

def ia(self,x,y):
    if self.f:
        while True:
            d = randint(0,3)
            dx, dy = ((-0.1,0),(0,-0.1),(0,0.1),(0.1,0))[d]
            if d != (3,2,1,0)[self.d] and self.espace(dx,dy):
                self.d = d
                break
    else:
        distances = [9999 for _ in range(4)]
        for i in range(4):
            if i != (3,2,1,0)[self.d]:
                dx, dy = ((-0.1,0),(0,-0.1),(0,0.1),(0.1,0))[i]
                if self.espace(dx,dy):
                    distances[i] = sqrt((self.y + dy - y)**2 + (self.x + dx - x)**2)
        self.d = distances.index(min(distances))

On voit qu’elle comporte deux parties, c’est un des éléments clés de Pac-Man : quand les fantômes sont dans l’état effrayé, ils choisissent une direction au hasard, sinon, ils choisissent la direction qui leur permet d’avoir la plus courte distance euclidienne à un point. Rajoutons que les fantômes n’ont pas le droit de faire demi-tour.

Mais une question se pose : Quel est donc ce point que visent les fantômes ?

Quatrième étape : Les fantômes débarquent !

Dans Pac-Man, il y a quatre fantômes. Mais il n’y a pas que leur couleur qui change, leur comportement aussi !

Petit listing exhaustif :

Blinky poursuit Pac-Man, ainsi le point qu’il cherche à atteindre et le point au centre de Pac-Man.

Pinky est la plus intelligente, ainsi le point qu’elle cherche à atteindre est deux cases devant Pac-Man dans la direction qu’il regarde.

Inky est un peu plus farceur, pour savoir ou il vise, il faut prendre en compte la position de Blinky et de Pac-Man. Posons v le vecteur Blinky-Point deux cases devant Pac-Man dans la direction qu’il regarde, Inky visera le point situé à 2v, ce qui le rend imprévisible.

Clyde quant à lui est un froussard, il agit comme Blinky quand à lui, est à 4 « mètres » de Pac-Man, mais vise un angle de la carte quand il est proche de Pac-Man.

Cinquième étape : Déplacer Pac-Man

Les fantômes maintenant capables de changer de direction, il n’en n’est rien pour Pac-Man…Retour ligne automatique
Comment se déplace Pac-Man ? Pac-Man se déplace jusqu’au bout d’un chemin avant de s’arrêter. Si on lui donne une direction, il la prendra dès qui le pourra sauf si la direction en question est la direction opposée à celle qu’il emprunte déjà.

Du coup, avec nos méthodes et un peu d’astuce, c’est tout simple !

for i in range(4):
    if keydown(i):
        if i == (3,2,1,0)[pacman.d]:
            pacman.d = i
        pacman.nd = i
if pacman.espace():
    pacman.d = pacman.nd

Sixième étape : Gestion des pac-gommes

Vous l’aurez peut-être remarqué mais le jeu est relativement fluide et rapide.Retour ligne automatique
Tout ça repose sur une grosse optimisation sur les pac-gommes, sans cette optimisation, le jeu tourne à 4 IPS.

Une question importante se pose : Comment réussir à afficher et rafraichir les pac-gommes ?

Une première approche innocente serait de stocker les pac-gommes sous forme de tableau de 0, 1 et 2 et le parcourir en affichant ou non les précieuses gommes. Sauf que là, bonjour le temps pour chaque image…

Une deuxième approche est de créer deux listes d’entier et d’utiliser les opérateurs binaires et les soustractions pour stocker les pac-gommes.Retour ligne automatique
Enfin, et c’est la l’énorme gain de temps. Pour chaque entités, après un mouvement, on regarde dans les deux listes si une (super) pac-gomme se trouve sur la case précédente, que ce soit un mur ou non, et on dessine une pac-gomme si besoin. Et c’est comme ça qu’on atteint une fluidité de jeu.

En plus, au lieu d’un parcours de liste, on a juste a implémenter les cinq lignes suivantes :

px, py = int(self.x - 5.5*dx), int(self.y - 5.5*dy)
if pacgommes[py]>>(bits-1-px) & 1:
    fill_rect(px*10+144,py*10+5,2,2,(250, 207, 173))
if superpacgommes[py]>>(bits-1-px) & 1:
    fill_rect(px*10+143,py*10+4,4,4,(250, 207, 173))

Septième étape : Gestion du score et des états des fantômes

Pour le score, on a juste à implémenter les règles citées en début d’article.

Pour la gestion des états des fantômes, c’est un peu plus compliqué qu’une simple variable.
Il faut rajouter un attribut afin que lorsqu’on mange un fantôme, il ne soit plus effrayé sans pour autant que les autres ne le soient plus.
Enfin, il faut rajouter une clock qui nous permettra de rendre leur état normal au fantômes après un certain temps en le rendant blanc juste avant pour alerter le joueur.

Conclusion

Evidemment, je ne me suis pas attardé sur tous les détails car se serait beaucoup trop long. Mais ce sont les éléments principaux pour un Pac-Man.
Je n’ai pas rajouté les changement de phases entre Chase et Scatter, de peur d’impacter les performances ou de dépasser la place disponible en mémoire.
Le Pac-Man fini rend bien :

Code jouable disponible ici :

Projets

Méli mélo de formule de Physique-Chimie

Ce projet a été réalisé par des élèves en spécialité NSI du Lycée Louis Pasteur. Ils sont également les auteurs de ce compte rendu. Pour en savoir plus : Les projets en spécialité NSI

Présentation du programme

Ce programme propose trois aides en physique-chimie : 
1 – Convertir un nombre d’entités en mole
2 – Donner la composition finale d’une réaction 
3 – Registre des significations des lettres et symboles avec leur unité

aperçu du menu
def menu():
   
    print("\n--------MENU PRINCIPAL--------\n")
    print("1 - Convertir un nombre \n d'entites en mole")
    print("2 - Donner la composition \nfinale d'une reaction")
    print("3 - Registre des significatons \ndes lettres et symboles avec \n leur unite")
    choix=int(input("Choix =\t"))
    print()
    if choix==1:
        f1()
    elif choix==2:
        f2()
    elif choix==3:
        f3()
    else:
        print("Choix non valide\n")
        menu()
 
def f1():
    n = int(input("Donner le nombre d'entites a\n convertir:\t "))
    na = 6.02214076 * 10 ** 23
    r = n / na
    print("\n La quantite de matiere\n correspondante est\n %.3e"%r, "moles" )
    input ()
    menu ()
   
def compo_finale(a,b,c,d,nx,ny):
    x=min(nx/a,ny/b)
    return nx-a*x,ny-b*x,c*x,d*x
 
def f2():
    A = int(input("Veuillez renseigner\n le coefficient A:\t"))
    B = int(input("\nVeuillez renseigner\n le coefficient B:\t"))
    C = int(input("\nVeuillez renseigner\n le coefficient C:\t"))
    D = int(input("\nVeuillez renseigner\n le coefficient D:\t"))
    n_x = int(input("\nVeuillez renseigner\n la quantite de matiere\n de A:\t"))
    n_y = int(input("\nVeuillez renseigner\n la quantite de matiere\n de B:\t"))
 
    nfA,nfB,nfC,nfD = compo_finale(A,B,C,D,n_x,n_y)
    print("Il reste %.3e"%nfA, "\nmoles de A\n")
    print("Il reste %.3e"%nfB, "\nmoles de B\n")
    print("Il reste %.3e"%nfC, "\nmoles de C\n")
    print("Il reste %.3e"%nfD, "\nmoles de D\n")
    input()
    menu()
 
def f3():
    print ("m : masse de l'échantillon\n ou masse d'un corps (g)")
    print ("\nM : masse molaire de\n l'echantillon (g.mol-1)")
    print ("\nn : quantite de matiere (mol)")
    print ("\nV : volume d un corps\n (L ou m3)")
    print ("\nrho : masse volumique de la\n solution (g.L-1 ou kg.m-3)")
    print ("\nd : densite (sans unite)")
    print ("\nn : quantite de matiere (mol)")
    print ("\nCM: concentration molaire\n (mol.L-1)")
    print ("\nU : tension (V, volts)")
    print ("\nI : intensite du courant\n (A, amperes)")
    print ("\nR : resistance (Omega, ohms)")
    print ("\nT : temperature en kelvin (K)")
    input()
    menu ()
   
menu()

Les deux premiers sous-programmes calculent automatiquement vos résultats avec les données que vous aurez préalablement rentrées et le dernier sera juste là en tant qu’aide ou rappel.

Menu de sélection

aperçu du menu
def menu():
   
    print("\n--------MENU PRINCIPAL--------\n")
    print("1 - Convertir un nombre \n d'entites en mole")
    print("2 - Donner la composition \nfinale d'une reaction")
    print("3 - Registre des significatons \ndes lettres et symboles avec \n leur unite")
    choix=int(input("Choix =\t"))
    print()
    if choix==1:
        f1()
    elif choix==2:
        f2()
    elif choix==3:
        f3()
    else:
        print("Choix non valide\n")
        menu()

Le choix de l’aide se fait par un menu où il suffit de rentrer le nombre désiré (en l’occurrence 1, 2 ou 3). Si un autre nombre que ceux proposés est rentré, “Choix non valide” s’affichera et vous serez automatiquement redirigé vers le menu.

Sous programme 1 : Convertir un nombre d’entités en mole

aperçu choix 1
def f1():
    n = int(input("Donner le nombre d'entites a\n convertir:\t "))
    na = 6.02214076 * 10 ** 23
    r = n / na
    print("\n La quantite de matiere\n correspondante est\n %.3e"%r, "moles" )
    input ()
    menu ()

Ce programme sert comme son nom l’indique à obtenir une quantité d’atome en mole. Pour ce faire on demande simplement à l’utilisateur d’entrer un nombre d’atome que le programme divise par le nombre d’Avogadro.

Sous programme 2 : Donner la composition finale d’une réaction

aperçu choix 2 (1/2)
aperçu choix 2 (2/2)
def compo_finale(a,b,c,d,nx,ny):
    x=min(nx/a,ny/b)
    return nx-a*x,ny-b*x,c*x,d*x
 
def f2():
    A = int(input("Veuillez renseigner\n le coefficient A:\t"))
    B = int(input("\nVeuillez renseigner\n le coefficient B:\t"))
    C = int(input("\nVeuillez renseigner\n le coefficient C:\t"))
    D = int(input("\nVeuillez renseigner\n le coefficient D:\t"))
    n_x = int(input("\nVeuillez renseigner\n la quantite de matiere\n de A:\t"))
    n_y = int(input("\nVeuillez renseigner\n la quantite de matiere\n de B:\t"))
 
    nfA,nfB,nfC,nfD = compo_finale(A,B,C,D,n_x,n_y)
    print("Il reste %.3e"%nfA, "\nmoles de A\n")
    print("Il reste %.3e"%nfB, "\nmoles de B\n")
    print("Il reste %.3e"%nfC, "\nmoles de C\n")
    print("Il reste %.3e"%nfD, "\nmoles de D\n")
    input()
    menu()

Ce sous programme en renseignant les coefficients directeurs de A, B, C et D ainsi que la quantité de matière de A et B permet de calculer la composition finale d’une réaction.

Sous programme 3 : Registre des significations des lettres et symboles avec leur unité

aperçu choix 3
def f3():
    print ("m : masse de l'échantillon\n ou masse d'un corps (g)")
    print ("\nM : masse molaire de\n l'echantillon (g.mol-1)")
    print ("\nn : quantite de matiere (mol)")
    print ("\nV : volume d un corps\n (L ou m3)")
    print ("\nrho : masse volumique de la\n solution (g.L-1 ou kg.m-3)")
    print ("\nd : densite (sans unite)")
    print ("\nn : quantite de matiere (mol)")
    print ("\nCM: concentration molaire\n (mol.L-1)")
    print ("\nU : tension (V, volts)")
    print ("\nI : intensite du courant\n (A, amperes)")
    print ("\nR : resistance (Omega, ohms)")
    print ("\nT : temperature en kelvin (K)")
    input()
    menu ()
   
menu()

Le choix 3 est présent en tant qu’aide afin de savoir à quoi correspond chaque lettre ou symbole ainsi que l’unité qui l’accompagne.

Bonus

%.3e »%

Ce morceau de programme permet de présenter le résultat sous forme d’écriture scientifique avec trois chiffres après la virgule.

Télécharger le programme

Lien vers le script sur le Workshop Numworks : https://workshop.numworks.com/python/p3r50nne/pc1g

Projets

Une brève navigation dans l’espace sur python

Naviguez au cœur du système solaire, et découvrez les caractéristiques de chaque planètes qui le composent, soit, la période de révolution, la distance au soleil, la masse, le rayon et enfin les satellites connus (leur nombre) …

Ce projet est un programme réalisé sur python permettant de naviguer dans l’espace, et plus précisément dans notre système solaire. Il permet de découvrir les caractéristiques des planètes qui le compose, soit, la période de révolution, la distance au soleil, la masse, le rayon et enfin les satellites connus (nombre). Ce programme a été developpé sur omega et peut être téléchargeable sur la calculatrice Numworks via les liens hypertextes en bas de l’article.

Difficultés rencontrées…

À la genèse de notre projet, nous fûmes légèrement idéaliste quant à nos capacités, et à celles de la calculatrice ; nous voulions créer une animation, tel un court-métrage, avec l’histoire du big bang se déroulant sous nos yeux ébahis, puis la galaxie, et enfin atterrir dans notre système solaire, qui aurait été animé… Après un dur retour à la réalité, nous nous sommes accordées pour simplifier notre concept originel. Malgré avoir réalisé une deuxième couche graphique composée d’un trou noir ; Saggitarius A*, au centre de notre galaxie, et du système solaire, nous n’avons pu l’insérer dans le code initial.

Comment tout a commencé…

Notre programme a été conçu en deux grandes phases :

  • la couche graphique
  • l’interaction

La couche graphique

Premièrement, il a fallu tracer des cercles pour retrouver la forme des planètes, et insérer des dégradés afin de s’approcher au plus des couleurs initiales, en adoptant les modules mathkandinsky et random.Retour ligne automatique
Cette image a été le pilier de la création du fond graphique :

Pour ce faire, du à nos faibles connaissances en python, nous sommes allées nous renseigner auprès du célèbre Philippe Moutou.

def cercle(x0,y0,r,c,e):# fonction pour tracer contour du cercle
 for i in range(2*e):
   xd=x0-int((r-i*0.5)/sqrt(2))
   xf=x0+int((r-i*0.5)/sqrt(2))
   for x in range(xd,xf+1):
     x1=x
     y1=y0+int(sqrt((r-i*0.5)**2-(x-x0)**2))
     set_pixel(x,y1,c)
     for j in range(3):
       x2=x0+y1-y0
       y2=y0+x0-x1
       set_pixel(x2,y2,c)
       x1,y1=x2,y2
 
def cercle_plein(x0,y0,r,c1,e,c2): #remplir le cercle
 cercle(x0,y0,r,c1,e)
 cercle(x0,y0,r-e,c2,r-e)
 
def cercle_grade(x0,y0,R,c1,e,c2):#faire un dégradé de couleur
 for i in range(R):
   r=c1[0]+i*(c2[0]-c1[0])//R
   g=c1[1]+i*(c2[1]-c1[1])//R
   b=c1[2]+i*(c2[2]-c1[2])//R
   cercle(x0,y0,i,color(r,g,b),1)

Grâce à son génie, nous n’avons eu qu’à changer couleurs, rayons ou encore coordonnées dans les diverses fonctions, et créer des listes pour regrouper les différents globes, soit neuf au total en comptant l’astre qui nous fournit en énergie. Pour trouver les couleurs appropriées, nous nous sommes servies de code couleur html, afin de concevoir le plus précisément possible les textures.

Voici un exemple d’appel de fonction, qui a été fait pour chaque planète, et mis dans une liste pour simplifier le code :

cExt=[251,136,7]
cInt= [106,73,32]
cercle_grade(197,95,8,cExt,10,cInt)

Ensuite nous sommes passées à la conception du fond étoilé avec toujours l’aide de notre cher Moutou :

def degrade(c1,c2,k):
 dr=c2[0]-c1[0]
 dg=c2[1]-c1[1]
 db=c2[2]-c1[2]
 return color(c1[0]+int(k*dr),c1[1]+int(k*dg),c1[2]+int(k*db))
 
def tirage(n):
 for i in range(n):
   x=randint(0,320)
   y=randint(0,222)
   c=couleur(x,y)
   set_pixel(x,y,c)
   set_pixel(x+1,y,c)
   set_pixel(x,y+1,c)
   set_pixel(x+1,y+1,c)
 
def couleur(x,y):
 d=sqrt((x-160)**2+(y-111)**2)/32.5
 return degrade(c[int(d)],c[(int(d)+1)%6],d-int(d))

Il nous a suffit de changer les couleurs pour faire un magnifique dégradé galactique, et effectuer un tirage non exhaustif afin de révéler des points blancs.

c=[[235,128,0],[13,89,175],[13,89,175],[44,122,211],[207,230,230],[207,230,230]]
tirage(250)

Pour afficher les anneaux blancs qui représentent l’orbite de chaque planète, rien de plus simple, il suffit d’appeler la fonction traçant le contour d’un cercle.

Etant donné qu’il y a 8 planètes on se sert de la variable for in range :

c_blanc=[119,135,135]
r_orb = [22,32,42,52,62,76,92,109]
for i in range(8):
   cercle(160,111,r_orb[i],c_blanc,1)

Bien évidemment cet appel de fonction doit se faire après celui du fond étoilé, mais avant celui des planètes, pour que tout se superpose parfaitement.

Voici le résultat escompté après de maints efforts :

L’interactivité :

Méconnus du grand public, les modules time et ion ont été le support de cette interaction, utilisée pour naviguer entre les diverses planètes, grâce aux flèches du keyboard, numérotées de 0 à 3. En effet, grâce au getkey, disponible sur omega, qui est la capacité de la calculatrice à détecter si une touche est pressée, le déplacement devient envisageable.

Après plusieurs essais désastreux pour cette tâche plus complexe, nous avons chercher de l’aide auprès d’une source externe ; un grand mage.

Nous avons alors pu avoir accès à un fragment d’un de ses sortilèges que nous avons dû comprendre de nous même pour la suite de notre programme.

On définit tout d’abord dans une liste toutes les caractéristiques des planètes étudiées :

systeme = [ ("Soleil",'centre du sytème solaire','dis soleil: 0','masse: 1,989 × 10^30 kg','rayon: 696340 km', 'satellites connus: 0'),
           ("Venus",'periode de revo: 225 jours','dis soleil: 104 millions km','masse: 4,867 × 10^24 kg','rayon: 6051.8 km', 'satellites connus: 0'),
           #etc pour toutes les planètes
           ]
 
coord = [(160,111,16), (185,95,8)#etc...]
couleur1 = [[255,255,0], [190,183,150]#etc...]
couleur2 = [[235,128,0], [121,104,83]#etc...]

Ensuite on crée une fonction qui permet de tracer un rond blanc à la place de l’astre choisi lorsque degrade n’est pas égal à 1 (égal à un de base), sinon les astres restent tel quel.

def solar_systeme_dessine(n, degrade=1):
 # Affiche un corps du sytème solaire, numéro du corps dans systeme[], degradé
 p = 2 + 9 * (n != 0)
 if degrade == 1:
   cercle_grade(coord[n][0], coord[n][1], coord[n][2], couleur1[n], p, couleur2[n])
 else:
   cercle_grade(coord[n][0], coord[n][1], coord[n][2], [255,255,255], p, [255,255,255])

Avec l’ajout d’un code pour définir les touches et leur mouvement, ainsi qu’un autre pour afficher le texte voulu, on peut désormais naviguer entre les différents astres et voir leurs caractéristiques !

Conclusion

Pour pouvoir profiter du système solaire, il vous faudra donc télécharger le code via le lien en bas de page, et manipuler les flèches pour vous déportez sur les diverses planètes. Pour afficher les informations liées à chaque globe, vous manipulerez les flèches du haut et du bas. 
Bon exode planétaire !

La prochaine fois que quelqu’un se plaint que vous avez fait une erreur, dites-lui que c’est peut-être une bonne chose. Parce que sans imperfections, ni toi ni moi n’existerions.
Stephen Hawking

Télécharger et tester

Serveur Workshop de NumWorks tiplanet.org nsi.xyz 
RemarquesPermet un téléchargement rapide sur la calculatriceTéléchargement .pyTéléchargement .zip
Liens hypertexteslienNumWorks > Physique > Lien
Projets

Un site internet pour tester à la volée des…

Ici nous allons vous montrer un site internet pour essayer les codes HTML ; CSS ; javascript.

Introduction au projet

On ne voulait utiliser un site fait maison pour être sûr de pas se faire attaquer par le DNS du service informatique, qui peut arbitrairement décider de bloquer tel ou tel site web.

On a alors posé un cahier des charges :

  • Un site permettant de charger du HTML, du CSS et du JS.
  • Intuitif.
  • Un retour console pour le JS car c’est mieux que d’aller dans la console du navigateur.

Une fois fait, on s’est mis a coder, on était large, on avait 2 jours pour proposer au prof un outil clé en main.

Interface

L’idée de l’interface est simple :
<emb751|center>
En rouge : le site retour.
En bleu : les zones d’édition.
En noir : le bouton pour envoyer tout ce beau code

L’architecture est un système de div, très pratique pour la mise en page.
Afin de ne pas interférer avec le code éventuel des élèves, on donne des ID aléatoirement générés pour les parties vitales du site (inputs, outputs).

Le JavaScript

C’est la partie la plus importante du site.

Pour le bon fonctionnement du site, il nous faut 3 fonctions :

  • Une fonction de récupération de console.
  • Une fonction d’envoi du code.
  • Une fonction traitant le CSS à envoyer.

Récupération console

On réécrit la fonction console.log et on associe cette fonction à la fonction window.onerror.

<code class="javascript">Retour ligne automatique
console.log = function () Retour ligne automatique
// On recupère le message passé en argumentRetour ligne automatique
var message = [].join.call(arguments, " ") ;

// On crée un nouvel élément <div> qu'on ajoute dans le codeRetour ligne automatique
var div = document.createElement("div") ;Retour ligne automatique
div.appendChild(document.createTextNode(message)) ;Retour ligne automatique
document.getElementById("vfRDiMPLLlGMBuKV").appendChild(div) ;Retour ligne automatique
 ;

// Redéfinition de la fonction d'erreurRetour ligne automatique
window.onerror = console.log ;Retour ligne automatique
</code>

Fonction de traitement du CSS

On commence par convertir le CSS en une seule ligne.
Ensuite on split la chaine obtenue avec le charactère «  », ça nous permet d’avoir un Array contenant des strings commençant toujours par un objet à modifier en CSS ou une string vide.

Comme notre fenêtre visible et modifiable par les élèves porte l’ID « main », on ajoute « #main  » a chaque objet ou on remplace « body » par « #main » afin de n’affecter que la div main.

<code class="javascript">Retour ligne automatique
function convertCSS(code) Retour ligne automatique
code = code.replace("\n", "") ;Retour ligne automatique
code = code.replace("\r", "") ;Retour ligne automatique
var newCode = code.split("") ;Retour ligne automatique
for (var i = newCode.length ; i >= 0 ; i—) Retour ligne automatique
if (newCode[i] !== undefined && newCode[i] !== "") Retour ligne automatique
newCode[i] = newCode[i].replace(/^\s+|\s+$/g, "") ;Retour ligne automatique
if (newCode[i].startsWith("body")) Retour ligne automatique
newCode[i] = "#main " + newCode[i].substring(4) ;Retour ligne automatique
Retour ligne automatique
if (!newCode[i].startsWith("#main")) Retour ligne automatique
newCode[i] = "#main " + newCode[i] ;Retour ligne automatique
Retour ligne automatique
newCode[i] += "" ;Retour ligne automatique
Retour ligne automatique
Retour ligne automatique
return newCode.join("") ;Retour ligne automatique
Retour ligne automatique
</code>

Fonction d’envoi du code

On commence par clear la console.
Puis on envoie un retour console avec un id précis pour changer son style. Ce retour permet de nous assurer que le code a été envoyé.

On actualise les balises du site qui assurent le bon fonctionnement de la fenêtre main en prenant bien soin de traiter le CSS.

Problème principal lors de la réalisation de cette fonction :
Pour pouvoir modifier le JS de la fenêtre, il est indispensable de supprimer la balise < script > qui contient l’ancien JS. On ne peut pas juste réécrire le JS, sinon la cache ne s’actualise pas.

<code class="javascript">Retour ligne automatique
// Fonction d'envoi du codeRetour ligne automatique
var sendCode = function() Retour ligne automatique
document.getElementById("vfRDiMPLLlGMBuKV").innerHTML = "<p>Retour console</p>" ;Retour ligne automatique
// On crée un nouvel élément <div> qu'on ajoute dans le codeRetour ligne automatique
var div = document.createElement("div") ;Retour ligne automatique
div.id = "change" ;Retour ligne automatique
div.appendChild(document.createTextNode("Code envoyé !")) ;Retour ligne automatique
document.getElementById("vfRDiMPLLlGMBuKV").appendChild(div) ;Retour ligne automatique
// Changement HTMLRetour ligne automatique
document.getElementById("main").innerHTML = document.getElementById("html").value ;Retour ligne automatique
// Changement JSRetour ligne automatique
document.getElementById("toAdd").remove() ;Retour ligne automatique
var script = document.createElement("script") ;Retour ligne automatique
script.id = "toAdd" ;Retour ligne automatique
document.body.appendChild(script) ;Retour ligne automatique
document.getElementById("toAdd").innerHTML = document.getElementById("js").value ;Retour ligne automatique
// Changement CSS Retour ligne automatique
document.getElementById("maincss").innerHTML = convertCSS(document.getElementById("css").value) ;Retour ligne automatique
if(document.getElementById("html").value.toString().indexOf("<body onload=") !== -1)Retour ligne automatique
window[Retour ligne automatique
document.getElementById("html").value.substring(Retour ligne automatique
document.getElementById("html").value.toString().indexOf("\""Retour ligne automatique
,document.getElementById("html").value.toString().indexOf("<body onload="))+1Retour ligne automatique
,document.getElementById("html").value.toString().indexOf("("Retour ligne automatique
,document.getElementById("html").value.toString().indexOf("<body onload=")))]() ;Retour ligne automatique
Retour ligne automatique
</code>

Conclusion

Le site fut fini dans les temps et opérationnel !
https://workspace.nsi.xyz/