def main(): movies = MovieCollection() movies.load_movies('movies.csv') # input_file = open("movies.csv", "r") # movies = input_file.readlines() print("Movies To Watch 1.0 - by <Shen Zhaozhe>") print('{} movies loaded'.format(len(movies))) # print the menu for choosing while True: print( "Menu:\nL - List movies\nA - Add new movies\nW - Watch movies\nQ - Quit" ) enter = input(">>> ").upper() if enter == "L": List(movies) elif enter == "A": Add(movies) elif enter == "W": if all_watched: print("You have watched all movies") else: Watch(movies) elif enter == "Q": print("{} movies saved to movies.csv\nHave a nice day :)".format( len(movies))) return False else: print("Invalid choice") print( "Menu:\nL - List movies\nA - Add new movies\nW - Watch movies\nQ - Quit" ) enter = input(">>> ").upper() input_file.close()
class MoviesToWatchApp(App): """Main application to watch movies""" def __init__(self, **kwargs): super().__init__(**kwargs) self.movie_collection = MovieCollection() self.movie_collection.load_movies("movies.csv") self.sorted_by = "year" def build(self): self.title = "Movies To Watch 2.0" self.root = Builder.load_file('app.kv') self.sort_movies(self.sorted_by) return self.root def movie_listed(self): self.root.ids.movies.clear_widgets() self.root.ids.top_label.text = 'To watch: {}. Watched: {}'.format(self.movie_collection.count_unwatched_movies, self.movie_collection.count_watched_movies) for movie in self.movies: button = Button(text=str(movie)) button.bind(on_press=self.movie_click) button.movie = movie self.root.ids.movies.add_widget(button) if movie.is_watched: button.background_color = '#6e94b9' else: button.background_color = '#b26c6c' def movie_click(self, button): movie = button.movie if movie.is_watched: movie.watched_unwatched() self.root.ids.bottom_label.text = 'You have watched {}'.format(movie.title) else: movie.unwatched_watched() self.root.ids.bottom_label.text = 'You have unwatched {}'.format(movie.title) self.movie_listed() def sort_movies(self, sorted_by): self.sorted_by = sorted_by self.movie_collection.sort(sorted_by) self.movie_listed() def add_movie(self): movie = Movie(self.root.ids.title.text, int(self.root.ids.year.text), self.root.ids.category.text, False) self.movies.add_movie(movie) self.sort_movies(self.sorted_by) def clear(self): self.root.ids.title.text = "" self.root.ids.year.text = "" self.root.ids.category.text = "" self.root.ids.bottom_label.text = "" def over_app(self): self.movies.save_movies("movies.csv") pass
def __init__(self, **kwargs): """Construct main app.""" super().__init__(**kwargs) # basic data example - dictionary of names: phone numbers # TODO: After running it, add another entry to the dictionary and see how the layout changes # self.name_to_phone = {"Bob Brown": "0414144411", "Cat Cyan": "0441411211", "Oren Ochre": "0432123456"} self.movie_collection = MovieCollection() self.movie_collection.load_movies('movies.csv')
def __init__(self, **kwargs): """creat the main of the app.""" super().__init__(**kwargs) self.text_attr = DICTIONARY self.sort_methods = list(self.text_attr.keys()) self.sort_current = self.sort_methods[0] self.movies = MovieCollection() self.movies.load_movies(DATA) self.information = WELCOME Window.size = (1000, 750)
def main(): """ Contains a menu with four capabilities; displaying a movie list, adding to the movie list, watching a movie from the list and quitting the program. """ MENU = "Menu:\nL - List movies\nA - Add new movie\nW - Watch a movie\nQ - Quit" movie_collection = MovieCollection() movie_collection.load_movies("movies.csv") print("Movies To Watch 2.0 - by Jonache Hilton\n{} movies loaded\n\n{}".format(len(movie_collection.movies), MENU)) menu_choice = input(">>>").upper() while menu_choice != "Q": if menu_choice == "L": display_list(movie_collection.movies, calculate_dynamic_width(movie_collection.movies), movie_collection) elif menu_choice == "A": movie_name = "" is_valid_input = False while not is_valid_input: print("Title:") movie_name = input(">>>") is_valid_input = check_string_error(movie_name) print("Year:") movie_year = check_integer_error() print("Category:") movie_category = "" is_valid_input = False while not is_valid_input: movie_category = input(">>>") is_valid_input = check_string_error(movie_category) movie_to_add = Movie(movie_name, movie_year, movie_category, False) movie_collection.add_movie(movie_to_add) print("{} ({} from {}) added to movie list".format(movie_name, movie_category, movie_year)) elif menu_choice == "W": if movie_collection.get_number_of_watched_movies() == len(movie_collection.movies): print("No more movies to watch!") else: print("Enter the number of a movie to mark as watched") watch_movie(movie_collection.movies) else: print("Invalid menu choice") print(MENU) menu_choice = input(">>>").upper() movie_collection.save_movies("movies.csv")
def __init__(self): """ construct things needed for class""" self.movie_collection = MovieCollection() # call movie collection self.movie_collection.load_movies('movies.csv') # to open csv file self.movie_collection.get_unwatched_movies( ) # getting the number of unwatched movies self.movie_collection.get_watched_movies( ) # getting the number watch movies self.num_of_unwatch = self.movie_collection.unwatch_movie # count unwatched movies self.num_of_watch = self.movie_collection.watch_movie # count watched movie self.movie_dict = { movie.title: movie for movie in self.movie_collection.movies } # to initialize the dictionary self.btn_movie = [] # list data for button self.sorting_type = list(sorting.keys()) # sorting type self.current_display_sorting = self.sorting_type[ +2] # set default sorting super().__init__()
def run_tests(): """Test MovieCollection class.""" # Test empty MovieCollection (defaults) print("Test empty MovieCollection:") movie_collection = MovieCollection() print(movie_collection) assert not movie_collection.movies # an empty list is considered False # Test loading movies print("Test loading movies:") movie_collection.load_movies('movies.csv') print(movie_collection) assert movie_collection.movies # Test adding a new Movie with values print("Test adding new movie:") movie_collection.add_movie(Movie("Cats", 2019, "Musical", "u")) # adding new movies print(movie_collection) # Test sorting movies """ print("Test sorting - year:") movie_collection.sort_movie("year"). 7 print(movie_collection) """ # Test to get number of unwatched movies print("Test getting number of unwatched movies:") print(movie_collection.get_unwatched_movies()) # Test to get number of watched movies print("Test getting number of watched movies:") print(movie_collection.get_watched_movies()) print("Test saving movies into the file") movie_collection.save_file('movies.csv')
def run_tests(): """Test MovieCollection class.""" # Test empty MovieCollection (defaults) print("Test empty MovieCollection:") movie_collection = MovieCollection() print(movie_collection) assert not movie_collection.movies # an empty list is considered False # Test loading movies print("Test loading movies:") movie_collection.load_movies('movies.csv') print(movie_collection) assert movie_collection.movies # assuming CSV file is non-empty, non-empty list is considered True # Test adding a new Movie with values print("Test adding new movie:") movie_collection.add_movie(Movie("Amazing Grace", 2006, "Drama", False)) print(movie_collection) # Test sorting movies print("Test sorting - year:") movie_collection.sort("year") print(movie_collection)
def main(): """Program is a list of movies that allows a user to track movies that they have watched and wish to watch.""" movies = MovieCollection() movies.load_movies(FILE_NAME) movies.sort_movies(SORT_CONDITION) menu = """Menu:\nL - List movies\nA - Add new movie\nW - Watch a movie\nQ - Quit""" print("Movies To Watch 2.0 - by Dallas Marshall\n{} movies loaded\n{}".format(len(movies), menu)) menu_selection = input(">>> ").upper() while menu_selection != 'Q': if menu_selection == 'L': list_movies(movies) elif menu_selection == 'A': add_movie(movies) elif menu_selection == 'W': watch_movie(movies) else: print("Invalid menu choice") print(menu) menu_selection = input(">>> ").upper() print("{} movies saved to {}\nHave a nice day :)".format(len(movies), FILE_NAME)) save_movies(movies)
class MoviesToWatchApp(App): """MoviesToWatchApp(App) with Kivy APP following movies """ current_spinner = StringProperty() message = StringProperty() watched_status = StringProperty() sorting_keys = ListProperty() # Construct the main app. def __init__(self, **kwargs): super(MoviesToWatchApp, self).__init__(**kwargs) self.movies = MovieCollection() # Create the main app def build(self): Window.size = (800, 500) self.title = "Movies Watch system 3.1 by Kyaw Soe Naing " self.root = Builder.load_file('app.kv') self.sorting_keys = SORTING_KEY.keys() self.current_spinner = self.sorting_keys[0] self.movies.load_movies("movies.csv") self.show_movie() return self.root # Show the movie list def show_movie(self): count = 0 print(self.current_spinner) self.movies.sort(SORTING_KEY[self.current_spinner]) self.root.ids.movies_box.clear_widgets() for movie in self.movies.movies: if movie.is_watched: color = [0.3, 0.7, 0.9, 0.5] mark = "watched" else: color = [0.8, 0.3, 1.0, 1] mark = "" movie_text = "{} ({} from {:d}) {}".format(movie.title, movie.category, movie.year, mark) movie_button = Button(text=movie_text, id=str(count), background_color=color) movie_button.bind(on_release=self.press_movie) self.root.ids.movies_box.add_widget(movie_button) count += 1 unwatched_number = self.movies.get_unwatched() watched_number = self.movies.get_watched() self.watched_status = "To watch: {:d}. Watched: {:d}".format(unwatched_number, watched_number) # check watch and unwatch def press_movie(self, instance): """ """ movie_id = int(instance.id) movie_data = self.movies.movies[movie_id] movie_title = movie_data.title if movie_data.is_watched: movie_data.mark_unwatched() self.message = "You need to watch {:s}".format(movie_title) else: movie_data.mark_watched() self.message = "You have watched {:s}".format(movie_title) self.movies.sort(SORTING_KEY[self.current_spinner]) self.show_movie() # sort key for sorting def choose_key(self, key): self.current_spinner = key self.show_movie() # add new movie to movies def add_movie(self): m_title = self.root.ids.input_title.text m_year = self.root.ids.input_year.text m_category = self.root.ids.input_cate.text m_title = m_title.strip() m_year = m_year.strip() m_category = m_category.strip().upper() if (m_title == "") or (m_year == "") or (m_category == ""): self.message = "All fields must be completed" return if not m_year.isdigit(): self.message = "Please enter a valid number" return m_year = int(m_year) if m_year < 0: self.message = "Year must be more than 0" found = False count = 0 for i in range(len(CATEGORY_LIST)): if m_category == CATEGORY_LIST[i].upper(): found = True count = i break if not found: self.message = "The category must be one of Action, Comedy, Documentary, Drama, Fantasy, Thriller" return else: m_category = CATEGORY_LIST[count] new_movie = Movie(m_title, m_year, m_category) self.movies.add_movie(new_movie) self.all_clear() self.show_movie() # clear all the fill box def all_clear(self): self.root.ids.input_title.text = "" self.root.ids.input_cate.text = "" self.root.ids.input_year.text = "" self.message = "" def stop_now(self): self.movies.save_movies("movies.csv")
def __init__(self, **kwargs): super(MoviesToWatchApp, self).__init__(**kwargs) self.movies = MovieCollection()
def run_tests(): """Test MovieCollection class.""" # Test empty MovieCollection (defaults) print("Test empty MovieCollection:") movie_collection = MovieCollection() print(movie_collection) assert not movie_collection.movies # an empty list is considered False # Test loading movies print("Test loading movies:") movie_collection.load_movies('movies.csv') print(movie_collection) print("Movie Colletion . movies") print(movie_collection.movies) assert movie_collection.movies # assuming CSV file is non-empty, non-empty list is considered True # Test adding a new Movie with values print("Test adding new movie:") movie_collection.add_movie(Movie("Amazing Grace", 2006, "Drama", False)) print(movie_collection) # Test sorting movies by year print("Test sorting - year:") movie_collection.sort("year") print(movie_collection) # Test sorting movies by category print("Test sorting - Category:") movie_collection.sort("category") print(movie_collection) # TODO: Test saving movies (check CSV file manually to see results) print("Test saving movies") movie_collection.save_movies("movies.csv") # TODO: Add more tests, as appropriate, for each method print("Unwatched movie counts") print(movie_collection.get_unwatched())
def initCollection(self): """ Method to initialize movie and movie collection instances""" self.movie = Movie() self.movie_collection = MovieCollection() self.movie_collection.load_movies(FILE_NAME) self.movie_collection.sort("category")
class MoviesToWatchApp(App): """Watchmovies app GUI version""" sort_by = StringProperty() category = ListProperty() order = ListProperty() current_order = StringProperty() def __init__(self, **kwargs): """Creat the core of Watchmovies app""" Window.size = (900, 700) super(MoviesToWatchApp, self).__init__(**kwargs) self.my_collection = MovieCollection() self.movie_to_show = [] def build(self): """Build kivy GUI file""" self.title = "Movie To Watch 2.0 by JialeTang " self.root = Builder.load_file('app.kv') # Setting category lists self.category = ['Title', 'Year', 'Category'] self.sort_by = self.category[0] return self.root def on_start(self): self.my_collection.load_movies('movies.csv') self.movie_to_show = self.my_collection.movies self.root.ids.movie_list.bind( minimum_height=self.root.ids.movie_list.setter('height')) # Show the message self.root.ids.message.text = 'Let\'s watch some movies :)' # Load movies self.load_movies() # Showing watched or unwatch self.count_watch() def on_stop(self): """Saving the data to csv when close the app""" self.my_collection.save_movies('movies.csv') def count_watch(self): self.root.ids.watch_count.text = 'To watch: {}. Watched: {}'.format( self.my_collection.count_unwatch(), self.my_collection.count_watch()) def sort_movies(self, key): """Sort movie based on key""" self.sort_by = key self.load_movies() def handle_order(self, element): """Sort movie based on order""" self.current_order = element self.load_movies() def handle_add_movie(self, title, year, category): """Add movies to the movies list""" # Only add movie when title, year, category are provided if title and year and category: title_check = self.handle_input(title, is_title=True) category_check = self.handle_input(category, is_category=True) year_check = self.handle_input(year, is_year=True) if year_check and category_check and title_check: clean_title = ' '.join(title.split()) pretty_title = capwords(clean_title) if self.check_exist(title_check, year_check, category_check): self.show_popup_message('The movie is already exist') else: self.my_collection.add_movie( Movie(title_check, year_check, category_check)) self.load_movies() self.show_popup_message( '{} have been add to movie list'.format(pretty_title)) self.handle_clear_button(is_add=True) else: # Showing error message if any field is blank self.show_popup_message('All fields are required') def load_movies(self): self.root.ids.movie_list.clear_widgets() desc = self.current_order == 'Descending Order' self.movie_to_show = self.my_collection.sort_movies(self.sort_by, desc) for index, movie in enumerate(self.movie_to_show): watch_mark = 'watched' if movie.is_watched else '' btn = Button(text='{} ({} from {}) {}'.format( movie.title, movie.category, movie.year, watch_mark), size_hint_y=None, height=200) btn.movie = movie btn.bind(on_press=self.handle_watch_movie) # background color if watch_mark: btn.background_color = (0.5, 0.25, 1.0, 1.0) else: btn.background_color = (1, 0, 0, 5) self.root.ids.movie_list.add_widget(btn) def handle_watch_movie(self, instance): """Handle watch movie if user click on movie""" current_movie = instance.movie current_movie.is_watched = not current_movie.is_watched self.load_movies() watch_mark = 'watched' if current_movie.is_watched else 'unwatched' self.root.ids.message.text = 'You have {} {}'.format( watch_mark, current_movie.title) self.count_watch() def show_popup_message(self, text): """show popup message""" self.root.ids.popup_message.text = text self.root.ids.popup.open() def handle_close_popup(self): """Close the popup""" self.root.ids.popup_message.text = '' self.root.ids.popup.dismiss() def handle_clear_button(self, is_add=False, is_search=False): """Clear input when pressed""" if is_add: self.root.ids.title.text = '' self.root.ids.year.text = '' self.root.ids.category.text = '' elif is_search: self.root.ids.title_search.text = '' self.root.ids.year_search.text = '' self.root.ids.category_search.text = '' self.root.ids.watch_search.text = '' # Else clear all else: self.root.ids.title.text = '' self.root.ids.year.text = '' self.root.ids.category.text = '' self.root.ids.title_search.text = '' self.root.ids.year_search.text = '' self.root.ids.category_search.text = '' self.root.ids.watch_search.text = '' def check_exist(self, title, year, category): """Check if movie is existed""" def find_duplicate(movie): filter_title = title.lower() == movie.title.lower() filter_year = int(movie.year) == int(year) filter_category = movie.category.lower() == category.lower() return filter_title and filter_year and filter_category return list(filter(find_duplicate, self.my_collection.movies)) def handle_input(self, input_data, is_title=False, is_year=False, is_category=False, is_watch=False, blank=False): """Handle input data""" if blank and not input_data: return True else: if is_year: try: year = int(input_data) if year < 0: raise ValueError() return input_data.strip() except ValueError: self.show_popup_message( 'Your year must be a number and greater than 0') elif is_category: if input_data.lower().strip() not in [ 'action', 'comedy', 'documentary', 'drama', 'fantasy', 'thriller' ]: self.show_popup_message( 'Please enter a correct category ' '(Action, Comedy, Documentary, Drama, Fantasy, Thriller)' ) else: return input_data.strip() elif is_watch: if input_data.lower() not in ['y', 'n']: self.show_popup_message('Your watch field must be Y or N') else: return True elif not input_data.strip() and is_title: self.show_popup_message('Your title must not be blank') else: return input_data.strip()
def run_tests(): """Test MovieCollection class.""" # Test empty MovieCollection (defaults) print("Test empty MovieCollection:") movie_collection = MovieCollection() print(movie_collection) assert not movie_collection.movies # an empty list is considered False # Test loading movies print("Test loading movies:") movie_collection.load_movies('movies.csv') print(movie_collection) assert movie_collection.movies # assuming CSV file is non-empty, non-empty list is considered True # Test adding a new Movie with values print("Test adding new movie:") movie_collection.add_movie(Movie("Amazing Grace", 2006, "Drama", False)) print(movie_collection) assert movie_collection.movies # Test sorting movies print("Test sorting - year:") movie_collection.sort("year") print(movie_collection) assert movie_collection.movies print("Test sorting - title:") movie_collection.sort("title") print(movie_collection) assert movie_collection.movies print("Test sorting - category:") movie_collection.sort("category") print(movie_collection) assert movie_collection.movies # TODO: Add more sorting tests # TODO: Test saving movies (check CSV file manually to see results) print("Test saving movies:") movie_collection.save_movies('movies.csv') print(movie_collection) assert movie_collection.movies
def run_tests(): """Test MovieCollection class.""" # Test empty MovieCollection (defaults) print("Test empty MovieCollection:") movie_collection = MovieCollection() print(movie_collection) assert not movie_collection.movies # an empty list is considered False # Test loading movies print("Test loading movies:") movie_collection.load_movies('movies.csv') print(movie_collection) assert movie_collection.movies # assuming CSV file is non-empty, non-empty list is considered True # Test adding a new Movie with values print("Test adding new movie:") movie_collection.add_movie(Movie("Amazing Grace", 2006, "Drama", False)) print(movie_collection) # Test sorting movies print("Test sorting - year:") movie_collection.sort("year") print(movie_collection) print("Test sorting - title:") movie_collection.sort("title") print(movie_collection) print("Test sorting - category:") movie_collection.sort("category") print(movie_collection) print("Test sorting - watched:") movie_collection.sort("is_watched") print(movie_collection) print("Test getting number of watched movies:") print(movie_collection.get_number_of_watched_movies()) print("Test getting number of unwatched movies:") print(movie_collection.get_number_of_unwatched_movies()) print("Test saving movies (check file):") movie_collection.save_movies("movies.csv")
def run_tests(): """Test MovieCollection class.""" # Test empty MovieCollection (defaults) print("Test empty MovieCollection:") movie_collection = MovieCollection() print(movie_collection) assert not movie_collection.movies # an empty list is considered False # Test loading movies print("Test loading movies:") movie_collection.load_movies('movies.csv') print(movie_collection) assert movie_collection.movies # assuming CSV file is non-empty, non-empty list is considered True # Test adding a new Movie with values print("Test adding new movie:") movie_collection.add_movie(Movie("Chinatown", 1974, "Film Noir", False)) print(movie_collection) # Test sorting movies print("Test sorting - year:") sorted_list = movie_collection.sort_movies("year", desc=True) print(MovieCollection.format_data(sorted_list)) # TODO: Add more sorting tests # TODO: Test saving movies (check CSV file manually to see results) print("Test saving movie:") movie_collection.save_movies('movies.csv') # TODO: Add more tests, as appropriate, for each method print("Test unwatched count:") print(movie_collection.count_unwatch()) print("Test watched count:") print(movie_collection.count_watch()) # Add filter method print('Test filter method:') movie_collection.search_movies('star', 1977, 'action') print(MovieCollection.format_data(movie_collection.search_list))
# TODO: Copy your first assignment to this file, then update it to use Movie class # Optionally, you may also use MovieCollection class from movie import Movie from moviecollection import MovieCollection print("Movies To Watch 1.0 - by Kyaw Soe Naing") MENU = """Menu: L - List movies A - Add new movies W - Watch a movie Q - Quit """ # Read all data from movies.csv file DATAFILE = "movies.csv" moviecollection = MovieCollection() moviecollection.load_movies(DATAFILE) # all data from csv file is stored in movies = [] as nested list movies = [] # Main Function including other many functions def main(): user_input = menu() while user_input != "q": if user_input == "l": all_movies() user_input = menu() elif user_input == "a": add_movies() user_input = menu()
def __init__(self, **kwargs): """Constructor that initiate my collection and movie list""" super(MoviesToWatchApp, self).__init__(**kwargs) self.my_collection = MovieCollection() # Create another list to not TOUCH the original list, in case for back-up or error self.movie_to_show = []
def __init__(self, **kwargs): """Construct main app.""" super().__init__(**kwargs) self.movie_collection = MovieCollection() self.movie_collection.load_movies("movies.csv") self.sorted_by = "category"
class MoviesToWatchApp(App): """MoviesToWatchApp is a Kivy App for keeping track of movies from a file """ bottom_status_text = StringProperty() top_status_text = StringProperty() def __init__(self, **kwargs): """Construct main app.""" super().__init__(**kwargs) self.movie_collection = MovieCollection() self.movie_collection.load_movies("movies.csv") self.sorted_by = "category" def build(self): """ Build the Kivy GUI. :return: reference to the root Kivy widget """ self.title = "Movies To Watch 2.0 - by Jonache Hilton" self.root = Builder.load_file('app.kv') self.sort_movies(self.sorted_by) return self.root def create_widgets(self): """ Create buttons from list of Movie objects and add them to the GUI. :return: None """ self.clear_movie_widgets() self.top_status_text = "To watch: {}. Watched: {}".format( self.movie_collection.get_number_of_unwatched_movies(), self.movie_collection.get_number_of_watched_movies()) for movie in self.movie_collection.movies: # Create a button for each Movie object, specifying the text temp_button = Button(text=str(movie)) temp_button.bind(on_release=self.press_movie) # Store a reference to the movie object in the button object temp_button.movie = movie self.root.ids.movie_box.add_widget(temp_button) if movie.is_watched: temp_button.background_color = GREEN_COLOUR else: temp_button.background_color = RED_COLOUR def press_movie(self, instance): """ Handle pressing movie buttons, changing watched status of a Movie and updating display. :param instance: the Kivy button instance :return: None """ # Each button is given its own ".movie" object reference, to get it directly movie = instance.movie if movie.is_watched: movie.unwatch() watched_string = "You need to watch" else: movie.watch() watched_string = "You have watched" # Update button text instance.text = str(movie) self.sort_movies(self.sorted_by) self.bottom_status_text = "{} {}".format(watched_string, movie.title) def press_add_movie(self): """ Handle pressing add movie button, adding Movie object to list and updating display. :return: None """ # Check if any errors occur before continuing is_valid_input = self.check_text_input_errors() if is_valid_input: movie_to_add = Movie(self.root.ids.title_input.text, int(self.root.ids.year_input.text), self.root.ids.category_input.text.title(), False) self.movie_collection.add_movie(movie_to_add) self.clear_fields() self.sort_movies(self.sorted_by) self.clear_bottom_status_text() def check_text_input_errors(self): """Check text inputs for a range of errors and returns True if no errors have occurred.""" try: # Check if any of the text inputs are blank if self.root.ids.title_input.text == "" or self.root.ids.year_input.text == "" or \ self.root.ids.category_input.text == "": self.bottom_status_text = "All fields must be completed" return False elif int(self.root.ids.year_input.text) < 0: self.bottom_status_text = "Year must be >= 0" return False elif self.root.ids.category_input.text.title() not in [ "Action", "Comedy", "Documentary", "Drama", "Fantasy", "Thriller" ]: self.bottom_status_text = "The category must be one of the following: Action, Comedy, Documentary," \ " Drama, Fantasy, Thriller" return False except ValueError: self.bottom_status_text = "Please enter a valid number" else: return True def sort_movies(self, sorted_by): """ Sort the movie widgets based on the sorted_by parameter. :param sorted_by: the selected sorting method from the GUI spinner :return: None """ self.sorted_by = sorted_by.lower() # Convert "watched" to "is_watched" as "watched" is not a valid for attrgetter if self.sorted_by == "watched": self.sorted_by = "is_watched" self.movie_collection.sort(self.sorted_by) self.create_widgets() def clear_fields(self): """ Clear the text input fields. :return: None """ self.root.ids.title_input.text = "" self.root.ids.category_input.text = "" self.root.ids.year_input.text = "" def clear_movie_widgets(self): """ Clear all of the widgets that are children of the "movie_box" layout widget. :return: None """ self.root.ids.movie_box.clear_widgets() def clear_bottom_status_text(self): """ Clear the bottom status text. :return: None """ self.bottom_status_text = "" def on_stop(self): """ Save movies back to file when GUI is closed. :return: None """ self.movie_collection.save_movies("movies.csv")
def __init__(self, **kwargs): """Creat the core of Watchmovies app""" Window.size = (900, 700) super(MoviesToWatchApp, self).__init__(**kwargs) self.my_collection = MovieCollection() self.movie_to_show = []
class MoviesToWatchApp(App): """ Kivy app for movie app""" display_sort = StringProperty() sort_type = ListProperty() def display_sorting(self, text): """ show sorting based on the user want""" self.current_display_sorting = text self.show_movie() def __init__(self): """ construct things needed for class""" self.movie_collection = MovieCollection() # call movie collection self.movie_collection.load_movies('movies.csv') # to open csv file self.movie_collection.get_unwatched_movies( ) # getting the number of unwatched movies self.movie_collection.get_watched_movies( ) # getting the number watch movies self.num_of_unwatch = self.movie_collection.unwatch_movie # count unwatched movies self.num_of_watch = self.movie_collection.watch_movie # count watched movie self.movie_dict = { movie.title: movie for movie in self.movie_collection.movies } # to initialize the dictionary self.btn_movie = [] # list data for button self.sorting_type = list(sorting.keys()) # sorting type self.current_display_sorting = self.sorting_type[ +2] # set default sorting super().__init__() def build(self): """Build the Kivy app from the kv file.""" self.title = "Movie to Watch 2.0" # title for the kivy app self.root = Builder.load_file('app.kv') # opening kivy with file name self.show_movie() # to show movies self.root.ids.status_watch.text = ( "To watch: {}. Watched: {}".format(self.num_of_unwatch, self.num_of_watch) ) # display how many movies watched and left to watch return self.root def sort_display(self, text): """display sorting based on the user want""" self.current_display_sorting = text self.show_movie() def clear(self): """ this is to clear data so that the previous movie not added again""" for value in self.btn_movie: self.root.ids.display_movie.remove_widget(value) def show_movie(self): """ displaying movies from list""" self.clear() # clear the input value from widget self.movie_collection.sort_movie(sorting[self.current_display_sorting]) self.btn_movie = [] for movie in self.movie_collection.movies: color = COLORS[movie.is_watched] # the color of the button text = "{} ({} from {})".format(movie.title, movie.category, movie.year) # writing on button if movie.is_watched: # if movie is watched, add this string text += " (Watched)" btn = Button(text=text, id=movie.title, background_color=color) btn.bind(on_release=self.change_watch) self.btn_movie.append(btn) self.root.ids.display_movie.add_widget(btn) def change_watch(self, instance): """ Change interfaces an texts on kivy when the users watch or not watch the movie""" watch = self.movie_dict[instance.id] if watch.is_watched: watch.check_unwatched() if watch.year_level(): self.root.ids.message.text = ("You need to watch {}".format( watch.title)) else: watch.check_unwatched() self.root.ids.message.text = ("You need to watch {}".format( watch.title)) else: watch.check_watched() if watch.year_level(): self.root.ids.message.text = ("You have watched {}".format( watch.title)) else: watch.check_watched() self.root.ids.message.text = ( "you have watched {}.".format(watch.title) ) # if the movie is watched, display this message self.movie_collection.get_unwatched_movies( ) # get number of unwatched movies self.movie_collection.get_watched_movies() # update and display number of movie watched and need to watch self.root.ids.status_watch.text = ("To watch: {}. Watched: {}".format( self.movie_collection.unwatch_movie, self.movie_collection.watch_movie)) instance.background_color = COLORS[ watch.is_watched] # change the button colour self.show_movie() # display new buttons def add_movie(self): """ method to add new movies from users""" title = self.root.ids.title.text # add input title = title.capitalize() year = self.root.ids.year.text category = self.root.ids.category.text error_check = self.error_checker() # error check input # after error checking done if not error_check: m = Movie(title, year, category) # add input to the list self.movie_collection.add_movie(m) self.movie_dict[title] = m # add into the dictionary self.show_movie() self.movie_collection.get_unwatched_movies( ) # to get update number of unwatched movie self.root.ids.status_watch.text = ( "To watch: {}. Watched: {}".format( self.movie_collection.unwatch_movie, self.movie_collection.watch_movie)) self.clear_input_movie( ) # clear input when the movie successfully added self.root.ids.message.text = '' # check the input def error_checker(self): """ error checking user input""" error_check = False title = self.root.ids.title.text # add input from the user title = title.capitalize( ) # auto capitalize so the input will not interfere with sort category = self.root.ids.category.text category = category.capitalize() year = self.root.ids.year.text if category not in ('Action', 'Comedy', 'Documentary', 'Drama', 'Fantasy', 'Thriller'): # prevent user from entering invalid words other than categories self.root.ids.message.text = ( 'Category must be one of Action, Comedy,' ' Documentary, Drama, Fantasy, and Thriller') error_check = True return error_check if not (title and year and category): # asks user to fill in all fields self.root.ids.message.text = 'All fields must be completed.' error_check = True elif not year.isdigit( ): # prevents user from inputting things other than digits self.root.ids.message.text = 'Please enter a valid number.' error_check = True elif len(str(year) ) < 4: # prevent user inputting numbers less than 4 digits self.root.ids.message.text = 'Year must be 4 digits.' error_check = True return error_check def clear_input_movie(self): """ delete all user inputs when the user clicks clear button""" self.root.ids.title.text = "" self.root.ids.year.text = "" self.root.ids.category.text = "" def on_stop(self): """saves updated movies into the csv file""" self.movie_collection.save_file("movies.csv")
def __init__(self, **kwargs): """Load movies from file.""" super().__init__(**kwargs) self.movie_collection = MovieCollection() self.movie_collection.load_movies(FILE_NAME)
class MainApp(App): """ MainApp is a Kivy App for managing watched/unwatched films """ current_state = StringProperty() state_codes = ListProperty() def build(self): self.initCollection() """ Method to save the movies when quiting...""" Window.bind(on_request_close=self.on_request_close) """ build Kivy app from the kv file """ self.title = "Movies to Watch 2.1" self.root = Builder.load_file('app.kv') self.state_codes = sorted(STATES.keys()) self.current_state = self.state_codes[0] self.update_status_label() return self.root def initCollection(self): """ Method to initialize movie and movie collection instances""" self.movie = Movie() self.movie_collection = MovieCollection() self.movie_collection.load_movies(FILE_NAME) self.movie_collection.sort("category") def change_state(self, state_code): """ handle change of spinner selection, output result to sort dinamic widgets """ self.Sort(STATES[state_code]) def update_event_label(self, text): self.root.ids.event_label.text = text def update_status_label(self): watched = self.movie_collection.movie_watched_count() unwatched = self.movie_collection.movie_unwatched_count() self.root.ids.status_label.text = "To watch: {}, Watched: {}".format( unwatched, watched) def Sort(self, key): """ Method to sort movies *when sorting key is 'watched(GUI)/is_watched(app)' it will do reverse sort """ self.root.ids.entries_box.clear_widgets() if key == "is_watched": self.movie_collection.sort(key, reverse=True) else: self.movie_collection.sort(key) self.create_movie_buttons() def clear(self): """Method to clears texts and inputs""" self.root.ids.input_title.text = "" self.root.ids.input_category.text = "" self.root.ids.input_year.text = "" self.update_event_label("") self.root.ids.status_label.text = "" def add_movie(self): """Method to add a new movie and set the statuses""" title = self.root.ids.input_title.text category = self.root.ids.input_category.text year = self.root.ids.input_year.text if not title or not category or not year: self.update_event_label("All fields must be completed") return if category not in ALLOWED_CATEGORIES: self.update_event_label("Allowed categories are " + ", ".join(ALLOWED_CATEGORIES)) return self.movie_collection.add_movie((title, year, category, False)) self.root.ids.entries_box.clear_widgets() self.create_movie_buttons() self.root.ids.input_title.text = "" self.root.ids.input_category.text = "" self.root.ids.input_year.text = "" def create_movie_buttons(self): """ Create the movie buttons and add them to the GUI """ for movie in self.movie_collection.movies: # create a button for each phonebook entry temp_button = Button(text=str(movie)) temp_button.bind(on_release=self.press_entry) temp_button.state = 'down' if movie.is_watched else 'normal' temp_button.movie = movie temp_button.background_color = WATCHED_COLOR if temp_button.state == 'down' else UN_WATCHED_COLOR self.root.ids.entries_box.add_widget(temp_button) def press_entry(self, instance): """ Method to set triggered button's state (activity, color, watched), Method sets status about marked movie, Method called when movie buttons triggered on_release signal""" if instance.state == 'down': instance.state = 'normal' else: instance.state = 'down' name = instance.text if instance.state == 'down': instance.movie.mark_watched() instance.background_color = WATCHED_COLOR self.update_event_label("You have {} {}".format("watched", name)) else: instance.movie.mark_unwatched() instance.background_color = UN_WATCHED_COLOR self.update_status_label() def on_request_close(self, *args, **kwargs): # print cd u("------closeing"*2) self.movie_collection.save_movies(FILE_NAME)
def __init__(self, **kwargs): super().__init__(**kwargs) self.movie_collection = MovieCollection() self.movie_collection.load_movies("movies.csv") self.sorted_by = "year"
def main(): """Main part of the movie.""" print(WELCOME) data_file = "movies.csv" movies = MovieCollection() movies.load_movies(data_file) print("{0} movies loaded from {1}".format(movies.movies_num(), data_file)) while True: print(MENU) movies.sort("is_watched") command = input() command = command.lower() movies_num = movies.movies_num() unwatched_num = movies.watched_num() # read the movie from the list if command == "l": print_inf(movies) # input l read the list elif command == "a": title = input_string("Title: ") category = input_string("Category: ") year = input_int("Year: ") # add movie into movies movies.add_movies(Movie(title, category, year)) print("{} ({} from {}) added to the movie list".format( title, category, year)) # input a read the "add movies" elif command == "m": if unwatched_num >= 1: print_inf(movies) print("Enter the number of a movies to mark as watched") while True: sign_num = input_int("") if sign_num > movies_num: print("Invalid number") elif sign_num > unwatched_num: print("That movie is already watched") break else: sign_index = sign_num - 1 movie = movies.movies[sign_index] title = movie.title category = movie.category movie.watched() print("{0} in {1} visited!".format(title, category)) break else: print("No more movies to watch!") # input m to get the number of wwatched movies and unwatched movies. elif command == "q": movies.save_movies(data_file) print("{0} movies saved to {1}".format(movies_num, data_file)) print("Thanks for watching") break else: print("Invalid menu choice")
def run_tests(): """Test MovieCollection class.""" # Test empty MovieCollection (defaults) print("Test empty MovieCollection:") movie_collection = MovieCollection() print(movie_collection) assert not movie_collection.movies # an empty list is considered False # Test loading movies print("\nTest loading movies:") movie_collection.load_movies('movies.csv') print(movie_collection) assert movie_collection.movies # assuming CSV file is non-empty, non-empty list is considered True # Test adding a new Movie with values print("\nTest adding new movie:") movie_collection.add_movie(Movie("Amazing Grace", 2006, "Drama", False)) print(movie_collection) # Test sorting movies print("\nTest sorting - year:") movie_collection.sort_movies("year") print(movie_collection) print("\nTest sorting - title:") movie_collection.sort_movies("title") print(movie_collection) # Test saving movies (check CSV file manually to see results) movie_collection.save_movies('test.csv') # test number of un/watched movies print("\nTest get_number_watched:") print("expected 2 got {}".format(movie_collection.get_number_watched())) print("\nTest get_number_un_watched") print("expected 4 got {}".format(movie_collection.get_number_un_watched())) # Test length of movies print("\nTest __len__:") print("Expected 6 got {}".format(len(movie_collection))) print("\nTest calculate_longest_title:") print("Expected 34 got {}".format( movie_collection.calculate_longest_title())) print("\nTest list_movies prints to console:") longest_title_length = 35 movie_collection.sort_movies('year') movie_collection.list_movies(longest_title_length) print("\nTest set_movie_watched:") movie_collection.set_movie_watched(0) movie_collection.list_movies(35) movie_collection.set_movie_watched(0) print("\nTest bool_to_status:") print(movie_collection) movie_collection.bool_to_status() print(movie_collection)
class MoviesToWatchApp(App): """Class for GUI movie app""" # Initiate string and list properties sort_by = StringProperty() category = ListProperty() order = ListProperty() current_order = StringProperty() def __init__(self, **kwargs): """Constructor that initiate my collection and movie list""" super(MoviesToWatchApp, self).__init__(**kwargs) self.my_collection = MovieCollection() # Create another list to not TOUCH the original list, in case for back-up or error self.movie_to_show = [] def build(self): """Build from the root kv file""" Window.size = (1000, 800) self.title = "Movie To Watch 2.0 by Van Phuong Nguyen" self.root = Builder.load_file('app.kv') # Set category list self.category = ['Title', 'Year', 'Category', 'Unwatch'] # Default sorting option self.sort_by = self.category[0] # Set order list self.order = ['Ascending Order', 'Descending Order'] # Set default order self.current_order = self.order[0] return self.root def on_start(self): """Start when program start""" self.my_collection.load_movies('movies.csv') # Separate movie list to not change to original list self.movie_to_show = self.my_collection.movies # Make sure the height is such that there is something to scroll. self.root.ids.movie_list.bind( minimum_height=self.root.ids.movie_list.setter('height')) # Show welcome message self.root.ids.message.text = 'Let\'s watch some movies :)' # Load movies self.load_movies() # Show watch and unwatch count self.count_watch() def on_stop(self): """Close program and save movies to the file""" self.my_collection.save_movies('movies.csv') def count_watch(self): """Count movie based on watch and unwatch""" self.root.ids.watch_count.text = 'To watch: {}. Watched: {}'.format( self.my_collection.count_unwatch(), self.my_collection.count_watch()) def sort_movies(self, key): """Sort movie based on key""" # Change current sort_by key based on the key from the sort spinner self.sort_by = key # Load movies based on key provided self.load_movies() def handle_order(self, element): """Sort movie based on order""" # Change current order for loading self.current_order = element # Load movie based on current order self.load_movies() def handle_add_movie(self, title, year, category): """Add movie to movie list""" # Only add movie when title, year, category are provided if title and year and category: # Make sure that title input is correct title_check = self.handle_input(title, is_title=True) # Make sure that category is on category list category_check = self.handle_input(category, is_category=True) # Make sure that year is a number >= 0 year_check = self.handle_input(year, is_year=True) if year_check and category_check and title_check: # Make the input prettier clean_title = ' '.join(title.split()) pretty_title = capwords(clean_title) pretty_category = capwords(category) # Check if movie is already exist if self.check_exist(title_check, year_check, category_check): self.show_popup_message('The movie is already exist') else: # Add movie to list, then reload movie list self.my_collection.add_movie( Movie(title_check, year_check, category_check)) self.load_movies() self.show_popup_message( '{} have been add to movie list'.format(pretty_title)) self.handle_clear_button(is_add=True) else: # Show error if any field blank self.show_popup_message('All fields are required') def load_movies(self): """Load movie to the GUI movie list""" # First clear the current movie on list self.root.ids.movie_list.clear_widgets() # Check the current order desc = self.current_order == 'Descending Order' # Add movies based on current sort_by and order to movie to show list self.movie_to_show = self.my_collection.sort_movies(self.sort_by, desc) # Add buttons based on movie list for index, movie in enumerate(self.movie_to_show): watch_mark = 'watched' if movie.is_watched else '' btn = Button(text='{} ({} from {}) {}'.format( movie.title, movie.category, movie.year, watch_mark), size_hint_y=None, height=30) # Save movie object to btn btn.movie = movie # If pressed, execute handle_watch_movie function btn.bind(on_press=self.handle_watch_movie) # If movie is watched, change background color if watch_mark: btn.background_color = (1, 0.5, 0.5, 1) # Add btn to movie_list id self.root.ids.movie_list.add_widget(btn) def handle_watch_movie(self, instance): """Handle watch movie if user click on movie""" # Movie object is saved to btn.movie >> instance.movie current_movie = instance.movie # Toggle between watch/unwatch current_movie.is_watched = not current_movie.is_watched # Load movie to the GUI list for immediate sorting self.load_movies() # Show message and reload the count watch watch_mark = 'watched' if current_movie.is_watched else 'unwatched' self.root.ids.message.text = 'You have {} {}'.format( watch_mark, current_movie.title) self.count_watch() def show_popup_message(self, text): """Handle show popup message""" self.root.ids.popup_message.text = text self.root.ids.popup.open() def handle_close_popup(self): """Close the popup""" self.root.ids.popup_message.text = '' self.root.ids.popup.dismiss() def handle_clear_button(self, is_add=False, is_search=False): """Clear input when pressed""" # If is_add, clear the add movie input if is_add: self.root.ids.title.text = '' self.root.ids.year.text = '' self.root.ids.category.text = '' # If is_search, clear the search input elif is_search: self.root.ids.title_search.text = '' self.root.ids.year_search.text = '' self.root.ids.category_search.text = '' self.root.ids.watch_search.text = '' # Else clear all else: self.root.ids.title.text = '' self.root.ids.year.text = '' self.root.ids.category.text = '' self.root.ids.title_search.text = '' self.root.ids.year_search.text = '' self.root.ids.category_search.text = '' self.root.ids.watch_search.text = '' def handle_search(self, title, year, category, watch): """Search for movie in list""" # Only search when at least on field is provided if title or category or watch or year: # Check for valid year, category and title title_check = self.handle_input(title, is_title=True, blank=True) year_check = self.handle_input(year, is_year=True, blank=True) category_check = self.handle_input(category, is_category=True, blank=True) watch_check = self.handle_input(watch, is_watch=True, blank=True) # If all are valid, then search if title_check and year_check and category_check and watch_check: # If is_watched is provided, change to bool, else None is_watched = None if watch: is_watched = watch.lower() == 'y' # Search movie method self.my_collection.search_movies(title.strip(), year, category, is_watched) # If found, show movie count and display in GUI movie list if self.my_collection.search_list: self.movie_to_show = self.my_collection.search_list self.show_popup_message('We have found: {} movies'.format( len(self.movie_to_show))) self.load_movies() # Clear the input when completed self.handle_clear_button(is_search=True) # If no movie found, show error message else: self.show_popup_message('No movie found!') else: # If no field is fill in, show error message self.show_popup_message('Your must at least fill in one field') def handle_clear_search(self): """Clear the search and return the original list""" # Set search list to empty self.my_collection.search_list = [] self.handle_clear_button(is_search=True) self.load_movies() def check_exist(self, title, year, category): """Check if movie is existed""" # Filter method based on title, year, category def find_duplicate(movie): filter_title = title.lower() == movie.title.lower() filter_year = int(movie.year) == int(year) filter_category = movie.category.lower() == category.lower() return filter_title and filter_year and filter_category return list(filter(find_duplicate, self.my_collection.movies)) def handle_input(self, input_data, is_title=False, is_year=False, is_category=False, is_watch=False, blank=False): """Handle input data""" # Check if year > 0 and is a number if blank and not input_data: return True else: if is_year: try: year = int(input_data) if year < 0: raise ValueError() return input_data.strip() except ValueError: self.show_popup_message( 'Your year must be a number and greater than 0') # Check if input in category list elif is_category: # Check if category is in the category list if input_data.lower().strip() not in [ 'action', 'comedy', 'documentary', 'drama', 'fantasy', 'thriller' ]: self.show_popup_message( 'Please enter a correct category ' '(Action, Comedy, Documentary, Drama, Fantasy, Thriller)' ) else: return input_data.strip() # Check if valid watch elif is_watch: if input_data.lower() not in ['y', 'n']: self.show_popup_message('Your watch field must be Y or N') else: return True # Check if title is blank elif not input_data.strip() and is_title: self.show_popup_message('Your title must not be blank') else: return input_data.strip()
class MoviesToWatchApp(App): """Kivy app constructor class to create GUI for assignment 2.""" movies_to_watch_text = StringProperty() status_text = StringProperty() current_selection = StringProperty() sort_options = ListProperty() def __init__(self, **kwargs): """Load movies from file.""" super().__init__(**kwargs) self.movie_collection = MovieCollection() self.movie_collection.load_movies(FILE_NAME) def build(self): """Build the Kivy GUI.""" self.title = "Movies To Watch 2.0" self.root = Builder.load_file('app.kv') self.sort_options = sorted(SPINNER_OPTIONS_TO_KEYWORD.keys()) self.current_selection = self.sort_options[0] self.movies_to_watch_text = "To watch: {} Watched: {}".format( self.movie_collection.get_number_un_watched(), self.movie_collection.get_number_watched()) return self.root def create_widgets(self): """Create buttons from MovieCollection entries and add them to the GUI.""" for movie in self.movie_collection.movies: display_color = self.set_button_color(movie) # create a button for each data entry, specifying the text and id temp_button = Button(text=self.display_watched(movie), id=movie.title, background_color=display_color) temp_button.bind(on_release=self.handle_press_movie) # Store a reference to the movie object in the button object temp_button.movie = movie # add the button to the "entries_box" layout widget self.root.ids.entries_box.add_widget(temp_button) @staticmethod def set_button_color(movie): """Set color code depending on movie.is_watched.""" display_color = UN_WATCHED_COLOR if movie.is_watched: display_color = WATCHED_COLOR return display_color def handle_press_movie(self, instance): """Handle pressing movie buttons.""" # toggle watched / un watched if instance.movie.is_watched: instance.movie.un_watch_movie() else: instance.movie.watch_movie() # update button colour instance.background_color = self.set_button_color(instance.movie) # update status text unwatched_string = 'need to watch' if instance.movie.is_watched: unwatched_string = 'have watched' # Change status text if movie is unwatched self.status_text = "You {} {}".format(unwatched_string, instance.movie.title) instance.text = self.display_watched(instance.movie) self.update_movie_buttons() # update movies to watch text self.movies_to_watch_text = "To watch: {} Watched: {}".format( self.movie_collection.get_number_un_watched(), self.movie_collection.get_number_watched()) def change_spinner_selection(self, new_sort_selection): """Handle changing spinner sort condition.""" self.current_selection = new_sort_selection self.update_movie_buttons() def update_movie_buttons(self): """Update movie button order in GUI.""" self.movie_collection.sort_movies( SPINNER_OPTIONS_TO_KEYWORD[self.current_selection]) self.root.ids.entries_box.clear_widgets() self.create_widgets() def handle_press_add_movie(self, new_title, new_year, new_category): """Handle adding a new movie object.""" if self.is_valid_inputs(new_title, new_year, new_category): self.movie_collection.add_movie( Movie(new_title, int(new_year), new_category, False)) # create a button for new movie temp_button = Button(text="{} ({} from {})".format( new_title, new_category, new_year), id=new_title, background_color=UN_WATCHED_COLOR) temp_button.bind(on_release=self.handle_press_movie) # Store a reference to the movie object in the button object temp_button.movie = self.movie_collection.movies[-1] # clear text fields in entry boxes self.clear_fields() self.update_movie_buttons() def is_valid_inputs(self, title, year, category): """Check if user inputs meet requirements.""" input_fields = [title, year, category] # check no empty input fields for field in input_fields: if field == '': self.status_text = "All fields must be completed" return False # check year is a number try: year = int(year) except ValueError: self.status_text = "Please enter a valid number" return False # check year is >=0 if not year >= 0: self.status_text = "Year must be >=0" return False # check valid category valid_category_options = [ "Action", "Comedy", "Documentary", "Drama", 'Fantasy', 'Thriller' ] if category not in valid_category_options: self.status_text = "Category must be one of Action, Comedy, Documentary, Drama, Fantasy, Thriller" return False return True def clear_fields(self): """Clear text inputs and status bar on press.""" self.root.ids.new_title.text = '' self.root.ids.new_year.text = '' self.root.ids.new_category.text = '' self.status_text = '' @staticmethod def display_watched(instance): """Display 'watched' after titles that have been watched.""" watched_string = 'watched' if not instance.is_watched: watched_string = '' button_display_text = instance.text = "{} ({} from {}) {}".format( instance.title, instance.category, instance.year, watched_string) return button_display_text def on_stop(self): """Run when the app exits and save movies to file.""" self.movie_collection.bool_to_status() self.movie_collection.save_movies(FILE_NAME)