From a262e25a0948711c91faaf79cdc04d2f647b3e8b Mon Sep 17 00:00:00 2001 From: Oliver Smith Date: Sun, 21 Dec 2014 21:50:30 -0800 Subject: [PATCH] Added --near and --ly options to olddata command --- commands/buy_cmd.py | 16 ++++---- commands/olddata_cmd.py | 90 ++++++++++++++++++++++++++++++++++++++--- tradedb.py | 11 +++++ 3 files changed, 103 insertions(+), 14 deletions(-) diff --git a/commands/buy_cmd.py b/commands/buy_cmd.py index 66d8d354..90866830 100644 --- a/commands/buy_cmd.py +++ b/commands/buy_cmd.py @@ -18,35 +18,35 @@ help='Require at least this quantity.', default=0, type=int, - ), + ), ParseArgument('--near', help='Find sellers within jump range of this system.', type=str - ), - ParseArgument('--ly-per', - help='Maximum light years per jump.', + ), + ParseArgument('--ly', + help='[Requires --near] Systems within this range of --near.', default=None, dest='maxLyPer', metavar='N.NN', type=float, - ), + ), ParseArgument('--limit', help='Maximum number of results to list.', default=None, type=int, - ), + ), ParseArgument('--ages', help='Show age of data.', default=False, action='store_true', - ), + ), MutuallyExclusiveGroup( ParseArgument('--price-sort', '-P', help='(When using --near) Sort by price not distance', action='store_true', default=False, dest='sortByPrice', - ), + ), ParseArgument('--stock-sort', '-S', help='Sort by stock followed by price', action='store_true', diff --git a/commands/olddata_cmd.py b/commands/olddata_cmd.py index 626b4541..f4b49873 100644 --- a/commands/olddata_cmd.py +++ b/commands/olddata_cmd.py @@ -18,7 +18,18 @@ help='Maximum number of results to show', default=20, type=int, - ), + ), + ParseArgument('--near', + help='Find sellers within jump range of this system.', + type=str + ), + ParseArgument('--ly', + help='[Requires --near] Systems within this range of --near.', + default=None, + dest='maxLyPer', + metavar='N.NN', + type=float, + ), ] ###################################################################### @@ -39,22 +50,84 @@ def run(results, cmdenv, tdb): else: limitClause = "" + fields = [ + "si.station_id", + "JULIANDAY('NOW') - JULIANDAY(MAX(si.modified))", + "stn.ls_from_star", + ] + + joins = [] + wheres = [] + havings = [] + + nearSys = cmdenv.nearSystem + if nearSys: + maxLy = cmdenv.maxLyPer or tdb.maxSystemLinkLy + maxLy2 = maxLy ** 2 + fields.append( + "dist2(" + "sys.pos_x, sys.pos_y, sys.pos_z," + "{}, {}, {}" + ") AS d2".format( + nearSys.posX, + nearSys.posY, + nearSys.posZ, + )) + joins.append("INNER JOIN System sys USING (system_id)") + wheres.append("""( + sys.pos_x BETWEEN {} and {} + AND sys.pos_y BETWEEN {} and {} + AND sys.pos_z BETWEEN {} and {} + )""".format( + nearSys.posX - maxLy, + nearSys.posX + maxLy, + nearSys.posY - maxLy, + nearSys.posY + maxLy, + nearSys.posZ - maxLy, + nearSys.posZ + maxLy, + )) + havings.append("d2 <= {}".format(maxLy2)) + else: + fields.append("0") + + fieldStr = ','.join(fields) + + if joins: + joinStr = ' '.join(joins) + else: + joinStr = '' + + if wheres: + whereStr = 'WHERE ' + ' AND '.join(wheres) + else: + whereStr = '' + + if havings: + haveStr = 'HAVING ' + ' AND '.join(havings) + else: + haveStr = '' + stmt = """ - SELECT si.station_id, - JULIANDAY('NOW') - JULIANDAY(MAX(si.modified)), - stn.ls_from_star + SELECT {fields} FROM StationItem as si INNER JOIN Station stn USING (station_id) + {joins} + {wheres} GROUP BY 1 + {having} ORDER BY 2 DESC {limit} """.format( - limit=limitClause + fields=fieldStr, + joins=joinStr, + wheres=whereStr, + having=haveStr, + limit=limitClause, ) cmdenv.DEBUG1(stmt) - for (stnID, age, ls) in tdb.query(stmt): + for (stnID, age, ls, dist2) in tdb.query(stmt): cmdenv.DEBUG2("{}:{}:{}", stnID, age, ls) row = ResultRow() row.station = tdb.stationByID[stnID] @@ -63,6 +136,7 @@ def run(results, cmdenv, tdb): row.ls = "{:n}".format(ls) else: row.ls = "?" + row.dist2 = dist2 results.rows.append(row) return results @@ -92,6 +166,10 @@ def render(results, cmdenv, tdb): key=lambda row: row.ls) ) + if cmdenv.nearSystem: + rowFmt.addColumn('Dist', '>', 6, '.2f', + key=lambda row: math.sqrt(row.dist2)) + if not cmdenv.quiet: heading, underline = rowFmt.heading() print(heading, underline, sep='\n') diff --git a/tradedb.py b/tradedb.py index 9a9d8045..9ba5d173 100644 --- a/tradedb.py +++ b/tradedb.py @@ -337,6 +337,16 @@ def __init__(self, maxSystemLinkLy=tdenv.maxSystemLinkLy, ) + @staticmethod + def calculateDistance2(lx, ly, lz, rx, ry, rz): + """ + Returns the square of the distance between two points + """ + dX = (lx - rx) + dY = (ly - ry) + dZ = (lz - rz) + return (dX ** 2) + (dY ** 2) + (dZ ** 2) + ############################################################ # Access to the underlying database. @@ -348,6 +358,7 @@ def getDB(self): import sqlite3 conn = sqlite3.connect(self.dbFilename) conn.execute("PRAGMA foreign_keys=ON") + conn.create_function('dist2', 6, TradeDB.calculateDistance2) return conn except ImportError as e: print("ERROR: You don't appear to have the Python sqlite3 module installed. Impressive. No, wait, the other one: crazy.")