///|
pub(all) struct AnalysisSnapshot {
label : String
score : Int
errors : Int
warnings : Int
notes : Int
profile : String
} derive(Debug, Eq, ToJson)
///|
pub(all) struct AnalysisHistory {
snapshots : Array[AnalysisSnapshot]
best_score : Int
latest_score : Int
improvement : Int
} derive(Debug, Eq, ToJson)
///|
pub fn snapshot(
label : String,
validation : PairValidation,
) -> AnalysisSnapshot {
{
label,
score: validation.quality_score(),
errors: validation.summary.errors,
warnings: validation.summary.warnings,
notes: validation.counterpoint.note_count,
profile: validation.profile,
}
}
///|
pub fn empty_history() -> AnalysisHistory {
{ snapshots: [], best_score: 0, latest_score: 0, improvement: 0 }
}
///|
pub fn add_snapshot(
history : AnalysisHistory,
value : AnalysisSnapshot,
) -> AnalysisHistory {
let snapshots = history.snapshots.copy()
snapshots.push(value)
let mut best = history.best_score
if value.score > best {
best = value.score
}
let previous = history.latest_score
{
snapshots,
best_score: best,
latest_score: value.score,
improvement: value.score - previous,
}
}
///|
pub fn history_from_validations(
labels : Array[String],
validations : Array[PairValidation],
) -> AnalysisHistory {
let result = empty_history()
let count = if labels.length() < validations.length() {
labels.length()
} else {
validations.length()
}
let mut history = result
for i in 0.. Bool {
history.improvement > 0
}
///|
pub fn history_average(history : AnalysisHistory) -> Int {
if history.snapshots.length() == 0 {
return 0
}
let mut total = 0
for value in history.snapshots {
total += value.score
}
total / history.snapshots.length()
}
///|
pub fn history_errors(history : AnalysisHistory) -> Int {
let mut total = 0
for value in history.snapshots {
total += value.errors
}
total
}
///|
pub fn history_warnings(history : AnalysisHistory) -> Int {
let mut total = 0
for value in history.snapshots {
total += value.warnings
}
total
}
///|
pub fn history_latest(history : AnalysisHistory) -> AnalysisSnapshot? {
if history.snapshots.length() == 0 {
None
} else {
Some(history.snapshots[history.snapshots.length() - 1])
}
}
///|
pub fn history_best(history : AnalysisHistory) -> AnalysisSnapshot? {
if history.snapshots.length() == 0 {
return None
}
let mut best = history.snapshots[0]
for value in history.snapshots {
if value.score > best.score {
best = value
}
}
Some(best)
}
///|
pub fn history_markdown(history : AnalysisHistory) -> String {
let lines : Array[String] = [
"## Analysis history",
"",
"- Runs: \{history.snapshots.length()}",
"- Average score: \{history_average(history)}",
"- Best score: \{history.best_score}",
"- Improvement: \{history.improvement}",
"",
]
for value in history.snapshots {
lines.push(
"- \{value.label}: \{value.score}/100, errors=\{value.errors}, warnings=\{value.warnings}",
)
}
lines.join("\n")
}
///|
pub fn history_fingerprint(history : AnalysisHistory) -> String {
let values : Array[String] = []
for snapshot in history.snapshots {
values.push(
"\{snapshot.label}:\{snapshot.score}:\{snapshot.errors}:\{snapshot.warnings}",
)
}
values.join("|")
}
///|
pub fn history_scores(history : AnalysisHistory) -> Array[Int] {
let result : Array[Int] = []
for snapshot in history.snapshots {
result.push(snapshot.score)
}
result
}
///|
pub fn history_delta(
history : AnalysisHistory,
first : Int,
second : Int,
) -> Int? {
if first < 0 ||
second < 0 ||
first >= history.snapshots.length() ||
second >= history.snapshots.length() {
None
} else {
Some(history.snapshots[second].score - history.snapshots[first].score)
}
}