1
00:00:04,600 --> 00:00:08,340
so I mentioned at the end of the
previous video the parabola function

2
00:00:08,340 --> 00:00:13,380
itself on line 7 isn't really doing all
it could do though because the main

3
00:00:13,380 --> 00:00:18,420
program needs still needs to loop through
on line 34 where the loop is starting on line 34

4
00:00:18,420 --> 00:00:23,850
and go through all the values it
returns in order to print a parabola so

5
00:00:23,850 --> 00:00:27,370
I think it'd be more useful if the
function plotted the points and all we

6
00:00:27,370 --> 00:00:31,610
had to do was tell it how big the
parabola should be and then give it a

7
00:00:31,610 --> 00:00:36,830
canvas to draw on now before we get
into that though I just want to talk about

8
00:00:36,830 --> 00:00:40,080
some of the warnings that are on the
screen and remember these warnings here on the

9
00:00:40,080 --> 00:00:44,350
right hand side let's just fix a couple
of these up so the first one is at least

10
00:00:44,350 --> 00:00:48,350
two spaces so I made a mistake we need 2 spaces when we are putting a comment

11
00:00:48,350 --> 00:00:52,690
in line at the end of a line so that
should fix that one up the second one

12
00:00:52,690 --> 00:00:57,260
camel case variable import as lower case
that's because we're doing import with a

13
00:00:57,260 --> 00:01:02,850
capital T for Tkinter and s the lowercase Tkinter
for Pythont 2 so that is ok we

14
00:01:02,850 --> 00:01:08,240
don't need to fix that but these other ones
here are all the same shadow name x show named

15
00:01:08,240 --> 00:01:13,880
Shadow named canvas the errors is the same basically it's a different name but

16
00:01:13,880 --> 00:01:19,440
shadow name from out of scope is the error
now what it is is one of the variables

17
00:01:19,440 --> 00:01:24,260
in our function shadows of variable
with the same name in the main program

18
00:01:24,260 --> 00:01:31,070
so the first one actually reads if you go back here and have a look actually we will do a better

19
00:01:31,070 --> 00:01:37,100
example come down here to the canvas so shadow name canvas from outer scope

20
00:01:37,100 --> 00:01:42,090
inspection that detects shadowing names defining outer scope so when they talk about

21
00:01:42,090 --> 00:01:47,000
the outer scope what they mean is the
main program where we created a variable

22
00:01:47,000 --> 00:01:51,190
called canvas and you can see that we
did get on line 29 the errors actually

23
00:01:51,190 --> 00:01:55,320
coming up talking about the canvas
variable that is defined on line 12 as a

24
00:01:55,320 --> 00:01:59,440
parameter to the draw_axis function and that's because when I

25
00:01:59,440 --> 00:02:03,060
gave the parameter to the draw_axis function and name it canvas it the function

26
00:02:03,060 --> 00:02:08,080
then lost the ability to see the canvas
variable in the main program that's

27
00:02:08,080 --> 00:02:12,900
because they're both the same name so all
references to canvas within the draw_axis

28
00:02:12,900 --> 00:02:14,910
function

29
00:02:14,910 --> 00:02:19,850
mean that the perimeter referred to the
parameter that was passed in and not the

30
00:02:19,850 --> 00:02:23,930
canvas variable from the main part of
the program even thought they are called the same thing

31
00:02:23,930 --> 00:02:28,350
that's actually the reason why its
confusing so it's really important to

32
00:02:28,350 --> 00:02:33,320
understand this variable scope as this is what it is and as

33
00:02:33,320 --> 00:02:37,180
functions are one of the few big things
in Python that actually introduce new scope

34
00:02:37,180 --> 00:02:40,550
it's worth spending a bit of time here
just to understand that so you are aware

35
00:02:40,550 --> 00:02:44,580
of how this actually works so to explain
the difference between the canvas that

36
00:02:44,580 --> 00:02:49,250
is local to the draw_axis function and
the one thats global what we gotta do is

37
00:02:49,250 --> 00:02:53,460
create another canvas and then side those both so that they can each occupies half

38
00:02:53,460 --> 00:02:56,130
of the window now our original canvas

39
00:02:56,130 --> 00:03:02,020
will need its width changed to 2320 and this
is one on line 29 and the reason for that is

40
00:03:02,020 --> 00:03:05,630
because we gotta put two canvases where
there was one before the same space so

41
00:03:05,630 --> 00:03:08,380
if you're using a larger width and height

42
00:03:08,380 --> 00:03:12,740
you will just basically divide it by 2 in this
case we are going to make it 320 that's the first one

43
00:03:12,740 --> 00:03:20,500
and we are adding it to grid which is correct but then we are gonna add the
second variable.....

44
00:03:20,500 --> 00:03:31,850
.....

45
00:03:31,850 --> 00:03:37,970
....the difference
will be on the next line we're going to

46
00:03:37,970 --> 00:03:41,850
add it into the next column so of course it
appears to the right hand side so...

47
00:03:41,850 --> 00:03:48,460
.....

48
00:03:48,460 --> 00:03:57,070
...and we got a draw_axis function on line 35 which
is correct but on line

49
00:03:57,070 --> 00:04:01,990
36 we're going to add the draw_axis for the other side so.......

50
00:04:01,990 --> 00:04:06,750
....so just confirming that if we actually

51
00:04:06,750 --> 00:04:13,900
run that to see that it does work
and you could see it basically got

52
00:04:13,900 --> 00:04:17,120
two canvases now we've got to the first
canvas which were drawing on the half

53
00:04:17,899 --> 00:04:21,709
basically left hand side of the screen
and our parabola drawing just on

54
00:04:21,709 --> 00:04:25,380
that and we also got this canvas on the
right hand side as well

55
00:04:25,380 --> 00:04:28,870
and we are drawing the axis to that so in
the past in the previous program of course

56
00:04:28,870 --> 00:04:34,530
it was just one occupying the entire 640
by 480 for our window so that's working

57
00:04:34,530 --> 00:04:39,270
and actually what I didn't do what I might do now is I am going to come back here just to make it a bit more obvious

58
00:04:39,270 --> 00:04:46,680
and then I'm gonna put....

59
00:04:46,680 --> 00:04:51,770
....and that will make it clearer because we
got a blue background as you can

60
00:04:51,770 --> 00:04:56,180
probably guess that will do now its a little bit
more obvious now that we got this new

61
00:04:56,180 --> 00:05:00,960
canvas which we actually added which is now got a blue
background ok so each time it's called

62
00:05:00,960 --> 00:05:05,020
it's own variable called canvas is assigned the canvas object that is pass to

63
00:05:05,020 --> 00:05:10,550
the parameter in the call so here
basically on line 35 passes up a

64
00:05:10,550 --> 00:05:15,370
passes the canvas object
and the passes on to line 12 to the draw_axis

65
00:05:15,370 --> 00:05:20,710
function the that calls that canvasses as well
and likewise for canvas 2 even though we

66
00:05:20,710 --> 00:05:24,650
referred to it as canvas 2 its
referred to as canvas for the function

67
00:05:24,650 --> 00:05:28,580
name and it's going to be using that name when
it's processing that for also for canvas 2

68
00:05:28,580 --> 00:05:33,250
now we can see that a little bit better by
printing out some details of the canvas

69
00:05:33,250 --> 00:05:38,080
objects so there's a function that shows
the representation of the object called

70
00:05:38,080 --> 00:05:43,060
repr r-e-p-r so let's just put that
in and you can actually just sort of

71
00:05:43,060 --> 00:05:47,710
print out some details about an object
in a format suitable for printing

72
00:05:47,710 --> 00:05:58,610
so i can type.......and that will just printed

73
00:05:58,610 --> 00:06:02,560
it out each time it's called it's going to
print out the basically the memory reserved

74
00:06:02,560 --> 00:06:06,460
so if we just run that to confirm it is actually working you
notice now that we've actually got this

75
00:06:06,460 --> 00:06:11,780
little print out on the screen now and you can see here the number at the end of each

76
00:06:11,780 --> 00:06:17,050
part of this tkinter.Canvas object print out is meant to represent the memory

77
00:06:17,050 --> 00:06:21,210
location where that particular object
was created in memory so obviously there

78
00:06:21,210 --> 00:06:24,140
we got a different number in both cases in
which means that they're obviously

79
00:06:24,140 --> 00:06:27,240
separate objects which is correct but
the other thing is just out of interest

80
00:06:27,240 --> 00:06:33,500
if we stop this close it and run again you will note those
numbers will be different

81
00:06:34,070 --> 00:06:37,630
basically different each time you run
the program different in that these will be

82
00:06:37,630 --> 00:06:41,390
different to each other because they are
separate objects but also the individual

83
00:06:41,390 --> 00:06:45,560
numbers allocated to each object is also
different because the computer every

84
00:06:45,560 --> 00:06:50,320
time you run it is a assigning its using making a
decision where to put these in memory and

85
00:06:50,320 --> 00:06:54,650
that changes each time you run it and no doubt these numbers are likely to be

86
00:06:54,650 --> 00:06:58,790
a bit different when you run it on your computer as well
that's good so we can see that their

87
00:06:58,790 --> 00:07:01,790
separate objects

88
00:07:03,150 --> 00:07:06,600
but what is also cool is we can print
local variables

89
00:07:07,290 --> 00:07:11,490
so Python has this ability called using the
locals function to print out all the

90
00:07:11,490 --> 00:07:17,470
local variables for a method so what we can do is make a change to that so lets put this at the end of

91
00:07:17,470 --> 00:07:23,860
line 18 so type....and that is the locals is the method that enables a printout of

92
00:07:23,860 --> 00:07:27,800
all the variables that have been defined
for that particular function obviously

93
00:07:27,800 --> 00:07:31,320
has to be the code has to be in a
function too be called its

94
00:07:31,320 --> 00:07:36,180
going to just basically look at all the
variables in that function so if we run

95
00:07:36,180 --> 00:07:43,940
that you can see their its showing us that we got the canvas object and note that the numbers here

96
00:07:43,940 --> 00:07:47,740
so for the first time we call it canvas
represents the same variable

97
00:07:47,740 --> 00:07:52,430
canvas this first one here as we pointed that out and then
also its got a y location

98
00:07:52,430 --> 00:07:59,430
y_origin and x_origin and that is the variables
that we are creating on line 14 and 15 but note

99
00:07:59,430 --> 00:08:03,370
that we are getting consistency here we got
the number their corresponding to that

100
00:08:03,370 --> 00:08:06,490
number the first time it's called and the
second time that number corresponds to

101
00:08:06,490 --> 00:08:10,370
that one so we can see that it actually
is working so it can be useful tool when

102
00:08:10,370 --> 00:08:13,860
you're debugging to have the locals
function and also the representation code

103
00:08:14,680 --> 00:08:18,970
the repr function as well so you think
at this point ok so everything's working fine

104
00:08:18,970 --> 00:08:23,690
so why is IntelliJ actually coming up
with these warnings what is the problem

105
00:08:23,690 --> 00:08:27,560
well firstly with a small program like
this where we can pretty much see

106
00:08:27,560 --> 00:08:31,110
everything at once on the screen is not
really that big a deal I mean all the

107
00:08:31,110 --> 00:08:35,020
codes there on the screen we can access
it and you probably not gonna get into

108
00:08:35,020 --> 00:08:38,799
difficulty but chances are that you
gonna be ending up writing much larger

109
00:08:38,799 --> 00:08:43,320
programs and you can find it can cause
unexpected problems if we make a mistake

110
00:08:43,320 --> 00:08:45,960
somewhere pretty much I can guarantee that will happen on

111
00:08:45,960 --> 00:08:51,720
some point on your programming journey that you make a
mistake so what I'm going to do is

112
00:08:51,720 --> 00:08:56,210
simulate one possible mistakes in the
way to simulate that is to rename the

113
00:08:56,210 --> 00:09:01,560
parameter canvas and to call a page so
I'm talking about the parameter here

114
00:09:01,560 --> 00:09:07,680
on line 12 so we are gonna change that to page you
can see their and we need to make a few

115
00:09:07,680 --> 00:09:13,390
other changes we need to call this
now page.update so.....

116
00:09:13,390 --> 00:09:16,170
and as I'm going to be doing this you might be
thinking well Tim why aren't you using the

117
00:09:16,170 --> 00:09:17,910
refactor facility

118
00:09:17,910 --> 00:09:22,350
well it's slightly contrived example
here because obviously that would

119
00:09:22,350 --> 00:09:25,590
automatically rename all occurrences
for us but it's possible that you might

120
00:09:25,590 --> 00:09:28,960
be making a quick change using some
other editor as I'm doing it manually

121
00:09:28,960 --> 00:09:32,860
to simulate a potential problem so lets just assume I did that and I remembered most

122
00:09:32,860 --> 00:09:34,800
of these so I'll change that one as well

123
00:09:34,800 --> 00:09:41,570
.....

124
00:09:41,570 --> 00:09:46,360
......so if I actually run this having knowing
that I forgot to make the change on line

125
00:09:46,360 --> 00:09:53,740
18 and you notice we've got a different
output here we've got no y axis

126
00:09:53,740 --> 00:09:57,540
showing in the right hand canvas so you
might be looking at that thinking well

127
00:09:57,540 --> 00:09:59,520
why that suddenly stopped working

128
00:09:59,520 --> 00:10:03,980
you know if you made this quick change like I have and you neglected to make that change as I did

129
00:10:03,980 --> 00:10:11,240
on line 18 and what I need to do is run it again so we can see now that with the output from

130
00:10:11,240 --> 00:10:16,770
the locals function that the variables
is called page so on line 18 the yaxis is

131
00:10:16,770 --> 00:10:20,950
being drawn on the canvas from the main
program so that one has its axis drawn

132
00:10:20,950 --> 00:10:24,420
twice effectively so I basically we can see
what's happening their the canvas

133
00:10:24,420 --> 00:10:29,530
variable that's been referred to their on line 18 is actually the canvass

134
00:10:29,530 --> 00:10:33,090
variable that was defined in the main part of the

135
00:10:33,090 --> 00:10:37,150
program and not from this function now again I did say this was a bit contrived

136
00:10:37,150 --> 00:10:41,550
but if I originally called the parameter
graph instead of canvas for arguments sake so if we

137
00:10:41,550 --> 00:10:42,560
comeback and do that lets

138
00:10:42,560 --> 00:10:45,560
presume that it was called graph......

139
00:10:47,840 --> 00:10:53,100
and we actually run this clearly we get a different error
altogether and the reason we've now got

140
00:10:53,100 --> 00:10:57,860
an error is it Python notice that ok this
variable graph doesn't exist we are not

141
00:10:57,860 --> 00:11:05,020
shadowing the canvas variable from the
main program anymore and consequently

142
00:11:05,020 --> 00:11:08,580
we've got you know we know that there's
a problem we can actually fix it this is

143
00:11:08,580 --> 00:11:13,250
probably not only crops up if you try
to use a name the same name in your

144
00:11:13,250 --> 00:11:17,170
parameter as your using for your variable that is
defined in the main part of the program so

145
00:11:17,170 --> 00:11:20,910
although python did mind that local main variables have the same name it can

146
00:11:20,910 --> 00:11:24,600
be a source error and that's one reason why
IntelliJ is warning you about that for

147
00:11:24,600 --> 00:11:28,650
these types of errors that you might run
into and it's probably a bad idea to

148
00:11:28,650 --> 00:11:32,440
have the same names but with that said
there's also another reason why

149
00:11:32,440 --> 00:11:36,380
shadowing is a bad idea in Python and
will have a look at that a little bit

150
00:11:36,380 --> 00:11:41,510
later so this example has also hopefully
demonstrated the scope of the variables

151
00:11:41,510 --> 00:11:45,240
so draw axis has its own local
variable called canvas

152
00:11:45,240 --> 00:11:50,200
that is now called page and in the main program there
were two canvases called canvas and canvas 2

153
00:11:50,200 --> 00:11:55,290
but inside the draw_axis function we can
and did actually refer to the

154
00:11:55,290 --> 00:11:59,450
canvas from the main program but if we
now we try to refer to pages in main program

155
00:11:59,450 --> 00:12:05,280
it won't work so it doesn't go 2 ways so firstly I'll fix this Graph put that back to page so

156
00:12:05,280 --> 00:12:08,990
clearly in the draw_axis function
we're able to refer to these variables

157
00:12:08,990 --> 00:12:12,990
defined in the main part of the program
of the Python program but we can't do

158
00:12:12,990 --> 00:12:17,440
things in other ways in other words we can't
come back here for example and put print

159
00:12:17,440 --> 00:12:26,520
...if you try to do that you can already see you got an error and if we try to run it name page is not defined and that is

160
00:12:26,520 --> 00:12:31,960
because we're a variable is visible it can be
used is called scope and that's really

161
00:12:31,960 --> 00:12:35,410
all there is to understanding the scope in Python now their is some other some other things we

162
00:12:35,410 --> 00:12:39,650
can do to specify the scope of a variable
but we'll look at that later but for now

163
00:12:39,650 --> 00:12:43,930
just remember that a function can use
the variables from the main program but

164
00:12:43,930 --> 00:12:48,620
the main program cannot see variables
that are local to the function so I'm gonna

165
00:12:48,620 --> 00:12:54,980
end the video here actually what I'll do before I end I'm gonna delete line 40 so

166
00:12:54,980 --> 00:12:57,890
that we haven't got any code errors their

167
00:12:57,890 --> 00:13:01,280
and will continue on with this in the
next video

