Horrible abuse of __init_subclass__, or elegant hack?

Chris Angelico rosuav at gmail.com
Sun Apr 4 14:24:55 EDT 2021


On Mon, Apr 5, 2021 at 2:21 AM jak <nospam at please.ty> wrote:
>
> I modified your code in the following way:
>
> line 65-66:
> from:
>
>      if (qty <= alternate["per_minute"]
>         and (costs[Extractor], costs) > (alternate["costs"][Extractor],
> alternate["costs"])
>
> to:
>      if (qty <= alternate["per_minute"]
>          and (costs[Extractor], set(costs)) >
> (alternate["costs"][Extractor], set(alternate["costs"]))


Unfortunately, set comparisons aren't equivalent. The point of these
checks is to see if the quantities are also lower (or higher) than on
the other side.

It'd probably be easiest to monkeypatch the functionality in. You can
either borrow the implementation from the CPython sources (it uses
all() and a couple of nested loops to scan over everything), or use
this implementation:

class Counter(Counter):
    def __le__(self, other):
        return not (self - other)
    def __gt__(self, other):
        return not (self <= other)

When you subtract a Counter from a Counter, anything that would become
negative is omitted, so if subtracting the Counters results in an
empty container, this one is less than that one.

> The program runs now. Is the result correct?
>
> Specify one or more target items

Well, it successfully ran to completion, which is a good sign, but
it's impossible to say whether it's correct since it didn't actually
produce any real output. Try adding an argument:

PRODUCING: Fuel
====================================
Requires Oil at 100.00%
Produces 40/min Fuel
Produces 30/min Resin
Crude - Extractor at 100.00%
Fuel - Refinery at 100.00%

Requires Oil at 250.00%
Requires Water at 83.33%
Produces 100/min Fuel
Produces 100/min Plastic
Crude - Extractor at 250.00%
Plastic - Refinery at 500.00%
Water - Extractor at 83.33%
Diluted Fuel - Blender at 100.00%

Requires Oil at 125.00%
Requires Water at 83.33%
Produces 100/min Fuel
Produces 50/min Rubber
Crude - Extractor at 125.00%
Rubber - Refinery at 250.00%
Water - Extractor at 83.33%
Diluted Fuel - Blender at 100.00%

Requires Water at 83.33%
Requires Oil at 62.50%
Produces 100/min Fuel
Produces 25/min Resin
Crude - Extractor at 62.50%
Heavy Oil Residue - Refinery at 125.00%
Water - Extractor at 83.33%
Diluted Fuel - Blender at 100.00%


I've incorporated this change (and a small clarifying tweak to the
failure message) into the pushed version, so rather than manually
making the change, you could grab a fresh copy, if that's easier.

Thanks for pointing this out. I like to support more Python versions
than just the unreleased alpha!!

ChrisA


More information about the Python-list mailing list