class SongsToLearnApp(App): message = StringProperty() message2 = StringProperty() current_state = StringProperty() sort_by = ListProperty() def __init__(self, **kwargs): """ construct the main app """ super(SongsToLearnApp, self).__init__(**kwargs) self.sort_by = ["Title", "Artist", "Year", "Is_required"]# Create a list for "spinner" self.current_state = self.sort_by[0]# Set the "Title" as the default option self.song_list = SongList() self.song_list.load_songs() def build(self): """ Build the Kivy GUI :return: reference to the root Kivy widget """ self.title = "Songs to learn 2.0 by PengJie" self.root = Builder.load_file('app.kv') self.create_widgets() return self.root def change_sort(self): self.song_list.sort_songs.sort(self) def press_clear(self): # Clean the all the inputs self.root.ids.title.text = '' self.root.ids.artist.text = '' self.root.ids.year.text = '' def create_widgets(self): """ Create widgets to show the song list """ num_song = len(self.song_list.list_songs) learned_song = 0# Set the 0 to the number of songs learned for song in self.song_list.list_songs:# create a button for each data entry, specifying the text and id title = song.title artist = song.artist year = song.year learned = song.is_required display_text = self.formatText(title, artist, year, learned)# Display what should be added to the widget if learned == "n": learned_song += 1 button_color = [0.7, 1, 0, 1]# If the song is learned,display green button else: button_color = [255, 0, 0, 1] # If the song is not learned, display red button #If users click a song, the song will be learned temp_button = Button(text=display_text, id=song.title, background_color=button_color) temp_button.bind(on_release=self.press_entry)# The message2 will display that the song is learned self.root.ids.entriesBox.add_widget(temp_button) self.message = "To learn: {}. Learned: {}".format(num_song - learned_song, learned_song)# Display number of songs learned and not learned def formatText(self, title, artist, year, learned): """ Format the text displayed in the messages2 """ if learned == "n": display_text = "{} by {} ({}) (Learned)".format(title, artist, year) else: display_text = "{} by {} ({})".format(title, artist, year) return display_text def press_entry(self, button): """ The text displays in the message2 :param instance: the Kivy button instance :return: None """ buttonText = button.text #Determine the text on the widget buttons selectedSong = Song() for song in self.song_list.list_songs: displaymessage = self.formatText(song.title, song.artist, song.year, song.is_required) if buttonText == displaymessage: selectedSong = song break selectedSong.mark_learned() # Mark the song learned self.root.ids.entriesBox.clear_widgets() self.create_widgets() self.message2 = "You have learned {}".format(selectedSong.title)#Display the song you have learned def add_songs(self): """ Users add song to the song list """ #Check whether users input empty information if self.root.ids.title.text == "" or self.root.ids.artist.text == "" or self.root.ids.year.text == "": self.message2 = "The field can not be blank" try: # check whether users input valid information is_required = "y" title = str(self.root.ids.title.text) artist = str(self.root.ids.artist.text) year = int(self.root.ids.year.text) # Add the song inputted to the song list self.song_list.add_to_list(title, artist, year, is_required) temp_button = Button(text=self.formatText(title, artist, year, is_required)) temp_button.bind(on_release=self.press_entry) self.root.ids.entriesBox.add_widget(temp_button) # Empty the inputs after adding the song self.root.ids.title.text = "" self.root.ids.artist.text = "" self.root.ids.year.text = "" except ValueError: self.message2 = "Please enter a valid number"
""" Tests for SongList class """ from songlist import SongList from song import Song # test empty SongList song_list = SongList() print(song_list) assert len(song_list.list_songs) == 0 # test loading songs song_list.load_songs() print(song_list.list_songs) assert len(song_list.list_songs) == 6 print(song_list) assert len(song_list.list_songs) > 0 # assuming CSV file is not empty q # test sorting songs song_list.sort("title") # test adding a new Song song_list.add_to_list(Song("21 Guns", "Green Day", "2006", "y")) print(song_list) # test getting the number of required and learned songs (separately) # test saving songs (check CSV file manually to see results)
class SongsToLearnApp(App): # Class refering to the Kivy app """ Main program: Display a list of songs in a GUI model using Kivy app """ message = StringProperty() # Define first status text message2 = StringProperty() # Define second status text current_sort = StringProperty() # Define current sorting of song list sort_choices = ListProperty() # Define sorting options of song list def __init__(self, **kwargs): """ Initiate song_list to SongList class Initiate sort_choices as an array Initiate the current sorting option as "title" Initiate the function load_songs to load csv file :param kwargs: returns None """ super(SongsToLearnApp, self).__init__(**kwargs) self.song_list = SongList() self.sort_choices = ["title", "artist", "year", "is_required"] self.current_sort = self.sort_choices[0] self.song_list.load_songs() def build(self): """ Build the Kivy GUI :return: widgets of the GUI """ self.learn___ = "Songs to learn 2.0" # Name the GUI's name self.title = self.learn___ self.root = Builder.load_file('app.kv') # Connect to Kivy app self.create_widgets() # Create widgets in Kivy GUI return self.root def change_sort(self, sorting_choice): """ Function to change the sorting of the song list :param sorting_choice: Based on what choice the user selects, the song list will be sorted that way :return: sorted song list """ self.message = "song have been sorted by: {}".format(sorting_choice) self.song_list.sort(sorting_choice) self.root.ids.entriesBox.clear_widgets() self.create_widgets() sort_index = self.sort_choices.index(sorting_choice) self.current_sort = self.sort_choices[sort_index] def blank(self): """ Clear all inputs after clicking the Clear button :return: blanks at inputs """ self.root.ids.song_title.text = '' # Empty the song title input self.root.ids.song_artist.text = '' # Empty the song artist input self.root.ids.song_year.text = '' # Empty the song year input def create_widgets(self): """ Create widgets that lists the songs from the csv file :return: song list widgets """ num_song = len(self.song_list.list_songs ) # Determine the number of songs in the list learned_song = 0 # Initial number of learned song is 0 for song in self.song_list.list_songs: # Loop from the first song to the last song within the song list title = song.title # Dim the title of each song artist = song.artist # Dim the artist of each song year = song.year # Dim the year of each song learned = song.is_required # Dim the need for the song to either be learned or not learned display_text = self.generateDisplayText( title, artist, year, learned) # display what should be added to the widget if learned == "n": # Condition when the song is learned, count the number of learned songs and format their background color (Velvet) learned_song += 1 button_color = self.getColor(learned) else: button_color = self.getColor( learned) # If the song is not learned, display Blue color # By clicking a song, that song will be learned temp_button = Button( text=display_text, id=song.title, background_color=button_color) # Mark the song learned temp_button.bind(on_release=self.press_entry ) # Display the message of the GUI status self.root.ids.entriesBox.add_widget( temp_button) # Apply to the Kivy app self.message = "To learn: {}. Learned: {}".format( num_song - learned_song, learned_song) # Display number of songs learned and not learned def generateDisplayText( self, title, artist, year, learned): #Formating any text displayed in the messages if learned == "n": display_text = "{} by {} ({}) (Learned)".format( title, artist, year) else: display_text = "{} by {} ({})".format(title, artist, year) return display_text def getColor(self, learned): #Display colors of the song widgets if learned == "n": button_color = [1, 0, 0, 1] else: button_color = [0, 0, 1, 1] return button_color def press_entry(self, button): #Function that displays the 2nd message buttonText = button.text #Determine the text on the widget buttons selectedSong = Song() for song in self.song_list.list_songs: #Loop the songs within the song list songDisplayText = self.generateDisplayText(song.title, song.artist, song.year, song.is_required) #Display the text as formatted in generateDisplayText if buttonText == songDisplayText: selectedSong = song break selectedSong.mark_learned() #Mark the song learned self.root.ids.entriesBox.clear_widgets() #Apply to Kivy GUI self.create_widgets() self.message2 = "You have learned {}".format( selectedSong.title) #Display whatever changed in message 2 def add_songs(self): """ Function allows user to add any song they want :return: Add the song inputted to the song list """ #Check for empty inputs if self.root.ids.song_title.text == "" or self.root.ids.song_artist.text == "" or self.root.ids.song_year.text == "": self.root.ids.status2.text = "All fields must be completed" return try: #Define song items inputted song_title = str(self.root.ids.song_title.text) song_artist = str(self.root.ids.song_artist.text) song_year = int(self.root.ids.song_year.text) is_required = "y" #Add the song inputted to the song list self.song_list.add_to_list(song_title, song_artist, song_year, is_required) temp_button = Button(text=self.generateDisplayText( song_title, song_artist, song_year, is_required)) temp_button.bind(on_release=self.press_entry) #Format the new song items temp_button.background_color = self.getColor(is_required) self.root.ids.entriesBox.add_widget(temp_button) #Empty the inputs after adding the song self.root.ids.song_title.text = "" self.root.ids.song_artist.text = "" self.root.ids.song_year.text = "" except ValueError: #Display error when year input is not a number self.message2 = "Please enter a valid year" def on_stop(self): #stop the GUI and save changes self.song_list.save_songs()
class LearnSongsApp(App): """ Main program: show the list of songs by GUI """ status_text = StringProperty() # the first status text status_text2 = StringProperty() # the second status text current_sort = StringProperty() # the current sorting of song list sort_choices = ListProperty() # the sorting options of song list def __init__(self, **kwargs): """ Construct main app """ super(LearnSongsApp, self).__init__(**kwargs) self.song_list = SongList() self.sort_choices = ["year", "artist"] self.current_sort = self.sort_choices[0] self.song_list.load_songs() def build(self): """ Build the Kivy GUI """ self.title_ = "Songs to learn 2.0 by Chen Jianjian" # Name the GUI's name self.root = Builder.load_file('app.kv') # Connect to Kivy app self.create_buttons() # Create the songs button return self.root def change_sort(self, sorting_choice): """ change the sorting of the song list """ self.song_list.sort(sorting_choice) self.root.ids.entriesBox.clear_widgets() self.create_buttons() sort_index = self.sort_choices.index(sorting_choice) self.current_sort = self.sort_choices[sort_index] def create_buttons(self): """ Create Songs' buttons from the csv file """ num_song = len(self.song_list.list_songs) # Count the number of songs learned_song = 0 for song in self.song_list.list_songs: # find the songs name = self.button_Text(song.title, song.artist, song.year,song.is_required) # showing the information in be the button) learned = song.is_required if learned == 'n': background_color = (1, 2, 1, 0.7)#if the song id learned show this color learned_song += 1 else: # If the song is not learned show blue color background_color = (1, 3, 4, 0.6) # clicking a song to learn temp_button = Button(text=name,background_color=background_color) # Add the song learned temp_button.bind(on_release=self.press_song) # show the message of the status self.root.ids.entriesBox.add_widget(temp_button) # add the song to the Kivy app self.status_text = 'To Learned: {} Learned: {}'.format(num_song-learned_song,learned_song) def button_Text(self, title, artist, year, learned): # show messages if learned == "n": display_text = "{} by {} {} (Learned)".format(title,artist,year) else: display_text = "{} by {} {}".format(title,artist,year) return display_text def press_song(self, button): # when you press the song button buttonText = button.text # Determine the text on the buttons selectedSong = Song() for song in self.song_list.list_songs: songDisplayText = self.button_Text(song.title, song.artist, song.year, song.is_required) # show text in Button if buttonText == songDisplayText: selectedSong = song break selectedSong.add_learned() self.root.ids.entriesBox.clear_widgets() # Apply to Kivy self.create_buttons() self.status_text2 = "You have learned {}".format(selectedSong.title) # Display the status text 2 def add_songs(self): """ add a song to learn """ # Check if have empty inputs if self.root.ids.song_title.text == "" or self.root.ids.song_artist.text == "" or self.root.ids.song_year.text == "": self.root.ids.status2.text = "All fields must be completed" return try: # Define song items inputted song_title = str(self.root.ids.song_title.text) song_artist = str(self.root.ids.song_artist.text) song_year = int(self.root.ids.song_year.text) is_required = "y" # Add the song to the song list self.song_list.add_to_list(song_title, song_artist, song_year, is_required) temp_button = Button(text=self.button_Text(song_title, song_artist, song_year, is_required)) temp_button.bind(on_release=self.press_song) # the new song button color temp_button.background_color = (1, 3, 4, 0.6) self.root.ids.entriesBox.add_widget(temp_button) # empty inputs self.root.ids.song_title.text = "" self.root.ids.song_artist.text = "" self.root.ids.song_year.text = "" except ValueError: # Display error when year input is not a number self.status_text2 = "Please enter a valid year" self.song_list.save_songs() def press_clear(self): """ Clear status text and inputs """ self.status_text = "" # Clear status_text self.status_text2 = "" # Clear status_text2 self.root.ids.song_title.text = '' # Clear title input self.root.ids.song_artist.text = '' # Clear artist input self.root.ids.song_year.text = '' # Clear year input
class SongsToLearnApp(App): """ Main program:Display a list of songs in a GUI model using Kivy app""" message = StringProperty() # Define status text news = StringProperty() current_sort = StringProperty() # Define sort sort_choices = ListProperty() def __init__(self, **kwargs): """Construct main app""" super(SongsToLearnApp, self).__init__(**kwargs) self.song_list = SongList() self.sort_choices = ["title", "artist", "year", "is_required"] self.current_sort = self.sort_choices[0] self.song_list.load_songs() def build(self): """ Build the Kivy GUI. :return: reference to the root Kivy widgit """ self.title = "Songs to learn by ZhuKunBo" # Name GUI name self.root = Builder.load_file('app.kv') # Load app.kivy self.create_widget() # Create widget in GUI return self.root def change_sort(self, sorting_choice): """ Function to change the sorting of the song list :param sorting_choice: Based on what choice the user selects, the song list will be sorted that way :return: sorted song list """ self.message = "song have been sorted by: {}".format(sorting_choice) self.song_list.sort(sorting_choice) self.root.ids.entriesBox.clear_widgets() self.create_widget() sort_index = self.sort_choices.index(sorting_choice) self.current_sort = self.sort_choices[sort_index] def Clear_input(self): """Clear inputs after clicking the Clear button""" self.root.ids.song_title.text = '' # Clear input self.root.ids.song_artist.text = '' self.root.ids.song_year.text = '' def create_widget(self): """Create widgets that lists the songs from the csv file""" self.root.ids.entriesBox.clear_widgets() num_song = len(self.song_list.list_songs ) # Determine the number of songs in the list learned_song = 0 for song in self.song_list.list_songs: # Loop from first song to last song title = song.title artist = song.artist year = song.year learned = song.is_required display_text = self.generateDisplayText( title, artist, year, learned) # Display song's information on the widget if learned == "n": learned_song += 1 button_color = self.getColor(learned) else: button_color = self.getColor(learned) temp_button = Button( text=display_text, id=song.title, background_color=button_color) # Mark the song learned temp_button.bind(on_release=self.press_entry ) # Display message of the GUI status self.root.ids.entriesBox.add_widget(temp_button) self.message = "To learn: {}. Learned: {}".format( num_song - learned_song, learned_song) # Display number of song learned or not learned def generateDisplayText(self, title, artist, year, learned): """Formating text display in the message""" if learned == "n": display_text = "{} by {} ({}) (Learned)".format( title, artist, year) else: display_text = "{} by {} ({})".format(title, artist, year) return display_text def getColor(self, learned): """Display colors of the song learned and not learned""" if learned == "n": button_color = [0.4, 0.6, 0, 1] else: button_color = [0.4, 0.7, 0.9, 1] return button_color def press_entry(self, button): """Display the 2nd message""" buttonText = button.text selectedSong = Song() for song in self.song_list.list_songs: songDisplayText = self.generateDisplayText(song.title, song.artist, song.year, song.is_required) if buttonText == songDisplayText: selectedSong = song break selectedSong.mark_learned() # Mark the song learned self.root.ids.entriesBox.clear_widgets() # Apply to GUI self.create_widget() self.news = "You have learned {}".format( selectedSong.title) # Display change in news def add_songs(self): """ Add the new song :return: Add the song inputted to the song list """ if self.root.ids.song_title.text == "" or self.root.ids.song_artist.text == "" or self.root.ids.song_year.text == "": self.root.ids.status2.text = "All fields must be completed" return try: # Define song item inputted song_title = str(self.root.ids.song_title.text) song_artist = str(self.root.ids.song_artist.text) song_year = int(self.root.ids.song_year.text) is_required = "y" # Add songs's input to the songlist self.song_list.add_to_list(song_title, song_artist, song_year, is_required) temp_button = Button(text=self.generateDisplayText( song_title, song_artist, song_year, is_required)) temp_button.bind(on_release=self.press_entry) # Format new song item temp_button.background_color = self.getColor(is_required) self.root.ids.entriesBox.add_widget(temp_button) self.create_widget() # Clear input after adding song self.root.ids.song_title.text = "" self.root.ids.song_artist.text = " " self.root.ids.song_year.text = "" except ValueError: # Display error when type is wrong self.news = "Please enter a valid year" def on_stop(self): # Stop GUI and save self.song_list.save_songs()