Partage
  • Partager sur Facebook
  • Partager sur Twitter

Voir l'avancement d'une boucle

Sujet résolu
    25 mai 2015 à 18:50:57

    Bonjour,

    J'ai crée une boucle du type: for i in range (1,10000):

    avec de bons gros calculs au milieu à l'intérieur. Ca doit faire maintenant 5 minutes que j'attends et ce n'est toujours pas terminé. Y'a pas moyen de savoir "en direct" la valeur de "i", pour savoir où en est ma boucle?

    Je précise que j'utilise Spyder (Python 2.7)!

    Merci :)

    -
    Edité par Jarka 25 mai 2015 à 18:51:45

    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      25 mai 2015 à 19:51:16

      Voici quelque chose qui pourrait t'intéresser:

      https://github.com/coagulant/progressbar-python3

      Tu as des exemples, et tout le code du module :)

      -
      Edité par Anonyme 25 mai 2015 à 20:06:14

      • Partager sur Facebook
      • Partager sur Twitter
        25 mai 2015 à 19:56:49

        Es-tu absolument certain que ce n'est pas une boucle infinie ?

        Sinon, un simple :

        print(i,"\n")

        devrait faire l'affaire (mais cela ralentit cependant la vitesse d’exécution)

        Enfin, c'est ce que j'ai compris du problème, si ce n'est pas ça, n'hésite pas ^^

        • Partager sur Facebook
        • Partager sur Twitter
          25 mai 2015 à 20:41:39

          Nelimee a écrit:

          Voici quelque chose qui pourrait t'intéresser:

          https://github.com/coagulant/progressbar-python3

          Tu as des exemples, et tout le code du module :)

          -
          Edité par Nelimee il y a 30 minutes


          Merci mais c'est pour Python 3 d'après ce que je lis, ça fonctionnera quand même en Python 2.7?

          BunshinKage: Noncar depuis que j'ai crée le topic j'ai eu le temps de laisser mon calcul s’exécuter, il prend fin généralement au bout de 10 à 15 minutes... C'est un peu barbant à la longue car je dois refaire l’expérience plusieurs fois en changeant les variables qui entrent en jeu. Mon dual core a l'air de cracher ses poumons.

          Sinon c'est vrai que c'est tout bête pour le i, je vais faire ça!

          -
          Edité par Jarka 25 mai 2015 à 20:44:16

          • Partager sur Facebook
          • Partager sur Twitter
          Anonyme
            25 mai 2015 à 21:20:23

            Jarkamit a écrit:

            Nelimee a écrit:

            Voici quelque chose qui pourrait t'intéresser:

            https://github.com/coagulant/progressbar-python3

            Tu as des exemples, et tout le code du module :)

            -
            Edité par Nelimee il y a 30 minutes


            Merci mais c'est pour Python 3 d'après ce que je lis, ça fonctionnera quand même en Python 2.7?


            Google.fr -> 'progressbar python' -> Résultat 1, Résultat 2. Le lien que je t'ai donné a été fait par une personne qui avait besoin de la compatibilité Python3.

            PS: Dois-je apprendre Python 2 ou Python 3?

            PS2: Pour éviter d'avoir 10.000 (ou plus) lignes qui vont s'afficher dans ta console (et qui en plus vont te bouffer pas mal de performances mine de rien), je préfère (c'est personnel, à toi de voir) mon print dans un if, comme ceci:

            for i in range(10**8):
            
                # Calcul complexe
            
                # Equivalent à (i % 2**10) = (i % 1024)
                if not i & 0b11111111111:
                    print(i)

            ou avec un modulo classique, c'est à toi de voir :)



            -
            Edité par Anonyme 25 mai 2015 à 21:29:38

            • Partager sur Facebook
            • Partager sur Twitter
              25 mai 2015 à 21:37:08

              Ouais j'ai gardé la solution avec modulo finalement, merci à vous :)
              • Partager sur Facebook
              • Partager sur Twitter
                25 mai 2015 à 23:00:57

                Pendant qu'on aborde le sujet, je me suis toujours demandé quelque chose quant à ces solutions...

                Le but est (en plus de ne pas avoir 10000 lignes dans la console évidemment) de n'afficher i que lorsqu'il est divisible par 100. Dans ce cas, un test est nécessaire, et ce à chaque fois.

                Donc théoriquement, ça met le même temps à s'exécuter, ce qui est dommage. Personne n'aurait une idée algorithmique pour pallier à ce problème ?

                • Partager sur Facebook
                • Partager sur Twitter
                Anonyme
                  25 mai 2015 à 23:20:36

                  BunshinKage a écrit:

                  Pendant qu'on aborde le sujet, je me suis toujours demandé quelque chose quant à ces solutions...

                  Le but est (en plus de ne pas avoir 10000 lignes dans la console évidemment) de n'afficher i que lorsqu'il est divisible par 100. Dans ce cas, un test est nécessaire, et ce à chaque fois.

                  Donc théoriquement, ça met le même temps à s'exécuter, ce qui est dommage. Personne n'aurait une idée algorithmique pour pallier à ce problème ?


                  Un rapide

                  In [1]: %timeit [(2**20)%i for i in range(1, 100000)]
                  10 loops, best of 3: 23.3 ms per loop
                  
                  In [2]: %timeit [(2**20)%i for i in range(100000, 1000001)]
                  1 loops, best of 3: 229 ms per loop
                  

                  et un calcul te montrent que l'opération % (même sur des très grands nombres) est très performante. Ici, on a un % qui prends environ 233 nano-secondes (pour le premier temps) ou environ 254 nano-secondes (pour le second temps).

                  Même si tu fais une boucle de 1.000.000 opérations tu ne perds pas énormément de temps (<0.3s non?).

                  Sinon tu peux toujours te rabattre sur les opérateurs binaires, qui sont plus rapides. Les opérateurs logiques aussi seront un peu plus rapides:

                  if i == 0: #~75ns
                      pass
                  # Plus lent que:
                  if not i:  #~57ns
                      pass


                  Enfin, tu peux faire ça:

                  for i in range(1000):
                      for j in range(1000):
                          # Opérations
                          # Les indices deviennent 1000*i+j
                      print(i)

                  mais:

                  • C'est lourd sur les indices, de devoir se taper tout le temps un '1000*i+j' au lieu d'un simple 'i'
                  • C'est pas clair comme code, on voit mal ce que tu veux faire
                  • C'est pas bien maintenable
                  • Bref, c'est pas mal solution préférée ^^
                  • Partager sur Facebook
                  • Partager sur Twitter
                    26 mai 2015 à 1:37:33

                    Ah, la deuxième solution m'intéresse beaucoup, merci ! :D
                    • Partager sur Facebook
                    • Partager sur Twitter
                    Anonyme
                      26 mai 2015 à 11:54:13

                      Au final la seconde solution n'est vraiment pas meilleure, sur tous les points.

                      J'ai lancé:

                      from time import time
                      from statistics import mean
                      
                      A = range(1024**2)
                      B = range(1024)
                      C = range(1024)
                      
                      REPEAT = 10
                      
                      times = []
                      for r in range(REPEAT):
                          t = time()
                          for i in A:
                              k = i**2
                              if i%1024 == 0:
                                  print(i, "\r", end='', sep='')
                          times.append(time()-t)
                          
                      print("i%1024==0:", mean(times), min(times))
                      
                      times = []
                      for r in range(REPEAT):
                          t = time()
                          for i in A:
                              k = i**2
                              if not i%1024:
                                  print(i, "\r", end='', sep='')
                          times.append(time()-t)
                      print("not i%1024:", mean(times), min(times))
                      
                      times = []
                      for r in range(REPEAT):
                          t = time()
                          for i in A:
                              k = i**2
                              if not i&0b11111111111:
                                  print(i, "\r", end='', sep='')
                          times.append(time()-t)
                      print("not i&0b11111111111:", mean(times), min(times))
                      
                      times = []
                      for r in range(REPEAT):
                          t = time()
                          for i in B:
                              for j in C:
                                  k = (i*1024 + j)**2
                              print(i, "\r", end='', sep='')
                          times.append(time()-t)
                      print("Double for imbriqué:", mean(times), min(times))
                      

                      Les '\r', end='', sep='') à la fin du print servent à ne pas encombrer l'écran avec tout plein de lignes de texte.

                      Et voici le résultat:

                      i%1024==0: 0.7044766902923584 0.6842665672302246
                      not i%1024: 0.6794845342636109 0.6753804683685303
                      not i&0b11111111111: 0.6257542848587037 0.6193525791168213
                      Double for imbriqué: 0.6808295965194702 0.6769440174102783
                      

                      Donc au final tu ne gagne pas de performance avec un double for imbriqué, au contraire. Mais bon c'est un perte un peu anecdotique quand même :)




                      • Partager sur Facebook
                      • Partager sur Twitter
                        26 mai 2015 à 19:32:37

                        L'avantage du double for étant tout de même de pouvoir s'utiliser dans d'autres langages de progammation ^^

                        Merci beaucoup en tout cas !

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Anonyme
                          26 mai 2015 à 20:42:24

                          BunshinKage a écrit:

                          L'avantage du double for étant tout de même de pouvoir s'utiliser dans d'autres langages de progammation ^^

                          Merci beaucoup en tout cas !


                          Trouve moi un langage de programmation qui n'implémente pas le modulo (%), l'égalité entre deux entiers (==), les conditionnements (if - else), les opérateurs bit-à-bit (ça j'en suis moins sûr, mais bon tout langage hérité du C les a normalement), ou la négation (not en Python, ! en C). Enfin bon, c'est futile comme débat, chacun ses goûts et on ne discute pas des goûts et des couleurs :)

                          PS: Jarkamit, pense à passer le sujet en résolu si ton problème est résolu.

                          • Partager sur Facebook
                          • Partager sur Twitter
                            27 mai 2015 à 0:08:43

                            Nelimee a écrit:

                            BunshinKage a écrit:

                            L'avantage du double for étant tout de même de pouvoir s'utiliser dans d'autres langages de progammation ^^

                            Merci beaucoup en tout cas !


                            Trouve moi un langage de programmation qui n'implémente pas le modulo (%), l'égalité entre deux entiers (==), les conditionnements (if - else), les opérateurs bit-à-bit (ça j'en suis moins sûr, mais bon tout langage hérité du C les a normalement), ou la négation (not en Python, ! en C). Enfin bon, c'est futile comme débat, chacun ses goûts et on ne discute pas des goûts et des couleurs :)

                            PS: Jarkamit, pense à passer le sujet en résolu si ton problème est résolu.

                            La fonction modulo du Basic Casio bloque à partir d'un certain nombre.

                            L'égalité entre deux entiers peut-être imprécise parfois lorsqu'on traite avec des grands nombres.

                            Bon, un langage de prog sans if-else, la pour le coup, ...

                            Les opérateurs bit-à-bit, n'y pense même pas non plus, et la négation n'existe pas :p

                            Après, on a pas les mêmes besoins, ça influe aussi ^^

                            Après, pour la futilité du débat, je suis à la fois d'accord et pas d'accord. Ouais bon, ça sert pas à grand chose mais c'est intéressant en tout cas :)

                            -
                            Edité par BunshinKage 27 mai 2015 à 0:09:32

                            • Partager sur Facebook
                            • Partager sur Twitter

                            Voir l'avancement d'une boucle

                            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                            • Editeur
                            • Markdown