def get_shift_data(path_to_csv, path_to_json_dir, company, department, needs_type='manual'): """ Combines all data into a list of tuples (X_df, y_df). :param path_to_csv: String. Path to csv file of all the shifts. :param path_to_json_dir: String. Path to a directory containing all json schedules. :param company: String. Name of the company. :param department: String. Name of the department in the company. :param needs_type: String. Specifies type of needs to use. 'manual', 'avg', or 'median'. :return: Tuple of (list of (features_df, labels_df), max_scale_value). """ company = org_names_filter(company) department = org_names_filter(department) shift_ratios = create_shift_ratios(path_to_csv, path_to_json_dir) # called for training the model. manual_needs, auto_avg_needs, auto_median_needs = get_needs_methods(path_to_json_dir, company, department) json_schedules = get_json_schedules(path_to_json_dir) if needs_type == 'manual': needs = manual_needs elif needs_type == 'avg': needs = auto_avg_needs elif needs_type == 'median': needs = auto_median_needs else: raise ValueError('Invalid needs_type: \'' + needs_type + '\'. Must be string \'manual\', \'avg\', or \'median\'.') data, max_scale_value = features_targets_from_needs_list(needs, shift_ratios, json_schedules, path_to_json_dir) return data, max_scale_value
def get_full_needs(company, department): # past and present needs company = org_names_filter(company) department = org_names_filter(department) current_needs_dict = get_needs(company, department) past_needs_list = get_past_needs(company, department) past_needs_list.append(current_needs_dict) return past_needs_list
def get_user_data(path_to_csv, company, department, shifts_key): company = org_names_filter(company) department = org_names_filter(department) ratio_a, ratio_b = create_user_ratios(path_to_csv, shifts_key) data = features_targets_from_user_ratios(path_to_csv, ratio_a, ratio_b, shifts_key) return data
def test(company, department): company = org_names_filter(company) department = org_names_filter(department) department_avails, department_time_offs = get_full_avail_and_time_off( company, department) print(department_avails) print(department_time_offs ) # time off might be none. If so, set all the ratios to zero.
def parse_csv(path_to_csv): """ Path :param path_to_csv: Filepath to the csv file with a list of users in the new client company. :return: Dict with structure: {'company': String, 'departments': [String], 'users': [{}, {}, {}]} """ company_name = '' departments_dict = {} users = [] with open(path_to_csv, 'r', encoding='utf-8-sig') as csv_file: reader = csv.reader(csv_file, delimiter=',') for row in reader: company_name = org_names_filter(row[0]) user_departments = row[1].split(', ') for department in user_departments: departments_dict[org_names_filter(department)] = True last_name = row[2] first_name = row[3] email = row[4] position = row[5] is_pt = bool(row[6]) account_type = int(row[7]) current_user_dict = { 'last_name': last_name, # type string 'first_name': first_name, # type string 'email': email, # type string 'position': position, # type string 'departments': user_departments, # type list of strings 'company': company_name, # type string 'is_pt': is_pt, # type int 0 for full time or 1 for part time. Can be bool as well 'account_type': account_type, # type int 0 for basic, 1 for manager, 2 for master 'status': 'active' # type string 'active', 'leave', 'remove' } users.append(current_user_dict) departments_list = list(departments_dict.keys()) parsed_company_dict = { 'company': company_name, 'departments': departments_list, 'users': users } return parsed_company_dict
def get_manager_users(company, department): current_company = get_company_from_local_db(org_names_filter(company)) department_name = org_names_filter(department) users_ref = current_company.collection('manager_users') user_docs = users_ref.where('primary_department', '==', department_name).get() users = [] for user in user_docs: user_dict = user.to_dict() user_dict['is_part_time'] = True users.append(user_dict) return users
def add_manager_user(user_dict, company): user_dict['primary_department'] = org_names_filter(user_dict['departments'][0]) new_user_dict = { 'email': user_dict['email'], 'name': user_dict['name'], 'position': user_dict['position'], 'primary_department': user_dict['primary_department'], 'account_type': user_dict['account_type'], 'status': user_dict['status'] } new_onboarding = { 'is_password_changed': False, 'is_onboard_complete': False } new_avail = { 'is_part_time': user_dict['is_part_time'], } encoded_email = user_dict['encoded_email'] current_company = get_company_by_name(company) current_company.collection('manager_users').document(encoded_email).set(new_user_dict) current_company.collection('manager_users').document(encoded_email + '/scheduling/onboarding').set(new_onboarding) current_company.collection('manager_users').document(encoded_email + '/scheduling/availability').set(new_avail)
def get_full_avail_and_time_off(company, department): company = org_names_filter(company) department = org_names_filter(department) all_department_basic_users = get_users(company, department) availabilities = {} time_offs = {} for user in all_department_basic_users: email = user['email'] encoded_email = encode_email(email) avail_dict = get_availability(company, encoded_email) time_off_dict = get_user_time_off(company, encoded_email) availabilities[email] = avail_dict time_offs[email] = time_off_dict return availabilities, time_offs
def predict_week_users(path_to_csv, company, department, shifts_key, classifier_id=None): """ Predicts the chance of each user having every shift on every day of the week. :param path_to_csv: String. Path to csv file of all the shifts. :param company: String. Name of the company. :param department: String. Name of the department in the company. :param shifts_key: List of strings representing every possible shift to be had, in specific order. :param classifier_id: String. The classifier to use for training and prediction. 'random_forest', 'k_neighbors', 'radius_neighbors' or None. If None, use a neural net from Tensorflow. :return: Tuple. Nested Dict. Day of week -> email -> predictions vector. AND list of users_dicts. AND shifts_key """ company = org_names_filter(company) department = org_names_filter(department) model, day_of_week_key = train_model_for_prediction(path_to_csv, company, department, shifts_key, classifier_id=classifier_id) ratio_a, ratio_b = create_user_ratios(path_to_csv, shifts_key) predictions, users = get_week_prediction(model, ratio_a, ratio_b, company, department, shifts_key) return predictions, users, shifts_key
def add_basic_user(user_dict, company): company_code = get_company_code_by_name(company) user_dict['primary_department'] = org_names_filter(user_dict['departments'][0]) departments = [] for department in user_dict['departments']: department_doc = db.document('companies/' + company_code + '/departments/' + org_names_filter(department)) departments.append(department_doc) user_dict['departments'] = departments new_user_dict = { 'email': user_dict['email'], 'name': user_dict['name'], 'position': user_dict['position'], 'primary_department': user_dict['primary_department'], 'account_type': user_dict['account_type'], 'status': user_dict['status'] } new_onboarding = { 'is_password_changed': False, 'is_onboard_complete': False } new_avail = { 'is_part_time': user_dict['is_part_time'], 'departments': departments } encoded_email = user_dict['encoded_email'] current_company = get_company_by_name(company) current_company.collection('basic_users').document(encoded_email).set(new_user_dict) current_company.collection('basic_users').document(encoded_email + '/scheduling/onboarding').set(new_onboarding) current_company.collection('basic_users').document(encoded_email + '/scheduling/availability').set(new_avail)
def get_users(company, department): # gets all basic users current_company = get_company_from_local_db(org_names_filter(company)) department_name = org_names_filter(department) users_ref = current_company.collection('basic_users') user_docs = users_ref.where('primary_department', '==', department_name).get() users = [] for user in user_docs: user_dict = user.to_dict() availability_ref = get_user_availability_ref(company, encode_email(user_dict['email'])) availability = availability_ref.get() availability_dict = availability.to_dict() user_dict['is_part_time'] = availability_dict['is_part_time'] user_dict['avail'] = availability_dict # new_departments = department_list_to_dict(user_dict['departments']) # user_dict['departments'] = new_departments users.append(user_dict) return users
def create_new_client(path_to_csv): """ :return: The company code. """ new_client_dict = parse_csv(path_to_csv) company_dict = company_to_dict(new_client_dict['company'], new_client_dict['departments']) # Create the company in databases and then add the users add_company(company_dict) email_data = add_new_users(new_client_dict) # email the user their password and the company code company_code = get_company_code_by_name( org_names_filter(new_client_dict['company'])) email_temp_passwords(email_data, company_code)
def add_single_user(user_dict, company): """ Adds a single user to a company. :param user_dict: Dict of the user containing last_name (string), first_name (string), email (string), position (string), departments([string]), is_pt (Bool), account_type (int), status (string) :param company: Name of the company, assumed to be unfiltered. :return: A dict of data containing everything needed for emailing the user their onboarding info. """ last_name = user_dict['last_name'] first_name = user_dict['first_name'] full_name = first_name + ' ' + last_name email = user_dict['email'] position = user_dict['position'] departments = user_dict['departments'] is_pt = user_dict['is_pt'] account_type = user_dict['account_type'] status = user_dict['status'] auto_generated_password = generate_password(randint(10, 15)) is_already_added = False try: auth.create_user(email=email, password=auto_generated_password, display_name=full_name) except AuthError: is_already_added = True user_dict = user_to_dict(position, departments, email, first_name, last_name, is_pt, account_type, status) add_user(user_dict, org_names_filter(company)) email_dict = { 'email_address': email, 'temp_password': auto_generated_password, 'first_name': first_name, 'company_name': company, 'is_already_added': is_already_added } return email_dict
def test(path_to_csv, path_to_json_dir, company, department, needs_type='avg', remove_ratios=False, remove_needs=False, classifier_id=None, include_manager=False): """ :param path_to_csv: String. Path to csv file of all the shifts. :param path_to_json_dir: String. Path to a directory containing all json schedules. :param company: String. Name of the company. :param department: String. Name of the department in the company. :param needs_type: String. Specifies type of needs to use. 'manual', 'avg', or 'median'. :param remove_ratios: Bool. Whether or not the remove the ratios from the features. :param remove_needs: Bool. Whether or not the remove the needs from the features. :param classifier_id: String. The classifier to use for training and prediction of the user predictor. 'random_forest', 'k_neighbors', 'radius_neighbors' or None. If None, use a neural net from Tensorflow. :param include_manager: Bool. Whether or not to include the scheduling manager of the department in the schedule. :return: """ company = org_names_filter(company) department = org_names_filter(department) shifts_predictions, shifts_shifts_key = predict_week_shifts( path_to_csv, path_to_json_dir, company, department, needs_type=needs_type, remove_ratios=remove_ratios, remove_needs=remove_needs) user_predictions, users, shifts_key = predict_week_users( path_to_csv, company, department, shifts_shifts_key, classifier_id=classifier_id) print(shifts_predictions) print(user_predictions) for a, b in zip(shifts_shifts_key, shifts_key): if a != b: raise ValueError('shifts_keys not aligned') for day_of_week, shift_pred in shifts_predictions.items(): needed_shift_indexes = {} for index, shift in enumerate(shift_pred): if shift == 1: needed_shift_indexes[index] = '' # what if a user wins two in one day??? for shift_index in needed_shift_indexes.keys(): current_highest = 0 for email, user_pred in user_predictions[day_of_week].items(): if user_pred[0][shift_index] > current_highest: current_highest = user_pred[0][shift_index] needed_shift_indexes[shift_index] = email print(needed_shift_indexes) print(users[0])