mirror of
https://github.com/rmontanana/mdlp.git
synced 2025-08-21 02:15:57 +00:00
Compare commits
6 Commits
fcbd05d842
...
a2ba5ee7e0
Author | SHA1 | Date | |
---|---|---|---|
a2ba5ee7e0
|
|||
d6276b46cd
|
|||
d9bd689a10
|
|||
6f8f535b40
|
|||
872385e3ee
|
|||
cb3659b225
|
15
.github/workflows/build.yml
vendored
15
.github/workflows/build.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
env:
|
||||
BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory # Directory where build-wrapper output will be placed
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.6
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
|
||||
- name: Install sonar-scanner and build-wrapper
|
||||
@@ -28,17 +28,16 @@ jobs:
|
||||
unzip libtorch-cxx11-abi-shared-with-deps-2.3.1+cpu.zip
|
||||
- name: Tests & build-wrapper
|
||||
run: |
|
||||
cmake -S . -B build -Wno-dev -DCMAKE_PREFIX_PATH=$(pwd)/libtorch -DENABLE_TESTING=ON
|
||||
build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build/ --config Release
|
||||
cmake -S . -B build -Wno-dev -DCMAKE_PREFIX_PATH=$(pwd)/libtorch -DCMAKE_BUILD_TYPE=Debug -DENABLE_TESTING=ON
|
||||
build-wrapper-linux-x86-64 --out-dir ${{ env.BUILD_WRAPPER_OUT_DIR }} cmake --build build/ --config Debug
|
||||
cmake --build build -j 4
|
||||
cd build
|
||||
make
|
||||
ctest -C Release --output-on-failure --test-dir tests
|
||||
cd ..
|
||||
gcovr -f CPPFImdlp.cpp -f Metrics.cpp -f BinDisc.cpp -f Discretizer.cpp --txt --sonarqube=coverage.xml
|
||||
ctest -C Debug --output-on-failure -j 4
|
||||
gcovr -f ../CPPFImdlp.cpp -f ../Metrics.cpp -f ../BinDisc.cpp -f ../Discretizer.cpp --txt --sonarqube=coverage.xml
|
||||
- name: Run sonar-scanner
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
run: |
|
||||
sonar-scanner --define sonar.cfamily.build-wrapper-output="${{ env.BUILD_WRAPPER_OUT_DIR }}" \
|
||||
--define sonar.coverageReportPaths=coverage.xml
|
||||
--define sonar.coverageReportPaths=build/coverage.xml
|
||||
|
@@ -1,3 +1,9 @@
|
||||
// ****************************************************************
|
||||
// SPDX - FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez
|
||||
// SPDX - FileType: SOURCE
|
||||
// SPDX - License - Identifier: MIT
|
||||
// ****************************************************************
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include "BinDisc.h"
|
||||
|
@@ -1,3 +1,9 @@
|
||||
// ****************************************************************
|
||||
// SPDX - FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez
|
||||
// SPDX - FileType: SOURCE
|
||||
// SPDX - License - Identifier: MIT
|
||||
// ****************************************************************
|
||||
|
||||
#ifndef BINDISC_H
|
||||
#define BINDISC_H
|
||||
|
||||
|
@@ -6,6 +6,15 @@ include_directories(${TORCH_INCLUDE_DIRS})
|
||||
add_library(mdlp CPPFImdlp.cpp Metrics.cpp BinDisc.cpp Discretizer.cpp)
|
||||
target_link_libraries(mdlp "${TORCH_LIBRARIES}")
|
||||
add_subdirectory(sample)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-elide-constructors")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
|
||||
if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-default-inline")
|
||||
endif()
|
||||
if (ENABLE_TESTING)
|
||||
MESSAGE("Debug mode")
|
||||
enable_testing()
|
||||
set(CODE_COVERAGE ON)
|
||||
SET(GCC_COVERAGE_LINK_FLAGS " ${GCC_COVERAGE_LINK_FLAGS} -lgcov --coverage")
|
||||
add_subdirectory(tests)
|
||||
endif(ENABLE_TESTING)
|
@@ -1,3 +1,9 @@
|
||||
// ****************************************************************
|
||||
// SPDX - FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez
|
||||
// SPDX - FileType: SOURCE
|
||||
// SPDX - License - Identifier: MIT
|
||||
// ****************************************************************
|
||||
|
||||
#include <numeric>
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
|
@@ -1,3 +1,9 @@
|
||||
// ****************************************************************
|
||||
// SPDX - FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez
|
||||
// SPDX - FileType: SOURCE
|
||||
// SPDX - License - Identifier: MIT
|
||||
// ****************************************************************
|
||||
|
||||
#ifndef CPPFIMDLP_H
|
||||
#define CPPFIMDLP_H
|
||||
|
||||
|
@@ -1,3 +1,9 @@
|
||||
// ****************************************************************
|
||||
// SPDX - FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez
|
||||
// SPDX - FileType: SOURCE
|
||||
// SPDX - License - Identifier: MIT
|
||||
// ****************************************************************
|
||||
|
||||
#include "Discretizer.h"
|
||||
|
||||
namespace mdlp {
|
||||
@@ -14,11 +20,6 @@ namespace mdlp {
|
||||
for (const precision_t& item : data) {
|
||||
auto pos = bound(first, last, item);
|
||||
int number = pos - first;
|
||||
/*
|
||||
OJO
|
||||
*/
|
||||
if (number < 0)
|
||||
throw std::runtime_error("number is less than 0 in discretizer::transform");
|
||||
discretizedData.push_back(number);
|
||||
}
|
||||
return discretizedData;
|
||||
|
@@ -1,3 +1,9 @@
|
||||
// ****************************************************************
|
||||
// SPDX - FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez
|
||||
// SPDX - FileType: SOURCE
|
||||
// SPDX - License - Identifier: MIT
|
||||
// ****************************************************************
|
||||
|
||||
#ifndef DISCRETIZER_H
|
||||
#define DISCRETIZER_H
|
||||
|
||||
@@ -24,7 +30,6 @@ namespace mdlp {
|
||||
torch::Tensor fit_transform_t(torch::Tensor& X_, torch::Tensor& y_);
|
||||
static inline std::string version() { return "1.2.3"; };
|
||||
protected:
|
||||
void normalize_cutpoints();
|
||||
labels_t discretizedData = labels_t();
|
||||
cutPoints_t cutPoints; // At least two cutpoints must be provided, the first and the last will be ignored in transform
|
||||
bound_dir_t direction; // used in transform
|
||||
|
25
Makefile
25
Makefile
@@ -1,13 +1,32 @@
|
||||
SHELL := /bin/bash
|
||||
.DEFAULT_GOAL := build
|
||||
.PHONY: build test
|
||||
lcov := lcov
|
||||
|
||||
build:
|
||||
@if [ -d build_release ]; then rm -fr build_release; fi
|
||||
@mkdir build_release
|
||||
@cmake -B build_release -S . -DCMAKE_BUILD_TYPE=Release -DENABLE_TESTING=OFF
|
||||
@cmake --build build_release
|
||||
@cmake --build build_release -j 8
|
||||
|
||||
test:
|
||||
@echo "Testing..."
|
||||
@cd tests && ./test
|
||||
@if [ -d build_debug ]; then rm -fr build_debug; fi
|
||||
@mkdir build_debug
|
||||
@cmake -B build_debug -S . -DCMAKE_BUILD_TYPE=Debug -DENABLE_TESTING=ON
|
||||
@cmake --build build_debug -j 8
|
||||
@cd build_debug/tests && ctest --output-on-failure -j 8
|
||||
@cd build_debug/tests && $(lcov) --capture --directory ../ --demangle-cpp --ignore-errors source,source --ignore-errors mismatch --output-file coverage.info >/dev/null 2>&1; \
|
||||
$(lcov) --remove coverage.info '/usr/*' --output-file coverage.info >/dev/null 2>&1; \
|
||||
$(lcov) --remove coverage.info 'lib/*' --output-file coverage.info >/dev/null 2>&1; \
|
||||
$(lcov) --remove coverage.info 'libtorch/*' --output-file coverage.info >/dev/null 2>&1; \
|
||||
$(lcov) --remove coverage.info 'tests/*' --output-file coverage.info >/dev/null 2>&1; \
|
||||
$(lcov) --remove coverage.info 'gtest/*' --output-file coverage.info >/dev/null 2>&1;
|
||||
@genhtml build_debug/tests/coverage.info --demangle-cpp --output-directory build_debug/tests/coverage --title "Discretizer mdlp Coverage Report" -s -k -f --legend
|
||||
@echo "* Coverage report is generated at build_debug/tests/coverage/index.html"
|
||||
@which python || (echo ">>> Please install python"; exit 1)
|
||||
@if [ ! -f build_debug/tests/coverage.info ]; then \
|
||||
echo ">>> No coverage.info file found!"; \
|
||||
exit 1; \
|
||||
fi
|
||||
@echo ">>> Updating coverage badge..."
|
||||
@env python update_coverage.py build_debug/tests
|
@@ -1,3 +1,9 @@
|
||||
// ****************************************************************
|
||||
// SPDX - FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez
|
||||
// SPDX - FileType: SOURCE
|
||||
// SPDX - License - Identifier: MIT
|
||||
// ****************************************************************
|
||||
|
||||
#include "Metrics.h"
|
||||
#include <set>
|
||||
#include <cmath>
|
||||
|
@@ -1,3 +1,9 @@
|
||||
// ****************************************************************
|
||||
// SPDX - FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez
|
||||
// SPDX - FileType: SOURCE
|
||||
// SPDX - License - Identifier: MIT
|
||||
// ****************************************************************
|
||||
|
||||
#ifndef CCMETRICS_H
|
||||
#define CCMETRICS_H
|
||||
|
||||
|
10
README.md
10
README.md
@@ -1,6 +1,7 @@
|
||||
[](https://github.com/rmontanana/mdlp/actions/workflows/build.yml)
|
||||
[](https://sonarcloud.io/summary/new_code?id=rmontanana_mdlp)
|
||||
[](https://sonarcloud.io/summary/new_code?id=rmontanana_mdlp)
|
||||
[](html/index.html)
|
||||
|
||||
# <img src="logo.png" alt="logo" width="50"/> mdlp
|
||||
|
||||
@@ -31,15 +32,14 @@ Other features:
|
||||
To run the sample, just execute the following commands:
|
||||
|
||||
```bash
|
||||
cmake -B build -S .
|
||||
cmake --build build
|
||||
build/sample/sample -f iris -m 2
|
||||
build/sample/sample -h
|
||||
make build
|
||||
build_release/sample/sample -f iris -m 2
|
||||
build_release/sample/sample -h
|
||||
```
|
||||
|
||||
## Test
|
||||
|
||||
To run the tests and see coverage (llvm & gcovr have to be installed), execute the following commands:
|
||||
To run the tests and see coverage (llvm with lcov and genhtml have to be installed), execute the following commands:
|
||||
|
||||
```bash
|
||||
make test
|
||||
|
@@ -1,3 +1,9 @@
|
||||
// ****************************************************************
|
||||
// SPDX - FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez
|
||||
// SPDX - FileType: SOURCE
|
||||
// SPDX - License - Identifier: MIT
|
||||
// ****************************************************************
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <iomanip>
|
||||
|
@@ -3,7 +3,7 @@ sonar.organization=rmontanana
|
||||
|
||||
# This is the name and version displayed in the SonarCloud UI.
|
||||
sonar.projectName=mdlp
|
||||
sonar.projectVersion=1.2.1
|
||||
sonar.projectVersion=2.0.0
|
||||
# sonar.test.exclusions=tests/**
|
||||
# sonar.tests=tests/
|
||||
# sonar.coverage.exclusions=tests/**,sample/**
|
||||
@@ -12,3 +12,4 @@ sonar.projectVersion=1.2.1
|
||||
|
||||
# Encoding of the source code. Default is default system encoding
|
||||
sonar.sourceEncoding=UTF-8
|
||||
sonar.cfamily.compile-commands
|
@@ -1,3 +1,9 @@
|
||||
// ****************************************************************
|
||||
// SPDX - FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez
|
||||
// SPDX - FileType: SOURCE
|
||||
// SPDX - License - Identifier: MIT
|
||||
// ****************************************************************
|
||||
|
||||
#include "ArffFiles.h"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
@@ -1,3 +1,9 @@
|
||||
// ****************************************************************
|
||||
// SPDX - FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez
|
||||
// SPDX - FileType: SOURCE
|
||||
// SPDX - License - Identifier: MIT
|
||||
// ****************************************************************
|
||||
|
||||
#ifndef ARFFFILES_H
|
||||
#define ARFFFILES_H
|
||||
|
||||
|
@@ -1,3 +1,9 @@
|
||||
// ****************************************************************
|
||||
// SPDX - FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez
|
||||
// SPDX - FileType: SOURCE
|
||||
// SPDX - License - Identifier: MIT
|
||||
// ****************************************************************
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
@@ -1,3 +1,9 @@
|
||||
// ****************************************************************
|
||||
// SPDX - FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez
|
||||
// SPDX - FileType: SOURCE
|
||||
// SPDX - License - Identifier: MIT
|
||||
// ****************************************************************
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
@@ -20,7 +26,7 @@ namespace mdlp {
|
||||
return "../../tests/datasets/";
|
||||
}
|
||||
const std::string data_path = set_data_path();
|
||||
|
||||
const labels_t iris_quantile = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 3, 3, 3, 1, 3, 1, 2, 0, 3, 1, 0, 2, 2, 2, 1, 3, 1, 2, 2, 1, 2, 2, 2, 2, 3, 3, 3, 3, 2, 1, 1, 1, 2, 2, 1, 2, 3, 2, 1, 1, 1, 2, 2, 0, 1, 1, 1, 2, 1, 1, 2, 2, 3, 2, 3, 3, 0, 3, 3, 3, 3, 3, 3, 1, 2, 3, 3, 3, 3, 2, 3, 1, 3, 2, 3, 3, 2, 2, 3, 3, 3, 3, 3, 2, 2, 3, 2, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 2, 2 };
|
||||
TEST(Discretizer, Version)
|
||||
{
|
||||
Discretizer* disc = new BinDisc(4, strategy_t::UNIFORM);
|
||||
@@ -51,9 +57,42 @@ namespace mdlp {
|
||||
auto y = labels_t();
|
||||
disc->fit(X[0], y);
|
||||
auto Xt = disc->transform(X[0]);
|
||||
labels_t expected = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 3, 3, 3, 1, 3, 1, 2, 0, 3, 1, 0, 2, 2, 2, 1, 3, 1, 2, 2, 1, 2, 2, 2, 2, 3, 3, 3, 3, 2, 1, 1, 1, 2, 2, 1, 2, 3, 2, 1, 1, 1, 2, 2, 0, 1, 1, 1, 2, 1, 1, 2, 2, 3, 2, 3, 3, 0, 3, 3, 3, 3, 3, 3, 1, 2, 3, 3, 3, 3, 2, 3, 1, 3, 2, 3, 3, 2, 2, 3, 3, 3, 3, 3, 2, 2, 3, 2, 3, 2, 3, 3, 3, 2, 3, 3, 3, 2, 3, 2, 2 };
|
||||
delete disc;
|
||||
EXPECT_EQ(expected, Xt);
|
||||
EXPECT_EQ(iris_quantile, Xt);
|
||||
}
|
||||
|
||||
TEST(Discretizer, BinIrisQuantileTorch)
|
||||
{
|
||||
ArffFiles file;
|
||||
Discretizer* disc = new BinDisc(4, strategy_t::QUANTILE);
|
||||
file.load(data_path + "iris.arff", true);
|
||||
auto X = file.getX();
|
||||
auto y = file.getY();
|
||||
auto X_torch = torch::tensor(X[0], torch::kFloat32);
|
||||
auto yt = torch::tensor(y, torch::kInt32);
|
||||
disc->fit_t(X_torch, yt);
|
||||
torch::Tensor Xt = disc->transform_t(X_torch);
|
||||
delete disc;
|
||||
EXPECT_EQ(iris_quantile.size(), Xt.size(0));
|
||||
for (int i = 0; i < iris_quantile.size(); ++i) {
|
||||
EXPECT_EQ(iris_quantile.at(i), Xt[i].item<int>());
|
||||
}
|
||||
}
|
||||
TEST(Discretizer, BinIrisQuantileTorchFit_transform)
|
||||
{
|
||||
ArffFiles file;
|
||||
Discretizer* disc = new BinDisc(4, strategy_t::QUANTILE);
|
||||
file.load(data_path + "iris.arff", true);
|
||||
auto X = file.getX();
|
||||
auto y = file.getY();
|
||||
auto X_torch = torch::tensor(X[0], torch::kFloat32);
|
||||
auto yt = torch::tensor(y, torch::kInt32);
|
||||
torch::Tensor Xt = disc->fit_transform_t(X_torch, yt);
|
||||
delete disc;
|
||||
EXPECT_EQ(iris_quantile.size(), Xt.size(0));
|
||||
for (int i = 0; i < iris_quantile.size(); ++i) {
|
||||
EXPECT_EQ(iris_quantile.at(i), Xt[i].item<int>());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Discretizer, FImdlpIris)
|
||||
|
@@ -1,3 +1,9 @@
|
||||
// ****************************************************************
|
||||
// SPDX - FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez
|
||||
// SPDX - FileType: SOURCE
|
||||
// SPDX - License - Identifier: MIT
|
||||
// ****************************************************************
|
||||
|
||||
#ifndef EXPERIMENTS_HPP
|
||||
#define EXPERIMENTS_HPP
|
||||
#include<sstream>
|
||||
|
@@ -1,3 +1,9 @@
|
||||
// ****************************************************************
|
||||
// SPDX - FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez
|
||||
// SPDX - FileType: SOURCE
|
||||
// SPDX - License - Identifier: MIT
|
||||
// ****************************************************************
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "../Metrics.h"
|
||||
#include "../CPPFImdlp.h"
|
||||
|
@@ -1,3 +1,9 @@
|
||||
// ****************************************************************
|
||||
// SPDX - FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez
|
||||
// SPDX - FileType: SOURCE
|
||||
// SPDX - License - Identifier: MIT
|
||||
// ****************************************************************
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "../Metrics.h"
|
||||
|
||||
|
@@ -1 +0,0 @@
|
||||
---
|
@@ -1,3 +0,0 @@
|
||||
Start testing: Jul 03 18:09 CEST
|
||||
----------------------------------------------------------
|
||||
End testing: Jul 03 18:09 CEST
|
15
tests/test
15
tests/test
@@ -1,15 +0,0 @@
|
||||
#!/bin/bash
|
||||
if [ -d build ] && [ "$1" != "run" ]; then
|
||||
rm -fr build
|
||||
fi
|
||||
if [ -d gcovr-report ] ; then
|
||||
rm -fr gcovr-report
|
||||
fi
|
||||
cmake -S . -B build -Wno-dev -DCMAKE_BUILD_TYPE=Debug -DCMAKE_CXX_FLAGS="--coverage" -DCMAKE_C_FLAGS="--coverage"
|
||||
cmake --build build
|
||||
cd build
|
||||
ctest --output-on-failure -j 8
|
||||
cd ..
|
||||
mkdir gcovr-report
|
||||
cd ..
|
||||
gcovr --gcov-filter "CPPFImdlp.cpp" --gcov-filter "Metrics.cpp" --gcov-filter "BinDisc.cpp" --gcov-filter "Discretizer.cpp" --txt --sonarqube=tests/gcovr-report/coverage.xml --exclude-noncode-lines
|
@@ -1,3 +1,9 @@
|
||||
# ***************************************************************
|
||||
# SPDX-FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez
|
||||
# SPDX-FileType: SOURCE
|
||||
# SPDX-License-Identifier: MIT
|
||||
# ***************************************************************
|
||||
|
||||
import json
|
||||
from sklearn.preprocessing import KBinsDiscretizer
|
||||
|
||||
|
38
update_coverage.py
Normal file
38
update_coverage.py
Normal file
@@ -0,0 +1,38 @@
|
||||
# ***************************************************************
|
||||
# SPDX-FileCopyrightText: Copyright 2024 Ricardo Montañana Gómez
|
||||
# SPDX-FileType: SOURCE
|
||||
# SPDX-License-Identifier: MIT
|
||||
# ***************************************************************
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
readme_file = "README.md"
|
||||
print("Updating coverage...")
|
||||
# Generate badge line
|
||||
output = subprocess.check_output(
|
||||
"lcov --summary " + sys.argv[1] + "/coverage.info",
|
||||
shell=True,
|
||||
)
|
||||
value = output.decode("utf-8").strip()
|
||||
percentage = 0
|
||||
for line in value.splitlines():
|
||||
if "lines" in line:
|
||||
percentage = float(line.split(":")[1].split("%")[0])
|
||||
break
|
||||
print(f"Coverage: {percentage}%")
|
||||
if percentage < 90:
|
||||
print("⛔Coverage is less than 90%. I won't update the badge.")
|
||||
sys.exit(1)
|
||||
percentage_label = str(percentage).replace(".", ",")
|
||||
coverage_line = f"[](html/index.html)"
|
||||
# Update README.md
|
||||
with open(readme_file, "r") as f:
|
||||
lines = f.readlines()
|
||||
with open(readme_file, "w") as f:
|
||||
for line in lines:
|
||||
if "img.shields.io/badge/Coverage" in line:
|
||||
f.write(coverage_line + "\n")
|
||||
else:
|
||||
f.write(line)
|
||||
print(f"✅Coverage updated with value: {percentage}")
|
Reference in New Issue
Block a user