Exemplo n.º 1
0
def run(results, cmdenv, tdb):
    from commands.commandenv import ResultRow

    calc = TradeCalc(tdb, cmdenv)

    lhs = cmdenv.startStation
    rhs = cmdenv.stopStation

    if lhs == rhs:
        raise CommandLineError("Must specify two different stations.")

    results.summary = ResultRow()
    results.summary.fromStation = lhs
    results.summary.toStation = rhs

    trades = calc.getTrades(lhs, rhs)
    if not trades:
        raise CommandLineError("No profitable trades {} -> {}".format(
            lhs.name(), rhs.name()))

    if cmdenv.detail > 1:
        tdb.getAverageSelling()
        tdb.getAverageBuying()

    for item in trades:
        results.rows.append(item)

    return results
Exemplo n.º 2
0
def run(results, cmdenv, tdb):
    from commands.commandenv import ResultRow

    calc = TradeCalc(tdb, cmdenv)

    lhs = cmdenv.startStation
    rhs = cmdenv.stopStation

    if lhs == rhs:
        raise CommandLineError("Must specify two different stations.")

    results.summary = ResultRow()
    results.summary.fromStation = lhs
    results.summary.toStation = rhs

    trades = calc.getTrades(lhs, rhs)
    if not trades:
        raise CommandLineError("No profitable trades {} -> {}".format(
            lhs.name(), rhs.name()
        ))

    if cmdenv.detail > 1:
        tdb.getAverageSelling()
        tdb.getAverageBuying()

    for item in trades:
        results.rows.append(item)

    return results
Exemplo n.º 3
0
def run(results, cmdenv, tdb):
    cmdenv.DEBUG1("loading trades")

    if tdb.tradingCount == 0:
        raise NoDataError("Database does not contain any profitable trades.")

    # Instantiate the calculator object
    calc = TradeCalc(tdb, cmdenv)

    validateRunArguments(tdb, cmdenv, calc)

    origPlace, viaSet = cmdenv.origPlace, cmdenv.viaSet
    avoidPlaces = cmdenv.avoidPlaces
    stopStations = cmdenv.destinations
    goalSystem = cmdenv.goalSystem
    maxLs = cmdenv.maxLs

    # seed the route table with starting places
    startCr = cmdenv.credits - cmdenv.insurance
    routes = [
        Route(
            stations=(src,),
            hops=(),
            jumps=(),
            startCr=startCr,
            gainCr=0,
            score=0
        )
        for src in cmdenv.origins
    ]

    numHops = cmdenv.hops
    lastHop = numHops - 1
    viaStartPos = 1 if origPlace else 0

    cmdenv.DEBUG1("numHops {}, vias {}, adhocHops {}",
                numHops, len(viaSet), cmdenv.adhocHops)

    results.summary = ResultRow()
    results.summary.exception = ""

    if cmdenv.loop:
        routePickPred = lambda route: \
            route.lastStation is route.firstStation
    elif cmdenv.shorten:
        if not cmdenv.destPlace:
            routePickPred = lambda route: \
                route.lastStation is route.firstStation
        elif isinstance(cmdenv.destPlace, System):
            routePickPred = lambda route: \
                route.lastSystem is cmdenv.destPlace
        else:
            routePickPred = lambda route: \
                route.lastStation is cmdenv.destPlace
    else:
        routePickPred = None

    pickedRoutes = []

    pruneMod = cmdenv.pruneScores / 100

    if cmdenv.loop:
        distancePruning = lambda rt, distLeft: \
            rt.lastSystem.distanceTo(rt.firstSystem) <= distLeft
    elif cmdenv.destPlace and not cmdenv.direct:
        distancePruning = lambda rt, distLeft: \
            any(
                stop for stop in stopSystems
                if rt.lastSystem.distanceTo(stop) <= distLeft
            )
    else:
        distancePruning = False

    if distancePruning:
        maxHopDistLy = cmdenv.maxJumpsPer * cmdenv.maxLyPer
        if not cmdenv.loop:
            stopSystems = {stop.system for stop in stopStations}

    for hopNo in range(numHops):
        restrictTo = None
        if hopNo == lastHop and stopStations:
            restrictTo = set(stopStations)
            manualRestriction = bool(cmdenv.destPlace)
        elif len(viaSet) > cmdenv.adhocHops:
            restrictTo = viaSet
            manualRestriction = True

        if distancePruning:
            preCrop = len(routes)
            distLeft = maxHopDistLy * (numHops - hopNo)
            routes = [rt for rt in routes if distancePruning(rt, distLeft)]
            if not routes:
                if pickedRoutes:
                    break
                raise NoDataError(
                    "No routes are in-range of any end stations at the end of hop {}"
                    .format(hopNo)
                )
            pruned = preCrop - len(routes)
            if pruned:
                cmdenv.NOTE("Pruned {} origins too far from any end stations", pruned)

        if hopNo >= 1 and (cmdenv.maxRoutes or pruneMod):
            routes.sort()
            if pruneMod and hopNo + 1 >= cmdenv.pruneHops and len(routes) > 10:
                crop = int(len(routes) * pruneMod)
                routes = routes[:-crop]
                cmdenv.NOTE("Pruned {} origins", crop)

            if cmdenv.maxRoutes and len(routes) > cmdenv.maxRoutes:
                routes = routes[:cmdenv.maxRoutes]

        if cmdenv.progress:
            extra = ""
            if hopNo > 0 and cmdenv.detail > 1:
                extra = extraRouteProgress(routes)
            print(
                "* Hop {:3n}: {:.>10n} origins {}"
                .format(hopNo+1, len(routes), extra)
            )
        elif cmdenv.debug:
            cmdenv.DEBUG0("Hop {}...", hopNo+1)

        try:
            newRoutes = calc.getBestHops(routes, restrictTo=restrictTo)
        except NoHopsError:
            if hopNo == 0 and len(cmdenv.origSystems) == 1:
                raise NoDataError(
                    "Couldn't find any trading links within {} x {}ly jumps of {}."
                    .format(
                        cmdenv.maxJumpsPer,
                        cmdenv.maxLyPer,
                        cmdenv.origSystems[0].name(),
                    )
                )
            raise NoDataError(
                "No routes had reachable trading links at hop #{}".format(hopNo + 1)
            )

        if not newRoutes:
            if pickedRoutes:
                break
            checkReachability(tdb, cmdenv)
            if hopNo > 0:
                if restrictTo and manualRestriction:
                    results.summary.exception += routeFailedRestrictions(
                        tdb, cmdenv, restrictTo, maxLs, hopNo
                    )
                    break
                results.summary.exception += (
                    "SORRY: Could not find profitable destinations "
                    "beyond hop #{:n}\n"
                    .format(hopNo + 1)
                )
                break
            if hopNo == 0:
                if cmdenv.origPlace and len(routes) == 1:
                    errText = (
                        "No profitable buyers found for the goods at {}.\n"
                        "\n"
                        "You may want to try:\n"
                        "  {} local \"{}\" --ly {} -vv --stations --trading"
                        .format(
                            routes[0].lastStation.name(),
                            sys.argv[0], cmdenv.origPlace.system.name(),
                            cmdenv.maxJumpsPer * cmdenv.maxLyPer,
                        )
                    )
                    if isinstance(cmdenv.origPlace, Station):
                        errText += (
                            "\n"
                            "or:\n"
                            "  {} market \"{}\" --sell -vv"
                            .format(
                                sys.argv[0], cmdenv.origPlace.name(),
                            )
                        )
                    raise NoDataError(errText)

        routes = newRoutes
        if routes and goalSystem:
            # Promote the winning route to the top of the list
            # while leaving the remainder of the list intact
            routes.sort(
                key=lambda route:
                    0 if route.lastSystem is goalSystem else 1
            )
            if routes[0].lastSystem is goalSystem:
                cmdenv.NOTE("Goal system reached!")
                routes = routes[:1]
                break

        if routePickPred:
            pickedRoutes.extend(
                route for route in routes if routePickPred(route)
            )

    if cmdenv.loop or cmdenv.shorten:
        cmdenv.DEBUG0("Using {} picked routes", len(pickedRoutes))
        routes = pickedRoutes
        # normalise the scores for fairness...
        for route in routes:
            cmdenv.DEBUG0(
                "{} hops, {} score, {} gpt",
                len(route.hops), route.score, route.gpt
            )
            route.score /= len(route.hops)

    if not routes:
        raise NoDataError(
            "No profitable trades matched your critera, "
            "or price data along the route is missing."
        )

    if viaSet:
        routes, caution = filterByVia(routes, viaSet, viaStartPos)
        if caution:
            results.summary.exception += caution + "\n"

    routes.sort()
    results.data = routes

    return results
Exemplo n.º 4
0
def run(results, cmdenv, tdb):
    cmdenv.DEBUG1("loading trades")

    if tdb.tradingCount == 0:
        raise NoDataError("Database does not contain any profitable trades.")

    # Instantiate the calculator object
    calc = TradeCalc(tdb, cmdenv)

    validateRunArguments(tdb, cmdenv, calc)

    origPlace, viaSet = cmdenv.origPlace, cmdenv.viaSet
    avoidPlaces = cmdenv.avoidPlaces
    stopStations = cmdenv.destinations
    goalSystem = cmdenv.goalSystem
    maxLs = cmdenv.maxLs

    # seed the route table with starting places
    startCr = cmdenv.credits - cmdenv.insurance
    routes = [
        Route(
            stations=(src,),
            hops=(),
            jumps=(),
            startCr=startCr,
            gainCr=0,
            score=0
        )
        for src in cmdenv.origins
    ]

    numHops = cmdenv.hops
    lastHop = numHops - 1
    viaStartPos = 1 if origPlace else 0

    cmdenv.DEBUG1("numHops {}, vias {}, adhocHops {}",
                numHops, len(viaSet), cmdenv.adhocHops)

    results.summary = ResultRow()
    results.summary.exception = ""

    if cmdenv.loop:
        routePickPred = lambda route: \
            route.lastStation is route.firstStation
    elif cmdenv.shorten:
        if not cmdenv.destPlace:
            routePickPred = lambda route: \
                route.lastStation is route.firstStation
        elif isinstance(cmdenv.destPlace, System):
            routePickPred = lambda route: \
                route.lastSystem is cmdenv.destPlace
        else:
            routePickPred = lambda route: \
                route.lastStation is cmdenv.destPlace
    else:
        routePickPred = None

    pickedRoutes = []

    pruneMod = cmdenv.pruneScores / 100

    if cmdenv.loop:
        distancePruning = lambda rt, distLeft: \
            rt.lastSystem.distanceTo(rt.firstSystem) <= distLeft
    elif cmdenv.destPlace and not cmdenv.direct:
        distancePruning = lambda rt, distLeft: \
            any(
                stop for stop in stopSystems
                if rt.lastSystem.distanceTo(stop) <= distLeft
            )
    else:
        distancePruning = False

    if distancePruning:
        maxHopDistLy = cmdenv.maxJumpsPer * cmdenv.maxLyPer
        if not cmdenv.loop:
            stopSystems = {stop.system for stop in stopStations}

    for hopNo in range(numHops):
        restrictTo = None
        if hopNo == lastHop and stopStations:
            restrictTo = set(stopStations)
            manualRestriction = bool(cmdenv.destPlace)
        elif len(viaSet) > cmdenv.adhocHops:
            restrictTo = viaSet
            manualRestriction = True

        if distancePruning:
            preCrop = len(routes)
            distLeft = maxHopDistLy * (numHops - hopNo)
            routes = [rt for rt in routes if distancePruning(rt, distLeft)]
            if not routes:
                if pickedRoutes:
                    break
                raise NoDataError(
                    "No routes are in-range of any end stations at the end of hop {}"
                    .format(hopNo)
                )
            pruned = preCrop - len(routes)
            if pruned:
                cmdenv.NOTE("Pruned {} origins too far from any end stations", pruned)

        if hopNo >= 1 and (cmdenv.maxRoutes or pruneMod):
            routes.sort()
            if pruneMod and hopNo + 1 >= cmdenv.pruneHops and len(routes) > 10:
                crop = int(len(routes) * pruneMod)
                routes = routes[:-crop]
                cmdenv.NOTE("Pruned {} origins", crop)

            if cmdenv.maxRoutes and len(routes) > cmdenv.maxRoutes:
                routes = routes[:cmdenv.maxRoutes]

        if cmdenv.progress:
            extra = ""
            if hopNo > 0 and cmdenv.detail > 1:
                extra = extraRouteProgress(routes)
            print(
                "* Hop {:3n}: {:.>10n} origins {}"
                .format(hopNo+1, len(routes), extra)
            )
        elif cmdenv.debug:
            cmdenv.DEBUG0("Hop {}...", hopNo+1)

        try:
            newRoutes = calc.getBestHops(routes, restrictTo=restrictTo)
        except NoHopsError:
            if hopNo == 0 and len(cmdenv.origSystems) == 1:
                raise NoDataError(
                    "Couldn't find any trading links within {} x {}ly jumps of {}."
                    .format(
                        cmdenv.maxJumpsPer,
                        cmdenv.maxLyPer,
                        cmdenv.origSystems[0].name(),
                    )
                )
            raise NoDataError(
                "No routes had reachable trading links at hop #{}".format(hopNo + 1)
            )

        if not newRoutes:
            if pickedRoutes:
                break
            checkReachability(tdb, cmdenv)
            if hopNo > 0:
                if restrictTo and manualRestriction:
                    results.summary.exception += routeFailedRestrictions(
                        tdb, cmdenv, restrictTo, maxLs, hopNo
                    )
                    break
                results.summary.exception += (
                    "SORRY: Could not find profitable destinations "
                    "beyond hop #{:n}\n"
                    .format(hopNo + 1)
                )
                break
            if hopNo == 0:
                if cmdenv.origPlace and len(routes) == 1:
                    errText = (
                        "No profitable buyers found for the goods at {}.\n"
                        "\n"
                        "You may want to try:\n"
                        "  {} local \"{}\" --ly {} -vv --stations --trading"
                        .format(
                            routes[0].lastStation.name(),
                            sys.argv[0], cmdenv.origPlace.system.name(),
                            cmdenv.maxJumpsPer * cmdenv.maxLyPer,
                        )
                    )
                    if isinstance(cmdenv.origPlace, Station):
                        errText += (
                            "\n"
                            "or:\n"
                            "  {} market \"{}\" --sell -vv"
                            .format(
                                sys.argv[0], cmdenv.origPlace.name(),
                            )
                        )
                    raise NoDataError(errText)

        routes = newRoutes
        if routes and goalSystem:
            # Promote the winning route to the top of the list
            # while leaving the remainder of the list intact
            routes.sort(
                key=lambda route:
                    0 if route.lastSystem is goalSystem else 1
            )
            if routes[0].lastSystem is goalSystem:
                cmdenv.NOTE("Goal system reached!")
                routes = routes[:1]
                break

        if routePickPred:
            pickedRoutes.extend(
                route for route in routes if routePickPred(route)
            )

    if cmdenv.loop or cmdenv.shorten:
        cmdenv.DEBUG0("Using {} picked routes", len(pickedRoutes))
        routes = pickedRoutes
        # normalise the scores for fairness...
        for route in routes:
            cmdenv.DEBUG0(
                "{} hops, {} score, {} gpt",
                len(route.hops), route.score, route.gpt
            )
            route.score /= len(route.hops)

    if not routes:
        raise NoDataError(
            "No profitable trades matched your critera, "
            "or price data along the route is missing."
        )

    if viaSet:
        routes, caution = filterByVia(routes, viaSet, viaStartPos)
        if caution:
            results.summary.exception += caution + "\n"

    routes.sort()
    results.data = routes

    return results