diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b510c1f..2de6e9b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,14 @@ on: [push] jobs: build: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + python-version: [3.6, 3.7, 3.8] + exclude: + - os: macos-latest + python-version: 3.8 steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2f52033..4e81d27 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -4,7 +4,14 @@ on: [push] jobs: build: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + python-version: [3.6, 3.7, 3.8] + exclude: + - os: macos-latest + python-version: 3.8 steps: - uses: actions/checkout@v2 @@ -34,7 +41,16 @@ jobs: flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics test: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: [3.6, 3.7, 3.8, pypy-3.6] + exclude: + - os: macos-latest + python-version: 3.8 + - os: windows-latest + python-version: 3.6 steps: - uses: actions/checkout@v2 - name: Set up Python 3.7 diff --git a/README.md b/README.md index 16523eb..97e4164 100644 --- a/README.md +++ b/README.md @@ -45,23 +45,15 @@ $ julia --color=yes -e 'using Pkg; Pkg.add(Pkg.PackageSpec(path="https://github. ```bash $ python3 -m pip install --upgrade pip -$ git clone https://github.com/APLA-Toolbox/PythonPDDL -$ cd PythonPDDL -$ python3 -m pip install -r requirements.txt +$ python3 -m pip install jupyddl ``` -# Usage - -Navigate to the root directory and you can run the tool by using : `python3 main.py "data/domain.pddl" "data/problem.pddl"` - # REFL Mode -- Clone the repository: `git clone https://github.com/APLA-Toolbox/PythonPDDL` -- Move to the repository folder: `cd PythonPDDL` - Run `python3` in the terminal. - Use the AutomatedPlanner class to do what you want: ```python -from src.automated_planner import AutomatedPlanner # takes some time because it has to instantiate the Julia interface +from jupyddl import AutomatedPlanner # takes some time because it has to instantiate the Julia interface apl = AutomatedPlanner("data/domain.pddl", "data/problem.pddl) apl.initial_state @@ -85,15 +77,11 @@ print(apl.get_actions_from_path(path)) [, , ] ``` -# Script mode - -UC - # Contribute Open an issue to state clearly the contribution you want to make. Upon aproval send in a PR with the Issue referenced. (Implement Issue #No / Fix Issue #No). -# Contributors +# Maintainers - Erwin Lejeune - Sampreet Sarkar diff --git a/jupyddl/__init__.py b/jupyddl/__init__.py new file mode 100644 index 0000000..ae6baae --- /dev/null +++ b/jupyddl/__init__.py @@ -0,0 +1,4 @@ +from .automated_planner import AutomatedPlanner + +if __name__ == "__main__": + _ = AutomatedPlanner("data/domain.pddl", "data/problem.pddl") diff --git a/src/a_star.py b/jupyddl/a_star.py similarity index 100% rename from src/a_star.py rename to jupyddl/a_star.py diff --git a/src/automated_planner.py b/jupyddl/automated_planner.py similarity index 93% rename from src/automated_planner.py rename to jupyddl/automated_planner.py index 7403bbc..6729bd2 100644 --- a/src/automated_planner.py +++ b/jupyddl/automated_planner.py @@ -47,8 +47,7 @@ def satisfies(self, asserted_state, state): def state_has_term(self, state, term): if self.pddl.has_term_in_state(self.domain, state, term): return True - else: - return False + return False def __flatten_goal(self): return self.pddl.flatten_goal(self.problem) @@ -74,8 +73,7 @@ def get_actions_from_path(self, path): cost = self.pddl.get_value(path[-1].state, "total-cost") if not cost: return actions - else: - return (actions, cost) + return (actions, cost) def get_state_def_from_path(self, path): if not path: @@ -92,8 +90,7 @@ def breadth_first_search(self, time_it=False): path = self.__retrace_path(last_node) if time_it: return path, total_time - else: - return path, None + return path, None def depth_first_search(self, time_it=False): dfs = DepthFirstSearch(self) @@ -101,8 +98,7 @@ def depth_first_search(self, time_it=False): path = self.__retrace_path(last_node) if time_it: return path, total_time - else: - return path, None + return path, None def dijktra_best_first_search(self, time_it=False): dijkstra = DijkstraBestFirstSearch(self) @@ -110,8 +106,7 @@ def dijktra_best_first_search(self, time_it=False): path = self.__retrace_path(last_node) if time_it: return path, total_time - else: - return path, None + return path, None def astar_best_first_search(self, time_it=False, heuristic=goal_count_heuristic): astar = AStarBestFirstSearch(self, heuristic) @@ -119,5 +114,4 @@ def astar_best_first_search(self, time_it=False, heuristic=goal_count_heuristic) path = self.__retrace_path(last_node) if time_it: return path, total_time - else: - return path, None + return path, None diff --git a/src/bfs.py b/jupyddl/bfs.py similarity index 100% rename from src/bfs.py rename to jupyddl/bfs.py diff --git a/src/dfs.py b/jupyddl/dfs.py similarity index 100% rename from src/dfs.py rename to jupyddl/dfs.py diff --git a/src/dijkstra.py b/jupyddl/dijkstra.py similarity index 100% rename from src/dijkstra.py rename to jupyddl/dijkstra.py diff --git a/src/heuristics.py b/jupyddl/heuristics.py similarity index 100% rename from src/heuristics.py rename to jupyddl/heuristics.py diff --git a/src/node.py b/jupyddl/node.py similarity index 100% rename from src/node.py rename to jupyddl/node.py diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..730e7b8 --- /dev/null +++ b/setup.py @@ -0,0 +1,33 @@ +import setuptools + +with open("requirements.txt") as f: + required = f.read().splitlines() + +with open("README.md", "r", encoding="utf-8") as fh: + long_description = fh.read() + + +setuptools.setup( + name="jupyddl", # Replace with your own username + version="0.2.4", + author="Erwin Lejeune", + author_email="erwinlejeune.pro@gmail.com", + description="Jupyddl is a PDDL planner built on top of a Julia parser", + long_description=long_description, + long_description_content_type="text/markdown", + url="https://github.com/apla-toolbox/pythonpddl", + packages=setuptools.find_packages(), + install_requires=required, + classifiers=[ + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3", + "License :: OSI Approved :: Apache Software License", + "Operating System :: Unix", + "Operating System :: MacOS", + "Framework :: Pytest", + ], + python_requires=">=3.6", +) diff --git a/src/__init__.py b/src/__init__.py deleted file mode 100644 index 8b13789..0000000 --- a/src/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/tests/test_automated_planner.py b/tests/test_automated_planner.py index bc4538f..cc18d0c 100644 --- a/tests/test_automated_planner.py +++ b/tests/test_automated_planner.py @@ -28,9 +28,9 @@ def test_execute_action(): def test_state_has_term(): apla = AutomatedPlanner("data/domain.pddl", "data/problem.pddl") is_goal = apla.state_has_term(apla.initial_state, apla.goals[0]) - assert is_goal == False + assert not is_goal def test_state_assertion(): apla = AutomatedPlanner("data/domain.pddl", "data/problem.pddl") - assert apla.satisfies(apla.problem.goal, apla.initial_state) == False + assert not apla.satisfies(apla.problem.goal, apla.initial_state)