1
00:00:00,390 --> 00:00:00,720
All right.

2
00:00:00,720 --> 00:00:05,720
So in the last lesson we did a lot of setup and we got our game to have the

3
00:00:05,880 --> 00:00:06,810
basic features.

4
00:00:06,870 --> 00:00:11,250
It's got a popup that asks us for a states' name,

5
00:00:11,610 --> 00:00:15,870
and when I type a name in here, I can receive it inside my code

6
00:00:15,900 --> 00:00:17,340
using this answer_state.

7
00:00:18,030 --> 00:00:22,590
Now your job is to use that 50_states.csv

8
00:00:23,070 --> 00:00:23,430
to

9
00:00:23,430 --> 00:00:28,430
check the user's answer against all of the states inside this table and see if

10
00:00:29,580 --> 00:00:31,650
it matches one of them. Now,

11
00:00:31,650 --> 00:00:36,210
the user might spell it with a capital to begin with say, Ohio,

12
00:00:36,270 --> 00:00:40,740
or they might just write ohio and it should work for both of these cases.

13
00:00:41,760 --> 00:00:42,510
In addition,

14
00:00:42,510 --> 00:00:47,510
when the user types in a state that is inside that 50_states.csv,

15
00:00:48,660 --> 00:00:53,660
then that state should be written onto the screen at the location where it

16
00:00:53,820 --> 00:00:54,653
exists.

17
00:00:54,750 --> 00:00:59,190
So it remember the location corresponds to the X and Y values that we already

18
00:00:59,190 --> 00:01:01,710
logged inside this data file.

19
00:01:02,310 --> 00:01:05,430
But if the user guesses a state that's wrong,

20
00:01:05,970 --> 00:01:10,020
then nothing happens and our input box appears again

21
00:01:10,410 --> 00:01:12,480
asking for a new input.

22
00:01:13,860 --> 00:01:16,860
Now notice how here in the title of the text input

23
00:01:16,920 --> 00:01:21,920
I'm also keeping track of how many states they have guessed correctly out of 50.

24
00:01:22,590 --> 00:01:25,560
And every time they add a new, um,

25
00:01:25,620 --> 00:01:28,380
new state, then that number updates.

26
00:01:29,700 --> 00:01:34,290
his is going to rely on the knowledge that you've learned about reading from

27
00:01:34,290 --> 00:01:35,370
CSV data,

28
00:01:35,730 --> 00:01:39,390
getting hold of the specific parts of the CSV data,

29
00:01:39,720 --> 00:01:43,500
finding for example, a particular row or a particular column,

30
00:01:43,950 --> 00:01:48,950
and working with that data in order to check to see if the user got the state

31
00:01:49,530 --> 00:01:50,363
right,

32
00:01:50,370 --> 00:01:55,370
and then using the data inside that row to figure out where to write some text

33
00:01:55,980 --> 00:01:57,960
at which X and Y location

34
00:01:58,200 --> 00:02:02,670
so that we can get the actual name of the state written at the location where

35
00:02:02,670 --> 00:02:06,120
they appear on the map. So this is quite a challenge

36
00:02:06,180 --> 00:02:09,660
and I expect that you'll have to think about it and play around with the code

37
00:02:09,660 --> 00:02:13,050
for at least 10 to 20 minutes. So give it the time that it needs,

38
00:02:13,350 --> 00:02:17,970
have a think about how you would break down this problem and try and complete

39
00:02:17,970 --> 00:02:20,220
this challenge. So pause the video now.

40
00:02:25,700 --> 00:02:26,210
Okay.

41
00:02:26,210 --> 00:02:28,640
All right. So I'm going to walk through the solution with you,

42
00:02:28,910 --> 00:02:31,070
but I want you to do a conscience check.

43
00:02:31,670 --> 00:02:35,930
If you haven't spent at least 20 minutes working on this problem, fixing it,

44
00:02:36,080 --> 00:02:40,400
getting it to do what you want it to do, then go back, try again.

45
00:02:40,460 --> 00:02:42,860
You need to feel the struggle in order to learn.

46
00:02:43,220 --> 00:02:47,150
I can tell you how to do anything, but if that answer didn't come from you,

47
00:02:47,390 --> 00:02:50,840
then you're not actually going to make progress. So I really,

48
00:02:50,840 --> 00:02:55,460
really urge you to give it a go before you watch the solution. All right.

49
00:02:55,460 --> 00:02:58,910
So back to our code, the first thing I'm going to do is

50
00:02:59,260 --> 00:03:02,320
I'm going to import the pandas module.

51
00:03:02,710 --> 00:03:04,450
So I'm going to import pandas.

52
00:03:04,960 --> 00:03:09,760
Now I've already installed pandas on the starting project that you downloaded,

53
00:03:10,090 --> 00:03:14,170
but if you're doing this completely from scratch from your own starting file,

54
00:03:14,380 --> 00:03:18,010
then you'll probably get a red squiggly line under the pandas

55
00:03:18,040 --> 00:03:21,640
and it will ask you to install the package. But if you don't have it,

56
00:03:21,640 --> 00:03:24,160
then it means it's already installed and ready to use.

57
00:03:24,640 --> 00:03:29,640
Now we're going to get our pandas to go ahead and read our CSV file, and the

58
00:03:30,190 --> 00:03:33,940
CSV file is called the 50_states.csv.

59
00:03:34,420 --> 00:03:36,370
So once the prompt comes up,

60
00:03:36,670 --> 00:03:40,570
then I'm going to hit enter to get PyCharm to just insert it automatically.

61
00:03:41,410 --> 00:03:45,550
Now I'm going to save that data frame that comes from reading that CSV to a

62
00:03:45,550 --> 00:03:47,110
variable called data.

63
00:03:47,890 --> 00:03:52,890
Now our data has 50 rows of data and the first row is the column headings

64
00:03:54,550 --> 00:03:59,230
for each of them. So we've got the state, the X and the Y values.

65
00:04:00,310 --> 00:04:04,420
Let's have a think about how we might break down this problem that we have.

66
00:04:04,840 --> 00:04:07,000
So when the user types an answer,

67
00:04:07,450 --> 00:04:10,630
we have to check to see if that, um,

68
00:04:10,930 --> 00:04:15,930
answer_state is one of the states in all the states of the 50_states.csv.

69
00:04:23,230 --> 00:04:27,250
The first column is a list of all 50 States.

70
00:04:27,790 --> 00:04:32,790
So if we could somehow check to see if this state that they've guessed is one of

71
00:04:34,120 --> 00:04:39,010
the states in that column, then we know whether if they got it right or wrong.

72
00:04:39,520 --> 00:04:41,470
If they got it right,

73
00:04:41,950 --> 00:04:46,950
then we need to figure out how we can create a turtle to write

74
00:04:50,050 --> 00:04:55,050
the name of the state at the state's X and Y coordinate.

75
00:04:57,940 --> 00:04:59,980
For example, if the user guessed

76
00:05:00,010 --> 00:05:04,210
South Carolina and indeed South Carolina is one of the 50 States,

77
00:05:04,510 --> 00:05:08,410
then we should be able to pull out this entire row and then create a turtle,

78
00:05:08,440 --> 00:05:11,110
make it go to this X and Y location,

79
00:05:11,470 --> 00:05:16,470
and to write the name of the state onto this blank state image in our turtle

80
00:05:18,640 --> 00:05:22,540
game. Let's see if we can tackle this. Now,

81
00:05:22,540 --> 00:05:27,010
the first thing we need to figure out is how do we get hold of all the states of

82
00:05:27,010 --> 00:05:30,070
the 50_states.csv? So we've got our data frame

83
00:05:30,280 --> 00:05:34,900
and if I go ahead and say data, then I can pull out one of the columns.

84
00:05:35,350 --> 00:05:37,390
So the column name is state,

85
00:05:37,870 --> 00:05:41,950
and I can either use that as a key with a set of square brackets,

86
00:05:42,220 --> 00:05:45,190
or I can use it as simply a attribute name.

87
00:05:46,510 --> 00:05:51,280
This gets me the data series which is that first column.

88
00:05:52,180 --> 00:05:54,850
And if I want to be able to turn that into a list,

89
00:05:55,150 --> 00:05:58,070
remember that we saw that method to_list,

90
00:05:58,700 --> 00:06:01,970
and that means we can work with it just like any other list.

91
00:06:02,480 --> 00:06:04,730
So let's call this all_states.

92
00:06:06,110 --> 00:06:08,900
And once we've got whole of this all_states, well,

93
00:06:08,900 --> 00:06:13,900
we can check to see if the answer_state is in the all_states.

94
00:06:17,210 --> 00:06:19,670
This is something that you won't be able to do,

95
00:06:19,670 --> 00:06:23,120
so checking for membership using the in keyword

96
00:06:23,450 --> 00:06:26,420
unless you have converted this into a list.

97
00:06:27,350 --> 00:06:32,350
So once we've figured out that this answer of the user provided is in fact,

98
00:06:32,450 --> 00:06:35,270
one of the states in our 50 States,

99
00:06:35,600 --> 00:06:39,200
then the next thing we need to do is to create a turtle.

100
00:06:39,830 --> 00:06:42,410
So let's create a new turtle, which we'll call t,

101
00:06:42,920 --> 00:06:47,510
and we're going to use the turtle.Turtle class to construct it.

102
00:06:47,990 --> 00:06:52,100
And then we're going to get the turtle to hide the actual turtle shape,

103
00:06:52,460 --> 00:06:57,020
and we're also going to get it to pen up so that it doesn't actually do any

104
00:06:57,020 --> 00:06:57,853
drawing.

105
00:06:58,190 --> 00:07:03,190
But what we do need it to do is we needed to go to a particular X and Y

106
00:07:03,560 --> 00:07:04,393
location.

107
00:07:04,910 --> 00:07:09,910
The X and Y location is going to correspond to the state that the user has

108
00:07:10,070 --> 00:07:15,070
correctly guessed and the row of data from our 50_states.csv.

109
00:07:17,570 --> 00:07:22,570
So how can we get hold of the actual row of data that corresponds to this state?

110
00:07:24,350 --> 00:07:28,790
Well, we can take our data and then inside some square brackets,

111
00:07:29,000 --> 00:07:34,000
we can check that the data.state is double equal to the answer_state.

112
00:07:37,220 --> 00:07:42,220
This is going to pull out the row where the state is equal to the answer_state.

113
00:07:44,960 --> 00:07:49,160
So I'm going to save that under something called state_data.

114
00:07:50,270 --> 00:07:55,270
And now I can tell my turtle to go to state_data.x and state_data.y.

115
00:07:59,180 --> 00:08:01,730
So, because this is a row of data,

116
00:08:02,330 --> 00:08:06,710
then I can tap into it's attributes using the name of the columns,

117
00:08:07,100 --> 00:08:08,870
the X and the Y.

118
00:08:10,400 --> 00:08:12,620
And once my turtle gets there,

119
00:08:12,710 --> 00:08:16,910
then I want it to write the name of the state.

120
00:08:17,360 --> 00:08:22,340
So it's going to be state_data.state. Now,

121
00:08:22,340 --> 00:08:27,320
when we hit run on this code and guess the name of a state that definitely

122
00:08:27,320 --> 00:08:30,740
exists, when we click OK, we're going to get an error.

123
00:08:31,340 --> 00:08:34,159
And it's really important that you get used to seeing errors

124
00:08:34,429 --> 00:08:37,460
because they're going to happen to you all the time. Just as in life

125
00:08:37,700 --> 00:08:42,200
the only certainties are death and taxes, in Programming the only certainty

126
00:08:42,230 --> 00:08:44,179
is you will get bugs and you will get errors.

127
00:08:44,570 --> 00:08:48,110
The important thing is to figure out what's causing the error.

128
00:08:48,620 --> 00:08:53,270
So if we go ahead and copy this error at the end, bad screen distance,

129
00:08:53,300 --> 00:08:55,710
that seems to be telling us what is actually going on.

130
00:08:56,460 --> 00:09:00,720
And then I go into Google and I search for this particular error,

131
00:09:01,200 --> 00:09:05,040
then I can see other people who've encountered this issue.

132
00:09:05,700 --> 00:09:09,660
So if we read through all of this, between all of the subtext,

133
00:09:09,720 --> 00:09:14,720
it tells us that the issue is actually that our coordinates are stored as

134
00:09:15,090 --> 00:09:19,710
strings. We need to get the coordinates into actual numbers.

135
00:09:20,880 --> 00:09:24,450
So the one oversight that you might've made which is really common

136
00:09:24,840 --> 00:09:28,200
is to simply tell it to go to date state_data.x,

137
00:09:28,260 --> 00:09:33,260
state_data.y without first converting them into integers.

138
00:09:35,610 --> 00:09:40,610
So now if we bring back our screen.exitonclick and then run our code,

139
00:09:41,370 --> 00:09:45,030
we can type the name of the state click OK,

140
00:09:45,300 --> 00:09:50,300
and you can see the state data show up on the location that corresponds to that

141
00:09:50,400 --> 00:09:52,320
particular state. Now,

142
00:09:52,350 --> 00:09:56,280
the only problem is we don't want all of this junk to be written here, right?

143
00:09:56,610 --> 00:10:01,530
And this is showing up because we're getting this data from our data series.

144
00:10:01,920 --> 00:10:04,440
So what's a much simpler way? Well,

145
00:10:04,470 --> 00:10:07,950
we've already got hold of the answer that the user typed, right?

146
00:10:08,280 --> 00:10:12,000
So why don't we just write the answer_state?

147
00:10:13,110 --> 00:10:18,000
So now when I type in the state and it matches one of the states in the 50

148
00:10:18,000 --> 00:10:18,833
states,

149
00:10:18,840 --> 00:10:23,840
then it's going to go to the X and Y location of that state and print the name

150
00:10:23,910 --> 00:10:26,550
of the state that the user has typed in.

151
00:10:27,060 --> 00:10:31,710
And because we've made sure that it's a correct state with a correct spelling,

152
00:10:31,980 --> 00:10:34,740
then it doesn't actually matter if we use the answer_state

153
00:10:34,950 --> 00:10:38,220
or if we use the state_data. Now,

154
00:10:38,250 --> 00:10:42,360
if you really want to use state_data instead of answer_state

155
00:10:42,450 --> 00:10:46,380
because say you're writing a different program and you need this functionality,

156
00:10:46,710 --> 00:10:51,390
then you can actually tap into state_data.state,

157
00:10:51,990 --> 00:10:56,910
which will get us the state name from the row corresponding to the matching

158
00:10:56,910 --> 00:11:01,830
state. And then we can use a method called item.

159
00:11:02,670 --> 00:11:06,030
Now, item is a method on the pandas series.

160
00:11:06,840 --> 00:11:09,990
So we know that this is a Panda data series

161
00:11:10,050 --> 00:11:13,410
and you can do a type check on that if you want to confirm.

162
00:11:13,830 --> 00:11:18,830
But what the item does is it looks into the underlying data and it basically

163
00:11:18,990 --> 00:11:23,400
just grabs the first element. So now, if I run the game

164
00:11:23,400 --> 00:11:26,520
as it is and I type in the name of a state,

165
00:11:26,790 --> 00:11:31,790
you can see it fetches the actual value under state_data.state without any

166
00:11:32,790 --> 00:11:36,750
of the index, the zero or any of the other parts of the data series.

167
00:11:37,380 --> 00:11:42,380
So I just wanted to show you that you can actually get a row of data from a data

168
00:11:42,390 --> 00:11:46,230
frame and then get a particular value from that row,

169
00:11:46,560 --> 00:11:51,540
and get the actual raw value from that. But personally, in this line of code,

170
00:11:51,570 --> 00:11:56,410
I prefer using the answer_state because we know it's already been title cased, its

171
00:11:56,410 --> 00:11:57,910
already formatted correctly

172
00:11:58,180 --> 00:12:02,050
and it just makes the code look a bit cleaner and it's easier to understand.

173
00:12:02,170 --> 00:12:05,860
So I'm going to stick with this. So now that it's working,

174
00:12:06,070 --> 00:12:07,870
all we need to do is to get this

175
00:12:07,870 --> 00:12:12,280
to repeat itself every single time the user makes a new guess.

176
00:12:12,700 --> 00:12:16,600
That means we're probably going to have to put it inside some sort of while loop,

177
00:12:17,320 --> 00:12:20,080
what should be our while condition? Well,

178
00:12:20,110 --> 00:12:24,310
we know that the user is going to guess all of the states. And once they've

179
00:12:24,310 --> 00:12:26,920
guessed all of them, then they win, right?

180
00:12:27,310 --> 00:12:32,310
So why don't we create a list of guessed states and set that to equal a empty

181
00:12:33,940 --> 00:12:34,773
list.

182
00:12:34,960 --> 00:12:39,960
And we can check while the length of the guessed_states is less than 50,

183
00:12:41,980 --> 00:12:45,550
then we can continue rerunning all of this code,

184
00:12:45,790 --> 00:12:50,320
getting them to put a new input, checking the input and writing the state name.

185
00:12:51,160 --> 00:12:54,580
But every time the user guesses a state correctly,

186
00:12:54,910 --> 00:12:59,910
then we're going to add this answer_states to the guessed_state.

187
00:13:00,310 --> 00:13:02,740
So we can say guessed_states.append,

188
00:13:03,100 --> 00:13:06,100
and then we're going to append this new answer_state.

189
00:13:06,820 --> 00:13:11,800
So now when I run this code again, then you can see that every time

190
00:13:11,800 --> 00:13:16,240
I guess a new state, this text input pops up again

191
00:13:16,540 --> 00:13:21,070
and I can basically just keep going until I've named all the states.

192
00:13:21,790 --> 00:13:26,440
Now, the next thing I want to change is the title of this text input window.

193
00:13:26,980 --> 00:13:28,540
Instead of saying Guess the state,

194
00:13:28,690 --> 00:13:33,070
I want it to keep track of the number of states I've guessed correctly.

195
00:13:33,430 --> 00:13:38,430
So I basically want to say something like zero or 10 or whatever, out of 50

196
00:13:38,590 --> 00:13:40,000
states correct.

197
00:13:40,630 --> 00:13:44,260
This zero is going to be replaced by a f-string

198
00:13:44,650 --> 00:13:49,060
and we're going to use the length of our guessed_states in order to get that

199
00:13:49,060 --> 00:13:53,230
number. So now when I run this code, you can see that

200
00:13:53,230 --> 00:13:57,400
I start out with zero states, 0/50, and every time I guess

201
00:13:57,400 --> 00:14:01,780
a new state, then it adds to that count

202
00:14:01,810 --> 00:14:05,020
so I can keep track of how many I have guessed and how many I've got left.

203
00:14:06,610 --> 00:14:06,820
Now,

204
00:14:06,820 --> 00:14:11,820
the next thing you'll realize if you test this a few times is even if you get a

205
00:14:12,190 --> 00:14:13,180
state right

206
00:14:13,480 --> 00:14:18,400
but if you actually didn't spell it with a capital C or capital letter to begin

207
00:14:18,400 --> 00:14:22,990
with, then it's not going to accept it. So we don't see 'california' showing up.

208
00:14:23,350 --> 00:14:25,780
And this is because in our state data,

209
00:14:25,930 --> 00:14:30,490
they all have a title case were the first letter is capitalized.

210
00:14:31,090 --> 00:14:34,150
So how can we make sure that our game works

211
00:14:34,150 --> 00:14:38,830
if the user types all lower case or all upper case or title case?

212
00:14:38,890 --> 00:14:42,610
As long as they got the spelling right we should ignore the casing.

213
00:14:44,080 --> 00:14:48,310
So one way of doing this is to take this answer_state

214
00:14:48,340 --> 00:14:52,430
which comes from that text input that the user has entered,

215
00:14:52,820 --> 00:14:57,290
and then at the very end, we can change that to a title case.

216
00:14:57,560 --> 00:15:00,200
So this is a method that's on all strings.

217
00:15:00,590 --> 00:15:05,270
So that means if I start out with a string, which is,

218
00:15:05,300 --> 00:15:09,770
um, angela, and then I say str.title,

219
00:15:10,280 --> 00:15:13,490
then this will give me the same string back

220
00:15:13,520 --> 00:15:15,710
but it will make the first letter capitalized.

221
00:15:16,400 --> 00:15:18,650
This is what we're going to do to the user's answer.

222
00:15:19,100 --> 00:15:22,070
And then we'll be able to check it against all the States.

223
00:15:22,400 --> 00:15:27,020
And now it doesn't matter if the user has typed everything in all caps,

224
00:15:27,350 --> 00:15:30,680
or if they have typed it with all lower case,

225
00:15:31,100 --> 00:15:34,370
or if they've done something really crazy like this,

226
00:15:34,430 --> 00:15:36,350
it will still be accepted.

227
00:15:37,990 --> 00:15:39,130
So we've now got most of

228
00:15:39,370 --> 00:15:42,940
the functionality of our game. In the next lesson,

229
00:15:43,000 --> 00:15:46,690
we're going to figure out how we can get this game to become more of an

230
00:15:46,690 --> 00:15:50,950
educational tool and for it to create a final CSV

231
00:15:51,340 --> 00:15:52,960
when we're ready to exit the game

232
00:15:53,230 --> 00:15:57,400
that's going to tell us all the states that we missed so that we can learn them,

233
00:15:57,670 --> 00:16:02,320
so that we can come back to the game with more knowledge. For all of that and

234
00:16:02,320 --> 00:16:04,270
more, I'll see you on the next lesson.

