Esempio n. 1
0
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")
Esempio n. 2
0
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")
Esempio n. 3
0
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")