Je veux afficher la progression en Python!

Aperçu

Lorsque vous exécutez un processus qui prend beaucoup de temps, s'il n'y a pas de réponse, vous inquiétez-vous de "jusqu'où le processus progresse" ou "est-ce qu'il fonctionne?" Il y a, non? Oui, il y a (utilisation en 3 étapes). Je vais donc noter comment afficher la progression du traitement de la boucle.

↓ ↓ ↓ Au fait, ça ressemble à ça ↓ ↓ ↓ progress_DB.gif Si vous le trouvez utile, je vous serais reconnaissant de bien vouloir commenter le stock LGTM.

table des matières

Utilisation du package tqdm

Tout d'abord, je voudrais vous présenter tqdm, la voie royale de l'affichage du progrès (je pense que c'est égoïste). C'est très facile à utiliser, il suffit de l'importer et de l'intégrer dans votre boucle comme ceci:

tqdm_test.py


%!pip install tqdm
import tqdm
import numpy as np


for i in tqdm.tqdm(range(int(1e7))):
    np.pi*np.pi

Maintenant, vous devriez voir quelque chose comme ceci: tqdm_test.gif C'est pratique ~ Puisque vous passez un objet itérable (bouclable) à tqdm.tqdm (), vous pouvez également passer des listes, des dictionnaires, des chaînes, etc. Cependant, comme mise en garde, ce serait terrible s'il y avait une sortie standard telle que la fonction print dans le traitement en boucle.

tqdm_test.py


%!pip install tqdm
import tqdm
import numpy as np


for i in tqdm.tqdm(range(int(1e7))):
    np.pi*np.pi
    if i % 1e6 == 0:
        print(i)

tqdm_test_fail.png Le même raisonnement est qu'il serait terrible de montrer les progrès avec la fonction tqdm.tqdm pour l'imbrication de boucles.

tqdm_test.py


import tqdm
for t in tqdm.tqdm(range(10)):
    for i in tqdm.tqdm(range(int(1e6))):
        np.pi*np.pi

tqdm_test_nest.gif Ce genre de chose est très rarement gênant, n'est-ce pas? Avez-vous tous une telle expérience? Il y a, non? Oui, il y a (utilisation en 3 étapes). Alors faisons quelque chose nous-mêmes.

Essayez de le faire vous-même

Au moins en Python, il semble que ** la chaîne de sortie standard quitte le contrôle du programme au moment du saut de ligne **. Inversement, cela signifie qu'il peut être utilisé par programme même après une sortie standard tant qu'il n'y a pas de saut de ligne **.

progress.py


for i in range(int(1e7)):
    if i % 1e4 == 0:
        print("\r", i, end="")
    np.pi*np.pi

test_print_r.gif Le \ r et end =" " permet au programme de garder le contrôle après la sortie standard. end =" " est une option pour spécifier la chaîne de caractères à ajouter à la fin de la chaîne de caractères sortie par la fonction print, et \ n (saut de ligne) est spécifié par défaut. Par conséquent, si vous le modifiez pour ajouter un caractère vide en définissant end =" " (bien que ce soit étrange à dire), il n'y aura pas de sauts de ligne, vous pouvez donc jouer avec la sortie standard par programmation. Tel qu'il apparaît ici, «\ r» et «\ n» commençant par une barre oblique inverse sont appelés ** séquences d'échappement **, et sont un groupe de chaînes de caractères qui permettent un contrôle spécial que vous souhaitez inclure dans la chaîne de caractères. Je vais.

Séquence d'échappement

Comme mentionné ci-dessus, la séquence d'échappement est un groupe de chaînes de caractères utilisé lorsque vous souhaitez donner un contrôle spécial à une chaîne de caractères. Les types typiques sont indiqués dans le tableau ci-dessous.

Séquence d'échappement effet
\b Espace arrière
\n nouvelle ligne
\t languette
\r Retour en haut de la ligne

En termes de traitement, la barre oblique inverse indique le début de la description de la séquence d'échappement, et elle est convertie en instruction de contrôle ou en code de caractère correspondant à la chaîne de caractères qui suit. Par conséquent, il est également utilisé lors de la sortie de la chaîne de caractères utilisée dans l'instruction de contrôle de la chaîne de caractères elle-même telle que les guillemets doubles " .

test_esc.py


print("\"")
print("\'")
print("\\")

Il est possible d'utiliser cette fonctionnalité pour lire une chaîne en Unicode, mais ce n'est probablement pas le cas.

test_esc.py


# Hello world!
print("\x48\x65\x6c\x6c\x6f\x20\x77\x6f\x72\x6c\x64\x21")

Essayez de faire une barre de progression

Créons votre propre barre de progression en utilisant la séquence d'échappement \ r.

progress.py


import time
for i in range(50):
    print("\r[" + "#"*i + "]", end="")
    time.sleep(0.1)

progress_first.gif Pour le moment, nous avons créé quelque chose qui peut être appelé une barre de progression! Au fait, je ne sais pas pourquoi, mais la séquence d'échappement ne fonctionne pas lorsque j'utilise la fonction format. Cela n'a pas bon goût, alors imaginons-en plus.

progress.py


import time
epoch = 50
for i in range(epoch):
    bar = "="*i + (">" if i < epoch-1 else "=") + " "*(epoch-i-1)
    print("\r[" + bar + "]", "{}/{}".format(i+1, epoch), end="")
    time.sleep(0.1)

Comme explication, écrivez d'abord la chaîne de caractères du corps principal de la barre de progression dans la variable bar. Dans le code, la barre de progression est remplie d'espaces pour fixer la longueur et le début est une flèche.

De plus, vous pouvez tout faire car vous n'avez qu'à définir l'imbrication que vous ne pouvez pas faire avec tqdm.

progress.py


import time


t_epoch = 10
i_epoch = 50
lap_time = -1
start_time = time.time()
for t in range(t_epoch):
    t_per = int((t+1)/t_epoch*i_epoch)
    for i in range(i_epoch):
        i_per = int((i+1)/i_epoch*i_epoch)
        if i_per <= t_per:
            bar = ("progress:[" + "X"*i_per
                                + "\\"*(t_per-i_per)
                                + " "*(i_epoch-t_per) + "]")
        else:
            bar = ("progress:[" + "X"*t_per
                                + "/"*(i_per-t_per)
                                + " "*(i_epoch-i_per) + "]")
        time.sleep(1e-2)
        elapsed_time = time.time() - start_time
        print("\r" + bar, "{}s/{}s".format(
                int(elapsed_time),
                int(lap_time*t_epoch) if lap_time > 0 
           else int(elapsed_time*(i_epoch/(i+1))*t_epoch)),
              end="")
    lap_time = (time.time() - start_time)/(t+1)

progress_second.gif C'est devenu soudainement compliqué ... Je vais vous expliquer. «t_per» et «i_per» calculent et contiennent le nombre de caractères requis pour afficher la progression dans la boucle «t» et la boucle «i» sous forme de chaîne de caractères. bar est la barre de progression elle-même

Il est programmé pour être comme ça. La barre oblique inverse est le caractère de début de la séquence d'échappement, vous devez donc utiliser " \\ ". lap_time contient le temps pris pour une boucle de i. J'essaie de prendre la moyenne pour obtenir une valeur plus précise. elapsed_time est le temps écoulé jusqu'à présent.

progress.py


                int(lap_time*t_epoch) if lap_time > 0 
           else int(elapsed_time*(i_epoch/(i+1))*t_epoch))

Cependant, si lap_time est calculé, il est affiché, et sinon (c'est-à-dire lors de l'entrée dans la boucle de i pour la première fois), le temps au tour est estimé à partir du temps écoulé et affiché.

Ceci n'est qu'un exemple, alors réfléchissez-y.

Évolution: code d'échappement ANSI

L'histoire a jusqu'ici dit que "la sortie standard ne peut pas être écrasée s'il y a un saut de ligne", mais en fait, il est possible de fonctionner même s'il y a un saut de ligne. La méthode est le ** code d'échappement ANSI **.

progress.py


import time
epoch = 25

print(" "*(epoch-10) + "彡 ノ ノ ノ Hami ⌒ Mi")
print(" "*(epoch-11) + " (´ ・ ω ・ `)ω ・ `)maintenant! Tirez avec Ora!")
print(" "*(epoch-13) + "⊂∩∩tsu)")
print(" "*(epoch-10) + "/   〈   〈")
print(" "*(epoch-11) + " ( /⌒ ` J ⌒'")
print("\n\n")
print(" "*(epoch-1)  + "Non")
print(" "*(epoch-4)  + "彡 ノ")
print(" "*(epoch-6)  + "Non")
print(" "*(epoch-8)  + "Nono Minono")
print()
print(" "*(epoch-11) + "(´;ω;`)ω^`)Merde ah ah ah! !! !!")
print(" "*(epoch-13) + "⊂∩∩tsu)")
print(" "*(epoch-10) + "/   〈   〈")
print(" "*(epoch-11) + " ( /⌒ ` J ⌒'")
print("\033[6A")
for i in range(epoch):
    bar = "弌"*i + "⊃" + " "*(epoch-i-1)
    print("\à r" + bar + "]", "{}/{}".format(i+1, epoch), end="")
    time.sleep(0.1)
print()
print("\033[5B")

progress_DB.gif S'il vous plaît passer à travers si le moyen de cacher des informations personnelles est compliqué lol Savez-vous C'est une parodie AA de la célèbre scène de Dragon Ball, contre Radits. (J'ai trouvé quelque chose, alors je l'ai utilisé) Le code pour afficher la partie AA est comme vous pouvez le voir. Cependant, notez que tous les AA ont été émis à l'avance. Et

progress.py


print("\033[6A")

Pré-ouvert par

progress.py


print(" "*(epoch-8)  + "Nono Minono")
print()
print(" "*(epoch-11) + "(´;ω;`)ω^`)Merde ah ah ah! !! !!")

Je suis passé à la partie ligne vide et j'ai affiché la méthode Manuki Kosatsu de la même manière qu'avant. finalement

progress.py


print()
print("\033[5B")

La méthode Manuki Kosatsu est interrompue et déplacée vers la dernière ligne de la sortie standard.

Eh bien, un code mystérieux sort, c'est le ** code d'échappement ANSI **. En Python, il existe des codes d'échappement ANSI dans le tableau suivant.

Code d'échappement ANSI effet
\033[nA Déplacer le curseur vers le haut de n lignes
\033[nB Déplacer le curseur vers le bas de n lignes
\033[nC Déplacer le curseur vers la droite n
\033[nD Déplacer le curseur vers la gauche n
\033[nE Déplacez le curseur vers le bas de n lignes, puis passez au début de cette ligne
\033[nF Déplacez le curseur vers le haut de n lignes, puis passez au début de cette ligne
\033[nG Déplacez le curseur à la nième position en comptant à partir de l'extrémité gauche
\033[n;mH Déplacez le curseur sur la nième ligne à compter du haut de la console et à la position m en comptant à partir de l'extrémité gauche
\033[nJ n=Lorsqu'il vaut 0, la chaîne de caractères après le curseur(Comprend les lignes suivantes)Tout supprimer, n=Lorsqu'il vaut 1, la chaîne de caractères avant le curseur(Comprend la ligne précédente)Supprimer, n=Lorsqu'il est 2, toute la chaîne de caractères(Toutes les sorties)Supprimer
\033[nK ~~n=Lorsqu'il vaut 0, la chaîne de caractères après la suppression du curseur, n=Lorsque 1, la chaîne de caractères avant le curseur est supprimée, n=S'il s'agit de 2, supprimez toute la ligne~~Cela peut ne pas fonctionner en Python.
\033[nS Faites défiler la console de n lignes ensuite
\033[nT Faire défiler la console de n lignes vers l'avant
\033[n;mf Déplacez le curseur comme en H
\033[nm SGR:Sélectionnez la commande Rendu graphique. Effectuer un contrôle graphique. Le détail estIci

Si vous avez des questions, rendons disponibles uniquement les quatre premiers. En utilisant ce code ANSI, vous pouvez opérer avec un degré de liberté élevé comme auparavant.

À propos, ce code ANSI semble être utilisable uniquement lors de l'utilisation d'une console telle qu'un terminal, alors acceptons la barre de progression sur une seule ligne à \ r dans le notebook jupyter, etc.

en conclusion

J'ai donc pris note de la sortie standard étonnamment compliquée. Eh bien, il semble peu probable que les personnes qui ont besoin de créer leur propre barre de progression ... Eh bien, je suis sûr que c'est bien que vous puissiez jouer à diverses choses en utilisant ces fonctions.

référence

Recommended Posts

Je veux afficher la progression en Python!
Je veux afficher la barre de progression
Je veux écrire en Python! (3) Utiliser des simulacres
Je veux utiliser le jeu de données R avec python
Je veux faire le test de Dunnett en Python
Je veux créer une fenêtre avec Python
Je veux fusionner des dictionnaires imbriqués en Python
Je veux convertir par lots le résultat de "chaîne de caractères" .split () en Python
Je veux expliquer en détail la classe abstraite (ABCmeta) de Python
Je veux écrire en Python! (1) Vérification du format de code
Je souhaite intégrer une variable dans une chaîne Python
Je veux facilement implémenter le délai d'expiration en python
Je veux écrire en Python! (2) Écrivons un test
Même avec JavaScript, je veux voir Python `range ()`!
Je veux échantillonner au hasard un fichier avec Python
Je veux hériter de l'arrière avec la classe de données python
Je veux travailler avec un robot en python.
Je veux faire quelque chose avec Python à la fin
Je veux manipuler des chaînes dans Kotlin comme Python!
Python Open CV a essayé d'afficher l'image sous forme de texte.
Je souhaite utiliser Python dans l'environnement de pyenv + pipenv sous Windows 10
Dans la commande python, python pointe vers python3.8
J'ai écrit la file d'attente en Python
Je veux obtenir le nom du fichier, le numéro de ligne et le nom de la fonction dans Python 3.4
J'ai écrit la pile en Python
Je veux initialiser si la valeur est vide (python)
maya Python Je veux réparer à nouveau l'animation cuite.
Je veux faire quelque chose comme sort uniq en Python
[Python] Je souhaite utiliser l'option -h avec argparse
J'ai essayé d'implémenter la fonction d'envoi de courrier en Python
Je veux connaître la nature de Python et pip
Je veux rendre le type de dictionnaire dans la liste unique
Je veux aligner les nombres valides dans le tableau Numpy
Je veux pouvoir exécuter Python avec VS Code
Je veux ajouter un joli complément à input () en python
Je ne voulais pas écrire la clé AWS dans le programme
Je veux juste trouver l'intervalle de confiance à 95% de la différence de ratio de population en Python
Je veux remplacer les variables dans le fichier de modèle python et le produire en masse dans un autre fichier
Je veux épingler Spyder à la barre des tâches
J'ai essayé d'implémenter PLSA en Python
Je veux sortir froidement sur la console
Je veux imprimer dans la notation d'inclusion
Je veux gérer la rime part1
Je veux gérer la rime part3
J'ai essayé d'implémenter PLSA dans Python 2
Afficher Python 3 dans le navigateur avec MAMP
Je veux utiliser jar de python
Je veux créer un environnement Python
Je veux analyser les journaux avec Python
Comment afficher la table quatre-vingt-dix-neuf en python
Je veux jouer avec aws avec python
J'ai essayé d'implémenter ADALINE en Python
Je voulais résoudre ABC159 avec Python
J'ai essayé d'implémenter PPO en Python
Je veux intégrer Matplotlib dans PySimpleGUI
Comment afficher Hello World en python
Je veux gérer la rime part2
Je veux gérer la rime part5
Je veux gérer la rime part4
[Linux] Je souhaite connaître la date à laquelle l'utilisateur s'est connecté