Debido a que las herramientas de secuencia de comandos comparten la aplicación, usted tiene control sobre el cuadro de diálogo de progreso. Puede controlar la apariencia del cuadro de diálogo de progreso seleccionando el indicador de progreso predeterminado o el indicador de progreso por pasos.
Para obtener más información sobre el cuadro de diálogo de progreso, consulte Entender el cuadro de diálogo de progreso en las herramientas de secuencia de comandos
El siguiente código demuestra el uso completo de los indicadores de progreso predeterminado y por pasos. Copie este código en el editor de Python, guárdelo y a continuación cree una herramienta de secuencia de comandos para él. La herramienta de secuencia de comandos tiene dos parámetros de números enteros largos como se describe en los comentarios del código. Después, ejecute la herramienta de secuencia de comandos, proporcionando valores diferentes para los parámetros (comenzar con n = 10 y p = 1, después intente n = 101 y 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()
Seleccionar un incremento adecuado cuando el máximo puede ser grande
Es bastante común escribir secuencias de comandos que iteren una cantidad de veces no conocida. Por ejemplo, la secuencia de comandos puede utilizar un SearchCursor para iterar por todas las filas de una tabla y no se conoce la cantidad de filas de antemano: la secuencia de comandos se puede utilizar con tablas de cualquier tamaño, desde varios miles de filas hasta millones de filas. Incrementar un indicador de progreso por pasos para cada fila en una tabla grande es un cuello de botella de rendimiento y es posible que usted desee evitar tales situaciones.
Para demostrar y evaluar los problemas de rendimiento con indicadores de progreso por pasos, copie el siguiente código en el editor de Python, guárdelo, y a continuación cree una herramienta de secuencia de comandos para él. La herramienta tiene dos entradas: un parámetro de tabla y un parámetro de campo. Ejecute la herramienta de secuencia de comandos con una variedad de tamaños de tablas, pero asegúrese de intentar con una clase de entidad o tabla que contenga 10.000 filas o más para ver las diferencias en el rendimiento. (También puede intentar la ejecución de la herramienta dentro y fuera del proceso para evaluar el aumento de rendimiento al ejecutarla dentro del proceso).
La secuencia de comandos ejecuta tres bucles separados y cada bucle captura todas las filas de la tabla. Los bucles se diferencian en la manera de actualizar el indicador de progreso por pasos. El primer y segundo bucle actualizan el indicador de progreso por pasos en incrementos grandes y el último bucle incrementa el indicador de progreso por pasos una vez para cada fila. Cuando ejecute la herramienta, verá que este último bucle tarda más en ejecutarse.
Es posible que desee emplear las técnicas que se encuentran en este código en las herramientas de secuencia de comandos.
'''
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])