Skip to content

Commit f8394ec

Browse files
committed
PCC13 pavelekshin
1 parent 02b7765 commit f8394ec

File tree

3 files changed

+5156
-0
lines changed

3 files changed

+5156
-0
lines changed

13/pavelekshin/directors.py

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import csv
2+
from collections import defaultdict, namedtuple, OrderedDict, ChainMap
3+
from pprint import pprint
4+
5+
MOVIE_DATA = "movie_metadata.csv"
6+
NUM_TOP_DIRECTORS = 20
7+
MIN_MOVIES = 4
8+
MIN_YEAR = 1960
9+
Movie = namedtuple("Movie", "title year score")
10+
11+
12+
def get_movies_by_director():
13+
"""Extracts all movies from csv and stores them in a dictionary
14+
where keys are directors, and values is a list of movies (named tuples)"""
15+
with open(MOVIE_DATA, "r", encoding="utf-8") as f:
16+
reader = csv.DictReader(f)
17+
d = defaultdict(list)
18+
for row in reader:
19+
director = row["director_name"]
20+
title = row["movie_title"].replace("\xa0", "")
21+
year = row["title_year"]
22+
score = float(row["imdb_score"])
23+
if director:
24+
d[director].append(Movie(title=title, year=year, score=score))
25+
return d
26+
27+
28+
def get_average_scores(directors):
29+
"""Filter directors with < MIN_MOVIES and calculate averge score"""
30+
fd, dd = {}, {}
31+
Movie = namedtuple("Movie", "score movies")
32+
for k, v in directors.items():
33+
if len(v) > MIN_MOVIES:
34+
score = _calc_mean(v)
35+
fd[k] = Movie(score=score, movies=v)
36+
sd = OrderedDict(
37+
{k: v for k, v in sorted(fd.items(), key=lambda x: x[1][0], reverse=True)}
38+
)
39+
return sd
40+
41+
42+
def _calc_mean(movies):
43+
"""Helper method to calculate mean of list of Movie namedtuples"""
44+
score = 0
45+
for i in movies:
46+
score += i.score
47+
return round(score / len(movies), 1)
48+
49+
50+
def print_results(directors):
51+
"""Print directors ordered by highest average rating. For each director
52+
print his/her movies also ordered by highest rated movie.
53+
See http://pybit.es/codechallenge13.html for example output"""
54+
fmt_director_entry = "{counter:02}. {director:<52} {avg}"
55+
fmt_movie_entry = "{year} {title:<50} {score}"
56+
sep_line = "-" * 60
57+
for count, (director, movies) in enumerate(directors.items(), 1):
58+
print(fmt_director_entry.format(counter=count, director=director, avg=movies.score))
59+
print(sep_line)
60+
for title, year, score in sorted(
61+
movies.movies, key=lambda x: x[2], reverse=True
62+
):
63+
print(fmt_movie_entry.format(year=year, title=title, score=score))
64+
print("\n")
65+
66+
67+
def main():
68+
"""This is a template, feel free to structure your code differently.
69+
We wrote some tests based on our solution: test_directors.py"""
70+
directors = get_movies_by_director()
71+
directors = get_average_scores(directors)
72+
print_results(directors)
73+
74+
75+
if __name__ == "__main__":
76+
main()

0 commit comments

Comments
 (0)