def _single(self, content: Dict) -> None: raw: Optional[Any] = nesteddicts.get(content, self.source_path, default=None) if raw is None: return display: str = self.display_format(raw) nesteddicts.put(content, self.target_path, display)
def test_put_parent_missing(): target: Dict = {"a": {}} spec: List[str] = ["a", "b", "c"] value: str = "value" nesteddicts.put(target, spec, value) expected: Dict = {"a": {"b": {"c": "value"}}} assert expected == target
def assign_bmi_by_year(person: Dict) -> None: height = nesteddicts.get(person, ["immutable", "height"]) years = set(person.keys()) - {"immutable"} h_squared = height**2 for year in years: weight = nesteddicts.get(person, [year, "weight"]) bmi = weight / h_squared * 703 nesteddicts.put(person, [year, "bmi"], bmi)
def test_put_tree_exists(): target: Dict = {"a": {"b": {"c": "old value"}}} spec: List[str] = ["a", "b", "c"] value: str = "new value" nesteddicts.put(target, spec, value) expected: Dict = {"a": {"b": {"c": "new value"}}} assert expected == target
def _record_exception(self, exception_type: str, path: List[str], value: Optional[Any], period: Optional[str]) -> None: # Note: in the event that there is a list in the path, it will be omitted; hence, if there is more than one # exception in that list, you will only see a single example error_path: List[str] = [ period or "immutable", "qc", "_exceptions", exception_type ] + path nesteddicts.put(self.composite.content, error_path, value)
def assign_regression_stats(person: Dict) -> None: years = set(person.keys()) - {"immutable"} years_ordered = sorted([int(year) for year in years]) weights = [ nesteddicts.get(person, [str(year), "weight"]) for year in years_ordered ] slope, intercept, r_value, p_value, std_err = scipy.stats.linregress( years_ordered, weights) nesteddicts.put(person, ["immutable", "weight_change", "slope"], slope) nesteddicts.put(person, ["immutable", "weight_change", "p_value"], p_value)
def _assign(self, content: Dict, value: Optional[Any], value_identifier: Optional[str] = None) -> None: """ Places a value (min, max, etc.) and possibly a value identifier (e.g. argmin) into the appropriate place in the content dictionary. """ if value is None: return target_path: ListType[str] = self.schema.get(self.value_target).absolute_path nesteddicts.put(content, target_path, value) if self.identifier_target is not None and value_identifier != POLYTROPOS_NA: id_target_path: ListType[str] = self.schema.get(self.identifier_target).absolute_path nesteddicts.put(content, id_target_path, value_identifier)
def encode_list(self, mappings: Dict[str, VariableId], content: List[Dict]) -> Iterator[Dict]: """Create a schema-compliant version of a list of dicts based on data structured in some other format. :param mappings: A mapping between the internal list item names and the IDs of the list-item variables they correspond to. :param content: The content in the internal format.""" for list_item in content: ret: Dict = {} for internal_key in list_item.keys(): if internal_key not in mappings: raise ValueError( 'No mapping specified from internal key "%s" to schema' % internal_key) var_id: VariableId = mappings[internal_key] var: Variable = self.schema.get(var_id) path: List[str] = list(var.relative_path) nesteddicts.put(ret, path, list_item[internal_key]) yield ret
def encode_named_list(self, mappings: Dict[str, str], content: Dict[str, Dict]) -> Dict: """Create a schema-compliant version of a named list of dicts based on data structured in some other format. :param mappings: A mapping between the internal list item names and the IDs of the list-item variables they correspond to. :param content: The content in the internal format.""" ret = {} for key, list_item in content.items(): encoded: Dict = {} for internal_key in list_item.keys(): if internal_key not in mappings: raise ValueError( 'No mapping specified from internal key "%s" to schema' % internal_key) var_id: str = mappings[internal_key] var: Variable = self.schema.get(var_id) path: List[str] = list(var.relative_path) nesteddicts.put(encoded, path, list_item[internal_key]) ret[key] = encoded return ret
def put_observation(self, var_id: VariableId, period: str, value: Optional[Any]) -> None: """Assign (or overwrite) the value of a temporal variable into a particular time period's observation.""" var = self.as_var(var_id, track_type=TrackType.TEMPORAL) path: List = [period] + list(var.absolute_path) nesteddicts.put(self.content, path, value)
def put_immutable(self, var_id: VariableId, value: Optional[Any]) -> None: var = self.as_var(var_id, track_type=TrackType.IMMUTABLE) path: List = ["immutable"] + list(var.absolute_path) nesteddicts.put(self.content, path, value)
def test_put_incomplete_nesting(): target: Dict = {"a": "b"} spec: List[str] = ["a", "b", "c"] value: str = "value" with raises(nesteddicts.IncompleteNestingError): nesteddicts.put(target, spec, value)
def assign_mean_bmi(person: Dict) -> None: years = set(person.keys()) - {"immutable"} bmis = [nesteddicts.get(person, [year, "bmi"]) for year in years] mean_bmi = numpy.average(bmis) nesteddicts.put(person, ["immutable", "mean_bmi"], mean_bmi)
genders = ["male", "female", "overall"] for gender in genders: mean_bmi_dict[gender] = {} for fn, person in people.items(): gender: str = "female" if person["immutable"]["male"]: gender = "male" mean_bmi = person["immutable"]["mean_bmi"] mean_bmi_dict[gender][fn] = mean_bmi mean_bmi_dict["overall"][fn] = mean_bmi ranked: Dict[str, List[str]] = {} for gender in genders: people_ranked = list( sorted(mean_bmi_dict[gender].keys(), key=lambda k: -1 * mean_bmi_dict[gender][k])) ranked[gender] = people_ranked for gender in ["male", "female"]: for k, person in enumerate(ranked[gender]): nesteddicts.put(people[person], ["immutable", "bmi_rank_within_gender"], k + 1) for k, person in enumerate(ranked["overall"]): nesteddicts.put(people[person], ["immutable", "bmi_rank_overall"], k + 1) for fn, person in people.items(): with open("%s/expected/%s" % (basepath, fn), "w") as output_fh: json.dump(person, output_fh, indent=2)