Skip to content

Restructure the source code like the JS/Go versions#30

Merged
kirsle merged 1 commit intomasterfrom
feature/code-restructure
Jul 21, 2016
Merged

Restructure the source code like the JS/Go versions#30
kirsle merged 1 commit intomasterfrom
feature/code-restructure

Conversation

@kirsle
Copy link
Copy Markdown
Member

@kirsle kirsle commented Jul 13, 2016

This brings a long-needed code structure update to the Python version to put it on par with what the JS and Go versions are doing.

      .   .       
     .:...::      RiveScript Interpreter (Python)
    .::   ::.     Library Version: v1.13.0
 ..:;;. ' .;;:..  
    .  '''  .     Type '/quit' to quit.
     :;,:,;:      Type '/help' for more options.
     :     :      

Using the RiveScript bot found in: eg/brain
Type a message to the bot and press Return to send it.

You> hello bot
Bot> How do you do. Please state your problem.

Testing

You can install this branch with pip:

pip install https://github.com/aichaos/rivescript-python/archive/feature/code-restructure.zip

Code Reorganization

This mostly breaks the monolithic rivescript.py into a handful of smaller, more focused pieces, and moves some functions around.

  • rivescript.parser now contains all the parsing logic used under the hood by functions like load_file() and stream(). Its parse() function is decoupled from RiveScript (apart from debug log methods) and it returns a data structure of what was parsed from the file. This may be useful to third-party developers if they just want to parse RiveScript code.
  • rivescript.brain now holds the logic for actually fetching a reply for the user. This includes the implementation of the reply() method and helper functions (tag processing, input message formatting, regexp compiling)
  • rivescript.inheritance includes utility functions for crawling the inheritance tree to find triggers.
  • rivescript.sorting includes the functions for sorting replies.
  • rivescript.utils has the miscellaneous internal utility functions.

The biggest change is with regards to how triggers are stored internally. The old way had the self._topics structure contain a bunch of nested dictionaries, with keys like:

_topics = {
  "random": {
    "hello bot": {
      "reply": { "0": "Hello human!" },
      "redirect": "",
      # etc
    }
  }
}

This way had problems such as how to handle duplicate triggers and it made it messier to keep track of triggers that had %Previous tags apart from those that do not. The new way keeps the triggers in an array, and includes a pointer to the trigger's data along with the text itself (no needing to do separate lookups! For example, there used to be a thattrig map that correlated %Previous triggers with their data locations... and the inheritance functions used to have a method of find_trigger_by_inheritance and that's no longer needed either).

It now looks more like:

_topics = {
  "random": [ # array of triggers! duplicates technically allowed
    {
      "trigger": "hello bot",
      "reply": [ # the reply is a simple array, not a fake array hash map!
            "Hello human!"
      ],
      "redirect": None,
      # etc.
    },
    # more triggers...
  ]
}

API Shuffling

Some functions were moved out of the rivescript.rivescript module and into their own, more relevant spots. Other functions were no longer needed and were removed.

Most of these were internal, private use functions that you shouldn't have been using anyway, but here's the complete list:

  • rivescript.rs_version attribute now belongs to brain.rs_version
  • _initTT() is now in sorting.init_topic() and does a lot less work.
  • _sort_that_triggers() is removed.
  • _sort_trigger_set() is moved to sorting.sort_trigger_set()
  • _sort_list() is moved to sorting.sort_list()
  • _init_sort_track() is moved to sorting.init_sort_track()
  • _format_message(), _getreply(), _substitute(), _do_expand_array(), _expand_array(), _reply_regexp(), _process_tags() and the implementation of reply() have all been moved to rivescript.brain
  • _string_format, _word_count, _is_atomic and _strip_nasties are all moved to utils
  • _topic_triggers is now in rivescript.inheritance.get_topic_triggers
  • _find_trigger_by_inheritance is removed.
  • _get_topic_tree is now in rivesript.inheritance.get_topic_tree

Other Changes

  • Refactor the rivescript.interactive script to use argparse instead of getopt and add a pretty logo.
  • Add a shell.py as an (easier?) way to invoke the interactive mode.

Things To Do

At some point in the future I want to:

  • Break unit tests apart into smaller more focused files like the JS version.
  • Put the deparse() and related functions into its own module
  • Rename rivescript.python as something like rivescript.lang.python for consistency with the other implementations.
  • Revisit all docstrings and rewrite them in Google style.

@kirsle kirsle force-pushed the feature/code-restructure branch 6 times, most recently from 1a8f6a7 to 82b5a6f Compare July 13, 2016 22:08
@kirsle kirsle merged commit e26fc77 into master Jul 21, 2016
@kirsle kirsle deleted the feature/code-restructure branch July 21, 2016 17:54
deldesir added a commit to deldesir/rivescript-python that referenced this pull request Mar 21, 2026
Restructure the source code like the JS/Go versions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant