Esempio n. 1
0
    async def solved(self, ctx, *usernames):
        """Plot problems solved over time"""
        usernames = list(usernames)

        query = Query()
        if usernames == []:
            usernames = [query.get_handle(ctx.author.id, ctx.guild.id)]

        users = await asyncio.gather(
            *[query.get_user(username) for username in usernames])
        usernames = [user.username for user in users]
        for i in range(len(users)):
            if users[i] is None:
                return await ctx.send(f'{usernames[i]} does not exist on DMOJ')
        if len(users) > 10:
            return await ctx.send('Too many users given, max 10')

        total_data = {}
        not_cached = []
        for username in usernames:
            q = session.query(Submission_DB)\
                .filter(Submission_DB._user == username)
            if q.count() == 0:
                not_cached.append(username)

            q = session.query(func.min(Submission_DB.date))\
                .join(Problem_DB, Problem_DB.code == Submission_DB._code)\
                .filter(Submission_DB._user == username)\
                .filter(Submission_DB.points == Problem_DB.points)\
                .group_by(Submission_DB._code)
            dates = list(map(first_tuple, q.all()))
            dates.sort()
            data_to_plot = {}
            cnt = 0
            for date in dates:
                cnt += 1
                data_to_plot[date] = cnt
            total_data[username] = data_to_plot

        plot_solved(total_data)

        if len(not_cached):
            await ctx.send(f"`{', '.join(not_cached)} do not have any cached "
                           f"submissions. Please use +cache [username]`")

        plot_points(total_data)

        with open('./graphs/plot.png', 'rb') as file:
            file = discord.File(io.BytesIO(file.read()), filename='plot.png')
        embed = discord.Embed(
            title='Problems Solved',
            color=0xfcdb05,
        )
        embed.set_image(url=f'attachment://plot.png', )

        return await ctx.send(embed=embed, file=file)
Esempio n. 2
0
    async def points(self, ctx, *usernames):
        """Plot point progression"""
        usernames = list(usernames)

        query = Query()
        if usernames == []:
            usernames = [query.get_handle(ctx.author.id, ctx.guild.id)]

        users = await asyncio.gather(
            *[query.get_user(username) for username in usernames])
        usernames = [user.username for user in users]
        for i in range(len(users)):
            if users[i] is None:
                return await ctx.send(f'{usernames[i]} does not exist on DMOJ')
        if len(users) > 10:
            return await ctx.send('Too many users given, max 10')

        total_data = {}
        not_cached = []
        for username in usernames:
            q = session.query(Submission_DB)\
                .options(orm.joinedload('problem'))\
                .join(User_DB, User_DB.username == Submission_DB._user,
                      aliased=True)\
                .filter(User_DB.username == username)\
                .order_by(Submission_DB.date)

            def calculate_points(points, fully_solved):
                b = 150 * (1 - 0.997**fully_solved)
                p = 0
                for i in range(min(100, len(points))):
                    p += (0.95**i) * points[i]
                return b + p

            submissions = q.all()
            if len(submissions) == 0:
                not_cached.append(username)
            problems_ACed = dict()
            code_to_points = dict()

            points_arr = []
            data_to_plot = {}
            # O(N^2logN) :blobcreep:
            for submission in submissions:
                code = submission.problem[0].code
                points = submission.points
                result = submission.result

                if points is not None:
                    if result == 'AC':
                        problems_ACed[code] = 1
                    if code not in code_to_points:
                        # log N search, N insert
                        code_to_points[code] = points
                        bisect.insort(points_arr, points)
                    elif points > code_to_points[code]:
                        # N remove, log N search, N insert
                        points_arr.remove(code_to_points[code])
                        code_to_points[code] = points
                        bisect.insort(points_arr, points)
                    cur_points = calculate_points(points_arr[::-1],
                                                  len(problems_ACed))
                    data_to_plot[submission.date] = cur_points
            total_data[username] = data_to_plot

        if len(not_cached):
            await ctx.send(f"`{', '.join(not_cached)} do not have any cached "
                           f"submissions. Please use +cache [username]`")

        plot_points(total_data)

        with open('./graphs/plot.png', 'rb') as file:
            file = discord.File(io.BytesIO(file.read()), filename='plot.png')
        embed = discord.Embed(
            title='Point Progression',
            color=0xfcdb05,
        )
        embed.set_image(url='attachment://plot.png')

        return await ctx.send(embed=embed, file=file)
Esempio n. 3
0
async def points(ctx):
    """Plot point progression"""
    usernames = ctx.options.usernames

    query = Query()
    if usernames == []:
        usernames = [query.get_handle(ctx.author.id, ctx.get_guild().id)]

    try:
        users = await asyncio.gather(*[query.get_user(username) for username in usernames])
    except ObjectNotFound:
        return await ctx.respond("User not found")

    usernames = [user.username for user in users]
    for i in range(len(users)):
        if users[i] is None:
            return await ctx.respond(f"{usernames[i]} does not exist on DMOJ")
    if len(users) > 10:
        return await ctx.respond("Too many users given, max 10")

    total_data = {}
    for username in usernames:
        q = (
            session.query(Submission_DB)
            .options(orm.joinedload("problem"))
            .join(User_DB, User_DB.username == Submission_DB._user, aliased=True)
            .filter(User_DB.username == username)
            .order_by(Submission_DB.date)
        )

        submissions = q.all()
        if len(submissions) == 0:
            await ctx.respond(f"`{username}` does not have any cached submissions, caching now")
            await query.get_submissions(username)
            submissions = q.all()
        problems_ACed = dict()
        code_to_points = dict()

        points_arr = []
        data_to_plot = {}
        # O(N^2logN) :blobcreep:
        for submission in submissions:
            code = submission.problem[0].code
            points = submission.points
            result = submission.result

            if points is not None:
                if result == "AC":
                    problems_ACed[code] = 1
                if code not in code_to_points:
                    # log N search, N insert
                    code_to_points[code] = points
                    bisect.insort(points_arr, points)
                elif points > code_to_points[code]:
                    # N remove, log N search, N insert
                    points_arr.remove(code_to_points[code])
                    code_to_points[code] = points
                    bisect.insort(points_arr, points)
                cur_points = calculate_points(points_arr[::-1], len(problems_ACed))
                data_to_plot[submission.date] = cur_points
        total_data[username] = data_to_plot

    plot_points(total_data)

    embed = hikari.Embed(
        title="Problems Progression",
        color=0xFCDB05,
    )
    with open("./graphs/plot.png", "rb") as file:
        embed.set_image(hikari.Bytes(file.read(), "plot.png"))

    return await ctx.respond(embed=embed)
Esempio n. 4
0
    async def points(self, ctx, *usernames):
        '''Plot point progression'''
        usernames = list(usernames)

        query = Query()
        if usernames == []:
            usernames = [query.get_handle(ctx.author.id, ctx.guild.id)]

        try:
            users = await asyncio.gather(
                *[query.get_user(username) for username in usernames])
        except ObjectNotFound:
            return await ctx.send('User not found')

        usernames = [user.username for user in users]
        for i in range(len(users)):
            if users[i] is None:
                return await ctx.send(f'{usernames[i]} does not exist on DMOJ')
        if len(users) > 10:
            return await ctx.send('Too many users given, max 10')

        total_data = {}
        for username in usernames:
            await query.get_submissions(username)
            q = session.query(Submission_DB)\
                .options(orm.joinedload('problem'))\
                .join(User_DB, User_DB.username == Submission_DB._user,
                      aliased=True)\
                .filter(User_DB.username == username)\
                .order_by(Submission_DB.date)

            submissions = q.all()
            if len(submissions) == 0:
                await ctx.send(
                    f'`{username}` does not have any cached submissions, caching now'
                )
                await query.get_submissions(username)
                submissions = q.all()
            problems_ACed = dict()
            code_to_points = dict()

            points_arr = []
            data_to_plot = {}
            # O(N^2logN) :blobcreep:
            for submission in submissions:
                code = submission.problem[0].code
                points = submission.points
                result = submission.result

                if points is not None:
                    if result == 'AC':
                        problems_ACed[code] = 1
                    if code not in code_to_points:
                        # log N search, N insert
                        code_to_points[code] = points
                        bisect.insort(points_arr, points)
                    elif points > code_to_points[code]:
                        # N remove, log N search, N insert
                        points_arr.remove(code_to_points[code])
                        code_to_points[code] = points
                        bisect.insort(points_arr, points)
                    cur_points = calculate_points(points_arr[::-1],
                                                  len(problems_ACed))
                    data_to_plot[submission.date] = cur_points
            total_data[username] = data_to_plot

        plot_points(total_data)

        with open('./graphs/plot.png', 'rb') as file:
            file = discord.File(io.BytesIO(file.read()), filename='plot.png')
        embed = discord.Embed(
            title='Point Progression',
            color=0xfcdb05,
        )
        embed.set_image(url='attachment://plot.png')

        return await ctx.send(embed=embed, file=file)