How can I differentiate between a multi-word argument and a second argument?

Question:

So, I’m writing a Discord bot in Python, and I made a poll command. However, the issue is that whenever I try to make a multi-word poll (Such as "Who is better?") it takes the first word as the poll name, but everything else becomes options.

To put it simply…

#Poll command, command prefix is $
@bot.command()
async def poll(ctx,message,q1,q2,q3=None,q4=None,q5=None):
    q1r = '1️⃣'
    q2r = '2️⃣'
    q3r = '3️⃣'
    q4r = '4️⃣'
    q5r = '5️⃣'
    msg = q1r + " " + q1 + "n " + q2r + " " + q2
    if q3 != None:
        msg = msg + "n " + q3r + " " + q3
    if q4 != None:
        msg = msg + "n " + q4r + " " + q4
    if q5 != None:
        msg = msg + "n " + q5r + " " + q5
    embed = discord.Embed(title=message,description=msg)
    msg = await ctx.send(embed=embed)
    await msg.add_reaction(q1r)
    await msg.add_reaction(q2r)
    if q3 != None:
        await msg.add_reaction(q3r)
    if q4 != None:
        await msg.add_reaction(q4r)
    if q5 != None:
        await msg.add_reaction(q5r)

In a discord server with the bot, I type $poll Who is better? Spider-Man Iron-Man, and I get a poll with the name "Who", and I get options "is", "better?", "Spider-Man", "Iron-Man".
I know it is an issue with how the command is written, but I do not know how to write it so that the poll name can contain multiple words.

Really, I have no idea what to do for this. any help is appreciated, and I would love to fix this so that I can get to working on other commands for the bot.

Asked By: Fuery

||

Answers:

When you pass parameters, use double quotes to group multi-word parameters:

program "Who is better?"

Inside program, first parameter ($1) receives ‘Who is better?’ value, without double quotes.

If you intend to pass this value to another program, you may use double quotes again:

Some languages use some scape character like "":

msg = """ + q1r + "" "" + q1 + ""n "" + q2r + "" "" + q2 + """

Others use duplicated characters:

msg = """" + q1r + """ """ + q1 + """n """ + q2r + """ """ + q2 + """"

Answered By: Arthur Heinrich

You can use an asterisk (*) to make your arguments parse differently, just like regular Python functions. By default, discord.py splits a string on spaces, but wrapping something in "double quotes" will parse it as 1 string (even though there’s a space in there).

Docs: https://discordpy.readthedocs.io/en/latest/ext/commands/commands.html#parameters

async def command(ctx, argument1, argument2):
    # Invoking "!command first second" will be parsed as
    # argument1: "first"
    # argument2: "second"

# Varargs-style
async def command(ctx, argument1, *argument2):  # Note the asterisk
    # Invoking "!command first second third fourth" will be parsed as
    # argument1: "first"
    # argument2: ("second", "third", "fourth")

# Keyword-args-style
async def command(ctx, argument1, *, argument2):  # Note the position of the asterisk
    # Invoking "!command first second third fourth" will be parsed as
    # argument1: "first"
    # argument2: "second third fourth"

You mentioned in the comments that you’d like to split the arguments based on commas instead, and you can use basic Python string splitting for that, combined with the third option above ^. Taking the entire argument as 1 single string and using .split(",") should do what you want. Though you might want to call strip() on them in case people add spaces before/after their commas.

Alternatively, you can write your own custom converter to parse the arguments yourself into a custom class & make the string parsing a bit fancier. All up to you.

Answered By: stijndcl
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.