Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Randomly select functions

I am writing a test script which contains different functions for different tests. I would like to be able to randomly select a test to run. I have already achieved this with the following function...

test_options = ("AOI", "RMODE")

def random_test(test_options, control_obj):
  ran_test_opt = choice(test_options)

  if ran_test_opt.upper() == "AOI":
     logging.debug("Random AOI Test selected")
     random_aoi()
  elif ran_test_opt.upper() == "RMODE":
    logging.debug("Random Read Mode Test selected")
    random_read_mode(control_obj)

However, I want to be to add further test functions without having to modify the random test select function. All I would like to do is add in the test function to the script. Additionally I would also like a way to selecting which test will be included in the random selection. This is what the variable test_options does. How would I go about changing my random generate function to achieve this?

EDIT: I got around the fact that all the tests might need different arguments by including them all in a test class. All the arguments will be passed into the init and the test functions will refer to them using "self." when they need a specific variable...

class Test(object):
  """A class that contains and keeps track of the tests and the different modes"""

  def __init__(self, parser, control_obj):
    self.parser = parser
    self.control_obj = control_obj

  def random_test(self):
    test_options = []
    for name in self.parser.options('Test_Selection'):
        if self.parser.getboolean('Test_Selection', name):
            test_options.append(name.lower())

    ran_test_opt = choice(test_options)
    ran_test_func = getattr(self, ran_test_opt)
    ran_test_func()

  #### TESTS ####
  def random_aoi(self):
    logging.info("Random AOI Test")
    self.control_obj.random_readout_size()

  def random_read_mode(self):
    logging.info("Random Readout Mode Test")
    self.control_obj.random_read_mode()
like image 534
Marmstrong Avatar asked Mar 21 '23 11:03

Marmstrong


2 Answers

You can create a list of functions in python which you can call:

test_options = (random_aoi, random_read_mode)

def random_test(test_options, control_obj):
    ran_test_opt = choice(test_options)
    ran_test_opt(control_obj) # call the randomly selected function

You have to make each function take the same arguments this way, so you can call them all the same way.

like image 140
Ikke Avatar answered Apr 02 '23 13:04

Ikke


If you need to have some human readable names for the functions, you can store them in a dictionary, together with the function. I expect that you pass the control_obj to every function.

EDIT: This seems to be identical to the answer by @Ikke, but uses the dictionary instead of a list of functions.

>>> test_options = {'AOI': random_aoi, 'RMODE': random_read_mode}

>>> def random_test(test_options, control_obj):
...    ran_test_opt = test_options[choice(test_options.keys())]
...    ran_test_opt(control_obj)

Or you could pick out a test from test_options.values(). The 'extra' call to list() is because in python 3.x, dict.values() returns an iterator.

>>> ran_test_opt = choice(list(test_options.values()))
like image 30
msvalkon Avatar answered Apr 02 '23 14:04

msvalkon