title: Discord Python Bot: Leveling Up System
body: <p>So I've googled a few different searches and I've watched this video <a href="https://www.youtube.com/watch?v=pKkrCHnun0M" rel="nofollow noreferrer">https://www.youtube.com/watch?v=pKkrCHnun0M</a> about making a level system for my bot. Basically, the bot (IN PYTHON) is like an adventure tank game; the game gives you a tank to start, allows you to select a map, moving to different sectors of the map, and will use rng to decide if there's an enemy tank. Each destroyed enemy tank gives you 10 xp points. Now, in the video aforementioned, to add xp, he uses messages, and also begins a player's statistic profile upon their entrance to the server.</p>
  
  <p>Now, I want my user to begin his profile upon the entering of the command '&amp;stats'. In the video, he uses json. I have never used json before, so naturally I was confused, but I followed the video's guidance.</p>
  
  <p>I get this error:</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>Ignoring exception in on_message
  Traceback (most recent call last):  File "/home/runner/.local/share/virtualenvs/python3/lib/python3.
  7/site-packages/discord/client.py", line 270, in _run_event
      await coro(*args, **kwargs)
    File "main.py", line 72, in on_message
      await level_up(users, author, message.channel)  File "main.py", line 435, in level_up
      lvl_end = float('experience ** 1/2')
  ValueError: could not convert string to float: 'experience ** 1/2'</code></pre>
  </div>
  </div>
  </p>
  
  <p>Upon entering any message on my testing server. But alas, I fear it is unimportant. 
  I'm building this bot in repl.it, I should mention at this point,
  So I want to figure out how I can start the json file upon a command, and I also want to add xp to a player's profile (and Kill amount but that doesn't matter too much) by the destruction of enemies. And I need the levels as well. Currently my code for all this stuff is </p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>@client.event
  async def on_message(message):
    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)
  @client.event
  async def on_message(message):
    author = message.author
  
    with open('users.json', 'r') as f:
      users = json.load(f)
  
      await update_data(users, author)
      await add_experience(users, author, 5)
      await level_up(users, author, message.channel)
    with open("users.json", 'w') as f:
      json.dump(users, f)
  
  
    if message.content.startswith("&amp;stats"):
      global Pxp
      global KA
      Pxp = 0
      KA = 0
      await message.channel.send("XP: " + str(Pxp) + ". Enemy Tanks Killed: " + str(KA) + ".")
    if message.content.startswith('&amp;start'):
      await message.channel.send('Choose vehicle: VT-4, M1 Abrams, T-18 Armata. 1, 2, 3.')</code></pre>
  </div>
  </div>
  </p>
  
  <p>and at the bottom, </p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>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 = float('experience ** 1/2')
  
    if level_start &lt; lvl_end:
      await message.channel.send('{} leveled up to level {}'.format(user.mention, lvl_end))
      users[user.id]['level'] = lvl_end</code></pre>
  </div>
  </div>
  </p>
  
  <p>Note that the last snippet generates the previously posted error.</p>
  
  <p>This is also my first post and I didn't know how specific I should be, please be nice :^) I'm sorry that it's so long, and if it's all wrong, just tell me.</p>
  
  <p>Any help is appreciated. If you want to see more code, just ask.</p>