1 00:00:07,880 --> 00:00:11,970 Welcome back. The scope of a variable is 2 00:00:11,970 --> 00:00:15,780 the set of statements where a variable name can be accessed. 3 00:00:15,780 --> 00:00:17,955 In the function square, 4 00:00:17,955 --> 00:00:24,060 on line two, we assign y to have a value. 5 00:00:24,060 --> 00:00:27,690 Since that assignment is inside the function definition, 6 00:00:27,690 --> 00:00:31,125 the scope is only the rest of that function definition. 7 00:00:31,125 --> 00:00:36,585 On line six, we really can't refer to y. 8 00:00:36,585 --> 00:00:40,530 In fact, we really can't refer to y. 9 00:00:40,530 --> 00:00:44,515 We get an error. On line six, 10 00:00:44,515 --> 00:00:49,460 the error message is telling us the name y is not defined, 11 00:00:49,460 --> 00:00:55,145 and that's true even though line two will already have executed, 12 00:00:55,145 --> 00:00:58,745 line five causes the square function to run. 13 00:00:58,745 --> 00:01:02,910 So, line two will have executed, but even so, 14 00:01:02,950 --> 00:01:09,860 we say that that variable y was local to the function square, 15 00:01:09,860 --> 00:01:11,735 and its scope is local, 16 00:01:11,735 --> 00:01:15,730 we can't access it out here on line six. 17 00:01:15,730 --> 00:01:23,070 Now, suppose we had a variable y at the top level outside of any function definition. 18 00:01:23,070 --> 00:01:30,210 Say, we did y equals five. 19 00:01:31,310 --> 00:01:34,320 Now, when we get to line six, 20 00:01:34,320 --> 00:01:36,465 y will be defined, 21 00:01:36,465 --> 00:01:40,310 but the value will be five and not 100. 22 00:01:40,310 --> 00:01:45,080 What we get is the value five that we signed on line 23 00:01:45,080 --> 00:01:50,535 four and not the value 100 that we would have assigned on line two. 24 00:01:50,535 --> 00:01:53,825 It's going to help to introduce a little vocabulary here, 25 00:01:53,825 --> 00:01:56,150 the idea of a namespace. 26 00:01:56,150 --> 00:02:00,580 A namespace is an environment where all names are unique. 27 00:02:00,580 --> 00:02:02,595 The city of Ann Arbor, Michigan, 28 00:02:02,595 --> 00:02:07,290 we can only have one Main Street and a single stadium, boulevard. 29 00:02:07,290 --> 00:02:10,430 That names can be reuse in other namespaces. 30 00:02:10,430 --> 00:02:12,935 Other cities have a street named Main Street, 31 00:02:12,935 --> 00:02:17,040 but it doesn't refer to our street, it refers to theirs. 32 00:02:17,040 --> 00:02:22,085 In Python, there was one global or top-level namespace. 33 00:02:22,085 --> 00:02:27,110 Then, each invocation of a function creates a new namespace. 34 00:02:27,110 --> 00:02:32,650 In CodeLens, we show these namespaces as stack frames. 35 00:02:32,650 --> 00:02:38,870 There's a global frame where we've defined square and we've defined y, 36 00:02:38,870 --> 00:02:42,155 and then we invoke the square function that creates 37 00:02:42,155 --> 00:02:46,670 a new stack frame and CodeLens is nice enough to label it for us. 38 00:02:46,670 --> 00:02:52,050 It says, "This is the stack frame for the invocation of the square function." 39 00:02:54,260 --> 00:02:59,765 The behind the scenes assignment where the formal parameter name 40 00:02:59,765 --> 00:03:04,985 x got its value of 10 because we passed in the value 10 for it, 41 00:03:04,985 --> 00:03:07,700 that goes into the local stack frame. 42 00:03:07,700 --> 00:03:11,950 That's in the local namespace for the invocation of square. 43 00:03:15,340 --> 00:03:20,110 Then, we set y to be 100. 44 00:03:20,110 --> 00:03:23,700 That's also in the local stack frame. 45 00:03:23,700 --> 00:03:26,465 So, it's really interesting to notice here, 46 00:03:26,465 --> 00:03:28,640 we've got y is five, 47 00:03:28,640 --> 00:03:30,910 we've got y is 100. 48 00:03:30,910 --> 00:03:34,805 This works just fine because they're different namespaces. 49 00:03:34,805 --> 00:03:38,900 Just like we have Main Street and Ann Arbor and Main Street in another city, 50 00:03:38,900 --> 00:03:44,160 we can have Y in the global frame and y in the local frame. 51 00:03:45,020 --> 00:03:47,600 So, here's the gory details of 52 00:03:47,600 --> 00:03:51,500 how variable lookup and variable assignment work with namespaces. 53 00:03:51,500 --> 00:03:55,570 I'm just going to adjust this example slightly. 54 00:03:55,570 --> 00:04:01,055 The first rule is if you refer to a variable in the code inside a function, 55 00:04:01,055 --> 00:04:06,770 if that variable name is ever assigned a value inside the function definition, 56 00:04:06,770 --> 00:04:09,385 even further on in that function definition, 57 00:04:09,385 --> 00:04:12,240 then it treats the reference as local. 58 00:04:12,240 --> 00:04:15,350 If it finds the value on the local stack frame, 59 00:04:15,350 --> 00:04:18,860 it uses that value and otherwise, it's an error. 60 00:04:18,860 --> 00:04:24,750 So, here, it's going to be an error on line two. 61 00:04:25,390 --> 00:04:31,615 We are referring to the variable y, 62 00:04:31,615 --> 00:04:34,070 y is assigned a value somewhere in 63 00:04:34,070 --> 00:04:39,385 the square function which means that y should be a local variable throughout, 64 00:04:39,385 --> 00:04:41,505 but when we are on line two, 65 00:04:41,505 --> 00:04:43,350 y doesn't have a value. 66 00:04:43,350 --> 00:04:47,255 It does not go and get the y equals five from the global stack frame. 67 00:04:47,255 --> 00:04:52,175 It just says, "Y is referenced before assignment on line two." 68 00:04:52,175 --> 00:04:54,235 So, that's an error. 69 00:04:54,235 --> 00:05:00,520 If, however, the variable name is never assigned a value inside the function definition, 70 00:05:00,520 --> 00:05:04,075 then it will look in the global stack frame. 71 00:05:04,075 --> 00:05:10,790 Suppose I do, w equals q plus one, 72 00:05:15,080 --> 00:05:19,910 well, let's show it in CodeLens so we can really see what's happening. 73 00:05:21,750 --> 00:05:26,260 Define all these variables in the global frame, 74 00:05:26,260 --> 00:05:29,260 and now, we start running square. 75 00:05:29,260 --> 00:05:30,670 So, we get to line two, 76 00:05:30,670 --> 00:05:39,580 it tries to look up q. Q is never going to be a local variable in the square function, 77 00:05:39,580 --> 00:05:42,250 so therefore, when we look up q, 78 00:05:42,250 --> 00:05:46,220 it'll go look it up in the global frame. 79 00:05:49,160 --> 00:05:52,540 We get seven, add one to it, 80 00:05:52,540 --> 00:05:55,070 and w gets the value eight. 81 00:05:55,400 --> 00:05:58,660 So, if we look up a reference to 82 00:05:58,660 --> 00:06:02,410 a variable and that variable is ever local inside the function, 83 00:06:02,410 --> 00:06:06,050 it's got to look it up only in the local frame. 84 00:06:06,050 --> 00:06:08,530 It's never going to be a local variable in 85 00:06:08,530 --> 00:06:12,080 that function than it looks it up in the global frame. 86 00:06:13,040 --> 00:06:20,765 This can be pretty confusing and your programs will be a lot easier to understand 87 00:06:20,765 --> 00:06:28,860 if all of your variable references are just references in the local frame. 88 00:06:29,810 --> 00:06:34,325 So, my recommendation is avoid referring to global variables 89 00:06:34,325 --> 00:06:38,495 inside a function definition. Don't do this. 90 00:06:38,495 --> 00:06:42,810 It's legal Python, but it's not a good idea. 91 00:06:42,810 --> 00:06:46,280 Make another formal parameter for the function and have 92 00:06:46,280 --> 00:06:52,110 whatever value you need to get passed in as a parameter to the function. 93 00:06:53,240 --> 00:06:59,690 So, that's how variable lookups references happen inside of functions. 94 00:06:59,690 --> 00:07:02,270 What about assignment inside a function? 95 00:07:02,270 --> 00:07:06,385 Assignment is always done in the local namespace, 96 00:07:06,385 --> 00:07:08,390 the stack frame for that function call. 97 00:07:08,390 --> 00:07:12,245 So, if we go back to our original code, 98 00:07:12,245 --> 00:07:18,720 notice that line two creates a variable y on the local stack frame. 99 00:07:19,130 --> 00:07:22,635 So, there's already a y in the global frame. 100 00:07:22,635 --> 00:07:25,290 But when we get to line two, 101 00:07:25,290 --> 00:07:29,230 we create one in the local stack frame. 102 00:07:30,320 --> 00:07:37,445 So, the rule for assignments is that we're always assigning to a local variable. 103 00:07:37,445 --> 00:07:41,210 There are actually easy way to force lookup an assignment 104 00:07:41,210 --> 00:07:44,650 inside of a function to use the global stack frame. 105 00:07:44,650 --> 00:07:48,150 I'm going to show you how to do this for your understanding, 106 00:07:48,150 --> 00:07:50,520 but don't do it in your programs. 107 00:07:50,520 --> 00:07:53,585 It'll lead to confusing programs that are hard to debug. 108 00:07:53,585 --> 00:07:55,700 Other programmers will shun you. 109 00:07:55,700 --> 00:07:58,180 You'll have no friends and you'll live a miserable life, 110 00:07:58,180 --> 00:07:59,895 okay, and it won't be that bad. 111 00:07:59,895 --> 00:08:01,845 But just don't do this. 112 00:08:01,845 --> 00:08:05,260 I'm going to show you for your understanding. 113 00:08:05,260 --> 00:08:09,090 I can declare y to be global. 114 00:08:09,460 --> 00:08:13,855 If I now say w equals y plus one, 115 00:08:13,855 --> 00:08:18,510 again, don't do this just so you can understand it. 116 00:08:20,510 --> 00:08:24,015 Y is five on the global frame. 117 00:08:24,015 --> 00:08:29,290 We say please treat y as the global y. 118 00:08:29,290 --> 00:08:33,520 Now, line three works because we can get to 119 00:08:33,520 --> 00:08:37,655 the y equals five and w gets to be the value six. 120 00:08:37,655 --> 00:08:41,470 Now, we're going to change y in the global frame, 121 00:08:41,470 --> 00:08:45,990 and we're going to return our 100. 122 00:08:45,990 --> 00:08:51,440 So, this is doable that it leads to very confusing code. 123 00:08:53,450 --> 00:08:56,605 That's local and global variables for you. 124 00:08:56,605 --> 00:08:58,840 Inside a function definition, 125 00:08:58,840 --> 00:09:01,910 variable assignments create local variables. 126 00:09:01,910 --> 00:09:03,980 They can't be referenced outside the code for 127 00:09:03,980 --> 00:09:07,940 that function and that includes the formal parameters of the function. 128 00:09:07,940 --> 00:09:10,355 Those will also be local variables. 129 00:09:10,355 --> 00:09:15,740 Variable references use the local version of the variable. 130 00:09:15,740 --> 00:09:20,960 You can reference a global variable inside a function either by explicitly declaring it 131 00:09:20,960 --> 00:09:22,790 global or by referencing 132 00:09:22,790 --> 00:09:26,895 a variable name that is never assigned a value inside the function. 133 00:09:26,895 --> 00:09:31,460 But your life will be better if you never do that and make all of your references 134 00:09:31,460 --> 00:09:36,544 to variables inside of functions, the local references. 135 00:09:36,544 --> 00:09:39,270 I'll see you next time.