Need Advice me complete a rank command with rewrite and json

so far I build a working rank(r2[prints level and exp]) and leaderboard(levels[prints the first 20 ranks on the server]) command. Now I want my users.json to also save someones rank(place) on the server and not only the exp and level. So there dont have to use the leaderboard everytime. Is there anyway that this is possible?

My code:

import asyncio
import discord
import json
import random
import time
from discord.ext import commands
from discord import Guild
intents = discord.Intents.default()
intents.members = True
intents.typing = True

client = client = discord.Client(intents=intents)

client = commands.Bot(command_prefix = 'sco!')

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 on_message(message):
    if == False:
        with open('users.json', 'r') as f:
            users = json.load(f)

        await update_data(users,
        await add_experience(users,, 5)
        await level_up(users,, message)
        with open('users.json', 'w') as f:
            json.dump(users, f)

    await client.process_commands(message)

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

async def add_experience(users, user, exp):
    users[f'{}']['xp'] += exp

async def level_up(users, user, message):
    with open('users.json', 'r') as g:
        levels = json.load(g)
    experience = users[f'{}']['xp']
    lvl_start = users[f'{}']['level']
    lvl_end = int(experience ** (1 / 4))
    if lvl_start < lvl_end:
        await'{user.mention} ist gerade auf Level {lvl_end} gestiegen!')
        users[f'{}']['level'] = lvl_end

async def r2(ctx, *, member:discord.Member=None):
    if member == None:
        memberID =
        mentioned =
        memberID =
        mentioned =
    with open('users.json', 'r') as f:
        users = json.load(f)
        xp = users[str(memberID)]['xp']
        lvl = users[str(memberID)]['level']

        embed = discord.Embed(title='')
        embed.add_field(name="Spieler", value=mentioned, inline=True)
        embed.add_field(name="Level:", value=lvl, inline=True)
        embed.add_field(name="Experience:", value=xp, inline=True)
        await ctx.send(embed=embed)

async def levels(ctx):
    with open('users.json', 'r') as f:
        data = json.load(f)

    top_spieler = {k: v for k, v in sorted(data.items(), key=lambda item: item[1]["xp"], reverse=True)}

    names = ''
    for position, user in enumerate(top_spieler):
        names += f"{position+1} - <@!{user}> mit Level: {top_spieler[user]['level']} Exp: {top_spieler[user]['xp']}n"
        embed = discord.Embed(title='')
        embed.add_field(name="Spieler", value=names, inline=False)
        if position+1 > 19:
    await ctx.send(embed=embed)

My JSON (only me on the server right now)

{"395805781863170050": {"xp": 15, "level": 1}}

What r2 does: enter image description here

What levels does: enter image description here

I hope there is someone who can help me.


One way is getting all the XP’s on a list, append the new value and sort the list (in reverse), then getting the index of the new value, example:

>>> xp_list = [120, 90, 110, 150]
>>> new_xp = 100 # By logic, the "rank" would be 4
>>> xp_list.append(new_xp) # -> [120, 90, 110, 150, 100]
>>> xp_list.sort(reverse=True) # -> [150, 120, 110, 100, 90]
>>> rank = xp_list.index(new_xp) + 1
>>> print(rank)
4 # It's in fact 4

In a function:

def calculate_rank(user_xp: int, data: dict=None) -> int:
    if data is None:
        # Loading the data
        with open("whatever.json", "r") as f: # Change the path accordingly
            data = json.load(f)

    # Getting ONLY the XP of the users
    xp = [value["xp"] for value in data.values()] # -> [15, ...]
    # Appending the new XP
    # Sorting the list
    # Returning the "rank"
    return xp.index(xp) + 1

# To use it pass the user XP
# You can also pass the data directly as a kwarg
rank = calculate_rank(10) 

You won’t need to store the rank in the JSON this way, (tbh it’s a bad option to store it, you’ll have to re-calculate all the ranks everytime someone gets more XP)