WEBVTT 1 00:00:01.930 --> 00:00:05.939 so as I mentioned at the end of the previous video theirs a fundamental problem 2 00:00:05.939 --> 00:00:11.430 with the code for the account class that we've created and although fixing it is 3 00:00:11.430 --> 00:00:16.490 easy there's more than one way to do so so I'm gonna cover that later but so I 4 00:00:16.490 --> 00:00:19.600 will let you see if you can spot the problem until we get to that part 5 00:00:19.600 --> 00:00:24.350 of this course so now that we have a program that is using the class to maintain an 6 00:00:24.350 --> 00:00:28.560 account balance it's easy to see hopefully easy to see how the class 7 00:00:28.560 --> 00:00:33.879 encapsulates the balance attributes and the methods to manipulate it without any client of 8 00:00:33.879 --> 00:00:38.270 the class having to worry about the details now a client is anything 9 00:00:38.270 --> 00:00:43.160 that uses a particular class or this class so clients don't have to worry about the 10 00:00:43.160 --> 00:00:47.170 implementation details they just need to call the deposit method to put more money 11 00:00:47.170 --> 00:00:52.390 in and the withdrawal method to take money out so one advantage provided 12 00:00:52.390 --> 00:00:56.710 by encapsulation is that we can change the way that the methods are implemented 13 00:00:56.710 --> 00:01:01.489 as long as we don't change their signature in a way that is it that is 14 00:01:01.489 --> 00:01:05.610 incompatible with the current signature so if we do that any client code will 15 00:01:05.610 --> 00:01:10.409 continue to work now if you remember back from the lectures on functions that a 16 00:01:10.409 --> 00:01:15.130 signature is the definition of the name and parameters of a function as well as 17 00:01:15.130 --> 00:01:21.430 any return value and applies to methods as well so to demonstrate that what I'll do is I'll keep the bank 18 00:01:21.430 --> 00:01:25.540 orders as happy by including a transaction log to track the details of all deposits 19 00:01:25.540 --> 00:01:31.170 and withdrawals now will start by just tracking deposits because the same code 20 00:01:31.170 --> 00:01:34.979 will ultimately be used for withdrawals and you know rather than duplicating the 21 00:01:34.979 --> 00:01:38.570 code I'll use that as an opportunity to introduce class methods 22 00:01:39.250 --> 00:01:43.549 and first I'll add a list to the classes data attributes and modify the deposit 23 00:01:43.549 --> 00:01:47.689 method to add the transaction details to the list the details to be log will be 24 00:01:47.689 --> 00:01:51.390 using the date and time of the transaction also the amount so we'll need 25 00:01:51.390 --> 00:01:55.790 to import the date time module and remember from the videos in section eleven that 26 00:01:55.790 --> 00:02:01.200 to we really should install local time so we'll also used to pytz module so 27 00:02:01.200 --> 00:02:06.619 that we can log our location and where UTC time so lets go ahead and start the changes and 28 00:02:06.619 --> 00:02:09.530 the first we need to do is import those 2 29 00:02:09.530 --> 00:02:16.990 modules so....and remember if you having 30 00:02:16.990 --> 00:02:21.560 problems with pytz getting that to work we did install that in a previous sections so go 31 00:02:21.560 --> 00:02:22.610 back and check that out 32 00:02:22.610 --> 00:02:27.630 as its not installed usually by default with the Python installation alright so what we're 33 00:02:27.630 --> 00:02:32.400 going to do is we need to add the list to the class attributes so that we can store 34 00:02:32.400 --> 00:02:34.060 the log and we'll do that in our 35 00:02:34.060 --> 00:02:39.989 init method so we'll come down here to the init and.... 36 00:02:39.989 --> 00:02:47.920 ....and what we need to do is in 37 00:02:47.920 --> 00:02:52.360 the deposit method we need to add the call that is going to append the amount 38 00:02:52.360 --> 00:02:57.930 of the deposit with the UTC time so we'll do that by typing... 39 00:02:57.930 --> 00:03:02.920 ... 40 00:03:05.350 --> 00:03:19.230 .... 41 00:03:19.230 --> 00:03:26.730 ....and attribute called transaction list has been created in 42 00:03:26.730 --> 00:03:32.030 the init method and that sent to an empty list initially and in the deposit method 43 00:03:32.030 --> 00:03:37.489 we then appended the transaction details to the list which is the date and the 44 00:03:37.489 --> 00:03:42.239 amount in this case now I'll come back to how the dates is calculated in a 45 00:03:42.239 --> 00:03:47.430 minute because their have been a quite a few video since the ones on dates and times in Python 46 00:03:48.410 --> 00:03:52.459 and I have chose to store the details as a tuple containing the date time and the amount 47 00:03:52.459 --> 00:03:56.329 so I'll add the method to print out the transaction log after the show balance 48 00:03:56.329 --> 00:04:03.080 method so let's go ahead and do that so... 49 00:04:03.080 --> 00:04:18.660 ... 50 00:04:18.660 --> 00:04:20.390 .... 51 00:04:20.390 --> 00:04:35.030 ... 52 00:04:35.030 --> 00:05:15.020 .... 53 00:05:16.280 --> 00:05:27.070 .....and that should be it so before I make any changes to the main 54 00:05:27.070 --> 00:05:32.220 program down here lets just run it to make sure that it still works even though I've 55 00:05:32.220 --> 00:05:36.540 made changes to the implementation of course of the deposit method by adding the call 56 00:05:36.540 --> 00:05:44.710 to add the transaction log so if I just run that so it still works but the 57 00:05:44.710 --> 00:05:49.400 class now has got additional functionality the ability to display a 58 00:05:49.400 --> 00:05:53.580 transaction list so any existing code doesn't break as a result of the changes 59 00:05:53.580 --> 00:05:57.610 we made to the deposit method bit if we want to we can also print out the transaction 60 00:05:57.610 --> 00:06:03.900 list by adding that to our main so we can come down here after the withdrawal.... 61 00:06:03.900 --> 00:06:07.820 ...and if we run that 62 00:06:08.880 --> 00:06:17.900 ....you can see $1000 deposited on the date of the transaction in UTC time and in the local time which is 63 00:06:17.900 --> 00:06:23.280 works out to 8:32 in the morning Australian time so before I move on you might be wondering 64 00:06:23.280 --> 00:06:29.520 about the for loop in line 30 or on line 30 where the code iterates through the 65 00:06:29.520 --> 00:06:34.510 transaction list so we created the transaction list to contain tuples and in 66 00:06:34.510 --> 00:06:38.690 the videos on tuples I showed you that you can assign a value to several variables in a 67 00:06:38.690 --> 00:06:42.350 single assignment statement by using a tuple and that's all it's really 68 00:06:42.350 --> 00:06:46.450 happening in the for loop instead of just assigning a value to a single variable for 69 00:06:46.450 --> 00:06:48.010 each value in the list 70 00:06:48.010 --> 00:06:53.120 Python unpacks the tuple and assigns the value to both data and amount at the same 71 00:06:53.120 --> 00:06:53.600 time 72 00:06:53.600 --> 00:06:58.230 ok so our class now logs deposits and I could do the same thing in the 73 00:06:58.230 --> 00:07:02.000 withdrawal method to log withdrawals as well and to do that that would involve 74 00:07:02.000 --> 00:07:07.600 duplicating the code that creates a date and time with time zone information so its 75 00:07:07.600 --> 00:07:12.030 probably better to create a function to do that instead now I could do that by 76 00:07:12.030 --> 00:07:15.870 adding another method to the class but the method wouldn't be acting on any 77 00:07:15.870 --> 00:07:19.270 data attributes and there's no point including it in the namespace of every 78 00:07:19.270 --> 00:07:23.960 single instance when a function in the would do the job just fine so 79 00:07:23.960 --> 00:07:28.900 it's a good place to introduce static methods which is the same term used in 80 00:07:28.900 --> 00:07:34.000 Java and C++ so what i'll do is i'll start by creating it as a method which I 81 00:07:34.000 --> 00:07:39.900 put right at the start of the class so we are going 82 00:07:39.900 --> 00:07:47.040 put it above the init so.... 83 00:07:47.040 --> 00:07:58.380 .... 84 00:07:58.380 --> 00:08:01.200 ... 85 00:08:01.200 --> 00:08:10.880 .....so two things firstly you notice I've use a underscore at the start when defining 86 00:08:10.880 --> 00:08:16.180 the method and also we've got a warning so IntelliJ has detected that the 87 00:08:16.180 --> 00:08:18.940 self parameter isn't use and suggest that the method 88 00:08:18.940 --> 00:08:25.320 can be implemented as a static method instead...so detecting 89 00:08:25.320 --> 00:08:30.420 a method which may safely be made static so you can just repeat what I said it's detected that the 90 00:08:30.420 --> 00:08:34.789 self parameter isn't being used in the method that was created and its 91 00:08:34.789 --> 00:08:39.390 suggesting that this method can be implemented as static method instead a 92 00:08:39.390 --> 00:08:43.400 static method is shared by all instances of the class in the same way that the 93 00:08:43.400 --> 00:08:47.700 power_source class attribute of our kettle class was shared 94 00:08:47.700 --> 00:08:52.770 by all instances so making the method static is pretty simple we just remove the 95 00:08:52.770 --> 00:08:57.360 self parameter and put an annotation before the method definition so if I 96 00:08:57.360 --> 00:09:05.700 removed self after we delete that parameter we also have to put annotation so above the method we put... 97 00:09:05.700 --> 00:09:11.000 ...and notice how the warnings disappeared 98 00:09:11.000 --> 00:09:16.270 and if we hold the Ctrl key down or command on a Mac and hover over the annotation 99 00:09:16.270 --> 00:09:22.190 you can see that it's coming up and showing its a class and as I said everything in 100 00:09:22.190 --> 00:09:27.670 Python is an object so if we now click while holding down control or command on this 101 00:09:27.670 --> 00:09:34.250 annotation you see definitions showing up here in the built ins module that useful 102 00:09:34.250 --> 00:09:37.640 to remember again that everything is an object but unless your experience in object 103 00:09:37.640 --> 00:09:40.530 oriented programming I wouldn't worry too much about this implementation 104 00:09:40.530 --> 00:09:47.730 details just yet so the current time method uses the date time class or the date time 105 00:09:47.730 --> 00:09:52.680 module to get the current date and time in UTC format and then uses the pytz 106 00:09:52.680 --> 00:09:57.190 module to localize it so that it stores time zone information for the current location 107 00:09:57.190 --> 00:10:04.520 and then on line 10 it returns the localize UTC date time so we looked at pytz and 108 00:10:04.520 --> 00:10:08.780 time zones in section eleven and here I'm just making sure that I store UTC time 109 00:10:08.780 --> 00:10:12.530 but have the ability to also display the times in the local time that the 110 00:10:12.530 --> 00:10:17.420 transaction happen and I've also named the current underscore time method 111 00:10:17.420 --> 00:10:21.460 with the leading underscore to indicate to anyone using this class that this 112 00:10:21.460 --> 00:10:25.930 method isn't really part of the normal usage of the class now this conventional 113 00:10:25.930 --> 00:10:30.400 the convention is that names starting with an underscore are non-public 114 00:10:30.400 --> 00:10:34.910 even though if you remember theirs nothing in Python that enforces this so the account 115 00:10:34.910 --> 00:10:39.660 class is concerned with managing bank accounts not with dates and times so 116 00:10:39.660 --> 00:10:42.690 although clients can call the current underscore time method if they want to 117 00:10:42.690 --> 00:10:47.250 the underscore makes it clear that this method isn't intended to be used outside 118 00:10:47.250 --> 00:10:51.630 of the class now if someone who does use the current time method from outside our 119 00:10:51.630 --> 00:10:56.370 account class they run the risk that we may remove it in later version or change 120 00:10:56.370 --> 00:10:59.550 it to remove to return something completely different in the future 121 00:10:59.550 --> 00:11:02.700 starting the name again with an underscore is the Python way of 122 00:11:02.700 --> 00:11:06.270 informing them of this they used the method at their own risk 123 00:11:06.970 --> 00:11:12.660 ok so now we've implemented this static method we can go back to our deposit 124 00:11:12.660 --> 00:11:17.330 method and used that static method instead of performing the conversion in 125 00:11:17.330 --> 00:11:22.370 places as we currently got on line 22 so come down and make a change to that so let's 126 00:11:22.370 --> 00:11:23.420 make the change here 127 00:11:23.420 --> 00:11:29.090 delete all this code now in the transaction_list.append 128 00:11:29.090 --> 00:11:34.720 then brackets that will only be a matter of now adding an extra set of brackets and 129 00:11:34.720 --> 00:11:37.720 .... 130 00:11:39.060 --> 00:11:45.750 ...so that's all we need to do now so its 131 00:11:45.750 --> 00:11:51.160 now calling the static method that we defined on line 8 returning or adding the 132 00:11:51.160 --> 00:11:57.620 returned date and then also as it was doing before appending the amount and we 133 00:11:57.620 --> 00:12:03.700 can go back to our withdrawal method and in the code that's confirmed that 134 00:12:03.700 --> 00:12:10.070 we're able to do the withdraw after we deducted the amount we put.... 135 00:12:10.070 --> 00:12:26.660 .... 136 00:12:26.660 --> 00:12:31.490 ...so if we run this to confirm its running you can see now we've got our code working 137 00:12:31.490 --> 00:12:35.040 quite nicely we got our deposit and withdrawal by showing nicely in it's 138 00:12:35.040 --> 00:12:39.070 formatted as it should be and obviously we could do a bit of work if we wanted to 139 00:12:39.070 --> 00:12:41.480 do to fix these dates up but we will leave them for now 140 00:12:41.480 --> 00:12:45.430 so the point here is that despite the additional functionality that the class 141 00:12:45.430 --> 00:12:49.620 now has the program still runs fine without any modification to the main 142 00:12:49.620 --> 00:12:54.500 part in other words we didn't modify anything here in the code from line 143 00:12:54.500 --> 00:12:59.160 46 onwards that's still as it was before and its still working despite us making 144 00:12:59.160 --> 00:13:04.519 these changes in the various class methods and looking at lines 145 00:13:04.519 --> 00:13:10.070 22 and 28 you notice that when we are calling our static method were 146 00:13:10.070 --> 00:13:14.750 using the class name then the name of the method so we're not using self in other 147 00:13:14.750 --> 00:13:20.100 words again that's because the current time method is a static or class method now you 148 00:13:20.100 --> 00:13:24.690 can call class method on an instance as I said some in other words I can change that and 149 00:13:24.690 --> 00:13:33.389 just make this say here....and that's will work just as well as but theirs no advantage to 150 00:13:33.389 --> 00:13:37.790 doing so and in actual fact performance slightly suffers because 151 00:13:37.790 --> 00:13:41.870 Python will first attempt to find the method in the instances namespace and 152 00:13:41.870 --> 00:13:47.000 when it fails it then checks the class name space so if you know you got a static methods best to leave it 153 00:13:47.000 --> 00:13:50.949 there just a to say that little bit of time and to make it clear also in the 154 00:13:50.949 --> 00:13:55.649 code that it is a static method so some ways needed to tell the difference 155 00:13:55.649 --> 00:13:59.190 between deposits and withdrawals and negating the amount is a quick way to do 156 00:13:59.190 --> 00:14:04.800 this you could as an alternative add a transaction type item to the tuple if you wanted a tuple 157 00:14:04.800 --> 00:14:08.680 if you wanted to do that so I'm going to end the video here and then the next video we're 158 00:14:08.680 --> 00:14:12.760 going to talk a little bit more about the transactions and start a mini 159 00:14:12.760 --> 00:14:14.260 challenge so see you in the next video