-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add JSON support for VerificationResults #93
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
from __future__ import annotations | ||
|
||
import csv | ||
import json | ||
from collections.abc import Sequence | ||
from dataclasses import dataclass | ||
from pathlib import Path | ||
|
@@ -22,6 +23,7 @@ | |
class VerificationDataResult: | ||
"""_summary_.""" | ||
|
||
# TODO: Convert files to path objects | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would not put todos in the code. I would rather create an issue from this |
||
network: str | ||
property: str | ||
timeout: int | None | ||
|
@@ -30,9 +32,9 @@ class VerificationDataResult: | |
success: Literal["OK", "ERR"] | ||
result: VerificationResultString | ||
took: float | ||
counter_example: str | tuple[str, str] | None | ||
stderr: str | None | ||
stdout: str | None | ||
counter_example: str | tuple[str, str] | None = None | ||
stderr: str | None = None | ||
stdout: str | None = None | ||
|
||
def __post_init__(self): | ||
"""_summary_.""" | ||
|
@@ -58,6 +60,25 @@ def as_csv_row(self) -> list[str]: | |
self.stdout or "", | ||
] | ||
|
||
def as_json_row(self) -> dict[str, Any]: | ||
"""Convert data to a json item.""" | ||
if isinstance(self.counter_example, tuple): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we still need this, if the counter example is not returned? |
||
self.counter_example = "\n".join(self.counter_example) | ||
|
||
return { | ||
"network": str(self.network), | ||
"property": str(self.property), | ||
"timeout": str(self.timeout), | ||
"verifier": self.verifier, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why are the verifier, success and result not wrapped into str()? |
||
"config": str(self.config), | ||
"success": self.success, | ||
"result": self.result, | ||
"took": str(self.took), | ||
# "counter_example": self.counter_example or "", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would not publish commented code |
||
"stderr": self.stderr or "", | ||
"stdout": self.stdout or "", | ||
} | ||
|
||
@classmethod | ||
def from_verification_result( | ||
cls, | ||
|
@@ -97,6 +118,30 @@ def csv_append_verification_result( | |
writer.writerow(verification_result.as_csv_row()) | ||
|
||
|
||
def json_write_verification_result( | ||
verification_result: VerificationDataResult, json_path: Path | ||
): | ||
"""_summary_.""" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't this summary be changed to contain some information? |
||
# Create json file if it does not exist | ||
if not json_path.exists(): | ||
with open(str(json_path.expanduser()), "w") as json_file: | ||
json.dump({"instances": []}, json_file) | ||
|
||
# Append to json file | ||
with open(str(json_path.expanduser()), "r+") as json_file: | ||
try: | ||
file_data = json.load(json_file) | ||
# Check if file_data is empty | ||
if not file_data: | ||
file_data = {"instances": []} | ||
except json.decoder.JSONDecodeError: | ||
file_data = {"instances": []} | ||
|
||
file_data["instances"].append(verification_result.as_json_row()) | ||
json_file.seek(0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this necessary? |
||
json.dump(file_data, json_file) | ||
|
||
|
||
def read_verification_result_from_csv( | ||
csv_path: Path, | ||
) -> list[VerificationDataResult]: | ||
|
@@ -111,6 +156,20 @@ def read_verification_result_from_csv( | |
return verification_results | ||
|
||
|
||
def read_verification_result_from_json( | ||
json_path: Path, | ||
) -> list[VerificationDataResult]: | ||
"""Reads a verification results json to a list of its dataclass.""" | ||
results = pd.read_json(json_path)["instances"].tolist() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't we maybe use the json package for parsing the json here? Pandas can quite easily break for parsing jsons. Also were will an error occuring here be catched? |
||
|
||
verification_results: list[VerificationDataResult] = [] | ||
|
||
for res in results: | ||
verification_results.append(VerificationDataResult(**res)) | ||
|
||
return verification_results | ||
|
||
|
||
def write_verification_results_to_csv(results: pd.DataFrame, csv_path: Path): | ||
"""Writes a verification results df to a csv.""" | ||
results.to_csv(csv_path, index=False) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think these abbrevations like inst_d and vdr are not so readable. I would rather put the full names for readability