Placeholder to set different frequencies of sin wave output to each key press
Question: I want to use the placeholder %f to set different frequencies for my sin wave
sound output, for each key. However, I get the error message 'SyntaxError:
can't assign to literal'. I checked to see if my syntax was incorrect, though
I found a similar example - can anyone see what the problem is and why my code
won't run? traceback: File "test.py", line 50 (Python, Pygame).

    
    
       import pygame
        from pygame.locals import *
    
    import math
    import numpy
    
    bits = 16
    #the number of channels specified here is NOT 
    #the channels talked about here http://www.pygame.org/docs/ref/mixer.html#pygame.mixer.get_num_channels
    
    pygame.mixer.pre_init(44100, -bits, 2)
    pygame.init()
    
    size = (1200, 720)
    _display_surf = pygame.display.set_mode(size, pygame.HWSURFACE | pygame.DOUBLEBUF)
    
    
    duration = 1.0          # in seconds
    
    #this sounds totally different coming out of a laptop versus coming out of headphones
    
    sample_rate = 44100
    
    n_samples = int(round(duration*sample_rate))
    
    #setup our numpy array to handle 16 bit ints, which is what we set our mixer to expect with "bits" up above
    buf = numpy.zeros((n_samples, 2), dtype = numpy.int16)
    max_sample = 2**(bits - 1) - 1
    
        #default frequency - not used
    frequency = 440
    
    for s in range(n_samples):
            t = float(s)/sample_rate    # time in seconds
    
    #This will keep the sound playing forever, the quit event handling allows the pygame window to close without crashing
    _running = True
    while _running:
    
        for event in pygame.event.get():
            if event.type == KEYDOWN:
                if event.key == K_a:
                        frequency = 261.6
                        buf[s][0] = int(round(max_sample*math.sin(2*math.pi*frequency*t)))        # left
                        buf[s][1] = int(round(max_sample*0.5*math.sin(2*math.pi*frequency*t)))    # right
    
                        sound = pygame.sndarray.make_sound(buf)
                        sound.play()
    
                    elif event.key == K_s:
                        frequency = 293.7
                        buf[s][0] = int(round(max_sample*math.sin(2*math.pi*frequency*t)))        # left
                        buf[s][1] = int(round(max_sample*0.5*math.sin(2*math.pi*frequency*t)))    # right
                        sound = pygame.sndarray.make_sound(buf)
                        sound.play()
    
            if event.type == KEYUP:
                sound.stop()
    
            if event.type == pygame.QUIT or event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    _running = False
                    break
    
    pygame.quit()
    


Answer: String `"%f"` can be variable name. You can't assign `'%f' = 261.6` \- this is
your error `"can't assign to literal"`.

Name it for example `freq` and use it in place of `"%f"`

    
    
    freq = 261.6
    
    sin(2*math.pi* freq *t)
    

* * *

BTW: Placeholder `%f` can be use only in string formating (or string parsing).

* * *

**EDIT:**

    
    
    import pygame
    from pygame.locals import *
    
    import math
    import numpy
    
    
    def generate_sound(freq):
    
        #setup our numpy array to handle 16 bit ints, which is what we set our mixer to expect with "bits" up above
        buf = numpy.zeros((n_samples, 2), dtype = numpy.int16)
        max_sample = 2**(bits - 1) - 1
    
        for s in range(n_samples):
            t = float(s)/sample_rate    # time in seconds
            buf[s][0] = int(round(max_sample*math.sin(2*math.pi*freq*t)))        # left
            buf[s][1] = int(round(max_sample*0.5*math.sin(2*math.pi*freq*t)))    # right
    
        return pygame.sndarray.make_sound(buf)
    
    
    bits = 16
    #the number of channels specified here is NOT 
    #the channels talked about here http://www.pygame.org/docs/ref/mixer.html#pygame.mixer.get_num_channels
    
    pygame.mixer.pre_init(44100, -bits, 2)
    pygame.init()
    
    size = (1200, 720)
    screen = pygame.display.set_mode(size, pygame.HWSURFACE | pygame.DOUBLEBUF)
    
    
    duration = 1.0          # in seconds
    
    #this sounds totally different coming out of a laptop versus coming out of headphones
    
    sample_rate = 44100
    
    n_samples = int(round(duration*sample_rate))
    
    
    #default frequency - not used
    sound = None
    sound_261_6 = generate_sound(261.6)
    sound_293_7 = generate_sound(293.7)
    
    #This will keep the sound playing forever, the quit event handling allows the pygame window to close without crashing
    _running = True
    while _running:
    
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                _running = False
    
            if event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    _running = False
                elif event.key == K_a:
                    if not sound:
                        sound = sound_261_6
                        sound.play()
    
                elif event.key == K_s:
                    if not sound:
                        sound = sound_261_6
                        sound.play()
    
            if event.type == KEYUP:
                if sound:
                    sound.stop()
                    sound = None
    
    pygame.quit()
    

