1 00:00:00,480 --> 00:00:03,480 foreign 2 00:00:09,320 --> 00:00:15,000 taming the duck with type hints and it's 3 00:00:12,420 --> 00:00:18,000 an introduction to static typing or type 4 00:00:15,000 --> 00:00:19,440 hints in Python it's an introduction so 5 00:00:18,000 --> 00:00:21,720 I'm going to go through things very 6 00:00:19,440 --> 00:00:23,939 quickly what I'm really hoping is is 7 00:00:21,720 --> 00:00:26,699 that if you've heard of it but you 8 00:00:23,939 --> 00:00:28,560 haven't used it before that this might 9 00:00:26,699 --> 00:00:30,900 give you some motivation to use it so 10 00:00:28,560 --> 00:00:35,880 I'm going to do another one of these 11 00:00:30,900 --> 00:00:41,399 very shallow but hopefully broad talks 12 00:00:35,880 --> 00:00:43,559 first the context well python it uses a 13 00:00:41,399 --> 00:00:45,600 typing system that I'm sure you're very 14 00:00:43,559 --> 00:00:47,340 familiar with called duct typing which 15 00:00:45,600 --> 00:00:50,160 I'll get into a bit later because I want 16 00:00:47,340 --> 00:00:52,379 to contrast that with static typing and 17 00:00:50,160 --> 00:00:55,620 the nice thing about it is it allows 18 00:00:52,379 --> 00:00:57,480 programmers to be quick and to to very 19 00:00:55,620 --> 00:01:01,140 quickly develop programs without 20 00:00:57,480 --> 00:01:04,140 worrying about these pesky types and 21 00:01:01,140 --> 00:01:07,560 again we we need to remember that python 22 00:01:04,140 --> 00:01:10,500 was used in the the education system 23 00:01:07,560 --> 00:01:13,439 early on in the U.S because it is a 24 00:01:10,500 --> 00:01:16,260 simple elegant language 25 00:01:13,439 --> 00:01:19,560 um but the issue is is that we don't 26 00:01:16,260 --> 00:01:22,979 have to think about types but types are 27 00:01:19,560 --> 00:01:25,439 still there and if we don't pass the 28 00:01:22,979 --> 00:01:28,979 correct types to a function then we will 29 00:01:25,439 --> 00:01:31,259 have a problem we will have an exception 30 00:01:28,979 --> 00:01:34,920 so you know you've got the trade-off 31 00:01:31,259 --> 00:01:37,259 you're extremely productive and fast but 32 00:01:34,920 --> 00:01:40,799 errors can still be there 33 00:01:37,259 --> 00:01:44,100 so what this talk is looking at is where 34 00:01:40,799 --> 00:01:46,979 we get a Helper to help us with finding 35 00:01:44,100 --> 00:01:49,520 those errors early on which is the type 36 00:01:46,979 --> 00:01:49,520 hints 37 00:01:49,619 --> 00:01:53,460 so in this talk what we're going to be 38 00:01:51,659 --> 00:01:54,600 looking at is 39 00:01:53,460 --> 00:01:57,000 um 40 00:01:54,600 --> 00:01:58,640 the whole different kind of typing duck 41 00:01:57,000 --> 00:02:01,979 or otherwise 42 00:01:58,640 --> 00:02:05,340 and I'm hoping that it it 43 00:02:01,979 --> 00:02:08,160 answers the question for you could it 44 00:02:05,340 --> 00:02:10,380 actually help you because I'm not going 45 00:02:08,160 --> 00:02:12,060 to say that everyone should be using 46 00:02:10,380 --> 00:02:13,800 type hints that's silly people have 47 00:02:12,060 --> 00:02:15,540 different ways they're they have 48 00:02:13,800 --> 00:02:19,379 different areas that they're working in 49 00:02:15,540 --> 00:02:21,780 but I'm I'm hoping that you know you can 50 00:02:19,379 --> 00:02:23,580 make that decision a bit better we're 51 00:02:21,780 --> 00:02:25,560 also going to look at some of the Python 52 00:02:23,580 --> 00:02:28,379 syntax 53 00:02:25,560 --> 00:02:31,020 to create these type pins because I want 54 00:02:28,379 --> 00:02:32,480 to show you that it is quite a simple 55 00:02:31,020 --> 00:02:35,879 process 56 00:02:32,480 --> 00:02:38,420 and also there's the questions of if 57 00:02:35,879 --> 00:02:41,220 you've already got to have a code base 58 00:02:38,420 --> 00:02:44,700 how do you apply it do you have to apply 59 00:02:41,220 --> 00:02:46,819 all or a bit at a time and and the last 60 00:02:44,700 --> 00:02:49,739 point is what I started with which is 61 00:02:46,819 --> 00:02:52,019 but most of all I'm hoping that you'll 62 00:02:49,739 --> 00:02:53,819 want to try it just have a look see if 63 00:02:52,019 --> 00:02:56,580 it suits your style 64 00:02:53,819 --> 00:02:58,200 so it's a bit of a taste a taster of 65 00:02:56,580 --> 00:03:00,540 type hints 66 00:02:58,200 --> 00:03:03,019 okay just a bit of background about 67 00:03:00,540 --> 00:03:03,019 myself 68 00:03:03,360 --> 00:03:08,280 why am I interested in type hints well 69 00:03:06,239 --> 00:03:10,140 it's mainly because I've been working 70 00:03:08,280 --> 00:03:12,720 with statically typed languages for over 71 00:03:10,140 --> 00:03:14,099 30 years and 72 00:03:12,720 --> 00:03:16,500 um 73 00:03:14,099 --> 00:03:19,680 as a kind of professional programmer I 74 00:03:16,500 --> 00:03:22,620 want my tools so my whole environment my 75 00:03:19,680 --> 00:03:25,379 compilers my editors all that I want 76 00:03:22,620 --> 00:03:27,599 them to help me to create code to be 77 00:03:25,379 --> 00:03:30,840 able to understand code so that's more 78 00:03:27,599 --> 00:03:33,500 kind of the editor and tools but also to 79 00:03:30,840 --> 00:03:36,959 make more correct code 80 00:03:33,500 --> 00:03:39,480 debugging is much harder than if you 81 00:03:36,959 --> 00:03:43,440 write it correctly in the first place 82 00:03:39,480 --> 00:03:46,560 so uh and with uh C C plus plus I'm used 83 00:03:43,440 --> 00:03:48,959 to a compiler that gives me these uh 84 00:03:46,560 --> 00:03:50,720 these checks so that I can write more 85 00:03:48,959 --> 00:03:54,720 correct code 86 00:03:50,720 --> 00:03:56,700 but I've started using the type hints 87 00:03:54,720 --> 00:03:58,319 um so I haven't used them a heck of a 88 00:03:56,700 --> 00:04:00,720 lot but 89 00:03:58,319 --> 00:04:03,599 um because I'm not focusing totally on 90 00:04:00,720 --> 00:04:04,760 python but I do use it for uh tooling 91 00:04:03,599 --> 00:04:07,379 and test 92 00:04:04,760 --> 00:04:09,780 and I found that I am getting the same 93 00:04:07,379 --> 00:04:11,879 sort of benefits that I get from my c 94 00:04:09,780 --> 00:04:12,900 plus compiler when I'm using the type 95 00:04:11,879 --> 00:04:14,900 pins 96 00:04:12,900 --> 00:04:18,060 just an aside 97 00:04:14,900 --> 00:04:20,579 about five years ago I actually went to 98 00:04:18,060 --> 00:04:24,240 go language for a while and it was all 99 00:04:20,579 --> 00:04:26,699 because I was frustrated that when I had 100 00:04:24,240 --> 00:04:29,639 large code bases in Python I couldn't 101 00:04:26,699 --> 00:04:31,699 find the mistakes without testing or 102 00:04:29,639 --> 00:04:35,580 shipping even worse 103 00:04:31,699 --> 00:04:39,540 so I liked go but I still really liked 104 00:04:35,580 --> 00:04:41,100 the python uh better but I did find 105 00:04:39,540 --> 00:04:43,199 things like interfaces and that that 106 00:04:41,100 --> 00:04:45,540 we'll be looking at a bit later that 107 00:04:43,199 --> 00:04:49,620 were very useful 108 00:04:45,540 --> 00:04:52,320 so so that's why I'm interested in this 109 00:04:49,620 --> 00:04:54,600 okay so let's start talking about types 110 00:04:52,320 --> 00:04:58,500 and types of types is kind of neat it 111 00:04:54,600 --> 00:05:02,100 sounds very meta but um as I said at the 112 00:04:58,500 --> 00:05:05,520 very beginning python has types uh so 113 00:05:02,100 --> 00:05:07,560 like you know integers spools floats all 114 00:05:05,520 --> 00:05:09,240 of those types that we're used to and 115 00:05:07,560 --> 00:05:11,460 also some of the types 116 00:05:09,240 --> 00:05:13,380 of why I found python so interesting 117 00:05:11,460 --> 00:05:15,419 when I first came to it which were the 118 00:05:13,380 --> 00:05:18,360 collection types the tuples and 119 00:05:15,419 --> 00:05:20,460 dictionaries and they also have some 120 00:05:18,360 --> 00:05:22,620 special ones like callable and things 121 00:05:20,460 --> 00:05:27,000 like that that are quite interesting so 122 00:05:22,620 --> 00:05:29,520 python has lots of types in fact every 123 00:05:27,000 --> 00:05:32,460 object or variable that you create in 124 00:05:29,520 --> 00:05:35,460 Python has a type and a value and an ID 125 00:05:32,460 --> 00:05:38,400 and some other things but every object 126 00:05:35,460 --> 00:05:41,520 is an object of a certain type 127 00:05:38,400 --> 00:05:45,660 and the type that the object is that 128 00:05:41,520 --> 00:05:49,080 defines what operations are valid on 129 00:05:45,660 --> 00:05:52,380 that the value of the type what will 130 00:05:49,080 --> 00:05:54,000 what it can do 131 00:05:52,380 --> 00:05:55,620 I've got some examples that will make 132 00:05:54,000 --> 00:05:59,520 more sense in a second 133 00:05:55,620 --> 00:06:01,620 so um and when we try to use an invalid 134 00:05:59,520 --> 00:06:04,139 operation on an object we get an 135 00:06:01,620 --> 00:06:05,580 exception so this is the case where you 136 00:06:04,139 --> 00:06:09,000 have a function that's doing something 137 00:06:05,580 --> 00:06:12,060 somebody's passed a object in which is 138 00:06:09,000 --> 00:06:15,180 of the wrong type you try to use it you 139 00:06:12,060 --> 00:06:17,520 get an exception now something I find 140 00:06:15,180 --> 00:06:19,620 that's really good about python is this 141 00:06:17,520 --> 00:06:24,000 fail fast idea 142 00:06:19,620 --> 00:06:27,000 so it doesn't try to coerce types behind 143 00:06:24,000 --> 00:06:30,780 the scenes for you and and like you know 144 00:06:27,000 --> 00:06:34,560 just carry on instead it tries to do the 145 00:06:30,780 --> 00:06:37,139 operation and if it can't do it an 146 00:06:34,560 --> 00:06:38,639 exceptions raised and in fact there's 147 00:06:37,139 --> 00:06:42,660 been a lot of work on error messages 148 00:06:38,639 --> 00:06:44,520 recently that has made these error 149 00:06:42,660 --> 00:06:46,560 messages that that you get in the 150 00:06:44,520 --> 00:06:50,840 exception make a lot more sense 151 00:06:46,560 --> 00:06:50,840 so I actually like that 152 00:06:51,060 --> 00:06:58,380 by the way I'm I'm going to be using 153 00:06:54,139 --> 00:07:00,600 names in this talk not particularly 154 00:06:58,380 --> 00:07:04,139 precisely and that's because I just want 155 00:07:00,600 --> 00:07:08,039 to get the idea across so you know I I 156 00:07:04,139 --> 00:07:10,020 but one one type one name I'm using a 157 00:07:08,039 --> 00:07:12,360 lot of is type hints and I'm sticking 158 00:07:10,020 --> 00:07:14,639 with that because I really like the idea 159 00:07:12,360 --> 00:07:15,840 that it's saying this is a hint it's not 160 00:07:14,639 --> 00:07:18,479 part of the language it's not 161 00:07:15,840 --> 00:07:19,680 constraining the language it's a hint to 162 00:07:18,479 --> 00:07:21,479 other tools 163 00:07:19,680 --> 00:07:24,240 so instead of things like type 164 00:07:21,479 --> 00:07:27,539 annotations or statically typed that's 165 00:07:24,240 --> 00:07:28,919 why we call it type hints 166 00:07:27,539 --> 00:07:31,620 okay 167 00:07:28,919 --> 00:07:33,180 right so I'm going to look well that's 168 00:07:31,620 --> 00:07:36,660 where the high isn't it 169 00:07:33,180 --> 00:07:39,860 um I'm going to just look at some of the 170 00:07:36,660 --> 00:07:43,620 terms that we talk about when we say 171 00:07:39,860 --> 00:07:44,819 python is a dynamically typed duct type 172 00:07:43,620 --> 00:07:46,639 language 173 00:07:44,819 --> 00:07:49,139 so 174 00:07:46,639 --> 00:07:51,539 in the in the way that I'm looking at 175 00:07:49,139 --> 00:07:54,900 Dynamic typing here is just the fact 176 00:07:51,539 --> 00:07:56,639 that if you have a variable I'm going to 177 00:07:54,900 --> 00:07:59,220 call a variable instead of an object if 178 00:07:56,639 --> 00:08:00,660 you have a variable of a particular name 179 00:07:59,220 --> 00:08:02,880 like Factor 180 00:08:00,660 --> 00:08:06,479 it now has a type 181 00:08:02,880 --> 00:08:09,180 so when it's first assigned python knows 182 00:08:06,479 --> 00:08:10,860 this is a string and if I actually ran 183 00:08:09,180 --> 00:08:12,620 this the type Factor would actually say 184 00:08:10,860 --> 00:08:16,500 yeah it's a string 185 00:08:12,620 --> 00:08:19,379 but we can actually change that type so 186 00:08:16,500 --> 00:08:21,479 when we say Factor equal 2.7 as well as 187 00:08:19,379 --> 00:08:24,419 changing the value it changes the type 188 00:08:21,479 --> 00:08:28,440 for that so that's the dynamic typing 189 00:08:24,419 --> 00:08:30,479 that I'm talking about here now again it 190 00:08:28,440 --> 00:08:32,219 makes it easier to program in Python 191 00:08:30,479 --> 00:08:35,099 especially for beginners because there's 192 00:08:32,219 --> 00:08:36,360 less rules for them to learn it just 193 00:08:35,099 --> 00:08:38,520 kind of works 194 00:08:36,360 --> 00:08:42,180 so so there's definitely a benefit there 195 00:08:38,520 --> 00:08:46,080 but it also as your program grows it 196 00:08:42,180 --> 00:08:48,839 actually makes it harder to reason and 197 00:08:46,080 --> 00:08:51,420 discuss the code because what is Factor 198 00:08:48,839 --> 00:08:54,360 well Factor at the top is one thing and 199 00:08:51,420 --> 00:08:56,399 Factor later is something different so 200 00:08:54,360 --> 00:09:00,060 it has a bit of a code smell 201 00:08:56,399 --> 00:09:04,040 that is valid in the language but isn't 202 00:09:00,060 --> 00:09:04,040 necessarily the best coding 203 00:09:04,080 --> 00:09:08,339 to use 204 00:09:05,820 --> 00:09:12,000 okay the good one the interesting one 205 00:09:08,339 --> 00:09:14,279 duct typing now I'm sure most of you are 206 00:09:12,000 --> 00:09:15,660 aware of this you've been using python 207 00:09:14,279 --> 00:09:19,320 but 208 00:09:15,660 --> 00:09:22,980 um the idea behind it is 209 00:09:19,320 --> 00:09:25,140 um is it comes from this this saying 210 00:09:22,980 --> 00:09:28,019 that if it walks like a duck and quacks 211 00:09:25,140 --> 00:09:29,339 like a duck then it must be a duck so 212 00:09:28,019 --> 00:09:32,100 this is kind of like a good enough 213 00:09:29,339 --> 00:09:35,220 principle if it's close enough to a duck 214 00:09:32,100 --> 00:09:37,800 the stuff I want like in this case it 215 00:09:35,220 --> 00:09:39,540 would be walking and quacking as long as 216 00:09:37,800 --> 00:09:41,820 it can do those two things I'm going to 217 00:09:39,540 --> 00:09:44,640 call it a duck for my purposes 218 00:09:41,820 --> 00:09:48,320 so that's the idea behind duct typing 219 00:09:44,640 --> 00:09:50,940 and python uses that 220 00:09:48,320 --> 00:09:52,740 by assuming so it's it's an optimist 221 00:09:50,940 --> 00:09:56,760 it's saying well hey I've got a function 222 00:09:52,740 --> 00:09:58,380 you've passed me a parameter and you 223 00:09:56,760 --> 00:10:01,500 know that it should be a duck so I'm 224 00:09:58,380 --> 00:10:03,860 going to assume it's a duck and I'll ask 225 00:10:01,500 --> 00:10:08,459 it to quack for me 226 00:10:03,860 --> 00:10:10,800 and if we actually ask it to quack and 227 00:10:08,459 --> 00:10:12,899 it doesn't know how to quack 228 00:10:10,800 --> 00:10:16,380 taking this one a bit far unfortunately 229 00:10:12,899 --> 00:10:19,019 but then 230 00:10:16,380 --> 00:10:21,540 we will get an exception so if the type 231 00:10:19,019 --> 00:10:23,459 isn't compatible isn't the right type we 232 00:10:21,540 --> 00:10:26,220 will get an exception 233 00:10:23,459 --> 00:10:28,680 so another thing I I just I'll be saying 234 00:10:26,220 --> 00:10:31,920 a couple times during this talk is that 235 00:10:28,680 --> 00:10:34,800 all python code uses and will and will 236 00:10:31,920 --> 00:10:36,779 continue to use duck and dynamic typing 237 00:10:34,800 --> 00:10:37,800 nobody's suggesting we actually change 238 00:10:36,779 --> 00:10:40,860 that 239 00:10:37,800 --> 00:10:42,540 so when you take a look at this code you 240 00:10:40,860 --> 00:10:45,180 can see that there's a function scaled 241 00:10:42,540 --> 00:10:47,519 down which takes a value and a factor so 242 00:10:45,180 --> 00:10:50,160 it's an idea of scaling down a number 243 00:10:47,519 --> 00:10:55,260 and returning that and at the very 244 00:10:50,160 --> 00:10:58,860 beginning we pass it the float value and 245 00:10:55,260 --> 00:11:01,380 the float or integer factor and the 246 00:10:58,860 --> 00:11:04,440 scale value it runs fine 247 00:11:01,380 --> 00:11:06,240 but if we then change the factor to 248 00:11:04,440 --> 00:11:09,480 actually be of a different type where 249 00:11:06,240 --> 00:11:12,839 it's now string then when we run it we 250 00:11:09,480 --> 00:11:16,860 get this exception raised 251 00:11:12,839 --> 00:11:19,620 so um and that's that is python just 252 00:11:16,860 --> 00:11:21,300 giving it giving it a go and finding 253 00:11:19,620 --> 00:11:24,620 that it didn't work and then informing 254 00:11:21,300 --> 00:11:24,620 the user failing fast 255 00:11:24,660 --> 00:11:29,700 okay type hints 256 00:11:27,839 --> 00:11:32,160 10 minutes in we're starting to talk 257 00:11:29,700 --> 00:11:34,860 about type hints so 258 00:11:32,160 --> 00:11:37,140 what's happened here is on the uh the 259 00:11:34,860 --> 00:11:41,579 top function 260 00:11:37,140 --> 00:11:44,339 I have added hints to tell 261 00:11:41,579 --> 00:11:49,500 to tell who I'll say in a second but uh 262 00:11:44,339 --> 00:11:52,800 it's hints for what the type of the 263 00:11:49,500 --> 00:11:56,579 um of the value when factor is and also 264 00:11:52,800 --> 00:11:58,200 uh what it returns so the hint is just a 265 00:11:56,579 --> 00:12:01,980 type 266 00:11:58,200 --> 00:12:06,120 um after a colon for the arguments and 267 00:12:01,980 --> 00:12:07,680 an arrow and a type for the return but 268 00:12:06,120 --> 00:12:09,540 everything else looks exactly the same 269 00:12:07,680 --> 00:12:12,240 you still have the colon at the end of 270 00:12:09,540 --> 00:12:14,640 the float on the right to say that we 271 00:12:12,240 --> 00:12:17,339 are defining a function and the body's 272 00:12:14,640 --> 00:12:19,800 below nothing else has changed there 273 00:12:17,339 --> 00:12:23,279 but the interesting bit is if we now run 274 00:12:19,800 --> 00:12:24,899 this in Python nothing changes and 275 00:12:23,279 --> 00:12:27,779 that's that's what's important because a 276 00:12:24,899 --> 00:12:30,000 lot of people when type hits first were 277 00:12:27,779 --> 00:12:31,500 talked about in 2015 they were totally 278 00:12:30,000 --> 00:12:33,720 against them because they're saying this 279 00:12:31,500 --> 00:12:36,600 is changing language I know and love 280 00:12:33,720 --> 00:12:38,579 but it didn't change the language 281 00:12:36,600 --> 00:12:40,740 why have we done it 282 00:12:38,579 --> 00:12:43,320 well we've done it because we can now 283 00:12:40,740 --> 00:12:46,079 use type checkers 284 00:12:43,320 --> 00:12:48,240 and so this slide is talking about a 285 00:12:46,079 --> 00:12:50,880 particular type chat Checker called My 286 00:12:48,240 --> 00:12:54,060 Pie and there's quite a few out there 287 00:12:50,880 --> 00:12:57,120 and on the um on the top line I'm saying 288 00:12:54,060 --> 00:12:58,440 that there's Pi type PI right Pi Pi 289 00:12:57,120 --> 00:13:02,339 charm 290 00:12:58,440 --> 00:13:04,079 um so and and more I'm just using my Pi 291 00:13:02,339 --> 00:13:06,300 because it's you know open source easy 292 00:13:04,079 --> 00:13:08,540 to see it was one of the first ones 293 00:13:06,300 --> 00:13:11,579 along with pie charm 294 00:13:08,540 --> 00:13:14,160 and uh and so yeah through this talk 295 00:13:11,579 --> 00:13:17,579 we're just talking about my pie 296 00:13:14,160 --> 00:13:20,760 so running this type Checker is as 297 00:13:17,579 --> 00:13:23,639 simple as invoking my pie with the name 298 00:13:20,760 --> 00:13:25,860 of your top level file 299 00:13:23,639 --> 00:13:29,839 and it will actually look at all files 300 00:13:25,860 --> 00:13:33,360 that it Imports and and do an analysis 301 00:13:29,839 --> 00:13:35,820 using the type hints to uh to figure out 302 00:13:33,360 --> 00:13:38,579 what should be correct 303 00:13:35,820 --> 00:13:40,380 so when that happens we actually get two 304 00:13:38,579 --> 00:13:44,399 errors I'm going to look at the second 305 00:13:40,380 --> 00:13:47,880 one first so the second error is exactly 306 00:13:44,399 --> 00:13:50,519 where python complained where it was 307 00:13:47,880 --> 00:13:54,480 saying that the second argument I can't 308 00:13:50,519 --> 00:13:57,139 divide that because dividing a a float 309 00:13:54,480 --> 00:13:59,220 by a string isn't supported 310 00:13:57,139 --> 00:14:01,860 but the first error is kind of 311 00:13:59,220 --> 00:14:04,800 interesting so this one is looking at 312 00:14:01,860 --> 00:14:06,720 the dynamic types and as I said before 313 00:14:04,800 --> 00:14:11,160 Dynamic types are okay in the language 314 00:14:06,720 --> 00:14:13,320 but it does and can make your code a bit 315 00:14:11,160 --> 00:14:15,600 harder to understand so instead of 316 00:14:13,320 --> 00:14:18,480 dynamic types why not have two different 317 00:14:15,600 --> 00:14:20,579 variables and then the names can 318 00:14:18,480 --> 00:14:21,440 actually make more sense so it's 319 00:14:20,579 --> 00:14:25,980 actually 320 00:14:21,440 --> 00:14:27,899 it's actually picked up that the type of 321 00:14:25,980 --> 00:14:29,880 that variable had changed 322 00:14:27,899 --> 00:14:32,899 and we're going to look at how it does 323 00:14:29,880 --> 00:14:32,899 that in a second 324 00:14:34,560 --> 00:14:40,740 okay so static typing with Dynamic 325 00:14:39,240 --> 00:14:41,399 typing 326 00:14:40,740 --> 00:14:43,440 um 327 00:14:41,399 --> 00:14:45,360 so 328 00:14:43,440 --> 00:14:47,880 and Doc but we're going to get more to 329 00:14:45,360 --> 00:14:51,060 that in a minute but the static typing 330 00:14:47,880 --> 00:14:54,540 comes by way of type hints as we saw and 331 00:14:51,060 --> 00:14:57,060 that we use different uh type checking 332 00:14:54,540 --> 00:15:01,320 tools to check that the other nice thing 333 00:14:57,060 --> 00:15:04,019 is is that the Ides or editors are using 334 00:15:01,320 --> 00:15:08,459 that same information now pycharm 335 00:15:04,019 --> 00:15:10,740 started it from my reading but now like 336 00:15:08,459 --> 00:15:13,380 my editor emacs it understands it as 337 00:15:10,740 --> 00:15:17,220 well so it's actually checking doing 338 00:15:13,380 --> 00:15:20,579 those my pie checks as I as I type 339 00:15:17,220 --> 00:15:23,160 and I just again this this was the last 340 00:15:20,579 --> 00:15:26,339 time I'll say it but the goal of type 341 00:15:23,160 --> 00:15:30,300 hints at least in the C python 342 00:15:26,339 --> 00:15:31,519 implementation is not to not to use them 343 00:15:30,300 --> 00:15:34,139 for the language 344 00:15:31,519 --> 00:15:35,220 but it's to be used by the separate 345 00:15:34,139 --> 00:15:40,199 tools 346 00:15:35,220 --> 00:15:41,880 and that was said in in pet 526 347 00:15:40,199 --> 00:15:44,399 okay 348 00:15:41,880 --> 00:15:47,519 so now we're going to look at uh 349 00:15:44,399 --> 00:15:49,980 we looked at using type hints for 350 00:15:47,519 --> 00:15:53,040 function arguments now let's take a look 351 00:15:49,980 --> 00:15:54,800 at using type hints for variables 352 00:15:53,040 --> 00:15:58,079 and 353 00:15:54,800 --> 00:15:59,519 the top example I'm having trouble 354 00:15:58,079 --> 00:16:02,760 reading my screen here because of the 355 00:15:59,519 --> 00:16:05,220 lights but the top example is is where 356 00:16:02,760 --> 00:16:07,380 we have two variables color and files 357 00:16:05,220 --> 00:16:09,380 and 358 00:16:07,380 --> 00:16:09,380 um 359 00:16:10,279 --> 00:16:16,440 my pie infers the types 360 00:16:13,940 --> 00:16:19,500 when it sees them as I kind of mentioned 361 00:16:16,440 --> 00:16:20,940 before and in this little piece of code 362 00:16:19,500 --> 00:16:23,160 I've 363 00:16:20,940 --> 00:16:27,420 changed the type on it 364 00:16:23,160 --> 00:16:29,160 so so then when I run my Pi on it so 365 00:16:27,420 --> 00:16:33,720 there's no functions here at all but 366 00:16:29,160 --> 00:16:36,300 when I run my tie my Pi on it it's 367 00:16:33,720 --> 00:16:37,440 telling me again that these types have 368 00:16:36,300 --> 00:16:41,699 changed 369 00:16:37,440 --> 00:16:43,019 so so it gives it to me for free 370 00:16:41,699 --> 00:16:46,740 um 371 00:16:43,019 --> 00:16:51,240 but that inferring of types it does have 372 00:16:46,740 --> 00:16:53,639 some problems an example of that is when 373 00:16:51,240 --> 00:16:56,639 we want to use none to carry error 374 00:16:53,639 --> 00:16:58,440 information back from a function say so 375 00:16:56,639 --> 00:17:01,380 we we start out and we say okay this 376 00:16:58,440 --> 00:17:03,060 variable is none but normally if we if 377 00:17:01,380 --> 00:17:05,520 we didn't have an error it's going to be 378 00:17:03,060 --> 00:17:07,140 a list of strings so that's what my 379 00:17:05,520 --> 00:17:10,640 files one was there 380 00:17:07,140 --> 00:17:14,760 so on the the second code fragment 381 00:17:10,640 --> 00:17:17,880 we're using a module that is in Python 382 00:17:14,760 --> 00:17:20,459 called typing and we're using a a 383 00:17:17,880 --> 00:17:22,040 something out of that called optional so 384 00:17:20,459 --> 00:17:25,980 I've just thrown this in now I'll 385 00:17:22,040 --> 00:17:28,500 explain this in more detail further on 386 00:17:25,980 --> 00:17:31,200 but then we're we're making the type of 387 00:17:28,500 --> 00:17:33,679 file list we're giving the hint that it 388 00:17:31,200 --> 00:17:36,720 is a list of strings 389 00:17:33,679 --> 00:17:40,080 or it could be none and that's exactly 390 00:17:36,720 --> 00:17:43,620 what optional means so when I assign 391 00:17:40,080 --> 00:17:45,120 none to it my pie at the bottom it was 392 00:17:43,620 --> 00:17:47,280 fine with that 393 00:17:45,120 --> 00:17:48,960 if I just said it was a list of strings 394 00:17:47,280 --> 00:17:53,820 it would have given me an error on that 395 00:17:48,960 --> 00:17:56,520 so now I can assign a a new list of 396 00:17:53,820 --> 00:17:58,080 strings to it I can add to that bit of a 397 00:17:56,520 --> 00:18:01,440 mistake in my code I meant to say file 398 00:17:58,080 --> 00:18:04,740 two but hey we can live 399 00:18:01,440 --> 00:18:08,760 okay now this is something that I really 400 00:18:04,740 --> 00:18:11,220 like where with python as we all know we 401 00:18:08,760 --> 00:18:14,400 have a convention for constants which is 402 00:18:11,220 --> 00:18:16,620 just the uppercase snake case for 403 00:18:14,400 --> 00:18:19,679 constants and that's worked reasonably 404 00:18:16,620 --> 00:18:22,140 well but if somebody actually assigns to 405 00:18:19,679 --> 00:18:24,539 the constant later there's no 406 00:18:22,140 --> 00:18:28,140 implications of that so it's easy for us 407 00:18:24,539 --> 00:18:31,200 to have an error in it so again from the 408 00:18:28,140 --> 00:18:33,960 typing module we have this idea of a 409 00:18:31,200 --> 00:18:36,200 final which means it can be assigned 410 00:18:33,960 --> 00:18:40,320 once but it can't be changed 411 00:18:36,200 --> 00:18:42,840 so with the with the type or with the 412 00:18:40,320 --> 00:18:46,500 constants the default scale factor and 413 00:18:42,840 --> 00:18:49,200 so on I've defined sorry I've hinted 414 00:18:46,500 --> 00:18:52,799 that this can't be changed it's final 415 00:18:49,200 --> 00:18:54,960 and it has a type of float 416 00:18:52,799 --> 00:18:58,860 um and similarly with the string 417 00:18:54,960 --> 00:19:00,419 I'm violating that in the next in uh 418 00:18:58,860 --> 00:19:01,260 lines 419 00:19:00,419 --> 00:19:04,140 um 420 00:19:01,260 --> 00:19:06,900 eight and nine so I'm violating that and 421 00:19:04,140 --> 00:19:09,000 when I run my pi over it it's telling me 422 00:19:06,900 --> 00:19:11,520 that the problem here was not that the 423 00:19:09,000 --> 00:19:14,700 that you had a change of type it was 424 00:19:11,520 --> 00:19:17,340 that you assigned to it at all I really 425 00:19:14,700 --> 00:19:18,720 like this I'm always assuming that you 426 00:19:17,340 --> 00:19:20,220 know I'll set up something and I'll say 427 00:19:18,720 --> 00:19:22,860 hey this is a constant and then somebody 428 00:19:20,220 --> 00:19:25,440 will change it and it's hard to find so 429 00:19:22,860 --> 00:19:27,840 uh so it's a small thing but I really 430 00:19:25,440 --> 00:19:30,059 like it 431 00:19:27,840 --> 00:19:32,880 ah okay 432 00:19:30,059 --> 00:19:36,419 um so type Checkers understand a lot of 433 00:19:32,880 --> 00:19:37,860 types so we're now up to a stage where a 434 00:19:36,419 --> 00:19:42,840 lot of peps have come through the system 435 00:19:37,860 --> 00:19:46,260 since uh python 3.5 and there's been a 436 00:19:42,840 --> 00:19:49,559 lot of extra tight Machinery added so 437 00:19:46,260 --> 00:19:51,600 that we can easily put in hints that 438 00:19:49,559 --> 00:19:54,500 really reflect our code 439 00:19:51,600 --> 00:19:58,200 so um so we've got all the simple types 440 00:19:54,500 --> 00:20:00,780 like integers floats and so on but we 441 00:19:58,200 --> 00:20:03,419 also have the collections and you can 442 00:20:00,780 --> 00:20:06,000 see the syntax there where we use a 443 00:20:03,419 --> 00:20:10,160 square bracket to say what the types are 444 00:20:06,000 --> 00:20:13,640 for that collection so Tuple it can have 445 00:20:10,160 --> 00:20:13,640 each of its 446 00:20:13,740 --> 00:20:19,260 indices each of its things in the Tuple 447 00:20:17,520 --> 00:20:22,260 can be different types so I've said that 448 00:20:19,260 --> 00:20:25,140 as T1 T2 and so on where with a list we 449 00:20:22,260 --> 00:20:26,580 we have a single type and a set and a 450 00:20:25,140 --> 00:20:28,080 dictionary we have a type for the key 451 00:20:26,580 --> 00:20:29,220 and a type for the value and they can be 452 00:20:28,080 --> 00:20:31,020 different 453 00:20:29,220 --> 00:20:34,740 and of course 454 00:20:31,020 --> 00:20:36,480 any of those types can be inside a 455 00:20:34,740 --> 00:20:40,679 collection so you can start to have 456 00:20:36,480 --> 00:20:43,320 types inside types but it reflects the 457 00:20:40,679 --> 00:20:45,600 code we write and that's the key thing 458 00:20:43,320 --> 00:20:46,860 if the Machinery wasn't up to the code 459 00:20:45,600 --> 00:20:49,740 that we write 460 00:20:46,860 --> 00:20:51,120 nobody would use it 461 00:20:49,740 --> 00:20:52,440 okay 462 00:20:51,120 --> 00:20:55,020 um 463 00:20:52,440 --> 00:20:57,000 yeah so so I just did a reason big 464 00:20:55,020 --> 00:21:00,179 complex one with that list which has a 465 00:20:57,000 --> 00:21:03,720 tuple and so on and the other one of 466 00:21:00,179 --> 00:21:07,559 course is classes classes are types as 467 00:21:03,720 --> 00:21:10,559 well so we can use a class from the 468 00:21:07,559 --> 00:21:11,820 standard Library we can use our own and 469 00:21:10,559 --> 00:21:12,539 we can 470 00:21:11,820 --> 00:21:15,240 um 471 00:21:12,539 --> 00:21:16,980 type hint that we expect an object of 472 00:21:15,240 --> 00:21:19,500 this particular class 473 00:21:16,980 --> 00:21:21,900 okay so some some really bad examples 474 00:21:19,500 --> 00:21:24,179 they're just little code Snippets of 475 00:21:21,900 --> 00:21:25,559 just showing how we can use the type 476 00:21:24,179 --> 00:21:26,700 hints 477 00:21:25,559 --> 00:21:29,880 um 478 00:21:26,700 --> 00:21:31,860 with the count list where we pass in we 479 00:21:29,880 --> 00:21:36,000 say that we will pass in a list of 480 00:21:31,860 --> 00:21:37,740 integers and return an integer same idea 481 00:21:36,000 --> 00:21:40,200 for find keys 482 00:21:37,740 --> 00:21:43,500 but we're using a dictionary so that 483 00:21:40,200 --> 00:21:46,080 that syntax is it's pretty small there's 484 00:21:43,500 --> 00:21:48,600 not a lot of noise 485 00:21:46,080 --> 00:21:51,780 originally There Was You Know type hints 486 00:21:48,600 --> 00:21:55,520 in documentation all that stuff it was 487 00:21:51,780 --> 00:21:59,880 so verbose for a uh a small 488 00:21:55,520 --> 00:22:01,740 code fragment like this your type 489 00:21:59,880 --> 00:22:04,200 information would be larger than the 490 00:22:01,740 --> 00:22:06,559 fragment so this is quite 491 00:22:04,200 --> 00:22:09,780 um quite succinct 492 00:22:06,559 --> 00:22:12,840 with the line eight I'm actually using 493 00:22:09,780 --> 00:22:16,260 something called the type Alias and the 494 00:22:12,840 --> 00:22:21,840 idea here is to make things readable so 495 00:22:16,260 --> 00:22:22,799 we we actually b day is uh is actually a 496 00:22:21,840 --> 00:22:25,260 new type 497 00:22:22,799 --> 00:22:28,260 which means the Tuple type that you see 498 00:22:25,260 --> 00:22:29,179 there and I'll show that in in a slide 499 00:22:28,260 --> 00:22:33,840 or two 500 00:22:29,179 --> 00:22:38,120 so we have our ad birthdays that take a 501 00:22:33,840 --> 00:22:41,880 list of that Tuple type and a single 502 00:22:38,120 --> 00:22:42,539 Tuple type or sorry yeah a single 503 00:22:41,880 --> 00:22:45,960 um 504 00:22:42,539 --> 00:22:48,140 uh b-day one to add a birthday to that 505 00:22:45,960 --> 00:22:48,140 list 506 00:22:49,080 --> 00:22:52,740 okay 507 00:22:51,059 --> 00:22:54,419 again I'm going through stuff really 508 00:22:52,740 --> 00:22:57,419 quickly because I'm assuming that a lot 509 00:22:54,419 --> 00:22:59,820 of people are are used to some of this 510 00:22:57,419 --> 00:23:02,280 and I want to get to some interesting 511 00:22:59,820 --> 00:23:04,200 ones but I've put this slide early 512 00:23:02,280 --> 00:23:07,140 because I was afraid that I would go too 513 00:23:04,200 --> 00:23:08,580 slow and I would run out of time so I 514 00:23:07,140 --> 00:23:09,360 still have seven minutes so it's not too 515 00:23:08,580 --> 00:23:11,880 bad 516 00:23:09,360 --> 00:23:14,100 but um so here's the question that I 517 00:23:11,880 --> 00:23:16,799 wanted to answer at the beginning and I 518 00:23:14,100 --> 00:23:21,059 want you know have I convinced you that 519 00:23:16,799 --> 00:23:22,740 these are easy to use but helpful so 520 00:23:21,059 --> 00:23:24,960 again this is the third time I'm going 521 00:23:22,740 --> 00:23:28,320 to mention that python remains a dynamic 522 00:23:24,960 --> 00:23:30,440 duct type language and you lose nothing 523 00:23:28,320 --> 00:23:32,940 when you go to type hints 524 00:23:30,440 --> 00:23:35,780 though there are some cons which is 525 00:23:32,940 --> 00:23:38,280 coming up so the pros what do you get 526 00:23:35,780 --> 00:23:41,880 well it means that you can use a type 527 00:23:38,280 --> 00:23:43,559 Checker to help you so in this case I 528 00:23:41,880 --> 00:23:44,940 was using my pie but it's true of a 529 00:23:43,559 --> 00:23:46,980 whole bunch of other ones 530 00:23:44,940 --> 00:23:50,039 and one of the interesting things is is 531 00:23:46,980 --> 00:23:52,980 that there is the definition of the full 532 00:23:50,039 --> 00:23:54,780 standard Library when you download My 533 00:23:52,980 --> 00:23:58,440 Pie you get this thing called the type 534 00:23:54,780 --> 00:24:01,559 shed with the current instance of it and 535 00:23:58,440 --> 00:24:05,159 it it has all of the stubs for the 536 00:24:01,559 --> 00:24:07,080 standard Library so all of your use will 537 00:24:05,159 --> 00:24:09,720 be checked 538 00:24:07,080 --> 00:24:12,120 um all of your code will be checked when 539 00:24:09,720 --> 00:24:16,080 you use the standard Library I mentioned 540 00:24:12,120 --> 00:24:17,940 before that Ides and editors are using 541 00:24:16,080 --> 00:24:20,220 these hints to provide better tooling 542 00:24:17,940 --> 00:24:22,580 I'm really liking that 543 00:24:20,220 --> 00:24:24,900 better documentation 544 00:24:22,580 --> 00:24:27,720 as well where you're actually saying 545 00:24:24,900 --> 00:24:30,720 what your intent is with the code that 546 00:24:27,720 --> 00:24:32,940 you're expecting that a a variable of 547 00:24:30,720 --> 00:24:35,280 this type will be passed to you the 548 00:24:32,940 --> 00:24:39,179 downside is that you have to take the 549 00:24:35,280 --> 00:24:40,760 time to one not reuse variables for 550 00:24:39,179 --> 00:24:43,919 different purposes 551 00:24:40,760 --> 00:24:47,340 think about the functions a bit more and 552 00:24:43,919 --> 00:24:50,580 be explicit about the types add the type 553 00:24:47,340 --> 00:24:51,900 hints in and the other one is is run a 554 00:24:50,580 --> 00:24:53,340 type Checker against it because you 555 00:24:51,900 --> 00:24:55,280 don't run a type Checker against it that 556 00:24:53,340 --> 00:24:58,140 was a bit of a waste of time 557 00:24:55,280 --> 00:25:00,059 and if you have a large code base that 558 00:24:58,140 --> 00:25:02,580 can be a bit more difficult to add type 559 00:25:00,059 --> 00:25:05,940 hints because when you start adding type 560 00:25:02,580 --> 00:25:06,960 hints you will start getting errors and 561 00:25:05,940 --> 00:25:09,539 um 562 00:25:06,960 --> 00:25:10,860 it can be a bit more difficult 563 00:25:09,539 --> 00:25:11,820 and 564 00:25:10,860 --> 00:25:13,740 um 565 00:25:11,820 --> 00:25:15,419 again everybody doesn't have to use type 566 00:25:13,740 --> 00:25:18,840 hints because it just depends on if it 567 00:25:15,419 --> 00:25:21,780 goes with your style but trying it I 568 00:25:18,840 --> 00:25:24,360 think that's something that we can do 569 00:25:21,780 --> 00:25:26,460 okay uh so some more interesting 570 00:25:24,360 --> 00:25:27,900 Machinery is 571 00:25:26,460 --> 00:25:31,380 um 572 00:25:27,900 --> 00:25:34,200 I've shown optional from the typing 573 00:25:31,380 --> 00:25:36,000 module we also have some other special 574 00:25:34,200 --> 00:25:39,000 types like any 575 00:25:36,000 --> 00:25:41,960 uh and any is the default type when my 576 00:25:39,000 --> 00:25:45,179 Pi looks at your code to check it it 577 00:25:41,960 --> 00:25:48,299 defaults to any for all of the arguments 578 00:25:45,179 --> 00:25:50,520 all of the variables and what any means 579 00:25:48,299 --> 00:25:52,440 is it basically just means anything can 580 00:25:50,520 --> 00:25:54,539 happen so there's no use to check it 581 00:25:52,440 --> 00:25:57,900 because anything can happen 582 00:25:54,539 --> 00:26:00,200 so that's the default any string is kind 583 00:25:57,900 --> 00:26:03,120 of interesting because we often 584 00:26:00,200 --> 00:26:06,240 we often have interfaces that take 585 00:26:03,120 --> 00:26:08,220 either a string or bytes any string says 586 00:26:06,240 --> 00:26:11,700 it's just a type that can be either of 587 00:26:08,220 --> 00:26:15,659 those but it make sure you don't mix 588 00:26:11,700 --> 00:26:17,279 them so if you want bytes to be passed 589 00:26:15,659 --> 00:26:18,779 for both parameters and this will do it 590 00:26:17,279 --> 00:26:20,820 for you or string 591 00:26:18,779 --> 00:26:23,520 the other interesting one I really like 592 00:26:20,820 --> 00:26:26,460 is the union so the union is a way of 593 00:26:23,520 --> 00:26:29,580 saying ah in this in this function I 594 00:26:26,460 --> 00:26:32,159 will take Floats or I will take strings 595 00:26:29,580 --> 00:26:33,679 now of course if you do that you then 596 00:26:32,159 --> 00:26:36,720 have to 597 00:26:33,679 --> 00:26:38,880 make sure that you check it correctly in 598 00:26:36,720 --> 00:26:40,440 your code because you could get one or 599 00:26:38,880 --> 00:26:42,419 the other you can't assume that it's 600 00:26:40,440 --> 00:26:44,640 going to be afloat but that's where we 601 00:26:42,419 --> 00:26:45,600 have things like is instance and it is 602 00:26:44,640 --> 00:26:48,720 subclass 603 00:26:45,600 --> 00:26:50,520 uh where we can do that check same thing 604 00:26:48,720 --> 00:26:52,740 with the optional we'd have to check to 605 00:26:50,520 --> 00:26:55,679 see if none was passed in but then we 606 00:26:52,740 --> 00:26:57,059 have the if this is none so we've got a 607 00:26:55,679 --> 00:26:59,700 way to do that 608 00:26:57,059 --> 00:27:02,220 uh the code here uh you can just see 609 00:26:59,700 --> 00:27:04,380 I've got Union showing there and that's 610 00:27:02,220 --> 00:27:06,200 actually the old style of Union too 611 00:27:04,380 --> 00:27:08,640 difficult don't want to have to do that 612 00:27:06,200 --> 00:27:11,340 but you can see where we've just had a 613 00:27:08,640 --> 00:27:14,340 union of a string interfloat and we're 614 00:27:11,340 --> 00:27:17,760 using the is instance in the code to 615 00:27:14,340 --> 00:27:19,320 make sure we we don't call a function on 616 00:27:17,760 --> 00:27:24,539 something that it the type doesn't 617 00:27:19,320 --> 00:27:27,000 support on the take take various the 618 00:27:24,539 --> 00:27:30,539 second one now we actually have I think 619 00:27:27,000 --> 00:27:36,900 this came in in 310 we can use the uh 620 00:27:30,539 --> 00:27:38,580 the or bar in type hints to um 621 00:27:36,900 --> 00:27:40,260 to 622 00:27:38,580 --> 00:27:41,960 um 623 00:27:40,260 --> 00:27:46,260 let us Define 624 00:27:41,960 --> 00:27:50,220 Union type hints and that is used a lot 625 00:27:46,260 --> 00:27:52,559 okay I'm running a bit long one other 626 00:27:50,220 --> 00:27:54,840 thing I just want to say because it's so 627 00:27:52,559 --> 00:27:57,120 interesting is I want to describe 628 00:27:54,840 --> 00:28:00,600 something called a protocol and what 629 00:27:57,120 --> 00:28:02,279 this is is this is duct taping it's 630 00:28:00,600 --> 00:28:06,240 actually called structural typing in 631 00:28:02,279 --> 00:28:10,080 this case but it allows us to say that 632 00:28:06,240 --> 00:28:13,860 this function it takes not a particular 633 00:28:10,080 --> 00:28:16,580 type but it takes an object that has 634 00:28:13,860 --> 00:28:16,580 quack 635 00:28:16,799 --> 00:28:23,159 um so what we do is we create on line 636 00:28:20,039 --> 00:28:25,679 three a protocol called supports quack 637 00:28:23,159 --> 00:28:28,500 in this case and see the syntax where we 638 00:28:25,679 --> 00:28:32,159 just Define the signature of a function 639 00:28:28,500 --> 00:28:33,659 but then we use Ellipsis dot dot and 640 00:28:32,159 --> 00:28:35,220 that means we don't care about the body 641 00:28:33,659 --> 00:28:36,419 we're only talking about the function 642 00:28:35,220 --> 00:28:40,679 signature 643 00:28:36,419 --> 00:28:42,539 and then if we try to run this we we get 644 00:28:40,679 --> 00:28:44,640 an error because they're 645 00:28:42,539 --> 00:28:46,559 um sorry this isn't running this is my 646 00:28:44,640 --> 00:28:47,840 Pi this is the whole point when we try 647 00:28:46,559 --> 00:28:51,059 to check it 648 00:28:47,840 --> 00:28:53,039 we get an error immediately which is 649 00:28:51,059 --> 00:28:55,580 saying that hey this one doesn't support 650 00:28:53,039 --> 00:28:55,580 quack 651 00:28:56,220 --> 00:29:02,640 if we try it with a duck object 652 00:28:59,760 --> 00:29:04,380 that does support quack then my Pi is 653 00:29:02,640 --> 00:29:06,659 totally fine so this is where we're 654 00:29:04,380 --> 00:29:08,520 starting to go full circle where we can 655 00:29:06,659 --> 00:29:11,480 still have duct typing but we can also 656 00:29:08,520 --> 00:29:11,480 have checking as well 657 00:29:12,059 --> 00:29:15,960 there is this idea of gradual type 658 00:29:14,460 --> 00:29:19,980 hinting and it's because we've got 659 00:29:15,960 --> 00:29:23,520 millions of lines of python code so 660 00:29:19,980 --> 00:29:25,919 um so we we can just start putting 661 00:29:23,520 --> 00:29:27,899 typing on just a couple functions and 662 00:29:25,919 --> 00:29:30,539 just a couple files and we can still 663 00:29:27,899 --> 00:29:32,760 check things and we've I've got some 664 00:29:30,539 --> 00:29:35,100 hints at the bottom there where with my 665 00:29:32,760 --> 00:29:37,679 Pi the first one is is that we can use 666 00:29:35,100 --> 00:29:40,679 an option called ignore missing Imports 667 00:29:37,679 --> 00:29:43,440 which allows us to say don't worry about 668 00:29:40,679 --> 00:29:46,679 anything that I bring in 669 00:29:43,440 --> 00:29:48,059 um sorry I've got a wrap up uh work on 670 00:29:46,679 --> 00:29:51,000 type hints has been very fast and 671 00:29:48,059 --> 00:29:53,159 furious 30 peps in eight years that's 672 00:29:51,000 --> 00:29:55,080 ridiculous but that's because getting 673 00:29:53,159 --> 00:29:58,020 tight Machinery is hard 674 00:29:55,080 --> 00:29:59,820 uh I've got some references here 675 00:29:58,020 --> 00:30:04,980 um the one I just want to point out is 676 00:29:59,820 --> 00:30:08,460 go to the mypie org website and it has 677 00:30:04,980 --> 00:30:10,620 is it my pug work uh anyways the my Pi 678 00:30:08,460 --> 00:30:13,380 website it actually has a really good 679 00:30:10,620 --> 00:30:15,000 tutorial on everything to do with these 680 00:30:13,380 --> 00:30:17,460 types 681 00:30:15,000 --> 00:30:20,419 thank you very much and don't forget to 682 00:30:17,460 --> 00:30:20,419 run the type checker 683 00:30:23,419 --> 00:30:27,720 thank you Brian 684 00:30:25,919 --> 00:30:30,059 um unfortunately we won't have time to 685 00:30:27,720 --> 00:30:34,520 take questions but um there's the mug 686 00:30:30,059 --> 00:30:34,520 thanks very much this is why we do it 687 00:30:34,860 --> 00:30:39,120 um we'll be now heading on for a break 688 00:30:37,140 --> 00:30:42,740 and then we'll be having lightning talks 689 00:30:39,120 --> 00:30:46,279 in Hall C at 350. thank you everyone 690 00:30:42,740 --> 00:30:46,279 [Applause]