import spacy import subprocess from typing import Tuple from spacy import displacy from anytree import Node, RenderTree class Pipeline: def __init__( self ) -> None: self.nlp = None self.__ch_html_tree = None self.__ch_str_tree = None self.__ch_sentence = None self.__init_nlp(model="en_core_web_md") def __init_nlp( self, model: str ) -> None: self.nlp = None try: self.nlp = spacy.load(model) except: print(f"* Downloading {model} model...") _ = subprocess.Popen( f"python -m spacy download {model}", stdout=subprocess.PIPE, shell=True ).communicate() self.nlp = spacy.load(model) def __postag( self, tk: str ) -> str: tag = "" plural_tags = ["NNS", "NNPS"] if tk.tag_ in plural_tags: tag = " ({}) (Plural)".format(tk.tag_) else: tag = " ({})".format(tk.tag_) return tag def __genSyntacticTree( self, expr: str ) -> Tuple[str,str]: doc = self.nlp(expr) root = next(doc.sents).root node = Node("" + root.text + ": (Root)" + self.__postag(root), parent=None) def tree( tk: str, last_node: Node, depth: int ) -> None: if tk.n_lefts + tk.n_rights > 0: for child in tk.children: tree( child, Node( "" + child.text + ": " + str(depth + 1) + self.__postag(child), parent=last_node ), depth+1 ) tree(root, node, 0) syntactic_str_tree = "" for pre, fill, node in RenderTree(node): syntactic_str_tree += """{}{}\n""".format(pre, node.name) syntactic_tree = displacy.render(doc, style='dep', options={'distance': 100}) syntactic_html_tree = f"""
{syntactic_tree}
""" return syntactic_html_tree, syntactic_str_tree def compute( self, sentence: str ) -> Tuple[str,str,str]: error = "" error_template = """
""" if sentence.strip() == "": error = error_template.format("The sentence can not be empty!") return error, "", "" if sentence != self.__ch_sentence: self.__ch_sentence = sentence self.__ch_html_tree, self.__ch_str_tree = self.__genSyntacticTree(sentence) return error, self.__ch_html_tree, self.__ch_str_tree