WEBVTT 1 00:00:01.960 --> 00:00:05.620 an important part of object-oriented programming is the concept of 2 00:00:05.620 --> 00:00:11.240 encapsulation so the idea here is that objects contain the data and the methods 3 00:00:11.240 --> 00:00:16.080 that operate on that data and don't expose the actual implementation to the 4 00:00:16.080 --> 00:00:21.320 outside world so it's worth noting that object oriented programming is not the 5 00:00:21.320 --> 00:00:26.419 only way to achieve this and languages such as modular 2 aimed to 6 00:00:26.419 --> 00:00:32.780 provide encapsulation by using modules rather than objects modular 2 enhance to 7 00:00:32.780 --> 00:00:37.440 become modular 3 which was really quite influential in the design 8 00:00:37.440 --> 00:00:43.039 of Java, C++ and also Python although the object approach to encapsulation was 9 00:00:43.039 --> 00:00:47.749 the only one adopted by Java Python allows us to encapsulate data methods 10 00:00:47.749 --> 00:00:52.410 using either an object orientated paradigm or a modular approach and we 11 00:00:52.410 --> 00:00:56.559 saw the modular approach when using the pytz module to handle time zone 12 00:00:56.559 --> 00:01:02.059 information earlier in this course so you don't have to know how pytz was 13 00:01:02.059 --> 00:01:04.440 implemented in order to use it 14 00:01:04.440 --> 00:01:08.549 the method that provides and the time zone information it uses are encapsulated 15 00:01:08.549 --> 00:01:15.090 within the pytz module in fact pytz also uses classes internally so it's possible 16 00:01:15.090 --> 00:01:19.950 to mix both methods quite happily now I repeatedly pointed out that everything 17 00:01:19.950 --> 00:01:24.920 in Python is an object so it may seem strange that a language that is really 18 00:01:24.920 --> 00:01:31.030 so heavily based on objects doesn't restrict us to using an object approach this is 19 00:01:31.030 --> 00:01:36.310 one of the important design decisions of the Python language the basic principle 20 00:01:36.310 --> 00:01:41.229 being that we're all responsible adults at least when programming now I mention this 21 00:01:41.229 --> 00:01:46.009 because many languages work by imposing restrictions on what can be done with 22 00:01:46.009 --> 00:01:51.689 encapsulated data Java and C++ for example restrict access to class fields 23 00:01:51.689 --> 00:01:56.299 by allowing them to be marked as private in Python you can indicate that a 24 00:01:56.299 --> 00:02:00.100 method or attribute should be considered non public but it's extremely 25 00:02:00.100 --> 00:02:04.820 difficult to fully enforce this once you've been introduced to the idea of 26 00:02:04.820 --> 00:02:08.979 encapsulation it can be tempting to spend a lot of time trying to enforce it 27 00:02:08.979 --> 00:02:09.830 in Python 28 00:02:09.830 --> 00:02:13.980 especially if he used 2 other languages such as Java that do a reasonably good 29 00:02:13.980 --> 00:02:18.770 job of preventing access to private data but you be more productive if you accept 30 00:02:18.770 --> 00:02:21.430 that Python takes a different approach 31 00:02:21.430 --> 00:02:24.720 neither approach is necessarily better they are just different and each has its own 32 00:02:24.720 --> 00:02:29.620 advantages and disadvantages so let's continue our introduction to classes in 33 00:02:29.620 --> 00:02:34.050 Python with another example we are going to look at the concept of a bank account and 34 00:02:34.050 --> 00:02:38.700 the classes are going to enable money to be deposited withdrawn and will hopefully 35 00:02:38.700 --> 00:02:43.020 anyway maintain the correct balance for the account so I'm going to use the same 36 00:02:43.020 --> 00:02:46.810 file we use previously but I'm just going to create a new Python file so we are going call this one 37 00:02:47.700 --> 00:02:57.490 accounts....so let's start first by creating the class 38 00:02:57.490 --> 00:03:05.000 so we are gonna call the class account so.... and it's going to be a simple 39 00:03:05.000 --> 00:03:08.350 .... 40 00:03:11.569 --> 00:03:24.019 .... 41 00:03:24.019 --> 00:03:30.730 ....and incidentally the convention is to start class names with a capital letter and to use 42 00:03:30.730 --> 00:03:35.159 camel case being that each time you got a different word you capitalized 43 00:03:35.159 --> 00:03:41.079 just that word so if we're calling this the account number class we would type something like that 44 00:03:41.079 --> 00:03:42.790 capitalize each 45 00:03:42.790 --> 00:03:47.450 word but basically start with a capital letter so that is the convention in Python so 46 00:03:47.450 --> 00:03:52.090 ok will continue on with our init method so we want to passed name and balance to 47 00:03:52.090 --> 00:04:00.639 it and we are going to assign the attributes.... 48 00:04:00.639 --> 00:04:13.359 ..... 49 00:04:13.359 --> 00:04:18.739 .... 50 00:04:18.739 --> 00:04:26.599 ...and we are going to just check the amount that is passed 51 00:04:26.599 --> 00:04:36.320 to make sure that its greater than 0...and only add it to our balance if its greater than 0 and we will add the amount to what 52 00:04:36.320 --> 00:04:45.690 the current balance was like so....next let's do a withdraw method.... 53 00:04:45.690 --> 00:04:52.870 ... 54 00:04:52.870 --> 00:05:19.760 .... 55 00:05:19.760 --> 00:05:28.330 .....ok so there's our class and as I just mentioned the convention is to 56 00:05:28.330 --> 00:05:33.680 start class names with a capital letter and and to use camel case with that said you'll find 57 00:05:33.680 --> 00:05:38.240 many the built-in classes in Python do use lowercase nevertheless IntelliJ will 58 00:05:38.240 --> 00:05:41.750 give you a warning if you use lowercase or separate paths of the class name with 59 00:05:41.750 --> 00:05:54.460 underscores...another warning as you can see should only use case convention it's not 60 00:05:54.460 --> 00:06:01.580 happy if we use underscores now I've included a dot string on line 2 at the start of the class and it's a good idea to do 61 00:06:01.580 --> 00:06:05.980 this with all your classes although it can appear to be a bit redundant with simple classes like 62 00:06:05.980 --> 00:06:10.760 this one which he can really figure out the functionality just by glancing it's 63 00:06:10.760 --> 00:06:13.770 a good habit to get into and once your class structures get more complicated 64 00:06:14.590 --> 00:06:18.270 you will be glad that you did do this and so will anyone else who uses your classes 65 00:06:18.270 --> 00:06:23.520 and I'll be talking more about doc strings later when I show you what they used for in 66 00:06:23.520 --> 00:06:28.150 more detail now the init method as you recall is used to initialize the 67 00:06:28.150 --> 00:06:32.900 class and it's extremely rare to create a class without providing an init method 68 00:06:32.900 --> 00:06:37.890 now in an earlier video I used the term constructor to described the init method but 69 00:06:37.890 --> 00:06:42.570 really that's not strictly true in the new style Python classes that will be 70 00:06:42.570 --> 00:06:48.060 using for most of this section the Class creation process involves two steps so 71 00:06:48.060 --> 00:06:52.740 the first method to be called when a class instance is created is new and this 72 00:06:52.740 --> 00:06:57.810 takes care of the actual creation the init method then customizes the instance 73 00:06:57.810 --> 00:07:03.460 performing tasks such as giving values to the data attributes for example so 74 00:07:03.460 --> 00:07:08.250 technically the class constructor is the new method which is actually calling 75 00:07:08.250 --> 00:07:12.419 underscore underscore new underscore underscore as you probably expect 76 00:07:12.419 --> 00:07:16.940 generally speaking you don't need to define new except in special cases 77 00:07:17.520 --> 00:07:21.569 when subclassing certain types of classes so I won't be discussing you 78 00:07:21.569 --> 00:07:25.979 much in this section as a result now old style classes were the only type 79 00:07:25.979 --> 00:07:31.110 of class available in Python 2 up until 2.2 when the new style classes are 80 00:07:31.110 --> 00:07:36.419 introduced so in Python 2.2 onwards you could use both types of 81 00:07:36.419 --> 00:07:41.060 classes I will discuss the Python 2 classes later on 82 00:07:41.060 --> 00:07:45.340 so that your aware of the differences and can recognize them but in Python 3 83 00:07:45.340 --> 00:07:49.129 there are only the new style classes and as a results I'm going to be 84 00:07:49.129 --> 00:07:53.659 concentrating on those as we move forward so getting back to the account 85 00:07:53.659 --> 00:07:58.090 class the init method takes two parameters in addition to self and these 86 00:07:58.090 --> 00:08:03.669 are used to set the values of the data attributes name and balance now notice that all 87 00:08:03.669 --> 00:08:06.840 the methods takes self as their 1st parameter and you saw IntelliJ 88 00:08:06.840 --> 00:08:10.630 automatically adding that for us and whenever we want to refer to the data 89 00:08:10.630 --> 00:08:14.710 attributes we have to use the form self. and whatever the name of the attribute is 90 00:08:14.710 --> 00:08:20.340 again as you see me type in this class in Python there is no shorthand and self 91 00:08:20.340 --> 00:08:25.009 must be specified if your used to java you can omit the word this before 92 00:08:25.009 --> 00:08:29.349 a field if their references is not ambiguous but in Python you can't do that so you need 93 00:08:29.349 --> 00:08:33.690 to get into the habit of doing that each time I just wanna remember i just fixed that 94 00:08:33.690 --> 00:08:40.419 those warnings and add the extra space to keep IntelliJ happy now the positive withdrawal methods 95 00:08:40.419 --> 00:08:44.730 obviously a pretty simple and they adjust the balance by the amount passed to the parameter 96 00:08:44.730 --> 00:08:49.529 they also check that the amounts are positive although as withdrawal its just a negative 97 00:08:49.529 --> 00:08:53.770 deposit and a deposit is just a negative withdrawal we could have used a single 98 00:08:53.770 --> 00:08:58.250 method to handle both cases now there are extra steps that are really sure of 99 00:08:58.250 --> 00:09:01.370 implemented in the withdrawal method to make sure there is enough money in the 100 00:09:01.370 --> 00:09:05.910 account though so it makes sense to keep the two transaction type separate the 101 00:09:05.910 --> 00:09:10.690 show balance method again very simple it just prints the balance data attribute so now the 102 00:09:10.690 --> 00:09:14.220 that the classes been defined we can create accounts with people and start 103 00:09:14.220 --> 00:09:18.520 looking out for their money so I'll start by creating account for myself 104 00:09:18.520 --> 00:09:23.760 of course with a zero balance and then deposit withdraw some cash let's go ahead and do 105 00:09:23.760 --> 00:09:25.480 that 106 00:09:25.480 --> 00:09:56.760 .... 107 00:09:56.760 --> 00:10:06.079 .....and lets 108 00:10:06.079 --> 00:10:11.980 run this to make sure its workings account created for Tim the original balance was 109 00:10:11.980 --> 00:10:17.440 0 which would expect balances is a thousand when we deposited 1000 and we've 110 00:10:17.440 --> 00:10:22.589 withdrawn 500 and shows a balance of 500 so that's working fine 111 00:10:23.660 --> 00:10:26.970 so this is a very simple example as I said and theirs plenty of room for improvement 112 00:10:28.120 --> 00:10:31.550 now rather than having to call the show balance method after each transaction 113 00:10:31.550 --> 00:10:35.690 will probably be helpful if the balance if the deposit and withdrawal methods 114 00:10:35.690 --> 00:10:41.570 did this for us automatically I will also reluctantly fix the problem that lets me take as much 115 00:10:41.570 --> 00:10:45.880 money as I want regardless of the actual balance so for both methods I'm just gonna 116 00:10:45.880 --> 00:10:49.710 call the show balance method after adjusting the balance preventing 117 00:10:49.710 --> 00:10:54.070 unlimited withdrawals easily done just to confirm the way the withdrawal method is 118 00:10:54.070 --> 00:11:00.870 written at the moment I could quite happily withdraw 50,000 and it would 119 00:11:00.870 --> 00:11:05.460 work all be with a $49,000 overdrawn balance but the point is it would work and we need 120 00:11:05.460 --> 00:11:09.570 to restrict that so that when we are withdrawing money we can only withdraw the 121 00:11:09.570 --> 00:11:15.120 amount to the maximum amount we've got currently in the account so lets go ahead and do that so 122 00:11:15.120 --> 00:11:21.160 we are going to add to the deposit method so..... 123 00:11:21.160 --> 00:11:27.140 ... 124 00:11:27.140 --> 00:11:41.670 .... 125 00:11:42.620 --> 00:11:45.990 .... 126 00:11:47.570 --> 00:12:06.850 .... 127 00:12:06.850 --> 00:12:13.100 ....so we'll leave the initial show balance call on line 27 128 00:12:13.100 --> 00:12:18.810 but will comment out the other one because they can be called automatically 129 00:12:18.810 --> 00:12:23.760 when we call those methods and lets put a valid withdrawal if we went back into 500 130 00:12:23.760 --> 00:12:32.930 then we will put a invalid one in.....so lets run this one 131 00:12:32.930 --> 00:12:40.380 you can see balance is 0 account was created for 132 00:12:40.380 --> 00:12:42.220 Tim balance is 0 133 00:12:42.220 --> 00:12:49.060 balance is 1000 it is calling the show balance method now as we are calling the deposit 134 00:12:49.060 --> 00:12:52.430 and withdrawal methods balance is deducted to 500 and we got a message 135 00:12:52.430 --> 00:12:58.680 here when we called line 34 when line 34 was executed the amount must be 136 00:12:58.680 --> 00:13:03.000 greater than 0 no more than your account balance and it also reprinted the 137 00:13:03.000 --> 00:13:06.240 balance you can see the balance is still the same as it was when that method 138 00:13:06.240 --> 00:13:10.190 was called so this seems to be working fine and it does show that you can 139 00:13:10.190 --> 00:13:14.430 call methods from other methods as I mentioned earlier that you must prefix 140 00:13:14.430 --> 00:13:18.710 all attributes with self and that applies to method calls in this class and you 141 00:13:18.710 --> 00:13:23.410 probably saw when I was typing one of the show balance methods that I forgot to put the self their and 142 00:13:23.410 --> 00:13:29.150 IntelliJ was flagging as an error so this may catch Java programmers out for 143 00:13:29.150 --> 00:13:33.010 a while and it shouldn't be a huge problem because as you saw IntelliJ will let you 144 00:13:33.010 --> 00:13:38.270 know as soon as you tried to use attribute or a method call within a method without using 145 00:13:38.270 --> 00:13:46.230 self again just to confirm what I'm talking back we can delete that we then get an error un-resolve 146 00:13:46.230 --> 00:13:52.850 reference so we have to use self and likewise for the attributes we get an error 147 00:13:52.850 --> 00:13:56.200 unless you specifically do it so It will probably catch you out if your coming from another 148 00:13:56.200 --> 00:13:59.070 language such as Java but after you 149 00:13:59.070 --> 00:14:03.600 done a bit of Python coding it becomes pretty straightforward and 150 00:14:03.600 --> 00:14:08.480 again IntelliJ is helping you by flagging the error so you need to fix the 151 00:14:08.480 --> 00:14:12.290 errors to run the program so sooner or later you'll figure it out anyway but 152 00:14:12.290 --> 00:14:19.630 with that said there is a fundamental problem with the code for this account class and 153 00:14:19.630 --> 00:14:22.860 although fixing it is easy their more than one way to do so 154 00:14:22.860 --> 00:14:26.980 I'm gonna cover that later but for now I'm gonna see if you can spot the problem 155 00:14:26.980 --> 00:14:30.430 until we get to that section where our I will show you how to get around it 156 00:14:30.430 --> 00:14:32.840 so we'll start working on that in the next video