From 4f5f629124405f599b692354eba7d36732252d48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Monta=C3=B1ana=20G=C3=B3mez?= Date: Tue, 5 Mar 2024 23:44:19 +0100 Subject: [PATCH 1/4] Create class ReportExcelCompared --- src/CMakeLists.txt | 5 +++- src/manage/ManageResults.cc | 42 +++++++++++++++++++++++++++--- src/manage/ManageResults.h | 2 +- src/reports/ReportExcel.h | 2 +- src/reports/ReportExcelCompared.cc | 21 +++++++++++++++ src/reports/ReportExcelCompared.h | 14 ++++++++++ 6 files changed, 79 insertions(+), 7 deletions(-) create mode 100644 src/reports/ReportExcelCompared.cc create mode 100644 src/reports/ReportExcelCompared.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bcece79..b928c5d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -49,5 +49,8 @@ target_link_libraries(b_main PyClassifiers BayesNet ArffFiles mdlp) # b_manage set(manage_sources b_manage.cc ManageResults.cc CommandParser.cc Results.cc) list(TRANSFORM manage_sources PREPEND manage/) -add_executable(b_manage ${manage_sources} main/Result.cc reports/ReportConsole.cc reports/ReportExcel.cc reports/ReportBase.cc reports/ExcelFile.cc common/Datasets.cc common/Dataset.cc) +add_executable(b_manage ${manage_sources} main/Result.cc + reports/ReportConsole.cc reports/ReportExcel.cc reports/ReportExcelCompared.cc reports/ReportBase.cc reports/ExcelFile.cc + common/Datasets.cc common/Dataset.cc +) target_link_libraries(b_manage "${TORCH_LIBRARIES}" "${XLSXWRITER_LIB}" ArffFiles mdlp) diff --git a/src/manage/ManageResults.cc b/src/manage/ManageResults.cc index 078773f..fc4de4b 100644 --- a/src/manage/ManageResults.cc +++ b/src/manage/ManageResults.cc @@ -7,6 +7,7 @@ #include "Paths.h" #include "ReportConsole.h" #include "ReportExcel.h" +#include "ReportExcelCompared.h" namespace platform { @@ -84,6 +85,14 @@ namespace platform { std::cout << "Not done!" << std::endl; return false; } + void ManageResults::report_compared(const int index_A, const int index_B) + { + std::cout << "Comparing " << results.at(index_A).getFilename() << " with " << results.at(index_B).getFilename() << std::endl; + auto data_A = results.at(index_A).getJson(); + auto data_B = results.at(index_B).getJson(); + ReportExcelCompared reporter(data_A, data_B); + reporter.report(); + } void ManageResults::report(const int index, const bool excelReport) { std::cout << Colors::YELLOW() << "Reporting " << results.at(index).getFilename() << std::endl; @@ -140,7 +149,7 @@ namespace platform { void ManageResults::menu() { char option; - int index, subIndex; + int index, subIndex, index_A = -1, index_B = -1; bool finished = false; std::string filename; // tuple @@ -152,7 +161,10 @@ namespace platform { {"sort", 's', false}, {"report", 'r', true}, {"excel", 'e', true}, - {"title", 't', true} + {"title", 't', true}, + {"set A", 'a', true}, + {"set B", 'b', true}, + {"compare A~B", 'c', false} }; // tuple std::vector> listOptions = { @@ -172,9 +184,31 @@ namespace platform { case 'q': finished = true; break; + case 'a': + if (index == index_B) { + std::cout << Colors::RED() << "A and B cannot be the same!" << Colors::RESET() << std::endl; + break; + } + index_A = index; + break; case 'b': - // back to show the report - report(index, false); + if (indexList) { + if (index == index_A) { + std::cout << Colors::RED() << "A and B cannot be the same!" << Colors::RESET() << std::endl; + break; + } + index_B = index; + } else { + // back to show the report + report(index, false); + } + break; + case 'c': + if (index_A == -1 || index_B == -1) { + std::cout << Colors::RED() << "Need to set A and B first!" << Colors::RESET() << std::endl; + break; + } + report_compared(index_A, index_B); break; case 'l': list(); diff --git a/src/manage/ManageResults.h b/src/manage/ManageResults.h index 6bd3704..ba14f27 100644 --- a/src/manage/ManageResults.h +++ b/src/manage/ManageResults.h @@ -13,6 +13,7 @@ namespace platform { void list(); bool confirmAction(const std::string& intent, const std::string& fileName) const; void report(const int index, const bool excelReport); + void report_compared(const int index_A, const int index_B); void showIndex(const int index, const int idx); void sortList(); void menu(); @@ -25,7 +26,6 @@ namespace platform { Results results; lxw_workbook* workbook; }; - } #endif /* MANAGE_RESULTS_H */ \ No newline at end of file diff --git a/src/reports/ReportExcel.h b/src/reports/ReportExcel.h index 9e7b052..5052378 100644 --- a/src/reports/ReportExcel.h +++ b/src/reports/ReportExcel.h @@ -9,11 +9,11 @@ namespace platform { class ReportExcel : public ReportBase, public ExcelFile { public: explicit ReportExcel(json data_, bool compare, lxw_workbook* workbook, lxw_worksheet* worksheet = NULL); + void closeFile(); private: void formatColumns(); void createFile(); void createWorksheet(); - void closeFile(); void header() override; void body() override; void showSummary() override; diff --git a/src/reports/ReportExcelCompared.cc b/src/reports/ReportExcelCompared.cc new file mode 100644 index 0000000..97ae356 --- /dev/null +++ b/src/reports/ReportExcelCompared.cc @@ -0,0 +1,21 @@ +#include "ReportExcelCompared.h" + +namespace platform { + + ReportExcelCompared::ReportExcelCompared(json& data_A, json& data_B) : data_A(data_A), data_B(data_B), workbook(NULL) + { + ReportExcel report(data_A, false, workbook); + workbook = report.getWorkbook(); + report.show(); + report = ReportExcel(data_B, false, workbook); + report.show(); + } + ReportExcelCompared::~ReportExcelCompared() + { + workbook_close(workbook); + } + void ReportExcelCompared::report() + { + + } +} \ No newline at end of file diff --git a/src/reports/ReportExcelCompared.h b/src/reports/ReportExcelCompared.h new file mode 100644 index 0000000..d61d9f6 --- /dev/null +++ b/src/reports/ReportExcelCompared.h @@ -0,0 +1,14 @@ +#pragma once +#include "ReportExcel.h" +namespace platform { + class ReportExcelCompared { + public: + explicit ReportExcelCompared(json& data_A, json& data_B); + ~ReportExcelCompared(); + void report(); + private: + json& data_A; + json& data_B; + lxw_workbook* workbook; + }; +}; \ No newline at end of file -- 2.49.1 From 4eb08cd281c2aef0fe66873af171d0eb70d8b82f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Monta=C3=B1ana=20G=C3=B3mez?= Date: Wed, 6 Mar 2024 01:26:51 +0100 Subject: [PATCH 2/4] Complete sheet with totals --- src/manage/ManageResults.cc | 8 ++ src/reports/ExcelFile.cc | 7 +- src/reports/ReportExcelCompared.cc | 132 +++++++++++++++++++++++++++-- src/reports/ReportExcelCompared.h | 6 +- 4 files changed, 142 insertions(+), 11 deletions(-) diff --git a/src/manage/ManageResults.cc b/src/manage/ManageResults.cc index fc4de4b..ba4d73a 100644 --- a/src/manage/ManageResults.cc +++ b/src/manage/ManageResults.cc @@ -189,6 +189,10 @@ namespace platform { std::cout << Colors::RED() << "A and B cannot be the same!" << Colors::RESET() << std::endl; break; } + if (!results.at(index).isComplete()) { + std::cout << Colors::RED() << "A must be a complete result!" << Colors::RESET() << std::endl; + break; + } index_A = index; break; case 'b': @@ -197,6 +201,10 @@ namespace platform { std::cout << Colors::RED() << "A and B cannot be the same!" << Colors::RESET() << std::endl; break; } + if (!results.at(index).isComplete()) { + std::cout << Colors::RED() << "B must be a complete result!" << Colors::RESET() << std::endl; + break; + } index_B = index; } else { // back to show the report diff --git a/src/reports/ExcelFile.cc b/src/reports/ExcelFile.cc index e9407b6..611db74 100644 --- a/src/reports/ExcelFile.cc +++ b/src/reports/ExcelFile.cc @@ -121,12 +121,17 @@ namespace platform { format_set_align(style, LXW_ALIGN_VERTICAL_CENTER); format_set_font_size(style, normalSize); format_set_num_format(style, "#,##0.00"); + } else if (name == "percentage") { + format_set_border(style, LXW_BORDER_THIN); + format_set_align(style, LXW_ALIGN_VERTICAL_CENTER); + format_set_font_size(style, normalSize); + format_set_num_format(style, "0.00%"); } } void ExcelFile::createFormats() { - auto styleNames = { "text", "textCentered", "bodyHeader", "result", "time", "ints", "floats" }; + auto styleNames = { "text", "textCentered", "bodyHeader", "result", "time", "ints", "floats", "percentage" }; lxw_format* style; for (std::string name : styleNames) { lxw_format* style = workbook_add_format(workbook); diff --git a/src/reports/ReportExcelCompared.cc b/src/reports/ReportExcelCompared.cc index 97ae356..747691c 100644 --- a/src/reports/ReportExcelCompared.cc +++ b/src/reports/ReportExcelCompared.cc @@ -2,20 +2,136 @@ namespace platform { - ReportExcelCompared::ReportExcelCompared(json& data_A, json& data_B) : data_A(data_A), data_B(data_B), workbook(NULL) + ReportExcelCompared::ReportExcelCompared(json& data_A, json& data_B) : data_A(data_A), data_B(data_B), ExcelFile(NULL, NULL) { - ReportExcel report(data_A, false, workbook); - workbook = report.getWorkbook(); - report.show(); - report = ReportExcel(data_B, false, workbook); - report.show(); } ReportExcelCompared::~ReportExcelCompared() { - workbook_close(workbook); + if (workbook) + workbook_close(workbook); } void ReportExcelCompared::report() { - + // Create a new workbook and add the two worksheets A & B + workbook = workbook_new((Paths::excel() + Paths::excelResults()).c_str()); + worksheet = workbook_add_worksheet(workbook, "A"); + createFormats(); + ReportExcel report(data_A, false, workbook, worksheet); + workbook = report.getWorkbook(); + report.show(); + worksheet = workbook_add_worksheet(workbook, "B"); + report = ReportExcel(data_B, false, workbook, worksheet); + report.show(); + // Add the comparison worksheet + worksheet = workbook_add_worksheet(workbook, "Comparison"); + header(); + body(); + } + void ReportExcelCompared::header() + { + worksheet_merge_range(worksheet, 0, 0, 0, 20, "Compare Results A & B", styles["headerFirst"]); + } + double diff(double a, double b) + { + return (a - b) / b; + } + void ReportExcelCompared::body() + { + // Body Header + auto sizes = std::vector({ 22, 10, 9, 7, 12, 12, 9, 12, 12, 9, 12, 12, 9, 12, 12, 9, 15, 15, 9, 15, 15 }); + auto head_a = std::vector({ "Dataset", "Samples", "Features", "Classes" }); + auto head_b = std::vector({ "Nodes", "Edges", "States", "Score", "Time" }); + int headerRow = 3; + int col = 0; + for (const auto& item : head_a) { + worksheet_merge_range(worksheet, headerRow, col, headerRow + 1, col, item.c_str(), styles["bodyHeader_even"]); + col++; + } + for (const auto& item : head_b) { + worksheet_merge_range(worksheet, headerRow, col, headerRow, col + 2, item.c_str(), styles["bodyHeader_even"]); + writeString(headerRow + 1, col, "A", "bodyHeader"); + writeString(headerRow + 1, col + 1, "B", "bodyHeader"); + writeString(headerRow + 1, col + 2, "Δ", "bodyHeader"); + col += 3; + } + worksheet_merge_range(worksheet, headerRow, col, headerRow, col + 1, "Hyperparameters", styles["bodyHeader_even"]); + int hypCol = col; + writeString(headerRow + 1, hypCol, "A", "bodyHeader"); + writeString(headerRow + 1, hypCol + 1, "B", "bodyHeader"); + col = 0; + for (const auto size : sizes) { + worksheet_set_column(worksheet, col, col, size, NULL); + col++; + } + // Body Data + row = headerRow + 2; + col = 0; + int hypSize_A = 15; + int hypSize_B = 15; + auto compared = std::vector({ "nodes", "leaves", "depth", "score", "time" }); + auto compared_data = std::vector(compared.size(), 0.0); + auto totals_A = std::vector(compared.size(), 0.0); + auto totals_B = std::vector(compared.size(), 0.0); + std::string hyperparameters; + for (int i = 0; i < data_A["results"].size(); i++) { + const auto& r_A = data_A["results"][i]; + const auto& r_B = data_B["results"][i]; + for (int j = 0; j < compared.size(); j++) { + auto key = compared[j]; + compared_data[j] = diff(r_A[key].get(), r_B[key].get()); + totals_A[j] += r_A[key].get(); + totals_B[j] += r_B[key].get(); + } + // transform(compared.begin(), compared.end(), compared_data.begin(), [&](const std::string& key) { + // return diff(r_A[key].get(), r_B[key].get()); + // }); + writeString(row, col, r_A["dataset"].get(), "text"); + writeInt(row, col + 1, r_A["samples"].get(), "ints"); + writeInt(row, col + 2, r_A["features"].get(), "ints"); + writeInt(row, col + 3, r_A["classes"].get(), "ints"); + writeDouble(row, col + 4, r_A["nodes"].get(), "floats"); + writeDouble(row, col + 5, r_B["nodes"].get(), "floats"); + writeDouble(row, col + 6, compared_data[0], "percentage"); + writeDouble(row, col + 7, r_A["leaves"].get(), "floats"); + writeDouble(row, col + 8, r_B["leaves"].get(), "floats"); + writeDouble(row, col + 9, compared_data[1], "percentage"); + writeDouble(row, col + 10, r_A["depth"].get(), "floats"); + writeDouble(row, col + 11, r_B["depth"].get(), "floats"); + writeDouble(row, col + 12, compared_data[2], "percentage"); + writeDouble(row, col + 13, r_A["score"].get(), "result"); + writeDouble(row, col + 14, r_B["score"].get(), "result"); + writeDouble(row, col + 15, compared_data[3], "percentage"); + writeDouble(row, col + 16, r_A["time"].get(), "time"); + writeDouble(row, col + 17, r_B["time"].get(), "time"); + writeDouble(row, col + 18, compared_data[4], "percentage"); + hyperparameters = r_A["hyperparameters"].dump(); + if (hyperparameters.size() > hypSize_A) { + hypSize_A = hyperparameters.size(); + } + writeString(row, hypCol, hyperparameters, "text"); + hyperparameters = r_B["hyperparameters"].dump(); + if (hyperparameters.size() > hypSize_B) { + hypSize_B = hyperparameters.size(); + } + writeString(row, hypCol + 1, hyperparameters, "text"); + row++; + } + // Set the right column width of hyperparameters with the maximum length + worksheet_set_column(worksheet, hypCol, hypCol, hypSize_A + 5, NULL); + worksheet_set_column(worksheet, hypCol + 1, hypCol + 1, hypSize_B + 5, NULL); + // Show totals if only one dataset is present in the result + footer(totals_A, totals_B, row); + } + void ReportExcelCompared::footer(std::vector& totals_A, std::vector& totals_B, int row) + { + worksheet_merge_range(worksheet, row, 0, row, 3, "Total", styles["bodyHeader_even"]); + auto formats = std::vector({ "floats", "floats", "floats", "result", "result" }); + int col = 4; + for (int i = 0; i < totals_A.size(); i++) { + writeDouble(row, col, totals_A[i], formats[i]); + writeDouble(row, col + 1, totals_B[i], formats[i]); + writeDouble(row, col + 2, diff(totals_A[i], totals_B[i]), "percentage"); + col += 3; + } } } \ No newline at end of file diff --git a/src/reports/ReportExcelCompared.h b/src/reports/ReportExcelCompared.h index d61d9f6..fea47cb 100644 --- a/src/reports/ReportExcelCompared.h +++ b/src/reports/ReportExcelCompared.h @@ -1,14 +1,16 @@ #pragma once #include "ReportExcel.h" namespace platform { - class ReportExcelCompared { + class ReportExcelCompared : public ExcelFile { public: explicit ReportExcelCompared(json& data_A, json& data_B); ~ReportExcelCompared(); void report(); private: + void header(); + void body(); + void footer(std::vector& totals_A, std::vector& totals_B, int row); json& data_A; json& data_B; - lxw_workbook* workbook; }; }; \ No newline at end of file -- 2.49.1 From 183cf123004fe6cefbdcb707225ca33c4a82979c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Monta=C3=B1ana?= Date: Wed, 6 Mar 2024 10:35:42 +0100 Subject: [PATCH 3/4] Refactor column count and header --- src/reports/ReportExcelCompared.cc | 63 ++++++++++++++---------------- 1 file changed, 29 insertions(+), 34 deletions(-) diff --git a/src/reports/ReportExcelCompared.cc b/src/reports/ReportExcelCompared.cc index 747691c..9e6f24a 100644 --- a/src/reports/ReportExcelCompared.cc +++ b/src/reports/ReportExcelCompared.cc @@ -29,7 +29,8 @@ namespace platform { } void ReportExcelCompared::header() { - worksheet_merge_range(worksheet, 0, 0, 0, 20, "Compare Results A & B", styles["headerFirst"]); + worksheet_merge_range(worksheet, 0, 0, 0, 20, "Compare Results A vs B", styles["headerFirst"]); + worksheet_merge_range(worksheet, 1, 0, 1, 20, "Δ = (A - B) / B", styles["headerRest"]); } double diff(double a, double b) { @@ -49,10 +50,9 @@ namespace platform { } for (const auto& item : head_b) { worksheet_merge_range(worksheet, headerRow, col, headerRow, col + 2, item.c_str(), styles["bodyHeader_even"]); - writeString(headerRow + 1, col, "A", "bodyHeader"); - writeString(headerRow + 1, col + 1, "B", "bodyHeader"); - writeString(headerRow + 1, col + 2, "Δ", "bodyHeader"); - col += 3; + writeString(headerRow + 1, col++, "A", "bodyHeader"); + writeString(headerRow + 1, col++, "B", "bodyHeader"); + writeString(headerRow + 1, col++, "Δ", "bodyHeader"); } worksheet_merge_range(worksheet, headerRow, col, headerRow, col + 1, "Hyperparameters", styles["bodyHeader_even"]); int hypCol = col; @@ -60,12 +60,10 @@ namespace platform { writeString(headerRow + 1, hypCol + 1, "B", "bodyHeader"); col = 0; for (const auto size : sizes) { - worksheet_set_column(worksheet, col, col, size, NULL); - col++; + worksheet_set_column(worksheet, col, col++, size, NULL); } // Body Data row = headerRow + 2; - col = 0; int hypSize_A = 15; int hypSize_B = 15; auto compared = std::vector({ "nodes", "leaves", "depth", "score", "time" }); @@ -74,6 +72,7 @@ namespace platform { auto totals_B = std::vector(compared.size(), 0.0); std::string hyperparameters; for (int i = 0; i < data_A["results"].size(); i++) { + col = 0; const auto& r_A = data_A["results"][i]; const auto& r_B = data_B["results"][i]; for (int j = 0; j < compared.size(); j++) { @@ -82,28 +81,25 @@ namespace platform { totals_A[j] += r_A[key].get(); totals_B[j] += r_B[key].get(); } - // transform(compared.begin(), compared.end(), compared_data.begin(), [&](const std::string& key) { - // return diff(r_A[key].get(), r_B[key].get()); - // }); - writeString(row, col, r_A["dataset"].get(), "text"); - writeInt(row, col + 1, r_A["samples"].get(), "ints"); - writeInt(row, col + 2, r_A["features"].get(), "ints"); - writeInt(row, col + 3, r_A["classes"].get(), "ints"); - writeDouble(row, col + 4, r_A["nodes"].get(), "floats"); - writeDouble(row, col + 5, r_B["nodes"].get(), "floats"); - writeDouble(row, col + 6, compared_data[0], "percentage"); - writeDouble(row, col + 7, r_A["leaves"].get(), "floats"); - writeDouble(row, col + 8, r_B["leaves"].get(), "floats"); - writeDouble(row, col + 9, compared_data[1], "percentage"); - writeDouble(row, col + 10, r_A["depth"].get(), "floats"); - writeDouble(row, col + 11, r_B["depth"].get(), "floats"); - writeDouble(row, col + 12, compared_data[2], "percentage"); - writeDouble(row, col + 13, r_A["score"].get(), "result"); - writeDouble(row, col + 14, r_B["score"].get(), "result"); - writeDouble(row, col + 15, compared_data[3], "percentage"); - writeDouble(row, col + 16, r_A["time"].get(), "time"); - writeDouble(row, col + 17, r_B["time"].get(), "time"); - writeDouble(row, col + 18, compared_data[4], "percentage"); + writeString(row, col++, r_A["dataset"].get(), "text"); + writeInt(row, col++, r_A["samples"].get(), "ints"); + writeInt(row, col++, r_A["features"].get(), "ints"); + writeInt(row, col++, r_A["classes"].get(), "ints"); + writeDouble(row, col++, r_A["nodes"].get(), "floats"); + writeDouble(row, col++, r_B["nodes"].get(), "floats"); + writeDouble(row, col++, compared_data[0], "percentage"); + writeDouble(row, col++, r_A["leaves"].get(), "floats"); + writeDouble(row, col++, r_B["leaves"].get(), "floats"); + writeDouble(row, col++, compared_data[1], "percentage"); + writeDouble(row, col++, r_A["depth"].get(), "floats"); + writeDouble(row, col++, r_B["depth"].get(), "floats"); + writeDouble(row, col++, compared_data[2], "percentage"); + writeDouble(row, col++, r_A["score"].get(), "result"); + writeDouble(row, col++, r_B["score"].get(), "result"); + writeDouble(row, col++, compared_data[3], "percentage"); + writeDouble(row, col++, r_A["time"].get(), "time"); + writeDouble(row, col++, r_B["time"].get(), "time"); + writeDouble(row, col++, compared_data[4], "percentage"); hyperparameters = r_A["hyperparameters"].dump(); if (hyperparameters.size() > hypSize_A) { hypSize_A = hyperparameters.size(); @@ -128,10 +124,9 @@ namespace platform { auto formats = std::vector({ "floats", "floats", "floats", "result", "result" }); int col = 4; for (int i = 0; i < totals_A.size(); i++) { - writeDouble(row, col, totals_A[i], formats[i]); - writeDouble(row, col + 1, totals_B[i], formats[i]); - writeDouble(row, col + 2, diff(totals_A[i], totals_B[i]), "percentage"); - col += 3; + writeDouble(row, col++, totals_A[i], formats[i]); + writeDouble(row, col++, totals_B[i], formats[i]); + writeDouble(row, col++, diff(totals_A[i], totals_B[i]), "percentage"); } } } \ No newline at end of file -- 2.49.1 From e26b3c097089d8f1f8c223ae5b683c713ac221b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Montan=CC=83ana?= Date: Wed, 6 Mar 2024 11:22:43 +0100 Subject: [PATCH 4/4] Add fixed header to Delta --- src/reports/ReportExcelCompared.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/reports/ReportExcelCompared.cc b/src/reports/ReportExcelCompared.cc index 9e6f24a..5d3cbc1 100644 --- a/src/reports/ReportExcelCompared.cc +++ b/src/reports/ReportExcelCompared.cc @@ -23,7 +23,7 @@ namespace platform { report = ReportExcel(data_B, false, workbook, worksheet); report.show(); // Add the comparison worksheet - worksheet = workbook_add_worksheet(workbook, "Comparison"); + worksheet = workbook_add_worksheet(workbook, "Δ"); header(); body(); } @@ -31,6 +31,7 @@ namespace platform { { worksheet_merge_range(worksheet, 0, 0, 0, 20, "Compare Results A vs B", styles["headerFirst"]); worksheet_merge_range(worksheet, 1, 0, 1, 20, "Δ = (A - B) / B", styles["headerRest"]); + worksheet_freeze_panes(worksheet, 5, 1); } double diff(double a, double b) { @@ -60,7 +61,8 @@ namespace platform { writeString(headerRow + 1, hypCol + 1, "B", "bodyHeader"); col = 0; for (const auto size : sizes) { - worksheet_set_column(worksheet, col, col++, size, NULL); + worksheet_set_column(worksheet, col, col, size, NULL); + col++; } // Body Data row = headerRow + 2; -- 2.49.1