<?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: Pythonic Code Structure in Python Questions</title>
    <link>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175484#M13488</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;try timing the individual components to see where your bottleneck is.&amp;nbsp; This decorator needs your functions to return something... even if it is nothing.&amp;nbsp; Your functions don't return anything&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;from functools import wraps
#------- decorator -----------------------
def delta_time(func):
&amp;nbsp;&amp;nbsp;&amp;nbsp; """simple timing decorator function"""
&amp;nbsp;&amp;nbsp;&amp;nbsp; @wraps(func)
&amp;nbsp;&amp;nbsp;&amp;nbsp; def wrapper(*args, **kwargs):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t0 = time.time()&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; # start time
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = func(*args, **kwargs)&amp;nbsp; # ... run the function ...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t1 = time.time()&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; # end time
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print("Results for... {}".format(func.__name__))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print("&amp;nbsp; time taken ...{:12.9f} sec.".format(t1-t0))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #print("\n {}".format(result))&amp;nbsp; # uncomment to print within wrapper
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return result&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; # return the result of the function
&amp;nbsp;&amp;nbsp;&amp;nbsp; return wrapper&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;useage... just put the @delta_time line above functions that you want to time&lt;/P&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;@delta_time&amp;nbsp; 
def alpha(input=0):&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; """useless function 1 """&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; return input &lt;/PRE&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Sat, 11 Dec 2021 09:03:19 GMT</pubDate>
    <dc:creator>DanPatterson_Retired</dc:creator>
    <dc:date>2021-12-11T09:03:19Z</dc:date>
    <item>
      <title>Pythonic Code Structure</title>
      <link>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175483#M13487</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I'm busy rewriting my hydrological model python scripts into functions that are modular and found that my original python script runs twice as fast as my updated python script. The only reason I can find is that the original scripts outputs are saved in memory before being passed onto the next function. My new python script is writing and reading each output from disk. I might be incorrect in my understanding. If anyone can give me guidance on improving my new python script in both pythonic structure and performance.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Original Python Script&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 time
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"E:\Python\Temp\Model04\DEM\raw"
rasWs = r"E:\Python\Temp\Model04\Layers04"
outWs = r"E:\Python\Temp\Model04\Model04.gdb"


# Processing time
def hms_string(sec_elapsed):
&amp;nbsp;&amp;nbsp;&amp;nbsp; h = int(sec_elapsed / (60 * 60))
&amp;nbsp;&amp;nbsp;&amp;nbsp; m = int(sec_elapsed % (60 * 60) / 60)
&amp;nbsp;&amp;nbsp;&amp;nbsp; s = sec_elapsed % 60
&amp;nbsp;&amp;nbsp;&amp;nbsp; return "{}h:{:&amp;gt;02}m:{:&amp;gt;05.2f}s".format(h, m, s)


start_time1 = time.time()


# 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.125/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


# Determine the time take to process hydrological characteristics
end_time1 = time.time()
print ("It took {} to process hydrological characteristics".format(hms_string(end_time1 - start_time1)))


arcpy.CheckInExtension("Spatial")&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;New Python Script&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;'''
Created on Feb 24, 2016


@author: PeterW
'''
# import system modules and site packages
import time
from pathlib import Path
import arcpy
import ArcHydroTools


# check out extension
arcpy.CheckOutExtension("Spatial")


# set environment settings
arcpy.env.overwriteOutput = True


# set input and output arguments
dem = r"E:\Python\Temp\Model04\DEM\raw"
raster_workspace = r"E:\Python\Temp\Model04\Layers04"
fgdb = Path(r"E:\Python\Temp\Model04\Model04.gdb")


# Processing time
def hms_string(sec_elapsed):
&amp;nbsp;&amp;nbsp;&amp;nbsp; h = int(sec_elapsed / (60 * 60))
&amp;nbsp;&amp;nbsp;&amp;nbsp; m = int(sec_elapsed % (60 * 60) / 60)
&amp;nbsp;&amp;nbsp;&amp;nbsp; s = sec_elapsed % 60
&amp;nbsp;&amp;nbsp;&amp;nbsp; return "{}h:{:&amp;gt;02}m:{:&amp;gt;05.2f}s".format(h, m, s)


start_time1 = time.time()


# generate fill sinks grid
def&amp;nbsp; fill_sinks(dem, raster_workspace):
&amp;nbsp;&amp;nbsp;&amp;nbsp; fill_sinks = "{0}\\{1}".format(raster_workspace, "fil")
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing Fill Sinks")
&amp;nbsp;&amp;nbsp;&amp;nbsp; ArcHydroTools.FillSinks(dem, fill_sinks)

fill_sinks(dem, raster_workspace)


# generate flow direction grid
def flow_direction(raster_workspace):
&amp;nbsp;&amp;nbsp;&amp;nbsp; fill_sinks = "{0}\\{1}".format(raster_workspace, "fil")
&amp;nbsp;&amp;nbsp;&amp;nbsp; flow_direction = "{0}\\{1}".format(raster_workspace, "fdr")
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing Flow Direction")
&amp;nbsp;&amp;nbsp;&amp;nbsp; ArcHydroTools.FlowDirection(fill_sinks, flow_direction)
&amp;nbsp; 
flow_direction(raster_workspace)


# generate flow accumulation grid
def flow_accumulation(raster_workspace):
&amp;nbsp;&amp;nbsp;&amp;nbsp; flow_direction = "{0}\\{1}".format(raster_workspace, "fdr")
&amp;nbsp;&amp;nbsp;&amp;nbsp; flow_accumulation = "{0}\\{1}".format(raster_workspace, "fac")
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing Flow Accumulation")
&amp;nbsp;&amp;nbsp;&amp;nbsp; ArcHydroTools.FlowAccumulation(flow_direction, flow_accumulation)


flow_accumulation(raster_workspace)


# calculate stream threshold based on 0.5% of maximum flow accumulation
def stream_threshold(raster_workspace):
&amp;nbsp;&amp;nbsp;&amp;nbsp; flow_accumulation = "{0}\\{1}".format(raster_workspace, "fac")&amp;nbsp;&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing Flow Stream Threshold")
&amp;nbsp;&amp;nbsp;&amp;nbsp; maxcellsResult = arcpy.GetRasterProperties_management(flow_accumulation, "MAXIMUM")
&amp;nbsp;&amp;nbsp;&amp;nbsp; maxcells = maxcellsResult.getOutput(0)
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("{} Maximum Cells".format(maxcells))
&amp;nbsp;&amp;nbsp;&amp;nbsp; stream_threshold_numcells = (int(maxcells)*0.5/100)
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("{} Stream Threshold".format(stream_threshold_numcells))
&amp;nbsp;&amp;nbsp;&amp;nbsp; return stream_threshold_numcells


numcells = stream_threshold(raster_workspace)


# generate the stream definition grid
def stream_definition(raster_workspace):
&amp;nbsp;&amp;nbsp;&amp;nbsp; flow_accumulation = "{0}\\{1}".format(raster_workspace, "fac")
&amp;nbsp;&amp;nbsp;&amp;nbsp; stream = "{0}\\{1}".format(raster_workspace, "str")
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing Stream Definition")
&amp;nbsp;&amp;nbsp;&amp;nbsp; ArcHydroTools.StreamDefinition(flow_accumulation, numcells, stream)


stream_definition(raster_workspace)


# generate the stream segmentation grid
def stream_segmentation(raster_workspace):
&amp;nbsp;&amp;nbsp;&amp;nbsp; stream = "{0}\\{1}".format(raster_workspace, "str")
&amp;nbsp;&amp;nbsp;&amp;nbsp; flow_direction = "{0}\\{1}".format(raster_workspace, "fac")
&amp;nbsp;&amp;nbsp;&amp;nbsp; stream_link = "{0}\\{1}".format(raster_workspace, "strlnk")
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing Stream Segmentation")
&amp;nbsp;&amp;nbsp;&amp;nbsp; ArcHydroTools.StreamSegmentation(stream, flow_direction, stream_link)


stream_segmentation(raster_workspace)


# calculate the catchment grid delineation
def catchment_grid(raster_workspace):
&amp;nbsp;&amp;nbsp;&amp;nbsp; flow_direction = "{0}\\{1}".format(raster_workspace, "fdr")
&amp;nbsp;&amp;nbsp;&amp;nbsp; stream_link = "{0}\\{1}".format(raster_workspace, "strlnk")
&amp;nbsp;&amp;nbsp;&amp;nbsp; catchment_grid = "{0}\\{1}".format(raster_workspace, "cat")
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing Catchment Grid Delineation")
&amp;nbsp;&amp;nbsp;&amp;nbsp; ArcHydroTools.CatchmentGridDelineation(flow_direction, stream_link, catchment_grid)


catchment_grid(raster_workspace)


# calculate the catchment polygons from the catchment grid
def catchment_polygon(raster_workspace, fgdb):
&amp;nbsp;&amp;nbsp;&amp;nbsp; catchment_grid = "{0}\\{1}".format(raster_workspace, "cat")
&amp;nbsp;&amp;nbsp;&amp;nbsp; catchment_polygon = "{0}\\{1}".format(Path(fgdb, "Layers"), "Catchment")
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing Catchment Polygon")
&amp;nbsp;&amp;nbsp;&amp;nbsp; ArcHydroTools.CatchmentPolyProcessing(catchment_grid, catchment_polygon)


catchment_polygon(raster_workspace, fgdb)


# calculate the drainage lines from the stream segmentation grid
def drainage_line(raster_workspace, fgdb):
&amp;nbsp;&amp;nbsp;&amp;nbsp; stream_link = "{0}\\{1}".format(raster_workspace, "strlnk")
&amp;nbsp;&amp;nbsp;&amp;nbsp; flow_direction = "{0}\\{1}".format(raster_workspace, "fdr")
&amp;nbsp;&amp;nbsp;&amp;nbsp; drainage_line = "{0}\\{1}".format(Path(fgdb, "Layers"), "DrainageLine")
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing DrainageLine")
&amp;nbsp;&amp;nbsp;&amp;nbsp; ArcHydroTools.DrainageLineProcessing(stream_link, flow_direction, drainage_line)


drainage_line(raster_workspace, fgdb)


# calculate the adjoint catchment polygons
def adjoint_catchment(fgdb):
&amp;nbsp;&amp;nbsp;&amp;nbsp; drainage_line = "{0}\\{1}".format(Path(fgdb, "Layers"), "DrainageLine")
&amp;nbsp;&amp;nbsp;&amp;nbsp; catchment_polygon = "{0}\\{1}".format(Path(fgdb, "Layers"), "Catchment")
&amp;nbsp;&amp;nbsp;&amp;nbsp; adjoint_catchment = "{0}\\{1}".format(Path(fgdb, "Layers"), "AdjointCatchment")
&amp;nbsp;&amp;nbsp;&amp;nbsp; arcpy.AddMessage("Processing Adjoint Catchment")
&amp;nbsp;&amp;nbsp;&amp;nbsp; ArcHydroTools.AdjointCatchment(drainage_line, catchment_polygon, adjoint_catchment)


adjoint_catchment(fgdb)


arcpy.CheckInExtension("Spatial") 


# Determine the time take to process hydrological characteristics
end_time1 = time.time()
print ("It took {} to process hydrological characteristics".format(hms_string(end_time1 - start_time1)))&lt;/PRE&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sat, 11 Dec 2021 09:03:16 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175483#M13487</guid>
      <dc:creator>PeterWilson</dc:creator>
      <dc:date>2021-12-11T09:03:16Z</dc:date>
    </item>
    <item>
      <title>Re: Pythonic Code Structure</title>
      <link>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175484#M13488</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;try timing the individual components to see where your bottleneck is.&amp;nbsp; This decorator needs your functions to return something... even if it is nothing.&amp;nbsp; Your functions don't return anything&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;from functools import wraps
#------- decorator -----------------------
def delta_time(func):
&amp;nbsp;&amp;nbsp;&amp;nbsp; """simple timing decorator function"""
&amp;nbsp;&amp;nbsp;&amp;nbsp; @wraps(func)
&amp;nbsp;&amp;nbsp;&amp;nbsp; def wrapper(*args, **kwargs):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t0 = time.time()&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; # start time
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; result = func(*args, **kwargs)&amp;nbsp; # ... run the function ...
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; t1 = time.time()&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; # end time
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print("Results for... {}".format(func.__name__))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print("&amp;nbsp; time taken ...{:12.9f} sec.".format(t1-t0))
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #print("\n {}".format(result))&amp;nbsp; # uncomment to print within wrapper
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return result&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; # return the result of the function
&amp;nbsp;&amp;nbsp;&amp;nbsp; return wrapper&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;useage... just put the @delta_time line above functions that you want to time&lt;/P&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;@delta_time&amp;nbsp; 
def alpha(input=0):&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; """useless function 1 """&amp;nbsp; 
&amp;nbsp;&amp;nbsp;&amp;nbsp; return input &lt;/PRE&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sat, 11 Dec 2021 09:03:19 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175484#M13488</guid>
      <dc:creator>DanPatterson_Retired</dc:creator>
      <dc:date>2021-12-11T09:03:19Z</dc:date>
    </item>
    <item>
      <title>Re: Pythonic Code Structure</title>
      <link>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175485#M13489</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Dan&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thanks for the following, I'll have a look at the following this evening and get back to you if I get stuck, if that fine with you.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 25 Feb 2016 13:32:27 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175485#M13489</guid>
      <dc:creator>PeterWilson</dc:creator>
      <dc:date>2016-02-25T13:32:27Z</dc:date>
    </item>
    <item>
      <title>Re: Pythonic Code Structure</title>
      <link>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175486#M13490</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Totally unrelated to your problem, but I noticed you are using string processing to build file paths. There is a built in python module that handles this for you, and works across operating systems etc if this is ever a concern.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;In simple terms, it joins parameters, adding a slash in between.&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #000000; font-family: Consolas, 'Courier New', Courier, mono, serif; font-size: 12px; background-color: #f6f6f6;"&gt;&lt;SPAN style="color: #000000; font-family: Consolas, 'Courier New', Courier, mono, serif; font-size: 12px; background-color: #f6f6f6;"&gt; fill_sinks = &lt;/SPAN&gt;&lt;SPAN class="string" style="font-size: 12px; font-family: Consolas, 'Courier New', Courier, mono, serif; color: blue; background-color: #f6f6f6;"&gt;"{0}\\{1}"&lt;/SPAN&gt;&lt;SPAN style="font-size: 12px; font-family: Consolas, 'Courier New', Courier, mono, serif; color: #000000; background-color: #f6f6f6;"&gt;.format(raster_workspace, &lt;/SPAN&gt;&lt;SPAN class="string" style="font-size: 12px; font-family: Consolas, 'Courier New', Courier, mono, serif; color: blue; background-color: #f6f6f6;"&gt;"fil"&lt;/SPAN&gt;&lt;SPAN style="font-size: 12px; font-family: Consolas, 'Courier New', Courier, mono, serif; color: #000000; background-color: #f6f6f6;"&gt;)&amp;nbsp; &lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;Becomes:&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #000000; font-family: Consolas, 'Courier New', Courier, mono, serif; font-size: 12px; background-color: #f6f6f6;"&gt; fill_sinks = &lt;/SPAN&gt;&lt;SPAN style="background-color: #f6f6f6; color: #0000ff; font-size: 12px; font-family: Consolas, 'Courier New', Courier, mono, serif;"&gt;os.path.join&lt;/SPAN&gt;&lt;SPAN style="font-size: 12px; font-family: Consolas, 'Courier New', Courier, mono, serif; color: #000000; background-color: #f6f6f6;"&gt;(raster_workspace, &lt;/SPAN&gt;&lt;SPAN class="string" style="font-size: 12px; font-family: Consolas, 'Courier New', Courier, mono, serif; color: blue; background-color: #f6f6f6;"&gt;"fil"&lt;/SPAN&gt;&lt;SPAN style="font-size: 12px; font-family: Consolas, 'Courier New', Courier, mono, serif; color: #000000; background-color: #f6f6f6;"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;You can also do as many parameters as you like to build longer paths.&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #000000; font-family: Consolas, 'Courier New', Courier, mono, serif; font-size: 12px; background-color: #f6f6f6;"&gt; fill_sinks = &lt;/SPAN&gt;&lt;SPAN style="background-color: #f6f6f6; color: #0000ff; font-size: 12px; font-family: Consolas, 'Courier New', Courier, mono, serif;"&gt;os.path.join&lt;/SPAN&gt;&lt;SPAN style="font-size: 12px; font-family: Consolas, 'Courier New', Courier, mono, serif; color: #000000; background-color: #f6f6f6;"&gt;(raster_workspace, &lt;/SPAN&gt;&lt;SPAN class="string" style="font-size: 12px; font-family: Consolas, 'Courier New', Courier, mono, serif; color: blue; background-color: #f6f6f6;"&gt;"fil", "output", "test.shp"&lt;/SPAN&gt;&lt;SPAN style="font-size: 12px; font-family: Consolas, 'Courier New', Courier, mono, serif; color: #000000; background-color: #f6f6f6;"&gt;)&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN style="color: #0000ff; font-family: Consolas, 'Courier New', Courier, mono, serif; font-size: 12px; background-color: #f6f6f6;"&gt;Returns:&amp;nbsp; '&lt;/SPAN&gt;&lt;SPAN style="color: #0000ff; font-family: Consolas, 'Courier New', Courier, mono, serif; font-size: 12px; background-color: #f6f6f6;"&gt;E:\Python\Temp\Model04\Layers04\fil\output\test.shp'&lt;/SPAN&gt;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 25 Feb 2016 17:07:49 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175486#M13490</guid>
      <dc:creator>LukeWebb</dc:creator>
      <dc:date>2016-02-25T17:07:49Z</dc:date>
    </item>
    <item>
      <title>Re: Pythonic Code Structure</title>
      <link>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175487#M13491</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;If you look at my original Python Script I used os.path.join and decided to move to PathLib Path. The unfortunate thing is that all ArcPy scripts require paths to be string and not objects hence using strings to create the paths from the Path objects.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 25 Feb 2016 18:06:27 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175487#M13491</guid>
      <dc:creator>PeterWilson</dc:creator>
      <dc:date>2016-02-25T18:06:27Z</dc:date>
    </item>
    <item>
      <title>Re: Pythonic Code Structure</title>
      <link>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175488#M13492</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Peter, I suspect most are still using python 2.7.x.&amp;nbsp; For those that are interested, pathlib became available in python 3.4&amp;nbsp; more documentation is given here&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;A href="https://docs.python.org/3/library/pathlib.html" title="https://docs.python.org/3/library/pathlib.html"&gt;11.1. pathlib — Object-oriented filesystem paths — Python 3.5.1 documentation&lt;/A&gt; &lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 25 Feb 2016 18:33:06 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175488#M13492</guid>
      <dc:creator>DanPatterson_Retired</dc:creator>
      <dc:date>2016-02-25T18:33:06Z</dc:date>
    </item>
    <item>
      <title>Re: Pythonic Code Structure</title>
      <link>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175489#M13493</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Yeah.... I'm still on 2.7.x. What's the problem with os.path.join at 3.4? Not having 3.7 installed, but just looking through the documentation and playing around with a&lt;A href="http://ideone.com/" rel="nofollow noopener noreferrer" target="_blank"&gt; 3.x shell online&lt;/A&gt;, it seems that os.path.join returns a string object as it always has. It looks like the new pathlib is a way to store paths as objects instead of as strings so instead of having to do os.path.xyz(), you now may be able to do path.xyz.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Where I'm confused is how this affects the script. At the end of the day, &lt;A href="https://community.esri.com/migrated-users/4495" target="_blank"&gt;Peter Wilson&lt;/A&gt; is just formatting the path object back to a string. I don't see why os.path.join wouldn't have worked here (not that it's better than using the pathlib). Also it looks path has its own ways to concatenate paths.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I went ahead and installed pathlib into 2.7. It looks like you can do this:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;# constructor
p = Path('a', 'b', 'c')
print(p)
# append paths to end with the "/"
p = p / 'd'
print(p)
print(str(p))&lt;/PRE&gt;&lt;P&gt;and it will print&lt;/P&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;WindowsPath('a/b/c)
WindowsPath('a/b/c/d')
a\b\c&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Either way&lt;/P&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;os.path.join
str(Path)&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # and 
"{}".format(Path)&lt;/PRE&gt;&lt;P&gt;should all get you to the same end goal: A string representing a path.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sat, 11 Dec 2021 09:03:22 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175489#M13493</guid>
      <dc:creator>JasonTipton</dc:creator>
      <dc:date>2021-12-11T09:03:22Z</dc:date>
    </item>
    <item>
      <title>Re: Pythonic Code Structure</title>
      <link>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175490#M13494</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Jason&lt;/P&gt;&lt;P&gt;It is an alternate... that is all, the initial question was why Peter was doing it... the answer is because he is using python 3.4 and for his environment, he must prefer it. &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I haven't completed my tests to see how it handles escape characters should one forget to use raw notation (there is a current thread on paths and path constructs and Darren posted a poll).&amp;nbsp; One can also use glob as an alternate to os.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I think pathlib may be an attempt to further unify file handling under multiple platforms and environments.&amp;nbsp; Further testing might reveal advantages that I haven't come across yet.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;ADDENDUM&lt;/P&gt;&lt;P&gt;&lt;A __default_attr="2285" __jive_macro_name="polls" class="jive_macro_polls jive_macro" data-orig-content="How do you write Python path strings?" href="https://community.esri.com/"&gt;&lt;/A&gt; &lt;/P&gt;&lt;P&gt;&lt;A href="https://community.esri.com/migration-blogpost/55463"&gt;Filenames and file paths in Python&lt;/A&gt;&lt;/P&gt;&lt;P&gt;for addition quasi-related materials &lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 25 Feb 2016 21:25:13 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175490#M13494</guid>
      <dc:creator>DanPatterson_Retired</dc:creator>
      <dc:date>2016-02-25T21:25:13Z</dc:date>
    </item>
    <item>
      <title>Re: Pythonic Code Structure</title>
      <link>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175491#M13495</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;UL&gt;&lt;LI&gt;Group all of your methods at the top under imports instead of co-mingling functions and statements.&lt;/LI&gt;&lt;LI&gt;Define your variables once instead of multiple times. (flow_accumulation, flow_direction, etc) assuming they are always the same in every method.&lt;UL&gt;&lt;LI&gt;Line 98 (Script 2): It looks like you assigned flow accumulation "fac" to the flow_direction variable&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;LI&gt;Don't pass RasterWorkspace into every function. Declare it once and use it inside each method.&lt;/LI&gt;&lt;LI&gt;You don't really need methods.&lt;UL&gt;&lt;LI&gt;After you do the previous, the way it is currently written, you really just need print statements in between each statement letting the user know what is going on. Cutting back on recreating the same variable over and over will cut a lot of code out.&lt;/LI&gt;&lt;/UL&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;These won't improve performance*, but will make it more readable, less code to manage, and less code to mess up.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;*It may insignificantly improve by nanoseconds by not having to re-create the same variable over and over again!&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 25 Feb 2016 21:37:44 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175491#M13495</guid>
      <dc:creator>JasonTipton</dc:creator>
      <dc:date>2016-02-25T21:37:44Z</dc:date>
    </item>
    <item>
      <title>Re: Pythonic Code Structure</title>
      <link>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175492#M13496</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I misread his comment. I thought that he had moved from os.path.join to Path because he was having issues with os.path.join() and arcpy. I now see that he moved *in favor* of Path but that arcpy isn't expecting a Path object but a string.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;From a python perspective the Path object is an improvement because you are now dealing with a smarter object than a dumb string. The string doesn't know it is a path so you have to call some function to get the file name or directory or to append a subdirectory to the string. From looking at the methods, it looks like you can even create a directory or check if a path exists or not, all from the object itself without having to call another function.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;As for escape characters, it looks like it doesn't handle them unless you handle them: same as a string or os.path.join(). At the end of the day, I think you're still better off letting python add your slashes and just pass in your directory names in a list and let python make your path for you, whether that be os.path.join(a,b,c,d,e,...) or Path(a,b,c) / d / e / ...&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;# WRONG -- Don't use \t or \a
p = Path("dog\turtle\ant")
p
&amp;gt;&amp;gt; WindowsPath('dog\turtle\x07nt')
print(p)
&amp;gt;&amp;gt; dog&amp;nbsp;&amp;nbsp;&amp;nbsp; urtlent

# RIGHT
p = Path("dog", "turtle", "ant")
p
&amp;gt;&amp;gt; WindowsPath('dog/turtle/ant')
print(p)
&amp;gt;&amp;gt; dog\turtle\ant

# If you need to append, you are using the / operator, not the literal character '/'
p / 'cat' / 'mouse
&amp;gt;&amp;gt; WindowsPath('dog/turtle/ant/cat/mouse')&lt;/PRE&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sat, 11 Dec 2021 09:03:25 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175492#M13496</guid>
      <dc:creator>JasonTipton</dc:creator>
      <dc:date>2021-12-11T09:03:25Z</dc:date>
    </item>
    <item>
      <title>Re: Pythonic Code Structure</title>
      <link>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175493#M13497</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Jason...&lt;/P&gt;&lt;P&gt;Good, this will be useful to know for people working in ArcGIS Pro which is using python 3.4.x.&amp;nbsp; ArcMap 10.4 is sticking with the python 2.7.x version.&amp;nbsp; &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;So as people ... (transition from/stick with )... (ArcMap/ArcGIS Pro) things with become ..(clearer/more confusing).&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Thu, 25 Feb 2016 22:41:45 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175493#M13497</guid>
      <dc:creator>DanPatterson_Retired</dc:creator>
      <dc:date>2016-02-25T22:41:45Z</dc:date>
    </item>
    <item>
      <title>Re: Pythonic Code Structure</title>
      <link>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175494#M13498</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Jason&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thanks for your feedback, its truly appreciated as I'm still a novice when it comes to programming. With regards to your suggestions. Would you mind giving me an example to explain your first suggestion:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Group all of your methods at the top under imports instead of co-mingling functions and statements.&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I only realized once you pointed it out that I was defining my variables multiple times, thanks for pointing it out.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Lastly could you give me some advice how I could create a function that would build my input and output arguments based on the &lt;STRONG&gt;raster workspace&lt;/STRONG&gt; and &lt;STRONG&gt;fgdb&lt;/STRONG&gt;.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 26 Feb 2016 20:29:20 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175494#M13498</guid>
      <dc:creator>PeterWilson</dc:creator>
      <dc:date>2016-02-26T20:29:20Z</dc:date>
    </item>
    <item>
      <title>Re: Pythonic Code Structure</title>
      <link>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175495#M13499</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Peter-&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Your observations about read/write speeds are really important for effective geoprocessing.&amp;nbsp; Since you running in a stand-alone script, you can use the "IN_MEMORY" workspace to speed up many transactions.&amp;nbsp; I'll let you read up on it, but essentially you create a virtual GDB called "IN_MEMORY" and set your environment workspace to reference it.&amp;nbsp; For vector operations you can see huge improvements - raster as well, if you have the memory to support it.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;More generally, I'd look at the read-write configurations on your workstation.&amp;nbsp; Reading and writing to a server will be slow, reading and writing to a local SSD will be fast.&amp;nbsp; You will also see improvements if you can separate out read and write media - e.g. read from one SSD, write to another.&amp;nbsp;&amp;nbsp;&amp;nbsp; If you have lots of RAM, consider defining a RAM disk at the OS level - this will be&amp;nbsp; virtual hard drive that occupies RAM, and will be Very, Very fast.&amp;nbsp; But not as much room (typically ~4 GB for the free RamDisk tools).&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;As mentioned above, there are system profiling tools in Python to diagnose the relative cost of different implementations.&amp;nbsp;&amp;nbsp;&amp;nbsp; You can see dramatic changes in Python processing time by changing from C-based/C-optimized intrinsic functions, to true-Python functions.&amp;nbsp; Again, you can read up on that (especially with respect to iterators and memory models for hash tables).&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Have fun!&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;Daryl&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 26 Feb 2016 20:46:00 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175495#M13499</guid>
      <dc:creator>DarylVan_Dyke</dc:creator>
      <dc:date>2016-02-26T20:46:00Z</dc:date>
    </item>
    <item>
      <title>Re: Pythonic Code Structure</title>
      <link>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175496#M13500</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I'll second Daryl's comments and add that 'IN_MEMORY' can also vastly speed up table operations such as joins, especially when both datasets are 'IN_MEMORY'. The improvements I have documented depend on the tool, but 2-20x improvements are quite common. However, for table manipulation it's still not nearly as fast as storing data in a true SQL database and then doing your SQL operations there. File servers are notoriously slow but I haven't tried splitting my reads/writes between SSDs or using RAMdisk. Thanks for the ideas!&lt;/P&gt;&lt;P&gt;Brian&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Fri, 26 Feb 2016 21:37:03 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175496#M13500</guid>
      <dc:creator>BrianGelder</dc:creator>
      <dc:date>2016-02-26T21:37:03Z</dc:date>
    </item>
    <item>
      <title>Re: Pythonic Code Structure</title>
      <link>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175497#M13501</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Jason&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;After fixing the line 98 incorrect allocation of fac (Flow Accumulation) to Flow Direction, my script completes within the same amount of time as my previous script. I'm going to look into developing a function to allocate the variables automatically as this is standardised. The only input required from the user is the:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Input DEM&lt;/LI&gt;&lt;LI&gt;Raster Folder&lt;/LI&gt;&lt;LI&gt;File Geodatabase&lt;/LI&gt;&lt;/UL&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sat, 27 Feb 2016 18:05:30 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175497#M13501</guid>
      <dc:creator>PeterWilson</dc:creator>
      <dc:date>2016-02-27T18:05:30Z</dc:date>
    </item>
    <item>
      <title>Re: Pythonic Code Structure</title>
      <link>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175498#M13502</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;# imports at top
import os
import arcpy
# etc. . .

# define methods here
def fill_sinks():
&amp;nbsp;&amp;nbsp;&amp;nbsp; # fill sink code

def flow_direction():
&amp;nbsp;&amp;nbsp;&amp;nbsp; # flow direction code

def flow_accumulation():
&amp;nbsp;&amp;nbsp;&amp;nbsp; # flow accumulation code

# etc...

# write your statements inline here, and better yet test for "__main__" first
# to only execute this code if you are executing this file

if __name__ == '__main__'
&amp;nbsp;&amp;nbsp;&amp;nbsp; fill_sinks()
&amp;nbsp;&amp;nbsp;&amp;nbsp; flow_direction()
&amp;nbsp;&amp;nbsp;&amp;nbsp; flow_accumulation()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # etc . . .&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sat, 11 Dec 2021 09:03:27 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175498#M13502</guid>
      <dc:creator>JasonTipton</dc:creator>
      <dc:date>2021-12-11T09:03:27Z</dc:date>
    </item>
    <item>
      <title>Re: Pythonic Code Structure</title>
      <link>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175499#M13503</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Since this isn't a class, only a script, you really don't need to put this in a method. How you did it in your original script would work just fine:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE class="lia-code-sample line-numbers language-none"&gt;# 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") &lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;If you prefer Path, just replace os.path.join(x,y,z) with str(Path(x,y,z)).&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Honestly, for what you are doing, I think you might have over-engineered your solution on the 2nd script. The 1st one didn't look too bad. For performance, make sure everything is working in memory like other people have suggested. Only output it to disk when you are through processing it.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Sat, 11 Dec 2021 09:03:30 GMT</pubDate>
      <guid>https://community.esri.com/t5/python-questions/pythonic-code-structure/m-p/175499#M13503</guid>
      <dc:creator>JasonTipton</dc:creator>
      <dc:date>2021-12-11T09:03:30Z</dc:date>
    </item>
  </channel>
</rss>

