Python Forum

Full Version: argument parser: to execute single function, and subsequent functions also
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
Do we have any options in argument parser or any other way for continuing the execution from that respective position till the end of the code, on providing a command-line argument? Also the other way of executing only that function.

I have a simple script as below. When I execute with "script.py -f_2" it does execute only function_2. But I want to execute all the subsequent functions function_3 & function_4 as well till the end. How can I achieve both functionality like executing only that function and sometimes along with subsequent functions?

This script also read's and writes content from a file called sample_update.ini using config parser.

import sys
import os
import math
import alert
import ConfigParser
import argparse
from alert import alert_user

configParser = ConfigParser.ConfigParser()
configParser.add_section('Input')
configParser.add_section('Output')
configParser.read('sample_updated.ini')


def function_1(a, b):
    c = a + b
    # write to ini file
    print "input_1 of function_1: ", a
    print "input_2 of function_1: ", b
    print "output of function_1: ", c
    configParser.set('Input', 'function_1_1', str(a))
    configParser.set('Input', 'function_1_2', str(b))
    configParser.set('Output', 'function_1', str(c))
    return c

def function_2(c, b):
    d = c * b
    # write to ini file
    print "input_1 of function_2: ", c
    print "input_2 of function_2: ", b
    print "output of function_2: ", d

    configParser.set('Output', 'function_2', str(d))
    return d

def function_3(d, c):
    e = d / c
    # write to ini file
    print "input_1 of function_3: ", d
    print "input_2 of function_3: ", c
    print "output of function_3: ", e

    configParser.set('Output', 'function_3', str(e))
    return e

def function_4(d, e):
    f = d - e
    # write to ini file
    print "input_1 of function_4: ", d
    print "input_2 of function_4: ", e
    print "output of function_4: ", f

    configParser.set('Output', 'function_4', str(f))
    return f

if __name__ == '__main__':

    a = input("value of a: ")

    b = input("value of b: ")

    parser = argparse.ArgumentParser()

    # create argument parser

    parser.add_argument('-f_2', action='store_true', default=None, dest='function_2', help="execute from function_2")

    parser.add_argument('-f_3', action='store_true', default=None, dest='function_3', help="execution starts from function_3")

    parser.add_argument('-f_4', action='store_true', default=None, dest='function_4', help="execution starts from function_4")

    cmd_arguments = parser.parse_args()

    # print selected functions

    if cmd_arguments.function_2:
        function_2(configParser.getint('Output', 'function_1'), b)

    if cmd_arguments.function_3:
        function_3(configParser.getint('Output', 'function_2'), 

    if cmd_arguments.function_4:
        function_4(configParser.getint('Output', 'function_2'), configParser.getint('Output', 'function_3'))

    if not len(sys.argv) > 1:
        # store function outputs
        function_1(a, b)
        function_2(configParser.getint('Output', 'function_1'), b)
        function_3(configParser.getint('Output', 'function_2'), configParser.getint('Output', 'function_1'))
        function_4(configParser.getint('Output', 'function_2'), configParser.getint('Output', 'function_3'))

    with open('sample_updated.ini', 'w') as configfile:
        configParser.write(configfile)
If above script is not clear with the expected output. Below is the actual script which writes and reads variables from and to .ini file.

Someone help me to make changes in code. which should execution from function_3 till end of code when i give some argument as commandline while running the script.

import sys
import os
import math
import alert
import ConfigParser
import argparse
from alert import alert_user

configParser = ConfigParser.ConfigParser()
configParser.add_section('Input')
configParser.add_section('Output')
configParser.read('sample_updated.ini')


def function_1(a, b):
    c = a + b
    # write to ini file
    print "input_1 of function_1: ", a
    print "input_2 of function_1: ", b
    print "output of function_1: ", c
    configParser.set('Input', 'function_1_1', str(a))
    configParser.set('Input', 'function_1_2', str(b))
    configParser.set('Output', 'function_1', str(c))
    return c


def function_2(c, b):
    d = c * b
    # write to ini file
    print "input_1 of function_2: ", c
    print "input_2 of function_2: ", b
    print "output of function_2: ", d

    configParser.set('Output', 'function_2', str(d))
    return d


def function_3(d, c):
    e = d / c
    # write to ini file
    print "input_1 of function_3: ", d
    print "input_2 of function_3: ", c
    print "output of function_3: ", e

    configParser.set('Output', 'function_3', str(e))
    return e


def function_4(d, e):
    f = d - e
    # write to ini file
    print "input_1 of function_4: ", d
    print "input_2 of function_4: ", e
    print "output of function_4: ", f

    configParser.set('Output', 'function_4', str(f))
    return f

if __name__ == '__main__':

    a = input("value of a: ")
    b = input("value of b: ")

    function_1(a, b)
    function_2(configParser.getint('Output', 'function_1'), b)
    function_3(configParser.getint('Output', 'function_2'), configParser.getint('Output', 'function_1'))
    function_4(configParser.getint('Output', 'function_2'), configParser.getint('Output', 'function_3'))

    with open('sample_updated.ini', 'w') as configfile:
        configParser.write(configfile)
Use if/elif/else.

if parser.function_1:
    function_1()
    function_2()
    function_3()
    # etc.
elif parser.function_2:
    function_2()
    function_3()
    # etc.
# ....
else:
    # run all or do something else. whatever
Or you can put the functions to a list or tuple and iterate over them:

funcs = (function_1, function_2, function_3, function_4)

if parser.function_1:
    _ = [function() for function in funcs]
elif parser.function_2:
    _ = [function() for function in funcs[1:]]
elif parser.function_3:
    _ = [function() for function in funcs[2:]]
# etc.
I'm going to suggest a slightly different approach. How about if you allowed options such as -f 1 2 3? Meaning, run function_1(), then function_2(), followed by function_3().

This can be done with a single add_argument like this:
parser.add_argument("-f", nargs='+', default=[])
nargs='+' means any number of args, but at least 1. You can also use nargs='*' to mean any number, including 0. Including default=[] is nice because then your code doesn't have keep testing first if cmd_arguments.f == None.

The namespace object returned by parse_args() (cmd_arguments in your example) will have a member named f of type list. Now you can use if statements like:
if 1 in cmd_arguments.f:
    function_1()
This approach also gives great flexibility on not only which functions are to be run, but even what order: -f 3 1 2.
(Feb-01-2018, 07:35 AM)wavic Wrote: [ -> ]Use if/elif/else.

if parser.function_1:
    function_1()
    function_2()
    function_3()
    # etc.
elif parser.function_2:
    function_2()
    function_3()
    # etc.
# ....
else:
    # run all or do something else. whatever
Or you can put the functions to a list or tuple and iterate over them:

funcs = (function_1, function_2, function_3, function_4)

if parser.function_1:
    _ = [function() for function in funcs]
elif parser.function_2:
    _ = [function() for function in funcs[1:]]
elif parser.function_3:
    _ = [function() for function in funcs[2:]]
# etc.
@wavic
Thanks for the reply
But the 1st one won't be good option to go with, as function calling is duplicated here.
2nd solution. Do you think listing the arguments rather than function is a good idea. just wanted to check. Though, I am not sure how i gonna do that.
Did you try it?
Let me know if I am wrong. If the argument is func_1 you have to run all functions. If the argument is func_2 you want to run the functions starting from function_2?
@wavic, @dalwood
Thanks for your suggestions.

I got that functionality without using arg parser. I have incremented value of last_success_stage to 1 and stored it in 'ini' file for each successful execution of function and called the next function immediately. Below is the script that you can refer.

import sys
import os
import math
# import alert
import ConfigParser
import argparse
import json

# from alert import alert_user

configParser = ConfigParser.ConfigParser()
configParser.read('sample_updated.ini')


def function_1(a, b):
    c = a + b
    # write to ini file
    print "input_1 of function_1: ", a
    print "input_2 of function_1: ", b
    print "output of function_1: ", c

    configParser.set('Input', 'function_1_1', str(a))
    configParser.set('Input', 'function_1_2', str(b))
    configParser.set('Output', 'function_1', str(c))
    configParser.set('Output', 'last_success_stage', str(1))

    function_2(c,b)
    return c


def function_2(c, b):
    d = c * b
    # write to ini file
    print "input_1 of function_2: ", c
    print "input_2 of function_2: ", b
    print "output of function_2: ", d

    configParser.set('Output', 'function_2', str(d))
    configParser.set('Output', 'last_success_stage', str(2))
    print "-----------execute stage-3------------"
    function_3(d, c)
    return d


def function_3(d, c):

    e = d / c
    # write to ini file
    print "input_1 of function_3: ", d
    print "input_2 of function_3: ", c
    print "output of function_3: ", e

    configParser.set('Output', 'function_3', str(e))
    configParser.set('Output', 'last_success_stage', str(3))

    function_4(d, e)
    return e


def function_4(d, e):
    f = d - e
    # write to ini file
    print "input_1 of function_4: ", d
    print "input_2 of function_4: ", e
    print "output of function_4: ", f

    configParser.set('Output', 'function_4', str(f))
    configParser.set('Output', 'last_success_stage', str(4))

    return f


if __name__ == '__main__':

    a = input("value of a: ")

    b = input("value of b: ")

    # last_step = read_steps_file()

    curr_state = configParser.getint('Output', 'last_success_stage')

    if '1' in str(curr_state):
        function_2(configParser.getint('Output', 'function_1'), b)
    elif '2' in str(curr_state):
        function_3(configParser.getint('Output', 'function_2'), configParser.getint('Output', 'function_1'))

    elif '3' in str(curr_state):
        function_4(configParser.getint('Output', 'function_2'), configParser.getint('Output', 'function_3'))
        print "yettt"
    else:
        function_1(a, b)

with open('sample_updated.ini', 'w') as configfile:
    configParser.write(configfile)
@wavic, @dalwood

Is there a way to define above config-Parser into a separate function and call them where ever needed it write into ini file?
You can
@wavic
can you help me with the config parser function for the above script?
Pages: 1 2