1

How do I force the user to label positional arguments with commands in Discord.py. For instance, I have the following function:

bot = commands.Bot('#')
@bot.command()
async def example_function(ctx, a: int, b: int, c: int):
    await ctx.send((a+c)/b)

How do I force the user to label the arguments? i.e. invoke the command like this:

#example_function -a=7 -b=8 -c=5

The reason I ask is - I have several complex functions which need multiple variables to be passed for a Dicord Bot I created and it would be better and less error-prone if the user labels the arguments.

Patrick Haugh
  • 59,226
  • 13
  • 88
  • 96
Legion
  • 454
  • 2
  • 7
  • 17

1 Answers1

0

As far as I know, there is nothing built into discord.py that provides this feature. What you'll probably want to do is take in the entire message (everything past the command invocation), and then parse the message to extract the arguments.

import shlex

bot = commands.Bot('#')
@bot.command(pass_context=True)
async def example(self, context, *, message: str):
    ''' example command '''
    args = shlex.split(message)
    opts = {k.strip('-'): True if v.startswith('-') else v
       for k,v in zip(args, args[1:]+["--"]) if k.startswith('-')}
    a, b, c = (int(x) for x in (opts[y] for y in 'acb'))
    self.send((a + c) / b)

User invokes command with:

#example --a 7 --b 8 --c 5

options variable becomes:

{'a': '7', 'c': '5', 'b': '8'}

bot sends:

1.5

You'll probably want to provide your own handling of the options string, but this is a good starting point.

Option parsing taken from https://stackoverflow.com/a/12013711/5946921

Will Da Silva
  • 6,386
  • 2
  • 27
  • 52
  • Thanks for that, I had to chnage it a bit - but it eventually worked. One more question- what if I want to chnage the variable names to more complex ones (like scatter_dist, arc_tan, etc.)? – Legion Jun 07 '18 at 00:00
  • tokens_with_underscores will work fine with the important part of the provided code. The line where I assign the variables a, b, and c would need to be changed such that the iterable 'abc' is instead ('a', 'b', 'c', 'arc_tan', 'scatter_dist'), or something equivalent. That said, the way those variables are assigned is currently unsafe, probably unnecessary, and is only there for the sake of the example (i.e. doing what you wanted the code you posted to do). It'd probably be best to just maintain the opts dictionary, rather than assign every element that might be in it to a variable. – Will Da Silva Jun 07 '18 at 13:35