Source code for clingraph.utils

"""
Utils functions used across the project
"""
import os
import logging
from clingo.symbol import SymbolType
log = logging.getLogger('custom')


[docs]def apply(elements, function,**kwargs): """ Applies a given function to the elements. Args: elements (list[dic]|dic): A dictionary where the keys are considered the graph names and the function is applied to the values. Can also be a list of such dictionaries, where each element is considered a model. Any ``None`` values in the list will be skiped. function (callable): The function to be applied **kwargs: Any arguments passed to the function. If an argument ``name_format`` is passed, ``{graph_name}`` and ``{model_number}`` will be substituted in this string by the corresponding values during the iteration. Returns: (list[dic]|[dic]) The elements after appling the function to the values """ is_multi_model = isinstance(elements,list) if not is_multi_model: elements = [elements] name_format = None if 'name_format' in kwargs: if kwargs['name_format'] is None: name_format = "{graph_name}" else: name_format=kwargs['name_format'] if len(elements)>1 and '{model_number}' not in name_format: log.warning("Output files will be overwritten since no `{model_number}` is used in the name format argument.") result = [] for i,d in enumerate(elements): if d is None: result.append(None) continue element_result = {} for graph_name, e in d.items(): if name_format: kwargs["name_format"]=name_format.replace('{graph_name}', graph_name).replace('{model_number}',str(i)) element_result[graph_name]= function(e, **kwargs) result.append(element_result) if not is_multi_model: return result[0] return result
def _write(info, directory, format, name_format): """ Writes the string info Args: directory (str): Path to the directory where to write format (str): Output format name_format (str): The file name """ #pylint: disable=redefined-builtin file_name = name_format file_path = os.path.join( directory, f"{file_name}.{format}") os.makedirs(os.path.dirname(file_path), exist_ok=True) with open(file_path,'w',encoding='utf-8') as f: f.write(info) return file_path
[docs]def write(elements, directory, format, name_format=None): """ Writes all the elements info using :py:func:`apply` Args: elements (list|dic): A dictionary where the keys are considered the graph names and the write is applied to the values. Can also be a list of such dictionaries, where each element is considered a model. directory (str): Path to the directory where to write format (str): Output format name_format (str): The file name Returns: [dic | list[dic]]: A dictionary with the paths where the files where saved as values for each graph. Or a list of such dictionaries, each element corresponding to a model. """ #pylint: disable=redefined-builtin return apply(elements, _write, directory = directory, format = format, name_format=name_format)
[docs]def pythonify_symbol(s): """ Get a python element from a clingo symbol Args: s (clingo.Symbol): The clingo symbol Returns: A integer, string or tuple """ if s.type == SymbolType.Number: return s.number if s.type == SymbolType.String: return s.string if s.type == SymbolType.Function: if s.name == "": return tuple(pythonify_symbol(a) for a in s.arguments) return str(s) raise RuntimeError(f"Unsupported clingo type {s.type}")
[docs]def stringify_symbol(s): """ Get a string representation of a clingo symbol Args: s (clingo.Symbol): The clingo symbol Returns: A string """ return str(s).strip('"')