-
Notifications
You must be signed in to change notification settings - Fork 263
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
Remove dynamic classes and tidy imports #852
Conversation
Can this be fixed without removing strategy transformers?
|
I have no idea. It took me quite a while to get this far so I suggest that gets looked in to after this PR. Either way we're not going to remove strategy transformers right? |
@@ -21,8 +22,7 @@ class AverageCopier(Player): | |||
'manipulates_state': False | |||
} | |||
|
|||
@staticmethod | |||
def strategy(opponent: Player) -> Action: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because of the random?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was being pointed out as an error by mypy
something to do with the method not being in line with the parent class.
axelrod/strategies/lookerup.py
Outdated
# Add the generated class to the module dictionary so it can be | ||
# imported into other modules | ||
setattr(module, class_name, new_class) | ||
class EvolvedLookerUp0_0_1(LookerUp): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know that we actually want to add all of these to the library. I only included a few in the axelrod.strategies list -- maybe just add those? Some of the small ones shadow strategies in the library already, and the ones with larger parameters don't seem to outperform 2_2_2 for the most part.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, you only include 1-1-1 and 2-2-2 in the whole list. Should we go ahead and just include those?
I don't know? If not then why are we removing the dynamic class generation for LookerUp? For readability? I'm not opposed per se I'm just not sure what problem it solves. |
We certainly should not remove the strategy transformers.
Readability would be a big reason for me, I'd almost turn this around the other way, going back to my original question on #845: what problem does having dynamically generated classes solve? I actually found this quite hard to untangle working on this PR so would be strongly in favour of verbose class definitions (in line with the rest of the library). I'd also suggest that if we are only going to have 1-1-1 and 2-2-2 (which I'm fine with) then we could get rid of the data file for lookerups. I'd actually suggest that the whole reading in of data from the external source doesn't help with readability. For example in this particular case there was an error in the header which caused me a 5 minute labyrinth run around but that's perhaps a discussion for another PR. |
Ok, I understand. The reason I did it the way it currently is was so that if someone else wants to play with the other variants they can easily, and they wouldn't be tempted to add new variants that had already been created. It was also easy to add a bunch of variants to the library by just adding new lines in the data file rather than write new classes each time, which is pretty tedious and involves a lot of repeated boilerplate that's easy to mess up -- class name, data, player name, parent class... it was much easier to just comment out a line in the data file and add a new one. The dynamic code is ~20 lines, all the individuals classes written out are ~300. I also didn't want to remove all the variants, but I didn't want to add 15 very similar strategies to the standard tournament -- we already have a number of players that are quite similar, like the gobymajorities and retaliators. So I don't think there is a great solution, but if we want to say readability takes precedent then I'll go along with that. Regardless I think it's better no having large static data chunks in the strategy classes themselves, so I would prefer to keep the data loading as is. |
As I said, I'm not sure it's self evident that that's a good thing.
Yes my vote goes to readability. It would be a minor refactor to handle all this with inheritance which would appease your previous concern (and keep in line with the rest of the library with other such cases).
I would personally suggest keeping things in one spot where it's not tedious to do is better with the argument of removing complexity (I went on a bit of a merrygoround ride when working on this). I've just pushed removing the various ones that were not added to the list, so only have |
09daa29 refactors the code a bit more so that it makes use of inheritance. |
I've also just pushed some changes that removed unused code (mainly relevant to reading in the two patterns). None of my main changes (including the inheritance) are incompatible with reading in the data if we really want that to stay. |
axelrod/strategies/lookerup.py
Outdated
|
||
|
||
class Winner12(LookerUp): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer inheriting from LookerUp to reduce the number of inherited classes. It seems odd to me that Winner12 would derive from EvolvedLookerUp1_1_1 (same for the others that derive from it).
Perhaps we can assume that the lookup table is specified by a pattern.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've gone with an intermediate class. Let me know what you think.
@@ -1,19 +0,0 @@ | |||
# Name (string), plays (int), opp_plays(int), starting_plays(int), pattern (str) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we find somewhere else to save this data? (the evolver repository, perhaps)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call: Axelrod-Python/axelrod-dojo#20
axelrod/strategies/lookerup.py
Outdated
A 1_1_1 Lookerup trained with an evolutionary algorithm. | ||
|
||
Names: | ||
- Evolved Lookerup 1 1 1: Original name by Marc Harper |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The names are inconsistent -- let's pick underscores or no underscores.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
I think kwarg arguments for the pattern make more sense then the intermediate class having member variables. If I wanted to instantiate a new lookerup (say a 4, 4, 2) I have to make a derived classed; with arguments I could just use the existing abstract base class. Otherwise I'm happy with the PR. |
I'm not sure I understand. Are you talking about using kwargs in the |
I might have it, just working on a commit now :) |
Let me know if e7b02d6 is what you had in mind. |
Thanks, that's what I wanted :) I approved the changes, looks like we need a rebase and then we're good. |
Cool, just pushed that :) I also added another test for the pattern init. |
@drvinceknight can you rebase/merge? |
Just seen this :) Will have dinner and do it after. |
Done. 👍 |
This gets rid of the dynamic
lookerup
classes.I also tided a number of things in our imports to make type checking happier:
This is the remaining output of running mypy on the full library:
I suggest that once this PR is merged we take that list and open another issue aiming to get rid of those lasting items.