mirror of
https://github.com/Jylpah/blitz-tools.git
synced 2026-10-24 19:49:52 +02:00
Not finished
BattleRecordCategory.print_results()
This commit is contained in:
1 parent
eb1583f76e
commit
6ecddb3d95
1 file changed
+256
-207
+256
-207
@@ -69,15 +69,24 @@ replay_details_flds = [
|
|||||||
'enemies_spotted'
|
'enemies_spotted'
|
||||||
]
|
]
|
||||||
|
|
||||||
result_ratios = {
|
|
||||||
'KDR' : [ 'enemies_destroyed', 'destroyed' ],
|
|
||||||
'DR' : [ 'damage_made', 'damage_received' ],
|
|
||||||
'hit_rate' : [ 'shots_hit', 'shots_made' ],
|
|
||||||
'pen_rate' : [ 'shots_pen', 'shots_hit' ],
|
|
||||||
'dmg_block_rate' : [ 'damage_blocked', 'damage_received' ]
|
|
||||||
}
|
|
||||||
|
|
||||||
result_categories = {
|
## Syntax: key == stat field in https://api.wotblitz.eu/wotb/tanks/stats/ (all.KEY)
|
||||||
|
## Value array [ 'Stat Title', [ 0, data buckets ....], scaling_factor_for_bucket_values, 'print_format' ]
|
||||||
|
histogram_fields = {
|
||||||
|
'wins' : [ 'Win rate', [0, .35, .40, .45, .5, .55, .60, .65, 1], 100, '{:.0f}%' ],
|
||||||
|
'damage_dealt' : [ 'Avg. Dmg.', [0, .25e3, .5e3, 1e3, 1.5e3, 2e3,2.5e3,3e3,100e3], 1, '{:.0f}' ],
|
||||||
|
'battles' : [ 'Battles', [0, 1e3, 3e3, 5e3, 10e3, 15e3, 25e3, 50e3, 5e7], .001, '{:.0f}k'] # battles is a mandatory stat to include
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def def_value_zero():
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def def_value_BattleRecord():
|
||||||
|
return BattleRecord()
|
||||||
|
|
||||||
|
class BattleRecordCategory():
|
||||||
|
_result_categories = {
|
||||||
'total' : [ 'TOTAL', 'total' ],
|
'total' : [ 'TOTAL', 'total' ],
|
||||||
'battle_result' : [ 'Result', [ 'Loss', 'Win', 'Draw']],
|
'battle_result' : [ 'Result', [ 'Loss', 'Win', 'Draw']],
|
||||||
'battle_type' : [ 'Battle Type',['Encounter', 'Supremacy']],
|
'battle_type' : [ 'Battle Type',['Encounter', 'Supremacy']],
|
||||||
@@ -88,20 +97,104 @@ result_categories = {
|
|||||||
'battle_i' : [ 'Battle #', 'number']
|
'battle_i' : [ 'Battle #', 'number']
|
||||||
}
|
}
|
||||||
|
|
||||||
result_categories_default = [
|
_result_categories_default = [
|
||||||
'total',
|
'total',
|
||||||
'battle_result',
|
'battle_result',
|
||||||
'battle_type',
|
'battle_type',
|
||||||
'tank_tier',
|
'tank_tier',
|
||||||
'top_tier'
|
'top_tier'
|
||||||
]
|
]
|
||||||
|
|
||||||
RESULT_CAT_HEADER_FRMT = '{:_<17s}'
|
_result_categories_extended = [
|
||||||
RESULT_CAT_FRMT = '{:>17s}'
|
'tank_name',
|
||||||
|
'map_name',
|
||||||
|
'battle_i'
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
## Syntax: Check how the replay JSON files look. The algorithm is counting/recording fields
|
RESULT_CAT_FRMT = '{:>17s}'
|
||||||
result_fields = {
|
|
||||||
|
@classmethod
|
||||||
|
def get_result_categories(cls, extended_stats: bool = False):
|
||||||
|
if extended_stats:
|
||||||
|
return cls._result_categories_default + cls._result_categories_extended
|
||||||
|
else:
|
||||||
|
return cls._result_categories_default
|
||||||
|
|
||||||
|
def __init__(self, cat_name : str):
|
||||||
|
self.category_name = cat_name
|
||||||
|
self.category = collections.defaultdict(def_value_BattleRecord)
|
||||||
|
if self._result_categories[self.category_name][1] == 'string':
|
||||||
|
self.type = 'string'
|
||||||
|
elif self._result_categories[self.category_name][1] == 'number':
|
||||||
|
self.type = 'number'
|
||||||
|
elif self._result_categories[self.category_name][1] == 'total':
|
||||||
|
self.type = 'total'
|
||||||
|
else:
|
||||||
|
self.type = 'category'
|
||||||
|
|
||||||
|
|
||||||
|
def get_sub_categories(self):
|
||||||
|
return self.category.keys()
|
||||||
|
|
||||||
|
def record_result(self, result: dict):
|
||||||
|
try:
|
||||||
|
cat = None
|
||||||
|
if self.type == 'total':
|
||||||
|
cat = 'Total'
|
||||||
|
elif self.type == 'number':
|
||||||
|
cat = str(result[self.category_name])
|
||||||
|
elif self.type == 'string':
|
||||||
|
cat = result[self.category_name]
|
||||||
|
else:
|
||||||
|
cat = self._result_categories[self.category_name][1][result[self.category_name]]
|
||||||
|
self.category[cat].record_result(result)
|
||||||
|
return True
|
||||||
|
except KeyError as err:
|
||||||
|
bu.error('Key not found', err)
|
||||||
|
bu.error('Category: ', str(cat))
|
||||||
|
bu.error(str(result))
|
||||||
|
except Exception as err:
|
||||||
|
bu.error(str(err))
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def print_results(self):
|
||||||
|
try:
|
||||||
|
print(' '.join(self.get_headers()))
|
||||||
|
for row in self.get_results():
|
||||||
|
print(' : '.join(row))
|
||||||
|
except KeyError as err:
|
||||||
|
bu.error('Key not found', err)
|
||||||
|
except Exception as err:
|
||||||
|
bu.error(str(err))
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_results(self):
|
||||||
|
try:
|
||||||
|
results = []
|
||||||
|
# results.append(self.get_headers())
|
||||||
|
if self.type == 'number':
|
||||||
|
for cat in sorted( [ int(s) for s in self.category.keys() ] ):
|
||||||
|
cat = str(cat)
|
||||||
|
row = [ self.RESULT_CAT_FRMT.format(cat) ]
|
||||||
|
row.extend(self.category[cat].get_results())
|
||||||
|
results.append(row)
|
||||||
|
else:
|
||||||
|
for cat in sorted(self.category.keys() , key=str.casefold):
|
||||||
|
row = [ self.RESULT_CAT_FRMT.format(cat) ]
|
||||||
|
row.extend(self.category[cat].get_results())
|
||||||
|
results.append(row)
|
||||||
|
return results
|
||||||
|
except KeyError as err:
|
||||||
|
bu.error('Key not found', err)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
class BattleRecord():
|
||||||
|
|
||||||
|
## Syntax: Check how the replay JSON files look. The algorithm is counting/recording fields
|
||||||
|
_result_fields = {
|
||||||
'battles' : [ 'Battles', 'Number of battles', 8, '{:^8.0f}' ],
|
'battles' : [ 'Battles', 'Number of battles', 8, '{:^8.0f}' ],
|
||||||
'win' : [ 'WR', 'Win rate', 6, '{:6.1%}' ],
|
'win' : [ 'WR', 'Win rate', 6, '{:6.1%}' ],
|
||||||
'damage_made' : [ 'DPB', 'Average Damage', 5, '{:5.0f}' ],
|
'damage_made' : [ 'DPB', 'Average Damage', 5, '{:5.0f}' ],
|
||||||
@@ -118,42 +211,169 @@ result_fields = {
|
|||||||
'enemies_wins' : [ 'Enemies WR', 'Average WR of enemies at the tier of their tank', 10, '{:10.2%}' ],
|
'enemies_wins' : [ 'Enemies WR', 'Average WR of enemies at the tier of their tank', 10, '{:10.2%}' ],
|
||||||
'allies_battles' : [ 'Allies Btls', 'Average number battles of the allies', 11, '{:11.0f}' ],
|
'allies_battles' : [ 'Allies Btls', 'Average number battles of the allies', 11, '{:11.0f}' ],
|
||||||
'enemies_battles' : [ 'Enemies Btls', 'Average number battles of the enemies', 12, '{:12.0f}' ]
|
'enemies_battles' : [ 'Enemies Btls', 'Average number battles of the enemies', 12, '{:12.0f}' ]
|
||||||
}
|
}
|
||||||
|
|
||||||
# fields to display in results
|
# fields to display in results
|
||||||
result_display_fields = [
|
_result_fields_default = [
|
||||||
'battles',
|
'battles',
|
||||||
'win',
|
'win',
|
||||||
'damage_made',
|
'damage_made',
|
||||||
'DR',
|
|
||||||
'KDR',
|
|
||||||
'enemies_spotted',
|
'enemies_spotted',
|
||||||
'hit_rate',
|
|
||||||
'pen_rate',
|
|
||||||
'survived',
|
|
||||||
'time_alive%',
|
|
||||||
'top_tier',
|
'top_tier',
|
||||||
'allies_wins',
|
'allies_wins',
|
||||||
'enemies_wins',
|
'enemies_wins',
|
||||||
'allies_battles',
|
'allies_battles',
|
||||||
'enemies_battles',
|
'enemies_battles'
|
||||||
MISSING_STATS
|
]
|
||||||
]
|
|
||||||
|
|
||||||
## Syntax: key == stat field in https://api.wotblitz.eu/wotb/tanks/stats/ (all.KEY)
|
_result_fields_extended = [
|
||||||
## Value array [ 'Stat Title', [ 0, data buckets ....], scaling_factor_for_bucket_values, 'print_format' ]
|
'DR',
|
||||||
histogram_fields = {
|
'KDR',
|
||||||
'wins' : [ 'Win rate', [0, .35, .40, .45, .5, .55, .60, .65, 1], 100, '{:.0f}%' ],
|
'hit_rate',
|
||||||
'damage_dealt' : [ 'Avg. Dmg.', [0, .25e3, .5e3, 1e3, 1.5e3, 2e3,2.5e3,3e3,100e3], 1, '{:.0f}' ],
|
'pen_rate',
|
||||||
'battles' : [ 'Battles', [0, 1e3, 3e3, 5e3, 10e3, 15e3, 25e3, 50e3, 5e7], .001, '{:.0f}k'] # battles is a mandatory stat to include
|
'survived',
|
||||||
|
'time_alive%',
|
||||||
|
MISSING_STATS
|
||||||
|
]
|
||||||
|
|
||||||
|
_result_ratios = {
|
||||||
|
'KDR' : [ 'enemies_destroyed', 'destroyed' ],
|
||||||
|
'DR' : [ 'damage_made', 'damage_received' ],
|
||||||
|
'hit_rate' : [ 'shots_hit', 'shots_made' ],
|
||||||
|
'pen_rate' : [ 'shots_pen', 'shots_hit' ],
|
||||||
|
'dmg_block_rate' : [ 'damage_blocked', 'damage_received' ]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def def_value_zero():
|
RESULT_CAT_HEADER_FRMT = '{:_<17s}'
|
||||||
return 0
|
|
||||||
|
|
||||||
def def_value_BattleRecord():
|
|
||||||
return BattleRecord()
|
@classmethod
|
||||||
|
def get_result_fields(cls, extended_stats: bool = False):
|
||||||
|
if extended_stats:
|
||||||
|
return cls._result_fields_default + cls._result_fields_extended
|
||||||
|
else:
|
||||||
|
return cls._result_fields_default
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_fields_avg(cls) -> set:
|
||||||
|
avg_fields = set(cls.get_result_fields(True))
|
||||||
|
avg_fields.remove('battles')
|
||||||
|
avg_fields.remove(MISSING_STATS)
|
||||||
|
avg_fields.difference_update(cls._result_ratios.keys())
|
||||||
|
return avg_fields
|
||||||
|
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_fields_ratio(cls) -> set:
|
||||||
|
ratio_fields = set()
|
||||||
|
for ratio in cls._result_ratios.keys():
|
||||||
|
ratio_fields.add(cls._result_ratios[ratio][0])
|
||||||
|
ratio_fields.add(cls._result_ratios[ratio][1])
|
||||||
|
return ratio_fields
|
||||||
|
|
||||||
|
|
||||||
|
def __init__(self, extended_stats: bool = False):
|
||||||
|
try:
|
||||||
|
self.battles = 0
|
||||||
|
self.missing_stats = 0
|
||||||
|
self.n_players = 0
|
||||||
|
self.ratios_ready = False
|
||||||
|
self.results_ready = False
|
||||||
|
self.results = collections.defaultdict(def_value_zero)
|
||||||
|
self.avg_fields = self.get_fields_avg()
|
||||||
|
self.ratio_fields = self.get_fields_ratio()
|
||||||
|
self.result_fields = self.get_result_fields(extended_stats)
|
||||||
|
self.result_fields_ratio = set(self._result_ratios.keys()) & set(self.get_result_fields(extended_stats))
|
||||||
|
|
||||||
|
|
||||||
|
except KeyError as err:
|
||||||
|
bu.error('Key not found', err)
|
||||||
|
|
||||||
|
|
||||||
|
def record_result(self, result : dict) -> bool:
|
||||||
|
try:
|
||||||
|
for field in self.avg_fields | self.ratio_fields:
|
||||||
|
if (field in result) and (result[field] != None):
|
||||||
|
self.results[field] += result[field]
|
||||||
|
self.battles += 1
|
||||||
|
self.n_players += result[N_PLAYERS]
|
||||||
|
self.missing_stats += result[MISSING_STATS]
|
||||||
|
return True
|
||||||
|
except KeyError as err:
|
||||||
|
bu.error('Key not found', err)
|
||||||
|
bu.error(str(result))
|
||||||
|
except Exception as err:
|
||||||
|
bu.error('BattleRecord:' ,exception=err)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def calc_ratios(self) -> bool:
|
||||||
|
if self.ratios_ready:
|
||||||
|
return True
|
||||||
|
try:
|
||||||
|
for field in self.result_fields_ratio:
|
||||||
|
if self.results[self._result_ratios[field][1]] != 0:
|
||||||
|
self.results[field] = self.results[self._result_ratios[field][0]] / self.results[self._result_ratios[field][1]]
|
||||||
|
else:
|
||||||
|
self.results[field] = float('Inf')
|
||||||
|
self.ratios_ready = True
|
||||||
|
return True
|
||||||
|
except KeyError as err:
|
||||||
|
bu.error('Key not found', err)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def calc_results(self):
|
||||||
|
if self.results_ready == True:
|
||||||
|
return True
|
||||||
|
if not self.ratios_ready:
|
||||||
|
self.calc_ratios()
|
||||||
|
try:
|
||||||
|
for field in self.avg_fields:
|
||||||
|
self.results[field] = self.results[field] / max(self.battles,1)
|
||||||
|
self.results['battles'] = self.battles
|
||||||
|
self.results[MISSING_STATS] = self.missing_stats / self.n_players
|
||||||
|
self.results_ready = True
|
||||||
|
return True
|
||||||
|
except KeyError as err:
|
||||||
|
bu.error('Key not found', err)
|
||||||
|
except Exception as err:
|
||||||
|
bu.error(exception=err)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def get_headers(self, cat_name: str):
|
||||||
|
try:
|
||||||
|
headers = [ self.RESULT_CAT_HEADER_FRMT.format(cat_name) ]
|
||||||
|
for field in self.result_fields:
|
||||||
|
print_format = '{:^' + str(self._result_fields[field][2]) + 's}'
|
||||||
|
headers.append(print_format.format(self._result_fields[field][0]))
|
||||||
|
return headers
|
||||||
|
except KeyError as err:
|
||||||
|
bu.error('Key not found', err)
|
||||||
|
except Exception as err:
|
||||||
|
bu.error(str(err))
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_results(self):
|
||||||
|
if not self.results_ready:
|
||||||
|
self.calc_results()
|
||||||
|
results = []
|
||||||
|
try:
|
||||||
|
for field in self.result_fields:
|
||||||
|
results.append(self._result_fields[field][3].format(self.results[field]) )
|
||||||
|
return results
|
||||||
|
except KeyError as err:
|
||||||
|
bu.error('Key not found', err)
|
||||||
|
except Exception as err:
|
||||||
|
bu.error(exception=err)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def print_results(self):
|
||||||
|
print(' : '.join(self.get_results()))
|
||||||
|
|
||||||
|
|
||||||
class PlayerHistogram():
|
class PlayerHistogram():
|
||||||
@@ -208,177 +428,6 @@ class PlayerHistogram():
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class BattleRecord():
|
|
||||||
def __init__(self):
|
|
||||||
try:
|
|
||||||
self.battles = 0
|
|
||||||
self.missing_stats = 0
|
|
||||||
self.n_players = 0
|
|
||||||
self.ratios_ready = False
|
|
||||||
self.results_ready = False
|
|
||||||
self.results = collections.defaultdict(def_value_zero)
|
|
||||||
self.avg_fields = set(result_fields.keys())
|
|
||||||
self.avg_fields.remove('battles')
|
|
||||||
self.avg_fields.remove(MISSING_STATS)
|
|
||||||
self.avg_fields.difference_update(result_ratios.keys())
|
|
||||||
self.ratio_fields = set()
|
|
||||||
for ratio in result_ratios.keys():
|
|
||||||
self.ratio_fields.add(result_ratios[ratio][0])
|
|
||||||
self.ratio_fields.add(result_ratios[ratio][1])
|
|
||||||
|
|
||||||
except KeyError as err:
|
|
||||||
bu.error('Key not found', err)
|
|
||||||
|
|
||||||
def record_result(self, result : dict) -> bool:
|
|
||||||
try:
|
|
||||||
for field in self.avg_fields | self.ratio_fields:
|
|
||||||
if (field in result) and (result[field] != None):
|
|
||||||
self.results[field] += result[field]
|
|
||||||
self.battles += 1
|
|
||||||
self.n_players += result[N_PLAYERS]
|
|
||||||
self.missing_stats += result[MISSING_STATS]
|
|
||||||
return True
|
|
||||||
except KeyError as err:
|
|
||||||
bu.error('Key not found', err)
|
|
||||||
bu.error(str(result))
|
|
||||||
except Exception as err:
|
|
||||||
bu.error('BattleRecord:' ,exception=err)
|
|
||||||
return False
|
|
||||||
|
|
||||||
def calc_ratios(self) -> bool:
|
|
||||||
if self.ratios_ready:
|
|
||||||
return True
|
|
||||||
try:
|
|
||||||
ratio_result_flds = set(result_ratios.keys()) & set(result_fields.keys())
|
|
||||||
|
|
||||||
for field in ratio_result_flds:
|
|
||||||
if self.results[result_ratios[field][1]] != 0:
|
|
||||||
self.results[field] = self.results[result_ratios[field][0]] / self.results[result_ratios[field][1]]
|
|
||||||
else:
|
|
||||||
self.results[field] = float('Inf')
|
|
||||||
self.ratios_ready = True
|
|
||||||
return True
|
|
||||||
except KeyError as err:
|
|
||||||
bu.error('Key not found', err)
|
|
||||||
return False
|
|
||||||
|
|
||||||
def calc_results(self):
|
|
||||||
if self.results_ready == True:
|
|
||||||
return True
|
|
||||||
if not self.ratios_ready:
|
|
||||||
self.calc_ratios()
|
|
||||||
try:
|
|
||||||
for field in self.avg_fields:
|
|
||||||
self.results[field] = self.results[field] / max(self.battles,1)
|
|
||||||
self.results['battles'] = self.battles
|
|
||||||
self.results[MISSING_STATS] = self.missing_stats / self.n_players
|
|
||||||
self.results_ready = True
|
|
||||||
return True
|
|
||||||
except KeyError as err:
|
|
||||||
bu.error('Key not found', err)
|
|
||||||
except Exception as err:
|
|
||||||
bu.error(exception=err)
|
|
||||||
return False
|
|
||||||
|
|
||||||
def get_results(self):
|
|
||||||
if not self.results_ready:
|
|
||||||
self.calc_results()
|
|
||||||
results = []
|
|
||||||
try:
|
|
||||||
for field in result_display_fields:
|
|
||||||
results.append( result_fields[field][3].format(self.results[field]) )
|
|
||||||
return results
|
|
||||||
except KeyError as err:
|
|
||||||
bu.error('Key not found', err)
|
|
||||||
except Exception as err:
|
|
||||||
bu.error(exception=err)
|
|
||||||
return None
|
|
||||||
|
|
||||||
def print_results(self):
|
|
||||||
print(' : '.join(self.get_results()))
|
|
||||||
|
|
||||||
|
|
||||||
class BattleRecordCategory():
|
|
||||||
def __init__(self, cat_name : str):
|
|
||||||
self.category_name = cat_name
|
|
||||||
self.category = collections.defaultdict(def_value_BattleRecord)
|
|
||||||
if result_categories[self.category_name][1] == 'string':
|
|
||||||
self.type = 'string'
|
|
||||||
elif result_categories[self.category_name][1] == 'number':
|
|
||||||
self.type = 'number'
|
|
||||||
elif result_categories[self.category_name][1] == 'total':
|
|
||||||
self.type = 'total'
|
|
||||||
else:
|
|
||||||
self.type = 'category'
|
|
||||||
|
|
||||||
def get_sub_categories(self):
|
|
||||||
return self.category.keys()
|
|
||||||
|
|
||||||
def record_result(self, result: dict):
|
|
||||||
try:
|
|
||||||
cat = None
|
|
||||||
if self.type == 'total':
|
|
||||||
cat = 'Total'
|
|
||||||
elif self.type == 'number':
|
|
||||||
cat = str(result[self.category_name])
|
|
||||||
elif self.type == 'string':
|
|
||||||
cat = result[self.category_name]
|
|
||||||
else:
|
|
||||||
cat = result_categories[self.category_name][1][result[self.category_name]]
|
|
||||||
self.category[cat].record_result(result)
|
|
||||||
return True
|
|
||||||
except KeyError as err:
|
|
||||||
bu.error('Key not found', err)
|
|
||||||
bu.error('Category: ', str(cat))
|
|
||||||
bu.error(str(result))
|
|
||||||
except Exception as err:
|
|
||||||
bu.error(str(err))
|
|
||||||
return False
|
|
||||||
|
|
||||||
def get_headers(self):
|
|
||||||
try:
|
|
||||||
headers = [ RESULT_CAT_HEADER_FRMT.format(result_categories[self.category_name][0]) ]
|
|
||||||
for field in result_display_fields:
|
|
||||||
print_format = '{:^' + str(result_fields[field][2]) + 's}'
|
|
||||||
headers.append(print_format.format(result_fields[field][0]))
|
|
||||||
return headers
|
|
||||||
except KeyError as err:
|
|
||||||
bu.error('Key not found', err)
|
|
||||||
except Exception as err:
|
|
||||||
bu.error(str(err))
|
|
||||||
return None
|
|
||||||
|
|
||||||
def print_results(self):
|
|
||||||
try:
|
|
||||||
print(' '.join(self.get_headers()))
|
|
||||||
for row in self.get_results():
|
|
||||||
print(' : '.join(row))
|
|
||||||
except KeyError as err:
|
|
||||||
bu.error('Key not found', err)
|
|
||||||
except Exception as err:
|
|
||||||
bu.error(str(err))
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_results(self):
|
|
||||||
try:
|
|
||||||
results = []
|
|
||||||
# results.append(self.get_headers())
|
|
||||||
if self.type == 'number':
|
|
||||||
for cat in sorted( [ int(s) for s in self.category.keys() ] ):
|
|
||||||
cat = str(cat)
|
|
||||||
row = [ RESULT_CAT_FRMT.format(cat) ]
|
|
||||||
row.extend(self.category[cat].get_results())
|
|
||||||
results.append(row)
|
|
||||||
else:
|
|
||||||
for cat in sorted(self.category.keys() , key=str.casefold):
|
|
||||||
row = [ RESULT_CAT_FRMT.format(cat) ]
|
|
||||||
row.extend(self.category[cat].get_results())
|
|
||||||
results.append(row)
|
|
||||||
return results
|
|
||||||
except KeyError as err:
|
|
||||||
bu.error('Key not found', err)
|
|
||||||
return None
|
|
||||||
|
|
||||||
## main() -------------------------------------------------------------
|
## main() -------------------------------------------------------------
|
||||||
|
|
||||||
async def main(argv):
|
async def main(argv):
|
||||||
|
|||||||
Reference in new issue
Block a user