简体   繁体   中英

Calling a function inside a variable (randomly)

So, I have a collection of different questions, which are each asked depending on what function is called. I want to have it so for every question, a random type of question (function) is called. I think this is the best way to do it but I don't know why it's not working.

x = addition_question(int(random.randrange(0,101,1)),int(random.randrange(0,101,1)))

y = multiply_question(int(random.randint(1,10)),int(random.randint(1,10)))

z = subtract_question(int(random.randrange(0,101,1)),int(random.randrange(0,101,1)))

vars = [x,y,z]


import random

print("Question 1:")
print(random.sample(vars,1))
time.sleep(.25)

Running this returns this: http://puu.sh/bP9dL/416caa5bc1.png

Instead of going to the line with 'print ("Question 1:")' it for some reason prints the functions without the variable being called.

NOTE: The error is in the randomising of the variables, and calling them. When I specify the type of question (function) I would like to use, it works as planned.

print("Question 1:")
addition_question(int(random.randrange(0,101,1)),int(random.randrange(0,101,1))) #creates addition question with randomised numbers between 1 and 101
print("")
time.sleep(.25)

print("Question 2:")
multiply_question(int(random.randint(1,10)),int(random.randint(1,10))) #creates multiplication question with randomised numbers between 1 and 10
print("")
time.sleep(.25)

Feel free to ask questions about the rest of the code!

When you write lines like this:

x = addition_question(int(random.randrange(0,101,1)),int(random.randrange(0,101,1)))

That calls the function addition_question right now, and assigns the result of calling that function to x .

What you want to do is create something that you can lazily call later—and call repeatedly, getting a different value back each time.

The way do to that is to define a function:

def x():
    return addition_question(int(random.randrange(0,101,1)),int(random.randrange(0,101,1)))

And then, of course, you don't want to just print out x , you want to call x and print out the result :

print(random.sample(vars,1)())

That's all it takes.


A few side notes on your code:

  • random.randrange returns an integer; there's no reason to pass its result to int .
  • random.sample(spam, n) chooses n values without replacement; when n is always going to be 1 , random.choice(spam) does the same thing more simply and readably.
  • random.randrange , like range , has default values for its parameters, so you can just write randrange(101) , not randrange(0, 101, 1) .
  • Long lines of code with no spaces are hard to read, even more so in places like StackOverflow or a typical terminal window that can only fit 80 characters. Put spaces between arguments, break lines in two (or reorganize them into separate lines with intermediate values stored in temporary variables) if they get too long, etc. See [PEP 8( http://legacy.python.org/dev/peps/pep-0008/ ) for the standard Python style guide.

You already called your functions before storing them into the vars list. Just store references to the functions, and pass in random values for the arguments after picking one:

questions = (addition_question, multiply_question, subtract_question)
print("Question 1:")
random.choice(questions)(random.randint(1,10), random.randint(1,10))

The random.choice() picks one of the three function references at random, and the (...) part after the random.choice() call then calls that random function. At that moment we pass in randomly picked arguments.

Note that I did not use int() on the return value of random.randint() ; that function already returns an integer and there is no need to turn that into an integer again. I also used random.choice() rather than use random.sample() with sample size of 1.

If your functions need different random integer ranges, then you have a few different options:

  • store the ranges with the functions, say in a tuple, and after picking a tuple at random call random.randint() and the picked function:

     questions = ( (addition_question, 0, 100), (multiply_question, 1, 10), (subtract_question, 0, 100), ) question, low, high = random.choice(questions) question(random.randint(low, high), random.randint(low, high)) 
  • Store lambdas; these are anonymous functions, encapsulating another expression to be executed when called:

     questions = ( lambda: addition_question(random.randrange(101), random.randrange(101)), lambda: multiply_question(random.randint(1, 10), random.randint(1, 10)), lambda: subtract_question(random.randrange(101), random.randrange(101)), ) random.choice(questions)() 

In the first option I adjusted the values to be usable for random.randint() and in the second I used the simplest form of random.randrange() ; with just one argument it'll default the start to 0 and the step to 1 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM