 Hi a pretty big crowd for an art doc. So I'm already happy. This is games of life talk about generative art in Python My name is Wukash. I come from the internet. No, actually from Paul's night. It's not very far. I literally drove here I work as a CPython developer in residence meaning I literally work on Python as a my day job So thanks for the PSF for making that happen and thanks to meta for actually sponsoring me Uh, yeah, we're actually having an open position right now called the deputy developer in residence So if you want to hear more about this just look at our job listings It's or just talk to me at the rest of the conference like we're trying to hire another person to do what I am doing So, uh, please come and apply So I usually do like two kinds of talks right like the most popular talks that you know I give are usually that the kind of deeply technical ones where there's like, you know, typing generics or async IO You know and this sort of thing and the other kind that I like because I just like those topics are those kind of meditative talks where nobody asks me to do things like fm synthesis in python or Medi sequencing or whatever But I just feel better knowing that I did this and you know, I was just always curious to do this So this talk is this latter kind right like it's uh, it's going to be a talk where This is not bringing bread to my table. It's just something I was always curious about and I feel like, you know A lot of joy just playing with So to be clear this is going to be code that we are generating We're not going to be using large models pre-generated with uh tens of Millions of dollars of equipment and so on and so on so even though it's definitely fun to use them And you know, I myself i'm pretty curious about them This is not going to be about it. But like just to get it out of the way Here's a friend of mine david. We could turn it into, you know, tanos You know, we could turn him into God of war or we could turn him into the vocalist of the smashing pumpkins Right. So like, you know, all of those things like are definitely possible today You know, I just did this on my computer like, you know, like a few days back just to show you that this is possible But no what we're going to be talking about today Is something where we can actually see the code and it's very small. It is surprisingly small It is in fact deceptively small But the result kind of looks like it is doing something complex like it is a little bit alive, right and What's that's called its emergence, right? So it's you know, when you have properties or behaviors of an entity that its parts do not have on their own And what better place to introduce this concept in Prague where johannes kepler started his scientific, you know, journey And discover that okay, we actually have planets, uh, you know Traveling on orbits and those orbits are not circular and they're not uh ovals. They're in fact ellipses, right? So everybody knows this now like it was not, you know, very obvious back then So he discovered this but what I discovered really recently is that oh really earth Is not really our ellipses the system of Earth and its moon is an ellipses over the sun But the earth itself due to the moon existing has little squiggles in its orbit So I never knew about this obviously those are, you know, vastly exaggerated so you can see what I'm talking about but, uh Just just this was already like more complex than I Actually anticipated, you know, you kind of learn at school, you know, this is the orbit. Those are the planets. This is Jupiter So I never expected this and when I Searched for books to read during covet where you know, there was nothing else to do I found this great series by luci shin Where the first book is called the three-body problem where literally it's about, you know What would happen if there were three objects of similar mass actually interacting? With one another gravitationally and he poses well the that the orbits then like are no longer very simple They're indistinguishable from a totally chaotic system. So I was like, okay python Tell me how they look like and python is like Here's how they look like and am I okay? This is a little informative But I still You know, I still cannot Figure out like how it would feel to be on one of those planets So what I did is just to generate an animation that would show me like, you know, how they interact and obviously Pablo Galindo my friend who is an actual physicist was really quick to say like This is not actually how this would go, you know, uh in actual physics But it's close enough for me to be able to just you know notice like all those interactions between those three objects are in fact pretty chaotic and uh Complex so I did a bunch of this, uh, you know back in what it was a 2021. I guess Um, I like this and that's just math blood libs So, you know, I could tell you about like all the derivatives there that I played with and whatnot But honestly not that very interesting, uh, you know for the context of the stock Just saying this is how I started actually playing with uh, kind of, you know, this sort of topic Um pretty pretty um in my case. Oh well in my opinion at least So yeah, let's leave the derivatives. Let's leave the theory here Let's just say how did I make this animate? Well, it turns out that math blood libs allows you to do this very easily Which I was very happy to discover The only thing you have to do is create a funk animation object for which you give a callback That generates each frame, but it will even, you know, connect the frames together You don't have to use any ffm pack directly. You don't have to do anything Magical to get an mp4 file that you can play on the browser You can play on your Mac. So I was very happy about this. Uh, yeah, and that's that's essentially the kind of thing that we're going to be talking about today. So, uh, There's going to be a lot of code. I don't expect you to, you know, write the code down today In fact, the code lives on github. You can get the link later I don't want you to look at it right now either because you're going to be looking at me And I like when you look at me. So, uh, let's just start with talking and then I'm going to give you the link. Okay, the fair deal So the kind of most simple and maybe even like over talked and over researched system that has this emergent behavior is Conway's game of life But I would still want to kind of begin with it because it's very Fun to even give it to beginners to implement because it's just so easy Like there's literally just three rules In which, you know, this little system operates and the end result is surprisingly Fun and complex. So the rules are essentially this right? You have a grid and Those grids have cells and the cells can be either alive or not And any live cell with two or three live neighbors survives to the next round Any dead cell with three live neighbors becomes a live cell All other live cells die in the next generation. Similarly, all dead cells stay dead So, you know, you can just use those three rules and then just a few lines of python and matpoldeba again You can just get a result like this and when you animate this, you notice that, you know, okay Like I can sort of figure out what is going on but certain behaviors are surprising Certain parts of the image are too stable. It's like why and certain are extremely chaotic And others even oscillate, right? Like you have those little Well, it animates so quickly that they look like pluses, right? Well, you can see they oscillate So there's quite a bit of action going on here. So just to implement this It's, you know, very, very, uh, you know, kind of straightforward So I was able to do the entire thing in one day not even knowing matpoldeba live like, you know, very well beforehand So it's very happy that, you know, kind of this sort of thing can be achieved So let's look at the implementation. So I Wouldn't need to use data classes and I better didn't because now like Kinect is looking at me angrily, but um, you know Just for clarity just to have some kind of model that we're talking about like There's going to be an object that has a representation of the grid So rows and columns and a bunch of other helper fields that we don't initialize Well, we don't actually Require for the user to initialize we do it for the for the user, right? So Matpold Lib subplots are going to give us the figure and the axes the grid is just NumPy array MPT is numpy typing It's a package where you can use it so that my pie understands what's going on. So that's pretty cool Yeah, and the image is just a widget, I guess on matpold lib so that we can actually show the grid from From numpy directly on the plot and you know The update uh callback that we're going to be using Just a single Screen of code Of which like easily half is just calculating the neighbors And you would say like well, we can probably do it easier and we we can but this one has a nice feature Which is that it wraps around so if you kind of go to the edge of the of the board You know if you followed you're going to reach the other opposite edge, right? So it wraps around it's it's kind of nice for animations and so on so, you know You can see even the rules of the game literally in the if and elif there So that's just four four lines There's just four lines because the third thing that you know what what's dead stays dead Is just guaranteed by us just copying the array at uh at the at the top, right? And the main function is again, we're just creating the game of life model And funk animation that we used previously allow us to just you know run it In the slide before what we had was just randomly generating stuff for us There's two slides below. Uh, yeah, so like numpy random choice But you know, we already seen how that looks like So i'm going to show you something that was actually pre-chosen for by me to just show you some of the research Kind of emergent behaviors of converse game of life So you can see that you know, there are Certain oscillators the one on the top left has like this period of three So three different frames, but the one next to it has a period of 15 So there's 15 different forms of it, but it just actually loops forever And then then there's those three What I would say they're birds, but the or you know, the researchers call them spaceships So there's this uh lightweight spaceship middle weight spaceship and the heavy weight spaceship And the little thing that goes, you know, kind of Diagonally, that's the glider. I think I've probably the most famous thing that you know is Animated in converse game of life So you're saying who cash like, you know, I don't want to see matlow live ever again. Like this is boring This is what my day job is about Uh, so good news is like you don't even need matlow live You don't even need like numpy if you don't want to like you can do game of life in anything Like you can literally just use the turtle module and in fact like turtle is so easy because it just Comes like with python it runs in a browser as we learned, you know, uh in the day before Like today before I'm doing one of those talks So let's just see how that would look like and it would look like very easily You create some of the turtle things that you need You know, and when there is turtle if you would ever heard about it Like what it's doing is it has this actor on in the on the screen and with those commands you can just Draw things animated right so obviously we're not going to be doing something a little more complex But it's already pretty interesting that even kids can learn to code with turtle because you know Okay in a very few commands allow you to have some graphical result on the screen Right for example here. We actually have a function so we can learn about functions And when you call it a few times, you know kind of you have a graphical effect, you know with the rotation It actually becomes pretty interesting. So the fun thing about this educationally is that it runs also in the browser as I said So this is python sandbox.com by ken burris. It's unfortunately based on sculpt So this is python 2 so it is fully functional But you know, you might discover quickly that if if the kids try something more complex You're going to see that this is not the python that the current dogs talk about and so on and so on But the pyscript people are currently actually working on uh Making turtle work directly with pyscript So soon enough you're going to be able to just use that and pyscript is the future. So obviously very interesting So, okay, like, you know Triangles aside like let's uh go and implement our game of life In fact, our model becomes easier than it was before because we no longer need those maplot lib Figures and axes what we need is to essentially Generate our grid. I kept it as an umpire array for simplicity, but it could be just a regular array From python or just lists of list if you want to And then we have some setup for the turtle And functions I made them, you know different functions so that we can see some the rest You know the structuring right that we draw the board by drawing cells and that's the kind of simple um Double for loop and so on and so on so the little complicated thing with turtle is you know It always has the pen down and it wants to animate everything nicely So if you want to actually draw a lot of things you have to kind of Work against it to to stop doing the animating thing. So we did a lot of that And then the updating the board is essentially again a double for loop that updates every cell And here I kind of caved to your you know judgmental looks and I'm like, okay I actually know we can count the neighbors you're using numpy vector operations. So Let's let's let's do that here. It still You know takes a lot of space Because the font needs to be a little big so you can read it And you know the other format really insists on this kind of formatting Well, um, but yeah, but the if and el if that is the rules of the game Still the same. So finally our main function is just uh wild loop right now And with our predefined Grid it would something like it will look something like this, right? So we already know about the oscillators. We already know about the spaceship but now we reach some differences in behavior because The vector functions that I use now like for Counting the neighbors that do not wrap around and so The behavior changes. So that is also something very interesting about playing with stuff like this because Even small changes might actually result in some different behavior. Is it correct or was the uh previous one correct? Who's to say like that's the fun thing about playing with graphics is like most of the time This is not your day job. So um, this is just kind of interesting discoveries about like, oh, um, you know like Little, uh, edge cases and little, uh, effects of what you're using affect the end result in fun ways But you know, you're like, okay, uh I want something more impressive, you know, this this game of live. I've heard about it in turtle. Come on, dude So let's go and look at stranger tractors. So, uh, systems that are also super easy to understand, uh, But look much more, uh, kind of pleasing to the eye, right? So the one of the most, uh, kind of popular probably is the cliford attractor that You know, you just define, uh X and y points of the next generation by signs and cosines With the formulas right here. So there's four parameters a b c d, uh, which you can twid tweak to get different results from this attractor, right? So doing the same integral, we would have to configure not to walk around and do stuff very slowly. Uh, We literally just implement the cliford attractor like this So you can recognize the new x and ui lines being directly Taken from the formulas the mathematical formulas And yeah, and we're just drawing dots in the place where, uh, where the new x is Um, so just making it work. Is it going to be super impressive? Yeah, okay could be better. Uh, it kind of looks like, uh, you know, uh Old, you know, um, badly developed picture. We can do better. Um, so we can change our super trivial Uh, cliford attractor function to for example treat the points that were generated first as points that are in the back So if they're in the back, they should be less bright. They should be darker So we can just do that and just say, okay, so if we have a part which is just i Uh divided by our iterations Let's just set the pen color to this and the pen color here, you know, just uses the rgb part We're using the same one. So it's gonna be Uh gray scale and just with that it already looks a little nicer. So at this point you're asking, okay turtle works when with, um Pyscript now, so can we do this with pyscript? I tried and I could generate 10 000 points if I tried more Well The tab crashed. So like probably there's some efficiency things that you know, the pyscript people have to still Kind of you know work on. Um, but yeah, it is possible But not to the extent where it is actually very graphically pleasing So let's just go back and just do a bit more like in regular tk inter turtle So if we uh look at our previous picture We think, you know, okay And if we can maybe make it a little more colorful and also if something is in the back Maybe it should have this kind of you know out of focus effect So it should be more kind of you know larger and the things in the front should be smaller But how can we make the things in smaller than a dot in turtle? And that was a little bit of a head scratcher for me because the the implementation of even a dot Makes it kind of a big circle So what you can do is you can just say that uh turtle should, you know Pen down and go forward zero steps and then it just actually puts a single pixel where it stands So having this this already looks like some you know kind of art from You know from an old book or so or so like there's not enough points for this to be interesting But we can do this kind of now all this Kind of out of focus effect, right? So how do we achieve this? We just say the pen size should be different depending on how far we went and with this and the colorful changes so you know kind of Before we just went linearly, but if we multiply we're going to get a more kind of uh, you know, um Slowly growing um Function right like so with the rgb We're going to grow like r quadratically and g uh, you know cubely. I don't know how to say in English Yeah, so it it'll should look more or less kind of violety and it does And that is already like quite interesting because you know we're getting kind of effects that are I would never think before that you know Actually turtle can be used for something that doesn't look like you know Just those three triangles that kids are learning like you can do quite a bit with that And uh that generates pretty quickly So yeah, like obviously this would not be that interesting if it were the only images So we can just say that if I divide it well like the mod 500 is uh zero then let's update the turtle so we can actually achieve Um animation or that where you know the cliff or the tractor appears out of nowhere And I find that pleasing it's kind of looks like you know I could put it on a uh screensaver Obviously those don't really have that many points because turtle When people research the cliff or the tractor and other attractors what they usually do is they generate millions of points Not thousands, right? So I have like 50 000 points there or 100 000. This would be 50 million So maybe it doesn't look very impressive to you right now But like if you zoom in Those have so many details in them and yet they kind of look, you know Like organic like there will be some intention behind them. Uh, so yeah, very cool And they Also look sort of like they're 3d even if they're done because you know, it's just x and y that we're calculating So it got me thinking like what if I could do something 3d in python And obviously I was thinking about pie script the entire time because you know, uh, the browser is a very nice Deployment target. It's very easy to just show people what you did when they don't have to install anything So this is what I did and in fact that actually works pretty well And I was very happy to you know, kind of work out the kinks It just at the web assembly sounded earlier in the in the week So actually I can confidently say that this is this is working now very well So yeah, like pie script you just make it work by adding a script tag in your html file and a style sheet And yeah, there are so those two like blue lines that hide a bit of details there But there's a pie config file and a pie script code that you're actually writing So this is pretty easy if you're really wondering about those blue lines Like the first one is an es6 import map where we can specify some javascript dependencies that we have And the other one is something that should not exist But currently does because pie script does not handle those es6 import maps very well yet So, okay, we need to have this but then you can actually use your pie config to for example install packages like numpy or whatnot In fact, like there was a talk earlier in the day about how those packages do install in your browser when you're using pie script So that's pretty interesting and you can have dependencies of your own like your own files You can have more or those files in your project So you don't have to put everything in a single minified python file So yeah, so Let's say like on the left. There's we're gonna have to actually have this main file and on the right I'm gonna be showing you portions of the lib3 Where we're actually going to be drawing things so to draw things We're thinking in 3d and web gl is essentially open gl 3.0 es. So like this simplified edition that is available on small devices Including in your car probably honesty It's not very well used there, but it is there in the microcontroller Yeah, so it's it's great, but it's also very low level and annoying to use So there's a very popular library for javascript called 3js And with pie script we can just use that so I wrote lib3 like as just you know to just encapsulate what is happening So I can explain it much easier that there's a scene So the scene is this three dimensional place that holds some objects that we're gonna draw There's a camera. So, you know a very special object that just looks at the scene, right? So it is directed towards some objects, you know, it has also like a physical position there There is a renderer. So a canvas on html that is going to actually show us what the camera is seeing And there's controls so you can You know affect what you are doing with say a trackpad a mouse or you know A controller whatever and then there's the lights there has to be some lights in the scene Otherwise everything is back and you cannot see anything And I just added stats so we can see how many fps we can get actually, you know when python is generating 3d stuff So yeah on the library side, we need to import things from js which imports them from the global this And the uppercase three is our 3js library that we're going to be using Um, so yeah like a lot of the things look a little bit weird just a little bit weird because You for example have to create new objects by using dot new on those objects Because there is a new keyword in javascript and you have to remember the things that we just imported magically It's an ffi You know like technology. We're essentially interacting with javascript code in a seamless way So I can take this dot new, you know, kind of Ugliness any day for this ability to be able to interact with 3js from python So yeah, we get the scene we create a camera with some Pyrameters so that you know, it kind of looks naturally We create the renderer or that is a web gl renderer set its size and we append it to the document body So we actually have this element. We're going to be able to see it Lights I thought, you know, it's going to be fun if there's more than one So we have a green light that is reaching very far But it's kind of dim and there's a white light that is not reaching that far So it's only going to light the objects that are very close to us sort of like a flash of a cell phone Um, and the controls. Yeah, like it would be way way less cool if it wasn't interactive. So I added some controls The stats are very easy to use because it's kind of like a Enclosed library. So you just you know, you just have to start them and stop them on your frames But you know, other than that is going to display by itself if you appended it to the document which we did And then yeah, we have to generate some cubes So the fun thing here is that we are generating them with the python random module and that works And we are interacting with the javascript world like and we even generate them using a Generator it's a python generator and it's even, you know, kind of unlimited, right? So it would generate as many cubes as you want unless you stop it. So in the init Function that I wrote I actually stop it after 50 000 cubes. So like this is how many we reach And here we have this animate callback. So yeah, it Gathers stats so you can see the stats begin and stats end But the only thing that will do it's it'll move the camera around using signs and cosines because that really looks kind of naturally But also it moves the lights with us So it's it's as if we were you know shedding the light on the object So it looks more naturally other otherwise it would be looking like the lights are from some invisible lamp And we're just you know, kind of it will look way less natural. So now lights are following the camera Yeah, and the only magical thing there is that we are Scheduling the next callback ourselves by just telling the javascript engine in the browser Request animation frame is going to be this callback and this callback has to be Proxy from python to javascript only because Reference counting in python would destroy Too many things for us if we did not hold on to this memory like this. So yeah, we can Actually fire this up and when we do Okay We actually see this effect where You know, it's barely what like 20 fps But to me that is pretty cool That you know, there was like a few lines of python that we wrote and it's running in a browser We can actually move it right so we can actually use our mouse to affect where we're going So yeah, like this starts being really interesting to me Like, you know, like this is something that i'm definitely going to be working on more in the future since You know, um, this is just randomly placed cubes and it's already looks Pretty engrossing. Uh, and it would be even more interesting if those cubes actually, you know Did something interesting. So yeah, okay, uh, web gl we can do it in python I can also approximate images with triangles. So, uh, another thing that is super interesting to me is like How is it that, you know, you can have a picture I can input picture and then make the computer Recreate that picture in a cubist, you know combination of Some primitives like triangles or rectangles or so on and so on like how does that actually work? So I saw work by michael fogerman who did like a bot for twitter where he, uh, you know, kind of had creative comments images from From flicker. I think of being, you know, kind of changed into this cubist thing And I was like, oh, this looks awesome. Like, can I do this in python? So I took this picture And I wanted to essentially create something like this, right? So, you know, that is actually a picture from my trip last year to Spain so it's topical because we we've seen the Pablo Picasso museum, you know, so, you know, kind of cubist But my first attempts were a little different. Like, you know, I couldn't quite figure it out very quickly But I tried very hard. So at some point I actually got like, oh, how do you get there? So, uh, first of all, like, you know, I can do some epiphanies I had like we're like, for example, that well when you start optimizing So essentially what you're doing is you're putting one triangle at a time, right? And you want to put the most Correct triangle and then then most second, you know, another most correct triangle and so on and so on So how do you decide that they are the most correct triangle? Well, you can use like, you know, as Square mean Error and this is this is what I used for this, but you have to start somewhere. So for example Making the canvas use the average color of the resulting image is already kind of putting you somewhere where it actually already looks sort of non terrible and one weird discovery was that you can Count the average color of an image by just rescaling it to one pixel and then the pixel is the average color So it's uh, yeah that I don't know like for me. It was a little fun Um, so yeah, like what we are doing here is uh, we have essentially a loop where we're generating as many triangles as we have to Those triangles are generated by just choosing the next triangle Um, and yeah, and then we save the results. So how do we choose the next triangle? Well, we have to generate that kind of the triangle and that's literally just, you know Just generate any triangle, you know any triangle is fine We assign it a color from, you know, the place uh on the input image where we uh that that we would put the triangle on Um, and then what we calculate whether the square mean error is a little Better than it was without the triangle and so on and so on and if there is an improvement We're just, you know, repeating the process over and over again uh, so how do you Calculate the difference square mean error in um In numpy it's very easy. In fact, you could even use fewer lines But if you would actually do the square mean you would use the dot mean right and I use dot sum because I like integers better There are a little faster and that actually allows me to debug easier like I don't I don't need the mean I'm not going to be comparing different images of different sizes and so on like I'm always comparing like the previous state of the same image with the next one So having the sum is perfectly fine for this purpose and it lets me with Let's me with integers So that's pretty good. Um, the candidate triangle random stuff The candidate color here is only just, you know, taking this actual rectangle of the place where the uh Where the triangle would be and that was already not too bad But it was also not too great. The colors were a little kind of mushy, you know They're like not not so bright as they should be So I actually had to bite the bullet and count only the average colors under the triangle And that was a little painful for my high school math and you know, kind of Not knowing how numpy works. So it took me a while to figure it out And also later on I figured out that you know, actually just converting on pill images So pillow images to numpy arrays is not a free operation. So if you do it a lot, it's just slow But the result was already better, right? And we could improve on this later on With, you know, generating the candidate triangles in a little more Smart way, right? So for example, you you generate a random triangle But after some point when you already found one that is improving your score We can just try to mutate it so we can just try to just move it a little so I could just You know kind of single Point a little right or left So that we are actually improving on our score on something that we already know That is not bad and this kind of approach is called hill climbing where you already have some result That is not terrible and you're improving on it. So having this we already started achieving something that resembles human beings It's still like very far off. But you know kind of It already made me hopeful that I can actually do something with this So I made many further optimizations, obviously because You know kind of this sort of rabbit hole does not see any any end But in the end I managed to actually make this monstrosity of an async IO multiprocess thing that you know I kind of actually reports the progress of the worker processes as well, which I'm pretty proud of Rich by the way amazing. I I I love this framework So yeah, like you know kind of I did a bunch of things where I tried and abandoned things But in the end it worked out. Is it easy to debug if you have multiprocessing? It is not so if you are on linux, for example Because it does not work on macOS. I'm sorry and you're wondering why this task three Is going slower than all the other ones. You can use a bloomberg library or tool called pystack to actually Look into a running process and see like what is it doing right now? I guess it's Super useful. I wish it worked on macOS because on linux it works very well So for example looking at this master process You would see that oh, there is a process. It's python It has the gill and the entire nice stack trace But it's the current stack trace of what is happening at the moment So you can see that actually I wasn't lying about the async IO I wasn't lying about the multiprocessing There is some shenanigans happening there But looking at our slow Worker process you could see for example that it doesn't say it holds the gill But why not that that is a little weird So if you scroll down because the trace back is really long you will discover that okay It's in numpy and numpy is famously freeing the gill if it's doing the miracle operation so that you can do something else With threads with python. So yeah, you can also notice that there's a route there because You know kind of looking into other processes requires administrative privileges, but yeah, I highly recommend you looking at Pi stack if you want to debug Applications that are already running like this is you know a stupid toy that I'm writing But if you are in production and you have production servers and they miss behaving Pi stack sounds like an awesome tool for this like where you can actually see what is going on So yeah, like you know kind of long story short I managed to evolve this a little so that you know if you squint or if you're really in the back like It kind of looks like the original image, you know, and maybe if you're like, okay I only know this is the original image because I saw it first Then maybe you can tell me like, you know like does this look like anything to you and obviously I'm animating because we can animate now So that's also cool We're gonna wait for those 500 triangles to generate They generate like takes like eight minutes for them to generate In python it should be faster, but this is the fastest I could get So yeah, if you don't know what that is it is a piece of cake which implementing it wasn't But you know, it's it's it's it's a lot of fun. So Yeah, this is this has been a random talk, right? But even in this random talk like what we learned about was That there are systems that are emergent So they have like literally just two lines of the actual logic the core logic and They generate things that have a lot of complexity in them Game of life is the obvious example that you now know all about because you know about the middle weight spaceship But we also talked about the clipboard attractor We talked about web gl which I made work in pyscrit, which I'm super about super happy about And then we looked at triangles right like, you know, so how we can approximate images to triangles And now the most interesting thing is that this rabbit hole has no Bottom right you can just imagine that there are things that you could do with this knowledge To just connect the you know Disjointed elements of this talk into something that makes more consistent sense. For example We generate points for the clipboard attractor And some we already kind of treat us if they are in the back, right? Because we are dimming them here in the turtle image But what if we just generated those points in web gl instead of just doing random boxes that are just randomly placed We could then travel through the clipboard attractor, which would maybe be more interesting, right? And even the triangles if you think about this any triangle in 3d can be represented as this equilateral triangle that is just you know kind of skewed somehow right is placed in 3d So it doesn't look from your perspective as if it's Equilateral but it is so we could make this image in 3d Such that we can travel through it and it doesn't look like anything to you But then we pan out we zoom out and suddenly it's our logo or something right like which I think you know Can if it's something that is intriguing to Pursue, right? So yeah, the code does live on github. In fact like you know, it's those are very short programs Like you know, I claim no responsibility over them But what i'm essentially saying is like If you ever ever feel overwhelmed by your day job, which is entirely You know kind of serious you can always just go and just try to play with something that it has immediate visible results And graphics is that like I have avoided it for a long time because I somehow never you know kind of Thought about this line of work as something that you know, I could do but it turns out like no, okay Maybe I don't want to work on which are four But you know for just to generate a bunch of images that look nice This is very easy with python So yeah, I got inspired by a bunch of people ron still has an excellent article on the earth orbit wiggles There's some work on the three body problem gravitational systems. That was more Kind of physically correct than what I did the Clifford attractor article by BL badger has excellent examples of different sorts of abcd parameters that you can put there And obviously all of this kind of started by michael fogelman And his primitive bot on twitter. So yeah, my name is ukash langa and this has been Games of five. Thank you for coming So we do have five minutes for questions. Yeah, okay, let's go If people want to Hi, thank you for the talk I noticed in your code that you use in many places While loop with a counter instead of for loop with range or something like that. Is there a reason for it? Is it faster? Oh, all right So maybe it is like the the reason for most weirdness probably in the code is that it just evolved So like there had been like previous versions that had to be a while loop But then they stopped having to be a while loop because they're more regular right now in the end But having a while loop just usually just lets you be a little more You know kind of flexible in how you want to exit the loop or progress it for example In the generating of the Triangles, I think I ended up in with code where I don't think I have it on a slide Where it's um, it doesn't always Count the next iteration if the triangle that you're getting is invalid for whatever reason For example, we've already tried whether this one is better or The triangle where we allow for it to be a little bit out of bounds because otherwise you will never cover bounds like in your image So we allow it to be a little bit out of bounds But what if it's entirely out of bounds the entire triangle is not on the screen then you can't really do anything with that So we reject those triangles without advancing the loop, right? So this is very easy with a while loop because you can just continue without You know incrementing the counter With a for loop that would be a little more complicated to achieve I would have to have a loop in the inside the loop to you know cover for those special cases. Yeah. Thank you All right. Okay. It looks like no more questions. Thank you very much