def get_budget(message, entity_name, structured_value, fallback_value, bot_message): """Use BudgetDetector to detect budget Args: message (str): natural text on which detection logic is to be run. Note if structured value is detection is run on structured value instead of message entity_name (str): name of the entity. Also acts as elastic-search dictionary name if entity uses elastic-search lookup structured_value (str): Value obtained from any structured elements. Note if structured value is detection is run on structured value instead of message (For example, UI elements like form, payload, etc) fallback_value (str): If the detection logic fails to detect any value either from structured_value or message then we return a fallback_value as an output. bot_message (str): previous message from a bot/agent. Returns: dict or None: dictionary containing entity_value, original_text and detection; entity_value is in itself a dict with its keys varying from entity to entity Example: message = "shirts between 2000 to 3000" entity_name = 'budget' structured_value = None fallback_value = None bot_message = None output = get_budget(message=message, entity_name=entity_name, structured_value=structured_value, fallback_value=fallback_value, bot_message=bot_message) print output >> [{'detection': 'message', 'original_text': '2000 to 3000', 'entity_value': {'max_budget': 3000, 'type': 'normal_budget', 'min_budget': 2000}}] """ budget_detection = BudgetDetector(entity_name=entity_name) if structured_value: entity_list, original_text_list = budget_detection.detect_entity(text=structured_value) if entity_list: return output_entity_dict_list(entity_list, original_text_list, FROM_STRUCTURE_VALUE_VERIFIED) else: return output_entity_dict_list([structured_value], [structured_value], FROM_STRUCTURE_VALUE_NOT_VERIFIED) else: entity_list, original_text_list = budget_detection.detect_entity(text=message) if entity_list: return output_entity_dict_list(entity_list, original_text_list, FROM_MESSAGE) elif fallback_value: return output_entity_dict_list([fallback_value], [fallback_value], FROM_FALLBACK_VALUE) return None
def get_budget(message, entity_name, structured_value, fallback_value, bot_message): """This functionality calls the BudgetDetector class to detect budget Attributes: NOTE: Explained above Output: NOTE: Explained above For Example: message = "shirts between 2000 to 3000" entity_name = 'budget' structured_value = None fallback_value = None bot_message = None output = get_budget(message=message, entity_name=entity_name, structured_value=structured_value, fallback_value=fallback_value, bot_message=bot_message) print output >> [{'detection': 'message', 'original_text': '2000 to 3000', 'entity_value': {'max_budget': 3000, 'type': 'normal_budget', 'min_budget': 2000}}] """ budget_detection = BudgetDetector(entity_name=entity_name) if structured_value: entity_list, original_text_list = budget_detection.detect_entity( text=structured_value) if entity_list: return output_entity_dict_list(entity_list, original_text_list, FROM_STRUCTURE_VALUE_VERIFIED) else: return output_entity_dict_value(structured_value, structured_value, FROM_STRUCTURE_VALUE_NOT_VERIFIED) else: entity_list, original_text_list = budget_detection.detect_entity( text=message) if entity_list: return output_entity_dict_list(entity_list, original_text_list, FROM_MESSAGE) elif fallback_value: return output_entity_dict_value(fallback_value, fallback_value, FROM_FALLBACK_VALUE) return None
def setUp(self): self.budget_detector = BudgetDetector(entity_name='budget') self.budget_detector.set_min_max_digits(min_digit=1, max_digit=15)
class TestBudgetDetector(TestCase): def setUp(self): self.budget_detector = BudgetDetector(entity_name='budget') self.budget_detector.set_min_max_digits(min_digit=1, max_digit=15) @staticmethod def make_budget_dict(min_budget=0, max_budget=0): return { 'min_budget': min_budget, 'max_budget': max_budget, 'type': 'normal_budget' } def test_min_max_digits_limits(self): """ Test min max digits limit """ self.budget_detector.set_min_max_digits(min_digit=2, max_digit=5) positive_tests = [ 'Show products in 10,000 - 20,000 range', 'This costs about 10 rs', ] negative_tests = [ 'my budget is .5cr', 'Annual operating budget is 1.2cr', 'Show me cars that cost less than 2.99mil', 'Rs. 1 is the minimum denomination' ] for test in positive_tests: budget_dicts, original_texts = self.budget_detector.detect_entity( text=test) self.assertTrue(original_texts) for test in negative_tests: budget_dicts, original_texts = self.budget_detector.detect_entity( text=test) self.assertFalse(original_texts) def test_max_budget(self): """ Test v1 max budget """ tests = [('Show me cars that cost below rs. 5000', 0, 5000, 'below rs. 5000'), ('Show me cars that cost less than 6k', 0, 6000, 'less than 6k'), ('at most 30 rs.', 0, 30, 'at most 30 rs.'), ('costs upto Rs.100', 0, 100, 'upto rs.100')] for test, min_budget, max_budget, original_text in tests: budget_dicts, original_texts = self.budget_detector.detect_entity( text=test) self.assertEqual(budget_dicts, [self.make_budget_dict(max_budget=max_budget)]) self.assertEqual(original_texts, [original_text]) def test_min_budget(self): """ Test v1 min budget """ tests = [ ('Show me cars that cost above rs. 5000', 5000, 0, 'above rs. 5000'), ('Show me cars that cost more than 6k', 6000, 0, 'more than 6k'), ('at least 30 rs.', 30, 0, 'at least 30 rs.'), ('costs greater than Rs.100', 100, 0, 'greater than rs.100'), ] for test, min_budget, max_budget, original_text in tests: budget_dicts, original_texts = self.budget_detector.detect_entity( text=test) self.assertEqual(budget_dicts, [self.make_budget_dict(min_budget=min_budget)]) self.assertEqual(original_texts, [original_text]) def test_range(self): """ Test v1 budget range """ tests = [ ('Show products in 10,000 - 20,000 range', 10000, 20000, '10,000 - 20,000'), ('Show products in 10,000-20,000 range', 10000, 20000, '10,000-20,000'), ('Show products in 10,000 till Rs. 20k range', 10000, 20000, '10,000 till rs. 20k'), ('Show products from rs. 5,5,00 to 6,0,0,0 rupees', 5500, 6000, 'rs. 5,5,00 to 6,0,0,0 rupees'), ] for test, min_budget, max_budget, original_text in tests: budget_dicts, original_texts = self.budget_detector.detect_entity( text=test) self.assertEqual(budget_dicts, [ self.make_budget_dict(min_budget=min_budget, max_budget=max_budget) ]) self.assertEqual(original_texts, [original_text]) def test_any_budget(self): """ Test v1 budget any """ tests = [ ('.5cr', 0, 5000000, '.5cr'), ('1.2cr', 0, 12000000, '1.2cr'), ('1.5 thousand', 0, 1500, '1.5 thousand'), ('5 hazar', 0, 5000, '5 hazar'), ('10 rs', 0, 10, '10 rs'), ] for test, min_budget, max_budget, original_text in tests: budget_dicts, original_texts = self.budget_detector.detect_entity( text=test) self.assertEqual(budget_dicts, [self.make_budget_dict(max_budget=max_budget)]) self.assertEqual(original_texts, [original_text]) def test_not_budgets(self): """ Test sentences that do not have any budget """ tests = [ 'I want to buy 5liters of milk', 'Your flight number is 9w998', 'hello, your coupon code is Amazon50', 'hello, your coupon code is 50Amazon', 'the insect is 120millimeters tall' ] for test in tests: budget_dicts, original_texts = self.budget_detector.detect_entity( text=test) self.assertEqual(budget_dicts, []) self.assertEqual(original_texts, []) def test_budgets_without_scales(self): """ Test budgets without scales """ tests = [ ('I want to buy 5 liters of milk', 0, 5, '5'), ('the insect is 120 millimeters tall', 0, 120, '120'), ('hello, your coupon code is 50 Amazon', 0, 50, '50'), ('Your flight number is 9w 998', 0, 998, '998'), ] for test, min_budget, max_budget, original_text in tests: budget_dicts, original_texts = self.budget_detector.detect_entity( text=test) self.assertEqual(budget_dicts, [self.make_budget_dict(max_budget=max_budget)]) self.assertEqual(original_texts, [original_text]) def test_all_budget_scales(self): """ Test all supported budget scales """ tests = [ ('2k', 0, 2000, '2k'), ('2 thousand', 0, 2000, '2 thousand'), ('2 hazar', 0, 2000, '2 hazar'), ('2 hazaar', 0, 2000, '2 hazaar'), ('2 hajar', 0, 2000, '2 hajar'), ('2 hajaar', 0, 2000, '2 hajaar'), ('2l', 0, 200000, '2l'), ('2 lac', 0, 200000, '2 lac'), ('2 lacs', 0, 200000, '2 lacs'), ('2 lak', 0, 200000, '2 lak'), ('2 laks', 0, 200000, '2 laks'), ('2 lakh', 0, 200000, '2 lakh'), ('2 lakhs', 0, 200000, '2 lakhs'), ('2m', 0, 2000000, '2m'), ('2mn', 0, 2000000, '2mn'), ('2 mil', 0, 2000000, '2 mil'), ('2 mill', 0, 2000000, '2 mill'), ('2 million', 0, 2000000, '2 million'), ('2c', 0, 20000000, '2c'), ('2 cr', 0, 20000000, '2 cr'), ('2 cro', 0, 20000000, '2 cro'), ('2 cror', 0, 20000000, '2 cror'), ('2 crore', 0, 20000000, '2 crore'), ('2 crores', 0, 20000000, '2 crores'), ] for test, min_budget, max_budget, original_text in tests: budget_dicts, original_texts = self.budget_detector.detect_entity( text=test) self.assertEqual(budget_dicts, [self.make_budget_dict(max_budget=max_budget)]) self.assertEqual(original_texts, [original_text])