forked from UNN/2026-rff_mp
Compare commits
2 Commits
1224a5afee
...
ef877978d2
| Author | SHA1 | Date | |
|---|---|---|---|
| ef877978d2 | |||
| e54b6c0a7e |
9
stepushovgs/labyrinth/mazes/tests/test_lab3.txt
Normal file
9
stepushovgs/labyrinth/mazes/tests/test_lab3.txt
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
####################
|
||||||
|
#S #
|
||||||
|
# ########## #
|
||||||
|
# #### #
|
||||||
|
# ######## #
|
||||||
|
# #
|
||||||
|
# ####### #### #
|
||||||
|
# E #
|
||||||
|
####################
|
||||||
|
|
@ -5,6 +5,7 @@ from source.strategy import PathFindingStrategy, reconstruct_path
|
||||||
from source.classes import Maze, Cell
|
from source.classes import Maze, Cell
|
||||||
|
|
||||||
class BFS(PathFindingStrategy):
|
class BFS(PathFindingStrategy):
|
||||||
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"""Возвращает название метода"""
|
"""Возвращает название метода"""
|
||||||
return "BFS"
|
return "BFS"
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,64 @@
|
||||||
from source.strategy import PathFindingStrategy
|
from heapq import *
|
||||||
|
|
||||||
|
|
||||||
|
from source.strategy import PathFindingStrategy, reconstruct_path
|
||||||
from source.classes import Maze, Cell
|
from source.classes import Maze, Cell
|
||||||
|
|
||||||
|
|
||||||
class AStar(PathFindingStrategy):
|
class AStar(PathFindingStrategy):
|
||||||
def findPath(self, maze: Maze, start: Cell, exit: Cell):
|
@property
|
||||||
pass
|
def name(self) -> str:
|
||||||
|
return "A*"
|
||||||
|
|
||||||
|
def heuristic(self, a: Cell, b: Cell) -> int:
|
||||||
|
x1, y1 = a.getXY()
|
||||||
|
x2, y2 = b.getXY()
|
||||||
|
|
||||||
def __A__(self, maze: Maze, start: Cell, exit: Cell):
|
return abs(x1 - x2) + abs(y1 - y2)
|
||||||
pass
|
|
||||||
|
def findPath(self, maze: Maze):
|
||||||
|
start_cell = maze.start
|
||||||
|
exit_cell = maze.exit
|
||||||
|
|
||||||
|
queue = []
|
||||||
|
counter = 0 # счётчик для уникальности, чтобы не сравнивать клетки
|
||||||
|
|
||||||
|
start_h = self.heuristic(start_cell, exit_cell)
|
||||||
|
|
||||||
|
heappush(queue, (start_h, counter, start_cell))
|
||||||
|
counter += 1
|
||||||
|
|
||||||
|
cost_visited = {start_cell.getXY(): 0}
|
||||||
|
came_from = {start_cell.getXY(): None}
|
||||||
|
visited_count = 1
|
||||||
|
|
||||||
|
while queue:
|
||||||
|
current_cost, _, current_cell = heappop(queue)
|
||||||
|
current_g = cost_visited[current_cell.getXY()]
|
||||||
|
|
||||||
|
if current_cell.getXY() == exit_cell.getXY():
|
||||||
|
return reconstruct_path(
|
||||||
|
came_from=came_from,
|
||||||
|
start=start_cell,
|
||||||
|
end=current_cell
|
||||||
|
), visited_count
|
||||||
|
|
||||||
|
next_cells = maze.getNeighbors(current_cell)
|
||||||
|
|
||||||
|
for next_cell in next_cells:
|
||||||
|
neighbor_cost = next_cell.value
|
||||||
|
neighbor_cell_xy = next_cell.getXY()
|
||||||
|
|
||||||
|
new_cost = current_g + neighbor_cost
|
||||||
|
|
||||||
|
if neighbor_cell_xy not in cost_visited or new_cost < cost_visited[neighbor_cell_xy]:
|
||||||
|
priority = new_cost + self.heuristic(next_cell, exit_cell)
|
||||||
|
|
||||||
|
heappush(queue, (priority, counter, next_cell))
|
||||||
|
counter += 1
|
||||||
|
|
||||||
|
cost_visited[neighbor_cell_xy] = new_cost
|
||||||
|
came_from[neighbor_cell_xy] = current_cell
|
||||||
|
visited_count += 1
|
||||||
|
|
||||||
|
return [], visited_count
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ class MazeSolver:
|
||||||
self.strategy = strategy
|
self.strategy = strategy
|
||||||
self.observer = observer
|
self.observer = observer
|
||||||
|
|
||||||
def strategyName(self):
|
def strategyName(self) -> str:
|
||||||
return self.strategy.name
|
return self.strategy.name
|
||||||
|
|
||||||
def setStrategy(self, strategy: PathFindingStrategy):
|
def setStrategy(self, strategy: PathFindingStrategy):
|
||||||
|
|
@ -45,4 +45,8 @@ class SearchStats:
|
||||||
self.timeMs = timeMs
|
self.timeMs = timeMs
|
||||||
self.visitedCells = visitedCells
|
self.visitedCells = visitedCells
|
||||||
self.pathLength = pathLength
|
self.pathLength = pathLength
|
||||||
self.path = path
|
self.path = path
|
||||||
|
|
||||||
|
def show(self):
|
||||||
|
"""Вывод информации о тесте в консоль"""
|
||||||
|
print(f'time: {self.timeMs} ms\nvisited cells: {self.visitedCells}\npath length: {self.pathLength}')
|
||||||
|
|
@ -2,14 +2,14 @@
|
||||||
"cells": [
|
"cells": [
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 12,
|
"execution_count": 15,
|
||||||
"id": "4dbe48b6",
|
"id": "4dbe48b6",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"from source.builder import TextFileMazeBuilder\n",
|
"from source.builder import TextFileMazeBuilder\n",
|
||||||
"from source.observer import ConsoleView, Event\n",
|
"from source.observer import ConsoleView, Event\n",
|
||||||
"from source.strategy import MazeSolver, BFS, DFS\n",
|
"from source.strategy import MazeSolver, BFS, DFS, Dijkstra, AStar\n",
|
||||||
"# from source.strategy.maze_solver import \n",
|
"# from source.strategy.maze_solver import \n",
|
||||||
"from source.classes import Cell\n",
|
"from source.classes import Cell\n",
|
||||||
"# from source.strategy import "
|
"# from source.strategy import "
|
||||||
|
|
@ -17,19 +17,20 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 13,
|
"execution_count": null,
|
||||||
"id": "007bf97a",
|
"id": "007bf97a",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"test_lab = './mazes/tests/test_lab.txt'\n",
|
"test_lab = './mazes/tests/test_lab.txt'\n",
|
||||||
"test_lab2 = './mazes/tests/test_lab2.txt'\n",
|
"test_lab2 = './mazes/tests/test_lab2.txt'\n",
|
||||||
"test_lab3 = './mazes/tests/test_lab20x20.txt'"
|
"test_lab3 = './mazes/tests/test_lab3.txt'\n",
|
||||||
|
"test_lab4 = './mazes/tests/test_lab20x20.txt'"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 14,
|
"execution_count": 17,
|
||||||
"id": "4489fc7e",
|
"id": "4489fc7e",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
|
|
@ -55,7 +56,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 15,
|
"execution_count": 18,
|
||||||
"id": "fde1eddb",
|
"id": "fde1eddb",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
|
|
@ -83,7 +84,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 16,
|
"execution_count": 19,
|
||||||
"id": "22325f68",
|
"id": "22325f68",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
|
|
@ -116,7 +117,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 17,
|
"execution_count": 20,
|
||||||
"id": "19840429",
|
"id": "19840429",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
|
|
@ -154,7 +155,7 @@
|
||||||
" (7, 1)])"
|
" (7, 1)])"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 17,
|
"execution_count": 20,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
|
@ -168,7 +169,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 18,
|
"execution_count": 21,
|
||||||
"id": "73ba37a8",
|
"id": "73ba37a8",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
|
|
@ -206,7 +207,7 @@
|
||||||
" (7, 1)])"
|
" (7, 1)])"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 18,
|
"execution_count": 21,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
|
@ -220,7 +221,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 19,
|
"execution_count": 22,
|
||||||
"id": "857c5c04",
|
"id": "857c5c04",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
|
|
@ -230,10 +231,9 @@
|
||||||
"text": [
|
"text": [
|
||||||
"0\n",
|
"0\n",
|
||||||
"1\n",
|
"1\n",
|
||||||
|
"3\n",
|
||||||
"4\n",
|
"4\n",
|
||||||
"2\n",
|
"2\n",
|
||||||
"3\n",
|
|
||||||
"3\n",
|
|
||||||
"2\n"
|
"2\n"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
@ -243,7 +243,7 @@
|
||||||
"{'0', '1', '2', '3', '4'}"
|
"{'0', '1', '2', '3', '4'}"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"execution_count": 19,
|
"execution_count": 22,
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"output_type": "execute_result"
|
"output_type": "execute_result"
|
||||||
}
|
}
|
||||||
|
|
@ -272,7 +272,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 20,
|
"execution_count": 23,
|
||||||
"id": "9a5ea5cb",
|
"id": "9a5ea5cb",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
|
|
@ -358,7 +358,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 21,
|
"execution_count": 24,
|
||||||
"id": "32edf4d1",
|
"id": "32edf4d1",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
|
|
@ -383,7 +383,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 22,
|
"execution_count": 25,
|
||||||
"id": "48d20564",
|
"id": "48d20564",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
|
|
@ -391,40 +391,37 @@
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
|
"BFS\n",
|
||||||
"Путь найден:\n",
|
"Путь найден:\n",
|
||||||
"# # # # # # # # # # # # # # # # # # # #\n",
|
"#####################################\n",
|
||||||
"S. # # # #\n",
|
"#S #\n",
|
||||||
"#.# # # # # # # # # # # # #\n",
|
"#. #\n",
|
||||||
"#..... # # # # # # # # #\n",
|
"#. #\n",
|
||||||
"# #.# # # # # # # # # # # #\n",
|
"#. #\n",
|
||||||
"# #............. # # # # #\n",
|
"#. #\n",
|
||||||
"# # # # # # #. # # # # # # #\n",
|
"#. #\n",
|
||||||
"# # # # #..... # # # # #\n",
|
"#. #\n",
|
||||||
"# # # # # # #. # # # # #\n",
|
"#. #\n",
|
||||||
"# # # # #. # # # # #\n",
|
"#..................................E#\n",
|
||||||
"# # # # # # #. # # # # #\n",
|
"#####################################\n",
|
||||||
"# # # # #..... # # # #\n",
|
"time: 0.0008461000002171204 ms\n",
|
||||||
"# # # # # # # # #. # # # #\n",
|
"visited cells: 315\n",
|
||||||
"# # # # #. # # #\n",
|
"path length: 43\n"
|
||||||
"# # # # # # # # #. # # # # #\n",
|
|
||||||
"# # # # # # #. # # # #\n",
|
|
||||||
"# # # # # # #. # # # #\n",
|
|
||||||
"# # # # # # #. # # # #\n",
|
|
||||||
"# # # #...........E #\n",
|
|
||||||
"# # # # # # # # # # # # # # # # # # # #\n"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"source": [
|
"source": [
|
||||||
"maze2 = builder.buildFromFile(test_lab3)\n",
|
"maze2 = builder.buildFromFile(test_lab2)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"solver = MazeSolver(maze2, BFS(), ConsoleView())\n",
|
"solver = MazeSolver(maze2, BFS(), ConsoleView())\n",
|
||||||
"stats = solver.solve()"
|
"print(solver.strategyName())\n",
|
||||||
|
"stats = solver.solve()\n",
|
||||||
|
"stats.show()"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": 23,
|
"execution_count": 26,
|
||||||
"id": "bf13d5ba",
|
"id": "bf13d5ba",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [
|
"outputs": [
|
||||||
|
|
@ -432,27 +429,31 @@
|
||||||
"name": "stdout",
|
"name": "stdout",
|
||||||
"output_type": "stream",
|
"output_type": "stream",
|
||||||
"text": [
|
"text": [
|
||||||
|
"DFS\n",
|
||||||
"Путь найден:\n",
|
"Путь найден:\n",
|
||||||
"# # # # # # # # # # # # # # # # # # # #\n",
|
"####################\n",
|
||||||
"S.......# # # #\n",
|
"S...# # # #\n",
|
||||||
"# # # .# # # # # # # # # # #\n",
|
"###.# ### # ### # ##\n",
|
||||||
"#.......# # # # # # # # #\n",
|
"#...# # # # # # # ##\n",
|
||||||
"#. # # # # # # # # # # # # #\n",
|
"#.### # ### # ### ##\n",
|
||||||
"#...# ...........# # # # #\n",
|
"#.# .....# # # ##\n",
|
||||||
"# .# # #. # # # .# # # # # # #\n",
|
"#.###.###.### # # ##\n",
|
||||||
"#...# #...# # .....# # # # #\n",
|
"#.# #.# #...# # # ##\n",
|
||||||
"#. # # .# # # # .# # # # #\n",
|
"#.# #.# ###.# # # ##\n",
|
||||||
"#...# #...# #...# # # # #\n",
|
"#.# #.# #.# # # ##\n",
|
||||||
"# .# #. # # # #. # # # # #\n",
|
"#.# #.### #.# # # ##\n",
|
||||||
"#...# #..... # #.......# # # #\n",
|
"#.# #...# #...# # ##\n",
|
||||||
"#. # # # #...# # # # .# # # #\n",
|
"#.# ###.# ###.# # ##\n",
|
||||||
"#...#.......# .# #...# # #\n",
|
"#.# #.# #.# ##\n",
|
||||||
"# .#.# # .#...# # # #. # # # # #\n",
|
"#.### #.### #.### ##\n",
|
||||||
"#...#. #...#. # # #...# # # #\n",
|
"#.#...#.# # #.# # ##\n",
|
||||||
"#. #...#. #...# # # .# # # #\n",
|
"#.#.#.#.# # #.# # ##\n",
|
||||||
"#...# .#...# .# # # .# # # #\n",
|
"#.#.#.#.# # #.# # ##\n",
|
||||||
"# .....# .....# # .........E #\n",
|
"#...#...# #.....E#\n",
|
||||||
"# # # # # # # # # # # # # # # # # # # #\n"
|
"####################\n",
|
||||||
|
"time: 0.00014700000019729487 ms\n",
|
||||||
|
"visited cells: 83\n",
|
||||||
|
"path length: 76\n"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -460,13 +461,109 @@
|
||||||
"maze2 = builder.buildFromFile(test_lab3)\n",
|
"maze2 = builder.buildFromFile(test_lab3)\n",
|
||||||
"\n",
|
"\n",
|
||||||
"solver = MazeSolver(maze2, DFS(), ConsoleView())\n",
|
"solver = MazeSolver(maze2, DFS(), ConsoleView())\n",
|
||||||
"stats = solver.solve()"
|
"print(solver.strategyName())\n",
|
||||||
|
"stats = solver.solve()\n",
|
||||||
|
"stats.show()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 27,
|
||||||
|
"id": "9383cb75",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"Dijkstra\n",
|
||||||
|
"Путь найден:\n",
|
||||||
|
"####################\n",
|
||||||
|
"S...# # # #\n",
|
||||||
|
"###.# ### # ### # ##\n",
|
||||||
|
"#...# # # # # # # ##\n",
|
||||||
|
"#.### # ### # ### ##\n",
|
||||||
|
"#.# .....# # # ##\n",
|
||||||
|
"#.###.###.### # # ##\n",
|
||||||
|
"#.# #.# #...# # # ##\n",
|
||||||
|
"#.# #.# ###.# # # ##\n",
|
||||||
|
"#.# #.# #.# # # ##\n",
|
||||||
|
"#.# #.### #.# # # ##\n",
|
||||||
|
"#.# #...# #...# # ##\n",
|
||||||
|
"#.# ###.# ###.# # ##\n",
|
||||||
|
"#.# #.# #.# ##\n",
|
||||||
|
"#.### #.### #.### ##\n",
|
||||||
|
"#.#...#.# # #.# # ##\n",
|
||||||
|
"#.#.#.#.# # #.# # ##\n",
|
||||||
|
"#.#.#.#.# # #.# # ##\n",
|
||||||
|
"#...#...# #.....E#\n",
|
||||||
|
"####################\n",
|
||||||
|
"time: 0.00022080000007917988 ms\n",
|
||||||
|
"visited cells: 120\n",
|
||||||
|
"path length: 76\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"maze2 = builder.buildFromFile(test_lab3)\n",
|
||||||
|
"\n",
|
||||||
|
"solver = MazeSolver(maze2, Dijkstra(), ConsoleView())\n",
|
||||||
|
"print(solver.strategyName())\n",
|
||||||
|
"stats = solver.solve()\n",
|
||||||
|
"stats.show()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 28,
|
||||||
|
"id": "835cff61",
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"A*\n",
|
||||||
|
"Путь найден:\n",
|
||||||
|
"####################\n",
|
||||||
|
"S...# # # #\n",
|
||||||
|
"###.# ### # ### # ##\n",
|
||||||
|
"#...# # # # # # # ##\n",
|
||||||
|
"#.### # ### # ### ##\n",
|
||||||
|
"#.# .....# # # ##\n",
|
||||||
|
"#.###.###.### # # ##\n",
|
||||||
|
"#.# #.# #...# # # ##\n",
|
||||||
|
"#.# #.# ###.# # # ##\n",
|
||||||
|
"#.# #.# #.# # # ##\n",
|
||||||
|
"#.# #.### #.# # # ##\n",
|
||||||
|
"#.# #...# #...# # ##\n",
|
||||||
|
"#.# ###.# ###.# # ##\n",
|
||||||
|
"#.# #.# #.# ##\n",
|
||||||
|
"#.### #.### #.### ##\n",
|
||||||
|
"#.#...#.# # #.# # ##\n",
|
||||||
|
"#.#.#.#.# # #.# # ##\n",
|
||||||
|
"#.#.#.#.# # #.# # ##\n",
|
||||||
|
"#...#...# #.....E#\n",
|
||||||
|
"####################\n",
|
||||||
|
"time: 0.00025749999986146577 ms\n",
|
||||||
|
"visited cells: 92\n",
|
||||||
|
"path length: 76\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"maze2 = builder.buildFromFile(test_lab3)\n",
|
||||||
|
"\n",
|
||||||
|
"solver = MazeSolver(maze2, AStar(), ConsoleView())\n",
|
||||||
|
"print(solver.strategyName())\n",
|
||||||
|
"stats = solver.solve()\n",
|
||||||
|
"stats.show()"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cell_type": "code",
|
"cell_type": "code",
|
||||||
"execution_count": null,
|
"execution_count": null,
|
||||||
"id": "9383cb75",
|
"id": "2d84a151",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": []
|
"source": []
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user