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