-2

in my current command, I get the leaderboard from a single json file called users.json that stores several XP from multiple users:

@bot.command(pass_context=True)
async def top(ctx):

    with open('profile/users.json', 'r') as fp:
        users = json.load(fp)
        lb = [(member, users[member.id].get('xp')) for member in ctx.message.server.members if member.id in users]
        lb.sort(key=lambda x: x[1], reverse=True)

However, I changed the command, and had each person store their XP in a separate json file: What was once 'profile/users.json' became several 'profile/{}.json'.format(ctx.message.author.id)
Now inside the profile folder, there are several json files of each user, with their respective xp, instead of a single json file. I would like a way to do a leaderboard using multiple json files at once, rather than just one, using my code, what can I do?
Complete answers please, if you need more data, please tell me that and I will edit the question

Lucas Tesch
  • 147
  • 1
  • 3
  • 11

1 Answers1

1

Instead of opening and loading one file, iterate over all the filenames in the profile directory. Load each one and store it in a list for later.

import glob
import json    

filenames_of_all_users = glob.glob("profile/*.json")
users = []
for filename in filenames_of_all_users:
    with open(filename) as file:
        users.append(json.load(file))

users.sort(key=lambda user: user["xp"], reverse=True)

output = ["'''"]
for i, user in enumerate(users, 1):
    output.append(f"{i}. {user['name']}: {user['xp']} XP")
    if i == 20:
        break
output.append("'''")
result = "\n".join(output)
print(result)

I've made a couple of other changes here, which aren't essential to the solution, but which are more idiomatic and/or efficient:

  • using enumerate instead of manually keeping track of the index in the for loop
  • using join() instead of concatenating strings with +=
Kevin
  • 74,910
  • 12
  • 133
  • 166