1 00:00:00,000 --> 00:00:03,955 All right, so I've got my motion detection 2 00:00:03,979 --> 00:00:07,320 program running here, and as 3 00:00:07,320 --> 00:00:09,660 you see this is capturing me moving at 4 00:00:09,660 --> 00:00:12,721 the moment. If I move away, 5 00:00:12,746 --> 00:00:15,151 [No audio] 6 00:00:15,194 --> 00:00:16,890 you can only see some shadows there, 7 00:00:16,915 --> 00:00:18,915 [No audio] 8 00:00:18,940 --> 00:00:20,640 and so this 9 00:00:20,640 --> 00:00:23,820 is great. But as I said, you may want to 10 00:00:23,820 --> 00:00:26,160 store the time, so when an object enters 11 00:00:26,435 --> 00:00:28,388 the frame, so that you end up 12 00:00:28,412 --> 00:00:29,621 with something like this. 13 00:00:29,645 --> 00:00:32,191 [No audio] 14 00:00:32,216 --> 00:00:36,030 So this is the first entrance, as the start time here 15 00:00:36,030 --> 00:00:38,160 is where the object exited the frame, 16 00:00:38,190 --> 00:00:41,430 and then the second entrance of the 17 00:00:41,430 --> 00:00:45,870 object, and so on. So in this 18 00:00:45,870 --> 00:00:48,180 lecture, I'll show you how to build 19 00:00:48,180 --> 00:00:51,150 that table using this script. So we 20 00:00:51,150 --> 00:00:55,260 will add some more code here, and the way to 21 00:00:55,260 --> 00:00:58,320 start doing this is to first figure out 22 00:00:58,680 --> 00:01:01,080 the point, the line in the script where 23 00:01:01,080 --> 00:01:04,470 the status is changing from, let's say, 24 00:01:04,715 --> 00:01:08,767 motion to non-motion. Hence, you, we have 25 00:01:08,798 --> 00:01:12,427 non-motion in here. So as soon as 26 00:01:12,606 --> 00:01:16,565 webcam triggers, let's say the status is 27 00:01:16,590 --> 00:01:20,160 0. So just a symbol that I'm choosing 28 00:01:20,160 --> 00:01:23,100 to denote that there's no motion in the 29 00:01:23,100 --> 00:01:26,100 current frame. So then you get that 30 00:01:26,370 --> 00:01:28,590 first_frame, which has a status of 0, 31 00:01:29,130 --> 00:01:33,270 and then you grayed out, and then you check 32 00:01:33,270 --> 00:01:34,740 if the first_frame is None and then you 33 00:01:34,740 --> 00:01:37,200 continue the loop again, and then you grab 34 00:01:37,200 --> 00:01:41,280 the second frame, so the status is still 35 00:01:41,280 --> 00:01:46,260 0, and then you apply the difference and the 36 00:01:46,260 --> 00:01:50,130 threshold, and the dilate, and then you iterate 37 00:01:50,130 --> 00:01:53,520 through contours. So if you find an area 38 00:01:53,520 --> 00:01:55,980 that is less than, I changed this 39 00:01:56,010 --> 00:02:00,150 earlier, I put it 10000. So I wanted to 40 00:02:00,150 --> 00:02:02,640 detect bigger objects, because I was 41 00:02:02,670 --> 00:02:04,590 closer to the camera, so I wanted to 42 00:02:04,590 --> 00:02:07,380 adjust it. So depending on what objects 43 00:02:07,380 --> 00:02:09,930 you want to capture, here you want to adjust 44 00:02:09,930 --> 00:02:10,971 these pixels here. 45 00:02:10,995 --> 00:02:12,995 [No audio] 46 00:02:13,024 --> 00:02:15,855 So 10000 is something like 47 00:02:16,112 --> 00:02:18,956 100 by 100 pixels window. 48 00:02:19,410 --> 00:02:22,350 So we're checking if you don't find a 49 00:02:22,350 --> 00:02:25,410 window that is bigger than 10000, then 50 00:02:25,410 --> 00:02:27,210 you continue to the beginning of the 51 00:02:27,210 --> 00:02:30,390 loop until you find a contour with 52 00:02:30,420 --> 00:02:33,450 this size bigger than this. When Python 53 00:02:33,450 --> 00:02:36,810 finds that contour with that size, we 54 00:02:36,810 --> 00:02:40,464 want to change the status to 1. 55 00:02:40,488 --> 00:02:42,912 [No audio] 56 00:02:42,937 --> 00:02:43,943 Okay. 57 00:02:45,230 --> 00:02:49,388 And let's now print out that status variable. 58 00:02:49,412 --> 00:02:51,681 [No audio] 59 00:02:51,706 --> 00:02:54,240 So what you want to do is 60 00:02:55,266 --> 00:02:59,376 print it at the end of your loop, so status. 61 00:03:00,900 --> 00:03:03,720 And let me delete this NumPy arrays, 62 00:03:03,750 --> 00:03:06,060 which are being printed, we don't need 63 00:03:06,060 --> 00:03:09,540 those, and make some room here. 64 00:03:09,564 --> 00:03:14,525 [No audio] 65 00:03:14,550 --> 00:03:18,780 So this is inside the loop, and I now expect 66 00:03:18,810 --> 00:03:21,600 to see the status, so 1 or 0 or 0 printed 67 00:03:21,625 --> 00:03:25,200 out depending on whether there is an 68 00:03:25,200 --> 00:03:28,230 object in the frame or not. So if this 69 00:03:28,230 --> 00:03:31,347 is working, that means we now have 70 00:03:31,574 --> 00:03:34,020 actual status of the frame, and we can 71 00:03:34,020 --> 00:03:37,688 use that 1 or 0 for other things. So let's see. 72 00:03:37,712 --> 00:03:42,027 [No audio] 73 00:03:42,052 --> 00:03:45,509 Okay, there is nothing at the moment. Let me 74 00:03:45,534 --> 00:03:47,534 [No audio] 75 00:03:47,559 --> 00:03:49,380 minimize this. So we can 76 00:03:49,380 --> 00:03:50,655 see the console. 77 00:03:50,679 --> 00:03:52,721 [No audio] 78 00:03:52,746 --> 00:03:55,860 This as well. Great. So 79 00:03:55,860 --> 00:03:58,110 0 is being printed out, and if 80 00:03:58,110 --> 00:04:00,780 something shows up, now you see 1s. 81 00:04:00,804 --> 00:04:04,161 [No audio] 82 00:04:04,186 --> 00:04:10,621 Again, 1, 0, 1, 1, 0, great. 83 00:04:10,645 --> 00:04:12,876 [No audio] 84 00:04:12,901 --> 00:04:17,790 We can now simply apply a datetime method, 85 00:04:18,180 --> 00:04:21,120 you know, such as datetime.now, 86 00:04:22,920 --> 00:04:25,590 and that would record the time of 87 00:04:25,590 --> 00:04:28,740 each frame. So we don't want that 88 00:04:28,740 --> 00:04:31,921 exactly. We want to use a datetime.now 89 00:04:31,945 --> 00:04:34,530 method but not like that. Because 90 00:04:34,530 --> 00:04:36,180 that would record times for 91 00:04:36,180 --> 00:04:40,020 every frame. So what we want instead is 92 00:04:40,800 --> 00:04:43,200 we want to know when the status changes 93 00:04:43,200 --> 00:04:46,530 from 0 to 1, which indicates that 94 00:04:46,560 --> 00:04:48,780 there is an object entering the frame. 95 00:04:49,110 --> 00:04:51,690 So we want to record that time, and we 96 00:04:51,690 --> 00:04:53,880 also want to record the other time when 97 00:04:54,450 --> 00:04:57,000 the status changes from 1 to 0, so 98 00:04:57,030 --> 00:04:59,940 the object exits the frame. Let's say 99 00:05:00,319 --> 00:05:03,379 status_list, that will be equal to 100 00:05:03,690 --> 00:05:06,570 empty brackets, so an empty list, and 101 00:05:06,570 --> 00:05:10,920 then I want to append the status of the 102 00:05:10,920 --> 00:05:12,807 object to that list. 103 00:05:14,497 --> 00:05:16,688 So after this loop finishes, 104 00:05:17,643 --> 00:05:22,020 which is here, so I want to be 105 00:05:22,020 --> 00:05:24,000 here at the same level with the loop, so I 106 00:05:24,025 --> 00:05:25,705 want to apply something outside the loop, 107 00:05:26,970 --> 00:05:31,950 so status_list, I want to append the 108 00:05:31,950 --> 00:05:34,470 current status of the list here in the 109 00:05:34,470 --> 00:05:39,180 status_list. Great, and to illustrate, 110 00:05:39,480 --> 00:05:41,970 to show you what this status_list is 111 00:05:41,970 --> 00:05:45,121 about, I'd like to print that out actually, 112 00:05:45,145 --> 00:05:48,383 [No audio] 113 00:05:48,408 --> 00:05:50,460 and I would want to print out 114 00:05:50,760 --> 00:05:53,130 a list outside the while loop. So I 115 00:05:53,130 --> 00:05:55,188 don't want to print out every 116 00:05:55,212 --> 00:05:56,788 time the loop iterates. 117 00:05:56,812 --> 00:06:00,817 [No audio] 118 00:06:00,842 --> 00:06:03,121 So no movement, movement here, 119 00:06:03,145 --> 00:06:07,572 [No audio] 120 00:06:07,597 --> 00:06:10,770 and quit. So these are the statuses 121 00:06:10,770 --> 00:06:14,340 for each of the frames, so 0, 0, 0, no movement, 122 00:06:14,370 --> 00:06:18,300 and then something entered the frame, and 123 00:06:18,300 --> 00:06:21,870 then something entered, like, let's 124 00:06:21,870 --> 00:06:25,985 say 30 frames and then the object exits 125 00:06:26,010 --> 00:06:30,750 the frame, and that's it. So what we 126 00:06:30,750 --> 00:06:33,570 want to do now is we want to capture, so 127 00:06:33,600 --> 00:06:36,240 what's next. So the next thing is we 128 00:06:36,240 --> 00:06:39,480 want to capture the time that we switch 129 00:06:39,480 --> 00:06:43,050 from 0 to 1, and also from 1 to 130 00:06:43,050 --> 00:06:45,720 0. So basically, what we're 131 00:06:45,720 --> 00:06:49,170 interested about is to capture the last 132 00:06:49,200 --> 00:06:53,940 two items on the status_list. So let's 133 00:06:53,940 --> 00:06:56,730 say we have status 0, so we 134 00:06:56,730 --> 00:06:59,400 start with a empty list, and the first item 135 00:06:59,400 --> 00:07:02,160 that will be appended to the status_list 136 00:07:02,225 --> 00:07:06,005 is 0, and then the second item, let's 137 00:07:06,030 --> 00:07:08,730 say will be 0, or let's say will be 138 00:07:08,730 --> 00:07:12,180 1, and so we want to apply a conditional 139 00:07:12,180 --> 00:07:15,360 to check whether the last two items of 140 00:07:15,360 --> 00:07:19,200 the lists are changing. So I know all this 141 00:07:19,230 --> 00:07:21,630 may be confusing, but once I write the, 142 00:07:21,660 --> 00:07:23,700 this four lines of code here, you'll 143 00:07:23,700 --> 00:07:25,800 understand it, and it will make a lot of 144 00:07:25,825 --> 00:07:30,813 sense. So we want to check if status_list, 145 00:07:30,941 --> 00:07:34,388 so the last item of the status_list, 146 00:07:34,985 --> 00:07:37,200 which has an index of -1, 147 00:07:37,230 --> 00:07:40,350 remember, list indexing, if that is 148 00:07:40,350 --> 00:07:41,616 equal to 1, 149 00:07:41,640 --> 00:07:43,898 [No audio] 150 00:07:43,923 --> 00:07:48,540 and status_list with index 151 00:07:48,565 --> 00:07:53,190 of -2, so the item that was added 152 00:07:53,190 --> 00:07:56,102 first, the item that was added second, 153 00:07:57,729 --> 00:07:58,957 is equal to 0. 154 00:07:58,981 --> 00:08:01,323 [No audio] 155 00:08:01,348 --> 00:08:03,240 We want to record the 156 00:08:03,240 --> 00:08:06,480 datetime of this event in the list. So 157 00:08:06,506 --> 00:08:09,206 let's create a list here, say times 158 00:08:10,593 --> 00:08:15,513 equals empty, and then we go here, here, 159 00:08:15,775 --> 00:08:22,554 and we say times.append datetime.now, 160 00:08:23,137 --> 00:08:24,540 you know about this function 161 00:08:24,540 --> 00:08:27,840 already, and hence so we want to append the 162 00:08:27,900 --> 00:08:30,894 current timestamp when this change occurred. 163 00:08:30,919 --> 00:08:32,927 [No audio] 164 00:08:32,952 --> 00:08:35,571 So that means we need to import 165 00:08:35,595 --> 00:08:38,310 [Author typing] 166 00:08:38,341 --> 00:08:42,246 or from datetime import 167 00:08:42,389 --> 00:08:48,220 datetime. So datetime class from the datetime library. 168 00:08:48,244 --> 00:08:50,944 [No audio] 169 00:08:50,969 --> 00:08:53,088 So we're basically recording the 170 00:08:53,117 --> 00:08:55,175 time when a status 171 00:08:55,200 --> 00:08:57,600 changed to 1, and we also wants to 172 00:08:57,600 --> 00:09:01,050 record the time when the status changes 173 00:09:01,050 --> 00:09:03,750 from 1 to 0. So we would have a 174 00:09:03,750 --> 00:09:05,460 similar conditional 175 00:09:06,690 --> 00:09:10,560 but this will be 0 and this would be 176 00:09:10,560 --> 00:09:13,170 1, okay. 177 00:09:13,194 --> 00:09:18,095 [No audio] 178 00:09:18,120 --> 00:09:21,990 So what's happening here is let's go 179 00:09:22,015 --> 00:09:25,465 back to the start of the loop. So, 180 00:09:25,805 --> 00:09:29,315 Python captured the first_frame and it 181 00:09:29,340 --> 00:09:32,670 converts it to gray and blurred it and 182 00:09:32,670 --> 00:09:36,221 apply GaussianBlur there to the first_frame, 183 00:09:36,245 --> 00:09:38,190 and then we store the first_frame 184 00:09:38,220 --> 00:09:40,170 in the first_frame variable and then we 185 00:09:40,170 --> 00:09:42,840 go ahead and calculate the difference 186 00:09:43,115 --> 00:09:44,760 between the first_frame and the current 187 00:09:44,786 --> 00:09:50,250 frame, findContours, and then if this 188 00:09:50,250 --> 00:09:52,440 little findContours greater than 189 00:09:52,440 --> 00:09:56,640 10000, a status variable changes from 190 00:09:56,640 --> 00:09:59,490 0, so it started at 0, so it changes 191 00:09:59,490 --> 00:10:03,150 at 1 here, and that means this empty 192 00:10:03,150 --> 00:10:06,600 status_list will get the another value. But 193 00:10:06,630 --> 00:10:09,720 the first value is always 0. So the 194 00:10:09,720 --> 00:10:13,380 list will start with 0, you know, 195 00:10:13,380 --> 00:10:16,288 like here, so the very first value is 0, 196 00:10:18,015 --> 00:10:20,550 and so on. Let's say for the next 10 197 00:10:20,550 --> 00:10:24,990 frames, it will be 0, 0, 0, 0, and so on, and 198 00:10:24,990 --> 00:10:28,560 then if an object enters the frame and then the 199 00:10:28,560 --> 00:10:30,810 status changes to 1, so we'll have 200 00:10:30,810 --> 00:10:34,920 0, 0, 0, 0, and then 1, and then what we're 201 00:10:34,920 --> 00:10:38,790 doing here is, we're comparing the last 202 00:10:38,872 --> 00:10:43,642 two items of the list, okay. And here, I'd like to 203 00:10:44,105 --> 00:10:48,335 print out the times.list, so that you see 204 00:10:48,360 --> 00:10:51,990 what's going on, and I expect to get an 205 00:10:52,015 --> 00:10:54,595 error at the first execution here, 206 00:10:54,930 --> 00:10:56,730 because we have something more to do. 207 00:10:56,730 --> 00:10:57,860 But let's see. 208 00:10:57,884 --> 00:11:02,055 [No audio] 209 00:11:02,080 --> 00:11:03,420 So yeah, it says list 210 00:11:03,420 --> 00:11:06,990 index is out of range. So that means 211 00:11:06,990 --> 00:11:10,350 Python is having troubles accessing the 212 00:11:10,380 --> 00:11:13,260 second item of the list, because the 213 00:11:13,260 --> 00:11:16,320 list has no items here, so it has no 214 00:11:16,320 --> 00:11:19,530 items, and then we add an item, so we 215 00:11:19,530 --> 00:11:22,950 add status, and then Python tries to 216 00:11:22,950 --> 00:11:24,510 find the second item, but there is no 217 00:11:24,510 --> 00:11:26,970 second item. So we need to do a trick 218 00:11:26,970 --> 00:11:31,830 here, we need to add two items, okay. Let's 219 00:11:31,830 --> 00:11:33,088 say None and None. 220 00:11:34,443 --> 00:11:36,030 Now let's execute the script again. 221 00:11:36,054 --> 00:11:41,225 [No audio] 222 00:11:41,262 --> 00:11:43,722 So there's no object there at the moment, 223 00:11:44,940 --> 00:11:48,330 now an object appears. It goes out 224 00:11:48,355 --> 00:11:54,870 again, two times, and one more time, so 225 00:11:54,870 --> 00:11:56,107 three entrances, 226 00:11:56,131 --> 00:11:58,640 [No audio] 227 00:11:58,665 --> 00:12:01,080 and I quit it. So let 228 00:12:01,080 --> 00:12:03,150 me go through this list now. This is 229 00:12:03,175 --> 00:12:07,585 our times.list, and so this is the time, 230 00:12:07,745 --> 00:12:12,488 so the year, the month, a day, and hour, 231 00:12:12,512 --> 00:12:15,270 minutes, and seconds, and then 232 00:12:15,270 --> 00:12:17,880 microseconds in here. So this is the 233 00:12:17,880 --> 00:12:21,210 start time when an object entered the 234 00:12:21,210 --> 00:12:23,640 frame for the first time, and then this 235 00:12:23,640 --> 00:12:25,590 is the time when the object exits the 236 00:12:25,590 --> 00:12:28,740 frame. So I stayed there for 2 seconds, 237 00:12:28,740 --> 00:12:34,170 so 51 upto 53, and then the next object 238 00:12:34,170 --> 00:12:39,600 enter the frame, so from this seconds to 239 00:12:39,625 --> 00:12:43,225 this, so for 2 other seconds, and then 240 00:12:43,260 --> 00:12:48,030 another third time, from 0 to 1, for 241 00:12:48,030 --> 00:12:52,105 1 second. So we've got three entrances 242 00:12:52,130 --> 00:12:55,500 in the frame. So I hope that makes 243 00:12:55,500 --> 00:12:58,800 sense. This is good. But sometimes, see 244 00:12:58,800 --> 00:13:02,121 it can happen that when you're running the script, 245 00:13:02,145 --> 00:13:04,338 [No audio] 246 00:13:04,363 --> 00:13:06,870 so you have background, and then 247 00:13:06,895 --> 00:13:10,675 the object shows, and the object disappears, 248 00:13:11,280 --> 00:13:14,520 and shows again, and then if you quit the 249 00:13:14,520 --> 00:13:17,010 program at this point, so let me quit it, 250 00:13:17,034 --> 00:13:19,034 [No audio] 251 00:13:19,059 --> 00:13:21,450 you'll see that you have the start time 252 00:13:21,725 --> 00:13:25,085 here for the first entrance, then the 253 00:13:25,110 --> 00:13:28,299 end time, and then you have another start 254 00:13:28,324 --> 00:13:29,880 time here for the second entrance. 255 00:13:30,155 --> 00:13:33,155 But then you don't have the exit time. So 256 00:13:33,186 --> 00:13:36,568 you may want to add the end time of 257 00:13:36,593 --> 00:13:39,210 the exit of your last object, which 258 00:13:39,210 --> 00:13:41,820 happens to be when the window was quit. 259 00:13:42,210 --> 00:13:45,840 So you want to go here at the end, and 260 00:13:45,865 --> 00:13:47,790 the script is waiting for a key, so if 261 00:13:47,790 --> 00:13:51,900 you press quit here, the while loop will 262 00:13:51,900 --> 00:13:54,510 break. But before that, you may want to 263 00:13:54,535 --> 00:13:57,235 check the status. So if status is 1, 264 00:13:57,777 --> 00:14:00,297 and in that case, you'd add knob with 265 00:14:00,330 --> 00:14:03,840 this scenario here. So if status is 1, 266 00:14:03,840 --> 00:14:06,521 when you press the Q key from the keyboard, 267 00:14:06,545 --> 00:14:08,647 [No audio] 268 00:14:08,672 --> 00:14:11,010 you want to add another item 269 00:14:11,035 --> 00:14:15,113 to your times.list, so times.append 270 00:14:16,480 --> 00:14:20,150 datetime.now. Great. 271 00:14:20,174 --> 00:14:22,345 [No audio] 272 00:14:22,370 --> 00:14:25,260 So that should work differently now. So 273 00:14:25,285 --> 00:14:26,288 let's execute the script. 274 00:14:26,312 --> 00:14:28,656 [No audio] 275 00:14:28,681 --> 00:14:33,725 No object, object, no object, object in the frame, 276 00:14:33,750 --> 00:14:36,930 quit, and now we should have four 277 00:14:36,930 --> 00:14:42,150 datetimes here, four timestamps 1, 2, 3, and 278 00:14:42,150 --> 00:14:47,940 4. So this here was recorded in this 279 00:14:47,975 --> 00:14:52,985 expression here. Great. And the next thing 280 00:14:53,010 --> 00:14:56,310 we want to do now is to throw this list 281 00:14:56,340 --> 00:14:59,160 into a Pandas DataFrame, and then into a 282 00:14:59,160 --> 00:15:01,500 csv file, so we'll have a start 283 00:15:01,500 --> 00:15:03,150 and an end column, and in the start 284 00:15:03,150 --> 00:15:05,520 column, we would have, for instance, 285 00:15:05,970 --> 00:15:09,060 this value, and in the end column, we 286 00:15:09,060 --> 00:15:11,280 would have the other values, so this one 287 00:15:11,280 --> 00:15:16,860 here, and the last one, this, okay, so first 288 00:15:16,860 --> 00:15:19,140 of all, we need an empty DataFrame, a 289 00:15:19,140 --> 00:15:21,270 Pandas DataFrame. So we'll be using 290 00:15:21,295 --> 00:15:24,565 Pandas to create DataFrames, of course. 291 00:15:25,429 --> 00:15:29,749 So let me import pandas here, and let's 292 00:15:29,814 --> 00:15:36,718 say, DataFrame, df equals to pandas.DataFrame, 293 00:15:36,743 --> 00:15:39,158 [No audio] 294 00:15:39,183 --> 00:15:40,252 with columns 295 00:15:40,276 --> 00:15:42,813 [No audio] 296 00:15:42,838 --> 00:15:47,880 Start and End, as easy as that. So that will 297 00:15:47,880 --> 00:15:50,400 create a DataFrame structure for us, 298 00:15:50,645 --> 00:15:54,064 which has no values, but it has two columns. 299 00:15:54,097 --> 00:15:56,097 [No audio] 300 00:15:56,128 --> 00:15:58,694 And then the next thing you want to do is 301 00:16:00,081 --> 00:16:01,950 outside the loop, so once 302 00:16:01,950 --> 00:16:03,450 you have created, once you have 303 00:16:03,450 --> 00:16:06,600 generated your times.list, you want to 304 00:16:06,600 --> 00:16:09,030 iterate through that list, and then 305 00:16:09,060 --> 00:16:11,430 append those values into the Pandas 306 00:16:11,430 --> 00:16:15,270 DataFrame. So you need a loop, let's 307 00:16:15,270 --> 00:16:21,960 say for i in range, and so for here, 308 00:16:21,960 --> 00:16:24,090 you'd have to iterate with a step of 309 00:16:24,120 --> 00:16:28,320 2 , and you'd want to iterate as many 310 00:16:28,320 --> 00:16:31,800 times as there are values in the list. 311 00:16:32,195 --> 00:16:36,185 So you'll start from 0, and then you'd 312 00:16:36,210 --> 00:16:39,030 end up at how many values you have in the 313 00:16:39,030 --> 00:16:40,770 list? Well, you can find that using the 314 00:16:40,770 --> 00:16:44,700 length method. So length times with a 315 00:16:44,700 --> 00:16:49,770 step of 2, great, so that will be, so 316 00:16:49,770 --> 00:16:52,500 for each iteration df, so the DataFrame 317 00:16:52,500 --> 00:16:57,330 will be equal to itself, .attend, so 318 00:16:57,330 --> 00:16:59,880 you are updating the DataFrame, and 319 00:16:59,880 --> 00:17:02,460 here you'd need to pass a dictionary. So 320 00:17:02,460 --> 00:17:06,330 for the Start column, you'd want to 321 00:17:06,360 --> 00:17:11,055 enter times i 322 00:17:11,916 --> 00:17:13,499 and for the End column, 323 00:17:13,530 --> 00:17:15,575 [No audio] 324 00:17:15,600 --> 00:17:18,420 so the keys of the dictionary here are 325 00:17:18,445 --> 00:17:21,655 Start and End, and you'd want to append 326 00:17:21,720 --> 00:17:25,288 times i+1, 327 00:17:25,992 --> 00:17:29,625 and you want to ignore_index, 328 00:17:31,116 --> 00:17:36,000 so equal to True. Great. So what 329 00:17:36,000 --> 00:17:39,180 this is doing is, let's say for i in 330 00:17:39,180 --> 00:17:41,520 range, this will be, let's say, we have a 331 00:17:41,520 --> 00:17:44,820 list with 6 items. So we have 3 332 00:17:44,820 --> 00:17:48,330 Start times and 3 End times. So that 333 00:17:48,330 --> 00:17:51,600 would mean range 0 to 6 with a 334 00:17:51,600 --> 00:17:54,660 step of 2. So for 0, we would do 335 00:17:54,660 --> 00:17:57,570 this. So we will start from 0 in the 336 00:17:57,570 --> 00:18:01,320 loop, and we would access the item with 337 00:18:01,320 --> 00:18:04,440 the 0 index in times, which happens 338 00:18:04,440 --> 00:18:06,951 to be this item for instance, so the first item 339 00:18:06,979 --> 00:18:08,979 [No audio] 340 00:18:09,004 --> 00:18:10,410 and then we append that item 341 00:18:10,410 --> 00:18:13,050 to the first row of the Start column. 342 00:18:13,074 --> 00:18:15,395 [No audio] 343 00:18:15,420 --> 00:18:18,255 And then we access the item 0+1 344 00:18:18,279 --> 00:18:20,040 which happens to be item with index 345 00:18:20,040 --> 00:18:22,980 1, which should be this item, so the 346 00:18:22,980 --> 00:18:25,560 second item, and we append that item to 347 00:18:25,560 --> 00:18:29,645 the End column for the same row. So 348 00:18:29,670 --> 00:18:31,890 that's it, then we go to the next item. 349 00:18:32,513 --> 00:18:36,653 So for so this time, we would start with 350 00:18:36,690 --> 00:18:42,270 index 3, so 3 here added to the 351 00:18:42,270 --> 00:18:44,760 Start column and then 4 added to the 352 00:18:44,760 --> 00:18:47,410 Start column to the add column, so we add 353 00:18:47,435 --> 00:18:50,490 so on, and lastly, we would have a 354 00:18:50,490 --> 00:18:53,580 DataFrame, and what you might want to 355 00:18:53,580 --> 00:18:56,688 do then is df.to_csv, 356 00:18:56,712 --> 00:18:59,672 [Author typing] 357 00:18:59,697 --> 00:19:01,749 let's say times.csv. 358 00:19:02,012 --> 00:19:04,088 So we are exporting the DataFrame 359 00:19:04,112 --> 00:19:05,588 to a csv file. 360 00:19:06,223 --> 00:19:08,700 Great. So let's see how this will go. 361 00:19:08,724 --> 00:19:15,515 [No audio] 362 00:19:15,540 --> 00:19:21,570 It's getting quite dark here. Okay, and 363 00:19:21,595 --> 00:19:25,318 one more time, frame, quit, 364 00:19:25,342 --> 00:19:27,886 [No audio] 365 00:19:27,911 --> 00:19:30,188 and as you see times.csv was 366 00:19:30,212 --> 00:19:32,610 created in my file system. 367 00:19:32,634 --> 00:19:35,315 [No audio] 368 00:19:35,340 --> 00:19:37,088 So these are the times. 369 00:19:37,125 --> 00:19:39,245 [No audio] 370 00:19:39,270 --> 00:19:41,620 I can also open it using Excel. 371 00:19:41,644 --> 00:19:45,385 [No audio] 372 00:19:45,410 --> 00:19:46,860 So these are the 373 00:19:46,860 --> 00:19:49,410 Start and End times. if you want to get 374 00:19:49,410 --> 00:19:52,290 four month then just four months sales, 375 00:19:53,070 --> 00:19:55,860 here and you can see the dates now. 376 00:19:56,070 --> 00:19:58,355 Great. Great. 377 00:19:58,379 --> 00:20:02,034 [No audio] 378 00:20:02,059 --> 00:20:04,505 So that ends this lecture. 379 00:20:04,530 --> 00:20:07,830 And I hope you enjoyed it. We have quite 380 00:20:07,830 --> 00:20:10,740 a good script now, and to make it more 381 00:20:10,770 --> 00:20:14,130 beautiful, we would want to display 382 00:20:14,160 --> 00:20:17,100 these times in a graph. So that's how 383 00:20:17,100 --> 00:20:19,290 you turn your data into real 384 00:20:19,290 --> 00:20:22,140 information. And we'll do that through the 385 00:20:22,140 --> 00:20:24,390 next lectures. But before I'd like to 386 00:20:24,420 --> 00:20:26,700 introduce you to the bokeh library, 387 00:20:26,945 --> 00:20:29,105 which is a library for interactive 388 00:20:29,130 --> 00:20:31,530 visualizations in the browser, so 389 00:20:31,530 --> 00:20:33,030 please follow the lectures in the 390 00:20:33,030 --> 00:20:35,880 correct order, and I'm sure you will 391 00:20:35,880 --> 00:20:38,373 learn a lot. Talk to you later.