def test_ranking_parser_whitespace_partial_token_matches(): expected_result = ("The_orange_cat", "The_grey_cat") rp = RankingParser() result = rp.parse_statements([ "The orange cat before The grey cat", ]) assert (result == expected_result)
def test_ranking_parser_parse_whitespace_in_brackets(): expected_result = ("Captain_Blackbeard", "Long_John_Silver") rp = RankingParser() result = rp.parse_statements([ "[Captain Blackbeard] is not last", "[Long John Silver] is not first" ]) assert (result == expected_result)
def test_ranking_parser_whitespace_partial_token_matches_missed_capital(): expected_result = ("The_orange_cat", "Grey_cat") rp = RankingParser() result = rp.parse_statements([ "The orange cat is before the Grey cat", ]) assert (result == expected_result)
def solve_challenge(): rl = RankingLexer() hl = HighLighter(rl, STYLE_MAP) print() for s in programmer_riddle: print(hl.highlight(s)) print() print("Solving by specifying rules") print(Fore.CYAN + ("=" * 30) + Fore.RESET) r = RankingProblem() r.set_items(["Jessie", "Evan", "John", "Sarah", "Matt"]).\ not_first("Jessie").not_last("Evan").\ not_first("John").not_last("John").\ is_before("Sarah", "Evan").\ not_directly_before_or_after("Matt", "John").\ not_directly_before_or_after("John", "Evan") solutions = r.solve() for s in solutions: typewrite_print(", ".join(s)) print() print("Solving by parsing") print(Fore.CYAN + ("=" * 30) + Fore.RESET) rp = RankingParser() typewrite_print(", ".join(rp.parse_statements(programmer_riddle)))
def __init__(self, project_id=None, log_history=True): self.generated_project = True self.log_history = log_history self.project_id = None self.set_project_id(project_id) self._rp = RankingParser() self._rl = RankingLexer() self.lexer = self._rl.build() self._rp.build() self._hl = HighLighter(self._rl, STYLE_MAP) self.history = list() self.pp = pprint.PrettyPrinter(indent=4)
def test_ranking_parser_parse_statements(): expected_result = ( "Sarah", "John", "Jessie", "Evan", "Matt", ) rp = RankingParser() result = rp.parse_statements(programmer_riddle) print(result) assert (result == expected_result)
def test_ranking_parser_parse_add_entity_statements(): rp = RankingParser() expected_result = [ "George_Harrison", "John_Lennon", "Paul_McCartney", "Ringo_Starr", ] result = rp.parse_statements([ "+[Ringo Starr]", "John Lennon", "[Paul McCartney]", "+George Harrison", ]) assert (sorted(result) == expected_result)
def test_export_csv(): test = RankingParser() lines = None filename = str(uuid.uuid1()) filename = f"{filename}.csv" solutions = test.parse_statements(tea_steps, return_last_parsed=False) try: export_csv(solutions, filename) with open(filename, "r") as txt_file: lines = txt_file.readlines() finally: os.remove(filename) assert ("".join(lines) == tea_steps_result_csv)
def test_ranking_parser_parse_whitespace_no_brackets_multiline(): expected_result = [("Walk_the_dog", "Feed_the_cat")] rp = RankingParser() rp.build() rp.parse("""Walk the dog is not last Feed the cat is not first""") result = rp.solve() assert (result == expected_result)
def test_ranking_parser_multi_line_input(): multi_line_input = """ [Green] before [Red] [Yellow] before [Green] """ expected_result = [("Yellow", "Green", "Red")] rp = RankingParser() rp.build() rp.parse(multi_line_input) assert (rp.solve() == expected_result)
def generate_viz_from_statements( statements: List[str], output_dot_viz: str = None, max_pen_width=12, ): rp = RankingParser() rp.build() for step in statements: rp.parse(step) solutions = rp.solve() return generate_viz_from_solutions(solutions, output_dot_viz, max_pen_width=max_pen_width)
def test_ranking_parser_parse_statements_no_statements(): rp = RankingParser() with pytest.raises(IncompleteResultsError): rp.parse_statements([])
class Session(object): def __init__(self, project_id=None, log_history=True): self.generated_project = True self.log_history = log_history self.project_id = None self.set_project_id(project_id) self._rp = None self.reset_ranking_parser() self._rl = RankingLexer() self._rg = RankingGraph() self._rn = RankingNetwork() self.lexer = self._rl.build() self._hl = HighLighter(self._rl, STYLE_MAP) self.history = list() self.pp = pprint.PrettyPrinter(indent=4) def reset_ranking_parser(self): self._rp = RankingParser() self._rp.build() def set_project_id(self, project_id): if project_id is not None: self.generated_project = False self.project_id = project_id else: self.project_id = str(uuid.uuid1()) def change_project_id(self, project_id, move_files=True): if self.project_id == project_id: return if not path.exists(project_id): if self.generated_project or move_files: if path.exists(self.project_id): move(self.project_id, project_id) else: mkdir(project_id) else: if path.exists(self.project_id): copytree(self.project_id, project_id) else: mkdir(project_id) self.generated_project = False self.set_project_id(project_id) else: self.reset_ranking_parser() self.generated_project = False self.set_project_id(project_id) self.load_history(project_id) def file_in_project(self, filename, extension="txt"): result = check_file_extension(filename, extension) if result[:len(self.project_id)] != self.project_id: result = f"{self.project_id}/{result}" return result def do_parse(self, text, write_history=True): if text.strip() == "": return print(self._hl.highlight(text)) try: result = self._rp.parse(text) except ParsingError as e: print(STYLE_MAP["ERROR"], f"ERROR: {e}", STYLE_MAP["RESET"]) return if result is not None: self.history.append(text) if write_history: self.write_history() if not self._rp.ranking_problem.is_solvable: self.undo() if write_history: self.write_history() def write_history(self): if not self.log_history: return try: if not path.exists(self.project_id): mkdir(self.project_id) file_name = self.file_in_project("output", "txt") export_lines_to_text(self.history, file_name) except: pass def load_history(self, project_id): file_name = f"{project_id}/output.txt" lines = import_text_to_lines(file_name) if len(lines) == 0: print(f"Nothing to read from {file_name}") return self.history.clear() for l in lines: self.do_parse(l, write_history=False) def import_items(self, file_name): lines = import_text_to_lines(file_name) if len(lines) == 0: print(f"Nothing to read from {file_name}") return for l in lines: self.do_parse(f"+ [{l.strip()}]") print("imported items") def export_items(self, file_name): output_file_name = self.file_in_project(file_name, "txt") export_lines_to_text(self._rp.items, output_file_name) print(f"exported items to {output_file_name}") def do_tokenize(self, text): result = self._rl.tokenize(text.strip()) self.pp.pprint(result) def undo(self): if len(self.history) > 0: print(f"{STYLE_MAP['ERROR']}Undoing:{STYLE_MAP['RESET']}", self._hl.highlight(self.history[-1])) self._rp.remove_last_constraint() def print_history(self): for h in self.history: print(self._hl.highlight(h)) def print_token_debug(self, s): self.do_tokenize(s.strip()) def generate_graph(self, filename): solutions = self.solve() if len(solutions) == 0: print("No solutions to generate a graph from") return generate_viz_from_solutions(solutions, filename) def export_csv(self, filename): solutions = self.solve() if len(solutions) == 0: print("No solutions to generate a graph from") return output_filename = self.file_in_project(filename, "csv") export_csv(solutions, output_filename) def suggest_pair(self): pair = None try: pair = self._rp.ranking_problem.least_most_common_variable except Exception as e: print("Couldn't suggest pair", e) return print(self._hl.highlight(f"[{pair[0]}] versus [{pair[1]}]")) def solve(self): result = list() try: result = self._rp.solve() except IncompleteResultsError as e: print( f"{STYLE_MAP['ERROR']}{e.message}{Style.NORMAL}{STYLE_MAP['RESET']}" ) # result = e.results except UnsolvableModelError as e: print( f"{STYLE_MAP['ERROR']}{e.message}{Style.NORMAL}{STYLE_MAP['RESET']}" ) return result def print_stats(self, filename=None): solutions = self.solve() if len(solutions) == 0: print("No solutions to generate a stats from") return result = stats_from_solutions(solutions) print(Style.RESET_ALL) for item in result: print(f"{Style.BRIGHT}{item}{Style.NORMAL}") printout(result[item], item) print(Style.RESET_ALL) if filename is not None: lines = list() for key in result: lines.append(f"{key}={result[key]}") export_lines_to_text(lines, self.file_in_project(filename)) def display_commands(self): for key in commands: print(Style.RESET_ALL) print(f"{Style.BRIGHT}{key}{Style.NORMAL} : {commands[key][0]}") try: command_example = self._hl.highlight(commands[key][1]) except ParsingError as e: command_example = commands[key][1] print(f"{Style.DIM}{command_example}{Style.NORMAL}") print() print(Style.RESET_ALL) def display_solution(self): result = self.solve() if len(result) == 1: self.pp.pprint(result[0]) elif len(result) < 5: self.pp.pprint(result) else: print( f"{STYLE_MAP['INFO']}More than 5 results showing the path(s) with most support{STYLE_MAP['RESET']}" ) highlight_path = export_highlighted_path(result) self.pp.pprint(highlight_path) def read_input(self, text): text_split = text.split(" ") if text == "=": self.display_solution() elif text == "undo": self.undo() elif text == "history": self.print_history() elif text_split[0] in ["import_items", "import"]: if len(text_split) > 1: self.import_items(text_split[1]) else: print("Need to specify a filename") elif text_split[0] in ["export_items", "export"]: if len(text_split) > 1: self.export_items(text_split[1]) else: print("Need to specify a filename") elif text_split[0] == "load": if len(text_split) > 1: self.change_project_id(text_split[1]) else: print("Need to specify a filename") elif text_split[0] == "copy": if len(text_split) > 1: self.change_project_id(text_split[1], move_files=False) else: print("Need to specify a filename") elif text_split[0] in ["graph", "diagram"]: if len(text_split) > 1: self.generate_graph(f"{self.project_id}/{text_split[1]}") else: print("Need to specify a filename") elif text_split[0] in ["csv"]: if len(text_split) > 1: self.export_csv(f"{self.project_id}/{text_split[1]}") else: print("Need to specify a filename") elif text_split[0] == "~": self.suggest_pair() elif text_split[0] in ["stats"]: if len(text_split) > 1: self.print_stats(text_split[1]) else: self.print_stats() elif text[0] == "?": if len(text) > 2: self.print_token_debug(text[1:].strip()) else: print("insufficient parameters") elif text_split[0] == "help": self.display_commands() else: self.do_parse(text) def start(self): prompt_session = PromptSession() word_completer = WordCompleter(self._rp.items, ignore_case=True) while True: prompt = "RankParser>" if not self.generated_project: prompt = f"{self.project_id}>" text = prompt_session.prompt(prompt, auto_suggest=AutoSuggestFromHistory(), completer=word_completer, complete_in_thread=True) if text.lower() == "quit": break if text != "": try: self.read_input(text) except Exception as e: print(Style.RESET_ALL) print(f"{STYLE_MAP['ERROR']}Error reading input: {text}") print(f"{e}{Style.NORMAL}") else: word_completer.words = self._rp.items
def test_can_create_rule_parser(): rp = RankingParser() assert (isinstance(rp, RankingParser))
def reset_ranking_parser(self): self._rp = RankingParser() self._rp.build()
def test_ranking_parser_parse_statements_no_statements(): rp = RankingParser() result = rp.parse_statements([]) assert (result is None)
class Session(object): def __init__(self, project_id=None, log_history=True): self.generated_project = True self.log_history = log_history self.project_id = None self.set_project_id(project_id) self._rp = RankingParser() self._rl = RankingLexer() self.lexer = self._rl.build() self._rp.build() self._hl = HighLighter(self._rl, STYLE_MAP) self.history = list() self.pp = pprint.PrettyPrinter(indent=4) def set_project_id(self, project_id): if project_id is not None: self.generated_project = False self.project_id = project_id else: self.project_id = str(uuid.uuid1()) def change_project_id(self, project_id): self.generated_project = False if not path.exists(project_id): move(self.project_id, project_id) self.set_project_id(project_id) else: self.set_project_id(project_id) self.load_history(project_id) def do_parse(self, text, write_history=True): if text.strip() == "": return print(self._hl.highlight(text)) try: result = self._rp.parse(text) except TypeError as e: print(e) return if result is not None: self.history.append(text) if write_history: self.write_history() def write_history(self): if not self.log_history: return try: if not path.exists(self.project_id): mkdir(self.project_id) file_name = f"{self.project_id}/output.txt" with open(file_name, "w") as f: for l in self.history: f.write(f"{l}\n") except: pass def load_history(self, project_id): file_name = f"{project_id}/output.txt" lines = [] with open(file_name, "r") as f: lines = f.readlines() if len(lines) == 0: print(f"Nothing to read from {file_name}") return self.history.clear() for l in lines: self.do_parse(l, write_history=False) def import_items(self, file_name): with open(file_name, "r") as f: lines = f.readlines() if len(lines) == 0: print(f"Nothing to read from {file_name}") return for l in lines: self.do_parse(f"+ [{l.strip()}]") print("imported items") def do_tokenize(self, text): result = self._rl.tokenize(text.strip()) self.pp.pprint(result) def undo(self): self._rp.remove_last_constraint() print(self._rp.solve()) def print_history(self): for h in self.history: print(self._hl.highlight(h)) def print_token_debug(self, s): self.do_tokenize(s.strip()) def generate_graph(self, filename): solutions = self._rp.solve() if len(solutions) == 0: print("No solutions to generate a graph from") return generate_viz_from_solutions(solutions, filename) def suggest_pair(self): pair = None try: pair = self._rp.ranking_problem.least_most_common_variable() except Exception as e: print("Couldnt suggest pair", e) return print(self._hl.highlight(f"[{pair[0]}] versus [{pair[1]}]")) def display_commands(self): for key in commands: print(f"{key} : {commands[key][0]}") print(self._hl.highlight(commands[key][1])) try: self.do_tokenize(commands[key][1]) except: pass print() def read_input(self, text): text_split = text.split(" ") if text == "=": result = self._rp.solve() if len(result) == 1: self.pp.pprint(result[0]) elif len(result) > 1: self.pp.pprint(result) elif text == "undo": self.undo() elif text == "history": self.print_history() elif text == "import_items": if len(text_split) > 1: self.import_items(text_split[1]) else: print("Need to specify a filename") elif text_split[0] == "load": if len(text_split) > 1: self.change_project_id(text_split[1]) else: print("Need to specify a filename") elif text_split[0] in ["graph", "diagram"]: if len(text_split) > 1: self.generate_graph(f"{self.project_id}/{text_split[1]}") else: print("Need to specify a filename") elif text_split[0] == "~": self.suggest_pair() elif text[0] == "?": if len(text) > 2: self.print_token_debug(text[1:].strip()) else: print("insufficient parameters") elif text_split[0] == "help": self.display_commands() else: self.do_parse(text) def start(self): self._rp.build() while True: prompt = "RankParser>" if not self.generated_project: prompt = f"{self.project_id}>" text = input(prompt).strip() if text.lower() == "quit": break if text != "": try: self.read_input(text) except Exception as e: print(f"Error reading input: {text}") print(e)