Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core: Add has_list and count_list and improve (?) count_group #2934

Merged
merged 8 commits into from
May 7, 2024

Conversation

NewSoupVi
Copy link
Member

@NewSoupVi NewSoupVi commented Mar 11, 2024

What was done

has_list and count_list

has_group and count_group currently exist to be able to check for a specific overall quantity of a list of items.
However, these need item groups to be defined, and also the user has no way of telling this function which items from a group actually exist. Those functions will just blindly try all items from the item group.

So, I decided to add two new functions called has_list and count_list, that are completely analogous to has_group and count_group, except you can specify the list of items you care about. This way, you 1. don't need an item group to be defined for the items and 2. can prepare the item list yourself, first sorting out any items that don't exist because of e.g. the options the player chose.

count_group refactor

This function uses a for loop for a sum despite not having any sort of early exit / lazy eval (like e.g. has_group does). This should probably just be a return sum(...) expression.

Motivation

An new world dev asked for it and me and Treble agreed that the current implementation is not really das Gelbe vom Ei, at least if it's going to be the only option for this.

Considerations

Some of these decisions might have been made because of how frozen builds are optimised. I'm not sure how to judge or test that. If the count_group refactor actually makes the frozen build slower bc of some weird optimisation thing, I am happy to revert it and take it out of the scope of this PR.

@github-actions github-actions bot added affects: core Issues/PRs that touch core and may need additional validation. waiting-on: peer-review Issue/PR has not been reviewed by enough people yet. labels Mar 11, 2024
Copy link
Contributor

@Ixrec Ixrec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since has_list and has_group appear to have identical implementations except for the self.multiworld.worlds[player].item_name_groups[item_name_group] expression, maybe we should deduplicate them by reimplementing has_group as a call to has_list?

Code LGTM and I agree this is useful. Methods are short enough it's fine if we leave them slightly duped.

Can't help with the concerns about frozen performance.

@NewSoupVi
Copy link
Member Author

Since has_list and has_group appear to have identical implementations except for the self.multiworld.worlds[player].item_name_groups[item_name_group] expression, maybe we should deduplicate them by reimplementing has_group as a call to has_list?

I try to avoid calling functions in state methods because function calls take (an admittely very tiny amount of) time, duplicating the code is faster. At least in bare python ,compiled Python might be different. But even if it does take time, in this case I think it could maybe be worth it, as this is a slower function so adding one function call would probably not be the worst thing. Would like more opinions on that if ppl have them

Copy link
Collaborator

@Exempt-Medic Exempt-Medic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes LGTM. Tested them with a few groups that they actually worked

@Exempt-Medic Exempt-Medic added waiting-on: core-review Issue/PR has been peer-reviewed and is ready to be merged or needs input from a core maintainer. is: enhancement Issues requesting new features or pull requests implementing new features. and removed waiting-on: peer-review Issue/PR has not been reviewed by enough people yet. labels Apr 5, 2024
@NewSoupVi
Copy link
Member Author

NewSoupVi commented Apr 21, 2024

Making a note here: If both this PR and #3192 are merged, that implies the necessity of two more new functions, has_list_exclusive and count_list_exclusive.

I will probably update this PR to add those if #3192 is merged first, and ask for them to be added to #3192 if this PR is merged first.

BaseClasses.py Outdated Show resolved Hide resolved
BaseClasses.py Outdated Show resolved Hide resolved
BaseClasses.py Outdated Show resolved Hide resolved
@NewSoupVi
Copy link
Member Author

Addressed all the feedback

Rewritten docstrings should be rereviewed

Copy link
Member

@black-sliver black-sliver left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code and doc strings look correct and same as with the other PR: moving more things to state allows us to change implementations without changing worlds.

@NewSoupVi NewSoupVi merged commit e04db57 into ArchipelagoMW:main May 7, 2024
16 checks passed
Copy link
Collaborator

@Jarno458 Jarno458 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont see any tests added for these new state checks

@@ -767,8 +767,23 @@ def item_count(self, item: str, player: int) -> int:
Utils.deprecate("Use count instead.")
return self.count(item, player)

def has_from_list(self, items: Iterable[str], player: int, count: int) -> bool:
Copy link
Collaborator

@Jarno458 Jarno458 May 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to be honest, the doc string do make it clear, but when i see state.has_from_list(["itemA", "ItemB"], 3, player) it would be unclear to me at first glance what it does
has_from_list to me from its method name looks very simular to state.has_any(["itemA", "ItemB"], player) is with the only difference is that you can specify a minimal amount rather than just 1 (any)
so my recommendation would be to name it has_atleast()

return True
return False

def count_from_list(self, items: Iterable[str], player: int) -> int:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just name this count and make it an overload?

jnschurig pushed a commit to Tranquilite0/Archipelago-SoulBlazer that referenced this pull request Jun 13, 2024
…elagoMW#2934)

* Add has_list and count_list and improve (?) count_group

* MESSENGER STOP

* Add docstrings to has_list and count_list

* Add docstrings for has_group and count_group as well

* oops

* Rename to has_from

* docstrings improvement again

* Docstring
qwint pushed a commit to qwint/Archipelago that referenced this pull request Jun 24, 2024
…elagoMW#2934)

* Add has_list and count_list and improve (?) count_group

* MESSENGER STOP

* Add docstrings to has_list and count_list

* Add docstrings for has_group and count_group as well

* oops

* Rename to has_from

* docstrings improvement again

* Docstring
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
affects: core Issues/PRs that touch core and may need additional validation. is: enhancement Issues requesting new features or pull requests implementing new features. waiting-on: core-review Issue/PR has been peer-reviewed and is ready to be merged or needs input from a core maintainer.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants