NGuyen
NGuyen

Reputation: 275

Python 3: How to run functions with parameter in random order?

I knew how to run functions which doesn't have parameter. In this case, I want to run functions which has parameter in random order ?

It showed the result but not random and there is some error: Please help me correct the my code. Thank you :)

import random
def hi(name):
    print('a ' + name)

def howold(old, name):
    print( name + 'is ' + old + "years old")

def howmuch(money):
    print(money + ' dollars')


functions = [hi('John'),howold('20', 'John'),howmuch('50')]
random.shuffle(functions)
for i in functions:
    i()

Upvotes: 1

Views: 757

Answers (4)

Guillaume
Guillaume

Reputation: 6019

When this line executes:

functions = [hi('John'),howold('20', 'John'),howmuch('50')]

Python will call your 3 functions hi(), howold() then howmuch() in that order, then store their result in a list called functions. So all print() will run at that point. That's why, as you said, "it showed the result but not random". Since all your functions do not return anything, your functions will be equal to [None, None, None].

Then the following code:

random.shuffle(functions)
for i in functions:
    i()

Will try to execute None(). That will produce an error, as you said "there is some error": this error is TypeError: 'NoneType' object is not callable.

How to fix: use for example functools.partial()

from functools import partial
functions = [partial(hi, 'John'), partial(howold, '20', 'John'), partial(howmuch, '50')]
random.shuffle(functions)
for i in functions:
    i()

Official doc here: https://docs.python.org/2/library/functools.html#functools.partial

Upvotes: 1

dkasak
dkasak

Reputation: 2703

Your functions list contains results of already evaluated functions, not a partially applied function with no arguments (so that you can call them with i()) in the loop.

You can use lambdas to produce new functions with no arguments like this:

functions = [lambda: hi('John'),
             lambda: howold('20', 'John'),
             lambda: howmuch('50')]
random.shuffle(functions)

for f in functions:
    f()

Upvotes: 3

Fuxi
Fuxi

Reputation: 5508

Try something like that:

functions = [(hi, ['John']), (howold, ['20', 'John']), (howmuch, ['50'])]

random.shuffle(functions)
for func, args in functions:
    func(*args)

Upvotes: 3

Cleared
Cleared

Reputation: 2590

In your loop, i is a function and not a string, therefore comparing it to a string wont work and you end up in else. Instead use if i.__name__ == 'hi

Upvotes: -1

Related Questions