#๐ Help with command
226 messages ยท Page 1 of 1 (latest)
@tall belfry
Remember to:
- Ask your Python question, not if you can ask or if there's an expert who can help.
- Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
- Explain what you expect to happen and what actually happens.
:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.
The Error:
The code:
def save_warn(ctx, member: discord.Member):
with open('warns.json', 'r') as f:
warns = json.load(f)
warns[str(member.id)] += 1
with open('warns.json', 'w') as f:
json.dump(warns, f)
def remove_warn(ctx, member: discord.Member, amount: int):
with open('warns.json', 'r') as f:
warns = json.load(f)
warns[str(member.id)] -= amount
with open('warns.json', 'w') as f:
json.dump(warns, f)
def warns_check(member: discord.Member):
with open('warns.json', 'r') as f:
warns = json.load(f)
warns[str(member.id)]
return warns
@bot.command()
@commands.has_permissions(kick_members=True)
async def warn(ctx, member: discord.Member, *, reason):
save_warn(ctx, member)
dm = await bot.fetch_user(member.id)
em=discord.Embed(title="Warning", description=f"Server: {ctx.guild.id}\nReason: {reason}"
await dm.send(embed=em)
@bot.command()
@commands.has_permissions(kick_members=True)
async def warnings(ctx, member: discord.Member):
warns = warns_check(member)
await ctx.send(f"{member.name} has {warns} warnings.")
@bot.command()
@commands.has_permissions(kick_members=True)
async def rmwarn(ctx, member: discord.Member, amount: int):
remove_warn(ctx, member, amount)
await ctx.send(f"Removed {amount} warnings from {member.name}!")```
I believe it is the formatting of the json please have a look at the structure of the json files
look at your json file it is not in json file formatting missing comma or bracket or something likle that
json files
ohhh i understand i guess
Im getting a mental breakdown๐ฅฒ
Tbh i dont know what i've done but idk what to fix or to look for i fixed the json file
Check if you are on a call. This is unrelated to your problem but your notification bar suggests so.
I am on a call with my gf
ok
I want you to scroll to the end of the error message as well
def warns_check(member: discord.Member):
with open('warns.json', 'r') as f:
warns = json.load(f)
# Added a default value (an empty list) which is
# returned when the user has no warnings
warns.get(str(member.id), [])
return warns
Ima try that 1 sec
Why does it only return the {} ?
How do you store your warnings? As a list as I assumed, or do you use a dictionary?
In other words, what is the return type of the function I edited?
Uhh
Idk tbh im kinda confused rn
Like im pretty new to python but i got the basic knowlegde and my friend bascially teaches me if i need help and he told me to do it in this way and it will work fine
does dm feature work?
I'll change it once i got the code working, but it does not work as of right now.
I just found out you store warnings as a number not a list
warns.get(str(member.id), 0)
This should work
lemme try
Share this error as text instead of screenshot. I want to tell you something.
i cant due to me being on mobile
What app are u using to code?
Ok, just clear the json file and run it again
just basically an empty file or what should i put in it?
remove the file
yes
but then you will get an error
FileNotFoundError
Just try one last time to copy the error text
File "/home/container/.local/lib/python3.13/site -packages/discord/ext/commands/core.py", line 235, in wrapped
ret = await coro(*args, **kwargs)
File "/home/container/main.py", line 652, in war nings
warns warns_check(member)
File "/home/container/main.py", line 55, in warn s_check
warns [str(member.id)]
KeyError: '1244794665769766967'
The above exception was the direct cause of the fo llowing exception:
Traceback (most recent call last):
File "/home/container/.local/lib/python3.13/site -packages/discord/ext/commands/bot.py", line 1366, in invoke
await ctx.command.invoke(ctx)
File "/home/container/.local/lib/python3.13/site
-packages/discord/ext/commands/core.py", line 1029 , in invoke
await injected(*ctx.args, **ctx.kwargs) # typ e: ignore
File "/home/container/.local/lib/python3.13/site -packages/discord/ext/commands/core.py", line 244, in wrapped
raise Command Invoke Error (exc) from exc discord.ext.commands.errors.Command InvokeError: Co mmand raised an exception: KeyError: '124479466576 9766967'
Like this?
File "/home/container/.local/lib/python3.13/site -packages/discord/ext/commands/core.py", line 235, in wrapped
ret = await coro(*args, **kwargs)
File "/home/container/main.py", line 652, in war nings
warns warns_check(member)
File "/home/container/main.py", line 55, in warn s_check
warns [str(member.id)]
KeyError: '1244794665769766967'
The above exception was the direct cause of the fo llowing exception:
Traceback (most recent call last):
File "/home/container/.local/lib/python3.13/site -packages/discord/ext/commands/bot.py", line 1366, in invoke
await ctx.command.invoke(ctx)
File "/home/container/.local/lib/python3.13/site
-packages/discord/ext/commands/core.py", line 1029 , in invoke
await injected(*ctx.args, **ctx.kwargs) # typ e: ignore
File "/home/container/.local/lib/python3.13/site -packages/discord/ext/commands/core.py", line 244, in wrapped
raise Command Invoke Error (exc) from exc discord.ext.commands.errors.Command InvokeError: Co mmand raised an exception: KeyError: '124479466576 9766967'```
There we gi
Go
without the py since this is not entirely python code
File "/home/container/.local/lib/python3.13/site -packages/discord/ext/commands/core.py", line 235, in wrapped
ret = await coro(*args, **kwargs)
File "/home/container/main.py", line 652, in war nings
warns warns_check(member)
File "/home/container/main.py", line 55, in warn s_check
warns [str(member.id)]
KeyError: '1244794665769766967'
The above exception was the direct cause of the fo llowing exception:
Traceback (most recent call last):
File "/home/container/.local/lib/python3.13/site -packages/discord/ext/commands/bot.py", line 1366, in invoke
await ctx.command.invoke(ctx)
File "/home/container/.local/lib/python3.13/site
-packages/discord/ext/commands/core.py", line 1029 , in invoke
await injected(*ctx.args, **ctx.kwargs) # typ e: ignore
File "/home/container/.local/lib/python3.13/site -packages/discord/ext/commands/core.py", line 244, in wrapped
raise Command Invoke Error (exc) from exc discord.ext.commands.errors.Command InvokeError: Co mmand raised an exception: KeyError: '124479466576 9766967'```
Like this?
Its the one from the picture you replied on
I am interested in this portion ```
File "/home/container/.local/lib/python3.13/site -packages/discord/ext/commands/core.py", line 235, in wrapped
ret = await coro(*args, **kwargs)
File "/home/container/main.py", line 652, in war nings
warns warns_check(member)
File "/home/container/main.py", line 55, in warn s_check
warns [str(member.id)]
KeyError: '1244794665769766967'
This part specifically ```
File "/home/container/main.py", line 55, in warn s_check
warns [str(member.id)]
KeyError: '1244794665769766967'
yes
It says there was a KeyError in line number 55 in warns_check function
Do you see how errors can be helpful?
The part above tells you what happened before that. The part below tells you what other error occured as a result of this error.
It also tells you which file the function is located in
yes, but what is a KeyError ?
Exactly, the right question
A KeyError is an error that occurs when you access a missing data. Here is an example
!e ```py
warns = {"user1": 5}
print(warns["user1"])
print(warns["user2"])
:x: Your 3.13 eval job has completed with return code 1.
001 | 5
002 | Traceback (most recent call last):
003 | File [35m"/home/main.py"[0m, line [35m3[0m, in [35m<module>[0m
004 | print([31mwarns[0m[1;31m["user2"][0m)
005 | [31m~~~~~[0m[1;31m^^^^^^^^^[0m
006 | [1;35mKeyError[0m: [35m'user2'[0m
I understand so the KeyError in my code is that its looking for the data (my user id) in warns.json but it cant find it so it returns the error right?
The first print ran correctly because the key "user1" is present in the dictionary. The second one failed and gave a key error
You can always check if a key is present in the dictionary before using it.
if "user2" in warns:
warns["user2"] += 1
Or you can use .get method (as I did) to get a default value when the key is missing. ```py
warns = {"user1": 5}
print(warns.get("user2", 0)) # prints 0
These are 2 possible fixes you can apply when facing such a problem.
Is that good so far?
Uh i tried the one with the 0 at the end but it still returned the {}
Because this is a different error
Yes it returns 0 when the key is missing, but it will return the stored value if it is there
In this case the stored value was, for some reason, an empty dict {}
So it returned the {} ?
That's why I told you to clear the json file.
I did its completely empty and the bot is not responding and its giving me an new error
Deleting the file will result in FileNotFoundError when you run the code.
This error is somewhat similar to the one we explored, except it is for when trying to read from a file that doesn't exist.
I see
Hmm but what's the error than i mean json.load is the right thing to use right?
You can't pass this function an empty file
It expects to find something in there
write this in your json file {}
I did
Looks like you are smart
I had it in the file before you told me to delete it but it returned the {} but thanks
Is your bot working now?
I think I can fix this for you
you can?
I am not finished yet ๐
Including the warns.json ?
I trust it is in good shape
just the functions
def save_warn(ctx, member: discord.Member):
with open ('warns.json', 'r') as f:
warns = json.load(f)
warns[str(member.id)] += 1
with open ('warns.json', 'w') as f:
json.dump(warns, f)
def remove_warn(ctx, member: discord.Member, amount: int):
with open('warns.json', 'r') as f:
warns = json.load(f)
warns[str(member.id)] -= amount
with open('warns.json', 'w') as f:
json.dump(warns, f)
def warns_check(member: discord.Member):
with open('warns.json', 'r') as f:
warns = json.load(f)
warns.get(str(member.id), 0)
return warns
@bot.command()
@commands.has_permissions(kick_members=True)
async def warn(ctx, member: discord.Member, *, reason):
save_warn(ctx, member)
dm = await bot.fetch_user(member.id)
em=discord.Embed(title="Warning", description=f"Server: {ctx.guild.id}\nReason: {reason}")
await dm.send(embed=em)
@bot.command()
@commands.has_permissions(kick_members=True)
async def warnings(ctx, member: discord.Member):
warns = warns_check(member)
await ctx.send(f"{member.name} has {warns} warnings.")
@bot.command()
@commands.has_permissions(kick_members=True)
async def rmwarn(ctx, member: discord.Member, amount: int):
remove_warn(ctx, member, amount)
await ctx.send(f"Removed {amount} warnings from {member.name}!")```
This is the current code
You have to ask yourself, what happens when the json is empty and you add a warning to it?
The Warning will get stored in the file?
It doesn't
It will add 1 warning to the the user id?
If it is already there
If not, this should be an error
Instead
This line is equal to ```py
key = str(member.id)
warns[key] = warns[key] + 1
Basically,
- get the value
- add one
- store the value
I will change that to
key = str(member.id)
warns[key] = warns.get(key, 0) + 1
But like the code will add 1 warn to the user id if its in the warns.json but what if its not in there like how will i add the value in the file
Just add this in place. You already have the code that stores the value back in the file.
But don't test your bot yet
There is another change
Or maybe, yes go ahead and see the result.
So what should i change before i test?
replace this line
with this
Alr 1 sec
really?
replace with this instead
Alr
You are actually doing well
Still one change after this to get it working
I am using my phone right now just like you do
Alright whats the next change?
What did you get?
def warns_check(member: discord.Member):
with open('warns.json', 'r') as f:
warns = json.load(f)
warns.get(str(member.id), 0) # gets the right value
return warns # returns the whole dictionary
Can I look at your code? The part that was changed?
Can you edit my code bc i dont know where to replace it i think i messed it up
yh ik i think i messed it up badly๐ฅฒ
def save_warn(ctx, member: discord.Member):
with open ('warns.json', 'r') as f:
warns = json.load(f)
warns[str(member.id)] += 1
with open ('warns.json', 'w') as f:
json.dump(warns, f)
def remove_warn(ctx, member: discord.Member, amount: int):
with open('warns.json', 'r') as f:
warns = json.load(f)
warns[str(member.id)] -= amount
with open('warns.json', 'w') as f:
json.dump(warns, f)
def warns_check(member: discord.Member):
with open('warns.json', 'r') as f:
warns = json.load(f)
key = str(member.id)
warns[key] = warns[key] + 1
return warns```
I changed some stuff in here
I cant๐
This function ...
def save_warn(ctx, member: discord.Member):
with open ('warns.json', 'r') as f:
warns = json.load(f)
warns[str(member.id)] += 1
with open ('warns.json', 'w') as f:
json.dump(warns, f)
yes?
Ok just follow along
Tell me what it does
It saves the warn
It opens it
Don't be afraid, I am only checking your understanding
def save_warn(ctx, member: discord.Member):
# open file in reading mode
with open ('warns.json', 'r') as f:
# loads content of the file, warns is a dictionary now
warns = json.load(f)
# updates the value
warns[str(member.id)] += 1
# open the same file again in writing mode
with open ('warns.json', 'w') as f:
# store the data into the file
json.dump(warns, f)
# updates the value
warns[str(member.id)] += 1
# issue: it only updates the value if it is there
# solution: replace this line
key = str(member.id)
if key in warns:
# increase by one
warns[key] += 1
else:
# set to one
warns[key] = 1
def save_warn(ctx, member: discord.Member):
# open file in reading mode
with open ('warns.json', 'r') as f:
# loads content of the file, warns is a dictionary now
warns = json.load(f)
# update the value
key = str(member.id)
if key in warns:
# increase by one
warns[key] += 1
else:
# set to one
warns[key] = 1
# open the same file again in writing mode
with open ('warns.json', 'w') as f:
# store the data into the file
json.dump(warns, f)
@tall belfry Is that clear?
yes
Do you see how we, programmers, replace code?
This is what I wanted you to do
This is how your check function looked like before it was messed up
def warns_check(member: discord.Member):
with open('warns.json', 'r') as f:
warns = json.load(f)
key = str(member.id)
warns.get(key, 0) # gets the amount
return warns # return the dictionary
Coding on phone is hard, ik
I was there there too,
@tall belfry can you, ahh.. , edit your code again?
Like replace it with yours?
Yes, but not blindly
just be aware of what you are replacing
Now look at this
I want you to take a look at this function and tell me what is wrong with it
-# hint: what does the function return?
the warns
And what is warns? What value is stored in there?
The user id and the amount ?
-# just return the amount instead of returning the entire dictionary
yh but how can i only return the amount like over a variable ?
def warns_check(member: discord.Member):
with open('warns.json', 'r') as f:
warns = json.load(f)
key = str(member.id)
warns.get(key, 0) # gets the amount
return warns # return the dictionary
def warns_check(member: discord.Member):
with open('warns.json', 'r') as f:
warns = json.load(f)
key = str(member.id)
return warns.get(key, 0) # get the amount and return the amount
Did you get it?
look at the function that saves warning, it will be similar to that
like if the key is present reduce by the given amount, and if it is not there set it to zero
def remove_warn(ctx, member: discord.Member, amount: int):
with open('warns.json', 'r') as f:
warns = json.load(f):
key = str(member.id)
if key in warns:
warns[key] -= amount
else:
warns[key] = 0
with open('warns.json', 'w') as f:
json.dump(warns, f)```
Is this right?
fix the indent
def remove_warn(ctx, member: discord.Member, amount: int):
with open('warns.json', 'r') as f:
warns = json.load(f):
key = str(member.id)
if key in warns:
warns[key] -= amount
else:
warns[key] = 0
with open('warns.json', 'w') as f:
json.dump(warns, f)
This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.