For my first Python project, I decided to create a script that would automatically collate MP3 files into a music countdown. I wanted to 'learn by doing', so I dived straight in and used the Python docs and Stack Overflow as my primary learning resource.
The idea is as follows:
- Python script resides in base directory.
- In the base directory there are sub-folders for each voter containing their MP3 files. Each sub-folder is named with the voter's name.
- Each voter submits their MP3 files in the following format:
(vote_count). Artist - Song Title.mp3.
So, for example,
10. Foo Fighters - Walk.mp3
. The '10.' at the start of the song specifies how many votes are being allocated to this song.
- Once sub-folders have been populated and named correctly in the format, the script can be executed.
- Upon execution, the script will scan all sub-folders for files ending in .mp3
- It will then strip the necessary information such as vote count and song title and add the songs to a list.
- Any duplicates (i.e multivotes) and the script will add the votes together to get the total vote count for that song.
- Final results will then output to a CSV file in order of song with highest votes first.
So far so good. I have completed everything in that list, however there are still some more features i would like to add, like renaming all of the MP3 files so they are in the correct order for importing to a playlist. I.e add numbers to the start of each filename.
import os, csv, operator, itertools
from collections import Counter, defaultdict
print("*****Welcome to the Music vote Collator*****" + '\n')
print("STAGE 1. Processing Votes..." + '\n')
folder_list = os.getcwd() #Get list of files in all directories
#global variables and lists
song_list = []
voter_list = defaultdict(list)
tally = Counter()
total_songs = 0
for subdir, dirs, files in os.walk(folder_list):
for file in files:
if file.endswith(".mp3"):
base_dir = os.path.join(subdir) #defines base directory...maybe not needed anymore
file_name = file.split('.')[1] #removes the .mp3 extension and numbers at the start of the file to clean up song name
vote_count = file.split('.')[0] #retrieves vote count for each song
head, tail = os.path.split(subdir) #retrieves the name of the voter from the folder name
song = file_name.lower() #create variable for song and convert all letters to lowercase to prevent song name match issues
if (song not in song_list and
song not in tally):
song_list.append(song) #appends song to song_list to keep track of processed songs
if (song in song_list and
song not in tally):
tally[song] += 0 #for duplicate entries, adds the song to the tally Counter
total_songs += 1 #adds plus one to the total_songs variable for stat reporting
if (song in song_list and
song in tally):
tally[song] += int(vote_count) #for duplicate entries, adds the votes to the song in tally Counter
voter_list[song].append(tail)
voter_list[song].append(vote_count)
tally_list = sorted(list(Counter((tally)).items()),key=operator.itemgetter(1), reverse=True) #converts tally counter to a list and sorts songs based on highest votes
with open('resultsout.csv', 'w') as resultsout:
writer = csv.writer(resultsout)
writer.writerows(tally_list)
print("STAGE 2. Listing Top 3 Songs:" + '\n')
with open('resultsout.csv', 'r') as results:
reader = csv.reader(results)
for row in itertools.islice(reader, 0, 1):
print("The number one song for this year's count is:" + str(row[0]) + ", with a total of " + str(row[1]) + " votes!")
for row in itertools.islice(reader, 0, 1):
print("The number two song for this year's count is:" + str(row[0]) + ", with a total of " + str(row[1]) + " votes!")
for row in itertools.islice(reader, 0, 1):
print("The number three song for this year's count is:" + str(row[0]) + ", with a total of " + str(row[1]) + " votes!")
print('\n' + "There are a total number of " + str(total_songs) + " songs in this year's count.")
I understand that I should have defined functions. I only just discovered it. The code works fine anyway as I have no real need to call functions; everything just happens in order. Is there any reason to use functions in this script?
Something I haven't figured out yet is how to append the voter's name and votes to each song they vote for. The counter does support append.
I would appreciate anyone who takes the time to provide feedback/recommendations. I'm sure someone else here could probably do the same thing in about 10 lines, but bear in mind this is all a learning experience.