TimefoldAI / timefold-solver-python

Timefold Solver is an AI constraint solver for Python to optimize the Vehicle Routing Problem, Employee Rostering, Maintenance Scheduling, Task Assignment, School Timetabling, Cloud Optimization, Conference Scheduling, Job Shop Scheduling, Bin Packing and many more planning problems.
https://timefold.ai
Apache License 2.0
27 stars 3 forks source link

Getter throws error about name format #86

Closed mmmvvvppp closed 2 weeks ago

mmmvvvppp commented 2 weeks ago

Describe the bug Getter methods for accessing planning entities are not usable. I am unsure if this is an intended behavior of Timefold or not, but this was the recommended method for OptaPy. If not a bug then increased documentation would be helpful.

Expected behavior I expect to be able to annotate either atttributes or methods in a class and still construct a valid PlanningSolution.

Actual behavior Error is thrown

To Reproduce I was able to reproduce by modifying tests/test_solver_factory.py. The Solution class now reads:

@planning_solution
@dataclass
class Solution:
    entities: List[Entity]
    value_range: Annotated[List[int], ValueRangeProvider]
    score: Annotated[SimpleScore, PlanningScore] = field(default=None)

    def get_entities(self) -> Annotated[List[Entity], PlanningEntityCollectionProperty]:
        return self.entities

    def __str__(self) -> str:
        return str(self.entities)

Note the approach here of Annotating the method similar to the original Annotated attribute.

I received:

java.lang.java.lang.IllegalStateException: java.lang.IllegalStateException: The getterMethod (public ai.timefold.jpyinterpreter.types.collections.PythonLikeList org.jpyinterpreter.user.__main__.Solution.$method$get_entities()) with a PlanningEntityCollectionProperty annotation has a methodName ($method$get_entities) that does not start with a valid prefix ([get, is]).

Environment

Timefold Solver Version or Git ref: 1.11.0b0

Python version used: 3.12.4

Output of uname -a or ver: Darwin MacBook-Pro-4.local 23.5.0 Darwin Kernel Version 23.5.0: Wed May 1 20:14:38 PDT 2024; root:xnu-10063.121.3~5/RELEASE_ARM64_T6020 arm64

Additional information

Occurred during migration from OptaPy.

Christopher-Chianelli commented 2 weeks ago

timefold has a significantly different API than optapy. In particular, instead of trying to mimic Java API, it provides a pythonic interface. Currently, using annotations that require setters (namely, PlanningEntityCollectionProperty, PlanningEntityProperty, and PlanningVariable) with Annotated is not supported. Read-only annotations on methods and Attributes are supported though:

@planning_solution
@dataclass
class Solution:
    entities: Annotated[List[Entity], PlanningEntityCollectionProperty]
    score: Annotated[SimpleScore, PlanningScore] = field(default=None)

    def value_range(self) -> Annotated[List[int], ValueRangeProvider]:
        return [i for i in range(10)]

    def __str__(self) -> str:
        return str(self.entities)

Created https://github.com/TimefoldAI/timefold-solver-python/issues/87 for tracking.