Skip to content

Commit

Permalink
Merge branch '2024-streamlit'
Browse files Browse the repository at this point in the history
  • Loading branch information
Arjan Egges committed May 21, 2024
2 parents c4ad78d + d907241 commit 2ee83e2
Show file tree
Hide file tree
Showing 7 changed files with 1,706 additions and 0 deletions.
37 changes: 37 additions & 0 deletions 2024/streamlit/hello_world.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import streamlit as st
from py_wanderer import ALGORITHMS, HEURISTICS


def configure_page() -> None:
st.set_page_config(page_title="Maze and Pathfinding Visualizer", layout="wide")


def configure_overview() -> None:
st.markdown("## Overview")
st.markdown("This app generates a maze and visualizes the pathfinding algorithms solving it.")
st.markdown("The aim is to compare the performance of different algorithms and heuristics.")


def configure_available_algo_heuristics() -> None:
st.markdown("## Algorithms and Heuristics")
st.markdown("The following algorithms and heuristics are available:")

with st.expander("Algorithms and Heuristics"):
left, right = st.columns(2)
left.markdown("### Algorithms")
for algorithm in ALGORITHMS:
left.markdown(f"- {algorithm.__name__}")

right.markdown("### Heuristics")
for heuristic in HEURISTICS:
right.markdown(f"- {heuristic.__name__.title()}")


def main() -> None:
configure_page()
configure_overview()
configure_available_algo_heuristics()


if __name__ == "__main__":
main()
1,435 changes: 1,435 additions & 0 deletions 2024/streamlit/poetry.lock

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions 2024/streamlit/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[tool.poetry]
name = "streamlit-tutorial"
version = "0.1.0"
description = ""
authors = ["ArjanCodes"]
package-mode = false

[tool.poetry.dependencies]
python = "^3.10"
py_wanderer = "1.0.4"
matplotlib = "3.8.4"
streamlit = "^1.33.0"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
60 changes: 60 additions & 0 deletions 2024/streamlit/sidebar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import streamlit as st
from matplotlib.figure import Figure
from py_wanderer import ALGORITHMS, HEURISTICS
from py_wanderer.plotter import plot_maze_with_paths

from utils import generate_maze, solve_maze, MazeConfig


def configure_page() -> None:
st.set_page_config(page_title="Maze and Pathfinding Visualizer", layout="wide")


def configure_overview() -> None:
st.markdown("## Overview")
st.markdown("This app generates a maze and visualizes the pathfinding algorithms solving it.")
st.markdown("The aim is to compare the performance of different algorithms and heuristics.")


def configure_available_algo_heuristics() -> None:
st.markdown("## Algorithms and Heuristics")
st.markdown("The following algorithms and heuristics are available:")

with st.expander("Algorithms and Heuristics"):
left, right = st.columns(2)
left.markdown("### Algorithms")
for algorithm in ALGORITHMS:
left.markdown(f"- {algorithm.__name__}")

right.markdown("### Heuristics")
for heuristic in HEURISTICS:
right.markdown(f"- {heuristic.__name__.title()}")


def configure_sidebar() -> MazeConfig:
seed = st.sidebar.number_input("Seed", 0, 10, 0)
width = st.sidebar.slider("Width", 5, 25, 11)
height = st.sidebar.slider("Height", 5, 25, 11)
num_rooms = st.sidebar.slider("Number of rooms", 0, 5, 0)
room_size_range = st.sidebar.slider("Room size range", 1, min(width, height) // 4, (3, 6))
return MazeConfig(seed, width, height, num_rooms, room_size_range)


def create_plot(maze_config: MazeConfig) -> Figure:
maze = generate_maze(maze_config.seed, maze_config.width, maze_config.height, maze_config.num_rooms, maze_config.room_size_range)
paths = solve_maze(maze, ((ALGORITHMS[0], HEURISTICS[0]),))
fig = plot_maze_with_paths(maze, paths)
return fig


def main() -> None:
configure_page()
configure_overview()
configure_available_algo_heuristics()
maze_config = configure_sidebar()
fig = create_plot(maze_config)
st.pyplot(fig)


if __name__ == "__main__":
main()
70 changes: 70 additions & 0 deletions 2024/streamlit/sidebar_expanded.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import streamlit as st
from matplotlib.figure import Figure
from py_wanderer import ALGORITHMS, HEURISTICS
from py_wanderer.plotter import plot_maze_with_paths

from utils import generate_maze, solve_maze, MazeConfig, SolvingStrategy, SolvingStrategies


def configure_page() -> None:
st.set_page_config(page_title="Maze and Pathfinding Visualizer", layout="wide")


def configure_overview() -> None:
st.markdown("## Overview")
st.markdown("This app generates a maze and visualizes the pathfinding algorithms solving it.")
st.markdown("The aim is to compare the performance of different algorithms and heuristics.")


def configure_available_algo_heuristics() -> None:
st.markdown("## Algorithms and Heuristics")
st.markdown("The following algorithms and heuristics are available:")

with st.expander("Algorithms and Heuristics"):
left, right = st.columns(2)
left.markdown("### Algorithms")
for algorithm in ALGORITHMS:
left.markdown(f"- {algorithm.__name__}")

right.markdown("### Heuristics")
for heuristic in HEURISTICS:
right.markdown(f"- {heuristic.__name__.title()}")


def configure_sidebar() -> MazeConfig:
seed = st.sidebar.number_input("Seed", 0, 10, 0)
width = st.sidebar.slider("Width", 5, 101, 11)
height = st.sidebar.slider("Height", 5, 101, 11)
num_rooms = st.sidebar.slider("Number of rooms", 0, 5, 0)
room_size_range = st.sidebar.slider("Room size range", 1, min(width, height) // 4, (3, 6))

algorithms_multiselect = st.sidebar.multiselect(
"Select algorithms", ALGORITHMS, [ALGORITHMS[0]], format_func=lambda x: x.__name__)
heuristics_multiselect = st.sidebar.multiselect(
"Select heuristics", HEURISTICS, [HEURISTICS[0]], format_func=lambda x: x.__name__.title())
solving_strategies: SolvingStrategies = tuple(
(algorithm, heuristic) for algorithm in algorithms_multiselect for heuristic in heuristics_multiselect
)

return MazeConfig(seed, width, height, num_rooms, room_size_range, solving_strategies)


def create_plot(maze_config: MazeConfig) -> Figure:
maze = generate_maze(maze_config.seed, maze_config.width, maze_config.height, maze_config.num_rooms,
maze_config.room_size_range)
paths = solve_maze(maze, maze_config.solving_strategies)
fig = plot_maze_with_paths(maze, paths)
return fig


def main() -> None:
configure_page()
configure_overview()
configure_available_algo_heuristics()
maze_config = configure_sidebar()
fig = create_plot(maze_config)
st.pyplot(fig)


if __name__ == "__main__":
main()
51 changes: 51 additions & 0 deletions 2024/streamlit/simple_plot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import streamlit as st
from matplotlib.figure import Figure
from py_wanderer import ALGORITHMS, HEURISTICS
from py_wanderer.plotter import plot_maze_with_paths

from utils import generate_maze, solve_maze, MazeConfig


def configure_page() -> None:
st.set_page_config(page_title="Maze and Pathfinding Visualizer", layout="wide")


def configure_overview() -> None:
st.markdown("## Overview")
st.markdown("This app generates a maze and visualizes the pathfinding algorithms solving it.")
st.markdown("The aim is to compare the performance of different algorithms and heuristics.")


def configure_available_algo_heuristics() -> None:
st.markdown("## Algorithms and Heuristics")
st.markdown("The following algorithms and heuristics are available:")

with st.expander("Algorithms and Heuristics"):
left, right = st.columns(2)
left.markdown("### Algorithms")
for algorithm in ALGORITHMS:
left.markdown(f"- {algorithm.__name__}")

right.markdown("### Heuristics")
for heuristic in HEURISTICS:
right.markdown(f"- {heuristic.__name__.title()}")


def create_plot(maze_config: MazeConfig) -> Figure:
maze = generate_maze(maze_config.seed, maze_config.width, maze_config.height, maze_config.num_rooms, maze_config.room_size_range)
paths = solve_maze(maze, ((ALGORITHMS[0], HEURISTICS[0]),))
fig = plot_maze_with_paths(maze, paths)
return fig


def main() -> None:
maze_config = MazeConfig(seed=0, width=11, height=11, num_rooms=0, room_size_range=(3, 6))
configure_page()
configure_overview()
configure_available_algo_heuristics()
fig = create_plot(maze_config)
st.pyplot(fig)


if __name__ == "__main__":
main()
37 changes: 37 additions & 0 deletions 2024/streamlit/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import random
from dataclasses import astuple, dataclass

from py_wanderer import ALGORITHMS, HEURISTICS, Heuristic, Maze, PathfindingAlgorithm

SolvingStrategy = tuple[PathfindingAlgorithm, Heuristic]
SolvingStrategies = tuple[SolvingStrategy]


@dataclass
class MazeConfig:
seed: int
width: int
height: int
num_rooms: int
room_size_range: tuple[int, int]
solving_strategies: SolvingStrategies = ((ALGORITHMS[0], HEURISTICS[0]),)

def __hash__(self):
return hash(astuple(self))


def generate_maze(
seed: int, width: int, height: int, num_rooms: int, room_size_range: tuple[int, int]
):
width += width % 2 == 0
height += height % 2 == 0
start, end = (1, 1), (height - 2, width - 2)
state = random.getstate()
random.seed(seed)
maze = Maze(width, height, start, end, num_rooms, room_size_range).generate()
random.setstate(state)
return maze


def solve_maze(maze: Maze, strategies: SolvingStrategies):
return maze.solve_many(list(strategies))

0 comments on commit 2ee83e2

Please sign in to comment.