WEBVTT 1 00:00:01.939 --> 00:00:06.250 so just running our application again to see where we're at and you can see we've 2 00:00:06.250 --> 00:00:10.660 got the transaction log correctly showing deposits and withdrawals and the 3 00:00:10.660 --> 00:00:15.059 way they were able to differentiate the 2 was by negating the amount in the 4 00:00:15.059 --> 00:00:18.770 withdrawal method so we put a minus and whatever the amount is and consequently we 5 00:00:18.770 --> 00:00:23.140 can when we are in the transaction print out we're actually checking to see if the 6 00:00:23.140 --> 00:00:28.180 amounts is greater than 0 if it is it's deposited otherwise its withdrawn so that is 7 00:00:28.180 --> 00:00:33.390 how it knows how to figure out whether it's an withdrawal or a deposit 8 00:00:33.390 --> 00:00:38.059 so looking at the transaction log in the output if I run it again 9 00:00:38.059 --> 00:00:44.219 we can easily calculate that I had a balance of $500 and that's only possible 10 00:00:44.219 --> 00:00:49.399 because we know that when we open the count for myself on line 46 the account had 11 00:00:49.399 --> 00:00:54.989 a zero balance but lets open and another account and by doing that we can see the 12 00:00:54.989 --> 00:00:59.539 problem if the initial balance isn't 0 and once we do that I'll set a mini 13 00:00:59.539 --> 00:01:03.760 challenged for you to fix the problem so what we wanted to do is add some code down at the 14 00:01:03.760 --> 00:01:11.380 end so after the show transactions for my balance lets create another one... 15 00:01:11.380 --> 00:01:33.400 .... 16 00:01:33.400 --> 00:01:43.280 ...lets just run that but before we do that one thing I 17 00:01:43.280 --> 00:01:48.910 meant to do at the start of the video is you noticed up here we got the warning here 18 00:01:48.910 --> 00:01:52.570 for IntelliJ saying it needs two lines to blank lines and that's talking about 19 00:01:52.570 --> 00:01:57.280 the two lines above the class definition so I'll add another line just to fix that problem 20 00:01:57.280 --> 00:02:02.140 up so after the imports normally allowed two lines their to keep IntelliJ 21 00:02:02.140 --> 00:02:08.280 happy ok so if we run this application now we made those code changes looking 22 00:02:08.280 --> 00:02:13.340 at the transaction log down the bottom we got a 100 deposited and 200 withdrawn so according 23 00:02:13.340 --> 00:02:17.489 to that transaction log steph is overdrawn by a 100 and that because the show 24 00:02:17.489 --> 00:02:22.170 transactions method isn't taking into account the initial deposit so it's time 25 00:02:22.170 --> 00:02:27.450 for that mini challenge and the mini challenge is quite simple so just to change the class 26 00:02:27.450 --> 00:02:33.440 so that the amount used to open the account also appears in the transaction list so no 27 00:02:33.440 --> 00:02:38.110 change needs to be made to the main part of the program only the class itself can 28 00:02:38.110 --> 00:02:41.760 be changed so again what we're trying to do is change the class so that the 29 00:02:41.760 --> 00:02:46.299 amount used to open the account also appears in the transaction list so 30 00:02:46.299 --> 00:02:49.959 go away and make that changed when you're ready to see our solution come back 31 00:02:49.959 --> 00:02:52.959 and I'll take you through.... 32 00:02:54.770 --> 00:03:00.210 ok so how did you get on did you figure out how to do that let's go and have a look at our way of fixing 33 00:03:00.210 --> 00:03:12.030 this and the change that we need to make is in the init methods so lets go back to the init on line 13 we got our attributes set on lines 34 00:03:12.030 --> 00:03:18.560 14 15 and 16 but what we wanted to do is make a change to transaction list so instead of 35 00:03:18.560 --> 00:03:22.520 starting with an empty one what we want to do is we want to set up and put that initial 36 00:03:22.520 --> 00:03:29.470 transaction in and we can do that easily by within the initialization on lines 37 00:03:29.470 --> 00:03:42.100 16 we are going to change that to..... 38 00:03:42.100 --> 00:03:51.140 and what we can also do then is put a self....at that stage so now if we run it we can see 39 00:03:51.140 --> 00:03:56.470 in the case of steph now $800 deposited which was the initial deposit a 100 deposited and in 40 00:03:56.470 --> 00:04:00.040 200 withdrawn so just as when logging the deposits and withdrawals 41 00:04:00.040 --> 00:04:06.480 the date and balanced are enclosed in parentheses as you saw be put on line 16 doing that 42 00:04:06.480 --> 00:04:11.590 way so their added as single tuple rather than separate items in the list now running the 43 00:04:11.590 --> 00:04:17.750 program we do get a more complete transaction history however theirs no mention on 44 00:04:17.750 --> 00:04:25.110 the fail withdrawn of 2000 from my account and scrolling down this on here I'm talking 45 00:04:25.110 --> 00:04:30.830 about on line 56 but anything that can affect the balance is logged or is it 46 00:04:30.830 --> 00:04:35.470 so before finishing with the accounts classes theirs a couple more things I like to 47 00:04:35.470 --> 00:04:39.930 cover concerning underscores the first is that the naming of the data 48 00:04:39.930 --> 00:04:44.310 attributes for class now although we can't prevent them from being changed by the 49 00:04:44.310 --> 00:04:47.919 main program we should really give clients an indication that they're not 50 00:04:47.919 --> 00:04:53.490 intended to be modified as that bypasses the transaction logging so if what I mean is if I 51 00:04:53.490 --> 00:04:54.510 just closing this down 52 00:04:54.510 --> 00:04:59.200 in the case of steph here we could there's nothing stopping us from putting 53 00:04:59.200 --> 00:05:01.550 steph.... 54 00:05:01.550 --> 00:05:15.230 .....and so we can run that as you can see now the balance 55 00:05:15.230 --> 00:05:20.770 doesn't match the transaction history so again theirs no indication that the 56 00:05:20.770 --> 00:05:25.150 client accessing this class shouldn't directly modify the balance data 57 00:05:25.150 --> 00:05:30.120 attribute so the least that we should do is really rename all 3 data attributes so 58 00:05:30.120 --> 00:05:34.300 that their names start with an underscore now IntelliJ makes it easy to refactor 59 00:05:34.300 --> 00:05:38.930 the attributes when they are defined in the init method so close that down come back 60 00:05:38.930 --> 00:05:54.420 up to init method and we just refactor this so make this an underscore you can see its made the changes for us 61 00:05:54.420 --> 00:05:58.990 underscore balanced and just to be complete will also do it for transaction list as well 62 00:06:02.690 --> 00:06:09.130 ok it has been changed throughout now strangely enough on line 61 as you can see 63 00:06:09.130 --> 00:06:13.380 their IntelliJ is not actually giving us a warning when we assign a new value to the 64 00:06:13.380 --> 00:06:16.730 balance we've got a warning when using underscore module variables but with 65 00:06:16.730 --> 00:06:22.250 classes it is down to us to remember this convention so the rule is attributes 66 00:06:22.250 --> 00:06:26.080 whose name start with a single underscore are for internal use only 67 00:06:26.620 --> 00:06:29.970 there's nothing to prevent you from messing with them but things will 68 00:06:29.970 --> 00:06:34.570 probably break if you do mess with them so I've been using the term non public 69 00:06:34.570 --> 00:06:39.600 rather than private and that's because private implies that it's enforced and 70 00:06:39.600 --> 00:06:42.050 the second thing is something I mentioned in the previous section 71 00:06:42.050 --> 00:06:46.080 that applies to classes and that's the convention of using 2 underscores at 72 00:06:46.080 --> 00:06:50.750 the start of a name now that is really intended for use when subclassing which 73 00:06:50.750 --> 00:06:55.290 we're going to be looking at later in this section and the idea of that is to prevent name clashes 74 00:06:55.290 --> 00:06:58.270 and it causes Python to perform name mangling 75 00:06:58.270 --> 00:07:04.290 on the attribute or method name so that its not accidentally reused by sub class so to demonstrate 76 00:07:04.290 --> 00:07:07.530 what I'm talking about lets refactor the balanced attribute to start with two underscores 77 00:07:07.530 --> 00:07:21.730 we will do that in the init method....and run it....800 78 00:07:21.730 --> 00:07:28.580 800 deposit initially then a 100 makes 900 200 deducted balances is 700 so 79 00:07:28.580 --> 00:07:33.490 the balance agrees with the transaction histories and what's interesting is it 80 00:07:33.490 --> 00:07:39.310 the balance attribute wasn't changed by the code on line 61 this code here even though the 81 00:07:39.310 --> 00:07:44.820 name __balance is correct so that strange and obviously for it not to 82 00:07:44.820 --> 00:07:49.280 change something funny is going on you know what's what's going on why is it doing 83 00:07:49.280 --> 00:07:51.460 that well the answer is that 84 00:07:51.460 --> 00:07:57.020 Python as I mentioned Mangles the names of class attributes both methods 85 00:07:57.020 --> 00:08:01.310 and variables that start with two underscores and the easiest way to see whats 86 00:08:01.310 --> 00:08:07.890 going on is to print out the dic so let's go ahead and do that so if go under the 87 00:08:07.890 --> 00:08:17.960 show balance lets do....so if we do that we can see what's going on 88 00:08:20.480 --> 00:08:27.260 so theirs couple of things to know here firstly as you can see at the start steph has an attribute called underscore underscore balance with a 89 00:08:27.260 --> 00:08:34.650 value of $200 now this data attribute was created when we assign the value of 20o to it on line 61 90 00:08:34.650 --> 00:08:38.900 Python didn't find an attribute with that name in steps namespace so it looked at the 91 00:08:38.900 --> 00:08:42.630 name space from the class and didn't find it there either now as a result it 92 00:08:42.630 --> 00:08:46.530 created a new data attribute and we saw that happening in an earlier video when we 93 00:08:46.530 --> 00:08:51.150 created a power attribute for the kenwood kettle and the second thing which is also 94 00:08:51.150 --> 00:08:55.050 the reason why python didn't find the balance attribute is it there is a data 95 00:08:55.050 --> 00:08:59.370 attribute called account balance and again that's got the expected value of 700 96 00:08:59.370 --> 00:09:04.270 so by prefixing the name balanced with two underscores we are asking Python to 97 00:09:04.270 --> 00:09:06.990 perform name mangling 98 00:09:06.990 --> 00:09:11.279 and it automatically renames the attributes to start with an underscore and the name of the classes 99 00:09:11.279 --> 00:09:15.709 as you can see and this is done behind the scenes our source code isn't 100 00:09:15.709 --> 00:09:20.920 changed now whenever we refer to the balance attribute within the class Python mangles 101 00:09:20.920 --> 00:09:26.810 the name for us when we use the same name outside the class well it doesn't so in 102 00:09:26.810 --> 00:09:31.370 this way the attribute is hidden so that's not accidentally changed 103 00:09:31.370 --> 00:09:38.050 now if you really wanted to and we also need to remember to be always responsible so Python won't stop us doing something that we 104 00:09:38.050 --> 00:09:41.990 really want to do so if you really want to do that then we can change the mangled attribute 105 00:09:43.140 --> 00:09:47.140 and just to see how you go about doing that lets make a change to that so we could do something 106 00:09:47.140 --> 00:09:55.330 like here by something on line 67 so..... 107 00:09:55.330 --> 00:10:05.110 ...so run that and 108 00:10:05.110 --> 00:10:08.810 you can see the balanced now has been affected by that so this mechanism is 109 00:10:08.810 --> 00:10:11.720 really intended to prevent accidental 110 00:10:11.720 --> 00:10:16.260 accidental shadowing of attributes when creating sub classes and although it can 111 00:10:16.260 --> 00:10:20.529 be used to indicate a sort of private access to the variables this used is 112 00:10:20.529 --> 00:10:23.940 discouraged and if you think about it there really isn't much point using 113 00:10:23.940 --> 00:10:28.209 double underscores merely to try and force private access it doesn't work for one 114 00:10:28.209 --> 00:10:32.279 thing and it's still possible to access the real attribute using the form 115 00:10:32.279 --> 00:10:35.790 underscore class underscore underscore attribute name as we've done here on 116 00:10:35.790 --> 00:10:42.320 line 67 it also doesn't provide any great indication that the attribute is 117 00:10:42.320 --> 00:10:47.500 non-public that a single underscore does now you're unlikely to accidentally 118 00:10:47.500 --> 00:10:51.520 access a non-public attribute by typing a lead underscore anyway so 119 00:10:51.520 --> 00:10:54.520 there's really no need to make access even more difficult 120 00:10:55.250 --> 00:11:00.240 now if this absolutely horrifies you it's possible it's actually possible to read and write to 121 00:11:00.240 --> 00:11:06.270 private class fields in Java and C++ in Java you can use a technique known as reflection 122 00:11:06.270 --> 00:11:11.240 to do this it's not easy but it can be done so Python just makes it easy to do it if 123 00:11:11.240 --> 00:11:15.170 you are certainly need to do it in both cases it's really not something that 124 00:11:15.170 --> 00:11:16.400 you'll end up doing 125 00:11:16.400 --> 00:11:21.240 accidentally now the final comment on this is that ending an attribute name with 126 00:11:21.240 --> 00:11:25.770 2 underscores doesn't result in the name being magnled so names are only 127 00:11:25.770 --> 00:11:29.850 mangled if they start with two underscores and if they end with no more than a 128 00:11:29.850 --> 00:11:34.730 single underscore so init method for example is not mangled and we are talking about 129 00:11:34.730 --> 00:11:39.990 the init method which has got a underscore underscore init underscore underscore all right so I'm going to end 130 00:11:39.990 --> 00:11:44.700 this video here now in the next video we gonna start talking about doc strings 131 00:11:45.390 --> 00:11:48.980 and continue our discussion on classes so see you in the next video