WEBVTT

0
00:00.140 --> 00:04.100
One of the first things I want to talk about is randomization.

1
00:04.100 --> 00:08.180
And this is a concept that we're super familiar with.

2
00:08.300 --> 00:14.540
Randomization is really, really important when we want to create computer programs that have a degree

3
00:14.540 --> 00:16.100
of unpredictability.

4
00:16.130 --> 00:19.100
Now the biggest category of that is of course, games.

5
00:19.100 --> 00:19.610
Right?

6
00:19.610 --> 00:21.710
Can you imagine if you had to play Tetris,

7
00:21.710 --> 00:27.170
and every single time the block that fell down was like predictable? You always knew that it was going

8
00:27.170 --> 00:32.510
to be a T, and then it was going to be an L, like there would be no fun in that, right?

9
00:32.510 --> 00:39.770
So how do we create this randomness for our programs? Now in nature and in our everyday lives,

10
00:39.770 --> 00:42.560
it's really easy to create randomness.

11
00:42.560 --> 00:46.490
If you splash some paint on a canvas, that's going to be pretty random.

12
00:46.490 --> 00:54.110
If you take a look at the TV static from the analog TVs, that's also a whole bunch of randomness there.

13
00:54.110 --> 01:00.740
But when we're talking about computers, then these machines are what we would call deterministic.

14
01:00.740 --> 01:06.140
They will perform repeatable actions in a fully predictable way.

15
01:06.140 --> 01:13.490
So how do we wrangle these machines that operate basically on 1's and 0's to get them to create some

16
01:13.490 --> 01:14.750
random numbers?

17
01:14.750 --> 01:20.680
Well, there's a whole bunch of maths that can be applied to create what are called Pseudo Random Number

18
01:20.680 --> 01:21.610
Generators.

19
01:21.610 --> 01:25.570
And the one that Python uses is something called the Mersenne Twister.

20
01:25.570 --> 01:31.150
And if you really want to read about it, then you can have a look on Wikipedia and take a look under

21
01:31.150 --> 01:32.710
the Algorithmic detail.

22
01:32.710 --> 01:38.470
But to be honest, it's a little bit too much information for anybody, unless you're really interested

23
01:38.470 --> 01:41.260
in these types of number generators.

24
01:41.260 --> 01:47.650
But what I recommend, though, is a free video from the Khan Academy where they explain Pseudorandom

25
01:47.650 --> 01:55.180
Number Generators and it's really well produced, and it tells you a lot of different aspects of pseudorandom

26
01:55.180 --> 01:56.500
number generation.

27
01:56.500 --> 01:57.730
So have a look at that,

28
01:57.730 --> 02:02.860
if you're interested to learn a little bit more about Pseudorandom Number Generators.

29
02:03.130 --> 02:07.150
We've talked a lot about randomness, but let's see it in action.

30
02:07.150 --> 02:10.150
Let's write some code and produce some random numbers.

31
02:10.150 --> 02:16.570
We know that we want to get hold of some random numbers, but we don't really want to implement the

32
02:16.570 --> 02:22.330
Mersenne Twister ourselves because it's horrendously complicated, using lots and lots of maths,

33
02:22.330 --> 02:25.450
and probably it'll take us months to write the code for.

34
02:25.810 --> 02:28.090
So how can we get random numbers?

35
02:28.360 --> 02:32.830
If you think about it, it's a little bit like searching for something in Google.

36
02:32.830 --> 02:39.460
The Google algorithm is horrendously complicated, and it's taken them years and years to refine and

37
02:39.460 --> 02:44.110
perfect to such an extent where I think Google knows me better than myself,

38
02:44.110 --> 02:48.280
because when I search for something, it always gives me the most relevant results.

39
02:48.280 --> 02:55.060
And if you're questioning the complexity of the Google algorithm, just go to Bing and try searching

40
02:55.060 --> 02:58.030
for something and see how relevant the results are.

41
02:58.060 --> 03:03.220
So they have this super complex algorithm, which we're never going to get a chance to see, let alone

42
03:03.220 --> 03:04.240
understand.

43
03:04.270 --> 03:11.680
And yet, every day we're able to search things on Google and use this Google algorithm to get the things

44
03:11.680 --> 03:16.540
that we want, like the air speed velocity of a laden swallow.

45
03:16.660 --> 03:21.000
Now we can do the same thing when we want to generate random numbers.

46
03:21.000 --> 03:27.270
Because this is such frequently needed functionality, the Python team have already created a Random

47
03:27.270 --> 03:34.050
Module, and you can get a direct link to this documentation just by clicking on the link in the Description

48
03:34.050 --> 03:39.720
box here. And you can see that it contains a whole bunch of functions that you can use that allows

49
03:39.720 --> 03:42.000
you to generate random integers.

50
03:42.000 --> 03:45.720
So random whole numbers, or random floating point numbers.

51
03:45.720 --> 03:49.290
So let's see how we can tap into this Random Module.

52
03:49.740 --> 03:51.900
We first have to import it.

53
03:51.900 --> 03:54.510
So we write, "import random".

54
03:55.290 --> 04:00.840
And now we're able to use this Random Module in our Python code.

55
04:01.230 --> 04:07.920
So we can look into the documentation to figure out how we can generate random whole numbers,

56
04:07.920 --> 04:13.830
to random integers using this Random Module from Python.

57
04:13.830 --> 04:21.390
So if you scroll down on this documentation file and you go to the section, Functions for integers,

58
04:21.390 --> 04:27.690
then you can see a whole bunch of different things that we can do to generate random whole numbers.

59
04:27.690 --> 04:32.880
Now the one that we're going to look into is random.randint().

60
04:32.880 --> 04:38.400
And this is going to generate a random integer between a and b.

61
04:38.400 --> 04:42.870
And these are the numbers that we have to provide to set that range.

62
04:42.870 --> 04:52.260
So the way that randint(a, b) works is that it will generate a random number that is greater than or equal

63
04:52.260 --> 04:56.600
to a and less than or equal to b.

64
04:56.600 --> 05:05.030
So basically, between this range a and b that we provide, but inclusive of both a and b.

65
05:05.030 --> 05:06.980
So let's give it a go.

66
05:07.070 --> 05:11.840
If we go into our code file and we use the Random Module.

67
05:11.840 --> 05:13.610
So we first write, "random".

68
05:13.610 --> 05:21.020
This refers to this module that we just imported which contains all the code for generating random numbers.

69
05:21.020 --> 05:26.210
And then we write a full stop, which in programming is normally called a dot.

70
05:26.210 --> 05:28.010
So random.

71
05:28.010 --> 05:32.990
and then we're going to use the name of that function that we found, randint.

72
05:33.140 --> 05:36.920
So this randint needs some open parentheses,

73
05:36.920 --> 05:44.000
and you can see from the code hints it's asking us for a which is an integer, and b which is an integer,

74
05:44.000 --> 05:47.330
and we already know this is the range that we want.

75
05:47.330 --> 05:49.490
So let's go ahead and give it a range.

76
05:49.490 --> 05:53.960
And I want a random whole number between 1 and 10.

77
05:54.200 --> 06:00.140
So in this case I've got 1 as the first starting value.

78
06:00.140 --> 06:03.410
So it's going to give me a random number that could include 1,

79
06:03.410 --> 06:07.910
and then it goes up to 10 and including 10.

80
06:07.910 --> 06:12.380
So it means that we will get random numbers between 1 and 10.

81
06:12.380 --> 06:20.570
So let's go ahead and save this into a variable which we'll call, random_integer.

82
06:21.410 --> 06:25.850
And now I'm going to print this random_integer.

83
06:26.030 --> 06:30.740
And every single time I run it, you'll notice that I'll get a different number,

84
06:30.740 --> 06:36.200
or maybe sometimes the same, but it's a random number between the range that I've specified.

85
06:37.040 --> 06:42.260
Now, I've mentioned that the Random M odule is a Python module.

86
06:42.260 --> 06:44.540
So what exactly is a module?

87
06:44.570 --> 06:50.570
Well, you've seen that we've mostly been writing our code all on the same page in a sort of script

88
06:50.570 --> 06:50.990
style,

89
06:50.990 --> 06:51.200
right?

90
06:51.200 --> 06:54.500
And everything just kind of gets executed from top to bottom.

91
06:54.500 --> 07:01.000
But sometimes your code will get so long because you're trying to create something complicated, and

92
07:01.000 --> 07:06.700
it's no longer possible to understand what's going on in such a large piece of code.

93
07:06.730 --> 07:14.650
What people will do in that case is to split the code up into individual modules, where each module

94
07:14.650 --> 07:21.530
is responsible for a different bit of functionality of your program, and if you have a complex project

95
07:21.530 --> 07:25.910
with many, many modules, then you could have collaboration on your project, right?

96
07:25.910 --> 07:31.310
Lots of people could be working on it, each person working on a different thing. Say if a factory was

97
07:31.310 --> 07:37.250
building a car, it wouldn't make sense for one person to build the entire car from wheels to axles

98
07:37.250 --> 07:38.000
to the chassis.

99
07:38.000 --> 07:39.230
That's crazy.

100
07:39.230 --> 07:45.310
Instead, you have different people working on different modules, like the Tire module, or the Chassis

101
07:45.310 --> 07:51.460
Module, or the Engine Module, and then once they put everything together, you end up with the final

102
07:51.460 --> 07:54.520
car or in our case, the final program.

103
07:54.820 --> 08:01.300
So we know that the Random Module is a module that the Python team created to make it easier for us

104
08:01.300 --> 08:07.870
to generate our random numbers without needing to get into the complexities of all of the math that's

105
08:07.870 --> 08:11.020
required to Generate Pseudorandom Numbers.

106
08:11.020 --> 08:15.490
But how can we create our own modules, and how do modules work anyways?

107
08:15.520 --> 08:17.230
Well, it's actually very simple.

108
08:17.380 --> 08:25.630
If you open up the file inspector over here and you go into today's task, Random Module and you right-click

109
08:25.630 --> 08:32.110
click on it, you can go into New and we're going to create a new Python file.

110
08:32.110 --> 08:39.180
Now we're going to create our Python file and call it my_module, so that I can show you how to create

111
08:39.180 --> 08:40.920
your very own module.

112
08:41.340 --> 08:49.590
Now let's say inside my_module, I decide to create a variable called my_favorite number,

113
08:49.590 --> 08:53.430
and it happens to be 3.1415.

114
08:53.460 --> 09:01.680
Now, if I want to use this number that I've created in my_module, all I have to do is to go back into

115
09:01.680 --> 09:07.530
the task.py, which is the main entry point, at least in this course format.

116
09:07.530 --> 09:14.310
And normally when you're writing code in Python, it might be called something like main.py or app.py,

117
09:14.310 --> 09:21.330
but either way, there's usually a primary file that you use where you write most of your starting and

118
09:21.330 --> 09:22.410
core code.

119
09:22.440 --> 09:30.060
Now, if I want to use the code in my_module, all I have to do is, same as the Random Module,

120
09:30.060 --> 09:31.350
I have to import it.

121
09:31.350 --> 09:35.880
So I'll import my_module into this task.py file.

122
09:35.880 --> 09:39.750
And then I can use it by simply printing,

123
09:39.750 --> 09:44.730
for example, my_module.my_favorite_number.

124
09:44.730 --> 09:48.360
And you can see it's exactly the same way as the Random Module,

125
09:48.360 --> 09:53.550
we imported it and then we used a function inside it called, randint.

126
09:53.550 --> 09:57.270
And now if I go ahead and print, you can see the,

127
09:57.270 --> 10:02.610
my_favorite_number is printed by using and tapping into this module.

128
10:03.180 --> 10:10.230
Now coming back to our main task of generating random numbers, let's take a look how we can generate

129
10:10.230 --> 10:12.510
random floating point numbers.

130
10:12.510 --> 10:17.790
So I'm going to go ahead and delete my module and all the related code.

131
10:17.790 --> 10:23.790
You can keep yours if you want just for revision, but I want to keep everything as clean as possible.

132
10:23.790 --> 10:30.780
So I'm also going to comment out this section where we've got the random_integer as well.

133
10:30.780 --> 10:34.520
So how do we create random floating point numbers?

134
10:34.550 --> 10:37.340
Well, let's take a look at the documentation.

135
10:37.340 --> 10:44.840
If you scroll down to this area called Real-valued distributions, you can see that one way of generating

136
10:44.840 --> 10:50.120
random floating point numbers is using the random.random() function.

137
10:50.120 --> 10:56.570
And this is one of the core functions that we use a lot when we're dealing with random numbers in Python,

138
10:56.570 --> 11:00.020
because it is one of the most adaptive functions.

139
11:00.020 --> 11:06.530
It generates a random floating point number between 0 and 1.

140
11:06.530 --> 11:12.650
Now if you look at these symbols, you'll see that the random number that's generated can be greater

141
11:12.650 --> 11:13.940
or equal to zero.

142
11:13.940 --> 11:17.540
So that means zero is included in the possibility,

143
11:17.540 --> 11:19.430
but it is less than one.

144
11:19.430 --> 11:24.620
So one is not um in the generated random numbers.

145
11:24.800 --> 11:26.600
Now let's try that out.

146
11:26.600 --> 11:33.950
So we will create a random_number_0_to_1.

147
11:33.950 --> 11:39.110
And this is going to be set to random.random.

148
11:39.110 --> 11:44.240
And notice that it's actually exactly the same, spelled the same, same casing,

149
11:44.240 --> 11:49.550
but the first one refers to the Module, and when you hover over it, it should show you it's the Module

150
11:49.550 --> 11:54.680
random, and the second one refers to the function random.

151
11:54.680 --> 11:58.160
And this is something that doesn't take any inputs,

152
11:58.160 --> 12:03.470
and all you need to do is to add an empty set of parentheses to activate it.

153
12:03.470 --> 12:10.100
When we're looking at functions such as the randint(), we always see a set of parentheses, and it's

154
12:10.100 --> 12:17.530
been used to put in inputs like what to print or what is the prompt for input, or what is the range

155
12:17.530 --> 12:18.700
for a random integer,

156
12:18.700 --> 12:25.720
but remember that some functions don't take any inputs at all, but they still need the set of parentheses

157
12:25.720 --> 12:30.880
in order to carry out the action that the function is supposed to perform.

158
12:30.880 --> 12:39.460
So let's go ahead and print this new random_number_0_to_1, and you will see that every time I press

159
12:39.460 --> 12:43.510
the print button, it generates a new floating point number,

160
12:43.510 --> 12:49.990
and it's between 0 inclusive and up to 1, not inclusive.

161
12:49.990 --> 12:57.580
So you can use this random number generator, random.random() to expand it.

162
12:57.580 --> 12:58.870
So what do I mean by that?

163
12:58.870 --> 13:06.250
If we multiply this by 10, then you'll see that the numbers that are generated are going to be between

164
13:06.250 --> 13:15.880
0 to 10 and not inclusive of 10, because we're basically multiplying the lower range 0 by 10,

165
13:15.880 --> 13:20.410
which is 0, and the upper range by 10, 1 * 10 is 10.

166
13:20.410 --> 13:27.940
So then we've shifted this random number generator to create floating point numbers between 0 and

167
13:27.940 --> 13:30.190
whatever it is that we desire.

168
13:31.150 --> 13:38.080
So you can have a play around with that, but you might also discover another function if you look through

169
13:38.080 --> 13:43.450
the documentation, which is a Random Floating Point Number Generator.

170
13:43.450 --> 13:46.600
So I'm going to call this variable, random_float.

171
13:46.600 --> 13:51.880
And I'm going to use the random.uniform() function.

172
13:51.880 --> 14:01.570
And this function will return a random floating point number such that the number is greater than or

173
14:01.570 --> 14:08.260
equal to the lower bound and less than or equal to the upper bound.

174
14:08.260 --> 14:14.820
So basically it's going to generate numbers between a and b, inclusive of a and b.

175
14:16.050 --> 14:19.920
So to use that we would say, random.uniform()

176
14:19.920 --> 14:24.600
and then we can provide a number say 1 to 10 again.

177
14:24.600 --> 14:31.980
And then let's print this random_float...and let me comment out the other part.

178
14:32.070 --> 14:37.380
And now when I run this you can see it almost does the same thing.

179
14:37.380 --> 14:45.690
The only difference is it's not entirely sure depending on rounding, whether if you will get 10 or

180
14:45.690 --> 14:48.180
not in the random_float.

181
14:48.180 --> 14:52.320
But if you want to be really sure of the range,

182
14:52.830 --> 15:01.530
so this is known as a semi-open range, where you have random.random() that always includes 1 but may

183
15:01.530 --> 15:09.120
never include 1, and you can multiply it and do whatever you like with it reliably knowing that.

184
15:09.120 --> 15:16.830
But because this one can vary depending on the rounding of the upper bound, then you may get the upper

185
15:16.830 --> 15:17.190
bound,

186
15:17.190 --> 15:17.850
you may not.

187
15:17.850 --> 15:21.270
So these are all really minute differences.

188
15:21.270 --> 15:29.370
I recommend to use random.random() if you can, and you understand how it works to extend the range.

189
15:30.690 --> 15:36.360
Now it's time to do some practice and see what you can actually do with random numbers,

190
15:36.360 --> 15:41.340
and I want you to create a heads or tail program.

191
15:41.340 --> 15:48.780
So the idea is that you should be able to comment out all the existing code if you have any, or delete

192
15:48.780 --> 15:49.860
it if you wish.

193
15:49.860 --> 15:59.430
And you're going to create a program that either prints out, "Heads", or it prints out "Tails", and whether

194
15:59.430 --> 16:07.170
if it prints out Heads or Tails will entirely depend on a random number that you generate.

195
16:07.170 --> 16:09.450
So think about how you can do that.

196
16:09.450 --> 16:11.520
Pause the video and give this a go.

197
16:17.210 --> 16:17.750
All right.

198
16:17.750 --> 16:19.880
So how do we do this?

199
16:19.910 --> 16:22.670
Well we need some conditions, right?

200
16:22.670 --> 16:26.540
We need to know that we can generate two random numbers;

201
16:26.540 --> 16:30.650
one will represent heads, and one will represent tails.

202
16:30.680 --> 16:38.480
Now if we want the numbers to occur at the same rate then we could for example, generate a random number

203
16:38.480 --> 16:41.000
that is either 1 or 0.

204
16:41.090 --> 16:42.710
So how can we do that?

205
16:42.710 --> 16:46.820
Well, we can use this randint() function that we learned earlier.

206
16:46.820 --> 16:51.620
So making sure that we've already got "import random" written up here.

207
16:51.620 --> 16:55.790
And don't worry if it goes gray, it does that because it's not being used.

208
16:55.790 --> 16:58.010
We can now use it.

209
16:58.010 --> 17:02.570
And you can see it turns it into normal syntax highlighting color.

210
17:02.780 --> 17:05.600
And then we can say random.randint(),

211
17:05.600 --> 17:09.710
and we want a random number between 0 and 1.

212
17:09.710 --> 17:11.390
So therefore we're going to get 0,

213
17:11.390 --> 17:12.860
or we're going to get 1,

214
17:12.860 --> 17:22.010
and we're going to set this to equal our random_heads_or_tails.

215
17:23.090 --> 17:26.060
Now you can of course call this whatever it is you wish,

216
17:26.060 --> 17:32.840
but essentially what we have here is a random number that is either 1 or 0.

217
17:32.840 --> 17:36.950
And we can verify this just by running this a few times.

218
17:36.950 --> 17:39.200
And you can see it's 1 or it's 0.

219
17:39.320 --> 17:46.550
So now instead of printing it out let's use an if statement and check if the random_heads_or_tails is

220
17:46.550 --> 17:47.900
equal to 0,

221
17:47.930 --> 17:52.420
well in that case, let's go ahead and print, "Heads",

222
17:52.420 --> 17:58.060
but otherwise the only other option is Tails.

223
17:58.060 --> 18:02.500
So let's go ahead and put print("Tails") into the else statement.

224
18:02.500 --> 18:07.810
So when it's 0 it's going to print "Heads" for any other situation which is only 1,

225
18:07.810 --> 18:09.430
then it's going to print "Tails".

226
18:09.430 --> 18:11.080
So now let's hit Run.

227
18:11.080 --> 18:15.760
You can see we have now a random coin toss.

228
18:15.760 --> 18:20.410
So because it's random you might see the same thing occur lots of times,

229
18:20.410 --> 18:26.530
but hopefully over a hundred times you will see it's roughly a 50/50 split.

230
18:27.520 --> 18:33.280
So I hope you had fun creating this program using your newfound knowledge.

231
18:33.280 --> 18:38.080
And once you're ready, head over to the next lesson and we'll continue the day's lessons.