python - How should multiple parsers for keywords in strings be structured? -


i'm writing code parses strings, using simple keywords. on parsing, code performs various actions, such printing response, running functions etc. , keeps track of whether able respond.

i using multiple parsers , have illustrated in code shown below.

what better ways structure code, particularly mind scalability , code compactness? example, imagine many more parsers being added operate on principles more complex simple keyword-spotting.

mwe:

#!/usr/bin/python  import json import os import requests import subprocess import sys  def main():      message = "how you"     #message = "ip address"     #message = "restart"      triggered = [         parse_1(message = message),         parse_2(message = message)     ]      if not any(triggered):          report_help()  def parse_1(     message = none     ):      def keyphrases_text_response(         message    = none,         keyphrases = none,         response   = none         ):          if any(pattern in message pattern in keyphrases):              print(response)              return true          else:              return false      triggered = [         keyphrases_text_response(             message    = message,             keyphrases = [                         "image"                         ],             response   = "http://i.imgur.com/miqrlth.jpg"         ),         keyphrases_text_response(             message    = message,             keyphrases = [                         "sup",                         "hi"                         ],             response   = "sup home bean"         ),         keyphrases_text_response(             message    = message,             keyphrases = [                         "how you",                         "are well",                         "status"                         ],             response   = "nae bad fam"         ),         keyphrases_text_response(             message    = message,             keyphrases = [                         "help",                         "what can do"                         ],             response   = "i can report ip address , can restart script."         )     ]      if any(triggered):          return true      else:          return false  def parse_2(     message = none     ):      triggered = []      if any(pattern in message pattern in\         [             "ip",             "i.p.",             "ip address",             "i.p. address",             "ip address"         ]         ):          triggered.append(true)         report_ip()      if any(pattern in message pattern in\         [             "restart"         ]         ):          triggered.append(true)         restart()      if any(pattern in message pattern in\         [             "ssh",             "reverse"         ]         ):          triggered.append(true)         engage_command(             command    = "ssh -r 10000:localhost:22 www.sern.ch",             background = true         )      if any(triggered):          return true      else:          return false  def report_ip(     contact = none,     country = true     ):      ip = "unknown"      try:          data_ip_website = requests.get("http://ipinfo.io/json")         data_ip         = data_ip_website.json()         ip              = data_ip["ip"]         country         = data_ip["country"]      except:          pass      text = "ip address: " + ip      if country:          text = text + " (" + country + ")"      print(text)  def restart():      print("restart! (and i'm in crazy loop!)")     import __main__     os.execv(__main__.__file__, sys.argv)  def report_help():      print("i can report ip address, can restart script , can run commands.")  def engage_command(     command    = none,     background = false     ):      print("engage command: {command}".format(command = command))      if not background:          process = subprocess.popen(             [command],             shell      = true,             executable = "/bin/bash"         )         process.wait()         output, errors = process.communicate()          return output      else:          subprocess.popen(             [command],             shell      = true,             executable = "/bin/bash"         )          return none  if __name__ == "__main__":      main() 

note: code below python 3.5 or higher.
first, separate logic of parsers logic of code runs strings through parsers. let's start code latter:

from typing import list   def run_parsers(message: str, parsers: list[baseparser]) -> none:     parser in parsers:         parser.parse_message(message) 

note: in latest python versions, can annotate code. reason why chose here make clear function doesn't care "type" of parser gets. expects list of baseparser instances(including instances of classes inherit baseparser) , calls parse_sting method of each of them on message. function doesn't care parse_message does.
next, want define api parser objects run_parsers can use them without knowing how work.

class baseparser:     def __init__(self):         self.triggered = false      def parse_message(self, message: str):         raise notimplementederror 

as can see baseparser has no logic, says whoever inherits me should define parse_message. also, inheriters triggered attribute.
now, let's see code 1 such inheriter.

class imageparser:      def __init__(self):         super().__init__()         self.key_phrases = ('jpg', 'png')      def parse_message(self, message):         phrase in self.key_phrases:             if phrase in message:                 self.respond()                 self.triggered = true      def respond(self):         do_something_here() 

as long inheriters follow "rules" set baseinheriter(i.e. implement method , have attribute called triggered), run_parsers happily run them.
note:imageparser sets triggered true , how can determine parsers took action.
finally, let's convert main function make work above code:

def main():     message = 'how  you?'     parsers = [imageparser(), ipparser()]     run_parsers(message, parsers)     if not any([parser.triggered parser in parsers]):         show_help() 

important tip: make sure read , use pep8 guidelines. object-oriented design complicates flow of application , don't want further complicate things coming own code style or conventions.


Comments

Popular posts from this blog

android - InAppBilling registering BroadcastReceiver in AndroidManifest -

python Tkinter Capturing keyboard events save as one single string -

sql server - Why does Linq-to-SQL add unnecessary COUNT()? -