Python dataclasses.replace() Examples

The following are 30 code examples of dataclasses.replace(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module dataclasses , or try the search function .
Example #1
Source File: record_editor.py    From recordexpungPDX with MIT License 6 votes vote down vote up
def _edit_case(case: OeciCase, case_edits) -> Tuple[OeciCase, List[Charge]]:
        case_summary_edits: Dict[str, Any] = {}
        for key, value in case_edits["summary"].items():
            if key == "edit_status":
                case_summary_edits["edit_status"] = EditStatus(value)
            if key == "date":
                case_summary_edits["date"] = date_class.fromdatetime(datetime.strptime(value, "%m/%d/%Y"))
            elif key == "balance_due":
                case_summary_edits["balance_due_in_cents"] = CaseCreator.compute_balance_due_in_cents(value)
            elif key == "birth_year":
                case_summary_edits["birth_year"] = int(value)
            else:
                case_summary_edits[key] = value
        edited_summary = replace(case.summary, **case_summary_edits)
        new_charges: List[Charge] = []
        if case_summary_edits["edit_status"] == EditStatus.DELETE:
            edited_charges = RecordEditor._mark_charges_as_deleted(case.charges)
        elif "charges" in case_edits.keys():
            edited_charges, new_charges = RecordEditor._edit_charges(
                case.summary.case_number, case.charges, case_edits["charges"]
            )
        else:
            edited_charges = case.charges
        return OeciCase(edited_summary, edited_charges), new_charges 
Example #2
Source File: rollout.py    From imitation with MIT License 6 votes vote down vote up
def unwrap_traj(traj: types.TrajectoryWithRew) -> types.TrajectoryWithRew:
    """Uses `RolloutInfoWrapper`-captured `obs` and `rews` to replace fields.

    This can be useful for bypassing other wrappers to retrieve the original
    `obs` and `rews`.

    Fails if `infos` is None or if the trajectory was generated from an
    environment without imitation.util.rollout.RolloutInfoWrapper

    Args:
      traj: A trajectory generated from `RolloutInfoWrapper`-wrapped Environments.

    Returns:
      A copy of `traj` with replaced `obs` and `rews` fields.
    """
    ep_info = traj.infos[-1]["rollout"]
    res = dataclasses.replace(traj, obs=ep_info["obs"], rews=ep_info["rews"])
    assert len(res.obs) == len(res.acts) + 1
    assert len(res.rews) == len(res.acts)
    return res 
Example #3
Source File: runner.py    From randovania with GNU General Public License v3.0 6 votes vote down vote up
def replace_hints_without_precision_with_jokes(patches: GamePatches,
                                               ) -> GamePatches:
    """
    Adds WRONG_GAME precision to all hints that are missing one precision.
    :param patches:
    :return:
    """

    hints_to_replace = {
        asset: dataclasses.replace(hint, precision=PrecisionPair.joke())
        for asset, hint in patches.hints.items()
        if hint.precision
    }

    return dataclasses.replace(patches, hints={
        asset: hints_to_replace.get(asset, hint)
        for asset, hint in patches.hints.items()
    }) 
Example #4
Source File: _ir0_to_cpp.py    From tmppy with Apache License 2.0 6 votes vote down vote up
def expr_to_cpp(expr: ir0.Expr,
                context: Context) -> str:
    if isinstance(expr, ir0.Literal):
        return literal_to_cpp(expr)
    elif isinstance(expr, ir0.ComparisonExpr):
        return comparison_expr_to_cpp(expr, context)
    elif isinstance(expr, ir0.NotExpr):
        return not_expr_to_cpp(expr, context)
    elif isinstance(expr, ir0.UnaryMinusExpr):
        return unary_minus_expr_to_cpp(expr, context)
    elif isinstance(expr, ir0.Int64BinaryOpExpr):
        return int64_binary_op_expr_to_cpp(expr, context)
    elif isinstance(expr, ir0.BoolBinaryOpExpr):
        return bool_binary_op_expr_to_cpp(expr, context)
    else:
        writer = ExprWriter(context.writer)
        type_expr_to_cpp(expr, dataclasses.replace(context, writer=writer))
        return ''.join(writer.strings) 
Example #5
Source File: test_item_hints.py    From randovania with GNU General Public License v3.0 6 votes vote down vote up
def test_create_hints_guardians(empty_patches, pickup_index_and_guardian, pickup, item):
    # Setup
    asset_id = 1000
    pickup_index, guardian = pickup_index_and_guardian

    logbook_node, _, world_list = _create_world_list(asset_id, pickup_index)

    patches = dataclasses.replace(
        empty_patches,
        pickup_assignment={
            pickup_index: PickupTarget(pickup, 0),
        },
        hints={
            logbook_node.resource(): Hint(HintType.GUARDIAN,
                                          PrecisionPair(PrecisionPair.detailed(), item[0]),
                                          pickup_index)
        })
    rng = MagicMock()

    # Run
    result = item_hints.create_hints(patches, world_list, rng)

    # Assert
    message = f"{guardian} is guarding {item[1]}."
    assert result == [{'asset_id': asset_id, 'strings': [message, '', message]}] 
Example #6
Source File: console.py    From rich with MIT License 6 votes vote down vote up
def update(
        self,
        width: int = None,
        min_width: int = None,
        max_width: int = None,
        justify: JustifyMethod = None,
        overflow: OverflowMethod = None,
        no_wrap: bool = None,
    ) -> "ConsoleOptions":
        """Update values, return a copy."""
        options = replace(self)
        if width is not None:
            options.min_width = options.max_width = width
        if min_width is not None:
            options.min_width = min_width
        if max_width is not None:
            options.max_width = max_width
        if justify is not None:
            options.justify = justify
        if overflow is not None:
            options.overflow = overflow
        if no_wrap is not None:
            options.no_wrap = no_wrap
        return options 
Example #7
Source File: hyperparameters.py    From squeezenas with MIT License 6 votes vote down vote up
def get_cityscapes_hyperparams_small(width_multiplier=1.0, num_classes=19, init_channels=16, mid_channels=128,
                                     skip_output_block_index=7, last_conv_channels=256):
    block_hyperparams = (InvertResidualNetBlockMetaHyperparameters(num_channels=16, num_repeat=4, stride=2),
                         InvertResidualNetBlockMetaHyperparameters(num_channels=24, num_repeat=4, stride=2),
                         InvertResidualNetBlockMetaHyperparameters(num_channels=40, num_repeat=4, stride=2),
                         InvertResidualNetBlockMetaHyperparameters(num_channels=48, num_repeat=4, stride=1),
                         InvertResidualNetBlockMetaHyperparameters(num_channels=96, num_repeat=4, stride=1),)
    if width_multiplier != 1.0:
        block_hyperparams = tuple(
            dataclasses.replace(meta_block, num_channels=round(meta_block.num_channels * width_multiplier))
            for meta_block in block_hyperparams)
    hyperparams = SqueezeNASNetCityscapesHyperparameters(init_channels=init_channels, blocks=block_hyperparams,
                                                         num_classes=num_classes,
                                                         skip_output_block_index=skip_output_block_index,
                                                         mid_channels=mid_channels, last_channels=last_conv_channels)
    return hyperparams 
Example #8
Source File: hyperparameters.py    From squeezenas with MIT License 6 votes vote down vote up
def get_cityscapes_hyperparams_large(width_multiplier=1.0, num_classes=19, init_channels=16, mid_channels=128,
                                     final_width_multiplier=0.5, skip_output_block_index=8):
    block_hyperparams = (InvertResidualNetBlockMetaHyperparameters(num_channels=16, num_repeat=1, stride=1),
                         InvertResidualNetBlockMetaHyperparameters(num_channels=24, num_repeat=4, stride=2),
                         InvertResidualNetBlockMetaHyperparameters(num_channels=32, num_repeat=4, stride=2),
                         InvertResidualNetBlockMetaHyperparameters(num_channels=64, num_repeat=4, stride=2),
                         InvertResidualNetBlockMetaHyperparameters(num_channels=96, num_repeat=4, stride=1),
                         InvertResidualNetBlockMetaHyperparameters(num_channels=160, num_repeat=4, stride=1),
                         InvertResidualNetBlockMetaHyperparameters(num_channels=round(320 * final_width_multiplier),
                                                                   num_repeat=1, stride=1),)
    if width_multiplier != 1.0:
        block_hyperparams = tuple(
            dataclasses.replace(meta_block, num_channels=round(meta_block.num_channels * width_multiplier))
            for meta_block in block_hyperparams)
    hyperparams = SqueezeNASNetCityscapesHyperparameters(init_channels=init_channels, blocks=block_hyperparams,
                                                         num_classes=num_classes,
                                                         skip_output_block_index=skip_output_block_index,
                                                         mid_channels=mid_channels)
    return hyperparams 
Example #9
Source File: hyperparameters.py    From squeezenas with MIT License 6 votes vote down vote up
def get_cityscapes_hyperparams_xlarge(width_multiplier=1.0, num_classes=19, init_channels=48, mid_channels=160,
                                      final_width_multiplier=1.0, skip_output_block_index=4):
    block_hyperparams = (InvertResidualNetBlockMetaHyperparameters(num_channels=24, num_repeat=1, stride=1),
                         InvertResidualNetBlockMetaHyperparameters(num_channels=32, num_repeat=4, stride=2),
                         InvertResidualNetBlockMetaHyperparameters(num_channels=48, num_repeat=4, stride=2),
                         InvertResidualNetBlockMetaHyperparameters(num_channels=96, num_repeat=4, stride=2),
                         InvertResidualNetBlockMetaHyperparameters(num_channels=144, num_repeat=4, stride=1),
                         InvertResidualNetBlockMetaHyperparameters(num_channels=240, num_repeat=4, stride=1),
                         InvertResidualNetBlockMetaHyperparameters(num_channels=round(320 * final_width_multiplier),
                                                                   num_repeat=1, stride=1),)
    if width_multiplier != 1.0:
        block_hyperparams = tuple(
            dataclasses.replace(meta_block, num_channels=round(meta_block.num_channels * width_multiplier))
            for meta_block in block_hyperparams)
    hyperparams = SqueezeNASNetCityscapesHyperparameters(init_channels=init_channels, blocks=block_hyperparams,
                                                         num_classes=num_classes,
                                                         skip_output_block_index=skip_output_block_index,
                                                         mid_channels=mid_channels)
    return hyperparams 
Example #10
Source File: test_preset_editor.py    From randovania with GNU General Public License v3.0 6 votes vote down vote up
def test_edit_layout_trick_level(editor: PresetEditor,
                                 initial_layout_configuration_params: dict,
                                 default_layout_configuration,
                                 new_trick_level: LayoutTrickLevel):
    # Setup
    editor._layout_configuration = dataclasses.replace(default_layout_configuration,
                                                       **initial_layout_configuration_params)
    editor._nested_autosave_level = 1

    # Run
    initial_layout_configuration_params["trick_level_configuration"] = TrickLevelConfiguration(new_trick_level)
    editor.set_layout_configuration_field("trick_level_configuration", TrickLevelConfiguration(new_trick_level))

    # Assert
    assert editor.layout_configuration == dataclasses.replace(default_layout_configuration,
                                                              **initial_layout_configuration_params) 
Example #11
Source File: test_base_patches_factory.py    From randovania with GNU General Public License v3.0 6 votes vote down vote up
def test_add_elevator_connections_to_patches_vanilla(echoes_game_data,
                                                     skip_final_bosses: bool,
                                                     default_layout_configuration):
    # Setup
    game = data_reader.decode_data(echoes_game_data)
    expected = dataclasses.replace(game.create_game_patches())
    if skip_final_bosses:
        expected.elevator_connection[136970379] = AreaLocation(1006255871, 1393588666)

    # Run
    result = base_patches_factory.add_elevator_connections_to_patches(
        dataclasses.replace(default_layout_configuration, skip_final_bosses=skip_final_bosses),
        Random(0),
        game.create_game_patches())

    # Assert
    assert result == expected 
Example #12
Source File: generator.py    From randovania with GNU General Public License v3.0 6 votes vote down vote up
def create_player_pool(rng: Random, configuration: LayoutConfiguration, player_index: int) -> PlayerPool:
    game = data_reader.decode_data(configuration.game_data)

    base_patches = dataclasses.replace(base_patches_factory.create_base_patches(configuration, rng, game),
                                       player_index=player_index)

    item_pool, pickup_assignment, initial_items = pool_creator.calculate_pool_results(configuration,
                                                                                      game.resource_database)
    target_assignment = {
        index: PickupTarget(pickup, player_index)
        for index, pickup in pickup_assignment.items()
    }
    patches = base_patches.assign_pickup_assignment(target_assignment).assign_extra_initial_items(initial_items)

    return PlayerPool(
        game=game,
        configuration=configuration,
        patches=patches,
        pickups=item_pool,
    ) 
Example #13
Source File: record_editor.py    From recordexpungPDX with MIT License 6 votes vote down vote up
def _update_or_delete_charge(charges, case_number, edit_action_ambiguous_charge_id, edit) -> OeciCharge:
        charge = next((charge for charge in charges if charge.ambiguous_charge_id == edit_action_ambiguous_charge_id))
        charge_dict = RecordEditor._parse_charge_edits(edit)
        charge_type_string = charge_dict.pop("charge_type", None)
        edited_oeci_charge = replace(charge, **charge_dict)
        if charge_type_string:
            charge_type_data = {
                "id": f"{charge.ambiguous_charge_id}-0",
                "case_number": case_number,
                "charge_type": RecordEditor._get_charge_type(charge_type_string),
                **asdict(edited_oeci_charge),
            }
            new_charge = from_dict(data_class=Charge, data=charge_type_data)
            return new_charge
        else:
            return edited_oeci_charge 
Example #14
Source File: wrappers.py    From gapic-generator-python with Apache License 2.0 6 votes vote down vote up
def with_context(self, *, collisions: FrozenSet[str]) -> 'Field':
        """Return a derivative of this field with the provided context.

        This method is used to address naming collisions. The returned
        ``Field`` object aliases module names to avoid naming collisions
        in the file being written.
        """
        return dataclasses.replace(
            self,
            message=self.message.with_context(
                collisions=collisions,
                skip_fields=True,
            ) if self.message else None,
            enum=self.enum.with_context(collisions=collisions)
            if self.enum else None,
            meta=self.meta.with_context(collisions=collisions),
        ) 
Example #15
Source File: wrappers.py    From gapic-generator-python with Apache License 2.0 6 votes vote down vote up
def with_context(self, *, collisions: FrozenSet[str]) -> 'OperationInfo':
        """Return a derivative of this OperationInfo with the provided context.

          This method is used to address naming collisions. The returned
          ``OperationInfo`` object aliases module names to avoid naming collisions
          in the file being written.
          """
        return dataclasses.replace(
            self,
            response_type=self.response_type.with_context(
                collisions=collisions
            ),
            metadata_type=self.metadata_type.with_context(
                collisions=collisions
            ),
        ) 
Example #16
Source File: wrappers.py    From gapic-generator-python with Apache License 2.0 6 votes vote down vote up
def with_context(self, *, collisions: FrozenSet[str]) -> 'Method':
        """Return a derivative of this method with the provided context.

        This method is used to address naming collisions. The returned
        ``Method`` object aliases module names to avoid naming collisions
        in the file being written.
        """
        maybe_lro = self.lro.with_context(
            collisions=collisions
        ) if self.lro else None

        return dataclasses.replace(
            self,
            lro=maybe_lro,
            input=self.input.with_context(collisions=collisions),
            output=self.output.with_context(collisions=collisions),
            meta=self.meta.with_context(collisions=collisions),
        ) 
Example #17
Source File: metadata.py    From gapic-generator-python with Apache License 2.0 6 votes vote down vote up
def child(self, child_name: str, path: Tuple[int, ...]) -> 'Address':
        """Return a new child of the current Address.

        Args:
            child_name (str): The name of the child node.
                This address' name is appended to ``parent``.

        Returns:
            ~.Address: The new address object.
        """
        return dataclasses.replace(
            self,
            module_path=self.module_path + path,
            name=child_name,
            parent=self.parent + (self.name,) if self.name else self.parent,
        ) 
Example #18
Source File: api.py    From gapic-generator-python with Apache License 2.0 6 votes vote down vote up
def subpackages(self) -> Mapping[str, 'API']:
        """Return a map of all subpackages, if any.

        Each value in the mapping is another API object, but the ``protos``
        property only shows protos belonging to the subpackage.
        """
        answer: Dict[str, API] = collections.OrderedDict()

        # Get the actual subpackages we have.
        #
        # Note that this intentionally only goes one level deep; nested
        # subpackages can be accessed by requesting subpackages of the
        # derivative API objects returned here.
        level = len(self.subpackage_view)
        for subpkg_name in sorted({p.meta.address.subpackage[0]
                                   for p in self.protos.values()
                                   if len(p.meta.address.subpackage) > level and
                                   p.meta.address.subpackage[:level] == self.subpackage_view}):
            answer[subpkg_name] = dataclasses.replace(self,
                                                      subpackage_view=self.subpackage_view +
                                                      (subpkg_name,),
                                                      )
        return answer 
Example #19
Source File: test_generator_reach.py    From randovania with GNU General Public License v3.0 6 votes vote down vote up
def test_reach_size_from_start(echoes_game_description, default_layout_configuration):
    # Setup
    layout_configuration = dataclasses.replace(
        default_layout_configuration,
        trick_level_configuration=TrickLevelConfiguration(LayoutTrickLevel.HYPERMODE),
    )
    player_pool = generator.create_player_pool(Random(15000), layout_configuration, 0)

    game, state = logic_bootstrap(layout_configuration, player_pool.game, player_pool.patches)

    # Run
    reach = GeneratorReach.reach_from_state(game, state)

    # Assert
    assert len(list(reach.nodes)) == 44
    assert len(list(reach.safe_nodes)) == 5 
Example #20
Source File: base.py    From dffml with MIT License 6 votes vote down vote up
def mkoverride(
        cls,
        other,
        *,
        uuid: uuid.UUID = None,
        name: str = None,
        url: URL = None,
        license: License = None,
        extra: Dict[str, object] = {},
    ):
        new_extra = other.extra.copy()
        new_extra.update(extra)
        return dataclasses.replace(
            other,
            uuid=uuid if uuid else other.uuid,
            name=name if name else other.name,
            url=url if url else other.url,
            license=license if license else other.license,
            extra=new_extra,
        ) 
Example #21
Source File: wrappers.py    From gapic-generator-python with Apache License 2.0 5 votes vote down vote up
def with_context(self, *,
                     collisions: FrozenSet[str],
                     skip_fields: bool = False,
                     ) -> 'MessageType':
        """Return a derivative of this message with the provided context.

        This method is used to address naming collisions. The returned
        ``MessageType`` object aliases module names to avoid naming collisions
        in the file being written.

        The ``skip_fields`` argument will omit applying the context to the
        underlying fields. This provides for an "exit" in the case of circular
        references.
        """
        return dataclasses.replace(
            self,
            fields=collections.OrderedDict(
                (k, v.with_context(collisions=collisions))
                for k, v in self.fields.items()
            ) if not skip_fields else self.fields,
            nested_enums=collections.OrderedDict(
                (k, v.with_context(collisions=collisions))
                for k, v in self.nested_enums.items()
            ),
            nested_messages=collections.OrderedDict(
                (k, v.with_context(
                    collisions=collisions,
                    skip_fields=skip_fields,))
                for k, v in self.nested_messages.items()),
            meta=self.meta.with_context(collisions=collisions),
        ) 
Example #22
Source File: record_creator.py    From recordexpungPDX with MIT License 5 votes vote down vote up
def _analyze_ambiguous_record(ambiguous_record: AmbiguousRecord, charge_ids_with_question: List[str]):
        charge_id_to_time_eligibilities = []
        ambiguous_record_with_errors = []
        for record in ambiguous_record:
            charge_id_to_time_eligibility = Expunger.run(record)
            charge_id_to_time_eligibilities.append(charge_id_to_time_eligibility)
            ambiguous_record_with_errors.append(record)
        record = RecordMerger.merge(
            ambiguous_record_with_errors, charge_id_to_time_eligibilities, charge_ids_with_question
        )
        sorted_record = RecordCreator.sort_record(record)
        return replace(sorted_record, errors=tuple(ErrorChecker.check(sorted_record))) 
Example #23
Source File: generator.py    From recordexpungPDX with MIT License 5 votes vote down vote up
def build_record_strategy(draw: Callable[[SearchStrategy], Any], min_cases_size=0, min_charges_size=0) -> Record:
    case_strategy = _build_case_strategy(min_charges_size)
    cases = draw(lists(case_strategy, min_cases_size))
    record = draw(builds(Record, cases=none()))
    return replace(record, cases=tuple(cases)) 
Example #24
Source File: crawler.py    From recordexpungPDX with MIT License 5 votes vote down vote up
def _read_case(session: Session, case_summary: CaseSummary) -> OeciCase:
        case_parser_data = Crawler._parse_case(session, case_summary)
        balance_due_in_cents = CaseCreator.compute_balance_due_in_cents(case_parser_data.balance_due)
        charges: List[OeciCharge] = []
        for charge_id, charge_dict in case_parser_data.hashed_charge_data.items():
            ambiguous_charge_id = f"{case_summary.case_number}-{charge_id}"
            charge = Crawler._build_oeci_charge(
                charge_id, ambiguous_charge_id, charge_dict, case_parser_data, balance_due_in_cents
            )
            charges.append(charge)
        updated_case_summary = replace(
            case_summary, balance_due_in_cents=balance_due_in_cents, edit_status=EditStatus.UNCHANGED
        )
        return OeciCase(updated_case_summary, charges=tuple(charges)) 
Example #25
Source File: test_charge.py    From recordexpungPDX with MIT License 5 votes vote down vote up
def test_dismissed_charge_is_not_a_recent_conviction(self):
        charge = ChargeFactory.create()
        charge_with_disposition = replace(
            charge, disposition=DispositionCreator.create(self.LESS_THAN_TEN_YEARS_AGO, "Dismissed")
        )

        assert charge_with_disposition.recent_conviction() is False 
Example #26
Source File: record_creator.py    From recordexpungPDX with MIT License 5 votes vote down vote up
def sort_record(record):
        updated_cases = []
        for case in record.cases:
            sorted_charges = sorted(case.charges, key=lambda charge: charge.ambiguous_charge_id)
            updated_case = replace(case, charges=tuple(sorted_charges))
            updated_cases.append(updated_case)
        record_with_sorted_charges = replace(record, cases=tuple(updated_cases))
        return RecordCreator.sort_record_by_case_date(record_with_sorted_charges) 
Example #27
Source File: record_creator.py    From recordexpungPDX with MIT License 5 votes vote down vote up
def sort_record_by_case_date(record):
        sorted_cases = sorted(record.cases, key=lambda case: case.summary.date, reverse=True)
        return replace(record, cases=tuple(sorted_cases)) 
Example #28
Source File: charge_classifier.py    From recordexpungPDX with MIT License 5 votes vote down vote up
def _handle_pcs_and_manufacture_delivery(name, level, statute, schedule_2_handler):
        if any([schedule_2_keyword in name for schedule_2_keyword in ["2", "ii", "heroin", "cocaine", "meth"]]):
            return schedule_2_handler(level)
        elif any([schedule_3_keyword in name for schedule_3_keyword in ["3", "iii", "4", " iv"]]):
            return ChargeClassifier._classification_by_level(level, statute)
        else:
            # The name contains either a "1" or no schedule number, and thus is possibly a marijuana charge.
            question_string = "Was the underlying substance marijuana?"
            charge_types_with_question = ChargeClassifier._classification_by_level(level, statute)
            if level == "felony unclassified":
                felony_unclassified_question_id = (
                    f"{question_string}-No-{charge_types_with_question.question.question_id}"
                )
                felony_unclassified_question = replace(
                    charge_types_with_question.question, question_id=felony_unclassified_question_id
                )
                charge_types = [MarijuanaEligible()] + charge_types_with_question.ambiguous_charge_type
                question = Question(
                    question_string,
                    question_string,
                    {
                        "Yes": Answer(edit={"charge_type": MarijuanaEligible.__name__}),
                        "No": Answer(question=felony_unclassified_question),
                    },
                )
                return AmbiguousChargeTypeWithQuestion(charge_types, question)
            elif level == "felony class a" or level == "felony class b":
                charge_type = charge_types_with_question.ambiguous_charge_type[0]
                options = {"Yes": MarijuanaEligible(), "No": charge_type}
                return ChargeClassifier._build_ambiguous_charge_type_with_question(question_string, options)

    # TODO: Assert for when Felony Unclassified 
Example #29
Source File: record_editor.py    From recordexpungPDX with MIT License 5 votes vote down vote up
def _mark_charges_as_deleted(charges: Tuple[OeciCharge, ...]) -> Tuple[OeciCharge, ...]:
        deleted_charges = []
        for charge in charges:
            deleted_charge = replace(charge, edit_status=EditStatus.DELETE)
            deleted_charges.append(deleted_charge)
        return tuple(deleted_charges) 
Example #30
Source File: runner.py    From randovania with GNU General Public License v3.0 5 votes vote down vote up
def fill_unassigned_hints(patches: GamePatches,
                          world_list: WorldList,
                          rng: Random,
                          ) -> GamePatches:
    new_hints = copy.copy(patches.hints)

    # Get all LogbookAssets from the WorldList
    potential_hint_locations: Set[LogbookAsset] = {
        node.resource()
        for node in world_list.all_nodes
        if isinstance(node, LogbookNode)
    }

    # But remove these that already have hints
    potential_hint_locations -= patches.hints.keys()

    # Get interesting items to place hints for
    possible_indices = set(patches.pickup_assignment.keys())
    possible_indices -= {hint.target for hint in patches.hints.values()}
    possible_indices -= {index for index in possible_indices
                         if not should_have_hint(patches.pickup_assignment[index].pickup.item_category)}

    debug.debug_print("fill_unassigned_hints had {} decent indices for {} hint locations".format(
        len(possible_indices), len(potential_hint_locations)))

    # But if we don't have enough hints, just pick randomly from everything
    if len(possible_indices) < len(potential_hint_locations):
        possible_indices = {node.pickup_index
                            for node in world_list.all_nodes
                            if isinstance(node, PickupNode)}

    # Get an stable order then shuffle
    possible_indices = list(sorted(possible_indices))
    rng.shuffle(possible_indices)

    for logbook in sorted(potential_hint_locations):
        new_hints[logbook] = Hint(HintType.LOCATION, None, possible_indices.pop())
        debug.debug_print(f"Added hint at {logbook} for item at {new_hints[logbook].target}")

    return dataclasses.replace(patches, hints=new_hints)