Select to view content in your preferred language

How to pass arguments to function in module?

7067
10
Jump to solution
05-29-2019 10:15 AM
ZacharyHart
Honored Contributor

I know there's a ton of other material here and @ SE regarding this subject, but conceptually i'm just stuck. In an effort to improve the modularity of my code, I'm trying to get better at importing existing functions into scripts. I'm stuck on successfully passing arguments captured within the script to the imported module. Ideally I just want to use the script and pass it a handful of client identifiers (arguments) and have those cascade down into several modules called up in  the script. Like: functiontest2('identifier')

some crude code:

functiontest2.py

from HarvestTable import HarvestTableReport
import sys
HarvestThing = sys.argv[1]

HarvestTableReport(HarvestThing)
‍‍‍‍‍

HarvestTable.py

import numpy as np
import pandas as pd
import arcpy
    
def HarvestTableReport(HarvestID):
    table = "\\\\fileshare\SDE_CONNECTIONS\\LV_NEXUS.sde\\LV_NEXUS.DATAOWNER.NORTHEAST\\clientGDB.featureclass"
    HUID = HarvestID
    whereClause = """ "LV_HARVEST_UNIT_ID" = '{0}' """.format(HUID)
    tableArray = arcpy.da.TableToNumPyArray(table, ['SUPER_TYPE','STRATA', 'OS_TYPE', 'STAND_NUMB', 'SILV_PRES', 'ACRES'], where_clause = whereClause)
    df = round(pd.DataFrame(tableArray),1)
    report = df.groupby(['SUPER_TYPE']).apply(lambda sub_df:  sub_df.pivot_table(index=['STRATA', 'OS_TYPE', 'STAND_NUMB', 'SILV_PRES'], values=['ACRES'],aggfunc=np.sum, margins=True,margins_name= 'TOTAL'))
    # this is creating a new row at level(1) called grand total
    # set it equal to the sum of ACRES where level(1) != 'Total' so you are not counting the  calculated totals in the total sum
    report.loc[('', 'GRAND TOTAL','','',''), :] = report[report.index.get_level_values(1) != 'TOTAL'].sum()
    print(whereClause)
    return np.round(report,1)
    
if __name__ == '__main__':
    HarvestTableReport()‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
10 Replies
LukeWebb
Frequent Contributor

You are basically there and its looking good!

Im probably using incorrect concepts for advanced/correct coding, but I like to keep it simpler!

What you have basically created in your file functiontest2.py   is what I like to call an interface or GUI. 

I would rename this file:

harvest_report_commandline.py

from HarvestTable import HarvestTableReport
import sys
HarvestThing = sys.argv[1]

HarvestTableReport(HarvestThing)

Now to run this, you run it from cmd as you are probably familiar, passing in the sys argument.

Often, I would then make another interface/gui file, so that I can easily test it inside an IDE. Something like this:

harvest_report_python.py

from HarvestTable import HarvestTableReport

HarvestThing = 'MY ID'
HarvestTableReport(HarvestThing)

Further down the line, I would also make a .tbx file, so it works inside arcmap as a toolbox! Something like:

harvest_report_ArcTool.py

class harvestArcToolGUI(object):
    def __init__(self):
        self.label = 'Harvest Report'
        self.description = 'Get your report here!'

        self.parameters = [
            parameter('Harvest ID', 'HarvestID', 'String'),
        ]

    def execute(self, parameters, messages):
        '''
        Reference the business logic captured in your object defined
        separately in the module, preferably above.
        '''

        inHarvestID = parameters[0].value

        ###Tool Logic

        execTool = HarvestTable.HarvestTableReport (inHarvestID)

        return







Now, if you make changes to the orginal HarvestTable.py,    all the other interfaces will be running the updated code.