Source code for pydialogue.language.helpers

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
This module contains functions that are used by all other modules in this folder.
"""

import functools
import random

from . import components as lc


[docs] def auto_fill(args_ignored_ids=None, args_ignored_keys=None): """ Creates a decorator that fills the missing argument parts in the :mod:`language.sentences <pydialogue.language.sentences>` functions and the :mod:`language.queries <pydialogue.language.queries>` modules. Each argument of the functions is a tuple (argument_value, argument_part). If the argument_value is the only one provided, the argument_part is automatically filled, and the necessary tuple is created. Parameters ---------- args_ignored_ids : list, optional The indices of the arguments that should not be filled. The indices start from 0, 1, ... 0 represents the first argument in the function. args_ignored_keys : list, optional The keys of the arguments that should not be filled. The keys are the argument names. For example, the argument name "player" in sentences.go. Returns ------- function The function decorator. """ def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): arg_dict = {} arg_list = list() for idx, key in enumerate(args): if idx in args_ignored_ids or isinstance(args[idx], tuple): arg_list.append(args[idx]) else: arg_list.append((args[idx], convert_obj_to_part(args[idx]))) for key, value in kwargs.items(): if key in args_ignored_keys or isinstance(value, tuple): arg_dict[key] = value else: arg_dict[key] = (value, convert_obj_to_part(value)) return func(*arg_list, **arg_dict) return wrapper return decorator
[docs] def convert_obj_to_part(obj): """ Converts the object to a language component (Word, Phrase, or list). """ from ..environment import entities as em part = obj if isinstance(obj, str): part = lc.Word(obj) elif isinstance(obj, em.BaseEntity): part = obj.describe() elif isinstance(obj, (tuple, list)): new_list = [] for elem in obj: new_list.append(convert_obj_to_part(elem)) part = new_list elif isinstance(obj, set): shuffled_list = list(obj) random.shuffle(shuffled_list) new_list = [] for elem in obj: new_list.append(convert_obj_to_part(elem)) part = new_list return part
[docs] def returns_same(sentence): """ Returns the same object. """ return sentence
[docs] def join_parts_with_connector(parts, connector): """ Adds a Word(connector) between each of the language components (Word, Phrase, or Sentence). """ joined = [parts[0]] for i in range(1, len(parts)): word_connector = lc.Word(connector) joined.append(word_connector) joined.append(parts[i]) return joined
[docs] def reduce_sentences(sentences, memo=None, add_original=False): """ Reduce the sentences to simpler ones. Please check the components.Sentence.reduce for more information. Parameters ---------- sentences : list The list of sentences to be reduced. Each sentence should be an instance of the class :class:`Sentence <pydialogue.language.components.Sentence>` and have the reduce method implemented or should define the field sent.customizers['reduce'] by creating an instance of the class :class:`Customizer <pydialogue.language.components.Customizer>`. If the reduce method is not implemented, the same sentence is returned. memo : dict, optional A dictionary that prevents reducing the same sentence twice. add_original : bool, optional Whether to add the original/unreduced form of the sentence to the list. Returns ------- reduced : list The list of reduced sentences. """ if memo is None: memo = dict() reduced = [] for sent in sentences: sent_id = id(sent) if sent_id not in memo: memo[sent_id] = sent reduc = sent.reduce() if not isinstance(reduc, list): reduc = [reduc] if len(reduc) == 1 and id(reduc[0]) == id(sent): reduced += reduc else: if add_original: reduced.append(sent) reduced += reduce_sentences(reduc, memo, add_original) return reduced