def glotaran_value_as_markdown( self, value: Any, all_parameters: ParameterGroup | None = None, initial_parameters: ParameterGroup | None = None, ) -> MarkdownStr: """Get a markdown representation of the property. Parameters ---------- value : Any The property value. all_parameters : ParameterGroup | None A parameter group containing the whole parameter set (used for expression lookup). initial_parameters : ParameterGroup | None The initial parameter. Returns ------- MarkdownStr The property as markdown string. """ md = "" if self.glotaran_is_scalar_property: md = self.glotaran_format_value(value, all_parameters, initial_parameters) elif self.glotaran_is_sequence_property: for v in value: md += f"\n * {self.glotaran_format_value(v,all_parameters, initial_parameters)}" elif self.glotaran_is_mapping_property: for k, v in value.items(): md += ( f"\n * {k}: " f"{self.glotaran_format_value(v,all_parameters, initial_parameters)}" ) return MarkdownStr(md)
def mprint_item(self, all_parameters: ParameterGroup = None, initial_parameters: ParameterGroup = None) -> MarkdownStr: f"""Returns a string with the {cls.__name__} formatted in markdown.""" md = "\n" if self._glotaran_has_label: md = f"**{self.label}**" if hasattr(self, "type"): md += f" ({self.type})" md += ":\n" elif hasattr(self, "type"): md = f"**{self.type}**:\n" for name in self._glotaran_properties: prop = getattr(self.__class__, name) value = getattr(self, name) if value is None: continue property_md = indent( f"* *{name.replace('_', ' ').title()}*: " f"{prop.glotaran_value_as_markdown(value,all_parameters, initial_parameters)}\n", " ", ) md += property_md return MarkdownStr(md)
def markdown( self, parameters: ParameterGroup = None, initial_parameters: ParameterGroup = None, base_heading_level: int = 1, ) -> MarkdownStr: """Formats the model as Markdown string. Parameters will be included if specified. Parameters ---------- parameter: ParameterGroup Parameter to include. initial_parameters: ParameterGroup Initial values for the parameters. base_heading_level: int Base heading level of the markdown sections. E.g.: - If it is 1 the string will start with '# Model'. - If it is 3 the string will start with '### Model'. """ base_heading = "#" * base_heading_level string = f"{base_heading} Model\n\n" string += "_Megacomplex Types_: " string += ", ".join(self._megacomplex_types) string += "\n\n" string += f"{base_heading}# Dataset Groups\n\n" for group_name, group in self.dataset_group_models.items(): string += f"* **{group_name}**:\n" string += f" * *Label*: {group_name}\n" for item_name, item_value in asdict(group).items(): string += f" * *{item_name}*: {item_value}\n" string += "\n" for name in self.model_items: items = getattr(self, name) if not items: continue string += f"{base_heading}# {name.replace('_', ' ').title()}\n\n" if isinstance(items, dict): items = items.values() for item in items: item_str = item.markdown( all_parameters=parameters, initial_parameters=initial_parameters ).split("\n") string += f"* {item_str[0]}\n" for s in item_str[1:]: string += f" {s}\n" string += "\n" return MarkdownStr(string)
def test_display_file(tmp_path: Path): """str and PathLike give the same result""" file_content = "kinetic:\n - ['1', 1]" expected = MarkdownStr(file_content, syntax="yaml") tmp_file = tmp_path / "test.yml" tmp_file.write_text(file_content) assert display_file(tmp_file, syntax="yaml") == expected assert display_file(str(tmp_file), syntax="yaml") == expected
def markdown(self, float_format: str = ".3e") -> MarkdownStr: """Format the :class:`ParameterGroup` as markdown string. This is done by recursing the nested :class:`ParameterGroup` tree. Parameters ---------- float_format: str Format string for floating point numbers, by default ".3e" Returns ------- MarkdownStr : The markdown representation as string. """ node_indentation = " " * self.get_nr_roots() return_string = "" table_header = [ "_Label_", "_Value_", "_Standard Error_", "_Minimum_", "_Maximum_", "_Vary_", "_Non-Negative_", "_Expression_", ] if self.label is not None: return_string += f"{node_indentation}* __{self.label}__:\n" if len(self._parameters): parameter_rows = [[ parameter.label, parameter.value, parameter.standard_error, parameter.minimum, parameter.maximum, parameter.vary, parameter.non_negative, f"`{parameter.expression}`", ] for _, parameter in self._parameters.items()] parameter_table = indent( tabulate( parameter_rows, headers=table_header, tablefmt="github", missingval="None", floatfmt=float_format, ), f" {node_indentation}", ) return_string += f"\n{parameter_table}\n\n" for _, child_group in sorted(self.items()): return_string += f"{child_group.markdown(float_format=float_format)}" return MarkdownStr(return_string)
def test_markdown_str_render(raw_str: str, result_str: str, syntax: str): """Rendering""" result = MarkdownStr(raw_str, syntax=syntax) assert str(result) == result_str assert result == result_str rendered_result = format_display_data(result)[0] assert "text/markdown" in rendered_result assert rendered_result["text/markdown"] == result_str assert rendered_result["text/plain"] == repr(raw_str)
def markdown( self, all_parameters: ParameterGroup | None = None, initial_parameters: ParameterGroup | None = None, ) -> MarkdownStr: """Get a markdown representation of the parameter. Parameters ---------- all_parameters : ParameterGroup | None A parameter group containing the whole parameter set (used for expression lookup). initial_parameters : ParameterGroup | None The initial parameter. Returns ------- MarkdownStr The parameter as markdown string. """ md = f"{self.full_label}" parameter = self if all_parameters is None else all_parameters.get( self.full_label) value = f"{parameter.value:.2e}" if parameter.vary: if parameter.standard_error is not np.nan: value += f"±{parameter.standard_error:.2e}" if initial_parameters is not None: initial_value = initial_parameters.get( parameter.full_label).value value += f", initial: {initial_value:.2e}" md += f"({value})" elif parameter.expression is not None: expression = parameter.expression if all_parameters is not None: for match in PARAMETER_EXPRESSION_REGEX.findall(expression): label = match[0] parameter = all_parameters.get(label) expression = expression.replace( "$" + label, f"_{parameter.markdown(all_parameters=all_parameters)}_" ) md += f"({value}={expression})" else: md += f"({value}, fixed)" return MarkdownStr(md)
def _array_as_markdown(array, row_header, column_header) -> MarkdownStr: markdown = "| compartment | " markdown += " | ".join(f"{e:.4e}" if not isinstance(e, str) else e for e in column_header) markdown += "\n|" markdown += "|".join("---" for _ in range(len(column_header) + 1)) markdown += "\n" for i, row in enumerate(array): markdown += ( f"| {row_header[i]} | " if isinstance(row_header[i], str) else f"| {row_header[i]:.4e} | " ) markdown += " | ".join(f"{e:.4e}" if not isinstance(e, str) else e for e in row) markdown += "|\n" return MarkdownStr(markdown)
def markdown(self): """Format the :class:`Scheme` as markdown string. Returns ------- MarkdownStr The scheme as markdown string. """ model_markdown_str = self.model.markdown(parameters=self.parameters) markdown_str = "\n\n" markdown_str += "__Scheme__\n\n" if self.non_negative_least_squares is not None: markdown_str += f"* *non_negative_least_squares*: {self.non_negative_least_squares}\n" markdown_str += ( "* *maximum_number_function_evaluations*: " f"{self.maximum_number_function_evaluations}\n" ) markdown_str += f"* *clp_link_tolerance*: {self.clp_link_tolerance}\n" return model_markdown_str + MarkdownStr(markdown_str)
def project_io_plugin_table( *, plugin_names: bool = False, full_names: bool = False ) -> MarkdownStr: """Return registered project io plugins and which functions they support as markdown table. This is especially useful when you work with new plugins. Parameters ---------- plugin_names : bool Whether or not to add the names of the plugins to the table. full_names : bool Whether to display the full names the plugins are registered under as well. Returns ------- MarkdownStr Markdown table of project io plugins. """ table_data = methods_differ_from_baseclass_table( PROJECT_IO_METHODS, known_project_formats(full_names=full_names), get_project_io, ProjectIoInterface, plugin_names=plugin_names, ) header_values = ["Format name", *PROJECT_IO_METHODS] if plugin_names: header_values.append("Plugin name") headers = tuple(map(lambda x: f"__{x}__", header_values)) return MarkdownStr( tabulate( bool_table_repr(table_data), tablefmt="github", headers=headers, stralign="center" ) )
def megacomplex_plugin_table( *, plugin_names: bool = False, full_names: bool = False ) -> MarkdownStr: """Return registered megacomplex plugins as markdown table. This is especially useful when you work with new plugins. Parameters ---------- plugin_names : bool Whether or not to add the names of the plugins to the table. full_names : bool Whether to display the full names the plugins are registered under as well. Returns ------- MarkdownStr Markdown table of megacomplexnames. """ table_data = [] megacomplex_names = known_megacomplex_names(full_names=full_names) header_values = ["Megacomplex name"] if plugin_names: header_values.append("Plugin name") for megacomplex_name in megacomplex_names: table_data.append( [ f"`{megacomplex_name}`", f"`{full_plugin_name(get_megacomplex(megacomplex_name))}`", ] ) else: table_data = [[f"`{megacomplex_name}`"] for megacomplex_name in megacomplex_names] headers = tuple(map(lambda x: f"__{x}__", header_values)) return MarkdownStr(tabulate(table_data, tablefmt="github", headers=headers, stralign="center"))
def markdown(self, with_model: bool = True, base_heading_level: int = 1) -> MarkdownStr: """Format the model as a markdown text. Parameters ---------- with_model : bool If `True`, the model will be printed with initial and optimized parameters filled in. base_heading_level : int The level of the base heading. Returns ------- MarkdownStr : str The scheme as markdown string. """ general_table_rows: list[list[Any]] = [ [ "Number of residual evaluation", self.number_of_function_evaluations ], ["Number of variables", self.number_of_variables], ["Number of datapoints", self.number_of_data_points], ["Degrees of freedom", self.degrees_of_freedom], ["Chi Square", f"{self.chi_square or np.nan:.2e}"], ["Reduced Chi Square", f"{self.reduced_chi_square or np.nan:.2e}"], [ "Root Mean Square Error (RMSE)", f"{self.root_mean_square_error or np.nan:.2e}" ], ] if self.additional_penalty is not None: general_table_rows.append( ["RMSE additional penalty", self.additional_penalty]) result_table = tabulate( general_table_rows, headers=["Optimization Result", ""], tablefmt="github", disable_numparse=True, ) if len(self.data) > 1: RMSE_rows = [[ f"{index}.{label}:", dataset.weighted_root_mean_square_error, dataset.root_mean_square_error, ] for index, (label, dataset) in enumerate(self.data.items(), start=1)] RMSE_table = tabulate( RMSE_rows, headers=["RMSE (per dataset)", "weighted", "unweighted"], floatfmt=".2e", tablefmt="github", ) result_table = f"{result_table}\n\n{RMSE_table}" if with_model: model_md = self.model.markdown( parameters=self.optimized_parameters, initial_parameters=self.initial_parameters, base_heading_level=base_heading_level, ) result_table = f"{result_table}\n\n{model_md}" return MarkdownStr(result_table)