I'm using
sys.stdout.write( "." )
in a a loop to print a series of dots when it has processed an .mxd that didn't fit the criteria that I am working on (if it fits criteria, then it lists the path). It's just a very simple "progress bar" for my tool.
This works fine in a python window, but I'm not sure how to do this in a tool, without getting a bunch of newlines that come with a print or arcpy.AddMessage (which looks messy...but I could live with it)
I've read ab out many of the progress bar approaches, but this one line (or equivalent) is what I'm hoping for. I'll include a snippet of the code..
# ... snippet....will not run as standalone as is
updateServices = []
update = False
myMsgs("\nFinding STARTED services accesing {0} to STOP\n Dots represent services that are OK".format(updateDS[0]))
for startedService in myServices:
mxdFound = False
if not update: # will print a dot for services or df within mxd that are ok, using for progress status
sys.stdout.write( "." )
update = False
#myMsgs("Reviewing service: {0}".format(startedService))
theServicePath = os.path.join(servicesDir, startedService)
if not arcpy.Exists(theServicePath):
myMsgs("...we have a problem")
exit
else:
# myMsgs(" {0}".format(startedService)) # Can use if want to list all services
for root, dirs, files in os.walk(theServicePath):
for fn in files:
fullPath = os.path.join(root, fn)
basename, extension = os.path.splitext(fn)
if not extension == ".mxd":
pass
else:
#myMsgs(" mxd file found")
mxd = arcpy.mapping.MapDocument(fullPath)
try:
# Do stuff with MXD using arcpy.mapping
for df in arcpy.mapping.ListDataFrames(mxd):
lyrList = arcpy.mapping.ListLayers(mxd)
mxdFound = True
for lyr in lyrList:
if lyr.isFeatureLayer and update == False:
if lyr.supports("dataSource") and update == False:
theSource = lyr.dataSource
if updateDS[0] in theSource:
update = True
myMsgs(" {0} is using {1}".format(startedService, updateDS[0]))
updateServices.append(startedService)
break
except AttributeError:
myMsgs("\n !!! WARNING: {0} has unreadable dataframes(s),\n will stop as precaution...\n".format(os.path.basename(mxd.filePath)))
updateServices.append(startedService)
update = True
pass
del mxd
# ...
Line #8 is where the line is that works in the python window.
Thanks.
You are going to hate me
>>> # python 2.7
>>> for i in range(5): print(i),
...
0 1 2 3 4
>>> # python 3.x
>>> for i in range(5): print(i, end=" ")
...
0 1 2 3 4
don't know about add message since I am on the iThingy
Oh yeah... it is the ',' for 2.7 and end="" or end=" " in 3.*
Thanks for the quick response Dan, took me a while to test it out in many different configurations.
The "comma" is a nice trick for the print statement, but it doesn't work for the AddMessage either. Also, since my for loop is a bit different, the print sill wanted to include at least a "space" with my dots.
I had seen and tried the (i, end=" ") option in one of the thread but got a syntax error....now I know why (3.4). I'm still in 10.2.2 (and/or 10.3.x)
This is what I really want, and I am getting in the python window (from my script), but as a arcpy tool, it doesn't seem to like the stdout and of course none of the print option above will work
Finding STARTED services accessing Master_current.gdb to STOP
Dots represent services that are OK
........................................... wc_public//gmuLetterLandscape.MapServer is using Master_current.gdb
wc_public//GMUSpArea.MapServer is using Master_current.gdb
wc_public//GMUSubunits.MapServer is using Master_current.gdb
wc_public//GMUSubunitsTest.MapServer is using Master_current.gdb
. wc_public//qryGMU.MapServer is using Master_current.gdb
wc_public//SpecialAreas.MapServer is using Master_current.gdb
wc_public//SpecialAreas2.MapServer is using Master_current.gdb
wc_public//SpecialAreas3.MapServer is using Master_current.gdb
Since the tool ignores print and wants AddMessage, I always use my little script, especially when writing/testing...
# shows messages for python window or tool
def myMsgs(message):
arcpy.AddMessage(message)
print(message)
This may be one of those thing that I either have to write a fancy function for....or just live with it. I'm the only one that runs it right now, so no biggie....but thinking about future and many more services (i.e., when it sites for more than 5 seconds). I have many other options and I may just have to do one of those. I'll leave this open for a bit...but it might end up being a "assumed answered" for lack of real answer.
-------------------------------------------------
EDIT: As a work around, I'll list the info if running from tool
myMsgs("\nFinding STARTED services accesing {0} to STOP".format(updateDS[0]))
for startedService in myServices:
mxdFound = False
if not update: # will print a dot for services or df within mxd that are ok, using for progress status
sys.stdout.write( "." )
arcpy.AddMessage(" Skipping...source not used in {0} ".format(startedService))
How aren't the built-in ArcPy progress dialogs working for you?
HI Joshua, Thanks for the suggestion.
I was just trying to have is show a dot or a # for each service it didn't need to add to my list. I thought it was getting to noisy to list the path/service out for things I was going to skip, and I thought the few second delay may look like it wasn't worked (also wanted it in the Results). After testing what Dan had sent, I decided that not listing them was a bit silly on my part, so I modified my output format and I'm ok with it. It's amazing what and extra space here or there can do to improve readability. So, when all is said and done, my output doesn't look so bad. But it would be nice if there was a way to suppress the newline after a message. Default should be newline....but one in a while....
Re: your question of why I wasn't using arcpy.SetProgressor One...forgot about that command, and two) guess it was because I wanted something simple/clean in the Results, not something in the status area at the bottom, where I think the SetProgressor shows, correct??
For the sake of closing this thread, I ended up going a different route, printing out all the services but for those that match, giving a different message. A snippet (out of context) is
# #####
# ##### Finds running services, filters for those using updated fgdb
# #####
StatusFilter = "STARTED" # other options for function: "STOPPED", "all""
updateServicesList = [] # initialize list
update = False # initial updae status
runningServices = getServiceList(siteURL, theToken, StatusFilter)
#myMsgs("\n{0} services on {1}: \n{2}".format(StatusFilter, server, runningServices)) # will list all services with StatusFilter
myMsgs("\nFinding STARTED services accessing {0} \n Building list....".format(updateDS[0]))
for startedService in runningServices: # Checks service for fgdb use
mxdFound = False # initialize and reset
update = False # initialize and reset
"""if not update: # prints dot for services/df w/in mxd if ok, for progress status
sys.stdout.write( "." )
arcpy.AddMessage(" Skipping...source not used for service: {0} ".format(startedService))
# tried all those below, none worked so using sys.stdout.wrtie(".")
# dot = "." print(dot) , print(".") myMsgs(dot)
"""
#myMsgs("\nReviewing service: {0}".format(startedService)) # can uncomment for debugging
theServicePath = os.path.join(servicesDir, startedService)
if not arcpy.Exists(theServicePath):
myMsgs("theServicePath: {0}".format(theServicePath))
myMsgs(" ...we might have a problem, theServicePath variable doesn't exist")
#showStatus(statusINI, scriptNum, newValue = "ERROR: not done. Fix and rerun")
#sys.exit()
updateStatusAndExit(statusINI, scriptNum)
else:
if ".MapServer" in startedService:
# myMsgs(" {0}".format(startedService)) # Can use if want to list all services
for root, dirs, files in os.walk(theServicePath):
for fname in files:
fullPath = os.path.join(root, fname)
basename, extension = os.path.splitext(fname)
if not extension == ".mxd": # walks thru files to find .mxd
pass
else:
#myMsgs(" mxd file found")
mxd = arcpy.mapping.MapDocument(fullPath)
try:
# Do stuff with MXD using arcpy.mapping
for df in arcpy.mapping.ListDataFrames(mxd):
lyrList = arcpy.mapping.ListLayers(mxd)
mxdFound = True
for lyr in lyrList:
if lyr.isFeatureLayer and update == False:
if lyr.supports("dataSource") and update == False:
theSource = lyr.dataSource
if updateDS[0] in theSource:
update = True
myMsgs(" +Adding {0}".format(startedService)) #, updateDS[0]))
updateServicesList.append(startedService)
break
except AttributeError:
myMsgs("\n !!! WARNING: {0} has unreadable dataframes(s),\n will stop as precaution...\n".format(os.path.basename(mxd.filePath)))
update = True
myMsgs(" +Adding {0}".format(startedService))
updateServicesList.append(startedService)
pass
del mxd
if not update: # prints dot for services/df w/in mxd if ok, for progress status
sys.stdout.write( "." )
myMsgs(" Skipping...source not used for service: {0} ".format(startedService))
# tried all those below, none worked so using sys.stdout.wrtie(".")
# dot = "." print(dot) , print(".") myMsgs(dot)
elif ".GPServer" in startedService:
with lines 52-64 basically what I ended up with. my output is similar to this...
Just in case this helps anyone else.