diff --git a/examples/stories/movie_lister/README.rst b/examples/stories/movie_lister/README.rst index c333fe7c..39357662 100644 --- a/examples/stories/movie_lister/README.rst +++ b/examples/stories/movie_lister/README.rst @@ -5,3 +5,13 @@ Example implementation of dependency injection in Python from Martin Fowler's article about dependency injection and inversion of control: http://www.martinfowler.com/articles/injection.html + + +Instructions for running: + +.. code-block:: bash + + python _create_db.py + + python app_csv.py + python app_db.py diff --git a/examples/stories/movie_lister/app_csv.py b/examples/stories/movie_lister/app_csv.py index cf4dd67d..778f440c 100644 --- a/examples/stories/movie_lister/app_csv.py +++ b/examples/stories/movie_lister/app_csv.py @@ -38,7 +38,7 @@ def main(movie_lister): persons and then prints all movies that were released in 2015. :param movie_lister: Movie lister instance - :type movie_lister: :py:class:`movies.listers.MovieLister` + :type movie_lister: movies.listers.MovieLister """ print movie_lister.movies_directed_by('Francis Lawrence') print movie_lister.movies_directed_by('Patricia Riggen') diff --git a/examples/stories/movie_lister/app_db.py b/examples/stories/movie_lister/app_db.py index 3635092d..f5cc5fd5 100644 --- a/examples/stories/movie_lister/app_db.py +++ b/examples/stories/movie_lister/app_db.py @@ -47,7 +47,7 @@ def main(movie_lister): persons and then prints all movies that were released in 2015. :param movie_lister: Movie lister instance - :type movie_lister: :py:class:`movies.listers.MovieLister` + :type movie_lister: movies.listers.MovieLister """ print movie_lister.movies_directed_by('Francis Lawrence') print movie_lister.movies_directed_by('Patricia Riggen') diff --git a/examples/stories/movie_lister/data/.gitignore b/examples/stories/movie_lister/data/.gitignore deleted file mode 100644 index 1bcf41d7..00000000 --- a/examples/stories/movie_lister/data/.gitignore +++ /dev/null @@ -1 +0,0 @@ -movies.* diff --git a/examples/stories/movie_lister/data/movies.csv b/examples/stories/movie_lister/data/movies.csv new file mode 100644 index 00000000..6cb91ddf --- /dev/null +++ b/examples/stories/movie_lister/data/movies.csv @@ -0,0 +1,3 @@ +The Hunger Games: Mockingjay - Part 2,2015,Francis Lawrence +The 33,2015,Patricia Riggen +Star Wars: Episode VII - The Force Awakens,2015,JJ Abrams diff --git a/examples/stories/movie_lister/movies/__init__.py b/examples/stories/movie_lister/movies/__init__.py index b1cdbc7b..f6709119 100644 --- a/examples/stories/movie_lister/movies/__init__.py +++ b/examples/stories/movie_lister/movies/__init__.py @@ -1,4 +1,11 @@ -"""Movies package.""" +"""Movies package. + +Top-level package of movies library. This package contains catalog of movies +module components - ``MoviesModule``. It is recommended to use movies library +functionality by fetching required instances from ``MoviesModule`` providers. + +Each of ``MoviesModule`` providers could be overridden. +""" from . import finders from . import listers diff --git a/examples/stories/movie_lister/movies/finders.py b/examples/stories/movie_lister/movies/finders.py index 21c9f3c9..37cfb48d 100644 --- a/examples/stories/movie_lister/movies/finders.py +++ b/examples/stories/movie_lister/movies/finders.py @@ -1,59 +1,87 @@ -"""Movie finders.""" +"""Movie finders module. + +This module contains all finder implementations. +""" import csv class MovieFinder(object): - """Movie finder.""" + """Movie finder component. + + Movie finder component is responsible for fetching movies data from + different storages. + """ def __init__(self, movie_model): - """Initializer.""" - self.movie_model = movie_model + """Initializer. + + :param movie_model: Movie model's factory + :type movie_model: (object) -> movies.models.Movie + """ + self._movie_model = movie_model def find_all(self): """Return all found movies. - :rtype: list[:py:class:`Movie`] + :rtype: list[movies.models.Movie] :return: List of movie instances. """ raise NotImplementedError() class CsvMovieFinder(MovieFinder): - """Movie finder that fetches movies info from csv file.""" + """Movie finder that fetches movies data from csv file.""" def __init__(self, movie_model, csv_file, delimeter): - """Initializer.""" - self.csv_file = csv_file - self.delimeter = delimeter + """Initializer. + + :param movie_model: Movie model's factory + :type movie_model: (object) -> movies.models.Movie + + :param csv_file: Path to csv file with movies data + :type csv_file: str + + :param delimeter: Csv file's delimeter + :type delimeter: str + """ + self._csv_file = csv_file + self._delimeter = delimeter super(CsvMovieFinder, self).__init__(movie_model) def find_all(self): """Return all found movies. - :rtype: list[:py:class:`Movie`] + :rtype: list[movies.models.Movie] :return: List of movie instances. """ - with open(self.csv_file) as csv_file: - reader = csv.reader(csv_file, delimiter=self.delimeter) - return [self.movie_model(*row) for row in reader] + with open(self._csv_file) as csv_file: + reader = csv.reader(csv_file, delimiter=self._delimeter) + return [self._movie_model(*row) for row in reader] class SqliteMovieFinder(MovieFinder): - """Movie finder that fetches movies info from sqlite database.""" + """Movie finder that fetches movies data from sqlite database.""" def __init__(self, movie_model, database): - """Initializer.""" - self.database = database + """Initializer. + + :param movie_model: Movie model's factory + :type movie_model: (object) -> movies.models.Movie + + :param database: Connection to sqlite database with movies data + :type database: sqlite3.Connection + """ + self._database = database super(SqliteMovieFinder, self).__init__(movie_model) def find_all(self): """Return all found movies. - :rtype: list[:py:class:`Movie`] + :rtype: list[movies.models.Movie] :return: List of movie instances. """ - with self.database: - rows = self.database.execute('SELECT name, year, director ' - 'FROM movies') - return [self.movie_model(*row) for row in rows] + with self._database: + rows = self._database.execute('SELECT name, year, director ' + 'FROM movies') + return [self._movie_model(*row) for row in rows] diff --git a/examples/stories/movie_lister/movies/listers.py b/examples/stories/movie_lister/movies/listers.py index f70aa75f..23448d79 100644 --- a/examples/stories/movie_lister/movies/listers.py +++ b/examples/stories/movie_lister/movies/listers.py @@ -1,11 +1,22 @@ -"""Movie listers.""" +"""Movie listers module. + +This module contains all lister implementations. +""" class MovieLister(object): - """Movie lister.""" + """Movie lister component. + + Movie lister component provides several methods for filtering movies by + specific criteria. + """ def __init__(self, movie_finder): - """Initializer.""" + """Initializer. + + :param movie_finder: Movie finder instance + :type movie_finder: movies.finders.MovieFinder + """ self.movie_finder = movie_finder def movies_directed_by(self, director): @@ -14,7 +25,7 @@ class MovieLister(object): :param director: Director's name :type director: str - :rtype: list[:py:class:`Movie`] + :rtype: list[movies.models.Movie] :return: List of movie instances. """ return [movie for movie in self.movie_finder.find_all() @@ -26,7 +37,7 @@ class MovieLister(object): :param year: Release year :type year: int - :rtype: list[:py:class:`Movie`] + :rtype: list[movies.models.Movie] :return: List of movie instances. """ return [movie for movie in self.movie_finder.find_all() diff --git a/examples/stories/movie_lister/movies/models.py b/examples/stories/movie_lister/movies/models.py index e1b5a174..9e22d693 100644 --- a/examples/stories/movie_lister/movies/models.py +++ b/examples/stories/movie_lister/movies/models.py @@ -1,17 +1,34 @@ -"""Movie models.""" +"""Movie models module. + +This module contains all model implementations. +""" class Movie(object): - """Movie model.""" + """Base movie model.""" def __init__(self, name, year, director): - """Initializer.""" + """Initializer. + + :param name: Movie's name + :type name: str + + :param year: Year, when movie was released + :type year: int + + :param director: Name of person, that directed the movie + :type director: str + """ self.name = str(name) self.year = int(year) self.director = str(director) def __repr__(self): - """Return string representation of movie instance.""" + """Return string representation of movie instance. + + :rtype: str + :return: Movie's string representation. + """ return '{0}(name={1}, year={2}, director={3})'.format( self.__class__.__name__, repr(self.name),