Converted Random to wrap. Added a long converter to assist this.

This commit is contained in:
James Vega 2004-11-28 02:23:59 +00:00
parent d31b672634
commit 7eed44eef7
4 changed files with 48 additions and 60 deletions

View File

@ -38,9 +38,9 @@ import random
import supybot.conf as conf import supybot.conf as conf
import supybot.utils as utils import supybot.utils as utils
from supybot.commands import *
import supybot.ircmsgs as ircmsgs import supybot.ircmsgs as ircmsgs
import supybot.ircutils as ircutils import supybot.ircutils as ircutils
import supybot.privmsgs as privmsgs
import supybot.registry as registry import supybot.registry as registry
import supybot.callbacks as callbacks import supybot.callbacks as callbacks
@ -65,7 +65,7 @@ class Seed(registry.Integer):
def serialize(self): def serialize(self):
# We do this so if it's 0, it doesn't store a real time. # We do this so if it's 0, it doesn't store a real time.
return str(self.value) return str(self.value)
conf.registerPlugin('Random') conf.registerPlugin('Random')
conf.registerGlobalValue(conf.supybot.plugins.Random, 'seed', Seed(0, """ conf.registerGlobalValue(conf.supybot.plugins.Random, 'seed', Seed(0, """
Sets the seed of the random number generator. The seed must be a valid Sets the seed of the random number generator. The seed must be a valid
@ -84,78 +84,53 @@ class Random(callbacks.Privmsg):
generator. generator.
""" """
irc.reply(str(self.rng.random())) irc.reply(str(self.rng.random()))
random = wrap(random)
def seed(self, irc, msg, args): def seed(self, irc, msg, args, seed):
"""<seed> """<seed>
Sets the seed of the random number generator. <seed> must be an int Sets the seed of the random number generator. <seed> must be an int
or a long. or a long.
""" """
seed = privmsgs.getArgs(args)
try:
seed = long(seed)
except ValueError:
# It wasn't a valid long!
irc.errorInvalid('number', seed)
return
self.rng.seed(seed) self.rng.seed(seed)
irc.replySuccess() irc.replySuccess()
seed = wrap(seed, ['long'])
def range(self, irc, msg, args): def range(self, irc, msg, args, start, end):
"""<start> <end> """<start> <end>
Returns a number between <start> and <end>, inclusive (i.e., the number Returns a number between <start> and <end>, inclusive (i.e., the number
can be either of the endpoints. can be either of the endpoints.
""" """
(start, end) = privmsgs.getArgs(args, required=2)
try:
end = int(end)
start = int(start)
except ValueError:
irc.error('<start> and <end> must both be integers.')
return
# .randrange() doesn't include the endpoint, so we use end+1. # .randrange() doesn't include the endpoint, so we use end+1.
irc.reply(str(self.rng.randrange(start, end+1))) irc.reply(str(self.rng.randrange(start, end+1)))
range = wrap(range, ['int', 'int'])
def sample(self, irc, msg, args): def sample(self, irc, msg, args, n, items):
"""<number of items> [<text> ...] """<number of items> [<text> ...]
Returns a sample of the <number of items> taken from the remaining Returns a sample of the <number of items> taken from the remaining
arguments. Obviously <number of items> must be less than the number arguments. Obviously <number of items> must be less than the number
of arguments given. of arguments given.
""" """
try: if n > len(items):
n = args.pop(0)
n = int(n)
except IndexError: # raised by .pop(0)
raise callbacks.ArgumentError
except ValueError:
irc.errorInvalid('number', n)
return
if n > len(args):
irc.error('<number of items> must be less than the number ' irc.error('<number of items> must be less than the number '
'of arguments.') 'of arguments.')
return return
sample = self.rng.sample(args, n) sample = self.rng.sample(items, n)
sample.sort() sample.sort()
irc.reply(utils.commaAndify(sample)) irc.reply(utils.commaAndify(sample))
sample = wrap(sample, ['int', many('something')])
def diceroll(self, irc, msg, args): def diceroll(self, irc, msg, args, n):
"""[<number of sides>] """[<number of sides>]
Rolls a die with <number of sides> sides. The default number of Rolls a die with <number of sides> sides. The default number of
sides is 6. sides is 6.
""" """
try:
n = privmsgs.getArgs(args, required=0, optional=1)
if not n:
n = 6
n = int(n)
except ValueError:
irc.error('Dice have integer numbers of sides. Use one.')
return
s = 'rolls a %s' % self.rng.randrange(1, n) s = 'rolls a %s' % self.rng.randrange(1, n)
irc.reply(s, action=True) irc.reply(s, action=True)
diceroll = wrap(diceroll, [additional(('int', 'number of sides'), 6)])
Class = Random Class = Random

View File

@ -147,7 +147,11 @@ def urlSnarfer(f):
### ###
# This is just so we can centralize this, since it may change. # This is just so we can centralize this, since it may change.
def _int(s): def _int(s, Long=False):
if not Long:
Type = int
else:
Type = long
base = 10 base = 10
if s.startswith('0x'): if s.startswith('0x'):
base = 16 base = 16
@ -159,59 +163,62 @@ def _int(s):
base = 8 base = 8
s = s[1:] s = s[1:]
try: try:
return int(s, base) return Type(s, base)
except ValueError: except ValueError:
if base == 10: if base == 10:
return int(float(s)) return Type(float(s))
else: else:
raise raise
def getInt(irc, msg, args, state, type='integer', p=None): def getInt(irc, msg, args, state, Type='integer', p=None, Long=False):
try: try:
i = _int(args[0]) i = _int(args[0], Long)
if p is not None: if p is not None:
if not p(i): if not p(i):
irc.errorInvalid(type, args[0]) irc.errorInvalid(Type, args[0])
state.args.append(i) state.args.append(i)
del args[0] del args[0]
except ValueError: except ValueError:
irc.errorInvalid(type, args[0]) irc.errorInvalid(Type, args[0])
def getNonInt(irc, msg, args, state, type='non-integer value'): def getNonInt(irc, msg, args, state, Type='non-integer value'):
try: try:
i = _int(args[0]) i = _int(args[0])
irc.errorInvalid(type, args[0]) irc.errorInvalid(Type, args[0])
except ValueError: except ValueError:
state.args.append(args.pop(0)) state.args.append(args.pop(0))
def getFloat(irc, msg, args, state, type='floating point number'): def getLong(irc, msg, args, state, Type='long number'):
getInt(irc, msg, args, state, Type, Long=True)
def getFloat(irc, msg, args, state, Type='floating point number'):
try: try:
state.args.append(float(args[0])) state.args.append(float(args[0]))
del args[0] del args[0]
except ValueError: except ValueError:
irc.errorInvalid(type, args[0]) irc.errorInvalid(Type, args[0])
def getPositiveInt(irc, msg, args, state, *L): def getPositiveInt(irc, msg, args, state, *L):
getInt(irc, msg, args, state, getInt(irc, msg, args, state,
p=lambda i: i>0, type='positive integer', *L) p=lambda i: i>0, Type='positive integer', *L)
def getNonNegativeInt(irc, msg, args, state, *L): def getNonNegativeInt(irc, msg, args, state, *L):
getInt(irc, msg, args, state, getInt(irc, msg, args, state,
p=lambda i: i>=0, type='non-negative integer', *L) p=lambda i: i>=0, Type='non-negative integer', *L)
def getIndex(irc, msg, args, state): def getIndex(irc, msg, args, state):
getInt(irc, msg, args, state, type='index') getInt(irc, msg, args, state, Type='index')
if state.args[-1] > 0: if state.args[-1] > 0:
state.args[-1] -= 1 state.args[-1] -= 1
def getId(irc, msg, args, state, kind=None): def getId(irc, msg, args, state, kind=None):
type = 'id' Type = 'id'
if kind is not None and not kind.endswith('id'): if kind is not None and not kind.endswith('id'):
type = kind + ' id' Type = kind + ' id'
original = args[0] original = args[0]
try: try:
args[0] = args[0].lstrip('#') args[0] = args[0].lstrip('#')
getInt(irc, msg, args, state, type=type) getInt(irc, msg, args, state, Type=Type)
except Exception, e: except Exception, e:
args[0] = original args[0] = original
raise raise
@ -527,6 +534,7 @@ wrappers = ircutils.IrcDict({
'url': getUrl, 'url': getUrl,
'httpUrl': getHttpUrl, 'httpUrl': getHttpUrl,
'float': getFloat, 'float': getFloat,
'long': getLong,
'nonInt': getNonInt, 'nonInt': getNonInt,
'positiveInt': getPositiveInt, 'positiveInt': getPositiveInt,
'nonNegativeInt': getNonNegativeInt, 'nonNegativeInt': getNonNegativeInt,
@ -725,7 +733,7 @@ class commalist(context):
except Exception, e: except Exception, e:
args[:] = original args[:] = original
raise raise
class getopts(context): class getopts(context):
"""The empty string indicates that no argument is taken; None indicates """The empty string indicates that no argument is taken; None indicates
that there is no converter for the argument.""" that there is no converter for the argument."""
@ -761,7 +769,7 @@ class getopts(context):
state.args.append(getopts) state.args.append(getopts)
args[:] = rest args[:] = rest
log.debug('args after %r: %r', self, args) log.debug('args after %r: %r', self, args)
### ###
# This is our state object, passed to converters along with irc, msg, and args. # This is our state object, passed to converters along with irc, msg, and args.
### ###
@ -785,7 +793,7 @@ class State(object):
return '%s(args=%r, kwargs=%r, channel=%r)' % (self.__class__.__name__, return '%s(args=%r, kwargs=%r, channel=%r)' % (self.__class__.__name__,
self.args, self.kwargs, self.args, self.kwargs,
self.channel) self.channel)
### ###
# This is a compiled Spec object. # This is a compiled Spec object.

View File

@ -40,11 +40,11 @@ class RandomTestCase(PluginTestCase):
def testRange(self): def testRange(self):
for x in range(iters): for x in range(iters):
self.assertRegexp('range 1 2', '^(1|2)$') self.assertRegexp('range 1 2', '^(1|2)$')
def testDiceroll(self): def testDiceroll(self):
for x in range(iters): for x in range(iters):
self.assertActionRegexp('diceroll', '^rolls a (1|2|3|4|5|6)$') self.assertActionRegexp('diceroll', '^rolls a (1|2|3|4|5|6)$')
def testSample(self): def testSample(self):
for x in range(iters): for x in range(iters):
self.assertRegexp('sample 1 a b c', '^(a|b|c)$') self.assertRegexp('sample 1 a b c', '^(a|b|c)$')

View File

@ -54,6 +54,11 @@ class CommandsTestCase(SupyTestCase):
self.assertState(['int'], ['1'], [1]) self.assertState(['int'], ['1'], [1])
self.assertState(['int', 'int', 'int'], ['1', '2', '3'], [1, 2, 3]) self.assertState(['int', 'int', 'int'], ['1', '2', '3'], [1, 2, 3])
def testSpecLong(self):
self.assertState(['long'], ['1'], [1L])
self.assertState(['long', 'long', 'long'], ['1', '2', '3'],
[1L, 2L, 3L])
def testRestHandling(self): def testRestHandling(self):
self.assertState([rest(None)], ['foo', 'bar', 'baz'], ['foo bar baz']) self.assertState([rest(None)], ['foo', 'bar', 'baz'], ['foo bar baz'])