353
8
06-25-2020 10:15 AM
Occasional Contributor III

I am working on fine-tuning my collection of Python Scripts and one thing I want to do is to add the AddMessage feature to my script. I have a particular script that produces a series of .PDF Graphs from a SearchCursor function. What I want to be able to do is each time an individual .PDF is created, I want to use the built-in SearchCursor with AddMessage to print a message to the screen showing the name of the .PDF created.

Here is a portion of my script.

list = []

rows = arcpy.SearchCursor(table)
for row in rows:
list.append(row.SERVICE_IDENTIFIER) # Double

del row, rows

# Remove duplicates from list
list = dict.fromkeys(list)
list = list.keys()

for n in list:
arcpy.TableSelect_analysis(table, r"in_memory\table_sel", "SERVICE_IDENTIFIER = " + str(n)) # Double

# Get TWACs_Number value
for row in arcpy.SearchCursor(r"in_memory\table_sel"):

out_graph_name = n
out_graph_pdf = r"Z:\Operations\Maps and Records\GeoDatabase\MEWCO GIS System\GIS Attachments\Electric System\Electric Usage Demand Graphs\F1 Feeder ALL" + "\\" + str(n)[:-2] + ".pdf"
input_template = r"Y:\MEWCo GIS System - LOCAL\ELECTRIC SYSTEM\ELECTRIC GRAPHS - CONSTRUCT\GIS Graph Temps\ELECTRIC METER DEMAND - UPDATED 2020.grf"
input_data = r"in_memory\table_sel"

Thank You

8 Replies
MVP Esteemed Contributor

Occasional Contributor III
env.workspace = r"Y:\MEWCo GIS System - LOCAL\ELECTRIC SYSTEM\ELECTRIC DATASET\MEWCo ELECTRIC SYSTEM\MEWCo ELECTRIC SYSTEM.gdb"

list = []

rows = arcpy.SearchCursor(table)
for row in rows:
list.append(row.SERVICE_IDENTIFIER) # Double

del row, rows

# Remove duplicates from list
list = dict.fromkeys(list)
list = list.keys()

for n in list:
arcpy.TableSelect_analysis(table, r"in_memory\table_sel", "SERVICE_IDENTIFIER = " + str(n)) # Double

# Get TWACs_Number value
for row in arcpy.SearchCursor(r"in_memory\table_sel"):

out_graph_name = n
out_graph_pdf = r"Z:\Operations\Maps and Records\GeoDatabase\MEWCO GIS System\GIS Attachments\Electric System\Electric Usage Demand Graphs\F1 Feeder ALL" + "\\" + str(n)[:-2] + ".pdf"
input_template = r"Y:\MEWCo GIS System - LOCAL\ELECTRIC SYSTEM\ELECTRIC GRAPHS - CONSTRUCT\GIS Graph Temps\ELECTRIC METER DEMAND - UPDATED 2020.grf"
input_data = r"in_memory\table_sel"‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
MVP Esteemed Contributor

Although list isn't a reserved word in Python, it is a built-in class, and people are strongly discouraged from naming variables after built-in objects.

In terms of ArcPy, I recommend switching to SearchCursor—Data Access module | Documentation.  Not only are Data Access cursors more Pythonic, they perform much faster on larger data sets.

For finding unique values, instead of creating a list and then using a dict, you can just create a Set - Built-in Types — Python 3.8.3 documentation from the beginning and populate it within the cursor.

Where are you having issues with AddMessage, I don't see it anywhere in your code?

Occasional Contributor III

Joshua:

I appreciate your feedback. I will take a look at what you recommended. Regarding the AddMessage, its not in the code because I am not really sure how to write/include it. With each .PDF created, I would like a message displayed saying something along the lines of file created and the file name.

MVP Esteemed Contributor

You can just stick AddMessage right before the code where you generate the PDF.  Speaking of which, where is the code that generates the PDF?

MVP Esteemed Contributor

AddMessage isn't going to reveal anything unless you are running this inside Pro, use something that covers both inside and standalone scripts.

def tweet(msg):
"""Print a message for both arcpy and python."""
m = "\n{}\n".format(msg)
print(m)‍‍‍‍‍

... sort of retired...
MVP Esteemed Contributor

I can't say when the behavior changed, or even if it ever did, but AddMessage from a stand-alone script or outside of Pro prints the message to the console:

>>> from arcpy import AddMessage
>>>
>>> print("Hello World")
Hello World
Hello World
>>>‍‍‍‍‍‍‍
MVP Esteemed Contributor

I like to create log files that can capture when events take place; typically every geoprocessing step I do is in it's own def and the heavy lifting is in a try/except block: if the process is successful the try block writes a message to the log file saying so; if the process fails the except block logs the error and also sends me an email saying something went wrong.

If you are just running the script from a console, you don't need to bother with a log file, but I still suggest the try/accept approach and just print() the appropriate message.  Here is some sample code:

import arcpy, sys, os, smtplib, shutil, time

def sendEmail(errMessage):   # if errors send email
subject = "SOMETHING WENT WRONG IN SOME SCRIPT"
msg_text = errMessage
server = smtplib.SMTP(server)
server.quit()

try:
except Exception as err:
print(f'Error: could not create locator: {out_address_locator}')
print (err)
sendEmail(err)

def main():

logFile r"SomeDrive:\path\to\processName.log"
logoutput = open(logFile,'w')
beginTime = time.strftime('%Y-%m-%d %H:%M:%S')
logoutput.write("Began at # " + beginTime + "\n")
sys.stdout = logoutput

logoutput.close()   ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍