async def distrib(self, ctx): """ Hiện phân phối điểm của các bài tập. """ bin_size = 0.2 bins = 10 height = [0] * bins problem_points = common.get_problem_points() for p, point in problem_points.items(): height[min(bins - 1, int(point // bin_size))] += 1 x = [k * bin_size for k in range(bins)] label = ['{:.2f} ({})'.format(r, c) for r,c in zip(x, height)] colors = [] for rank in badge.RATED_RANKS: colors.append('#' + '%06x' % rank.color_embed) colors = colors[:bins] assert len(colors) > 0, 'Expected colors len is greater than 0' while len(colors) < bins: colors.append(colors[-1]) plt.clf() plt.xlabel('Point') plt.ylabel('Number of problems') plt.xticks(rotation=45) plt.bar(x, height, bin_size*0.9, color=colors, tick_label=label) discord_file = gc.get_current_figure_as_file() embed = discord_common.cf_color_embed( title="Phân phối điểm của bài tập VOJ") discord_common.attach_image(embed, discord_file) # discord_common.set_author_footer(embed, ctx.author) await ctx.send(embed=embed, file=discord_file)
async def gimme(self, ctx, *args): """ Đề xuất một số bài tập theo dạng. Có một số tag sau đây: [DP, DS, geometry, graph, math, string, ad-hoc, other] Ví dụ ;voj gimme DP 0.2 0.5 là list các bài DP có độ khó từ 0.2 tới 0.5 """ low = 0 - 0.1 hi = 2 + 0.1 bound = [] tag = "" for arg in args: if is_float(arg): bound.append(float(arg)) else: tag = arg if len(bound) == 1: low = max(low, bound[0]) elif len(bound) == 2: low = max(low, bound[0]) hi = min(hi, bound[1]) category = tag.upper() if category != "" and category not in self.category: await ctx.send( 'không tìm thấy category `{0}`. '.format(tag) + 'Chỉ dùng các tag sau đây `[DP, DS, geometry, graph, math, string, ad-hoc, other]`. ' 'Tham khảo trang <http://vnoi.info/problems/list/> để có danh sách tag chi tiết hơn.' ) return handle = await common.get_handle(ctx, None) if handle is None: return problem_point = common.get_problem_points() un_solved_problem = self.get_un_solved_problem(handle) if category != "": un_solved_problem = list( filter( lambda x: x[1][:x[1].find('-')].strip() in self.category[ category], un_solved_problem)) un_solved_problem = list( filter( lambda p: low <= problem_point[int(p[0])] and problem_point[ int(p[0])] <= hi, un_solved_problem)) if len(un_solved_problem) == 0: await ctx.send( 'Không tìm được bài tập nào với các tham số hiện tại.') return problems = random.sample(un_solved_problem, k=min(10, len(un_solved_problem))) if tag == "": tag = "ngẫu nhiên" title = "{0} bài {1}".format(len(problems), tag) msg = "" for p in problems: msg += to_message(p, problem_point) + "\n" embed = discord.Embed(title=title, description=msg.strip(), color=discord_common._SUCCESS_BLUE_) discord_common.set_author_footer(embed, ctx.author) await ctx.send(embed=embed)
def get_rating_change(self, handle): # problem id, result, date raw_subs = RankingDb.RankingDb.get_info_solved_problem(handle) raw_subs = list(filter(lambda x: (x[1] == 'AC') or (float(x[1]) > 0.01), raw_subs)) raw_subs = sorted(raw_subs, key=lambda x: x[2]) problem_points = common.get_problem_points() rating_changes = [(-1, -1)] rating = 0 for problem_id, result, date in raw_subs: if rating_changes[-1][1] != date: rating_changes.append((0, date)) if result == 'AC': result = 100 rating += problem_points[int(problem_id)] * float(result) / 100 # rating += 2 * float(result) / 100 rating_changes[-1] = (rating, date) return rating_changes[1:]
async def calculate_rank(self, ctx): start = time.perf_counter() message = "" if ctx != None: message = await ctx.send( '<:pingreee:665243570655199246> Calculating ...') # calculating problem_points = common.get_problem_points(force=True) badge.MAX_SCORE = 0 # for p, point in problem_points.items(): # #remove scale # badge.MAX_SCORE += point # # badge.MAX_SCORE += 2 user_data = RankingDb.RankingDb.get_data('user_data', limit=None) user_handles = {} for cf_id, handle, discord_id in user_data: if cf_id is None: continue user_handles[int(cf_id)] = handle user_points = {} solved_info = RankingDb.RankingDb.get_data('solved_info', limit=None) for user_id, problem_id, result, date in solved_info: handle = user_handles[int(user_id)] if handle not in user_points: user_points[handle] = 0 if result == 'AC': result = 100 result = float(result) #remove scale user_points[handle] += result * problem_points[int( problem_id)] / 100 # user_points[handle] += result * 2 / 100 self.rank_cache = [] badge.MAX_SCORE = 0 for handle, point in user_points.items(): self.rank_cache.append((point, handle)) badge.MAX_SCORE = max(badge.MAX_SCORE, point) self.rank_cache.sort(reverse=True) end = time.perf_counter() duration = (end - start) * 1000 if ctx != None: await message.edit( content=f'Done. Calculation time: {int(duration)}ms.')
async def calculate_rank(self, ctx): start = time.perf_counter() message = "" if ctx != None: message = await ctx.send('<:pingreee:665243570655199246> Calculating ...') # calculating problem_points = common.get_problem_points(force=True) badge.MAX_SCORE = 0 # for p, point in problem_points.items(): # #remove scale # badge.MAX_SCORE += point # # badge.MAX_SCORE += 2 user_points = {} user_table = RankingDb.RankingDb.get_table(RankingDb.USER_TABLE) user_handle = {} for x in user_table: user_handle[x['codeforcesId']] = x['handle'] solved_info = RankingDb.RankingDb.get_table(RankingDb.SUBMISSION_TABLE) solved_info = list(map(lambda x: (user_handle[x['codeforcesId']], x['problemName'], x['point'], x['timestamp']), solved_info)) for handle, problem_name, result, date in solved_info: if handle not in user_points: user_points[handle] = 0 if result == 'AC': result = 100 result = float(result) #remove scale user_points[handle] += result * problem_points[problem_name] / 100 # user_points[handle] += result * 2 / 100 self.rank_cache = [] badge.MAX_SCORE = 0 for handle, point in user_points.items(): self.rank_cache.append((point, handle)) badge.MAX_SCORE = max(badge.MAX_SCORE, point) self.rank_cache.sort(reverse=True) end = time.perf_counter() duration = (end - start) * 1000 if ctx != None: await message.edit(content=f'Done. Calculation time: {int(duration)}ms.')