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 tagbar(self, ctx, *args): """ Hiện biểu đồ các bài đã giải theo tag của nick codeforces tương ứng. Ví dụ ;voj tagbar CKQ """ filt = DayFilter() handle = filt.parse(args) handle = await common.get_handle(ctx, handle) if handle is None: return #name result date problem_list = RankingDb.RankingDb.get_info_solved_problem(handle) problem_list = list(filter(lambda x: x[1] >= 100 - 0.1, problem_list)) problem_list = list(filter(lambda x: filt.filter(datetime.strptime(x[2], '%Y/%m/%d')), problem_list)) if len(problem_list) == 0: await ctx.send('Không tìm thấy submission của `{0}` với các tham số hiện tại.'.format(handle)) return cnt = {'No tag' : 0} for tag in TAGS: cnt[tag] = 0 for name, *junks in problem_list: name = name[:name.find('-')].strip() tags = [] if name not in self.tag: tags = ['No tag'] else: tags = self.tag[name] for tag in tags: if tag not in cnt: cnt[tag] = 0 cnt[tag] += 1 #/// plt.clf() plt.xlabel('Tag') plt.ylabel('Number solved') x_pos = list(range(len(TAGS))) colors = ['tab:blue', 'tab:orange', 'tab:green', 'tab:red', 'tab:purple', 'tab:pink', 'tab:olive', 'tab:cyan'] plt.bar(x_pos, [cnt[x] for x in TAGS], color=colors) plt.xticks(x_pos, TAGS) for index, value in enumerate(TAGS): if cnt[value] < 10: plt.text(index - 0.1, cnt[value], str(cnt[value])) elif cnt[value] < 100: plt.text(index - 0.15, cnt[value], str(cnt[value])) else: plt.text(index - 0.25, cnt[value], str(cnt[value])) total = len(problem_list) plt.legend(title=f"{handle}: {total} ({cnt['No tag']} no tag)", title_fontsize=plt.rcParams['legend.fontsize']) plt.gcf().autofmt_xdate() discord_file = gc.get_current_figure_as_file() embed = discord_common.cf_color_embed( title='Số lượng bài giải được trong từng category') 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 exp(self, ctx, *args): """ Hiện biểu đồ kinh nghiệm của handle cho trước. Ví dụ ;voj exp CKQ d<16022020 d>=05062019 """ filt = DayFilter() handle = filt.parse(args) handle = await common.get_handle(ctx, handle) if handle is None: return if badge.MAX_SCORE == None: await ctx.send('Ranking chưa được tính, ping Cá Nóc.') return resp = self.get_rating_change(handle) resp = list(filter(lambda x: filt.filter( datetime.strptime(x[1], '%Y/%m/%d')), resp)) if len(resp) == 0: await ctx.send('Không tìm thấy submission của `{0}` với các tham số hiện tại.'.format(handle)) return plt.clf() _plot_rating([resp], MAX_SCORE=badge.MAX_SCORE) current_rating = resp[-1][0] current_badge = badge.point2rank(current_rating, badge.MAX_SCORE) rank_title = current_badge.title + " {:.3f}".format(current_rating) labels = [f'\N{ZERO WIDTH SPACE}{handle} ({rank_title})'] plt.legend(labels, loc='upper left') min_rating = current_rating max_rating = current_rating for rating, date in resp: min_rating = min(min_rating, rating) max_rating = max(max_rating, rating) max_rating = max(max_rating + 0.5 * badge.MAX_SCORE / 100, min(100, current_badge.high + 0.1) * badge.MAX_SCORE / 100) min_rating -= 0.5 * badge.MAX_SCORE / 100 if min_rating < 0: min_rating = 0 plt.ylim(min_rating, max_rating) msg = "" if current_badge.high < 100: upper_bound = current_badge.high * badge.MAX_SCORE / 100 nxt_badge = badge.point2rank(upper_bound + 0.0001, MAX_SCORE=badge.MAX_SCORE) msg = "`{}` cần khoảng {:.2f} exp nữa để có badge {} <:orz:661153248186597386>".format( handle, upper_bound - current_rating, nxt_badge.title ) discord_file = gc.get_current_figure_as_file() embed = discord_common.cf_color_embed( title='Biểu đồ kinh nghiệm trong group VNOI.') discord_common.attach_image(embed, discord_file) discord_common.set_author_footer(embed, ctx.author) await ctx.send(msg, embed=embed, file=discord_file)
async def group_hist(self, ctx, *args): """Hiện histogram của toàn group. Ví dụ ;voj group_hist d<16022020 d>=05062019 """ filt = DayFilter() handle = filt.parse(args) solved_info = RankingDb.RankingDb.get_data('solved_info', limit=None) raw_subs = [] for user_id, problem_id, result, date in solved_info: if str(user_id) not in WHILELIST_USER_IDs: raw_subs.append((problem_id, result, date)) raw_subs = list(filter(lambda x: filt.filter(datetime.strptime(x[2], '%Y/%m/%d')), raw_subs)) if len(raw_subs) == 0: await ctx.send('Không tìm thấy submission với các tham số hiện tại.') return subs = [] types = ['AC', 'IC', 'PC'] solved_by_type = {'AC': [], 'IC': [], 'PC': []} cnt = 0 plt.clf() plt.xlabel('Time') plt.ylabel('Number solved') for problem_id, result, date in raw_subs: t = result if t != 'AC' and float(t) <= 0 + 0.01: t = 'IC' elif t != 'AC': t = 'PC' solved_by_type[t].append(date) all_times = [[datetime.strptime(date, '%Y/%m/%d') for date in solved_by_type[t]] for t in types] labels = ['Accepted', 'Incorrect', 'Partial Result'] colors = ['g', 'r', 'y'] plt.hist(all_times, stacked=True, label=labels, bins=34, color=colors) total = sum(map(len, all_times)) plt.legend( title=f'VNOI Group: {total}', title_fontsize=plt.rcParams['legend.fontsize']) plt.gcf().autofmt_xdate() discord_file = gc.get_current_figure_as_file() embed = discord_common.cf_color_embed( title='Số bài làm theo thời gian.') 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 hist(self, ctx, *args): """Hiện histogram về thời gian làm bài của handle cho trước. Ví dụ ;voj hist CKQ d<16022020 d>=05062019 """ filt = DayFilter() handle = filt.parse(args) handle = await common.get_handle(ctx, handle) if handle is None: return raw_subs = RankingDb.RankingDb.get_info_solved_problem(handle) raw_subs = list(filter(lambda x: filt.filter( datetime.strptime(x[2], '%Y/%m/%d')), raw_subs)) if len(raw_subs) == 0: await ctx.send('Không tìm thấy submission của `{0}` với các tham số hiện tại.'.format(handle)) return subs = [] types = ['AC', 'IC', 'PC'] solved_by_type = {'AC': [], 'IC': [], 'PC': []} cnt = 0 plt.clf() plt.xlabel('Time') plt.ylabel('Number solved') for problem_id, result, date in raw_subs: t = result if t != 'AC' and float(t) <= 0 + 0.01: t = 'IC' elif t != 'AC': t = 'PC' solved_by_type[t].append(date) all_times = [[datetime.strptime(date, '%Y/%m/%d') for date in solved_by_type[t]] for t in types] labels = ['Accepted', 'Incorrect', 'Partial Result'] colors = ['g', 'r', 'y'] plt.hist(all_times, stacked=True, label=labels, bins=34, color=colors) total = sum(map(len, all_times)) plt.legend(title=f'{handle}: {total}', title_fontsize=plt.rcParams['legend.fontsize']) plt.gcf().autofmt_xdate() discord_file = gc.get_current_figure_as_file() embed = discord_common.cf_color_embed( title='Số bài làm theo thời gian.') 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 group_hist(self, ctx, *args): """Hiện histogram của toàn group. Ví dụ ;voj group_hist d<16022020 d>=05062019 """ filt = DayFilter() handle = filt.parse(args) solved_info = RankingDb.RankingDb.get_table(RankingDb.SUBMISSION_TABLE) raw_subs = list(map(lambda x: (x['problemName'], x['point'], x['timestamp']), solved_info)) raw_subs = list(filter(lambda x: filt.filter(datetime.fromtimestamp(x[2])), raw_subs)) if len(raw_subs) == 0: await ctx.send('Không tìm thấy submission với các tham số hiện tại.') return subs = [] types = ['AC', 'IC', 'PC'] solved_by_type = {'AC': [], 'IC': [], 'PC': []} cnt = 0 plt.clf() plt.xlabel('Time') plt.ylabel('Number solved') for problem_name, point, timestamp in raw_subs: t = 'AC' if point <= 0 + 0.01: t = 'IC' elif point < 100 - 0.01: t = 'PC' solved_by_type[t].append(datetime.fromtimestamp(timestamp)) all_times = [[date for date in solved_by_type[t]] for t in types] labels = ['Accepted', 'Incorrect', 'Partial Result'] colors = ['g', 'r', 'y'] plt.hist(all_times, stacked=True, label=labels, bins=34, color=colors) total = sum(map(len, all_times)) plt.legend( title=f'VNOI Group: {total}', title_fontsize=plt.rcParams['legend.fontsize']) plt.gcf().autofmt_xdate() discord_file = gc.get_current_figure_as_file() embed = discord_common.cf_color_embed( title='Số bài làm theo thời gian.') discord_common.attach_image(embed, discord_file) discord_common.set_author_footer(embed, ctx.author) await ctx.send(embed=embed, file=discord_file)