Using Python build your own song remixing solution. As an example: given the following American children’s song (this is ONE of the 3 songs I’m giving you in the starter code that includes the data you'll use for your program) Starter file: music.py (data file for my songs and playlist) here below; SONG = ['old macdonald had a farm - ee-i-ee-i-o.', 'and on that farm he had a cow - ee-i-ee-i-o.', 'with a moo moo here and a moo moo there', 'here a moo - there a moo - everywhere a moo moo', 'old macdonald had a farm - ee-i-ee-i-o.' ] Do This: Create a solution that allows users to: Load a new song from our playlist When requested, show the title of the song you’re currently remixing Continue the above operations on demand, until the user explicitly quits your program. Note that there is punctuation in some of the songs we've given you. When you remix a song, you should remove the punctuation (see the example reverse below). If you are unable to perform the remix, do NOT remove any punctuation - leave the song in its current state (see the last example below). Of course, if the song has already been altered, the "current state" has no punctuation anyway, so there's no punctuation alteration you would perform anyway. We will be performing both unit-testing of your solution AND some whole-system tests as well. For unit tests, you must provide the following function in remix_master.py: load_song(selection: int) -> list This function takes an integer (which is an index into our playlist) and returns a list that contains the selected song AND a string which represents the song title from our playlist. For the list returned: the song must be placed in index 0 and the title must be placed in index 1. If the selection is not valid, this function returns an empty list. Important Note: This function is mapped to the user-centered selection operation, NOT our computer science index scheme. Therefore, load_song(1) retrieves the FIRST song in our playlist, not the second song. PRE: This function's input parameters must be integers. Input values are NOT guaranteed to be within the range of our playlist POST: If selection is found in the playlist, a list containing the song and the song title will be returned. Otherwise an empty list will be returned Example screen captures are below. Note that if you try to substitute a new word for a song and the song cannot be remixed, you should leave the current version untouched. For your development effort, I’m giving you 3 songs for my playlist. Do NOT hard-code your solution based on these 3 songs!!! During our testing of your solution, we will expand the playlist to more than the three original songs. Your solution should be flexible enough to handle any sized playlist that has at least 1 song in it. So, if my test playlist has 7 songs in it, your solution should still work properly. Focus on good procedural decomposition where each of your functions are short (<15 lines of code, discounting comments) and doing 1 thing well (NB: Your main() can be a bit longer than 15 lines, if your user menu is being handled there). No global variables (Global CONSTANTS are okay) Stretch-goal (try your best on this): Work to see if you can design your solution with a good "separation of concerns". See if you can construct your code for the user-interface to deal primarily with those aspects (e.g. getting input from the user and printing to the screen) and the other "business logic" to work without intermingling print statements, etc.
Using Python
build your own song remixing solution.
As an example: given the following American children’s song (this is ONE of the 3 songs I’m giving you in the starter code that includes the data you'll use for your program)
- Starter file: music.py (data file for my songs and playlist) here below;
SONG = ['old macdonald had a farm - ee-i-ee-i-o.',
'and on that farm he had a cow - ee-i-ee-i-o.',
'with a moo moo here and a moo moo there',
'here a moo - there a moo - everywhere a moo moo',
'old macdonald had a farm - ee-i-ee-i-o.' ]
Do This:
Create a solution that allows users to:
- Load a new song from our playlist
- When requested, show the title of the song you’re currently remixing
- Continue the above operations on demand, until the user explicitly quits your program.
- Note that there is punctuation in some of the songs we've given you. When you remix a song, you should remove the punctuation (see the example reverse below). If you are unable to perform the remix, do NOT remove any punctuation - leave the song in its current state (see the last example below). Of course, if the song has already been altered, the "current state" has no punctuation anyway, so there's no punctuation alteration you would perform anyway.
We will be performing both unit-testing of your solution AND some whole-system tests as well. For unit tests, you must provide the following function in remix_master.py:
- load_song(selection: int) -> list
This function takes an integer (which is an index into our playlist) and returns a list that contains the selected song AND a string which represents the song title from our playlist. For the list returned: the song must be placed in index 0 and the title must be placed in index 1. If the selection is not valid, this function returns an empty list.
Important Note: This function is mapped to the user-centered selection operation, NOT our computer science index scheme. Therefore, load_song(1) retrieves the FIRST song in our playlist, not the second song.
PRE: This function's input parameters must be integers. Input values are NOT guaranteed to be within the range of our playlist
POST: If selection is found in the playlist, a list containing the song and the song title will be returned. Otherwise an empty list will be returned
Example screen captures are below.
Note that if you try to substitute a new word for a song and the song cannot be remixed, you should leave the current version untouched.
- For your development effort, I’m giving you 3 songs for my playlist. Do NOT hard-code your solution based on these 3 songs!!! During our testing of your solution, we will expand the playlist to more than the three original songs. Your solution should be flexible enough to handle any sized playlist that has at least 1 song in it. So, if my test playlist has 7 songs in it, your solution should still work properly.
- Focus on good procedural decomposition where each of your functions are short (<15 lines of code, discounting comments) and doing 1 thing well (NB: Your main() can be a bit longer than 15 lines, if your user menu is being handled there).
- No global variables (Global CONSTANTS are okay)
- Stretch-goal (try your best on this): Work to see if you can design your solution with a good "separation of concerns". See if you can construct your code for the user-interface to deal primarily with those aspects (e.g. getting input from the user and printing to the screen) and the other "business logic" to work without intermingling print statements, etc.
import music
# Get the playlist and song contents from music file
PLAYLIST = music.PLAYLIST
SONGS = music.SONGS
# Define punctuations and operation commands
PUNCTUATION = " .,?!"
OPERATION_MENU = ["L", "T", "S", "P", "R", "X", "Q"]
def welcome():
"""
Function -- welcome
Print a welcome title
Parameters:
None
Returns nothing
"""
print("Welcome to ReMix-Master. You can remix the greatest hits!")
def print_menu():
"""
Function -- print_menu
Print the operation menu here
Parameters:
None
Returns nothing
"""
print("\nReMix-Master:\n"
" L: Load a different song\n"
" T: Title of current song\n"
" S: Substitute a word\n"
" P: Playback your song\n"
" R: Reverse it!\n"
" X: Reset it\n"
" Q: Quit?\n")
def get_choice():
"""
Function -- get_choice
Get user's choice of operation
Parameters:
None
Returns a character representing user's choice
"""
choice = input(" Your choice: ").strip().upper()
while choice not in OPERATION_MENU:
choice = input(" Sorry, please enter again: ").strip().upper()
return choice
def load(choice, song_choice, song_backup, playlist):
"""
Function -- load_operation
According to the choice make specific operation
Parameters:
choice (character) -- the user's operation choice
song_choice (list) -- the current song content and title
song_backup (list) -- the unmodified song content
playlist (list) -- the titles of all songs
Returns nothing
"""
if choice == "L":
new_choice = get_song(playlist)
# Make a deepcopy of song_choice in case of modifying
song_choice[0].clear()
for index in range(len(new_choice[0])):
song_choice[0].append(new_choice[0][index])
song_choice[1] = new_choice[1]
song_backup = new_choice[0]
elif choice == "T":
get_title(song_choice)
elif choice == "S":
make_a_substitute(song_choice)
elif choice == "P":
play_the_song(song_choice)
elif choice == "R":
song_choice[0] = reverse_it(song_choice[0])
else:
song_choice = reset(song_choice, song_backup)
return song_choice, song_backup
def play_the_song(song_choice):
"""
Function -- play_the_song
Play a specific song
Parameters:
song_choice (list) -- the list of the song lyric and title
Returns nothing
"""
print("Turn up the 808's and drop the beat! Here's your remix:")
for content in song_choice[0]:
print(content)
print(20 * "-♫")
def get_title(song_choice):
"""
Function -- get_title
get the title of current song
Parameters:
song_choice (list) -- the current song content and title
Returns nothing
"""
title = song_choice[1]
print(20 * "-♫")
print(f"You are mixing the song: {title}")
def print_playlist(playlist):
"""
Function -- print_playlist
Print all titles of songs in the playlish
Parameters:
playlist (list) -- the titles of all songs
Returns nothing
"""
for index, title in enumerate(playlist):
print(f"{index + 1} : {title}")
print()
def get_selection():
"""
Function -- get_selection
Get the selection for a new song
Parameters:
None
Returns an int representing the selection
"""
selection = input("Your choice: ").strip()
while selection.isdigit() is False:
selection = input("Sorry, please enter again: ").strip()
selection = int(selection)
return selection
def get_song(playlist):
"""
Function -- get_song
Help the user to choose a song to load
Parameters:
playlist (list) -- the titles of all songs
Returns nothing
"""
print_playlist(playlist)
selection = get_selection()
new_choice = load_song(selection)
while not new_choice:
print("Sorry, your input is out of range")
selection = get_selection()
new_choice = load_song(selection)
return new_choice
def load_song(selection):
"""
Function -- load_song
load the selection of song
Parameters:
selection (int) -- users input of selection
Returns a list representing a new song choice
"""
index = selection - 1
if selection <= 0 or selection > len(PLAYLIST):
empty = []
return empty
else:
song_choice = [SONGS[index], PLAYLIST[index]]
return song_choice
def make_a_substitute(song_choice):
"""
Function -- make_a_substitue
make a substitute of the current song content
Parameters:
song_choice (list) -- the current song content and title
Returns nothing
"""
old_word = input("What word do you want to"
"replace in the existing song? ").strip().lower()
new_word = input("What new word do you want to"
"use for the song? ").strip().lower()
song = song_choice[0]
tag = substitute(song, old_word, new_word)
if tag is True:
song_choice[0] = song
else:
print(f"Sorry. I didn't find {old_word} in the existing song.")
def substitute(song, old_word, new_word):
"""
Function -- substitute
Replace every occurrence of the old word with the new word.
Parameters:
song (list) -- a list containing multiple strings of lyrics
old_word (str) -- a word which has existed in the song
new_word (str) -- a word which the user want replace with
Returns a bool representing substitute is successful or not
"""
tag = False
for index, content in enumerate(song):
content_ls = content.split(' ')
for word_index in range(len(content_ls)):
content_ls[word_index] = content_ls[word_index].strip(PUNCTUATION)
if content_ls[word_index].lower() == old_word:
content_ls[word_index] = new_word
tag = True
song[index] = ' '.join(content_ls)
return tag
def reverse_it(song):
"""
Function -- reverse_it
Reverse all the words in each sentence of the song
Parameters:
song (list) -- the content of current song
Returns a list representing the reversed content
"""
for index, content in enumerate(song):
content_ls = content.split(' ')
content_ls = content_ls[-1::-1]
for word_index in range(len(content_ls)):
content_ls[word_index] = content_ls[word_index].strip(PUNCTUATION)
song[index] = ' '.join(content_ls)
return song
def reset(song_choice, song_backup):
"""
Function -- reset
Reset the current song content to the original content
Parameters:
song_choice (list) -- the current song content and title
song_backup (list) -- the unmodified song content
Returns nothing
"""
song_choice[0] = song_backup.copy()
return song_choice
def remix_driver(playlist, songs):
"""
Function -- remix_driver
Complete all functions of ReMix-Master
Parameters:
playlist (list) -- a list of song titles
songs (list) -- a list of song contents
Returns nothing
"""
# First Step: Make a welcome and play the default song.
welcome()
default_choice = [songs[0], playlist[0]]
# Step 2: Copy and load the initial value of each attributes
song_choice = [[], []]
for index in range(len(default_choice[0])):
song_choice[0].append(default_choice[0][index])
song_choice[1] = default_choice[1]
song_bk = default_choice[0]
choice = "P"
# Step 3: Load ReMix-Master
while choice != "Q":
song_choice, song_bk = load(choice, song_choice, song_bk, playlist)
print_menu()
choice = get_choice()
def main():
playlist = PLAYLIST.copy()
songs = SONGS.copy()
# Start the ReMix-Master!
remix_driver(playlist, songs)
if __name__ == "__main__":
main()
Step by step
Solved in 3 steps with 1 images