Étiquette : Python

Projets

Jeux de Calcul Mental chronométré en python

Êtes-vous bon en calcul mental ? Ce script en python vous propose de tester vos capacités à travers différents niveaux de difficulté, et tout cela chronométré !

Objectif

L’objectif de ce projet est de tester mes capacités en python et de mobiliser les notions vues en python en spécialité NSI (and, or, not, …etc). De plus, cela à pour but de proposer un outil pour s’entraîner au calcul mental. Je pense aussi l’adapter plus tard pour la calculatrice Numworks, ce qui donnera la possibilité d’y jouer dessus.

Projet

Le choix du langage pour ce projet est assez simple : python. C’est un langage assez simple à maitriser et adapté pour l’idée de mon jeux. Il propose aussi des bibliothèques assez intéressantes pour sa réalisation notamment time et random.

Analyse du code

Analysons le code.

Dans un premier temps on importe différentes bibliothèques qui vont nous être utilise. Nous utilisons la bibliothèque random pour générer des valeurs aléatoires pour diversifier les calculs ainsi que le module time.

import math
from random import *
from time import time
from art import text2art

operateurs1 = ["+","-"]
operateurs2 = ["+","-","x"]])

Subséquemment, vous pouvez aussi voir une bibliothèque art avec le module text2art qui nous sert à convertir du texte en ascii art et donc à sublimer par exemple le menu.

La première liste sert uniquement au niveau 1 qui est censé être le plus simple, on se limite donc à des additions/soustractions tandis que la deuxième liste est destinée au niveaux 2 et 3.

Passons maintenant au menu.

def menu(): # Interface du début
    titre1 = text2art("NSI : Calcul \t mental") # Titre en ascii art
    print(titre1)
    
    print("Il y a 3 niveaux:") # Présente les différents niveaux 
    print("1-Niveau facile")
    print("2-Niveau intermédiaire") 
    print("3-Niveau difficile")
    
    choix = int(input("\nAlors, qu'allez vous choisir :\n"))
    
    while choix not in [1, 2, 3]:  # Empêche toutes valeurs autre que 1, 2 ou 3
        input("Veuillez choisir un chiffre :\n")
    
    if choix == 1: # Renvoie au niveau choisie
        niveau1()
        
    if choix == 2:
        niveau2()
        
    if choix == 3:
        niveau3()

menu()

On commence par présenter les différents niveaux avec des print() et aussi un titre en ascii art grâce au module text2art(). Vous allez voir que tout au long du code que nous allons utiliser des input() qui permettent à l’utilisateur de rentrer des valeurs ou une chaîne de caractère.

Ici, la boucle à la ligne 12 est nécessaire pour que l’utilisateur entre quelque chose de valable, la logique est simple : tant que qu’il n’a pas rentrer une valeur valable on réitère la question et dès lors qu’il tapera 1,2 ou 3 le script pourra continuer.

Enfin, on ajoute des conditions avec if pour le rediriger le joueur sur le niveau choisi. Passons maintenant à la structure d’un niveau.

def niveau2(): # Deuxième niveau
    score = 0
    compteur =  0
    while compteur < 10:
        indice_aleatoire = randint(0,len(operateurs1)-1)
        generation1 = randint(2,4)
        generation2 = randint(11,42)
        generation3 = randint(300,600)
        generation4 = randint(384,666)  # Plus de génération car on ajoute des multiplications
        
        if indice_aleatoire == 2:
            print("\nPeux tu calculer", str(generation1), operateurs1[indice_aleatoire], str(generation2), "? Tu as 7 secondes.")
        else:
            print("\nPeux tu calculer", str(generation4), operateurs1[indice_aleatoire], str(generation3), "? Tu as 7 secondes.")
        
        depart_temps = time() # Calcule le temps
        rep = int(input("\nMa réponse : "))
        
        fin_temps = time()-depart_temps

Nous allons ici prendre pour exemple le niveau 2 (intermédiaire), mais les autres niveaux ne sont pas si différents que ça. On va diviser le niveau en 3 parties :

  • La génération du calcul et la réponse de l’utilisateur
  • La correction de la réponse
  • Félicite le joueur en fonction de son score

Dans un premier temps, on commence par initialiser le score et le compteur qui correspond au nombre de question, donc ici 12 questions. Le compteur s’incrémente à chaque fin de question d’où l’utilisation de while.

On génère ensuite un indice aléatoire pour choisir entre tous les opérateurs et des nombres pour les calculs. Si cela tombe sur une multiplication on va multiplier des nombres par des petites valeurs (entre 2 et 4), sinon on fait l’addition ou soustraction de deux nombres entre environ 300 à 600.

Enfin, on lance le chrono avec le module time(), on demande alors la réponse et on arrête le chrono pour savoir le temps passé.

if operateurs2[indice_aleatoire] == "+": # Détermine l'opérateur pour la correction
    resultat = generation4 + generation3
elif operateurs2[indice_aleatoire] == "-":
    resultat = generation4 - generation3
elif operateurs2[indice_aleatoire] == "x":
    resultat = generation1 * generation2
else:
    resultat = None
        
if resultat is not None and resultat == rep and fin_temps <=7: # Correction en fonction du résultat et du temps mis
    print("Bravo, tu as donné la bonne réponse dans le temps imparti. Ton temps:", fin_temps)
    score += 1
elif resultat is not None and resultat == rep and fin_temps > 7:
    print("Tu as donné la bonne réponse mais pas dans le temps imparti. Ton temps:", fin_temps)
            
else:
    print("\nAh...apparemment tu t'es trompé, réessaye !")
    
suite = input("\nPrêt pout ma suite ? o/n\n")  # Demande si l'utilisateur est prêt
if suite.lower() != "o":
    break
compteur += 1

Dans un deuxième temps, on détermine l’opérateur pour effectuer la correction avec la réponse de l’utilisateur. Il y a 3 cas possibles :

  • La réponse est correcte et a été donnée dans le temps imparti (dans ce cas la le score s’incrémente)
  • La réponse est correcte mais n’a pas été donnée dans le temps imparti
  • La réponse est incorrecte et n’a pas été donnée dans le temps imparti

Ensuite, on demande si l’utilisateur est prêt pour passer à la suite. Ici, on utilise la méthode .lower() qui permet d’éviter que le script plante si l’utilisateur a mis un « o » ou un « n » en majuscule.

Puis on incrémente le compteur comme nous l’avons expliqué précédemment.

if score > 4:
    print("\nBravo tu as répondu à tous les calculs et tu a au moins la moyenne, ton  score est de", score) # Donne le score et félicite le joueur
    gg = text2art("gg")
    print(gg)
else:
    print("\nTon score est de", score,", ce n'est pas fameux ! Je te conseille d'acheter ma formation pour seulemment 773€/mois") # Peut être que je vais la prendre cette formation finalement

Dans un troisième temps, à la fin de toutes les questions, on obtient plusieurs grades de félicitation en fonction du score du joueur.

On retrouve aussi l’utilisation tu module text2art() qui permet de dire bien joué.

Conclusion

Le projet était assez plaisant à faire et il a permis de tester mes capacités en python tout en mobilisant des notions vues en spé NSI notamment not, and, or, les boucles, …etc. Ce script peut aussi être adapté sur la numworks dans l’avenir, ce qui peut être sympa.

Télécharger le script

NumApps

Sudoku en python, NumWorks

Le sudoku est un jeu de logique qui se joue sur une grille de 9×9 cases, divisée en 9 blocs de 3×3 cases. Le but est de remplir chaque case avec un chiffre de 1 à 9, en respectant certaines règles : chaque chiffre ne doit apparaître qu’une seule fois par ligne, colonne et bloc. Le jeu est terminé lorsque toutes les cases sont remplies ou lorsque toutes les vies ont été usées.

Fonctionnalités

  • 4 difficultés
  • Système de vies
  • Génération aléatoire des grilles à chaque nouvelle partie
  • Menu d’aide

Captures d’écran

Commandes

◁ △ ▷ et ▽OKPavé numérique
Se déplacer / ParamétrerValiderPlacer un nombre

En savoir plus

Si vous souhaitez en apprendre plus sur ce projet, cet article pourrait vous intéresser.

Télécharger

Voici le lien pour récupérer le code du jeu et le télécharger sur votre calculatrice.

NumApps

Reversi en python, NumWorks

Le Reversi est un jeu de société pour deux joueurs qui se joue sur un plateau de 64 cases. Les joueurs placent tour à tour des pions noirs ou blancs sur le plateau en capturant les pions adverses et en retournant les pions de l’adversaire pour gagner le contrôle du plateau. Le joueur avec le plus de pions de sa couleur à la fin de la partie est déclaré vainqueur.

Fonctionnalités

  • Mode multijoueur et contre IA
  • 2 niveaux de difficultés pour l’IA
  • Système de score
  • Easter egg (trichez pas en regardant le code)

Captures d’écran

Commandes

◁ △ ▷ et ▽OK
Se déplacer / ParamétrerValider

En savoir plus

Si vous souhaitez en apprendre plus sur ce projet, cet article pourrait vous intéresser.

Télécharger

Voici différents liens pour récupérer le code du jeu et le télécharger sur votre calculatrice.

NumApps

Puissance 4 en python, NumWorks

Le Puissance 4 est un jeu de société qui se joue à deux. Le principe est d’aligner 4 jetons que ça soit horizontalement, verticalement ou en diagonale.

Captures d’écran

Commandes

◁ et ▷OK ou Exe
Choisir la colonneValider le coup

À propos

Vous pouvez en savoir plus sur le jeu en lisant l’article qui détaille le programme en lui même, un projet réalisé dans le cadre de la spécialité NSI.

Lien du jeu

Il existe deux liens pour le jeu, sachez que seul le premier garanti de disposer de la dernière version et que le deuxième est un lien alternatif qui peut être dépassé.

Tutoriels

Utiliser une IA pour générer, corriger, et modifier un…

Vous avez enfin décidé de débarquer et d’explorer le vaste monde de la programmation ? Dans ce cas, bienvenue chez les fous ! Entre cassage d’écran, arrachage de cheveux, ou encore saut par la fenêtre, vous vous rendrez vite compte comment ce vaste univers peut vous rendre maboule de 1001 manières. Ainsi, si vous souhaitez gagner du temps et être productif en programmation, ce tutoriel est fait pour vous !

En effet, il existe heureusement depuis quelques années des outils, se perfectionnant de mois en mois (voire même de jour en jour), permettant de vous faciliter la vie et surtout de gagner énormément de temps. La chose dont une développeuse ou un développeur a le plus besoin. L’un des outils ayant fait le plus parlé de lui ces dernières semaines est #ChatGPT, une intelligence artificielle capable de dialoguer avec nous en nous apportant des connaissances dans quasiment tous les domaines (mathématiques, langues, physique, etc.). Et donc dans ce tutoriel nous nous intéresseront à l’utilisation de #ChatGPT dans le domaine de la programmation en Python.

Une IA, c’est quoi ?

L’intelligence artificielle (IA) est une technologie qui permet à des machines de simuler l’intelligence humaine. Elle est utilisée dans de nombreux domaines, allant de la reconnaissance de la parole et de l’image à la robotique en passant par la finance et la santé.

Dans le domaine de la programmation, l’IA peut être utilisée pour automatiser certaines tâches de développement, comme la génération de code, la correction de bugs et la modification de scripts existants. Elle peut également être utilisée pour analyser et optimiser des algorithmes, ainsi que pour effectuer des tâches de test et de débogage.

Avantages de l’utilisation d’une IA

L’utilisation de l’intelligence artificielle (IA) dans le domaine de la programmation peut apporter plusieurs avantages incroyables. Voici une ribambelle d’exemples :

  1. L’automatisation de tâches fastidieuses : l’IA peut être utilisée pour automatiser certaines tâches de développement, comme la génération de code, la correction de bugs et la modification de scripts existants. Cela peut aider les développeurs à gagner du temps et à se concentrer sur des tâches plus complexes.
  2. Amélioration de la qualité du code : l’IA peut être utilisée pour analyser et optimiser des algorithmes, ce qui peut aider à améliorer la qualité du code et à réduire les erreurs.
  3. Test et débogage plus efficaces : l’IA peut être utilisée pour effectuer des tests et du débogage de manière plus rapide et plus précise, ce qui peut réduire le temps de développement.

Il est important de noter que l’utilisation de l’IA dans le domaine de la programmation nécessite un minimum de compétence en matière de développement. Une IA n’est pas (encore) parfaite et peut commettre des erreurs, il est donc nécessaire de toujours relire, vérifier, comprendre, et tester un code généré par une IA. Il est également important de veiller à utiliser l’IA de manière éthique et responsable. 😉

Comment accéder à l’IA

Nous utiliserons donc dans ce tutoriel ChatGPT, un chatbot qui utilise l’intelligence artificielle.

Le chat est disponible à tous gratuitement via l’URL suivante : https://chat.openai.com/auth/login. Voici la page dans laquelle vous accèderez :

Comme vous l’avez sans doute deviner, vous aurez besoin d’un compte OpenAI pour utiliser cette IA. Cliquez donc sur le bouton Sign up pour créer un compte, ou sur Log in si vous en avez déjà un.

Quand vous vous serez alors connecté avec succès, vous tomberez normalement nez à nez avec la page suivante, la page principale :

Cette page est assez simple au final, nous retrouvons en haut à gauche un bouton qui nous permet de créer d’autres chat. En effet, l’IA est capable de « retenir », réutiliser, et prendre en compte l’historique des précédents messages ! Donc si on discute avec elle sur des sujets précis, et que nous souhaitons ne pas mélanger des conversations, nous pouvons en ouvrir plusieurs qui seront indépendantes les unes des autres, il suffit donc d’appuyer sur ce bouton, intitulé New Chat.

Et puis en bas, nous retrouvons la barre où nous pourrons écrire et discuter avec l’IA. Tout ce qu’il y a de plus classique.

Utilisation de l’IA pour générer et modifier des scripts Python

L’IA peut être utilisé pour la génération, ou plutôt l’écriture de scripts Python.

Voici donc ci-dessous quelques exemples, assez époustouflants, où nous pouvons utiliser l’IA pour générer des scripts Python.

Mise en situation : Catastrophe, un DS de mathématiques demain et j’avais complètement oublié ! Il me faudrait un script Python qui puisse me calculer le discriminant ainsi que les racines d’une fonction, cela me ferait gagner beaucoup de temps…

Voyons de quoi est capable l’IA :

Aussitôt dit, aussitôt fait, l’IA nous pond une fonction python qui nous permet de calculer le discriminant et les racines d’une fonction du second degré.

Vous noterez qu’il est déjà possible d’obtenir le discriminant et les racines d’une fonction du second degré sans script python en sachant bien utiliser sa calculatrice. 😁

Essayons autre chose, un peu d’art pour voir ! J’aurai besoin d’une fonction me permettant de créer une étoile, à l’aide du module Turtle. Mais ajoutons un peu de piment à tout ça ! La fonction devra prendre en paramètre : La position x et y de l’étoile, la couleur de l’étoile, la taille de l’étoile, ainsi que le nombre de branches de l’étoile. 😈

Et maintenant, la question tant attendu : Est-ce que ça marche cette sorcellerie ? Et bien la meilleur façon de savoir, c’est de tester !

Voici donc le rendu sur Thonny :

Comme vous le voyez c’est très très impressionnant.

En expliquant clairement nos attentes, et nos contraintes. L’IA les respecte (ou en tout cas essaie) et nous offre un code documenté, et la plupart du temps optimisé.

À ce stade, la première question que nous pouvons nous poser est de savoir si le code généré par l’IA sort de ses mains, ou si elles il vient d’Internet. Pour le savoir, je vous laissez deviner, demandons lui simplement !

Ainsi, nous avons vu que l’IA était capable d’écrire du code python selon nos envies. Mais à l’évidence, elle peut aussi être utilisée pour modifier du code python. De la même manière, nous n’avons qu’à lui soumettre notre script à modifier, et lui demander ce qu’elle a à faire. Ensuite, laissez la magie opérer…

Voyons cela, voici le code suivant (qui n’a pas été écrit par l’IA) :

n = input("Choisissez un nombre.\t")
try:
    n = int(n)
except ValueError:
    exit("Ce n'est pas un nombre.")

is_prime = 1*(n > 1)
for i in range(2, n):
    if n % i == 0:
        is_prime = 0
        break
print("Ce nombre est premier." if is_prime else "Ce nombre n'est pas premier.")

Grosso modo, ce script nous dit si un nombre n est premier ou non. Demandons lui de l’optimiser :

Effrayant ou époustouflant ? 🤔

Utilisation de l’IA pour corriger des scripts Python

Bon jusqu’ici, nous n’avons pas été déçu. Voyons de quoi elle vaut dans la correction de scripts python. Voici ci-dessous un exemple concret d’utilisation pour corriger un script Python.

Ci-dessous, un script Python censé afficher la table de 5 :

table = 5
print("Table de" + table + ":")
for i in range(11):
    print("5x" + i + " = " + 5*i)

Malheureusement, je n’arrive à lancer le script et je ne comprends pas l’erreur :
TypeError: can only concatenate str (not "int") to str

Demandons donc à l’IA. Enfin, nous allons seulement lui envoyer notre bout de code tel quel et observer ce qu’il se passe :

Vous avez bien compris, l’IA a deviné par elle même que je voulais qu’elle corrige mon code en python, en remarquant qu’il y avait des erreurs dans celui-ci.

Nonobstant, en cas d’incompréhension d’une erreur, je conseille d’abord de demander à l’IA ce que signifie l’erreur, et d’essayer de la corriger sans son aide. L’IA est capable d’expliquer très clairement un concept, avec des exemples et possiblement des formulations différentes :

Comme vous le voyez, c’est assez spectaculaire, l’IA nous explique explicitement l’erreur, et ajoute des exemples tout au long de son explication. En l’occurrence comme vous l’avez vu, c’était un problème de concaténation.

Conclusion

En conclusion, l’utilisation d’une intelligence artificielle (IA) peut être un outil très utile pour aider les développeurs Python à générer, corriger et modifier leur code. Il existe de nombreux outils et bibliothèques qui permettent d’intégrer l’IA dans le développement de logiciels, comme nous l’avons vu précédemment il y a ChatGPT, mais il existe aussi des alternatives tout aussi époustouflantes, comme GitHub Copilot.

En utilisant ces outils, les développeurs peuvent gagner du temps et de l’efficacité dans leur travail quotidien et se concentrer sur des tâches plus complexes. Cependant, il est important de noter qu’il est toujours important de comprendre et de maîtriser les principes de base du développement de logiciels, même si l’on utilise l’IA pour automatiser certaines tâches.

Vous l’aurez compris, pour ne pas finir à l’hôpital des fous, il est toujours sympa d’avoir un petit assistant sous la main !

Tutoriels

Comprendre comment fonctionne un interpréteur python :

On se lance souvent dans un code et dans une programmation sur son IDE favori sans avoir réellement compris comment un ordinateur, outil totalement numérique, fait pour comprendre des ordres écrit en Anglais principalement, et les exécuter par la suite. Pour comprendre cela, gardons en tête que nos ordinateurs ne comprennent individuellement, que peu de choses, 0101010101…

Avant tout, rappelons qu’un interpréteur Python est un programme qui exécute du code Python. Lorsque vous exécutez un script, l’interpréteur lit votre code ligne par ligne et exécute les instructions que vous avez écrites. On remarque que l’interpréteur interactif python, celui qui « répond » directement dans la console lorsque vous y saisissez une commande peut effectuer des actions ne nécessitant pas de mots spécifiques au langage Python, comme de simples opérations mathématiques :

OpérateurRôleMéthode équivalente
(dièse)Introduction d’un commentaire
«  » (guillemets) ou  » (apostrophes)Encadrement du texte
(plus)
Addition, et concaténation de chaînes de caractères
add(), et concat()
– (moins)Négation, soustractionneg(), sub()
(étoile)Multiplication de chiffres, ou wildcard des caractèresmul()
(barre oblique), et //Division de chiffresdiv(), truediv(), et floordiv()
<Inférieur àlt()
>Supérieur àgt()
<=Inférieur ou égal àle()
>=Supérieur ou égal àge()
(égal)Définition de variable(s)
==Égal àeq()
!=, ou <> (chevrons)Différent dene()
() (parenthèses)Appel d’une fonction ou méthode
call()
[] (crochets)Accès à une liste indexéegetitem(), getslice()
(virgule)Séparation de paramètres
(point)Virgule décimale, ou séparation des paramètres avec leur méthode
** (étoiles)Puissance (ou exposant)pow()
%Modulomod()
+=Incrémentation
-=Décrémentation
<<Modification de gauchelshift()
>>Modification de droitershift()
(et commercial)Bit à bit « et »and()
(barre verticale)Bit à bit « ou »or()
(accent circonflexe)Bit à bit « ou exclusif »xor()
(tilde)Bit à bit « inversion »invert()
tableau des principales actions réalisables dans la console python

Rappelons ce qu’est un langage interprété :

Un langage interprété est un langage qui est lu ligne par ligne par un interpréteur. L’interpréteur va passer à travers chaque ligne de votre code Python pour le traduire en langage machine (votre ordinateur ne sait pas exécuter du code Python directement, il a besoin de langage machine). La traduction se fait en temps réel, lors de l’exécution. L’un des avantages est qu’un même script peut être exécuté sur plusieurs plateformes différentes, en revanche la traduction (interprétation) du code à chaque exécution a un impact sur les performances.

Si vous donnez votre script Python à un de vos amis qui n’a pas d’interpréteur Python sur sa machine, il ne pourra pas exécuter votre script.

Le langage machine est la suite de bits qui est interprétée par le processeur de l’ordinateur lors de l’exécution d’un programme. C’est le langage natif du processeur, et le seul qui soit reconnu par celui-ci. Un processeur ne peut comprendre un langage rentré par l’utilisateur, un programme python ou java par exemple. Un langage interprété, c’est donc tout d’abord un langage qui a besoin d’un interpréteur pour fonctionner. Dans le cas de Python on parle donc de l’interpréteur Python.

Ce langage machine qui s’identifie en bits signifie :

Pour clôturer l’interpréteur Python, on utilise la commande

exit()

Afin de réaliser ce tuto ainsi que cet article, j’ ai avant tout eu des difficultés a me documenter de façon précise, puisque les recherches que j’effectuais qui paraissaient pourtant les plus claires possibles, ne m’apportaient pas de véritable réponse en lien avec ma requête, tel le jour ou j ai voulu comprendre une notion dont peu de monde s’attarde dessus ; la compréhension de l anglais par un logiciel 🤔

ici, les liens proposés n’ont que peu de chose a voir avec ma demande..

Les deux modes d’utilisation du langage Python

Au sein de l’interpréteur python, il faut distinctement savoir différencier les deux modes d utilisations du langage python, qui sont le mode Interactif, ainsi que le mode Script.

  • Le mode interactif : Dans le mode interactif, aussi appelé mode console, l’interpréteur vous permet d’encoder les instructions une à une. Aussitôt une instruction encodée, il suffit d’appuyer sur la touche ENTER pour que l’interpréteur l’exécute. Pour quitter le mode interactif, il suffit d’exécuter l’instruction exit(). Il s’agit de nouveau d’une fonction prédéfinie de Python permettant de quitter l’interpréteur. Le mode interactif est très pratique pour rapidement tester des instructions et directement voir leurs résultats. Son utilisation reste néanmoins limitée à des programmes de quelques instructions. En effet, devoir à chaque fois retaper toutes les instructions s’avèrera vite pénible.
  • Le mode script : Dans le mode script où vous devez avoir préalablement écrit toutes les instructions de votre programme dans un fichier texte, et l’avoir enregistré sur votre ordinateur. On utilise généralement l’extension de fichier .py pour des fichiers contenant du code Python. Une fois cela fait, l’interpréteur va lire ce fichier et exécuter son contenu, instruction par instruction, comme si vous les aviez tapées l’une après l’autre dans le mode interactif. Les résultats intermédiaires des différentes instructions ne sont par contre pas affichés ; seuls les affichages explicites (avec la fonction print, par exemple) se produisent.

L’interpréteur python a évolué continuellement depuis sa création, durant la fin du XXème . Afin de comprendre et de considérer au mieux la progression de cette structure, est référencé un site html retraçant brièvement ces différents points de vus et paliers au cours du temps.

Historique-de-python

En conclusion, Il est important de comprendre comment fonctionne l’interpréteur Python pour pouvoir écrire du code efficacement et le faire exécuter correctement. En effet, l’interpréteur joue un rôle clé dans la traduction du code Python en instructions compréhensibles par la machine, et cela peut avoir un impact sur la performance et la fiabilité du programme. Par conséquent, il est essentiel de prendre en compte les particularités de l’interpréteur lors de l’écriture du code et de s’assurer qu’il est correctement exécuté. Insistons sur le fait que python joue un rôle d’intermédiaire entre celui qui écrit le code et l’ordinateur

Art

Perspective : un paysage Synthwave

Dans le cadre de la 5ème édition du dispositif “Regards de Géomètre”, nous avons décidé dans le thème « Perspective » de produire un paysage synthwave.

Origines de la Synthwave

Avant tout la synthwave est un genre musical électronique ayant émergé dans les années 2000/2010 qui s’inspire d’éléments des années 80. Et c’est justement dans les clips de ces musiques que l’on va retrouver ce type d’image.

Pour en savoir plus nous vous conseillons cette vidéo qui explique brièvement les origines.

Le Projet

Revenons donc au projet. Pour ce projet nous avons donc décidé de produire une image d’un paysage synthwave. Pour cela nous utilisons le module turtle ainsi que le module random, le module turtle est utilisé pour produire l’image est le module random est utilisé pour les étoiles de l’image où la taille et leur position est générée aléatoirement nous avons également utilisé le script permettant d’exporter une image générée par turtle en .png que vous pouvez retrouver ici.

Structure du script

Pour la structure du script nous avons décidé de découper chaque partie de l’image (pavage, fond, étoiles, soleil, ville et montagnes) afin de créer des fonctions et à la fin nous les avons toutes appelées dans un ordre précis pour que les différentes parties de l’image soit dans leur plan respectif.

Analyse du script

Nous allons donc analyser le script.

Commençons par l’appel des modules et la mise en place de turtle.

from turtle import *
from random import randint
# vérification des modules importés
try:
    from PIL import Image
    pillow_installed = True
except:
    print("Oops! - ModuleNotFoundError: No module named 'PIL' - RTFM :")
    print("https://nsi.xyz/py2png")
    pillow_installed = False
titre = "Perspective - Un paysage Synthwave"
title(titre+" | Au lycée, la meilleure spécialité, c'est la spé NSI")
setup(1280, 720) # définit la taille de la fenêtre
colormode(255) # permet l'utilisation de couleurs rgb
speed(0) #Remplaçable par tracer(2) (10x plus rapide) mais si il est utilisé des lignes du pavage peuvent manquer
hideturtle() #dissimule la tortue

On appelle les fonctions turtle, random avec pour random uniquement randint et on utilise une partie du script « exporter une image générée par turtle » pour vérifier que l’utilisateur a bien installé le module PIL et dans le cas contraire un message d’erreur s’affichera et lui donnera un lien pour installer le module et tout ça sans que le script ne s’arrête. Après la vérification on met en place le titre de la fenêtre qui va affiché le rendu ainsi que sa taille. Enfin on définit le type de couleurs utilisées (R,G,B), la vitesse de la tortue, et on dissimule la tortue (c’est plus joli).

Commençons par la première fonction : le fond

def fond():
    penup()
    rciel = 0
    gciel = 0 
    bciel = 0
    hauteur = -360
    goto(-642,-358)
    pendown()
    while hauteur != 360:
        pencolor(round(239 + rciel), round(41 + gciel), round(209 + bciel))
        forward(1280)
        hauteur += 1
        goto(-640, hauteur)
        rciel += (-29/180)
        gciel += (2/45)
        bciel += (7/720)

Pour le fond on aurait pu utiliser une fonction qui crée un rectangle et qui le remplit avec fill_rect, cependant la couleur dans ce cas est uni ce qui ne nous intéresse pas. Nous avons donc produit un script qui fait un fond dégradé qui fait avancer la tortue sur une ligne d’un pixel de large et à la fin de cette ligne la tortue est envoyé grâce à un goto à la ligne d’après et qui ajoute la différence de chaque couleur (rouge,vert et bleu) entre la couleur de début du dégradé et la couleur de fin. Tout ceci est arrondi car turtle n’est pas compatible avec des arguments à virgule (pour la fonction pencolor en tout cas).

Par la suite la fonction qui produit les étoiles a été codée :

def etoile():
    for i in range(90):
        penup()
        goto(randint(-720,720), randint(0,360))
        pendown()
        pencolor(255, 255, 255)
        lcercle = randint(1,3)
        fillcolor('white')
        begin_fill()
        circle(lcercle)
        end_fill()

Pour les étoiles on définit aléatoirement leur position sur la moitié haute de l’image, on les met en blanc, on définit aussi aléatoirement la taille de l’étoile et on créer l’étoile avec sa position, et sa taille en aléatoire puis on refait ce processus 90 fois pour avoir 90 étoiles.

Ensuite nous avons le soleil (Le script affiché n’est qu’une petite partie du script total du soleil car il est très long et qu’il se répète, il est donc inutile de commenter la suite) :

def soleil():
    penup()
    liste1 = [10,7,5,4,3,3,3,3,2,2,2,2,2,2,2,1,2,1,2,1,1,2,1,1,1,1,2,1,1,1]
    liste2 = [1,1,1,0,1,1,1,1,1,0,1,1,1,0,1,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0]
    pliste1 = 0
    pliste2 = 0
    rsoleil = 0
    gsoleil = 0
    bsoleil = 0
    lsoleil = 8
    hauteur = 30
    goto(0,30)
    pendown()
    for i in range(15):
        pencolor(round(255 + rsoleil), round(23 + gsoleil), round(226 + bsoleil))
        forward(lsoleil)
        backward(2*lsoleil)
        hauteur += 1
        lsoleil += liste1[pliste1]
        pliste1 += 1
        goto(0, hauteur)
        rsoleil += (0)
        gsoleil += (114/101)
        bsoleil += (-203/202)
    forward(lsoleil)
    backward(2*lsoleil)
    penup()

Pour le soleil nous réutilisons le script du dégradé, cependant nous l’avons modifier pour que le point d’origine de la tortue soit au centre du rectangle et que la longueur de chaque ligne soit défini par une liste (ce qui permet de faire un cercle en prenant les longueur d’un cercle utilisable en pixel art). Pour ce qui est des endroits ou le soleil est coupé la tortue fait le tracé mais on a utilisé la fonction penup() qui fait que la tortue ne dessine plus.

Après nous avons la fonctions des montagnes (Encore une fois le script n’est pas complet car il se répète encore 3 fois après.) :

def montagne():
    #montagne derrière la première
    penup()
    goto(-480,0)
    fillcolor(110, 27, 188)
    begin_fill()
    for i in range(3):
        forward(250)
        left(120)
    end_fill()
    
    goto(-480,0)
    pencolor(51, 210, 246)
    ymontagne = 10
    for i in range(11):
        pendown()
        goto(-355,ymontagne)
        goto(-230,0)
        penup()
        goto(-480,0)
        ymontagne += 20

Pour le script des montagnes nous avons utilisé le script pour faire des triangles équilatéraux retrouvable ici. Et ensuite nous avons utilisé un ‘for i in range’ pour faire des goto enchaîné pour faire les lignes des montagnes.

Ensuite nous avons les fonctions de la ville. Pourquoi les fonctions car il y a une fonction pour chaque bâtiment différent ainsi qu’une fonction finale qui définit l’ordre des bâtiments.

def bat1():
    penup()
    rbat = 0
    gbat = 0 
    bbat = 0
    hauteur = 0
    pendown()
    xturtle, yturtle = pos()
    while hauteur != 72:
        pencolor(round(125 + rbat), round(35 + gbat), round(216 + bbat))
        forward(42)
        hauteur += 1
        goto(xturtle, hauteur)
        rbat += (-5/3)
        gbat += (-7/15)
        bbat += (-72/25)
    forward(42)
    penup()
    right(90)
    forward(72)
    left(90)

Pour le bâtiment 1 il y a un dégradé (toujours le même script) puis on fait que la tortue finisse le bâtiment en bas à droite de ce dernier pour pouvoir enchainer les bâtiments.

fun fact : Au début nous n’avions pas prévu les quelques lignes à la fin pour que la tortue puisse enchaîner les bâtiments sans que les fonctions des bâtiments aient besoin d’être modifiés ce qui nous a amené à avoir tous les bâtiments qui se chevauchaient.

def ville():
    penup()
    goto(-320,0)
    bat3(), bat2(), bat1(), bat4() ,bat3(), bat4(), bat3(), bat2(), bat1(), bat2(), bat1(), bat3(), bat1(), bat4(), bat2(), bat1(), bat3(), bat1(), bat4(), bat3()

Et à la fin on a fait la fonction ville qui appelle dans l’ordre choisi les bâtiments. Le goto permet de définir où commence le premier bâtiment, les autres se mettent juste après le premier sans se chevaucher ni laisser un espace.

Par la suite nous avons le pavage (très long aussi, il sera donc coupé) :

def pavage():
    colormode(255)
    pensize(5)
    speed(0)
    rciel = 0
    gciel = 0 
    bciel = 0
    hauteur = -360
    penup()
    goto(-640,-360)
    pendown()
    while hauteur != 0:
        pencolor(round(15 + rciel), round(4 + gciel), round(76 + bciel))
        forward(1280)
        hauteur += 1
        goto(-640, hauteur)
        rciel += (91/180)
        gciel += (1/36)
        bciel += (7/18)

Pour le début du pavage on retrouve encore le script du dégradé mais avec les couleurs modifiées.

pencolor(229, 123, 240)
    #Lignes au dessus du pavage
    pensize(4),penup(),goto(-640,0),pendown(),goto(640,0),pensize(2),penup(),goto(-640, 0),pendown()
    #lignes gauche
    penup(),goto(-20.00,0),pendown(),goto(-60.00,-360.00),penup(),goto(-60.00,0),pendown(),goto(-180.00,-360.00),penup(),goto(-100.00,0),pendown(),goto(-300.00,-360.00),penup(),goto(-140.00,0),pendown(),goto(-420.00,-360.00),penup(),goto(-180.00,0),pendown(),goto(-540.00,-360.00),penup(),goto(-220.00,0),pendown(),goto(-660.00,-360.00),penup(),goto(-260.00,0),pendown(),goto(-780.00,-360.00),penup(),goto(-300.00,0),pendown(),goto(-900.00,-360.00),penup(),goto(-340.00,0),pendown(),goto(-1020.00,-360.00),penup(),goto(-380.00,0),pendown(),goto(-1140.00,-360.00),penup(),goto(-420.00,0),pendown(),goto(-1260.00,-360.00),penup(),goto(-460.00,0),pendown(),goto(-1380.00,-360.00),penup(),goto(-500.00,0),pendown(),goto(-1500.00,-360.00),penup(),goto(-540.00,0),pendown(),goto(-1620.00,-360.00),penup(),goto(-580.00,0),pendown(),goto(-1740.00,-360.00),penup(),goto(-620.00,0),pendown(),goto(-1760.00,-360.00)
    #lignes droites
    penup(),goto(20,0),pendown(),goto(60.00,-360.00),penup(),goto(60.00,0),pendown(),goto(180.00,-360.00),penup(),goto(100.00,0),pendown(),goto(300.00,-360.00),penup(),goto(140.00,0),pendown(),goto(420.00,-360.00),penup(),goto(180.00,0),pendown(),goto(540.00,-360.00),penup(),goto(220.00,0),pendown(),goto(660.00,-360.00),penup(),goto(260.00,0),pendown(),goto(780.00,-360.00),penup(),goto(300.00,0),pendown(),goto(900.00,-360.00),penup(),goto(340.00,0),pendown(),goto(1020.00,-360.00),penup(),goto(380.00,0),pendown(),goto(1140.00,-360.00),penup(),goto(420.00,0),pendown(),goto(1260.00,-360.00),penup(),goto(460.00,0),pendown(),goto(1380.00,-360.00),penup(),goto(500.00,0),pendown(),goto(1500.00,-360.00),penup(),goto(540.00,0),pendown(),goto(1620.00,-360.00),penup(),goto(580.00,0),pendown(),goto(1740.00,-360.00),penup(),goto(620.00,0),pendown(),goto(1760.00,-360.00)
    #Lignes horizontales
    penup(),goto(-640, -300),pendown(),goto(640, -300),penup(),goto(-640, -240),pendown(),goto(640, -240),penup(),goto(-640, -190),pendown(),goto(640, -190),penup(),goto(-640, -140),pendown(),goto(640, -140),penup(),goto(-640, -100),pendown(),goto(640, -100),penup(),goto(-640, -70),pendown(),goto(640, -70),penup(),goto(-640, -40),pendown(),goto(640, -40),penup(),goto(-640, -15),pendown(),goto(640, -15),

On a par la suite énormément de goto afin de faire le quadrillage du pavage.

Pour produire l’image finale nous avons les appels des différents fonctions à la fin :

#appel de toutes les fonctions
fond(), etoile(), soleil(), montagne(), ville(), pavage()

Et pour exporter l’image finale en .png il y a la suite du script pour exporter une image générée par turtle en .png utilisé au début du script.

#enregistrement de l'image finale avec vérification des modules importés
image = getcanvas()
nom_du_fichier_sans_extension=titre+"_"+hex(randint(2**30+2**25,2**30+2**25+2**24-1))[2:]
image.postscript(file=nom_du_fichier_sans_extension+".ps", colormode='color')
try:
    psimage = Image.open(nom_du_fichier_sans_extension+".ps")
    psimage.load(scale=2)
    psimage_resized = psimage.resize((1280, 720))
    psimage.save(nom_du_fichier_sans_extension+".png")
    print(nom_du_fichier_sans_extension+".png", psimage.size, "sauvegardé dans le dossier")    
except:
    if not pillow_installed:
        print("Oops! - ModuleNotFoundError: No module named 'PIL' - RTFM :")
        print("https://nsi.xyz/py2png")
    else:
        print("Oops! - 'ghostscript' not installed- RTFM :")
        print("https://nsi.xyz/py2png")
exitonclick()

Le script va donc générer une image en .ps et la convertir en .png avec un nom généré aléatoirement pour éviter que à chaque fois que vous générez une image l’image soit écrasée

Télécharger le .py

L’image finale

Art

Astronomie : Un semblant de liberté

« C’est dur, oui, il a tant cherché sa place dans l’univers : société, nature sauvage, vie luxueuse,… mais rien de tout ça ne lui convenait. Se tournant vers le ciel, c’était peut-être parmi les étoiles que se trouvait sa place… »


Introduction

À l’aide du module Turtle, on va pouvoir créer une image en python, animée ou non.
Aujourd’hui, ce sera alors plutôt un dessin que nous générerons par notre code, de plus, celle-ci sera différente à chaque exécution !
Nous allons alors décortiquer des parties de celui-ci afin de le comprendre, si ce n’est pas déjà le cas ! 😉


Une mise en bouche qui nous prépare

colormode(255)
color(5,9,44)
goto(-640,0)
pensize(1000)
forward(1000)

Ce bloc de code permet de préparer le dessin en y installant un fond bleu nuit rappelant l’espace.
La couleur est définie dans les 2 premières lignes, ensuite on se rend à des coordonnées hors du champ de vision puis on trace un trait très épais.


Des fonctions par-ci, des fonctions par-là

def etoile():
    pensize(2)
    couleur = randint(0,3)
    if couleur == 0:
        color(250, 137, 25)
    else:
        color(247,247,36)
    for _ in range(5):
        forward(10)
        right(144)

Le bloc de code suivant est une fonction, elle nous permet de définir une suite d’instructions qu’on peut utiliser par la suite.
Elle dessine une étoile tout en utilisant un autre module permettant d’utiliser l’aléatoire, à l’aide de celui-ci et de structure conditionnelles, on choisit aléatoirement entre 2 couleurs pour l’étoile.
Puis, on la trace à l’aide d’une boucle bornée. 😵

def position_aleatoire():
    penup()
    x = randint(-640,640)
    y = randint(-320,320)
    goto(x,y)
    pendown()

Cette seconde fonction diffère de la 1ère par son utilité-même : elle permet de choisir une position aléatoire.
La fonction génère aléatoirement des coordonnées dans un intervalle défini, ici, celle de la fenêtre puis elle s’y rend.

for _ in range(42):
    position_aleatoire()
    type_etoile = randint(0,2)
    if type_etoile == 0:
        etoile_2()
    else:
        etoile()

C’est alors que la magie entre en scène, on manipule les fonctions précédemment créées afin de produire un splendide ciel étoilé !
On se rend à un endroit aléatoire grâce à la 2ème fonction puis on dessine une étoile grâce à la 1ère fonction (et une autre produisant un autre type d’étoile), et ceci 42 fois !! 😱


Des éléments de décoration


D’autres éléments constituant l’image proviennent de fonctions, prenons ici l’exemple de la fusée :

def fusee():
    left(55)
    penup()
    goto(-100,-40)
    pendown()
    corps_fusee()
    for i in range(2):
        penup()
        goto(-125+i*275/100*25,-50-i*5/2*20)
        pendown()
        moteur()
    for i in range(2):
        penup()
        goto(-15+i*35*135/100,-65/2+i*50*135/100)
        pendown()
        hublot()
    right(30)
    penup()
    goto(15,125)
    pendown()
    toit()


On peut voir une différence notable avec les fonctions précédentes, cette fonction est elle-même constituée de fonctions : « corps_fusee » ; « moteur » ; « hublot » et « toit ».
Et comme dit plus tôt, on utilise et manipule ces fonctions, par exemple en les utilisant plusieurs fois dans une boucle, en définissant un angle au préalable,… et ça ne s’arrête pas là ! on pourrait très bien utiliser la fonction définissant la fusée afin de lui donner une autre utilité !

C’est alors en usant de fonctions, de boucles et de structures conditionnelles qu’on peut facilement produire une œuvre avec le module Turtle, mais tout cela ne peut se réaliser qu’avec de la pratique, car comme j’ai dit : « C’est en programmant que l’on devient programmeur ».

L’image finale

Télécharger le .py

Art

Urbanisme : La skyline de New York

Pour ce premier projet en classe de première NSI nous avons choisi comme thème l’urbanisme. Nous avons souhaiter créer un projet original. Ce programme a pour but de réaliser un rendu graphique qui se rapproche au maximum du flat design. 

C’est quoi le flat design ?

Petit point de culture générale : Très brièvement le flat design est un style graphique caractérisé par le minimalisme et la simplicité des éléments présents sur le rendu. On ne cherche pas à faire à être dans le détail avec des ombres, des effets 3d… mais à être dans la simplicité avec une recherche en amont. Le flat design est aujourd’hui utilisé dans différentes catégories telle que l’illustration ou encore dans l’UI design où il consistera à obtenir un rendu fluide et ergonomique pour l’utilisateur. Un très grand artiste français qui utilise le flat design est Malika Favre voilà quelques exemples de créations qu’il a pu réaliser :

Les Recherches

Dans un premier temps pour réaliser ce projet nous avons dû faire différentes recherches sur internet. Les recherches finies, nous avons créer un moodboard pour mettre nos idées au claire et pour avoir de l’inspiration.

Nous avons sélectionné une image de la Skyline sur internet et nous l’avons directement modifiée sur Photoshop pour ne pas avoir de soucis avec les droits d’auteur.

Skyline/ Photoshop

Dans un second temps, nous nous sommes mis d’accord pour ne pas créer une simple Skyline mais bien plus. Notre point de départ est un couché de soleil avec des couleurs pastelles pour obtenir un rendu idéal qui se rapproche du flat design.

Une fois que nous étions d’accord sur les détails de notre projet, nous avons commencé le script phyton. Nous nous sommes divisés le travail en deux groupes :

  • Skyline : Noah / Henry
  • Ciel : Constance

Le code en entier

from turtle import *
from random import randint

#Lever de soleil

colormode(255)
bgcolor("#ffb399")

def disque(rayon, x, y, couleur=(1, 1, 1)):
    penup()
    goto(x, y-rayon)
    pendown()
    pencolor(couleur)
    fillcolor(couleur)
    begin_fill()
    circle(rayon)
    end_fill()
    
x, y = (0,-120)
radius = (500)
color = ("#ffc6b3")
disque(radius, x, y, color) 

x, y = (0,-120)
radius = (400)
color = ("#ffd9cc")
disque(radius, x, y, color) 
    
x, y = (0,-120)
radius = (300)
color = ("#ffece6")
disque(radius, x, y, color)     

x, y = (0,-120)
radius = (200)
color = ('white')
disque(radius, x, y, color)   


def arrondi_gauche():
    for i in range(180):
        left(1)
        forward(7/45)
        
def arrondi_droit():
    for i in range(180):
        right(1)
        forward(7/100)


def nuage():
    speed(10)
    pendown()
    width(2)
    pencolor("#ffffb3")
    fillcolor("#ffffb3")
    begin_fill()
    forward(210)
    arrondi_gauche()
    forward (21)
    arrondi_droit()
    forward(14)
    arrondi_gauche()
    forward(70)
    arrondi_droit()
    forward(56)
    arrondi_gauche()
    forward(28)
    arrondi_droit()
    forward(14)
    arrondi_gauche()
    forward(20)
    for i in range(90):
        right(1)
        forward(7/50)
    for i in range(90):
        left(1)
        forward(7/45)
    forward(35)
    for i in range(90):
        left(1)
        forward(7/45)
    for i in range(90):
        right(1)
        forward(7/50)
    forward(21)
    arrondi_gauche()
    forward(14)
    arrondi_droit()
    forward(49)
    arrondi_gauche()
    forward(42)
    arrondi_droit()
    forward(56)
    arrondi_gauche()
    forward(7)
    arrondi_droit()
    forward(42)
    arrondi_gauche()
    forward(10)
    end_fill()

penup()
goto(-450,-40)
nuage()

penup()
goto(300,55)
nuage()

penup()
goto(-50,200)
nuage()

#Skyline

pensize(3)
def building1(longueur,largeur, couleur=(1,1,1)):
    pendown()
    pencolor(couleur)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    right(90)
    forward(longueur/1.5)
    left(90)
    forward(longueur/2)
 
def building2(longueur, largeur, couleur=(1,1,1)):
    etage(longueur, largeur/5)
    etage(longueur/2 , largeur/5)
    etage(longueur/3 , largeur/5)
    left(80)
    forward(longueur/2)

def etage(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)

def etage_inverse(longueur, largeur, couleur=(1,1,1)):
    forward(largeur)
    left(270)
    forward(longueur)
    left(90)
def building2_inverse(longueur, largeur, couleur=(1,1,1)):
    right(160)
    forward(longueur/2)
    left(80)
    etage_inverse(longueur/3, largeur/5)
    etage_inverse(longueur/2 , largeur/5)
    etage_inverse(longueur, largeur/5)

def building3(longueur, largeur, couleur=(1,1,1)):
   forward(longueur/3)
   left(90)
   forward(longueur)
   right(90)
   forward(largeur)
   right(90)
   forward(longueur/4)
   left(90)
   forward(largeur)
   left(90)
   forward(longueur/5)
   right(90)
   forward(largeur)
   right(90)
   forward(longueur/2)
   
def building4(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur/3)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    left(90)
    forward(longueur-30)
    right(90)
    forward(largeur+25)
    right(90)
    forward(longueur+20)
    
def building5(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    right(90)
    forward(longueur/2)
    left(45)
    forward(longueur/2)
    right(225)
    forward(longueur/3)
    right(90)
    forward(largeur+5)
    right(90)
    forward(longueur+30)
    
def building6(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur)
    left(90)
    forward(longueur)
    right(30)
    forward(longueur/8)
    left(30)
    forward(30)
    right(30)
    forward(longueur/8)
    left(30)
    forward(60)

def building6_reverse(longueur, largeur, couleur=(1,1,1)):
    left(180)
    forward(60)
    left(30)
    forward(longueur/8)
    right(30)
    forward(30)
    left(30)
    forward(longueur/8)
    right(30)
    forward(longueur)
    left(90)
    forward(largeur)
    
def building7(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    left(90)
    forward(longueur/3)
    right(90)
    forward(largeur)
    right(90)
    forward(longueur-130)
    left(90)
    forward(largeur)
    right(90)
    forward(longueur-50)
    left(35)
    forward(largeur*2)
    right(35)
    forward(longueur-75)


def building8(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    right(90)
    forward(longueur/2)
    left(35)
    forward (largeur)
    right(35)
    forward(longueur-20)
       
    
    
penup()
fillcolor("#80586D")
begin_fill()
goto(-630,-350)
goto(-630,-300)
building1(60,30, couleur=("#80586D"))
building2(150,80 , couleur=("#80586D"))
building2_inverse(150,80 , couleur=("#80586D"))
building3(120,30, couleur=("#80586D"))
building4(100,40, couleur=("#80586D"))
building5(80,25, couleur=("#80586D"))
building6(275,50, couleur=("#80586D"))
building6_reverse(275,50, couleur=("#80586D"))
right(90)
building4(90,30, couleur=("#80586D"))
building7(165,35, couleur=("#80586D"))
left(90)
building3(170,35, couleur=("#80586D"))
building8(150,45, couleur=("#80586D"))
pendown()
goto(630,-350)
goto(-630,-350)
end_fill()



penup()
fillcolor("#01343D")
begin_fill()
left(90)
goto(-620,-350)
building1(60,30, couleur=("#01343D"))
building2(150,80 , couleur=("#01343D"))
building2_inverse(150,80 , couleur=("#01343D"))
building3(120,30, couleur=("#01343D"))
building4(100,40, couleur=("#01343D"))
building5(80,25, couleur=("#01343D"))
building6(275,50, couleur=("#01343D"))
building6_reverse(275,50, couleur=("#01343D"))
right(90)
building4(90,30, couleur=("#01343D"))
building7(165,35, couleur=("#01343D"))
left(90)
building3(170,35, couleur=("#01343D"))
building8(150,45, couleur=("#01343D"))
pendown()
goto(-630,-350)
end_fill()

Le Fond

def disque(rayon, x, y, couleur=(1, 1, 1)):
    penup()
    goto(x, y-rayon)
    pendown()
    pencolor(couleur)
    fillcolor(couleur)
    begin_fill()
    circle(rayon)
    end_fill()
    
x, y = (0,-120)
radius = (500)
color = ("#ffc6b3")
disque(radius, x, y, color) 

x, y = (0,-120)
radius = (400)
color = ("#ffd9cc")
disque(radius, x, y, color) 
    
x, y = (0,-120)
radius = (300)
color = ("#ffece6")
disque(radius, x, y, color)     

x, y = (0,-120)
radius = (200)
color = ('white')
disque(radius, x, y, color)   


def arrondi_gauche():
    for i in range(180):
        left(1)
        forward(7/45)
        
def arrondi_droit():
    for i in range(180):
        right(1)
        forward(7/100)
Fond

Pour réaliser le fond, j’ai adapté la fonction disque des exemples donnés afin de faire un dégradé de disques partant d’un peu plus bas que le centre et du plus clair au plus foncé. De cette manière, le disque au centre est blanc et représente donc le Soleil. De plus, les disques autour forment un dégradé de couleurs modélisant le levé du Soleil dans le ciel.

Les nuages

def nuage():
    speed(10)
    pendown()
    width(2)
    pencolor("#ffffb3")
    fillcolor("#ffffb3")
    begin_fill()
    forward(210)
    arrondi_gauche()
    forward (21)
    arrondi_droit()
    forward(14)
    arrondi_gauche()
    forward(70)
    arrondi_droit()
    forward(56)
    arrondi_gauche()
    forward(28)
    arrondi_droit()
    forward(14)
    arrondi_gauche()
    forward(20)
    for i in range(90):
        right(1)
        forward(7/50)
    for i in range(90):
        left(1)
        forward(7/45)
    forward(35)
    for i in range(90):
        left(1)
        forward(7/45)
    for i in range(90):
        right(1)
        forward(7/50)
    forward(21)
    arrondi_gauche()
    forward(14)
    arrondi_droit()
    forward(49)
    arrondi_gauche()
    forward(42)
    arrondi_droit()
    forward(56)
    arrondi_gauche()
    forward(7)
    arrondi_droit()
    forward(42)
    arrondi_gauche()
    forward(10)
    end_fill()

penup()
goto(-450,-40)
nuage()

penup()
goto(300,55)
nuage()

penup()
goto(-50,200)
nuage()

Pour rajouter un effet naturel au ciel, on a décidé d’ajouter des nuages avec une couleur et une forme adaptée au moment de la journée du levé de Soleil. J’ai donc crée une fonction nuage qui comprend également deux autres fonctions pour arrondir chaque bosse des nuages. De cette façon, le script est bien plus court. Pour faire les arrondis, j’ai d’abord fait le script d’un cercle, puis je l’ai adapté dans chacune des fonctions afin que sa largeur puisse varier.

La Skyline

def building1(longueur,largeur, couleur=(1,1,1)):
    pendown()
    pencolor(couleur)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    right(90)
    forward(longueur/1.5)
    left(90)
    forward(longueur/2)
 
def building2(longueur, largeur, couleur=(1,1,1)):
    etage(longueur, largeur/5)
    etage(longueur/2 , largeur/5)
    etage(longueur/3 , largeur/5)
    left(80)
    forward(longueur/2)

def etage(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)

def etage_inverse(longueur, largeur, couleur=(1,1,1)):
    forward(largeur)
    left(270)
    forward(longueur)
    left(90)
def building2_inverse(longueur, largeur, couleur=(1,1,1)):
    right(160)
    forward(longueur/2)
    left(80)
    etage_inverse(longueur/3, largeur/5)
    etage_inverse(longueur/2 , largeur/5)
    etage_inverse(longueur, largeur/5)

def building3(longueur, largeur, couleur=(1,1,1)):
   forward(longueur/3)
   left(90)
   forward(longueur)
   right(90)
   forward(largeur)
   right(90)
   forward(longueur/4)
   left(90)
   forward(largeur)
   left(90)
   forward(longueur/5)
   right(90)
   forward(largeur)
   right(90)
   forward(longueur/2)
   
def building4(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur/3)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    left(90)
    forward(longueur-30)
    right(90)
    forward(largeur+25)
    right(90)
    forward(longueur+20)
    
def building5(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    right(90)
    forward(longueur/2)
    left(45)
    forward(longueur/2)
    right(225)
    forward(longueur/3)
    right(90)
    forward(largeur+5)
    right(90)
    forward(longueur+30)
    
def building6(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur)
    left(90)
    forward(longueur)
    right(30)
    forward(longueur/8)
    left(30)
    forward(30)
    right(30)
    forward(longueur/8)
    left(30)
    forward(60)

def building6_reverse(longueur, largeur, couleur=(1,1,1)):
    left(180)
    forward(60)
    left(30)
    forward(longueur/8)
    right(30)
    forward(30)
    left(30)
    forward(longueur/8)
    right(30)
    forward(longueur)
    left(90)
    forward(largeur)
    
def building7(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    left(90)
    forward(longueur/3)
    right(90)
    forward(largeur)
    right(90)
    forward(longueur-130)
    left(90)
    forward(largeur)
    right(90)
    forward(longueur-50)
    left(35)
    forward(largeur*2)
    right(35)
    forward(longueur-75)


def building8(longueur, largeur, couleur=(1,1,1)):
    left(90)
    forward(largeur)
    left(90)
    forward(longueur)
    right(90)
    forward(largeur)
    right(90)
    forward(longueur/2)
    left(35)
    forward (largeur)
    right(35)
    forward(longueur-20)
       
    
    
penup()
fillcolor("#80586D")
begin_fill()
goto(-630,-350)
goto(-630,-300)
building1(60,30, couleur=("#80586D"))
building2(150,80 , couleur=("#80586D"))
building2_inverse(150,80 , couleur=("#80586D"))
building3(120,30, couleur=("#80586D"))
building4(100,40, couleur=("#80586D"))
building5(80,25, couleur=("#80586D"))
building6(275,50, couleur=("#80586D"))
building6_reverse(275,50, couleur=("#80586D"))
right(90)
building4(90,30, couleur=("#80586D"))
building7(165,35, couleur=("#80586D"))
left(90)
building3(170,35, couleur=("#80586D"))
building8(150,45, couleur=("#80586D"))
pendown()
goto(630,-350)
goto(-630,-350)
end_fill()



penup()
fillcolor("#01343D")
begin_fill()
left(90)
goto(-620,-350)
building1(60,30, couleur=("#01343D"))
building2(150,80 , couleur=("#01343D"))
building2_inverse(150,80 , couleur=("#01343D"))
building3(120,30, couleur=("#01343D"))
building4(100,40, couleur=("#01343D"))
building5(80,25, couleur=("#01343D"))
building6(275,50, couleur=("#01343D"))
building6_reverse(275,50, couleur=("#01343D"))
right(90)
building4(90,30, couleur=("#01343D"))
building7(165,35, couleur=("#01343D"))
left(90)
building3(170,35, couleur=("#01343D"))
building8(150,45, couleur=("#01343D"))
pendown()
goto(-630,-350)
end_fill()
New York Skyline

Dans le cas de la Skyline, le principal défi a été d’éviter de reproduire la même chose. Donc pour remédier au problème, nous avons coder de nombreuses fonctions « def » pour initialiser les buildings. Ensuite, il s’agissait surtout de calculer les bâtiments et les étages car ils étaient tous hétérogènes. Enfin, il nous suffisait d’utiliser les fonctions en rentrant les mesures et définir les couleurs puis la Skyline de New York prend vie.

Conclusion

En réalisant ce projet, nous avons étudié l’architecture de New York en analysant les suites logiques de buildings en fonction de leurs tailles par exemple. Nous avons aussi travaillé sur la meilleure façon de représenter un lever de Soleil de manière simple et évidente en regardant des exemples sur des dessins et des photos. En python, on a appris à manipuler les fonctions pour exécuter des scripts sans les réécrire plusieurs fois (avec les arrondis des nuages par exemple). Nous avons aussi du travailler beaucoup avec les couleurs avec les plusieurs plans des buildings qui ont permis de donner du relief à l’image grâce aux couleurs mais aussi avec le dégradé du ciel pour qu’il paraisse naturel. Nous avons aussi du visualiser l’image finale en gardant le meilleur de différentes inspirations et tout calculer pour que l’image ne soit ni trop vide ni trop surchargée d’éléments. Cette réalisation avait pour but d’être esthétique, moderne et simple.4

Télécharger le .py

Si vous voulez l’essayer, vous trouverez le script ci-dessous, mais attention, les nuages prennent énormément de temp à s’exécuter !

Art

Musique : Pink Floyd et son album lumineux

Le choix de la pochette d’album « The Dark Side of the Moon » n’a, d’après les membres du groupe, pas de signification précise. Lassés des photographies chargées ou des collages compliqués, ceux-ci cherchaient un visuel simple et facile à retenir. C’est bien le cas puisque 50 ans après, l’image du spectre lumineux se dispersant à travers un prisme est presque toujours associée au groupe Pink Floyd.

Vidéo de présentation du projet

De la physique à la musique

Lors du feuilletage d’un manuel de physique, l’attention du graphiste des Pink Floyd a été retenue par une photographie en noir et blanc d’un prisme à travers lequel se dispersait la lumière. L’idée lui est alors venue de choisir cette image en guise de pochette d’album.

En physique, un spectre lumineux est le résultat de la décomposition de la lumière par un spectroscope. Il permet d’analyser celle ci grâce aux radiations qui la composent.

Cette image n’est pas sans rappeler les éclairages des concerts où des faisceaux lumineux traversent la scène en se modifiant au contact des musiciens, tel le spectre traversant le prisme.

De la musique à la NSI

Nous avons donc décidé de récréer numériquement cette pochette d’album. Pour ce faire, nous avons utilisé le langage python et l’émulateur Thonny.

Tout d’abord, nous avons instauré le fond de couleur noir en utilisant la fonction bgcolor().

Nous avons ensuite tracé le triangle principal en veillant à le placer au centre. Pour cela, nous avons mis pour point d’abscisse de départ la valeur « -100 » afin que la longueur du triangle soit de « 200 ».

Puis, nous nous sommes penchés sur la partie gauche de notre image en commençant par tirer un trait défini par ses points de coordonnées de départ et d’arrivée.

Effet dégradé à l’intérieur du triangle :

Vient ensuite une partie plus complexe : l’élargissement du trait en dégradé, partant de la couleur initiale du trait pour aller vers le noir de l’arrière plan.

Pour cela, le script effectue des traits en allers-retours (grâce à une boucle for), d’un point défini sur le triangle jusqu’au milieu du triangle. Pour chaque trait, l’opacité (a) diminue au fur et à mesure que le trait se rapproche du milieu du triangle. L’opacité est remise à sa valeur initiale (a=255) avant chaque traçage de trait.

turtle.colormode(255)
for i in range(20):
    penup()
    a = 255
    go to(-40, 100)
    for i in range(41):
        turtle.color(a,a,a)
        pendown()
        turtle.forward(1)
        a += -6
    turtle.right(1)

Et voici le résultat:

Réalisation du triangle et du faisceaux lumineux entrant

Création de l’arc en ciel :

Ensuite, en partant d’un point situé sur la bordure droite du triangle, nous avons créé une boucle for permettant de réaliser les traits de couleur à droite, définis par une liste. Pour que les couleurs attendus soient identiques à celle de la pochette d’album originale, nous avons trouvé leur équivalent en hexadécimal grâce au site « Image Color Picker ».

liste = ["#6f597a","#3476b2","#78ab23", "#f9fc49","#e8b30d","#de2b05",]
goto(63 - 10/6, 81)
turtle.right(12)
turtle.pensize(10)
s=5
for i in range(6):
    turtle.color(liste[i%6])
    pendown()
    turtle.forward(355 + 0.1*i)
    penup()
    goto(58 - 10/6*i, 80 + s + 4*i)
    turtle.left(1)
    s+=-1
Script initial avec ajout de l’arc en ciel

Enfin, nous avons reproduit les commandes de lecture, situées dans la partie inferieure de notre rendu visuel, en utilisant encore une fois des boucles for pour créer des formes géométriques telles que des rectangles ou des triangles.

Afin de créer un effet visuel plus esthétique nous avons aussi intégré les fonctions begin_fill() et end_fill() qui permettent de colorer l’intérieur de formes géométriques telles que le « bouton pause » par exemple.

Nous vous proposons la découverte de notre rendu final ci-dessous, j’espère qu’il vous plaira!

Rendu final du script après exécution

Télécharger le .py :

Pour finir, nous vous partageons l’intégralité de notre projet afin que vous puissiez le découvrir plus en détail !