Skip to content

Instantly share code, notes, and snippets.

@mbrownnycnyc
Last active February 15, 2025 16:21
Show Gist options
  • Save mbrownnycnyc/a5a133b2147da3c2c8b758c3ee35e6ab to your computer and use it in GitHub Desktop.
Save mbrownnycnyc/a5a133b2147da3c2c8b758c3ee35e6ab to your computer and use it in GitHub Desktop.
piano_training_month_1.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"authorship_tag": "ABX9TyMzDzJZYKIl8qnQtoWUuYmp",
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/mbrownnycnyc/a5a133b2147da3c2c8b758c3ee35e6ab/piano_training_month_1.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"source": [
"# 1-Month Beginner Piano Practice Plan\n",
"\n",
"## Schedule: 45 minutes every 2 days\n",
"\n",
"| **Week** | **Exercise** | **Focus Area** | **Duration** |\n",
"|-----------|-------------|---------------|-------------|\n",
"| **Week 1** | Exercise 1: C Major Scale (Hands Separate) | Finger independence, familiarity with keys | 10 min |\n",
"| | Exercise 2: C Major Scale (Hands Together) | Coordination | 10 min |\n",
"| | Exercise 3: Simple Chord Progressions (I-IV-V-I) | Left-hand chord shapes | 10 min |\n",
"| | Exercise 4: Right-Hand Melody with Left-Hand Chords | Hand independence | 15 min |\n",
"| **Week 2** | Exercise 5: G Major Scale (Hands Separate & Together) | Finger positioning | 10 min |\n",
"| | Exercise 6: Chord Progressions in G Major | Chord transitions | 10 min |\n",
"| | Exercise 7: Easy Two-Hand Etude | Reading & coordination | 10 min |\n",
"| | Exercise 8: Simple Arpeggios (C & G Major) | Smooth hand movement | 15 min |\n",
"| **Week 3** | Exercise 9: D Major Scale (Hands Separate & Together) | Expanding key familiarity | 10 min |\n",
"| | Exercise 10: Broken Chords in D Major | Dynamic control | 10 min |\n",
"| | Exercise 11: Short Left-Hand Bassline & Right-Hand Melody | Rhythm control | 10 min |\n",
"| | Exercise 12: Simple Sight-Reading Exercise | Sheet music skills | 15 min |\n",
"| **Week 4** | Exercise 13: A Major Scale & Progressions | Advanced major scale practice | 10 min |\n",
"| | Exercise 14: Two-Octave Arpeggios | Hand movement expansion | 10 min |\n",
"| | Exercise 15: Easy Beginner Song (Twinkle Twinkle, Ode to Joy) | Full piece execution | 15 min |\n",
"| | Exercise 16: Review All Exercises & Free Play | Consolidation | 10 min |\n"
],
"metadata": {
"id": "ycGgiPD4JMJ3"
}
},
{
"cell_type": "code",
"source": [
"!pip install mido"
],
"metadata": {
"id": "eg_wAi7iduuR",
"outputId": "cfddd27a-7647-4305-ed23-10747451be78",
"colab": {
"base_uri": "https://localhost:8080/"
}
},
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Collecting mido\n",
" Downloading mido-1.3.3-py3-none-any.whl.metadata (6.4 kB)\n",
"Requirement already satisfied: packaging in /usr/local/lib/python3.11/dist-packages (from mido) (24.2)\n",
"Downloading mido-1.3.3-py3-none-any.whl (54 kB)\n",
"\u001b[?25l \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/54.6 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m54.6/54.6 kB\u001b[0m \u001b[31m1.7 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
"\u001b[?25hInstalling collected packages: mido\n",
"Successfully installed mido-1.3.3\n"
]
}
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ClvSRXzrJHDh",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 17
},
"outputId": "4d8cb30c-708f-42b2-d449-20c38db8dc3a"
},
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"<IPython.core.display.Javascript object>"
],
"application/javascript": [
"\n",
" async function download(id, filename, size) {\n",
" if (!google.colab.kernel.accessAllowed) {\n",
" return;\n",
" }\n",
" const div = document.createElement('div');\n",
" const label = document.createElement('label');\n",
" label.textContent = `Downloading \"${filename}\": `;\n",
" div.appendChild(label);\n",
" const progress = document.createElement('progress');\n",
" progress.max = size;\n",
" div.appendChild(progress);\n",
" document.body.appendChild(div);\n",
"\n",
" const buffers = [];\n",
" let downloaded = 0;\n",
"\n",
" const channel = await google.colab.kernel.comms.open(id);\n",
" // Send a message to notify the kernel that we're ready.\n",
" channel.send({})\n",
"\n",
" for await (const message of channel.messages) {\n",
" // Send a message to notify the kernel that we're ready.\n",
" channel.send({})\n",
" if (message.buffers) {\n",
" for (const buffer of message.buffers) {\n",
" buffers.push(buffer);\n",
" downloaded += buffer.byteLength;\n",
" progress.value = downloaded;\n",
" }\n",
" }\n",
" }\n",
" const blob = new Blob(buffers, {type: 'application/binary'});\n",
" const a = document.createElement('a');\n",
" a.href = window.URL.createObjectURL(blob);\n",
" a.download = filename;\n",
" div.appendChild(a);\n",
" a.click();\n",
" div.remove();\n",
" }\n",
" "
]
},
"metadata": {}
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"<IPython.core.display.Javascript object>"
],
"application/javascript": [
"download(\"download_49afceed-786b-4b17-914a-a14dfc644485\", \"piano_exercises.zip\", 4254)"
]
},
"metadata": {}
}
],
"source": [
"from google.colab import files\n",
"import mido\n",
"from mido import Message, MidiFile, MidiTrack\n",
"import zipfile\n",
"import os\n",
"\n",
"# Directory to store generated MIDI files\n",
"midi_dir = \"piano_exercises_midi\"\n",
"os.makedirs(midi_dir, exist_ok=True)\n",
"\n",
"# Define exercises with corresponding note sequences\n",
"def create_scale_midi(filename, scale_notes, hands_together=False):\n",
" midi = MidiFile()\n",
" track = MidiTrack()\n",
" midi.tracks.append(track)\n",
"\n",
" for _ in range(4): # Extend to 4-8 bars\n",
" if hands_together:\n",
" for note in scale_notes:\n",
" track.append(Message('note_on', note=note, velocity=64, time=200))\n",
" track.append(Message('note_on', note=note-12, velocity=64, time=200))\n",
" track.append(Message('note_off', note=note, velocity=64, time=200))\n",
" track.append(Message('note_off', note=note-12, velocity=64, time=200))\n",
" else:\n",
" for note in scale_notes:\n",
" track.append(Message('note_on', note=note, velocity=64, time=200))\n",
" track.append(Message('note_off', note=note, velocity=64, time=200))\n",
"\n",
" midi.save(os.path.join(midi_dir, filename))\n",
"\n",
"def create_chord_midi(filename, chords):\n",
" midi = MidiFile()\n",
" track = MidiTrack()\n",
" midi.tracks.append(track)\n",
"\n",
" for _ in range(4): # Extend to 4-8 bars\n",
" for chord in chords:\n",
" for note in chord:\n",
" track.append(Message('note_on', note=note, velocity=64, time=0))\n",
" track.append(Message('note_off', note=chord[0], velocity=64, time=400))\n",
"\n",
" midi.save(os.path.join(midi_dir, filename))\n",
"\n",
"def create_two_hand_exercise(filename, right_hand_notes, left_hand_notes):\n",
" midi = MidiFile()\n",
" track = MidiTrack()\n",
" midi.tracks.append(track)\n",
"\n",
" for _ in range(4): # Extend to 4-8 bars\n",
" for rh_note, lh_note in zip(right_hand_notes, left_hand_notes):\n",
" track.append(Message('note_on', note=rh_note, velocity=64, time=200))\n",
" track.append(Message('note_on', note=lh_note, velocity=64, time=200))\n",
" track.append(Message('note_off', note=rh_note, velocity=64, time=200))\n",
" track.append(Message('note_off', note=lh_note, velocity=64, time=200))\n",
"\n",
" midi.save(os.path.join(midi_dir, filename))\n",
"\n",
"# Define exercises\n",
"scales = {\n",
" \"Exercise_1_C_Major_Scale_Hands_Separate.mid\": [60, 62, 64, 65, 67, 69, 71, 72],\n",
" \"Exercise_2_C_Major_Scale_Hands_Together.mid\": [60, 62, 64, 65, 67, 69, 71, 72],\n",
" \"Exercise_5_G_Major_Scale_Hands_Separate_Together.mid\": [67, 69, 71, 72, 74, 76, 78, 79],\n",
" \"Exercise_9_D_Major_Scale_Hands_Separate_Together.mid\": [62, 64, 66, 67, 69, 71, 73, 74],\n",
" \"Exercise_13_A_Major_Scale_Progressions.mid\": [69, 71, 73, 74, 76, 78, 80, 81]\n",
"}\n",
"\n",
"for filename, notes in scales.items():\n",
" create_scale_midi(filename, notes, hands_together=\"Together\" in filename)\n",
"\n",
"chords = {\n",
" \"Exercise_3_Simple_Chord_Progressions.mid\": [[60, 64, 67], [65, 69, 72], [67, 71, 74], [60, 64, 67]],\n",
" \"Exercise_6_Chord_Progressions_in_G_Major.mid\": [[67, 71, 74], [72, 76, 79], [74, 78, 81], [67, 71, 74]],\n",
" \"Exercise_10_Broken_Chords_in_D_Major.mid\": [[62, 66, 69], [67, 71, 74], [69, 73, 76], [62, 66, 69]]\n",
"}\n",
"\n",
"for filename, chord_seq in chords.items():\n",
" create_chord_midi(filename, chord_seq)\n",
"\n",
"two_hand_exercises = {\n",
" \"Exercise_4_Right_Hand_Melody_Left_Hand_Chords.mid\": ([72, 74, 76, 77], [48, 50, 52, 53]),\n",
" \"Exercise_7_Easy_Two_Hand_Etude.mid\": ([64, 66, 68, 69], [40, 42, 44, 45]),\n",
" \"Exercise_8_Simple_Arpeggios_C_G_Major.mid\": ([60, 64, 67, 72], [48, 52, 55, 60]),\n",
" \"Exercise_11_Short_Left_Hand_Bassline_Right_Hand_Melody.mid\": ([72, 74, 76, 77], [36, 38, 40, 41]),\n",
" \"Exercise_12_Simple_Sight_Reading_Exercise.mid\": ([62, 64, 66, 67], [50, 52, 54, 55]),\n",
" \"Exercise_14_Two_Octave_Arpeggios.mid\": ([60, 64, 67, 72, 76], [48, 52, 55, 60, 64]),\n",
" \"Exercise_15_Easy_Beginner_Song.mid\": ([60, 62, 64, 65, 67, 69, 71, 72], [48, 50, 52, 53, 55, 57, 59, 60])\n",
"}\n",
"\n",
"for filename, (rh_notes, lh_notes) in two_hand_exercises.items():\n",
" create_two_hand_exercise(filename, rh_notes, lh_notes)\n",
"\n",
"# Create a zip file with all MIDI exercises\n",
"zip_filename = \"piano_exercises_midi.zip\"\n",
"with zipfile.ZipFile(zip_filename, 'w') as zipf:\n",
" for file in os.listdir(midi_dir):\n",
" zipf.write(os.path.join(midi_dir, file), file)\n",
"\n",
"print(f\"MIDI exercises saved to {zip_filename}\")\n",
"\n",
"files.download(zip_filename)\n"
]
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment