How To Fix This Iterative Python Code And Reduce Repetition?
Solution 1:
You seem to use the numbers only for dispatching. The same result (calling each of 10 functions in random order) can be achieved without going through numbers first, like so:
import random
def roll():
qs = [q1, q2, q3, q4, q5, q6, q7, q8, q9, q10]
random.shuffle(qs)
for q in qs:
yield q
# ...for rolled inroll():
rolled()
By not invoking the q#()
functions directly and instead yielding them, they can be invoked whenever it's convenient for the caller.
Solution 2:
Keeping one function per question is not a good strategy. What if you want to change slightly how questions, hints and answers are given? You're going to change dozens or even hundreds of functions?
A much better approach is an object-oriented one- for example, where each question is an object of the Question
class. For example:
classQuestion:
def__init__(self, question, hints, answer):
self.question = question
self.hints = hints
self.answer = answer
defask_question(self):
print"Here is your question:"print self.question
defgive_hint(self):
iflen(self.hints) == 0:
print"That's all the hints I have!"else:
print self.hints.pop(0)
defguess(self, guess):
if guess == self.answer:
print"You guessed correctly!"else:
print"No, try again!"
Any behavior that you originally encapsulated in the question function (limiting the number of guesses, limited amount of time, displaying in a certain format, whatever) would all be handled by methods of the Question
class. In the meantime, all the information specific to one question would be held in the data members (in this case question
, hints
and answers
, although there could be other variables) that are specific to that question.
You would create a question like this:
q1 = Question("How many roads must a man walk down?", ["Think Douglas Adams.", "It's more than 40 and less than 50"], "42")
Or better yet, create them from a tab delimited file, where the file is something like:
How many roads must a man walk down? Think Douglas Adams./It's more than 40 and less than 50 42
And they are created like:
questions = []
withopen("questions.txt") as inf:
for l in inf:
question, hints, answer = l[:-1].split("\t")
questions.append(Question(question, hints.split("/"), answer))
Then your main function would call methods of the Question
, which encapsulate its question-asking behavior. This would keep you from ever having to repeat code (all the code exists only in one place: the methods of the Question
object) and would keep all your questions in a flexible format.
Solution 3:
What about:
def roll():
var = random.randint(1,10)
ifvarnotin numlist:
roll()
else:
numlist.remove(var)
call_me = getattr(module, 'q%s'% var)
Solution 4:
I'm not sure if you can, but instead of having 10 functions q1()..q10 I would make a function that accepts a parameter this way:
def roll():
var = random.randint(1,10)
ifvarnotin numlist:
roll()
else:
numlist.remove(var)
q(var)
You should also be checking if numlist
is empty (just in case).
Also, there is a very unlikely chance that the random int is never the one in the list causing a stack overflow, with 10 ints very unlikely though, but if you want to make sure this can't happen you should:
make a list with the choices:
choices = range(1,11)
you should use choice to chose from that list:
var = random.choice(choices)
and then remove that choice:
choices.remove(var)
Solution 5:
You can put all the functions in a list, shuffle the list and then pop out the result question function:
>>>import random>>>>>>l = [q1, q2, q3, q4, q5, q6, q7, q8, q9, q10]>>>random.shuffle(l)>>>qfunc = l.pop()
Post a Comment for "How To Fix This Iterative Python Code And Reduce Repetition?"