<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Python Functions? in Python Questions</title>
    <link>https://community.esri.com/t5/python-questions/python-functions/m-p/489844#M38315</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;For me, the main reasons to refactor code into functions (and classes, modules, packages...) are readability and reusability.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;On readability - if I have a long script with a number of steps, each with a number of lines of code, I will usually bust each step out into a function so it's easier to follow the overall logic of the script.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;On reusability - if I find myself writing the same code over and over again to do the same thing with different inputs, I will turn that code into a function.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I don't see anything in your code that requires moving into a function.&amp;nbsp; It's a very straightforward script, is very readable and there's nothing in it that is reusable.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;A cautionary note... it's easy to get too caught up in refactoring and go too far. I was recently reviewing another programmers code where &lt;EM&gt;everything&lt;/EM&gt; was a function, and functions called functions which called more functions &lt;EM&gt;ad-infinitum&lt;/EM&gt; and understanding what the script was doing meant jumping all over the place in the file. It was basically unreadable.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Tue, 07 Jul 2015 00:29:19 GMT</pubDate>
    <dc:creator>Luke_Pinner</dc:creator>
    <dc:date>2015-07-07T00:29:19Z</dc:date>
    <item>
      <title>Python Functions?</title>
      <link>https://community.esri.com/t5/python-questions/python-functions/m-p/489842#M38313</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I've been writing Python scripts for a while now, and when a colleague of mine viewed my code, he cringed that it wasn't structured into Python Functions. I'd like some advice from the ESRI community in how I could structure my Python scripts into functions\modules that will make it easier to reuse and call within new scripts. I've attached one of my Python scripts that uses ArcPy and ArcHydro Functions.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;'''
Created on May 20, 2015
@author: PeterW
'''
# import system modules and site packages
import os
import arcpy
import ArcHydroTools
# check out Spatial Analyst Extension
arcpy.CheckOutExtension("Spatial")
# set environment settings
arcpy.env.overwriteOutput = True
# set input and output arguments
raw = r"F:\Projects\2015\G111443\ArcHydro\Methodology_Models\Section03\Sect3A\DEM04\raw"
rasWs = r"F:\Projects\2015\G111443\ArcHydro\Methodology_Models\Section03\Sect3A\Layers04"
outWs = r"F:\Projects\2015\G111443\ArcHydro\Methodology_Models\Section03\Sect3A\Model04.gdb"

# ArcHydro variables
fill_sinks = os.path.join(rasWs, "fil")
flow_dir = os.path.join(rasWs, "fdr")
flow_acc = os.path.join(rasWs, "fac")
streams = os.path.join(rasWs, "str")
stream_seg = os.path.join(rasWs, "strlnk")
catchment_grid = os.path.join(rasWs, "cat")
catchment_poly = os.path.join(outWs, "Layers","Catchment")
drainage_line = os.path.join(outWs, "Layers", "DrainageLine")
adj_catch = os.path.join(outWs, "Layers", "AdjointCatchment")

try:
&amp;nbsp;&amp;nbsp;&amp;nbsp; # calculate the fill sinks
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing Fill Sinks")
&amp;nbsp;&amp;nbsp;&amp;nbsp; ArcHydroTools.FillSinks(raw, fill_sinks)
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; # calculate the flow direction
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing Flow Direction")
&amp;nbsp;&amp;nbsp;&amp;nbsp; ArcHydroTools.FlowDirection(fill_sinks, flow_dir)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; # calculate the flow accumulation
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing Flow Accumulation")
&amp;nbsp;&amp;nbsp;&amp;nbsp; ArcHydroTools.FlowAccumulation(flow_dir, flow_acc)
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; # calculate the maximum flow accumulation
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing Flow Accumulation Maximum")
&amp;nbsp;&amp;nbsp;&amp;nbsp; maxcellsResult = arcpy.GetRasterProperties_management(flow_acc, "MAXIMUM")
&amp;nbsp;&amp;nbsp;&amp;nbsp; maxcells = maxcellsResult.getOutput(0)
&amp;nbsp;&amp;nbsp;&amp;nbsp; print maxcells
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; # calculate the stream threshold number of cells
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing Stream Threshold")
&amp;nbsp;&amp;nbsp;&amp;nbsp; stream_threshold_numcells = (int(maxcells)*0.25/100)
&amp;nbsp;&amp;nbsp;&amp;nbsp; print stream_threshold_numcells
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; # calculate the stream definition
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing Stream Definition")
&amp;nbsp;&amp;nbsp;&amp;nbsp; ArcHydroTools.StreamDefinition(flow_acc, stream_threshold_numcells, streams)
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; # calculate the stream segmentation
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing Stream Segmentation")
&amp;nbsp;&amp;nbsp;&amp;nbsp; ArcHydroTools.StreamSegmentation(streams, flow_dir, stream_seg)
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; # calculate the catchment grid delineation
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing Catchment Grid Delineation")
&amp;nbsp;&amp;nbsp;&amp;nbsp; ArcHydroTools.CatchmentGridDelineation(flow_dir, stream_seg, catchment_grid)
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; # calculate the catchment polygons from the catchment grid
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing Catchment Polygons")
&amp;nbsp;&amp;nbsp;&amp;nbsp; ArcHydroTools.CatchmentPolyProcessing(catchment_grid, catchment_poly)
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; # calculate the drainage lines from the stream segmentation grid
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing DrainageLines")
&amp;nbsp;&amp;nbsp;&amp;nbsp; ArcHydroTools.DrainageLineProcessing(stream_seg, flow_dir, drainage_line)
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; # calculate the adjoint catchment polygons
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing Ajdoint Catchments")
&amp;nbsp;&amp;nbsp;&amp;nbsp; ArcHydroTools.AdjointCatchment(drainage_line, catchment_poly, adj_catch)
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Completed Processing ArcHydro Main Model")
except:
&amp;nbsp;&amp;nbsp;&amp;nbsp; print(arcpy.GetMessages(2))
&amp;nbsp;&amp;nbsp;&amp;nbsp; pass
arcpy.CheckInExtension("Spatial")&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Any advice and assistance will be appreciated.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Regards&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Peter Wilson&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sat, 11 Dec 2021 21:33:30 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/python-functions/m-p/489842#M38313</guid>
      <dc:creator>PeterWilson</dc:creator>
      <dc:date>2021-12-11T21:33:30Z</dc:date>
    </item>
    <item>
      <title>Re: Python Functions?</title>
      <link>https://community.esri.com/t5/python-questions/python-functions/m-p/489843#M38314</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I'm not one to answer this in full, but I have a few files that I read in each time (thanks to &lt;A href="https://community.esri.com/migrated-users/14792" target="_blank"&gt;Freddie Gibson&lt;/A&gt;​ and/or &lt;A href="https://community.esri.com/migrated-users/3200" target="_blank"&gt;Jeff Barrette&lt;/A&gt; ) that take care of a few things for me.&lt;/P&gt;&lt;OL&gt;&lt;LI&gt;a util file that takes care of the arcpy.AddMessage vs. the debugging print statement; appends a datetime to the message (since that isn't always done), and creates a log file. (mine is called ADFGutils.py)&lt;/LI&gt;&lt;LI&gt;a "decorator" file that takes care of the try...except part for me. (gpdecorators.py)&lt;/LI&gt;&lt;/OL&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;These can be place in the&amp;nbsp; (example)&amp;nbsp; c:\Python27\ArcGIS10.3\Lib folder, or in another relative location to your calling script.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;the ADFGutils.py (...named for my dept, but you can name whatever you want)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/P&gt;&lt;P&gt;call in your program:&amp;nbsp;&amp;nbsp; &lt;/P&gt;&lt;UL&gt;&lt;LI&gt;from ADFGutils import *&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;Use&amp;nbsp; similar to print or arcpy.addMessage&amp;nbsp;&amp;nbsp; (may duplicate the message in some debuggers)&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;myMsgs()&lt;/LI&gt;&lt;/UL&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;import time
import arcpy
import os
from time import localtime

def timeStamp():
&amp;nbsp;&amp;nbsp;&amp;nbsp; """
&amp;nbsp;&amp;nbsp;&amp;nbsp; returns time stamp.
&amp;nbsp;&amp;nbsp;&amp;nbsp; """
&amp;nbsp;&amp;nbsp;&amp;nbsp; return time.strftime(' --&amp;nbsp; %B %d - %H:%M:%S')

def myMsgs(message):
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage(message + ' %s' %(timeStamp()))
&amp;nbsp;&amp;nbsp;&amp;nbsp; print(message + ' %s' %(timeStamp()))

&amp;nbsp;&amp;nbsp;&amp;nbsp; global messageCount
&amp;nbsp;&amp;nbsp;&amp;nbsp; logFolder = r"C:\ESRITEST"
&amp;nbsp;&amp;nbsp;&amp;nbsp; if not arcpy.Exists(logFolder):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.CreateFolder_management(os.sep.join(logFolder.split(os.sep)[:-1]), logFolder.split(os.sep)[-1])
&amp;nbsp;&amp;nbsp;&amp;nbsp; mdy = curDate()
&amp;nbsp;&amp;nbsp;&amp;nbsp; logName = "logfile_" + "_".join(mdy.split("/")) + ".log"
&amp;nbsp;&amp;nbsp;&amp;nbsp; logFile = open(os.path.join(logFolder, logName), "a")&amp;nbsp; #a=append, w=create new
&amp;nbsp;&amp;nbsp;&amp;nbsp; if message.lower() == "blank line":
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; logFile.write("\n\n")
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print "\n\n"
&amp;nbsp;&amp;nbsp;&amp;nbsp; elif message.lower() == "close logfile":
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; logFile.write("\n\n*****&amp;nbsp; finished&amp;nbsp; *****\n\n")
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; logFile.close()
&amp;nbsp;&amp;nbsp;&amp;nbsp; else:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; messageCount += 1
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; logFile.write("0" * (5 - len(str(messageCount))) + str(messageCount) + ".&amp;nbsp;&amp;nbsp; ")
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; logFile.write(message)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; logFile.write("\n")
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #print message
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #arcpy.AddMessage(message)

def curDate():
&amp;nbsp;&amp;nbsp;&amp;nbsp; rawTime = localtime()
&amp;nbsp;&amp;nbsp;&amp;nbsp; yr = str(rawTime[0]) # Collect the year from the rawTime variable
&amp;nbsp;&amp;nbsp;&amp;nbsp; mo = str(rawTime[1]) # Collect the month from the rawTime variable
&amp;nbsp;&amp;nbsp;&amp;nbsp; dy = str(rawTime[2]) # Collect the day from the rawTime variable
&amp;nbsp;&amp;nbsp;&amp;nbsp; return "/".join([mo, dy, yr])

messageCount = 0
&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The gpdecorator.py&lt;/P&gt;&lt;P style="padding-left: 60px;"&gt;To call in your program&lt;/P&gt;&lt;UL style="padding-left: 60px;"&gt;&lt;LI style="padding-left: 60px;"&gt;from gpdecorators import *&lt;/LI&gt;&lt;/UL&gt;&lt;P style="padding-left: 60px;"&gt;To use....at the&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;# catch_errors decorator must preceed a function using the @ notation.&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;@catch_errors&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;def main():&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; """&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Main function to create the new master feature dataset.&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; """&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Script arguments...&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;&amp;nbsp;&amp;nbsp; '''.......your program'''&lt;/P&gt;&lt;P style="padding-left: 120px;"&gt;&lt;/P&gt;&lt;TABLE style="padding-left: 60px;"&gt;&lt;TBODY style="padding-left: 60px;"&gt;&lt;TR style="padding-left: 60px;"&gt;&lt;TD style="padding-left: 60px;"&gt;&lt;/TD&gt;&lt;TD style="padding-left: 60px;"&gt;myMsgs('!!! Success !!!&amp;nbsp; ')&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;P style="padding-left: 60px;"&gt;&lt;/P&gt;&lt;P style="padding-left: 60px;"&gt;# End main function&lt;/P&gt;&lt;P style="padding-left: 60px;"&gt;&lt;/P&gt;&lt;P style="padding-left: 60px;"&gt;if __name__ == '__main__':&lt;/P&gt;&lt;P style="padding-left: 60px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; main()&lt;/P&gt;&lt;P style="padding-left: 60px;"&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;"""
A decorator to wrap error handling.
"""
import sys as _sys
import traceback as _traceback
import arcpy

def catch_errors(func):
&amp;nbsp;&amp;nbsp;&amp;nbsp; """
&amp;nbsp;&amp;nbsp;&amp;nbsp; Decorator function to support error handling
&amp;nbsp;&amp;nbsp;&amp;nbsp; """
&amp;nbsp;&amp;nbsp;&amp;nbsp; def decorator(*args, **kwargs):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; """
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Decorator function
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; """
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; f = func(*args, **kwargs)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return f
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; except Exception:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tb = _sys.exc_info()[2]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; tbInfo = _traceback.format_tb(tb)[-1]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddError('PYTHON ERRORS:\n%s\n%s: %s\n' %
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (tbInfo, _sys.exc_type, _sys.exc_value))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print('PYTHON ERRORS:\n%s\n%s: %s\n' %
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (tbInfo, _sys.exc_type, _sys.exc_value))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; gp_errors = arcpy.GetMessages(2)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if gp_errors:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddError('GP ERRORS:\n%s\n' % gp_errors)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print('GP ERRORS:\n%s\n' % gp_errors)
&amp;nbsp;&amp;nbsp;&amp;nbsp; # End decorator function
&amp;nbsp;&amp;nbsp;&amp;nbsp; return decorator
# End catch_errors function

if __name__ == '__main__':
&amp;nbsp;&amp;nbsp;&amp;nbsp; pass&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;That may not be all your colleague was pointing out, but I know those help me.&amp;nbsp; These most likely could be in one file, btw, but I've never combined them. fwiw.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sat, 11 Dec 2021 21:33:33 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/python-functions/m-p/489843#M38314</guid>
      <dc:creator>RebeccaStrauch__GISP</dc:creator>
      <dc:date>2021-12-11T21:33:33Z</dc:date>
    </item>
    <item>
      <title>Re: Python Functions?</title>
      <link>https://community.esri.com/t5/python-questions/python-functions/m-p/489844#M38315</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;For me, the main reasons to refactor code into functions (and classes, modules, packages...) are readability and reusability.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;On readability - if I have a long script with a number of steps, each with a number of lines of code, I will usually bust each step out into a function so it's easier to follow the overall logic of the script.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;On reusability - if I find myself writing the same code over and over again to do the same thing with different inputs, I will turn that code into a function.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I don't see anything in your code that requires moving into a function.&amp;nbsp; It's a very straightforward script, is very readable and there's nothing in it that is reusable.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;A cautionary note... it's easy to get too caught up in refactoring and go too far. I was recently reviewing another programmers code where &lt;EM&gt;everything&lt;/EM&gt; was a function, and functions called functions which called more functions &lt;EM&gt;ad-infinitum&lt;/EM&gt; and understanding what the script was doing meant jumping all over the place in the file. It was basically unreadable.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Tue, 07 Jul 2015 00:29:19 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/python-functions/m-p/489844#M38315</guid>
      <dc:creator>Luke_Pinner</dc:creator>
      <dc:date>2015-07-07T00:29:19Z</dc:date>
    </item>
    <item>
      <title>Re: Python Functions?</title>
      <link>https://community.esri.com/t5/python-questions/python-functions/m-p/489845#M38316</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Luke&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thanks for you advice, it's truly appreciated. Is there anyway of better handling my Arc Hydro Variables. The inputs\outputs are either rasters or feature classes\tables and they are being read\written to two workspaces.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The rasters are being saved or read from a single folder and the feature classes\tables are being saved or read from a File Geodatabase.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Regards&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Peter Wilson&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Tue, 07 Jul 2015 08:24:34 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/python-functions/m-p/489845#M38316</guid>
      <dc:creator>PeterWilson</dc:creator>
      <dc:date>2015-07-07T08:24:34Z</dc:date>
    </item>
    <item>
      <title>Re: Python Functions?</title>
      <link>https://community.esri.com/t5/python-questions/python-functions/m-p/489846#M38317</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P style="font-family: arial, helvetica, 'helvetica neue', verdana, sans-serif;"&gt;I would like to agree with your cautionary note. Also, regarding OOP, I always keep this in mind:&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;TABLE border="1"&gt;&lt;TBODY&gt;&lt;TR&gt;&lt;TD&gt;&lt;BLOCKQUOTE class="templatequote" style="font-family: sans-serif; color: #252525;"&gt;&lt;P style="margin-top: 0.5em; margin-bottom: 0.5em; font-weight: inherit; font-style: inherit; font-family: inherit;"&gt;The problem with object-oriented languages is they've got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.&lt;/P&gt;&lt;P style="margin-top: 0.5em; margin-bottom: 0.5em; font-weight: inherit; font-style: inherit; font-family: inherit;"&gt;-Joe Armstrong&lt;SPAN style="font-weight: inherit; font-style: inherit;"&gt;, developer of &lt;/SPAN&gt;Erlang programming language.&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;/TD&gt;&lt;/TR&gt;&lt;/TBODY&gt;&lt;/TABLE&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;I like OOP, I do, but sometimes I've seen cases where this has definitely been true. &lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Tue, 07 Jul 2015 13:58:25 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/python-functions/m-p/489846#M38317</guid>
      <dc:creator>ChrisSmith7</dc:creator>
      <dc:date>2015-07-07T13:58:25Z</dc:date>
    </item>
    <item>
      <title>Re: Python Functions?</title>
      <link>https://community.esri.com/t5/python-questions/python-functions/m-p/489847#M38318</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Peter, your variables look fine to me.&amp;nbsp; The only suggestion I might make is to pass your inputs in to the script using arguments and access them with &lt;SPAN style="font-family: courier new,courier;"&gt;sys.argv&lt;/SPAN&gt; or &lt;SPAN style="font-family: courier new,courier;"&gt;arcpy.GetParameterAsText&lt;/SPAN&gt;. And I'd only recommend that if you're going to be using the code as a commandline or ArcToolbox script tool and you may want to use different inputs/workspaces when running the code.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I write code that ranges from simple step-by-step scripts to large libraries that are spread across multiple files in python packages.&amp;nbsp; Here's how I roughly think about when deciding whether to modularise/refactor code:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;For straightforward scripts, I will hardcode variables such as you have done.&lt;/LI&gt;&lt;LI&gt;If I want to reuse the script with different inputs, I will pass the inputs as parameters/arguments and access them with &lt;SPAN style="font-family: courier new,courier;"&gt;sys.argv&lt;/SPAN&gt; or &lt;SPAN style="font-family: courier new,courier;"&gt;arcpy.GetParameterAsText&lt;/SPAN&gt;&lt;/LI&gt;&lt;LI&gt;If it's a long and complex script, I might turn some of the steps into functions to enhance readability or if I want to reuse a bit of code within the script&lt;/LI&gt;&lt;LI&gt;if parts of the code could be reused in other scripts, I will turn that bit of code into a function or class and put it in a module that can be imported. I'll group similar bits of code in individual modules, i.e a module for statistics related code, one for certain types of filesystem IO, one for geometry operations, one for interacting with ArcObjects, etc...&lt;/LI&gt;&lt;/UL&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 08 Jul 2015 22:54:08 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/python-functions/m-p/489847#M38318</guid>
      <dc:creator>Luke_Pinner</dc:creator>
      <dc:date>2015-07-08T22:54:08Z</dc:date>
    </item>
    <item>
      <title>Re: Python Functions?</title>
      <link>https://community.esri.com/t5/python-questions/python-functions/m-p/489848#M38319</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I don't have any comments regarding the formatting/structure of the code.&amp;nbsp; I think others have already provided good feedback on that topic.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;In taking a quick look over your code, I do have a couple questions regarding content, if you are open to discussing content as well as structure.&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;What is the purpose of the &lt;SPAN style="font-family: courier new,courier;"&gt;pass&lt;/SPAN&gt; statement on Line #80 or what do you think it is doing?&lt;/LI&gt;&lt;LI&gt;Seeing the use of ArcPy messaging, I assume you are running this as a script tool.&amp;nbsp; Am I right?&lt;UL&gt;&lt;LI&gt;I ask because the current structure of the code will basically hide errors from the user, i.e., the Results window will always show the script as completing even if it generated an error and didn't complete.&amp;nbsp; As &lt;A href="https://www.python.org/dev/peps/pep-0020/"&gt;The Zen of Python &lt;/A&gt;states: "Errors should never pass silently."&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 09 Jul 2015 20:03:39 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/python-functions/m-p/489848#M38319</guid>
      <dc:creator>JoshuaBixby</dc:creator>
      <dc:date>2015-07-09T20:03:39Z</dc:date>
    </item>
  </channel>
</rss>

