async def gimme(self, ctx, *args): tags = [] bounds = [] for arg in args: if arg.isdigit(): bounds.append(int(arg)) else: tags.append(arg) handle, = await cf_common.resolve_handles(ctx, self.converter, ('!' + str(ctx.author), )) user = cf_common.user_db.fetch_cfuser(handle) rating = user.rating submissions = await cf.user.status(handle=handle) solved = { sub.problem.name for sub in submissions if sub.verdict == 'OK' } lower = bounds[0] if len(bounds) > 0 else None if lower is None: lower = rating # round later. rounding a null value causes exception if lower is None: await ctx.send( 'Personal cf data not found. Assume rating of 1500.') lower = 1500 else: lower = round(lower, -2) upper = bounds[1] if len(bounds) > 1 else lower + 200 problems = [ prob for prob in cf_common.cache2.problem_cache.problems if lower <= prob.rating and prob.name not in solved ] problems = [ prob for prob in problems if not cf_common.is_contest_writer(prob.contestId, handle) ] if tags: problems = [prob for prob in problems if prob.tag_matches(tags)] if not problems: await ctx.send('Problems not found within the search parameters') return upper = max(upper, min([prob.rating for prob in problems])) problems = [prob for prob in problems if prob.rating <= upper] problems.sort(key=lambda problem: cf_common.cache2.contest_cache. get_contest(problem.contestId).startTimeSeconds) choice = max([random.randrange(len(problems)) for _ in range(2)]) problem = problems[choice] title = f'{problem.index}. {problem.name}' desc = cf_common.cache2.contest_cache.get_contest( problem.contestId).name embed = discord.Embed(title=title, url=problem.url, description=desc) embed.add_field(name='Rating', value=problem.rating) if tags: tagslist = ', '.join(problem.tag_matches(tags)) embed.add_field(name='Matched tags', value=tagslist) await ctx.send(f'Recommended problem for `{handle}`', embed=embed)
def get_problems(rating): return [ prob for prob in cf_common.cache2.problem_cache.problems if prob.rating == rating and prob.name not in solved and not any( cf_common.is_contest_writer(prob.contestId, handle) for handle in handles) and not cf_common.is_nonstandard_problem(prob) ]
async def vc(self, ctx, *args: str): """Recommends a contest based on Codeforces rating of the handle provided. e.g ;vc mblazev c1729 +global +hello +goodbye +avito""" markers = [x for x in args if x[0] == '+'] handles = [x for x in args if x[0] != '+'] or ('!' + str(ctx.author), ) handles = await cf_common.resolve_handles(ctx, self.converter, handles, maxcnt=25) info = await cf.user.info(handles=handles) contests = cf_common.cache2.contest_cache.get_contests_in_phase( 'FINISHED') if not markers: divr = sum(user.effective_rating for user in info) / len(handles) div1_indicators = ['div1', 'global', 'avito', 'goodbye', 'hello'] markers = [ 'div3' ] if divr < 1600 else ['div2'] if divr < 2100 else div1_indicators recommendations = { contest.id for contest in contests if contest.matches(markers) and not cf_common.is_nonstandard_contest(contest) and not any( cf_common.is_contest_writer(contest.id, handle) for handle in handles) } # Discard contests in which user has non-CE submissions. visited_contests = await cf_common.get_visited_contests(handles) recommendations -= visited_contests if not recommendations: raise CodeforcesCogError('Unable to recommend a contest') recommendations = list(recommendations) random.shuffle(recommendations) contests = [ cf_common.cache2.contest_cache.get_contest(contest_id) for contest_id in recommendations[:25] ] def make_line(c): return f'[{c.name}]({c.url}) {cf_common.pretty_time_format(c.durationSeconds)}' def make_page(chunk): str_handles = '`, `'.join(handles) message = f'Recommended contest(s) for `{str_handles}`' vc_str = '\n'.join(make_line(contest) for contest in chunk) embed = discord_common.cf_color_embed(description=vc_str) return message, embed pages = [make_page(chunk) for chunk in paginator.chunkify(contests, 5)] paginator.paginate(self.bot, ctx.channel, pages, wait_time=5 * 60, set_pagenum_footers=True)
async def gimme(self, ctx, *args): handle, = await cf_common.resolve_handles(ctx, self.converter, ('!' + str(ctx.author), )) rating = round( cf_common.user_db.fetch_cf_user(handle).effective_rating, -2) tags = [] notags = [] for arg in args: if arg.isdigit(): rating = int(arg) else: if arg[0] == '-': notags.append(arg[1:]) else: tags.append(arg) submissions = await cf.user.status(handle=handle) solved = { sub.problem.name for sub in submissions if sub.verdict == 'OK' } problems = [ prob for prob in cf_common.cache2.problem_cache.problems if prob.rating == rating and prob.name not in solved and not cf_common.is_contest_writer(prob.contestId, handle) ] if tags: problems = [prob for prob in problems if prob.tag_matches(tags)] if notags: problems = [ prob for prob in problems if (prob.tag_matches_or(notags) == None) ] if not problems: raise CodeforcesCogError( 'Problems not found within the search parameters') problems.sort(key=lambda problem: cf_common.cache2.contest_cache. get_contest(problem.contestId).startTimeSeconds) choice = max([random.randrange(len(problems)) for _ in range(2)]) problem = problems[choice] title = f'{problem.index}. {problem.name}' desc = cf_common.cache2.contest_cache.get_contest( problem.contestId).name embed = discord.Embed(title=title, url=problem.url, description=desc) embed.add_field(name='Rating', value=problem.rating) if tags: tagslist = ', '.join(problem.tag_matches(tags)) embed.add_field(name='Matched tags', value=tagslist) await ctx.send(f'Recommended problem for `{handle}`', embed=embed)
async def gimme(self, ctx, *args): tags = [] bounds = [] for arg in args: if arg.isdigit(): bounds.append(int(arg)) else: tags.append(arg) (handle, ) = await cf_common.resolve_handles(ctx, self.converter, ("!" + str(ctx.author), )) submissions = await cf.user.status(handle=handle) solved = { sub.problem.name for sub in submissions if sub.verdict == "OK" } lower = bounds[0] if len(bounds) > 0 else None if lower is None: user = cf_common.user_db.fetch_cf_user(handle) lower = round(user.effective_rating, -2) upper = bounds[1] if len(bounds) > 1 else lower + 200 problems = [ prob for prob in cf_common.cache2.problem_cache.problems if lower <= prob.rating and prob.name not in solved ] problems = [ prob for prob in problems if not cf_common.is_contest_writer(prob.contestId, handle) ] if tags: problems = [prob for prob in problems if prob.tag_matches(tags)] if not problems: await ctx.send("Problems not found within the search parameters") return upper = max(upper, min([prob.rating for prob in problems])) problems = [prob for prob in problems if prob.rating <= upper] problems.sort(key=lambda problem: cf_common.cache2.contest_cache. get_contest(problem.contestId).startTimeSeconds) choice = max([random.randrange(len(problems)) for _ in range(2)]) problem = problems[choice] title = f"{problem.index}. {problem.name}" desc = cf_common.cache2.contest_cache.get_contest( problem.contestId).name embed = discord.Embed(title=title, url=problem.url, description=desc) embed.add_field(name="Rating", value=problem.rating) if tags: tagslist = ", ".join(problem.tag_matches(tags)) embed.add_field(name="Matched tags", value=tagslist) await ctx.send(f"Recommended problem for `{handle}`", embed=embed)
async def mashup(self, ctx, *args): """Create a mashup contest using problems within +-100 of average rating of handles provided. Add tags with "+" before them. Ban tags with "~" before them. """ handles = [arg for arg in args if arg[0] not in '+~'] tags = cf_common.parse_tags(args, prefix='+') bantags = cf_common.parse_tags(args, prefix='~') handles = handles or ('!' + str(ctx.author), ) handles = await cf_common.resolve_handles(ctx, self.converter, handles) resp = [await cf.user.status(handle=handle) for handle in handles] submissions = [sub for user in resp for sub in user] solved = {sub.problem.name for sub in submissions} info = await cf.user.info(handles=handles) rating = int( round( sum(user.effective_rating for user in info) / len(handles), -2)) problems = [ prob for prob in cf_common.cache2.problem_cache.problems if abs(prob.rating - rating) <= 100 and prob.name not in solved and not any( cf_common.is_contest_writer(prob.contestId, handle) for handle in handles) and not cf_common.is_nonstandard_problem(prob) and prob.matches_all_tags(tags) and not prob.matches_any_tag(bantags) ] if len(problems) < 4: raise CodeforcesCogError( 'Problems not found within the search parameters') problems.sort(key=lambda problem: cf_common.cache2.contest_cache. get_contest(problem.contestId).startTimeSeconds) choices = [] for i in range(4): k = max(random.randrange(len(problems) - i) for _ in range(2)) for c in choices: if k >= c: k += 1 choices.append(k) choices.sort() problems = reversed([problems[k] for k in choices]) msg = '\n'.join(f'{"ABCD"[i]}: [{p.name}]({p.url}) [{p.rating}]' for i, p in enumerate(problems)) str_handles = '`, `'.join(handles) embed = discord_common.cf_color_embed(description=msg) await ctx.send(f'Mashup contest for `{str_handles}`', embed=embed)
async def mashup(self, ctx, *args): """Create a mashup contest using problems within +-100 of average rating of handles provided. Add tags with "+" before them. """ handles = [arg for arg in args if arg[0] != "+"] tags = [arg[1:] for arg in args if arg[0] == "+" and len(arg) > 1] handles = handles or ("!" + str(ctx.author), ) handles = await cf_common.resolve_handles(ctx, self.converter, handles) resp = [await cf.user.status(handle=handle) for handle in handles] submissions = [sub for user in resp for sub in user] solved = {sub.problem.name for sub in submissions} info = await cf.user.info(handles=handles) rating = int( round( sum(user.effective_rating for user in info) / len(handles), -2)) problems = [ prob for prob in cf_common.cache2.problem_cache.problems if abs(prob.rating - rating) <= 100 and prob.name not in solved and not any( cf_common.is_contest_writer(prob.contestId, handle) for handle in handles) and not cf_common.is_nonstandard_problem(prob) ] if tags: problems = [prob for prob in problems if prob.tag_matches(tags)] if len(problems) < 4: await ctx.send("Problems not found within the search parameters") return problems = self._get_problems(problems) choices = [] for i in range(4): k = max(random.randrange(len(problems) - i) for _ in range(2)) for c in choices: if k >= c: k += 1 choices.append(k) choices.sort() problems = reversed([problems[k] for k in choices]) msg = "\n".join(f'{"ABCD"[i]}: [{p.name}]({p.url}) [{p.rating}]' for i, p in enumerate(problems)) str_handles = "`, `".join(handles) embed = discord_common.cf_color_embed(description=msg) await ctx.send(f"Mashup contest for `{str_handles}`", embed=embed)
async def vc(self, ctx, *args: str): """Recommends a contest based on Codeforces rating of the handle provided. e.g ;vc mblazev c1729 +global +hello +goodbye +avito""" markers = [x for x in args if x[0] == '+'] handles = [x for x in args if x[0] != '+'] or ('!' + str(ctx.author), ) handles = await cf_common.resolve_handles(ctx, self.converter, handles, maxcnt=25) info = await cf.user.info(handles=handles) contests = cf_common.cache2.contest_cache.get_contests_in_phase( 'FINISHED') if not markers: divr = sum(user.effective_rating for user in info) / len(handles) div1_indicators = ['div1', 'global', 'avito', 'goodbye', 'hello'] markers = [ 'div3' ] if divr < 1600 else ['div2'] if divr < 2100 else div1_indicators recommendations = { contest.id for contest in contests if contest.matches(markers) and not cf_common.is_nonstandard_contest(contest) and not any( cf_common.is_contest_writer(contest.id, handle) for handle in handles) } # Discard contests in which user has non-CE submissions. visited_contests = await cf_common.get_visited_contests(handles) recommendations -= visited_contests if not recommendations: raise CodeforcesCogError('Unable to recommend a contest') recommendations = list(recommendations) random.shuffle(recommendations) contests = [ cf_common.cache2.contest_cache.get_contest(contest_id) for contest_id in recommendations[:5] ] msg = '\n'.join(f'{i+1}. [{c.name}]({c.url})' for i, c in enumerate(contests)) embed = discord_common.cf_color_embed(description=msg) str_handles = '`, `'.join(handles) await ctx.send(f'Recommended contest(s) for `{str_handles}`', embed=embed)
async def vc(self, ctx, *args: str): """Recommends a contest based on Codeforces rating of the handle provided. e.g ;vc mblazev c1729 +global +hello +goodbye +avito""" markers = [x for x in args if x[0] == '+'] handles = [x for x in args if x[0] != '+'] or ('!' + str(ctx.author),) handles = await cf_common.resolve_handles(ctx, self.converter, handles, maxcnt=10) user_submissions = [await cf.user.status(handle=handle) for handle in handles] info = await cf.user.info(handles=handles) contests = cf_common.cache2.contest_cache.get_contests_in_phase('FINISHED') problem_to_contests = cf_common.cache2.problemset_cache.problem_to_contests if not markers: divr = sum(user.effective_rating for user in info) / len(handles) div1_indicators = ['div1', 'global', 'avito', 'goodbye', 'hello'] markers = ['div3'] if divr < 1600 else ['div2'] if divr < 2100 else div1_indicators recommendations = {contest.id for contest in contests if contest.matches(markers) and not cf_common.is_nonstandard_contest(contest) and not any(cf_common.is_contest_writer(contest.id, handle) for handle in handles)} # discard contests in which user has non-CE submissions for subs in user_submissions: for sub in subs: if sub.verdict == 'COMPILATION_ERROR': continue try: contest = cf_common.cache2.contest_cache.get_contest(sub.problem.contestId) problem_id = (sub.problem.name, contest.startTimeSeconds) for cid in problem_to_contests[problem_id]: recommendations.discard(cid) except cache_system2.ContestNotFound: pass if not recommendations: raise CodeforcesCogError('Unable to recommend a contest') recommendations = list(recommendations) random.shuffle(recommendations) contests = [cf_common.cache2.contest_cache.get_contest(contest_id) for contest_id in recommendations[:5]] msg = '\n'.join(f'{i+1}. [{c.name}]({c.url})' for i, c in enumerate(contests)) embed = discord_common.cf_color_embed(description=msg) str_handles = '`, `'.join(handles) await ctx.send(f'Recommended contest(s) for `{str_handles}`', embed=embed)
async def mashup(self, ctx, *handles: str): """Create a mashup contest using problems within +-100 of average rating of handles provided. """ handles = handles or ('!' + str(ctx.author), ) handles = await cf_common.resolve_handles(ctx, self.converter, handles) resp = [await cf.user.status(handle=handle) for handle in handles] submissions = [sub for user in resp for sub in user] solved = {sub.problem.name for sub in submissions} info = await cf.user.info(handles=handles) rating = int( round( sum(user.rating or 1500 for user in info) / len(handles), -2)) problems = [ prob for prob in cf_common.cache2.problem_cache.problems if abs(prob.rating - rating) <= 100 and prob.name not in solved and not any( cf_common.is_contest_writer(prob.contestId, handle) for handle in handles) ] if len(problems) < 4: await ctx.send('Problems not found within the search parameters') return problems.sort(key=lambda problem: cf_common.cache2.contest_cache. get_contest(problem.contestId).startTimeSeconds) choices = [] for i in range(4): k = max(random.randrange(len(problems) - i) for _ in range(2)) for c in choices: if k >= c: k += 1 choices.append(k) choices.sort() problems = reversed([problems[k] for k in choices]) msg = '\n'.join(f'{"ABCD"[i]}: [{p.name}]({p.url}) [{p.rating}]' for i, p in enumerate(problems)) str_handles = '`, `'.join(handles) embed = discord_common.cf_color_embed(description=msg) await ctx.send(f'Mashup contest for `{str_handles}`', embed=embed)
def check(problem): return not cf_common.is_nonstandard_problem( problem) and not cf_common.is_contest_writer( problem.contestId, handle)
def check(problem): contest = cf_common.cache2.contest_cache.get_contest( problem.contestId) return (not cf_common.is_nonstandard_contest(contest) and not cf_common.is_contest_writer(problem.contestId, handle))
async def mashup(self, ctx, *args): """Create a mashup contest using problems within -200 and +400 of average rating of handles provided. Add tags with "+" before them. """ delta = 100 handles = [arg for arg in args if arg[0] != '+' and arg[0] != '?'] tags = [arg[1:] for arg in args if arg[0] == '+' and len(arg) > 1] deltaStr = [arg[1:] for arg in args if arg[0] == '?' and len(arg) > 1] if len(deltaStr) > 1: raise CodeforcesCogError('Only one delta argument is allowed') if len(deltaStr) == 1: try: delta += round(int(deltaStr[0]), -2) except ValueError: raise CodeforcesCogError( 'delta could not be interpreted as number') handles = handles or ('!' + str(ctx.author), ) handles = await cf_common.resolve_handles(ctx, self.converter, handles) resp = [await cf.user.status(handle=handle) for handle in handles] submissions = [sub for user in resp for sub in user] solved = {sub.problem.name for sub in submissions} info = await cf.user.info(handles=handles) rating = int( round( sum(user.effective_rating for user in info) / len(handles), -2)) rating += delta rating = max(800, rating) rating = min(3500, rating) problems = [ prob for prob in cf_common.cache2.problem_cache.problems if abs(prob.rating - rating) <= 300 and prob.name not in solved and not any( cf_common.is_contest_writer(prob.contestId, handle) for handle in handles) and not cf_common.is_nonstandard_problem(prob) ] if tags: problems = [prob for prob in problems if prob.tag_matches(tags)] if len(problems) < 4: raise CodeforcesCogError( 'Problems not found within the search parameters') problems.sort(key=lambda problem: cf_common.cache2.contest_cache. get_contest(problem.contestId).startTimeSeconds) choices = [] for i in range(4): k = max(random.randrange(len(problems) - i) for _ in range(2)) for c in choices: if k >= c: k += 1 choices.append(k) choices.sort() problems = sorted([problems[k] for k in choices], key=lambda problem: problem.rating) msg = '\n'.join(f'{"ABCD"[i]}: [{p.name}]({p.url}) [{p.rating}]' for i, p in enumerate(problems)) str_handles = '`, `'.join(handles) embed = discord_common.cf_color_embed(description=msg) await ctx.send(f'Mashup contest for `{str_handles}`', embed=embed)