Python: calling three functions in one script?

1672
3
12-01-2016 11:50 AM
JaredPilbeam1
Occasional Contributor

I have three consecutive scripts that 1) update features in a map, 2) zip them, then copy them to a new folder, 3) append a .txt file to the zip. But, I can't quite grasp how to run all of them in order. I ran RemoveAddLayer.py assuming I was calling the other two scripts correctly. There was an error(s) (see very bottom).

###RemoveAddLayer.py###

import arcpy
import os
from arcpy import env

#import functions
import ZipFiles
import Append2Zip

arcpy.overwriteOutput = True

env.workspace = r"Database Connections\ims to plainfield.sde\gisedit.DBO.MGU_Will"

#set path to mxd 
mxd = arcpy.mapping.MapDocument(r"Z:\Jared\Data_Request.mxd")

#reference the dataframe
for df in arcpy.mapping.ListDataFrames(mxd):
    print df
    #reference the layers to be removed
    for lyr in arcpy.mapping.ListLayers(mxd, "gisedit.DBO.Address_Points", df):
        arcpy.mapping.RemoveLayer(df, lyr)
        print lyr
        for lyr in arcpy.mapping.ListLayers(mxd, "gisedit.DBO.Street", df):
            arcpy.mapping.RemoveLayer(df, lyr)
            print lyr
            #reference the layers to be added
            addLayer = arcpy.mapping.Layer(r"Database Connections\ims to plainfield.sde\gisedit.DBO.MGU_Will\gisedit.DBO.Address_Points")
            arcpy.mapping.AddLayer(df, addLayer, "TOP")
            print addLayer
            addLayer = arcpy.mapping.Layer(r"Database Connections\ims to plainfield.sde\gisedit.DBO.MGU_Will\gisedit.DBO.Street")
            arcpy.mapping.AddLayer(df, addLayer, "TOP")
            print addLayer
            
            #delete old files
            if arcpy.Exists("WillCounty_AddressPoint"):
                arcpy.Delete_management("WillCounty_AddressPoint")

                if arcpy.Exists("WillCounty_Street"):
                    arcpy.Delete_management("WillCounty_Street")

                    #address points variables to be copied/saved in folder
                    inFeatures = "gisedit.DBO.Address_Points"
                    outLocation = r"Z:\Jared\Python Scripts\Data"
                    outFeatureClass = "WillCounty_AddressPoint"
                    
                    #execute and copy/save in folder. FeatureClassToFeatureClass_conversion syntax (in_features, out_path, out_name,
                    #{where_clause}, {field_mapping}, {config_keyword})
                    arcpy.FeatureClassToFeatureClass_conversion(inFeatures, outLocation, outFeatureClass)
                    print "finished Address_Point.shp"

                    #variables to be copied/saved in folder
                    inFeatures = "gisedit.DBO.Street"
                    outLocation = r"Z:\Jared\Python Scripts\Data"
                    outFeatureClass = "WillCounty_Street"

                    #execute and copy/save in folder. FeatureClassToFeatureClass_conversion syntax (in_features, out_path, out_name,
                    #{where_clause}, {field_mapping}, {config_keyword})
                    arcpy.FeatureClassToFeatureClass_conversion(inFeatures, outLocation, outFeatureClass)
                    print "finished Street.shp"
del mxd

if __name__ == '__main__':

    path = r"Z:\Jared\Python Scripts\Data"
    
    out_path = r"W:\Data"

    ZipShapes(path, out_path)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

###ZipFiles.py

import arcpy
import os
from arcpy import env
from os import path as p
import zipfile

def ZipShapes(path, out_path):
    arcpy.env.workspace = path
    shapes = arcpy.ListFeatureClasses()

#iterate through list of shapefiles
    for shapes in shapes:
        name = p.splitext(shapes)[0]
        print name
        print shapes
        zip_path = p.join(out_path, name + '.zip')
        zip = zipfile.ZipFile(zip_path, 'w', compression=zipfile.ZIP_DEFLATED)
        zip.write(p.join(path,shapes), shapes)
        for f in arcpy.ListFiles('%s*' %name):
            if not f.endswith('.shp'):
                zip.write(p.join(path,f),f)
        print 'All file written to %s' %zip_path
        zip.close()‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

###Append2Zip.py

def append2Zip(zipfolder, path): # define function; name of function followed by any arguments in ()
    print 'Appending to ' + zipfolder
    zf = zipfile.ZipFile(zipfolder, mode= 'a')
    try:
        zf.write(path, os.path.basename(path))
    finally:
        zf.close()

path = r'Z:\Jared\Disclaimer - Final.txt'
zipfolders = [r'W:\Data\WillCounty_AddressPoint.zip', r'W:\Data\WillCounty_Street.zip'] #list of zip folders

for zipfolder in zipfolders: # loop through zipfolders
    append2Zip(zipfolder, path) #call function above‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Tags (3)
0 Kudos
3 Replies
DanPatterson_Retired
MVP Emeritus
from ZipFiles import ZipShapes as z_shp
from Append2Zip import appendtozip as a2z

from module import function, otherwise the useage in the main script is

the_returned = ZipFiles.z_shp( the stuff)

instead of

the_returned = z_shp( the stuff)

You just have to watch namespace, in your case the chance of running into a module or function conflict are minimal.  In practice, I tend to use

preference I suppose

import mymodule as my
# assume there is a function called zip_stuff
returned = my.zip_stuff( ...parameters go here...)
DanPatterson_Retired
MVP Emeritus

PS... you might want to have a look at this

/blogs/dan_patterson/2016/11/08/documenting-functions-and-functions-for-documenting 

to get some idea about documentation and retrieving documentation from functions and the like.  Could save you a whole load of grief

Luke_Pinner
MVP Regular Contributor

The cause of your actual error is not importing the zipfile module in Append2Zip.py, but that is the least of your worries.

Have a read of 6. Modules — Python 2.7.13 documentation 

You've got quite a mess there. A script calling functions from another module that contains code that will get executed when the module is imported is a big issue and will come back and bite you in the future.  Make sure you understand what 'if __name__ == "__main__:' is doing, any code that is outside this if statement will get run when the module is imported.

For example, the code in Append2Zip.py will get executed when it's imported, i.e before your RemoveAddLayer and ZipFiles.ZipShape code.

Without spending ages rewriting your script for you, here is the simplest way to fix your code:

###RemoveAddLayer.py##

#import arcpy
import os
from arcpy import env

#import functions
import ZipFiles
import Append2Zip

def RemoveAddLayer
    #your remove addlayer code
    
if __name__ == "__main__:    
    RemoveAddLayer()
    
    path = r"Z:\Jared\Python Scripts\Data"    
    out_path = r"W:\Data"    
    ZipFiles.ZipShapes(path, out_path)    
    
    path = r'Z:\Jared\Disclaimer - Final.txt'        
    zipfolders = [r'W:\Data\WillCounty_AddressPoint.zip', r'W:\Data\WillCounty_Street.zip'] #list of zip folders        
    for zipfolder in zipfolders: # loop through zipfolders           
        Append2Zip.append2Zip(zipfolder, path) #call function above?????????????????????????