From 5df8ce36b73abdb1608cb5aa43a279596af88849 Mon Sep 17 00:00:00 2001 From: A_D Date: Fri, 10 Jul 2020 05:17:23 +0200 Subject: [PATCH 01/11] Cleaned class_rating closure This replaces a bunch of repeated string concats with a single string concat and string interpolation. It also does a little bit of type hinting as I needed to see what was used where --- edshipyard.py | 51 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/edshipyard.py b/edshipyard.py index 4f0b5563..2e4a1481 100644 --- a/edshipyard.py +++ b/edshipyard.py @@ -11,13 +11,20 @@ from config import config import companion import outfitting +from typing import Dict, Union, List +__Module = Dict[str, Union[str, List[str]]] # Map API ship names to E:D Shipyard ship names -ship_map = dict(companion.ship_map) -ship_map['cobramkiii'] = 'Cobra Mk III' -ship_map['cobramkiv'] = 'Cobra Mk IV', -ship_map['viper'] = 'Viper' -ship_map['viper_mkiv'] = 'Viper Mk IV' +ship_map = companion.ship_map.copy() + +ship_map.update( + { + 'cobramkiii': 'Cobra Mk III', + 'cobramkiv' : 'Cobra Mk IV', + 'viper' : 'Viper', + 'viper_mkiv': 'Viper Mk IV', + } +) # Map API slot names to E:D Shipyard slot names @@ -40,21 +47,33 @@ slot_map = { # Ship masses -ships = pickle.load(open(join(config.respath, 'ships.p'), 'rb')) +# TODO: prefer something other than pickle for this storage (dev readability, security) +ships = pickle.load(open(join(config.respath, 'ships.p'), 'rb')) # Export ship loadout in E:D Shipyard plain text format def export(data, filename=None): + def class_rating(module: __Module): + mod_class = module['class'] + mod_rating = module['rating'] + mod_mount = module.get('mount') + mod_guidance = module.get('guidance') + + ret = '{clazz}{rating}'.format(clazz=mod_class, rating=mod_rating) + if 'guidance' in module: # Missiles + ret += "/{mount}{guidance}".format( + mount=mod_mount[0] if mod_mount is not None else 'F', + guidance=mod_guidance[0], + ) + + elif 'mount' in module: # Hardpoints + ret += "/{mount}".format(mount=mod_mount) + + elif 'Cabin' in module['name']: # Passenger cabins + ret += "/{name}".format(name=module['name'][0]) + + return ret + ' ' - def class_rating(module): - if 'guidance' in module: # Missiles - return module['class'] + module['rating'] + '/' + module.get('mount', 'F')[0] + module['guidance'][0] + ' ' - elif 'mount' in module: # Hardpoints - return module['class'] + module['rating'] + '/' + module['mount'][0] + ' ' - elif 'Cabin' in module['name']: # Passenger cabins - return module['class'] + module['rating'] + '/' + module['name'][0] + ' ' - else: - return module['class'] + module['rating'] + ' ' querytime = config.getint('querytime') or int(time.time()) @@ -71,7 +90,7 @@ def export(data, filename=None): try: if not v: continue - module = outfitting.lookup(v['module'], ship_map) + module: __Module = outfitting.lookup(v['module'], ship_map) if not module: continue cr = class_rating(module) From b2ae2c1ecfc63794d5006d07e64606f3014e129f Mon Sep 17 00:00:00 2001 From: A_D Date: Fri, 10 Jul 2020 05:20:15 +0200 Subject: [PATCH 02/11] Removed oneliners Oneline ifs are against pep8 and are a pain to read. --- edshipyard.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/edshipyard.py b/edshipyard.py index 2e4a1481..479fc7d0 100644 --- a/edshipyard.py +++ b/edshipyard.py @@ -88,10 +88,12 @@ def export(data, filename=None): v = data['ship']['modules'][slot] try: - if not v: continue + if not v: + continue module: __Module = outfitting.lookup(v['module'], ship_map) - if not module: continue + if not module: + continue cr = class_rating(module) mods = v.get('modifications') or v.get('WorkInProgress_modifications') or {} @@ -129,10 +131,13 @@ def export(data, filename=None): print('EDShipyard: Unknown slot %s' % slot) except AssertionError as e: - if __debug__: print('EDShipyard: %s' % e) + if __debug__: + print('EDShipyard: %s' % e) continue # Silently skip unrecognized modules + except: - if __debug__: raise + if __debug__: + raise # Construct description ship = ship_map.get(data['ship']['name'].lower(), data['ship']['name']) @@ -157,7 +162,8 @@ def export(data, filename=None): multiplier / (mass + fuel) + jumpboost, multiplier / (mass + fuel + cargo) + jumpboost) except: - if __debug__: raise + if __debug__: + raise if filename: with open(filename, 'wt') as h: From 11df049d0c34185c4071c2e3093e9b47e3718909 Mon Sep 17 00:00:00 2001 From: A_D Date: Fri, 10 Jul 2020 05:21:16 +0200 Subject: [PATCH 03/11] Added line breaks where logical Line breaks after scope change helps to wrap your head around code --- edshipyard.py | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/edshipyard.py b/edshipyard.py index 479fc7d0..66454be8 100644 --- a/edshipyard.py +++ b/edshipyard.py @@ -74,7 +74,6 @@ def export(data, filename=None): return ret + ' ' - querytime = config.getint('querytime') or int(time.time()) loadout = defaultdict(list) @@ -99,6 +98,7 @@ def export(data, filename=None): mods = v.get('modifications') or v.get('WorkInProgress_modifications') or {} if mods.get('OutfittingFieldType_Mass'): mass += (module.get('mass', 0) * mods['OutfittingFieldType_Mass']['value']) + else: mass += module.get('mass', 0) @@ -106,33 +106,41 @@ def export(data, filename=None): if 'Fuel Tank'in module['name']: fuel += 2**int(module['class']) name = '%s (Capacity: %d)' % (module['name'], 2**int(module['class'])) + elif 'Cargo Rack' in module['name']: cargo += 2**int(module['class']) name = '%s (Capacity: %d)' % (module['name'], 2**int(module['class'])) + else: name = module['name'] if name == 'Frame Shift Drive': fsd = module # save for range calculation + if mods.get('OutfittingFieldType_FSDOptimalMass'): fsd['optmass'] *= mods['OutfittingFieldType_FSDOptimalMass']['value'] + if mods.get('OutfittingFieldType_MaxFuelPerJump'): fsd['maxfuel'] *= mods['OutfittingFieldType_MaxFuelPerJump']['value'] + jumpboost += module.get('jumpboost', 0) for s in slot_map: if slot.lower().startswith(s): loadout[slot_map[s]].append(cr + name) break + else: if slot.lower().startswith('slot'): loadout[slot[-1]].append(cr + name) + elif __debug__ and not slot.lower().startswith('planetaryapproachsuite'): print('EDShipyard: Unknown slot %s' % slot) except AssertionError as e: if __debug__: print('EDShipyard: %s' % e) + continue # Silently skip unrecognized modules except: @@ -145,14 +153,17 @@ def export(data, filename=None): for slot in ['H', 'L', 'M', 'S', 'U', None, 'BH', 'RB', 'TM', 'FH', 'EC', 'PC', 'SS', 'FS', None, 'MC', None, '9', '8', '7', '6', '5', '4', '3', '2', '1']: if not slot: string += '\n' + elif slot in loadout: for name in loadout[slot]: string += '%s: %s\n' % (slot, name) + string += '---\nCargo : %d T\nFuel : %d T\n' % (cargo, fuel) # Add mass and range assert data['ship']['name'].lower() in companion.ship_map, data['ship']['name'] assert companion.ship_map[data['ship']['name'].lower()] in ships, companion.ship_map[data['ship']['name'].lower()] + try: # https://github.com/cmmcleod/coriolis/blob/master/app/js/shipyard/module-shipyard.js#L184 mass += ships[companion.ship_map[data['ship']['name'].lower()]]['hullMass'] @@ -161,6 +172,7 @@ def export(data, filename=None): string += 'Range : %.2f LY unladen\n %.2f LY laden\n' % ( multiplier / (mass + fuel) + jumpboost, multiplier / (mass + fuel + cargo) + jumpboost) + except: if __debug__: raise @@ -168,6 +180,7 @@ def export(data, filename=None): if filename: with open(filename, 'wt') as h: h.write(string) + return # Look for last ship of this type From 7879a803e12f12633463ed1652fe633e5240071c Mon Sep 17 00:00:00 2001 From: A_D Date: Fri, 10 Jul 2020 05:22:14 +0200 Subject: [PATCH 04/11] Replaced bare except clauses with except Exception Catching SystemExit and KeyboardInterrupt is bad. --- edshipyard.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/edshipyard.py b/edshipyard.py index 66454be8..e3b941c2 100644 --- a/edshipyard.py +++ b/edshipyard.py @@ -143,7 +143,7 @@ def export(data, filename=None): continue # Silently skip unrecognized modules - except: + except Exception: if __debug__: raise @@ -173,7 +173,7 @@ def export(data, filename=None): multiplier / (mass + fuel) + jumpboost, multiplier / (mass + fuel + cargo) + jumpboost) - except: + except Exception: if __debug__: raise From 9581ead7ccc10e8826338e4bf779e8031c803137 Mon Sep 17 00:00:00 2001 From: A_D Date: Fri, 10 Jul 2020 05:23:33 +0200 Subject: [PATCH 05/11] Fixed inline comments using tabs for separation Two spaces after tabs, according to flake8 --- edshipyard.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/edshipyard.py b/edshipyard.py index e3b941c2..2fb162bb 100644 --- a/edshipyard.py +++ b/edshipyard.py @@ -115,7 +115,7 @@ def export(data, filename=None): name = module['name'] if name == 'Frame Shift Drive': - fsd = module # save for range calculation + fsd = module # save for range calculation if mods.get('OutfittingFieldType_FSDOptimalMass'): fsd['optmass'] *= mods['OutfittingFieldType_FSDOptimalMass']['value'] @@ -141,8 +141,8 @@ def export(data, filename=None): if __debug__: print('EDShipyard: %s' % e) - continue # Silently skip unrecognized modules - + continue # Silently skip unrecognized modules + except Exception: if __debug__: raise @@ -190,7 +190,7 @@ def export(data, filename=None): if oldfiles: with open(join(config.get('outdir'), oldfiles[-1]), 'rU') as h: if h.read() == string: - return # same as last time - don't write + return # same as last time - don't write # Write filename = join(config.get('outdir'), '%s.%s.txt' % (ship, time.strftime('%Y-%m-%dT%H.%M.%S', time.localtime(querytime)))) From 82fce9e8c0744dbd5eef6c28b6cb688be4ec899e Mon Sep 17 00:00:00 2001 From: A_D Date: Fri, 10 Jul 2020 05:44:29 +0200 Subject: [PATCH 06/11] Replaced modulo string interpolation with .format .format is newer and easier to read --- edshipyard.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/edshipyard.py b/edshipyard.py index 2fb162bb..c6f5fa00 100644 --- a/edshipyard.py +++ b/edshipyard.py @@ -156,9 +156,9 @@ def export(data, filename=None): elif slot in loadout: for name in loadout[slot]: - string += '%s: %s\n' % (slot, name) + string += '{}: {}\n'.format(slot, name) - string += '---\nCargo : %d T\nFuel : %d T\n' % (cargo, fuel) + string += '---\nCargo : {} T\nFuel : {} T\n'.format(cargo, fuel) # Add mass and range assert data['ship']['name'].lower() in companion.ship_map, data['ship']['name'] @@ -167,11 +167,14 @@ def export(data, filename=None): try: # https://github.com/cmmcleod/coriolis/blob/master/app/js/shipyard/module-shipyard.js#L184 mass += ships[companion.ship_map[data['ship']['name'].lower()]]['hullMass'] - string += 'Mass : %.2f T empty\n %.2f T full\n' % (mass, mass + fuel + cargo) + string += 'Mass : {:.2f} T empty\n {:.2f} T full\n'.format(mass, mass + fuel + cargo) + multiplier = pow(min(fuel, fsd['maxfuel']) / fsd['fuelmul'], 1.0 / fsd['fuelpower']) * fsd['optmass'] - string += 'Range : %.2f LY unladen\n %.2f LY laden\n' % ( + + string += 'Range : {:.2f} LY unladen\n {:.2f} LY laden\n'.format( multiplier / (mass + fuel) + jumpboost, - multiplier / (mass + fuel + cargo) + jumpboost) + multiplier / (mass + fuel + cargo) + jumpboost + ) except Exception: if __debug__: @@ -193,6 +196,9 @@ def export(data, filename=None): return # same as last time - don't write # Write - filename = join(config.get('outdir'), '%s.%s.txt' % (ship, time.strftime('%Y-%m-%dT%H.%M.%S', time.localtime(querytime)))) + filename = join(config.get('outdir'), '{}.{}.txt'.format( + ship, time.strftime('%Y-%m-%dT%H.%M.%S', time.localtime(querytime))) + ) + with open(filename, 'wt') as h: h.write(string) From 87ad0f3080f0fceb0031d7be43f0ac53e9277ddc Mon Sep 17 00:00:00 2001 From: A_D Date: Fri, 10 Jul 2020 05:46:22 +0200 Subject: [PATCH 07/11] Replaced or magic with multiline if Abusing ors for that is incredibly confusing. Additionally, I replaced the .join() call with a static .format call, as the join is confusing for no reason --- edshipyard.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/edshipyard.py b/edshipyard.py index c6f5fa00..4b7c1b13 100644 --- a/edshipyard.py +++ b/edshipyard.py @@ -149,7 +149,14 @@ def export(data, filename=None): # Construct description ship = ship_map.get(data['ship']['name'].lower(), data['ship']['name']) - string = '[%s]\n' % (data['ship'].get('shipName') and ', '.join([ship, data['ship']['shipName']]) or ship) + + if data['ship'].get('shipName') is not None: + _ships = '{}, {}'.format(ship, data['ship']['shipName']) + else: + _ships = ship + + string = '[{}]\n'.format(_ships) + for slot in ['H', 'L', 'M', 'S', 'U', None, 'BH', 'RB', 'TM', 'FH', 'EC', 'PC', 'SS', 'FS', None, 'MC', None, '9', '8', '7', '6', '5', '4', '3', '2', '1']: if not slot: string += '\n' From be9ac29a5b968fcd0294bb42648068fa4681fdc4 Mon Sep 17 00:00:00 2001 From: A_D Date: Fri, 10 Jul 2020 05:47:38 +0200 Subject: [PATCH 08/11] Replaced for x in $list with $tuple Tuples are static and smaller memory wise --- edshipyard.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/edshipyard.py b/edshipyard.py index 4b7c1b13..dd159529 100644 --- a/edshipyard.py +++ b/edshipyard.py @@ -157,7 +157,11 @@ def export(data, filename=None): string = '[{}]\n'.format(_ships) - for slot in ['H', 'L', 'M', 'S', 'U', None, 'BH', 'RB', 'TM', 'FH', 'EC', 'PC', 'SS', 'FS', None, 'MC', None, '9', '8', '7', '6', '5', '4', '3', '2', '1']: + SLOT_TYPES = ( + 'H', 'L', 'M', 'S', 'U', None, 'BH', 'RB', 'TM', 'FH', 'EC', 'PC', 'SS', 'FS', None, 'MC', None, '9', '8', + '7', '6', '5', '4', '3', '2', '1' + ) + for slot in SLOT_TYPES: if not slot: string += '\n' @@ -172,6 +176,7 @@ def export(data, filename=None): assert companion.ship_map[data['ship']['name'].lower()] in ships, companion.ship_map[data['ship']['name'].lower()] try: + # TODO: broken link # https://github.com/cmmcleod/coriolis/blob/master/app/js/shipyard/module-shipyard.js#L184 mass += ships[companion.ship_map[data['ship']['name'].lower()]]['hullMass'] string += 'Mass : {:.2f} T empty\n {:.2f} T full\n'.format(mass, mass + fuel + cargo) From a6e6b6353dd9a599780fffceed12b6c1ba4c9128 Mon Sep 17 00:00:00 2001 From: A_D Date: Fri, 10 Jul 2020 05:49:21 +0200 Subject: [PATCH 09/11] Tidied regexp Python regexps should always be held in r'' or raw strings, ensuring that python doesn't try to expand the regexp escapes. I also removed the escaped -, as they're only special characters in character groups --- edshipyard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/edshipyard.py b/edshipyard.py index dd159529..bb5e4ef2 100644 --- a/edshipyard.py +++ b/edshipyard.py @@ -200,7 +200,7 @@ def export(data, filename=None): # Look for last ship of this type ship = companion.ship_file_name(data['ship'].get('shipName'), data['ship']['name']) - regexp = re.compile(re.escape(ship) + '\.\d\d\d\d\-\d\d\-\d\dT\d\d\.\d\d\.\d\d\.txt') + regexp = re.compile(re.escape(ship) + r'\.\d{4}-\d\d-\d\dT\d\d\.\d\d\.\d\d\.txt') oldfiles = sorted([x for x in os.listdir(config.get('outdir')) if regexp.match(x)]) if oldfiles: with open(join(config.get('outdir'), oldfiles[-1]), 'rU') as h: From c4abe6b3ca16581d702e5165de5a41b6e6320d6c Mon Sep 17 00:00:00 2001 From: A_D Date: Fri, 10 Jul 2020 05:51:40 +0200 Subject: [PATCH 10/11] Replaced missed modulo formatting --- edshipyard.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/edshipyard.py b/edshipyard.py index bb5e4ef2..7b3953fb 100644 --- a/edshipyard.py +++ b/edshipyard.py @@ -105,11 +105,11 @@ def export(data, filename=None): # Specials if 'Fuel Tank'in module['name']: fuel += 2**int(module['class']) - name = '%s (Capacity: %d)' % (module['name'], 2**int(module['class'])) + name = '{} (Capacity: {})'.format(module['name'], 2**int(module['class'])) elif 'Cargo Rack' in module['name']: cargo += 2**int(module['class']) - name = '%s (Capacity: %d)' % (module['name'], 2**int(module['class'])) + name = '{} (Capacity: {})'.format(module['name'], 2**int(module['class'])) else: name = module['name'] @@ -135,11 +135,11 @@ def export(data, filename=None): loadout[slot[-1]].append(cr + name) elif __debug__ and not slot.lower().startswith('planetaryapproachsuite'): - print('EDShipyard: Unknown slot %s' % slot) + print('EDShipyard: Unknown slot {}'.format(slot)) except AssertionError as e: if __debug__: - print('EDShipyard: %s' % e) + print('EDShipyard: {}'.format(e)) continue # Silently skip unrecognized modules From 192837957154d92a2a563ff01df66a2e4a8565ae Mon Sep 17 00:00:00 2001 From: A_D Date: Fri, 10 Jul 2020 23:44:11 +0200 Subject: [PATCH 11/11] Removed broken link, fixed interpolation key name Broken link didn't appear to add any further information as per discussion in PR --- edshipyard.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/edshipyard.py b/edshipyard.py index 7b3953fb..f3ce48a4 100644 --- a/edshipyard.py +++ b/edshipyard.py @@ -59,7 +59,7 @@ def export(data, filename=None): mod_mount = module.get('mount') mod_guidance = module.get('guidance') - ret = '{clazz}{rating}'.format(clazz=mod_class, rating=mod_rating) + ret = '{mod_class}{rating}'.format(mod_class=mod_class, rating=mod_rating) if 'guidance' in module: # Missiles ret += "/{mount}{guidance}".format( mount=mod_mount[0] if mod_mount is not None else 'F', @@ -103,7 +103,7 @@ def export(data, filename=None): mass += module.get('mass', 0) # Specials - if 'Fuel Tank'in module['name']: + if 'Fuel Tank' in module['name']: fuel += 2**int(module['class']) name = '{} (Capacity: {})'.format(module['name'], 2**int(module['class'])) @@ -176,8 +176,6 @@ def export(data, filename=None): assert companion.ship_map[data['ship']['name'].lower()] in ships, companion.ship_map[data['ship']['name'].lower()] try: - # TODO: broken link - # https://github.com/cmmcleod/coriolis/blob/master/app/js/shipyard/module-shipyard.js#L184 mass += ships[companion.ship_map[data['ship']['name'].lower()]]['hullMass'] string += 'Mass : {:.2f} T empty\n {:.2f} T full\n'.format(mass, mass + fuel + cargo)