42 Commits

Author SHA1 Message Date
Ricardo Montañana Gómez
765112073c Update README.md 2025-05-06 14:04:14 +02:00
69e21584bd Fix tests in python 3.13 2024-12-16 01:27:34 +01:00
419c899c94 Fix some errors in tests 2024-12-16 00:53:11 +01:00
2a2ed81a6c Fix Arff datasets mistake
Fix table_report partial mistake
2024-12-14 23:50:58 +01:00
4c5502611a Update version and copyright 2024-09-18 16:00:31 +02:00
Ricardo Montañana Gómez
70f1da5fc7 Merge pull request #10 from Doctorado-ML/flask
Flask
2024-03-13 16:18:55 +01:00
Ricardo Montañana Gómez
14dba5edb8 Merge branch 'main' into flask 2024-03-13 16:18:47 +01:00
a31d62263d Remove Bayesian classifiers 2024-03-13 16:16:35 +01:00
3f3a18e4fe Remove Bayesian Classifiers 2024-03-12 16:01:03 +01:00
6844d13973 Update format to report 2023-06-26 11:07:12 +02:00
4b17cc2230 Add boostAODE model 2023-06-26 10:09:01 +02:00
257cb8e95a Fix excel route in select 2023-06-02 16:51:19 +02:00
34b4cb6477 Add automatic download excel files 2023-06-01 20:48:53 +02:00
0b258595f9 Fix datasets 2023-06-01 11:44:03 +02:00
ff25581e99 Separate folders 2023-06-01 11:40:41 +02:00
aeec3a65af Fix checkboxes on change page 2023-06-01 01:49:23 +02:00
b7d26b82b1 flavour fix 2023-06-01 01:14:38 +02:00
f7ed11562b Add format to report_best 2023-06-01 01:11:06 +02:00
a51fed6281 Begin best results report 2023-05-31 23:30:51 +02:00
7d5f3058c3 add blueprint to app 2023-05-31 17:21:35 +02:00
54d141e861 Create separate app 2023-05-31 17:00:48 +02:00
04ea568c71 Refactor macros and font family 2023-05-31 14:29:25 +02:00
d8285eb2bb Add excel to report datasets 2023-05-31 01:35:40 +02:00
5f7fb7d5ac Begin add datasets report with excel 2023-05-30 17:04:33 +02:00
dd3cb91951 Fix compare problem in Excel files 2023-05-30 00:47:24 +02:00
40af738ed9 Add persistence of checkbox compare on app 2023-05-30 00:08:36 +02:00
10c352fdb5 Add double click to show file 2023-05-29 23:07:10 +02:00
1b362f2110 Add wait cursor during ajax 2023-05-29 22:37:05 +02:00
007c419979 Add generate excel fault tolerance with compare 2023-05-29 20:07:00 +02:00
2df055334c Add select all/none buttons with icons 2023-05-29 19:35:54 +02:00
395a64abb7 Add button reset and refactor buttons in select
Change position of excel button in report
2023-05-29 18:53:08 +02:00
8fe4b888b8 Add icons to actions 2023-05-29 16:47:03 +02:00
60086b3925 container-fluid and error tolerance in compare 2023-05-29 12:06:44 +02:00
c55a0b29ab Add compare with best results in reports 2023-05-29 11:50:49 +02:00
c2415576c9 Add excel to report 2023-05-28 23:14:14 +02:00
663a0b0258 Add select row to report 2023-05-28 20:06:33 +02:00
655c1db889 Fix row selection in bootstrap 2023-05-28 18:09:11 +02:00
e17e7d4e00 Generate excel file from results 2023-05-28 18:03:20 +02:00
be62e38e77 Add title and score to select page 2023-05-28 11:56:14 +02:00
83cfc3e5f5 Enhance report templates 2023-05-28 03:20:15 +02:00
3928b9c583 Change partials criteria 2023-05-28 03:12:12 +02:00
219b626061 Add flask templates 2023-05-28 00:04:30 +02:00
46 changed files with 1179 additions and 68 deletions

View File

@@ -1,7 +1,4 @@
[![CI](https://github.com/Doctorado-ML/benchmark/actions/workflows/main.yml/badge.svg)](https://github.com/Doctorado-ML/benchmark/actions/workflows/main.yml)
[![codecov](https://codecov.io/gh/Doctorado-ML/benchmark/branch/main/graph/badge.svg?token=ZRP937NDSG)](https://codecov.io/gh/Doctorado-ML/benchmark)
[![Quality Gate Status](https://sonar.rmontanana.es/api/project_badges/measure?project=benchmark&metric=alert_status&token=336a6e501988888543c3153baa91bad4b9914dd2)](https://sonar.rmontanana.es/dashboard?id=benchmark)
[![Technical Debt](https://sonar.rmontanana.es/api/project_badges/measure?project=benchmark&metric=sqale_index&token=336a6e501988888543c3153baa91bad4b9914dd2)](https://sonar.rmontanana.es/dashboard?id=benchmark)
![https://img.shields.io/badge/python-3.8%2B-blue](https://img.shields.io/badge/python-3.8%2B-brightgreen)
# benchmark

View File

@@ -13,21 +13,27 @@ ALL_METRICS = (
class EnvData:
@staticmethod
def load():
args = {}
def __init__(self):
self.args = {}
def load(self):
try:
with open(Files.dot_env) as f:
for line in f.read().splitlines():
if line == "" or line.startswith("#"):
continue
key, value = line.split("=")
args[key] = value
self.args[key] = value
except FileNotFoundError:
print(NO_ENV, file=sys.stderr)
exit(1)
else:
return args
return self.args
def save(self):
with open(Files.dot_env, "w") as f:
for key, value in self.args.items():
f.write(f"{key}={value}\n")
class EnvDefault(argparse.Action):
@@ -35,7 +41,7 @@ class EnvDefault(argparse.Action):
def __init__(
self, envvar, required=True, default=None, mandatory=False, **kwargs
):
self._args = EnvData.load()
self._args = EnvData().load()
self._overrides = {}
if required and not mandatory:
default = self._args[envvar]
@@ -229,6 +235,19 @@ class Arguments(argparse.ArgumentParser):
"help": "number of folds",
},
],
"output": [
("-o", "--output"),
{
"type": str,
"default": "local",
"choices": ["local", "docker"],
"required": False,
"help": (
"in be_flask tells if it is running in local or "
"in docker {local, docker}"
),
},
],
"platform": [
("-P", "--platform"),
{

View File

@@ -32,6 +32,8 @@ class DatasetsArff:
def get_range_features(X, c_features):
if c_features.strip() == "all":
return list(range(X.shape[1]))
if c_features.strip() == "none":
return []
return json.loads(c_features)
def load(self, name, class_name):
@@ -109,7 +111,7 @@ class DatasetsSurcov:
class Datasets:
def __init__(self, dataset_name=None, discretize=None):
env_data = EnvData.load()
env_data = EnvData().load()
# DatasetsSurcov, DatasetsTanveer, DatasetsArff,...
source_name = getattr(
__import__(__name__),
@@ -129,29 +131,28 @@ class Datasets:
def _init_names(self, dataset_name):
file_name = os.path.join(self.dataset.folder(), Files.index)
default_class = "class"
self.continuous_features = {}
with open(file_name) as f:
sets = f.read().splitlines()
sets = [x for x in sets if not x.startswith("#")]
class_names = [default_class] * len(sets)
if "," in sets[0]:
result = []
results = []
class_names = []
for data in sets:
name, class_name, features = data.split(",", 2)
result.append(name)
for set_name in sets:
try:
name, class_name, features = set_name.split(";")
except ValueError:
class_name = "class"
features = "all"
name = set_name
results.append(name)
class_names.append(class_name)
features = features.strip()
self.continuous_features[name] = features
sets = result
else:
for name in sets:
self.continuous_features[name] = None
# Set as dataset list the dataset passed as argument
if dataset_name is None:
return class_names, sets
return class_names, results
try:
class_name = class_names[sets.index(dataset_name)]
class_name = class_names[results.index(dataset_name)]
except ValueError:
raise ValueError(f"Unknown dataset: {dataset_name}")
return [class_name], [dataset_name]

View File

@@ -22,7 +22,7 @@ from .Arguments import EnvData
class Randomized:
@staticmethod
def seeds():
return json.loads(EnvData.load()["seeds"])
return json.loads(EnvData().load()["seeds"])
class BestResults:
@@ -117,7 +117,7 @@ class Experiment:
discretize=None,
folds=5,
):
env_data = EnvData.load()
env_data = EnvData().load()
today = datetime.now()
self.time = today.strftime("%H:%M:%S")
self.date = today.strftime("%Y-%m-%d")

View File

@@ -8,7 +8,8 @@ from sklearn.ensemble import (
)
from sklearn.svm import SVC
from stree import Stree
from bayesclass.clfs import TAN, KDB, AODE, KDBNew, TANNew, AODENew
# from bayesclass.clfs import TAN, KDB, AODE, KDBNew, TANNew, AODENew, BoostAODE
from wodt import Wodt
from odte import Odte
from xgboost import XGBClassifier
@@ -39,12 +40,13 @@ class Models:
def define_models(random_state):
return {
"STree": Stree(random_state=random_state),
"TAN": TAN(random_state=random_state),
"KDB": KDB(k=2),
"TANNew": TANNew(random_state=random_state),
"KDBNew": KDBNew(k=2),
"AODENew": AODENew(random_state=random_state),
"AODE": AODE(random_state=random_state),
# "TAN": TAN(random_state=random_state),
# "KDB": KDB(k=2),
# "TANNew": TANNew(random_state=random_state),
# "KDBNew": KDBNew(k=2),
# "AODENew": AODENew(random_state=random_state),
# "AODE": AODE(random_state=random_state),
# "BoostAODE": BoostAODE(random_state=random_state),
"Cart": DecisionTreeClassifier(random_state=random_state),
"ExtraTree": ExtraTreeClassifier(random_state=random_state),
"Wodt": Wodt(random_state=random_state),

View File

@@ -71,7 +71,6 @@ class Report(BaseReport):
self._load_best_results(
self.data["score_name"], self.data["model"]
)
self._compare_totals = {}
self.header_line("*")
self.header_line(
f" {self.data['model']} ver. {self.data['version']}"

View File

@@ -52,10 +52,11 @@ class BaseReport(abc.ABC):
self.score_name = self.data["score_name"]
self.__load_env_data()
self.__compute_best_results_ever()
self._compare_totals = {}
def __load_env_data(self):
# Set the labels for nodes, leaves, depth
env_data = EnvData.load()
env_data = EnvData().load()
self.nodes_label = env_data["nodes"]
self.leaves_label = env_data["leaves"]
self.depth_label = env_data["depth"]
@@ -107,10 +108,12 @@ class BaseReport(abc.ABC):
status = (
Symbols.cross
if accuracy <= max_value
else Symbols.upward_arrow
else (
Symbols.upward_arrow
if accuracy > max_value
else " "
)
)
if status != " ":
if status not in self._compare_totals:
self._compare_totals[status] = 1
@@ -148,8 +151,11 @@ class BaseReport(abc.ABC):
class StubReport(BaseReport):
def __init__(self, file_name):
def __init__(self, file_name, compare=False):
self.compare = compare
super().__init__(file_name=file_name, best_file=False)
if self.compare:
self._load_best_results(self.score_name, self.data["model"])
def print_line(self, line) -> None:
pass
@@ -157,6 +163,11 @@ class StubReport(BaseReport):
def header(self) -> None:
self.title = self.data["title"]
self.duration = self.data["duration"]
self.model = self.data["model"]
self.date = self.data["date"]
self.time = self.data["time"]
self.metric = self.data["score_name"]
self.platform = self.data["platform"]
def footer(self, accuracy: float) -> None:
self.accuracy = accuracy
@@ -165,7 +176,7 @@ class StubReport(BaseReport):
class Summary:
def __init__(self, hidden=False, compare=False) -> None:
self.results = Files().get_all_results(hidden=hidden)
self.results = Files.get_all_results(hidden=hidden)
self.data = []
self.data_filtered = []
self.datasets = {}
@@ -191,9 +202,11 @@ class Summary:
self.models.add(model)
report = StubReport(
os.path.join(
(
Folders.hidden_results
if self.hidden
else Folders.results,
else Folders.results
),
result,
)
)

View File

@@ -299,11 +299,11 @@ class ReportDatasets:
color2 = "#FDE9D9"
color3 = "#B1A0C7"
def __init__(self, excel=False, book=None):
def __init__(self, excel=False, book=None, output=True):
self.excel = excel
self.env = EnvData().load()
self.close = False
self.output = True
self.output = output
self.header_text = f"Datasets used in benchmark ver. {__version__}"
if excel:
self.max_length = 0
@@ -620,7 +620,7 @@ class Benchmark:
self.__compute_best_results_ever()
def __compute_best_results_ever(self):
args = EnvData.load()
args = EnvData().load()
key = args["source_data"]
best = BestResultsEver()
_, self.best_score_value = best.get_name_value(key, self._score)

View File

@@ -15,6 +15,7 @@ class Folders:
img = "img"
excel = "excel"
sql = "sql"
current = os.getcwd()
@staticmethod
def src():
@@ -108,7 +109,8 @@ class Files:
)
return None
def get_all_results(self, hidden) -> list[str]:
@staticmethod
def get_all_results(hidden) -> list[str]:
result_path = os.path.join(
".", Folders.hidden_results if hidden else Folders.results
)
@@ -117,7 +119,7 @@ class Files:
else:
raise ValueError(f"{result_path} does not exist")
result = []
prefix, suffix = self.results_suffixes()
prefix, suffix = Files.results_suffixes()
for result_file in files_list:
if result_file.startswith(prefix) and result_file.endswith(suffix):
result.append(result_file)

View File

@@ -10,7 +10,7 @@ from .Results import Report
from ._version import __version__
__author__ = "Ricardo Montañana Gómez"
__copyright__ = "Copyright 2020-2023, Ricardo Montañana Gómez"
__copyright__ = "Copyright 2020-2024, Ricardo Montañana Gómez"
__license__ = "MIT License"
__author_email__ = "ricardo.montanana@alu.uclm.es"

View File

@@ -1 +1 @@
__version__ = "0.5.0"
__version__ = "1.0.1"

View File

20
benchmark/scripts/app/app.py Executable file
View File

@@ -0,0 +1,20 @@
#!/usr/bin/env python
from benchmark.Arguments import EnvData
from flask import Flask
from .main import main, OUTPUT
FRAMEWORK = "framework"
FRAMEWORKS = "frameworks"
TEST = "test"
def create_app(output="local"):
app = Flask(__name__)
config = EnvData().load()
app.register_blueprint(main)
app.config[FRAMEWORK] = config[FRAMEWORK]
app.config[FRAMEWORKS] = ["bootstrap", "bulma"]
app.config[OUTPUT] = output
app.jinja_env.auto_reload = True
app.config["TEMPLATES_AUTO_RELOAD"] = True
return app

210
benchmark/scripts/app/main.py Executable file
View File

@@ -0,0 +1,210 @@
#!/usr/bin/env python
import os
import json
import shutil
import xlsxwriter
from dotenv import dotenv_values
from benchmark.Utils import Files, Folders
from benchmark.Arguments import EnvData
from benchmark.ResultsBase import StubReport
from benchmark.ResultsFiles import Excel, ReportDatasets
from benchmark.Datasets import Datasets
from flask import Blueprint, current_app, send_file
from flask import render_template, request, redirect, url_for
main = Blueprint("main", __name__)
FRAMEWORK = "framework"
FRAMEWORKS = "frameworks"
OUTPUT = "output"
TEST = "test"
class AjaxResponse:
def __init__(self, success, file_name, code=200):
self.success = success
self.file_name = file_name
self.code = code
def to_string(self):
return (
json.dumps(
{
"success": self.success,
"file": self.file_name,
"output": current_app.config[OUTPUT],
}
),
self.code,
{"ContentType": "application/json"},
)
def process_data(file_name, compare, data):
report = StubReport(
os.path.join(Folders.results, file_name), compare=compare
)
new_list = []
for result in data["results"]:
symbol = report._compute_status(result["dataset"], result["score"])
result["symbol"] = symbol if symbol != " " else "&nbsp;"
new_list.append(result)
data["results"] = new_list
# Compute summary with explanation of symbols
summary = {}
for key, value in report._compare_totals.items():
summary[key] = (report._status_meaning(key), value)
return summary
@main.route("/index/<compare>")
@main.route("/")
def index(compare="False"):
# Get a list of files in a directory
files = {}
names = Files.get_all_results(hidden=False)
for name in names:
report = StubReport(os.path.join(Folders.results, name))
report.report()
files[name] = {
"duration": report.duration,
"score": report.score,
"title": report.title,
}
candidate = current_app.config[FRAMEWORKS].copy()
candidate.remove(current_app.config[FRAMEWORK])
return render_template(
"select.html",
files=files,
candidate=candidate[0],
framework=current_app.config[FRAMEWORK],
compare=compare.capitalize() == "True",
)
@main.route("/datasets/<compare>")
def datasets(compare):
dt = Datasets()
datos = []
for dataset in dt:
datos.append(dt.get_attributes(dataset))
return render_template(
"datasets.html",
datasets=datos,
compare=compare,
framework=current_app.config[FRAMEWORK],
)
@main.route("/showfile/<file_name>/<compare>")
def showfile(file_name, compare, back=None):
compare = compare.capitalize() == "True"
back = request.args["url"] if back is None else back
app_config = dotenv_values(".env")
with open(os.path.join(Folders.results, file_name)) as f:
data = json.load(f)
try:
summary = process_data(file_name, compare, data)
except Exception as e:
return render_template("error.html", message=str(e), compare=compare)
return render_template(
"report.html",
data=data,
file=file_name,
summary=summary,
framework=current_app.config[FRAMEWORK],
back=back,
app_config=app_config,
)
@main.route("/show", methods=["post"])
def show():
selected_file = request.form["selected-file"]
compare = request.form["compare"]
return showfile(
file_name=selected_file,
compare=compare,
back=url_for(
"main.index", compare=compare, output=current_app.config[OUTPUT]
),
)
@main.route("/excel", methods=["post"])
def excel():
selected_files = request.json["selectedFiles"]
compare = request.json["compare"]
book = None
if selected_files[0] == "datasets":
# Create a list of datasets
report = ReportDatasets(excel=True, output=False)
report.report()
excel_name = os.path.join(Folders.excel, Files.datasets_report_excel)
if current_app.config[OUTPUT] == "local":
Files.open(excel_name, test=current_app.config[TEST])
return AjaxResponse(True, Files.datasets_report_excel).to_string()
try:
for file_name in selected_files:
file_name_result = os.path.join(Folders.results, file_name)
if book is None:
file_excel = os.path.join(Folders.excel, Files.be_list_excel)
book = xlsxwriter.Workbook(
file_excel, {"nan_inf_to_errors": True}
)
excel = Excel(
file_name=file_name_result,
book=book,
compare=compare,
)
excel.report()
except Exception as e:
if book is not None:
book.close()
return AjaxResponse(
False, "Could not create excel file, " + str(e)
).to_string()
if book is not None:
book.close()
if current_app.config[OUTPUT] == "local":
Files.open(file_excel, test=current_app.config[TEST])
return AjaxResponse(True, Files.be_list_excel).to_string()
@main.route("/download/<file_name>")
def download(file_name):
src = os.path.join(Folders.current, Folders.excel, file_name)
dest = os.path.join(
Folders.src(), "scripts", "app", "static", "excel", file_name
)
shutil.copyfile(src, dest)
return send_file(dest, as_attachment=True)
@main.route("/config/<framework>/<compare>")
def config(framework, compare):
if framework not in current_app.config[FRAMEWORKS]:
message = f"framework {framework} not supported"
return render_template("error.html", message=message)
env = EnvData()
env.load()
env.args[FRAMEWORK] = framework
env.save()
current_app.config[FRAMEWORK] = framework
return redirect(url_for("main.index", compare=compare))
@main.route("/best_results/<file>/<compare>")
def best_results(file, compare):
compare = compare.capitalize() == "True"
try:
with open(os.path.join(Folders.results, file)) as f:
data = json.load(f)
except Exception as e:
return render_template("error.html", message=str(e), compare=compare)
return render_template(
"report_best.html",
data=data,
compare=compare,
framework=current_app.config[FRAMEWORK],
)

View File

@@ -0,0 +1,30 @@
.alternate-font {
font-family: Arial;
}
tbody {
font-family: Courier;
}
.tag {
cursor: pointer;
}
.ajaxLoading {
cursor: progress !important;
}
#file-table tbody tr.selected td {
background-color: #0dcaf0;
color: white;
}
#report-table tbody tr.selected td {
background-color: #0dcaf0;
color: white;
}
.btn-small {
padding: 0.25rem 0.5rem;
font-size: 0.75rem;
}

View File

@@ -0,0 +1 @@
*.xlsx

View File

@@ -0,0 +1,29 @@
function excelFiles(selectedFiles, compare) {
var data = {
"selectedFiles": selectedFiles,
"compare": compare
};
// send data to server with ajax post
$.ajax({
type:'POST',
url:'/excel',
data: JSON.stringify(data),
contentType: "application/json",
dataType: 'json',
success: function(data){
if (data.success) {
if (data.output == "local") {
alert("Se ha generado el archivo " + data.file);
} else {
window.open('/download/' + data.file, "_blank");
}
} else {
alert(data.file);
}
},
error: function (xhr, ajaxOptions, thrownError) {
var mensaje = JSON.parse(xhr.responseText || '{\"mensaje\": \"Error indeterminado\"}');
alert(mensaje.mensaje);
}
});
}

View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous" />
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,500,600" rel="stylesheet" />
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.25/css/jquery.dataTables.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/MaterialDesign-Webfont/7.1.96/css/materialdesignicons.css" integrity="sha512-lD1LHcZ8tFHvMFNeo6qOLY/HjzSPCasPJOAoir22byDxlZI1R71S5lZel8zRL2TZ+Dut1wOHfYgSU2lHXuL00w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}" />
</head>
<body>
{% block content %}
{% endblock %}
</body>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
{% block jscript %}
{% endblock %}
</html>

View File

@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.9.3/css/bulma.min.css" />
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.25/css/jquery.dataTables.min.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/MaterialDesign-Webfont/7.1.96/css/materialdesignicons.css" integrity="sha512-lD1LHcZ8tFHvMFNeo6qOLY/HjzSPCasPJOAoir22byDxlZI1R71S5lZel8zRL2TZ+Dut1wOHfYgSU2lHXuL00w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}" />
</head>
<body>
{% block content %}
{% endblock %}
</body>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
{% block jscript %}
{% endblock %}
</html>

View File

@@ -0,0 +1,68 @@
{% extends 'base_' ~ framework ~ '.html' %}
{% macro javascript(file) %}
<script src="{{ url_for('static', filename=file) }}"></script>
{% endmacro %}
{% if framework == 'bootstrap' %}
{% set button_class = 'btn btn-primary btn-small' %}
{% set h1_class = 'text-center' %}
{% set table_class = 'table table-striped table-hover table-bordered' %}
{% set head_class = 'bg-primary text-white' %}
{% set text_right = 'text-end' %}
{% set container = 'container' %}
{% set selected = 'selected' %}
{%- macro header(title, close, url) -%}
<div class="p-4 bg-primary text-white">
{%- if close -%}
<button type="button" class="btn-close" aria-label="Close" onclick="location.href = '{{ url }}'"></button>
{%- endif -%}
<h1 class="alternate-font">{{ title }}</h1>
</div>
{%- endmacro -%}
{% else %}
{% set button_class = 'button is-primary is-small' %}
{% set h1_class = 'title is-1 has-text-centered' %}
{% set table_class = 'table is-striped is-hoverable cell-border is-bordered' %}
{% set head_class = 'is-selected' %}
{% set text_right = 'has-text-right' %}
{% set container = 'container' %}
{% set selected = 'is-selected' %}
{%- macro header(title, close, url) -%}
<div class="hero is-info is-bold">
<div class="hero-body">
{%- if close -%}
<button class="delete is-large" onclick="location.href = '{{ url }}'"></button>
{%- endif -%}
<h1 class="is-size-3 alternate-font">{{ title }}</h1>
</div>
</div>
{%- endmacro -%}
{% endif %}
{% block content %}
<div class="{{ container }}">
{{ header('Benchmark Datasets Report', True, url_for('main.index', compare = compare)) }}
<button class="{{ button_class }}" onclick="excelFiles(['datasets'], false)"><i class="mdi mdi-file-excel"></i> Excel</button>
{% include 'partials/datasets_table.html' %}
</div>
{% endblock %}
{% block jscript %}
{{ javascript("js/excelFiles.js") }}
<script>
$(document).ready(function () {
$(document).ajaxStart(function(){
$("body").addClass('ajaxLoading');
});
$(document).ajaxStop(function(){
$("body").removeClass('ajaxLoading');
});
});
// Check if row is selected
$('#file-table tbody').on('click', 'tr', function () {
if ($(this).hasClass('{{ selected }}')) {
$(this).removeClass('{{ selected }}');
} else {
$('#file-table tbody tr.{{ selected }}').removeClass("{{ selected }}")
$(this).addClass('{{ selected }}');
}
});
</script>
{% endblock %}

View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<title>Error</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ" crossorigin="anonymous">
</head>
<body>
<div class="container">
<div class="alert alert-danger my-5" role="alert">
<h4 class="alert-heading"><button class="btn-close btn-sm" type="button"
onclick="location.href='/index/{{ compare }}';"></button>Error</h4>
<p>There was an error processing action, {{ message }}. Please try again later.</p>
<hr>
<p class="mb-0">If the problem persists, please contact support.</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,22 @@
$(document).ready(function () {
// Check if row is selected
$('#report-table tbody').on('click', 'tr', function () {
if ($(this).hasClass('{{ selected }}')) {
$(this).removeClass('{{ selected }}');
} else {
$('#report-table tbody tr.{{ selected }}').removeClass("{{ selected }}")
$(this).addClass('{{ selected }}');
}
});
$(document).ajaxStart(function(){
$("body").addClass('ajaxLoading');
});
$(document).ajaxStop(function(){
$("body").removeClass('ajaxLoading');
});
});
function excelFile() {
var selectedFiles = ["{{ file }}"];
var compare = "{{ compare }}" == "True";
excelFiles(selectedFiles, compare)
}

View File

@@ -0,0 +1,97 @@
$(document).ready(function () {
var table = $("#file-table").DataTable({
paging: true,
searching: true,
ordering: true,
info: true,
"select.items": "row",
pageLength: 25,
columnDefs: [
{
targets: 8,
orderable: false,
},
],
//"language": {
// "lengthMenu": "_MENU_"
//}
});
$('#file-table').on( 'draw.dt', function () {
enable_disable_best_buttons();
} );
// Check if row is selected
$("#file-table tbody").on("click", "tr", function () {
if ($(this).hasClass("{{ select.selected() }}")) {
$(this).removeClass("{{ select.selected() }}");
} else {
table
.$("tr.{{ select.selected() }}")
.removeClass("{{ select.selected() }}");
$(this).addClass("{{ select.selected() }}");
}
});
// Show file with doubleclick
$("#file-table tbody").on("dblclick", "tr", function () {
showFile($(this).attr("id"));
});
$(document).ajaxStart(function () {
$("body").addClass("ajaxLoading");
});
$(document).ajaxStop(function () {
$("body").removeClass("ajaxLoading");
});
$('#compare').change(function() {
enable_disable_best_buttons();
});
enable_disable_best_buttons();
});
function enable_disable_best_buttons(){
if ($('#compare').is(':checked')) {
$("[name='best_buttons']").addClass("tag is-link is-normal");
$("[name='best_buttons']").removeAttr("hidden");
} else {
$("[name='best_buttons']").removeClass("tag is-link is-normal");
$("[name='best_buttons']").attr("hidden", true);
}
}
function showFile(selectedFile) {
var form = $(
'<form action="/show" method="post">' +
'<input type="hidden" name="selected-file" value="' +
selectedFile +
'" />' +
'<input type="hidden" name="compare" value=' +
$("#compare").is(":checked") +
" />" +
"</form>"
);
$("body").append(form);
form.submit();
}
function excel() {
var checkbox = document.getElementsByName("selected_files");
var selectedFiles = [];
for (var i = 0; i < checkbox.length; i++) {
if (checkbox[i].checked) {
selectedFiles.push(checkbox[i].value);
}
}
if (selectedFiles.length == 0) {
alert("Select at least one file");
return;
}
var compare = $("#compare").is(":checked");
excelFiles(selectedFiles, compare);
}
function setCheckBoxes(value) {
var checkbox = document.getElementsByName("selected_files");
for (i = 0; i < checkbox.length; i++) {
checkbox[i].checked = value;
}
}
function redirectDouble(route, parameter) {
location.href = "/"+ route + "/" + parameter + "/" + $("#compare").is(":checked");
}
function redirectSimple(route) {
location.href = "/" + route + "/" + $("#compare").is(":checked");
}

View File

@@ -0,0 +1,56 @@
{%- macro header(title, close=False, url="") -%}
<div class="p-4 bg-primary text-white">
{%- if close -%}
<button type="button" class="btn-close" aria-label="Close" onclick="location.href = '{{url}}'"></button>
{%- endif -%}
<h1 class="alternate-font">{{ title }}</h1>
</div>
{%- endmacro -%}
{%- macro get_table_class() -%}
table table-striped table-hover table-bordered
{%- endmacro -%}
{%- macro icon(icon_name) -%}
<i class="mdi mdi-{{icon_name}}"></i>
{%- endmacro -%}
{%- macro get_button(text, action) -%}
<button class="btn btn-primary btn-small" onclick="{{ action }}">{{ text|safe }}</button>
{%- endmacro -%}
{%- macro get_button_class() -%}
button btn-primary btn-small
{%- endmacro %}
{%- macro get_button_tag(icon_name, method, visible=True, name="") -%}
<button class="btn btn-primary btn-small" onclick="{{ method }}" {{ "" if visible else "hidden='true'" }} {{ "" if name=="" else "name='" + name +"'"}}><i class="mdi mdi-{{ icon_name }}"></i></button>
{%- endmacro -%}
{%- macro get_button_reset() -%}
<button class="btn btn-primary btn-small btn-danger" onclick="setCheckBoxes(false)"><i class="mdi mdi-checkbox-multiple-blank"></i></button>
{%- endmacro -%}
{%- macro get_button_all() -%}
<button class="btn btn-primary btn-small btn-success" onclick="setCheckBoxes(true)"><i class="mdi mdi-checkbox-multiple-marked"></i></button>
{%- endmacro -%}
{%- macro get_tag_class() -%}
badge bg-info bg-small
{%- endmacro -%}
{%- macro get_container_class() -%}
container-fluid
{%- endmacro -%}
{%- macro selected() -%}
selected
{%- endmacro -%}
{%- macro get_level_class() -%}
navbar
{%- endmacro -%}
{%- macro get_align_right() -%}
text-end
{%- endmacro -%}
{%- macro get_left_position() -%}
float-left
{%- endmacro -%}
{%- macro get_right_position() -%}
float-right
{%- endmacro -%}
{%- macro get_row_head_class() -%}
bg-primary text-white
{%- endmacro -%}
{%- macro get_align_center() -%}
text-center
{%- endmacro -%}

View File

@@ -0,0 +1,58 @@
{%- macro header(title, close=False, url="") -%}
<div class="hero is-info is-bold">
<div class="hero-body">
{%- if close -%}
<button class="delete is-large" onclick="location.href = '{{ url }}'"></button>
{%- endif -%}
<h1 class="is-size-3 alternate-font">{{ title }}</h1>
</div>
</div>
{%- endmacro -%}
{%- macro get_table_class() -%}
table is-striped is-hoverable cell-border is-bordered
{%- endmacro -%}
{%- macro icon(icon_name) -%}
<i class="mdi mdi-{{icon_name}}"></i>
{%- endmacro -%}
{%- macro get_button(text, action) -%}
<button class="button is-primary is-small" onclick="{{ action }}">{{ text|safe }}</button>
{%- endmacro -%}
{%- macro get_button_tag(icon_name, method, visible=True, name="") -%}
<span class="{{ "tag is-link is-normal" if visible else "" }}" type="button" onclick="{{ method }}" {{ "" if visible else "hidden='true'" }} {{ "" if name=="" else "name='" + name +"'"}}>{{icon(icon_name)}}</span>
{%- endmacro -%}
{%- macro get_button_reset() -%}
<span class="tag is-link is-danger" type="button" onclick="setCheckBoxes(false)"><i class="mdi mdi-checkbox-multiple-blank"></i></span>
{%- endmacro -%}
{%- macro get_button_all() -%}
<span class="tag is-link is-success" type="button" onclick="setCheckBoxes(true)"><i class="mdi mdi-checkbox-multiple-marked"></i></span>
{%- endmacro -%}
{%- macro get_tag_class() -%}
tag is-info is-small
{%- endmacro -%}
{%- macro get_container_class() -%}
container is-fluid
{%- endmacro -%}
{%- macro selected() -%}
is-selected
{%- endmacro -%}
{%- macro get_level_class() -%}
level
{%- endmacro -%}
{%- macro get_align_right() -%}
has-text-right
{%- endmacro -%}
{%- macro get_align_center() -%}
has-text-center
{%- endmacro -%}
{%- macro get_left_position() -%}
float-left
{%- endmacro -%}
{%- macro get_right_position() -%}
float-right
{%- endmacro -%}
{%- macro get_row_head_class() -%}
is-selected
{%- endmacro -%}
{%- macro get_align_center() -%}
has-text-center
{%- endmacro -%}

View File

@@ -0,0 +1,27 @@
{% extends "base_" ~ framework ~ ".html" %}
{% block content %}
<table id="file-table" class="{{ table_class }}">
<thead>
<tr class="{{ head_class }}">
<th class="{{ text_center }}">Dataset</th>
<th class="{{ text_center }}">Samples</th>
<th class="{{ text_center }}">Features</th>
<th class="{{ text_center }}">Cont. Feat.</th>
<th class="{{ text_center }}">Classes</th>
<th class="{{ text_center }}">Balance</th>
</tr>
</thead>
<tbody>
{% for dataset in datasets %}
<tr>
<td>{{ dataset.dataset }}</td>
<td class="{{ text_right }}">{{ "{:,}".format(dataset.samples) }}</td>
<td class="{{ text_right }}">{{ "{:,}".format(dataset.features) }}</td>
<td class="{{ text_right }}">{{ dataset.cont_features }}</td>
<td class="{{ text_right }}">{{ dataset.classes }}</td>
<td>{{ dataset.balance }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View File

@@ -0,0 +1,14 @@
{% for item in data.results %}
<tr>
<td>{{ item.dataset }}</td>
<td class="{{ right }}">{{ '{:,}'.format(item.samples) }}</td>
<td class="{{ right }}">{{"%d" % item.features}}</td>
<td class="{{ right }}">{{"%d" % item.classes}}</td>
<td class="{{ right }}">{{ '{:,.2f}'.format(item.nodes|float) }}</td>
<td class="{{ right }}">{{ '{:,.2f}'.format(item.leaves|float) }}</td>
<td class="{{ right }}">{{ '{:,.2f}'.format(item.depth|float) }}</td>
<td class="{{ right }}">{{"%.6f±%.4f" % (item.score, item.score_std)}} {{ item.symbol|safe }}</td>
<td class="{{ right }}">{{"%.6f±%.4f" % (item.time, item.time_std)}}</td>
<td class="{{ center }}">{{ item.hyperparameters }}</td>
</tr>
{% endfor %}

View File

@@ -0,0 +1,102 @@
<div id="app">
<section class="section">
<div class="container-fluid">
<div class="p-4 bg-primary text-white">
<button type="button"
class="btn-close"
aria-label="Close"
onclick="location.href = '{{ back }}'"></button>
<h1>{{ data.title }}</h1>
</div>
<div>
<table class="table table-bordered">
<thead>
<tr class="bg-info text-white">
<th class="text-center">Platform</th>
<th class="text-center">Model</th>
<th class="text-center">Date</th>
<th class="text-center">Time</th>
{% if data.duration > 7200 %}
{% set unit = "h" %}
{% set divider = 3600 %}
{% else %}
{% set unit = "min" %}
{% set divider = 60 %}
{% endif %}
<th class="text-center">Duration ({{ unit }})</th>
<th class="text-center">Stratified</th>
<th class="text-center">Discretized</th>
<th class="text-center"># Folds</th>
</tr>
<tr>
<th class="text-center">{{ data.platform }}</th>
<th class="text-center">{{ data.model }} {{ data.version }}</th>
<th class="text-center">{{ data.date }}</th>
<th class="text-center">{{ data.time }}</th>
<th class="text-center">{{ "%.2f" % (data.duration/divider) }}</th>
<th class="text-center">{{ data.stratified }}</th>
<th class="text-center">{{ data.discretized }}</th>
<th class="text-center">{{ data.folds }}</th>
</tr>
<tr>
<th class="text-center bg-info text-white">Language</th>
<th class="text-center" colspan=3>{{ data.language }} {{ data.language_version }}</th>
<th class="text-center bg-info text-white">Seeds</th>
<th class="text-center" colspan=6>{{ data.seeds }}</th>
</tr>
</thead>
</table>
<div>
<button class="{{ button }}" onclick="excelFile()">
<i class="mdi mdi-file-excel"></i> Excel
</button>
</div>
<table id="report-table"
class="table table-striped table-hover table-bordered">
<thead>
<tr class="bg-primary text-white">
<th class="text-center">Dataset</th>
<th class="text-center">Samples</th>
<th class="text-center">Features</th>
<th class="text-center">Classes</th>
<th class="text-center">{{ app_config.nodes }}</th>
<th class="text-center">{{ app_config.leaves }}</th>
<th class="text-center">{{ app_config.depth }}</th>
<th class="text-center">{{ data.score_name|capitalize }}</th>
<th class="text-center">Time</th>
<th class="text-center">hyperparameters</th>
</tr>
</thead>
<tbody>
{% include "partials/table_report.html" %}
</tbody>
</table>
{% if summary|length > 0 %}
<div class="col-4 col-lg-4">
<table class="table table-bordered">
<thead>
<tr>
<th class="text-center bg-primary text-white">Symbol</th>
<th class="text-center bg-primary text-white">Meaning</th>
<th class="text-center bg-primary text-white">Count</th>
</tr>
</thead>
{% include "partials/table_summary.html" %}
</table>
</div>
{% endif %}
<button type="button"
class="btn-close"
aria-label="Close"
onclick="location.href = '{{ back }}'"></button>
<h7>
<b>
Total score: {{ "%.6f" % (data.results | sum(attribute="score") ) }}
</b>
</h7>
<h7>
Number of files: {{ data.results | length }}
</h7>
</div>
</section>
</div>

View File

@@ -0,0 +1,100 @@
<div id="app">
<header>
<div class="container is-fluid">
<div class="hero is-info is-bold">
<div class="hero-body">
<button class="delete is-large" onclick="location.href = '{{ back }}'"></button>
<h1 class="is-size-3">{{ data.title }}</h1>
</div>
</div>
</div>
</header>
<section class="section">
<div class="container is-fluid">
<div>
<table class="table is-fullwidth is-striped is-bordered">
<thead>
<tr class="is-selected">
<th class="has-text-centered">Platform</th>
<th class="has-text-centered">Model</th>
<th class="has-text-centered">Date</th>
<th class="has-text-centered">Time</th>
{% if data.duration > 7200 %}
{% set unit = "h" %}
{% set divider = 3600 %}
{% else %}
{% set unit = "min" %}
{% set divider = 60 %}
{% endif %}
<th class="has-text-centered">Duration ({{ unit }})</th>
<th class="has-text-centered">Stratified</th>
<th class="has-text-centered">Discretized</th>
<th class="has-text-centered"># Folds</th>
</tr>
<tr>
<th class="has-text-centered">{{ data.platform }}</th>
<th class="has-text-centered">{{ data.model }} {{ data.version }}</th>
<th class="has-text-centered">{{ data.date }}</th>
<th class="has-text-centered">{{ data.time }}</th>
<th class="has-text-centered">{{ "%.2f" % (data.duration/divider) }}</th>
<th class="has-text-centered">{{ data.stratified }}</th>
<th class="has-text-centered">{{ data.discretized }}</th>
<th class="has-text-centered">{{ data.folds }}</th>
</tr>
<tr>
<th class="has-text-center is-selected">Language</th>
<th class="has-text-centered" colspan=3>{{ data.language }} {{ data.language_version }}</th>
<th class="has-text-centered is-selected">Seeds</th>
<th class="has-text-centered" colspan=6>{{ data.seeds }}</th>
</tr>
</thead>
</table>
<div>
<button class="{{ button }}" onclick="excelFile()">
<i class="mdi mdi-file-excel"></i> Excel
</button>
</div>
<table id="report-table"
class="table is-fullwidth is-striped is-hoverable is-bordered">
<thead>
<tr class="is-selected">
<th class="has-text-centered">Dataset</th>
<th class="has-text-centered">Samples</th>
<th class="has-text-centered">Features</th>
<th class="has-text-centered">Classes</th>
<th class="has-text-centered">{{ app_config.nodes }}</th>
<th class="has-text-centered">{{ app_config.leaves }}</th>
<th class="has-text-centered">{{ app_config.depth }}</th>
<th class="has-text-centered">{{ data.score_name|capitalize }}</th>
<th class="has-text-centered">Time</th>
<th class="has-text-centered">hyperparameters</th>
</tr>
</thead>
<tbody>
{% include "partials/table_report.html" %}
</tbody>
</table>
{% if summary|length > 0 %}
<div class="col-2 col-lg-2">
<table class="table is-bordered">
<thead>
<tr class="is-selected">
<th class="has-text-centered">Symbol</th>
<th class="has-text-centered">Meaning</th>
<th class="has-text-centered">Count</th>
</tr>
</thead>
{% include "partials/table_summary.html" %}
</table>
</div>
{% endif %}
<h2 class="has-text-white has-background-primary">
<b>
<button class="delete" onclick="location.href = '{{ back }}'"></button>
Total score: {{ "%.6f" % (data.results | sum(attribute="score") ) }}
</b>
</h2>
<h2>Number of files: {{ data.results | length }}</h2>
</div>
</section>
</div>

View File

@@ -0,0 +1,41 @@
<table id="file-table" class="{{ select.get_table_class() }}">
<thead>
<tr>
<th>Model</th>
<th>Metric</th>
<th>Platform</th>
<th>Date</th>
<th>Time</th>
<th>Stratified</th>
<th>Title</th>
<th>Score</th>
<th>{{ select.get_button_reset()|safe }} {{ select.get_button_all()|safe }}</th>
</tr>
</thead>
<tbody>
{% for file, data in files.items() %}
{% set parts = file.split('_') %}
{% set stratified = parts[6].split('.')[0] %}
<tr id="{{ file }}">
<td>{{ parts[2] }}</td>
<td>{{ parts[1] }}</td>
<td>{{ parts[3] }}</td>
<td>{{ parts[4] }}</td>
<td>{{ parts[5] }}</td>
<td>{{ 'True' if stratified =='1' else 'False' }}</td>
<td>{{ "%s" % data["title"] }}</td>
<td class="{{ select.get_align_right() }}">{{ "%.6f" % data["score"] }}</td>
<td>
{{ select.get_button_tag("table-eye", "showFile('" ~ file ~ "')") | safe }}
{% set file_best = "best_results_" ~ parts[1] ~ "_" ~ parts[2] ~ ".json" %}
{{ select.get_button_tag("star-circle-outline", "redirectDouble('best_results', '" ~ file_best ~ "')", visible=False, name="best_buttons") | safe }}
<input
type="checkbox"
name="selected_files"
value="{{ file }}"
/>
</td>
</tr>
{% endfor %}
</tbody>
</table>

View File

@@ -0,0 +1,15 @@
<div class="{{ select.get_container_class() }}">
{{ select.header("Benchmark Results") }}
<div class="{{ select.get_level_class() }}">
<div class="{{ select.get_left_position() }}">
{{ select.get_button("Use " ~ candidate, "redirectDouble('config', '" ~ candidate ~ "')")|safe }}
{{ select.get_button(select.icon("excel") ~ " Excel", "excel()")|safe }}
{{ select.get_button(select.icon("database-eye") ~ " Datasets", "redirectSimple('datasets')")|safe }}
</div>
<div class="{{ select.get_right_position() }}">
<input type="checkbox" id="compare" name="compare" {% if compare %} {{ "checked" }} {% endif %}>
<span class="{{ select.get_tag_class() }}">Comparing with best results</span>
</div>
</div>
{% include "partials/table_select.html" %}
</div>

View File

@@ -0,0 +1,13 @@
{% for key, value in summary.items() %}
<tr>
<td class="{{ center }}">
{{key}}
</td>
<td >
{{value[0]}}
</td>
<td class={{ right }}>
{{'{:,}'.format(value[1])}}
</td>
</tr>
{% endfor %}

View File

@@ -0,0 +1,29 @@
{% macro javascript(file) %}
<script src="{{ url_for('static', filename=file) }}"></script>
{% endmacro %}
{% set title = 'Report Viewer' %}
{% extends 'base_' ~ framework ~ '.html' %}
{% block content %}
{% if framework == 'bootstrap' %}
{% set center = 'text-center' %}
{% set right = 'text-end' %}
{% set button = 'btn btn-primary' %}
{% include 'partials/table_report_bootstrap.html' %}
{% else %}
{% set center = 'has-text-centered' %}
{% set right = 'has-text-right' %}
{% set button = 'button is-primary' %}
{% include 'partials/table_report_bulma.html' %}
{% endif %}
{% endblock %}
{% block jscript %}
{% if framework == 'bootstrap' %}
{% set selected = 'selected' %}
{% else %}
{% set selected = 'is-selected' %}
{% endif %}
<script>
{% include "js/report.js" %}
</script>
{{ javascript("js/excelFiles.js") }}
{% endblock %}

View File

@@ -0,0 +1,47 @@
{% set title = "Best Results" %}
{% extends "base_" ~ framework ~ ".html" %}
{% import "partials/cfg_select_" ~ framework ~ ".jinja" as select %}
{% block content %}
<div class="container">
{{ select.header(title, True, url_for("main.index", compare=compare)) }}
<table id="file-table" class="{{ select.get_table_class() }}">
<thead>
<tr class="{{ select.get_row_head_class() }}">
<th class="{{ select.get_align_center() }}">Dataset</th>
<th class="{{ select.get_align_center() }}">Score</th>
<th class="{{ select.get_align_center() }}">Hyperparameters</th>
<th class="{{ select.get_align_center() }}">File</th>
</tr>
</thead>
<tbody>
{% for dataset, info in data.items() %}
<tr>
<td>{{ dataset }}</td>
<td class="{{ select.get_align_right() }}">{{ '%9.7f' % info[0] }}</td>
<td class="{{ select.get_align_center() }}">{{ info[1] }}</td>
<td>
{% set url = url_for(request.endpoint, **request.view_args)|urlencode %}
<a href="{{ url_for('main.showfile', file_name = info[2], compare = compare) }}?url={{ url }}">{{ info[2] }}</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
{% block jscript %}
<script>
$(document).ready(function () {
// Check if row is selected
$('#file-table tbody').on('click', 'tr', function () {
if ($(this).hasClass('{{ select.selected() }}')) {
$(this).removeClass('{{ select.selected() }}');
} else {
$('#file-table tbody tr.{{ select.selected() }}').removeClass("{{ select.selected() }}")
$(this).addClass('{{ select.selected() }}');
}
});
});
</script>
{% endblock %}

View File

@@ -0,0 +1,20 @@
{% macro javascript(file) %}
<script src="{{ url_for('static', filename=file) }}"></script>
{% endmacro %}
{% set title = 'Benchmark Results' %}
{% extends 'base_' ~ framework ~ '.html' %}
{% import 'partials/cfg_select_' ~ framework ~ '.jinja' as select %}
{% block content %}
{% include 'partials/table_select_design.html' %}
{% endblock %}
{% block jscript %}
<script src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.min.js"></script>
{% if framework == 'bootstrap' %}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.min.js" integrity="sha384-cuYeSxntonz0PPNlHhBs68uyIAVpIIOZZ5JqeqvYYIcEL727kskC66kF92t6Xl2V" crossorigin="anonymous"></script>
{% endif %}
<script>
{% include'/js/select.js' %}
</script>
{{ javascript('js/excelFiles.js') }}
{% endblock %}

18
benchmark/scripts/be_flask.py Executable file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/env python
import webbrowser
from benchmark.Arguments import Arguments
from benchmark.scripts.app.app import create_app, TEST, OUTPUT
# Launch a flask server to serve the results
def main(args_test=None):
arguments = Arguments(prog="be_flask")
arguments.xset("output")
args = arguments.parse(args_test)
app = create_app()
app.config[TEST] = args_test is not None
app.config[OUTPUT] = args.output
print("Output is ", args.output)
if args.output == "local":
webbrowser.open_new("http://127.0.0.1:1234/")
app.run(port=1234, host="0.0.0.0")

View File

@@ -68,7 +68,7 @@ class ArgumentsTest(TestBase):
test_args = ["-n", "3", "-k", "date"]
with self.assertRaises(SystemExit):
arguments.parse(test_args)
self.assertRegexpMatches(
self.assertRegex(
stderr.getvalue(),
r"error: the following arguments are required: -m/--model",
)
@@ -79,7 +79,7 @@ class ArgumentsTest(TestBase):
test_args = ["-n", "3", "-m", "SVC"]
with self.assertRaises(SystemExit):
arguments.parse(test_args)
self.assertRegexpMatches(
self.assertRegex(
stderr.getvalue(),
r"error: the following arguments are required: -k/--key",
)
@@ -114,7 +114,7 @@ class ArgumentsTest(TestBase):
test_args = None
with self.assertRaises(SystemExit):
arguments.parse(test_args)
self.assertRegexpMatches(
self.assertRegex(
stderr.getvalue(),
r"error: the following arguments are required: -m/--model, "
"-k/--key, --title",

View File

@@ -102,7 +102,7 @@ class ModelTest(TestBase):
test = {
"STree": ((11, 6, 4), 1.0),
"Wodt": ((303, 152, 50), 0.9382022471910112),
"ODTE": ((7.86, 4.43, 3.37), 1.0),
"ODTE": ((786, 443, 337), 1.0),
"Cart": ((23, 12, 5), 1.0),
"SVC": ((0, 0, 0), 0.7078651685393258),
"RandomForest": ((21.3, 11, 5.26), 1.0),

View File

@@ -118,7 +118,7 @@ class UtilTest(TestBase):
def test_Files_get_results(self):
os.chdir(os.path.dirname(os.path.abspath(__file__)))
self.assertCountEqual(
Files().get_all_results(hidden=False),
Files.get_all_results(hidden=False),
[
"results_accuracy_STree_iMac27_2021-10-27_09:40:40_0.json",
"results_accuracy_STree_iMac27_2021-09-30_11:42:07_0.json",
@@ -130,7 +130,7 @@ class UtilTest(TestBase):
],
)
self.assertCountEqual(
Files().get_all_results(hidden=True),
Files.get_all_results(hidden=True),
[
"results_accuracy_STree_iMac27_2021-11-01_23:55:16_0.json",
"results_accuracy_XGBoost_MacBookpro16_2022-05-04_11:00:35_"
@@ -143,7 +143,7 @@ class UtilTest(TestBase):
# check with results
os.rename(Folders.results, f"{Folders.results}.test")
try:
Files().get_all_results(hidden=False)
Files.get_all_results(hidden=False)
except ValueError:
pass
else:
@@ -153,7 +153,7 @@ class UtilTest(TestBase):
# check with hidden_results
os.rename(Folders.hidden_results, f"{Folders.hidden_results}.test")
try:
Files().get_all_results(hidden=True)
Files.get_all_results(hidden=True)
except ValueError:
pass
else:

View File

@@ -1,2 +1,2 @@
iris,class,all
wine,class,[0, 1]
iris;class;all
wine;class;[0, 1]

View File

@@ -6,7 +6,7 @@
"kernel": "liblinear",
"multiclass_strategy": "ovr"
},
"v. 1.3.1, Computed on Test on 2022-02-22 at 12:00:00 took 1s"
"v. 1.4.0, Computed on Test on 2022-02-22 at 12:00:00 took 1s"
],
"balloons": [
0.625,
@@ -15,6 +15,6 @@
"kernel": "linear",
"multiclass_strategy": "ovr"
},
"v. 1.3.1, Computed on Test on 2022-02-22 at 12:00:00 took 1s"
"v. 1.4.0, Computed on Test on 2022-02-22 at 12:00:00 took 1s"
]
}

View File

@@ -120,7 +120,7 @@ class BeMainTest(TestBase):
module.main(parameter)
self.assertEqual(msg.exception.code, 2)
self.assertEqual(stderr.getvalue(), "")
self.assertRegexpMatches(stdout.getvalue(), message)
self.assertRegex(stdout.getvalue(), message)
def test_be_main_best_params_non_existent(self):
model = "GBC"

View File

@@ -1,4 +1,4 @@
1;1;"Datasets used in benchmark ver. 0.5.0"
1;1;"Datasets used in benchmark ver. 1.0.1"
2;1;" Default score accuracy"
2;2;"Cross validation"
2;6;"5 Folds"

View File

@@ -1,4 +1,4 @@
Datasets used in benchmark ver. 0.5.0
Datasets used in benchmark ver. 1.0.1
Dataset Sampl. Feat. Cont Cls Balance
============================== ====== ===== ==== === ==========================================

View File

@@ -5,7 +5,7 @@ odte
cython
fimdlp
mufs
bayesclass @ git+ssh://git@github.com/doctorado-ml/bayesclass.git
#bayesclass @ git+ssh://git@github.com/doctorado-ml/bayesclass.git
xlsxwriter
openpyxl
tqdm
@@ -13,3 +13,4 @@ xgboost
graphviz
Wodt @ git+ssh://git@github.com/doctorado-ml/Wodt.git#egg=Wodt
unittest-xml-reporting
flask

View File

@@ -39,6 +39,7 @@ def script_names():
"report",
"summary",
"init_project",
"flask",
]
result = []
for script in scripts: