diff --git a/most_active_mentors.py b/most_active_mentors.py old mode 100644 new mode 100755 index 8af2142..e5f2e78 --- a/most_active_mentors.py +++ b/most_active_mentors.py @@ -1,18 +1,22 @@ """A module for measuring the number of very active mentors -This module provides functions for measuring the number of active mentors on a project. +This module provides functions for measuring the number of active mentors on a +project. -This is measured by number of PR comments. We are working under the assumption that PR -comments are left in good faith to move contributors further instead of nitpicking and -dis-couraging them. +This is measured by number of PR comments. We are working under the assumption +that PR comments are left in good faith to move contributors further instead of +nitpicking and discouraging them. Open questions: - - should there be an option to limit this to certain users, e.g. core maintainers? - - should there be a limit to how many comments per PR we consider to avoid having - the statistic dominated by contested PRs? - - should this metric count consecutive comments coming from the same user as only - one to avoid people unnessesarily splitting their comments to game the metric? - - instead of PR comments should we count PRs on which a username was seen as commenter? + - should there be an option to limit this to certain users, e.g. core + maintainers? + - should there be a limit to how many comments per PR we consider to avoid + having the statistic dominated by contested PRs? + - should this metric count consecutive comments coming from the same user as + only one to avoid people unnessesarily splitting their comments to game the + metric? + - instead of PR comments should we count PRs on which a username was seen as + commenter? Functions: collect_response_usernames( @@ -21,39 +25,38 @@ pull_request: Union[github3.pulls.PullRequest, None], max_comments_to_evaluate, ) -> ____________ - Collect the number of responses per username for single item. Take only top n - comments (max_comments_to_evaluate) into consideration. + Collect the number of responses per username for single item. Take only + top n comments (max_comments_to_evaluate) into consideration. get_number_of_active_reviewers( mentors: List [mentors with metrics) ) -> int active_number Count the number of mentors active at least n times """ -from datetime import datetime, timedelta +from datetime import datetime from typing import List, Union import github3 -import numpy - -from classes import IssueWithMetrics def count_comments_per_user( issue: Union[github3.issues.Issue, None], # type: ignore - discussion: Union[dict, None] = None, pull_request: Union[github3.pulls.PullRequest, None] = None, ready_for_review_at: Union[datetime, None] = None, ignore_users: List[str] = None, - max_comments_to_eval = 20, + max_comments_to_eval=20, + heavily_involved=3, ) -> dict: """Count the number of times a user was seen commenting on a single item. Args: issue (Union[github3.issues.Issue, None]): A GitHub issue. - discussion (Union[dict, None]): A GitHub discussion. - pull_request (Union[github3.pulls.PullRequest, None]): A GitHub pull request. - ignore_users (List[str]): A list of GitHub usernames to ignore. + pull_request (Union[github3.pulls.PullRequest, None]): A GitHub pull + request. ignore_users (List[str]): A list of GitHub usernames to + ignore. max_comments_to_eval: Maximum number of comments per item to look at. + heavily_involved: Maximum number of comments to count for one + user per issue. Returns: dict: A dictionary of usernames seen and number of comments they left. @@ -78,15 +81,17 @@ def count_comments_per_user( ): continue # increase the number of comments left by current user by 1 - if (comment.user.login in mentor_count): - mentor_count[comment.user.login] += 1 + if comment.user.login in mentor_count: + if mentor_count[comment.user.login] < heavily_involved: + mentor_count[comment.user.login] += 1 else: mentor_count[comment.user.login] = 1 # Check if the issue is actually a pull request # so we may also get the first review comment time if pull_request: - review_comments = pull_request.reviews(number=max_comments_to_eval) # type: ignore + review_comments = pull_request.reviews(number=max_comments_to_eval) + # type: ignore for review_comment in review_comments: if ignore_comment( issue.issue.user, @@ -98,7 +103,7 @@ def count_comments_per_user( continue # increase the number of comments left by current user by 1 - if (review_comment.user.login in mentor_count): + if review_comment.user.login in mentor_count: mentor_count[review_comment.user.login] += 1 else: mentor_count[review_comment.user.login] = 1 @@ -133,17 +138,17 @@ def get_mentor_count( """ Calculate the number of active mentors on the project. Args: - mentor_activity (dict: A dictionary with usernames to count of comments left. - cutoff (int: the minimum number of comments a user has to leave to count as active mentor.) + mentor_activity (dict: A dictionary with usernames to count of comments + left. cutoff (int: the minimum number of comments a user has to leave + to count as active mentor.) Returns: int: Number of active mentors """ active_mentor_count = 0 - for mentor, count in mentor_activity.items(): - if (count >= cutoff): + for count in mentor_activity.values(): + if count >= cutoff: active_mentor_count += 1 return active_mentor_count - diff --git a/test_most_active_mentors.py b/test_most_active_mentors.py old mode 100644 new mode 100755 index 76501e9..4e2bcce --- a/test_most_active_mentors.py +++ b/test_most_active_mentors.py @@ -5,19 +5,17 @@ The tests use mock GitHub issues and comments to test the functions' behavior. Classes: - TestCountCommentsPerUser: A class to test the count_comments_per_user function. + TestCountCommentsPerUser: A class testing count_comments_per_user. TestGetMentorCount: A class to test the get_mentor_count function. """ import unittest -from datetime import datetime, timedelta +from datetime import datetime from unittest.mock import MagicMock -from classes import IssueWithMetrics from most_active_mentors import ( count_comments_per_user, - get_mentor_count, ) @@ -27,8 +25,9 @@ class TestCountCommentsPerUser(unittest.TestCase): def test_count_comments_per_user(self): """Test that count_comments_per_user correctly counts user comments. - This test mocks the GitHub connection and issue comments, and checks that - count_comments_per_user correctly considers user comments for counting. + This test mocks the GitHub connection and issue comments, and checks + that count_comments_per_user correctly considers user comments for + counting. """ # Set up the mock GitHub issues @@ -47,8 +46,7 @@ def test_count_comments_per_user(self): # Call the function result = count_comments_per_user(mock_issue1) - expected_result = {"very_active_user": 20} + expected_result = {"very_active_user": 3} # Check the results self.assertEqual(result, expected_result) -