def get_next_slot_text(self, slot_name, slot_required): try: types_with_options = u.choices_type_list slot = self.get_slot(slot_name) useful_info = '' value_type = slot[u.value_type] required_string = fn.get_required_string(slot_required) if value_type in types_with_options: choice_list = slot[u.choice_list] option_string = fn.get_string_from_list(choice_list) if value_type in [u.dropdown, u.checkbox]: string = f"Select the {slot_name} in the following list {option_string}. {required_string}" elif value_type == u.radio: string = f"Choose your {slot_name} in the following list {option_string}. {required_string}" if u.DEBUG: print("choice list") print(choice_list) else: # we construct some useful info. if value_type in [u.number, u.decimal, u.integer]: useful_info = f'\nThe value should be a number between {slot[u.min_value]} and {slot[u.max_value]}.' insert_style = styles.get_insert() please_style = styles.get_please() string = f"{please_style} {insert_style} the {slot_name}. {required_string}" string = f'{string}{useful_info}' return string except: print("ERROR: Fail to extract the text for the next slot") raise Exception
def verify_compatibility_integer(value, min_value=-float('inf'), max_value=float('inf')): try: value = value.replace(' ', '') int_value = get_integer(value) sorry_style = styles.get_sorry() insert_style = styles.get_insert() please_style = styles.get_please() if int_value is None: text = f'{sorry_style} the value {value} is not an integer, {please_style} {insert_style} a valid value.' return False, text number = int(int_value) if number < min_value or number > max_value: if number < min_value: text = f'{sorry_style} the value inserted is less than the minimum value acceptable {min_value}.' else: text = f'{sorry_style} the value inserted is more than the maximum value acceptable {max_value}.' return False, text return True, int_value except: print( f'Fail to verify the compatibility of the value {value} for the type integer' ) raise Exception
def verify_compatibility_number(value, min_value=-float('inf'), max_value=float('inf')): try: value = value.replace(' ', '') int_value = int(get_integer(value)) interval_text = '' if min_value != -float('inf'): interval_text = f'The minimum value for this field is {min_value}. ' if max_value != float('inf'): interval_text = f'{interval_text}The maximum value for this field is {max_value}.' if int_value is None: sorry_style = styles.get_sorry() insert_style = styles.get_insert() please_style = styles.get_please() text = f'{sorry_style} the value {value} is not a number, {please_style} {insert_style} a valid value.' return False, text if int_value < min_value or int_value > max_value: if int_value < min_value: text = f'{sorry_style} the value inserted is less than the minimum value acceptable {min_value}.' else: text = f'{sorry_style} the value inserted is more than the maximum value acceptable {max_value}.' return False, text return True, value except: print( f'Fail to verify the compatibility of the value {value} for the type number' ) raise Exception
def verify_compatibility_tel(value): try: text = value # we should not have the space in the final value if ' ' in value: text = text.replace(' ', '') if '-' in value: text = text.replace('-', '') plus_sign = "+" num_occur = value.count(plus_sign) if num_occur == 1: if value[0] != plus_sign: text = f'The character < {plus_sign} > could only be at the beginning of the number' return False, text elif num_occur > 1: text = f'A telephone number should not contain the character < {plus_sign} > several times' return False, text # we remove the eventual plus sign at the beginning number = value.replace(plus_sign, '') # we verify if the remaining string only contains digits from 0 to 9 number = fn.convert_to_int(number) if number is None or len(value) < u.min_length_phone_number: sorry_style = styles.get_sorry() insert_style = styles.get_insert() please_style = styles.get_please() text = f'{sorry_style} the value {value} is not valid, {please_style} {insert_style} a valid phone number' return False, text return True, text except: print( f'Fail to verify the compatibility of {value} for the type phone number' ) raise Exception
def next_char_string(): try: # we add styles to the output next_style = styles.get_next() please_style = styles.get_please() insert_style = styles.get_insert() end_style = styles.get_end() # we set the message to be returned to the user string = (f'{please_style} {insert_style} the {next_style} character, remember that you can use the expression SPACE for the blank' + f' and the expression TERMINATE to {end_style} the spelling') return string except: print('Fail to get the string for asking the next character') raise Exception
def verify_compatibility_decimal(value, precision=2, min_value=-float('inf'), max_value=float('inf')): try: value = value.replace(' ', '') dec_value = get_decimal(value) sorry_style = styles.get_sorry() insert_style = styles.get_insert() please_style = styles.get_please() if dec_value is None: text = f'{sorry_style} the value {value} is not a decimal, {please_style} {insert_style} a valid value.' return False, text # float takes the 'dot' as separator, so we should transform it before getting the float number = float(dec_value.replace(',', '.')) if number < min_value or number > max_value: if number < min_value: text = f'{sorry_style} the value inserted is less than the minimum value acceptable {min_value}.' else: text = f'{sorry_style} the value inserted is more than the maximum value acceptable {max_value}.' return False, text if ',' not in dec_value: return True, dec_value # the value has a decimal part if precision == float('inf'): return True, dec_value dec_part = dec_value[dec_value.index(',') + 1:] if len(dec_part) <= 2: # the precision is respected return True, dec_value # the precision is more accurate then what required, we decide to troncate, no rounding dec_value = dec_value[:dec_value.index(',') + precision + 1] return True, dec_value except: print( f'Fail to verify the compatibility of the value {value} for the type decimal with precision {precision}' ) raise Exception
def fillGenericField(self): try: entities = self.state.get_latest_message()["entities"] intent = self.state.get_latest_message()["intent"]["name"] count = len(entities) if count == 0: # the user wants to modify a field but did not specify which field modify_style = styles.get_modify() insert_style = styles.get_insert() string = ( f"Which field exactly do you want to {modify_style}, and which value" + f" do you want to {insert_style} for that field?") self.state.set_possible_next_action(u.fill_field_action) return string slot_name_list, slot_value_list = fn.extract_fields_names_and_values( entities) # we first verify if each slot_name corresponds to a field in the dorm correct, string = self.state.all_fields_present(slot_name_list) if not correct: return string """we extract now the spelling field and we insert them in the spelling list after that we fill the generic fields before passing the floor to fillSpellingField to complete the fields in spelling list.""" slot_name_list, slot_value_list = self.state.set_spelling_list( slot_name_list, slot_value_list) # the spelling list have been set and we can continue if len(slot_value_list) + len(slot_name_list) == 0: string = self.fillSpellingField() return string if len(slot_value_list) + len(slot_name_list) >= 1: # there is at least one generic info # the use of possible_next_action here is to mitigate training error. with a perfect training they are not necessary if len(slot_value_list) == 1 and len(slot_name_list) == 0 and ( self.state.get_possible_next_action() == u.fill_field_action or intent == u.fill_field_action): # we are inserting a value for the current field slot_name = self.state.get_next_slot( only_name=True ) # return also if the next slot is required or not # We make verify if the current field is spelling spelling_fields = self.state.get_spelling_fields() if slot_name in spelling_fields: string = self.fillSpellingField() return string slot_value = slot_value_list[0] # the slot value can change, being put in the right format # we go to the filling procedure insuring that the field is not spelling string = self.state.filling_procedure( slot_name, slot_value) elif self.state.get_possible_next_action( ) != u.fill_field_action and intent != u.fill_field_action: # probably bad destination due to misinterpretation sorry_style = styles.get_sorry() please_style = styles.get_please() text = f'{sorry_style} i do not understand your request, could you reformulate {please_style}?' _, required = self.state.get_next_slot() if not required: text = f'{text} otherwise, you can {u.fun_skip} or {u.fun_submit}' else: text = f'{text} otherwise, you can {u.fun_explain_field} or {u.fun_complete_field}' self.state.set_warning_message(text) raise Exception else: # we have a list of fields with their values string = self.state.fill_generic_slots( slot_name_list=slot_name_list, slot_value_list=slot_value_list) next_field_before = self.state.get_next_slot(only_name=True) # we verify if the spelling_list is empty or not if len(self.state.get_spelling_list()) != 0: string_spelling = self.fillSpellingField() next_field_after = self.state.get_next_slot(only_name=True) if next_field_before == next_field_after: # the spelling did not modified the Web page, we return the string from the non spelling fields return string # the spelling mofified the Web Form, so we use its string return string_spelling return string except: if not self.state.get_warning_present(): print( "A problem occured while a registration form bot tries to fill a camp" ) raise Exception