예제 #1
0
    async def type(self,
                   ctx,
                   as_percent: typing.Optional[as_percentage] = True,
                   graph: typing.Optional[graph_type] = 'radar',
                   *usernames):
        """Graph problems solved by popular problem types"""
        # This is aids, pls fix

        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])
        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) > 6:
            return await ctx.send('Too many users given, max 6')

        usernames = [data.username for data in users]

        important_types = [['Data Structures'], ['Dynamic Programming'],
                           ['Graph Theory'], ['String Algorithms'],
                           [
                               'Advanced Math', 'Geometry',
                               'Intermediate Math', 'Simple Math'
                           ], ['Ad Hoc'], ['Greedy Algorithms']]
        labels = [
            'Data Structures', 'Dynamic Programming', 'Graph Theory',
            'String Algorithms', 'Math', 'Ad Hoc', 'Greedy Algorithms'
        ]

        data = {}
        data['group'] = []
        for label in labels:
            data[label] = []
        for username in usernames:
            data['group'].append(username)

        def calculate_points(points: int):
            p = 0
            for i in range(min(100, len(points))):
                p += (0.95**i) * points[i]
            return p

        def to_points(problem):
            return problem.points

        max_percentage = 0
        not_cached = []

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

        for i, types in enumerate(important_types):
            total_problems = await query.get_problems(_type=types, cached=True)
            total_points = list(map(to_points, total_problems))
            total_points.sort(reverse=True)
            total_points = calculate_points(total_points)

            for username in usernames:
                problems = query.get_attempted_problems(username, types)

                points = list(map(to_points, problems))
                points.sort(reverse=True)

                points = calculate_points(points)
                if as_percent:
                    percentage = 100 * points / total_points
                else:
                    percentage = points
                max_percentage = max(max_percentage, percentage)
                data[labels[i]].append(percentage)

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

        if graph == 'radar':
            plot_type_radar(data, as_percent, max_percentage)
        elif graph == 'bar':
            plot_type_bar(data, as_percent)

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

        return await ctx.send(embed=embed, file=file)
예제 #2
0
async def type(ctx):
    """Graph problems solved by popular problem types"""
    # TODO: This is aids, pls fix

    usernames = ctx.options.usernames
    graph_type = ctx.options.graph_type
    as_percent = ctx.options.as_percent

    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")

    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) > 6:
        return await ctx.respond("Too many users given, max 6")

    usernames = [data.username for data in users]

    important_types = [
        ["Data Structures"],
        ["Dynamic Programming"],
        ["Graph Theory"],
        ["String Algorithms"],
        ["Advanced Math", "Geometry", "Intermediate Math", "Simple Math"],
        ["Ad Hoc"],
        ["Greedy Algorithms"],
    ]
    labels = [
        "Data Structures",
        "Dynamic Programming",
        "Graph Theory",
        "String Algorithms",
        "Math",
        "Ad Hoc",
        "Greedy Algorithms",
    ]

    data = {}
    data["group"] = []
    for label in labels:
        data[label] = []
    for username in usernames:
        data["group"].append(username)

    def calculate_partial_points(points: int):
        p = 0
        for i in range(min(100, len(points))):
            p += (0.95**i) * points[i]
        return p

    max_percentage = 0

    for username in usernames:
        q = session.query(Submission_DB).filter(Submission_DB._user == username)
        if q.count() == 0:
            await ctx.respond(f"`{username}` does not have any cached submissions, caching now")
            await query.get_submissions(username)

    for i, types in enumerate(important_types):
        total_problems = await query.get_problems(_type=types, cached=True)
        total_points = list(map(attrgetter("points"), total_problems))
        total_points.sort(reverse=True)
        total_points = calculate_partial_points(total_points)

        for username in usernames:
            points = query.get_attempted_problems(username, types)

            points.sort(reverse=True)

            points = calculate_partial_points(points)
            if as_percent:
                percentage = 100 * points / total_points
            else:
                percentage = points
            max_percentage = max(max_percentage, percentage)
            data[labels[i]].append(percentage)

    logger.debug("plot type data: %s", data)

    if graph_type == "radar":
        plot_type_radar(data, as_percent, max_percentage)
    elif graph_type == "bar":
        plot_type_bar(data, as_percent)

    embed = hikari.Embed(
        title="Problem types solved",
        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)