<commit_before>/**
 * math.cpp - I got tired of writing flash cards over and over,
 * and my son was quite distracted by all the flashy math games.
 * I suspect he was paying far more attention to the graphics than
 * he was the math. I built this and it was  almost an instant hit and
 * he seems to be getting far faster with his arithmetic. I'll eventually
 * clean up the code if he sticks to it. I wrote this in about 10 minutes
 * so it's fairly basic and well....by my standards quite messy, so 
 * please excuse.
 *
 * @author: <NAME>
 * @version: Sun Oct 25 16:58:29 2015
 * 
 * Copyright 2015 <NAME>
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstdint>
#include <iomanip>
#include <array>
#include <random>
#include <unistd.h>
#include <sstream>
#include <fstream>
#include <chrono>
#include <functional>
#include <cassert>
/** if you don't have this one, grab CmdArgs from my repo **/
#include <cmd>
#include <signal.h>
#include <unistd.h>
#include <iomanip>
#include <thread>
#include <limits>
#include <float.h>

/** constants **/
const static  std::string BLUE          = "\033[1;36m";
const static  std::string NORMAL        = "\033[0m";
const static  std::string RED           = "\033[1;31m";
const static  std::string LIGHT_GREY    = "\033[0;37m";
const static  std::string PURPLE        = "\033[1;35m";

/** unfortunate, but sig handler so...**/
static std::ofstream    userlog;

struct STAT{
    double           fraction         = 0.0;
    double           min_time         = DBL_MAX;
    double           max_time         = -DBL_MAX;
    double           avg_time         = 0.0;
    std::uint32_t    count            = 0;
    double           tot_time         = 0.0;
    static std::uint32_t total;
} correct, incorrect;

std::uint32_t STAT::total = 0;

decltype( std::chrono::system_clock::now() ) start;

static void updateStats( STAT &st, const double curr_dur ) noexcept
{
    st.count++;
    st.tot_time += curr_dur;
    if( st.min_time > curr_dur ){ st.min_time = curr_dur; }
    if( st.max_time < curr_dur ){ st.max_time = curr_dur; }
    st.avg_time = st.tot_time / st.count;
    STAT::total++;
    st.fraction =(double) st.count / (double) STAT::total;
    return;
}

static void printStats( const std::string &&type, const STAT &st, std::ostream &stream )
{
    stream << PURPLE << type << " stats:" << NORMAL << "\n";
    stream << "perecentage: " <<  std::setprecision( 4 ) << (st.fraction) << "\n";
    stream << "min time: " << std::setprecision( 2 ) << st.min_time << "\n";
    stream << "avg time: " << std::setprecision( 2 ) << st.avg_time << "\n";
    stream << "max time: " << std::setprecision( 2 ) << st.max_time << "\n\n";
}


static
void sig_handler( int sig )
{
   if( userlog.is_open() )
   {
      userlog << std::flush;
      userlog.close();
   }
   std::cout << "\n\n";
   printStats( "correct", correct, std::cout );
   printStats( "incorrect", incorrect, std::cout );
   //just in case we interrupted the say cmd
   unlink( "/tmp/speach" );
   exit( EXIT_SUCCESS );<commit_msg>fixed input sanitization problem, added timing, and fixed a few bugs...need to clean up code later..<commit_after>/**
 * math.cpp - I got tired of writing flash cards over and over,
 * and my son was quite distracted by all the flashy math games.
 * I suspect he was paying far more attention to the graphics than
 * he was the math. I built this and it was  almost an instant hit and
 * he seems to be getting far faster with his arithmetic. I'll eventually
 * clean up the code if he sticks to it. I wrote this in about 10 minutes
 * so it's fairly basic and well....by my standards quite messy, so 
 * please excuse.
 *
 * @author: <NAME>
 * @version: Sun Oct 25 16:58:29 2015
 * 
 * Copyright 2015 <NAME>
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstdint>
#include <iomanip>
#include <array>
#include <random>
#include <unistd.h>
#include <sstream>
#include <fstream>
#include <chrono>
#include <functional>
#include <cassert>
/** if you don't have this one, grab CmdArgs from my repo **/
#include <cmd>
#include <signal.h>
#include <unistd.h>
#include <iomanip>
#include <thread>
#include <limits>
#include <float.h>

/** constants **/
const static  std::string BLUE          = "\033[1;36m";
const static  std::string NORMAL        = "\033[0m";
const static  std::string RED           = "\033[1;31m";
const static  std::string LIGHT_GREY    = "\033[0;37m";
const static  std::string PURPLE        = "\033[1;35m";

/** unfortunate, but sig handler so...**/
static std::ofstream    userlog;

struct STAT{
    double           fraction         = 0.0;
    double           min_time         = DBL_MAX;
    double           max_time         = -DBL_MAX;
    double           avg_time         = 0.0;
    std::uint32_t    count            = 0;
    double           tot_time         = 0.0;
    static std::uint32_t total;
} correct, incorrect;

std::uint32_t STAT::total = 0;

decltype( std::chrono::system_clock::now() ) start;

static void updateStats( STAT &st, const double curr_dur ) noexcept
{
    st.count++;
    st.tot_time += curr_dur;
    if( st.min_time > curr_dur ){ st.min_time = curr_dur; }
    if( st.max_time < curr_dur ){ st.max_time = curr_dur; }
    st.avg_time = st.tot_time / st.count;
    STAT::total++;
    st.fraction =(double) st.count / (double) STAT::total;
    return;
}

static void printStats( const std::string &&type, const STAT &st, std::ostream &stream )
{
    stream << PURPLE << type << " stats:" << NORMAL << "\n";
    stream << "perecentage: " <<  std::setprecision( 4 ) << (st.fraction) << "\n";
    stream << "min time: " << std::setprecision( 2 ) << st.min_time << "s\n";
    stream << "avg time: " << std::setprecision( 2 ) << st.avg_time << "s\n";
    stream << "max time: " << std::setprecision( 2 ) << st.max_time << "s\n\n";
}


static
void sig_handler( int sig )
{
   if( userlog.is_open() )
   {
      userlog << std::flush;
      userlog.close();
   }
   std::cout << "\n\n";
   printStats( "correct", correct, std::cout );
   printStats( "incorrect", incorrect, std::cout );
   //just in case we interrupted the say cmd
   unlink( "/tmp/speach" );
   exit( EXIT_SUCCESS );
{'fraction_non_alphanumeric': 0.13401639344262295, 'fraction_numerical': 0.018579234972677595, 'mean_word_length': 3.033608815426997, 'pattern_counts': {'":': 0, '<': 141, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6995466', 'n_tokens_mistral': 2461, 'n_tokens_neox': 2339, 'n_words': 825}