A
A
AdvoKappa2020-06-01 22:36:45
Python
AdvoKappa, 2020-06-01 22:36:45

Strange operation of json storage, what to do?

import discord
import json
import os
from discord.ext import commands

client = commands.Bot(command_prefix='$')
os.chdir(r'C:\Sublime Text 3')

@client.event
async def on_ready():
    print('lvl ready')

@client.event
async def on_message(message):

    if message.content == 'system lvl':
        channel = message.channel
        await channel.send(channel, '{} level up {}'.format(user.mention, lvl_end))
        users[user.id]['level'] = lvl_end

    with open('users.json', 'r') as f:
        users = json.load(f)

        await update_data(users, message.author)
        await add_experience(users, message.author, 5)
        await level_up(users, message.author, message.channel)

    with open('users.json','w') as f:
        json.dump(users, f)

@client.event
async def on_member_join(member):
    with open('users.json', 'r') as f:
        users = json.load(f)

    await update_data(users, member)

    with open('users.json','w') as f:
        json.dump(users, f)

async def update_data(users, user):
    if not user.id in users:
        users[user.id] = {}
        users[user.id]['experience'] = 0
        users[user.id]['level'] = 1

async def add_experience(users, user, exp):
    users[user.id]['experience'] += exp

async def level_up(users, user, channel):
    experience = users[user.id]['experience']
    lvl_start = users[user.id]['level']
    lvl_end = int(experience ** (1/4))


    if lvl_start < lvl_end:
        await channel.send(channel, '{} level up {}'.format(user.mention, lvl_end))
        users[user.id]['level'] = lvl_end


when writing a message, everything works, if I wrote two, the json file outputs this:
{"293396418834464768": {"experience": 5, "level": 1}, "293396418834464768": {"experience": 5, "level": 1 }}

Why is this happening? According to the idea, it should add exp, but somehow it works very strangely.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
S
soremix, 2020-06-02
@AdvoKappa

user.id is a number initially? The number is not a valid key when json.dump()
Initially, in the code, the dictionary looks like this:
{293396418834464768: {"experience": 5, "level": 1}}
After the dump, it will be written to the file as
{"293396418834464768": {" experience": 5, "level": 1}}
Accordingly, if you read such a file and drop it into

async def update_data(users, user):
    if not user.id in users:
        users[user.id] = {}
        users[user.id]['experience'] = 0
        users[user.id]['level'] = 1

Then it will create a new object (because after reading the key changes to the string "293396418834464768", and the numeric 293396418834464768 is checked)
It can be clearly seen here:
import json


data = {1: 'value'}


with open('test', 'w') as f:
    json.dump(data, f)

print(data)


with open('test', 'r') as f:
    data = json.load(f)

print(data)

Conclusion:
{1: 'value'}
{'1': 'value'}

ps: I did not read the code completely, maybe there is an error in another, I wrote it in a quick way

D
Dr. Bacon, 2020-06-01
@bacon

json.dumps({'321': '1', 321: '1'})But whether the author will master it, the question is.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question