From d0d94c30fac5cde93e52f3b27f95c2045ba84b43 Mon Sep 17 00:00:00 2001 From: luciano Date: Wed, 22 Jul 2026 20:50:20 +0200 Subject: [PATCH] feat: Studio op.84 n.10 di Dancla tra gli esercizi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 177 note (Sol3-Re6, Sol maggiore, 4/4) estratte dal MusicXML con il parser dell'app; livello 4, con test di presenza e sanità. Co-Authored-By: Claude Fable 5 --- .claude/scheduled_tasks.lock | 1 - .../exercises/ExerciseRepository.kt | 191 ++++++++++++++++++ .../exercises/ExerciseRepositoryTest.kt | 26 +++ 3 files changed, 217 insertions(+), 1 deletion(-) delete mode 100644 .claude/scheduled_tasks.lock create mode 100644 shared/src/commonTest/kotlin/com/notemusicali/exercises/ExerciseRepositoryTest.kt diff --git a/.claude/scheduled_tasks.lock b/.claude/scheduled_tasks.lock deleted file mode 100644 index b44ee4e..0000000 --- a/.claude/scheduled_tasks.lock +++ /dev/null @@ -1 +0,0 @@ -{"sessionId":"db412f81-3e15-4e3f-9010-4a026dced776","pid":79175,"procStart":"Tue Jul 21 20:39:41 2026","acquiredAt":1784666538953} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/com/notemusicali/exercises/ExerciseRepository.kt b/shared/src/commonMain/kotlin/com/notemusicali/exercises/ExerciseRepository.kt index ee09d3b..0a85c1c 100644 --- a/shared/src/commonMain/kotlin/com/notemusicali/exercises/ExerciseRepository.kt +++ b/shared/src/commonMain/kotlin/com/notemusicali/exercises/ExerciseRepository.kt @@ -1,6 +1,7 @@ package com.notemusicali.exercises import com.notemusicali.music.MusicalNote +import com.notemusicali.music.NoteDuration import com.notemusicali.music.NoteSequence data class Exercise( @@ -125,5 +126,195 @@ object ExerciseRepository { ), ), ), + Exercise( + id = 6, + title = "Studio op.84 n.10 — Dancla", + description = "Studio per violino in Sol maggiore", + level = 4, + sequence = NoteSequence( + name = "Studio op.84 n.10 — Dancla", + notes = listOf( + MusicalNote.fromMidi(55, NoteDuration.EIGHTH), + MusicalNote.fromMidi(59, NoteDuration.EIGHTH), + MusicalNote.fromMidi(62, NoteDuration.EIGHTH), + MusicalNote.fromMidi(67, NoteDuration.EIGHTH), + MusicalNote.fromMidi(71, NoteDuration.HALF), + MusicalNote.fromMidi(59, NoteDuration.EIGHTH), + MusicalNote.fromMidi(62, NoteDuration.EIGHTH), + MusicalNote.fromMidi(67, NoteDuration.EIGHTH), + MusicalNote.fromMidi(71, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.HALF), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(72, NoteDuration.EIGHTH), + MusicalNote.fromMidi(69, NoteDuration.EIGHTH), + MusicalNote.fromMidi(76, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.HALF), + MusicalNote.fromMidi(67, NoteDuration.EIGHTH), + MusicalNote.fromMidi(71, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(79, NoteDuration.EIGHTH), + MusicalNote.fromMidi(83, NoteDuration.HALF), + MusicalNote.fromMidi(55, NoteDuration.EIGHTH), + MusicalNote.fromMidi(59, NoteDuration.EIGHTH), + MusicalNote.fromMidi(62, NoteDuration.EIGHTH), + MusicalNote.fromMidi(67, NoteDuration.EIGHTH), + MusicalNote.fromMidi(71, NoteDuration.HALF), + MusicalNote.fromMidi(59, NoteDuration.EIGHTH), + MusicalNote.fromMidi(62, NoteDuration.EIGHTH), + MusicalNote.fromMidi(67, NoteDuration.EIGHTH), + MusicalNote.fromMidi(71, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.HALF), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(72, NoteDuration.EIGHTH), + MusicalNote.fromMidi(69, NoteDuration.EIGHTH), + MusicalNote.fromMidi(76, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.HALF), + MusicalNote.fromMidi(67, NoteDuration.EIGHTH), + MusicalNote.fromMidi(71, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(79, NoteDuration.EIGHTH), + MusicalNote.fromMidi(69, NoteDuration.HALF), + MusicalNote.fromMidi(66, NoteDuration.EIGHTH), + MusicalNote.fromMidi(69, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(78, NoteDuration.EIGHTH), + MusicalNote.fromMidi(81, NoteDuration.HALF), + MusicalNote.fromMidi(81, NoteDuration.EIGHTH), + MusicalNote.fromMidi(79, NoteDuration.EIGHTH), + MusicalNote.fromMidi(76, NoteDuration.EIGHTH), + MusicalNote.fromMidi(73, NoteDuration.EIGHTH), + MusicalNote.fromMidi(69, NoteDuration.HALF), + MusicalNote.fromMidi(64, NoteDuration.EIGHTH), + MusicalNote.fromMidi(69, NoteDuration.EIGHTH), + MusicalNote.fromMidi(73, NoteDuration.EIGHTH), + MusicalNote.fromMidi(76, NoteDuration.EIGHTH), + MusicalNote.fromMidi(81, NoteDuration.HALF), + MusicalNote.fromMidi(81, NoteDuration.EIGHTH), + MusicalNote.fromMidi(78, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(69, NoteDuration.EIGHTH), + MusicalNote.fromMidi(66, NoteDuration.HALF), + MusicalNote.fromMidi(67, NoteDuration.EIGHTH), + MusicalNote.fromMidi(71, NoteDuration.EIGHTH), + MusicalNote.fromMidi(76, NoteDuration.EIGHTH), + MusicalNote.fromMidi(79, NoteDuration.EIGHTH), + MusicalNote.fromMidi(83, NoteDuration.HALF), + MusicalNote.fromMidi(66, NoteDuration.EIGHTH), + MusicalNote.fromMidi(69, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(78, NoteDuration.EIGHTH), + MusicalNote.fromMidi(81, NoteDuration.HALF), + MusicalNote.fromMidi(81, NoteDuration.EIGHTH), + MusicalNote.fromMidi(79, NoteDuration.EIGHTH), + MusicalNote.fromMidi(76, NoteDuration.EIGHTH), + MusicalNote.fromMidi(73, NoteDuration.EIGHTH), + MusicalNote.fromMidi(69, NoteDuration.HALF), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(69, NoteDuration.EIGHTH), + MusicalNote.fromMidi(66, NoteDuration.EIGHTH), + MusicalNote.fromMidi(69, NoteDuration.EIGHTH), + MusicalNote.fromMidi(62, NoteDuration.HALF), + MusicalNote.fromMidi(62, NoteDuration.EIGHTH), + MusicalNote.fromMidi(66, NoteDuration.EIGHTH), + MusicalNote.fromMidi(69, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(62, NoteDuration.HALF), + MusicalNote.fromMidi(62, NoteDuration.EIGHTH), + MusicalNote.fromMidi(67, NoteDuration.EIGHTH), + MusicalNote.fromMidi(70, NoteDuration.EIGHTH, preferFlat = true), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(62, NoteDuration.HALF), + MusicalNote.fromMidi(67, NoteDuration.EIGHTH), + MusicalNote.fromMidi(70, NoteDuration.EIGHTH, preferFlat = true), + MusicalNote.fromMidi(70, NoteDuration.EIGHTH, preferFlat = true), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(79, NoteDuration.EIGHTH), + MusicalNote.fromMidi(79, NoteDuration.EIGHTH), + MusicalNote.fromMidi(78, NoteDuration.EIGHTH), + MusicalNote.fromMidi(78, NoteDuration.EIGHTH), + MusicalNote.fromMidi(81, NoteDuration.EIGHTH), + MusicalNote.fromMidi(81, NoteDuration.EIGHTH), + MusicalNote.fromMidi(86, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.HALF), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(69, NoteDuration.EIGHTH), + MusicalNote.fromMidi(66, NoteDuration.EIGHTH), + MusicalNote.fromMidi(69, NoteDuration.EIGHTH), + MusicalNote.fromMidi(62, NoteDuration.HALF), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(70, NoteDuration.EIGHTH, preferFlat = true), + MusicalNote.fromMidi(67, NoteDuration.EIGHTH), + MusicalNote.fromMidi(70, NoteDuration.EIGHTH, preferFlat = true), + MusicalNote.fromMidi(62, NoteDuration.HALF), + MusicalNote.fromMidi(55, NoteDuration.EIGHTH), + MusicalNote.fromMidi(58, NoteDuration.EIGHTH, preferFlat = true), + MusicalNote.fromMidi(58, NoteDuration.EIGHTH, preferFlat = true), + MusicalNote.fromMidi(62, NoteDuration.EIGHTH), + MusicalNote.fromMidi(62, NoteDuration.EIGHTH), + MusicalNote.fromMidi(67, NoteDuration.EIGHTH), + MusicalNote.fromMidi(67, NoteDuration.EIGHTH), + MusicalNote.fromMidi(66, NoteDuration.EIGHTH), + MusicalNote.fromMidi(66, NoteDuration.EIGHTH), + MusicalNote.fromMidi(62, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(62, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(62, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(62, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(71, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(79, NoteDuration.EIGHTH), + MusicalNote.fromMidi(83, NoteDuration.EIGHTH), + MusicalNote.fromMidi(86, NoteDuration.HALF), + MusicalNote.fromMidi(86, NoteDuration.EIGHTH), + MusicalNote.fromMidi(84, NoteDuration.EIGHTH), + MusicalNote.fromMidi(81, NoteDuration.EIGHTH), + MusicalNote.fromMidi(78, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.HALF), + MusicalNote.fromMidi(69, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(78, NoteDuration.EIGHTH), + MusicalNote.fromMidi(81, NoteDuration.EIGHTH), + MusicalNote.fromMidi(86, NoteDuration.HALF), + MusicalNote.fromMidi(83, NoteDuration.EIGHTH), + MusicalNote.fromMidi(79, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.EIGHTH), + MusicalNote.fromMidi(71, NoteDuration.EIGHTH), + MusicalNote.fromMidi(67, NoteDuration.HALF), + MusicalNote.fromMidi(60, NoteDuration.EIGHTH), + MusicalNote.fromMidi(64, NoteDuration.EIGHTH), + MusicalNote.fromMidi(69, NoteDuration.EIGHTH), + MusicalNote.fromMidi(72, NoteDuration.EIGHTH), + MusicalNote.fromMidi(76, NoteDuration.HALF), + MusicalNote.fromMidi(59, NoteDuration.EIGHTH), + MusicalNote.fromMidi(62, NoteDuration.EIGHTH), + MusicalNote.fromMidi(67, NoteDuration.EIGHTH), + MusicalNote.fromMidi(71, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.HALF), + MusicalNote.fromMidi(57, NoteDuration.EIGHTH), + MusicalNote.fromMidi(62, NoteDuration.EIGHTH), + MusicalNote.fromMidi(66, NoteDuration.EIGHTH), + MusicalNote.fromMidi(69, NoteDuration.EIGHTH), + MusicalNote.fromMidi(74, NoteDuration.HALF), + MusicalNote.fromMidi(67, NoteDuration.EIGHTH), + MusicalNote.fromMidi(62, NoteDuration.EIGHTH), + MusicalNote.fromMidi(59, NoteDuration.EIGHTH), + MusicalNote.fromMidi(62, NoteDuration.EIGHTH), + MusicalNote.fromMidi(55, NoteDuration.QUARTER), + ), + beats = 4, + beatType = 4, + ), + ), ) } diff --git a/shared/src/commonTest/kotlin/com/notemusicali/exercises/ExerciseRepositoryTest.kt b/shared/src/commonTest/kotlin/com/notemusicali/exercises/ExerciseRepositoryTest.kt new file mode 100644 index 0000000..b71ec05 --- /dev/null +++ b/shared/src/commonTest/kotlin/com/notemusicali/exercises/ExerciseRepositoryTest.kt @@ -0,0 +1,26 @@ +package com.notemusicali.exercises + +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNotNull +import kotlin.test.assertTrue + +class ExerciseRepositoryTest { + + @Test + fun `dancla study op84 n10 is available as exercise`() { + val exercise = ExerciseRepository.all.firstOrNull { it.title.contains("Dancla") } + assertNotNull(exercise, "lo studio di Dancla deve essere tra gli esercizi") + assertTrue(exercise.sequence.notes.size > 100, "atteso lo studio completo, trovate ${exercise.sequence.notes.size} note") + assertEquals(4, exercise.sequence.beats) + assertEquals(4, exercise.sequence.beatType) + // Studio per violino: tutte le note dentro l'estensione del violino (G3..E7) + assertTrue(exercise.sequence.notes.all { it.midiNumber in 55..100 }) + } + + @Test + fun `exercise ids are unique`() { + val ids = ExerciseRepository.all.map { it.id } + assertEquals(ids.size, ids.toSet().size) + } +}