//Autor: Mateusz Krakowski

#include <iostream>
#include <ranges>
#include <string>
#include <vector>
void rangesZipShowcase() {
    /*
    Sources:
    - https://en.cppreference.com/w/cpp/ranges/zip_view
    - https://medium.com/@simontoth/daily-bit-e-of-c-std-views-zip-c4429066b069
    Lets say that we want to evaluate the performence of a ML model. We have two vectors, one
    with the true class and one with the predicted class from some binary classification model.
    We can use zip to iterate over both vectors at the same time and compare the values so we can
    calculate the confusion matrix.
    */
    std::cout << "Ranges Zip Showcase" << std::endl;

    std::vector<int> grand_truth{1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0};
    std::vector<int> prediction{1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0};

    int tp = 0, fn = 0, fp = 0, tn = 0;
    // We can iterate over grand_truth and prediction at the same time and compare the values to
    // create the confusion matrix
    for (const auto& [gt, pred] : std::views::zip(grand_truth, prediction)) {
        if(gt == 1){
            if(pred == 1){
                ++tp;
            }else{
                ++fn;
            }
        } else {
            if(pred == 1){
                ++fp;
            }else{
                ++tn;
            }
        }
    }
    /* 
    // We can also use this algorithm, it is easier to read but it is probably less efficient because it
    // has more logic checks
    for (const auto& [gt, pred] : std::views::zip(grand_truth, prediction)) {
        if (gt == 1 && pred == 1) {
            ++tp;
        } else if (gt == 0 && pred == 1) {
            ++fp;
        } else if (gt == 1 && pred == 0) {
            ++fn;
        } else{
            ++tn;
        }
    }
    */

    std::cout << "Confusion Matrix" << std::endl;
    std::cout << "TP: " << tp << " FN: " << fn << std::endl;
    std::cout << "FP: " << fp << " TN: " << tn << std::endl;
}
int main() {
    rangesZipShowcase();
    std::cout << std::endl;

    return 0;
}
