From cf061e3783a77d781701ff96370b7d2923e22bfc Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Wed, 25 Mar 2026 13:01:56 -0400 Subject: [PATCH] Rewrite all 13 songs with per-part effects (reverb, delay, lowpass) Every song now uses the full effects chain. Added 3 new songs: Kingston After Dark (dub), Minimal Techno, Gospel Shuffle. Each demonstrates different effect combinations. Co-Authored-By: Claude Opus 4.6 (1M context) --- examples/song.py | 341 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 257 insertions(+), 84 deletions(-) diff --git a/examples/song.py b/examples/song.py index c7019c4..4a41206 100644 --- a/examples/song.py +++ b/examples/song.py @@ -1,11 +1,13 @@ -"""Play songs with PyTheory — drums, chords, bass, and synth leads. +"""Play songs with PyTheory — drums, chords, bass, leads, and effects. Requires PortAudio: brew install portaudio (macOS) -Each song uses the multi-part Score API: -- Drum pattern presets (48 genres) -- Named parts with independent synth voices and envelopes -- Chord pads, walking bass lines, and melody leads +Each song showcases the full Score API: +- 58 drum pattern presets with genre-matched fills +- 10 synth waveforms (sine, saw, triangle, square, pulse, FM, noise, supersaw, PWM slow/fast) +- 8 ADSR envelope presets +- Per-part effects: reverb, delay, lowpass filter with resonance +- Named parts with independent voices mixed together Usage: python examples/song.py @@ -13,10 +15,8 @@ Usage: import sounddevice as sd -from pytheory import ( - Chord, Key, Pattern, Duration, Score, -) -from pytheory.play import play_score, render_score, SAMPLE_RATE +from pytheory import Chord, Key, Pattern, Duration, Score +from pytheory.play import render_score, SAMPLE_RATE def play_song(score, label=""): @@ -37,19 +37,24 @@ def play_song(score, label=""): # ── Songs ────────────────────────────────────────────────────────────────── def bossa_nova_girl(): - """Bossa nova in A minor — full arrangement.""" + """Bossa nova in A minor — Ipanema vibes with reverb-washed chords.""" print(" Bossa Nova in A minor") - print(" Drums: bossa nova | Lead: triangle | Bass: triangle") + print(" bossa nova drums | FM rhodes + reverb | triangle lead + delay") + print(" sine bass + LP 600Hz") score = Score("4/4", bpm=140) - score.add_pattern(Pattern.preset("bossa nova"), repeats=4) + score.drums("bossa nova", repeats=4) - chords = score.part("chords", synth="sine", envelope="pad", volume=0.35) - lead = score.part("lead", synth="triangle", envelope="pluck", volume=0.5) - bass = score.part("bass", synth="triangle", envelope="pluck", volume=0.45) + rhodes = score.part("rhodes", synth="fm", envelope="piano", + volume=0.3, reverb=0.4, reverb_decay=1.8) + lead = score.part("lead", synth="triangle", envelope="pluck", + volume=0.45, delay=0.25, delay_time=0.32, + delay_feedback=0.35, reverb=0.2) + bass = score.part("bass", synth="sine", envelope="pluck", + volume=0.45, lowpass=600) for sym in ["Am", "Am", "Dm", "Dm", "E7", "E7", "Am", "Am"]: - chords.add(Chord.from_symbol(sym), Duration.WHOLE) + rhodes.add(Chord.from_symbol(sym), Duration.WHOLE) for n, d in [ ("E5",.67),("D5",.33),("C5",.67),("B4",.33),("A4",1),("C5",.67),("E5",.33), @@ -63,29 +68,32 @@ def bossa_nova_girl(): ]: lead.rest(d) if n is None else lead.add(n, d) - for n in ["A2","B2","C3","E3","D3","E3","F3","E3", - "E3","D3","C3","B2","A2","G2","A2","B2", - "A2","B2","C3","E3","D3","E3","F3","E3", - "E3","D3","C3","B2","A2","E2","A2","A2"]: + for n in ["A2","E2","A2","C3","D2","A2","D2","F2", + "E2","B2","E2","G#2","A2","E2","A2","C3", + "A2","E2","A2","C3","D2","A2","D2","F2", + "E2","B2","E2","G#2","A2","E2","A2","A2"]: bass.add(n, Duration.QUARTER) play_song(score) def bebop_in_bb(): - """Bebop in Bb — rhythm changes with horn lead and walking bass.""" + """Bebop in Bb — horn lead over rhythm changes with walking bass.""" print(" Bebop in Bb major") - print(" Drums: bebop | Lead: sawtooth | Bass: triangle") + print(" bebop drums + fill | saw lead + LP 4kHz | FM rhodes + reverb") score = Score("4/4", bpm=160) - score.add_pattern(Pattern.preset("bebop"), repeats=8) + score.drums("bebop", repeats=8, fill="jazz", fill_every=8) - chords = score.part("chords", synth="sine", envelope="piano", volume=0.3) - lead = score.part("lead", synth="saw", envelope="pluck", volume=0.45) - bass = score.part("bass", synth="triangle", envelope="pluck", volume=0.4) + rhodes = score.part("rhodes", synth="fm", envelope="piano", + volume=0.25, reverb=0.35, reverb_decay=1.2) + lead = score.part("lead", synth="saw", envelope="pluck", + volume=0.4, lowpass=4000, lowpass_q=1.1) + bass = score.part("bass", synth="triangle", envelope="pluck", + volume=0.4, lowpass=900) for sym in ["Bb", "Gm", "Cm", "F7"] * 2: - chords.add(Chord.from_symbol(sym), Duration.WHOLE) + rhodes.add(Chord.from_symbol(sym), Duration.WHOLE) for n, d in [ ("Bb4",.67),("D5",.33),("F5",.67),("D5",.33), @@ -117,19 +125,23 @@ def bebop_in_bb(): def salsa_descarga(): - """Salsa descarga in D minor — clave-driven jam.""" + """Salsa descarga in D minor — clave-driven with timbale lead.""" print(" Salsa Descarga in D minor") - print(" Drums: salsa | Lead: sawtooth | Bass: sine") + print(" salsa drums + fill | saw lead + delay | pulse bass + LP 500Hz") score = Score("4/4", bpm=180) - score.add_pattern(Pattern.preset("salsa"), repeats=4) + score.drums("salsa", repeats=8, fill="salsa", fill_every=4) - chords = score.part("chords", synth="sine", envelope="pad", volume=0.3) - lead = score.part("lead", synth="saw", envelope="pluck", volume=0.4) - bass = score.part("bass", synth="sine", envelope="pluck", volume=0.45) + pads = score.part("pads", synth="pwm_slow", envelope="pad", + volume=0.2, reverb=0.3, lowpass=2000) + lead = score.part("lead", synth="saw", envelope="pluck", + volume=0.4, delay=0.2, delay_time=0.167, + delay_feedback=0.3) + bass = score.part("bass", synth="pulse", envelope="pluck", + volume=0.45, lowpass=500, lowpass_q=1.3) for sym in ["Em7b5", "A7", "Dm7", "Bbmaj7"] * 2: - chords.add(Chord.from_symbol(sym), Duration.WHOLE) + pads.add(Chord.from_symbol(sym), Duration.WHOLE) for n, d in [ ("E5",.67),("G5",.33),("Bb5",.67),("A5",.33), @@ -148,7 +160,6 @@ def salsa_descarga(): ]: lead.rest(d) if n is None else lead.add(n, d) - # Salsa bass: tumbao pattern for n in ["E2","E3","A2","A3","D2","D3","Bb2","Bb3"] * 4: bass.add(n, Duration.QUARTER) @@ -156,21 +167,24 @@ def salsa_descarga(): def afrobeat_groove(): - """Afrobeat in E minor — Fela Kuti-inspired.""" + """Afrobeat in E minor — Fela-inspired hypnotic groove.""" print(" Afrobeat in E minor") - print(" Drums: afrobeat | Lead: sawtooth | Bass: sine") + print(" afrobeat drums + fill | saw lead + LP 3kHz | supersaw pads + reverb") score = Score("4/4", bpm=115) - score.add_pattern(Pattern.preset("afrobeat"), repeats=8) + score.drums("afrobeat", repeats=8, fill="afrobeat", fill_every=8) - chords = score.part("chords", synth="sine", envelope="pad", volume=0.3) - lead = score.part("lead", synth="saw", envelope="pluck", volume=0.4) - bass = score.part("bass", synth="sine", envelope="pluck", volume=0.45) + pads = score.part("pads", synth="supersaw", envelope="pad", + volume=0.2, reverb=0.4, reverb_decay=2.0, + lowpass=3000) + lead = score.part("lead", synth="saw", envelope="pluck", + volume=0.4, lowpass=3000, lowpass_q=1.0) + bass = score.part("bass", synth="sine", envelope="pluck", + volume=0.5, lowpass=500) for sym in ["Em", "Am", "D", "C"] * 2: - chords.add(Chord.from_symbol(sym), Duration.WHOLE) + pads.add(Chord.from_symbol(sym), Duration.WHOLE) - # Hypnotic pentatonic riff riff = [("E5",.5),("G5",.5),("A5",.5),("G5",.5), ("E5",.5),("D5",.5),("E5",1), ("E5",.5),("G5",.5),("A5",.5),("B5",.5), @@ -190,16 +204,22 @@ def afrobeat_groove(): def reggae_one_drop(): - """Reggae one-drop in G major.""" + """Reggae one-drop in G major — roots vibes with dub effects.""" print(" Reggae One-Drop in G major") - print(" Drums: reggae | Lead: triangle | Bass: sine") + print(" reggae drums + fill | triangle lead + delay + reverb") + print(" square chords + reverb | sine bass + LP 400Hz") score = Score("4/4", bpm=80) - score.add_pattern(Pattern.preset("reggae"), repeats=8) + score.drums("reggae", repeats=8, fill="reggae", fill_every=8) - chords = score.part("chords", synth="sine", envelope="organ", volume=0.35) - lead = score.part("lead", synth="triangle", envelope="pad", volume=0.45) - bass = score.part("bass", synth="sine", envelope="pluck", volume=0.5) + chords = score.part("chords", synth="square", envelope="staccato", + volume=0.2, reverb=0.5, reverb_decay=2.0, + lowpass=2000) + lead = score.part("lead", synth="triangle", envelope="strings", + volume=0.4, delay=0.35, delay_time=0.5625, + delay_feedback=0.45, reverb=0.3) + bass = score.part("bass", synth="sine", envelope="pluck", + volume=0.55, lowpass=400, lowpass_q=1.3) for sym in ["G", "C", "D", "C"] * 2: chords.add(Chord.from_symbol(sym), Duration.WHOLE) @@ -226,16 +246,20 @@ def reggae_one_drop(): def funk_workout(): - """Funk in E minor — syncopated groove.""" + """Funk in E minor — syncopated 16ths with filtered everything.""" print(" Funk Workout in E minor") - print(" Drums: funk | Lead: sawtooth | Bass: sine") + print(" funk drums + fill | saw lead + LP 3.5kHz Q=1.5 | pulse bass") score = Score("4/4", bpm=100) - score.add_pattern(Pattern.preset("funk"), repeats=8) + score.drums("funk", repeats=8, fill="funk", fill_every=4) - chords = score.part("chords", synth="sine", envelope="staccato", volume=0.3) - lead = score.part("lead", synth="saw", envelope="pluck", volume=0.4) - bass = score.part("bass", synth="sine", envelope="pluck", volume=0.5) + chords = score.part("chords", synth="square", envelope="staccato", + volume=0.25, lowpass=2500, reverb=0.15) + lead = score.part("lead", synth="saw", envelope="pluck", + volume=0.4, lowpass=3500, lowpass_q=1.5, + delay=0.15, delay_time=0.15, delay_feedback=0.25) + bass = score.part("bass", synth="pulse", envelope="pluck", + volume=0.5, lowpass=600, lowpass_q=1.2) for sym in ["Em", "Am", "D", "B7"] * 2: chords.add(Chord.from_symbol(sym), Duration.WHOLE) @@ -266,16 +290,21 @@ def funk_workout(): def blues_shuffle(): - """12/8 blues in A — slow shuffle.""" + """12/8 blues in A — slow shuffle with wailing lead.""" print(" 12/8 Blues Shuffle in A") - print(" Drums: 12/8 blues | Lead: sawtooth | Bass: sine") + print(" 12/8 blues drums | saw lead + reverb + delay | sine bass + LP 500Hz") score = Score("12/8", bpm=70) - score.add_pattern(Pattern.preset("12/8 blues"), repeats=6) + score.drums("12/8 blues", repeats=6) - chords = score.part("chords", synth="sine", envelope="piano", volume=0.35) - lead = score.part("lead", synth="saw", envelope="pluck", volume=0.45) - bass = score.part("bass", synth="sine", envelope="pluck", volume=0.45) + chords = score.part("chords", synth="fm", envelope="piano", + volume=0.3, reverb=0.3, reverb_decay=1.5) + lead = score.part("lead", synth="saw", envelope="pluck", + volume=0.45, reverb=0.3, reverb_decay=1.2, + delay=0.2, delay_time=0.43, delay_feedback=0.3, + lowpass=3500) + bass = score.part("bass", synth="sine", envelope="pluck", + volume=0.5, lowpass=500) for sym in ["A", "A", "D", "D", "E7", "A"]: chords.add(Chord.from_symbol(sym), Duration.DOTTED_HALF) @@ -306,19 +335,24 @@ def blues_shuffle(): def samba_de_janeiro(): - """Samba in G major — carnival energy.""" + """Samba in G major — carnival energy with shimmering pads.""" print(" Samba in G major") - print(" Drums: samba | Lead: triangle | Bass: sine") + print(" samba drums + fill | triangle lead + delay | supersaw pads + reverb") score = Score("4/4", bpm=170) - score.add_pattern(Pattern.preset("samba"), repeats=8) + score.drums("samba", repeats=8, fill="samba", fill_every=8) - chords = score.part("chords", synth="sine", envelope="pad", volume=0.3) - lead = score.part("lead", synth="triangle", envelope="pluck", volume=0.45) - bass = score.part("bass", synth="sine", envelope="pluck", volume=0.45) + pads = score.part("pads", synth="supersaw", envelope="pad", + volume=0.2, reverb=0.45, reverb_decay=2.0, + lowpass=4000) + lead = score.part("lead", synth="triangle", envelope="pluck", + volume=0.45, delay=0.2, delay_time=0.176, + delay_feedback=0.3) + bass = score.part("bass", synth="sine", envelope="pluck", + volume=0.45, lowpass=700) for sym in ["G", "Em", "Am", "D7"] * 2: - chords.add(Chord.from_symbol(sym), Duration.WHOLE) + pads.add(Chord.from_symbol(sym), Duration.WHOLE) for n, d in [ ("B5",.33),("A5",.33),("G5",.34),("F#5",.5),("E5",.5), @@ -341,21 +375,25 @@ def samba_de_janeiro(): def jazz_waltz(): - """Jazz waltz in F major — 3/4 time.""" + """Jazz waltz in F major — 3/4 with brushes and space.""" print(" Jazz Waltz in F major") - print(" Drums: waltz | Lead: triangle | Bass: sine") + print(" waltz drums | triangle lead + reverb + delay | FM rhodes") score = Score("3/4", bpm=150) - score.add_pattern(Pattern.preset("waltz"), repeats=16) + score.drums("waltz", repeats=16) - chords = score.part("chords", synth="sine", envelope="pad", volume=0.35) - lead = score.part("lead", synth="triangle", envelope="pluck", volume=0.45) - bass = score.part("bass", synth="sine", envelope="pluck", volume=0.4) + rhodes = score.part("rhodes", synth="fm", envelope="piano", + volume=0.3, reverb=0.4, reverb_decay=2.0) + lead = score.part("lead", synth="triangle", envelope="strings", + volume=0.4, reverb=0.3, reverb_decay=1.5, + delay=0.2, delay_time=0.4, delay_feedback=0.3) + bass = score.part("bass", synth="sine", envelope="pluck", + volume=0.4, lowpass=600) for _ in range(2): for sym in ["Fmaj7", "Gm", "C7", "Fmaj7"]: for _ in range(4): - chords.add(Chord.from_symbol(sym), Duration.DOTTED_HALF) + rhodes.add(Chord.from_symbol(sym), Duration.DOTTED_HALF) for n, d in [ ("A5",1.5),("G5",.5),("F5",1),("E5",1),("C5",1),("F5",1), @@ -378,19 +416,25 @@ def jazz_waltz(): def house_anthem(): """House in C minor — four-on-the-floor with acid lead.""" print(" House Anthem in C minor") - print(" Drums: house | Lead: sawtooth (acid) | Bass: sine") + print(" house drums + fill | saw acid lead + LP 2kHz Q=2 + delay") + print(" supersaw pads + reverb | sine bass") score = Score("4/4", bpm=124) - score.add_pattern(Pattern.preset("house"), repeats=8) + score.drums("house", repeats=8, fill="house", fill_every=8) - chords = score.part("chords", synth="sine", envelope="pad", volume=0.35) - lead = score.part("lead", synth="saw", envelope="staccato", volume=0.4) - bass = score.part("bass", synth="sine", envelope="pluck", volume=0.5) + pads = score.part("pads", synth="supersaw", envelope="pad", + volume=0.25, reverb=0.5, reverb_decay=2.5, + lowpass=5000) + lead = score.part("lead", synth="saw", envelope="staccato", + volume=0.35, lowpass=2000, lowpass_q=2.0, + delay=0.2, delay_time=0.242, + delay_feedback=0.35) + bass = score.part("bass", synth="sine", envelope="pluck", + volume=0.55, lowpass=300) for sym in ["Cm", "Ab", "Bb", "Cm"] * 2: - chords.add(Chord.from_symbol(sym), Duration.WHOLE) + pads.add(Chord.from_symbol(sym), Duration.WHOLE) - # Acid arpeggios for n, d in [ ("C5",.25),("Eb5",.25),("G5",.25),("C5",.25), ("Eb5",.25),("G5",.25),("C5",.25),("Eb5",.25), @@ -418,7 +462,6 @@ def house_anthem(): ]: lead.rest(d) if n is None else lead.add(n, d) - # Pumping bass for n in ["C2","C2","C2","C2","Ab1","Ab1","Ab1","Ab1", "Bb1","Bb1","Bb1","Bb1","C2","C2","C2","C2"] * 2: bass.add(n, Duration.QUARTER) @@ -426,6 +469,133 @@ def house_anthem(): play_song(score) +def dub_kingston(): + """Dub in A minor — deep, sparse, drenched in effects.""" + print(" Kingston After Dark") + print(" dub drums | triangle melodica + delay + reverb") + print(" square skank + reverb + LP 1.5kHz | sine bass + LP 400Hz") + print(" PWM siren + reverb + LP 1.2kHz") + + score = Score("4/4", bpm=72) + score.drums("dub", repeats=8) + + chords = score.part("chords", synth="square", envelope="staccato", + volume=0.2, reverb=0.6, reverb_decay=2.5, + lowpass=1500, lowpass_q=0.9) + lead = score.part("lead", synth="triangle", envelope="strings", + volume=0.4, delay=0.45, delay_time=0.625, + delay_feedback=0.5, reverb=0.35, reverb_decay=2.0) + bass = score.part("bass", synth="sine", envelope="pluck", + volume=0.6, lowpass=400, lowpass_q=1.5) + siren = score.part("siren", synth="pwm_slow", envelope="pad", + volume=0.15, reverb=0.7, reverb_decay=3.0, + lowpass=1200) + + for sym in ["Am", "Am", "Dm", "Dm", "Am", "Am", "Em", "Am"]: + chords.add(Chord.from_symbol(sym), Duration.WHOLE) + + for n, d in [ + ("A4", 2), (None, 2), ("C5", 1.5), (None, 2.5), + ("D5", 1), ("C5", 1), ("A4", 2), (None, 4), + ("E5", 2), (None, 2), ("D5", 1.5), ("C5", 1.5), (None, 3), + ("A4", 1), ("G4", 1), ("A4", 3), (None, 3), + ]: + lead.rest(d) if n is None else lead.add(n, d) + + for n in ["A1","A1","A1","A1","D1","D1","D1","D1", + "A1","A1","A1","A1","E1","E1","A1","A1"]: + bass.add(n, Duration.HALF) + + for n, d in [ + (None, 8), ("A5", 4), (None, 4), + (None, 4), ("E5", 3), (None, 5), + ("D5", 4), (None, 4), + ]: + siren.rest(d) if n is None else siren.add(n, d) + + play_song(score) + + +def techno_minimal(): + """Minimal techno in F minor — hypnotic and relentless.""" + print(" Minimal Techno in F minor") + print(" techno drums | PWM fast lead + LP 1.5kHz Q=3 + delay") + print(" supersaw pad + reverb | sine sub bass") + + score = Score("4/4", bpm=130) + score.drums("techno", repeats=8, fill="house", fill_every=8) + + pad = score.part("pad", synth="supersaw", envelope="pad", + volume=0.2, reverb=0.5, reverb_decay=3.0, + lowpass=3000) + lead = score.part("lead", synth="pwm_fast", envelope="staccato", + volume=0.35, lowpass=1500, lowpass_q=3.0, + delay=0.3, delay_time=0.231, + delay_feedback=0.4) + bass = score.part("bass", synth="sine", envelope="pluck", + volume=0.55, lowpass=250) + + for sym in ["Fm", "Db", "Eb", "Fm"] * 2: + pad.add(Chord.from_symbol(sym), Duration.WHOLE) + + # Minimal arpeggiated sequence — hypnotic repetition + seq = [("F4",.25),("Ab4",.25),("C5",.25),("F4",.25), + ("Ab4",.25),("C5",.25),("Eb5",.25),("C5",.25)] + for n, d in seq * 8: + lead.add(n, d) + + for n in ["F1","F1","F1","F1","Db1","Db1","Db1","Db1", + "Eb1","Eb1","Eb1","Eb1","F1","F1","F1","F1"] * 2: + bass.add(n, Duration.QUARTER) + + play_song(score) + + +def gospel_shuffle(): + """Gospel in C major — joyful shuffle with FM organ.""" + print(" Gospel Shuffle in C major") + print(" gospel drums + fill | FM organ + reverb | triangle lead + delay") + + score = Score("4/4", bpm=108) + score.drums("gospel", repeats=8, fill="buildup", fill_every=8) + + organ = score.part("organ", synth="fm", envelope="organ", + volume=0.3, reverb=0.45, reverb_decay=2.0) + lead = score.part("lead", synth="triangle", envelope="pluck", + volume=0.4, delay=0.2, delay_time=0.278, + delay_feedback=0.3, reverb=0.2) + bass = score.part("bass", synth="sine", envelope="pluck", + volume=0.45, lowpass=500) + + for sym in ["C", "Am", "F", "G"] * 2: + organ.add(Chord.from_symbol(sym), Duration.WHOLE) + + for n, d in [ + ("E5",.67),("G5",.33),("C6",1),("B5",.67),("A5",.33), + ("G5",1),(None,1), + ("A5",.67),("C6",.33),("E5",1),("D5",.67),("C5",.33), + ("A4",1),(None,1), + ("F5",.67),("A5",.33),("C6",1),("B5",.67),("A5",.33), + ("G5",.67),("E5",.33),("C5",1),(None,1), + ("D5",.67),("E5",.33),("G5",.67),("B5",.33), + ("C6",2),(None,2), + # Second half: more intense + ("C6",.67),("B5",.33),("A5",.67),("G5",.33), + ("E5",1),("C5",.67),("E5",.33), + ("A5",1),("G5",.67),("E5",.33),("C5",1),(None,1), + ("F5",1),("A5",.67),("C6",.33),("E6",2), + ("D6",.67),("C6",.33),("B5",.67),("G5",.33), + ("C6",3),(None,1), + ]: + lead.rest(d) if n is None else lead.add(n, d) + + for n in ["C2","E2","G2","C3","A1","C2","E2","A2", + "F2","A2","C3","F2","G2","B2","D3","G2"] * 2: + bass.add(n, Duration.QUARTER) + + play_song(score) + + # ── Main ─────────────────────────────────────────────────────────────────── SONGS = { @@ -439,6 +609,9 @@ SONGS = { "8": ("Samba in G major", samba_de_janeiro), "9": ("Jazz Waltz in F major", jazz_waltz), "10": ("House Anthem in C minor", house_anthem), + "11": ("Kingston After Dark (Dub)", dub_kingston), + "12": ("Minimal Techno in F minor", techno_minimal), + "13": ("Gospel Shuffle in C major", gospel_shuffle), } if __name__ == "__main__": @@ -452,7 +625,7 @@ if __name__ == "__main__": print(f" {key:>2}. {name}") print() - choice = input(" Pick a song (1-10, or 'all'): ").strip() + choice = input(" Pick a song (1-13, or 'all'): ").strip() print() if choice == "all":