If we aim to follow best practices in the code base, it should make the project more maintainable, customisable and easier to use.
Here are a few suggestions
High priority:
[ ] Replace all occurrences of type(<obj>).__name__ == "<Class>" with isinstance(<Class>, <obj>).
This will allow custom subclasses to be made and used with the project in the future
[ ] When checking for None obj is [not] None should be used instead of type (as above) or ==
[ ] Default arguments in should never be mutable (e.g. a list or dictionary) as they are not reset between function calls and this can lead to bugs. Instead, set default to None and replace None with the required value in the function.
[ ] When checking if a value is True or "Truthy" use if value and never if value == True.
if value is True should be avoided unless checking for exactly True (will be false if compared to numpy's value of True)
Medium Priority:
[ ] Use f-strings instead using .format on strings, this makes reading and writing much clearer
e.g. replace "pet-{}".format(name) with f"pet-{name}"
[ ] Define all class attributes (self.attribute) inside the __init__ function, even if setting to None.
[ ] Never use import * as this makes it hard to find the source of a function.
[ ] Use type annotations in public methods (e.g. oteam: Team) making it easier to understand and gaining better autocomplete
[ ] Use clearer names, not always clear what oteam / fteam / apet means, friendly_team, enemy_team is much clearer (and autocomplete will help with the extra characters)
[ ] Follow public/private naming conventions. Anything that starts with an _ (e.g. self._variable) should be treated as private and not be used outside the Class definition. At the moment we regularly use _health and _attack of the pet class. A solution could be to create setter functions (.set_attack) or rename them (.base_attack)
If we aim to follow best practices in the code base, it should make the project more maintainable, customisable and easier to use.
Here are a few suggestions High priority:
type(<obj>).__name__ == "<Class>"
withisinstance(<Class>, <obj>)
. This will allow custom subclasses to be made and used with the project in the futureobj is [not] None
should be used instead of type (as above) or==
if value
and neverif value == True
.if value is True
should be avoided unless checking for exactly True (will be false if compared to numpy's value of True)Medium Priority:
.format
on strings, this makes reading and writing much clearer e.g. replace"pet-{}".format(name)
withf"pet-{name}"
__init__
function, even if setting to None.import *
as this makes it hard to find the source of a function.oteam: Team
) making it easier to understand and gaining better autocompleteself._variable
) should be treated as private and not be used outside the Class definition. At the moment we regularly use _health and _attack of the pet class. A solution could be to create setter functions (.set_attack) or rename them (.base_attack)