lawkit_python/subcommands/
validate.rs

1use crate::colors;
2use crate::common_options;
3use crate::subcommands::integration_common::{
4    get_dataset_name, get_numbers_from_input, output_integration_result,
5};
6use clap::{ArgMatches, Command};
7use lawkit_core::common::output::{create_output_writer, OutputConfig};
8use lawkit_core::error::Result;
9use lawkit_core::laws::integration::{analyze_all_laws, cross_validate_laws};
10use std::io::Write;
11
12pub fn command() -> Command {
13    common_options::add_integration_options(common_options::add_common_options(
14        common_options::add_input_arg(
15            Command::new("validate").about("Data validation and consistency check"),
16        ),
17    ))
18}
19
20pub fn run(matches: &ArgMatches) -> Result<()> {
21    if matches.get_flag("cross-validation") {
22        return run_cross_validation_mode(matches);
23    }
24
25    if matches.get_flag("consistency-check") {
26        return run_consistency_check_mode(matches);
27    }
28
29    // Default: consistency check
30    run_consistency_check_mode(matches)
31}
32
33fn run_cross_validation_mode(matches: &ArgMatches) -> Result<()> {
34    let numbers = get_numbers_from_input(matches)?;
35    let dataset_name = get_dataset_name(matches);
36    let confidence_level = *matches.get_one::<f64>("confidence-level").unwrap();
37
38    let cv_result = cross_validate_laws(&numbers, &dataset_name, confidence_level)?;
39
40    let mut writer = create_output_writer(matches)?;
41    let output_config = OutputConfig::from_matches(matches);
42
43    output_cross_validation_result(&mut writer, &cv_result, &output_config)?;
44
45    Ok(())
46}
47
48fn run_consistency_check_mode(matches: &ArgMatches) -> Result<()> {
49    let numbers = get_numbers_from_input(matches)?;
50    let dataset_name = get_dataset_name(matches);
51    let threshold = *matches.get_one::<f64>("threshold").unwrap();
52
53    let result = analyze_all_laws(&numbers, &dataset_name)?;
54
55    let mut writer = create_output_writer(matches)?;
56    let output_config = OutputConfig::from_matches(matches);
57
58    output_consistency_check_result(&mut writer, &result, threshold, &output_config)?;
59
60    std::process::exit(result.risk_level.exit_code());
61}
62
63fn output_cross_validation_result(
64    writer: &mut Box<dyn Write>,
65    result: &lawkit_core::laws::integration::CrossValidationResult,
66    _config: &OutputConfig,
67) -> Result<()> {
68    writeln!(writer, "Cross-Validation Analysis")?;
69    writeln!(writer)?;
70    writeln!(writer, "Dataset: {}", result.dataset_name)?;
71    writeln!(writer, "Confidence Level: {:.3}", result.confidence_level)?;
72    writeln!(writer, "Overall Stability: {:.3}", result.overall_stability)?;
73    writeln!(
74        writer,
75        "Stability Assessment: {:?}",
76        result.stability_assessment
77    )?;
78    writeln!(writer)?;
79
80    writeln!(writer, "Validation Folds:")?;
81    for fold in &result.validation_folds {
82        writeln!(writer, "  Consistency Score: {:.3}", fold.consistency_score)?;
83    }
84
85    Ok(())
86}
87
88fn output_consistency_check_result(
89    writer: &mut Box<dyn Write>,
90    result: &lawkit_core::laws::integration::IntegrationResult,
91    threshold: f64,
92    config: &OutputConfig,
93) -> Result<()> {
94    writeln!(writer, "Data Validation and Consistency Check")?;
95    writeln!(writer)?;
96    writeln!(writer, "Dataset: {}", result.dataset_name)?;
97    writeln!(writer, "Threshold: {threshold:.3}")?;
98    writeln!(writer, "Consistency Score: {:.3}", result.consistency_score)?;
99    writeln!(writer)?;
100
101    if result.consistency_score < threshold {
102        writeln!(
103            writer,
104            "{}",
105            colors::level_warning("Consistency below threshold")
106        )?;
107        writeln!(
108            writer,
109            "Recommendation: Review data quality and collection methods"
110        )?;
111    } else {
112        writeln!(
113            writer,
114            "{}",
115            colors::level_pass("Data consistency meets requirements")
116        )?;
117    }
118
119    writeln!(writer)?;
120    output_integration_result(writer, result, config)?;
121
122    Ok(())
123}