Search code examples
pythonraspberry-piraspbiangpio

random.choice returns the same file on button press


For my first project, I'm working on building a soundboard using a Raspberry Pi as the base. I would like to have several buttons, each of which plays a random sound file from different lists on each press.

I'm using several built in libraries, specifically pygame, glob, random, and Button to make things easier. Glob is being used to generate a list of possible files to play, and random is being used to pick one of them.

pygame.init()

h = glob.glob('/file path/*.wav')

btn_0 = Button(2)

btn_0.when_pressed = pygame.mixer.Sound(random.choice(h)).play

From my admittedly basic understanding, this should call up a list of all files ending in .wav from the specific file path, and on the button press, randomly pick one to play through pygame.

What it is doing, though, is randomly picking a file from the list, and then playing that on a press. When I restart and run the code again, a different file is picked, so I know the list is being seen correctly.

Am I just missing something very obvious? Should I be using a different method? I'm just lost here.


Solution

  • This line

    btn_0.when_pressed = pygame.mixer.Sound(random.choice(h)).play
    

    assigns one file to .when_pressed; this will NOT change throughout the whole execution of the program.

    Have you tried to assign a function or lambda to .when_pressed instead, so that this function gets executed on every button press? Maybe like this:

    h = glob.glob('/file path/*.wav')
    btn_0.when_pressed = lambda: pygame.mixer.Sound(random.choice(h)).play()
    

    Does that work? I cannot test it right now on my machine.


    Of course, you could also instantiate glob.glob('/file path/*.wav') from scratch on each button press; that would allow you to add/remove files without closing the Python program because it will do a new filesystem search on each button press.

    btn_0.when_pressed = lambda: pygame.mixer.Sound(
        random.choice(glob.glob('/file path/*.wav'))).play()