Files
completely-fair-scheduler/wraparound.py
2024-05-12 23:42:33 -03:00

101 lines
2.6 KiB
Python

import argparse
import itertools
import json
import sys
from calendar import day_abbr, day_name
from math import floor
with open("data.json") as jsonfile:
raw_data = json.loads(jsonfile.read())
parser = argparse.ArgumentParser(
prog=sys.argv[0], description="Find autono-meeting times"
)
parser.add_argument("members", nargs="*", choices=[m["name"] for m in raw_data])
parser.add_argument("-n", "--number", default=2, type=int)
parser.add_argument("-d", "--days", nargs="+")
parser.add_argument("-v", "--verbose", action='store_true')
args = parser.parse_args()
data = {}
def slot2name(slot):
time, day = slot.split("-")
name = day_name[int(day) - 1]
return f"{time} {name}"
members_count = len(raw_data)
if args.members:
members_count = len(args.members)
if args.verbose:
print(f"I: finding slots for {members_count} members")
days = [str(d) for d in list(range(1, 8))]
if args.days:
days = [str(list(day_abbr).index(d) + 1) for d in args.days]
for member in raw_data:
name = member["name"]
if args.members and name not in args.members:
continue
for slot in member["availability"]:
if "00-" not in slot:
# not starting at an hour
continue
slot_day = slot.split("-")[1]
if slot_day not in days:
# not in specified days
continue
try:
data[slot].append(name)
except KeyError:
data[slot] = [name]
if args.verbose:
print(f"I: Checking {len(data.keys())} possible slots")
seen_times = []
counter = 1
l = [list(data.keys())] * args.number
combinations = list(itertools.product(*l))
if args.verbose:
print(f"I: Scanning {len(combinations)} combinations")
for combination in combinations:
if len(set(combination)) < args.number:
continue
if set(combination) in seen_times:
continue
seen_times.append(set(combination))
attendees_per_slot = [data[slot] for slot in combination]
attendees = set(itertools.chain(*attendees_per_slot))
if (
(len(attendees) == members_count)
and all(
[len(s) >= floor(members_count / args.number) for s in attendees_per_slot]
)
and all(
[
len(s) < (floor(members_count / args.number) + 2)
for s in attendees_per_slot
]
)
):
print(f"Option {counter}")
for i, slot in enumerate(combination):
print(f" Meeting {i+1}: ", slot2name(slot))
print(" ", ", ".join(attendees_per_slot[i]))
counter += 1
if counter == 1:
print("Oh no, no slots found")