├── models ├── __init__.py ├── article.py └── tag.py ├── tests ├── __init__.py ├── test_tag.py ├── test_article_analytics.py └── test_tag_analytics.py ├── tools ├── __init__.py ├── article_fetcher.py ├── tag_analytics.py └── article_analytics.py ├── .gitignore ├── .travis.yml ├── analyzer.py └── README.md /models/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tools/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | __pycache__ 3 | venv 4 | *.pyc 5 | 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "3.6" 4 | script: 5 | - python -m unittest discover tests 6 | -------------------------------------------------------------------------------- /analyzer.py: -------------------------------------------------------------------------------- 1 | from tools import article_analytics, tag_analytics, article_fetcher 2 | import argparse 3 | 4 | 5 | def parse_arguments(): 6 | parser = argparse.ArgumentParser(description="This tool analyzes the popularity of your DEV.to posts") 7 | parser.add_argument('--api-key', action="store", dest="api_key", required=True) 8 | return parser.parse_args() 9 | 10 | 11 | def analyze(api_key): 12 | articles = article_fetcher.get_articles_from_dev(api_key) 13 | article_analytics.analyse(articles) 14 | tags = tag_analytics.get_tags_from_articles(articles) 15 | tag_analytics.analyze(tags) 16 | 17 | 18 | if __name__ == "__main__": 19 | api_key = parse_arguments().api_key 20 | analyze(api_key) 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.com/sandordargo/dev-to-analytics.svg?branch=master)](https://travis-ci.com/sandordargo/dev-to-analytics) 2 | 3 | # Dev.to Analytics 4 | 5 | The purpose of this set of small scripts is to get some insights of your most popular articles and tags posted on [dev.to](https://dev.to/). 6 | 7 | Its usage is very simple. You obviously need an account on [dev.to](https://dev.to/) and post some articles, if you read this, most probably you have already done this. 8 | 9 | Then the next steps are: 10 | * Go your [account settings](https://dev.to/settings/account) and generate a new API key. The description doesn't really matter, but DevToAnalytics should be just fine. 11 | * Copy the just generated active API Key 12 | * Clone this project 13 | * Run `python analyzer.py --api-key ` 14 | * Read the output and get some insights 15 | 16 | # Contribution 17 | 18 | All ideas and code contributions are welcome. Please respect the [PEP 8 guidelines](https://www.python.org/dev/peps/pep-0008/) and provide unit tests, otherwise I won't merge. 19 | 20 | For new ideas, feel free to open issues. 21 | -------------------------------------------------------------------------------- /tests/test_tag.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from models.article import Article 3 | from models.tag import Tag 4 | 5 | 6 | class TestTagAnalytics(unittest.TestCase): 7 | def setUp(self): 8 | self.tags = [Tag("tagname1"), 9 | Tag("tagname2"), 10 | Tag("tagname3") 11 | ] 12 | 13 | def test_article_of_tag_is_registered(self): 14 | article = Article("article", 100, 10, 1, None, ["tagname1"]) 15 | self.tags[0].register_article(article) 16 | self.assertEqual(self.tags[0].views, 100) 17 | self.assertEqual(self.tags[0].reactions, 10) 18 | self.assertEqual(self.tags[0].comments, 1) 19 | self.assertEqual(self.tags[0].articles, [article]) 20 | 21 | def test_article_of_different_tag_is_not_registered(self): 22 | article = Article("article", 100, 10, 1, None, ["tagname0"]) 23 | self.tags[0].register_article(article) 24 | self.assertEqual(self.tags[0].views, 0) 25 | self.assertEqual(self.tags[0].reactions, 0) 26 | self.assertEqual(self.tags[0].comments, 0) 27 | self.assertEqual(len(self.tags[0].articles), 0) 28 | -------------------------------------------------------------------------------- /models/article.py: -------------------------------------------------------------------------------- 1 | class Article: 2 | 3 | def __init__(self, title, views, reactions, comments, creation_time=None, tags=None): 4 | self.title = title 5 | self.views = views 6 | self.reactions = reactions 7 | self.comments = comments 8 | self.creation_time = creation_time 9 | self.tags = tags or [] 10 | 11 | def __eq__(self, other: object) -> bool: 12 | if type(self) != type(other): 13 | return False 14 | return self.title == other.title and \ 15 | self.views == other.views and \ 16 | self.reactions == other.reactions and \ 17 | self.comments == other.comments and \ 18 | self.creation_time == other.creation_time and \ 19 | self.tags == other.tags 20 | 21 | def __repr__(self): 22 | return "Article(title={title}," \ 23 | " views={views}," \ 24 | " reactions={reactions}," \ 25 | " comments={comments}," \ 26 | " creation_time={creation_time}" \ 27 | " tags={tags})\n".format(title=self.title, 28 | views=self.views, 29 | reactions=self.reactions, 30 | comments=self.comments, 31 | creation_time=self.creation_time, 32 | tags=self.tags) 33 | 34 | 35 | -------------------------------------------------------------------------------- /tools/article_fetcher.py: -------------------------------------------------------------------------------- 1 | import http.client 2 | import json 3 | from models import article 4 | import ssl 5 | 6 | def get_articles_from_dev(api_key): 7 | connection = http.client.HTTPSConnection("dev.to", context=ssl._create_unverified_context()) 8 | articles = [] 9 | 10 | current_page = 1 11 | while current_page == 1 or len(articles_on_page) > 0: 12 | json_reply = get_json_data_from_page(connection, current_page, api_key) 13 | articles_on_page = extract_articles_from_json(json_reply) 14 | articles += articles_on_page 15 | current_page += 1 16 | return articles 17 | 18 | 19 | def extract_articles_from_json(json_data): 20 | return [article.Article(article_as_json['title'], 21 | article_as_json["page_views_count"], 22 | article_as_json['positive_reactions_count'], 23 | article_as_json['comments_count'], 24 | article_as_json["published_timestamp"], 25 | article_as_json["tag_list"]) 26 | for article_as_json in json_data] 27 | 28 | 29 | def get_json_data_from_page(connecion, page_index, api_key): 30 | connecion.request("GET", "/api/articles/me?page={}".format(page_index), headers={"api-key": api_key, "User-Agent": "dev-to-analytics"}, ) 31 | response = connecion.getresponse() 32 | if response.code != 200: # not OK 33 | print("Response code: {}".format(response.code)) 34 | exit(-1) 35 | return json.loads(response.read().decode("utf-8")) 36 | -------------------------------------------------------------------------------- /models/tag.py: -------------------------------------------------------------------------------- 1 | class Tag: 2 | 3 | def __init__(self, name, views=None, reactions=None, comments=None, articles=None): 4 | self.name = name 5 | self.views = views or 0 6 | self.reactions = reactions or 0 7 | self.comments = comments or 0 8 | self.articles = articles or [] 9 | 10 | def get_views_per_article(self): 11 | return self.views / len(self.articles) 12 | 13 | def get_comments_per_article(self): 14 | return self.comments / len(self.articles) 15 | 16 | def get_reactions_per_article(self): 17 | return self.reactions / len(self.articles) 18 | 19 | def register_article(self, article): 20 | if self.name in article.tags: 21 | self.views += article.views 22 | self.comments += article.comments 23 | self.reactions += article.reactions 24 | self.articles.append(article) 25 | 26 | def __eq__(self, other: object) -> bool: 27 | if type(self) != type(other): 28 | return False 29 | return self.name == other.name and \ 30 | self.views == other.views and \ 31 | self.reactions == other.reactions and \ 32 | self.comments == other.comments and \ 33 | self.articles == other.articles 34 | 35 | def __hash__(self) -> int: 36 | return super().__hash__() 37 | 38 | def __repr__(self): 39 | return "Tag(name={name}," \ 40 | " views={views}," \ 41 | " reactions={reactions}," \ 42 | " comments={comments}," \ 43 | " articles={articles})".format(name=self.name, 44 | views=self.views, 45 | reactions=self.reactions, 46 | comments=self.comments, 47 | articles=self.articles) 48 | -------------------------------------------------------------------------------- /tools/tag_analytics.py: -------------------------------------------------------------------------------- 1 | from models.tag import Tag 2 | 3 | 4 | def get_tags_from_articles(articles): 5 | tags = [] 6 | for article in articles: 7 | for tag_name in article.tags: 8 | tag_found = False 9 | tag_to_use = None 10 | for tag in tags: 11 | if tag.name == tag_name: 12 | tag_found = True 13 | tag_to_use = tag 14 | 15 | if not tag_found: 16 | new_tag = Tag(tag_name) 17 | tag_to_use = new_tag 18 | tags.append(new_tag) 19 | tag_to_use.register_article(article) 20 | return tags 21 | 22 | 23 | def analyze(tags): 24 | print("Tag analytics") 25 | print("=================") 26 | print("Your most viewed tag is: {} ({} views)".format(get_tag_with_most_views(tags).name, 27 | get_tag_with_most_views(tags).views)) 28 | print("Your tag with the most reactions is: {} ({} reactions)".format( 29 | get_tag_with_most_reactions(tags).name, 30 | get_tag_with_most_reactions(tags).reactions)) 31 | print( 32 | "Your tag with most comments is: {} ({} comments)".format(get_tag_with_most_comments(tags).name, 33 | get_tag_with_most_comments( 34 | tags).comments)) 35 | print("") 36 | print("Your tag with highest views per article ratio is: {} ({} views / article)".format( 37 | get_most_views_per_article_tag(tags).name, 38 | get_most_views_per_article_tag(tags).get_views_per_article())) 39 | print("Your tag with highest reactions per article ratio is: {} ({} reactions / article)".format( 40 | get_most_reactions_per_article_tag(tags).name, 41 | get_most_reactions_per_article_tag(tags).get_reactions_per_article())) 42 | print("Your tag with highest comments per article ratio is: {} ({} comments / article)".format( 43 | get_most_comments_per_article_tag(tags).name, 44 | get_most_comments_per_article_tag(tags).get_comments_per_article())) 45 | 46 | 47 | def get_tag_with_most_views(tags): 48 | return sorted(tags, reverse=True, key=lambda tag: tag.views)[0] 49 | 50 | 51 | def get_tag_with_most_comments(tags): 52 | return sorted(tags, reverse=True, key=lambda tag: tag.comments)[0] 53 | 54 | 55 | def get_tag_with_most_reactions(tags): 56 | return sorted(tags, reverse=True, key=lambda tag: tag.reactions)[0] 57 | 58 | 59 | def get_views_per_article_for_each_tag(tags): 60 | return {tag: tag.get_views_per_article() for tag in tags} 61 | 62 | 63 | def get_reactions_per_article_for_each_tag(tags): 64 | return {tag: tag.reactions / len(tag.articles) for tag in tags} 65 | 66 | 67 | def get_comments_per_article_for_each_tag(tags): 68 | return {tag: tag.comments / len(tag.articles) for tag in tags} 69 | 70 | 71 | def get_most_views_per_article_tag(tags): 72 | return sorted(tags, key=Tag.get_views_per_article, reverse=True)[0] 73 | 74 | 75 | def get_most_reactions_per_article_tag(tags): 76 | return sorted(tags, key=Tag.get_reactions_per_article, reverse=True)[0] 77 | 78 | 79 | def get_most_comments_per_article_tag(tags): 80 | return sorted(tags, key=Tag.get_comments_per_article, reverse=True)[0] 81 | -------------------------------------------------------------------------------- /tests/test_article_analytics.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from models.article import Article 3 | from tools import article_analytics 4 | 5 | 6 | class TestArticleAnalytics(unittest.TestCase): 7 | def setUp(self): 8 | self.articles = [Article("title1", 100, 10, 1, None), 9 | Article("title2", 900, 90, 9, None), 10 | Article("title3", 300, 30, 3, None), 11 | Article("title4", 400, 40, 4, None), 12 | Article("title5", 500, 50, 5, None), 13 | Article("title6", 600, 60, 6, None), 14 | Article("title7", 700, 70, 7, None), 15 | Article("title8", 800, 80, 8, None), 16 | Article("title9", 200, 20, 2, None), 17 | Article("title10", 1000, 100, 10, None), 18 | ] 19 | 20 | def test_total_views(self): 21 | self.assertEqual(5500, article_analytics.get_total_views(self.articles)) 22 | 23 | def test_total_reactions(self): 24 | self.assertEqual(550, article_analytics.get_total_reactions(self.articles)) 25 | 26 | def test_total_comments(self): 27 | self.assertEqual(55, article_analytics.get_total_comments(self.articles)) 28 | 29 | def test_top_1_views(self): 30 | self.assertEqual([Article("title10", 1000, 100, 10, None)], article_analytics.get_top_n_views(self.articles, 1)) 31 | 32 | def test_top_3_views(self): 33 | self.assertEqual([Article("title10", 1000, 100, 10, None), 34 | Article("title2", 900, 90, 9, None), 35 | Article("title8", 800, 80, 8, None), 36 | ], article_analytics.get_top_n_views(self.articles, 3)) 37 | 38 | def test_top_1_comments(self): 39 | self.assertEqual([Article("title10", 1000, 100, 10, None)], article_analytics.get_top_n_comments(self.articles, 1)) 40 | 41 | def test_top_3_comments(self): 42 | self.assertEqual([Article("title10", 1000, 100, 10, None), 43 | Article("title2", 900, 90, 9, None), 44 | Article("title8", 800, 80, 8, None), 45 | ], article_analytics.get_top_n_comments(self.articles, 3)) 46 | 47 | def test_top_1_reactions(self): 48 | self.assertEqual([Article("title10", 1000, 100, 10, None)], article_analytics.get_top_n_reactions(self.articles, 1)) 49 | 50 | def test_top_3_reactions(self): 51 | self.assertEqual([Article("title10", 1000, 100, 10, None), 52 | Article("title2", 900, 90, 9, None), 53 | Article("title8", 800, 80, 8, None), 54 | ], article_analytics.get_top_n_reactions(self.articles, 3)) 55 | 56 | def test_ratio_of_articles_giving_80_percent_views(self): 57 | self.assertEqual(0.6, article_analytics.get_ratio_of_articles_giving_top_n_percent_of_views(self.articles, 80)) 58 | 59 | 60 | def test_ratio_of_articles_giving_80_percent_comments(self): 61 | self.assertEqual(0.6, article_analytics.get_ratio_of_articles_giving_top_n_percent_of_comments(self.articles, 80)) 62 | 63 | 64 | def test_ratio_of_articles_giving_80_percent_reactions(self): 65 | self.assertEqual(0.6, article_analytics.get_ration_of_articles_giving_top_n_percent_of_reactions(self.articles, 80)) 66 | -------------------------------------------------------------------------------- /tests/test_tag_analytics.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from models.article import Article 3 | from models.tag import Tag 4 | from tools import tag_analytics 5 | 6 | 7 | class TestTag(unittest.TestCase): 8 | def setUp(self): 9 | self.mostViewedTag = Tag("tagname1", views=700, reactions=70, comments=7) 10 | self.mostCommentedTag = Tag("tagname2", views=500, reactions=50, comments=10) 11 | self.mostReactedTag = Tag("tagname3", views=600, reactions=100, comments=6) 12 | self.tags = [self.mostViewedTag, 13 | self.mostCommentedTag, 14 | self.mostReactedTag 15 | ] 16 | 17 | def test_get_tag_with_most_views(self): 18 | self.assertEqual(self.mostViewedTag, tag_analytics.get_tag_with_most_views(self.tags)) 19 | 20 | def test_get_tag_with_most_comments(self): 21 | self.assertEqual(self.mostCommentedTag, tag_analytics.get_tag_with_most_comments(self.tags)) 22 | 23 | def test_get_tag_with_most_reactions(self): 24 | self.assertEqual(self.mostReactedTag, tag_analytics.get_tag_with_most_reactions(self.tags)) 25 | 26 | def test_get_views_per_tag(self): 27 | tag = Tag("tagname1") 28 | tag.register_article(Article('t', 300, 0, 0, None, ["tagname1"])) 29 | tag.register_article(Article('t', 500, 0, 0, None, ["tagname1"])) 30 | 31 | self.assertEqual( 32 | {tag: 400}, 33 | tag_analytics.get_views_per_article_for_each_tag([tag]) 34 | ) 35 | 36 | def test_get_reactions_per_tag(self): 37 | tag = Tag("tagname1") 38 | tag.register_article(Article('t', 0, 6, 0, None, ["tagname1"])) 39 | tag.register_article(Article('t', 0, 8, 0, None, ["tagname1"])) 40 | 41 | self.assertEqual( 42 | {tag: 7}, 43 | tag_analytics.get_reactions_per_article_for_each_tag([tag]) 44 | ) 45 | 46 | def test_get_comments_per_tag(self): 47 | tag = Tag("tagname1") 48 | tag.register_article(Article('t', 0, 0, 0, None, ["tagname1"])) 49 | tag.register_article(Article('t', 0, 0, 2, None, ["tagname1"])) 50 | 51 | self.assertEqual( 52 | {tag: 1}, 53 | tag_analytics.get_comments_per_article_for_each_tag([tag]) 54 | ) 55 | 56 | def test_get_most_views_per_article_tag(self): 57 | most_popular_tag = Tag("tagname1") 58 | most_popular_tag.register_article(Article('t', 300, 0, 0, None, ["tagname1"])) 59 | most_popular_tag.register_article(Article('t', 500, 0, 0, None, ["tagname1"])) 60 | 61 | other_tag = Tag("tagname2") 62 | other_tag.register_article(Article('t', 30, 0, 0, None, ["tagname2"])) 63 | other_tag.register_article(Article('t', 500, 0, 0, None, ["tagname2"])) 64 | 65 | self.assertEqual( 66 | most_popular_tag, 67 | tag_analytics.get_most_views_per_article_tag([most_popular_tag, other_tag]) 68 | ) 69 | 70 | def test_get_most_reactions_per_article_tag(self): 71 | most_popular_tag = Tag("tagname1") 72 | most_popular_tag.register_article(Article('t', 0, 6, 0, None, ["tagname1"])) 73 | most_popular_tag.register_article(Article('t', 0, 8, 0, None, ["tagname1"])) 74 | 75 | other_tag = Tag("tagname2") 76 | other_tag.register_article(Article('t', 0, 2, 0, None, ["tagname2"])) 77 | other_tag.register_article(Article('t', 0, 8, 0, None, ["tagname2"])) 78 | 79 | self.assertEqual( 80 | most_popular_tag, 81 | tag_analytics.get_most_reactions_per_article_tag([most_popular_tag, other_tag]) 82 | ) 83 | 84 | def test_get_most_comments_per_article_tag(self): 85 | most_popular_tag = Tag("tagname1") 86 | most_popular_tag.register_article(Article('t', 0, 0, 3, None, ["tagname1"])) 87 | most_popular_tag.register_article(Article('t', 0, 0, 3, None, ["tagname1"])) 88 | 89 | other_tag = Tag("tagname2") 90 | other_tag.register_article(Article('t', 0, 0, 3, None, ["tagname2"])) 91 | other_tag.register_article(Article('t', 0, 0, 1, None, ["tagname2"])) 92 | 93 | self.assertEqual( 94 | most_popular_tag, 95 | tag_analytics.get_most_comments_per_article_tag([most_popular_tag, other_tag]) 96 | ) 97 | -------------------------------------------------------------------------------- /tools/article_analytics.py: -------------------------------------------------------------------------------- 1 | def analyse(articles): 2 | print("Article analytics") 3 | print("=================") 4 | print("Number of your articles: {}".format(len(articles))) 5 | print("Number of your views: {}".format(get_total_views(articles))) 6 | print("Number of reactions received: {}".format(get_total_reactions(articles))) 7 | print("Number of comments received: {}".format(get_total_comments(articles))) 8 | print("") 9 | print("Top 5 most viewed articles:") 10 | for article in get_top_n_views(articles, 5): 11 | print(f"Title: {article.title}, views: {article.views}, reactions: {article.reactions}, comments: {article.comments}") 12 | print("") 13 | print("Top 5 most reacted articles:") 14 | for article in get_top_n_reactions(articles, 5): 15 | print( 16 | f"Title: {article.title}, views: {article.views}, reactions: {article.reactions}, comments: {article.comments}") 17 | print("") 18 | print("Top 5 most commented articles:") 19 | for article in get_top_n_comments(articles, 5): 20 | print( 21 | f"Title: {article.title}, views: {article.views}, reactions: {article.reactions}, comments: {article.comments}") 22 | print("") 23 | print("Percentage of all views of your most viewed article: {:.2f}%".format( 24 | get_part_of_most_viewed_article_out_of_total_views(articles) * 100)) 25 | print("Percentage of all reactions of your article with most reactions: {:.2f}%".format( 26 | get_part_of_article_with_most_reactions_out_of_total_reaction(articles) * 100)) 27 | print("Percentage of all comments of your article with most comments: {:.2f}%".format( 28 | get_part_of_article_with_most_comments_out_of_total_reaction(articles) * 100)) 29 | print("") 30 | print("Percentage of articles giving the {}% of all views: {:.2f}%".format(80, 31 | get_ratio_of_articles_giving_top_n_percent_of_views( 32 | articles, 33 | 80) * 100)) 34 | print("Percentage of articles giving the {}% of all views: {:.2f}%".format(95, 35 | get_ratio_of_articles_giving_top_n_percent_of_views( 36 | articles, 37 | 95) * 100)) 38 | print("Percentage of articles giving the {}% of all reactions: {:.2f}%".format(80, 39 | get_ration_of_articles_giving_top_n_percent_of_reactions( 40 | articles, 41 | 80) * 100)) 42 | print("Percentage of articles giving the {}% of all reactions: {:.2f}%".format(95, 43 | get_ration_of_articles_giving_top_n_percent_of_reactions( 44 | articles, 45 | 95) * 100)) 46 | print("Percentage of articles giving the {}% of all comments: {:.2f}%".format(80, 47 | get_ratio_of_articles_giving_top_n_percent_of_comments( 48 | articles, 49 | 80) * 100)) 50 | print("Percentage of articles giving the {}% of all comments: {:.2f}%".format(95, 51 | get_ratio_of_articles_giving_top_n_percent_of_comments( 52 | articles, 53 | 95) * 100)) 54 | print("") 55 | print("") 56 | 57 | 58 | def get_total_views(articles): 59 | return sum(article.views for article in articles) 60 | 61 | 62 | def get_total_reactions(articles): 63 | return sum(article.reactions for article in articles) 64 | 65 | 66 | def get_total_comments(articles): 67 | return sum(article.comments for article in articles) 68 | 69 | 70 | def get_top_n_views(articles, top_n): 71 | articles.sort(key=lambda article: article.views, reverse=True) 72 | return articles[:top_n] 73 | 74 | 75 | def get_top_n_comments(articles, top_n): 76 | articles.sort(key=lambda article: article.comments, reverse=True) 77 | return articles[:top_n] 78 | 79 | 80 | def get_top_n_reactions(articles, top_n): 81 | articles.sort(key=lambda article: article.reactions, reverse=True) 82 | return articles[:top_n] 83 | 84 | 85 | def get_ratio_of_articles_giving_top_n_percent_of_views(articles, top_n): 86 | articles.sort(key=lambda article: article.views, reverse=True) 87 | return get_ratio_of_articles_giving_top_n_percent_of(get_total_views, articles, top_n) 88 | 89 | 90 | def get_ratio_of_articles_giving_top_n_percent_of_comments(articles, top_n): 91 | articles.sort(key=lambda article: article.comments, reverse=True) 92 | return get_ratio_of_articles_giving_top_n_percent_of(get_total_comments, articles, top_n) 93 | 94 | 95 | def get_ration_of_articles_giving_top_n_percent_of_reactions(articles, top_n): 96 | articles.sort(key=lambda article: article.reactions, reverse=True) 97 | return get_ratio_of_articles_giving_top_n_percent_of(get_total_reactions, articles, top_n) 98 | 99 | 100 | def get_ratio_of_articles_giving_top_n_percent_of(function, articles, top_n): 101 | total = function(articles) 102 | number_of_articles = 1 103 | current_ratio = function(articles[:number_of_articles]) / total 104 | while current_ratio < top_n / 100: 105 | number_of_articles += 1 106 | current_ratio = function(articles[:number_of_articles]) / total 107 | return number_of_articles / len(articles) 108 | 109 | 110 | def get_part_of_most_viewed_article_out_of_total_views(articles): 111 | articles.sort(key=lambda article: article.views, reverse=True) 112 | return articles[0].views / get_total_views(articles) 113 | 114 | 115 | def get_part_of_article_with_most_reactions_out_of_total_reaction(articles): 116 | articles.sort(key=lambda article: article.reactions, reverse=True) 117 | return articles[0].reactions / get_total_reactions(articles) 118 | 119 | 120 | def get_part_of_article_with_most_comments_out_of_total_reaction(articles): 121 | articles.sort(key=lambda article: article.comments, reverse=True) 122 | return articles[0].comments / get_total_comments(articles) 123 | --------------------------------------------------------------------------------