1
00:00:00,450 --> 00:00:07,140
If you got stuck or if you had any problems completing this project, the first port of call is to review

2
00:00:07,140 --> 00:00:08,380
the lessons you learned today.

3
00:00:08,760 --> 00:00:14,280
It might just be that you need to see some of the theory a few more times and listen to it a few more

4
00:00:14,280 --> 00:00:19,410
times and practice it a few more times before you're ready to tackle this final challenge.

5
00:00:20,070 --> 00:00:24,660
But if you have completed it and you just want to see the solution, then I'm going to go through it

6
00:00:24,660 --> 00:00:25,380
with you right now.

7
00:00:26,400 --> 00:00:30,210
Again, we're going to complete all of the program requirements step by step.

8
00:00:30,570 --> 00:00:38,610
So the first thing is to print a report for all of the current resources in the coffee machine. Back

9
00:00:38,610 --> 00:00:39,090
in PyCharm,

10
00:00:39,330 --> 00:00:44,310
I'm actually going to collapse this entire project folder because I'm not going to be writing any code

11
00:00:44,310 --> 00:00:46,140
other than inside main.py.

12
00:00:47,040 --> 00:00:54,270
Now you can see up here, we've got access to four classes. And if we take a look inside the documentation,

13
00:00:54,480 --> 00:01:00,990
you can see that both the coffeemaker class and the money machine class have a method called report.

14
00:01:01,560 --> 00:01:06,690
And this is going to print a report of all of the resources like water, milk, coffee,

15
00:01:06,990 --> 00:01:09,810
and this is going to print a report of the current profit.

16
00:01:10,260 --> 00:01:16,290
So our final report is going to be both a report from the money machine as well as the coffee maker.

17
00:01:17,310 --> 00:01:22,380
Let's go ahead and start off by creating some objects from these classes.

18
00:01:22,950 --> 00:01:27,840
For example, the money machine is going to be just called money_machine

19
00:01:27,870 --> 00:01:30,250
or you could call it my_money_machine.

20
00:01:30,270 --> 00:01:33,090
You can actually name your objects anything you like.

21
00:01:33,720 --> 00:01:41,160
But I'm just going to use the default Python snake case to create a new variable money_machine, which

22
00:01:41,160 --> 00:01:46,980
is going to hold my object. And my object is going to be created, of course, from the money machine

23
00:01:46,980 --> 00:01:47,520
class.

24
00:01:48,090 --> 00:01:51,900
And the construction happens when I add the parentheses.

25
00:01:52,500 --> 00:01:58,440
So now I have a object created and stored inside this variable money_machine.

26
00:01:59,280 --> 00:02:06,870
Now, if I want this money machine to create a report, then all I have to do is tap into the object

27
00:02:07,260 --> 00:02:12,360
and then write a dot and then call the method that I need, which is report.

28
00:02:13,020 --> 00:02:15,630
So now if I go ahead and run my code,

29
00:02:18,360 --> 00:02:22,110
you can see it prints out the current amount of money in the machine.

30
00:02:22,890 --> 00:02:25,710
Now let's do the same thing for our coffee maker.

31
00:02:26,630 --> 00:02:31,010
Again, I'm going to call it coffee_maker, and you see this frequently.

32
00:02:31,020 --> 00:02:39,840
The object naming tends to be the lower case and snake case, so separated by underscores, version of the

33
00:02:39,840 --> 00:02:40,740
name of the class.

34
00:02:40,950 --> 00:02:47,580
So the name of the class is CoffeeMaker, and usually you'll see people name the object exactly the

35
00:02:47,580 --> 00:02:49,290
same, but in lowercase.

36
00:02:50,280 --> 00:02:57,900
And now that I have my coffee _maker, then I can go ahead and call the report method on that object

37
00:02:57,900 --> 00:02:58,410
as well.

38
00:02:58,800 --> 00:03:04,980
And now, if I run my code once more, you can see that I've got everything now being reported and printed

39
00:03:04,980 --> 00:03:05,190
out.

40
00:03:06,060 --> 00:03:12,870
So in this case, we don't actually have to care how report is implementing all of this functionality.

41
00:03:13,200 --> 00:03:19,470
All we have to do is read the documentation, find the method that does the thing that we want, and

42
00:03:19,470 --> 00:03:23,640
then trust that it will carry out the functionality as described.

43
00:03:24,870 --> 00:03:30,480
Now that we've completed step 1, the next one is to check that resources are sufficient.

44
00:03:31,080 --> 00:03:35,370
My first port of call is going to be going over to the documentation.

45
00:03:35,820 --> 00:03:42,240
And you can see that the coffeemaker class actually has a method called is _resource_efficient.

46
00:03:42,600 --> 00:03:50,130
And all we have to do is pass in the drink, which is a menu item, and then it's going to check and

47
00:03:50,130 --> 00:03:56,640
give us true, if that drink order can be made, and false if the ingredients are insufficient.

48
00:03:57,840 --> 00:04:03,930
So how do we get hold of this drink menu item to pass over to this method?

49
00:04:04,650 --> 00:04:11,700
Well, if we take a look at the menu class, you can see it has a method called get_items and this is

50
00:04:11,700 --> 00:04:15,030
where you really see reading the documentation properly,

51
00:04:15,450 --> 00:04:19,800
actually absorbing everything that's in here becomes really, really helpful.

52
00:04:20,459 --> 00:04:24,570
This menu class has two methods that are really useful.

53
00:04:25,050 --> 00:04:30,870
One, It's able to get a hold of the names of all the items that are available on the menu.

54
00:04:31,350 --> 00:04:35,370
And it returns it as a string separated by forward slashes.

55
00:04:36,120 --> 00:04:40,560
It's also able to find a drink based on the order name.

56
00:04:40,590 --> 00:04:47,550
So if we passed in one of these names to this function find_drink, then it's going to return a menu

57
00:04:47,550 --> 00:04:49,770
item object if it actually exists.

58
00:04:50,040 --> 00:04:51,990
Otherwise, it's going to return none.

59
00:04:52,620 --> 00:04:56,670
We're going to need both of these in order to ask the user what they want.

60
00:04:57,530 --> 00:05:02,520
Let's go ahead and set up our while loop. As we had previously

61
00:05:02,540 --> 00:05:08,660
I'm going to create a new variable called is_on and it's going to start off being true.

62
00:05:09,230 --> 00:05:16,880
And then while coffee machine is on, well then we're going to get hold of all the options that we

63
00:05:16,880 --> 00:05:22,850
can offer the user. And we get that by calling that method get_items.

64
00:05:23,300 --> 00:05:28,580
But of course, because this is a method, it's associated with an object.

65
00:05:28,670 --> 00:05:32,240
So we have to create an object from this menu blueprint.

66
00:05:33,440 --> 00:05:36,770
So let's do that next to all the other objects being created.

67
00:05:37,190 --> 00:05:42,050
So let's create a menu object and it's going to be created from the menu class,

68
00:05:42,050 --> 00:05:43,640
and then we add the parentheses.

69
00:05:44,030 --> 00:05:47,840
And now we have access to that object by the name menu.

70
00:05:48,380 --> 00:05:54,800
The options are going to be equal to the menu object and then we're going to call the get_items method.

71
00:05:55,340 --> 00:06:01,580
And then when this method returns, it's going to save the string and all the options into this variable

72
00:06:01,580 --> 00:06:02,390
called options.

73
00:06:02,990 --> 00:06:09,800
Now we can get the user's choice by asking them for what would you like?

74
00:06:11,170 --> 00:06:17,650
And then inside a set of parenthesis we'll offer them all the options. And then, of course, I need

75
00:06:17,650 --> 00:06:19,480
to turn this into an fstring.

76
00:06:19,630 --> 00:06:24,070
And the code highlighting immediately tells me that this is actually now working.

77
00:06:24,640 --> 00:06:32,740
So once I've got the user's choice, then I can incorporate the reporting behaviour into this choice.

78
00:06:33,130 --> 00:06:42,310
Remember, previously we said if the choice was equal to off, then that means the is_on is going

79
00:06:42,310 --> 00:06:45,390
to be equal to false, and elif

80
00:06:45,400 --> 00:06:47,860
the choice is equal to report,

81
00:06:48,310 --> 00:06:53,110
well, in this case, we're going to get the coffeemaker and the money machine to make their reports

82
00:06:53,110 --> 00:06:54,040
into the console.

83
00:06:54,970 --> 00:07:03,040
Finally, we're ready to tackle the next problem, which is how do we check that we have enough resources?

84
00:07:04,100 --> 00:07:10,520
And this is going to require us to find the drink given the order name that the user chose from the

85
00:07:10,520 --> 00:07:17,440
choice and then get hold of the menu item which comes as the output from this method call.

86
00:07:18,430 --> 00:07:26,110
So else, we're going to save our drink as a variable called drink, and then we're going to tap into

87
00:07:26,110 --> 00:07:35,500
the menu.find_drink. And find_drink, you'll notice, takes a order name as the input.

88
00:07:35,980 --> 00:07:42,370
So this is a string and this is going to be equal to whatever the user chose inside this choice.

89
00:07:42,940 --> 00:07:45,910
So let's put the choice in here as the input.

90
00:07:46,450 --> 00:07:51,190
And now, once we've got hold of this drink, let's go ahead and print it.

91
00:07:51,820 --> 00:07:55,930
Remember, we're expecting a menu item object at this stage.

92
00:07:56,500 --> 00:08:01,480
So let's click run, and let's make sure that we can hit report to get the report,

93
00:08:01,870 --> 00:08:11,440
we can say off to switch off the machine and exit the code, and we can also get hold of a latte by

94
00:08:11,440 --> 00:08:14,530
passing in latte as the drink that we want.

95
00:08:15,040 --> 00:08:21,940
And we now get printed a menu item object at this particular location in the computer's memory.

96
00:08:22,450 --> 00:08:23,040
Perfect.

97
00:08:23,050 --> 00:08:25,330
Everything is working as expected.

98
00:08:26,140 --> 00:08:32,590
Now, instead of printing the drink, I'm going to tackle this step 2, which is to check that the

99
00:08:32,590 --> 00:08:34,330
resources are sufficient.

100
00:08:35,440 --> 00:08:42,400
Again, that's going to require us to look through our documentation. And you'll see that the coffee

101
00:08:42,400 --> 00:08:43,600
maker class has

102
00:08:43,600 --> 00:08:50,260
that method is_resource _sufficient, and it expects a menu item object as the input.

103
00:08:50,710 --> 00:08:54,970
And then it's going to return true when it can be made and false if it can't.

104
00:08:55,960 --> 00:09:03,550
So let's get hold of our coffee maker object and then get it to check if the resources are sufficient

105
00:09:03,940 --> 00:09:07,000
to make the current drink that we're interested in.

106
00:09:07,870 --> 00:09:11,770
And let's go ahead and print the results here

107
00:09:12,820 --> 00:09:14,350
and run our code.

108
00:09:15,190 --> 00:09:23,290
Let's say that we wanted to make a latte. That's going to be resource sufficient, so true. Espresso,

109
00:09:23,620 --> 00:09:27,560
also true, and a Cappuccino is also true.

110
00:09:27,580 --> 00:09:29,740
So we can make all three drinks, basically.

111
00:09:30,070 --> 00:09:37,480
Now, instead of printing this, what we want to do is we want to check if this is true and then proceed

112
00:09:37,480 --> 00:09:40,210
to the next step if there are enough resources.

113
00:09:40,870 --> 00:09:47,830
Now the next step is to take payment from the user and to process the coins and check the transaction

114
00:09:47,830 --> 00:09:48,700
is successful.

115
00:09:49,630 --> 00:09:56,980
Notice how in our coffee machine documentation for the money machine, we don't actually have a way

116
00:09:56,980 --> 00:10:05,050
of processing the coins. But it what it does have is it allows us to make payments passing in the cost

117
00:10:05,050 --> 00:10:11,530
of the drink and then it will return true when the payment is accepted or false, if insufficient.

118
00:10:12,160 --> 00:10:15,650
So let's see what happens if we actually try to make payment.

119
00:10:16,510 --> 00:10:23,110
Let's tap into our money machine object and then call the make_payment method and we have to pass in

120
00:10:23,110 --> 00:10:26,170
the cost of the drink that the user ordered.

121
00:10:26,710 --> 00:10:34,480
So we've got the drink object here, which remember is a menu item, and each of the menu items have

122
00:10:34,480 --> 00:10:39,880
three attributes that we care about: the name of the drink, the cost of the drink and the ingredient

123
00:10:39,880 --> 00:10:40,240
list.

124
00:10:40,630 --> 00:10:49,360
So this is what we're interested in at the moment. So we can pass in the drink.cost which is the

125
00:10:49,360 --> 00:10:52,270
attribute that's associated with the drink object,

126
00:10:52,750 --> 00:10:59,110
and that cost is going to be processed by this make_payment method from the money machine.

127
00:10:59,740 --> 00:11:05,020
And then finally, it's going to tell us whether if this was successful or not.

128
00:11:05,410 --> 00:11:08,200
So let's see what happens when we run this code as it is.

129
00:11:09,230 --> 00:11:11,230
Let's say I wanted a latte,

130
00:11:12,170 --> 00:11:14,820
notice how it's asking me to insert coins:

131
00:11:14,840 --> 00:11:22,340
how many quarters, how many dimes, how many nickels and how many pennies. A the coffee machine,

132
00:11:22,700 --> 00:11:28,490
I don't actually need to care about how the money and the coins are processed.

133
00:11:29,090 --> 00:11:35,180
All I had to do is call make_payment and it deals with all of this automatically.

134
00:11:36,170 --> 00:11:43,430
Finally, it gives me the change and it returns true, telling me that this make_payment was indeed

135
00:11:43,430 --> 00:11:44,240
successful.

136
00:11:45,140 --> 00:11:52,610
If you actually look inside the money_machine code, then you can see that it has a method called process_

137
00:11:52,610 --> 00:11:56,790
coins, but it's called when make payment is triggered.

138
00:11:57,290 --> 00:12:02,960
This class is going to process coins, and then it's going to decide whether if it was successful

139
00:12:03,170 --> 00:12:07,820
or not. And if it was successful, it's going to add the cost to the profit,

140
00:12:08,120 --> 00:12:13,130
and if not, it's going to tell you that that was not enough money and your money is refunded.

141
00:12:14,980 --> 00:12:23,620
Coming back over here, if this is successful, then that means the user has managed to pay and we fulfilled

142
00:12:23,680 --> 00:12:27,850
step 3 and 4 just using one method.

143
00:12:28,960 --> 00:12:32,440
The final thing we have to do is to actually make the coffee.

144
00:12:33,160 --> 00:12:35,830
And that, of course, happens right at the end here.

145
00:12:36,430 --> 00:12:42,730
And all we have to do to make the coffee is get hold of the coffee maker object and then call the make_

146
00:12:42,730 --> 00:12:48,220
coffee method and we can pass in the order, which is our drink.

147
00:12:48,700 --> 00:12:54,850
Because remember that the make_coffee method expects a menu item as the input parameter.

148
00:12:55,990 --> 00:13:03,280
We can actually simplify this code even more by saying, well, if the coffee maker is_resource_sufficient

149
00:13:04,030 --> 00:13:11,620
and the money machine was able to take payment, well then we can get the coffee_maker to make coffee.

150
00:13:12,310 --> 00:13:14,320
So now let's go ahead and run our code.

151
00:13:16,530 --> 00:13:21,930
And let's report to begin with, to see how much resources we have to begin with.

152
00:13:22,380 --> 00:13:24,780
And then let's order a coffee.

153
00:13:26,930 --> 00:13:30,890
Insert lots of money and we've got our coffee back.

154
00:13:31,400 --> 00:13:39,800
So now let's go ahead and order a different coffee, latte, and let's go ahead and insert lots of money.

155
00:13:40,370 --> 00:13:42,380
And you can see, here's my latte.

156
00:13:42,770 --> 00:13:49,910
But now, if I hit report, you can see that the objects, the coffee maker has been managing our resources

157
00:13:50,420 --> 00:13:53,240
and the money_machine has been managing our profit.

158
00:13:53,960 --> 00:13:59,900
Now, if I decided to order another latte, then it should actually tell me, sorry, there's not enough

159
00:13:59,900 --> 00:14:04,520
water and there's not enough milk. So it can't make me that drink.

160
00:14:05,150 --> 00:14:12,650
And we've managed to achieve all of this functionality by writing very few lines of code, and the code

161
00:14:12,650 --> 00:14:16,130
itself is actually very, very easy to understand.

162
00:14:16,370 --> 00:14:22,840
Even if you came to this completely fresh, you've never seen how each of the methods are implemented,

163
00:14:22,850 --> 00:14:24,440
you don't know how the coffee maker works,

164
00:14:24,710 --> 00:14:26,240
you don't know how the money machine works,

165
00:14:26,540 --> 00:14:29,000
you can see quite easily what it's trying to do.

166
00:14:29,960 --> 00:14:35,660
And so if you only have to write this kind of code, then it would make it so much easier to create

167
00:14:35,660 --> 00:14:39,440
even more complex functionality in your coffee machine, right?

168
00:14:40,430 --> 00:14:43,130
So have a play around with these classes:

169
00:14:43,580 --> 00:14:50,270
the coffeeMaker, the moneyMachine, the menu, the menu item, etc. And see what else it is that

170
00:14:50,270 --> 00:14:51,590
you can do with this code

171
00:14:51,860 --> 00:14:55,880
while not touching any of the blueprints for each of these classes.

172
00:14:57,200 --> 00:15:02,660
Now, in the next lesson, I'm going to be showing you how to create your own classes so that you can

173
00:15:02,660 --> 00:15:07,880
actually start structuring your code using full object-oriented programming.

174
00:15:08,390 --> 00:15:14,420
And we're going to learn about these things like the initialization and how classes are declared and

175
00:15:14,420 --> 00:15:16,910
why there's all this self all over the place.

176
00:15:17,630 --> 00:15:20,480
That's all yet to come on tomorrow's lessons.

