From 2ab08a84cf4610dbdf06259d8090b5c78077dabe Mon Sep 17 00:00:00 2001 From: Mike Stark Date: Thu, 10 Dec 2015 10:36:59 -0500 Subject: [PATCH 1/3] [dice] Handle negative numbers and uppercase letters. First, add case-insensitivity to the "d" and "v" letters in the input regex by capturing [dD] and [vV] in regexes. Next, make sure we can handle negative numbers properly by capturing a possible "-" in front of any numbers. If dice_num or dice_type ends up negative, abort _roll_dice early (dice_type already had a negative check that wasn't being hit because "-" wasn't captured). --- sopel/modules/dice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sopel/modules/dice.py b/sopel/modules/dice.py index 2f8c559eab..026a52448b 100644 --- a/sopel/modules/dice.py +++ b/sopel/modules/dice.py @@ -184,7 +184,7 @@ def roll(bot, trigger): if not trigger.group(2): return bot.reply("No dice to roll.") arg_str = trigger.group(2) - dice_expressions = re.findall(dice_regexp, arg_str) + dice_expressions = re.findall(dice_regexp, arg_str, re.IGNORECASE) arg_str = arg_str.replace("%", "%%") arg_str = re.sub(dice_regexp, "%s", arg_str) From bb4af03de421e894272b891298faa0446764a6e2 Mon Sep 17 00:00:00 2001 From: Mike Stark Date: Thu, 10 Dec 2015 10:44:19 -0500 Subject: [PATCH 2/3] [dice] Handle negative numbers and uppercase letters. First, add case-insensitivity to the "d" and "v" letters in the input regex by capturing [dD] and [vV] in regexes. Next, make sure we can handle negative numbers properly by capturing a possible "-" in front of any numbers. If dice_num or dice_type ends up negative, abort _roll_dice early (dice_type already had a negative check that wasn't being hit because "-" wasn't captured). --- sopel/modules/dice.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/sopel/modules/dice.py b/sopel/modules/dice.py index 026a52448b..ab4f62ff8f 100644 --- a/sopel/modules/dice.py +++ b/sopel/modules/dice.py @@ -124,10 +124,10 @@ def get_number_of_faces(self): def _roll_dice(bot, dice_expression): result = re.search( r""" - (?P\d*) + (?P-?\d*) d - (?P\d+) - (v(?P\d+))? + (?P-?\d+) + (v(?P-?\d+))? $""", dice_expression, re.IGNORECASE | re.VERBOSE) @@ -140,6 +140,11 @@ def _roll_dice(bot, dice_expression): bot.reply("I don't have any dice with %d sides. =(" % dice_type) return None # Signal there was a problem + # Can't roll a negative number of dice. + if dice_num < 0: + bot.reply("I'd rather not roll a negative amount of dice. =(") + return None # Signal there was a problem + # Upper limit for dice should be at most a million. Creating a dict with # more than a million elements already takes a noticeable amount of time # on a fast computer and ~55kB of memory. @@ -176,7 +181,7 @@ def roll(bot, trigger): """ # This regexp is only allowed to have one captured group, because having # more would alter the output of re.findall. - dice_regexp = r"\d*d\d+(?:v\d+)?" + dice_regexp = r"-?\d*[dD]-?\d+(?:[vV]-?\d+)?" # Get a list of all dice expressions, evaluate them and then replace the # expressions in the original string with the results. Replacing is done @@ -184,7 +189,7 @@ def roll(bot, trigger): if not trigger.group(2): return bot.reply("No dice to roll.") arg_str = trigger.group(2) - dice_expressions = re.findall(dice_regexp, arg_str, re.IGNORECASE) + dice_expressions = re.findall(dice_regexp, arg_str) arg_str = arg_str.replace("%", "%%") arg_str = re.sub(dice_regexp, "%s", arg_str) From ee7562803a7ba55c1c0453b26d8b71de2720314f Mon Sep 17 00:00:00 2001 From: Mike Stark Date: Thu, 10 Dec 2015 10:50:34 -0500 Subject: [PATCH 3/3] [dice] Also handle negative drop_lowest values. --- sopel/modules/dice.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sopel/modules/dice.py b/sopel/modules/dice.py index ab4f62ff8f..0e5336533c 100644 --- a/sopel/modules/dice.py +++ b/sopel/modules/dice.py @@ -156,7 +156,10 @@ def _roll_dice(bot, dice_expression): if result.group('drop_lowest'): drop = int(result.group('drop_lowest')) - dice.drop_lowest(drop) + if drop >= 0: + dice.drop_lowest(drop) + else: + bot.reply("I can't drop the lowest %d dice. =(" % drop) return dice