commit e9c82ceae0fb080209d15948e0762dfe012a5e84 Author: stug Date: Wed May 25 15:31:14 2022 +0100 first commit diff --git a/appointments_training_reports.py b/appointments_training_reports.py new file mode 100644 index 0000000..650abe9 --- /dev/null +++ b/appointments_training_reports.py @@ -0,0 +1,233 @@ +#! python3 +#Appointments_Training_Reports.py +#A tool to process Compass Records and produce something human readable using the appointments report +#Licence: +#Written by Stuart Griffiths, stuart.griffiths@birminghamscouts.org.uk +#Started 19/05/2022 +#Version:0.1 +#Released: +#Status: Working - outputs to 2 seperate CSV files +#Inputs: CSV +#Outputs: 2 x CSV +#Next Steps: generate list of unique entries, upload to Drive?, retrive automatically, send e-mails, working directory selection, +#Issues: Lots of repeats (can be filtered for), +#Background IP: https://automatetheboringstuff.com/, Chapter 16 + +#Notes - CSV Column Numbers +#Membership_Number = 0 +#Surname = 2 +#Known_As = 3 +#Email = 4 +#Telephone = 5 +#Member_Role = 8 +#Roll_Status = 11 +#Roll_Start_Date = 9 +#Line_Manager = 13 +#Review_Date = 14 +#County Section = 18 +#District = 19 +#District section = 20 +#Scout_Group = 21 +#CE check = 23 +#Advisory committee approval = 24 +#commissioner approval = 25 +#Committee approval = 26 +#References = 27 +#Wood badge = 35 +#Safety Completed = 36 +#Safety Due = 37 +#Safeguarding completed = 38 +#Safeguarding due = 39 +#First Aid Completed = 40 +#First Aid Due = 41 + +#Libraries +import os #Enables file IO +from pathlib import Path #to work out current working directory +import csv #required to handle csv files +import datetime #required to deal with dates for due items +from dateutil.relativedelta import relativedelta #required to calculate 6 months later + +#import openpyxl + +#CHANGE ALL OF THIS + +#1. Set up Output files +#CSV files +safety_late_mandatory_file = open('safety_late_mandatory_training.csv', 'w', newline='') +safety_late_mandatory = csv.writer(safety_late_mandatory_file) +safety_late_mandatory.writerow(['Membership Number', 'Known_Name', 'Surname', 'E-Mail', 'Telephone', 'Role', 'Line Manager', 'Group', 'District', 'Safety', 'Safeguarding', 'First Aid']) + +safeguarding_late_mandatory_file = open('safeguarding_late_mandatory_training.csv', 'w', newline='') +safeguarding_late_mandatory = csv.writer(safeguarding_late_mandatory_file) +safeguarding_late_mandatory.writerow(['Membership Number', 'Known_Name', 'Surname', 'E-Mail', 'Telephone', 'Role', 'Line Manager', 'Group', 'District', 'Safety', 'Safeguarding', 'First Aid']) + +firstaid_late_mandatory_file = open('firstaid_late_mandatory_training.csv', 'w', newline='') +firstaid_late_mandatory = csv.writer(firstaid_late_mandatory_file) +firstaid_late_mandatory.writerow(['Membership Number', 'Known_Name', 'Surname', 'E-Mail', 'Telephone', 'Role', 'Line Manager', 'Group', 'District', 'Safety', 'Safeguarding', 'First Aid']) + +safety_due_mandatory_file = open('safety_due_mandatory_training.csv', 'w', newline='') +safety_due_mandatory = csv.writer(safety_due_mandatory_file) +safety_due_mandatory.writerow(['Membership Number', 'Known_Name', 'Surname', 'E-Mail', 'Telephone', 'Role', 'Line Manager', 'Group', 'District', 'Safety', 'Safeguarding', 'First Aid']) + +safeguarding_due_mandatory_file = open('safeguarding_due_mandatory_training.csv', 'w', newline='') +safeguarding_due_mandatory = csv.writer(safeguarding_due_mandatory_file) +safeguarding_due_mandatory.writerow(['Membership Number', 'Known_Name', 'Surname', 'E-Mail', 'Telephone', 'Role', 'Line Manager', 'Group', 'District', 'Safety', 'Safeguarding', 'First Aid']) + +firstaid_due_mandatory_file = open('firstaid_due_mandatory_training.csv', 'w', newline='') +firstaid_due_mandatory = csv.writer(firstaid_due_mandatory_file) +firstaid_due_mandatory.writerow(['Membership Number', 'Known_Name', 'Surname', 'E-Mail', 'Telephone', 'Role', 'Line Manager', 'Group', 'District', 'Safety', 'Safeguarding', 'First Aid']) + +#text files +statistics_file = open('_training_statistics_county.txt', 'w') + +#Modules +def training_report(): + #2. Open the file + file_name = str(Path.cwd()) + '/' + str('County Appointments Report (Beta).csv') + input_file = open(file_name) #assumes file is in working directory + #Create a list using the CSV file + input_data_reader = csv.reader(input_file) + input_data = list(input_data_reader) + + #3. Process the data + #Start at row 1 for the OSM output + line_num = int(1) #strips header out + #Ensure we start writing at row 2 + row_num_missing = 2 + row_num_late = 2 + row_num_due = 2 + row_num_started = 2 + #create lists for counting purposes + safety_missing_list = [] + safeguarding_missing_list = [] + firstaid_missing_list = [] + safety_due_list = [] + safeguarding_due_list = [] + firstaid_due_list = [] + while line_num < (len(input_data)-4): #while there is an entry to handle, do this + #3.1 Test 1 - Is Safety Complete? + #Read the column + safety = input_data[line_num][37] + #Check - Is it not blank? + if safety != "": + #Convert string to date object, has to be done here for the blanks! + safety = datetime.datetime.strptime(input_data[line_num][37], "%d/%m/%Y") + #Get today's date + today1 = str(datetime.date.today()) + today = datetime.datetime.strptime(today1, "%Y-%m-%d") #dodgy work around comparing datetime to date object error + #today = now.strftime("%d/%m/%Y") + #Check is it late? + #If date is less than today when program is ran, add to list using membership no, known_name, surname, email, telephone, member_role, manager, group, district, safety due, safeguarding due, first aid due + if safety < today: + safety_late_mandatory.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][8], input_data[line_num][13], input_data[line_num][21], input_data[line_num][19], input_data[line_num][37], '', '']) + member_number = input_data[line_num][0] + #check whether membership number is in the index and add it if not + try: + x = safety_missing_list.index(member_number) + #if it is, nothing happens + except: + #this executes if the membership number is not in the list + safety_missing_list.append(member_number) + #Establish comparative date - set at 6 months + Xmonths_later = datetime.datetime.now() + relativedelta(months=+6) + #If date is less than 6 momths from when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if safety < Xmonths_later and safety >= today: + safety_due_mandatory.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][8], input_data[line_num][13], input_data[line_num][21], input_data[line_num][19], input_data[line_num][37], '', '']) + member_number = input_data[line_num][0] + #check whether membership number is in the index and add it if not + try: + x = safety_due_list.index(member_number) + #if it is, nothing happens + except: + #this executes if the membership number is not in the list + safety_due_list.append(member_number) + #3.2 Test 2 - Is Safeguarding Complete? + #Read the column + safeguarding = input_data[line_num][39] + #Check - Is it not blank? + if safeguarding != "": + #Convert string to date object, has to be done here for the blanks! + safeguarding = datetime.datetime.strptime(input_data[line_num][39], "%d/%m/%Y") + #Already got today's date + #Check is it late? + #If date is less than today when program is ran, add to list using membership no, known_name, surname, email, telephone, member_role, manager, group, district, safety due, safeguarding due, first aid due + if safeguarding < today: + safeguarding_late_mandatory.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][8], input_data[line_num][13], input_data[line_num][21], input_data[line_num][19], '', input_data[line_num][39], '']) + member_number = input_data[line_num][0] + #check whether membership number is in the index and add it if not + try: + x = safeguarding_missing_list.index(member_number) + #if it is, nothing happens + except: + #this executes if the membership number is not in the list + safeguarding_missing_list.append(member_number) + #Check - Is it due soon? + #Already established comparative date - set at 6 months + #If date is less than 6 months from when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if safeguarding < Xmonths_later and safeguarding >= today: + safeguarding_due_mandatory.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][8], input_data[line_num][13], input_data[line_num][21], input_data[line_num][19], '', input_data[line_num][39], '']) + member_number = input_data[line_num][0] + #check whether membership number is in the index and add it if not + try: + x = safeguarding_due_list.index(member_number) + #if it is, nothing happens + except: + #this executes if the membership number is not in the list + safeguarding_due_list.append(member_number) + #3.3 Test 3 - Is First Aid Complete? + #Read the column + firstaid = input_data[line_num][41] + #Check - Is it not blank? + if firstaid != "": + #Convert string to date object, has to be done here for the blanks! + firstaid = datetime.datetime.strptime(input_data[line_num][41], "%d/%m/%Y") + #Already got today's date + #Check is it late? + #If date is less than today when program is ran, add to list using membership no, known_name, surname, email, telephone, member_role, manager, group, district, safety due, safeguarding due, first aid due + if firstaid < today: + firstaid_late_mandatory.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][8], input_data[line_num][13], input_data[line_num][21], input_data[line_num][19], '', '', input_data[line_num][41]]) + member_number = input_data[line_num][0] + #check whether membership number is in the index and add it if not + try: + x = firstaid_missing_list.index(member_number) + #if it is, nothing happens + except: + #this executes if the membership number is not in the list + firstaid_missing_list.append(member_number) + #Check - Is it due soon? + #Already established comparative date - set at 6 months + #If date is less than 6 months from when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if firstaid < Xmonths_later and firstaid >= today: + firstaid_due_mandatory.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][8], input_data[line_num][13], input_data[line_num][21], input_data[line_num][19], '', '', input_data[line_num][41]]) + member_number = input_data[line_num][0] + #check whether membership number is in the index and add it if not + try: + x = firstaid_due_list.index(member_number) + #if it is, nothing happens + except: + #this executes if the membership number is not in the list + firstaid_due_list.append(member_number) + line_num = line_num + 1 #continues the loop + #4: Statistics Generation Time + statistics_file.write('Statistics File for Training Reports\n') + statistics_file.write('====================================\n') + statistics_file.write('\n') + statistics_file.write('Leaders who are late with Safety module: ' + str(len(safety_missing_list))+'\n') + statistics_file.write('Leaders who need to complete the Safety module within 6 months: ' + str(len(safety_due_list))+'\n') + statistics_file.write('Leaders who are late with Safeguarding module: ' + str(len(safeguarding_missing_list))+'\n') + statistics_file.write('Leaders who need to complete the Safeguarding module within 6 months: ' + str(len(safeguarding_due_list))+'\n') + statistics_file.write('Leaders who are late with First Aid module: ' + str(len(firstaid_missing_list))+'\n') + statistics_file.write('Leaders who need to complete the First Aid module within 6 months: ' + str(len(firstaid_due_list))+'\n') + #5: Close files to show they are done + safety_late_mandatory_file.close() + safeguarding_late_mandatory_file.close() + firstaid_late_mandatory_file.close() + safety_due_mandatory_file.close() + safeguarding_due_mandatory_file.close() + firstaid_due_mandatory_file.close() + statistics_file.close() + print("Finished!") + +#Program +training_report() diff --git a/old working versions/appointments_training_reports_v0_1.py b/old working versions/appointments_training_reports_v0_1.py new file mode 100644 index 0000000..650abe9 --- /dev/null +++ b/old working versions/appointments_training_reports_v0_1.py @@ -0,0 +1,233 @@ +#! python3 +#Appointments_Training_Reports.py +#A tool to process Compass Records and produce something human readable using the appointments report +#Licence: +#Written by Stuart Griffiths, stuart.griffiths@birminghamscouts.org.uk +#Started 19/05/2022 +#Version:0.1 +#Released: +#Status: Working - outputs to 2 seperate CSV files +#Inputs: CSV +#Outputs: 2 x CSV +#Next Steps: generate list of unique entries, upload to Drive?, retrive automatically, send e-mails, working directory selection, +#Issues: Lots of repeats (can be filtered for), +#Background IP: https://automatetheboringstuff.com/, Chapter 16 + +#Notes - CSV Column Numbers +#Membership_Number = 0 +#Surname = 2 +#Known_As = 3 +#Email = 4 +#Telephone = 5 +#Member_Role = 8 +#Roll_Status = 11 +#Roll_Start_Date = 9 +#Line_Manager = 13 +#Review_Date = 14 +#County Section = 18 +#District = 19 +#District section = 20 +#Scout_Group = 21 +#CE check = 23 +#Advisory committee approval = 24 +#commissioner approval = 25 +#Committee approval = 26 +#References = 27 +#Wood badge = 35 +#Safety Completed = 36 +#Safety Due = 37 +#Safeguarding completed = 38 +#Safeguarding due = 39 +#First Aid Completed = 40 +#First Aid Due = 41 + +#Libraries +import os #Enables file IO +from pathlib import Path #to work out current working directory +import csv #required to handle csv files +import datetime #required to deal with dates for due items +from dateutil.relativedelta import relativedelta #required to calculate 6 months later + +#import openpyxl + +#CHANGE ALL OF THIS + +#1. Set up Output files +#CSV files +safety_late_mandatory_file = open('safety_late_mandatory_training.csv', 'w', newline='') +safety_late_mandatory = csv.writer(safety_late_mandatory_file) +safety_late_mandatory.writerow(['Membership Number', 'Known_Name', 'Surname', 'E-Mail', 'Telephone', 'Role', 'Line Manager', 'Group', 'District', 'Safety', 'Safeguarding', 'First Aid']) + +safeguarding_late_mandatory_file = open('safeguarding_late_mandatory_training.csv', 'w', newline='') +safeguarding_late_mandatory = csv.writer(safeguarding_late_mandatory_file) +safeguarding_late_mandatory.writerow(['Membership Number', 'Known_Name', 'Surname', 'E-Mail', 'Telephone', 'Role', 'Line Manager', 'Group', 'District', 'Safety', 'Safeguarding', 'First Aid']) + +firstaid_late_mandatory_file = open('firstaid_late_mandatory_training.csv', 'w', newline='') +firstaid_late_mandatory = csv.writer(firstaid_late_mandatory_file) +firstaid_late_mandatory.writerow(['Membership Number', 'Known_Name', 'Surname', 'E-Mail', 'Telephone', 'Role', 'Line Manager', 'Group', 'District', 'Safety', 'Safeguarding', 'First Aid']) + +safety_due_mandatory_file = open('safety_due_mandatory_training.csv', 'w', newline='') +safety_due_mandatory = csv.writer(safety_due_mandatory_file) +safety_due_mandatory.writerow(['Membership Number', 'Known_Name', 'Surname', 'E-Mail', 'Telephone', 'Role', 'Line Manager', 'Group', 'District', 'Safety', 'Safeguarding', 'First Aid']) + +safeguarding_due_mandatory_file = open('safeguarding_due_mandatory_training.csv', 'w', newline='') +safeguarding_due_mandatory = csv.writer(safeguarding_due_mandatory_file) +safeguarding_due_mandatory.writerow(['Membership Number', 'Known_Name', 'Surname', 'E-Mail', 'Telephone', 'Role', 'Line Manager', 'Group', 'District', 'Safety', 'Safeguarding', 'First Aid']) + +firstaid_due_mandatory_file = open('firstaid_due_mandatory_training.csv', 'w', newline='') +firstaid_due_mandatory = csv.writer(firstaid_due_mandatory_file) +firstaid_due_mandatory.writerow(['Membership Number', 'Known_Name', 'Surname', 'E-Mail', 'Telephone', 'Role', 'Line Manager', 'Group', 'District', 'Safety', 'Safeguarding', 'First Aid']) + +#text files +statistics_file = open('_training_statistics_county.txt', 'w') + +#Modules +def training_report(): + #2. Open the file + file_name = str(Path.cwd()) + '/' + str('County Appointments Report (Beta).csv') + input_file = open(file_name) #assumes file is in working directory + #Create a list using the CSV file + input_data_reader = csv.reader(input_file) + input_data = list(input_data_reader) + + #3. Process the data + #Start at row 1 for the OSM output + line_num = int(1) #strips header out + #Ensure we start writing at row 2 + row_num_missing = 2 + row_num_late = 2 + row_num_due = 2 + row_num_started = 2 + #create lists for counting purposes + safety_missing_list = [] + safeguarding_missing_list = [] + firstaid_missing_list = [] + safety_due_list = [] + safeguarding_due_list = [] + firstaid_due_list = [] + while line_num < (len(input_data)-4): #while there is an entry to handle, do this + #3.1 Test 1 - Is Safety Complete? + #Read the column + safety = input_data[line_num][37] + #Check - Is it not blank? + if safety != "": + #Convert string to date object, has to be done here for the blanks! + safety = datetime.datetime.strptime(input_data[line_num][37], "%d/%m/%Y") + #Get today's date + today1 = str(datetime.date.today()) + today = datetime.datetime.strptime(today1, "%Y-%m-%d") #dodgy work around comparing datetime to date object error + #today = now.strftime("%d/%m/%Y") + #Check is it late? + #If date is less than today when program is ran, add to list using membership no, known_name, surname, email, telephone, member_role, manager, group, district, safety due, safeguarding due, first aid due + if safety < today: + safety_late_mandatory.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][8], input_data[line_num][13], input_data[line_num][21], input_data[line_num][19], input_data[line_num][37], '', '']) + member_number = input_data[line_num][0] + #check whether membership number is in the index and add it if not + try: + x = safety_missing_list.index(member_number) + #if it is, nothing happens + except: + #this executes if the membership number is not in the list + safety_missing_list.append(member_number) + #Establish comparative date - set at 6 months + Xmonths_later = datetime.datetime.now() + relativedelta(months=+6) + #If date is less than 6 momths from when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if safety < Xmonths_later and safety >= today: + safety_due_mandatory.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][8], input_data[line_num][13], input_data[line_num][21], input_data[line_num][19], input_data[line_num][37], '', '']) + member_number = input_data[line_num][0] + #check whether membership number is in the index and add it if not + try: + x = safety_due_list.index(member_number) + #if it is, nothing happens + except: + #this executes if the membership number is not in the list + safety_due_list.append(member_number) + #3.2 Test 2 - Is Safeguarding Complete? + #Read the column + safeguarding = input_data[line_num][39] + #Check - Is it not blank? + if safeguarding != "": + #Convert string to date object, has to be done here for the blanks! + safeguarding = datetime.datetime.strptime(input_data[line_num][39], "%d/%m/%Y") + #Already got today's date + #Check is it late? + #If date is less than today when program is ran, add to list using membership no, known_name, surname, email, telephone, member_role, manager, group, district, safety due, safeguarding due, first aid due + if safeguarding < today: + safeguarding_late_mandatory.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][8], input_data[line_num][13], input_data[line_num][21], input_data[line_num][19], '', input_data[line_num][39], '']) + member_number = input_data[line_num][0] + #check whether membership number is in the index and add it if not + try: + x = safeguarding_missing_list.index(member_number) + #if it is, nothing happens + except: + #this executes if the membership number is not in the list + safeguarding_missing_list.append(member_number) + #Check - Is it due soon? + #Already established comparative date - set at 6 months + #If date is less than 6 months from when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if safeguarding < Xmonths_later and safeguarding >= today: + safeguarding_due_mandatory.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][8], input_data[line_num][13], input_data[line_num][21], input_data[line_num][19], '', input_data[line_num][39], '']) + member_number = input_data[line_num][0] + #check whether membership number is in the index and add it if not + try: + x = safeguarding_due_list.index(member_number) + #if it is, nothing happens + except: + #this executes if the membership number is not in the list + safeguarding_due_list.append(member_number) + #3.3 Test 3 - Is First Aid Complete? + #Read the column + firstaid = input_data[line_num][41] + #Check - Is it not blank? + if firstaid != "": + #Convert string to date object, has to be done here for the blanks! + firstaid = datetime.datetime.strptime(input_data[line_num][41], "%d/%m/%Y") + #Already got today's date + #Check is it late? + #If date is less than today when program is ran, add to list using membership no, known_name, surname, email, telephone, member_role, manager, group, district, safety due, safeguarding due, first aid due + if firstaid < today: + firstaid_late_mandatory.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][8], input_data[line_num][13], input_data[line_num][21], input_data[line_num][19], '', '', input_data[line_num][41]]) + member_number = input_data[line_num][0] + #check whether membership number is in the index and add it if not + try: + x = firstaid_missing_list.index(member_number) + #if it is, nothing happens + except: + #this executes if the membership number is not in the list + firstaid_missing_list.append(member_number) + #Check - Is it due soon? + #Already established comparative date - set at 6 months + #If date is less than 6 months from when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if firstaid < Xmonths_later and firstaid >= today: + firstaid_due_mandatory.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][8], input_data[line_num][13], input_data[line_num][21], input_data[line_num][19], '', '', input_data[line_num][41]]) + member_number = input_data[line_num][0] + #check whether membership number is in the index and add it if not + try: + x = firstaid_due_list.index(member_number) + #if it is, nothing happens + except: + #this executes if the membership number is not in the list + firstaid_due_list.append(member_number) + line_num = line_num + 1 #continues the loop + #4: Statistics Generation Time + statistics_file.write('Statistics File for Training Reports\n') + statistics_file.write('====================================\n') + statistics_file.write('\n') + statistics_file.write('Leaders who are late with Safety module: ' + str(len(safety_missing_list))+'\n') + statistics_file.write('Leaders who need to complete the Safety module within 6 months: ' + str(len(safety_due_list))+'\n') + statistics_file.write('Leaders who are late with Safeguarding module: ' + str(len(safeguarding_missing_list))+'\n') + statistics_file.write('Leaders who need to complete the Safeguarding module within 6 months: ' + str(len(safeguarding_due_list))+'\n') + statistics_file.write('Leaders who are late with First Aid module: ' + str(len(firstaid_missing_list))+'\n') + statistics_file.write('Leaders who need to complete the First Aid module within 6 months: ' + str(len(firstaid_due_list))+'\n') + #5: Close files to show they are done + safety_late_mandatory_file.close() + safeguarding_late_mandatory_file.close() + firstaid_late_mandatory_file.close() + safety_due_mandatory_file.close() + safeguarding_due_mandatory_file.close() + firstaid_due_mandatory_file.close() + statistics_file.close() + print("Finished!") + +#Program +training_report() diff --git a/old working versions/training_reports_excel_ver.py b/old working versions/training_reports_excel_ver.py new file mode 100644 index 0000000..7db0c59 --- /dev/null +++ b/old working versions/training_reports_excel_ver.py @@ -0,0 +1,215 @@ +#! python3 +#Training_Reports.py +#A tool to process Compass Records and produce something human readable +#Licence: +#Written by Stuart Griffiths, stuart.griffiths@birminghamscouts.org.uk +#Started 27/03/2022 +#Version:0.1 +#Released: +#Status: Working - outputs to text files +#Inputs: CSV +#Outputs: .txt +#Next Steps: Change to output in spreadsheet, generate list of unique entries +#Background IP: https://automatetheboringstuff.com/, Chapter 16 + +#Notes - CSV Column Numbers +#Membership_Number = 0 +#Surname = 2 +#Known_As = 3 +#Email = 4 +#Member_Role = 5 +#Roll_Status = 6 +#Roll_Start_Date = 7 +#Review_Date = 8 +#District = 12 +#Scout_Group = 14 +#Training_Module = 16 +#Module_Validated_On = 17 +#Module_Renewal_Date = 20 + +#Libraries +import os #Enables file IO +from pathlib import Path #to work out current working directory +import csv #required to handle csv files +import datetime #required to deal with dates for due items +from dateutil.relativedelta import relativedelta #required to calculate 6 months later +import openpyxl + +#1. Set up Output files +#Excel +wb = openpyxl.Workbook() #create new workbook +missing = wb.active +missing.title = 'Missing Training' #always have to change first sheet name +#Structure known_name, surname, email, member_role, group, district, training module +missing['A1'] = 'Known Name' +missing['B1'] = 'Surname' +missing['C1'] = 'E-Mail' +missing['D1'] = 'Role' +missing['E1'] = 'Group' +missing['F1'] = 'District' +missing['G1'] = 'Uncompleted Training Module' +late_mandatory = wb.create_sheet(index=2, title = 'Late Mandatory Training') +late_mandatory['A1'] = 'Known Name' +late_mandatory['B1'] = 'Surname' +late_mandatory['C1'] = 'E-Mail' +late_mandatory['D1'] = 'Role' +late_mandatory['E1'] = 'Group' +late_mandatory['F1'] = 'District' +late_mandatory['G1'] = 'Uncompleted Training Module' +late_mandatory['H1'] = 'Module Renewal Date' +due_mandatory = wb.create_sheet(index=3, title='Due Mandatory Training') +due_mandatory['A1'] = 'Known Name' +due_mandatory['B1'] = 'Surname' +due_mandatory['C1'] = 'E-Mail' +due_mandatory['D1'] = 'Role' +due_mandatory['E1'] = 'Group' +due_mandatory['F1'] = 'District' +due_mandatory['G1'] = 'Uncompleted Training Module' +due_mandatory['H1'] = 'Module Renewal Date' +getting_started = wb.create_sheet(index=4, title='Getting Started Training') +getting_started['A1'] = 'Known Name' +getting_started['B1'] = 'Surname' +getting_started['C1'] = 'E-Mail' +getting_started['D1'] = 'Role' +getting_started['E1'] = 'Group' +getting_started['F1'] = 'District' +getting_started['G1'] = 'Uncompleted Training Module' +getting_started['H1'] = 'Module Renewal Date' + +#text files +#missing_training_list = open('_missing_training.txt', 'w') +#late_mandatory_list = open('_late_mandatory_training.txt', 'w') +#due_mandatory_list = open('_due_mandatory_training.txt', 'w') +#getting_started_list = open('_getting_started_training.txt', 'w') + + +#Modules +def training_report(): + #2. Open the file + file_name = str(Path.cwd()) + '/' + str('CountyTrainingv1.csv') + input_file = open(file_name) #assumes file is in working directory + #Create a list using the CSV file + input_data_reader = csv.reader(input_file) + input_data = list(input_data_reader) + + #3. Process the data + #Start at row 4 for the OSM output + line_num = int(4) #strips header out + #Ensure we start writing at row 2 + row_num_missing = 2 + row_num_late = 2 + row_num_due = 2 + row_num_started = 2 + while line_num < (len(input_data)-4): #while there is an entry to handle, do this + #3.1. Test 1 - Are there training modules left to do? + #Read the column + role_training = input_data[line_num][17] + #Check - Is it blank? Means not completed so of interest + if role_training == "": + #If blank, add to list using known_name, surname, email, member_role, group, district, training module + missing_training_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16]) + missing_training_list.write('\n') #adds new line + #3.2 Test 2 - Are there any core modules to renew? + #Read the column + core_training = input_data[line_num][20] + #Check - Is it not blank? + if core_training != "": + #Slice the chracters to get days, months and year (remember starts 0) + dt = datetime.datetime.now() #need to call this to get current date + core_training_year = int(core_training[6:]) + core_training_month1 = core_training[3:] #removes first 3 characters + core_training_month = int(core_training_month1[:2]) #removes characters after first 2 + core_training_day = int(core_training[:2]) + #Check is it late? + #If year is less than year when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_year < dt.year: + late_madatory['A'] #GOT TO UPDATES HERE, GOT BORED + late_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20] + #late_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + #late_mandatory_list.write('\n') #adds new line + #Else if month is less than month when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_month <= dt.month: + late_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + late_mandatory_list.write('\n') #adds new line + #Else if year is less than year when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_day <= dt.day: + late_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + late_mandatory_list.write('\n') #adds new line + #Check - Is it due soon? + #Establish comparative date - set at 6 months + Xmonths_later = str(datetime.datetime.now() + relativedelta(months=+6)) + Xmonths_later_year = int(Xmonths_later[:4]) + Xmonths_later_month1 = Xmonths_later[5:] #removes first 3 characters + Xmonths_later_month = int(Xmonths_later_month1[:2]) #removes characters after first 2 + Xmonths_later_day1 = Xmonths_later[8:] + Xmonths_later_day = int(Xmonths_later_day1[:2]) + #If year is less than year when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_year < Xmonths_later_year: + due_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + due_mandatory_list.write('\n') #adds new line + #Else if month is less than month when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_month <= Xmonths_later_month: + due_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + due_mandatory_list.write('\n') #adds new line + #Else if year is less than year when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_day <= Xmonths_later_day: + due_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + due_mandatory_list.write('\n') #adds new line + #3.3 Test 3 - Have Getting Started Modules been completed? + #GDPR, Essential Information, Trustee Introduction, Tools for the Role Section Leaders, Managers and Supporters + #Check if Module is one we are interested in + module_name = str(input_data[line_num][16]) + if module_name == 'Essential Information': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + getting_started_list.write('\n') #adds new line + if module_name == 'General Data Protection Regulations': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + getting_started_list.write('\n') #adds new line + if module_name == 'Trustee Introduction': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + getting_started_list.write('\n') #adds new line + if module_name == 'Tools for the Role (Managers and Supporters)': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + getting_started_list.write('\n') #adds new line + if module_name == 'Tools for the Role (Section Leaders)': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + getting_started_list.write('\n') #adds new line + #Safety and Safeguarding + module_name = str(input_data[16]) + if module_name == 'MOGL: Safeguarding': + complete_check = str(input_data[line_num][20]) + #Check: is the date blank? + if complete_check == '': + getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + getting_started_list.write('\n') #adds new line + if module_name == 'MOGL: Safety': + complete_check = str(input_data[line_num][20]) + #Check: is the date blank? + if complete_check == '': + getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + getting_started_list.write('\n') #adds new line + line_num = line_num + 1 #continues the loop + #4: Close text files to show they are done + missing_training_list.close() + late_mandatory_list.close() + due_mandatory_list.close() + getting_started_list.close() + print("Finished!") + +#Program +training_report() diff --git a/old working versions/training_reports_v0_1.py b/old working versions/training_reports_v0_1.py new file mode 100644 index 0000000..6d9dbee --- /dev/null +++ b/old working versions/training_reports_v0_1.py @@ -0,0 +1,166 @@ +#! python3 +#Training_Reports.py +#A tool to process Compass Records and produce something human readable +#Licence: +#Written by Stuart Griffiths, stuart.griffiths@birminghamscouts.org.uk +#Started 27/03/2022 +#Version:0.1 +#Released: +#Status: Working - outputs to text files +#Inputs: CSV +#Outputs: .txt +#Next Steps: Change to output in spreadsheet, generate list of unique entries +#Background IP: https://automatetheboringstuff.com/, Chapter 16 + +#Notes - CSV Column Numbers +#Membership_Number = 0 +#Surname = 2 +#Known_As = 3 +#Email = 4 +#Member_Role = 5 +#Roll_Status = 6 +#Roll_Start_Date = 7 +#Review_Date = 8 +#District = 12 +#Scout_Group = 14 +#Training_Module = 16 +#Module_Validated_On = 17 +#Module_Renewal_Date = 20 + +#Libraries +import os #Enables file IO +from pathlib import Path #to work out current working directory +import csv #required to handle csv files +import datetime #required to deal with dates for due items +from dateutil.relativedelta import relativedelta #required to calculate 6 months later +import openpyxl + +#Modules +def training_report(): + #1. Set up Output files + missing_training_list = open('_missing_training.txt', 'w') + late_mandatory_list = open('_late_mandatory_training.txt', 'w') + due_mandatory_list = open('_due_mandatory_training.txt', 'w') + getting_started_list = open('_getting_started_training.txt', 'w') + + #2. Open the file + file_name = str(Path.cwd()) + '/' + str('CountyTrainingv1.csv') + input_file = open(file_name) #assumes file is in working directory + #Create a list using the CSV file + input_data_reader = csv.reader(input_file) + input_data = list(input_data_reader) + + #3. Process the data + #Start at row 4 for the OSM output + line_num = int(4) #strips header out + while line_num < (len(input_data)-4): #while there is an entry to handle, do this + #3.1. Test 1 - Are there training modules left to do? + #Read the column + role_training = input_data[line_num][17] + #Check - Is it blank? Means not completed so of interest + if role_training == "": + #If blank, add to list using known_name, surname, email, member_role, group, district, training module + missing_training_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16]) + missing_training_list.write('\n') #adds new line + #3.2 Test 2 - Are there any core modules to renew? + #Read the column + core_training = input_data[line_num][20] + #Check - Is it not blank? + if core_training != "": + #Slice the chracters to get days, months and year (remember starts 0) + dt = datetime.datetime.now() #need to call this to get current date + core_training_year = int(core_training[6:]) + core_training_month1 = core_training[3:] #removes first 3 characters + core_training_month = int(core_training_month1[:2]) #removes characters after first 2 + core_training_day = int(core_training[:2]) + #Check is it late? + #If year is less than year when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_year < dt.year: + late_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + late_mandatory_list.write('\n') #adds new line + #Else if month is less than month when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_month <= dt.month: + late_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + late_mandatory_list.write('\n') #adds new line + #Else if year is less than year when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_day <= dt.day: + late_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + late_mandatory_list.write('\n') #adds new line + #Check - Is it due soon? + #Establish comparative date - set at 6 months + Xmonths_later = str(datetime.datetime.now() + relativedelta(months=+6)) + Xmonths_later_year = int(Xmonths_later[:4]) + Xmonths_later_month1 = Xmonths_later[5:] #removes first 3 characters + Xmonths_later_month = int(Xmonths_later_month1[:2]) #removes characters after first 2 + Xmonths_later_day1 = Xmonths_later[8:] + Xmonths_later_day = int(Xmonths_later_day1[:2]) + #If year is less than year when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_year < Xmonths_later_year: + due_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + due_mandatory_list.write('\n') #adds new line + #Else if month is less than month when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_month <= Xmonths_later_month: + due_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + due_mandatory_list.write('\n') #adds new line + #Else if year is less than year when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_day <= Xmonths_later_day: + due_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + due_mandatory_list.write('\n') #adds new line + #3.3 Test 3 - Have Getting Started Modules been completed? + #GDPR, Essential Information, Trustee Introduction, Tools for the Role Section Leaders, Managers and Supporters + #Check if Module is one we are interested in + module_name = str(input_data[line_num][16]) + if module_name == 'Essential Information': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + getting_started_list.write('\n') #adds new line + if module_name == 'General Data Protection Regulations': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + getting_started_list.write('\n') #adds new line + if module_name == 'Trustee Introduction': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + getting_started_list.write('\n') #adds new line + if module_name == 'Tools for the Role (Managers and Supporters)': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + getting_started_list.write('\n') #adds new line + if module_name == 'Tools for the Role (Section Leaders)': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + getting_started_list.write('\n') #adds new line + #Safety and Safeguarding + module_name = str(input_data[16]) + if module_name == 'MOGL: Safeguarding': + complete_check = str(input_data[line_num][20]) + #Check: is the date blank? + if complete_check == '': + getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + getting_started_list.write('\n') #adds new line + if module_name == 'MOGL: Safety': + complete_check = str(input_data[line_num][20]) + #Check: is the date blank? + if complete_check == '': + getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + getting_started_list.write('\n') #adds new line + line_num = line_num + 1 #continues the loop + #4: Close text files to show they are done + missing_training_list.close() + late_mandatory_list.close() + due_mandatory_list.close() + getting_started_list.close() + print("Finished!") + +#Program +training_report() diff --git a/old working versions/training_reports_v0_2.py b/old working versions/training_reports_v0_2.py new file mode 100644 index 0000000..8198743 --- /dev/null +++ b/old working versions/training_reports_v0_2.py @@ -0,0 +1,209 @@ +#! python3 +#Training_Reports.py +#A tool to process Compass Records and produce something human readable +#Licence: +#Written by Stuart Griffiths, stuart.griffiths@birminghamscouts.org.uk +#Started 27/03/2022 +#Version:0.2 +#Released: +#Status: Working - outputs to 4 seperate CSV files +#Inputs: CSV +#Outputs: 4 x CSV +#Next Steps: generate list of unique entries, upload to Drive?, retrive automatically, send e-mails, working directory selection, +#Issues: View for mandatory learning is missing district and group info, need to cross reference +#Background IP: https://automatetheboringstuff.com/, Chapter 16 + +#Notes - CSV Column Numbers +#Membership_Number = 0 +#Surname = 2 +#Known_As = 3 +#Email = 4 +#Member_Role = 5 +#Roll_Status = 6 +#Roll_Start_Date = 7 +#Review_Date = 8 +#District = 12 +#Scout_Group = 14 +#Training_Module = 16 +#Module_Validated_On = 17 +#Module_Renewal_Date = 20 + +#Libraries +import os #Enables file IO +from pathlib import Path #to work out current working directory +import csv #required to handle csv files +import datetime #required to deal with dates for due items +from dateutil.relativedelta import relativedelta #required to calculate 6 months later +#import openpyxl + +#1. Set up Output files +#CSV +missing_file = open('missing_training.csv', 'w', newline='') +missing = csv.writer(missing_file) +missing.writerow(['Known Name', 'Surname', 'E-Mail', 'Role', 'Group', 'District', 'Uncompleted_Training_Module']) + +late_mandatory_file = open('late_mandatory_training.csv', 'w', newline='') +late_mandatory = csv.writer(late_mandatory_file) +late_mandatory.writerow(['Known_Name', 'Surname', 'E-Mail', 'Role', 'Group', 'District', 'Uncompleted_Training_Module', 'Due_Date']) + +due_mandatory_file = open('due_mandatory_training.csv', 'w', newline='') +due_mandatory = csv.writer(due_mandatory_file) +due_mandatory.writerow(['Known_Name', 'Surname', 'E-Mail', 'Role', 'Group', 'District', 'Uncompleted_Training_Module', 'Due_Date']) + +getting_started_file = open('getting_started_training.csv', 'w', newline='') +getting_started = csv.writer(getting_started_file) +getting_started.writerow(['Known_Name', 'Surname', 'E-Mail', 'Role', 'Group', 'District', 'Uncompleted_Training_Module', 'Role_Start_Date']) + +#text files +#missing_training_list = open('_missing_training.txt', 'w') +#late_mandatory_list = open('_late_mandatory_training.txt', 'w') +#due_mandatory_list = open('_due_mandatory_training.txt', 'w') +#getting_started_list = open('_getting_started_training.txt', 'w') + + +#Modules +def training_report(): + #2. Open the file + file_name = str(Path.cwd()) + '/' + str('CountyTrainingv1.csv') + input_file = open(file_name) #assumes file is in working directory + #Create a list using the CSV file + input_data_reader = csv.reader(input_file) + input_data = list(input_data_reader) + + #3. Process the data + #Start at row 4 for the OSM output + line_num = int(4) #strips header out + #Ensure we start writing at row 2 + row_num_missing = 2 + row_num_late = 2 + row_num_due = 2 + row_num_started = 2 + while line_num < (len(input_data)-4): #while there is an entry to handle, do this + #3.1. Test 1 - Are there training modules left to do? + #Read the column + role_training = input_data[line_num][17] + #Check - Is it blank? Means not completed so of interest + if role_training == "": + #If blank, add to list using known_name, surname, email, member_role, group, district, training module + missing.writerow([input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16]]) + #missing_training_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16]) + #missing_training_list.write('\n') #adds new line + #3.2 Test 2 - Are there any core modules to renew? + #Read the column + core_training = input_data[line_num][20] + #Check - Is it not blank? + if core_training != "": + #Slice the chracters to get days, months and year (remember starts 0) + dt = datetime.datetime.now() #need to call this to get current date + core_training_year = int(core_training[6:]) + core_training_month1 = core_training[3:] #removes first 3 characters + core_training_month = int(core_training_month1[:2]) #removes characters after first 2 + core_training_day = int(core_training[:2]) + #Check is it late? + #If year is less than year when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_year < dt.year: + late_mandatory.writerow([input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][20]]) + #late_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + #late_mandatory_list.write('\n') #adds new line + #Else if month is less than month when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_month <= dt.month: + late_mandatory.writerow([input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][20]]) + #late_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + #late_mandatory_list.write('\n') #adds new line + #Else if year is less than year when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_day <= dt.day: + late_mandatory.writerow([input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][20]]) + #late_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + #late_mandatory_list.write('\n') #adds new line + #Check - Is it due soon? + #Establish comparative date - set at 6 months + Xmonths_later = str(datetime.datetime.now() + relativedelta(months=+6)) + Xmonths_later_year = int(Xmonths_later[:4]) + Xmonths_later_month1 = Xmonths_later[5:] #removes first 3 characters + Xmonths_later_month = int(Xmonths_later_month1[:2]) #removes characters after first 2 + Xmonths_later_day1 = Xmonths_later[8:] + Xmonths_later_day = int(Xmonths_later_day1[:2]) + #If year is less than year when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_year < Xmonths_later_year: + due_mandatory.writerow([input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][20]]) + #due_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + #due_mandatory_list.write('\n') #adds new line + #Else if month is less than month when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_month <= Xmonths_later_month: + due_mandatory.writerow([input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][20]]) + #due_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + #due_mandatory_list.write('\n') #adds new line + #Else if year is less than year when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_day <= Xmonths_later_day: + due_mandatory.writerow([input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][20]]) + #due_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + #due_mandatory_list.write('\n') #adds new line + #3.3 Test 3 - Have Getting Started Modules been completed? + #GDPR, Essential Information, Trustee Introduction, Tools for the Role Section Leaders, Managers and Supporters + #Check if Module is one we are interested in + module_name = str(input_data[line_num][16]) + if module_name == 'Essential Information': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started.writerow([input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][7]]) + #getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + #getting_started_list.write('\n') #adds new line + if module_name == 'General Data Protection Regulations': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started.writerow([input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][7]]) + #getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + #getting_started_list.write('\n') #adds new line + if module_name == 'Trustee Introduction': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started.writerow([input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][7]]) + #getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + #getting_started_list.write('\n') #adds new line + if module_name == 'Tools for the Role (Managers and Supporters)': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started.writerow([input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][7]]) + #getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + #getting_started_list.write('\n') #adds new line + if module_name == 'Tools for the Role (Section Leaders)': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started.writerow([input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][7]]) + #getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + #getting_started_list.write('\n') #adds new line + #Safety and Safeguarding + module_name = str(input_data[16]) + if module_name == 'MOGL: Safeguarding': + complete_check = str(input_data[line_num][20]) + #Check: is the date blank? + if complete_check == '': + getting_started.writerow([input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][7]]) + #getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + #getting_started_list.write('\n') #adds new line + if module_name == 'MOGL: Safety': + complete_check = str(input_data[line_num][20]) + #Check: is the date blank? + if complete_check == '': + getting_started.writerow([input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][7]]) + #getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + #getting_started_list.write('\n') #adds new line + line_num = line_num + 1 #continues the loop + #4: Close files to show they are done + #missing_training_list.close() + #late_mandatory_list.close() + #due_mandatory_list.close() + #getting_started_list.close() + missing_file.close() + late_mandatory_file.close() + due_mandatory_file.close() + getting_started_file.close() + print("Finished!") + +#Program +training_report() diff --git a/training_reports.py b/training_reports.py new file mode 100644 index 0000000..4520f97 --- /dev/null +++ b/training_reports.py @@ -0,0 +1,209 @@ +#! python3 +#Training_Reports.py +#A tool to process Compass Records and produce something human readable +#Licence: +#Written by Stuart Griffiths, stuart.griffiths@birminghamscouts.org.uk +#Started 27/03/2022 +#Version:0.3 +#Released: +#Status: Working - outputs to 4 seperate CSV files +#Inputs: CSV +#Outputs: 4 x CSV +#Next Steps: generate list of unique entries, upload to Drive?, retrive automatically, send e-mails, working directory selection, +#Issues: View for mandatory learning is missing district and group info, need to cross reference - could solve through membership number filtering +#Background IP: https://automatetheboringstuff.com/, Chapter 16 + +#Notes - CSV Column Numbers +#Membership_Number = 0 +#Surname = 2 +#Known_As = 3 +#Email = 4 +#Member_Role = 5 +#Roll_Status = 6 +#Roll_Start_Date = 7 +#Review_Date = 8 +#District = 12 +#Scout_Group = 14 +#Training_Module = 16 +#Module_Validated_On = 17 +#Module_Renewal_Date = 20 + +#Libraries +import os #Enables file IO +from pathlib import Path #to work out current working directory +import csv #required to handle csv files +import datetime #required to deal with dates for due items +from dateutil.relativedelta import relativedelta #required to calculate 6 months later +#import openpyxl + +#1. Set up Output files +#CSV +missing_file = open('missing_training.csv', 'w', newline='') +missing = csv.writer(missing_file) +missing.writerow(['Membership Number', 'Known Name', 'Surname', 'E-Mail', 'Role', 'Group', 'District', 'Uncompleted_Training_Module']) + +late_mandatory_file = open('late_mandatory_training.csv', 'w', newline='') +late_mandatory = csv.writer(late_mandatory_file) +late_mandatory.writerow(['Membership Number', 'Known_Name', 'Surname', 'E-Mail', 'Role', 'Group', 'District', 'Uncompleted_Training_Module', 'Due_Date']) + +due_mandatory_file = open('due_mandatory_training.csv', 'w', newline='') +due_mandatory = csv.writer(due_mandatory_file) +due_mandatory.writerow(['Membership Number', 'Known_Name', 'Surname', 'E-Mail', 'Role', 'Group', 'District', 'Uncompleted_Training_Module', 'Due_Date']) + +getting_started_file = open('getting_started_training.csv', 'w', newline='') +getting_started = csv.writer(getting_started_file) +getting_started.writerow(['Membership Number', 'Known_Name', 'Surname', 'E-Mail', 'Role', 'Group', 'District', 'Uncompleted_Training_Module', 'Role_Start_Date']) + +#text files +#missing_training_list = open('_missing_training.txt', 'w') +#late_mandatory_list = open('_late_mandatory_training.txt', 'w') +#due_mandatory_list = open('_due_mandatory_training.txt', 'w') +#getting_started_list = open('_getting_started_training.txt', 'w') + + +#Modules +def training_report(): + #2. Open the file + file_name = str(Path.cwd()) + '/' + str('CountyTrainingv1.csv') + input_file = open(file_name) #assumes file is in working directory + #Create a list using the CSV file + input_data_reader = csv.reader(input_file) + input_data = list(input_data_reader) + + #3. Process the data + #Start at row 4 for the OSM output + line_num = int(4) #strips header out + #Ensure we start writing at row 2 + row_num_missing = 2 + row_num_late = 2 + row_num_due = 2 + row_num_started = 2 + while line_num < (len(input_data)-4): #while there is an entry to handle, do this + #3.1. Test 1 - Are there training modules left to do? + #Read the column + role_training = input_data[line_num][17] + #Check - Is it blank? Means not completed so of interest + if role_training == "": + #If blank, add to list using known_name, surname, email, member_role, group, district, training module + missing.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16]]) + #missing_training_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16]) + #missing_training_list.write('\n') #adds new line + #3.2 Test 2 - Are there any core modules to renew? + #Read the column + core_training = input_data[line_num][20] + #Check - Is it not blank? + if core_training != "": + #Slice the chracters to get days, months and year (remember starts 0) + dt = datetime.datetime.now() #need to call this to get current date + core_training_year = int(core_training[6:]) + core_training_month1 = core_training[3:] #removes first 3 characters + core_training_month = int(core_training_month1[:2]) #removes characters after first 2 + core_training_day = int(core_training[:2]) + #Check is it late? + #If year is less than year when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_year < dt.year: + late_mandatory.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][20]]) + #late_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + #late_mandatory_list.write('\n') #adds new line + #Else if month is less than month when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_month <= dt.month: + late_mandatory.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][20]]) + #late_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + #late_mandatory_list.write('\n') #adds new line + #Else if year is less than year when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_day <= dt.day: + late_mandatory.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][20]]) + #late_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + #late_mandatory_list.write('\n') #adds new line + #Check - Is it due soon? + #Establish comparative date - set at 6 months + Xmonths_later = str(datetime.datetime.now() + relativedelta(months=+6)) + Xmonths_later_year = int(Xmonths_later[:4]) + Xmonths_later_month1 = Xmonths_later[5:] #removes first 3 characters + Xmonths_later_month = int(Xmonths_later_month1[:2]) #removes characters after first 2 + Xmonths_later_day1 = Xmonths_later[8:] + Xmonths_later_day = int(Xmonths_later_day1[:2]) + #If year is less than year when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_year < Xmonths_later_year: + due_mandatory.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][20]]) + #due_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + #due_mandatory_list.write('\n') #adds new line + #Else if month is less than month when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_month <= Xmonths_later_month: + due_mandatory.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][20]]) + #due_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + #due_mandatory_list.write('\n') #adds new line + #Else if year is less than year when program is ran, add to list using known_name, surname, email, member_role, group, district, training module + if core_training_day <= Xmonths_later_day: + due_mandatory.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][20]]) + #due_mandatory_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][20]) + #due_mandatory_list.write('\n') #adds new line + #3.3 Test 3 - Have Getting Started Modules been completed? + #GDPR, Essential Information, Trustee Introduction, Tools for the Role Section Leaders, Managers and Supporters + #Check if Module is one we are interested in + module_name = str(input_data[line_num][16]) + if module_name == 'Essential Information': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][7]]) + #getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + #getting_started_list.write('\n') #adds new line + if module_name == 'General Data Protection Regulations': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][7]]) + #getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + #getting_started_list.write('\n') #adds new line + if module_name == 'Trustee Introduction': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][7]]) + #getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + #getting_started_list.write('\n') #adds new line + if module_name == 'Tools for the Role (Managers and Supporters)': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][7]]) + #getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + #getting_started_list.write('\n') #adds new line + if module_name == 'Tools for the Role (Section Leaders)': + complete_check = str(input_data[line_num][17]) + #Check: is the date blank? + if complete_check == '': + getting_started.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][7]]) + #getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + #getting_started_list.write('\n') #adds new line + #Safety and Safeguarding + module_name = str(input_data[16]) + if module_name == 'MOGL: Safeguarding': + complete_check = str(input_data[line_num][20]) + #Check: is the date blank? + if complete_check == '': + getting_started.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][7]]) + #getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + #getting_started_list.write('\n') #adds new line + if module_name == 'MOGL: Safety': + complete_check = str(input_data[line_num][20]) + #Check: is the date blank? + if complete_check == '': + getting_started.writerow([input_data[line_num][0], input_data[line_num][3], input_data[line_num][2], input_data[line_num][4], input_data[line_num][5], input_data[line_num][14], input_data[line_num][12], input_data[line_num][16], input_data[line_num][7]]) + #getting_started_list.write(input_data[line_num][3] + ' ' + input_data[line_num][2]+' '+ input_data[line_num][4] + ' ' + input_data[line_num][5] + ' ' + input_data[line_num][14] + ' ' + input_data[line_num][12] + ' ' + input_data[line_num][16] + ' ' + input_data[line_num][7]) + #getting_started_list.write('\n') #adds new line + line_num = line_num + 1 #continues the loop + #4: Close files to show they are done + #missing_training_list.close() + #late_mandatory_list.close() + #due_mandatory_list.close() + #getting_started_list.close() + missing_file.close() + late_mandatory_file.close() + due_mandatory_file.close() + getting_started_file.close() + print("Finished!") + +#Program +training_report()