Acknowledgments | xix |
Introduction | xxi |
Who Is This Book For? | xxii |
What's in This Book? | xxii |
What's New to the Second Edition? | xxiii |
Why Python? | xxiv |
The Code in This Book | xxvi |
Part I Warming Up | 1 |
1 The Koch Snowflake | 3 |
How It Works | 4 |
Using Recursion | 4 |
Computing the Snowflake | 5 |
Drawing with turtle Graphics | 9 |
Requirements | 11 |
The Code | 11 |
Calculating the Points | 11 |
Recursing | 12 |
Drawing a Flake | 13 |
Writing the main() Function | 13 |
Running the Snowflake Code | 14 |
Summary | 15 |
Experiments! | 15 |
The Complete Code | 16 |
2 Spirographs | 19 |
How It Works | 20 |
Understanding Parametric Equations | 20 |
Drawing Curves with turtle Graphics | 24 |
Requirements | 25 |
The Code | 25 |
Drawing the Spiros | 25 |
Coordinating the Animation | 29 |
Saving the Curves | 32 |
Parsing Command Line Arguments and Initialization | 33 |
Running the Spirograph Animation | 34 |
Summary | 36 |
Experiments! | 36 |
The Complete Code | 36 |
Part II Simulating Life | 43 |
3 Conway's Game of Life | 45 |
How It Works | 46 |
Requirements | 48 |
The Code | 49 |
Representing the Grid | 49 |
Setting the Initial Conditions | 50 |
Enforcing the Boundary Conditions | 51 |
Implementing the Rules | 51 |
Sending Command Line Arguments to the Program | 52 |
Initializing the Simulation | 53 |
Running the Game of Life Simulation | 54 |
Summary | 55 |
Experiments! | 55 |
The Complete Code | 56 |
4 Musical Overtones with Karplus-Strong | 59 |
How It Works | 62 |
The Simulation | 62 |
The WAV File Format | 64 |
The Minor Pentatonic Scale | 65 |
Requirements | 66 |
The Code | 66 |
Implementing the Ring Buffer with deque | 66 |
Implementing the Karplus-Strong Algorithm | 67 |
Writing a WAV File | 69 |
Playing WAV Files with pyaudio | 69 |
Creating Notes and Parsing Arguments | 71 |
Running the Plucked String Simulation | 73 |
Summary | 74 |
Experiments! | 74 |
The Complete Code | 74 |
5 Flocking Boids | 79 |
How It Works | 80 |
Requirements | 80 |
The Code | 81 |
Initializing the Simulation | 81 |
Setting Boundary Conditions | 83 |
Drawing a Boid | 84 |
Applying the Rules of the Boids | 86 |
Influencing the Simulation | 91 |
Incrementing the Simulation | 92 |
Parsing Arguments and Instantiating the Boids | 94 |
Running the Boids Simulation | 94 |
Summary | 95 |
Experiments! | 95 |
The Complete Code | 96 |
Part III Fun with Images | 99 |
6 ASCII Art | 101 |
How It Works | 102 |
Requirements | 104 |
The Code | 104 |
Defining the Grayscale Levels and Grid | 104 |
Computing the Average Brightness | 105 |
Generating the ASCII Content from the Image | 106 |
Creating Command Line Options | 107 |
Writing the ASCII Art Strings to a Text File | 107 |
Running the ASCII Art Generator | 108 |
Summary | 108 |
Experiments! | 108 |
The Complete Code | 109 |
7 Photomosaics | 113 |
How If Works | 114 |
Splitting the Target Image | 115 |
Averaging Color Values | 115 |
Matching Images | 116 |
Requirements | 119 |
The Code | 119 |
Reading In the Input Images | 119 |
Calculating the Average Color Value of an Image | 120 |
Splitting the Target Image into a Grid | 120 |
Finding the Best Match for a Tile | 121 |
Creating an Image Grid | 123 |
Creating the Photomosaic | 124 |
Writing the main() Function | 126 |
Running the Photomosaic Generator | 127 |
Summary | 129 |
Experiments! | 129 |
The Complete Code | 129 |
8 Autostereograms | 135 |
Haw It Works | 136 |
Perceiving Depth in an Autostereogram | 137 |
Working with Depth Maps | 138 |
Shifting Pixels | 140 |
Requirements | 141 |
The Code | 141 |
Creating a Tile from Random Circles | 142 |
Repeating a Given Tile | 143 |
Creating Autostereograms | 144 |
Providing Command Line Options | 145 |
Running the Autostereogram Generator | 146 |
Summary | 147 |
Experiments! | 147 |
The Complete Code | 147 |
Part IV Enter 3D | 151 |
9 Understanding Opengl | 153 |
How OpenGL Works | 154 |
Geometric Primitives | 155 |
3D Transformations | 156 |
Shaders | 158 |
Vertex Buffers | 160 |
Texture Mapping | 160 |
The OpenGL Context | 161 |
Requirements | 162 |
The Code | 162 |
The Render Window Class | 162 |
The Scene Class | 165 |
Utility Functions | 170 |
Running the OpenGL Application | 171 |
Summary | 171 |
Experiments! | 171 |
The Complete Code | 172 |
10 Conway's Game of Life on a Torus | 179 |
How It Works | 180 |
Computing Vertices | 180 |
Computing Normals for Lighting | 183 |
Rendering | 183 |
Coloring the Triangle Strips | 185 |
Controlling the Camera | 185 |
Mapping the Grid to the Torus | 187 |
Requirements | 187 |
The Code | 188 |
Rendering the Torus | 188 |
Implementing the Game of Life Simulation | 196 |
Creating the Camera | 197 |
Putting Everything Together | 198 |
Running the 3D Game of Life Simulation | 201 |
Summary | 203 |
Experiments! | 203 |
The Complete Torus Rendering Code | 203 |
The Complete Game of Life Simulation Code | 209 |
The Complete Camera Code | 211 |
The Complete RenderWindow Code | 211 |
11 Volume Rendering | 215 |
How It Works | 216 |
The Data Format | 217 |
Ray Generation | 217 |
The OpenGL Window | 220 |
Requirements | 220 |
The Code | 221 |
Generating a 3D Texture | 221 |
Generating Rays | 223 |
Implementing the Ray Casting Algorithm | 229 |
Showing 2D Slices | 233 |
Putting the Code Together | 238 |
Running the Program | 239 |
Summary | 240 |
Experiments! | 240 |
The Complete 3D Texture Code | 241 |
The Complete Ray Generation Code | 242 |
The Complete Volume Ray Casting Code | 248 |
The Complete 2D Slicing Code | 251 |
The Complete Main File Code | 254 |
Part V Hardware Hacking | 257 |
12 Karplus-Strong on a Raspberry Pi Pico | 259 |
How It Works | 260 |
Input and Output | 261 |
The 12S Protocol | 262 |
Requirements | 263 |
Hardware Setup | 263 |
MicroPython Setup | 266 |
The Code | 266 |
Setting Up | 266 |
Generating the Notes | 267 |
Playing a Note | 269 |
Writing the main() Function | 270 |
Running the Pico Code | 272 |
Summary | 273 |
Experiments! | 273 |
The Complete Code | 275 |
13 Laser Audio Display with a Raspberry Pi | 279 |
How It Works | 280 |
Generating Patterns with a Laser | 281 |
Analyzing Audio with the Fast Fourier Transform | 286 |
Requirements | 288 |
Setting Up the Raspberry Pi | 289 |
Constructing the Laser Display | 289 |
Hooking Up the Hardware | 291 |
The Code | 293 |
Setting Up | 293 |
Controlling the Hardware | 294 |
Processing the Audio | 296 |
Testing the Motors | 300 |
Putting It All Together | 301 |
Running the Laser Display | 302 |
Summary | 303 |
Experiments! | 304 |
The Complete Code | 305 |
14 IOT Garden | 311 |
How It Works | 312 |
Bluetooth Low Energy | 313 |
The Bottle Web Framework | 315 |
The SQLite Database | 316 |
Requirements | 317 |
Raspberry Pi Setup | 318 |
CircuitPython Setup | 318 |
If This Then That Setup | 319 |
The Code | 320 |
The CircuitPython Code | 321 |
The BLE Scanner Code | 325 |
The Web Server Code | 331 |
The Main Program File | 339 |
Running the IoT Garden | 341 |
Summary | 343 |
Experiments! | 343 |
The Complete CircuitPython Code | 343 |
The Complete BLE Scanner Code | 345 |
The Complete Python Web Server Code | 349 |
The Complete Main Program Code | 351 |
15 Audio ML on PI | 355 |
A Machine Learning Overview | 356 |
How It Works | 358 |
Spectrograms | 359 |
Inference on the Raspberry Pi | 362 |
Requirements | 364 |
The Code | 365 |
Training the Model in Google Colab | 365 |
Using the Model on the Raspberry Pi | 376 |
Running the Speech Recognition System | 386 |
Summary | 388 |
Experiments! | 388 |
The Complete Code | 389 |
A Python Installation | 395 |
Installing Source Code for the Book's Projects | 395 |
Installing Python and Python Modules | 396 |
Windows | 396 |
MacOS | 397 |
Linux | 397 |
B Raspberry Pi Setup | 399 |
Setting Up the Software | 402 |
Testing Your Connection | 402 |
Logging in to Your Pi with SSH | 404 |
Installing Python Modules | 404 |
Working Remotely with Visual Studio Code | 404 |
Index | 405 |