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")