WEBVTT 1 00:00:01.950 --> 00:00:06.850 so continuing on from the last video so global keyword tells Python to 2 00:00:06.850 --> 00:00:11.730 look for a variable in the global scope which is the modules name space but the 3 00:00:11.730 --> 00:00:16.410 non local keyword tells it to look for that variable in the enclosing 4 00:00:16.410 --> 00:00:20.570 scopes and you could see what we've done differently to other videos is 5 00:00:20.570 --> 00:00:25.000 we've got an embedded function here that we didn't have at the blackjack program so 6 00:00:25.000 --> 00:00:30.130 that's why on line 7 the global keyword wasn't appropriate so again the non local 7 00:00:30.130 --> 00:00:34.420 keyword if that is telling Python to look for the variable in the enclosing 8 00:00:34.420 --> 00:00:38.680 scope so non local won't check the global name space though so a 9 00:00:38.680 --> 00:00:44.240 non local variable must exist in the enclosing scope but not be global otherwise if it 10 00:00:44.240 --> 00:00:49.130 was global of course you would use the keyword global to do that another thing to know 11 00:00:49.130 --> 00:00:53.530 about the non local variables is that they must exist in the enclosing scope 12 00:00:53.530 --> 00:00:59.660 they can't be created in other words by the non local keywords so if we change this to try and put a declaration 13 00:00:59.660 --> 00:01:05.500 in their we get an error...end of statement expected because it's looking for us just to define 14 00:01:05.500 --> 00:01:09.859 the variable to say that it's a non-local variable but it has to actually exist as 15 00:01:09.859 --> 00:01:15.380 I mentioned in the outer scope or in the enclosing scope to be more precise now 16 00:01:15.380 --> 00:01:18.459 although we didn't do this we could have created our global variables for 17 00:01:18.459 --> 00:01:21.270 blackjack in the new_game method and they would have been 18 00:01:21.270 --> 00:01:25.979 available in the main program but it's not considered good style to that and 19 00:01:25.979 --> 00:01:30.100 can lead to difficulty debugging the programs but it's there and it is actually 20 00:01:30.100 --> 00:01:35.159 allowed but the same is not true for non local variables and that's because Python 21 00:01:35.159 --> 00:01:38.939 doesn't know which enclosing scope the should have existed and has really has no 22 00:01:38.939 --> 00:01:42.459 way to know whether to create them so they must already be present in an 23 00:01:42.459 --> 00:01:47.599 enclosing scope or you get an error for that reason so at this point its a 24 00:01:47.599 --> 00:01:51.770 good time to point out that the only things that create scope in Python are 25 00:01:51.770 --> 00:01:57.119 modules functions and classes now I've already talked about variables in a module 26 00:01:57.119 --> 00:02:01.679 being defined in a while for loop and then and remaining available to the rest 27 00:02:01.679 --> 00:02:06.159 of the program but that's because they become part of the global name space now 28 00:02:06.159 --> 00:02:10.259 that can seem odd if you come from Java for example but the idea that functions 29 00:02:10.259 --> 00:02:13.220 introduced a new scope will be familiar 30 00:02:13.220 --> 00:02:17.250 know when you define a function Python creates a new name space for it and 31 00:02:17.250 --> 00:02:23.510 any variables are part of the local scope and to that end we actually printed out the local 32 00:02:23.510 --> 00:02:29.460 variables using the locals function in the blackjack game a few videos ago so non 33 00:02:29.460 --> 00:02:33.930 local tells python to look for variables in an enclosing function and 34 00:02:33.930 --> 00:02:37.590 if it doesn't find it there to check in a functioning closing that and so on 35 00:02:37.590 --> 00:02:41.800 it will not though check the global name space as I mentioned so if you remember 36 00:02:41.800 --> 00:02:46.820 that it doesn't include globals then non local is a good name for it variables that are not 37 00:02:46.820 --> 00:02:50.720 local to the current scope ok so hopefully that made a lot of sense 38 00:02:50.720 --> 00:02:56.380 earlier implied that functions can be nested inside functions and themselves 39 00:02:56.380 --> 00:03:00.560 are themselves nested in another function its quite rare to have 40 00:03:00.560 --> 00:03:03.870 more than one level of nesting in any code that did so would have to be quite 41 00:03:03.870 --> 00:03:09.140 complicated so I use a variation of the spam function in the tutorial to 42 00:03:09.140 --> 00:03:14.160 demonstrate a deeper level of nesting and bearing in mind its probably not 43 00:03:14.160 --> 00:03:17.540 something you have to do very often but the functions would be very similar and 44 00:03:17.540 --> 00:03:19.810 just returned different amounts of spam 45 00:03:19.810 --> 00:03:23.930 in this case but that will let us focus on the scope issues rather than getting 46 00:03:23.930 --> 00:03:27.890 bogged down in complicated code so we are gonna create a new Python file called 47 00:03:27.890 --> 00:03:37.769 spam.py and we are going to enter the following code in it and just do a test 48 00:03:37.769 --> 00:03:47.540 on this and have a look at these functions so... 49 00:03:47.540 --> 00:03:53.320 .... 50 00:03:57.630 --> 00:04:29.860 .... 51 00:04:31.000 --> 00:04:37.000 .... 52 00:04:37.740 --> 00:04:51.220 .....so as you can see 53 00:04:51.220 --> 00:04:56.230 here the function spam one contains another function called spam 2 and 54 00:04:56.230 --> 00:05:05.160 that's spam 2 function contains a third function called spam 3 and if we run this 55 00:05:05.160 --> 00:05:11.530 you can see that spam 1 calls the spam 2 function and then adds its result on to spam 1's text and 56 00:05:11.530 --> 00:05:15.550 spam 2 in turn adds the result of the spam 3 function on its text and 57 00:05:15.550 --> 00:05:19.320 subsequently we get a lot of spam now to get a clearer idea of what's 58 00:05:19.320 --> 00:05:22.880 happening here we can print out the locals dictionary from inside each of the 59 00:05:22.880 --> 00:05:26.280 functions I'm going to use a format string so that we can add a label 60 00:05:26.280 --> 00:05:29.740 before each dictionary to be sure where it came from so let's go ahead and do 61 00:05:29.740 --> 00:05:46.750 that i'm gonna start in spam 3.... 62 00:05:46.750 --> 00:06:05.700 .... 63 00:06:06.240 --> 00:06:16.759 .... 64 00:06:16.759 --> 00:06:23.580 so if we run this again now I've done the same thing in my haste here 65 00:06:23.580 --> 00:06:28.539 so that should have been tabbed over my bad their when I was adding the new lines so 66 00:06:28.539 --> 00:06:36.860 try that again now we can see now and you can see that 67 00:06:36.860 --> 00:06:40.720 it's showing which names are local to each function and we can see that for example 68 00:06:40.720 --> 00:06:46.430 the function spam 3 just contains the string variable z but spam 2 69 00:06:46.430 --> 00:06:53.889 contains the string variable called y you can see it here nearly off the screen but it also contains 70 00:06:53.889 --> 00:06:55.770 a function as you can see there 71 00:06:55.770 --> 00:07:02.500 called spam 3 you can see that reference their and also spam 1 has got a local variable X 72 00:07:02.500 --> 00:07:08.050 and a function called spam 2 as you can see here so within spam 1 73 00:07:08.050 --> 00:07:12.599 itself we can't refer to the variables y&z because variables in an 74 00:07:12.599 --> 00:07:18.240 inner scope aren't available to the outer scope but however inside spam 2 we can 75 00:07:18.240 --> 00:07:22.169 refer to x and inside spam 3 we can refer to both X&Y 76 00:07:23.130 --> 00:07:28.009 so an inner scope has access to the variables defined in an outer scope and we can use the 77 00:07:28.009 --> 00:07:34.500 outer variables and spam 2 spam 3 lets do that by making small change to the code so 78 00:07:34.500 --> 00:07:46.050 close it down lets have a look on what its gonna look like so if we change this now and I'll make that even.... 79 00:07:46.050 --> 00:08:05.520 .... 80 00:08:05.520 --> 00:08:08.870 and run this to make sure it works so you could see that is working ok 81 00:08:09.590 --> 00:08:14.920 and because we're not assigning to X&Y in the inner functions the names don't shadow 82 00:08:14.920 --> 00:08:18.920 the variable in the outer scope and as a result the values are then available for 83 00:08:18.920 --> 00:08:24.010 use now I'm gonna demonstrate scope and it's not necessary sensible thing 84 00:08:24.010 --> 00:08:27.540 to do here but it will demonstrate what we're trying to get across to you and 85 00:08:27.540 --> 00:08:32.250 the reason is... 86 00:08:32.250 --> 00:08:34.190 lines 16 and 17 87 00:08:34.190 --> 00:08:39.000 cam be combined into a single expression and when I change them lets have a look 88 00:08:39.000 --> 00:08:44.090 and see what happens so this here I'm gonna make... 89 00:08:46.390 --> 00:08:52.000 now the mini challenge here is before actually running this program can you work at 90 00:08:52.000 --> 00:08:56.040 what's going to happen and why its going to happen because I only done a simple thing 91 00:08:56.040 --> 00:09:01.530 as you can see I've merged lines 16 and 17 to make it one line but I want you to see if you can 92 00:09:01.530 --> 00:09:07.130 figure out what's going to happen and why so pause the video now and have a think about it and when 93 00:09:07.130 --> 00:09:10.130 your ready to continue come back and we'll go through it 94 00:09:14.450 --> 00:09:18.660 ok so hopefully you have a look at it you might be actually curious if you didn't 95 00:09:18.660 --> 00:09:24.230 figure it out so let's talk about what actually happens now the change I made was 96 00:09:24.230 --> 00:09:27.910 quite simple and it might appear at face value to be a simple optimization 97 00:09:27.910 --> 00:09:33.160 but in actual fact that simple optimization breaks the code and without 98 00:09:33.160 --> 00:09:37.480 starting the spam 2 function it wasn't obvious that the code was gonna break 99 00:09:37.480 --> 00:09:42.370 so lets run it first to confirm that there is a problem and you can see we get 100 00:09:42.370 --> 00:09:46.780 these weird errors so three variable X is referenced before assignment in closing 101 00:09:46.780 --> 00:09:47.720 scope 102 00:09:47.720 --> 00:09:51.130 we got errors here on line 2016 and 11 103 00:09:51.130 --> 00:09:56.990 so what actually happened is that spam 2 the function attempts to use the 104 00:09:56.990 --> 00:10:02.930 value of x but spent spam 2 is called during the initial assignment to X so x doesn't 105 00:10:02.930 --> 00:10:09.320 yet have a value as a result we get the error free variable X 106 00:10:09.320 --> 00:10:12.660 this down here on the bottom free variable x referenced before 107 00:10:12.660 --> 00:10:16.690 assignment in closing scope so theirs actually 3 lessons to learn from the 108 00:10:16.690 --> 00:10:23.550 simple change I'm gonna move the it their so we can look at the source code at the same time while we are talking about it so 109 00:10:23.550 --> 00:10:28.120 the three things are wherever possible try to write functions so that they only 110 00:10:28.120 --> 00:10:33.890 use local variables and parameters only access global and non-local variables 111 00:10:33.890 --> 00:10:38.760 when it's absolutely necessary if you can see an unexpected code such as our 112 00:10:38.760 --> 00:10:46.840 use of 2 lines to assign x and even also to assign y on line 11 and 12 think carefully before 113 00:10:46.840 --> 00:10:50.180 changing them because it could be that the programmer who wrote them was having a 114 00:10:50.180 --> 00:10:55.420 bad day but also their could be a very valid reason why they used 2 lines 115 00:10:55.420 --> 00:10:59.900 when one would appear to do so no matter how trivial a change do you think you've 116 00:10:59.900 --> 00:11:04.700 made test the program thoroughly to make sure you haven't broken anything that's 117 00:11:04.700 --> 00:11:08.280 often simple changes like that that will actually break code and major changes 118 00:11:08.280 --> 00:11:12.040 will probably get through testing anyway but very simple modifications can get 119 00:11:12.040 --> 00:11:16.690 overlooked and this will be a case of the change that I've made on the 16 and 17 to 120 00:11:16.690 --> 00:11:19.420 merge them into one line would be something with that would often 121 00:11:19.420 --> 00:11:25.590 get overlooked and actually there's a fourth lesson here as well and that is that if your write unexpected 122 00:11:25.590 --> 00:11:30.840 code such as our use of 2 lines we assigning X&Y make sure you include a 123 00:11:30.840 --> 00:11:35.370 comment to explain why so the next person who works on your code doesn't do 124 00:11:35.370 --> 00:11:42.410 what you've just done so what we do is undo the change put it back to how it was 125 00:11:42.410 --> 00:11:50.740 before and we come back and say.... 126 00:11:51.660 --> 00:12:00.660 .....and on lines 11 and 12 we would 127 00:12:00.660 --> 00:12:06.070 say something like.... 128 00:12:09.700 --> 00:12:17.510 ...you will actually be surprised how often that next person is 129 00:12:17.510 --> 00:12:21.670 you so coming back to the code perhaps have looked at the program you have written for a 130 00:12:21.670 --> 00:12:26.580 number of days weeks months or even years so the person that you are writing 131 00:12:26.580 --> 00:12:33.460 this comments for could ultimately be used and I just put in an extra space here should have bee watching the 132 00:12:33.460 --> 00:12:39.840 warnings to keep the compiler happy so yeah the person could actually be you 133 00:12:39.840 --> 00:12:44.080 that you're trying to help out here and you can quickly really forget why you did something 134 00:12:44.080 --> 00:12:47.910 in a certain way so using comments like this to explain anything you do that's 135 00:12:47.910 --> 00:12:52.040 not obvious is very very highly recommended now before I finish this 136 00:12:52.040 --> 00:12:55.410 section out theirs two more things to look at the first is very simple 137 00:12:55.410 --> 00:12:59.740 their at the module level the local scope is the same as the global scope so we can 138 00:12:59.740 --> 00:13:05.300 see that by printing both out at the end of the program so lets add these couples of lines of output 139 00:13:05.300 --> 00:13:15.840 to just check that so...and if you run that 140 00:13:23.430 --> 00:13:27.460 and if we scroll across you should find that the basically the two outputs from locals to globals 141 00:13:27.460 --> 00:13:30.830 is giving us the identical output here you can see this looking pretty well 142 00:13:30.830 --> 00:13:35.890 identical right through to the end everything is basically identical that's 143 00:13:35.890 --> 00:13:40.260 for those last two lines of output which correspond to the output from line 22 to 23 144 00:13:41.880 --> 00:13:46.760 so that confirms that in the module scope locals and globals are the same 145 00:13:46.760 --> 00:13:51.630 second thing though is a bit odd and you might be wondering about it if 146 00:13:51.630 --> 00:13:54.600 you paid careful attention to the program's output since I added the non 147 00:13:54.600 --> 00:14:03.779 local variables so lets have a look at that again so spam 3 original had a single variable called z but 148 00:14:03.779 --> 00:14:10.810 now you can see up here it also has y as local and spam 2 you see that has 149 00:14:10.810 --> 00:14:16.209 now got an x its got the x as local as well now this is very odd it seems to go 150 00:14:16.209 --> 00:14:20.320 against everything I have just discussed about non local variables but in fact 151 00:14:20.320 --> 00:14:24.560 the explanation behavior of non local variables is perfectly correct so 152 00:14:24.560 --> 00:14:28.990 there's nothing to worry about what we are seeing is a result of the way the locals 153 00:14:28.990 --> 00:14:34.080 function works and some optimization of the part of Python and that's because whether 154 00:14:34.080 --> 00:14:38.680 you use a non-local variable in the way we've done python adds it to the local 155 00:14:38.680 --> 00:14:41.959 name space so that it doesn't have to go hunting through all the enclosing 156 00:14:41.959 --> 00:14:46.350 scopes every time you use it so it still referring to the non local variable 157 00:14:46.350 --> 00:14:52.400 its just a reference it in locals to make everything run faster and it might be worth your while 158 00:14:52.400 --> 00:15:00.360 having a look at the documentation for the locals function as well I'm just gonna bring that up on the screen 159 00:15:00.360 --> 00:15:03.360 theirs the link on the screen as you can see up there so we go to that 160 00:15:06.860 --> 00:15:15.060 theirs locals so a free variable is a variable that's used in a scope where it has not been 161 00:15:15.060 --> 00:15:20.750 defined which is exactly the same thing as a non-local variable when working 162 00:15:20.750 --> 00:15:24.010 with the scope of variables it is helpful to remember the analogy 163 00:15:24.010 --> 00:15:30.260 LEGB and that stands for local enclosing global built-ins and list the order to 164 00:15:30.260 --> 00:15:37.120 which Python searches for names so again its local enclosing global and built-ins so 165 00:15:37.120 --> 00:15:40.500 closing refers to non-local or free variables that I've discussed in this 166 00:15:40.500 --> 00:15:45.510 lecture now globals we have also seen and we have looked at how to use it and assigned to 167 00:15:45.510 --> 00:15:51.410 global variables of course in our functions built in refers to the name that are built-in to Python 168 00:15:51.410 --> 00:15:54.950 and that we've been using throughout the course we've got into the builtins.py module 169 00:15:54.950 --> 00:15:58.550 quite a few times now to have a look at the various functions and built-ins are 170 00:15:58.550 --> 00:16:02.620 the final place that Python will possible look to when trying to resolve a 171 00:16:02.620 --> 00:16:07.390 name now if you remember and understand that LEGB in order and again that is local enclosing 172 00:16:07.390 --> 00:16:11.820 global built-ins if remember that for resolving names and take note of the 173 00:16:11.820 --> 00:16:15.760 warnings that IntelliJ gives you should be quite comfortable with the way Python 174 00:16:15.760 --> 00:16:20.330 scoping works and then should also be able to use non-local and global variables 175 00:16:20.330 --> 00:16:21.240 when you need to 176 00:16:21.240 --> 00:16:27.800 ok finally that brings this section to an end it's been a very very long one we've 177 00:16:27.800 --> 00:16:31.020 looked at a few modules from the Python standard library and also the 178 00:16:31.020 --> 00:16:35.310 documentation so that other modules should be much easier to use when a program 179 00:16:35.310 --> 00:16:39.360 needs the functionality they provide and of course we also had a look at GUI 180 00:16:39.360 --> 00:16:44.470 programming called TKinter we did a lot with that but we are not done with that yet and theirs few more 181 00:16:44.470 --> 00:16:48.100 things we need to come before you can use it to its full potential and then 182 00:16:48.100 --> 00:16:51.520 covered functions showing you how they are or what they are I should say and how to write your own 183 00:16:51.520 --> 00:16:56.580 and in the process we learn about scope in Python now classes are also 184 00:16:56.580 --> 00:16:58.030 created a new namespace 185 00:16:58.030 --> 00:17:01.750 and we are gonna be covering object oriented programming in classes in the next section 186 00:17:01.750 --> 00:17:02.940 so I'll see you their