suever/MATL-Online

View on GitHub
matl_online/matl/documentation.py

Summary

Maintainability
A
0 mins
Test Coverage
import json
import pathlib
from typing import Any, Dict, List, Optional, Tuple
 
from pydantic import BaseModel, Field, parse_obj_as, root_validator, validator
from scipy.io import loadmat # type: ignore[import]
 
from matl_online.matl.source import get_matl_folder
 
 
class FunctionDocumentation(BaseModel):
source: str = Field(alias="sourcePlain")
brief: str = Field(alias="comm")
description: str = Field(alias="descr")
 
arguments: Optional[str] = None
 
@validator(
"source",
"brief",
"description",
pre=True,
)
def remove_newlines(cls, value: str) -> str:
return value.replace("\n", "")
 
# Workaround for https://github.com/pydantic/pydantic/issues/935
@root_validator(pre=True)
def set_arguments(cls, values: Dict[str, Any]) -> Dict[str, Any]:
if values["inOutTogether"] == 0 or len(values["out"]) == 0:
arguments = ""
else:
arguments = f"{values['in']}; {values['out']}"
 
values["arguments"] = arguments
return values
 
 
def struct_of_arrays_to_array_of_dicts(value: Any) -> List[Dict[str, Any]]:
"""Converts a numpy struct or arrays to an array of dictionaries."""
names: Tuple[str] = value.dtype.names
 
values_lists = [value[name].item() for name in names]
 
return [dict(zip(names, values)) for values in zip(*values_lists)]
 
 
def documentation_from_file(mat_file: pathlib.Path) -> List[FunctionDocumentation]:
file_contents = loadmat(mat_file.as_posix(), squeeze_me=True, variable_names="H")
functions = struct_of_arrays_to_array_of_dicts(file_contents["H"])
 
return parse_obj_as(List[FunctionDocumentation], functions)
 
 
def generate_documentation_json(
help_filename: pathlib.Path,
json_filename: pathlib.Path,
) -> pathlib.Path:
print(f"Generating new documentation at {json_filename.as_posix()}")
docs = documentation_from_file(help_filename)
 
TODO found
# TODO: Add documentation links
 
contents = {"data": [doc.dict() for doc in docs]}
 
with open(json_filename, "w") as fid:
json.dump(contents, fid)
 
return json_filename
 
 
def help_file(version: str) -> pathlib.Path:
"""Grab the help data for the specified version."""
folder = get_matl_folder(version)
 
help_json = folder.joinpath("help.json")
 
# If the file already exists, simply return it
if help_json.is_file():
return help_json
 
# Otherwise we need to generate it from the help.mat file
return generate_documentation_json(folder.joinpath("help.mat"), help_json)