0

How should I implement the following class? I want to create class that executes methods in random order when called and after all methods are called once reset array and reshuffle?

import random

class RandomFunctions(object):

    def f1():
        print("1")
    def f2():
        print("2")
    def f3():
        print("3")

    f = [f1, f2, f3]

    def __init__(self):
        super(RandomFunctions, self).__init__()
        random.shuffle(self.f)

    def execute(self):
        func = self.f.pop()
        if not self.f:
            reset f
        return func

def main():
    f = RandomFunctions()
    for i in range(6):
        f.execute()()

main()

These are the two ideas I came up with, but I'm still wondering what would be the smartest way to implement this sort of class?

discard = []
n = 0

    def execute(self):
        func = self.f[self.n]
        self.n += 1
        if self.n == len(self.f):
            self.n = 0
            random.shuffle(self.f)
        return func

    def execute_with_discard(self):
        func = self.f.pop(0)
        discard.append(func)
        if not self.f:
            f = discard[:]
            discard = []
            random.shuffle(self.f)
        return func
1
  • Hint: your constructor already contains most of the reset() method. Factor it out. Don't forget to refill the depleted list. Module copy could help you copy a list, or you could use the copy_of_list = source_list[:] idiom. Commented Sep 9, 2013 at 14:34

3 Answers 3

2
import random

class RandomFunctions(object):

    def f1(self):
        print("1")

    def f2(self):
        print("2")

    def f3(self):
        print("3")

    def execute(self):
        if not getattr(self, 'functions', None):
            self.functions = [self.f1, self.f2, self.f3]
            random.shuffle(self.functions)
        return self.functions.pop()


def main():
    f = RandomFunctions()
    for i in range(6):
        f.execute()()


main()
Sign up to request clarification or add additional context in comments.

Comments

1

Does it have to be a class like this? You could use a generator function:

def get_random_functions(*functions):
    while True:
        shuffled = list(functions)
        random.shuffle(shuffled)
        while shuffled:
            yield shuffled.pop()

for f in get_random_functions(f1, f2, f3):
    f()

Of course, if you prefer your class structure, you can use this by creating the generator in your __init__ method (self.gen = get_random_functions(*f)) and then have your execute method return next(self.gen).

Comments

1
import random

class RandomFunctions(object):

    def f1():
        print("1")
    def f2():
        print("2")
    def f3():
        print("3")

    f = [f1, f2, f3]

    def __init__(self):
        self.reset()

    def execute(self):
        func = self.f.pop()
        if not self.f:
            self.reset()
        return func()   # execute the function, return the result (if any)

    def reset(self):
        self.f = self.__class__.f[:]    # make copy of class f
        random.shuffle(self.f)

def main():
    f = RandomFunctions()
    for i in range(6):
        f.execute()     # now we only need one pair of parenthesis

main()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.