 Okay. Hello everyone, and happy Friday. Looks like I have got sound into OBS at least, so I think we should be good on audio. That looks like the right setting there. Let me shuffle some windows. Sorry I was a minute late here. I was just about to get going, and I decided I wanted to make a coffee really fast. Here noises. Yeah, that was probably me. The microphone, it's directional, but it was pointed in the direction I cracked some ice. My guess would be that was the sound, if anybody heard a loud sound. How's it going? See Grover and DJ Devin to Shippu as well. And then over on YouTube, how's it going? And happy Friday out to Devo Dessa, Biata, Snaky Maker Cat, and Biata is there too. Okay, we said that one. So let's see. Quick introduction for anybody that might be new. Sounds good, and video is on YouTube as well. Thank you. Audio is Good Stream Live. Nice. Thank you. Appreciate the heads up on the audio. Hello everyone, my name is Tim, and I go by FOMAGuy on the GitHub and Discord. This is the deep dive program. How's it going PaulSK? Happy Friday. This is the deep dive program. This is a weekly stream that occurs on the Adafruit, Twitch, and YouTube, as well as other live streaming platforms. In this stream that happens weekly, we are diving into the depths of CircuitPython. We are looking at either libraries for CircuitPython or projects that are made with CircuitPython, or sometimes diving into the CircuitPython core itself, which is the C code that makes up the actual core language that runs on the microcontrollers, the interpreter that runs on the microcontrollers. We do varying levels of depth just depending on what I happen to be working on for the week. I'll pull this back over here. We can look at this while I introduce it here. For anybody that might be new though, if you don't know what I'm talking about, if you're unsure what CircuitPython is, or if you want to learn more, a couple of things I can recommend. One of them is go over to circuitpython.org. This is the main website for the project. You can go here to learn more about what the project is and how to get involved with it if you're interested, or how to get a device that runs it, or you can check if your devices you already have run it. We have 331 boards supported, so there's a good chance if you have some kind of microcontroller or something. There's a good chance that we do already support it. It's not 100% of every device, so you can come here, you can search, see if we have support for your board. More generally speaking though, if there's anybody brand new to all of this and you don't know what CircuitPython is, this is a version of Python that's designed to run on these tiny computers. They are called microcontrollers. There's a bunch of pictures of them here on the downloads page, so they're all different shapes and sizes. They have different things built in. They're kind of made for different purposes, different price points, different form factors. All these things differentiate all these different devices, but the thing that ties them together is the fact that they can all run CircuitPython, which is this version of Python again that runs on these devices and allows you to edit your code file just directly right on the device as though it were a thumb drive. I just open it up in a text editor, write your Python code inside there, control S, save that text file and it will automatically run for you. You don't have to set up any complex tool chains. You don't have to install any kind of drivers or do anything like that. You just open up the file, edit the code, save it and it runs and that is what CircuitPython is all about. Of course on this program we are working at a deeper level, so in this case we are sometimes setting up complex tool chains in order to build CircuitPython or in order to build and test the library documentation and different things like this. What you'll see in this program, the deep dive program, is not necessarily the high level easy peasy stuff. We are kind of really trying to dive into the nitty-gritty and clean stuff up and make it better so that folks who are working at the high level easy peasy have a good time and don't run into weird trouble and stuff like that ultimately. If we can make it as easy as possible for newcomers, that's kind of the goal of the whole project is being nice and friendly and easy to pick up even for a person with no programming background or no electrical engineering background at all. The goal is that they would be able to pick up CircuitPython device and make something interesting from it relatively quickly within a couple hours or something in most cases. That's what the project is all about. Again, if you want to learn more, CircuitPython.org is the place to go. I will say it is an open source project. Thank you to all the folks who helped contribute to it over on GitHub. Everything, all the development happens out in the open over on GitHub. Thank you to everyone that contributes in that way. If you'd like to get involved in doing that, if you're not already and you want to get involved in development, join us over on the Discord. The link is down below somewhere over here. ADAFRU.IT slash Discord, head there. That's where all of the team that works on the development as well as the larger community is hanging out. Come over there, say hi. Let us know if you want to get started working on stuff. We can definitely help get you pointed in the right directions. Then if I will say as well, it's an open source project, but it is primarily funded by this company, ADAFRU. Of course, this is who's YouTube and Twitch we are on right now. Thank you to ADAFRU for providing the funding for the CircuitPython project by paying the folks who are working on the project. There's a team of folks who work on the project full-time that are paid by ADAFRUIT. There are some folks who work on the project part-time, such as myself. We are also paid by ADAFRUIT to work on it, to work on the libraries, to work on the core, to work on projects related to it, learn guides, documentations, updates. ADAFRUIT is paying us to work on the stuff. So thank you, huge thanks to them. And then as well, thank you to anybody who wants to purchase hardware from ADAFRUIT to help support, of course, the development of CircuitPython. So thanks to all those folks for that. How's it going? Have bored? Newbie to watching live here. Nice. Welcome in. Thanks for tuning in. This week, let's add Wi-Fi access point functionality in the CircuitPython web workflow with a new entry in the .mfile fingers crossed. Unfortunately, that is not at least what I will be working on. I don't necessarily have any kind of update or anything on that front, but that is not what I will be getting into. I have a couple things in mind. One of them is going to be following up on this PR in the EMC 2101 library, which is about fan controllers. I think this is right, PWM fan controllers. So it's a little breakout board that can drive like PC fans, essentially, right? We'll pull up this page real quick here. 2101. And there we are. So it's a little Stemma-ified breakout, right? It's got the Stemma plugs. This one is not hooked up via Stemma. It's using the breadboard with the side pins and everything, but it's got a Stemma breakout on there. And then you can hook up the other side to these little PC fans or like laptop fans, these little PWM fans like this. And the chip can do a couple of different things. It can turn the fan on and off. It can turn the fan to different intensities, so like 50% power or whatever, right? Stuff like this. And then it can also, it can have feedback from the fan. The fan can have, I think, what's called a tachometer. Is that the right word for it? I think so. Basically, there's a thing that can measure the RPMs or something like that, something, you know, essentially measure how fast the fan is running. And this can be fed back in through the wire, through the breakout board and ultimately to the microcontroller. And so in this case, what you can see is like it's spinning. This person puts their finger into it and then the RPMs drop drastically because now they're pressing on it and it's making it spin slower. So that's what this device is. There's a PRN that added a bunch of stuff to this library to allow for more functionality that was built into the main chip on this breakout. There was functionality inside this main chip that we did not currently have in the CircuitPython library yet. So that's what this PR is adding. And I'm gonna be following up on that. And then afterwards, with whatever time is left, we are getting back into Flip Clockland. We're gonna try to document, clean up the sprite rendering scripts and then maybe also render some smaller scripts and see if we can figure out if there's a viable size that we can use the Flip Clock on like a PyPortal, which has less memory than the ESP32S2, which is the first thing I put it on. So if we can, we're gonna make one with fewer frames in the animation. And then hopefully that will make the sprites small enough that the PyPortal can actually load them and we can have it on that device as well. So we'll play with that afterwards. I think I have one of those, Biotta. I guess you mean the fan controller here, probably. Axl Magnus, how's it going? Hey, I'm from Europe. Appreciate you tuning in. Devon's Workshop went from Blinken and LED to designing my own PCB in six months. Adafruit Discord community is amazing. That is awesome. That is super cool. Yeah, I have not gotten too much into the PCB design myself. I've kind of dipped my toes ever so gently, but I have not actually created one and got it in order and stuff like that. This is something I would like to get into, but so far I stick mostly at the software level and then just plugging stuff into these boards. That's kind of my level of depth on that front, the electrical front. For folks that don't know, my background is I came through this, came at this through software. So my day job is a software developer. I write web applications and Android applications during the day and I got into CircuitPython and this is yet another thing I can do with code. I can control stuff in the physical world with code, which was a new and fascinating thing to me and still is. So that's kind of the angle I come at this, very much so from the programming perspective. And I am still a newbie, a beginner learning the electrical side of things, the circuits, the electrical engineering, the PCB layouts, all of that kind of stuff. Okay, so this PR is a pretty big one. It's from a little while back and I think it's had a bit of activity in the last couple of days that I haven't seen. So there's a long history on this. If anybody is interested, it's pull request number 23. You can go find it over on EMC 2101. Hey, that's where I'm coming from, nice. Yeah, there's a long history, so I'm not going to read through the entire history here, but the most recent stuff is this person was kind of basically just saying, hey, I can't wait to use this. It looks really cool, kind of hinting at, I wish I could test it, but I don't know how. And so I had written them back to say, if you're still interested, yeah, yeah, to let them know how, basically. I tried to explain how they could check out the code in order to actually try it if they wanted to do that. If they will, that was actually still a while back, so that person may or may not come back. And then it looks like we've got some additional commits that came in after, which I have not had a chance to see these yet. So we'll take a look through these. We'll review the final version if we can. We'll look at what's there. We'll answer any questions we can. And yeah, thank you, Tectric. Also, Tectric is in the chat. I know Tectric has been working on this PR for a long time as well. So definitely a big thanks to him, to thank you to Tectric. Let's see, just submitted my branch to include the latest from Metafruit, so I guess merging main, this means, I don't think I messed up this update. There's merges in the area of version definition and init, emceelut. If someone cared to point out where it would be appropriate to add my name to the project as an author. I would say in regards to that, I guess this is not right. In regards to that, it'd be the copyright thing at the top of the file, I think is fine. Any file that this person edited or anybody who's watching, if you are submitting code for CircuitPython, I would say and you want to add your name to it for attribution right. There's a copyright string at the top of all the files. We make it automated with our CI tools to basically enforce the fact that that copyright string will be there. There's names at the end of it. It says the copyright year, it says the names and you can add your name into that if you submit contributions to a library. So that's definitely, I think the answer to this bit. I will, but while we're here, we could link to it maybe. I guess let's link to it. Because one thing we can do is just like point to the code. Yeah, I think they did. Yeah, no, I think this is them, right? Because isn't it our Vimy? Something like this, right? R-I-V-I-M-E-Y. Yeah, this has got to be them, right? This has got to be them. Okay, so it looks like they did find that out. I will let them know. I didn't look at all the files. Maybe there's some that don't have that. I don't actually know for sure. I don't know for sure if they touched all the files or maybe if they did already put their name in. So I'll just respond to that part and then I don't forget to... Usually when I'm following up on a thing like this where there's multiple different conversations going on about different parts of the code and stuff, I like to try it. I don't want to save it all up for one thing. Sometimes I do, I guess, but I'll forget parts of it. So if I can quick write out a response to one little bit of it, then that's nice to get that done out, get it on there so I don't forget it or just it gets hidden inside of a different bigger post or something. I can't wait about the memory change when we guys are working on a tool to help quantify so we can make better adjustments. I think it'd be really useful. I'm up for that. I don't necessarily feel like it's... I don't necessarily know that it's appropriate for me to be the one to pull the trigger on it. So I'm definitely up for that, but I will say I have not checked into the cookie cutter. Has there been any action on the cookie cutter? One. I would say mostly I look towards probably Catnip or Feedback or Dan or Jeff or, I mean, obviously Scott's not around, but I know. I really like this idea. It's worth rolling out. I mean, we could certainly start it on one. One thing I could do is if nothing else I could... Nothing else I could fork this and then put the memory size stuff in my fork and push it and then we could see the output. But will it post on the PR? I guess we wouldn't see the post on the PR. We could see it inside of actions or I could push a commit to this branch with that stuff in it. I would want to say like, yes, let's do it and then I add it. I feel like we should probably get feedback from the team before we do it just because it will be posted onto the comments. I'll try to remember to do this also on Monday. I'll put it in the weeds topic and I'll bring up that cookie cutter one and we'll see if we can get feedback from the team if folks are cool with what's there or if there's any other tweaks we want to do to it before we put it in cookie cutter and then we can also raise the idea of putting it in this library first and then put it in this PR. But yeah, I'm totally down for it. I just don't want to like pull the trigger and do it right away without hearing back from anybody. Maybe worth optimizing registers to place them in the files. Place them in the files they should be. This way we can use var name const underscore var name const. I'm not sure I understand the difference. I will say I don't know what the compiler or what some of them do. Is this less? Is this like somehow less memory? Does it not does it not keep the the name or something? I mean the difference I see is leading underscore. Does that make it treated differently? I don't actually know. Link to the PR, yeah thanks for dropping the link. Welcome to the Adafruit yep discord. Merge looks good from what I can see as far as version goes. I don't think I saw any issues with the knit either. Yeah, I think they were asking about adding it to the docs.conf but I don't think anyone updates that. It looks like they all add this spdx. Yeah, I've only as far as I can recall I only recall people adding it to those files. And I mean I know DocStreams does like pull some stuff out of those files so I don't know if they show up in the docs or where but I don't recall ever seen it added to docs.conf docs.conf.pi rather. Oh, Beata also if what you meant when you said you have one of these was this EMC 2101 do you happen to also have a fan that has tachometer support? So I have tested this but the fans that I have are output only. They don't have the tachometer line so they don't send the speed back to the control chip so I could test the output portion of it but I can't really test the input portion of it. One of these days I got to buy some new fans that have that if yours is handy and you happen to have a fan that does that though we could totally we totally could as Tetrick mentioned there we totally could use testing much mucho appreciated for sure but also cool not a problem if not I think there's an argument for testing it out in this Rupa PR similar to how we converted only a few libraries to Pi project yes you need a variable to start with underscore for the const to be defined okay well this so this one is is this one like not valid or this one is still valid but just doesn't work doesn't give you the benefit of using const underscore keeps I'll keep reading as well this might already be answered I know I'm catching up so underscore keeps the string out of the global namespace okay it's only true it's only true when used with underscore beat me to it I think I get it now okay yeah meaning the name is not going to be exported even if formally Python doesn't do the distinction micro Python circuit Python does with const okay only docs cough gets added to read the docs uh no no I don't no I don't think so like doc strings come from in the code right like you can put a you can put a well let's open it up you can put a comment like on a function in the code and that gets that comment gets pulled into the doc so I mean like the whole Python file is not but some stuff in that file is I don't know how much or which specific I know doc strings for sure like for functions I know the examples get pulled into the docs a lot of times as long as they're included in the samples dot Tom or something YAML file something one of those um definitely some stuff gets pulled in from the Python files for sure and and that stuff doesn't live in the docs folder initially let's go in a minute since I've opened this one attribution like authors year spdx isn't and I think I'm already on this branch but the problem oh well actually no I think I can pull okay I did sometimes I use ghpr checkout which checks out a branch but doesn't track it means you can't pull the newest version you kind of have to like delete the old one and do it again or or else you have to add the remote or something but it looks like I do have the remote defined so I'm able to just pull one thing I think I noticed on here was asking about something in the docs so do I understand so there are some are there some that aren't using the underscore const thing inside this now or oops okay these ones don't um so yeah I mean I do if I understand correctly that these need underscores in order for it to be worthwhile to use const then I do think we should I do think we should do that if the other question is about essentially breaking up this file I mean it would be more efficient probably but I also don't necessarily I mean it's only 100 lines or something 120 lines I don't know exactly how the all the importing works and stuff I imagine it is more efficient but I also would guess it's not that much more efficient we could always do it in the future as well if we wanted to break it up further I do think though we should if those leading underscores are needed then I do think we should definitely add those and removed like there's still proposed change with okay yeah so this was the nested I do kind of recall this this was like the nested handling the with context what do they call that context um I don't know the with context block or whatever there's code in here that is well this is outdated too though is that they're all in all in a file on their own it's that they are all in a file on their own so that they can be accessed between classes makes sense for the shared but some may benefit from being moved if they're only used within specific ones then use var name const but you can't use var name const in a file a and then access it oh I see I see it can't have the underscore because that has to be inside the specific file okay um they're supposed to be used outside I kind of prefer the namespacing them with classes you go about 300 lines on both most boards for you need to start doing optimization well I think it depends totally on what you import to as well um yeah I don't I wouldn't know I don't I don't have a good like I don't have a good idea or really any idea in mind what the difference would be if the difference is going to be massive then I'd say yeah let's do it if the difference is going to be minimal then I don't know that it's worth the effort to re-separate them back out I do from an organization's perspective I do kind of like having them all in this class but if that's less efficient then ultimately we will probably change it one of the days if we need to to get it to fit somewhere I wouldn't say that I am like strongly one way or the other on that break it like breaking those out versus keeping them in the file if it's massively more efficient then I swing towards like do the more efficient one but I suspect it would be minor um but I don't know for sure debug text could be removed yeah this one I do I mean I am with you on this I know one of the things you had mentioned Tectric was we don't necessarily need to support like in depth of with context we really only need like in the with context or not not necessarily like are we four levels deep or three levels or two levels and I am in agreement on that I do think we don't really need it I do think the additional code it requires and the additional logic and stuff is not worth not worth the added space and complexity I will say too though I am biased I fully recognize my own bias against the with context processor I don't really like the with context processor I don't think it's that good or useful or helpful personally so that could be controversial take and like that surely clouds my ability to be impartial about it inside the library like I don't find it very helpful I find it's more of a nuisance than anything helpful the majority of the times that I run into it so personally I will always go towards not using it rather than using it given the choice so this kind of stuff is a part of the API that I am unlikely to ever personally be doing too much with because I'll just choose not to use it that way but I do think it's worth like we I do think it's not worth the extra space to make it handle and level depth I think we only need just in a context or not and I do think that's fine although it did sound like maybe this author is not interested in making that change which we could talk about that if that is the case if you think it will happen and frequently could just raise OS error to cut out the string that's true OS error connection yeah but negative not negative temp in between means the data is corrupted connection I mean it my inclination would be like like my inclination would be to change connection to I2C data corrupted or I2C corrupted personally because just OS error connection doesn't really tell me I don't think what doesn't really tell me what the comment is although if the comment is right next to here then I would probably chase it back far enough and find this comment so maybe it's worth maybe it's worth saving the string space for just putting it in a comment see that argument moving the string was more of a suggestion if they didn't want to flesh it out I do think it's not the best I do think the actual string is not the best but also I2C data corrupted is probably longer if I'm just eyeballing it without counting characters so it's kind of a way of do we like the more descriptive error or the less memory slash file size personally like I would lean towards I think we should make it more descriptive rather than cut it out again unless we're like pretty much at the max size or memory or something if we're really trying to cram it down to fit it somewhere specific then it makes a good thing to cut but if we're not like specifically trying to scrunch it for some reason then I would lean towards keeping it and making it a little bit more descriptive personally string representers of the LUT and speed specifically so realistically I would make this decision based on the two different things they print um I have no idea what it would print by default if this wasn't here but if whatever it prints by default if this isn't here is not very helpful if it doesn't help you know what the thing is or know what it's doing or how it's set up or something like that then personally I'd be in favor of keeping it again unless we're like specifically trying to cut stuff to make room somewhere um but I think I will always I will always probably go towards more descriptive stuff more descriptive error messages more descriptive string representations personally I think I will probably always lean that direction but I do grant like there comes a time when you know if we're trying to freeze this library in a specific space or whatever like it may need to be cut to fit where we're trying to put it and in that situation I say okay cut it but if we're not in that situation yet then I would lean towards more descriptive outputs for string error messages any kind of stuff like that truthfully pretty much always pro error strings improved error messages is my favorite addition of 310 I still need to get into 310 I'm back I'm an oldie right now I'm on 3.8 on my PC I need to get updated ITC data crop would be almost the same as connection I don't those I don't mean the same to me I guess or maybe I misunderstand how they're going to get printed but to me ITC data corrupt tells me a lot more than OS error connection but I don't know almost the same characters I guess you're saying characters my bad my dad yeah never mind what I just said is not relevant yeah characters I think you're talking about my bad sorry all the structural pattern matching folks three more characters I see the follow up question understood there for a minute I believe they should be relative imports from see yeah probably I would yeah well yeah I'm surprised that works though right does that actually have one of these inside of it or is this old code or something I'm surprised that works or oh not so it's import regs I see no I mean I'm cool with it if it works I don't I think this is more common I feel like and I I'm surprised this one does work or I don't know if it does or not but I do think I am more used to seeing it this way but I don't have a preference one way or another if they both work personally and then this I think they mentioned I added which is probably true but I do not remember it did you have issues building the docks locally without this I would guess that I did if I added it but I don't have a specific recollection of it I might be in an old stream somewhere but I also don't know that for sure I reinstated the code and did and I thought it included got lost somewhere to do the defer update unwilling to make more changes already gone longer than it's happy debug print statements were left commented out very intentionally in building hardware software it's useful to know which things aren't working right I don't propose therefore to remove them I could see it both ways I mean they don't help anyone know anything printed out though right like I have intentionally split up the module so that those with limited memory can use it in the class based in it giving those with more resources to exploit the rest of the code big file that was deleted both arm and python bytecode yeah I don't mean I this size I don't think is what we're interested in we're mostly interested in the MPY size right this we're not there's probably some correlation but we're not compiling it or arm or compiling it for python bytecode we're doing MPY that's definitely the size that will that will be interested in okay so I think I mean ultimately we'll need to find somebody else to finish it up it sounds like it sounds like the original author is uninterested in making further changes which is totally totally fair right like they contributed their time and effort to add functionality to this it's totally fine if they're not wanting to do anymore right like I think they could back out at any point and that's totally fair so essentially what we do is like if we want to bring it in and we essentially need somebody to finish it up and I think the things rate the things waiting are for sure I think this I think we definitely want to undo the multi-level with context the print statements commented out I could take them or leave them I don't really have a strong opinion either way I don't know if they add size or not personally yeah I don't know I don't have a strong feeling either way on the commented print statements I can see the case for removing them because they don't do anything I can see the case for leaving them because if somebody wants to poke around and learn then it's a good thing for them to like flip one character and be able to get a little bit more information or knowledge about whatever they're looking at so I don't know I don't know which way is the correct one truthfully this I would be in favor of changing personally my preference would be a more descriptive string here and here and then string I would lean towards keeping it unless we are at like a threshold that's too big and then these I don't I don't know for sure about if this one works fine then I don't see any real better or worse between them but if this one doesn't work then we definitely should use the one that works and then the only other thing I would say is I feel like I've seen this one in other context like display text is obviously this is when I've done a lot of work inside and I'm pretty sure this does the imports that way like from made of fruit whatever import something I'd say that is the one that I am more familiar seeing but I can't say as though I know an actual difference or if one or the other is like correct or not and then the docs thing let's try the docs thing I don't know if I I mean because they did say I added that so I my guess is that I couldn't get the docs to build and then I added it and they did let's look back if we can see no where my actual commits were remove make file fix docs build interesting yeah the rest of these all make sense to me for sure as like I could see why these would need to be changed to make the docs build I will say like this doesn't really ring any bells I don't you not have specific recollection of doing that see what we get like this that built warning treated as error no module named regs but then maybe that is like that import that you found right where was that one this was maybe this got around the import problem maybe the reason the import was working go this isn't what or are there more of these are there each one in each of these actually this one did already have this way which is interesting import thing I'm too slow though are there any other places where it's like that I would say we should it should be consistent either way and there are it seems like all the other files so far were like this so I do I do think it should it should be consistent across all the files for sure someone doesn't import anything doesn't like that so yeah he probably am in favor of changing this one to be this way however yeah I can't build the docs the docs don't build without this can't say as though I know why I definitely don't understand why I honestly I probably unfortunately I can't even tell you how I would have ever came to the conclusion that this is what would fix it but it does seem to fix it for what it's worth so yeah so far I mean I would say seems pretty much like we need that unless we can figure out what else we could change to make this work but I don't I'm not quite noticing anything that is this missing the no this is up here maybe one of these is wrong maybe one of these is wrong there were a couple of these wrong right 2101 fan speed someone looks okay 101 EXT that one looks okay 101 enums 101 LUT yeah I don't know I don't know what's causing this but definitely that line in the conf seems to fix it so I would say we either got to keep that line or we got to figure out what's causing this and fix it I don't know failed to import module no module named I mean I I wish I would have left more of a note honestly that's on me that I didn't leave more I didn't say anything about it did I I just commit that's definitely my bad I should have left a comment with more information maybe this as I didn't read this today okay I did I did at least say something I did leave the comment there that's that's okay I I do wish I had pointed to like how I figured that out maybe because I like I said I don't have direct recollection of it and I don't know how I don't recall seeing an error like that and solving it like this before so or how I would have known to do that guess I would have searched something like this probably but how's it going Johnny when in a package you need to base it off that package but adding the sys path insert tells the interpreter it can look there for packages so it's helping Sphinx build it as a work around masking the import issue but I don't know what is what is the import issue right because I changed this one that you mentioned and that it's still not building so there's another one or or there's something different right because I changed this already and it still doesn't build like this so what is the import issue that we could change to not have to change Conf I'm not sure like I don't I don't know of anything else that could change anywhere to to affect it is it well now these are like individual things from here I mean are these supposed to be like this maybe these maybe these are supposed to be like this I think that was the only one okay the rest of them also need this I see I see no I don't know yeah I only changed the one at first I didn't realize these ones and then this is yeah this is gone okay interesting it's super weird that it's probably not as weird as it is in my head but in my head it's super weird that that Sphinx would not be able to find them but like Python on the device could I wonder how I wonder why it would work when we ran it on the device and why Sphinx can't figure it out the same way that is very odd yeah how's it going Johnny okay I will go let's do this revert docs build fix revert docs build bandaid resolve relative import as real fix I should run pre-commit or so I already made the commit now so here's cross interesting it works on the board I don't know if I ever tried I definitely did try it on the board however I will say I couldn't like I said earlier I couldn't do the I couldn't do the back like the the input from the fan so I guess it's possible if this file was only needed by that portion of it then then I did not actually test it but I did run it on my device well and this would have been a while back right definitely not the latest version but at one point I definitely did run the PR branch on my device with a fan plugged in and did outputs only I was able to output the speed and update it but I don't have attack pin on my fan and it was working for outputs it could be that you don't need this stuff for outputs that definitely could be it could be this is like more so for the back mode or I think there's like temperature mode as well you can have it like smart smart change like it will try to keep a temperature range for you or whatever you do fancy stuff like that as well with it actually kind of a neat little chip we did pass pre-commit so we should be able to push comment back on this one let's remove the insert path inside of conf.py so we basically need to try to find a person who's interested in like in my mind the two things for sure are remove the multi-level depth of width remove that stuff so that we only support a single level change these to better more descriptive strings again I'm on the fence either way I don't feel strongly about this one way or the other and then I would try to keep this at least unless we're specifically trying to scrunch it as small as we can so the strings the multi-level widths I think those are my top two and unfortunately like it like well not really I shouldn't say unfortunately like totally legit fair no problem original author is not interested so we'll have to find someone to do it and I'll say like if it doesn't get done long enough then eventually I will do it but I don't have the fan to test with and I don't know when I will do that right it will just be like it will come up on a Monday and I'll be like yeah let me do this today so if anybody is interested in working on that feel free if anybody is interested in working on that but feels like they need help or something like feel free to hit us up on the discord for sure leave a comment here if you're interested in working on it you can ping me if you want either here or on the discord if anybody is interested in working on it definitely be happy to have anyone who wants to give it a try I can help you through the get process if you need it I know it's kind of a weird one because you're like working on a PR that's already in progress but I can help you with the get side of things I can get you all set up so if anybody is interested in doing that reach out on the on the get hub or on on discord otherwise like probably I will do it one of these days but I don't know exactly when I think I could apply this to a similar problem with my own multi import in a lower project not prepending from not prepending them either and it was failing with similar error always learn something good watching from a guy nice the dot one is interesting from dot import I have to do stuff like this in a project for work and I never understood why in agreement with your comments thanks for the thorough review yeah for sure thanks for all of your work on this my friend yeah like I'm I'm happy to happy to help in however I can this one's definitely been a beast of a PR for sure so thank you for keeping up with it and going back through and just keep calling calling these things out getting them into the comments that way we can get them tracked and get them taken care of thank you double shout out again did I get you double last time as well the dot makes the imports always work if you rename that's a good point as well yeah which I guess I mean one thing that could happen hypothetically theoretically maybe maybe you know who knows but one thing that could possibly happen that that has happened let's say with some other libraries for instance it could get splitted into like kind of a basic and an advanced or something like that right and then maybe one you know it would fork in the road and one would add more functionality in the other one wouldn't and then one of them would get a new name so it would probably would get renamed at that point or move it into a sub module yeah I would say I'm done with any which way that works in there and I definitely don't this is still one of the portions of python that I'm least understanding of like I was saying a minute ago one of my work projects we have some weird stuff where we do our imports in a certain way and I've never understood why and like pie charm doesn't find them it's like this is missing but then you run it and it's like okay no problem just runs everything's fine I've never understood it and I it's one of the areas where I'm not quite not quite up with all the nuances in python of how the different types of imports can work okay so that's 2101 again if anybody wants help or is interested in working on that feels like they need help or a point in the right direction feel free to ping me I'm happy to help out in that way for sure next thing that we will dive into here on this deep dive Friday is back to the flip clock time for me to call it a day thanks Tim good night yeah take it easy Dave thanks for hanging out for a bit hope you have a nice night and all that good weekend everything flip clock so in a flip clock land today we would like to try to clean up and add comments to the PIL generator spreadsheet generator also make it into a proper like command line thing because right now it doesn't take arguments from the command line it just has all this stuff but I think it'd be nice if it was kind of command line double so to speak um I guess we want to go both ways maybe we want like we want the ability to change from the command line but I'd also maybe like a set of defaults that is in here and like theoretically you could modify it in here if you wanted different defaults one thing I will say is this function in particular I did not write and I can't say as though that I understand the math inside of it so I would probably struggle to write a good description find coefficients it takes two planes I do remember that of one given plane to the shape of another given plane a p a and p b are plane a and plane b plane as in the geometric description I don't actually know for sure what it is four four four points I think four points makes a plane so it's a shape that's bounded by four points polygon four-pointed polygon maybe but it could go in 3d2 I'm not sure I don't know the actual definition what's I always what is the syntax for arguments param colon param space type space name colon colon param space type no I say type or name space type think they're tuples because they're basically four points so I guess we should say the points that make up the first plane we should even maybe say the four points because I think it is four points specifically I never know if I should have periods after things sometimes or if it's like just by its own I don't know how if there's a best practice and then there's returns right as well but I don't have it in this well that was I guess in it though right I guess doesn't look like I have returns on these there's type type annotations for the returns so do we are we supposed to do this one tuple and then it returns another not a return to another tuple but maybe it maybe it returns a numpy thing what does numpy array reshape does this return in darray so I can't really add much to this unfortunately this was definitely just stack overflow on the code that does this so this is a pil image picture and then angle is a I want to say it is either an inter afloat catch up here I don't know how the imports could work on the board it looks like they definitely shouldn't maybe it's a numpy quirk could be I mean it could also just be I didn't exercise that portion of the code it's possible that those things were for functionalities I didn't use and maybe I just didn't see there because of that thank you for the review suggestions and help threesoncommunitybundleprs updating my submittal chi chi as we speak nice yeah for sure huge shout out to near doc and tech trick honestly for helping all kinds of folks with all kinds of things all over discord all over different parts of the community github everywhere for sure thank you to those folks it's a comment periods are only really needed to break up sentences if it's just one line send periods are useless and unnecessary okay I'll try to remember that there are some libraries thanks for contributions always love seeing that grow the community bundle also shout out to near doc for having to watch fly got a bunch more in the pipeline nice yeah you got some great stuff great stuff going on didn't we have PIL oh okay we already have image I see we don't need it this go ram I'll see I don't should I put it here I don't know PIL image or should I not image image so basically you give it an image and you give it an angle like 10 degrees or 20 degrees or whatever 90 degrees you give it an image and an angle it will find the coefficients that you can pass to get the perspective skew of that image at that angle and in this case it's the top half so the angle is as it moves forwards as it falls forwards like a flip clock would like the top half would fall down so that angle is representing you know 0 degrees is standing straight up 90 degrees is all the way flat laid down and so usually you're going to be somewhere between 0 and 90 it's going to get you the coefficients that you can then pass to the perspective skew thing to make that angle well to make it look like it's at that angle there's a difference I don't know maybe that's the same thing I guess so this one's actually weird it's like it's a list of tuples no it's a tuple of lists of tuples that bad the tuple of lists of tuples inside the list is that not a tuple I thought tuple lists tuple does it need all of these one two three four does it need four of these oh it's wanting to go deeper well that's a little much I think I don't I don't think we want that already a list can we leave it at just tuple of lists why does that not work find top half coefficient has double VZ oh thank you find it really it should say find I'm not even consistent with my periods or lack thereof that's the worst part I mean I definitely don't think we want this this seems excessive to me for sure this does not add anything useful right this is not helping us figure out the code so I don't want to code that whole thing I'm surprised this doesn't count right because it is a tuple of lists it even says that it got a tuple of lists it goes on to say all the stuff that's inside of it but we start as a tuple of lists but it says it doesn't match tuple list seemingly this is lowercase list also that make a difference flip book animation animations would be fun book animations that could be kind of fun I think I'm going to leave it like this I don't want the more I don't want this is too much like this doesn't really tell us anything honestly I can't even parse that know what that means and this has like a million any's inside of it we don't if anything it would be like these basically are what are inside the list but for some reason it's seeing some of them as any's seeing some of them as floats you know I guess these become floats here so stick for that stick with that for now this one's basically the same oops but it's for the bottom half tuple of lists of input points that can be passed to find coefficient function so this one does the same thing it's just that the angles are different the zero degree angle is like perpendicular the zero degree angle now is what the 90 degree angle was back here here the zero was upright standing straight 90 degrees was lying flat down on its face here zero degrees is lying down flat on its face and 90 degrees is all the way down this way straight but to the bottom so this is the bottom half of the flip you give it still an angle zero to 90 but it's now zero is straight 90 is down you know we probably should say here angle in degrees zero to 90 it might work for others I can only promise zero to 90 that's the only thing I wrote the code for so my guess would be it either won't work for others or it won't do the right thing for others just create a flipbook animation library when you're done name it it for animated gif well I mean the thing is like this library that I have created just takes the sprite sheets right you could just create a sprite sheet if you want and then do a flipbook of it the problem is though they're small like you can't make them too big because there's just not enough memory we could try maybe on disk bitmap that's one of the things I may try on the pi portal if we don't get a good size that lets it go into memory on the pi portal then maybe we'll try on disk bitmap style but I think that will make it draw slower so I don't know for sure would be good enough or look good enough but theoretically like once you the widget the actual circuit python widget it just takes the sprite sheets like this and animates them and it doesn't know that there's a 0 here or a 1 here or a 2 here I mean I guess it does because the API allows you to say dot value equals 4 and it knows to look at this row of the sprite sheet but like you can put a cat emoji on this and it would it would do that that's what it would show and so we already kind of have flip images you just have to get a different sprite sheet you could probably hack up this script that I'm documenting now to paste images instead of glyphs the digits 0 through 9 if you wanted I probably will not personally do that I don't think but that is something that somebody could do for sure is make this thing like paste images onto those flip cards instead of the digits image this is the PIL image and this returns I think this returns another PIL image right? image.crop I think this is returning the image represented by the rectangle that you give it oh man let me have the real docs though real docs returns a rectangular region from this image the box is a four tuple type image yes okay this is basically the same but bottom half make sprite is there a type for string of length is there a way I can type this as like string but specifically string with length one probably not right because it's not types at that point right it's values and we have literal right we have like literal values we'll just go string but it should be length one that's it definitely assumes that it's going to be length one I make no claims that it will keep working if you pass it something larger than that it's not char yeah that's what I was thinking in Java there's char which is like a single character string well not technically a string but single character but in Python we don't have that my gripe is you can't type lists of fixed lengths oh yeah that would be helpful too actually because sometimes yeah you want like this is a list with two things or four things or whatever set int format of one and convert to string not sure I follow X sprite this one I think it's going to return the image yeah it's going to return the image I think I don't know though what what does this do in English so this one is making the static ones or is this this static it makes static sheet X sprite X sprite now it's used for the animated sheet as well okay well I guess that makes sense because for the animated sheet it's going to render the static one and when I say static I mean basically one of these right one of these is a static tile of a digit so it's going to render a static one then it's going to cut the top half out cut the bottom half out and then get the angle sprites from that so it's used for those as well as the static ones so basically this will make an image make a make a pil image object representing a single digit or character a pil image representing a single static digit or character these get packed into the static sprite sheet and are used as the basis for the angled animation sprites param ring character factor single digit or character put on this static sprite ram int font size the size to render the font on sprite so one thing we should have which we don't is this should get passed in because spoiler alert if for anybody who wants to see show and tell but I went on show and tell and one of the things that Lady Ada asked for was a papyrus I think it was papyrus I got to go back and watch the video actually I think it was the papyrus font but I need to go check but basically Lady Ada asked for a different font if we could make an example using different font and so right now obviously this is hard coded but we want to be able to pass it in so we should and then I'm going to make it equals I'm going to make the default one this one I guess I should check into the repo as well probably the font character so I don't know what fonts does PIL support is it otf p ttf otf ttf this says otf ttf etc so I guess we'll list those two Python subtly letting you know maybe you want a tuple there's no variable types either these are type variants int equals length int 1f string int int equals length int like basically define a new object called int guess what you want is a list of length s x make it x arguments to a function but then piling it complains that you have too many arguments or which way you go somebody is displeased I thought subtly letting you know you want a tuple name tuples have fixed size technically name tuples are nice mostly because they're sort of like dictionaries and I'm a big fan of dictionaries why is this uh let's fix that oh we should we should like make this work right while we're here yeah let's do that a good idea angle sprite sheet static sheet sprite set sprite set okay image int so make angled sprite set so this takes a static sprite a single one of these right a single digit rendered into its little square or well rectangle whatever it takes one of those it takes a number of how many animation frames you want to output and it takes a boolean for bottom skew so remember how the top skew is different than bottom skew as I was describing earlier this is the boolean that controls that you pass in bottom skew true if you want to do the ones for the bottom you pass in bottom skew false which is the default if you want to do the ones for the top so it takes the static image and it returns to you a list of pil image objects that contain this many sprites where each one is angled an even amount so if you ask it for 10 sprites like I did it returns to you a list essentially containing these 10 images but of course if you give it a different count it will give you back that number so you tell it six here it will give you six image objects and it will equally it will try to equally space the angles between 0 and 90 image input static image pram int count number of animation frames to generate default 10 pram bottom skew Julian whether to render the bottom angles or top returns a list of images I'm not even sure type tuple makes sense name tuples have fixed I've speaking of things I struggle immutable structs like I can just use the variable name the best I got was type tuple but I'm not sure if tuple is better because var equals integer format int length then convert int string with string int explicit say it was good code or even valid code just an idea var equals integer int length or int string like it would take the int and then convert it itself rather than taking the string but I think we still can't I mean I think the goal was to do the type of single length string would I would still need to even if I passed an int I would want I mean I guess I could go type at that point if it's an int I could go type literal 0123456789 somehow though I need it to be less than 10 but then it does also throw off the idea of using emojis or letters or anything else which I do I want people to be able to do that I want people to feel free to be able to do that I'm doing numbers digits but I would certainly be thrilled if anybody takes it to the next takes it to the next page flips it to the next page let's say to add some emojis or some letters or other things Leon Wing Yin over on YouTube how's it going good evening my friend thanks for tuning in or well it's evening time where I'm at it may not be so for you but thanks for tuning in on the list this one was a list of image objects oh curly brackets JavaScript coming out image objects so like some of these types of things maybe could get removed sheets and stuff like that probably decent idea make static sheets so this should probably be getting the font also right like yeah cuz make sprite now should be accept x accepting accepting a font so this should also have font and then it will be the same default was league something can I just put leave something this returns this actually this might not return actually yeah no this doesn't return anything this just saves the sheet static sheet dot BMP and then doesn't return so let's use the font we got to pass that through images so this is a list of image objects with int pack a list of image objects into a sprite sheet into a sprite sheet within another pil image object a list of images images a list of image objects to pack into the sheet cram int with the number of sprites in each row so in our case this was 10 for the animation ones these ones I did 10 but ultimately the user gets to pass that in so like you could render smaller ones that's why this is a variable I think the format doesn't set max length per day I learned the name error console is not defined whoops speaking of JavaScript coming out that will uh that will happen you know what's worse is when you go the other way when you put print inside JavaScript because then it launches like a printer preview page I have done that probably a hundred times in my life you use a for loop with a range to keep the string value below 10 characters the for loop with a range to keep the string value below 10 characters I mean I do use a for loop when I render them when I render them into the final files but down in this in this specific function it's just accepting a single character well it's trying to accept a single character but it's as a string but it's like it's supposed to be a string with only a single character most likely one of the digits 0 through 9 that's what I'm using it for but another person could pass in letters and that'd be perfectly fine um or pass in emojis might also be perfectly fine I have no idea if PIL will render emojis but um so yeah the later on in my code where it actually makes use of that function it does it does totally have a for loop that makes it count 0 to 9 in fact here's where one of them is at least makesprite so it's calling makesprite inside the for loop as a param yeah I mean I think we'll leave it as string it's fine I put a single character in the doc string it's name the name of the variable is character so I feel like it should be pretty clear that it's expected to be a single one returns a image which is a PIL image object containing the packed sprite sheet and I guess we have this as the default we don't really need to add it here I suppose but we should probably take it as ultimately I want this to be a command line thing so we should take it as an argument and then we should pass it to here I guess nation sheets so this in turn it just saves the top sheet and the bottom sheet and this does do the digit 0 through 9 so if somebody wanted to reuse it for letters or something else they would have to change this part of it to loop over something different honestly these are the exact same as these right font and size back up here and then okay make sprite here needs font font bitmap and top animation sheet bitmap there we go spreadsheets spreadsheets no they're not spreadsheet microsoft excel paying you this one doesn't return saves one thing it is weird to like call this and then define this that bit's kind of weird this should probably be down here honestly we probably ought to give it one of these things right oh wait so how do we want to document well how do we want to make the command line stuff work and then I guess we document it however it works I was about to say how do we want to document it but the true question is how do we want to do it I'm tempted to use click I haven't ever used click to make a thing before personally because I would like it to where you can pass only the arguments you want change and I would also like it so that you could edit the things here and then just run it with no arguments and it would generate what you set up with these config options so I'm thinking the click is probably good because it will let us do like dash dash font space font name dash dash font size font size dash dash you know height space number width space number I never actually used click before really like typer for clis what is click never heard of that before it's a library for making cli tools in python I don't know anything more about it though other than that I think I'm pretty sure it's the thing that circup uses is click maybe disco tool I'm unsure near doc if near doc is still here maybe he could tell us about disco tool I don't know if that one uses click or not typer I think is a different one I'm down for either I don't have any first-hand experience with either oh what is this all what is that doing wow they have this is like a legit output here this is like this is a pretty sweet looking output I will give it that click helps you make command line interface programs yep that's right that format is used whenever optional dependencies are available for download the dash dash thing I think probably is what I must have been talking about when you said that really like how most python library developers have some sort of animated gif showing the use and the output of their library that's true yeah that is a really nice thing I agree with that our own libraries now support oh okay maybe you were talking about the all thing pip install 8 fruit circ python live name optional whenever optional dependencies let me re-read this again that format is used whenever optional dependencies are available okay so the all would install it with the dependencies which I guess probably would be like the rich it was talking about right didn't that say here yeah okay so I probably didn't my guess is I probably didn't get rich when I did that did I well it's up to python I guess right who knows what python would have done why does this even have its own version I don't know type or no it didn't get rich rich not sure but that's my guess that sounds right to me especially noticing that like right after that they do talk about that will include rich I wonder what it so I guess it must have other output if you don't have rich it must have like error handling that says if you do have it then draw these pretty tables but if you don't then fall back to ascii or something so we make a typer and then we go so here we go typer run main and in our case main is basically def main actually have kind of a lot of things we don't want name string but we have you have kind of a lot of things actually with height padding text color background color background color card color color transparent color int int fence with height padding text color background color transparent color font font size number animation frames and actually what I want to do is use these things up here pretty much so this is actually the size of the half tiles they're half height no no they're not no they're not they're full height they're full height so width and height here this is actually equals why is this all mad though? non-default parameter follows default parameter I see well I'm going to fill in defaults for all of these so why though do I keep putting the minus so close call this shouty because they're like kind of like constant variables basically so this stuff would pretty much be these inside of here font size font that's it I guess we should be passing the color to that as well maybe we should be passing colors to this in fact I think we have to be right if we want these to go through we'll work on that later right now it'll still use those variables so technically it'll still work I think and I am going to probably wrap it up here pretty soon I do want to try to run this and like fingers crossed hopefully we could get it to run once and then check around and fix a few things if I have to but I'm hoping to get it to run once and then probably head out for the night and then I'll probably pick up where I am here working on this tomorrow morning for my stream if anybody's interested in following along constants that just need to be heard from everywhere yes you gotta know you gotta you gotta flaunt your constants your constants everybody's gotta know this is a constant oh my god you can redefine one thing I've been copy pasting pycharm can do that shift f6 shift f6 or right click refactor rename is the way it works and shift f6 is how I use it in naming all my constants in capitals yeah I use refactor rename all the time I will say though I will say sometimes you don't want to do that right sometimes you actually want to rename it but leave all the code the same there's not a good option to do that other than like leave pycharm and edit a file like usually that's for a file name which you can also use shift f6 to rename a file but if you rename the file it will look for all of the usages and try to update those as well which sometimes that's what you want but sometimes you're trying to rename the file intentionally to make it so that the code no longer references it and that is actually kind of difficult it doesn't let you do that so sometimes I end up going like right click open in files and then f2 rename it here because here pycharm doesn't know or care it's not going to update anything else so that is my warning shift f6 it is amazing but be warned if you use it for files it will change references to those files to match the new name so that's not what you're trying to do then you can't do it that way and I have wrecked myself on more than one occasion by doing that and then being super confused why the code that I just renamed to something totally different was still getting run somehow you mean what stuff is already attached to that constant well I mean specifically when you rename a file so shift f6 will let you rename a variable if you highlight a variable and go shift f6 it's going to say rename this in this case it knows it's a parameter instead of just a regular variable but rename this variable but if you highlight a file over here and you go shift f6 then it's going to be renamed the file and it's usages so any other file in this project that refers to this one will get updated if we change the name with great come with great power comes great botubility definitely all right let's see if this runs what is it spreadsheet no module named p i l honestly this should be in here no module named none pie I don't know why this got its own virtual environment honestly I was just running these the other day and it was working so I guess maybe I have not run it inside of this project yet parameters to generic types must be types got module p i l image can't use image here parameters to generic types must be types got module p i l image I mean is it image dot image or this is on 159 s image oh yeah it looks like it is huge that means like pretty much all of these need to be this p i l that's not good here as well how do I do match case need to know regex oh match case let me start at the top skip that one but it's none I skipped out on the last couple of another one p 28 there we go we got a different error we got a lot of different errors oh probably the fonts missing there is a lot of output here I don't know that the end user would want to see all this right this is a lot of stuff free type that's got to be is file that we have right about over here we're going to need a license file for that and I'm pretty sure that there is one inside of here for this font bold instead of regular and this is bdf actually so yeah no not the same at all but close kind of a little bit but it is the same font it's just regular instead of bold so the stuff inside should be the same oh palette web got bottom sheet we got static sheet we got top that ran and spit out our writes are these the same where these purple things here before just never zoomed in that far alright sweet so that worked we want we not print as much stuff because it printed a lot of things oh my okay we need to looks like we're using a bunch of deprecated things which we need to fix we want to turn off these prints other deprecation we want to turn off these prints yeah so we got some deprecations to fix we got some prints to turn off but we're doing pretty good pretty darn good we got all of these functions typed up dock stringed up ready to go least actually documented a little bit now for what each one of them is got some more cleanup to do removing prints and apparently I must be using an old version of pillow would be my guess and now that I just did pip install pillow I got a newer one therefore some stuff is deprecated and needs to change needs to be a pill dot pill dot pill dot pacman images whole way down yeah inception I feel like I'm inside of inception images should be an image that image that image taketh lord giveth and taketh yeah alright I think that is it for now so thank you to everybody for watching I'll be back tomorrow morning at 10am central time for the next stream and I will probably take care try to take care of this stuff which I just talked about removing the prints fixing these deprecations getting this to pass pre-commit if it's not passing pre-commit not sure whether or not it is right now I'm gonna push it just because I did a bunch of work on this but if it's not passing pre-commit then we'll also work on that tomorrow yep yep I will commit see you tomorrow yep I'll see you Paul have a good night everybody let me close this one thanks for the great stream yeah you're welcome thank you thanks for tuning in everybody who's watching thanks of course for cgrover tech trick everybody who helped out in the chat near dark uh paul dj devin probably missing a couple thanks to johnny for tuning in getting the double shout outs triple now is it kind of triple now? I think so thanks to the youtube folks dave, biata axl pascale devins workshop sneaky maker cat thanks to all you folks for watching yep but yeah hope everybody has a good night and a good weekends and I will catch you tomorrow morning for the next stream see ya