Files
intono/shared/src/commonMain/kotlin/com/notemusicali/history/PracticeSession.kt
T
lucianoandClaude Fable 5 c00c27e606 docs: README con screenshot e badge; rifiniture pentagramma
- README riscritto: badge CI/release, screenshot reali (emulatore),
  funzionalità, architettura, istruzioni di build
- StaffLayout.lineBreaks: capienza riga in peso (√durata) con chiusura
  preferita alla stanghetta (5 test nuovi); usato da StaffFullView
- StaffFullView: travature globali clippate per riga (origine di beat
  corretta anche su righe spezzate a metà battuta)
- Cifre del tempo centrate su asse comune (metri tipo 12/8)
- PracticeSession persiste beats/beatType: il replay dalla cronologia
  conserva il metro (2 test, retrocompatibile con le sessioni salvate)
- fix: escaping Android-style (\' e \") reso letteralmente da compose
  resources in tutte le stringhe localizzate

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 11:38:02 +02:00

38 lines
1.0 KiB
Kotlin

package com.notemusicali.history
import kotlinx.serialization.Serializable
@Serializable
data class NoteResult(
val noteName: String,
val midiNumber: Int,
val centsDeviation: Float,
val reactionTimeMs: Long,
val firstAttemptSuccess: Boolean,
)
@Serializable
data class PracticeSession(
val id: String,
val sequenceName: String,
val instrumentName: String,
val dateMillis: Long,
val totalTimeMs: Long,
val noteResults: List<NoteResult>,
val noteMidiNumbers: List<Int>,
val completed: Boolean = true,
val beats: Int = 4,
val beatType: Int = 4,
) {
val averageCents: Float
get() = if (noteResults.isEmpty()) 0f
else noteResults.map { kotlin.math.abs(it.centsDeviation) }.average().toFloat()
val perfectNotes: Int
get() = noteResults.count { kotlin.math.abs(it.centsDeviation) <= 10f }
val firstAttemptRate: Float
get() = if (noteResults.isEmpty()) 0f
else noteResults.count { it.firstAttemptSuccess }.toFloat() / noteResults.size
}