Steuern des Verlaufsdialogfeldes

Da Skriptwerkzeuge die Anwendung gemeinsam verwenden, steuern Sie das Verlaufsdialogfeld. Sie können das Aussehen des Verlaufsdialogfeldes vorgeben, indem Sie wie unten abgebildet entweder die standardmäßige Verlaufsanzeige oder die schrittweise Verlaufsanzeige wählen.

Weitere Informationen zum Verlaufsdialogfeld finden Sie unter Verlaufsdialogfelder in Skriptwerkzeugen.

Der folgende Code zeigt die vollständige Verwendung der standardmäßigen und der schrittweisen Verlaufsanzeige. Kopieren Sie den Code in Ihren Python-Editor, speichern Sie ihn, und erstellen Sie ein Skriptwerkzeug für den Code. Das Skriptwerkzeug verfügt, wie in den Code-Kommentaren beschrieben, über zwei "Long"-Ganzzahlparameter. Führen Sie dann das Skriptwerkzeug aus, und stellen Sie dabei verschiedene Werte für die Parameter bereit. (Beginnen Sie mit n = 10 und p = 1, und versuchen Sie es dann mit n = 101 und p = 3.)

'''
Demonstration script showing examples of using the progressor
 Parameters:
   n - number to count to (a good first choice is 10)
   p - interval to count by (a good first choice is 1)
The various time.sleep() calls are just to slow the dialog down
so you can view messages and progressor labels.
'''

import arcpy
import time

n = int(arcpy.GetParameterAsText(0))
p = int(arcpy.GetParameterAsText(1))

readTime = 2.5  # Pause to read what's written on dialog
loopTime = 0.3  # Loop iteration delay

arcpy.AddMessage("Running demo with: {0} by {1}\n".format(n, p))

# Start by showing the default progress dialog, where the
#  progress bar goes back and forth. Note how the progress label
#  mimics working through some "phases", or chunks of work that
#  a script may perform.
#
arcpy.SetProgressor("default", "This is the default progressor")
time.sleep(readTime)

for i in xrange(1, 4):
    arcpy.SetProgressorLabel("Working on 'phase' {0}".format(i))
    arcpy.AddMessage("Messages for phase {0}".format(i))
    time.sleep(readTime)

# Setup the progressor with its initial label, min, max, and interval
#
arcpy.SetProgressor("step",
                    "Step progressor: Counting from 0 to {0}".format(n),
                    0, n, p)
time.sleep(readTime)

# Loop issuing a new label when the increment is divisible by the
#  value of countBy (p). The "%" is python's modulus operator - we
#  only update the position every p'th iteration
#
for i in range(n):
    if (i % p) == 0:
        arcpy.SetProgressorLabel("Iteration: {0}".format(i))
        arcpy.SetProgressorPosition(i)
        time.sleep(loopTime)

# Update the remainder that may be left over due to modulus operation
#
arcpy.SetProgressorLabel("Iteration: {0}".format(i + 1))
arcpy.SetProgressorPosition(i + 1)

arcpy.AddMessage("Done counting up\n")
time.sleep(readTime)

# Just for fun, make the progressor go backwards.
#
arcpy.SetProgressor("default", "Default progressor: Now we'll do a countdown")
time.sleep(readTime)
arcpy.AddMessage("Here comes the countdown...")
arcpy.SetProgressor("step",
                    "Step progressor: Counting backwards from {0}".format(n),
                    0, n, p)
time.sleep(readTime)
arcpy.AddMessage("Counting down now...\n")

for i in range(n, 0, -1):
    if (i % p) == 0:
        arcpy.SetProgressorLabel("Iteration: {0}".format(i))
        arcpy.SetProgressorPosition(i)
        time.sleep(loopTime)

# Update for remainder
#
arcpy.SetProgressorLabel("Iteration: {0}".format(i - 1))
arcpy.SetProgressorPosition(i - 1)
time.sleep(readTime)
arcpy.AddMessage("All done")
arcpy.ResetProgressor()

Wahl eines guten Intervalls bei einem potenziell großen Maximalwert

Bei vielen Skripten wissen Sie zunächst nicht, wie oft die Ausführung wiederholt wird. Beispiel: Ihr Skript läuft mit SearchCursor über die Zeilen in einer Tabelle. Die Anzahl der Zeilen ist Ihnen zunächst nicht bekannt. Ihr Skript kann für Tabellen beliebiger Größe verwendet werden, unabhängig davon, ob eine Tabelle nur einige Tausend oder Millionen von Zeilen aufweist. Wenn die schrittweise Verlaufsanzeige bei großen Tabellen um jeweils eine Zeile voranschreitet, kann dies zu einem Engpass bei der Performance führen, gegen den Sie vorbeugen sollten.

Um mögliche Performance-Probleme bei der schrittweisen Verlaufsanzeige abzuschätzen, kopieren Sie den folgenden Code in Ihren Python-Editor, speichern ihn und erstellen dann ein Skriptwerkzeug für den Code. Das Werkzeug hat zwei Eingaben: einen Tabellenparameter und einen Feldparameter. Führen Sie das Skriptwerkzeug mit verschiedenen Tabellengrößen aus. Verwenden Sie dabei eine Tabelle oder Feature-Class mit mindestens 10.000 Zeilen, damit die Performance-Unterschiede deutlich werden. (Sie können das Werkzeug auch innerhalb und außerhalb des Prozesses ausführen, um die bessere Performance bei der Ausführung im Prozess zu überprüfen.)

Das Skript durchläuft drei getrennte Schleifen und bei jeder Schleife werden alle Zeilen in der Tabelle abgerufen. Die schrittweise Verlaufsanzeige wird bei den einzelnen Schleifen unterschiedlich aktualisiert. Bei der ersten und zweiten Schleife wird die Verlaufsanzeige in großen Schritten aktualisiert, bei der letzten mit jeder Zeile. Wenn Sie das Werkzeug ausführen, werden Sie feststellen, dass die letzte Schleife länger dauert.

Sie können die in diesem Code verwendeten Vorgehensweisen auch für Ihre Skriptwerkzeuge nutzen.

'''
Demonstrates a step progressor by looping through records
on a table. Use a table with 10,000 or so rows - smaller tables
just whiz by.
   1 = table name
   2 = field on the table
'''

import arcpy
import time
import math

try:
    inTable = arcpy.GetParameterAsText(0)
    inField = arcpy.GetParameterAsText(1)

    # Determine number of records in table
    #
    record_count = int(arcpy.GetCount_management(inTable).getOutput(0))
    if record_count == 0:
        raise ValueError("{0} has no records to count".format(inTable))

    arcpy.AddMessage("Number of rows = {0}\n".format(record_count))

    # Method 1: Calculate and use a suitable base 10 increment
    # ===================================

    p = int(math.log10(record_count))
    if not p:
        p = 1
    increment = int(math.pow(10, p - 1))

    arcpy.SetProgressor(
        "step", "Incrementing by {0} on {1}".format(increment, inTable),
        0, record_count, increment)

    beginTime = time.clock()
    with arcpy.da.SearchCursor(inTable, [inField]) as cursor:
        for i, row in enumerate(cursor, 0):
            if (i % increment) == 0:
                arcpy.SetProgressorPosition(i)
            fieldValue = row[0]

    arcpy.SetProgressorPosition(i)
    arcpy.AddMessage("Method 1")
    arcpy.AddMessage("\tIncrement = {0}".format(increment))
    arcpy.AddMessage("\tElapsed time: {0}\n".format(time.clock() - beginTime))

    # Method 2: let's just move in 10 percent increments
    # ===================================
    increment = int(record_count / 10.0)
    arcpy.SetProgressor(
        "step", "Incrementing by {0} on {1}".format(increment, inTable),
        0, record_count, increment)

    beginTime = time.clock()
    with arcpy.da.SearchCursor(inTable, [inField]) as cursor:
        for i, row in enumerate(cursor, 0):
            if (i % increment) == 0:
                arcpy.SetProgressorPosition(i)
            fieldValue = row[0]

    arcpy.SetProgressorPosition(i)
    arcpy.AddMessage("Method 2")
    arcpy.AddMessage("\tIncrement = {0}".format(increment))
    arcpy.AddMessage("\tElapsed time: {0}\n".format(time.clock() - beginTime))

    # Method 3: use increment of 1
    # ===================================
    increment = 1
    arcpy.SetProgressor("step",
                        "Incrementing by 1 on {0}".format(inTable),
                        0, record_count, increment)

    beginTime = time.clock()
    with arcpy.da.SearchCursor(inTable, [inField]) as cursor:
        for row in cursor:
            arcpy.SetProgressorPosition()
            fieldValue = row[0]

    arcpy.SetProgressorPosition(record_count)
    arcpy.ResetProgressor()
    arcpy.AddMessage("Method 3")
    arcpy.AddMessage("\tIncrement = {0}".format(increment))
    arcpy.AddMessage("\tElapsed time: {0}\n".format(time.clock() - beginTime))

    arcpy.AddMessage("Pausing for a moment to allow viewing...")
    time.sleep(2.0)  # Allow viewing of the finished progressor

except Exception as e:
    arcpy.AddError(e[0])

Verwandte Themen

5/10/2014