Home > Net >  Is there a way to set all input arguments of a function to TRUE if one other input argument is TRUE
Is there a way to set all input arguments of a function to TRUE if one other input argument is TRUE

Time:08-14

I have the following function which I'm using to run pieces of analysis.

If I set run_all_analysis = True, I want to run both analysis_1 and analysis_2. If I set run_analysis_1 = True when run_all_analysis is False, I will just run analysis_1 (likewise for analysis_2)

def save_locally(self,
                 run_all_analysis: bool = False,
                 run_analysis_1: bool = False,
                 run_analysis_2: bool = False):
    if run_all_analysis:
        run_analysis_1 = True
        run_analysis_2 = True

    if run_analysis_1 = True
        # some function that saves analysis 1 to local folder

    if run_analysis_2 = True
        # some function that saves analysis 2 to local folder

The issue is, I have lots of different pieces of analysis (around 20) and so this function could get really long. Is there a way to automatically set all input arguments to TRUE if run_all_analysis is TRUE (rather than writing out all the input arguments one by one?)?

CodePudding user response:

If you use a kwargs dict instead of defining one by one each run_analysis_<n> argument, it's much simpler:


def save_locally(self,
                 run_all_analysis: bool = False,
                 **kwargs):
    
    if run_all_analysis:
        for key in kwargs.keys():
            kwargs[key] = True

    if kwargs["run_analysis_1"] is True:
        # some function that saves analysis 1 to local folder

    if kwargs["run_analysis_2"] is True:
        # some function that saves analysis 2 to local folder

If we wanted to make things even more compact, with only one if for however many analysis you have to perform, we would create a list that contains the function associated to each analysis flag:


def save_locally(self,
                 run_all_analysis: bool = False,
                 **kwargs):

    analysis_functions = [f1, f2, f3]
    
    for n, function in enumerate(analysis_functions, start=1):        
        if run_all_analysis or kwargs.get(f"run_analysis_{n}", False) is True:            
            function() # Some function that saves analysis n to local folder.

CodePudding user response:

Rather than finding some way to change all the run_analysis_x variables you could just use or:

def save_locally(self,
                 run_all_analysis: bool = False,
                 run_analysis_1: bool = False,
                 run_analysis_2: bool = False):

    if run_analysis_1 or run_all_analysis:
        # some function that saves analysis 1 to local folder

    if run_analysis_2 or run_all_analysis:
        # some function that saves analysis 2 to local folder

Even better, group your functions and their corresponding booleans in lists, and loop:

def save_locally(self, run_all_analysis: bool = False, *run_bools):
    analysis_funcs = [do_analysis_1, do_analysis_2, ...]

    for run_bool, func in zip(run_bools, analysis_funcs):
        if run_bool or run_all_analysis:
            func()
    ...

CodePudding user response:

A really janky way of doing it by exploiting the __dict__ attribute of the python class:

class TestClass:
    NUM_ANALYSIS = 20

    def save_locally(
        self,
        run_all_analysis: bool = False,
        run_analysis_1: bool = False,
        run_analysis_2: bool = False,
    ):
        self.run_all_analysis = run_all_analysis

        if run_all_analysis:
            for index in range(1, self.NUM_ANALYSIS   1):
                self.__dict__[f"run_analysis_{index}"] = True

        print(self.run_analysis_1) # prints: True
        print(self.run_analysis_2) # prints: True


test_class = TestClass()
test_class.save_locally(run_all_analysis=True)

CodePudding user response:

the easiest way is to use *args to take all the arguments after, loop and set the item using the or operator.

using then the locals() function to set the variables.

def save_locally(self,
                 run_all_analysis: bool = False,
                 *runs_analysis):
    for i, analysis in runs_analysis:
        locals()[f"run_analysis_{i}"] = analysis or run_all_analysis

    if run_analysis_1:
        # some function that saves analysis 1 to local folder

    if run_analysis_2:
        # some function that saves analysis 2 to local folder

This said, the documentation for locals explicitely says not to use it to modify the variables: "Note: The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter."

the problem is that if you have some IDE, the Intellisense will tell you that the variables aren't declared so i would go for something more readable, probably using kwargs:

def save_locally(self,
                 run_all_analysis: bool = False,
                 **kwargs):
    if run_all_analysis:
         for x in range(20):
             kwargs[f"run_analysis_{x}"] = True


    if kwargs["run_analysis_1"]:
        # some function that saves analysis 1 to local folder

    if kwargs["run_analysis_2"]:
        # some function that saves analysis 2 to local folder
  • Related