Repository: PokemonGoF/PokemonGo-Bot

Issue:
Wrong level_stats calculation
### Expected Behavior

at any level, level_stats should show (like the app):
XP earned at the current level / XP to pass next level
### Actual Behavior

in fact, level_apps shows (XP previous level + XP earned at the current level) / (XP previous level + XP to pass next level)
Ex: Level 16 is 20.000 and level 17 also, so when it starts, it shows 50% where it should show 0%
Level 16 (20,095 / 40,000, 50%)
### Your FULL config.json (remove your username, password, gmapkey and any other private info)

http://pastebin.com/XzFy46Tv
### Output when issue occurred

2016-08-22 14:57:34,214 [UpdateLiveStats] [INFO] [log_stats] XXX | Uptime : 0:19:01 | Earned 2,200 Stardust | +4,500 XP | 14,200 XP/h | Visited 15 stops | Level 16 (20,095 / 40,000, **50%**)
### Other Information

OS: OSX Capitan
Branch: dev
Git Commit: 4f2e976764242a69e4ed7551ceae805d19f3a55c
Python Version: Python 2.7.12



Discussion:
The code uses prev_level_xp, but it should use the current_level_xp
For example, if player is at level 11, which is 55,000 reaching level 12 which is 65,000
it should use (experience - 55,000) / (65,000 - 55,000)
where in fact it uses level 9 value 45,000 and calculates (experience - 45,000) / (65,000 - 45,000)

@mjmadsen where can I find some doc on the different api calls? in PokemonGo-Map? or directly in some rep in PokemonGo-Bot project?


Resolving patch:
diff --git a/pokemongo_bot/cell_workers/update_live_stats.py b/pokemongo_bot/cell_workers/update_live_stats.py
--- a/pokemongo_bot/cell_workers/update_live_stats.py
+++ b/pokemongo_bot/cell_workers/update_live_stats.py
@@ -6,6 +6,8 @@
 from pokemongo_bot.worker_result import WorkerResult
 from pokemongo_bot.tree_config_builder import ConfigException
 
+# XP file
+import json
 
 class UpdateLiveStats(BaseTask):
     """
@@ -62,6 +64,8 @@ class UpdateLiveStats(BaseTask):
     """
     SUPPORTED_TASK_API_VERSION = 1
 
+    global xp_per_level
+
     def __init__(self, bot, config):
         """
         Initializes the worker.
@@ -81,6 +85,64 @@ def __init__(self, bot, config):
 
         self.bot.event_manager.register_event('log_stats', parameters=('stats', 'stats_raw'))
 
+        # init xp_per_level
+        global xp_per_level
+        # If xp_level file exists, load variables from json
+        # file name should not be hard coded either
+        xpfile = "data/xp_per_level.json"
+        try:
+            with open(xpfile, 'rb') as data:
+                xp_per_level = json.load(data)
+        except ValueError:
+            # log somme warning message
+            self.emit_event(
+                'log_stats',
+                level='info',
+                formatted="Unable to read XP level file"
+            )
+            # load default valuesto supplement unknown current_level_xp
+            xp_per_level = [[1, 0, 0],
+                [2, 1000, 1000],
+                [3, 2000, 3000],
+                [4, 3000, 6000],
+                [5, 4000, 10000],
+                [6, 5000, 15000],
+                [7, 6000, 21000],
+                [8, 7000, 28000],
+                [9, 8000, 36000],
+                [10, 9000, 45000],
+                [11, 10000, 55000],
+                [12, 10000, 65000],
+                [13, 10000, 75000],
+                [14, 10000, 85000],
+                [15, 15000, 100000],
+                [16, 20000, 120000],
+                [17, 20000, 140000],
+                [18, 20000, 160000],
+                [19, 25000, 185000],
+                [20, 25000, 210000],
+                [21, 50000, 260000],
+                [22, 75000, 335000],
+                [23, 100000, 435000],
+                [24, 125000, 560000],
+                [25, 150000, 710000],
+                [26, 190000, 900000],
+                [27, 200000, 1100000],
+                [28, 250000, 1350000],
+                [29, 300000, 1650000],
+                [30, 350000, 2000000],
+                [31, 500000, 2500000],
+                [32, 500000, 3000000],
+                [33, 750000, 3750000],
+                [34, 1000000, 4750000],
+                [35, 1250000, 6000000],
+                [36, 1500000, 7500000],
+                [37, 2000000, 9500000],
+                [38, 2500000, 12000000],
+                [39, 3000000, 15000000],
+                [40, 5000000, 20000000]]
+        
+        
     def initialize(self):
         pass
 
@@ -172,8 +234,10 @@ def _update_title(self, title, platform):
             self.terminal_title = False
 
         self._compute_next_update()
-
+    
     def _get_stats(self, player_stats):
+        
+        global xp_per_level
         metrics = self.bot.metrics
         metrics.capture_stats()
         runtime = metrics.runtime()
@@ -182,7 +246,7 @@ def _get_stats(self, player_stats):
         username = player_data.get('username', '?')
         distance_travelled = metrics.distance_travelled()
         current_level = int(player_stats.get('level', 0))
-        prev_level_xp = int(player_stats.get('prev_level_xp', 0))
+        prev_level_xp = int(xp_per_level[current_level-1][2])
         next_level_xp = int(player_stats.get('next_level_xp', 0))
         experience = player_stats.get('experience', 0)
         current_level_xp = experience - prev_level_xp
@@ -252,6 +316,8 @@ def _get_stats_line(self, player_stats):
         if not self.displayed_stats:
             return ''
 
+        global xp_per_level
+
         # Gather stats values.
         metrics = self.bot.metrics
         metrics.capture_stats()
@@ -261,7 +327,7 @@ def _get_stats_line(self, player_stats):
         username = player_data.get('username', '?')
         distance_travelled = metrics.distance_travelled()
         current_level = int(player_stats.get('level', 0))
-        prev_level_xp = int(player_stats.get('prev_level_xp', 0))
+        prev_level_xp = int(xp_per_level[current_level-1][2])
         next_level_xp = int(player_stats.get('next_level_xp', 0))
         experience = int(player_stats.get('experience', 0))
         current_level_xp = experience - prev_level_xp


Test patch:
diff --git a/tests/update_live_stats_test.py b/tests/update_live_stats_test.py
--- a/tests/update_live_stats_test.py
+++ b/tests/update_live_stats_test.py
@@ -17,11 +17,12 @@ class UpdateLiveStatsTestCase(unittest.TestCase):
         'terminal_log': True,
         'terminal_title': False
     }
+    # updated to account for XP levels
     player_stats = {
         'level': 25,
-        'prev_level_xp': 1250000,
-        'next_level_xp': 1400000,
-        'experience': 1337500
+        'prev_level_xp': 710000,
+        'next_level_xp': 900000,
+        'experience': 753700
     }
 
     def setUp(self):
@@ -175,8 +176,8 @@ def test_get_stats_line(self):
         expected = 'Login | Username | Evolved 12 pokemon | Encountered 130 pokemon | ' \
                    'Uptime : 15:42:13 | Caught 120 pokemon | Visited 220 stops | ' \
                    '42.05km walked | Level 25 | Earned 24,069 Stardust | ' \
-                   '87,500 / 150,000 XP (58%) | 1,337 XP/h | Threw 145 pokeballs | ' \
-                   'Highest CP pokemon : highest_cp | Level 25 (87,500 / 150,000, 58%) | ' \
+                   '43,700 / 190,000 XP (23%) | 1,337 XP/h | Threw 145 pokeballs | ' \
+                   'Highest CP pokemon : highest_cp | Level 25 (43,700 / 190,000, 23%) | ' \
                    '+424,242 XP | Encountered 3 new pokemon | ' \
                    'Most perfect pokemon : most_perfect | ' \
                    'Encountered 130 pokemon, 120 caught, 30 released, 12 evolved, ' \