 Welcome back, everyone. My name is Brian. We're going to continue our journey into Python 3 with timers. So we're going to execute code at timed intervals. This is the first step in learning threading. And threading is a very complex topic. There's no way we're going to cover it all in one video without having a much longer video. But in case you're wondering what threading is, it looks something like this. So you have CPUs. Each CPU has multiple threads in it. So a thread, think of it in very loose terms as a slice of time. So think of the CPU as like a parent, like your mom. And your mom has three children. Well, she can't pay attention to all three children at the same time. So a thread is a slice of time. That the mom pays attention to the child. Now you think about that in terms of how fast computers are. They do this blistering fast. And then you get into virtualization and virtual CPUs and things like that. It just gets overly, overly complex. And if you want to make it even more complex, this is what it really kind of looks like under the hood. So you'll have physical memory or RAM with some memory space that's allocated towards the process. Each process can have multiple threads, which works with stacks, registers and things like that. The thread scheduler in the operating system will then push that out to the physical processor. Now notice the scheduler. So what we're really talking about here is layers of complexity that go way beyond Python. I mean, this is computer engineering right here. Really, what we're looking at is we want a part of that processor's attention. But really what we can do is run multiple things at the same time. And I'm going to demonstrate that. So you see this cursor blinking right here. Notice how if I open a menu, it stays blinking, but I can navigate the menu while it's blinking. Those are two different threads. If they're on the same thread, that cursor would stop blinking while I'm navigating the menu or the menu would stop working while the cursor is blinking. There's all sorts of complexities and issues you're running to with multi-threading. So let's dive in and take a look to start things out. We're going to do some imports and a display. So we're going to import time. I like to import time. I wish I had more time in the day, but we're going to import the time module. And then we're going to say from threading import timer. Now, one question I'm often asked is, which is the correct format? Well, if you're going to use most, if not all the module, do it this way. If you're going to use just one part of it, use this way right here, where you're only going to import just what you need. Threading is a big, big, big topic, a big module. So we really only want this right here. Now, if we mouse over this, you're going to see a thread module emulating a subset of Java's threading model. Wait a minute. Java, we're talking about Python. Well, Java really nailed down threading in the threading model. So Python's kind of emulated that. They're kind of, I don't want to say blatantly copying it or stealing it, but they're really doing it very similar to Java. So if you're used to Java, you're going to be right at home here. So we're going to say def display. And we just want to display some kind of message to the end user. And I'm going to actually, because this can get a little convoluted, depending on what you're looking for, I'm going to put a link to the documentation right here. But we're just going to basically say print. And there are, as you guessed, a million different ways to do this. We're going to print out the time. Notice we're using the time module. And we want the string format time, which whenever you hear the word format, that means we've got some funky symbols we need to put in here. And I've got the format queued up off the screen here. Very simple. Our minutes seconds. And this is on the 24 hour clock. You can get all this from the documentation link. There's tons and tons and tons of different formats you could do this in. I'm going to keep it just very simple, our minutes seconds. All right, let's go ahead and make a basic timer. When I call this basic, it's kind of a fire and forget solution. So we're going to say dev run once. And as the name would imply, it's going to run one time and one time only. So let's go ahead and let's look at this. We want to call our display function. We're going to say display run once, just so we know, hey, we're actually in this function. Then we're going to make an instance of the timer class. So I'm going to say timer and we've got a couple of parameters we need to put here. So timer needs an interval and this is going to be in seconds. Then we have a callable whenever you see callable really is just a function or a callback or whatever we want to do. And then we have some arguments or keyword arcs. So let's go ahead and say we want to wait five seconds. When this is done, we want to call our display function and notice our display function has some arguments. So we need to give it a list of arguments that's going to be passed. And we're going to say time out. So really what we're doing is we're saying create a timer. When the timer starts, wait five seconds, call the display function with horribly misspelled time out. There we go with a parameter of time out. Now we can go ahead and say teeny dot start. So we're going to actually start at timer under the hood. What happens is threading is going to make a new thread with a timer class and pump that out to it. And it's going to start that out there. This is not going to work the way you expect it to. If you don't understand threading. So for example, we're going to do run once. And then let's go ahead and say print waiting. And I'm putting waiting, even though most people would say something like this. Let's go ahead and run it like this. Just so you can see what I mean here. See how it says done? Well, wait a minute. Where's our timer drum roll? There it is. So what's going on here is we're calling run once it's calling display. So we see that, but then immediately it's jumping out here. Even though this code hasn't executed yet, this is the beauty of threading. You can tell the computer do something some other time or do it at the same time. So in the background, we're creating a timer and it's ticking away time counting down until it can actually fire off. And when it fires off, it's going to say all this with this. That's why this was waiting, not done. So basically when you start a thread, the context of execution is going to move forward instantly and the code on the other thread will move to the other thread and work out there. All right. So let's see it in action again. Now it looks a little better run once waiting and then we're going to get a time out. I'm going to put some notes in here just so we don't confuse people who decide to skip through this video. Notice this is run immediately, but it also only runs once. Now we're going to make a timer that runs on an interval. And this might have been what you were really expecting. So far we've talked about a single shot where it only fires off one time. We're going to make it fire off over and over and over again until we stop it. Got to pay some notes. So we're going to wrap this into a class. And this is where they're really emulating Java and we're going to make it run until we stop it. You can have multiple timers at the same time. Remember your computer is absolutely filled with timers. Here is the official documentation. It is not for the faint of heart. If you go out there and don't understand it, don't beat yourself up. Threading is very complex. So first thing we're going to do is say class repeat timer. And we're going to inherit the timer class from the threading module. This guy, ta-da! Now that we've inherited that, we've got everything it has. So we can just work with it directly. So I'm going to say def run. And this is a little confusing. What is run? Well, run is called automatically. Let's go back up here to our run once. We're saying, grade an instance of the timer and then timer start. In the background, run is called. So start is called. They do some stuff with threading in the background. And then they call the run function of the class. So when you see start, automatically understand that run is going to be called. So run is fired off when they actually start your class. So I'm going to say while, not, self, finished. We're going to go ahead and wait. And this is a little bit confusing. And admittedly, I did take this from a post on Stack Overflow. This is probably the best class I've seen so far. And you'll see why in just about a second here. So we're going to say while self has not finished, we're going to go ahead and wait for whatever interval we've set. And then in here, we're going to say, call the same function over again with the same arcs and keyword arcs. And then once we're done, we can just go ahead and print this out. It's so simple and elegant. If you actually go out and look at how to do this in other areas, you're going to have this big, long class with like admit and all this other stuff, you don't need any of that. This is all self-contained and it's only a few lines long. It's very elegant. It just works. I absolutely love it. So what we can do now is, well, you guessed it, we're going to start controlling this. So we're going to say timer equals repeat timer. We're going to do this every second. We're going to call display and we're going to give it an argument of repeating. So because we're inheriting this class, it is identical to if we were just calling it directly. Absolutely love that. Now that we have a timer, we can go ahead and work with it directly. So we're going to say timer start. Now remember, this is going to call run. So when we say timer start, run is actually being called. And then all of this happens. Now, before run is called, it does some stuff in the background with the OS scheduler and all that stuff and actually creates a thread on the operating system and works with it directly. We don't have to worry about any of that complexity. We just know that start will call run. Now this is where we're going to get a little confusing. I'm going to say time, not timer. So time, sleep. What we're doing here is we're putting the main thread or the thread this program is running on to sleep. So this thread will run in the background, but our main program is actually going to go to sleep. And we're going to go to sleep for 10 seconds. So I'm going to plop in some notes. So we're going to suspend the execution for a given number of seconds. So I'm going to just print out. Reading start. Actually, let's say started. And then finish in just so we can see what time sleep does. So if we mouse over this bad boy, it says the module time provides various functions to manipulate time values. So it's a little misleading how this actually ropes into our execution. Let's break that up just a little bit. Now we can go ahead and say timer dot cancel. So we're going to cancel this timer, basically just shut it off. Let's go ahead and run. Now remember when we do this, we also have this other timer from run once. So it's going to fire off time out. You're going to see that in the results. So waiting thread started repeating, repeating, repeating. And then we're going to get a time out. There's our time out and it's going to keep going. And then after 10 seconds have passed, it will stop. See, now had we not done this right here, we're going to get drastically different results. And this is really one of the minor complexities. I say minor because it can get really complex. But one of the minor complexities with threading, you see how immediately it says done. Now, wait a minute. Didn't work as we expected. Now we get a time out. That is super frustrating. So we have to suspend the execution of our current thread while the other thread's running or we get drastically horribly bad results. OK, so we have just scratched the surface of threading and what threading can do. Really, what you need to understand is that you can execute code at the same time on different threads. This is extremely cool and extremely powerful, but it comes with a level complexity. You're going to have to start wrapping your head around. Threading is, well, in any language, some of the hardest code you are going to ever work with. The big takeaway from this video is that threading in Python also has a timer class, which we can use, inherit and manipulate. I hope you enjoyed this video. You can find the source code out on github.com. If you need additional help, myself and thousands of other developers are hanging out in the Voidromes Facebook group. This is a large group with lots of developers and we talk about everything technology related, not just the technology that you just watched. And if you want official training, I do develop courses out on udemy.com. This is official classroom style training. If you go out there and the course you're looking for is just simply not there. Drop me a note. I'm either working on it or I will actually develop it. I will put a link down below for all three of those. And as always, help me help you smash that like and subscribe button. The more popular these videos become, the more I'll create and publish out on YouTube. Thank you for watching.