def print_individual_in_table( file_name="individual_metrics_storage", data_dict={}, headings=["EMAIL", "COMMITS", "ADDED", "REMOVED"], ): """Create and print the table using prettytable. Unless specified be sending data_dict=DICT as a parameter, the function. will print from the file. """ # Default headings are mentioned above in the parameter if not len(data_dict) == 0: dictionary = data_dict else: dictionary = json_handler.get_dict_from_json_file(file_name) # Initialize a PrettyTable instance data_table = PrettyTable() # add the username as a category for the headings data_table.field_names = ["Username"] + headings # Loop through every author in the dictionary for author in dictionary: # Add the authors name to the current row current_row = [author] for heading in headings: # add the value from every heading to the current row current_row.append(dictionary[author][heading]) # add row to prettytable instance data_table.add_row(current_row) # reset the current row to an empty list for the next iteration current_row = [] print(data_table)
def print_individual_in_table(file_name): """Create and print the table using prettytable.""" data_table = PrettyTable() current_data = json_handler.get_dict_from_json_file(file_name) dictionary = current_data["INDIVIDUAL_METRICS"] headings = [ "Username", "Email", "Commits", "+", "-", "Total", "Modified Lines", "Lines/Commit", "File Types", ] data_table.field_names = headings for key in dictionary: data_table.add_row( [ key, dictionary[key]["EMAIL"], dictionary[key]["COMMITS"], dictionary[key]["ADDED"], dictionary[key]["REMOVED"], dictionary[key]["TOTAL"], dictionary[key]["MODIFIED"], dictionary[key]["RATIO"], dictionary[key]["FORMAT"], ] ) print(data_table)
def print_individual_in_table(file_name="individual_metrics_storage"): """Create and print the table using prettytable. Use individual_metrics_storage as default file unless otherwise chosen. """ # Initialize pretty table object data_table = PrettyTable() # retreive data from the appropriate json file dictionary = json_handler.get_dict_from_json_file(file_name) # Add needed headings headings = [ "Username", "Email", "Commits", "+", "-", "Total", "Modified Lines", "Lines/Commit", "File Types", ] data_table.field_names = headings for key in dictionary: data_table.add_row([ key, dictionary[key]["EMAIL"], dictionary[key]["COMMITS"], dictionary[key]["ADDED"], dictionary[key]["REMOVED"], dictionary[key]["TOTAL"], dictionary[key]["MODIFIED"], dictionary[key]["RATIO"], dictionary[key]["FORMAT"], ]) print(data_table)
def calculate_individual_metrics(json_file_name): """Retrieve the data from .json file and create a dictionary keyed by user.""" current_data = json_handler.get_dict_from_json_file(json_file_name) # creates a hashmap where the key is the authors username data_dict = {} # Check if RAW_DATA is in json if "RAW_DATA" in current_data.keys(): for key in current_data["RAW_DATA"]: author = key["author_name"] email = key["author_email"] # NOTE check date compatibility with json # date = "N/A" # check if the key already in in the dicitionary if author in data_dict: # condition passed, adds one to the number of commits data_dict[author]["COMMITS"] += 1 else: # condition fails, creates a new key and adds empty data data_dict[author] = { "EMAIL": email, "COMMITS": 1, "ADDED": 0, "REMOVED": 0, "TOTAL": 0, "MODIFIED": 0, "RATIO": 0, "FILES": [], "FORMAT": [], } data_dict[author]["ADDED"] += key["line_added"] data_dict[author]["REMOVED"] += key["line_removed"] # NOTE: consider adding lines of code from data # check if the explored file is not in the list in index seven current_files = key["filename"] # add the current_files to the user files list without duplicates data_dict[author]["FILES"] = list( set(data_dict[author]["FILES"]) | set(current_files) ) # Sort list to ensure consistency when testing data_dict[author]["FILES"] = sorted(data_dict[author]["FILES"]) # iterate through the data to do final calculations for key in data_dict: data_dict[key]["TOTAL"] = ( data_dict[key]["ADDED"] - data_dict[key]["REMOVED"] ) data_dict[key]["MODIFIED"] = ( data_dict[key]["ADDED"] + data_dict[key]["REMOVED"] ) average = get_commit_average( data_dict[key]["MODIFIED"], data_dict[key]["COMMITS"] ) data_dict[key]["RATIO"] = average formats = get_file_formats(data_dict[key]["FILES"]) data_dict[key]["FORMAT"] = formats # Reformat the dictionary as a value of the key INDIVIDUAL_METRICS indvividual_metrics_dict = {"INDIVIDUAL_METRICS": data_dict} return indvividual_metrics_dict return {}
def add_raw_data_to_json(path_to_repo, json_file_name): """Check if raw data is in .json file and collects it if not.""" # get the data from .json file current_data = json_handler.get_dict_from_json_file(json_file_name) # check if data has not been collected and do so if it was not if "RAW_DATA" not in current_data.keys(): print("Raw data has not been collected, collecting it now...") # collects data from data_collection raw_data = {"RAW_DATA": collect_commits_hash(path_to_repo)} # Write raw data to .json file json_handler.add_entry(raw_data, json_file_name) print("Data collected")
def calculate_individual_metrics(json_file_name="raw_data_storage", data_path="./data/"): """Retrieve the data from .json file and create a dictionary keyed by user.""" # retreive data from raw data json current_data = json_handler.get_dict_from_json_file( json_file_name, data_path) # creates a dictionary where the key is the authors username data_dict = {} # Check if RAW_DATA is in json tp prevent a key error if "RAW_DATA" in current_data.keys(): for commit in current_data["RAW_DATA"]: author = commit["author_name"] email = commit["author_email"] # NOTE check date compatibility with json # check if the key already in in the dicitionary if author in data_dict: # condition passed, adds one to the number of commits data_dict[author]["COMMITS"] += 1 else: # condition fails, creates a new key and adds empty data data_dict[author] = { "EMAIL": email, "COMMITS": 1, "ADDED": 0, "REMOVED": 0, "TOTAL": 0, "MODIFIED": 0, "RATIO": 0, "FILES": [], "FORMAT": [], "issues_commented": [], "issues_opened": [], "pull_requests_commented": [], "pull_requests_opened": [], } data_dict[author]["ADDED"] += commit["line_added"] data_dict[author]["REMOVED"] += commit["line_removed"] # check if the explored file is not in the list in index seven current_files = commit["filename"] # add the current_files to the user files list without duplicates data_dict[author]["FILES"] = list( set(data_dict[author]["FILES"]) | set(current_files)) # Sort list to ensure consistency when testing data_dict[author]["FILES"] = sorted(data_dict[author]["FILES"]) return data_dict # if RAW_DATA key was not found, empty dictionary will be returned return {}
def initialize_contributor_data(file_path): """Load a dictionary based upon the given .json file.""" contributor_data = json_handler.get_dict_from_json_file(file_path) return contributor_data
def main(args): """Execute the CLI.""" if args["testwithprintargs"] == "y": for key, value in args.items(): print(key, ":", value) return if not args["clearJson"]: progress_bar = IncrementalBar("Processing", max=3) updated_metrics_dict = json_handler.get_dict_from_json_file( "individual_metrics_storage") # check for data in json file to catch user error in use of -- if len(updated_metrics_dict) == 0: print("\n\n Json empty: no data to retreive\n\n") return progress_bar.next(1) print(" Starting process...") progress_bar.next(1) print(" Retrieved json data") else: progress_bar = IncrementalBar("Processing", max=10) progress_bar.next(1) print(" Starting process...") updated_metrics_dict = collect_process_merge_data(args, progress_bar) if ("INVALID REPO/LINK" or "INVALID LINK") in updated_metrics_dict: return else: pass if args["metric"] in ["t", "team"]: progress_bar.next(1) print(" Calculating Team Scores") team(updated_metrics_dict, args["below"], args["above"], args["within"]) progress_bar.finish() elif args["metric"] in ["i", "individual"]: progress_bar.next(1) print(" Calculating Individual Scores") progress_bar.finish() individual(updated_metrics_dict) elif args["metric"] == "both": progress_bar.next(1) print(" Calculating Scores") progress_bar.finish() individual(updated_metrics_dict) team( updated_metrics_dict, args["below"], args["above"], args["within"], ) else: print( "unknown value given for '-m' '--metric' in command line arguments" ) progress_bar.finish() return # allows the user to enter the web interface if args["web"] is True: os.system("streamlit run src/web_interface.py") else: print( "To see the output in the web, simply add '-w yes' to your command line arguments." )
def web_interface(): """Execute the web interface.""" updated_dict = json_handler.get_dict_from_json_file( "individual_metrics_storage") # Sidebar menu options: add_selectbox = st.sidebar.selectbox( "What feature would you like to view?", ( "Home", "Merge Duplicate Usernames (Recommended)", "Commits By An Individual", "Lines of Code Added, Modified, Deleted by an Individual", "Types of Files Modified by an Individual", "Average Overall Team Score", "Issues Contributed To By An Individual", "Pull Requests Contributed To By An Individual", "Team Members Who Contribute Source Code Without Tests", "Individual Contribution Percentages", ), ) ################### Feature 1 ################### # How many commits did an individual make to a GitHub repository? if add_selectbox == "Home": home_page(updated_dict) elif add_selectbox == "Merge Duplicate Usernames (Recommended)": # while add_selectbox == "Merge Duplicate Usernames (Recommended)": merge_duplicate_users(updated_dict) elif add_selectbox == "Commits By An Individual": graph_commits_by_individual(updated_dict) ################### Feature 2 ################### # How many lines of code did an individual add, modify, and delete? elif add_selectbox == "Lines of Code Added, Modified, Deleted by an Individual": graph_lines_of_code(updated_dict) ################### Feature 3 ################### # What types of files did an individual normally modify in a repository? elif add_selectbox == "Types of Files Modified by an Individual": graph_types_of_files(updated_dict) ################### Feature 4 ################### # What is the overall score for an individual’s contribution to a team project? elif add_selectbox == "Average Overall Team Score": graph_team_score(updated_dict) ################### Feature 5 ################### # Issue info if add_selectbox == "Issues Contributed To By An Individual": graph_issues(updated_dict) ################### Feature 6 ################### # PR info elif add_selectbox == "Pull Requests Contributed To By An Individual": graph_pull_request(updated_dict) ################### Feature 7 ################### # Are there team members who contribute source code without also adding test cases? elif add_selectbox == "Team Members Who Contribute Source Code Without Tests": graph_test_contributions(updated_dict) elif add_selectbox == "Individual Contribution Percentages": graph_percent_individual_contribution(updated_dict) else: pass