Entry
Reducing redundant answers (was: strings in lists)
Jul 5th, 2000 09:59
Nathan Wallace, Hans Nowak, Snippet 75, Tim Peters
"""
Packages: miscellaneous.fun
"""
"""
[Christian Tismer]
> Congrats to us all, who answered in parallel.
>
> Five correct answers to one simple question,
> and none much worse than the others.
>
> Is there a way to save some redundancy in the future?:-)
Certainly! When you're deciding whether to reply, simply look at your
watch and reply if and only if it's between 0 and 11 seconds (inclusive)
after the minute.
Hmm. That's rather old-fashioned, isn't it? OK, I'll attach ohdear.py.
that-guido-thought-of-everything-ly y'rs - tim
"""
numwizards = 5
__doc__ = """Decide whether to reply to a simple c.l.py question.
Usage:
ohdear [numwizards]
where numwizards is an optional integer > 0, defaulting to %d, estimating
the number of currently active c.l.py wizards who are also wondering
whether to answer, and who-- also like you --believe a technological
approach has got to be the right thing to do no matter how stupid it is.
""" % (numwizards,)
import sys
import random
import bisect
class EightBall:
def __init__(self, answers, weights):
"""weights, answers -> an instance x of EightBall.
x.choose() returns answers[i] with relative frequency
weights[i]/sum(weights). answers and weights must have
the same number of elements, > 0.
"""
n = len(answers)
if n == 0:
raise ValueError("answers must not be empty")
if n != len(weights):
raise ValueError("must have same # of answers as weights")
sum = 0.0
for w in weights:
if not w >= 0:
raise ValueError("weights must be non-negative; " + `w`)
sum = sum + w
if sum == 0:
raise ValueError("must have at least one non-zero weight")
partial = 0.0
cumulative = []
for w in weights:
partial = partial + w
cumulative.append(partial / sum)
self.answers = answers
self.cumulative = cumulative
def choose(self):
i = bisect.bisect(self.cumulative, random.random())
return self.answers[i]
def _main():
global numwizards
realwizard = 1 # generosity is the true Python spirit
if len(sys.argv) > 2:
realwizard = 0
elif len(sys.argv) == 2:
try:
numwizards = int(sys.argv[1])
realwizard = numwizards > 0
except:
realwizard = 0
if not realwizard:
sys.stderr.write("No, you're not qualified to answer anything.\n")
sys.exit(1)
chooser = EightBall(
["No, chances are someone else will. Don't be a pest.",
"Yes, chances are nobody else will. Be a hero."],
[numwizards - 1, 1])
print chooser.choose()
if __name__ == "__main__":
random.seed() # seed via current time
_main()