-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrun.py
More file actions
403 lines (375 loc) · 17.1 KB
/
run.py
File metadata and controls
403 lines (375 loc) · 17.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
import gspread
from google.oauth2.service_account import Credentials
import re
SCOPE = [
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/drive.file",
"https://www.googleapis.com/auth/drive"
]
CREDS = Credentials.from_service_account_file('creds.json')
SCOPED_CREDS = CREDS.with_scopes(SCOPE)
GSPREAD_CLIENT = gspread.authorize(SCOPED_CREDS)
SHEET = GSPREAD_CLIENT.open("Learnpulse-Training-Register")
training = SHEET.worksheet('register')
def welcome_function():
"""
This function is the welcome function, it is called
first in the main_program_call function. The function
prints a welcome message and instructions to the user.
"""
print("WELCOME TO LEARNPULSE")
print("Through this program you can submit and search for"
" staff training information\n")
print("What would you like to do?")
while True:
print("\nPlease enter one of the following options to progress:")
print('\n- Enter "input" to add trainee data to the database')
print('- Enter "search" to search for trainee data')
user_branch_choice = input("\nPlease input your command:\n")
branch_choice_lower = user_branch_choice.lower()
if branch_choice_lower == "input":
return branch_choice_lower
elif branch_choice_lower == "search":
return branch_choice_lower
else:
print("\nYou entered an invalid command.\n"
"Please try again...")
continue
# Branching function checks are completed here
def input_function_check():
"""
This function asks the user whether they want to
input data incase they inputted the incorrect command.
The users input is limited to a Y/N for yes or no,
if the user inputs something other than the above, the
input loops and prints a command invalid message.
- If the user enters N, the main_program_call function is called again.
- If the user enters Y, the return is passed back to the main function
and assessed so that the next function in the input branch of the program
can be called.
"""
while True:
print("\nBased on your command, you want to input data -")
print("Is this right?")
print("\nPlease enter one of the following commands to progress:")
print('\n- Enter "Y" for yes')
print('- Enter "N" for no\n')
branch_input_check = input("Please enter your command:\n")
input_check_upper = branch_input_check.upper()
if input_check_upper == "Y":
return input_check_upper
if input_check_upper == "N":
print("\nBacking up to the start of the application.\n")
return main_program_call()
else:
print("\nThat command was invalid, please try again...")
continue
def search_function_check():
"""
This function asks the user whether or not they would like
to proceed with the data search functionality of the program.
It allows the user to get out of the functionality if their previous
input was accidentally incorrect.
The users input is limited to a Y/N for yes or no,
if the user inputs something other than the above, the
input loops and prints a command invalid message.
- If the user enters N, the main_program_call function is called again.
- If the user enters Y, the return is passed back to the main function
and assessed so that the next function in the search branch of the program
can be called.
"""
while True:
print("\nBased on your command, you want to search for trainee data -")
print("Is this right?")
print("\nPlease enter one of the following commands to progress:")
print('\n- Enter "Y" for yes')
print('- Enter "N" for no\n')
branch_search_check = input("Please enter your command:\n")
search_check_upper = branch_search_check.upper()
if search_check_upper == "Y":
return search_check_upper
if search_check_upper == "N":
print("\nBacking up to the start of the application.\n")
return main_program_call()
else:
print("\nThat command was invalid, please try again...")
continue
# Data input functionality begins here
def collect_trainee_personell_data():
"""
This function collects and validates trainee data by asking for
user input whilst at the same time loops the inputs and provides
guidance if the user inputs invalid data.
"""
print("\nLEARNPULSE DATA INPUT FUNCTION RUNNING....")
trainee_personell_data_row = []
""" - FULL NAME:
- This input asks the user for their full name.
- The block is contained in a while loop to loop if invalid data is
provided.
- If valid alpha data only is provided, the loop breaks and the input
from user is appended to the trainee_personell_data_row list.
CODE REFERENCE - I used a reg ex from the answers on this
stack overflow thread:
https://bit.ly/2VIyBJU
"""
while True:
print("You must only use alphabetical characters (a-z & A-Z)\n"
"when inputting a trainee's name.\n")
full_name = input("Enter the trainee's full name:\n")
if re.match("^[a-z A-Z]*$", full_name):
trainee_personell_data_row.append(full_name)
print("Input successfull, thank you...")
break
else:
print("\nSorry, that data was invalid, please try again...")
continue
""" - EMPLOYEE NUMBER:
- This input requests a five digit number from the user
- The block is looped if invalid data is provided.
- If valid data is provided, loop is broken and data is
appended to trainee_data_row list.
"""
while True:
emp_number = input("\nEnter the trainee's 5 digit employee number:\n")
if emp_number.isdigit() and len(emp_number) == 5:
print("Employee number accepted, thank you...")
trainee_personell_data_row.append(emp_number)
break
else:
print(f"You entered {emp_number}, you must enter five digits""\n")
continue
""" - TEAM ASSIGNMENT:
- This code block asks for the user to input a command to
asign the trainee to a team.
- Based on the command inputted, the trainee_team variable is
assigned a value of 'Team One' or Team 2"
- If valid command is entered, variable value is appended to trainee_
data_row list and while loop is broken.
- Error and guidance printed to user if invalid command is entered.
"""
while True:
print("\nTo select the trainee's team, issue a following command:")
print('\n- Enter "1" to assign the trainee to Team 1')
print('- Enter "2" to assign the trainee to Team 2')
trainee_team = int(input("\nPlease issue a team"
" assignment command:\n"))
if trainee_team == 1:
trainee_team = "Team 1"
trainee_personell_data_row.append(trainee_team)
print("\nTeam assignment successful, thank you.")
break
elif trainee_team == 2:
trainee_team = "Team 2"
trainee_personell_data_row.append(trainee_team)
print("\nTeam assignment successful, thank you.")
break
else:
print(f"You entered {trainee_team}, which is an invalid command.")
print("Please try again....\n")
return trainee_personell_data_row
def collect_trainee_training_dates(module):
"""
This function is a refactored version of the large
function I created to obtain trainee data. It
collects the date that the trainee sat the module
passed in via the module parameter each time the function is
called. It asks the user for input and verifies that the
input is formatted in DD/MM/YYYY format using Regular Expressions.
- If correct data inputted, function returns the value to main.
- If incorrect data inputted, loop continues until the data is correct.
CODE ACKNOWLEDGEMENT FOR REG EX -
https://blog.softhints.com/python-regex-match-date/#regexmatchingdate10102015
"""
while True:
print("\nEnter the date that the trainee sat their"
f" {module} Module")
print("The date must be formatted DD/MM/YYYY\n")
mod_date = input("Please enter the date:\n")
date = re.findall(r"[\d]{2}/[\d]{2}/[\d]{4}", mod_date)
if date:
print("\n"f'{mod_date} is a valid input, thank you...')
return mod_date
else:
print('Your input was formatted incorrectly')
print(f"You entered {mod_date}, follow DD/MM/YYYY format.")
continue
def collect_assessment_scores(ass_name, ass_score_total):
"""
This function collects the users assessment scores.
The function takes two arguments:
- ass_name: This takes the assessment name that must be entered
when the function is called.
- ass_score_total - This takes the assessment total score and
is again entered as an argument when the function is called.
This allows for the scope for this function to be universal
"""
while True:
print("\nPlease input the trainee's"
f" {ass_name} assessment score")
print(f"This assessment is out of {ass_score_total}")
ass_score = input(f"Enter the trainee's {ass_name}"
" assessment score:\n")
ass_score = int(ass_score)
if ass_score <= int(ass_score_total):
print("Input successful")
print(f"The trainee scored {ass_score}/{ass_score_total}")
return ass_score
else:
print(f"Sorry, you entered {ass_score}, that data was invalid.")
print("You must input a digit value that is greater than"
f" or equal too {ass_score_total} ")
continue
def update_training_register(comp_data_row):
"""
This function is passed the completed trainee data row
for insertion into the training register. Prior to insertion,
the data is displayed to the user to be checked and the user
is asked for a command to continue. The code from the command
request is duplicated from the input_check function.
"""
while True:
print("\n\nData collection complete, all inputs valid...")
print("Displaying data for review....\n")
print(f"Trainee Name: {comp_data_row[0]}")
print(f"Employee Number: {comp_data_row[1]}")
print(f"Assigned Team: {comp_data_row[2]}")
print("\n"f"Introduction Module Completed: {comp_data_row[3]}")
print(f"Health & Safety Module Completed: {comp_data_row[4]}")
print(f"Policy Adherence Module Completed: {comp_data_row[5]}")
print(f"Regulatory Module Completed: {comp_data_row[6]}")
print(f"Regulatory Assessment Score: {comp_data_row[7]}/33")
print("\nWould you like to insert the above data into the register:")
print('\n- Enter "Y" for yes')
print('- Enter "N" for no\n')
update_register = input("Please enter your command:\n")
update_register_upper = update_register.upper()
if update_register_upper == "Y":
print("\nSkynet activating........ Just kidding ;D.\n")
print("Updating Learnpulse Training Register.....")
register = SHEET.worksheet("register")
register.append_row(comp_data_row)
print("Learnpulse Training Register updated successfully...")
print("Exit function running...")
break
elif update_register_upper == "N":
print("It's not like I was made for this! Restarting....")
main_program_call()
else:
print("\nThat command was invalid, please try again...")
continue
# Search functionality begins here.
def search_function():
"""
This function runs once the user answers "Y" to the
search_function_check question.
Guidance is provided to user as to what they need to do
and an input for a trainee name is provided.
There is a try/except block:
- In the try block, the register is parsed for the text
content of the search variable and if a row with that text content
exists, try block will execute the row from the spreadsheet will be
assigned to the data_exists variable and returned to the main function.
- If the data does not exist or if there is a typo from the user, the
except block will execute and the user can either search again or exit
the program.
CODE REFERENCE - I found advice on the code to implement in the search
function from this stack overflow thread:
https://bit.ly/2VMS4cc
"""
print("\nLEARNPULSE DATA SEARCH FUNCTION RUNNING....\n")
print("This function will search the training"
" register and return a learning report\n")
print("Please note: should you mis-spell the trainee's name\n"
"or if the trainee does not exist, you will receive an error.")
search = input("\nPlease enter the name of the trainee you wish"
" to search for:\n")
try:
data_exists = training.row_values(training.find(search).row)
return data_exists
except Exception:
while True:
print("\nSorry, you have searched incorrectly or data for the\n"
"specified trainee does not yet exist")
print("\nWould you like to search again or exit the program?")
print("Please enter one of the following commands:")
print('\n- Enter "S" to search again')
print('- Enter "E" to exit the program')
data_error_cont = input("\nPlease enter your command:\n")
data_error_cont_upper = data_error_cont.upper()
if data_error_cont_upper == "S":
return data_error_cont_upper
elif data_error_cont_upper == "E":
return data_error_cont_upper
else:
print("That command was invalid, please try again...")
continue
def display_searched_data(found_row):
"""
This function receives the list from returned from the
search_function where a match has been found in the
register google sheet and displays the training data for
the trainee the user searched for.
"""
print("\nTrainee located, displaying learning report:\n")
print(f"Trainee Name: {found_row[0]}")
print(f"Employee Number: {found_row[1]}")
print(f"Assigned Team: {found_row[2]}")
print("\n"f"Introduction Module Completed: {found_row[3]}")
print(f"Health & Safety Module Completed: {found_row[4]}")
print(f"Policy Adherence Module Completed: {found_row[5]}")
print(f"Regulatory Module Completed: {found_row[6]}")
print(f"Regulatory Assessment Score: {found_row[7]}/33")
while True:
print("Would you like to search for another trainee or exit?")
print("\nEnter one of the following commands to proceed:")
print('\n- Enter "S" to search again')
print('- Enter "E" to exit the program')
search_again = input("\nPlease enter your command:\n")
search_again_upper = search_again.upper()
if search_again_upper == "S":
return search_again_upper
elif search_again_upper == "E":
return search_again_upper
else:
print("That command was invalid, please try again...")
continue
def main_program_call():
"""
This function is the main function in the program through which
all other functions are called.
"""
branching_variable = welcome_function()
if branching_variable == "input":
input_check_proceed = input_function_check()
if input_check_proceed == "Y":
trainee_data_row = collect_trainee_personell_data()
intro_mod_date = collect_trainee_training_dates("Introduction")
trainee_data_row.append(intro_mod_date)
hs_mod_date = collect_trainee_training_dates("Health & Safety")
trainee_data_row.append(hs_mod_date)
pam_mod_date = collect_trainee_training_dates("Policy Adherence")
trainee_data_row.append(pam_mod_date)
reg_mod_date = collect_trainee_training_dates("Regulatory")
trainee_data_row.append(reg_mod_date)
reg_ass_score = collect_assessment_scores("Regulatory", "33")
trainee_data_row.append(reg_ass_score)
update_training_register(trainee_data_row)
else:
search_check_proceed = search_function_check()
if search_check_proceed == "Y":
while True:
existing_trainee_data = search_function()
if existing_trainee_data == "S":
continue
if existing_trainee_data == "E":
print("Thanks for using Learnpulse, goodbye for now!")
raise SystemExit
else:
search_loop = display_searched_data(existing_trainee_data)
if search_loop == "S":
continue
else:
print("Thanks for using Learnpulse, goodbye for now!")
raise SystemExit
main_program_call()