Author: Constance A.

interface graphique Découvrir

Interface graphique, en python


Les interfaces graphiques en Python permettent de créer des applications avec une interface utilisateur graphique, offrant ainsi une expérience plus visuelle et interactive. Avec des bibliothèques tel que par exemple Tkinter, Python simplifie le développement d’interfaces utilisateur, que ce soit pour des applications de bureau, des outils de visualisation ou des applications mobiles.

Introduction :

Les interfaces graphiques en Python représentent un moyen puissant de créer des applications interactives, offrant une expérience utilisateur intuitive et visuellement attrayante. Ce projet a pour objectif principal de concevoir une interface graphique permettant l’affichage, la modification et la suppression d’éléments au sein d’une base de données à l’aide de la programmation en Python. Les outils clés employés dans ce projet incluent Tkinter pour la conception de l’interface utilisateur et pandas pour la manipulation des données de la base.

Le compte rendu suivra une structure organisée, mettant en valeur les aspects cruciaux du projet, de la conception de l’interface graphique à l’intégration de la base de données. Les grandes sections de ce compte rendu incluront la conception de l’interface graphique, l’intégration de la base de données, les fonctionnalités principales, la gestion des erreurs et les opportunités d’amélioration, concluant avec un récapitulatif des points saillants du projet. Ces sections aideront à fournir une vision globale et détaillée du processus de développement de l’interface graphique Python dédiée à la gestion de bases de données.

Fonctionnalités Principales :

L’utilisation de la bibliothèque pandas s’avère essentielle pour la manipulation agile des données au sein de notre interface. Cette section explore les techniques employées pour extraire, modifier et supprimer des données, assurant ainsi une cohérence entre les informations présentées à l’utilisateur et celles stockées dans la base de données. Tout comme Tkinter, qui est une bibliothèque d’interface graphique en Python qui permet de créer des applications avec une interface utilisateur visuelle, facilitant ainsi le développement d’applications interactives.

Affichage :

Le processus d’affichage se déroule en plusieurs parties. Pour débuter, nous avons opté pour la création d’une nouvelle fenêtre à laquelle nous avons attribué des dimensions de 800×1000 (une décision basée sur nos préférences personnelles).

def affichage():
    # Créer une nouvelle fenêtre pour afficher le Pokédex
    fenetreupdate = Toplevel()
    fenetreupdate.title("Pokédex")
    fenetreupdate.geometry("800x1000")

Ensuite, pour connecter le script à la base de données (sous format Excel), en considérant que « bdd » représente notre base de données et que l’argument engine='openpyxl' est utilisé pour orienter pandas vers le module openpyxl. Cela permet à pandas de lire et d’écrire des fichiers Excel dans le format spécifique .xlsx.

excel_data = pd.read_excel("bdd.xlsx", engine='openpyxl')

Enfin, pour exploiter chaque ligne et chaque colonne, l’utilisation d’une double boucle for s’est avérée la plus pertinente pour nous. Nous avons également souhaité personnaliser la première colonne (le nom des Pokémon) en appliquant une police en gras pour les mettre en valeur. De plus, nous avons ajouté un espacement entre les données du tableur afin d’améliorer la présentation générale.

for index, row in excel_data.iterrows():
    for col_index, value in enumerate(row):
        label = Label(fenetreupdate, text=str(value))
        if col_index == 0:
            label.config(font=("Arial", 14, "bold"))
        label.grid(row=index+1, column=col_index, padx=50, pady=10, columnspan=2)

Nous avons ensuite fait face a un problème de place car notre base de donnée était trop longue. Nous avons rajouté une scrollbar . Pour cela, on a du d’abord définir un canva qui entoure toute la fenêtre. Puis, configurer ou se trouve la barre par rapport a la fenêtre.

canvas = Canvas(fread)
    canvas.pack(side=LEFT, fill=BOTH, expand=True)
    scrollbar = Scrollbar(fread, orient=VERTICAL, command=canvas.yview)
    scrollbar.pack(side=RIGHT, fill=Y)
    canvas.configure(yscrollcommand=scrollbar.set)

Puis, on a du créer une fonction qui lierai l’évènement du mouvement de la souris avec la scrollbar:

    def bardef(event):
        canvas.configure(scrollregion=canvas.bbox('all'))
    frame.bind('<Configure>', bardef)
    canvas.bind_all("<MouseWheel>", lambda event: canvas.yview_scroll(int(-1 * (event.delta / 120)), "units"))

L’arborescence des fenêtres

Pour avoir un rendu de pokedex crédible, nous avons du trouver une bonne mise en forme des différentes fonctions. On est donc parti d’une première fenêtre qui afficherait deux boutons: Un pour afficher la base de donnée et un pour modifier le pokédex. La fenêtre « Modifier le pokédex » n’utilise pas de sql car elle ne modifie pas de base de donnée, elle répertorie les actions qu’on peut exécuter sur le pokedex ( ajouter, modifier et supprimer) sous forme de trois autres boutons.

	bouton3 = Button(fmodif, text="Ajouter un Pokemon", font=("Consolas", 15), bg="white", fg="black", command=create, width=50, height=3)
    bouton4 = Button(fmodif, text="Modifier un Pokemon", font=("Consolas", 15), bg="white", fg="black", command=update, width=50, height=3)
    bouton5 = Button(fmodif, text="Supprimer un Pokemon", font=("Consolas", 15), bg="white", fg="black", command=delete, width=50, height=3)

Voici les boutons que nous avons utilisé tout le long du code. Il fallait a chaque fois les appeler avec avec la fonction pack(). Un des erreurs que nous avons rencontré est de mettre tout les boutons a la fin du code alors qu’il fallait les placer dans leurs fonctions respectives.

La fonction create

Pour la fonction create, nous avons pensé à faire plusieurs champ de saisie a la suite afin que l’utilisateur puisse rentrer toutes les données du nouveau Pokémon. Voici a quoi ressemble un des champs de saisie:

#champ de saisie nom fr
    nom_pokemon_label = Label(fcreate, text="Entrez le nom du nouveau Pokémon", font=("Arial", 10), bg="red")
    nom_pokemon_label.pack(pady=10)
    nom_pokemon_entry = Entry(fcreate, bg="white")
    nom_pokemon_entry.pack(pady=10)

La variable ‘nom_pokemon_label’ sert a configurer la zone de texte qui permet de savoir a quoi sert le champ de saisie. La fonction Label sert a créer et modifier le style d’une zone de texte et ici, le texte au dessus du champ de saisie. La variable ‘nom_pokemon_entry’ sert a créer le champ de saisie et modifier son apparence. Les deux variables sont appelées avec la fonction pack() qui fait apparaitre les éléments graphiques.

Après avoir fait tout les champs de saisie de chacune des données, on a créé un bouton sauvegarde afin d’enregistrer les nouvelles données dans le fichier.

Dans la partie sql, on a donc d’abord créé une fonction enregistrer() qui prend en paramètre tout les noms de données afin d’enregistrer chaque valeur. Ensuite, nous avons créé la variable ‘nv_ligne’. Avec la commande DataFrame de panda, elle crée une nouvelle ligne en prenant en compte les colonnes du fichier excel. Avec a commande concat, elle enregistre les données en fonction du type de donnée dans chacune des colonnes de la nouvelle ligne. Le ignore_index sert a ne pas prendre en compte les id d’origines.

#création de la ligne du nv pokemon
    nv_ligne = pd.DataFrame([[idtf, nom_pokemon, nom_anglais, type_pokemon, type_secondaire, pv, attaque, defense]], columns=excel_data.columns)
#enregistrer les données dans la nouvelle ligne
    excel_data = pd.concat([excel_data, nv_ligne], ignore_index=True)

Comme a la fin de chaque fenêtre, nous utilisons destroy() pour ne pas accumuler les fenêtres. Donc, après avoir appuyé sur le bouton sauvegarde, la fenêtre se ferme mais un print sur la console d’exécution nous montre que le pokemon a été enregistré.

La fonction update

Nous avons utilisé a peu près le même fonctionnement pour les autres fonctions: une fonction qui crée la fenêtre avec la bibliothèque de tkinter et une autre qui modifie et enregistre les données de la base de données avec les bibliothèques de panda et sqlite3.

Donc, nous avons commencé par une fonction update qui génère la fenètre et son apparence. Nous avons choisis, pour modifier les données de créer d’abord un champ de saisie pour rentrer le nom Français du pokemon a modifier, puis une Combobox ( comme un champ de saisie mais ou on sélectionne la donnée dans une liste) afin de sélectionner la donnée a modifier, puis, un autre champ de saisie pour donc modifier le contenu de la donnée. Nous avons aussi ajouté un bouton sauvegarder qui utilise la fonction update_data qui prend en paramètre chaque variable utilisée par les champ de saisie et la combobox.

#champ de saisie pokemon a modifier
    userlbl = Label(fupdate, text="Entrez le nom du pokémon que vous voulez modifier", font=("Arial", 12), bg="red")
    userlbl.pack(pady=10)
    nom_pokemon = Entry(fupdate, bg="white")
    nom_pokemon.pack(pady=10)
#combobox type de donnée a modif
    liste_donnees = ["Indice", "Nom français", "Nom anglais", "Type", "Type secondaire", "PV", "Attaque", "Défense"]
    comboboxlbl = Label(fupdate, text="Choisissez le type de donnée à modifier", font=("Arial", 12), bg="red")
    comboboxlbl.pack(pady=10)
    listeCombo = ttk.Combobox(fupdate, values=liste_donnees)
    listeCombo.pack(pady=10)
 #cds nv donnée
    userlbl = Label(fupdate, text="Entrez la nouvelle donnée", font=("Arial", 12), bg="red")
    userlbl.pack(pady=10)
    nv_donnée_entry = Entry(fupdate, bg="white")
    nv_donnée_entry.pack(pady=10)

Les champs de saisies sont les même que ceux de la fonction ajouter. Pour la Combobox, c’est le meme principe sauf qu’il faut ajouter une liste avant ou on a rentré les différents types de données et qu’on appelle dans la variable listeCombo avec ‘values’.

Pour la sauvegarde, on a utilisé une fonction update_data() qui prend en paramètre le nom du pokémon a modifier, le type de donnée a modifier et la nouvelle valeur. Pour mettre a jour les données, on a du écrire un enchainement de elif car il faut que l’utilisateur puisse modifier chaque donnée et que donc le code est différent pour chaque donnée.

#maj des données
    if type_donnee == "Indice":
        excel_data.loc[excel_data['Nom français'] == nom_pokemon, 'Indice'] = nv_val
    elif type_donnee == "Nom français":
        excel_data.loc[excel_data['Nom français'] == nom_pokemon, 'Nom français'] = nv_val
    elif type_donnee == "Nom anglais":
        excel_data.loc[excel_data['Nom français'] == nom_pokemon, 'Nom anglais'] = nv_val
    elif type_donnee == "Type":
        excel_data.loc[excel_data['Nom français'] == nom_pokemon, 'Type'] = nv_val
    elif type_donnee == "Type secondaire":
        excel_data.loc[excel_data['Nom français'] == nom_pokemon, 'Type secondaire'] = nv_val
    elif type_donnee == "PV":
        excel_data.loc[excel_data['Nom français'] == nom_pokemon, 'PV'] = nv_val
    elif type_donnee == "Attaque":
        excel_data.loc[excel_data['Nom français'] == nom_pokemon, 'Attaque'] = nv_val
    elif type_donnee == "Défense":
        excel_data.loc[excel_data['Nom français'] == nom_pokemon, 'Défense'] = nv_val
       

A chaque fois on commence avec une vérification pour savoir quel est le type de donnée, puis, avec la fonction loc(), on cherche dans le fichier d’abord le pokémon avec son nom Français, puis on trouve le type de donnée a modifier et on le remplace par la nouvelle valeur. Les données sont ensuite enregistrées dans la base de donnée avec ‘excel_data.to_excel’ comme dans les autres fonctions, la fenêtre et détruite un print affiche que les données ont bien été modifiées.

La fonction delete

Pour la suppression d’un pokemon nous avons utilisé trois fonctions. Dans la première, ont créé la fenêtre et on y ajoute un champ de saisi. En effet, on a seulement besoin du nom du Pokemon puisqu’il s’agit de supprimer toutes les données de ce Pokémon a partir de son nom. Les deux autres fonctions sont liées puisque la première, pokemon_supp() sert a trouver le nom du pokemon qui correspond et utiliser la deuxième fonction suppression() qui met a jour la base de donnée avec ‘to_excel’.

def pokemon_supp(supp_entry):
    #enregistre le nom rentré
    nom_pokemon = supp_entry.get()
    #supprime de la base
    suppression(nom_pokemon)

def suppression(nom_pokemon):
    #connecte le xlsx
    excel_data = pd.read_excel("base de donnée.xlsx")
     # remplace par le nom de la collone du nom
    excel_data = excel_data[excel_data['Nom français'] != nom_pokemon]
    # recrée le exel sans le pokemon
    excel_data.to_excel("base de donnée.xlsx", index=False)

La méthode .get() sert a utiliser une variable avec entry, donc ici la variable du champ de saisie. Dans la fonction suppression(), on connecte d’abord les données du fichier grâce au ‘read_excel’ de panda, puis on sélectionne toutes les lignes du fichier sauf celle du pokémon sélectionné et on recrée la base de donnée avec.

Conclusion

En résumé, ce projet d’interface graphique en Python pour la gestion d’une base de données a été une expérience enrichissante. Nous avons exploré la création d’une fenêtre comportant des boutons, chacun dédié à une fonctionnalité spécifique. Nous avons également mis en place une zone de champs de texte pour manipuler les données à l’intérieur. Bien que cela ait été complexe, cette expérience nous a permis d’approfondir nos connaissances en programmation Python.

Merci d’avoir lu notre article, voici la base de donnée et le script a télécharger.

Tutoriels

Gérer l’espace de stockage sur son IPhone

Vous avez surement déja du faire face au problème du manque d’espace de stockage sur votre IPhone. L’espace de stockage est défini sur l’appareil Apple en question qu’il soit un Iphone, un IPad ou un Mac, a ne pas confondre avec le stockage ICloud qui correspond au stockage des photos, des fichiers ou d’autres documents disponibles sur tout vos appareils.

A force d’utiliser notre téléphone, nous emmagasinons les photos, les téléchargements et les messages qui se stockent dans l’espace de stockage. Au bout d’un moment, lorsque le stockage se rapproche de sa capacité maximale, on recoit des notifications de prévention. Ces notifications parviennent de plus en plus fréquemment et le smartphone commence a moins bien fonctionner. Il peut y avoir des bugs ou des latences.

C’est a ce moment la qu’il faut vider son espace de stockage, c’est a dire, se débarasser des documents encombrants qu’on a accumulé.

Dans ce tutoriel, je vais donc vous expliquer comment optimiser et gérer son espace de stockage sur un IPhone.

Introduction

Pour commencer a libérer de l’espace, il faut savoir quels éléments l’occupent. Pour ce faire, il faut aller dans l’application « réglages », puis « général », puis, « stockage IPhone ». Vous arrivez sur une page d’information concernant votre occupation de l’espace de stockage.

Les pièces jointes

Juste en dessous du schéma représantant l’espace de stockage, il y a un onglet « Recommandations » qui peut apparaitre. Il indique par ou commencer quand il faut vider l’espace de stockage, la par exemple, il propose de vider les pièces jointes envoyées ou recues par message. En effet, elles ne sont pas forcément visibles dans la galerie mais peuvent prendre une place importante dans les messages.

Effacer des applications

En dessous de l’onglet « recommandations », vous verrez la liste de vos applications prenant le plus de place jusqu’a celle qui vous en consomme le moins. Vous avez donc une idée de quelles applications vous pouvez supprimer et qui ne vous manqueront pas.

Malheuresement, ce sont les applications qui consomment le moins d’espaces, il faut donc examiner celles qui en consomment le plus. Ce sont souvent les photos, les boites mails, les réseaux sociaux et les applications de streaming.

L’application Photos

Il n’y a pas beaucoup de solutions concernant les photos a part les enregistrer sur votre Cloud, pour ce faire, retournez dans les réglages, appuyez sur votre nom tout en haut, puis « ICloud », sélectionnez « Sauvegarde ICloud » afin de sauvegarder vos photos sur votre Cloud ou « Gérer votre forfait » si le votre n’est pas suffisant.

Sélectionnez ensuite « Photos ICloud » puis « Télécharger et garder les originaux » qui optimisera la qualité des photos et prendra un espace minimum.

Le mieux a faire est en suite de supprimer les photos que vous avez en doublons ou inutiles ou supprimer les vidéos trop longues. N’oubliez pas également de tout supprimer dans vos photos et vidéos supprimées récemment qui prennent encore de la place.

Les applications de streaming

Dans les applications de streaming, ce qui prend le plus de place c’est les téléchargements. Vous avez peut etre sur des applications de streaming de musique par exemple téléchargé des playlists entières ou des albums que vous n’écoutez plus. Il faut donc penser a les enlever des téléchargements.

C’est exactement la meme chose sur les applications de streaming de films et de séries. Pensez a retirer des téléchargements les contenus que vous avez déja regardé afin de libérer de l’espace.

Sur les réseaux sociaux

Pour les réseaux sociaux comme Instagram, Snapchat et Tiktok, on ne veut pas toujours supprimer ses publications qui prennent de l’espace. Heureusement, il existe d’autres alternatives. Vous pouvez par exemple supprimer des anciennes conversations et surtout des anciens groupes, supprimer ses historiques quels qu’ils soient ou encore supprimer des fichiers multimédias comme des photos ou des vidéos.

Pour d’autres réseaux sociaux comme Whatsapp, une appliation qui accumule les pièces jointes et peut très vite prendre beaucoup d’espace, il faut aller dans les réglages de l’Iphone, puis, sélectionner « Gérer le stockage ». Vous pourrez donc trier et supprimer assez d’élements pour mettre fin a ce problème de manque d’espace.

Les boites mails

Les boites mails présente le meme problème que Whatsapp, de plus, elles accumulent également tout les brouillons, les spams et les mails non supprimés. Vous pouvez par exemple supprimer votre boite mail principale si vous y avez accès régulièrement sur un ordinateur, sinon, allez sur votre boite mail et supprimez les messages les plus volumineux, les spams et les mails dans la corbeille.

J’espere vous avoir aidé avec ces idées pour libérer le stockage de votre IPhone, la meilleure solution reste de placer tout ses documents sur son Cloud. Le manque d’espace de stockage peut etre très handicapant dans le fonctionnement du téléphone, je vous conseille donc de faire du tri le plus souvent possible.

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 !