Fix result name overlapping in simultaneous experiments

This commit is contained in:
2025-08-04 13:10:48 +02:00
parent e8b35d4c5e
commit b7f4651e2c
6 changed files with 49 additions and 14 deletions

View File

@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.20)
project(Platform
VERSION 1.1.0
VERSION 1.1.1
DESCRIPTION "Platform to run Experiments with classifiers."
HOMEPAGE_URL "https://github.com/rmontanana/platform"
LANGUAGES CXX

View File

@@ -41,8 +41,7 @@ namespace platform {
}
json bests;
for (const auto& file : files) {
auto result = Result();
result.load(path, file);
auto result = Result(path, file);
auto data = result.getJson();
for (auto const& item : data.at("results")) {
bool update = true;

View File

@@ -13,8 +13,7 @@ namespace platform {
for (const auto& file : directory_iterator(path)) {
auto filename = file.path().filename().string();
if (filename.find(".json") != std::string::npos && filename.find("results_") == 0) {
auto result = Result();
result.load(path, filename);
auto result = Result(path, filename);
bool addResult = true;
if (platform != "any" && result.getPlatform() != platform
|| model != "any" && result.getModel() != model

View File

@@ -1,6 +1,8 @@
#include <filesystem>
#include <fstream>
#include <sstream>
#include <random>
#include <cstdlib>
#include "best/BestScore.h"
#include "common/Colors.h"
#include "common/DotEnv.h"
@@ -34,14 +36,25 @@ namespace platform {
}
Result::Result()
{
path = Paths::results();
fileName = "none";
data["date"] = get_actual_date();
data["time"] = get_actual_time();
data["results"] = json::array();
data["seeds"] = json::array();
complete = false;
}
Result& Result::load(const std::string& path, const std::string& fileName)
std::string Result::getFilename() const
{
if (fileName == "none") {
throw std::runtime_error("Filename is not set. Use save() method to generate a filename.");
}
return fileName;
}
Result::Result(const std::string& path, const std::string& fileName)
{
this->path = path;
this->fileName = fileName;
std::ifstream resultData(path + "/" + fileName);
if (resultData.is_open()) {
data = json::parse(resultData);
@@ -58,7 +71,6 @@ namespace platform {
score /= best.second;
}
complete = data["results"].size() > 1;
return *this;
}
json Result::getJson()
{
@@ -71,11 +83,15 @@ namespace platform {
}
void Result::save(const std::string& path)
{
std::ofstream file(path + getFilename());
do {
fileName = generateFileName();
}
while (std::filesystem::exists(path + fileName));
std::ofstream file(path + fileName);
file << data;
file.close();
}
std::string Result::getFilename() const
std::string Result::generateFileName()
{
std::ostringstream oss;
std::string stratified;
@@ -85,13 +101,31 @@ namespace platform {
catch (nlohmann::json_abi_v3_11_3::detail::type_error) {
stratified = data["stratified"].get<int>() == 1 ? "1" : "0";
}
auto generateRandomString = [](int length) -> std::string {
const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
// Use thread-local static generator to avoid interfering with global random state
thread_local static std::random_device rd;
thread_local static std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, sizeof(alphanum) - 2);
std::string result;
for (int i = 0; i < length; ++i) {
result += alphanum[dis(gen)];
}
return result;
};
oss << "results_"
<< data.at("score_name").get<std::string>() << "_"
<< data.at("model").get<std::string>() << "_"
<< data.at("platform").get<std::string>() << "_"
<< data["date"].get<std::string>() << "_"
<< data["time"].get<std::string>() << "_"
<< stratified << ".json";
<< stratified << "_"
<< generateRandomString(5) << ".json";
return oss.str();
}
std::string Result::to_string(int maxModel, int maxTitle) const

View File

@@ -5,6 +5,7 @@
#include <string>
#include <nlohmann/json.hpp>
#include "common/Timer.hpp"
#include "common/Paths.h"
#include "main/HyperParameters.h"
#include "main/PartialResult.h"
@@ -14,7 +15,7 @@ namespace platform {
class Result {
public:
Result();
Result& load(const std::string& path, const std::string& filename);
Result(const std::string& path, const std::string& filename);
void save(const std::string& path);
std::vector<std::string> check();
// Getters
@@ -49,6 +50,9 @@ namespace platform {
void setNFolds(int nfolds) { data["folds"] = nfolds; };
void setPlatform(const std::string& platform_name) { data["platform"] = platform_name; };
private:
std::string generateFileName();
std::string path;
std::string fileName;
json data;
bool complete;
double score = 0.0;

View File

@@ -13,8 +13,7 @@ namespace platform {
for (const auto& file : directory_iterator(path)) {
auto filename = file.path().filename().string();
if (filename.find(".json") != std::string::npos && filename.find("results_") == 0) {
auto result = Result();
result.load(path, filename);
auto result = Result(path, filename);
if (model != "any" && result.getModel() != model)
continue;
auto data = result.getData()["results"];