Ich möchte den Fortschritt in Python anzeigen!

Überblick

Wenn Sie einen Prozess ausführen, der lange dauert und keine Antwort erfolgt, sind Sie besorgt darüber, "wie weit der Prozess fortgeschritten ist" oder "funktioniert er?" Es gibt, richtig? Ja, es gibt (3-Stufen-Nutzung). Daher werde ich feststellen, wie der Fortschritt der Schleifenverarbeitung angezeigt wird.

↓ ↓ ↓ Übrigens sieht es so aus ↓ ↓ ↓ progress_DB.gif Wenn Sie es nützlich finden, wäre ich Ihnen dankbar, wenn Sie die LGTM-Aktie kommentieren könnten.

Inhaltsverzeichnis

Verwendung des Pakets tqdm

Zunächst möchte ich "tqdm" vorstellen, die königliche Straße des Fortschritts (ich halte sie für egoistisch). Es ist sehr einfach zu bedienen, importieren Sie es einfach und binden Sie es wie folgt in Ihre Schleife ein:

tqdm_test.py


%!pip install tqdm
import tqdm
import numpy as np


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

Jetzt sollten Sie so etwas sehen: tqdm_test.gif Es ist bequem ~ Da Sie ein iterierbares (schleifenfähiges) Objekt an tqdm.tqdm () übergeben, können Sie auch Listen, Wörterbücher, Zeichenfolgen usw. übergeben. Als Einschränkung wäre es jedoch schrecklich, wenn es eine Standardausgabe wie die Druckfunktion in der Schleifenverarbeitung gibt.

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 Die gleiche Überlegung ist, dass es schrecklich wäre, Fortschritte mit der Funktion tqdm.tqdm zum Verschachteln von Schleifen zu zeigen.

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 So etwas ist sehr selten unpraktisch, oder? Haben Sie alle eine solche Erfahrung? Es gibt, richtig? Ja, es gibt (3-Stufen-Nutzung). Also lasst uns selbst etwas dagegen tun.

Versuche es selbst zu machen

Zumindest in Python scheint es, dass ** die Standardausgabezeichenfolge zum Zeitpunkt des Zeilenumbruchs die Kontrolle über das Programm verlässt **. Umgekehrt bedeutet dies, dass es auch nach Standardausgabe programmgesteuert betrieben werden kann, solange kein Zeilenumbruch vorliegt **.

progress.py


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

test_print_r.gif Diese \ r und end =" " ermöglichen es dem Programm, nach der Standardausgabe weiterhin die Kontrolle darüber zu übernehmen. end =" " ist eine Option zum Festlegen der Zeichenfolge, die am Ende der von der Funktion print ausgegebenen Zeichenfolge hinzugefügt werden soll, und \ n (Zeilenvorschub) ist standardmäßig angegeben. Wenn Sie es ändern, um ein leeres Zeichen hinzuzufügen, indem Sie "end =" "" setzen (obwohl es seltsam zu sagen ist), gibt es keine Zeilenumbrüche, sodass Sie programmgesteuert mit der Standardausgabe spielen können. Wie hier zu sehen ist, werden \ r und \ n, beginnend mit einem Backslash, als ** Escape-Sequenzen ** bezeichnet und sind eine Gruppe von Zeichenfolgen, die eine spezielle Steuerung ermöglichen, die Sie in die Zeichenfolge aufnehmen möchten. Ich werde.

Fluchtabfolge

Wie oben erwähnt, ist die Escape-Sequenz eine Gruppe von Zeichenfolgen, die verwendet werden, wenn Sie einer Zeichenfolge eine spezielle Steuerung geben möchten. Die typischen sind in der folgenden Tabelle aufgeführt.

Fluchtabfolge bewirken
\b Rückraum
\n Neue Zeile
\t Tab
\r Zurück zum Anfang

In Bezug auf die Verarbeitung gibt der Schrägstrich den Beginn der Escape-Sequenzbeschreibung an und wird in die Steueranweisung oder den Zeichencode konvertiert, der der folgenden Zeichenfolge entspricht. Daher wird es auch verwendet, wenn die in der Steueranweisung der Zeichenfolge selbst verwendete Zeichenfolge ausgegeben wird, z. B. doppeltes Anführungszeichen "".

test_esc.py


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

Mit dieser Funktion können Sie eine Zeichenfolge in Unicode lesen, dies ist jedoch wahrscheinlich nicht der Fall.

test_esc.py


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

Versuchen Sie, einen Fortschrittsbalken zu erstellen

Lassen Sie uns Ihren eigenen Fortschrittsbalken mit der Escape-Sequenz \ r erstellen.

progress.py


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

progress_first.gif Vorerst haben wir etwas geschaffen, das man als Fortschrittsbalken bezeichnen kann! Ich weiß übrigens nicht warum, aber die Escape-Sequenz funktioniert nicht, wenn ich die Funktion format verwende. Es schmeckt nicht so gut wie es ist, also lasst uns mehr entwickeln.

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)

Schreiben Sie zur Erklärung zuerst die Hauptteilzeichenfolge des Fortschrittsbalkens in die Variable bar. Im Code werden Leerzeichen ausgefüllt, um die Länge des Fortschrittsbalkens festzulegen, und der Anfang ist ein Pfeil.

Außerdem können Sie alles tun, weil Sie nur die Verschachtelung definieren müssen, die Sie mit tqdm nicht machen konnten.

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 Es wurde plötzlich kompliziert ... Ich werde es erklären. t_per und i_per berechnen und halten die Anzahl der Zeichen, die erforderlich sind, um den Fortschritt in der t-Schleife und i-Schleife als Zeichenfolge anzuzeigen. bar ist der Fortschrittsbalken selbst

Es ist so programmiert. Der Backslash ist das Startzeichen der Escape-Sequenz, daher müssen Sie "\" verwenden. lap_time enthält die Zeit, die für eine Schleife von i benötigt wird. Ich versuche, den Durchschnitt zu nehmen, um einen genaueren Wert zu erhalten. elapsed_time ist die verstrichene Zeit bis zur Gegenwart.

progress.py


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

Wenn jedoch "lap_time" berechnet wird, wird es angezeigt, und wenn dies nicht der Fall ist (dh wenn Sie zum ersten Mal in die Schleife von "i" eintreten), wird die Rundenzeit aus der verstrichenen Zeit geschätzt und angezeigt.

Dies ist nur ein Beispiel. Denken Sie also bitte darüber nach.

Evolution: ANSI-Escape-Code

In der bisherigen Geschichte heißt es, dass "die Standardausgabe bei einem Zeilenumbruch nicht überschrieben werden kann", aber tatsächlich auch bei einem Zeilenumbruch betrieben werden kann. Die Methode ist ** ANSI-Escape-Code **.

progress.py


import time
epoch = 25

print(" "*(epoch-10) + "I ノ ノ ノ Hami ⌒ Mi.")
print(" "*(epoch-11) + " (´ ・ ω ・ `)ω ・ `)jetzt! Schieß mit Ora!")
print(" "*(epoch-13) + "⊂∩∩tsu)")
print(" "*(epoch-10) + "/   〈   〈")
print(" "*(epoch-11) + " ( /⌒ ` J ⌒'")
print("\n\n")
print(" "*(epoch-1)  + "Nein")
print(" "*(epoch-4)  + "彡 ノ")
print(" "*(epoch-6)  + "Nein")
print(" "*(epoch-8)  + "Nono Minono")
print()
print(" "*(epoch-11) + "(´;ω;`)ω^`)Scheiße 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("\zu r" + bar + "]", "{}/{}".format(i+1, epoch), end="")
    time.sleep(0.1)
print()
print("\033[5B")

progress_DB.gif Bitte gehen Sie durch, wenn der Weg zum Verbergen persönlicher Informationen kompliziert ist lol Wissen Sie Es ist eine Parodie AA der berühmten Szene von Dragon Ball gegen Radits. (Ich habe etwas gefunden, also habe ich es benutzt) Der Code zum Anzeigen des AA-Teils ist wie Sie sehen können. Beachten Sie jedoch, dass alle AAs im Voraus ausgegeben wurden. Und

progress.py


print("\033[6A")

Vorgeöffnet von

progress.py


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

Ich ging zum leeren Zeilenteil von und zeigte die Manuki Kosatsu-Methode auf die gleiche Weise wie zuvor an. Schließlich

progress.py


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

Die Manuki Kosatsu-Methode ist fehlerhaft und wird in die letzte Zeile der Standardausgabe verschoben.

Nun kommt der mysteriöse Code heraus, dies ist der ** ANSI-Escape-Code **. In Python finden Sie in der folgenden Tabelle ANSI-Escape-Codes.

ANSI-Escape-Code bewirken
\033[nA Bewegen Sie den Cursor n Zeilen nach oben
\033[nB Bewegen Sie den Cursor n Zeilen nach unten
\033[nC Bewegen Sie den Cursor nach rechts n
\033[nD Bewegen Sie den Cursor nach links n
\033[nE Bewegen Sie den Cursor in n Zeilen nach unten und dann zum Anfang dieser Zeile
\033[nF Bewegen Sie den Cursor in n Zeilen nach oben und dann zum Anfang dieser Zeile
\033[nG Bewegen Sie den Cursor vom linken Ende auf die n-te Position
\033[n;mH Bewegen Sie den Cursor von oben auf der Konsole zur n-ten Zeile und vom linken Ende zur m-Position
\033[nJ n=Wenn es 0 ist, die Zeichenfolge nach dem Cursor(Enthält nachfolgende Zeilen)Alle löschen, n=Wenn es 1 ist, die Zeichenfolge vor dem Cursor(Beinhaltet die vorherige Zeile)Löschen, n=Wenn es 2 ist, die gesamte Zeichenfolge(Alle Ausgabe)Löschen
\033[nK ~~n=Wenn es 0 ist, wird die Zeichenfolge nach dem Löschen des Cursors n=Bei 1 wird die Zeichenfolge vor dem Cursor gelöscht, n=Wenn es 2 ist, löschen Sie die gesamte Zeile~~In Python funktioniert dies möglicherweise nicht.
\033[nS Scrollen Sie als nächstes in der n-Zeilen-Konsole
\033[nT Scrollen Sie vorwärts und n Zeilen Konsole
\033[n;mf Bewegen Sie den Cursor wie in H.
\033[nm SGR:Wählen Sie den Befehl Grafikwiedergabe. Führen Sie eine grafische Steuerung durch. Detail istHier

Wenn Sie Fragen haben, stellen wir nur die ersten vier zur Verfügung. Mit diesem ANSI-Code können Sie wie bisher mit einem hohen Freiheitsgrad arbeiten.

Übrigens scheint dieser ANSI-Code nur bei Verwendung einer Konsole wie eines Terminals verwendbar zu sein. Lassen Sie uns also den einzeiligen Fortschrittsbalken bei \ r im Jupiter-Notizbuch usw. in Kauf nehmen.

abschließend

Also habe ich mir die unerwartet komplizierte Standardausgabe notiert. Nun, es scheint unwahrscheinlich, dass Menschen, die ihre eigenen Fortschrittsbalken machen müssen ... Nun, ich bin sicher, es ist gut, dass Sie mit diesen Funktionen verschiedene Dinge spielen können.

Referenz

Recommended Posts

Ich möchte den Fortschritt in Python anzeigen!
Ich möchte den Fortschrittsbalken anzeigen
Ich möchte in Python schreiben! (3) Verwenden Sie Mock
Ich möchte R-Datensatz mit Python verwenden
Ich möchte Dunnetts Test in Python machen
Ich möchte mit Python ein Fenster erstellen
Ich möchte verschachtelte Dicts in Python zusammenführen
Ich möchte das Ergebnis von "Zeichenfolge" .split () in Python stapelweise konvertieren
Ich möchte die abstrakte Klasse (ABCmeta) von Python im Detail erklären
Ich möchte in Python schreiben! (1) Überprüfung des Codeformats
Ich möchte eine Variable in einen Python-String einbetten
Ich möchte Timeout einfach in Python implementieren
Ich möchte in Python schreiben! (2) Schreiben wir einen Test
Auch mit JavaScript möchte ich Python `range ()` sehen!
Ich möchte eine Datei mit Python zufällig testen
Ich möchte mit Python-Datenklasse nach hinten erben
Ich möchte mit einem Roboter in Python arbeiten.
Ich möchte am Ende etwas mit Python machen
Ich möchte Strings in Kotlin wie Python manipulieren!
Python Open CV hat versucht, das Bild im Text anzuzeigen.
Ich möchte Python in der Umgebung von pyenv + pipenv unter Windows 10 verwenden
Im Python-Befehl zeigt Python auf Python3.8
Ich habe die Warteschlange in Python geschrieben
Ich möchte den Dateinamen, die Zeilennummer und den Funktionsnamen in Python 3.4 erhalten
Ich habe den Stack in Python geschrieben
Ich möchte initialisieren, wenn der Wert leer ist (Python)
maya Python Ich möchte die gebackene Animation wieder reparieren.
Ich möchte so etwas wie Uniq in Python sortieren
[Python] Ich möchte die Option -h mit argparse verwenden
Ich habe versucht, die Mail-Sendefunktion in Python zu implementieren
Ich möchte die Natur von Python und Pip kennenlernen
Ich möchte den Wörterbuchtyp in der Liste eindeutig machen
Ich möchte die gültigen Zahlen im Numpy-Array ausrichten
Ich möchte Python mit VS-Code ausführen können
Ich möchte eine schöne Ergänzung zu input () in Python hinzufügen
Ich wollte den AWS-Schlüssel nicht in das Programm schreiben
Ich möchte nur das 95% -Konfidenzintervall des Unterschieds im Bevölkerungsverhältnis in Python ermitteln
Ich möchte die Variablen in der Python-Vorlagendatei ersetzen und in einer anderen Datei in Massenproduktion herstellen
Ich möchte Spyder an die Taskleiste anheften
Ich habe versucht, PLSA in Python zu implementieren
Ich möchte kühl auf die Konsole ausgeben
Ich möchte in der Einschlussnotation drucken
Ich möchte mit dem Reim Teil1 umgehen
Ich möchte mit dem Reim part3 umgehen
Ich habe versucht, PLSA in Python 2 zu implementieren
Zeigen Sie Python 3 im Browser mit MAMP an
Ich möchte ein Glas aus Python verwenden
Ich möchte eine Python-Umgebung erstellen
Ich möchte Protokolle mit Python analysieren
So zeigen Sie die neunundneunzig Tabelle in Python an
Ich möchte mit aws mit Python spielen
Ich habe versucht, ADALINE in Python zu implementieren
Ich wollte ABC159 mit Python lösen
Ich habe versucht, PPO in Python zu implementieren
Ich möchte Matplotlib in PySimpleGUI einbetten
So zeigen Sie Hello World in Python an
Ich möchte mit dem Reim part2 umgehen
Ich möchte mit dem Reim part5 umgehen
Ich möchte mit dem Reim part4 umgehen
[Linux] Ich möchte das Datum wissen, an dem sich der Benutzer angemeldet hat