#What is the Maximum for an Autoselect?
1 messages · Page 1 of 1 (latest)
Please use either the disnake or python tag, but not both. If your question pertains to disnake, please use the disnake tag. If your question is a general python question that does not depend on disnake, please use the python tag.
I've taken a guess based on the contents of your message which your question is actually about.
If you believe this to be in error, please let us know.
autoselect?
You mean autocomplete?
Yes
You can only display up to 25 options, but with some tricks you can dynamically update that list as the user types
How can I use this trick? I need to make 95 Options
Or is there an way to change an Autocomplete after I have chosen the autocomplete before that one
the easiest way for something basic is
return your list of options but spliced [:24]
How?
example:
@bot.slash_command(name="test")
async def test(inter, option: str):
pass
@test.autocomplete("option")
async def test_autocomplete(inter, option: str):
options = [str(i) for i in range(100)]
return [o for o in options if option in o][:25]
this would show options 0, 24, then as the user types, it would dynamically change to up to 25 possible options based on what has been typed so far
but, you might also want to look into fuzzy matching (maybe this? https://github.com/seatgeek/fuzzywuzzy)
you can have multiple autocompletes that can update as previous options are selected.
but be aware, autocomplete is not like choices. They are suggestions, but the user can still enter and submit whatever they want. choices are the only way to prevent the user from selecting any other option, but choices can't be handled dynamically in the same way as far as I'm aware
How?
I use thefuzz to match options in a list and return those matched options to the autocomplete
@game_roles_add.autocomplete("game")
async def autocomplete_games(self, inter: disnake.ApplicationCommandInteraction, game: str):
return await self.get_game(game)
async def get_game(self, string: str):
games = []
with open("/usr/app/gameslist.json") as f:
data = json.load(f)
for i in data:
games.append(i["name"])
values: list[str] = process.extract(string, games, limit=25)
return [i[0] for i in values]
You obviously don’t need the extra function but this is how I do it.
@test.autocomplete("TARGET_VARIABLE")
you define a auto completer for each named variable in the slash command
Wait
how about we uh
but if you want to have options based on a previous selected option, you need to pass the extra args to the next auto complete and then return different options based on the previously selected option
That means when I choose here Weapon I can instant change the name to an Autocomplete with all the weapon
An example showcasing the two ways of adding autocompletion to slash command options.
correct
you can see the values for previous options through
How can I do that? I dont get this out the autocomplete.py
-d disnake.Interaction.filled_options
Returns the follow up webhook for follow up interactions.
-d inter.data.filled_options
element_options(elementname)```
Returns the list of *elementname*’s options.
that won't work
property filled_options```
The options of the command (or sub-command) being invoked
whoops
inter.data.options should give you a list of all the options in the command, find the argument you're looking for and the value should be there i think
not sure, I just know filled_options is a simple dict of {option_name: value}
which is exactly what you want for this usecase
ah
What
what
I dont get it how to make it
i couldn't see the filled_options at first in the docs, my bad
all good ^^
- you make an autocomplete for
name - inside the autocomplete, you use
inter.filled_options["argument"]to figure out what the user picked there - you get all possible names for that argument
- you filter out the best 25 matches
- you return that
Now I just need to know how to make when I choose here in picture one Weapon how I can make that the argument name makes me an autocomplete with The weapons and when I choose Item there is not the autocomp that I have for the Weapons
that's what I just said.
I am confused
I am sharp eyes
what about this is unclear to you? just asking so I can try to explain
So I choose in the autocomp_weapon the Value Weapon then he will show me autocomp_weapon2 but when I choose Item as the Value I see autocomp_item right?
nope
But this is what I want
you're making an autocomplete for the parameter "name"
a single parameter can only have one autocomplete
you can't just assign a bunch of different callbacks to the same parameter
instead, you'll have to make one autocomplete for name, and use inter.filled_options inside that autocomplete to get the value the user entered at argument.
so I cannot get the value he had chosen in the argument field?
also gave you the exact step-by-step here
Wait I can make an global var that will send to the autocomp that I have choosen x or y and then when I have choosen x I will see xy and when I have chosen y I see yz
Weapons2 = ['Weapon1', 'Weapon2']
Items = ['Item1', 'Item2']
async def autocomp_weapon2(inter: disnake.ApplicationCommandInteraction, user_input: str):
if inter.filled_options == 'Weapon':
return [weapon for weapon in Weapons2 if user_input.lower() in weapon]
elif inter.filled_options == 'Item':
return [item for item in Items if user_input.lower() in item]
``` like this?
^
it's a dict
inter.filled_options will look like e.g. {"key": "dd", "argument": "Weapon"}
which should be enough to tell you what to do
I can just ask if "Weapon" is in {"key": "dd", "argument": "Weapon"}
that's not how dicts work, no
Wait I try
won't work
x in <dict> compares x to the keys of the dict
I just decode it as an Json
not the values
how about
if <dict>[<key>] == <value>
i.e. in your case
if inter.filled_options["argument"] == "Weapons":
Thanks
goods = {
"Weapons" : {"Weps","More Weps"},
"Fruits" : {"Bananas","Rubber Bananas"},
"Drugs" : {"Cake", "Valheim"}
}
qualities = {
"weapons" : {"Brand New","Broken"},
"fruits" : {"Rotten","Fresh"},
"drugs" : {"Cut", "Laced"}
}
@commands.slash_command(description="Buy some shit")
async def buy_shit(inter ,goods_type = commands.Param(choices = goods.keys(),specific_good = commands.Param(description="asd") , quality = commands.Param(description="lel")):
pass
@buy_shit.autocomplete("specific_good")
async def autocomp_specific_goods(inter,input:str):
return [item for item in goods[inter.filled_options["goods_type"]].casefold() if input.casefold() in item]
@buy_shit.autocomplete("quality")
async def autocomp_quality(inter,input:str):
if inter.filled_options["specific_good"].lower() in qualities: #Autocompleters don't enforce input so validity check is prudent
return [item for item in qualities[inter.filled_options["specific_good"]].casefold() if input.casefold() in item]
else:
return ["Check previous argument"]
Did like a 13 hour bender yd...
I have it now
please use /solved if your issue was resolved ^^