|
| https://realpython.com/ |
| Start Here | https://realpython.com/start-here/ |
|
Learn Python
| https://realpython.com/lessons/build-python-maze/ |
| Your Learning Plan →Your personalized Python learning plan | https://realpython.com/account/learning-plan/ |
| Python Tutorials →In-depth articles and video courses | https://realpython.com/search?kind=article&kind=course&order=newest&_from=nav_library |
| Learning Paths →Guided study plans for accelerated learning | https://realpython.com/learning-paths/ |
| Quizzes & Exercises →Check your learning progress | https://realpython.com/search?kind=exercise&kind=quiz&_from=nav_library |
| Browse Topics →Focus on a specific area or skill level | https://realpython.com/tutorials/all/ |
| Reference →Concise definitions for common Python terms | https://realpython.com/ref/ |
| Mentor AI →NewYour personal Python mentor | https://realpython.com/mentor/ |
| Office Hours →Live Q&A calls with Python experts | https://realpython.com/office-hours/ |
| Community Chat →Learn with other Pythonistas | https://realpython.com/community/ |
| Live Courses →Live, instructor-led Python courses | https://realpython.com/live/ |
| Books →Round out your knowledge and learn offline | https://realpython.com/products/books/ |
| Podcast →Hear what’s new in the world of Python | https://realpython.com/podcasts/rpp/ |
| Unlock All Content and Become a Python Expert →Get unlimited access to all Real Python has to offer | https://realpython.com/account/join/?from=navbar_learn |
| Unlock All Content →Become a Python Expert | https://realpython.com/account/join/?from=navbar_learn |
|
More
| https://realpython.com/lessons/build-python-maze/ |
| Learner Stories | https://realpython.com/learner-stories/ |
| Python Newsletter | https://realpython.com/newsletter/ |
| Python Job Board | https://www.pythonjobshq.com |
| Meet the Team | https://realpython.com/team/ |
| Become a Contributor | https://realpython.com/jobs/ |
| Search | https://realpython.com/search |
| https://realpython.com/search |
| Join | https://realpython.com/account/join/ |
| Sign‑In | https://realpython.com/account/login/?intent=navbar&next=%2Flessons%2Fbuild-python-maze%2F |
| Unlock This Lesson | https://realpython.com/account/join/?utm_source=rp_lesson&utm_content=python-maze-solver |
| Unlock This Lesson | https://realpython.com/account/join/?utm_source=rp_lesson&utm_content=python-maze-solver |
|
| https://realpython.com/courses/python-maze-solver/#team |
| Mazes in Python: Build, Visualize, Store, and Solve | https://realpython.com/courses/python-maze-solver/ |
| Darren Jones | https://realpython.com/courses/python-maze-solver/#team |
| Recommended Tutorial | https://realpython.com/python-maze-solver/ |
| Course Slides (.pdf) | https://realpython.com/courses/python-maze-solver/downloads/mazes-in-python-slides/ |
| Sample Code (.zip) | https://realpython.com/courses/python-maze-solver/downloads/mazes-in-python-code/ |
| Ask a Question | https://realpython.com/lessons/build-python-maze/#discussion |
| https://realpython.com/feedback/survey/course/python-maze-solver/liked/?from=lesson-title |
| https://realpython.com/feedback/survey/course/python-maze-solver/disliked/?from=lesson-title |
| Contents | https://realpython.com/lessons/build-python-maze/#description |
| Transcript | https://realpython.com/lessons/build-python-maze/#transcript |
| Discussion (2) | https://realpython.com/lessons/build-python-maze/#discussion |
| 00:00 | https://realpython.com/lessons/build-python-maze/#t=0.79 |
| Building the maze. | https://realpython.com/lessons/build-python-maze/#t=0.79 |
| At the very core, | https://realpython.com/lessons/build-python-maze/#t=2.931 |
| a maze is an ordered collection of squares, | https://realpython.com/lessons/build-python-maze/#t=5.28 |
| which you can represent with a Python tuple. | https://realpython.com/lessons/build-python-maze/#t=7.37 |
| However, | https://realpython.com/lessons/build-python-maze/#t=10.262 |
| you’ll eventually want to augment your maze model with additional properties and | https://realpython.com/lessons/build-python-maze/#t=11.02 |
| methods, | https://realpython.com/lessons/build-python-maze/#t=14.56 |
| so it makes sense to wrap the sequence of squares in a custom class right away. | https://realpython.com/lessons/build-python-maze/#t=15.18 |
| 00:21 | https://realpython.com/lessons/build-python-maze/#t=21.73 |
| Enter the code seen on-screen into the maze module. | https://realpython.com/lessons/build-python-maze/#t=21.73 |
| 00:34 | https://realpython.com/lessons/build-python-maze/#t=34.12 |
| Here, | https://realpython.com/lessons/build-python-maze/#t=34.12 |
| you use an immutable data class again to ensure that the underlying tuple of | https://realpython.com/lessons/build-python-maze/#t=34.59 |
| Square objects remains unchanged once assigned. | https://realpython.com/lessons/build-python-maze/#t=38.41 |
| You might be inclined to use a Python list instead of a tuple to keep your | https://realpython.com/lessons/build-python-maze/#t=42.49 |
| squares, | https://realpython.com/lessons/build-python-maze/#t=45.79 |
| but that would prevent you from caching partial results of your computations | https://realpython.com/lessons/build-python-maze/#t=46.53 |
| later. | https://realpython.com/lessons/build-python-maze/#t=49.84 |
| 00:50 | https://realpython.com/lessons/build-python-maze/#t=50.663 |
| Python’s | https://realpython.com/lessons/build-python-maze/#t=50.663 |
| cache requires memoized function arguments to be hashable and therefore | https://realpython.com/lessons/build-python-maze/#t=51.96 |
| immutable. | https://realpython.com/lessons/build-python-maze/#t=56.15 |
| To avoid the extra work when looping over the squares or when | https://realpython.com/lessons/build-python-maze/#t=56.762 |
| accessing one of them by index, | https://realpython.com/lessons/build-python-maze/#t=60.21 |
| you can make your class iterable and subscriptable by implementing these two | https://realpython.com/lessons/build-python-maze/#t=62.19 |
| special methods. | https://realpython.com/lessons/build-python-maze/#t=66.37 |
| 01:15 | https://realpython.com/lessons/build-python-maze/#t=75.87 |
| This method lets Maze instances cooperate with a for loop, | https://realpython.com/lessons/build-python-maze/#t=75.87 |
| while the second one enables square bracket notation for getting squares by | https://realpython.com/lessons/build-python-maze/#t=84.63 |
| index. | https://realpython.com/lessons/build-python-maze/#t=88.63 |
| 01:35 | https://realpython.com/lessons/build-python-maze/#t=95.16 |
| Next, | https://realpython.com/lessons/build-python-maze/#t=95.16 |
| you might want to calculate the width and height of the maze, knowing the column | https://realpython.com/lessons/build-python-maze/#t=95.67 |
| and row indices of the underlying squares. | https://realpython.com/lessons/build-python-maze/#t=99.11 |
| 01:54 | https://realpython.com/lessons/build-python-maze/#t=114.42 |
| You take advantage of the iterable nature of the maze by iterating over it to | https://realpython.com/lessons/build-python-maze/#t=114.42 |
| find the maximum column and row index of its squares | https://realpython.com/lessons/build-python-maze/#t=118.16 |
| with the help of the max() function. | https://realpython.com/lessons/build-python-maze/#t=120.92 |
| 02:03 | https://realpython.com/lessons/build-python-maze/#t=123.32 |
| Adding 1 to the highest index accounts for the zero-based numbering of tuple | https://realpython.com/lessons/build-python-maze/#t=123.32 |
| indices. | https://realpython.com/lessons/build-python-maze/#t=127.53 |
| Because looping is a relatively expensive operation, | https://realpython.com/lessons/build-python-maze/#t=128.205 |
| you cache the return values with functools.cached_property instead of using the | https://realpython.com/lessons/build-python-maze/#t=132.48 |
| built-in @property decorator. | https://realpython.com/lessons/build-python-maze/#t=136.9 |
| 02:19 | https://realpython.com/lessons/build-python-maze/#t=139.426 |
| As a result, | https://realpython.com/lessons/build-python-maze/#t=139.426 |
| the width and height are computed only once on demand, | https://realpython.com/lessons/build-python-maze/#t=140.45 |
| while their subsequent invocations will return the cached value. | https://realpython.com/lessons/build-python-maze/#t=143.72 |
| The benefit of calculating the maze size by hand is data consistency. | https://realpython.com/lessons/build-python-maze/#t=151.48 |
| 02:36 | https://realpython.com/lessons/build-python-maze/#t=156.04 |
| If you supplied the width and height through two extra parameters in the class, | https://realpython.com/lessons/build-python-maze/#t=156.04 |
| then there would be no guarantee that the rows and columns would match up with | https://realpython.com/lessons/build-python-maze/#t=159.53 |
| the flat index. | https://realpython.com/lessons/build-python-maze/#t=163.24 |
| 02:45 | https://realpython.com/lessons/build-python-maze/#t=165.04 |
| So inferring the size from the squares avoids this potential problem. | https://realpython.com/lessons/build-python-maze/#t=165.04 |
| Speaking of consistency, | https://realpython.com/lessons/build-python-maze/#t=170.99 |
| you can also include the validation of the maze by looping over it again when | https://realpython.com/lessons/build-python-maze/#t=172.65 |
| it’s created to make sure that its squares have the the expected rows and | https://realpython.com/lessons/build-python-maze/#t=176.27 |
| columns with matching indices. | https://realpython.com/lessons/build-python-maze/#t=180.12 |
| 03:03 | https://realpython.com/lessons/build-python-maze/#t=183.278 |
| To do that, | https://realpython.com/lessons/build-python-maze/#t=183.278 |
| you’ll leverage the special method .__post_init__() to hook into the | https://realpython.com/lessons/build-python-maze/#t=184.56 |
| initialization process of the data class. | https://realpython.com/lessons/build-python-maze/#t=188.82 |
| 03:28 | https://realpython.com/lessons/build-python-maze/#t=208.26 |
| The first function checks whether the .index property of each square fits into a | https://realpython.com/lessons/build-python-maze/#t=208.26 |
| continuous sequence of numbers that enumerates all the squares in the maze. | https://realpython.com/lessons/build-python-maze/#t=211.92 |
| 03:47 | https://realpython.com/lessons/build-python-maze/#t=227.18 |
| The second function iterates over the rows and columns in the maze, | https://realpython.com/lessons/build-python-maze/#t=227.18 |
| and this ensures that the .row and .column attributes of the corresponding square | https://realpython.com/lessons/build-python-maze/#t=230.66 |
| match up with the current row and column of the loops. | https://realpython.com/lessons/build-python-maze/#t=234.37 |
| 03:57 | https://realpython.com/lessons/build-python-maze/#t=237.822 |
| Watch out for proper | https://realpython.com/lessons/build-python-maze/#t=237.822 |
| indentation of these functions, as they don’t belong in the class body. | https://realpython.com/lessons/build-python-maze/#t=239.14 |
| Both validation functions rely on the assert statement to raise the AssertionError | https://realpython.com/lessons/build-python-maze/#t=245.69 |
| and prevent the maze from being created in the case of invalid data. | https://realpython.com/lessons/build-python-maze/#t=249.98 |
| 04:17 | https://realpython.com/lessons/build-python-maze/#t=257.91 |
| Earlier, you decided that a maze must have an entrance and an exit, | https://realpython.com/lessons/build-python-maze/#t=257.91 |
| so it’s worth confirming that it has both. | https://realpython.com/lessons/build-python-maze/#t=262.06 |
| Go ahead and add two more validation functions. | https://realpython.com/lessons/build-python-maze/#t=264.66 |
| 04:32 | https://realpython.com/lessons/build-python-maze/#t=272.23 |
| First Role is imported, as this will be needed in the new validation functions. | https://realpython.com/lessons/build-python-maze/#t=272.23 |
| Then the validation functions are added to the .__post_init__() method. | https://realpython.com/lessons/build-python-maze/#t=277.8 |
| 04:47 | https://realpython.com/lessons/build-python-maze/#t=287.27 |
| Finally, the functions are added to the bottom of the file. | https://realpython.com/lessons/build-python-maze/#t=287.27 |
| These count the number of squares whose role is either ENTRANCE or EXIT | https://realpython.com/lessons/build-python-maze/#t=293.51 |
| and verify that there’s exactly one of each. | https://realpython.com/lessons/build-python-maze/#t=297.12 |
| 05:28 | https://realpython.com/lessons/build-python-maze/#t=328.06 |
| For your convenience, | https://realpython.com/lessons/build-python-maze/#t=328.06 |
| you might as well implement the relevant properties that will return squares | https://realpython.com/lessons/build-python-maze/#t=329.18 |
| with those special roles. | https://realpython.com/lessons/build-python-maze/#t=332.52 |
| 05:47 | https://realpython.com/lessons/build-python-maze/#t=347.13 |
| This code calls next() on a generator expression that filters the squares by their | https://realpython.com/lessons/build-python-maze/#t=347.13 |
| role. | https://realpython.com/lessons/build-python-maze/#t=351.41 |
| Because you already validated them, | https://realpython.com/lessons/build-python-maze/#t=351.786 |
| you can safely assume that the appropriate squares exist in the maze, | https://realpython.com/lessons/build-python-maze/#t=354.26 |
| and next() won’t raise any exception. | https://realpython.com/lessons/build-python-maze/#t=358.1 |
| 06:07 | https://realpython.com/lessons/build-python-maze/#t=367.36 |
| At long last, | https://realpython.com/lessons/build-python-maze/#t=367.36 |
| you can finally build your first maze using the building blocks defined earlier. | https://realpython.com/lessons/build-python-maze/#t=368.44 |
| This maze will be needed a number of times in this course, | https://realpython.com/lessons/build-python-maze/#t=373.21 |
| so to save having to type it out multiple times in a REPL session, | https://realpython.com/lessons/build-python-maze/#t=375.96 |
| you’ll put it inside the mazes/ directory at the top level of the project, at the | https://realpython.com/lessons/build-python-maze/#t=379.24 |
| same level as the src/ folder. | https://realpython.com/lessons/build-python-maze/#t=383.98 |
| 06:28 | https://realpython.com/lessons/build-python-maze/#t=388.2 |
| This will keep you out to the way of the main project, | https://realpython.com/lessons/build-python-maze/#t=388.2 |
| but it will mean you’ll need to start your REPL session at that level later on | https://realpython.com/lessons/build-python-maze/#t=390.47 |
| when you want to import it. | https://realpython.com/lessons/build-python-maze/#t=394.28 |
| 06:58 | https://realpython.com/lessons/build-python-maze/#t=418.77 |
| This sample maze has twelve squares with ten unique border patterns, arranged in three | https://realpython.com/lessons/build-python-maze/#t=418.77 |
| rows and four columns. | https://realpython.com/lessons/build-python-maze/#t=423.37 |
| The entrance to the maze is located in the bottom-left corner, while the exit is | https://realpython.com/lessons/build-python-maze/#t=425.77 |
| in the first row, slightly to the right. | https://realpython.com/lessons/build-python-maze/#t=429.91 |
| 07:12 | https://realpython.com/lessons/build-python-maze/#t=432.84 |
| These squares are created at index two and eight. | https://realpython.com/lessons/build-python-maze/#t=432.84 |
| 08:16 | https://realpython.com/lessons/build-python-maze/#t=496.1 |
| Being able to visualize the final result just by looking at the code is quite a | https://realpython.com/lessons/build-python-maze/#t=496.1 |
| niche skill. | https://realpython.com/lessons/build-python-maze/#t=500.29 |
| So, on-screen you can see what the maze would look like. | https://realpython.com/lessons/build-python-maze/#t=500.914 |
| It may not be a masterpiece, | https://realpython.com/lessons/build-python-maze/#t=504.72 |
| but having a small dataset sample to work with is beneficial for several | https://realpython.com/lessons/build-python-maze/#t=506.14 |
| reasons. | https://realpython.com/lessons/build-python-maze/#t=509.89 |
| 08:30 | https://realpython.com/lessons/build-python-maze/#t=510.448 |
| When something doesn’t work as expected, | https://realpython.com/lessons/build-python-maze/#t=510.448 |
| you’ll be able to spot the problem much quicker. | https://realpython.com/lessons/build-python-maze/#t=513.25 |
| You’ll also have a better understanding of the underlying concepts, allowing you | https://realpython.com/lessons/build-python-maze/#t=516.33 |
| to debug code more efficiently. | https://realpython.com/lessons/build-python-maze/#t=520.07 |
| 08:42 | https://realpython.com/lessons/build-python-maze/#t=522.724 |
| Finally, | https://realpython.com/lessons/build-python-maze/#t=522.724 |
| because there’s little data to process, | https://realpython.com/lessons/build-python-maze/#t=523.58 |
| you’ll spend a lot less time waiting for the results in your development cycle. | https://realpython.com/lessons/build-python-maze/#t=525.69 |
| So far, | https://realpython.com/lessons/build-python-maze/#t=532.25 |
| you’ve identified the building blocks of the maze and implemented them in | https://realpython.com/lessons/build-python-maze/#t=532.67 |
| Python, but now you can build a maze, | https://realpython.com/lessons/build-python-maze/#t=535.91 |
| the next step will be to figure out how to display it in a graphical form, | https://realpython.com/lessons/build-python-maze/#t=538.61 |
| and that’s what you’ll be doing in the next section of the course. | https://realpython.com/lessons/build-python-maze/#t=542.41 |
| July 23, 2023 | https://realpython.com/lessons/build-python-maze/#comment-e9898014-063d-4eac-a73a-1fab2d0de04b |
| Aug. 7, 2023 | https://realpython.com/lessons/build-python-maze/#comment-e94fe249-79bb-4805-8c83-37876e7a3833 |
| separation of concerns | https://en.wikipedia.org/wiki/Separation_of_concerns |
| Become a Member | https://realpython.com/account/join/ |
| https://realpython.com/lessons/model-python-maze-square/ |
| Overview | https://realpython.com/courses/python-maze-solver/ |
| https://realpython.com/lessons/python-maze-svg/ |
|
Mazes in Python: Build and Visualize 02:47
| https://realpython.com/videos/python-maze-solver-part-1-overview/ |
|
Check Out What You'll Make 02:39
| https://realpython.com/videos/python-maze-solver-project/ |
|
Lay the Groundwork 04:02
| https://realpython.com/videos/python-maze-solver-groundwork/ |
|
Scaffold the Project Structure 04:50
| https://realpython.com/lessons/python-maze-solver-structure/ |
|
Represent the Maze With Objects 06:37
| https://realpython.com/lessons/represent-maze-with-objects/ |
|
Create Border Patterns 06:32
| https://realpython.com/lessons/python-maze-border-patterns/ |
|
Model the Square 02:25
| https://realpython.com/lessons/model-python-maze-square/ |
|
Build the Maze 09:07
| https://realpython.com/lessons/build-python-maze/ |
|
Visualize the Maze With SVG 04:45
| https://realpython.com/lessons/python-maze-svg/ |
|
Implement Geometric Primitives 04:48
| https://realpython.com/lessons/python-maze-geometric-primitives/ |
|
Add More Primitives 03:47
| https://realpython.com/lessons/python-maze-more-primitives/ |
|
Decompose the Border Into Primitives 04:41
| https://realpython.com/lessons/decompose-python-maze-border/ |
|
Add More Border Patterns 03:58
| https://realpython.com/lessons/python-maze-more-border-patterns/ |
|
Build the SVG Renderer 03:49
| https://realpython.com/lessons/python-maze-svg-renderer/ |
|
Add Features to the Renderer 06:50
| https://realpython.com/lessons/python-maze-renderer-features/ |
|
Draw the Solution 03:13
| https://realpython.com/lessons/draw-python-maze-solution/ |
|
Preview the Rendered Maze and Its Solution 04:56
| https://realpython.com/lessons/preview-python-maze/ |
|
Mazes in Python: Build and Visualize (Recap) 01:14
| https://realpython.com/lessons/python-maze-solver-part-1-summary/ |
|
Mazes in Python: Store and Solve 01:48
| https://realpython.com/videos/python-maze-solver-part-2-overview/ |
|
Load the Maze From a Binary File 04:55
| https://realpython.com/videos/python-maze-binary-file/ |
|
Choose Your Data Alignment 05:09
| https://realpython.com/videos/python-maze-data-alignment/ |
|
Define the File Header and Body 08:12
| https://realpython.com/lessons/python-maze-file-header-and-body/ |
|
Serialize the Maze 05:22
| https://realpython.com/lessons/serialize-python-maze/ |
|
Deserialize the Maze 04:32
| https://realpython.com/lessons/deserialize-python-maze/ |
|
Make the Maze Self-Contained 04:30
| https://realpython.com/lessons/python-self-contained-maze/ |
|
Update the Maze Class 03:16
| https://realpython.com/lessons/python-maze-class/ |
|
Solve the Maze Using a Graph-Based Approach 03:01
| https://realpython.com/lessons/solve-python-maze-graph-based/ |
|
Transform the Maze Into a Graph 07:06
| https://realpython.com/lessons/transform-python-maze-graph/ |
|
Find the Shortest Path 05:23
| https://realpython.com/lessons/python-maze-shortest-path/ |
|
Add Weights to Graph Edges 02:36
| https://realpython.com/lessons/python-map-weights-graph-edges/ |
|
Introduce Enemies and Rewards 06:04
| https://realpython.com/lessons/python-maze-enemies-rewards/ |
|
Make a Runnable Script 03:59
| https://realpython.com/lessons/python-maze-runnable-script/ |
|
Mazes in Python: Store and Solve (Recap) 01:23
| https://realpython.com/lessons/python-maze-solver-part-2-summary/ |
| Privacy Policy | https://realpython.com/privacy-policy/ |
Viewport: width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover