def run(self, event): if event.command_args.count(" ") == 0: number = event.command_args lang = "american" elif event.command_args.split()[1].lower() in ["british", "english"]: number = event.command_args.split()[0] lang = "english" elif event.command_args.split()[1].lower() in ["european", "french"]: number = event.command_args.split()[0] lang = "european" else: number = event.command_args.split()[0] lang = "american" if Commons.check_numbers(number): number = number elif Commons.check_calculation(number): function_dispatcher = event.server.hallo.function_dispatcher calc_func = function_dispatcher.get_function_by_name("calc") calc_obj = function_dispatcher.get_function_object( calc_func) # type: Calculate number = calc_obj.process_calculation(number) else: return event.create_response( "Error, you must enter a valid number or calculation.") return event.create_response(self.number_word(number, lang) + ".")
def preflight_checks(self, calc): # strip spaces calc_clean = calc.replace(" ", "").lower() # make sure only legit characters are allowed if not Commons.check_calculation(calc_clean): # TODO use custom exception raise Exception("Error, Invalid characters in expression") # make sure open brackets don't out-number close if calc.count("(") > calc.count(")"): raise Exception("Error, too many open brackets") # Make sure close brackets don't out-number open. # Previously I thought it would be okay to skip this, but "(21/3))+2))*5" evaluates as 17, rather than 45 if calc.count(")") > calc.count("("): raise Exception("Error, too many close brackets") if len(calc) == 0: raise Exception("Error, empty calculation or brackets") return True
def run(self, event): line_clean = event.command_args.strip().lower() if line_clean.isdigit(): number = int(line_clean) elif Commons.check_calculation(line_clean): function_dispatcher = event.server.hallo.function_dispatcher calc_func = function_dispatcher.get_function_by_name("calc") calc_obj = function_dispatcher.get_function_object( calc_func) # type: Calculate number_str = calc_obj.process_calculation(line_clean) if "." in number_str: return event.create_response( "Error, this calculation does not result in an integer. " + "The answer is: {}".format(number_str)) number = int(number_str) else: return event.create_response( "Error, this is not a valid number or calculation.") prime_factors = self.find_prime_factors(number) return event.create_response("The prime factors of {} are: {}.".format( number, "x".join(str(x) for x in prime_factors)))
def passive_run(self, event, hallo_obj): """Replies to an event not directly addressed to the bot.""" if not isinstance(event, EventMessage): return # Check if fullLine is a calculation, and is not just numbers, and contains numbers. if not Commons.check_calculation(event.text): return None if Commons.check_numbers(event.text.replace(".", "")): return None if not any([ char in event.text for char in [str(x) for x in range(10)] + ["e", "pi"] ]): return None # Clean up the line and feed to the calculator. calc = event.text.replace(" ", "").lower() try: self.preflight_checks(calc) answer = self.process_calculation(calc) return event.create_response(answer) except Exception as e: logger.error("Passive calc failed: ", exc_info=e) return None
def test_check_calculation__invalid(calculation): assert not Commons.check_calculation(calculation), ( "Invalid string judged to be calculation, " + calculation)
def test_check_calculation__valid(calculation): assert Commons.check_calculation(calculation), ( "Valid string judged to be not calculation, " + calculation)