Discord py send random interger in embed message - discord.py

im trying to make a random number generator command for discord py which will choose a random number from what the user have send, the first number, user can input any number but the second number, user need to input the bigger number than the first number so the bot will choose a random number between the first and the second number. The command works fine but the number only choose the first or second number and not the random number between the first and second number. Heres the code :
#client.command()
async def randomnumber(ctx):
def check(msg):
return msg.author == ctx.author and msg.content.isdigit() and \
msg.channel == ctx.channel
embed1 = discord.Embed(title = "Random Number Generator!!", description = "<:_Paimon6:827074349450133524>", color = ctx.author.color)
embed1.add_field(name='Type a number', value=f'First Number : Not Yet Added!!!\nSecond Number : Not Yet Added!!!', inline=False)
await ctx.send(embed = embed1)
msg1 = await client.wait_for("message", check=check)
embed2 = discord.Embed(title = "Random Number Generator!!!", description = "<:_Paimon6:827074349450133524>", color = ctx.author.color)
embed2.add_field(name='Type a second number, higher number than first number', value=f'First Number : {msg1.content}\nSecond Number : Not Yet Added!!!', inline=False)
await ctx.send(embed = embed2)
msg2 = await client.wait_for("message", check=check)
x = int(msg1.content)
y = int(msg2.content)
if x < y:
value = (x,y)
embed3 = discord.Embed(title = "Random Number Generator!!", description = "<:_Paimon6:827074349450133524>", color = ctx.author.color)
embed3.add_field(name='Result number', value=f'First Number : {msg1.content}\nSecond Number : {msg2.content}\n\nYou got {random.choice(value)} <:_pTooEaassy:827076106884087818>', inline=False)
await ctx.send(embed = embed3)
else:
embed4 = discord.Embed(title = "Random Number Generator!!", description = "<:_Paimon6:827074349450133524>", color = ctx.author.color)
embed4.add_field(name='Error', value='You didnt enter the number correctly so paimon dont know what to send <:_Paimon10:827077240079777812>', inline=False)
await ctx.send(embed = embed4)
I know that the problem was on the "value" one but idk what should i change there to make the bot choose a random number between the two number, thank you.

You can use the random.randrange function
>>> import random
>>> values = (1, 10) # hardcoding for demonstration purposes
>>> random.randrange(*values) # unpacking the tuple
6
>>> random.randrange(*values)
3
>>> random.randrange(*values)
4

Related

Problem in embed-reaction system. Discord.py

So I wrote this code that sends an embed and changes its value/item once the user reacts to certain emoji. It works fine for a single embed but when user asks for same multiple embeds like you see in the image, reaction to a embed changes value of other similar embeds too.
Code part
#client.command()
async def embed(ctx):
current = 1
embed = discord.Embed(title = f'{current}')
buttons = [ u"\u25C0", u"\u25FC" , u"\u25B6" , u"\U0001F5D1"]
msg = await ctx.send(embed = embed)
for button in buttons:
await msg.add_reaction(button)
while True:
try:
reaction , user = await client.wait_for("reaction_add", check = lambda reaction,user: user == ctx.author and reaction.emoji in buttons, timeout = 180.0)
except asyncio.TimeoutError:
embed.set_footer(text= "Timeout.")
await msg.clear_reactions()
else:
previous_page = current
if reaction.emoji == u"\u25C0":
current -= 1
embed.add_field(name = None, value = f'{current}')
elif reaction.emoji == u"\u25FC":
if current > 0:
current = 0
embed.add_field(name = None, value = f'{current}')
elif reaction.emoji == u"\u25B6":
current += 1
embed.add_field(name = None, value = f'{current}')
elif reaction.emoji == u"\U0001F5D1":
await msg.edit(embed = embed)
await msg.clear_reactions()
for button in buttons:
await msg.remove_reaction(button, ctx.author)
if current != previous_page:
embed.add_field(name = None, value = f'{current}')
await msg.edit(embed = embed)
Images: https://imgur.com/a/fEpz9jD
NOTE: The code I've used in my bot is exactly same as this one. I haven't included that and screenshots of those embeds because it is being used for NSFW purposes/images.
Thanks.
This may be happening because of your check function (line 13)
check = lambda reaction,user: user == ctx.author and reaction.emoji in buttons
Here you are checking that the emoji are matching, and the user reacting is the same user that executed the command. But you don't check which message the reaction was added to. To solve this, you could check for the message id, by checking if reaction.message.id == ctx.message.id what results in :
check = lambda reaction,user: user == ctx.author and reaction.emoji in buttons and reaction.message.id == msg.id

Getting input from reactions not working discord.py

I wanted to make a rock paper scissor game for my bot:
The bot creates an embed with instructions and reacts with a "rock", "paper", and "scissor" emoji, which the user has to click to input his/her choice.
But the problem is that the code doesn't go any further and shows an error.
Here is the code:
#client.command(aliases = ["rock_paper_scissors","rps"])
async def _rps(ctx): #rps is short for rock, paper, scissor
emojis = ['✊', '🖐️', '✌️']
embedVar = discord.Embed(title="CHOOSE YOUR WEAPON!",description = "Choose between rock, paper, or scissors, {}." . format(ctx.author.mention), color = 0xff9900)
embedVar.add_field(name=":fist: ROCK", value="React with :fist: emoji to choose rock.", inline = False)
embedVar.add_field(name=":hand_splayed: PAPER", value="React with :hand_splayed: emoji to choose paper.", inline = False)
embedVar.add_field(name=":v: SCISSORS", value="React with :v: emoji to choose scissors.", inline = False)
emb = await ctx.send(embed = embedVar)
for emoji in emojis:
await emb.add_reaction(emoji)
def chk(reaction):
return reaction.emb == emb and reaction.channel == ctx.channel
react = await client.wait_for('reaction_add', check=chk)
if react == '✊':
await ctx.send("You chose rock!")
elif react == '🖐️':
await ctx.send("You chose paper!")
elif react == '✌️':
await ctx.send("You chose scissors!")
I am getting this error:
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: chk() takes 1 positional argument but 2 were given
I tried many fixes but in vain.
Also, I want the bot to accept the input only from the user who had asked for the rock paper scissor game by the command in the first place (the author of the message, in other words), But I am not sure how to implement that, I tried, but it did not work.
How can I fix this?
reaction_add gives a tuple of a reaction and a user so in the chk function you need to have both the reaction and user. You should also use and user == ctx.author within the chk function to ensure the user is the same.
#client.command(aliases = ["rock_paper_scissors","rps"])
async def _rps(ctx): #rps is short for rock, paper, scissor
emojis = ['✊', '🖐️', '✌️']
embedVar = discord.Embed(title="CHOOSE YOUR WEAPON!",description = "Choose between rock, paper, or scissors, {}." . format(ctx.author.mention), color = 0xff9900)
embedVar.add_field(name=":fist: ROCK", value="React with :fist: emoji to choose rock.", inline = False)
embedVar.add_field(name=":hand_splayed: PAPER", value="React with :hand_splayed: emoji to choose paper.", inline = False)
embedVar.add_field(name=":v: SCISSORS", value="React with :v: emoji to choose scissors.", inline = False)
emb = await ctx.send(embed = embedVar)
for emoji in emojis:
await emb.add_reaction(emoji)
def chk(reaction, user):
return reaction.emb == emb and reaction.channel == ctx.channel and user == ctx.author
react, user = await client.wait_for('reaction_add', check=chk)
if react == '✊':
await ctx.send("You chose rock!")
elif react == '🖐️':
await ctx.send("You chose paper!")
elif react == '✌️':
await ctx.send("You chose scissors!")

Trying to make a kind of pls dep all or pls dep max kind of thing

I'm making a currency bot but I can't seem to figure out how to do something like: [prefix] deposit all/[prefix] withdraw all or [prefix] deposit max/[prefix] withdraw max but I can't seem to figure out how to do it. This is my code so far for deposit:
#client.command()
async def dep(ctx, amount=0):
users = await get_bank_data()
user = ctx.author
if amount > 0:
users[str(user.id)]['wallet'] -= amount
users[str(user.id)]['bank'] += amount
with open("mainbank.json", "w") as f:
json.dump(users, f)
await ctx.send(f"You have deposited {amount} coins!")
elif amount < 0:
await ctx.send(f"You can't deposit a negative amount of coins stupid!")
elif amount == 0:
await ctx.send(f"You can't deposit 0 coins stupid!")```
You can simply use the in keyword to check if the amount arg is either max or all, to check if it's a digit use str.isdigit()
async def dep(ctx, amount: str):
if amount.lower() in ["max", "all"]:
# Deposit all the money here
elif amount.isdigit() and int(amount) > 0:
amount = int(amount)
# The `amount` variable is now a positive integer, deposit it here
You can do the withdraw command on the same basis

problems with the leaderboard discord.py

The leaderboard shows the same username even if they are different users in case they have the same value.
I don't know how to solve it but when in the code I ask to resist a variable it gives me only 3 elements and not 4 even if 4 come out.
code:
#client.command(aliases = ["lb"])
async def leaderboard(ctx,x = 10):
leader_board = {}
total = []
for user in economy_system:
name = int(user)
total_amount = economy_system[user]["wallet"] + economy_system[user]["bank"]
leader_board[total_amount] = name
total.append(total_amount)
print(leader_board)
total = sorted(total,reverse=True)
embed = discord.Embed(
title = f"Top {x} Richest People",
description = "This is decided on the basis of raw money in the bank and wallet",
color = 0x003399
)
index = 1
for amt in total:
id_ = leader_board[amt]
member = client.get_user(id_)
name = member.name
print(name)
embed.add_field(
name = f"{index}. {name}",
value = f"{amt}",
inline = False
)
if index == x:
break
else:
index += 1
await ctx.send(embed=embed)
print resists this:
{100: 523967502665908227, 350: 554617490806800387, 1100: 350886488235311126}
Padre Mapper
Flore (Orsolinismo)
Aetna
Aetna
In theory there should also be 100: 488826524791734275 (i.e. my user id) but it doesn't find it.
Your problem comes from this line:
leader_board[total_amount] = name
If total_amount is already a key (eg. two users have the same amount of money), it will replace the previous value (which was a user ID) and replace it with another user ID. In this situation, if multiple users have the same amount of money, only one will be saved in leader_board.
Then, you have this line:
total.append(total_amount)
In this case, if two users have the same amount of money, you would just have two identical values, which is normal but, considering the problem above, this will create a shift.
Let's say you have ten users with two of them who have the same amount of money. leader_board will only contain 9 items whereas total will contain 10 values. That's the reason why you have two of the same name in your message.
To solve the problem:
#client.command(aliases = ["lb"])
async def leaderboard(ctx, x=10):
d = {user_id: info["wallet"] + info["bank"] for user_id, info in economy_system.items()}
leaderboard = {user_id: amount for user_id, amount in sorted(d.items(), key=lambda item: item[1], reverse=True)}
embed = discord.Embed(
title = f"Top {x} Richest People",
description = "This is decided on the basis of raw money in the bank and wallet",
color = 0x003399
)
for index, infos in enumerate(leaderboard.items()):
user_id, amount = infos
member = client.get_user(user_id)
embed.add_field(
name = f"{index}. {member.display_name}",
value = f"{amount}",
inline = False
)
await ctx.send(embed=embed)
If I guessed right and your dictionnary is organized like this, it should work:
economy_system = {
user_id: {"bank": x, "wallet": y}
}

discord.py rewrite | Problem with getting author message

I've been making a number game command in my server, and someone recommended I add difficulties. So, I have 3 difficulties for the user to chose from.
I have already got a bit of code which got the author's response and worked, so I re-used it in my code, and now I am stumped. It may be glaringly obvious, but I cannot find it:
#client.command(name='numgame',
brief='Guess a number between 1 and 100',
pass_ctx=True)
async def numgame(ctx):
if ctx.author.id != 368442355382222849:
await ctx.send('Command currently disabled')
return
await ctx.send('Difficulties: a] 1-10 b] 1-50 c] 1-100')
msg = await client.wait_for('message', check=check(ctx.author), timeout=30)
diff = str(msg.content)
if diff == 'a':
max = 10
number = random.randint(1,10)
await ctx.send('You have 5 guesses')
await ctx.send('Pick a number between 1 and 10')
elif diff == 'b':
max = 50
number = random.randint(1,50)
await ctx.send('You have 5 guesses')
await ctx.send('Pick a number between 1 and 50')
elif diff == 'c':
max = 100
number = random.randint(1,100)
await ctx.send('You have 5 guesses')
await ctx.send('Pick a number between 1 and 100')
else:
ctx.send('Please try the command again...')
return
msg = None
This is the check I am using:
def check(author):
def inner_check(message):
# author check
if message.author != author:
return False
# inner check
try:
int(message.content)
return True
except ValueError:
return False
When I respond to the bot in-chat with "a", "b" or "c", I get no response.
I disabled the command for everyone but me whilst I tried to fix it, but I have no idea how to start.
I would appreciate an answer, as I don't see the solution myself, thanks!
[I didn't show the actual number game, because it is irrelevant and long]
Just create a new check function that does what you want.
def abc_check(author):
def inner_check(message):
return author == message.author and message.content in ('a', 'b', 'c')
return inner_check

Resources