0

I am creating a program which generates a random list of songs, and I want to execute a function such that if a user wants to save a song from the random generated list, the user should click the button next to it. It seems that function only gets the last song/element in the list. How can I implement this correctly? And how would I prevent having similar or duplicate songs inside the alist?

This is the code:

 from tkinter import *
    import random
    a = [
        'Bruised and Scarred - Mayday Parade',
        'All Too Well - Taylor Swift',
        'Gravity - Sara Bareilles',
        'Perfectly Perfect - Simple Plan',
        'Welcome To The Black Parade - My Chemical Romance',
        'Everything Has Changed - Taylor Swift',
        'Champagne - Taylor Swift',
        'Piece of Your Heart - Mayday Parade',
        'Blame It On The Rain - He Is We',
        'Sad Song - We The Kings',
        'Give It All - He Is We',
        'Heavy - Linkin Park',
        'Ride - Twenty One Pilot',
        'One more light - Linkin Park',
        'Ride Home - Ben and Ben',
        'Leave - Ben and Ben',
        'Fall - Ben and Ben',
        'Maybe the night - Ben and Ben',
        'Sunrise - Ben and Ben'
    ]

    
    root = Tk()
    root.title('GUI test')
    root.iconbitmap('icon2.ico')
    
    alist=[]
    
    
    def list_generator():
        for title in random.sample(a, k=10):
            myLabel = Label(frame, text=title, font='times 12', anchor=W)
            myLabel.grid(column=2, columnspan=2, sticky=W+E)
    
        for i in range(10):
            Button(frame,
                   text=str(i + 1) + ".",
                   border=5,
                   padx=5,
                   pady=5,
                   command=lambda: alist.append(title)
                   ).grid(column=0, row=i)
    
    
    def list():
        print(alist)
    
    
    frame = LabelFrame(root, border=3, relief=GROOVE)
    frame.grid(row=1, column=0, padx=30, pady=20)
    
    
    myButton = Button(root, text="Generate Playlist?", padx=87, pady=20, command=list_generator,
                      fg="white", bg="#c0c0c0", font=("Bold", 16))
    myButton.grid(row=0, column=0, columnspan=3)
    
    exit_btn = Button(root, text='Exit Program', command=root.quit)
    exit_btn.grid(row=3, column=0)
    sl = Button(root, text='Your list', command=list)
    sl.grid(row=2, column=0)
    
    root.mainloop()
nanashi
  • 51
  • 5

1 Answers1

2
  • The second loop you had in list_generator only had access to the latest title value, so I removed the second loop and moved the code to the first one.
  • I change the loop to use enumerate so that we can get the index (like you had in the second loop).
  • The lambda function you had bound to the button didn't have the value for title stored, which causes all lambdas to use the same value, so I added it as a unique default value to the lambda function.
  • You overwrote the built-in keyword list which is no bueno, I changed it to print_list.

From @acw1668's comment

  • alist wasn't being cleared when list_generator was called.
  • myLabel.grid had it's row argument missing.

Final code:

from tkinter import *
import random
a = [
    'Bruised and Scarred - Mayday Parade',
    'All Too Well - Taylor Swift',
    'Gravity - Sara Bareilles',
    'Perfectly Perfect - Simple Plan',
    'Welcome To The Black Parade - My Chemical Romance',
    'Everything Has Changed - Taylor Swift',
    'Champagne - Taylor Swift',
    'Piece of Your Heart - Mayday Parade',
    'Blame It On The Rain - He Is We',
    'Sad Song - We The Kings',
    'Give It All - He Is We',
    'Heavy - Linkin Park',
    'Ride - Twenty One Pilot',
    'One more light - Linkin Park',
    'Ride Home - Ben and Ben',
    'Leave - Ben and Ben',
    'Fall - Ben and Ben',
    'Maybe the night - Ben and Ben',
    'Sunrise - Ben and Ben'
]


root = Tk()
root.title('GUI test')
root.iconbitmap('icon2.ico')

alist=[]


def list_generator():
    alist.clear()
    for i, title in enumerate(random.sample(a, k=10)):
        myLabel = Label(frame, text=title, font='times 12', anchor=W)
        myLabel.grid(column=2, columnspan=2, sticky=W+E, row=i)

        Button(frame,
               text=str(i + 1) + ".",
               border=5,
               padx=5,
               pady=5,
               command=lambda title=title: alist.append(title)
               ).grid(column=0, row=i)


def print_list():
    print(alist)


frame = LabelFrame(root, border=3, relief=GROOVE)
frame.grid(row=1, column=0, padx=30, pady=20)


myButton = Button(root, text="Generate Playlist?", padx=87, pady=20, command=list_generator,
                  fg="white", bg="#c0c0c0", font=("Bold", 16))
myButton.grid(row=0, column=0, columnspan=3)

exit_btn = Button(root, text='Exit Program', command=root.quit)
exit_btn.grid(row=3, column=0)
sl = Button(root, text='Your list', command=print_list)
sl.grid(row=2, column=0)

root.mainloop()
Mandera
  • 1,653
  • 3
  • 13
  • 20
  • 2
    I think that `alist` need to be clear at the beginning of `list_generator()`. Also `row=i` should be added in `myLabel.grid(...)` otherwise they will be appended to the end of displayed list if `list_generator()` is called more than once. – acw1668 Jan 08 '21 at 12:00
  • 2
    Use `alist.clear()`, then `global alist` can be removed. – acw1668 Jan 08 '21 at 13:52