wrote this for a pretty specific purpose but if you wanted to attempt to fairly/randomly schedule four people weekly shifts and avoid the same employee having the shift two weeks in a row and also generate a calendar at the same time, here you go
-
-
Save cxdy/94f108671ef1cfbcaaf43d6c06f1c9b0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from random import * | |
from icalendar import Calendar, Event, vCalAddress, vText | |
from datetime import datetime | |
from datetime import timedelta | |
from pathlib import Path | |
import os | |
import pytz | |
# init our calendar | |
cal = Calendar() | |
cal.add('prodid', '-//Schedule//yourdomain.com//') | |
cal.add('version', '2.0') | |
persons = ["First Last", "Last First", "Lirst Fast", "Fast Lirst"] | |
counts = [0, 0, 0, 0] | |
beginDate = datetime(2023, 1, 1, 0, 0, 0, tzinfo=pytz.utc) | |
theCount = [0] | |
personRotation = [] | |
def convertToEmail(person): | |
username = person.lower().replace(' ', '.') | |
emailAddress = username + "@yourdomain.com" | |
return emailAddress | |
def createEvent(calendar, startDate, endDate, person): | |
# this is long bc standards and shit | |
event = Event() | |
event.add('summary', 'Schedule - ' + person) | |
event.add('name', 'Schedule - ' + person) | |
event.add('description', 'Schedule (again)') | |
event.add('dtstart', startDate) | |
event.add('dtend', endDate) | |
organizer = vCalAddress('MAILTO:persons@yourdomain.com') | |
organizer.params['name'] = vText('Business Name') | |
organizer.params['role'] = vText('Robot') | |
event['organizer'] = organizer | |
event['location'] = vText('Somewhere') | |
event['uid'] = str(randint(0, 420696969)) | |
event.add('priority', 1) | |
attendee = vCalAddress('MAILTO:' + convertToEmail(person)) | |
attendee.params['name'] = vText(person) | |
attendee.params['role'] = vText('REQ-PARTICIPANT') | |
event.add('attendee', attendee, encode=0) | |
calendar.add_component(event) | |
def dumpCalendar(theCalendar): | |
directory = Path.cwd() / 'calendars' | |
f = open(os.path.join(directory, 'schedule.ics'), 'wb') | |
f.write(theCalendar.to_ical()) | |
f.close() | |
def pickperson(persons): | |
if (len(persons) - 1) == 0: | |
return | |
else: | |
index = randint(0,(len(persons) - 1)) | |
tempList = persons | |
if counts[index] >= 13: | |
persons.pop(index) | |
person = persons[index] | |
if not personRotation: | |
lastperson = "0" | |
else: | |
lastperson = str(personRotation[len(personRotation) - 1]) | |
if lastperson == person: | |
tempList.remove(person) | |
tempInt = randint(0,(len(tempList) - 1)) | |
person = tempList[tempInt] | |
tempList.append(lastperson) | |
personRotation.append(person) | |
theCount[0] += 1 | |
counts[index] += 1 | |
return person | |
# map to the same indexes | |
startDates = [] | |
endDates = [] | |
for i in range(52): | |
thisperson = pickperson(persons) | |
if i == 0: | |
startDates.append(beginDate) | |
endDt = beginDate + timedelta(days=6) | |
endDates.append(endDt) | |
createEvent(cal, beginDate, endDt, thisperson) | |
else: | |
index = i - 1 | |
startDates.append(endDates[index]) | |
endDt = endDates[index] + timedelta(days=7) | |
endDates.append(endDt) | |
createEvent(cal, endDates[index], endDt, thisperson) | |
dumpCalendar(cal) | |
print(counts) | |
print(personRotation) | |
print(theCount) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment