Skip to content
Advertisement

How can I make a command in discord.py that can print the graph of a linear equation?

import discord
from discord.ext import commands
import matplotlib.pyplot as plt


class Equations(commands.Cog):

    def __init__(self, client):
        self.client = client

    def plotlineareq(a, b, clr):
        x = [-10, 10]
        y = [(a * i + b) for i in x]
        plt.figure(figsize=(7, 7))  # #Size of Graph
        plt.xlim(x)  # #X Range [-6,6]
        plt.ylim(x)  # #Y Range [-6,6]
        axis = plt.gca()  # #Get Current Axis
        plt.plot(axis.get_xlim(), [0, 0], 'k--')  # #X Axis Plots Line Across
        plt.plot([0, 0], axis.get_ylim(), 'k--')  # #Y Axis Plots Line Across
        plt.locator_params(axis="x", nbins=20)
        plt.locator_params(axis="y", nbins=20)
        plt.plot(x, y, label='linear', linestyle='-', color=clr)
        plt.ylabel('y')
        plt.xlabel('x')
        mm = str(a)
        bb = str(b)
        plt.title("y = " + mm + "x + " + bb)
        plt.grid()
        plt.savefig("foo.png")

    @commands.command()
    async def linear(self, message):
        try:
            msg = message.content
            msg = msg.split("*linear")[1]
            msg = msg.replace(" ", "")
            mm = msg.split("x")[0]
            mx = mm.replace("x", "").replace("y=", "")
            bx = msg.split("+")[1]
            Equations.plotlineareq(mx, bx, 'b')
            file = discord.File("foo.png", filename='foo.png')
            embed = discord.Embed(color=0xff0000)
            embed = embed.set_image(url="attachment://foo.png")
            await message.channel.send(file=file, embed=embed)
        except:
            message.channel.send("An error occurred")

def setup(client):
    client.add_cog(Equations(client))

This is the code of my cog so far. The function “plotlineareq()” first makes a graph with 4 quadrants. Then it takes in the variables “a” (which is the gradient) and the variable “b” (which is the y-intercept). It creates a graph from these variables and saves it as foo.png. This part works separately. The other function is supposed to wait for a message that starts with my prefix “*” and “linear”. A sample message template would be “*linear y=3x+2”. When a message is sent it takes the values a and b from the message (in this case a=3 and b=2. This part also worked correctly alone It then runs the function “plotlineareq()” with these variables and then takes the image “foo” it creates and sends it as an embed. There is no error message that appears as an output. It just doesn’t seem to be triggering the function “linear”. What have I done wrong?

edit: After taking the suggestions of

    @commands.command()
    async def linear(self, ctx, equation):
        try:
            equation = equation.replace(" ", "")
            mx = equation.split("x")[0]
            mx = equation.replace("x", "").replace("y=", "")
            bx = equation.split("+")[1]
            Equations.plotlineareq(mx, bx, 'b')
            file = discord.File("foo.png", filename='foo.png')
            embed = discord.Embed(color=0xff0000)
            embed = embed.set_image(url="attachment://foo.png")
            await ctx.channel.send(file=file, embed=embed)

it still is not working. Again there is no error message. It just is not triggering the function.

Advertisement

Answer

The message argument you first passed in the command would be the Context, you also need to pass the equation argument

@commands.command()
async def linear(self, ctx, equation): # The `equation` arg is going to be a string
    print(equation)

# *linear y=3x+2
# [bot] y=3x+2

More things wrong in your code

  1. The plotlineareq should also take the self as the first argument
  2. When calling the plotlineareq function, you don’t call it like so Equation.plotlineareq, you call it like this: self.plotlineareq

Your whole code fixed:

import discord
from discord.ext import commands
import matplotlib.pyplot as plt


class Equations(commands.Cog):
    def __init__(self, client):
        self.client = client

    def plotlineareq(self, a, b, clr):
        x = [-10, 10]
        y = [(a * i + b) for i in x]
        plt.figure(figsize=(7, 7))  # #Size of Graph
        plt.xlim(x)  # #X Range [-6,6]
        plt.ylim(x)  # #Y Range [-6,6]
        axis = plt.gca()  # #Get Current Axis
        plt.plot(axis.get_xlim(), [0, 0], 'k--')  # #X Axis Plots Line Across
        plt.plot([0, 0], axis.get_ylim(), 'k--')  # #Y Axis Plots Line Across
        plt.locator_params(axis="x", nbins=20)
        plt.locator_params(axis="y", nbins=20)
        plt.plot(x, y, label='linear', linestyle='-', color=clr)
        plt.ylabel('y')
        plt.xlabel('x')
        mm = str(a)
        bb = str(b)
        plt.title("y = " + mm + "x + " + bb)
        plt.grid()
        plt.savefig("foo.png")

    @commands.command()
    async def linear(self, ctx, equation):
        try:
            equation = equation.replace(" ", "")
            mx = equation.split("x")[0]
            mx = equation.replace("x", "").replace("y=", "")
            bx = equation.split("+")[1]
            self.plotlineareq(mx, bx, 'b')
            file = discord.File("foo.png", filename='foo.png')
            embed = discord.Embed(color=0xff0000)
            embed = embed.set_image(url="attachment://foo.png")
            await ctx.send(file=file, embed=embed)
        
        except Exception as e:
            await ctx.send(f"An error occured: {e}")

def setup(client):
    client.add_cog(Equation(client))
Advertisement