1
00:00:05,440 --> 00:00:10,310
ok so moving on what will do now in the deal_player function

2
00:00:10,310 --> 00:00:15,570
is will just add that command that we saw in the
previous video to print all the local

3
00:00:15,570 --> 00:00:20,300
variables just so we're 100% clear on which
variables are local to the deal_player

4
00:00:20,300 --> 00:00:24,370
function so you can do
this right down here at the bottom will do

5
00:00:24,370 --> 00:00:30,680
a print out....and that is going

6
00:00:30,680 --> 00:00:35,730
to do just that print a list of all the
local variables so if we run the program

7
00:00:35,730 --> 00:00:47,570
now and go back to our game that is
running click the player function and

8
00:00:47,570 --> 00:00:51,670
you can see card_value which has a score
of 10 or value of ten and player_score

9
00:00:51,670 --> 00:00:57,800
which also has a value of ten
they are he 2 only local variables in this

10
00:00:57,800 --> 00:01:02,960
function so it can really be useful because any
confusion in your programs to use this

11
00:01:02,960 --> 00:01:10,790
locals function to call just so you are aware
fully which variables are local ok and it

12
00:01:10,790 --> 00:01:14,440
just bares repeating the rule again one
more time when you use the name of a

13
00:01:14,440 --> 00:01:19,620
global variable inside a function Python
is going to use the global variable as

14
00:01:19,620 --> 00:01:24,160
long as you don't assign a new value to
it as soon as you add code that tries to

15
00:01:24,160 --> 00:01:28,980
change the value the variable itself
becomes local and shadows the global

16
00:01:28,980 --> 00:01:33,270
variable with the same name so because
the function assigns the value in

17
00:01:33,270 --> 00:01:38,270
this case 0 to players_score I'm talking
about the code on line 47 player_score

18
00:01:38,270 --> 00:01:42,580
becomes local to the function and
because no values was assigned to player_ace

19
00:01:42,580 --> 00:01:47,800
we've only used the value we haven't
actually stored anything in there it's still

20
00:01:47,800 --> 00:01:51,940
refers to the global variable that also
means that you can have a function that

21
00:01:51,940 --> 00:01:56,670
happily using a global variable but will
suddenly switched to being local if you

22
00:01:56,670 --> 00:02:00,130
happen to add code to change the value
of the variable and that can be really really

23
00:02:00,130 --> 00:02:05,730
a gotcha their that will start potentially unpredictable
things or giving you unpredictable results

24
00:02:05,730 --> 00:02:11,120
in your program now the
deal_player function provides a

25
00:02:11,120 --> 00:02:13,440
good way to see this in action because

26
00:02:13,440 --> 00:02:18,330
should actually change the value of
player_ace and looking at the code on

27
00:02:18,330 --> 00:02:23,420
line 50 the card values is set to 11 if
this is the first ace dealt so if that

28
00:02:23,420 --> 00:02:27,280
is the case then what we really should
be doing is setting player_ace the

29
00:02:27,280 --> 00:02:31,060
variable player_ace to true so that
we know that there is a ace with a

30
00:02:31,060 --> 00:02:32,530
value 11

31
00:02:32,530 --> 00:02:37,700
so similarly you should also set to false when
we subtract 10 from score on line 54 so

32
00:02:37,700 --> 00:02:46,330
if you go ahead and add it to line 50 so up here
and we put....

33
00:02:48,530 --> 00:02:51,930
now immediately we gonna get an error well
two things happen when we did that

34
00:02:51,930 --> 00:02:55,200
there's an error on now on line 49

35
00:02:55,200 --> 00:03:00,720
and also IntelliJ is now warning  about player_ace
shadowing the global variable

36
00:03:00,720 --> 00:03:06,500
of the same name so the errors is unresolved
reference player_ace and this can

37
00:03:06,500 --> 00:03:11,530
be confusing probably thinking well hang on
player_ace tim you've just told me

38
00:03:11,530 --> 00:03:16,700
that that's a global variable why isn't that
working well again because we've assigned a value

39
00:03:16,700 --> 00:03:21,090
assigned a value now on line 50 what's
actually happened is its now being

40
00:03:21,090 --> 00:03:27,000
converted into a variable a local variable
for this method and on line 49 when we're

41
00:03:27,000 --> 00:03:31,840
doing a test for the value it hasn't
been initialize it hasn't been created as

42
00:03:31,840 --> 00:03:34,700
such and it doesn't exist so that's
its coming and saying unresolved

43
00:03:34,700 --> 00:03:40,810
reference to player_ace and
the other era in terms of the shadowing

44
00:03:40,810 --> 00:03:43,700
name well we talk about that extensively we
know why that's coming up and that's

45
00:03:43,700 --> 00:03:48,060
just because we're using the same
variable name of the variable in the

46
00:03:48,060 --> 00:03:54,620
global variable as we are in this case
in the local variable so deal_player wasn't working

47
00:03:54,620 --> 00:03:58,810
function but as soon as perfectly valid
assignment on line 50 was actually added

48
00:03:58,810 --> 00:04:03,340
then we started getting an error now before you actually gone

49
00:04:03,340 --> 00:04:07,680
through this video this type of error would
probably have driven you nuts now though

50
00:04:07,680 --> 00:04:10,920
you can see why the IntelliJ
warnings are coming up and immediately know

51
00:04:10,920 --> 00:04:16,019
what's going on so in a while what I'm
gonna do is rewrite the function so that

52
00:04:16,019 --> 00:04:20,589
it doesn't try to make use of global
variables ideally a function should be

53
00:04:20,589 --> 00:04:24,770
self-contained and not make changes to
anything outside itself now when a

54
00:04:24,770 --> 00:04:26,380
function does change things like

55
00:04:26,380 --> 00:04:30,180
global variables the changes are know as side
effects and it should really be avoided

56
00:04:30,180 --> 00:04:33,800
wherever possible but with that said sometimes
side effects

57
00:04:33,800 --> 00:04:38,570
are necessary so they are allowed but
aren't discouraged Python

58
00:04:38,570 --> 00:04:43,230
automatically changing a global variable
to local when you try to change when you

59
00:04:43,230 --> 00:04:47,070
try to change it is Python's way of
discouraging us from doing that because

60
00:04:47,070 --> 00:04:51,170
they are occasionally necessary Python does
provide a way to make changes to global

61
00:04:51,170 --> 00:04:55,080
variables within a function because of course
this is what the problem is here we

62
00:04:55,080 --> 00:04:59,920
actually on line 50 when it change the value
of a global variable and it's not

63
00:04:59,920 --> 00:05:03,210
allowing us to do that because as soon
as we've type in the same name and type in

64
00:05:03,210 --> 00:05:08,230
an assignment to save a value to that variable it's created a

65
00:05:08,230 --> 00:05:12,540
local variable and then consequently in
this case we got an error saying that

66
00:05:13,070 --> 00:05:17,330
as of line 49 that variable didn't exist so how
do we go about changing a global

67
00:05:17,330 --> 00:05:21,230
variable well the way to do that is to
specify that your intent on using global

68
00:05:21,230 --> 00:05:26,010
variable by using the global keyword but
before doing that let's get rid of the

69
00:05:26,010 --> 00:05:29,640
error on this line that sets player score to 0 every time the function is

70
00:05:29,640 --> 00:05:35,640
called because that shouldn't be there this
is the code on line 467 because we really do want to use the

71
00:05:35,640 --> 00:05:41,850
the score actually saved globally so
let's go ahead and delete that and as soon

72
00:05:41,850 --> 00:05:48,770
as we have done that you can see now their are other errors on line 51 53 54 55 and 56 their is now errors

73
00:05:48,770 --> 00:05:53,020
relating to player_score so
before I hover over and show you what the

74
00:05:53,020 --> 00:05:57,100
error is and taking into account what
I've said in the video the mini challenge

75
00:05:57,100 --> 00:06:00,960
for you is to answer this question and it's
why is now their an error when players_score

76
00:06:00,960 --> 00:06:04,510
is being accessed and the hint
here is that we've talked about this

77
00:06:04,510 --> 00:06:09,140
player_ace so have a think about that pause
the video and try and figure out why

78
00:06:09,140 --> 00:06:13,290
we're getting an error with player_score now and when we come back i'll go through that with you

79
00:06:15,480 --> 00:06:22,060
ok hopefully that made sense in terms of why that error
came up and what it is it's really the

80
00:06:22,060 --> 00:06:25,740
same reason that player_ace returned an error and of course I talked about

81
00:06:25,740 --> 00:06:29,420
that earlier in this video so by
removing the assignment that I did when I

82
00:06:29,420 --> 00:06:34,180
deleted line 47 player_score now
doesn't have a value as far as

83
00:06:34,180 --> 00:06:37,780
this functions concerned and this is just
primarily because we're trying to save

84
00:06:37,780 --> 00:06:41,820
a value into player_score so as of the code on line 51 player_score

85
00:06:42,730 --> 00:06:47,340
doesn't exist as a variable
because of the shadowing functionality

86
00:06:47,340 --> 00:06:50,930
that Python does that the local variable
variable hasn't been initialized and

87
00:06:50,930 --> 00:06:54,440
that's why we are getting those errors again
similarly to what was happening with

88
00:06:54,440 --> 00:06:58,300
player_ace and specifically the
augmented assignment like we're seeing

89
00:06:58,300 --> 00:07:02,920
on line 51 requires that the variable
already has a value and of course because

90
00:07:02,920 --> 00:07:07,170
of the shadowing technique Python knows that
we're using a variable of the same

91
00:07:07,170 --> 00:07:11,480
name and it's trying to create it would normally create a local variable but we

92
00:07:11,480 --> 00:07:14,930
haven't actually done that we haven't
initialized that variable at this point

93
00:07:14,930 --> 00:07:19,400
in time because their assignments
player_score is still a local variable

94
00:07:19,400 --> 00:07:24,340
but of course we just deleted the line
that gave it a value ok so enough talks so how in

95
00:07:24,340 --> 00:07:28,760
other words do we get the function in
this case to use the global variables of

96
00:07:28,760 --> 00:07:33,190
the same name well to tell Python we want to used the
global variables we just use the global

97
00:07:33,190 --> 00:07:37,760
keyword at the start of the function so
we came up here and on line 47 I'm gonna add

98
00:07:37,760 --> 00:07:48,470
global.....and what that immediately

99
00:07:48,470 --> 00:07:54,190
tells the function to use is to use the
global versions of those variables and

100
00:07:54,190 --> 00:07:58,270
not trying to create a local
variable of the same name and consequently

101
00:07:58,270 --> 00:08:02,480
all the errors  disappear at that point in
time and also the

102
00:08:02,480 --> 00:08:06,390
the errors about shadowing or the warnings about

103
00:08:06,390 --> 00:08:09,840
shadowing have also disappeared as well
because in fact we're not shadowing

104
00:08:09,840 --> 00:08:14,510
anymore because the global keyword essentially is really as I said

105
00:08:14,510 --> 00:08:18,260
telling the function to use the global
variables from this point forward in

106
00:08:18,260 --> 00:08:23,830
that function so now if we run the
program again and actually I need to make another

107
00:08:23,830 --> 00:08:25,170
change so just close it down

108
00:08:25,170 --> 00:08:30,230
before we do that because we needed to make the
change here to add player_ace =

109
00:08:30,230 --> 00:08:30,800
false

110
00:08:30,800 --> 00:08:35,600
so when we are deducting 10 from the ace if you
recall we need to actually say....

111
00:08:35,600 --> 00:08:42,730
.....so basically if the
card value is 1 in other words an ace and they haven't already

112
00:08:42,730 --> 00:08:47,350
got an ace then we're going to assign
the player_ace variable which now global to

113
00:08:47,350 --> 00:08:52,760
true but in the case of where there was
an ace their was an ace being treated as a

114
00:08:52,760 --> 00:08:57,630
value of 11 and we've detected 10 from
it then for all intent and purposes we haven't got

115
00:08:57,630 --> 00:09:06,100
that ace any more we are setting it back to false so now we should be able to run this and now when we run it

116
00:09:15,360 --> 00:09:22,900
we click on player a value of ten their value of
twenty and one more and we get the

117
00:09:22,900 --> 00:09:25,900
right message correctly coming up now
saying dealer wins so it's obviously

118
00:09:25,900 --> 00:09:30,190
working out clearly it's using the
global scope and just make sure this is

119
00:09:30,190 --> 00:09:43,080
working and it's random running game again
their is an ace 11 oh we got 21 we got blackjack now obviously

120
00:09:43,080 --> 00:09:46,590
we haven't got a calculation in here to
check for blackjack we actually only

121
00:09:46,590 --> 00:09:50,560
doing the score here score check if the
player scores greater than 21

122
00:09:51,260 --> 00:09:54,610
we are not basically figuring out whether the
players won yet and we should bust

123
00:09:54,610 --> 00:09:58,440
and if we click on one now it is clearly it's just
drawing random cards so its all working nicely

124
00:09:58,440 --> 00:10:03,560
so what we've determined now is that Python
does allow

125
00:10:03,560 --> 00:10:07,430
global variables to be modified inside a
function because of course that was the

126
00:10:07,430 --> 00:10:11,300
problem we're always been able to get
access to global variables but we're

127
00:10:11,300 --> 00:10:15,750
talking specifically about changing
those variables changing the values to

128
00:10:15,750 --> 00:10:19,170
do that in a function you need to use
the global keyword that I've

129
00:10:19,170 --> 00:10:23,920
shown you how to use on line 47 through 48
so the functions now working as we saw

130
00:10:23,920 --> 00:10:29,030
when we ran the game but if this functions
modifying the two global variables player_score

131
00:10:29,030 --> 00:10:33,570
and player_ace how can we will be
sure that some other function isn't also

132
00:10:33,570 --> 00:10:37,820
changing them and its quite possible when a game in that could happen and if something else

133
00:10:37,820 --> 00:10:41,170
does change them then the deal_plater function is no longer going to work

134
00:10:41,170 --> 00:10:45,030
correctly because it really is assuming
that it's got full control over those

135
00:10:45,030 --> 00:10:49,790
variables or the way that the code has been
written and this is the main reason why

136
00:10:49,790 --> 00:10:53,210
side effects are discouraged and why functions really should only be modified

137
00:10:53,210 --> 00:10:59,300
varaibles in the outer scope i.e. globally if
there's really no other way to perform

138
00:10:59,300 --> 00:11:02,310
the functionality that are you creating
and usually there is actually way

139
00:11:02,310 --> 00:11:06,690
around so before we write in the function
to remove the side effects it is actually

140
00:11:06,690 --> 00:11:11,660
worth revisiting the design so the deal_player gets a new card and

141
00:11:11,660 --> 00:11:15,850
maintains a total by adding the value of
that card to its tally and that

142
00:11:15,850 --> 00:11:18,930
tallies now stored in player_score as a global variable

143
00:11:19,850 --> 00:11:23,460
and we are gonna have to do the same thing for
the dealers so it may make sense to

144
00:11:23,460 --> 00:11:28,270
create a function that returns a score if
it's given a list of cards so what we

145
00:11:28,270 --> 00:11:32,390
gonna do is we are going to add a score _hand function and its purpose is

146
00:11:32,390 --> 00:11:37,290
to do that it to look at a hand and
calculate a score based on that hand so

147
00:11:37,290 --> 00:11:44,820
we are gonna create that under deal_cards
so down here we are gonna call it...

148
00:11:44,820 --> 00:11:49,390
....

149
00:11:50,130 --> 00:11:58,100
....

150
00:11:58,100 --> 00:12:21,940
.....

151
00:12:21,940 --> 00:12:28,240
....because when we first

152
00:12:28,240 --> 00:12:33,820
starting we haven't got any cards so obviously
we haven't got an ace and lets go through all the cards so....

153
00:12:33,820 --> 00:12:36,850
....

154
00:12:36,850 --> 00:12:48,260
......

155
00:12:48,260 --> 00:13:25,890
....

156
00:13:25,890 --> 00:13:31,150
.....

157
00:13:31,150 --> 00:13:38,210
....

158
00:13:38,210 --> 00:13:45,820
.....

159
00:13:46,400 --> 00:13:53,520
....

160
00:13:53,520 --> 00:14:01,560
.....and that's basically the method that's the

161
00:14:01,560 --> 00:14:10,280
loop that goes through each hand then when we finish we return the
score so given a list

162
00:14:10,280 --> 00:14:14,150
containing tuples wether the first item
in the tuple is the value that function is going

163
00:14:14,150 --> 00:14:18,710
add up all the values and return the score
and as I mention the first ace will have the value 11

164
00:14:18,710 --> 00:14:23,760
rather than 1 and if the total score goes above
21 and there is at least one ace then

165
00:14:23,760 --> 00:14:27,250
the total has decreased by 10 and
hopefully the player won't have busted but in

166
00:14:27,250 --> 00:14:30,940
any case we are going to return the score so that is
pretty much the same as what we're doing

167
00:14:30,940 --> 00:14:35,260
when dealing the card and it now goes through
the entire hand rather than the single

168
00:14:35,260 --> 00:14:39,680
card at a time so now that we've done
that we can actually implement this

169
00:14:39,680 --> 00:14:44,300
in deal_player and before calling
it the card just dealt is added to the

170
00:14:44,300 --> 00:14:47,860
list that contains the player's hands so going back to deal_player

171
00:14:50,920 --> 00:14:55,780
obviously our designed has changed
dramatically so what we gonna do here is

172
00:14:55,780 --> 00:14:59,550
we are going to delete all this function well what I'll do I'll just comment it

173
00:14:59,550 --> 00:15:05,650
out so you still got access to that if you
want to but it's now a lot easier so....

174
00:15:05,650 --> 00:15:31,390
....

175
00:15:32,580 --> 00:15:55,330
....

176
00:15:55,330 --> 00:16:04,920
...and that should

177
00:16:04,920 --> 00:16:10,410
be it so basically what we're doing now
is what we've done is we've

178
00:16:10,410 --> 00:16:16,320
rewritten the deal_player function to put all that logic call

179
00:16:16,320 --> 00:16:20,190
the logic that we've just created
in the score_hand and we are still getting

180
00:16:20,190 --> 00:16:25,220
this warning about shadowing but we no
longer need these global variables

181
00:16:25,220 --> 00:16:33,000
anymore so we are gonna delete player score = 0 and player ace = false so gonna go down and delete these

182
00:16:33,000 --> 00:16:37,880
now so player_score = 0 and player_ace = false so delete those

183
00:16:37,880 --> 00:16:43,450
now because we no longer need those and the video is getting a little bit long so I'm gonna stop

184
00:16:43,450 --> 00:16:47,190
this video here and in the next video when
we come back we're going to look at the

185
00:16:47,190 --> 00:16:52,290
deal_dealer function because
that is now very very similar to the deal_player

186
00:16:52,290 --> 00:16:55,840
but obviously need to do a
test to see whether the player wins and etc

187
00:16:55,840 --> 00:16:57,810
so I'll see you in the next video

