Python help: Globally defined item keeps yielding not defined error
Question:
PSA: Python learner (30 days and counting).
I am trying to create a python script which creates a playlist of videos which are randomly selected from given folder/sub-folder. When I run it, I get a "’selected_files’ is not defined" error in line 40 (in the "# create a VLC playlist in select folder" section) of my script, when I have clearly defined it globally…I think. Welcome the assist.
import os
import random
def find_files(folder, extensions):
files = []
for root, dirs, filenames in os.walk(folder):
for filename in filenames:
if any(filename.endswith(ext) for ext in extensions):
files.append(os.path.join(root, filename))
return files
def main():
global selected_files
# specify the folders to search and the file extensions to search for
folders = [r"pathtoshow1", r"pathtoshow2", r"pathtoshow3", r"pathtoshow4"]
extensions = (".mp4", ".avi", ".mkv")
selected_files = []
for folder in folders:
files = find_files(folder, extensions)
if files:
selected_files.append(random.choice(files))
else:
print(f"No files found in {folder}.")
if not selected_files:
print("No files found.")
return
# create a VLC playlist in select folder
playlist_folder = r"pathwhereplaylistissaved"
if not os.path.exists(playlist_folder):
os.makedirs(playlist_folder)
playlist_file = os.path.join(playlist_folder, "PMTV.xspf")
with open(playlist_file, "w", encoding='utf8') as f:
f.write('<?xml version="1.0" encoding="UTF-8"?>n')
f.write('<playlist xmlns="http://xspf.org/ns/0/" xmlns_vlc="http://www.videolan.org/vlc/playlist/ns/0/" version="1">n')
f.write('t<title></title>n')
f.write('t<trackList>n')
for file in selected_files:
f.write('tt<track>n')
f.write(f'ttt<location>{file}</location>n')
f.write('ttt<title></title>n')
f.write('ttt<duration></duration>n')
f.write('ttt<extension application="http://www.videolan.org/vlc/playlist/0">n')
f.write('tttt<vlc:id></vlc:id>n')
f.write('ttt</extension>n')
f.write('tt</track>n')
f.write('t</trackList>n')
f.write('</playlist>n')
print(f"{len(selected_files)} files added to {playlist_file}")
if __name__ == "__main__":
main()
Answers:
As your script is loaded, the code at
# create a VLC playlist in select folder
… gets executed, BEFORE reaching main
And it barfs at you as selected_files
has not been defined yet.
… so by inserting
selected_files=[]
you define it, and stop the barfing.
Now, beyond this you have a likely logic fault in this, as selected_files
contains nothing as you enter the loop at for file in selected_files:
– on line 40 – due to the fact that it has not been filled with items yet.
Thank you, Hannu and Chepner. Don’t have commenting privileges, yet (newbie on SuperUser) so I’ll post what I did as an answer.
I made two changes, which solved the riddle:
#1) Define folders in main ()
def main():
folders = folders = [pathtoshow1, pathtoshow2...yada...yada...yada...]
#2) Localize selected_files
selected_files = []
for folder in folders:
files = find_files(folder, extensions)
if files:
selected_files.append(random.choice(files))
PSA: Python learner (30 days and counting).
I am trying to create a python script which creates a playlist of videos which are randomly selected from given folder/sub-folder. When I run it, I get a "’selected_files’ is not defined" error in line 40 (in the "# create a VLC playlist in select folder" section) of my script, when I have clearly defined it globally…I think. Welcome the assist.
import os
import random
def find_files(folder, extensions):
files = []
for root, dirs, filenames in os.walk(folder):
for filename in filenames:
if any(filename.endswith(ext) for ext in extensions):
files.append(os.path.join(root, filename))
return files
def main():
global selected_files
# specify the folders to search and the file extensions to search for
folders = [r"pathtoshow1", r"pathtoshow2", r"pathtoshow3", r"pathtoshow4"]
extensions = (".mp4", ".avi", ".mkv")
selected_files = []
for folder in folders:
files = find_files(folder, extensions)
if files:
selected_files.append(random.choice(files))
else:
print(f"No files found in {folder}.")
if not selected_files:
print("No files found.")
return
# create a VLC playlist in select folder
playlist_folder = r"pathwhereplaylistissaved"
if not os.path.exists(playlist_folder):
os.makedirs(playlist_folder)
playlist_file = os.path.join(playlist_folder, "PMTV.xspf")
with open(playlist_file, "w", encoding='utf8') as f:
f.write('<?xml version="1.0" encoding="UTF-8"?>n')
f.write('<playlist xmlns="http://xspf.org/ns/0/" xmlns_vlc="http://www.videolan.org/vlc/playlist/ns/0/" version="1">n')
f.write('t<title></title>n')
f.write('t<trackList>n')
for file in selected_files:
f.write('tt<track>n')
f.write(f'ttt<location>{file}</location>n')
f.write('ttt<title></title>n')
f.write('ttt<duration></duration>n')
f.write('ttt<extension application="http://www.videolan.org/vlc/playlist/0">n')
f.write('tttt<vlc:id></vlc:id>n')
f.write('ttt</extension>n')
f.write('tt</track>n')
f.write('t</trackList>n')
f.write('</playlist>n')
print(f"{len(selected_files)} files added to {playlist_file}")
if __name__ == "__main__":
main()
As your script is loaded, the code at
# create a VLC playlist in select folder
… gets executed, BEFORE reaching main
And it barfs at you as selected_files
has not been defined yet.
… so by inserting
selected_files=[]
you define it, and stop the barfing.
Now, beyond this you have a likely logic fault in this, as selected_files
contains nothing as you enter the loop at for file in selected_files:
– on line 40 – due to the fact that it has not been filled with items yet.
Thank you, Hannu and Chepner. Don’t have commenting privileges, yet (newbie on SuperUser) so I’ll post what I did as an answer.
I made two changes, which solved the riddle:
#1) Define folders in main ()
def main():
folders = folders = [pathtoshow1, pathtoshow2...yada...yada...yada...]
#2) Localize selected_files
selected_files = []
for folder in folders:
files = find_files(folder, extensions)
if files:
selected_files.append(random.choice(files))