Skip to content

Instantly share code, notes, and snippets.

@Lvl4Sword
Last active December 23, 2016 07:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Lvl4Sword/3acf5742e3a91c710f38639e2d7b2a2b to your computer and use it in GitHub Desktop.
Save Lvl4Sword/3acf5742e3a91c710f38639e2d7b2a2b to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import csv
import Tkinter
import tkFileDialog
import sys
def calc_hours_shift(a_shift):
hours_shift = 0
str_from = a_shift[a_shift.find("[")+1:a_shift.find(" - ")]
int_from = int(str_from[:str_from.find("M")-1])
str_to = a_shift[a_shift.find(" - ")+3:a_shift.find("]")]
int_to = int(str_to[:str_to.rfind("M")-1])
if str_from.find("12AM") >= 0:
int_from = 0
if str_from.find("PM") >= 0 and str_from.find("12PM") < 0:
int_from += 12
if str_to.find("12AM") >= 0:
int_to = 24
if str_to.find("PM") >= 0 and str_to.find("12PM") < 0:
int_to += 12
if str_from.find("PM") >= 0 and str_to.find("AM") >= 0 and int_to < 24:
int_to += 24
hours_shift = (int_to-int_from)
return hours_shift
def calc_hours(shifts):
hours_shifts = 0
for a_shift in shifts:
hours_shifts += calc_hours_shift(a_shift)
return hours_shifts
class Shift_Person(object):
def __init__(self, shift, hours_shift, staff_person):
self.shift = shift
self.hours_shift = hours_shift
self.staff_person = staff_person
def get_shift(self):
return self.shift
def get_hours_shift(self):
return self.hours_shift
def get_staff(self):
return self.staff_person
def available_employ(self):
available = -1
for i in xrange(len(staff_person)-1, -1, -1):
if staff_person[i] == None:
available = i
return available
def add_person(self, new_person):
if self.available_employ() >= 0:
staff_person[self.available_employ()] = new_person
class Person(object):
def __init__ (self, full_name, hours_available, rank, num_shifts_available):
self.full_name = full_name
self.hours_available = hours_available
self.rank = rank
self.hours_worked = 0
self.shift_work = list()
self.cal_hours_work = [0] * num_shifts_available
def get_full_name(self):
return self.full_name
def get_max_hours_available(self):
return self.hours_available
def get_rank(self):
return self.rank
def get_hours_worked(self):
return self.hours_worked
def get_shifts_worked(self):
return self.shift_work
def get_cal_hours_work(self):
return self.cal_hours_work
def set_cal_hours_work(self, ind_hours, num_hours):
self.cal_hours_work[ind_hours] = num_hours
self.hours_worked = self.hours_worked + num_hours
def add_shift(self, a_shift):
self.shift_work.append(a_shift)
def __cmp__(self, Person1):
if self.rank is not Person1.get_rank():
return cmp(self.rank, Person1.get_rank())
else:
ratio1 = float(self.hours_worked)/float(self.hours_available)
ratio2 = float(Person1.get_hours_worked())/float(Person1.get_max_hours_available())
if ratio1 > ratio2:
return 1
if ratio1 < ratio2:
return -1
return 0
Tkinter.Tk().withdraw()
in_path_file = tkFileDialog.askopenfilename(filetypes=[("CSV", ".csv")])
out_path_file = in_path_file.replace(".csv", "_NEW.csv")
try:
csvfile = open(in_path_file)
except IOError:
sys.exit("CSV was not selected and we cannot proceed!")
min_for_swift = int(raw_input("How many people minimum for a shift? "))
max_for_swift = int(raw_input("How many people maximum for a shift? "))
or_min_for_swift = min_for_swift
reader = list(csv.reader(csvfile))
old_headers = reader[0]
new_headers = ["Full name", "Rank", "Actual allotted hours", "Preferred number of hours"]
for a_header in old_headers[7:]:
new_headers.append(a_header[a_header.find(",")+2:])
tot_hours = calc_hours(old_headers[7:])
max_hours_available = 0
staff = []
for a_line in reader[1:]:
a_person = Person(a_line[1] + " " + a_line[2], int(a_line[5]), a_line[3], len(old_headers)-7)
staff.append(a_person)
max_hours_available += int(a_line[5])
min_for_swift = max_hours_available/tot_hours
change_criteria = False
if min_for_swift<or_min_for_swift:
change_criteria = True
if min_for_swift > max_for_swift:
min_for_swift = max_for_swift
shift_staff = {}
for a_index in xrange(4, len(new_headers)):
a_shift = new_headers[a_index]
day_hour_shift = a_shift
hours_of_work = calc_hours_shift(a_shift)
a_staff_person = []
staff.sort(key=lambda x: x.hours_worked, reverse=False)
for i in xrange(min_for_swift):
for j in xrange(len(staff)):
if len(a_staff_person) <= 0 and ((staff[j].hours_worked+hours_of_work) <= staff[j].hours_available) and (sum(staff[j].cal_hours_work[a_index-9:a_index-4])+hours_of_work) < 10:
staff[j].add_shift(a_shift)
staff[j].set_cal_hours_work(a_index-4, hours_of_work)
a_staff_person.append(staff[j])
else:
level_occ = []
for tmp in a_staff_person:
level_occ.append(tmp.rank)
if staff[j].cal_hours_work[a_index-4] == 0 and staff[j].rank not in level_occ and ((staff[j].hours_worked+hours_of_work) <= staff[j].hours_available) and len(a_staff_person) < min_for_swift and (sum(staff[j].cal_hours_work[a_index-9:a_index-4])+hours_of_work) < 10:
staff[j].add_shift(a_shift)
staff[j].set_cal_hours_work(a_index-4, hours_of_work)
a_staff_person.append(staff[j])
if len(a_staff_person) < min_for_swift:
for j in xrange(len(staff)):
if staff[j].cal_hours_work[a_index-4] == 0 and ((staff[j].hours_worked+hours_of_work) <= staff[j].hours_available) and len(a_staff_person) < min_for_swift and (sum(staff[j].cal_hours_work[a_index-9:a_index-4])+hours_of_work) < 10:
staff[j].add_shift(a_shift)
staff[j].set_cal_hours_work(a_index-4, hours_of_work)
a_staff_person.append(staff[j])
a_shift_person = Shift_Person(a_shift, hours_of_work, a_staff_person)
shift_staff[a_shift] = a_shift_person
staff.sort(key=lambda x: x.rank, reverse=True)
new_shifts = []
new_shifts.append(new_headers)
for ap in staff:
a_line = []
a_line.append(ap.get_full_name())
a_line.append(ap.get_rank())
a_line.append(str(ap.get_hours_worked()))
a_line.append(str(ap.get_max_hours_available()))
for i in xrange(4, len(old_headers)-3):
a_line.append("")
if new_headers[i] in ap.get_shifts_worked():
a_line[i] = "Scheduled"
new_shifts.append(a_line)
writer = csv.writer(open(out_path_file, "wb"))
for row in new_shifts:
writer.writerow(row)
if change_criteria:
sys.exit("The available hours are insufficient to proceed according to these criteria!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment