summaryrefslogtreecommitdiff
path: root/commands.py
diff options
context:
space:
mode:
Diffstat (limited to 'commands.py')
-rw-r--r--commands.py58
1 files changed, 51 insertions, 7 deletions
diff --git a/commands.py b/commands.py
index feb6c74..62046f6 100644
--- a/commands.py
+++ b/commands.py
@@ -22,7 +22,7 @@ async def answer(ctx: commands.Context, msg: str):
@commands.command(help='display this help message', aliases=('hepl', 'h', '?'))
async def help(ctx: commands.Context):
command_doc = '\n'.join(
- f' * {config.COMMAND_PREFIX.strip()} {c.name:15} - {c.help}'
+ f' * {config.COMMAND_PREFIX}{c.name:15} - {c.help}'
for c in ctx.bot.commands)
await answer(ctx, f'''```
{config.HELP_TEXT}\nThese are all available commands:\n{command_doc}```''')
@@ -48,6 +48,27 @@ async def destroy(ctx: commands.Context):
ctx.bot.pair_channels = []
+def fac(n):
+ i = 1
+ for z in range(2, n+1):
+ i *= z
+ return i
+
+
+def n_th_permutation(n, lst):
+ nlst = [None for _ in lst]
+ indexes = list(range(len(lst)))
+ for i in lst:
+ n, index = divmod(n, len(indexes))
+ nlst[indexes.pop(index)] = i
+ return nlst
+
+
+def round_up_div(a, b):
+ a, b = divmod(a, b)
+ return a+1 if b else a
+
+
@commands.command(help='start shuffling', aliases=('start', 'run', 'strat', 'rnu'))
async def shuffle(ctx: commands.Context, channel_size=2):
if channel_size < 1:
@@ -65,7 +86,10 @@ async def shuffle(ctx: commands.Context, channel_size=2):
await answer(ctx, f'error: you are too few people ({len(members)}). Group size is {channel_size}')
return False
- channel_count, excess_slots = divmod(len(members), channel_size)
+ channel_count = len(members) // channel_size
+ counts = [0] * channel_count
+ for i, _ in enumerate(members):
+ counts[i % len(counts)] += 1
normals = []
tutors = []
random.shuffle(members)
@@ -74,14 +98,34 @@ async def shuffle(ctx: commands.Context, channel_size=2):
tutors.append(member)
else:
normals.append(member)
+
+ groups = [[] for _ in range(channel_count)]
+ for count, group in zip(counts, groups):
+ tutor_count = min(count, round_up_div(len(tutors), len(groups)))
+ for i in range(tutor_count):
+ if tutors:
+ group.append(tutors.pop())
+ for _ in range(count - tutor_count):
+ for i, member in enumerate(normals):
+ if any(frozenset((member.id, other.id)) in ctx.bot.oldgroups for other in group):
+ continue
+ group.append(normals.pop(i))
+ break
+ else:
+ group.append(normals.pop())
+
futures = []
ctx.bot.pair_channels = await ctx.bot.create_pair_channels(ctx, meta_channel, channel_count)
random.shuffle(ctx.bot.pair_channels)
- groups = [[] for _ in range(channel_count)]
- for i, member in enumerate(tutors + normals):
- n = i % channel_count
- futures.append(member.move_to(ctx.bot.pair_channels[n]))
- groups[n].append(member)
+ for n, group in enumerate(groups):
+ for member in group:
+ futures.append(member.move_to(ctx.bot.pair_channels[n]))
+ for member1 in group:
+ for member2 in group:
+ if member1 != member2:
+ ctx.bot.oldgroups.add(frozenset((member1, member2)))
+
+ random.shuffle(futures)
for group in groups:
for member in group:
futures.append(ctx.bot.send_panel(ctx, member, group))