diff --git a/eos/modifiedAttributeDict.py b/eos/modifiedAttributeDict.py index 0a9eda8a4c..c369d45890 100644 --- a/eos/modifiedAttributeDict.py +++ b/eos/modifiedAttributeDict.py @@ -18,7 +18,7 @@ # =============================================================================== -from collections import MutableMapping +from collections.abc import MutableMapping from copy import copy from math import exp diff --git a/eos/utils/stats.py b/eos/utils/stats.py index 8fd778c56c..76ed3edeb8 100644 --- a/eos/utils/stats.py +++ b/eos/utils/stats.py @@ -110,17 +110,16 @@ def __itruediv__(self, div): return self def __repr__(self): - spec = DmgTypes.Names() + spec = DmgTypes.names() spec.append('total') return makeReprStr(self, spec) @staticmethod - def Names(short=None, postProcessor=None): + def names(short=None, postProcessor=None): value = ['em', 'th', 'kin', 'exp'] if short else ['em', 'thermal', 'kinetic', 'explosive'] if postProcessor: value = [postProcessor(x) for x in value] - print(value) return value @@ -202,11 +201,11 @@ def __itruediv__(self, div): return self def __repr__(self): - spec = RRTypes.Names(False) + spec = RRTypes.names(False) return makeReprStr(self, spec) @staticmethod - def Names(ehpOnly=True, postProcessor=None): + def names(ehpOnly=True, postProcessor=None): value = ['shield', 'armor', 'hull'] if not ehpOnly: @@ -214,6 +213,5 @@ def Names(ehpOnly=True, postProcessor=None): if postProcessor: value = [postProcessor(x) for x in value] - print(value) return value diff --git a/gui/aboutData.py b/gui/aboutData.py index 2d658832fa..a574af2463 100644 --- a/gui/aboutData.py +++ b/gui/aboutData.py @@ -19,7 +19,12 @@ import config -versionString = "{0}".format(config.version) +try: + versionString = "{0}".format(config.getVersion()) +except NameError: + # is caught in case we run test and there are no config values initialized + versionString = "0.0" + licenses = ( "pyfa is released under GNU GPLv3 - see included LICENSE file", "All EVE-Online related materials are property of CCP hf.", diff --git a/service/port/shipstats.py b/service/port/shipstats.py index 897387122a..1f117d65c9 100644 --- a/service/port/shipstats.py +++ b/service/port/shipstats.py @@ -1,14 +1,15 @@ from functools import reduce from eos.saveddata.damagePattern import DamagePattern +from eos.utils.stats import RRTypes, DmgTypes from gui.utils.numberFormatter import formatAmount -tankTypes = ("shield", "armor", "hull") -damageTypes = ("em", "thermal", "kinetic", "explosive") +tankTypes = RRTypes.names() +damageTypes = DmgTypes.names() damagePatterns = [DamagePattern.oneType(damageType) for damageType in damageTypes] damageTypeResonanceNames = [damageType.capitalize() + "DamageResonance" for damageType in damageTypes] -resonanceNames = {"shield": ["shield" + s for s in damageTypeResonanceNames], - "armor": ["armor" + s for s in damageTypeResonanceNames], - "hull": [s[0].lower() + s[1:] for s in damageTypeResonanceNames]} +resonanceNames = {tankTypes[0]: [tankTypes[0] + s for s in damageTypeResonanceNames], + tankTypes[1]: [tankTypes[1] + s for s in damageTypeResonanceNames], + tankTypes[2]: [s[0].lower() + s[1:] for s in damageTypeResonanceNames]} def firepowerSection(fit): @@ -48,15 +49,43 @@ def tankSection(fit): # "Hull {:>7} {:>7.0%} {:>7.0%} {:>7.0%} {:>7.0%}\n".format(ehpStr[2], *resists["hull"]) def generalOutput(): + rowNames = ["EHP"] + rowNames.extend(RRTypes.names(postProcessor=lambda v: v.capitalize())) + colNames = DmgTypes.names(short=True, postProcessor=lambda v: " " + v.capitalize()) + colNames[0] = colNames[0][1::] + + outputScheme = [] + for index, rowName in enumerate(rowNames): + row = rowName + ": {:>} (" + subsValue = " {:.0%}," if index > 0 else " {:>}," + + row += ''.join([(colName + ":" + subsValue) for colName in colNames]) + row = row[:-1:] + ")\n" + + outputScheme.append(row) + return \ - "EHP: {:>} (Em: {:>}, Th: {:>}, Kin: {:>}, Exp: {:>})\n".format(ehpStr[3], *ehpAgainstDamageTypeStr) + \ - "Shield: {:>} (Em: {:.0%}, Th: {:.0%}, Kin: {:.0%}, Exp: {:.0%})\n".format(ehpStr[0], *resists["shield"]) + \ - "Armor: {:>} (Em: {:.0%}, Th: {:.0%}, Kin: {:.0%}, Exp: {:.0%})\n".format(ehpStr[1], *resists["armor"]) + \ - "Hull: {:>} (Em: {:.0%}, Th: {:.0%}, Kin: {:.0%}, Exp: {:.0%})\n".format(ehpStr[2], *resists["hull"]) + outputScheme[0].format(ehpStr[3], *ehpAgainstDamageTypeStr) + \ + outputScheme[1].format(ehpStr[0], *resists["shield"]) + \ + outputScheme[2].format(ehpStr[1], *resists["armor"]) + \ + outputScheme[3].format(ehpStr[2], *resists["hull"]) + + # return \ + # "EHP: {:>} (Em: {:>}, Th: {:>}, Kin: {:>}, Exp: {:>})\n".format(ehpStr[3], *ehpAgainstDamageTypeStr) + \ + # "Shield: {:>} (Em: {:.0%}, Th: {:.0%}, Kin: {:.0%}, Exp: {:.0%})\n".format(ehpStr[0], *resists["shield"]) + \ + # "Armor: {:>} (Em: {:.0%}, Th: {:.0%}, Kin: {:.0%}, Exp: {:.0%})\n".format(ehpStr[1], *resists["armor"]) + \ + # "Hull: {:>} (Em: {:.0%}, Th: {:.0%}, Kin: {:.0%}, Exp: {:.0%})\n".format(ehpStr[2], *resists["hull"]) return generalOutput() +def _addFormattedColumn(value, name, header, linesList, repStr): + if value: + header += "{:>7} ".format(name) + linesList = [line + "{:>7} ".format(rep) for line, rep in zip(linesList, repStr)] + + return header, linesList + def repsSection(fit): """ Returns the text of the repairs section""" selfRep = [fit.effectiveTank[tankType + "Repair"] for tankType in tankTypes] @@ -115,34 +144,23 @@ def repsSection(fit): shieldRegenStr = [formatAmount(rep, 3, 0, 9) if rep != 0 else "" for rep in shieldRegen] totalRepStr = [formatAmount(rep, 3, 0, 9) for rep in totalRep] - header = "REPS " - lines = [ - "Shield ", - "Armor ", - "Hull ", - "Total " - ] + lines = RRTypes.names(postProcessor=lambda v: v.capitalize()) + lines.append("Total") + lines = ["{:<8}".format(line) for line in lines] showSelfRepColumn = totalSelfRep > 0 showSustainRepColumn = sustainRep != selfRep showRemoteRepColumn = totalRemoteRep > 0 showShieldRegenColumn = totalShieldRegen > 0 - if showSelfRepColumn + showSustainRepColumn + showRemoteRepColumn + showShieldRegenColumn > 1: - header += "{:>7} ".format("TOTAL") - lines = [line + "{:>7} ".format(rep) for line, rep in zip(lines, totalRepStr)] - if showSelfRepColumn: - header += "{:>7} ".format("SELF") - lines = [line + "{:>7} ".format(rep) for line, rep in zip(lines, selfRepStr)] - if showSustainRepColumn: - header += "{:>7} ".format("SUST") - lines = [line + "{:>7} ".format(rep) for line, rep in zip(lines, sustainRepStr)] - if showRemoteRepColumn: - header += "{:>7} ".format("REMOTE") - lines = [line + "{:>7} ".format(rep) for line, rep in zip(lines, remoteRepStr)] - if showShieldRegenColumn: - header += "{:>7} ".format("REGEN") - lines = [line + "{:>7} ".format(rep) for line, rep in zip(lines, shieldRegenStr)] + header = "REPS " + header, lines = _addFormattedColumn( + (showSelfRepColumn + showSustainRepColumn + showRemoteRepColumn + showShieldRegenColumn > 1), + "TOTAL", header, lines, totalRepStr) + header, lines = _addFormattedColumn(showSelfRepColumn, "SELF", header, lines, selfRepStr) + header, lines = _addFormattedColumn(showSustainRepColumn, "SUST", header, lines, sustainRepStr) + header, lines = _addFormattedColumn(showRemoteRepColumn, "REMOTE", header, lines, remoteRepStr) + header, lines = _addFormattedColumn(showShieldRegenColumn, "REGEN", header, lines, shieldRegenStr) text += header + "\n" repsByTank = zip(totalRep, selfRep, sustainRep, remoteRep, shieldRegen) diff --git a/tests/test_modules/test_eos/test_utils/test_stats.py b/tests/test_modules/test_eos/test_utils/test_stats.py index 043f53a7f6..dc81adccc1 100644 --- a/tests/test_modules/test_eos/test_utils/test_stats.py +++ b/tests/test_modules/test_eos/test_utils/test_stats.py @@ -16,9 +16,9 @@ def setup_damage_types(): def test_dmgtypes_names(): - assert DmgTypes.Names() == ['em', 'thermal', 'kinetic', 'explosive'] - assert DmgTypes.Names(True) == ['em', 'th', 'kin', 'exp'] - assert DmgTypes.Names(short=True) == ['em', 'th', 'kin', 'exp'] + assert DmgTypes.names() == ['em', 'thermal', 'kinetic', 'explosive'] + assert DmgTypes.names(True) == ['em', 'th', 'kin', 'exp'] + assert DmgTypes.names(short=True) == ['em', 'th', 'kin', 'exp'] def test_dmgtypes__repr(setup_damage_types): @@ -26,8 +26,8 @@ def test_dmgtypes__repr(setup_damage_types): def test_dmgtypes_names_lambda(): - assert DmgTypes.Names(False, lambda v: v.capitalize()) == ['Em', 'Thermal', 'Kinetic', 'Explosive'] - assert DmgTypes.Names(True, lambda v: v.upper()) == ['EM', 'TH', 'KIN', 'EXP'] + assert DmgTypes.names(False, lambda v: v.capitalize()) == ['Em', 'Thermal', 'Kinetic', 'Explosive'] + assert DmgTypes.names(True, lambda v: v.upper()) == ['EM', 'TH', 'KIN', 'EXP'] @pytest.fixture() @@ -36,10 +36,10 @@ def setup_rr_types(): def test_rrtypes_names(): - assert RRTypes.Names() == ['shield', 'armor', 'hull'] - assert RRTypes.Names(True) == ['shield', 'armor', 'hull'] - assert RRTypes.Names(ehpOnly=True) == ['shield', 'armor', 'hull'] - assert RRTypes.Names(False) == ['shield', 'armor', 'hull', 'capacitor'] + assert RRTypes.names() == ['shield', 'armor', 'hull'] + assert RRTypes.names(True) == ['shield', 'armor', 'hull'] + assert RRTypes.names(ehpOnly=True) == ['shield', 'armor', 'hull'] + assert RRTypes.names(False) == ['shield', 'armor', 'hull', 'capacitor'] def test_rrtypes__repr(setup_rr_types): @@ -47,7 +47,7 @@ def test_rrtypes__repr(setup_rr_types): def test_rrtypes_names_lambda(): - assert RRTypes.Names(True, lambda v: v.capitalize()) == ['Shield', 'Armor', 'Hull'] - assert RRTypes.Names(postProcessor=lambda v: v.upper(), ehpOnly=False) == ['SHIELD', 'ARMOR', 'HULL', 'CAPACITOR'] + assert RRTypes.names(True, lambda v: v.capitalize()) == ['Shield', 'Armor', 'Hull'] + assert RRTypes.names(postProcessor=lambda v: v.upper(), ehpOnly=False) == ['SHIELD', 'ARMOR', 'HULL', 'CAPACITOR']