Source code for mlonmcu.report

#
# Copyright (c) 2022 TUM Department of Electrical and Computer Engineering.
#
# This file is part of MLonMCU.
# See https://github.com/tum-ei-eda/mlonmcu.git for further info.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""Definitions of the Report class used by MLonMCU sessions and runs."""
from pathlib import Path
import pandas as pd


pd.set_option("display.max_columns", None)
pd.set_option("display.max_rows", None)
pd.set_option("display.width", 0)

SUPPORTED_FMTS = ["csv", "xlsx"]


[docs] class Report: """Report class wrapped around multiple pandas dataframes.""" def __init__(self): self.pre_df = pd.DataFrame() self.main_df = pd.DataFrame() self.post_df = pd.DataFrame() @property def df(self): """Combine the three internal dataframes to a large one and return in.""" # TODO: handle this properly by either adding NAN or use a single set(pre=, post=, main=) method return pd.concat([self.pre_df, self.main_df, self.post_df], axis=1)
[docs] def export(self, path): """Export the report to a file. Arguments --------- path : str Destination path. """ ext = Path(path).suffix[1:] assert ext in SUPPORTED_FMTS, f"Unsupported report format: {ext}" parent = Path(path).parent if not parent.is_dir(): parent.mkdir() if ext == "csv": self.df.to_csv(path, index=False) elif ext in ["xlsx", "xls"]: self.df.to_excel(path, index=False) else: raise RuntimeError()
# def append(self, *args, **kwargs): # self.df = self.df.append(*args, **kwargs, ignore_index=True)
[docs] def set_pre(self, data): """Setter for the left third of the dataframe.""" self.pre_df = pd.DataFrame.from_records(data).reset_index(drop=True)
[docs] def set_post(self, data): """Setter for the right third of the dataframe.""" self.post_df = pd.DataFrame.from_records(data).reset_index(drop=True)
[docs] def set_main(self, data): """Setter for the center part of the dataframe.""" self.main_df = pd.DataFrame.from_records(data).reset_index(drop=True)
[docs] def set(self, pre=None, main=None, post=None): """Setter for the dataframe.""" size = len(pre) self.set_pre(pre if pre is not None else {}) if len(main) != size: assert len(main) == 0 # self.set_main(pd.Series()) else: self.set_main(main if main is not None else {}) self.set_post(post if post is not None else {})
[docs] def add(self, reports): """Helper function to append a line to an existing report.""" if not isinstance(reports, list): reports = [reports] for report in reports: self.pre_df = pd.concat([self.pre_df, report.pre_df], axis=0).reset_index(drop=True) self.main_df = pd.concat([self.main_df, report.main_df], axis=0).reset_index(drop=True) self.post_df = pd.concat([self.post_df, report.post_df], axis=0).reset_index(drop=True)