python - discord.py 排名系统排行榜
问题描述
我目前正在尝试为我的 Discord.py 级别系统制作排行榜,以便您这样做!排行榜,然后嵌入位置 1、2、3 等等
Level 和 Exp 存储在 Json 中,如下所示:
{"589898942527963157": {"experience": 25, "level": 2, "LastMessage": 202108011409}, "538477109148909599": {"experience": 0, "level": 0, "LastMessage": 202107312203}}
有没有人知道如何根据最高级别对其进行排序,然后将其放入排名为 1 2 3 等的排行榜中。
我此刻的代码如下所示:
import discord
from discord.ext import commands
import json
from datetime import datetime
import os
import random
os.chdir(r'C:\Users\Anwender\PycharmProjects\Normalo-Bot')
class levels(commands.Cog):
def __init__(self, client):
self.client = client
@commands.Cog.listener()
async def on_member_join(self, member):
with open('users.json', 'r')as f:
users = json.load(f)
await self.update_data(users, member)
with open('users.json', 'w')as f:
json.dump(users, f)
@commands.Cog.listener()
async def on_message(self, message):
if not message.author.bot:
with open('users.json','r')as f:
users = json.load(f)
await self.update_data(users, message.author)
if(users[str(message.author.id)]['LastMessage'] < await self.to_integer(datetime.now())):
await self.add_experience(users, message.author)
await self.level_up(users, message.author, message.channel)
with open('users.json', 'w')as f:
json.dump(users, f)
async def update_data(self, users, user):
if not str(user.id) in users:
users[str(user.id)] = {}
users[str(user.id)]['experience'] = 0
users[str(user.id)]['level'] = 0
users[str(user.id)]['LastMessage'] = await self.to_integer(datetime.now())
async def add_experience(self, users, user):
users[str(user.id)]['experience'] += random.randint(15,25)
users[str(user.id)]['LastMessage'] = await self.to_integer(datetime.now())
async def level_up(self, users, user,message):
experience = users[str(user.id)]['experience']
lvl = users[str(user.id)]['level']
lvl_end = 5 * (lvl ** 2) + (50 * lvl) + 100
print(user)
print(f"Level:{lvl}")
print(f"experience:{experience}")
print(f"lvl_end: {lvl_end} ")
if lvl_end <= experience:
channel=self.client.get_channel(810855960133894154)
await channel.send('{} has leveld up to level {}'.format(user.mention, lvl+1))
users[str(user.id)]['level'] = lvl+1
users[str(user.id)]['experience'] -= lvl_end
async def to_integer(self, dt_time):
answer = 100000000 * dt_time.year + 1000000 * dt_time.month + 10000 * dt_time.day + 100 * dt_time.hour + dt_time.minute
return int(answer)
@commands.command()
async def rank(self,ctx, user: discord.Member = None):
with open('users.json','r')as f:
users = json.load(f)
if user is None:
if not str(ctx.author.id) in users:
users[str(ctx.author.id)] = {}
users[str(ctx.author.id)]['experience'] = 0
users[str(ctx.author.id)]['level'] = 0
users[str(ctx.author.id)]['LastMessage'] = await self.to_integer(datetime.now())
user=ctx.author
lvl = int(users[str(ctx.author.id)]['level'])
exp = int(5 * (lvl ** 2) + (50 * lvl) + 100)
embed = discord.Embed(Title=f"**{user}'s Rang**",Description=f"Experience: {lvl}/{5 * (lvl ** 2) + (50 * lvl) + 100}", color=0x0091ff)
embed.set_thumbnail(url=f"{user.avatar_url}")
embed.add_field(name=f"**{user}'s Rang**", value=" ", inline=False)
embed.add_field(name="Level", value=f"**{users[str(user.id)]['level']}**", inline=True)
embed.add_field(name="Experience", value=f"**{str(int(users[str(user.id)]['experience']))} / {exp}**",inline=True)
embed.set_footer(text="Type more to level up!\nSpam is useless")
await ctx.send(embed=embed)
else:
if not str(user.id) in users:
users[str(user.id)] = {}
users[str(user.id)]['experience'] = 0
users[str(user.id)]['level'] = 0
users[str(user.id)]['LastMessage'] = await self.to_integer(datetime.now())
lvl = int(users[str(user.id)]['level'])
exp=int(5 * (lvl ** 2) + (50 * lvl) + 100)
embed=discord.Embed(Title=f"**{user}'s Rang**",Description=f"Experience: {lvl}/{5 * (lvl ** 2) + (50 * lvl) + 100}",color=0x0091ff)
embed.set_thumbnail(url=f"{user.avatar_url}")
embed.add_field(name=f"**{user}'s Rang**", value=" ", inline=False)
embed.add_field(name="Level",value=f"**{users[str(user.id)]['level']}**",inline=True)
embed.add_field(name="Experience", value=f"**{str(int(users[str(user.id)]['experience']))} / {exp}**", inline=True)
embed.set_footer(text="Type more to level up!\nSpam is useless")
await ctx.send(embed=embed)
with open('users.json', 'w')as f:
json.dump(users, f)
@commands.command()
@commands.has_permissions(administrator=True)
async def add_exp(self, ctx, user: discord.Member,nummer:int):
with open('users.json', 'r')as f:
users = json.load(f)
if not ctx.author.bot:
users[str(user.id)]['experience']+=int(nummer)
await ctx.send("exp added")
with open('users.json', 'w')as f:
json.dump(users, f)
@commands.command()
async def add_lvl(self, ctx, user: discord.Member,nummer:int):
with open('users.json', 'r')as f:
users = json.load(f)
if not ctx.author.bot:
users[str(user.id)]['level'] += int(nummer)
await ctx.send("level added")
with open('users.json', 'w')as f:
json.dump(users, f)
@commands.command()
async def add_database(self,ctx, user: discord.Member):
with open('users.json', 'r')as f:
users = json.load(f)
if not str(user.id) in users:
users[str(user.id)] = {}
users[str(user.id)]['experience'] = 0
users[str(user.id)]['level'] = 0
users[str(user.id)]['LastMessage'] = await self.to_integer(datetime.now())
await ctx.send("added to database!")
else:
await ctx.send("already in database!")
with open('users.json', 'w')as f:
json.dump(users, f)
def setup(client):
client.add_cog(levels(client))
解决方案
如果你想要一个快速的单线,sorted(x.items(), key=lambda n: n[1]['level'], reverse=True)
会是这样,这将返回一个带有元组的列表,按字典值的“级别”从高到低排序,在它上面调用 dict() 会给你排序的字典
对代码的某种解释,dict.items() 将返回一个基本上形式为 的可迭代对象[(key1, value1), (key2, value2)]
,并且列表的每个元素都被传递给 lambda 函数,该函数接受第二个元素,即外部的值dict,并按它的“级别”键排序
推荐阅读
- office-js - Office 插件身份验证
- javascript - 为什么我的代码在等待语句之后不执行?
- python - 使用 Python 对类似图像的数据执行图像裁剪
- php - PHP:从字符串集中递归增强数组
- php - 如何为我的 laravel eloquent DB::table 选择别名表?
- reactjs - 在 React js 中将功能组件转换为类组件
- bluespec - 寄存器大小的向量不能由模块参数参数化
- azure - 使用 azure devops 部署 webjob
- reactjs - 如何通过 Windows 身份验证详细信息来响应应用程序
- python - tweepy - ModuleNotFoundError