All right, hello everyone. Good afternoon and happy Friday to all. Let's see here. A few of these chat windows around. I think we'll be ready to go. Looks like I got sound going to OBS at least. Did I start up the YouTube one? I always want to double check that these days. YouTube, it looks like we're going YouTube as well. All right. How's it going, Sea Grover? All right. So hello, everyone. My name is Tim. I go by FOMI guy on GitHub and Discord. This is the deep dive program, which is a weekly live stream program where we are working on things related to circuit Python. Sometimes we are getting into the core of circuit Python, such as today, in fact, we're looking at a core PR tried out again. And sometimes we work on like libraries, sometimes we work on projects, sometimes we work on infrastructure. It just depends week to week. Whatever happens to be on my mind that week is what we get up to during this live stream program that occurs at the same time every week. Friday at, well, it's 4 p.m. central time, which is my time, but it's usually built in Pacific and Eastern. So it's 2 p.m. Pacific time and 5 p.m. Eastern time, I believe. And whoop, I really need this one necessarily bookmarked. So just for anybody that might be new, though, if you have never joined us on the deep dive stream before, if you don't know what we're working on, circuitpython.org is kind of the base website for the project. You can head there to learn more about it. Basically, circuit Python is an implementation of Python that runs on tiny computers called microcontrollers. There's a bunch of pictures of those over here. Each of these devices has circuit Python that can run on it, and when it's running circuitpython, you can plug it into your computer. It will show up like a thumb drive, and then you can edit a Python code file on that thumb drive and have it execute on the microcontroller. Microcontrollers typically have some available iopins along the sides of these devices here. Lots of the different ones have that, which you can connect other hardware devices to. Other ones are more built in, fully featured. In lieu of the iopins, this one has a bunch of built-in hardware, so it's got a grid of Cherry MX keys. It's got a rotary encoder knob. It's got a screen, a couple buttons and things, a couple other bits of built-in hardware. So all these little different microcontrollers come in different shapes and sizes. Some of them are made for more general projects where it's just iopins, and you can hook them up and do whatever you want. Others are more built to be a specific thing like this macro pad here, where it's got a bunch of stuff built in, but the common thread for all of them is that they can use this circuitpython language in order to execute your code with minimal software tooling and things like that. You can just open it up in a text file. If you're interested in learning more, recommend you to head over to circuitpython.org. You can find out a bit more of the high-level information about the project there, as well as join us over on Discord, which is linked down below, I believe, on the screen, a.d.a. fru.it slash discord. All the development takes place out in the open, and we coordinate through Discord. So you can, you know, if you want to ask questions or just have comments or anything that you're interested in about circuitpython, you can chat over on the Discord about that stuff. The Discord, that is also the chat that is below me on the screen right there. That is the live broadcast chat channel over on the Adafruit Discord, and that is where we tend to hang out when there's a live show, such as this one going on. How's it going, Jose? Let's see, what do we got? Testing the new... This is from Siegerover, testing the new Streamcar Racer Featherwing today. Be able to choose almost any MCU and STEM ascensor. This will make a fun and flexible robot. Nice. Yeah, that looks pretty cool. Got the big old switches on the sides there. Built switches. Nice Feather... Feather... I don't know, is it technically a Featherwing plug-in? I don't know, but it's like the kind of standard Feather plug-in there. Nice. Looking cool. Imagine using this, which is a... I cannot see this one. Blue. Is it a... I can't make out what's on that chip there. Thanks for following the Feather form factor. I don't recognize the main chip, though. FPGA. I got you. Probably much harder to use, but it'd be interesting. I see. Okay. How's it going, Jose? As well, in SCUR, as well as Beotograph over on YouTube. How are you doing today? How's it going? All right. So that's kind of the quick, high-level version of CircuitPython. Like I said, you can learn more in a couple of these places, circuitpython.org, as well as the Discord and stuff like that. CircuitPython is an open-source project. It's free to use, it's free to put on your own devices, it's free to run it on your devices and use them for your projects and all that sort of stuff. The development for CircuitPython is funded primarily by Adafruit. This is their website, Adafruit.com, their hardware and software company based out of New York and the United States. They manufacture some of the microcontrollers as well as some breakouts and all sorts of different things that you can hook up to the microcontrollers to do with them. They also resell other people's electronic projects as well. So head over to Adafruit.com. You can see all the stuff that they've got including all of the CircuitPython microcontrollers and all the things that you can hook up and do with them. Then I'll just say, of course, thank you to Adafruit for paying the folks who work on the project. There's a team of folks that work on the project full-time that Adafruit pays. There's also some folks like me who work on the project part-time, all who are paid by Adafruit to do so. Thank you to them and of course, thank you to anybody who wants to purchase hardware from them. That is how you can help out the CircuitPython project in your own sort of way by buying yourself some toys there. That helps them, obviously, pay the bills, which is helping them pay the folks working on the software. How's it going, Niradak? Today, I want to look back at the GIF new animated GIF support, which is currently in a PR for CURS core of CircuitPython, although it's looking like it's fairly close, I think. There's a couple of review action going on with it today and there's a couple updates since the last time I looked at this. We did take a look at this last week on, I don't think it was on Friday for the deep dive, but I think I did it on Saturday for my morning stream. And there have been, there were a couple of changes, I think, earlier in the week that I hadn't gotten back to see or try out yet, and then there's some new changes as of today as well. So we'll test out the new version of this on a couple of different devices and try it out with a couple of different GIFs and just see how it's going here. Definitely super excited for animated GIF support. So I'm happy to test this out, leave a comment if it's working and see if there's anything that we find that's not working and just help it move along however we can. Because definitely excited to have that support in display. A few generations younger than this one, basic stream car racer. Okay, okay. The ones that balance, I see what you mean, stream car. So it's, they balance on the string there and then it uses a motor kind of with a little grippy bit to ride itself along the string. I have seen some bots like that. Okay, so you've got the new designed one here which is, looks like this original one was just kind of wire circuit. You got the new one built around the PCB there. Are the big tilt switches part of the balancing mechanism? Are those like these little hooky, I assume this is like a paperclip or just some kind of metal wire hooky bit here? Are the tilt switches somehow replacing that thing or the tilt switch is something entirely different or are those even tilts? Yeah, I think those are, right? These big tilt switches here one on each side. A little speaker maybe it looks like on there, on off switch. Looks like probably a battery plug, is that one up there? Nice. So yeah, animated GIF, that's what we're looking at. Kind of fair warning blanket statement. Everything that we're going to look at related to this is in a PR7549. So it has not been merged yet. This is not part of CircuitPython support yet, although hopefully it will be soon. So yeah, if you want to be able to use this, you do have to build from this PR branch right now, but hopefully we will get merged in at some point.  So that's where we're at today though, is we are just going to build it. So I've actually got it open here. And I think I'm on the most up-to-date version. I kind of want to just double check though. So I think what I'm going to do is if we can find the latest commit and then check and see if my version has it. So this is on one. Shared bindings on disk if I checked out a few minutes ago before I started up the stream ran that. So I think we're on the newest one, but I don't know if there's been commit since then or I also don't know like since I already had the branch, I don't know if it like updates itself correctly or not. Okay, we don't have this one yet. This minimizes, which has been changed. Okay, so let's just let's just go back to main. This could have just been committed after or it could be the way I'm checking it out. Didn't actually work for updating it. I think what I'm going to do is I'm just going to go back to main. I'm going to go delete my local copy of this branch. Then we're just going to check that out fresh again. That way we no longer have old version. I don't know if this updates. Sometimes I feel like it does. Sometimes I feel like it doesn't. So should put us there. Stuff all got closed again though. The switches detect the end of the string. Okay, so you get all the way to one end and that will bump on the edge or whatever. That way you know to turn around and go back the other way. Nice. It's a good way to do it or to stop or whatever you want to do. Doesn't necessarily have to go back the other way I suppose, but so then is this like a string car racer? Is this kind of like what are the wooden cars? Pinewood Derby?  You'll race them to see whose time is the best. Is that the idea there or are you just kind of building it as that bot to play around with? Like a more organized race thing going on? Because I've definitely seen that for the wood cars. I've never seen a string one, but that sounds like a lot of fun. Definitely be into it. I'm a sensor. Okay, so we want shared bindings on this gift. We're back into here. Okay, now we got the latest one with the updated comment there. So we know we're on the most up-to-date version, so we'll go. We want a Raspberry Pi. I think let's do a expressive first. I have a couple of different devices we could try it on, but Feather TFT is kind of just like my default grab-and-go testing device these days typically. So here's our drive. We'll start on that one. Move them out for speed, smarts, autonomy, and longevity. I gotcha. Okay, so there's a different, what do they call it, different kind of like different versions, different classes or something different competitions to take part in, whether it's like fastest or most automated. Oh, let's go up to expressive, and then let's go make clean first so that we rebuild entirely. We need to do export this one dot, dot, slash, ESP, export. I think we're really successful, but it doesn't look normal.  It prints out on a nice little table at the end there. I did see some stuff back here that was, goodness, please, not this again. I can't climb in the window. Okay, these are warnings though. Unused operation type. Is this in anything to do with what we're doing? Panic Arch? No, I don't think so. Okay, let's try just try another clean real quick. Clean one again. Just verify that's like that. I don't know if we're actually back. Probably the YouTube link is broken, I guess, right? I don't think I can make the YouTube link work again. We are back. Are you watching on Twitch or YouTube, Jose? Very curiosity. I'm not sure if I need to be doing something for YouTube more. Still say live here. Back on YouTube, okay. I don't know how they got it linked up right, but that is good to hear. Thank you for the confirmation there. Okay, I think we're back. We're back. Should be back on both. Let me double check here. I don't know what that was. Usually that coincides with like weird stuff with USBs, but I... Nothing actually got plugged or unplugged when that happened. I don't really know what that was. Hopefully that's not going to be a thing that is happening a whole bunch. Or at all anymore would be good. Let me get a couple more. So yeah, I just locked up. Total computer just locked up all the way on me there. Had to have a forced power restart it. Okay, let me get back to where we were here. I guess let me just leave Py... Well, we're gonna have to have PyCharm at some point, right? I think we'll need it. I think this thing has a new IP finally for some reason. Brush the first time. Yeah, sorry, folks, for the technical issues here. Thanks for sticking with me a bit while we get back up and running. All right, good for now. Switch that around. We're definitely going to want to clean build after that. I wonder if the build was part of it. So we need to get back in expressive. We need to get back on this export thing. Fingers crossed. Moving my mouse around as if that's gonna help it somehow. Playing the cat partially. I looked over at the cat and I started to grab the octopus on a stick to entertain the cat for a minute so that he would stop trying to climb the window. And then when I looked back, my mouse no longer worked. Slowly realized that everything was frozen. Okay, we got a good build this time. Looks like this is what table of stuff I was expecting last time, which we didn't get. We do have it now, so we're good. So I do have to restart the device. Unfortunately, I kind of... I'll try not to just warn every time I do anything, but obviously since we already had an issue once, if we have an issue again, then I'll just try to hook it back up. Same as I did before. Thanks for bearing with me while I work through any additional issues, which hopefully there will be none of, but we do need to get this to bootloader mode. Which means we have to reset it, which is one of the things sometimes, ever so occasionally, the unplug, replug there tends to be, especially if I do it a ton of times in a row really fast. Sometimes we'll wig out my computer. I'm going to try not to do that. Should probably not be an issue if we just do it once, if we do it slow enough. But just in case, I'll mention that. Let's go copy that one, which is going to be what? Media? Is that media? This feather? But we need the file first. Obviously, build 50. Also, Ronald Covington over on YouTube. I don't know if you're still here. I don't know exactly if this message came before we crashed and came back or after, but I do see the message there. Hello, what are you building? Hello, first of all, thanks for tuning in. If you're still here, appreciate you watching along. I am building, well, if you meant literally, what was the thing, what was the code that was building? It was CircuitPython, the CircuitPython core, but in particular, the version with this PR that has GIF support. If you mean more generally, as far as a project, generally speaking, what am I building? I'm just working on testing the GIF support for CircuitPython. If you are interested and don't know what any of that stuff is or want a more in-depth explanation, let me know, and I can share more about it, obviously. Like most of the folks watching know most of what's going on, so I don't want to spend too much time explaining something if you already know what it is, but I'm happy to explain it if you are new and don't know anything more about what we're doing, but that's it. CircuitPython in particular, we're working on the GIF supports right now, so I believe we have hit the point where we pretty much are going to have to have this back open, so we'll do that, kind of just do as little as possible in the hopes that we don't anger the computer elves in there again. All right, we are maybe back again? Yeah, that one we did not. I don't even know. I don't even know. So yeah, all I could say is I'm sorry for all the issues we're having. Thank you to everybody sticking with us. I don't even know what happened that time just so BS died. Yeah, I don't know. We at least didn't lock up all the way this time, so I was able to get back a little bit quicker, I think, but fingers crossed. Hopefully, like, we're done with that kind of stuff for now. I'm not really ever had this much issue, so I don't exactly know what to do to troubleshoot it too much, so we're just going to, we're back up and running now. I got everything back. We're just going to fingers crossed and hope for the best. Let me just, I'm going to, let me put, let me turn off the preview. Let me keep OBS window open, but just turn off the preview that way. It's just chilling there, we're not touching it, we're not doing anything with it, but it's like over there. Having fun, I hope. Okay, goodness. All right. Yeah, thanks again, folks. Thanks for the heads up. Yeah, I will say too, also thank you for the folks that mentioned. I guess let's go for the remainder of the chat, if you wouldn't mind. If I do ever cut out again, just drop a note in the chat. That way I have another chance to see it, because this time it actually, it took me a second to notice that OBS was gone. The notes in the chat actually are what tipped me off there, so definitely appreciate that. Thank you to the folks doing that. And like I said, fingers crossed, hopefully we're just, I'm going to have you more issues. That would be the best. That would be ideal, certainly. So let's try for that. Otherwise, we'll, we'll trudge along here. Do we want to use party pair of tests? So will anything else need to change? I was not using any of the other arguments here. I don't know that, well, I don't know if we'll need this one. Maybe we could possibly be all right with, I want to say this one, we didn't use the swap done, right? For the party parrot. However, this is still the party parrot with transparency. We may also need to get one with out the transparency in it. I'm not sure where we ended up on that. So I'll have to try that out. What is this frame? So it's just counting. Okay. Need to sleep's anymore of refresh through this. The current version here is auto refresh false. And then it's calling refresh after it calls play frame. I don't know where my browser is that anymore. Third one over. No party parrot gift. We have Homer. Well, Homer's too, too big for this one. Maybe. But I don't have the party parrot that I deleted afterwards. Maybe I deleted it to make space. This one's not doesn't have a huge amount of space for a call rate. I just have to delete stuff. Actually, I do have this here. This one was on six, but I pasted it without any version or whatever. So there's no attribute play frame. Okay, so we have to see what's the new API. So this is still an older one. Was there another new commit fix? No, that was the one we saw a dog fix, I think. We do need to see what's the API now, though, because it seems like it's not the same. So let's see. Next frame, we just change it to next frame. Okay, the first time. Do we need to call this one? We could. Well, it's, yeah, I guess. I don't know. It may not matter, honestly. We might could just not call it here. And then it's like, we're not even, we don't even have the tile grid yet. So I guess this is probably loading the bitmap data. It's not really going to get drawn until it gets added to the tile grid, which has to have the palette created, then added to the group and then just shown on the display. Realistically, we probably could just let it fall into here and then the first time it gets called will be inside the loop. Yeah, so the transparency is still, that's still an issue. Let's see, I guess maybe we turn that off or do we try to angle it? Not great at showing the color when it's straight on, but so we would need to basically have this one filled in with non-transparency, which I think, did somebody say easygif my effects? Let's cut rotate resize video. Maker, skip and copy, loop count, crossfade, don't stack. Use, don't stack frames. Remove the frame when it's time to display the next one. Use the first frame as the background. No, we want it to use, I don't know, just black probably if we could. I don't know that that's going to be any different. 13k, how big is it currently? 13k, I don't think this is going to make a difference. Maybe if we put the, maybe if we added, but I don't really want it to show a blank frame either. Let's see, we could add a blank black frame to the front and then we could go check that box that said use the first frame as the background, but then it will flash when it loops basically. It's still doing that one. So we need to actually fill it in, I think. Overlay, cut, split, frames, don't crossfade, don't stack, why these are like the nesting checkboxes. Interesting. And I make a gif with a transparent background. How to add a background to a transparent gif. Adding the background, upload the background with the gif, drag and drop the background, pull the desired background image together with the gif, drag the background image to the first position, set the duration to one, select don't stack frames. Isn't it going to show, like it works with this one because the guy, the stick figure here leaves frame, right? The first frame in this case is the background by itself, but in our case the first frame, we want it to be the party parrot, but we don't want the first party parrot to get drawn behind all the other party parrots. How big is this? I'm 26 by 128. I'm going to drop frames. Can I upload a new one here? Seems like it. Here we go. Two files selected, delay one, this. Oh, yeah, I didn't read this enough. That's actually what we want. Okay, now we're looking good. It's 18k now. Try to optimize it better. I'm at 16k. A little bit difference. All right, delete that. That starts failing. Repair at seven, paste that there. Now we do need to set that to seven. Interesting dots. I'm actually going to try the one that is, oh wait, did I download this one or that one? Is that 18k? 16.8. Okay, let's do this one. I'm curious to see if those dots are from the compression. With the siren siren coming through too loud. Once we get this merged in, I think we should add a page to display a learning guide as well. Which will actually be good because we could probably show this process of fixing the gifs with transparency in them since it kind of needs to be opaque. Otherwise, it will stack like it was. So having a learn guide page where it explains how to do that process that I just did to give this an opaque background is probably a good idea. Because I suspect we'll have people asking about how to do it. I mean, even if we do provide it, probably some people will ask but we'll have a chance hopefully at least for some folks to see that and know how to do it from the jump. All right, eight. Okay, yeah, yeah. The dots were definitely part of the compression. I don't see the dots anymore. Like I said, the colors don't exactly come through the best. I wonder, so we did, I did try a few other ways of this the other day. Like we tried auto refresh and then not calling refresh here. And this is just calling as fast as it can. That's way quicker. So and then but this does return the result of the amount of time to wait. Theoretically we could go, there we go, and that will get it down to the speed that is embedded in the GIF itself, which makes it much easier to see the actual individual colors rather than just kind of like a chameleon of blinking neon or whatever. You can actually kind of make out the different colors in this one now. And then I think these are all declared in here. So the reason that was .04 was because of the four here, I guess this is in milliseconds. And then we had it as seconds. So .04, about four milliseconds. It seems really fast. Is this the one with the background? Where did our background go away after we optimized? And we came from here. Okay. Here. Partially I'm also learning about the GIF format. Like I don't really mess with GIFs that much. I'm also partially here just like trying to make sure that my understanding of this is correct. Like I'm thinking we got a .04 there because these were on four. So we changed this to 100. We should be getting .1 here, which then would be 10 frames per second on all of that stuff. We go make GIF. That seems way slower though, but it's not 100 seconds. I mean, is that 10 times a second? It's not. It can't be right. That's way too slow for that. This is almost like one time per second. Are these one one hundredths of a second? Does this say? Probably somewhere in the hell, but at least say what the units is. Straight 10. Or enough. My mental decimal math is not so good, TBH. 9. 9 is the 10 frames per second GIF, which does look a lot slower, but it is like artificially slowed down. Like it can actually render much faster than this. At this speed, it pretty much gets rid of the tearing as well, or it lessens it, I guess. You can still kind of see it there if you're watching for it. The tearing on the left side there, where it's just like in between refresh frames or whatever. Should we try back to this one? Maybe we should not have audit refresh on. Is that going to make the tearing better? Is it then this way? It will never refresh partway through? Oh, I took the refresh call out. Yeah, yeah, yeah. So we should refresh before we sleep or after before we sleep, I think. Now we do still get the tearing a little bit on the left over there.  Every now and then you can see kind of like that horizontal line. It's like in between the refreshes or something. That's pretty darn good still. And then we're not even. So if we wanted, so this is 10 per second, if we wanted, if we wanted to try to hit 30 frames per second, that's three times faster than this, which would be this over three, which is pretty close to where we started, I guess, actually. It's not the exact same. We started on four, which would be rounded, I guess, 3.33, repeating three and a third would be exactly. But this is a weird unit, though. So that means that this is in one hundredths of a second. Why is this highlighted? But I can't actually type in it. I will say to this camera, I can't really keep up with it. Like there's more, there's, it looks weirder. It looks worse coming to this screen here, which is what's feeding through to the stream that you all can see. Then it does directly just looking straight at the screen. The camera that's capturing this, I think is not actually, well, and it's also streaming over Wi-Fi. So like, whether, you know, the camera is probably plenty capable, but the network connection and everything is slowing it down to the point where I think what we're doing is we're missing every now and then we are, we're not seeing frames here that actually did occur on this screen. They just occurred and changed too fast. So we don't actually see them up here, but looking direct, you don't have that same phenomenon going on. It doesn't really give you those jumps. The head bob is smooth on the old party parrot. Did we change the xy of this? Is this thing xy at top left corner or who did not change anything with xy? Is there a blank space above it? Or did it start in bottom left? What do you, what even orientation is, well, it must be, okay, it must be face up in this orientation. How big is the actual screen on this? Is it too short for the party parrot? Let's see. I want the product page 240 by 135. So 135 tall and then party parrot was like 126 by 128, I think. So that does fit within 135. We have between 35 and 28, we have seven pixels of extra space. It does look like we're at the bottom left though, right? Let's put a background behind this so we can tell what's part of the GIF and what's part of the background. Let's put a white background in there. So let's see. Easiest way to make a white background, I think. Probably just vector IO, vector IO rectangle maybe, bg-rect. If you want to see frames, you could put digit 1234, 30 as images, generate the GIF, then display, then film with the high speed. Yeah, there we go. Slow it down, but then film at high speed. It'd be interesting to do a zoetrope type thing where you fed it more and more frames that made it seem like it was speeding up the zoetrope and then getting into focus how it, once you get it fast enough, it starts looking like no longer horizontal motion but instead just animation. It'd be interesting to make a GIF that tried to encompass that. So like you'd see the motion to start with and then it would kind of like lock in to just the animation and then slow back down, bring back the motion. I was looking at the GIF writer module as well. I have not played with that. I understand Jeff implemented that I think around the time he was working on cameras. I'm curious if we could just output a GIF from that module as well. I think it's made to work on files though, so I guess we would need, I mean, easiest thing would be to do it on a device with a SD card probably. I need pixel shader. Let's just go bgpallet equals displayo.just one color. Color is white.  There we go. Pixel shader bgpallet. What else? Width height xy. Okay, we are top left. We just have a bunch of blank space, which does make sense, I guess. See it in that, but it's like you can see the blank space here. We basically have seven pixels below, which means if we do y equals seven, we should be touching the bottom edge, I think. Could also turn this off. The print probably is slowing it down some. So, can we get the width of it? Let's see. Can we write a line it by saying x equals display width minus GIF dot width? Can we get the width of it? Nice. Yeah. And like if we wanted bottom right, we could go tile dot y equals display dot height minus GIF dot height on the right corner. We wanted it centered. We go display width over two minus GIF width over two. Same thing for the height, although the height will just be a few pixels off. Could we still use make transparent? No, because, well, maybe. Well, but it's going to just return black. Is that right? We still use make transparent? I don't think we can. I mean, I don't think anything will stop us from calling it, but I don't think it will work. What was wrong? It does work, but the problem is that, okay, okay, hold on a second though. So the problem is that there's black in the thing also, but if we chose a different color, it was a different color, we could still do that maybe. Okay, let's try that. Do we have, I mean, we have cool pinks, cool greens. Is that like, should we, that like full green green? That not quite, I think not quite, right? I think it's, oh yeah, we have plenty of room to use like actual green. Okay, let's go here.  I think I can like change this out. And now I, only thing I know is just go back to here kind of but change it to two new files. How's it going, Johnny? Orange is the new black. That's called the green screen. We go this. I want to, one of these times maybe we'll try Crossfade. I think, I don't know if, oh, this is probably not the right kind of gift for that.  I will just leave that on four. It's weird this is highlighted but doesn't actually let me type, start typing. Number 10, puppy number 11. That's interesting. Did we get the swapped palette now? We end up on the swapped palette. Maybe we were already on the swapped palette but didn't notice it because the colors are still rainbowy. Now we have our green is green but it's not, well, that's because I took out this. That did not, oh, black is still on zero though because that got rid of the black. It's kind of an interesting effect but not quite what we were after. So let's open this in Gimp. Move green to there. Export this back out. Yeah, it was not actually zero in my case. Should be zero now though. Oh, okay, yep, yep, yep, yep, yep. We turned that back off again. Oh, we got black again. That's weird. I think that doesn't seem like it actually saved our palette. I moved that to zero. Did I not save again? I think transparent is doing white. Yeah, yeah, yeah, white. Well, it's letting, yeah, yeah, letting the white show through from the background. Yeah, okay. I mean green is still, green is zero on this in Gimp at least. So this is number, this is parody part 13. Maybe I just didn't save the last one. Pick that. Delete this. Copy this one. Make sure we got the right one for 13. Paste that there. Close this and update that. Maybe 50 shades of green. Did you look at the right one? Yeah, there are more, there are more shades of green and I am not positive that I got the right one but I'm pretty sure that I got the right one because it's the most highlightery one. And the other thing is even if I didn't get the right one, I definitely put a green at index zero. So the fact that it made black disappear tells me that the palette is not actually working quite how I thought it did basically. Yeah. Oh, this takes color. This takes color, I think. Not, not index. This is not a palette. It's a color converter. Which in a circle like it, it haves kind of like a palette but it's actually a different thing. I need the docks. I think I need to give it a color though instead of an index. I'm trying to give it, I'm trying to give it index zero. It's interpreting it as zero x zero zero zero i.e. black, which black was at index zero before. So things get a bit confusing because I thought it was working one way but now the more I think about this, I'm thinking this thing wants me to give it a color. So we would want like zero x zero zero ff zero zero for green, I think. I'm just going to check the docks before I change it though. As long as this is quick, otherwise we'll just change it and hope for the best. Oh, it does say or index. Color or index. How could that work? It can't tell those two apart, can it? I guess if, well, but it doesn't say tuple here either. I'm going to say maybe if you did color as a tuple instead of x. Interesting. Should probably update, I'm not sure. We should probably update the docks here. I think this doesn't, can't actually work for both. It wouldn't know how to tell them apart. I don't think. That still didn't work also though. But maybe the swapping is part of the problem now, is this? No, that didn't make any difference. Other than that, like obviously now the red is green, but that didn't cut out any parts of it. And this, eyedropper. Oh, oh no, no, no, I clicked. I clicked. Okay, yeah, zero zero ff zero zero. Index only works on palettes lists. Yeah, I think that's right. But the docks here, this one's for color converter and it says it. So I think we should probably update the docks to not say or index unless this can't actually work somehow. Although truth be told, like, it's not actually working the second way how I thought it would work anyway. So it seems kind of possible at this point that I just don't understand how it works altogether, truthfully, because it doesn't seem to be working with color either. So with on disk bitmap, it gives you a, how do you get your palette with on disk bitmap? It gives it to you. It's either like it gets returned by this or it gets, it's on the object after you create it. Does this have one of those? I would love to see the palette and be able to just print the color and see if it's like, it thinks it's this green or what. And as a parsec with make transparent, is it, I'll take it, I'll take a look. I think that's probably with palettes. If it's the one, I do remember seeing one. And I think it was with palettes, but I will check it out. If I can search it up relatively easily goes bitmap.pixel shader. Does that exist for GIF? It's not how this example works. Pixel shader, there is. Can we try that? It's transparent sprites. Yeah. This one is with a palette, which this one does behave more like a list and it does use indexes rather than colors. But it's not quite the same, which color converter is still a bit of a mystery to me truthfully. I thought I understood how color converter worked and what it was and I'm realizing the more time goes on that I'm not quite, my understanding of it's not actually, not actually right, doesn't have attribute. Does have get pixel shader though. Have multiple palettes, one master and one for each frame. Could be. If it's the question mark on the end, I assume you're posing that as a question. I do not know the answer for certain personally. There's definitely, I mean, GIMP. As far as I can tell, GIMP believes there is at least this palette, which does show the most highlighter a green at zero. This just doesn't have pixel shader at all. I wonder if this exists. This exists. So it's not implemented in. We did have get height. Why are some of these are white and some of them are yellow? Why is that? I mean, is it get pixel shader? I believe that's like, there's our height and width. Get bitmap. So I guess we could look at the, can I have an animated GIF more than 256? I don't know that that will apply to me. I'm not necessarily trying to go over 256. I don't quite follow it. It feels like you need a special reader, right? Like, I don't know if I follow that quite right, but it feels like you need a special playback that's built to handle that different kind of GIF there. Not entirely sure though. I definitely don't. How's it going, DJ Devin? I definitely don't necessarily follow what they're saying on that post. Play max delay. We could be testing those things. We are GIF player has limitation. It will fail on those. You try to break the limit? Yeah. The way I understood that post, which I didn't, like I said, I don't think that I did actually understand it all the way. So everything I think I know about it's certainly subject to being wrong, but my understanding was it's like, it needs a special kind of player. You could implement the logic in our player to be able to do it, but you would have to actually do it. My guess is that by default, it would not actually work. And then on circuit Python, my next guess is that it would be even trickier still, because our system, as far as I know, kind of does have that limitation. I don't think palettes can be bigger than 255. But I also don't know that for a fact either. So like, I don't know, but that would be further potential problem on circuit Python, compared to like PC or browser or something. So I'm kind of thinking, is this extra? It doesn't feel like we can ever call this, right? Does anything not work if we remove that? Oh, is that not how you comment? Let's comment this way. Got a lot of tricks possible. Next partial updates, firmware. Let's just see if this one works. The loader, here's crossed, okay. Let's have this in here somewhere, right? Yeah. We could maybe get an individual bitmap, and that has, does that have a pixel shader? It does, actually. I don't think it does, because then you would, you need a tile grid, which will then come together with a, doesn't help you. I mean, we could do it to test it, but it doesn't actually help us get the color. Did I break it? I'm not sure. I used color converter for this, palette support would be nice, but I hadn't built it yet. Does this, you are here? I just posted on the thing, so you probably like just wires crossed me, but the, does this pixel shader? I'm assuming this is leftover. I'm starting to make a build without it and test it out. But I'm guessing that that's leftover, because of exactly what you say, which is that it uses color converter, which is different than palette. Whereas pixel shader here, I think, I think refers to a palette. It doesn't bitmap land or refers to a thing that behaves like a palette, let's say. Probably it's like technically different in a way that I don't quite understand yet, but does it, is it actually expected to work or do anything with GIFs? And if so, how do we do it? Because I actually didn't figure that part out either. If it's there, it's leftover. Okay. I will test without it. I made a build with it commented out. We will test that. Let's do frame count too, actually. We have our delays here. Frames, I, is that print somewhere down here, maybe? FPS, no. Well, it's just counting itself. Frames. Surprised the build didn't throw a warning about the unused reference. Yeah, that's actually, that's a good point. I could do a, I'll do a grep for it also. We are on the wrong colors right now. Sounded in the dictionary. Oh, the thing at the bottom down here? Like this thing, you mean? Yeah, dict table. That's true. Yeah, no, it isn't. I found it only in H. Let me, I will do a, I'll do a grep. Yeah, only one reference in dash H file. Inside shared bindings. And then my build currently has it commented out. So we will see if removing it causes any trouble. So far it seems fine. I was trying to work on transparent. I was trying to figure out if I could make this green transparent, but I, because like color converter here, color converter has a make transparent, but that works. It doesn't, it, like if we do make transparent zero, we can make the black transparent. So I have hope I have, like I'm thinking there's a good chance that like probably we could get a transparent background somehow. But I don't know what number to give this to make it happy. The zero index was my first thought. And then the zero X, like 00 ff 00 for green, that was my next thought, like, like, see here, our black is transparent now, but it doesn't work the same with green. Each frame has its own transparent. Now that can't be true, though, it's got to be shared. It's got to be shared, right? Because I did this make transparent zero here. And this makes all the frames have all the black gone. This is like none of the frames have any black now. And I only called this once. So this has to be affecting every frame. It seems to me at least. You don't look how a tile grid slash bitmap handles it. That's part of the tile grid bitmap drawing as opposed to the GIF. Yeah, well, it's yeah, I mean, it boils down to the kind of the color converter in this space in this case and the make transparent, which I don't know. I don't know how it works or how it's supposed to work, I guess, either. I definitely don't know how it does work. I don't even really know how it's supposed to work. But I know that some portion of it does work, though, that part I do know, because we did manage to successfully make all the parts that would be black transparent. And so they're showing the white through. So like if we let's make sure they're actually transparent, though, let's change this to like blue in the background or something. Yeah, so now all the parts that would be black on the parrot, they're actually showing through to the blue. So our transparency is working, we just need to figure out the right thing to tell it to transparent. I feel like it should be close to green, right? Does anything appreciably different happen if we do one? Yeah, all of our black comes back. Of course, I can tell nothing is really transparent, though. Not updating. I don't think this is updating either, actually. What are we expecting to throw? What am I expecting to show through the transparency? Do you have something behind it? I do. Yeah, the white. The white is a vector IO that's behind it. Vector IO rectangle. And so like what my goal hopefully is I'm trying to make it to where the green that's all around the outside there, we want that one to be transparent. Because if I can get that to work, that would basically bring us back to kind of pretty close to the original how the GIF was with its transparency inside of it. I know the actual transparency in it isn't supported directly because it would need all the logic about like which parts need to be dirty or whatever. But now it has backgrounds in it. But if we could then use color converter make transparent, we could kind of add that transparency after the fact kind of like we do with bitmaps. It's interesting. These don't appear like even when it's on zero, it doesn't do the same thing like it never shines through anymore. I don't think it's updating. Where's the green come from? The green I added to the GIF. The green is now part of the GIF. And to be more specific, if you're curious where it came from, I made a green box in here exported it as a PNG. And then I uploaded both the green box and the original GIF into easy GIF. And they have a setting inside of here called don't stack and then use first frame and then zero delay for first frame, which will basically make it so that whatever the first frame, which in my case was my background image there, this now becomes the background of every frame. And then because it's on zero itself, it means it doesn't get shown as its own frame, just all the rest of the frames contain it as the background. That makes sense. So that's where the green came from in my case. I added it in. I started with black actually. And we did with the black one, I was able to successfully, it was the same thing. It just like same thing we got a second ago where we were making all the black disappear. Yeah, yeah, I just, I hadn't ever used this bit before. I had to search around a bit to find this thing, but we got it going. I think what we'll do is once this gets merged in, I think we will want to update the display.io learn guide with a section for GIFs and we can have the steps for this process because I suspect people, I don't know how many transparent GIFs are out there. I assume kind of a lot like I just searched up party paired and this was the first one I found and it had the transparency in it. So I think it will be good for us to document these steps so that we have a thing for people to follow who want to make their GIFs opaque instead. Let's see also what's over there on the YouTube. Try a different RGB order. We could do that. We did have to swap it. I would think this thing should account for that. Is it different than FF because of the way it's 565? I would expect 00FF00 to work unless there was at least 65536 pallet entries. How many pallet entries? There should be 256 total pallet entries by my understanding because this, excuse me, this is, as far as I can tell, this is our pallet. I don't know if there's a better way to check it or whatever but this is the only way I know how to check it and we have 0-255. Look at GIF.Bitmap0. So I was starting down the road of pulling out the Bitmap0 so the cat has gone back to just tearing back and forth across the house. So if you hear what sounds like an earthquake in the background, that's actually just my cat running around or that for now. I had thought I'd learn guide pages to show how to use it will be good. Yeah. As we, meaning me, see what's being used for or not, we can add features. We could try to pull out an individual one. Let's do this. Let's not put that in there. So instead of 0, use the number for green. So I don't know, I'm not sure what you mean the number for green. If you mean the index for green, so like in this, in this list, green is on 0. So that 0 would be the index. If you mean the color number, like 0xff00. I did try that earlier. Like this one, we can put it back. Yeah, we can put it back. But it did not end up working. Okay, hold on because I took the, yeah, yeah, yeah, I took this out. With make transparent 0x00ff00, we do still get our green. But even if I could get individual bitmaps, like where like an individual bitmap, are they individual on disk bitmaps? Because the actual bitmap object doesn't have colors, doesn't have a palette. If you use a bitmap, meant the index. Yeah, so 0, the index as far as I can tell of green is 0, and we did do 0 in there, and that did black for us instead of green. Like if we do this one, just 0 there. And this will make the black transparent, basically. Everything that was black is now transparent. So yeah, it's like it's, it's contradictory or whatever, right? Like this makes it feel like it's doing black, the literal color, like 0x, you know, like this. But when we try green, it doesn't, if we remove the first frame, 0x is 24 bit, we need the 565 value. How do we find that? Maybe it always does black. Could be. See if this does something other than what we put in. Okay, we can try it. Sure, that's the right number still. If I remove the first frame, if I remove the first frame, I think, like I'm pretty sure I need the first frame because of the way that we used this to use like the first frame became the background. If we get rid of the first frame, then we're not going to have the background. We're going to be back to transparent like like actual transparent rather than just green. Black is 0 and what's that position? No, green is that position 0. And like if you mean in the, in here, green is that position 0. Black used to be at position 0. We did move green to be here, but currently right now with the one we're using green is that color index number 0 inside of the what I'll call the color map is what GIMP calls it. Try that 0x 07e E0. Is green some kind of special color that's hard coded? It shouldn't be, huh? No, to the best of my knowledge, there's no hard coding. I mean, like in user code, right? Like where I'm hard coding it here, like that is the special spot. That's the only place that I know of that it is hard coded. Let's see maybe it always does black and the number is the transparency. A lot of this isn't in the GIF itself in the Python code. A lot of this isn't in the GIF itself in the Python code. Try one, see whether it's still transparent. We did try one earlier. It was not still transparent. I will do it again. So yeah, when we do one, we can see the black. And I don't spot anything that has been made transparent. But I mean, if it was just a couple of pixels in there somewhere near an edge or whatever, just because I like the fading to the edges, then I probably would not know that I'd be able to see it. So for example, bitmaps without a palette. So bitmap equals that color converter, how great and then you give that as the palette basically, I need to figure out more about that. I don't really know what that I don't know how that works basically like, in my mind, like, is it a new thing that YouTube stops streaming if I switch to a different browser tab? Personally, for me, my YouTube will keep going if I switch browser tabs. Yeah. Because I use it a lot for music and other stuff in the background. So I don't have it running right now. So like, maybe it's broken right now or something, not actually checking it. But typically for me, if I am running a YouTube video, I can change to a different tab in the same browser and that video will keep running. And if I can even change to like a different window altogether, I can minimize and everything and it will still just keep playing on desktop, I will say on mobile YouTube does everything it can to not play in the background unless you have like paid YouTube or whatever. Can you toss the GIF into discord? Yeah. Not logged in. I am logged in when I do it. If you mean logged into YouTube, yeah, I am typically logged in when I do it. This is the current one that we are working on. Could be some weird internet glitch. I would not, I will try it not logged in at some point. I would not be surprised if it was treated differently, honestly, unfortunately, I don't think it should be, but Google is I'm sure would prefer you to log in basically. So unfortunately, they might make their services worse when you're not logged in. Try the palette number for green and not your GIMP palette. I'm not sure what you mean the palette number for green. If you mean like the color, like this one, we did try that earlier. It didn't seem to work. Or if you mean something else, I'm not not entirely sure. Sorry. Come on desktop, not logged in. Okay. The mobile requires premium. What does this do if you don't pass this at all? Oh, hey, we got a different output this time, which looks more like what somebody posted a minute ago. That's interesting, right? So all the colors are messed up on this one. It's like we only have green and blue. There's like no more reds. That's weird. No, the palette number that GIMP originally. I will try. I'm not sure if we have an easy way to get back to it. I guess maybe if I open the old one, I open the old one, it might still be there. I'll try. Yeah, that's a good idea. Maybe I just like isn't actually changing the index or whatever. Yeah, man, color converter. The more I do with color converter, the less I understand what it does. Like, where did our reds go? How does the default one have no reds in it? That's like, I'm so confused. Let's see. How can we find it? I guess if we open this one, it was 42 originally. Makes sense, I guess. Can you believe if that works? Setting it to 42 is what makes it work. Should be kind of hilarious. Keep watching the recording, but that GIF animation is a really great addition to CPL. I love it. Nice. Super stoked to have GIF. Yeah, when we did, one thing that is interesting, when we did, well, let's go to the docs. What is the default here? The default input color space. Default is 8888. If we don't specify, then we're going to get 8888, which is what this one did. Maybe that makes sense why reds are gone is because now we don't have numbers that are big enough or numbers that are too big or something like that, right? I guess that kind of maybe makes sense. And so then if we used 565 swapped instead, this now says converted to this though, but I want to input 8888 and output 565 default. Big small indian hurts my brain. So that gives me, this is going from 8888 to 565 and it has 0x7e0, which is similar to one of the ones we tried before, but not the exact same. Just totally put an O in there instead of a zero. That's right at all. There's one out there. Try this, make transparent E07. E007. I don't know how you knew that, but that was it. How'd you do that?  Just swap the highest bit order or whatever, the color, the color is 070e0, but the things are byte swapped to where it's becoming. Okay, and then byte swapped is each one is flipped. So the zero and the seven are flipped, the E and the zero are flipped, and then actually the two together are also flipped, so that we ended up with E007. So somehow we could get that, right? Yeah. So that's the technically the top left pixel, is that right? Of the first frame? It's not swapping within them. I may have made a typo earlier. Oh, okay. No, I don't know. I probably explained it bad, but it does, to me, it looks like they both swapped like the zero or oh, no, no, no. Okay, okay, okay. I'm with you. I'm with you. Yeah, yeah, yeah. Data, I see. I see. Yeah, yeah. Okay. The two different two sets swap, not that they don't swap in internally. So we got that from this. We can, like let's say we didn't want to count on knowing that the first pixel, this is a nice trick, I guess. If you always set up your GIF like I did, where your background is your first frame and your background is full, you know, green screen or whatever transparency color, then this actually is pretty easy because you could pass this in, right? Like we could take this. Well, let's put it back for now. We could take this and be what we passed to here, and then it should still work, right? What do we do there? Can convert string to int. Maybe we don't want hex. I don't know why it broke to REPL somehow, which is odd. There we go. Yeah, yeah, that works. But there should be, we should be able to do it without relying on the pixels too, right? Like we could use another color converter. So we pass in, we know we started with 888. That's what the computer is. And we know we want green in 8888. And so we can get that in the converter, but then can we, should we should be able to do like, how do we do that byte swap over here? Python change byte order? That would work if you don't know your background color. Yeah, using the, as long as the first pixel though, right? As long as the first pixel is actually your background color. Reverse? Is that what we need? Is that what we need? Is it? Actually, no. See it as Oh, something to think about is how the bitmap stores the color versus what the human seat is. Yeah, I would agree. That's a good thing to think about. And I, you're not necessarily understand all the ways in which it works. How do we get from a number to bytes? So our outputted value was this. So I'm trying to start from there. And how do we go back to int int from bytes byte order? Ruck unpacked. I don't know the code. If you can put the code in there, that would help me out. I don't know how to use it that way. Do this. Then bytes, bytes to little honestly, never use ripple and see why it's useful. Yeah, it's really good for testing short stuff, testing little stuff. Long story short, the gift parser reads a gift, which has a palette and converts it to our maybe 565 little Indian. So it gets stored in the bitmap object reading left to right as a human seems backwards. But that's how the display reads them. We could parse the gift into RGB 565 big Indian reads more like human left to right. But the color converter has to swap the bytes. Did it this way with an ion future optimization to Talgrid and the converters. We don't have to convert the color at save time. I gotcha. Yeah, I'm pro whatever is fastest. I think as long as we can provide sample code for people to be able to do make transparent to whatever color they want, like once I figured this out, what the process is to go through this, I'm definitely pro whatever is the fastest way. I'll take a speed at the expense of user code has to swap a few things around. I think that's totally fine personally. It's not up to me all the way. But that's my take on it, at least back to the wrong thing. One of these supposed to be big. There we go. Okay, so I will say no, I was thinking was wrong. Okay, so if you know your color is green, you can go convert my color in my 888 color converter. From there, we can take it to bytes, big Indian, we can then go back to a little Indian there. And we're then ready to pass it into here. And it works. So this kind of pipeline gets us from our hex on the computer are 888 that we're getting from here into working inside of here. So that I think is fine. It might be nice if color converter had a helper function that could help you with this, right? This feels like a thing. It feels like a common thing that you would want to do, right? Like, I guess the crux is here, though, that the GIF reader has like inside of here, it's done the conversion from 888 to 565. It sounds like unpacked with optimized state. Yeah, it is.  Okay, that's how we can use that one. So now when we go to bytes little, and then we go unpack from there. And then though, I think would we also need to go or is no, that's just the number. Yeah, okay. That's not right. Here we go. Oh, that's the wrong color converter. Yes, the wrong color converter. There we go. Yeah. She's the wrong one there. So if you know your transparent color, you can use an 888 color converter with struct or with two bytes from bytes, in order to tell it to make that color transparent. Or if you set up your GIF the same way I did where the first pixel of the first frame is the color that you want to use for transparency, then you can do it the bitmap way, which is actually like, probably more convenient, truthfully, right? Like this is one way. If you know the color, but if you know that first pixel is going to be what you want, then this is like, even way more convenient, right? So you can just go GIF, bitmap, zero, that works. Those are your two options there. Okay, you should make it make that into a function into the GIF library. It would be nice to have a helper function somewhere for sure. Yeah, I would agree. I don't know if it needs to be in the core. I'm hesitant to put it in the core. I don't think we need the speed of the core, but maybe the core is the best place to put it so that it can just be inside GIF IO and not need another library or whatever. The thing is, off the top of my head, I would think to write it in Python just like I did, but we don't really have a Python library that's in the mix here with GIFs, so not really a good place to put that Python code necessarily. I'd be happy if color converter, now, I guess, I don't know how, I'll have to look at, look at internally how it works maybe. Could it not be the case where you pass this in? Could it somehow work where you can make a conversion and give it the color space? Like, could it, instead of declaring it when you initialize it, could it be something like you know, cc.convert and then my color and then input the 8881? If we could do this on the convert call, then we wouldn't need the second one at least. That would basically make it to where the single color converter could basically do this for you. Yeah, we'll have to figure out the best place to put it. Probably could expand color converter. So I understand it though correctly just to double check. The GIFs will always be 565, right? You said it converts internally to 565 inside the GIF and then depending on your input, like maybe it's swapped or maybe it's not, but that depends on your input somehow. If that's the case, then I think maybe GIF, maybe the GIF object or inside GIF IO is probably the place you have some kind of helper function, since GIF is actually the thing technically that's converting it from 888. And then we're using, and I'm confused where the color converter, I really need to figure out color converter better just so I fancy the LED has color conversions. Okay, we'll have to look in there. Maybe there would be a more direct one. GIFs are pallets. I saved them as RGB 565 and the library converts them for display. We'll have to think about where that makes the most sense. If it's in the core or maybe it's like we make a Python layer for GIFs as well, like we have image load for bitmaps, which is like a Python layer for showing bitmaps, for loading them into memory specifically. We're not doing with the GIFs. The GIFs are on disk rather than memory, so it's a bit different, but maybe we need a GIF Python library as well for some of the helper stuff. I don't know. We'll have to think about where's the best place to put it. But I think I'm going to wrap it up there. We're a little bit about 20 minutes over two hours, so feel free to ping me later with questions or thoughts. Yeah, so far, I mean, so far everything looks good to me. The one that I did already comment was the pixel shader is the only thing so far I found that does seem extra. We did make a build with that commented out and it is still working. I'll go back and delete it and make a build. Try it like fully gone, but I mean theoretically it should be gone already because it's commented. So removing that is the only thing I saw as far as like potential change. Everything else seems good to me. Functionality seems all good to me, especially we got it worked out doing transparency now, which I think is super sweet. Yeah, thank you by the way. Yeah, huge hug report for Mark for working on this for folks that don't know Mark Gambler in the chat there is who did the work to make this work inside the core to make gifts actually be a thing that can happen inside Circle Python. So huge thanks, hug report for that. Thank you to everybody for watching. And yeah, I'll be back tomorrow morning if anyone is interested. I think I probably will not be working on this stuff directly. I got some other stuff in mind to work on tomorrow, but I may still change my mind too, so I don't want to say what it is right now. But I will be back tomorrow morning at 10 am central time over on my own channel. If you want to follow along with some more circuit Python stuff. I hope everyone has a good night. The good you know have a nice rest of your evening or day whatever time it is for you. And yeah, I will see you back here next Friday if you don't want to follow up tomorrow morning with me. We'll be back at the same time same place next week as well on the Adafruit channel here for deep dive. Otherwise that's going to do it. So yeah, see you later everybody. I will say real quick again, thanks for hanging in with all of the technical difficulties. Was bumpy there for a little bit. Luckily we kind of got it going and it didn't really wreck us anymore after the second time. So knock on wood, hopefully we won't be having that issue. But yeah, thanks for hanging out and especially hanging in there during all of the...


St. Lucia and the wider region are paying glowing tributes to the late Gordon Butch Stewart, who died this week. The founder of Sanders Resorts International established three of its 15 all-inclusive luxury Caribbean resorts in St. Lucia, employing some 2,000 island residents. Tourism officials hail him for his significant contribution to the vital sector. More in this report. Gordon Butch Stewart, the man behind the largest contribution to St. Lucia's tourism industry from the private sector, has passed on. The all-inclusive resort pioneer and founder of Sanders Resorts International died on January 4th, 2021, at age 79. Prime Minister Alan Chastney eulogized Stewart as a visionary, recalling the impact of the hotelier's business on island, beginning with Sanders Regency. He came in and he did the most remarkable job of transforming Sanders Latok, which really was a hotel that was a beautiful hotel, but was always under-delivered. I mean, if it had a 30% or 40% occupancy, that was a lot. And Mr. Stewart transformed this completely and put St. Lucia on the map. You know, prior to Sanders coming to St. Lucia, you would spend 15 minutes trying to explain to people where St. Lucia was. Afterwards, you would go to Chicago, to Charlotte and all these cities, and all of a sudden, because there was a Sanders in St. Lucia, people knew where St. Lucia was. The island's tourism minister, Honorable Dominic Fede, hailed Stewart a legend who will be genuinely missed. The world has seen Caribbean tourism in a way that Mr. Stewart has made such a significant difference. And, you know, I'm always very proud whenever I travel in global forums, and I see that a homegrown Caribbean company is the world's leading all-inclusive company. It's a source of inspiration for me, and it tells us what we can do in these islands if we believe and we have the courage to fight to get what we want. And he will be thoroughly missed, very strong leader. Recognizing the trailblazing efforts displayed by Stewart in the local sector for almost three decades, the St. Lucia Hospitality and Tourism Association president, Carolyn Trebettscoy, also offered tribute saying, quote, we have lost one of our most revered and respected Caribbean tourism icons. Gordon Butch Stewart was a pioneer and a perfectionist of an all-inclusive Caribbean hospitality model that other brands could never copy or come close to. The success of the brand over several decades speaks for itself. We must also thank him for his mentorship of and the countless career opportunities he created for Caribbean nationals surpassed only by his considerable philanthropic work through the Sandals Foundation, end quote. Sandals Resorts employs approximately 2,000 individuals on island at four properties. Sandals Grand St. Lucia Spa and Beach Resort, Sandals Halcyon Beach Resort, Sandals Regency Golf Resort and Spa, and the Sandals Golf and Country Club. Mrs. Stewart has no doubt contributed significantly to the development of tourism in St. Lucia. He's been here since 1990, and he operated some 800 rooms across three magnificent resorts. There's about 2,000 people and create business opportunities for hundreds of small, medium and large businesses. On the regional front, the Organization of Eastern Caribbean States Commission also described Stewart as a visionary and stated that his brands gave prominence to the Caribbean with its, quote, extensive international marketing and the extraordinarily high standards of hospitality and customer satisfaction that he defined, end quote. In Miami, acting CEO and Director General of the Caribbean Hotel and Tourism Association, Vanessa Ledesma said, quote, our industry will forever be indebted to Butch for his continued passion for excellence and legendary Caribbean hospitality. His vision has bestowed to the global industry a Caribbean organization that adheres to the highest standards of excellence, celebrates and promotes the region's uniqueness and invests in the development of our people and communities, end quote. Prior to his death, Stewart was reportedly working on resort chain expansions in St. Vincent and Curacao. He is survived by his wife, seven children, 12 grandchildren and four great-grandchildren. For the Government Information Service, I am Jesse Leance reporting.


Welcome to module 21, completion of a metric space. We have defined the concept of what is a complete metric space. So we want to now define what is the meaning of completion of a given metric space. So we shall describe this construction, a process which assigns to each metric space xb, another metric space x hat d hat that is the notation we have said such that the first condition is this x hat d hat is a complete metric space. It has to do something with the given metric space after all. So all those conditions are explained that in the 1, 2, 3 rest of them. So there is an injective mapping eta from xd to x hat d hat which is distance preserving. In fact any distance preserving map is automatically injective that we know. So injectivity is emphasized here but this is a consequence of distance preserving. The image eta x is dense in x hat. Any isometry f from x1 d1 to x2 d2, x tends to a unique isometry f hat from x1 hat d1 hat to x2 hat d2 hat. So this is what I meant by instead of just you know describing x hat d hat it is a process ok. So I cannot explain it more than that but I will use just to throw it over this is like what one calls canonical or categorical you know it is like a functor and so on ok. So that is the third part here. Any isometry f1 f from x1 to x2 extends uniquely from x1 hat to x2 hat. The fourth one is if xd is already complete then eta itself is an isometry. In other words up to isometry we are not doing any new thing here at all. It is the old xd itself. Something is already complete then there is no completion. Completion itself you know xd itself is its completion. So in what sense isometrically because the construction has to be there for more general space general thing then you have to in the special case it will not be just xd but some copy of xd copy means what again isometrically. So this eta itself is there the canonical embedding of that that will be surjective that is all ok it is injective it is isometric it is surjective the inverse will be also isometric. So these 1, 2, 3, 4 explain the relation between x hat d hat and xd the one which we have started with ok. So let us start with the construction. So this x hat d hat will be called completion of xd that is all. One point I want to remind you if you have done the metric completion of R in your analysis then the process that I am going to do is half of that work only 50% of that work. The metric completion of R starting with Q is exactly like this in the first half and then there is more work to do there. We have less work to do on the other hand if you have not done it at least half of that part you will be learning today. I will not do the other later half but I will later on if time permits I will just explain how that is also done in the case of real numbers. So what I mean to say is here you start with the rational numbers with the standard metric namely distance metric that we know that is not complete right. When you complete it in this process what you get is real numbers. This part we will not prove now ok we will only show the process of constructing the real numbers is similar to this one that is what I want to emphasize that is all. So the motivating fact is the following suppose we have two sequences A and B and in X such that both of them convert to the same point X then of course the first thing is both are Cauchy sequences moreover both the sequences are coming nearer to that point after certain stage that is the meaning of that right. So in particular they will be nearer to each other so how do you express that there exists epsilon for each epsilon there exist n such that after that so m is bigger than equal to a the distance between a m and b m the same m ok this will be less than epsilon ok. This all that you have to do is you have to use triangle inequality here so I will leave it to you to verify this one ok two Cauchy sequences converging then they will be nearer to each other by this definition ok. So that is the starting point which just means that you could take instead of X you could take a neatly chosen Cauchy sequence since there is no way to choose a particular Cauchy sequence what you would like to do is take all sequences Cauchy sequences converging to that point to represent that point. Now when that point is missing since that point is there for every Cauchy sequence then it is complete already when that point is missing the Cauchy sequence will be there still look at all the Cauchy sequences how to pick all of them they must be nearer to each other so that is all we come to this one take X X twiddle denote the set of all Cauchy sequences a n in X now I define a function X at X twiddle cross X twiddle to 0 infinity by the formula d twiddle of a b this a and b are now Cauchy sequences ok take the limit of d of a n b n as n tends to infinity so this is motivated by that if a n and b n were converging to same point then this distance would have limit of distance would have been 0 so that is our motive in general what we do we take this distance to measure their measure the distance between them so this is the measure that is what the d hat of a b so d twiddle of a b the limit of d of a n b n as n tends to infinity now here I want to caution you why this limit exists both a n and b n are Cauchy sequences therefore whether they are convergent or not they are bounded ok when you have both of them are bounded this limit will exist all right so that is our idea ok otherwise you can directly verify this d of a n b n minus d of a m b m ok by use use triangle inequality correctly this difference modulus is always less than equal to d of a n a m plus d of b n b m now if n and m are very large we know that this is less than epsilon these are less than epsilon or both of them are less than epsilon by 2 you can remember ok so here a n b n a m b m this will convert to 0 or some number because you do not know what this number is ok so if they are if they are Cauchy sequences and so on you can you can at least whatever I want to say is this is Cauchy sequence of real number it converges to something both of them this inequality is there so this will be convergent sequence that is all now by the very definition if you interchange b and a here b and a you will interchange the number is the same so limit will be the same so it is symmetric for each a b and c 3 sequences distance between a and c is limit of this one but a n to c n you can write it as a n to b n plus b n to c n so each term can be replaced by some of two terms when you take the limit it is the limit of the the sums right which is some of the limits so therefore what you get is Cauchy inequality d of a n c n is less than d of a n b n plus d of b n c n when you pass to the limit you triangle inequality for d it will triangle inequality is true symmetry is true it is a non-negative function the only thing is why d of a b 0 will imply a equal to b that is not true that is obviously not right you can take just you know just one of the elements you can change same sequence it will have same limit the first element you change the limit will be the same thing so this is not true at all ok however the only thing that is not true is that the positive definiteness positivity is of non-negativity still true the definiteness part is missing here the d 0 is missing here ok d 2 d 3 axiom for d 2 d 3 is true ok so the only thing which means to be d 1 this is one of the exercise given to you earlier if you have spent some time on it even if you have not solved completely these things should be easy for you to understand now in any case whatever is needed here in the proof of this theorem I am going to explain it ok so what we are going to do we make a relation on x hat on x vertical by saying that a is related to b if and only if d hat of a b is 0 just because d hat of a b is 0 does not imply it could be so we are making this relation otherwise there is no need using triangle inequality again you can check that this is a equivalence relation symmetry is obvious by the definition because d hat is symmetric function d d twiddled is symmetric function ok reflexivity is obvious d hat of a a is always 0 alright if d hat of d twiddled of a b is 0 and d twiddled of b c is 0 then you should see that d twiddled of ac is also 0 by triangle inequality that is all so this relation is an equivalence relation let us denote this by square bracket a the class of a the equivalence class of a ok so all Pochini sequences represented by this a they are all what equivalent to in this sense d hat of a comma b is 0 for all b in this class ok let us denote all these equivalence classes by a hat x hat denotes the set of all equivalence classes now I want to modify this definition d hat d hat on two equivalence classes is nothing but d twiddled of a b where a and b are representatives let us put this one to say that this is well defined what I have to do I have to show that this right hand side is independent of what representative I choose so they are all same then this left hand side can be equal to right hand side makes sense otherwise if d hat of a comma b keeps changing as you change the representative then this will not be well defined right well defined as means that so whenever you have choice in the definition you have to you have to verify that the whatever you have taken the right hand side is independent of the choice so suppose a is equivalent to a prime b is equivalent to b prime we must show that d hat of a b same thing d hat of a prime b prime d hat of a a prime is 0 that is the meaning of a is equivalent to a prime similarly d hat of b b d twiddled of b b prime is 0 right because b is equal to b prime again by triangle inequality d hat of a b is d hat of a prime b plus what plus d hat of a a prime so a to a prime I change so a a prime plus this one but a prime is 0 so it is just this one now I am from a a prime a prime b 2 I go to b prime by taking d hat of a prime b plus so a prime b prime plus d hat of b b prime but d hat of b b prime is 0 so this is less than this one so one is less than we could this but this symmetric argument I can start from here and that is less right so they are equal so that is what we wanted to show so you see all once the idea is there all verification is very canonical very easy therefore d hat is well defined and takes only non-negative real values why because d twiddled has that property now d twiddled symmetric also it satisfy triangle inequality also therefore d hat will also satisfy triangle inequality in that one the only thing is why if d hat d hat of you know a a is also 0 that is also clear but d hat of a b is 0 why does it imply that d hat of d sorry a and b are equal that is just a definition that is just a definition equal means what here they are equivalent you see equivalence class is same so this is trick you are using to get equality okay so this here equality is just equivalence classes alright so d hat becomes a metric on x hat alright so this first part is over as you have constructed this one now take a n to be a Cauchy sequence in x hat each a n is a is a Cauchy sequence right the equivalence class is one single element now you take a Cauchy sequence of that okay the Cauchy sequence in x hat let us denote the sequence a n a n is a sequence now okay he is a n m so multi index your views for each fixed n take a n m from 0 to infinity some people write it as a top but I do not want to do that because that may confuse if they are real numbers then the power has something some other meaning okay so for each n n choose a kn such that d of a n kn comma a n m is less than 1 by n so this is where I am using the fact that each a n is a Cauchy sequence okay so it will be less than 1 by n when for some choice of kn large enough for all m bigger than this one this should be true so this is where I have used that each a n is a Cauchy sequence okay this is the first step now look at the sequence a n equal to a n kn this is one element of a n of this sequence which one I have done what is the kn choice of kn it should satisfy this one okay for n 1 for n equal to 1 a 1 k 1 comma a 1 m where m is bigger than k 1 will be less than 1 for 2 it will be less than 1 by 2 similar like that is the meaning of this okay successively you have to make it more and more accurate all right claim is this sequence now this sequence is a sequence in x okay capital a n is a sequence in x these points are in the x right this sequence is a Cauchy in x and its equivalence classes okay sorry this a n is a sequence in here this converges to the equivalence class of this sequence inside x hat okay x hat is what equivalence classes of that this square brackets okay it started with a Cauchy sequence in x hat I have produced I am producing a Cauchy sequence whatever this is an element of x hat anyway the class of Cauchy sequence so that will be the limit of this one so that is the meaning of that is x hat di hat is complete every Cauchy sequence is convergent so this is a claim okay I have to show I have to do this one so the most of the work goes here that showing that it is complete here all right so let us carefully see that how it is coming here is a picture this is your a1 I have chosen this red point here somewhere this is a1 k1 this a2 this is a2 k2 a3 k3 and so on a n kn is this sequence okay so these are all sequence a1 a2 a n what is claimed is this sequence okay is a cluster point of all this namely all these things after certain space in this after certain stage shown here some epsilon ball here actually this is of epsilon by 2 ball so this radius is epsilon all of them are within this the tail end of this one these points may be somewhere the tail end for all of them will be here so something may be here omitted many things are here or omitted but the tail end so the tail ends are here that is the meaning of this one given any epsilon ball so this is what we have to prove this is a picture you can keep it in mind that's all all right so given epsilon that is this is the ball given epsilon tail end I have to find such that this fits all the sequences after certain stage both both ways that's what I have to choose the first choice is given epsilon choose the n1 itself n1 it's the 1 by n1 less than epsilon by 3 you can choose epsilon by 4 also if you want to be careful okay so here there is no nothing this is just real numbers property since a n okay is Cauchy in x hat okay there exists an n2 such that d twiddle of ar as is less than epsilon by 3 for every ar as less than n2 remember this d hat was nothing but d twiddle of the representatives okay these are classes ar you should put a bracket here d hat of ar d hat of d hat of ar and as here brackets that is less than epsilon by 3 is the statement for r and s bigger than equal to n2 but I don't have to put hat here I can directly put d twiddle of ar and ar remember ar and ar themselves Cauchy sequences and what is the definition of d twiddle d twiddle was the limit of as n tends to be arn as n of the original distance between ars and asn okay so finally everything is happening in the metric space x now you take the maximum of this n1 and n2 okay that is n3 I want to show that ar ar as is a Cauchy sequence first of all I haven't yet shown that without that it will not be it's not been x twiddle so it will not be inside x hat the first thing is to show that a itself is a Cauchy sequence that means what for any epsilon I must find a r and s such that the distance between ar and as is less than epsilon right or epsilon by 3 whatever you want to say so that is what I would show to fix ar and s where bigger than n3 for all of them I must show that d ar as this is ordinary distance between the the metric this is the points of x now right is less than epsilon I want to show okay so how do I show that so starting with these choices you see r and s are bigger than n3 so they will be bigger than n1 and n2 so both both these hypotheses will be applicable to d twiddle of ar as is already less than epsilon by 3 because of n they are bigger than n2 okay so this implies that there exists an n4 now I am using the definition of d twiddle because it was taking limits right the limit is less than limit is less than epsilon by 3 that is what I have to show that is what it is so d of ar m as m for large enough m is less than epsilon by 3 r and s are fixed here it is the variable here is the index is m okay for m sufficiently large namely n4 there is some n4 okay so this is one equation okay now you choose m to be bigger than m is bigger than all the time if some it has to be bigger than something I can choose it even bigger than that m to be bigger than k r k s and n4 okay then you can apply both this what is this 18 here see for this one m should be bigger than k r k n right so I am applying it for n equal to r so it will be bigger than k r applying it for n equal to s should be bigger than k s so I am taking it bigger than k r k s as well as to satisfy this bigger than n4 also okay so both 18 and 19 are available to me so I just use triangle inequality now d of ar s what are ar s by definition ar k r as k s so this is the ordinary distance of the metric metric space x right so triangle inequality right it is three different similarly ar k r to ar m okay where m is chosen to be larger than all these plus ar m to asm jump to sm from asm come back to asks so this is triangle inequality okay this is less than or this one from 18 these two things will be less than epsilon by 3 from 19 this should be less than epsilon by 3 so totally less than epsilon so this is a Cauchy sequence is what we have seen the next task is that the original sequence of classes a n converges to the class a that is what I have to show this what okay look at d of a n m and a m what is a m remember this one it is little a m k m right so that is whatever it is this is a number this this is just an element of x they are all elements of x so d of a n m makes sense it is less than d of a n m to a n and then a n to a m so this just triangle inequality okay now the first term on the right hand side this one is less than 1 by n for m bigger than k n right this k n was chosen such that look at this very first choice a n k n a n m is less than 1 by n so that I am applying it here okay so this term is less is as soon as m is bigger than k n this term is less than 1 by n all right this this term the second term can be made any more smaller than any anything once you choose n and m large enough that is right large enough this one this can be made less than m and n because just now we have shown that this is a Cauchy sequence therefore d hat of a n a a capital a here sorry the class a which is by definition 1 d twiddle of a n and a which is again by definition limit as m tends to infinity of d of this sequence a n m and the other sequence a m now here m tends to infinity okay each term is less than epsilon the limit will be less than epsilon after certain states all right so limit will be also less than epsilon okay so for this will apply when n is large enough because I have I have an n here okay so this is epsilon but I have to make a this n less than epsilon by 2 to make it epsilon epsilon so n must be large enough how large 1 by n should be less than epsilon by 2 that is all therefore if this is true for every epsilon look at here this is one sink one one single number here this less than epsilon for every epsilon therefore the limit as n tends to infinity this part d hat of a n a okay is 0 for for large n this is less than epsilon so it should take the limit of this one this should be 0 that is precisely the statement that this this sequence converges to this one okay when does a sequence x n converges x in a matrix space distance between x n and x limit is 0 okay so what we have done we have just completed the the construction and property 0 that x hat is a complete matrix space now we have to verify 1 2 3 4 they are all easy all right hard work is already done so it remains to prove that 4 properties 1 2 3 4 okay so first thing I have defined eta eta of x to x hat that is what I have to define given any x belong to x consider the constant sequence x x x x the nth term is x look at that sequence that is obviously a course is sequence take its class that is an element of x hat okay so this way I get the function eta x is the class of cx obviously eta is injective okay y suppose eta x is equal to eta y cx is in the same class of cy what is the meaning of that that distance the limit of that you see you have to take the limit is equal to 0 but limit is here x y x y d of x y x y so limit itself is d x y that is 0 means x equal to y x is a matrix space okay so this is a this is clearly a injective mapping okay actually we shall prove that we can check that its distance preserving what is the meaning of this take two points x and y cx and cy distance is also d x y so that is the meaning of this distance d hat of cx cy is equal to d of x y because it is both of them are constant sequences okay so it is automatically distance preserving and hence injective mapping what is the second thing here I forgot what is like eta is dense inside x hat the image is dense in x hat take any open ball in x hat you must find a point eta x inside that which might intersect eta capital X so that is the meaning of that right density of eta x okay so here it is we shall prove that every open ball in x hat intersect eta x okay given xn a sequence cosy sequence and its class okay take a r positive and take an open ball around that of radius r okay I want to get an element of the metric space so that the constant function constant sequence the its class of the constant sequence is in that ball that means its distance from xn to that must be for less than r so for that choose a k belonging to n such that this is a cosy sequence d xk xk plus m is less than r for all m okay once you have chosen k for all numbers bigger than k also is easily true so this is definitely true for k k and x k plus m less than r for all m now it follows that once you have chosen this one look at the constant sequence xk that sequence okay has distance less than r from d hat of xn okay so that is why this eta of xk now it belongs to this open ball okay finally take any two metric spaces and an isometry f that isometry itself extends to the whole of x hat to x1 hat to x2 hat so this is stronger than saying that you know x1 hat is unique up to isometry that is the meaning of this that that that is what we want to prove but we are proving say x is strong the actual isometry each isometry extends okay so how do we prove that isometry means distance preserving look at the construction of x1 hat and x2 hat it just depends upon the metric there that is our so in isometry it should metric equivalence right for everything it will be cosy sequence preserved everything will be preserved equivalence and preserved that is why so that is what you have take a sequence cosy sequence in x1 f hat of a which is f of an that sequence that will be cosy inside x2 even even just similarity would have given you this one right here we have an isometry okay since isometry preserved cosy sequence is first of all f hat is well defined from x1 to x2 to x2 okay here take a cosy sequence f of that will be a cosy sequence here okay now you see that this f hat is an isometry of the corresponding d1 twiddle d2 twiddle the pseudo metric spaces the d2 twiddle distance is preserved by this f hat f twiddle d2 twiddle of f of an f of bn by definition the limit as n tends to infinity d2 of f of an f of bn each f of an f of bn is the same thing as d1 distance between these d1 of a and bn right because f itself is an isometry its this limit is d twiddle of a b the given sequence a and bn so that in the meaning of that f is you know distance preserving from d1 to d2 d1 twiddle to d2 twiddle okay clearly f hat also preserves equivalence relations and hence defines an isometry f hat from x1 to x2 why this preserves equivalence what is equivalence an is equivalent to bn if the limit of distance between a and bn is 0 right distance between f of a and b also 0 limit so so everything is preserved that is what you have to verify so you get a map from f twiddle to f hat here from x1 hat to x2 the class here goes to the class there okay and the distances are distances in di at the same thing as distance we have defined for representative so they are preserved so it is preserved so it is an isometry or not so the net conclusion here is the construction depends only on the isometry class of x1 or x whatever starting with if x1 and x2 are isometry x1 hat and x2 hat are isometry okay the last one is suppose x itself was complete then I have to prove that just I have to prove that this eta is surjective then eta itself is an isometry okay so why it is surjective take any xn in x hat okay the class represented by a Cauchy sequence xn in x that is the meaning of this x hat right since x is complete it has a limit this xn has a limit this limit is independent of the Cauchy of the equivalence class all the sequences whatever sequence you take here okay representing this one they will all be convergent they will be convergent to the same x because the distance limit of distance between xn and yn that itself will be 0 so if this is x and that is y x will be equal to y so there is a unique limit here inside x okay now very easy to verify that the constant sequence Cx itself the equivalence class itself will be in the class of xn so you have to show that these two are required what is the meaning of that distance between xn and this Cx that is tends to 0 but that is the definition of that xn converges to x okay so that is the meaning of this one so this just shows that eta axis equal to the class xn so eta is circuit okay so that is more or less completes several things that we have in mind about metric spaces that does not mean that the study of metric space is completed there are many things but now onwards we will concentrate more and more on general topological spaces bringing in metric spaces only to strengthen the results that the topological results will give you about metric spaces okay any questions here are some exercises all straightforward exercises nothing to do with completion of course okay just ordinary exercises this is about the product finite product of metric spaces all right this is about again finite many things then you have to want to take it as the maximum metric just like l infinity norm you can do l infinity the d infinity metric here the d infinity corresponding to maximum that infinity is involved okay so that is the next chapter now so if there are no questions we will stop here thank you