Peut -on faire avec python ce qu'on fait avec basic ?

Bonjour,
bref je sais déja que la réponse est vrai , ma vrai question est d'ou commencer ?
j'ai un code basic qui donne la propagation d'une fissure , il calcule la distance minimale, puis tu initialise une fissure sur un écran qui s'affiche , et à chaque fois tu cliques sur un bouton , il te montre la l'evolution de la fissure .

Configuration: Windows / Chrome 102.0.0.0

13 réponses

Résumé de la discussion

On cherche à démarrer une simulation de propagation d'une fissure en Python et à choisir une approche graphique entre Tkinter et un canevas adapté au suivi des points et des pixels. Plusieurs recommandations indiquent que Tkinter n'est pas idéal pour le pixel-level et recommandent d'utiliser un canevas avec des petits points ou des tableaux coordonnés pré-calculés. Des questions techniques reviennent sur la signification de iid dans for iid in canvas.find_overlapping(*point_coord): et sur la possibilité d'appliquer la récupération de coordonnées à tout point du canvas, pas seulement sur des cercles. D'autres conseils soulignent que le travail sur les pixels peut être long et privilégient l'utilisation de tableaux coordonnés, comme dans le code Basic, pour gagner en performance et clarté.

Bobot (l’IA à votre service)
  1. Bonjour,

    Bien sur, ce que tu fais en Basic, on peut évidemment le faire en Python ...

    Et pour commencer, il faut se former à Python
    1. je sais déjà les bases de python , je veux juste savoir quel libraries je dois utiliser ou bien quoi chercher exactement pour me former
      1. Pour savoir quelles bibliothèques (library = bibliothèque en anglais) importer dans ton code Python, il faudrait savoir celles dont tu as besoin, donc de voir ce que fais exactement ton code Basic ...

        Exemples :
        je veux faire une interface graphique, j'importe la bibliothèque Tkinter (basique, mais bon ...)
        Je veux faire des calculs, j'importe la bibliothèque math
        etc ...
        1. https://www.mediafire.com/file/2iprx9i48t333rn/propag-fissure.zip/file
          Voici le lien du code Basic que je veux transcrire en python, pour voir le code, il faut l'ouvrir avec un éditeur de code comme Notepad ou changer l'extension de: ".bas" en: "txt" et l'ouvrir avec le bloc note
          je comprends bien comment il fonctionne et tout et j'aimerais le transcrire en python
          toute aide serait énormément apprécié
          1. Bonjour,

            Diable ! C'est ce truc-là ?
            J'ai fait du Basic dans le temps, mais là, j'avoue que je ne comprends pas tout :

               nomainwin
                mapw=800: maph= 520
                WindowWidth=mapw+15: WindowHeight=maph+40
                UpperLeftX = 10: UpperLeftY = 5
                BUTTON #w.n1, "Go !", [go], UL, 420, 480, 40, 25
                BUTTON #w.ag, "Again!", [ag], UL, 510, 480, 40, 25
               GRAPHICBOX #w.g, 5, 5, mapw, maph
                OPEN "Help" FOR window_nf AS #w
                #w, "TRAPCLOSE [closeHelp]"
                #w.g, "when leftButtonDown [point]"
                #w.g, "down;fill darkgray;color black;backcolor darkgray"
                #w.g, "font courrier 12 bold"
                #w.g, "place 20 15": #w.g, "\ Les taches claires sont des lacunes"
                #w.g, "place 20 490": #w.g, "\ Clic gauche et tracer de bas en haut sur 2 cm et--->"
                #w.g, "place 455 490": #w.g, "\  et--->"
                dim tagx(805), tagy(505)
                dim pointx(805), pointy(505)
                #w.g, "color lightgray;backcolor darkgray"
                n=60: #w.ag, "!disable"
                for x=1 to n
                   px=int(rnd(1)*790)+1: py=int(rnd(1)*470)+1
                   [ret]
                   siz=int(rnd(1)*20)+1
                   if siz < 5 then [ret]
                   #w.g, "size ";siz: #w.g, "set ";px;" ";py
                    pointx(x)=px: pointy(x)=py
                next x
                #w.g, "flush"
              wait
              [point]
                #w.g, "when leftButtonMove [trace]"
              wait
              [trace]
                mx=MouseX: my=MouseY
                #w.g, "color yellow;backcolor darkgray"
                #w.g, "place ";mx;" ";my: #w.g, "size  2;set"
              wait
              [go]
                g=1: #w.ag, "!enable"
               ' minDist=1e10   'overly big
                minDist=10000
                    for k = 1 to n
                      if pointy(k)<my then
                        dist = sqr((pointx(k)-mx)^2+(pointy(k)-my)^2)
                         if dist < minDist then
                            minDist= dist
                            tagx=pointx(k): tagy=pointy(k)
                         end if
                      end if
                  next k
                #w.g, "color red;backcolor darkgray"
                  #w.g, "size 5": #w.g, "set ";tagx;" ";tagy
                  '------------
                #w.g, "color yellow;backcolor darkgray; size 2"
                #w.g, "goto ";mx;" ";my'
              wait
              [ag]
                mx=tagx: my=tagy: #w.n1, "!disable"
                goto [go]
              wait
              [closeHelp]
                CLOSE  #w
                END


            Ca doit pouvoir se faire, avec une interface graphique (Tkinter)
            Il y a tout ce qu'il faut pour détecter les clics et les mouvements de souris
            1. bref, en gros ce code définit un nombre n de lacunes en des coordonnées aléatoires et avec des diamètres aléatoires mais inférieur à 5, puis on trace la fissure par la souris puis à partir du dernier point cliqué par la souris(de coordonnées mx et my) il parcourt les lacunes de 1 à n , et calcule les distances entre point du départ(mx,my) et le nouveau point, et le point choisi sera celui avec la distance minimale .
              j'ai besoin de l'aide juste pour commencer et faire tourner la roue
              1. Bonjour, faire tourner la roue ? J'ai rapidement lancé ton programme avec wine sur linux, et tout ce que je vois est quelques cercles sur un écran rempli d'une couleur, on peut via la souris tracer des lignes de points, et avec les boutons, faire des « liaisons » pour lier avec certaines distances les points, seulement, j'ai remarqué, que ça remonte vers le haut, chaque fois.

                Enfin, comme dit plus haut, un canvas tkinter pourra aboutir à faire cette toute petite interface, si tu as des bases en python, tu ne devrais pas trop avoir de mal à l'utiliser.
            2. Au vu de ça: "if siz < 5 then [ret]" c'est plutôt supérieur à 5, car si inférieur on refait un tirage ("ret" abréviation de retourne ?)
              1. Voici le code que j'ai crée jusqu'à maintenant :
                import random
                from tkinter import *
                
                window = Tk()
                window.geometry("400x400")
                window.config(bg = "white")
                window.title("Canvas - Draw Line")
                window.resizable(False, False)
                
                # Creating Canvas
                canvasScreen = Canvas(window, width = 350, height = 350, bg = "gray")
                canvasScreen.pack(pady=20)
                
                # Création de granulats
                canvasScreen.create_rectangle(10, 10, 50, 50, fill="red", outline="blue")
                canvasScreen.create_rectangle(40, 80, 90, 130, fill="red", outline="blue")
                canvasScreen.create_rectangle(200, 20, 250, 70, fill="red", outline="blue")
                canvasScreen.create_rectangle(250, 180, 300, 230, fill="red", outline="blue")
                canvasScreen.create_rectangle(60, 250, 110, 300, fill="red", outline="blue")
                canvasScreen.create_rectangle(230, 280, 270, 320, fill="red", outline="blue")
                canvasScreen.create_rectangle(125, 125, 175, 175, fill="red", outline="blue")
                
                # Paramètres de la pointe de fissure
                x=random.randint(0, 50)
                y=random.randint(0, 50)
                window.mainloop()


                J'ai uniquement posé le canvas (structure du béton), les polygones (granulats du béton) et j'ai posé un point de départ de la fissure aléatoirement. Maintenant, je veux parcourir tous les points dans le canvas.
                1. Contributeur
                  Peux-tu utiliser les balises de code quand tu partages du code?

                  Il me semble que tu n'as créé aucun "point" dans le canvas. Qu'appelles-tu un "point"? Combien en veux-tu?
              2. pour moi un point est chaque petit point du canvas comme si on va discrétiser le canvas
                1. Contributeur
                  Si tu veux travailler avec des pixels, je pense que tkinter n'est pas la bonne solution.
                  Tu peux créer des petits points dans un canevas, mais peut-être pas assez pour ce que tu souhaites.
              3. comment travailler avec les pixels donc ?
                1. Travailler avec les pixels sera forcément plus long (beaucoup), car tu devras parcourir toute la matrice (et Python n'a pas la rapidité du C).
                  Il est plus pertinent de travailler avec un (ou des) tableaux contenant les coordonnées de ce que tu affiche, comme il est fait dans le code Basic montré.
                  Reposte ton code en utilisant les balises (5ème icône du bandeau supérieur, poste le code entre les balises).
              4. nomainwin
                    mapw=800: maph= 520
                    WindowWidth=mapw+15: WindowHeight=maph+40
                    UpperLeftX = 10: UpperLeftY = 5
                    BUTTON #w.n1, "Go !", [go], UL, 420, 480, 40, 25
                    BUTTON #w.ag, "Again!", [ag], UL, 510, 480, 40, 25
                   GRAPHICBOX #w.g, 5, 5, mapw, maph
                    OPEN "Help" FOR window_nf AS #w
                    #w, "TRAPCLOSE [closeHelp]"
                    #w.g, "when leftButtonDown [point]"
                    #w.g, "down;fill darkgray;color black;backcolor darkgray"
                    #w.g, "font courrier 12 bold"
                    #w.g, "place 20 15": #w.g, "\ Les taches claires sont des lacunes"
                    #w.g, "place 20 490": #w.g, "\ Clic gauche et tracer de bas en haut sur 2 cm et--->"
                    #w.g, "place 455 490": #w.g, "\  et--->"
                    dim tagx(805), tagy(505)
                    dim pointx(805), pointy(505)
                    #w.g, "color lightgray;backcolor darkgray"
                    n=80: #w.ag, "!disable"
                    for x=1 to n
                       px=int(rnd(1)*790)+1: py=int(rnd(1)*470)+1
                       [ret]
                       siz=int(rnd(1)*20)+1
                       if siz < 5 then [ret]
                       #w.g, "size ";siz: #w.g, "set ";px;" ";py
                        pointx(x)=px: pointy(x)=py
                    next x
                    #w.g, "flush"
                  wait
                  [point]
                    #w.g, "when leftButtonMove [trace]"
                  wait
                  [trace]
                    mx=MouseX: my=MouseY
                    #w.g, "color yellow;backcolor darkgray"
                    #w.g, "place ";mx;" ";my: #w.g, "size  2;set"
                  wait
                  [go]
                    g=1: #w.ag, "!enable"
                   ' minDist=1e10   'overly big
                    minDist=10000
                        for k = 1 to n
                          if pointy(k)<my then
                            dist = sqr((pointx(k)-mx)^2+(pointy(k)-my)^2)
                             if dist < minDist then
                                minDist= dist
                                tagx=pointx(k): tagy=pointy(k)
                             end if
                          end if
                      next k
                    #w.g, "color red;backcolor darkgray"
                      #w.g, "size 5": #w.g, "set ";tagx;" ";tagy
                      '------------
                    #w.g, "color yellow;backcolor darkgray; size 2"
                    #w.g, "goto ";mx;" ";my'
                  wait
                  [ag]
                    mx=tagx: my=tagy: #w.n1, "!disable"
                    goto [go]
                  wait
                  [closeHelp]
                    CLOSE  #w
                    END
                
                
                1. Bonjour,

                  Cà, c'est ce que j'avais déjà fait hier à 16h20 ...
                2. Je n'y connais rien en basic, mais j'arrive malgré tout à comprendre un peu la logique du code par déduction.

                  Je te montre un simple exemple de quelques lignes de python permettant déjà d'obtenir à peu près la même chose à l'écran.

                  import tkinter as tk
                  import random
                  
                  def circles_draw(canvas, w, h, number, dist_min):
                      i = 0
                      dm = dist_min
                      while i < number:
                          x = random.randrange(dist_min, w)
                          y = random.randrange(dist_min, h)
                          size = random.randint(5, 20)
                          extended_coords = (x - dm, y - dm, x + size + dm, y + size + dm)
                          if canvas.find_overlapping(*extended_coords):
                              # Si les coordonnées choisies empiètent sur un cercle déjà tracé
                              # alors on passe au tour suivant pour choisir d'autres valeurs
                              continue
                          canvas.create_oval(
                              x, y, x + size, y + size, fill='lightGrey',
                              outline='lightGrey', tags='circle',
                          )
                          i += 1
                  
                  
                  def onclick_left(evt, canvas):
                      # print(dir(evt))
                      point_coord = (evt.x, evt.y, evt.x, evt.y)
                      for iid in canvas.find_overlapping(*point_coord):
                          if 'circle' in canvas.itemcget(iid, 'tags'):
                              print('clic sur un cercle !')
                              print(f'sur le point {evt.x} {evt.y}')
                  
                  
                  window = tk.Tk()
                  window.title("Canvas - Draw Line")
                  window.resizable(0, 0)
                  can = tk.Canvas(window, width=800, height=520, bg='darkGrey')
                  can.grid()
                  
                  # distance entre les cercles ainsi que des bords du canvas
                  dist_min = 5
                  circles_draw(can, 800 - dist_min * 2, 520 - dist_min * 2, 60, dist_min)
                  
                  can.focus_set()
                  can.bind('<Button-1>', lambda evt: onclick_left(evt, can))
                  
                  window.mainloop()


                  Il y a en bonus une fonction pour que tu voies comment on récupère la coordonnée du point cliqué, ce qui va te servir pour tracer les lignes avec la souris, à toi de faire cela, reste aussi à faire tes boutons et récupérer le tout petit algo permettant de relier automatiquement les cercles.

                  Tu as donc encore du boulot, et pour ça, il faut un peu expérimenter les possibilités de tkinter, donc potasser un peu la doc, pdf dispo en ligne.

                  Bon courage.
              5. pour la fonction qui récupère la coordonnée, est-ce-qu'on ne peut pas l'appliquer a tout point du canvas ?
                1. Ben oui, là j'ai simplement voulu montrer comment faire pour savoir si on a cliqué sur un cercle, enlève la condition et tu auras le print sur n'importe quel point cliqué., Teste, triture ce code comme bon te semble ^^
                2. @merle_rigoloj'ai supprimé la condition if 'circle' in canvas.itemcget(iid, 'tags'): , mais rien ne change
                3. @merle_rigoloet une autre question svp,dans cette boucle for iid in canvas.find_overlapping(*point_coord): , c'est quoi le iid ?
                4. Contributeur
                  @eva43_7781le iid ici a le même rôle que x dans l'instruction basic
                  for x=1 to n
                  , c'est l'indice de boucle.
                5. Contributeur
                  @eva43_7781Tu avais écrit "je sais déjà les bases de python".
                  Je pense que tu devrais d'abord réellement te former en Python.