Search code examples
pythondecorator

Can decorators be used to simulate trials?


Is there an elegant way to use decorators to simulate trials of some function, where the number of trials can be edited?

I expected this to work but it didn't. So I'm wondering how to fix it.

from functools import wraps
from random import randint

def DiceRoll(dice_size=6):
    return randint(1,dice_size)

def trials(func):
    @wraps(func)
    def wrapper(*args, num_trials, **kwargs):
        results = []
        for _ in range(num_trials):
            result = func(*args, **kwargs)
            results.append(result)
        return results
    return wrapper


@trials
def DiceRolls(dice_size=6, num_trials):
    return DiceRoll(dice_size)

DiceRolls(num_trials)

Solution

  • If anything, the number of trials should be only a parameter of the decorated function:

    def trials(func):
        @wraps(func)
        def wrapper(*args, num_trials=1,**kwargs):
            return [func(*args, **kwargs) for _ in range(num_trials)]
        return wrapper
    
    def DiceRoll(dice_size=6):
        return randint(1,dice_size)
    
    @trials
    def DiceRolls(dice_size=6):
        return DiceRoll(dice_size)
    
    >>> DiceRolls()
    [5]
    >>> DiceRolls(num_trials=3)
    [1, 1, 1]
    >>> DiceRolls(num_trials=5)
    [1, 5, 6, 1, 6]
    >>> DiceRolls(num_trials=5, dice_size=3)
    [2, 1, 1, 3, 1]