Source code for params.json_probs

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
This module is aimed at processing input json files specifying the probabilities of the syntactic constructs to
be created by Cnerator (command line option -P). See json/probabilities for particular examples.
"""

from core import probs_helper
from typing import Union, Dict
import json
import sys


[docs]def parse_probabilities_specification_json_file(file_name: str) -> Dict[str, dict]: """Parses a json file with probabilities specifications and returns a valid representation""" with open(file_name) as json_file: data = json.load(json_file) dictionary = _process_json_probs_data(data) return dictionary
def _process_json_probs_data(data: dict)-> Dict[str, dict]: """Takes the data extracted from the json file a dictionary of probabilities""" result = dict() for prob_name, prob_dictionary in data.items(): _process_json_probs_entry(prob_name, prob_dictionary, result) return result def _process_json_probs_entry(prob_name: str, prob_dictionary: dict, result: dict) -> None: """Takes one entry of the json probability specification file, process it and adds the correct representation to result""" from core import probs if not probs.does_this_probability_exist(prob_name): print(f"Unknown probability '{prob_name}'.", file=sys.stderr) # probability name is not in probs module elif "__prob_distribution__" not in prob_dictionary.keys(): # 1) fixed probability set by the user result[prob_name] = {_eval_str(key): content for (key, content) in prob_dictionary.items()} elif prob_dictionary["__prob_distribution__"] == "equal_prob": # 2) equal probability for a set of values if "__values__" not in prob_dictionary.keys(): print(f"Equal probability distribution requires a __values__ entry.", file=sys.stderr) else: values = set() for value_str in prob_dictionary["__values__"]: values.add(_eval_str(value_str)) result[prob_name] = probs_helper.compute_equal_prob(values) elif prob_dictionary["__prob_distribution__"] in ["proportional_prob", "inverse_proportional_prob"]: # 3) (inverse and direct) proportional probability for a set of values that do not sum 0 if "__values__" not in prob_dictionary.keys(): print(f"Proportional probability distribution requires a __values__ entry.", file=sys.stderr) else: # keys of the dict must be evaluated (e.g., "3" -> 3, "ast.Int" -> ast.Int) values_dict = {_eval_str(key): content for (key, content) in prob_dictionary["__values__"].items()} if prob_name == "proportional_prob": # direct proportional result[prob_name] = probs_helper.compute_proportional_prob(values_dict) else: # inverse proportional result[prob_name] = probs_helper.compute_inverse_proportional_prob(values_dict) elif prob_dictionary["__prob_distribution__"] == "normal_prob": # 5) normal probability, given a mean and standard deviation if not {"__mean__", "__stdev__"}.issubset(prob_dictionary.keys()): print(f"Normal probability distribution requires __mean__ and __stdev__ entries.", file=sys.stderr) else: result[prob_name] = probs_helper.compute_normal_prob(prob_dictionary["__mean__"], prob_dictionary["__stdev__"]) else: print(f"Unknown probability distribution '{prob_dictionary['__prob_distribution__']}'.", file=sys.stderr) def _eval_str(string: str) -> object: """Evaluates a string and returns its evaluation""" import core from core import ast global_variables = {"core": core, "cnerator": core, "ast": ast} try: return eval(string, global_variables) except: return string # if the string is not evaluable, then we just return the string