All language subtitles for English (auto-generated)_en_0_Harvard CS50_s Introduction to Programming with Python – Full University Course(1080P_HD)

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
ny Chichewa
zh-CN Chinese (Simplified)
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fr French
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranî)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
fa Persian
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu
Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated: 1 00:00:00,160 --> 00:00:04,799 this course from Harvard University is 2 00:00:02,440 --> 00:00:07,240 an introduction to programming using the 3 00:00:04,799 --> 00:00:09,960 Python programming language you will 4 00:00:07,240 --> 00:00:12,679 learn how to read and write code as well 5 00:00:09,960 --> 00:00:15,759 as how to test and debug it this course 6 00:00:12,679 --> 00:00:18,080 is taught by Dr David Meen and it's 7 00:00:15,759 --> 00:00:20,279 designed for students with or without 8 00:00:18,080 --> 00:00:23,760 prior programming experience who'd like 9 00:00:20,279 --> 00:00:23,760 to Learn Python 10 00:00:24,870 --> 00:00:34,719 [Music] 11 00:00:36,740 --> 00:00:43,609 [Music] 12 00:00:45,520 --> 00:00:49,879 hello world my name is David Meen and 13 00:00:47,920 --> 00:00:52,320 this is cs50's Introduction to 14 00:00:49,879 --> 00:00:53,800 programming with python whereas cs50 15 00:00:52,320 --> 00:00:55,520 itself is an introduction to the 16 00:00:53,800 --> 00:00:57,559 intellectual Enterprises of computer 17 00:00:55,520 --> 00:00:59,280 science and the Arts of programming this 18 00:00:57,559 --> 00:01:02,000 course is specifically focused on 19 00:00:59,280 --> 00:01:03,480 programming in Python itself at the 20 00:01:02,000 --> 00:01:05,080 beginning of the course will'll be focus 21 00:01:03,480 --> 00:01:07,240 on a topic in programming known as 22 00:01:05,080 --> 00:01:08,520 functions and variables mechanisms via 23 00:01:07,240 --> 00:01:10,439 which you can write code that solve 24 00:01:08,520 --> 00:01:12,280 smaller problems but you can compose 25 00:01:10,439 --> 00:01:14,400 those smaller Solutions into solutions 26 00:01:12,280 --> 00:01:16,720 to larger problems still we'll then 27 00:01:14,400 --> 00:01:18,680 transition to a look at conditionals a 28 00:01:16,720 --> 00:01:21,520 way in code of expressing yourself 29 00:01:18,680 --> 00:01:23,799 logically to maybe do something if some 30 00:01:21,520 --> 00:01:25,880 question has an answer of true or not do 31 00:01:23,799 --> 00:01:27,520 something if the answer is false we'll 32 00:01:25,880 --> 00:01:29,960 transition thereafter to introducing you 33 00:01:27,520 --> 00:01:32,000 to Loops the ability and code to do 34 00:01:29,960 --> 00:01:34,320 something again and again and again some 35 00:01:32,000 --> 00:01:35,799 number of times we then transition to 36 00:01:34,320 --> 00:01:38,000 something a little more technical known 37 00:01:35,799 --> 00:01:39,759 as exceptions unfortunately a lot can go 38 00:01:38,000 --> 00:01:41,320 wrong when you're writing code some of 39 00:01:39,759 --> 00:01:43,079 it your fault some of it perhaps someone 40 00:01:41,320 --> 00:01:45,280 else's fault but you can write code 41 00:01:43,079 --> 00:01:46,920 defensively so to speak and actually 42 00:01:45,280 --> 00:01:48,960 catch those kinds of exceptions those 43 00:01:46,920 --> 00:01:51,040 errors and handle them properly so that 44 00:01:48,960 --> 00:01:53,119 the users you're writing code for don't 45 00:01:51,040 --> 00:01:55,320 actually see the same thereafter we'll 46 00:01:53,119 --> 00:01:57,399 take a look at libraries third-party 47 00:01:55,320 --> 00:01:59,079 code written by other people often or 48 00:01:57,399 --> 00:02:01,399 perhaps yourself in the past that you 49 00:01:59,079 --> 00:02:03,520 can use and reuse in your own project so 50 00:02:01,399 --> 00:02:05,600 as to avoid Reinventing the wheel again 51 00:02:03,520 --> 00:02:07,600 and again we'll look thereafter at 52 00:02:05,600 --> 00:02:09,720 something called Unit tests and turns 53 00:02:07,600 --> 00:02:11,599 out you'll actually write code to test 54 00:02:09,720 --> 00:02:13,720 your own code but you won't have to 55 00:02:11,599 --> 00:02:15,560 write tests for your tests indeed this 56 00:02:13,720 --> 00:02:17,640 is a best practice in Industry writing 57 00:02:15,560 --> 00:02:19,080 tests for your code so that one you can 58 00:02:17,640 --> 00:02:20,760 be sure that your code today is 59 00:02:19,080 --> 00:02:23,200 hopefully if your tests are correct 60 00:02:20,760 --> 00:02:25,280 correct itself but moreover if you or 61 00:02:23,200 --> 00:02:27,400 someone else modifies your code tomorrow 62 00:02:25,280 --> 00:02:29,280 or down the line you can rerun those 63 00:02:27,400 --> 00:02:31,400 same tests to ensure that those new 64 00:02:29,280 --> 00:02:33,480 changes have not broken anything about 65 00:02:31,400 --> 00:02:35,720 your own code we'll then take a look at 66 00:02:33,480 --> 00:02:37,920 something called file Io Io for input 67 00:02:35,720 --> 00:02:39,959 and output the ability to not just store 68 00:02:37,920 --> 00:02:42,440 information inside of a computer's 69 00:02:39,959 --> 00:02:45,159 memory but rather save it persistently 70 00:02:42,440 --> 00:02:46,480 to diss so to speak to files and folders 71 00:02:45,159 --> 00:02:48,640 we'll then take a look at another 72 00:02:46,480 --> 00:02:50,480 technique known as regular expressions 73 00:02:48,640 --> 00:02:52,840 whereby in Python you can Define 74 00:02:50,480 --> 00:02:54,480 patterns and you can validate data to 75 00:02:52,840 --> 00:02:56,000 make sure the human type something in as 76 00:02:54,480 --> 00:02:57,879 you expect you can use regular 77 00:02:56,000 --> 00:03:00,239 Expressions to extract data perhaps from 78 00:02:57,879 --> 00:03:02,319 some data set you're trying to analyze 79 00:03:00,239 --> 00:03:04,840 we'll then take a look ultimately at 80 00:03:02,319 --> 00:03:06,640 objectoriented programming a paradigm a 81 00:03:04,840 --> 00:03:09,319 way of writing code whereby you can 82 00:03:06,640 --> 00:03:10,720 represent in code real world entities 83 00:03:09,319 --> 00:03:12,280 and this is in addition to other 84 00:03:10,720 --> 00:03:13,959 paradigms of programming that we'll also 85 00:03:12,280 --> 00:03:15,480 explore among them procedural 86 00:03:13,959 --> 00:03:17,480 programming where you write lots of 87 00:03:15,480 --> 00:03:19,560 those functions procedures really top to 88 00:03:17,480 --> 00:03:21,280 bottom to solve problems step by step 89 00:03:19,560 --> 00:03:23,319 and even something known as functional 90 00:03:21,280 --> 00:03:25,200 programming as well and then at the very 91 00:03:23,319 --> 00:03:27,799 end of the course will we equip you with 92 00:03:25,200 --> 00:03:29,920 all the more tools for your toolkit an 93 00:03:27,799 --> 00:03:31,959 additional uh building blocks additional 94 00:03:29,920 --> 00:03:33,799 vocabulary via which after this same 95 00:03:31,959 --> 00:03:35,360 course you can go off on your own and 96 00:03:33,799 --> 00:03:37,799 either take other courses or solve 97 00:03:35,360 --> 00:03:39,920 projects of your own using all of these 98 00:03:37,799 --> 00:03:42,200 mechanisms now this course itself 99 00:03:39,920 --> 00:03:43,599 assumes no prior programming background 100 00:03:42,200 --> 00:03:45,360 so you don't have to have written a 101 00:03:43,599 --> 00:03:47,760 single line of code in python or any 102 00:03:45,360 --> 00:03:50,360 language yet but this is also a course 103 00:03:47,760 --> 00:03:52,400 that you can take before during or even 104 00:03:50,360 --> 00:03:54,840 after cs50 itself if you'd like to get 105 00:03:52,400 --> 00:03:56,480 all the more versed with python each 106 00:03:54,840 --> 00:03:58,680 week via the course's lectures will we 107 00:03:56,480 --> 00:04:00,200 introduce you to any number of Concepts 108 00:03:58,680 --> 00:04:02,200 that will then drill down more deeply 109 00:04:00,200 --> 00:04:04,159 into in the form of problem sets each 110 00:04:02,200 --> 00:04:06,040 week that is programming projects that 111 00:04:04,159 --> 00:04:08,360 will enable you to apply some of those 112 00:04:06,040 --> 00:04:10,360 Lessons Learned to problems of your very 113 00:04:08,360 --> 00:04:12,319 own and by the end of the course you'll 114 00:04:10,360 --> 00:04:14,760 solve to have solved so many problems 115 00:04:12,319 --> 00:04:16,400 that ideally are representative of 116 00:04:14,760 --> 00:04:18,160 problems you'll eventually encounter in 117 00:04:16,400 --> 00:04:20,199 the real world whether you aspire to 118 00:04:18,160 --> 00:04:21,959 solve code in the technical world or 119 00:04:20,199 --> 00:04:23,960 perhaps in the Arts the humanities the 120 00:04:21,959 --> 00:04:25,880 social sciences the Natural Sciences or 121 00:04:23,960 --> 00:04:28,280 Beyond you'll have ultimately the 122 00:04:25,880 --> 00:04:30,240 vocabulary and the technical skills via 123 00:04:28,280 --> 00:04:33,600 which to approach the same 124 00:04:30,240 --> 00:04:38,320 this then is cs50 and this is cs50's 125 00:04:33,600 --> 00:04:38,320 Introduction to programming with python 126 00:04:45,430 --> 00:05:00,230 [Music] 127 00:05:02,320 --> 00:05:07,000 all right this is cs50's Introduction to 128 00:05:05,000 --> 00:05:09,000 programming with python my name is David 129 00:05:07,000 --> 00:05:11,479 men and this is our week on functions 130 00:05:09,000 --> 00:05:12,720 and variables but odds are many of you 131 00:05:11,479 --> 00:05:14,600 most of you have never actually 132 00:05:12,720 --> 00:05:17,160 programmed before so let's start by 133 00:05:14,600 --> 00:05:19,240 doing just that let me go ahead here and 134 00:05:17,160 --> 00:05:21,680 open up my computer and on it a program 135 00:05:19,240 --> 00:05:23,199 called Visual Studio code or VSS code 136 00:05:21,680 --> 00:05:25,319 which is just a very popular program 137 00:05:23,199 --> 00:05:27,120 nowadays for actually writing code now 138 00:05:25,319 --> 00:05:28,960 you don't have to write code using this 139 00:05:27,120 --> 00:05:30,560 particular tool in fact all we need at 140 00:05:28,960 --> 00:05:33,120 the end of the day is is a a so-called 141 00:05:30,560 --> 00:05:34,560 text editor a program for writing text 142 00:05:33,120 --> 00:05:36,280 and Heck if you really want you could 143 00:05:34,560 --> 00:05:38,360 even use something like Google Docs or 144 00:05:36,280 --> 00:05:39,960 Microsoft Word you'd have to save it in 145 00:05:38,360 --> 00:05:41,520 the right format but really at the end 146 00:05:39,960 --> 00:05:43,639 of the day all you need is a program for 147 00:05:41,520 --> 00:05:45,840 writing text because that's what code is 148 00:05:43,639 --> 00:05:47,160 text now within this particular program 149 00:05:45,840 --> 00:05:49,720 I'm going to have the ability to create 150 00:05:47,160 --> 00:05:51,720 one or more files via this top portion 151 00:05:49,720 --> 00:05:53,880 of the screen and I'm going to do so by 152 00:05:51,720 --> 00:05:55,759 diving right in and doing this at the 153 00:05:53,880 --> 00:05:58,160 bottom of my screen at the bottom of my 154 00:05:55,759 --> 00:06:00,680 screen is a so-called terminal window 155 00:05:58,160 --> 00:06:03,840 and this is a command line interface or 156 00:06:00,680 --> 00:06:06,039 CLI interface to the underlying computer 157 00:06:03,840 --> 00:06:07,759 be it your Mac or your PC or even some 158 00:06:06,039 --> 00:06:10,080 server in the cloud and what I'm going 159 00:06:07,759 --> 00:06:11,919 to do here is literally write code and 160 00:06:10,080 --> 00:06:13,639 then the name of the file that I want to 161 00:06:11,919 --> 00:06:16,199 code for instance 162 00:06:13,639 --> 00:06:18,039 hello.py as we'll soon see any program 163 00:06:16,199 --> 00:06:20,639 that you write in Python generally has a 164 00:06:18,039 --> 00:06:22,199 file name that ends inp to indicate to 165 00:06:20,639 --> 00:06:24,360 the computer that it's indeed a program 166 00:06:22,199 --> 00:06:25,840 written in Python now you'll see here at 167 00:06:24,360 --> 00:06:28,039 the top of my screen I have a blinking 168 00:06:25,840 --> 00:06:29,800 cursor a line one which is where the 169 00:06:28,039 --> 00:06:31,680 very first line of my code is going to 170 00:06:29,800 --> 00:06:34,120 and then just a tab that reminds me of 171 00:06:31,680 --> 00:06:36,319 the name of this file hello.py and 172 00:06:34,120 --> 00:06:37,759 without even knowing much python I'm 173 00:06:36,319 --> 00:06:41,319 going to write my very first program 174 00:06:37,759 --> 00:06:45,240 here as follows print open parenthesis 175 00:06:41,319 --> 00:06:47,280 quote hello comma World close quote and 176 00:06:45,240 --> 00:06:48,800 close parenthesis and you'll see that at 177 00:06:47,280 --> 00:06:50,560 my keyboard some of my thoughts were 178 00:06:48,800 --> 00:06:51,720 finished for me I only had to type one 179 00:06:50,560 --> 00:06:53,560 parenthesis and the other one 180 00:06:51,720 --> 00:06:55,479 automatically appeared and that's just a 181 00:06:53,560 --> 00:06:58,000 feature that we'll see of tools like 182 00:06:55,479 --> 00:07:00,240 this tool here now even if you've never 183 00:06:58,000 --> 00:07:03,039 programmed before odds already you can 184 00:07:00,240 --> 00:07:05,639 guess infer what this simple program is 185 00:07:03,039 --> 00:07:08,319 going to do and it's only one line print 186 00:07:05,639 --> 00:07:10,680 open parenthesis quote Hello World close 187 00:07:08,319 --> 00:07:12,039 quote close parenthesis indeed when I 188 00:07:10,680 --> 00:07:14,240 run this program ultimately it's just 189 00:07:12,039 --> 00:07:15,879 going to say hello to the world and in 190 00:07:14,240 --> 00:07:17,560 fact this is a very famous perhaps the 191 00:07:15,879 --> 00:07:19,199 most canonical program that you can 192 00:07:17,560 --> 00:07:20,800 write as your very first program in 193 00:07:19,199 --> 00:07:23,599 Python or any other language and so 194 00:07:20,800 --> 00:07:26,000 that's what I've done here but on my Mac 195 00:07:23,599 --> 00:07:28,039 my PC even my phone I'm generally in the 196 00:07:26,000 --> 00:07:29,840 habit like you of running programs by 197 00:07:28,039 --> 00:07:32,639 double clicking an icon or just tapping 198 00:07:29,840 --> 00:07:34,639 on the screen but I see no such icons 199 00:07:32,639 --> 00:07:36,879 here and in fact that's because my 200 00:07:34,639 --> 00:07:39,000 interface to at least my current Mac or 201 00:07:36,879 --> 00:07:41,879 PC or some server in the cloud is again 202 00:07:39,000 --> 00:07:43,240 only a CLI command line interface which 203 00:07:41,879 --> 00:07:45,479 even though it might feel like it's a 204 00:07:43,240 --> 00:07:46,919 step back from the menus and buttons and 205 00:07:45,479 --> 00:07:48,960 icons that you and I take for granted 206 00:07:46,919 --> 00:07:50,479 every day you'll find we think that it's 207 00:07:48,960 --> 00:07:52,800 ultimately a much more powerful 208 00:07:50,479 --> 00:07:55,120 interface and Incredibly popular to use 209 00:07:52,800 --> 00:07:57,159 among programmers in the real world so 210 00:07:55,120 --> 00:07:58,960 to run this program I'm going to have to 211 00:07:57,159 --> 00:08:00,800 use a command and I'm going to move my 212 00:07:58,960 --> 00:08:02,680 cursor back down to the bottom of the 213 00:08:00,800 --> 00:08:05,280 screen here where previously I already 214 00:08:02,680 --> 00:08:07,759 ran one command the command code which 215 00:08:05,280 --> 00:08:09,759 has the effect of opening vs code in my 216 00:08:07,759 --> 00:08:12,080 computer and then I passed in the name 217 00:08:09,759 --> 00:08:13,879 of the file that I wanted to code up now 218 00:08:12,080 --> 00:08:15,680 I have a chance to type a second command 219 00:08:13,879 --> 00:08:17,280 and you'll see I see a second dollar 220 00:08:15,680 --> 00:08:19,479 sign now the dollar sign here doesn't 221 00:08:17,280 --> 00:08:21,120 indicate any kind of currency or money 222 00:08:19,479 --> 00:08:23,080 it just is the symbol that's generally 223 00:08:21,120 --> 00:08:25,080 used to indicate your prompt where the 224 00:08:23,080 --> 00:08:27,720 command line interface wants you to put 225 00:08:25,080 --> 00:08:29,919 those commands now the command I can run 226 00:08:27,720 --> 00:08:32,440 here is going to be this I'm going to 227 00:08:29,919 --> 00:08:35,039 run python of 228 00:08:32,440 --> 00:08:37,039 hello.py now why is that well it turns 229 00:08:35,039 --> 00:08:39,039 out that when I actually write code in a 230 00:08:37,039 --> 00:08:42,279 language like python it's of course 231 00:08:39,039 --> 00:08:45,160 stored in that file hello.py but I need 232 00:08:42,279 --> 00:08:46,640 to interpret the code top to bottom left 233 00:08:45,160 --> 00:08:48,360 to right so that the computer knows what 234 00:08:46,640 --> 00:08:49,600 to do indeed at the end of the day even 235 00:08:48,360 --> 00:08:51,240 if you don't really know much about 236 00:08:49,600 --> 00:08:53,760 computers you've probably heard that 237 00:08:51,240 --> 00:08:56,040 computers only understand zeros and one 238 00:08:53,760 --> 00:08:58,240 the so-called binary system well if 239 00:08:56,040 --> 00:09:00,680 that's the case then something that says 240 00:08:58,240 --> 00:09:03,440 print and parenthe is and quote unquote 241 00:09:00,680 --> 00:09:05,120 hello world is not surely zeros and ones 242 00:09:03,440 --> 00:09:06,600 we have to somehow translate it into the 243 00:09:05,120 --> 00:09:08,760 zeros and ones that the computer 244 00:09:06,600 --> 00:09:10,680 understands now fortunately so long as 245 00:09:08,760 --> 00:09:13,000 you've installed such a program in 246 00:09:10,680 --> 00:09:15,399 advance there's a program as well as a 247 00:09:13,000 --> 00:09:16,800 language called python so python is not 248 00:09:15,399 --> 00:09:19,120 only a language in which we're going to 249 00:09:16,800 --> 00:09:21,360 write code it's also a program Otherwise 250 00:09:19,120 --> 00:09:23,440 Known As an interpreter that you install 251 00:09:21,360 --> 00:09:25,560 for free on your own Mac or PC or some 252 00:09:23,440 --> 00:09:28,279 server in the cloud and you can then run 253 00:09:25,560 --> 00:09:30,200 that program that interpreter passing to 254 00:09:28,279 --> 00:09:33,040 it as input the name of your file like 255 00:09:30,200 --> 00:09:34,880 mine here hello.py and then that program 256 00:09:33,040 --> 00:09:36,880 that interpreter will handle the process 257 00:09:34,880 --> 00:09:38,880 of reading it top to bottom left to 258 00:09:36,880 --> 00:09:40,519 right and translating it effectively 259 00:09:38,880 --> 00:09:43,040 into those zeros and ones that the 260 00:09:40,519 --> 00:09:45,480 computer can understand so let's do just 261 00:09:43,040 --> 00:09:47,800 that let me go back to vs code here I 262 00:09:45,480 --> 00:09:49,959 already typed out python of hello.py but 263 00:09:47,800 --> 00:09:51,680 I didn't get hit enter and that's what's 264 00:09:49,959 --> 00:09:53,800 now going to kick off this command and 265 00:09:51,680 --> 00:09:56,920 hopefully if I didn't mess any of this 266 00:09:53,800 --> 00:10:00,720 up I should see my very first program's 267 00:09:56,920 --> 00:10:03,279 output to the screen and voila hello 268 00:10:00,720 --> 00:10:05,519 world so if you two have typed exactly 269 00:10:03,279 --> 00:10:07,600 that same code and have executed exactly 270 00:10:05,519 --> 00:10:10,120 that same command you will have written 271 00:10:07,600 --> 00:10:12,200 your very first program in this case in 272 00:10:10,120 --> 00:10:14,320 Python well now let's take a step back 273 00:10:12,200 --> 00:10:15,959 and consider what is it that we actually 274 00:10:14,320 --> 00:10:17,560 just did and what is it we're looking 275 00:10:15,959 --> 00:10:19,079 here on the screen well first and 276 00:10:17,560 --> 00:10:20,480 foremost in most any programming 277 00:10:19,079 --> 00:10:22,560 language you tend to have access to what 278 00:10:20,480 --> 00:10:25,360 are called functions a function is like 279 00:10:22,560 --> 00:10:27,480 an action or a verb that lets you do 280 00:10:25,360 --> 00:10:29,760 something in the program and generally 281 00:10:27,480 --> 00:10:31,959 speaking any language comes with some 282 00:10:29,760 --> 00:10:34,760 predetermined set of functions some very 283 00:10:31,959 --> 00:10:36,360 basic actions or verbs that the computer 284 00:10:34,760 --> 00:10:37,880 will already know how to do for you that 285 00:10:36,360 --> 00:10:40,880 the language really will know how to do 286 00:10:37,880 --> 00:10:42,959 for you and you the programmer the human 287 00:10:40,880 --> 00:10:45,360 can use those functions at will to get 288 00:10:42,959 --> 00:10:48,639 the computer to do those things now the 289 00:10:45,360 --> 00:10:50,800 program in question here hello.py is 290 00:10:48,639 --> 00:10:52,279 using one function and you can perhaps 291 00:10:50,800 --> 00:10:55,040 guess what it is that function is of 292 00:10:52,279 --> 00:10:57,040 course going to be this function print 293 00:10:55,040 --> 00:10:59,440 and that print function of course 294 00:10:57,040 --> 00:11:02,000 doesn't print some pre-ordained string 295 00:10:59,440 --> 00:11:04,560 of text that is to say it prints 296 00:11:02,000 --> 00:11:06,639 whatever it is you want it to print and 297 00:11:04,560 --> 00:11:08,240 here too do we have another piece of 298 00:11:06,639 --> 00:11:11,360 terminology in the world of programming 299 00:11:08,240 --> 00:11:14,000 namely arguments an argument is an input 300 00:11:11,360 --> 00:11:15,920 to a function that somehow influences 301 00:11:14,000 --> 00:11:17,680 Its Behavior the people who invented 302 00:11:15,920 --> 00:11:19,279 python of course didn't necessarily know 303 00:11:17,680 --> 00:11:21,399 what it is you and I are going to want 304 00:11:19,279 --> 00:11:23,000 to print to the screen so they designed 305 00:11:21,399 --> 00:11:25,240 this print function using these 306 00:11:23,000 --> 00:11:27,480 parentheses with the ability to take as 307 00:11:25,240 --> 00:11:30,000 input some string of text be it in 308 00:11:27,480 --> 00:11:31,800 English or any other human language that 309 00:11:30,000 --> 00:11:34,959 is what you want this function 310 00:11:31,800 --> 00:11:36,600 ultimately to print onto the screen and 311 00:11:34,959 --> 00:11:38,639 what is it that the program's ultimately 312 00:11:36,600 --> 00:11:40,639 doing on the screen well it's printing 313 00:11:38,639 --> 00:11:42,200 of course it's showing us hello world on 314 00:11:40,639 --> 00:11:43,880 the screen and that's generally in 315 00:11:42,200 --> 00:11:45,480 programming known as a side effect it 316 00:11:43,880 --> 00:11:46,760 can be visual it can be audio in this 317 00:11:45,480 --> 00:11:48,920 case it's something that appears on the 318 00:11:46,760 --> 00:11:50,880 screen and functions therefore can 319 00:11:48,920 --> 00:11:53,160 indeed have these side effects one of 320 00:11:50,880 --> 00:11:54,880 the things they can do as this verb or 321 00:11:53,160 --> 00:11:56,800 action is to display on the screen as a 322 00:11:54,880 --> 00:11:59,959 side effect something like those World 323 00:11:56,800 --> 00:12:01,959 words that we wanted hello world 324 00:11:59,959 --> 00:12:03,480 so that's my first program and you know 325 00:12:01,959 --> 00:12:05,360 I'm feeling pretty good everything 326 00:12:03,480 --> 00:12:06,760 worked as planned I didn't make any 327 00:12:05,360 --> 00:12:08,920 mistakes but honestly when you're 328 00:12:06,760 --> 00:12:10,320 learning how to program and even once 329 00:12:08,920 --> 00:12:12,519 you've learned how to program years 330 00:12:10,320 --> 00:12:14,920 later you're going to make mistakes and 331 00:12:12,519 --> 00:12:16,320 those mistakes of course are refer to a 332 00:12:14,920 --> 00:12:18,199 term you might already know which is 333 00:12:16,320 --> 00:12:20,440 that of a bug a bug is a mistake in a 334 00:12:18,199 --> 00:12:23,199 program and they can take so many forms 335 00:12:20,440 --> 00:12:24,920 and take comfort perhaps in knowing that 336 00:12:23,199 --> 00:12:26,680 over the coming weeks you're going to 337 00:12:24,920 --> 00:12:28,760 make so many mistakes you're going to 338 00:12:26,680 --> 00:12:31,920 have so many bugs in your code just like 339 00:12:28,760 --> 00:12:33,680 I did and just as I still do and those 340 00:12:31,920 --> 00:12:35,560 bugs themselves are just mistakes that 341 00:12:33,680 --> 00:12:37,240 are problems for you to solve and over 342 00:12:35,560 --> 00:12:39,600 the weeks to come we're going to give 343 00:12:37,240 --> 00:12:41,440 you a lot of tools both mental and 344 00:12:39,600 --> 00:12:43,160 Technical via which you can solve those 345 00:12:41,440 --> 00:12:44,519 problems but just don't get discouraged 346 00:12:43,160 --> 00:12:46,680 if when writing your program for the 347 00:12:44,519 --> 00:12:49,040 first time it doesn't even work that 348 00:12:46,680 --> 00:12:51,399 first time it will with time with 349 00:12:49,040 --> 00:12:53,440 practice and with experience so let me 350 00:12:51,399 --> 00:12:55,360 deliberately now make a mistake that 351 00:12:53,440 --> 00:12:57,160 there was a nonzero chance I might have 352 00:12:55,360 --> 00:12:59,800 done accidentally already but I got 353 00:12:57,160 --> 00:13:01,680 lucky let me go ahead and just suppose I 354 00:12:59,800 --> 00:13:03,720 forgot to include something like the 355 00:13:01,680 --> 00:13:05,880 closing parenthesis at the end of this 356 00:13:03,720 --> 00:13:08,600 line of code you know the code is almost 357 00:13:05,880 --> 00:13:10,040 correct it's like 99% of the way there 358 00:13:08,600 --> 00:13:11,639 but now that I've pointed it out it's 359 00:13:10,040 --> 00:13:14,079 pretty obvious that it's missing that 360 00:13:11,639 --> 00:13:16,519 closed parenthesis but even little 361 00:13:14,079 --> 00:13:18,320 seemingly Minor Details like that that 362 00:13:16,519 --> 00:13:19,920 you and I as humans wouldn't really care 363 00:13:18,320 --> 00:13:21,880 about and if you're sending an email or 364 00:13:19,920 --> 00:13:24,079 a text message oh whatever it's just a 365 00:13:21,880 --> 00:13:25,560 typo it's not that big a deal it is 366 00:13:24,079 --> 00:13:27,199 going to be a big deal to the computer a 367 00:13:25,560 --> 00:13:29,000 computer is going to take you literally 368 00:13:27,199 --> 00:13:31,519 and if you don't finish your thought in 369 00:13:29,000 --> 00:13:33,519 the the way the language expects it's 370 00:13:31,519 --> 00:13:35,040 not going to necessarily run at all so 371 00:13:33,519 --> 00:13:36,800 let's do this I'm going to go ahead here 372 00:13:35,040 --> 00:13:38,480 and clear my screen down at the bottom 373 00:13:36,800 --> 00:13:40,519 just so I can start fresh and I'm going 374 00:13:38,480 --> 00:13:43,000 to go ahead and run this version of my 375 00:13:40,519 --> 00:13:44,800 program after having made that change by 376 00:13:43,000 --> 00:13:46,760 deleting the parenthesis I'm going to go 377 00:13:44,800 --> 00:13:49,440 ahead and type python again of 378 00:13:46,760 --> 00:13:51,240 hello.py and this time when I hit enter 379 00:13:49,440 --> 00:13:53,519 I'm hoping I'm going to see hello world 380 00:13:51,240 --> 00:13:57,000 but here we have an error on the screen 381 00:13:53,519 --> 00:13:59,320 a so-called syntax error which refers to 382 00:13:57,000 --> 00:14:01,199 my having made a mistake at my keyboard 383 00:13:59,320 --> 00:14:03,480 and it this one fortunately is pretty 384 00:14:01,199 --> 00:14:07,240 straightforward it indeed says that this 385 00:14:03,480 --> 00:14:09,240 open parenthesis was never closed and so 386 00:14:07,240 --> 00:14:10,639 that's probably pretty intuitive now 387 00:14:09,240 --> 00:14:12,639 what I need to do I need of course to 388 00:14:10,639 --> 00:14:14,160 close it unfortunately sometimes the 389 00:14:12,639 --> 00:14:15,800 error messages we'll see in the coming 390 00:14:14,160 --> 00:14:17,959 weeks are not going to be nearly that 391 00:14:15,800 --> 00:14:19,920 userfriendly but there too again with 392 00:14:17,959 --> 00:14:22,680 experience with practice will you get 393 00:14:19,920 --> 00:14:24,160 better at debugging such programs let me 394 00:14:22,680 --> 00:14:25,959 now make sure that I indeed fixed it 395 00:14:24,160 --> 00:14:28,680 correctly let me go ahead run now 396 00:14:25,959 --> 00:14:31,199 hello.py and hit enter and voila we're 397 00:14:28,680 --> 00:14:33,440 back in business well let me pause here 398 00:14:31,199 --> 00:14:36,120 and see if we have any questions now 399 00:14:33,440 --> 00:14:39,360 about python itself writing or running 400 00:14:36,120 --> 00:14:42,320 even the simplest of these 401 00:14:39,360 --> 00:14:45,399 programs uh could I write code inside a 402 00:14:42,320 --> 00:14:48,240 word or for example Microsoft Excel and 403 00:14:45,399 --> 00:14:50,040 what's the barrier to doing that a 404 00:14:48,240 --> 00:14:52,199 really good question and allow me to 405 00:14:50,040 --> 00:14:54,680 very explicitly say to the entire 406 00:14:52,199 --> 00:14:56,800 internet that you should not write code 407 00:14:54,680 --> 00:14:58,680 with Microsoft Word I mention that only 408 00:14:56,800 --> 00:15:00,399 because it's a tool via which you can 409 00:14:58,680 --> 00:15:02,199 write text and code is at the end of the 410 00:15:00,399 --> 00:15:03,720 day just text but it's not the right 411 00:15:02,199 --> 00:15:05,639 tool for the job we don't need bold 412 00:15:03,720 --> 00:15:07,320 facing underlining paragraphs and the 413 00:15:05,639 --> 00:15:09,199 like we generally want something much 414 00:15:07,320 --> 00:15:11,880 simpler than Microsoft Word or Google 415 00:15:09,199 --> 00:15:14,079 Docs and so VSS code is an example of 416 00:15:11,880 --> 00:15:15,880 just a more general purpose text editor 417 00:15:14,079 --> 00:15:18,240 its purpose in life is to allow you the 418 00:15:15,880 --> 00:15:20,199 human to edit text nowadays these text 419 00:15:18,240 --> 00:15:22,160 editors come with many more features in 420 00:15:20,199 --> 00:15:24,240 fact you'll notice that even in my code 421 00:15:22,160 --> 00:15:26,000 here even though it's just one line 422 00:15:24,240 --> 00:15:28,040 there's a bit of color to it the word 423 00:15:26,000 --> 00:15:29,880 print for me is appearing in blue the 424 00:15:28,040 --> 00:15:31,399 parentheses are black and we'll see as 425 00:15:29,880 --> 00:15:33,319 we might write more lines of code more 426 00:15:31,399 --> 00:15:35,880 and more of the lines will come to life 427 00:15:33,319 --> 00:15:37,639 in various colors now that's just one 428 00:15:35,880 --> 00:15:39,079 feature of a text editor we'll see too 429 00:15:37,639 --> 00:15:40,440 that it has features like this built-in 430 00:15:39,079 --> 00:15:42,720 terminal window it's going to have a 431 00:15:40,440 --> 00:15:44,560 built-in tool for debugging or finding 432 00:15:42,720 --> 00:15:46,480 problems with code and it's just a very 433 00:15:44,560 --> 00:15:48,120 popular tool nowadays but there are many 434 00:15:46,480 --> 00:15:50,160 many others out there you're welcome to 435 00:15:48,120 --> 00:15:51,880 use them for this course and Beyond we 436 00:15:50,160 --> 00:15:53,759 just happen to use this one in large 437 00:15:51,880 --> 00:15:56,959 part too because you can also use vs 438 00:15:53,759 --> 00:15:58,319 code nowadays uh for free in the cloud 439 00:15:56,959 --> 00:16:01,319 how about one other question here on 440 00:15:58,319 --> 00:16:03,800 programming with python or hello world 441 00:16:01,319 --> 00:16:05,480 or syntax more generally I was trying to 442 00:16:03,800 --> 00:16:07,839 ask 443 00:16:05,480 --> 00:16:10,279 if is not possible to run the code 444 00:16:07,839 --> 00:16:12,360 without using the terminal window I 445 00:16:10,279 --> 00:16:14,680 think I heard is it not if it's possible 446 00:16:12,360 --> 00:16:17,279 to run the program without the terminal 447 00:16:14,680 --> 00:16:19,079 window are you yes sir okay you froze 448 00:16:17,279 --> 00:16:21,279 for me again but let me infer what the 449 00:16:19,079 --> 00:16:23,279 question is so in this environment as 450 00:16:21,279 --> 00:16:25,399 I've configured my computer I can only 451 00:16:23,279 --> 00:16:27,360 run these python programs via the 452 00:16:25,399 --> 00:16:29,279 terminal window now that's good for me 453 00:16:27,360 --> 00:16:30,880 the programmer or the person who's 454 00:16:29,279 --> 00:16:32,600 trying to learn how to program but it's 455 00:16:30,880 --> 00:16:34,240 not very good if you want to ship this 456 00:16:32,600 --> 00:16:37,199 software and have other people use your 457 00:16:34,240 --> 00:16:39,240 actual code you can absolutely write 458 00:16:37,199 --> 00:16:41,079 programs and then allow other people to 459 00:16:39,240 --> 00:16:44,000 use not a command line interface but a 460 00:16:41,079 --> 00:16:46,160 graphical user interface or guey GUI 461 00:16:44,000 --> 00:16:47,839 this is just one mechanism and perhaps I 462 00:16:46,160 --> 00:16:49,720 think the the best one with which to 463 00:16:47,839 --> 00:16:52,120 start writing code because eventually 464 00:16:49,720 --> 00:16:53,639 it's going to give us a lot more control 465 00:16:52,120 --> 00:16:55,759 allow me to forge ahead here but please 466 00:16:53,639 --> 00:16:58,079 feel free to continue asking questions 467 00:16:55,759 --> 00:16:59,920 along the way if only via the chat let's 468 00:16:58,079 --> 00:17:02,319 consider now how we might go about 469 00:16:59,920 --> 00:17:03,720 improving this program let's go about 470 00:17:02,319 --> 00:17:06,160 improving this program to make it a 471 00:17:03,720 --> 00:17:08,160 little more interactive and not just 472 00:17:06,160 --> 00:17:09,919 assume that everyone is going to want to 473 00:17:08,160 --> 00:17:11,360 be greeted more generically as hello 474 00:17:09,919 --> 00:17:12,760 world let's see if I can't get this 475 00:17:11,360 --> 00:17:15,319 program to say something like hello 476 00:17:12,760 --> 00:17:18,439 David or hello Jeremiah or hello Horatio 477 00:17:15,319 --> 00:17:20,079 or whatever the actual user's name is 478 00:17:18,439 --> 00:17:22,559 well to do this I'm going to go back up 479 00:17:20,079 --> 00:17:24,520 to hello.py and I'm going to add another 480 00:17:22,559 --> 00:17:28,000 line of code at the very top that simply 481 00:17:24,520 --> 00:17:30,120 says for instance uh what's your name 482 00:17:28,000 --> 00:17:32,039 quote unquote with an extra space at the 483 00:17:30,120 --> 00:17:33,799 end so I'm printing to the user asking 484 00:17:32,039 --> 00:17:35,799 them a question for some input but now I 485 00:17:33,799 --> 00:17:38,440 need another function to actually get 486 00:17:35,799 --> 00:17:40,600 input from the user and perfectly enough 487 00:17:38,440 --> 00:17:42,240 python comes with a function named input 488 00:17:40,600 --> 00:17:45,679 so here I'm going to go ahead and call a 489 00:17:42,240 --> 00:17:47,360 function input open pen close pen and 490 00:17:45,679 --> 00:17:49,320 that's going to prompt the user with 491 00:17:47,360 --> 00:17:51,400 just a blinking cursor waiting for them 492 00:17:49,320 --> 00:17:53,320 to type something in now it turns out if 493 00:17:51,400 --> 00:17:55,600 I read the documentation for the input 494 00:17:53,320 --> 00:17:57,480 function it actually takes an argument 495 00:17:55,600 --> 00:17:59,440 itself I don't need to use print 496 00:17:57,480 --> 00:18:01,320 separately and then promp the user for 497 00:17:59,440 --> 00:18:03,520 input so I can actually simplify this 498 00:18:01,320 --> 00:18:05,600 code before we even use it I'm going to 499 00:18:03,520 --> 00:18:08,039 go ahead here and take that same string 500 00:18:05,600 --> 00:18:09,919 from print put it as an argument to the 501 00:18:08,039 --> 00:18:11,320 input function and get rid of the print 502 00:18:09,919 --> 00:18:12,840 alt together and in fact that print 503 00:18:11,320 --> 00:18:14,600 would have added a new line anyway so 504 00:18:12,840 --> 00:18:15,720 now I've just got a prompt where the 505 00:18:14,600 --> 00:18:17,320 user's cursor is going to end up 506 00:18:15,720 --> 00:18:19,880 blinking at the end of the line asking 507 00:18:17,320 --> 00:18:22,880 them what's your name in my terminal 508 00:18:19,880 --> 00:18:25,679 window I'm going to run python of 509 00:18:22,880 --> 00:18:27,240 hello.py enter okay we're making 510 00:18:25,679 --> 00:18:29,240 progress it seems that this new function 511 00:18:27,240 --> 00:18:30,480 input is indeed prompting me the human 512 00:18:29,240 --> 00:18:33,159 for input so I'm going to type in my 513 00:18:30,480 --> 00:18:35,080 name David and hit enter unfortunately 514 00:18:33,159 --> 00:18:37,360 it doesn't really do anything with my 515 00:18:35,080 --> 00:18:39,320 name it just outputs it immediately all 516 00:18:37,360 --> 00:18:41,320 right well I could fix this right I 517 00:18:39,320 --> 00:18:44,200 could go up to line two and I could 518 00:18:41,320 --> 00:18:46,559 change world to David and then back in 519 00:18:44,200 --> 00:18:49,840 my terminal window here I can do python 520 00:18:46,559 --> 00:18:51,919 of hello.py enter what's your name David 521 00:18:49,840 --> 00:18:54,280 enter and there we go all right now I'm 522 00:18:51,919 --> 00:18:57,760 up and running now my program is working 523 00:18:54,280 --> 00:18:59,799 as intended of course this isn't really 524 00:18:57,760 --> 00:19:01,760 working as intend Ed here let me go 525 00:18:59,799 --> 00:19:03,880 ahead and try pretending to be my 526 00:19:01,760 --> 00:19:05,480 colleague Carter here well Carter's name 527 00:19:03,880 --> 00:19:06,799 is this I'm going to go ahead and hit 528 00:19:05,480 --> 00:19:08,919 enter and I'll see of course hello 529 00:19:06,799 --> 00:19:10,960 Carter well obviously not because I've 530 00:19:08,919 --> 00:19:13,039 hardcoded so to speak I've written 531 00:19:10,960 --> 00:19:15,159 literally my name inside of the string 532 00:19:13,039 --> 00:19:18,039 so we need some way now of actually 533 00:19:15,159 --> 00:19:19,760 getting back what the user's input is 534 00:19:18,039 --> 00:19:20,840 and doing something with It ultimately 535 00:19:19,760 --> 00:19:23,080 and for this we're going to leverage 536 00:19:20,840 --> 00:19:24,960 another feature of programming 537 00:19:23,080 --> 00:19:26,679 specifically a feature of some functions 538 00:19:24,960 --> 00:19:29,520 which is that they can have return 539 00:19:26,679 --> 00:19:31,520 values as well if you think of input as 540 00:19:29,520 --> 00:19:33,320 being again this action this verb you 541 00:19:31,520 --> 00:19:34,880 can actually personify it as maybe a 542 00:19:33,320 --> 00:19:36,360 person like a friend of yours that 543 00:19:34,880 --> 00:19:38,000 you've asked a question of and you've 544 00:19:36,360 --> 00:19:39,679 asked your friend to go get input from 545 00:19:38,000 --> 00:19:41,760 someone else go ask that person their 546 00:19:39,679 --> 00:19:43,840 name and if your friend comes back 547 00:19:41,760 --> 00:19:46,280 knowing that person's name well wouldn't 548 00:19:43,840 --> 00:19:47,520 it be nice if they handed that name back 549 00:19:46,280 --> 00:19:49,200 to you that's kind of what we need 550 00:19:47,520 --> 00:19:51,280 metaphorically the function to do is get 551 00:19:49,200 --> 00:19:53,559 the user's input and then hand it back 552 00:19:51,280 --> 00:19:55,880 to me so that I the programmer can do 553 00:19:53,559 --> 00:19:57,960 something with it but if it's going to 554 00:19:55,880 --> 00:20:00,159 be handed back to me I kind of want to 555 00:19:57,960 --> 00:20:02,159 put it somewhere so that I can then 556 00:20:00,159 --> 00:20:03,440 print it back on the screen I need to do 557 00:20:02,159 --> 00:20:06,200 the equivalent of take out like a piece 558 00:20:03,440 --> 00:20:08,600 of paper or a Post-It note write down on 559 00:20:06,200 --> 00:20:11,200 this piece of paper what it is the human 560 00:20:08,600 --> 00:20:13,039 has said so that I can then feed it into 561 00:20:11,200 --> 00:20:14,159 as input that print function and to do 562 00:20:13,039 --> 00:20:17,080 that we're going to need one more 563 00:20:14,159 --> 00:20:18,880 feature of programming namely variables 564 00:20:17,080 --> 00:20:20,840 and odds are most everyone's familiar 565 00:20:18,880 --> 00:20:23,600 with variables from math class way back 566 00:20:20,840 --> 00:20:25,480 when X and Y and Z and the like well 567 00:20:23,600 --> 00:20:27,960 programming has that same capability 568 00:20:25,480 --> 00:20:29,720 this ability to create a variable in 569 00:20:27,960 --> 00:20:31,440 this case in the computer's memory not 570 00:20:29,720 --> 00:20:34,720 just on a piece of paper and that 571 00:20:31,440 --> 00:20:37,000 variable can store a value a number some 572 00:20:34,720 --> 00:20:39,159 text even an image or video or more a 573 00:20:37,000 --> 00:20:41,679 variable is just a container for some 574 00:20:39,159 --> 00:20:44,880 variable a variable is just a container 575 00:20:41,679 --> 00:20:46,880 for some value inside of a computer or 576 00:20:44,880 --> 00:20:49,480 inside of your own program so how do I 577 00:20:46,880 --> 00:20:50,760 go about expressing myself in this way 578 00:20:49,480 --> 00:20:52,200 well I think what I'm going to do is 579 00:20:50,760 --> 00:20:55,039 introduce a variable that's a little 580 00:20:52,200 --> 00:20:58,200 more interestingly named than x or y i i 581 00:20:55,039 --> 00:20:59,799 could just say this x equals input but 582 00:20:58,200 --> 00:21:01,840 I'm going to use a better name than a 583 00:20:59,799 --> 00:21:03,320 typical mathematical variable here and 584 00:21:01,840 --> 00:21:05,320 I'm going to literally call my variable 585 00:21:03,320 --> 00:21:06,760 name why well in programming because I 586 00:21:05,320 --> 00:21:08,440 have a whole keyboard in front of me I 587 00:21:06,760 --> 00:21:11,039 can use more descriptive terms to 588 00:21:08,440 --> 00:21:12,440 describe what it is I'm writing and now 589 00:21:11,039 --> 00:21:14,559 though there's an opportunity to 590 00:21:12,440 --> 00:21:16,960 consider a specific piece of syntax 591 00:21:14,559 --> 00:21:18,679 we've seen parentheses we've seen quotes 592 00:21:16,960 --> 00:21:22,039 all of which are necessary when passing 593 00:21:18,679 --> 00:21:24,760 inputs to a function but this equal sign 594 00:21:22,039 --> 00:21:27,320 here that's in between input on the 595 00:21:24,760 --> 00:21:29,320 right and name on the left is actually 596 00:21:27,320 --> 00:21:31,080 important and it's technically not an 597 00:21:29,320 --> 00:21:34,200 equal sign per se it doesn't mean 598 00:21:31,080 --> 00:21:36,279 equality as much as it means assignment 599 00:21:34,200 --> 00:21:38,480 so in Python and many programming 600 00:21:36,279 --> 00:21:40,360 languages a single equal sign is the 601 00:21:38,480 --> 00:21:42,840 assignment operator and what that means 602 00:21:40,360 --> 00:21:45,760 specifically is that you want to assign 603 00:21:42,840 --> 00:21:48,960 from right to left whatever the user's 604 00:21:45,760 --> 00:21:52,080 input is so the equal sign copies from 605 00:21:48,960 --> 00:21:54,679 the right to the left whatever the 606 00:21:52,080 --> 00:21:57,039 return value of the function on the 607 00:21:54,679 --> 00:21:58,799 right is so again the input function 608 00:21:57,039 --> 00:22:00,279 clearly gets input from the user that's 609 00:21:58,799 --> 00:22:03,120 why I was able to type my name or 610 00:22:00,279 --> 00:22:06,320 Carter's but it also sort of behind the 611 00:22:03,120 --> 00:22:08,520 scenes hands that value that return 612 00:22:06,320 --> 00:22:10,520 value back to me the programmer and if I 613 00:22:08,520 --> 00:22:13,159 use an equal sign in a variable no 614 00:22:10,520 --> 00:22:16,000 matter what I call it I can store that 615 00:22:13,159 --> 00:22:17,760 input in that variable so is to reuse it 616 00:22:16,000 --> 00:22:19,799 later so now sitting in the computer's 617 00:22:17,760 --> 00:22:22,640 memory somewhere is a container 618 00:22:19,799 --> 00:22:24,279 containing David quote unquote or Carter 619 00:22:22,640 --> 00:22:26,679 quote unquote or whatever the human has 620 00:22:24,279 --> 00:22:30,240 typed in but here it's easy to make a 621 00:22:26,679 --> 00:22:33,799 mistake suppose I decide to try to print 622 00:22:30,240 --> 00:22:36,120 that name and so I I kind of on a hunch 623 00:22:33,799 --> 00:22:38,520 type in this hello comma name just kind 624 00:22:36,120 --> 00:22:40,279 of plugging in the name of the variable 625 00:22:38,520 --> 00:22:41,039 well let me go ahead here and run python 626 00:22:40,279 --> 00:22:43,960 of 627 00:22:41,039 --> 00:22:45,600 hello.py and hit enter that's going to 628 00:22:43,960 --> 00:22:48,480 prompt me for my name and let me type in 629 00:22:45,600 --> 00:22:50,440 my name daid but I haven't hit enter yet 630 00:22:48,480 --> 00:22:53,720 and perhaps via the chat what's going to 631 00:22:50,440 --> 00:22:56,880 happen here when I now hit enter I'm 632 00:22:53,720 --> 00:22:59,320 hoping it says hello David I'd be okay 633 00:22:56,880 --> 00:23:01,200 if it says hello world but I don't want 634 00:22:59,320 --> 00:23:03,480 it to say what it's actually G to say 635 00:23:01,200 --> 00:23:04,480 and yep what we're seeing in the chat is 636 00:23:03,480 --> 00:23:07,440 well it's probably going to say 637 00:23:04,480 --> 00:23:09,640 literally hello comma name so that's not 638 00:23:07,440 --> 00:23:11,840 quite right so we need another way of 639 00:23:09,640 --> 00:23:15,039 printing out the value inside of that 640 00:23:11,840 --> 00:23:16,279 variable rather than just this word name 641 00:23:15,039 --> 00:23:18,080 well let me try this in a couple of 642 00:23:16,279 --> 00:23:20,480 different ways let me try this as 643 00:23:18,080 --> 00:23:22,080 follows let me go ahead and maybe undo 644 00:23:20,480 --> 00:23:24,039 this because I've gotten pretty good 645 00:23:22,080 --> 00:23:25,400 already at saying hello so let's let you 646 00:23:24,039 --> 00:23:26,440 know let's draw that Line in the Sand 647 00:23:25,400 --> 00:23:28,760 and just say all right let's get at 648 00:23:26,440 --> 00:23:30,960 least get hello comma out the door let's 649 00:23:28,760 --> 00:23:32,640 now print name and just on a hunch I'm 650 00:23:30,960 --> 00:23:33,960 going to try this I'm going to use print 651 00:23:32,640 --> 00:23:36,000 again because you can use these 652 00:23:33,960 --> 00:23:38,279 functions as many times as you need and 653 00:23:36,000 --> 00:23:40,720 I'm going to pass to the name to the 654 00:23:38,279 --> 00:23:42,880 print function the variable called name 655 00:23:40,720 --> 00:23:44,679 but notice I'm being a little clever now 656 00:23:42,880 --> 00:23:45,960 I'm not putting it in double quotes 657 00:23:44,679 --> 00:23:48,919 because we've seen already that double 658 00:23:45,960 --> 00:23:50,760 quotes means literally print out n m I'm 659 00:23:48,919 --> 00:23:53,760 getting rid of the quotes this time in 660 00:23:50,760 --> 00:23:56,960 hopes that now by passing the variable 661 00:23:53,760 --> 00:23:58,440 called name to the function called print 662 00:23:56,960 --> 00:24:01,080 it will in fact go about printing 663 00:23:58,440 --> 00:24:03,279 printing the contents of that variable 664 00:24:01,080 --> 00:24:05,440 that is its so-called value all right 665 00:24:03,279 --> 00:24:08,640 let's go ahead and do this here python 666 00:24:05,440 --> 00:24:11,080 of hello.py enter what's your name David 667 00:24:08,640 --> 00:24:14,919 and now crossing my finger still I see 668 00:24:11,080 --> 00:24:17,240 hello comma David all right so it's not 669 00:24:14,919 --> 00:24:19,159 the best program I'm I'm kind of cutting 670 00:24:17,240 --> 00:24:22,159 some Corners here so to speak I'm saying 671 00:24:19,159 --> 00:24:23,919 hello David on two separate lines so 672 00:24:22,159 --> 00:24:25,640 it's not as elegant it's not as pretty 673 00:24:23,919 --> 00:24:27,559 it's not as grammatically appropriate in 674 00:24:25,640 --> 00:24:29,320 English as just saying it all in one 675 00:24:27,559 --> 00:24:31,559 breath on one line but at least I've 676 00:24:29,320 --> 00:24:33,600 solved the problem just not very well 677 00:24:31,559 --> 00:24:35,080 yet but let me take a step back now and 678 00:24:33,600 --> 00:24:36,360 perhaps introduce a couple of other 679 00:24:35,080 --> 00:24:38,559 concepts with which we should be 680 00:24:36,360 --> 00:24:40,360 familiar which is as our programs get 681 00:24:38,559 --> 00:24:43,240 longer and they're no longer just one 682 00:24:40,360 --> 00:24:45,000 line or two or even three eventually our 683 00:24:43,240 --> 00:24:47,120 programs are going to become dozens of 684 00:24:45,000 --> 00:24:49,360 lines maybe even hundreds of lines long 685 00:24:47,120 --> 00:24:51,399 let's set the stage for Success moving 686 00:24:49,360 --> 00:24:53,240 forward it turns out that python and a 687 00:24:51,399 --> 00:24:55,320 lot of programming languages also 688 00:24:53,240 --> 00:24:58,679 support something called comments 689 00:24:55,320 --> 00:25:00,840 comments are notes to yourself in your 690 00:24:58,679 --> 00:25:02,520 code and you include comments by way of 691 00:25:00,840 --> 00:25:04,520 a special symbol in Python it's going to 692 00:25:02,520 --> 00:25:06,120 be the hash symbol typically and that 693 00:25:04,520 --> 00:25:07,919 allows you to write the equivalent of a 694 00:25:06,120 --> 00:25:09,559 note to yourself but in a way that's not 695 00:25:07,919 --> 00:25:11,919 going to break your code the computer 696 00:25:09,559 --> 00:25:13,520 actually ignores your comments it's just 697 00:25:11,919 --> 00:25:14,880 there for you it's just there for your 698 00:25:13,520 --> 00:25:16,600 teacher it's just there for your 699 00:25:14,880 --> 00:25:18,799 colleague with whom you're sharing 700 00:25:16,600 --> 00:25:20,760 ultimately that code so if I go back to 701 00:25:18,799 --> 00:25:23,000 VSS code here and I just want to add 702 00:25:20,760 --> 00:25:25,919 some comments to this program to explain 703 00:25:23,000 --> 00:25:27,880 to my teacher to myself to my colleagues 704 00:25:25,919 --> 00:25:29,279 what this program is doing well let's go 705 00:25:27,880 --> 00:25:32,120 ahead and do that I'm going to go at the 706 00:25:29,279 --> 00:25:33,960 very top of my program and on line one 707 00:25:32,120 --> 00:25:35,840 now I'm going to move that original line 708 00:25:33,960 --> 00:25:37,720 of code down a bit I'm going to add a 709 00:25:35,840 --> 00:25:41,600 hash and I'm going to say something like 710 00:25:37,720 --> 00:25:43,159 this uh ask user for their name now I 711 00:25:41,600 --> 00:25:45,120 don't have to use that language I don't 712 00:25:43,159 --> 00:25:46,919 have to use that uh that text I could 713 00:25:45,120 --> 00:25:49,159 use any human language whatsoever it 714 00:25:46,919 --> 00:25:51,559 doesn't have to be English but I'm going 715 00:25:49,159 --> 00:25:54,360 to now below that just say something 716 00:25:51,559 --> 00:25:55,960 like this say hello to user and you'll 717 00:25:54,360 --> 00:25:57,679 notice that vs code by default is kind 718 00:25:55,960 --> 00:25:59,240 of graying out my comments they're no 719 00:25:57,679 --> 00:26:00,760 longer blue there's no red there's no 720 00:25:59,240 --> 00:26:03,000 color in them and that's just because 721 00:26:00,760 --> 00:26:05,000 they're notes to myself and the computer 722 00:26:03,000 --> 00:26:07,039 ultimately is going to ignore them but 723 00:26:05,000 --> 00:26:08,840 what we have now is two comments ask 724 00:26:07,039 --> 00:26:11,000 user for their name and then a second 725 00:26:08,840 --> 00:26:13,640 comment say hello to user and I've just 726 00:26:11,000 --> 00:26:16,679 kind of commented each chunk of code 727 00:26:13,640 --> 00:26:18,960 like each line or lines plural of code 728 00:26:16,679 --> 00:26:20,799 that are doing something noteworthy why 729 00:26:18,960 --> 00:26:23,159 well tomorrow morning when I wake up 730 00:26:20,799 --> 00:26:25,039 having you know uh uh slept for quite 731 00:26:23,159 --> 00:26:26,760 some time forgotten what it is I did the 732 00:26:25,039 --> 00:26:28,760 previous day it's convenient with 733 00:26:26,760 --> 00:26:31,240 comments to just see in English or your 734 00:26:28,760 --> 00:26:32,640 own human language what it is this 735 00:26:31,240 --> 00:26:35,120 program is doing so that you don't have 736 00:26:32,640 --> 00:26:37,279 to read the code itself and better yet 737 00:26:35,120 --> 00:26:39,760 if there's maybe a mistake down the road 738 00:26:37,279 --> 00:26:41,120 you can read what your intention was and 739 00:26:39,760 --> 00:26:43,399 then you can look at the code and figure 740 00:26:41,120 --> 00:26:45,520 out if your codee's now doing what you 741 00:26:43,399 --> 00:26:47,440 intended so this isn't really necessary 742 00:26:45,520 --> 00:26:49,120 for a program this small it's pretty 743 00:26:47,440 --> 00:26:50,720 obvious with just one or two or three 744 00:26:49,120 --> 00:26:52,159 lines what the program is doing it's 745 00:26:50,720 --> 00:26:54,080 just as fast to read the code than the 746 00:26:52,159 --> 00:26:55,760 comments but getting into this habit is 747 00:26:54,080 --> 00:26:58,480 generally a good thing to comment your 748 00:26:55,760 --> 00:27:00,200 code every one or few lines so is to 749 00:26:58,480 --> 00:27:02,440 remind yourself and others what it is 750 00:27:00,200 --> 00:27:04,799 your intent and your code is doing 751 00:27:02,440 --> 00:27:07,200 what's nice about comments too is this 752 00:27:04,799 --> 00:27:09,360 comments can also serve to be sort of a 753 00:27:07,200 --> 00:27:11,799 to-do list for yourself there's this 754 00:27:09,360 --> 00:27:13,559 notion in uh programming of pseudo code 755 00:27:11,799 --> 00:27:15,840 pseudo code isn't a formal thing it's 756 00:27:13,559 --> 00:27:18,159 not one specific language it's just 757 00:27:15,840 --> 00:27:20,840 using English or your own human language 758 00:27:18,159 --> 00:27:23,640 to express your thoughts succinctly 759 00:27:20,840 --> 00:27:25,200 methodically algorithmically so to speak 760 00:27:23,640 --> 00:27:27,279 but pseudo code therefore because it's 761 00:27:25,200 --> 00:27:29,399 not Python and it's not necessarily 762 00:27:27,279 --> 00:27:31,600 English it just kind of allows you to 763 00:27:29,399 --> 00:27:34,559 outline your program even in advance so 764 00:27:31,600 --> 00:27:35,840 for instance if I wasn't sure today how 765 00:27:34,559 --> 00:27:38,000 I wanted to go about writing this 766 00:27:35,840 --> 00:27:40,240 program but I did know what I want to do 767 00:27:38,000 --> 00:27:43,760 I could have started today by just 768 00:27:40,240 --> 00:27:45,279 writing this in hello.py no code I could 769 00:27:43,760 --> 00:27:47,200 have written just a couple of comments 770 00:27:45,279 --> 00:27:50,039 to myself step one ask user for their 771 00:27:47,200 --> 00:27:52,080 name step two say hello to user then 772 00:27:50,039 --> 00:27:53,960 once I've outlined my program in pseudo 773 00:27:52,080 --> 00:27:55,519 code then I can go in there and say all 774 00:27:53,960 --> 00:27:57,519 right how do I ask the user for their 775 00:27:55,519 --> 00:27:59,399 name uh well I can do input quote 776 00:27:57,519 --> 00:28:01,519 unquote what what's your name question 777 00:27:59,399 --> 00:28:03,720 mark and then on the left here I can 778 00:28:01,519 --> 00:28:05,720 maybe put a variable and assign it to 779 00:28:03,720 --> 00:28:07,320 that okay how do I say hello to the user 780 00:28:05,720 --> 00:28:09,279 well I know I can use print to say 781 00:28:07,320 --> 00:28:11,559 things on the screen let me say hello 782 00:28:09,279 --> 00:28:13,960 comma uh and let me okay let me now 783 00:28:11,559 --> 00:28:15,720 print the person's name so again pseudo 784 00:28:13,960 --> 00:28:18,320 code is a nice way of structuring your 785 00:28:15,720 --> 00:28:20,080 to-do list especially if you have no 786 00:28:18,320 --> 00:28:23,000 idea how to write the code because it 787 00:28:20,080 --> 00:28:25,279 breaks a bigger program down into small 788 00:28:23,000 --> 00:28:26,360 bite-size tasks all right let me pause 789 00:28:25,279 --> 00:28:30,360 here to see if there are now any 790 00:28:26,360 --> 00:28:33,320 questions on comments pseudo code return 791 00:28:30,360 --> 00:28:36,279 values or 792 00:28:33,320 --> 00:28:38,960 variables any questions we can clear up 793 00:28:36,279 --> 00:28:42,080 here yeah my question is uh does the 794 00:28:38,960 --> 00:28:45,679 function input uh work for any type of 795 00:28:42,080 --> 00:28:47,399 of information or only for Words yeah 796 00:28:45,679 --> 00:28:49,039 really good question so according to its 797 00:28:47,399 --> 00:28:51,360 documentation and we'll look more at 798 00:28:49,039 --> 00:28:53,399 formal documentation soon input is going 799 00:28:51,360 --> 00:28:55,679 to expect what's called a string that is 800 00:28:53,399 --> 00:28:57,600 a sequence of text be it in English or 801 00:28:55,679 --> 00:28:59,799 any other human language but it's indeed 802 00:28:57,600 --> 00:29:02,480 going to be expecting text with which to 803 00:28:59,799 --> 00:29:03,840 prompt the user a good question how 804 00:29:02,480 --> 00:29:07,240 about another question from the group if 805 00:29:03,840 --> 00:29:09,679 we could I wanted to ask how I make 806 00:29:07,240 --> 00:29:11,559 several line comment oh how do you do 807 00:29:09,679 --> 00:29:14,799 many lines of comments if if I'm hearing 808 00:29:11,559 --> 00:29:16,760 you correctly sure uh you would just 809 00:29:14,799 --> 00:29:19,600 keep doing them like this you just 810 00:29:16,760 --> 00:29:21,840 prefix each of the lines with a hash 811 00:29:19,600 --> 00:29:24,039 symbol like I'm doing here there is 812 00:29:21,840 --> 00:29:25,720 another technique for doing multi-line 813 00:29:24,039 --> 00:29:27,760 comments in Python that actually tend to 814 00:29:25,720 --> 00:29:29,880 have special meaning you can do three 815 00:29:27,760 --> 00:29:33,000 double quotes like this and then 816 00:29:29,880 --> 00:29:34,440 anything in between here is a comment 817 00:29:33,000 --> 00:29:36,679 that's another technique or you can use 818 00:29:34,440 --> 00:29:39,039 single quotes as well but more on those 819 00:29:36,679 --> 00:29:40,559 I think another time all right well if 820 00:29:39,039 --> 00:29:42,279 you don't mind let me Forge ahead here 821 00:29:40,559 --> 00:29:44,399 and see how we might improve this 822 00:29:42,279 --> 00:29:45,919 program further and also introduce a few 823 00:29:44,399 --> 00:29:48,919 other features that we might want to 824 00:29:45,919 --> 00:29:50,760 take into account over time so it turns 825 00:29:48,919 --> 00:29:52,799 out that we can certainly improve on 826 00:29:50,760 --> 00:29:54,720 this program because it's a little 827 00:29:52,799 --> 00:29:56,840 disappointing that I'm cutting this 828 00:29:54,720 --> 00:29:59,120 corner and saying hello comma and then 829 00:29:56,840 --> 00:30:01,039 on a new line print out name like we can 830 00:29:59,120 --> 00:30:03,000 do better and most programs you use on 831 00:30:01,039 --> 00:30:05,120 your phone or your laptop certainly keep 832 00:30:03,000 --> 00:30:06,679 text together when people want so how 833 00:30:05,120 --> 00:30:08,480 can we go about doing that well there's 834 00:30:06,679 --> 00:30:10,320 a few different ways and in fact the 835 00:30:08,480 --> 00:30:11,760 goal here is not so much to solve this 836 00:30:10,320 --> 00:30:14,000 one problem but to demonstrate and 837 00:30:11,760 --> 00:30:16,320 emphasize that in programming Python and 838 00:30:14,000 --> 00:30:18,919 other languages there's so many ways 839 00:30:16,320 --> 00:30:20,919 sometimes to solve the same problem and 840 00:30:18,919 --> 00:30:23,720 here's one way to solve this problem let 841 00:30:20,919 --> 00:30:27,360 me go in here and let me go ahead now 842 00:30:23,720 --> 00:30:30,679 and say hello comma and let me just add 843 00:30:27,360 --> 00:30:32,640 to the end of that the user's name so 844 00:30:30,679 --> 00:30:34,960 I'm using Plus in kind of an interesting 845 00:30:32,640 --> 00:30:37,399 way this is not addition per se I'm not 846 00:30:34,960 --> 00:30:40,159 adding numbers obviously but I do kind 847 00:30:37,399 --> 00:30:43,320 of want to add the person's name to the 848 00:30:40,159 --> 00:30:45,120 string of text hello comma well let me 849 00:30:43,320 --> 00:30:48,120 go now down to my terminal window and 850 00:30:45,120 --> 00:30:49,440 run python of hello.py again enter 851 00:30:48,120 --> 00:30:53,240 what's your name I'm going to type in 852 00:30:49,440 --> 00:30:55,720 David enter okay it's better it's better 853 00:30:53,240 --> 00:30:57,639 but there's a minor bug albeit aesthetic 854 00:30:55,720 --> 00:30:59,159 here there's missing space but let's 855 00:30:57,639 --> 00:31:01,159 just use some intuition here well if I'm 856 00:30:59,159 --> 00:31:02,559 missing the space after the comma why 857 00:31:01,159 --> 00:31:05,120 don't I go ahead and just add it 858 00:31:02,559 --> 00:31:08,000 manually here let me now rerun the 859 00:31:05,120 --> 00:31:10,000 program python of hello.py enter David 860 00:31:08,000 --> 00:31:11,360 enter and there we go now we have 861 00:31:10,000 --> 00:31:13,600 something that looks a little prettier 862 00:31:11,360 --> 00:31:16,559 in terms of English grammar hello comma 863 00:31:13,600 --> 00:31:19,240 space David and now if we rewind you 864 00:31:16,559 --> 00:31:21,679 might have noticed before or wondered 865 00:31:19,240 --> 00:31:23,919 why I had this seemingly extra space 866 00:31:21,679 --> 00:31:25,600 after my question mark namely here 867 00:31:23,919 --> 00:31:27,159 there's a space after the question mark 868 00:31:25,600 --> 00:31:28,799 but before the double quote and that was 869 00:31:27,159 --> 00:31:31,440 just for Aesthetics to I wanted to move 870 00:31:28,799 --> 00:31:33,120 the user's cursor one space to the right 871 00:31:31,440 --> 00:31:34,600 so that when I type their name or they 872 00:31:33,120 --> 00:31:37,799 type their name it's not immediately 873 00:31:34,600 --> 00:31:39,919 next to that same question mark there 874 00:31:37,799 --> 00:31:42,320 but there's other ways we can do this it 875 00:31:39,919 --> 00:31:44,720 turns out that some functions print 876 00:31:42,320 --> 00:31:47,840 among them actually take multiple 877 00:31:44,720 --> 00:31:50,240 arguments and it turns out that if you 878 00:31:47,840 --> 00:31:52,080 separate the inputs to a function the 879 00:31:50,240 --> 00:31:54,200 so-called arguments to a function with a 880 00:31:52,080 --> 00:31:57,639 comma you can pass in not just one but 881 00:31:54,200 --> 00:32:00,039 two 3 four five onward so let me go 882 00:31:57,639 --> 00:32:03,919 ahead and pass in not just hello comma 883 00:32:00,039 --> 00:32:05,440 space but that followed by name and this 884 00:32:03,919 --> 00:32:06,760 is a little confusing potentially at 885 00:32:05,440 --> 00:32:08,559 first glance because now I've got two 886 00:32:06,760 --> 00:32:10,919 commas but it's important to note that 887 00:32:08,559 --> 00:32:13,960 the first comma is inside of my 888 00:32:10,919 --> 00:32:16,200 quotation marks which is uh simply an 889 00:32:13,960 --> 00:32:18,559 English grammatical thing the second 890 00:32:16,200 --> 00:32:20,960 comma here is outside of the quotes but 891 00:32:18,559 --> 00:32:23,120 between what are now two separate 892 00:32:20,960 --> 00:32:25,600 arguments to print the first argument is 893 00:32:23,120 --> 00:32:28,080 hello comma space the second argument is 894 00:32:25,600 --> 00:32:31,799 the name variable itself so let's see 895 00:32:28,080 --> 00:32:34,799 how this looks python of hello.py enter 896 00:32:31,799 --> 00:32:36,840 what's your name David enter okay I've 897 00:32:34,799 --> 00:32:38,679 kind of overcorrected now I've got two 898 00:32:36,840 --> 00:32:40,720 spaces for some reason well it turns out 899 00:32:38,679 --> 00:32:43,440 and this is subtle when you pass 900 00:32:40,720 --> 00:32:46,080 multiple arguments to print it 901 00:32:43,440 --> 00:32:48,120 automatically inserts a space for you 902 00:32:46,080 --> 00:32:51,919 this was not relevant earlier because I 903 00:32:48,120 --> 00:32:54,679 was passing in one big argument to print 904 00:32:51,919 --> 00:32:56,320 all at once by using that plus operator 905 00:32:54,679 --> 00:32:58,799 this time I'm passing in two because of 906 00:32:56,320 --> 00:33:01,200 the comma so if I don't want that extra 907 00:32:58,799 --> 00:33:03,480 space I don't need to pass in one myself 908 00:33:01,200 --> 00:33:05,320 I can just do this and now notice if I 909 00:33:03,480 --> 00:33:08,120 run this program again python of 910 00:33:05,320 --> 00:33:10,799 hello.py type in my name David now it 911 00:33:08,120 --> 00:33:12,440 looks grammatically like I might want 912 00:33:10,799 --> 00:33:14,880 now which of these approaches is better 913 00:33:12,440 --> 00:33:18,200 this approach uses a function print with 914 00:33:14,880 --> 00:33:20,679 two arguments hello comma and the name 915 00:33:18,200 --> 00:33:22,399 variable the previous version recall 916 00:33:20,679 --> 00:33:24,120 technically used one argument even 917 00:33:22,399 --> 00:33:25,600 though it looked a little curious It's 918 00:33:24,120 --> 00:33:27,440 one argument in the sense that the 919 00:33:25,600 --> 00:33:29,519 computer just like mathematicians are 920 00:33:27,440 --> 00:33:31,279 going to what's inside of parentheses 921 00:33:29,519 --> 00:33:34,519 first so if inside of parentheses you 922 00:33:31,279 --> 00:33:36,559 have this string of text hello comma and 923 00:33:34,519 --> 00:33:38,679 a space which I need to add back then 924 00:33:36,559 --> 00:33:41,440 you have a plus which means not addition 925 00:33:38,679 --> 00:33:42,919 per se but concatenation to join the 926 00:33:41,440 --> 00:33:45,600 thing on the left and the thing on the 927 00:33:42,919 --> 00:33:49,240 right this ultimately becomes the 928 00:33:45,600 --> 00:33:51,679 English phrase hello comma space David 929 00:33:49,240 --> 00:33:54,399 and then what's being passed ultimately 930 00:33:51,679 --> 00:33:56,120 to the function is technically something 931 00:33:54,399 --> 00:33:58,760 like this but it's doing it all 932 00:33:56,120 --> 00:34:01,240 dynamically it's not me typing in David 933 00:33:58,760 --> 00:34:03,639 as I I secretly as I discreetly did 934 00:34:01,240 --> 00:34:05,559 earlier it's figuring out dynamically 935 00:34:03,639 --> 00:34:07,880 what that value is after concatenating 936 00:34:05,559 --> 00:34:10,240 hello with the value of name and then 937 00:34:07,880 --> 00:34:12,760 passing that ultimately to print as the 938 00:34:10,240 --> 00:34:15,639 sole argument let me pause here to see 939 00:34:12,760 --> 00:34:18,280 if there's any questions on numbers of 940 00:34:15,639 --> 00:34:21,639 arguments now to 941 00:34:18,280 --> 00:34:23,879 functions can we use a function uh many 942 00:34:21,639 --> 00:34:26,040 times to solve a certain problem which 943 00:34:23,879 --> 00:34:28,399 we can encounter many times in our 944 00:34:26,040 --> 00:34:30,159 code you can you can can use a function 945 00:34:28,399 --> 00:34:32,200 many different times to solve some 946 00:34:30,159 --> 00:34:34,079 problem what we'll soon see though is if 947 00:34:32,200 --> 00:34:36,760 you find yourself as the programmer 948 00:34:34,079 --> 00:34:38,599 solving a problem the same way again and 949 00:34:36,760 --> 00:34:40,320 again and again it turns out you'll be 950 00:34:38,599 --> 00:34:42,359 able to make your own function so that 951 00:34:40,320 --> 00:34:45,560 you don't have to keep reusing the basic 952 00:34:42,359 --> 00:34:48,240 ones that come with the language I was 953 00:34:45,560 --> 00:34:51,320 curious about the comma and the plus 954 00:34:48,240 --> 00:34:53,359 sign so after plus sign can we give just 955 00:34:51,320 --> 00:34:55,679 one variable and after Comm again we 956 00:34:53,359 --> 00:34:57,920 give multiple variables like what is the 957 00:34:55,679 --> 00:35:00,320 difference a good question so in the 958 00:34:57,920 --> 00:35:02,240 context of strings and I keep using that 959 00:35:00,320 --> 00:35:03,800 term string is a technical term in a 960 00:35:02,240 --> 00:35:06,599 programming language and again it means 961 00:35:03,800 --> 00:35:09,680 a a sequence of text a character a word 962 00:35:06,599 --> 00:35:11,839 a whole paragraph even so the plus 963 00:35:09,680 --> 00:35:14,440 operator is not just used as we'll see 964 00:35:11,839 --> 00:35:17,000 for addition of numbers in Python like 965 00:35:14,440 --> 00:35:18,760 we do on paper pencil but it also is 966 00:35:17,000 --> 00:35:20,599 used for concatenation of strings on the 967 00:35:18,760 --> 00:35:22,640 left and the right if you did want to 968 00:35:20,599 --> 00:35:24,680 combine not just two strings left and 969 00:35:22,640 --> 00:35:27,839 right but a third and a fourth you can 970 00:35:24,680 --> 00:35:29,760 absolutely keep using plus plus plus 971 00:35:27,839 --> 00:35:31,680 plus and chain them together just like 972 00:35:29,760 --> 00:35:33,720 in math eventually that's going to start 973 00:35:31,680 --> 00:35:34,880 to look a little ugly I dare say 974 00:35:33,720 --> 00:35:36,839 especially if your line of code gets 975 00:35:34,880 --> 00:35:39,160 long so there's better ways that we'll 976 00:35:36,839 --> 00:35:41,359 actually soon see and a good question as 977 00:35:39,160 --> 00:35:43,520 well well let me come back to the code 978 00:35:41,359 --> 00:35:45,400 here in question and see if we can show 979 00:35:43,520 --> 00:35:46,960 you just a couple of other ways to solve 980 00:35:45,400 --> 00:35:48,520 the same problem along the way 981 00:35:46,960 --> 00:35:50,560 emphasizing that what we're technically 982 00:35:48,520 --> 00:35:52,200 talking about here yes are strings but 983 00:35:50,560 --> 00:35:55,000 there's even a technical term for these 984 00:35:52,200 --> 00:35:58,520 strings in Python it's just stir so to 985 00:35:55,000 --> 00:35:59,720 speak St for short for string as you may 986 00:35:58,520 --> 00:36:01,319 know if you programmed in other 987 00:35:59,720 --> 00:36:03,760 languages people who invent programming 988 00:36:01,319 --> 00:36:06,200 languages like to be very uh succinct to 989 00:36:03,760 --> 00:36:08,119 the point so we tend to use fairly short 990 00:36:06,200 --> 00:36:09,920 phrases to describe things not 991 00:36:08,119 --> 00:36:12,400 necessarily full words so while you 992 00:36:09,920 --> 00:36:14,079 might say string technically in Python 993 00:36:12,400 --> 00:36:16,359 what we're really talking about these 994 00:36:14,079 --> 00:36:19,040 sequences of text are technically stirs 995 00:36:16,359 --> 00:36:20,839 this is an actual type of data in a 996 00:36:19,040 --> 00:36:23,520 program but we'll soon see that there's 997 00:36:20,839 --> 00:36:25,680 other types of data in programs as well 998 00:36:23,520 --> 00:36:27,760 in fact let's see if we can't improve 999 00:36:25,680 --> 00:36:29,440 this in one other way I like the 1000 00:36:27,760 --> 00:36:31,280 progress we've made by keeping 1001 00:36:29,440 --> 00:36:34,200 everything on the same line hello comma 1002 00:36:31,280 --> 00:36:36,400 David all on the same line what more 1003 00:36:34,200 --> 00:36:38,440 though could we do in terms of solving 1004 00:36:36,400 --> 00:36:40,640 this problem well it turns out that we 1005 00:36:38,440 --> 00:36:42,920 didn't have to give up entirely with 1006 00:36:40,640 --> 00:36:45,480 using print twice let me rewind a little 1007 00:36:42,920 --> 00:36:47,160 bit and go back to that earlier version 1008 00:36:45,480 --> 00:36:49,599 where I wasn't really sure how to solve 1009 00:36:47,160 --> 00:36:50,960 this problem so I was using print once 1010 00:36:49,599 --> 00:36:52,760 to print out just the hello and the 1011 00:36:50,960 --> 00:36:55,839 space and the comma and then I used 1012 00:36:52,760 --> 00:36:58,560 print again to call uh to print name 1013 00:36:55,839 --> 00:37:00,480 that strictly speaking wasn't bad but 1014 00:36:58,560 --> 00:37:02,720 there was this visual side effect that I 1015 00:37:00,480 --> 00:37:04,520 just didn't like it just looked ugly to 1016 00:37:02,720 --> 00:37:06,480 have these two lines of text separate 1017 00:37:04,520 --> 00:37:09,160 from one another but there's another way 1018 00:37:06,480 --> 00:37:11,240 to fix this clearly it seems to be the 1019 00:37:09,160 --> 00:37:14,079 case that the print function is 1020 00:37:11,240 --> 00:37:15,920 automatically outputting a blank line 1021 00:37:14,079 --> 00:37:18,319 it's moving the cursor automatically for 1022 00:37:15,920 --> 00:37:20,599 me to the next line because that's why 1023 00:37:18,319 --> 00:37:22,280 I'm seeing hello on one line and David 1024 00:37:20,599 --> 00:37:24,800 on the next and then my prompt the 1025 00:37:22,280 --> 00:37:26,160 dollar sign on the line below that so 1026 00:37:24,800 --> 00:37:27,880 print seems to be presuming 1027 00:37:26,160 --> 00:37:29,800 automatically that you want it to move 1028 00:37:27,880 --> 00:37:31,480 the cursor to the next line after you 1029 00:37:29,800 --> 00:37:33,800 pass it some argument but you can 1030 00:37:31,480 --> 00:37:35,720 override that behavior again functions 1031 00:37:33,800 --> 00:37:37,400 take arguments which influence their 1032 00:37:35,720 --> 00:37:40,640 behavior you just have to know what 1033 00:37:37,400 --> 00:37:43,640 those arguments are and it turns out 1034 00:37:40,640 --> 00:37:46,160 that if we look at the documentation for 1035 00:37:43,640 --> 00:37:48,599 Python's print function we can actually 1036 00:37:46,160 --> 00:37:50,400 look up at this URL here docs. 1037 00:37:48,599 --> 00:37:52,880 python.org is where all of Python's 1038 00:37:50,400 --> 00:37:54,560 official documentation lies if I poke 1039 00:37:52,880 --> 00:37:56,880 around I can find my way to more 1040 00:37:54,560 --> 00:37:59,640 specifically this URL here where I can 1041 00:37:56,880 --> 00:38:01,920 find all of the available functions in 1042 00:37:59,640 --> 00:38:03,880 Python that and the documentation 1043 00:38:01,920 --> 00:38:05,720 therefore and if I go a little more 1044 00:38:03,880 --> 00:38:07,800 precisely I can even find specific 1045 00:38:05,720 --> 00:38:09,560 documentation for the print function 1046 00:38:07,800 --> 00:38:10,560 itself and rather than pull that up in a 1047 00:38:09,560 --> 00:38:12,839 browser I'm going to go ahead and 1048 00:38:10,560 --> 00:38:16,000 highlight just one line from that same 1049 00:38:12,839 --> 00:38:18,319 URL which is this and this is easily the 1050 00:38:16,000 --> 00:38:20,240 most cryptic thing we've seen yet but 1051 00:38:18,319 --> 00:38:21,960 this is the official documentation for 1052 00:38:20,240 --> 00:38:23,000 the print function and one of the best 1053 00:38:21,960 --> 00:38:24,720 things you can do when learning a 1054 00:38:23,000 --> 00:38:27,040 programming language is honestly learn 1055 00:38:24,720 --> 00:38:28,680 to read the documentation because truly 1056 00:38:27,040 --> 00:38:31,800 all of the answers to your questions 1057 00:38:28,680 --> 00:38:33,640 will in some way be there even though 1058 00:38:31,800 --> 00:38:35,240 admittedly it's not always obvious and I 1059 00:38:33,640 --> 00:38:37,240 will say too Python's documentation 1060 00:38:35,240 --> 00:38:39,520 isn't necessarily the easiest thing 1061 00:38:37,240 --> 00:38:41,520 especially for a first time or novice 1062 00:38:39,520 --> 00:38:42,960 programmer it too just takes practice so 1063 00:38:41,520 --> 00:38:44,640 try not to get overwhelmed if you're not 1064 00:38:42,960 --> 00:38:46,839 sure what you're looking at but let me 1065 00:38:44,640 --> 00:38:48,800 walk you through this example this again 1066 00:38:46,839 --> 00:38:50,800 is a line of text from Python's official 1067 00:38:48,800 --> 00:38:52,720 documentation for the print function 1068 00:38:50,800 --> 00:38:54,520 what this indicates as follows is this 1069 00:38:52,720 --> 00:38:56,480 the name of this function is of course 1070 00:38:54,520 --> 00:38:58,599 print then there's a parenthesis over 1071 00:38:56,480 --> 00:39:00,480 here and another Clos parenthesis way 1072 00:38:58,599 --> 00:39:02,640 over there everything inside of those 1073 00:39:00,480 --> 00:39:05,599 parentheses are the arguments the 1074 00:39:02,640 --> 00:39:07,960 potential arguments to the function 1075 00:39:05,599 --> 00:39:11,040 however when we're looking at these 1076 00:39:07,960 --> 00:39:12,400 arguments in the documentation like this 1077 00:39:11,040 --> 00:39:14,040 there's technically a different term 1078 00:39:12,400 --> 00:39:16,160 that we would use these are technically 1079 00:39:14,040 --> 00:39:18,800 the parameters to the function so when 1080 00:39:16,160 --> 00:39:21,839 you're talking about what you can pass 1081 00:39:18,800 --> 00:39:24,119 to a function and what those inputs are 1082 00:39:21,839 --> 00:39:26,480 called those are parameters when you 1083 00:39:24,119 --> 00:39:28,800 actually use the function and pass in 1084 00:39:26,480 --> 00:39:31,520 values in inside of those parentheses 1085 00:39:28,800 --> 00:39:33,040 those inputs those values are arguments 1086 00:39:31,520 --> 00:39:34,760 so we're talking about the exact same 1087 00:39:33,040 --> 00:39:36,359 thing parameters and arguments are 1088 00:39:34,760 --> 00:39:37,960 effectively the same thing but they 1089 00:39:36,359 --> 00:39:39,680 terms you use from looking at the 1090 00:39:37,960 --> 00:39:41,240 problem from different directions when 1091 00:39:39,680 --> 00:39:43,079 we're looking at what the function can 1092 00:39:41,240 --> 00:39:44,880 take versus what you're actually passing 1093 00:39:43,079 --> 00:39:47,680 into the function so what does this 1094 00:39:44,880 --> 00:39:49,400 imply well this syntax is pretty cryptic 1095 00:39:47,680 --> 00:39:51,760 but at the moment just know that an 1096 00:39:49,400 --> 00:39:53,640 asterisk a star and then the word 1097 00:39:51,760 --> 00:39:55,599 objects means that the print function 1098 00:39:53,640 --> 00:39:58,560 can take any number of objects you can 1099 00:39:55,599 --> 00:40:00,480 pass in zero strings text one string 1100 00:39:58,560 --> 00:40:02,520 like I did two strings like I did or 1101 00:40:00,480 --> 00:40:03,920 technically infinitely many if you you 1102 00:40:02,520 --> 00:40:06,240 really want though that code's not going 1103 00:40:03,920 --> 00:40:09,319 to look very good after that we see a 1104 00:40:06,240 --> 00:40:11,800 comma then we see another parameter here 1105 00:40:09,319 --> 00:40:13,839 called sep short for separator in 1106 00:40:11,800 --> 00:40:16,960 English and notice the equal sign and 1107 00:40:13,839 --> 00:40:19,720 the single quote space single quote so 1108 00:40:16,960 --> 00:40:21,720 quote unquote space I don't know what 1109 00:40:19,720 --> 00:40:23,520 that is yet but I I I think we've seen a 1110 00:40:21,720 --> 00:40:25,520 hint about it let's focus though for a 1111 00:40:23,520 --> 00:40:27,880 moment on this the print function takes 1112 00:40:25,520 --> 00:40:30,040 another parameter called n 1113 00:40:27,880 --> 00:40:32,240 and the default value of that parameter 1114 00:40:30,040 --> 00:40:35,960 is apparently based on this equal sign 1115 00:40:32,240 --> 00:40:37,680 and these quotes back sln and what is 1116 00:40:35,960 --> 00:40:39,680 backs slash n if you'd like to chime in 1117 00:40:37,680 --> 00:40:41,200 the chat anyone who's programmed before 1118 00:40:39,680 --> 00:40:43,280 has probably seen this though if you've 1119 00:40:41,200 --> 00:40:44,200 never programmed before this might look 1120 00:40:43,280 --> 00:40:46,280 quite 1121 00:40:44,200 --> 00:40:49,880 cryptic back 1122 00:40:46,280 --> 00:40:52,480 sln means new line and it's a way 1123 00:40:49,880 --> 00:40:54,040 textually of indicating if and one you 1124 00:40:52,480 --> 00:40:56,359 want the computer effectively to move 1125 00:40:54,040 --> 00:40:58,920 the cursor to the next line create a new 1126 00:40:56,359 --> 00:41:00,640 line of text and so technically if we 1127 00:40:58,920 --> 00:41:02,960 read into the documentation we'll see 1128 00:41:00,640 --> 00:41:05,240 more detail on this the fact that 1129 00:41:02,960 --> 00:41:07,319 there's a parameter called end in the 1130 00:41:05,240 --> 00:41:09,200 documentation for the print function 1131 00:41:07,319 --> 00:41:12,319 just means that by default this print 1132 00:41:09,200 --> 00:41:14,040 function is going to end every line with 1133 00:41:12,319 --> 00:41:15,920 back slash n you don't literally see 1134 00:41:14,040 --> 00:41:18,599 backs slash n you see a new line you see 1135 00:41:15,920 --> 00:41:21,280 the cursor moving to the next line now 1136 00:41:18,599 --> 00:41:24,000 by that logic let's move backwards sep 1137 00:41:21,280 --> 00:41:26,760 for separator the default value of 1138 00:41:24,000 --> 00:41:29,319 separator is apparently a single Blank 1139 00:41:26,760 --> 00:41:31,280 Space well where have we seen that well 1140 00:41:29,319 --> 00:41:33,839 recall in an earlier example when I 1141 00:41:31,280 --> 00:41:36,000 passed in not just one but two arguments 1142 00:41:33,839 --> 00:41:38,400 to the print function recall that they 1143 00:41:36,000 --> 00:41:40,280 magically had a space between them in 1144 00:41:38,400 --> 00:41:42,240 fact they had that space plus my own 1145 00:41:40,280 --> 00:41:44,160 space and that's why I deleted my space 1146 00:41:42,240 --> 00:41:45,480 because at that point it was extra so 1147 00:41:44,160 --> 00:41:47,599 this just means that when you pass 1148 00:41:45,480 --> 00:41:48,760 multiple arguments to print by default 1149 00:41:47,599 --> 00:41:51,040 they're going to be separated by a 1150 00:41:48,760 --> 00:41:53,480 single Space by default when you pass 1151 00:41:51,040 --> 00:41:56,240 arguments to print it's the whole thing 1152 00:41:53,480 --> 00:41:57,440 is going to be ended with a new line now 1153 00:41:56,240 --> 00:41:59,319 just by knowing this and let me let me 1154 00:41:57,440 --> 00:42:01,200 literally wave my hand at the rest of 1155 00:41:59,319 --> 00:42:02,640 the documentation for another day 1156 00:42:01,200 --> 00:42:04,400 there's more things that print can do 1157 00:42:02,640 --> 00:42:06,800 but we're going to focus just on sep and 1158 00:42:04,400 --> 00:42:09,040 on end let's see if we can't leverage 1159 00:42:06,800 --> 00:42:10,720 this now to solve that original problem 1160 00:42:09,040 --> 00:42:12,680 the original problem was this I don't 1161 00:42:10,720 --> 00:42:14,800 like how hello comma David is on two 1162 00:42:12,680 --> 00:42:16,359 different lines well that's happening 1163 00:42:14,800 --> 00:42:18,640 again because print is automatically 1164 00:42:16,359 --> 00:42:21,480 printing out a new line so let's tell it 1165 00:42:18,640 --> 00:42:24,400 not to do that let's Tell It by passing 1166 00:42:21,480 --> 00:42:27,680 a second argument to the first use of 1167 00:42:24,400 --> 00:42:31,160 print to say end equals 1168 00:42:27,680 --> 00:42:33,559 quote unquote not back sln which is the 1169 00:42:31,160 --> 00:42:36,760 default automatically let's make it 1170 00:42:33,559 --> 00:42:39,040 quote unquote nothing else let's 1171 00:42:36,760 --> 00:42:41,119 override the default value so there is 1172 00:42:39,040 --> 00:42:43,680 no new line there's literally nothing 1173 00:42:41,119 --> 00:42:45,599 there and let's see what happens let me 1174 00:42:43,680 --> 00:42:47,559 now go down to my terminal window and 1175 00:42:45,599 --> 00:42:49,520 clear it and I'm going to run python of 1176 00:42:47,559 --> 00:42:52,040 hello.py enter I'm going to type in my 1177 00:42:49,520 --> 00:42:54,240 name David and I think now everything's 1178 00:42:52,040 --> 00:42:58,280 going to stay on the same line because 1179 00:42:54,240 --> 00:43:01,000 and it did this line here five is going 1180 00:42:58,280 --> 00:43:02,640 to print out hello comma space but then 1181 00:43:01,000 --> 00:43:04,839 nothing at the end of it because I 1182 00:43:02,640 --> 00:43:06,800 changed it to be quote unquote the 1183 00:43:04,839 --> 00:43:08,760 second line is going to print the name 1184 00:43:06,800 --> 00:43:10,520 David or whatever the human's name is 1185 00:43:08,760 --> 00:43:13,040 and it will move the cursor to the next 1186 00:43:10,520 --> 00:43:15,359 line because I didn't override the value 1187 00:43:13,040 --> 00:43:17,400 of end there just to see this more 1188 00:43:15,359 --> 00:43:19,400 explicitly if you do something cryptic 1189 00:43:17,400 --> 00:43:20,920 like well I have no idea what's going on 1190 00:43:19,400 --> 00:43:23,000 let me just put in temporarily three 1191 00:43:20,920 --> 00:43:24,720 question marks here we'll see the 1192 00:43:23,000 --> 00:43:27,359 results of this too let me go back down 1193 00:43:24,720 --> 00:43:30,559 to my terminal window run python of. hi 1194 00:43:27,359 --> 00:43:32,640 what's your name David and now you see 1195 00:43:30,559 --> 00:43:34,760 literally really ugly output but you see 1196 00:43:32,640 --> 00:43:38,079 literally what's going on hello comma 1197 00:43:34,760 --> 00:43:41,680 space then three question marks and that 1198 00:43:38,079 --> 00:43:44,359 print statement and then you see d a ID 1199 00:43:41,680 --> 00:43:46,040 so not a good out outcome but it 1200 00:43:44,359 --> 00:43:48,599 demonstrates just how much control we 1201 00:43:46,040 --> 00:43:51,319 have here too and let me rewind further 1202 00:43:48,599 --> 00:43:54,240 recall that in our other version of this 1203 00:43:51,319 --> 00:43:57,079 when I passed in hello comma and name 1204 00:43:54,240 --> 00:44:01,079 they were separated by a single space so 1205 00:43:57,079 --> 00:44:03,720 Pyon of hello.py D Aid enter that just 1206 00:44:01,079 --> 00:44:06,640 worked well what if we override the 1207 00:44:03,720 --> 00:44:09,960 value of sep for separator instead of 1208 00:44:06,640 --> 00:44:12,160 being one space we could say something 1209 00:44:09,960 --> 00:44:13,400 like uh question mark question mark 1210 00:44:12,160 --> 00:44:15,720 question mark just to wrap our minds 1211 00:44:13,400 --> 00:44:19,559 around what's going on there let me now 1212 00:44:15,720 --> 00:44:23,119 do python of hello.py David enter and 1213 00:44:19,559 --> 00:44:25,119 you see two these two inputs hello comma 1214 00:44:23,119 --> 00:44:27,640 and the name are now separated in an 1215 00:44:25,119 --> 00:44:29,319 ugly Way by three question marks Mar s 1216 00:44:27,640 --> 00:44:31,359 because I've overridden the default 1217 00:44:29,319 --> 00:44:33,200 behavior of sep and even though the 1218 00:44:31,359 --> 00:44:34,720 documentation uses single quotes I've 1219 00:44:33,200 --> 00:44:37,079 been in the habit of using double quotes 1220 00:44:34,720 --> 00:44:38,440 in Python you can use either strictly 1221 00:44:37,079 --> 00:44:40,319 speaking it doesn't matter but you 1222 00:44:38,440 --> 00:44:42,079 should be consistent and I generally 1223 00:44:40,319 --> 00:44:45,400 always use double quotes Python's 1224 00:44:42,079 --> 00:44:49,359 documentation though always uses single 1225 00:44:45,400 --> 00:44:51,680 quotes questions now on these types of 1226 00:44:49,359 --> 00:44:54,040 parameters and allow me to propose that 1227 00:44:51,680 --> 00:44:56,559 we give these an official name up until 1228 00:44:54,040 --> 00:44:58,559 now when we've been passing values to 1229 00:44:56,559 --> 00:45:00,319 print those are called positional 1230 00:44:58,559 --> 00:45:01,920 parameters positional in the sense that 1231 00:45:00,319 --> 00:45:03,559 the first thing you pass to print gets 1232 00:45:01,920 --> 00:45:05,480 printed first the second thing you pass 1233 00:45:03,559 --> 00:45:07,440 to print after a comma gets printed 1234 00:45:05,480 --> 00:45:09,359 second and so forth but there's also 1235 00:45:07,440 --> 00:45:13,720 these things we've now seen called named 1236 00:45:09,359 --> 00:45:15,920 parameters named sep separator or end 1237 00:45:13,720 --> 00:45:18,160 end D for the line ending those are 1238 00:45:15,920 --> 00:45:20,440 named parameters because one they're 1239 00:45:18,160 --> 00:45:23,040 optional and you can pass them in at the 1240 00:45:20,440 --> 00:45:26,640 end of your print statement but you can 1241 00:45:23,040 --> 00:45:29,200 also call uh use them by name this may 1242 00:45:26,640 --> 00:45:31,839 be aird question but I was wondering uh 1243 00:45:29,200 --> 00:45:34,760 what if someone wants to like add 1244 00:45:31,839 --> 00:45:37,280 actually qu quotation marks within the 1245 00:45:34,760 --> 00:45:38,760 quotation marks yeah I like how you 1246 00:45:37,280 --> 00:45:41,040 think this is what we would call a 1247 00:45:38,760 --> 00:45:42,640 corner case right just when we've made 1248 00:45:41,040 --> 00:45:44,680 right this is this is all sounding great 1249 00:45:42,640 --> 00:45:46,000 at least as as programming goes but wait 1250 00:45:44,680 --> 00:45:47,880 a minute what if you want to print a 1251 00:45:46,000 --> 00:45:49,640 quote that's a really good question well 1252 00:45:47,880 --> 00:45:52,720 let's see if we can't figure this out 1253 00:45:49,640 --> 00:45:54,440 suppose that I want to print out not 1254 00:45:52,720 --> 00:45:55,839 just the user's name let me simplify 1255 00:45:54,440 --> 00:45:57,960 this further let me go ahead and get rid 1256 00:45:55,839 --> 00:46:00,119 of a lot of this and let me just say 1257 00:45:57,960 --> 00:46:03,520 something like 1258 00:46:00,119 --> 00:46:07,040 hello um maybe I'm being a little 1259 00:46:03,520 --> 00:46:08,839 sarcastic here hello friend you know in 1260 00:46:07,040 --> 00:46:11,119 that kind of tone well this is not going 1261 00:46:08,839 --> 00:46:13,559 to work actually because you are trying 1262 00:46:11,119 --> 00:46:15,000 to use quotes to be like friend in 1263 00:46:13,559 --> 00:46:16,839 finger quotes but you're also trying to 1264 00:46:15,000 --> 00:46:19,040 end the sentence and if I try running 1265 00:46:16,839 --> 00:46:20,599 this let's do this python if hello.py 1266 00:46:19,040 --> 00:46:22,800 you'll see that this is just invalid 1267 00:46:20,599 --> 00:46:24,200 syntax perhaps you forgot a comma and 1268 00:46:22,800 --> 00:46:26,280 this is actually a bit annoying 1269 00:46:24,200 --> 00:46:27,800 sometimes the error messages you see are 1270 00:46:26,280 --> 00:46:29,240 misleading like the computer the 1271 00:46:27,800 --> 00:46:31,000 language doesn't really know what's 1272 00:46:29,240 --> 00:46:33,960 going on so it gives its best guess but 1273 00:46:31,000 --> 00:46:36,000 it's not necessarily correct but I can 1274 00:46:33,960 --> 00:46:38,720 solve this problem in a couple of ways I 1275 00:46:36,000 --> 00:46:40,640 can do this I can change my outermost 1276 00:46:38,720 --> 00:46:42,680 quotes to single quotes because recall a 1277 00:46:40,640 --> 00:46:44,240 moment get I said you could use double 1278 00:46:42,680 --> 00:46:46,160 quotes or single quotes so long as 1279 00:46:44,240 --> 00:46:48,280 you're consistent so that's fine if you 1280 00:46:46,160 --> 00:46:50,079 use single quotes on the outside you can 1281 00:46:48,280 --> 00:46:51,559 then use double quotes on the inside and 1282 00:46:50,079 --> 00:46:54,599 you'll see them literally so for 1283 00:46:51,559 --> 00:46:57,119 instance if I run python of hello.py 1284 00:46:54,599 --> 00:46:59,520 there we go hello friend but there's 1285 00:46:57,119 --> 00:47:01,760 another way if you insist on using 1286 00:46:59,520 --> 00:47:04,240 double quotes as you might want to just 1287 00:47:01,760 --> 00:47:06,319 to be consistent you can also use that 1288 00:47:04,240 --> 00:47:08,520 backslash character again we saw the 1289 00:47:06,319 --> 00:47:10,839 backs slash n a moment ago and that 1290 00:47:08,520 --> 00:47:13,119 meant we don't want a literal n to be in 1291 00:47:10,839 --> 00:47:14,720 the output we wanted a new line so the 1292 00:47:13,119 --> 00:47:17,160 backslash actually represents what's 1293 00:47:14,720 --> 00:47:18,480 called an escape character an escape 1294 00:47:17,160 --> 00:47:21,119 character is one that you can't just 1295 00:47:18,480 --> 00:47:22,400 type necessarily once on your keyboard 1296 00:47:21,119 --> 00:47:24,559 you need to express it with multiple 1297 00:47:22,400 --> 00:47:27,760 characters so I can actually put 1298 00:47:24,559 --> 00:47:29,839 backslashes in front of these inner 1299 00:47:27,760 --> 00:47:31,319 double quotes so that the computer 1300 00:47:29,839 --> 00:47:33,280 realizes oh wait a minute those aren't 1301 00:47:31,319 --> 00:47:35,240 literal those aren't quotes that finish 1302 00:47:33,280 --> 00:47:36,800 or start the thought they're literal 1303 00:47:35,240 --> 00:47:39,839 quotes So now let me go back to my 1304 00:47:36,800 --> 00:47:43,040 terminal window run python of hello.py 1305 00:47:39,839 --> 00:47:44,559 enter and now it's working as well so 1306 00:47:43,040 --> 00:47:47,319 escaping is a general technique that 1307 00:47:44,559 --> 00:47:50,559 allows us to do that too and if I may 1308 00:47:47,319 --> 00:47:52,480 let me rewind now on these examples and 1309 00:47:50,559 --> 00:47:54,480 go back to where we left off with my 1310 00:47:52,480 --> 00:47:56,240 code I'm just undoing all of that 1311 00:47:54,480 --> 00:47:57,480 because I want to get back to the point 1312 00:47:56,240 --> 00:48:00,520 ultimately 1313 00:47:57,480 --> 00:48:03,079 of specifying now a a final way of 1314 00:48:00,520 --> 00:48:04,520 solving this problem well it turns out 1315 00:48:03,079 --> 00:48:07,040 that we have yet another way we can 1316 00:48:04,520 --> 00:48:10,440 solve this problem which is perhaps the 1317 00:48:07,040 --> 00:48:12,880 most frequently done now or at least the 1318 00:48:10,440 --> 00:48:16,040 most elegant when it comes to setting us 1319 00:48:12,880 --> 00:48:18,599 up for longer and longer uh uses of 1320 00:48:16,040 --> 00:48:21,160 strings you can use a relatively new 1321 00:48:18,599 --> 00:48:23,559 feature of python that allows you to do 1322 00:48:21,160 --> 00:48:25,680 this you can literally put not the name 1323 00:48:23,559 --> 00:48:27,359 of the variable like that in your string 1324 00:48:25,680 --> 00:48:29,359 because we already saw this is right if 1325 00:48:27,359 --> 00:48:31,760 you do this you will literally see hello 1326 00:48:29,359 --> 00:48:34,480 comma name but what if I do this what if 1327 00:48:31,760 --> 00:48:36,720 I put curly braces or curly brackets 1328 00:48:34,480 --> 00:48:38,160 around the variable's name notice vs 1329 00:48:36,720 --> 00:48:39,640 code is actually very subtly changing 1330 00:48:38,160 --> 00:48:41,720 the color of it so vs code knows 1331 00:48:39,640 --> 00:48:43,640 something interesting is going on here 1332 00:48:41,720 --> 00:48:47,880 let me run this program but I'm not done 1333 00:48:43,640 --> 00:48:50,079 yet python of hello.py enter David enter 1334 00:48:47,880 --> 00:48:52,000 okay obviously not what I want but I 1335 00:48:50,079 --> 00:48:53,799 need to tell python that this is a 1336 00:48:52,000 --> 00:48:56,760 special string this is what we're going 1337 00:48:53,799 --> 00:48:58,559 to call a format string or an F string a 1338 00:48:56,760 --> 00:49:01,160 relatively new feature of python in the 1339 00:48:58,559 --> 00:49:03,880 past few years that tells python to 1340 00:49:01,160 --> 00:49:06,200 actually format stuff in the string in a 1341 00:49:03,880 --> 00:49:07,920 special way and the symbol via what you 1342 00:49:06,200 --> 00:49:11,000 do this is a little weird but this is 1343 00:49:07,920 --> 00:49:14,160 what the world chose if you put a f at 1344 00:49:11,000 --> 00:49:17,000 the beginning of the string right before 1345 00:49:14,160 --> 00:49:19,200 the first quote Mark that's a clue to 1346 00:49:17,000 --> 00:49:21,160 python that o this is a special string 1347 00:49:19,200 --> 00:49:23,920 let me format this in a special way for 1348 00:49:21,160 --> 00:49:27,200 you let me now rerun the program python 1349 00:49:23,920 --> 00:49:30,000 hello.py enter David enter and now we 1350 00:49:27,200 --> 00:49:31,839 see the goal this whole time hello comma 1351 00:49:30,000 --> 00:49:33,240 David we don't start with this way 1352 00:49:31,839 --> 00:49:35,200 because I think if we did this the first 1353 00:49:33,240 --> 00:49:37,079 way you'd be like why are we doing this 1354 00:49:35,200 --> 00:49:39,200 what are all these magical symbols but 1355 00:49:37,079 --> 00:49:41,319 this is just yet another way to solve 1356 00:49:39,200 --> 00:49:43,880 the same problem but let me propose that 1357 00:49:41,319 --> 00:49:46,040 we consider now yet other things we can 1358 00:49:43,880 --> 00:49:48,319 do with strings and it turns out that 1359 00:49:46,040 --> 00:49:49,880 even as we've been doing some relatively 1360 00:49:48,319 --> 00:49:52,160 simple operations here we've generally 1361 00:49:49,880 --> 00:49:54,000 been trusting that the user is going to 1362 00:49:52,160 --> 00:49:55,240 cooperate and that is to say that 1363 00:49:54,000 --> 00:49:57,000 they're going to actually type in what 1364 00:49:55,240 --> 00:49:58,480 we want them to type now now just 1365 00:49:57,000 --> 00:49:59,760 because they type A String though 1366 00:49:58,480 --> 00:50:02,200 doesn't mean it's going to look the way 1367 00:49:59,760 --> 00:50:04,040 we want you and I honestly as humans are 1368 00:50:02,200 --> 00:50:05,960 actually in the habit on websites and 1369 00:50:04,040 --> 00:50:07,599 apps of like accidentally hitting the 1370 00:50:05,960 --> 00:50:09,720 space bar a lot either at the beginning 1371 00:50:07,599 --> 00:50:11,559 of our input or at the end maybe because 1372 00:50:09,720 --> 00:50:13,920 the space bar tends to be so big it's 1373 00:50:11,559 --> 00:50:16,319 pretty common to get accidental spaces 1374 00:50:13,920 --> 00:50:17,880 before or after some users input you and 1375 00:50:16,319 --> 00:50:20,000 I are definitely in the habit of not 1376 00:50:17,880 --> 00:50:21,680 necessarily capitalizing words like we 1377 00:50:20,000 --> 00:50:23,400 should if we're sending text messages 1378 00:50:21,680 --> 00:50:25,000 we're probably being a little quick and 1379 00:50:23,400 --> 00:50:26,280 just sending everything in lowercase for 1380 00:50:25,000 --> 00:50:28,440 instance if that's your style if your 1381 00:50:26,280 --> 00:50:29,920 phone's not fixing it for you maybe in a 1382 00:50:28,440 --> 00:50:31,640 formal letter you would capitalize 1383 00:50:29,920 --> 00:50:33,119 things properly but you and I as humans 1384 00:50:31,640 --> 00:50:35,160 we can't really be trusted to type 1385 00:50:33,119 --> 00:50:37,160 things in a nice way necessarily when 1386 00:50:35,160 --> 00:50:39,160 using some piece of software be it an 1387 00:50:37,160 --> 00:50:42,520 app or website or something else but it 1388 00:50:39,160 --> 00:50:44,440 turns out that strings themselves come 1389 00:50:42,520 --> 00:50:46,119 with a lot of built-in functionality and 1390 00:50:44,440 --> 00:50:49,599 you can see all of that in Python's own 1391 00:50:46,119 --> 00:50:51,000 documentation here the string data type 1392 00:50:49,599 --> 00:50:52,960 that we've been talking about comes with 1393 00:50:51,000 --> 00:50:54,880 a lot of functionality built in that 1394 00:50:52,960 --> 00:50:57,160 means that we can manipulate the user's 1395 00:50:54,880 --> 00:50:59,040 input to do more than just join it with 1396 00:50:57,160 --> 00:51:01,880 something else like hello we can 1397 00:50:59,040 --> 00:51:03,720 actually clean it up or reformat it in a 1398 00:51:01,880 --> 00:51:06,319 way that hopefully looks a little better 1399 00:51:03,720 --> 00:51:08,359 for us so let me go back to my code here 1400 00:51:06,319 --> 00:51:10,440 and let me just demonstrate what might 1401 00:51:08,359 --> 00:51:12,880 happen if a user doesn't cooperate if I 1402 00:51:10,440 --> 00:51:15,400 go ahead here and run python of hello.py 1403 00:51:12,880 --> 00:51:17,680 enter let me just sloppily hit the space 1404 00:51:15,400 --> 00:51:19,520 bar a few too many times why I just 1405 00:51:17,680 --> 00:51:21,680 wasn't paying attention and I'm going to 1406 00:51:19,520 --> 00:51:23,599 type in my name da viid and I don't know 1407 00:51:21,680 --> 00:51:24,960 I hit the space bar a couple more times 1408 00:51:23,599 --> 00:51:26,599 like it's kind of a mess it's all 1409 00:51:24,960 --> 00:51:28,119 lowercase that's not going to 1410 00:51:26,599 --> 00:51:30,319 necessarily look grammatically right 1411 00:51:28,119 --> 00:51:32,040 it's got spaces here and here the 1412 00:51:30,319 --> 00:51:33,680 program is going to print exactly that 1413 00:51:32,040 --> 00:51:35,319 and that looks really bad at least if 1414 00:51:33,680 --> 00:51:37,160 we're prioritizing Aesthetics and 1415 00:51:35,319 --> 00:51:38,799 grammar like why are there so many 1416 00:51:37,160 --> 00:51:41,720 spaces after the comma this is not a 1417 00:51:38,799 --> 00:51:44,000 very nice way to greet your users but we 1418 00:51:41,720 --> 00:51:47,200 can clean this up it turns out that 1419 00:51:44,000 --> 00:51:49,839 built into Strings which again is this 1420 00:51:47,200 --> 00:51:52,559 data type so to speak this type of data 1421 00:51:49,839 --> 00:51:54,880 in Python is the ability to actually do 1422 00:51:52,559 --> 00:51:56,599 things to that string so let me do this 1423 00:51:54,880 --> 00:52:01,040 I can actually go ahead and do something 1424 00:51:56,599 --> 00:52:05,040 something like this uh name equals name. 1425 00:52:01,040 --> 00:52:07,480 strip and what does this do remove Whit 1426 00:52:05,040 --> 00:52:10,280 space from 1427 00:52:07,480 --> 00:52:11,880 string and what do I mean by this well 1428 00:52:10,280 --> 00:52:14,880 on the right hand side notice I've 1429 00:52:11,880 --> 00:52:17,640 written the variable name called name 1430 00:52:14,880 --> 00:52:19,720 I've then used a period or a DOT and 1431 00:52:17,640 --> 00:52:21,400 then I seem to be doing what's a 1432 00:52:19,720 --> 00:52:23,240 function right anytime we've seen a 1433 00:52:21,400 --> 00:52:25,200 function thus far we see it's the the 1434 00:52:23,240 --> 00:52:26,520 function's name print or input then we 1435 00:52:25,200 --> 00:52:27,920 see a parenthesis then another 1436 00:52:26,520 --> 00:52:30,000 parenthesis and that's exactly what I 1437 00:52:27,920 --> 00:52:31,359 see here but I'm using this function a 1438 00:52:30,000 --> 00:52:33,319 little differently technically this 1439 00:52:31,359 --> 00:52:35,920 function is in this context called a 1440 00:52:33,319 --> 00:52:39,359 method and what do I mean by that well 1441 00:52:35,920 --> 00:52:41,079 if name is a string AKA stir well it 1442 00:52:39,359 --> 00:52:43,319 turns out according to the documentation 1443 00:52:41,079 --> 00:52:46,200 there's a lot of functions that come 1444 00:52:43,319 --> 00:52:48,240 with strings in Python and you can 1445 00:52:46,200 --> 00:52:50,240 access that functionality by using the 1446 00:52:48,240 --> 00:52:53,160 name of a string like literally name 1447 00:52:50,240 --> 00:52:55,160 here then a period Then the name of the 1448 00:52:53,160 --> 00:52:56,839 function and then an open parenthesis 1449 00:52:55,160 --> 00:52:58,520 and a closed parenthesis Maybe some 1450 00:52:56,839 --> 00:53:00,400 arguments inside of those parentheses 1451 00:52:58,520 --> 00:53:02,960 but in this case it doesn't need any 1452 00:53:00,400 --> 00:53:04,680 arguments I just want to strip the space 1453 00:53:02,960 --> 00:53:06,640 from the left and the space from the 1454 00:53:04,680 --> 00:53:08,520 right of the user's input but that's not 1455 00:53:06,640 --> 00:53:10,040 enough I want to remember that I've 1456 00:53:08,520 --> 00:53:11,760 stripped off that white space on the 1457 00:53:10,040 --> 00:53:14,319 left and the right so I'm going to use 1458 00:53:11,760 --> 00:53:15,920 the equal sign again here and notice 1459 00:53:14,319 --> 00:53:17,920 that just as before this doesn't mean 1460 00:53:15,920 --> 00:53:20,280 equality this means assignment from 1461 00:53:17,920 --> 00:53:24,880 right to left so when this line of code 1462 00:53:20,280 --> 00:53:27,040 here name. strip returns to me AKA a 1463 00:53:24,880 --> 00:53:28,440 return value it will return the same 1464 00:53:27,040 --> 00:53:30,400 thing that the user typed in but with no 1465 00:53:28,440 --> 00:53:33,599 more white space to the left or to the 1466 00:53:30,400 --> 00:53:35,680 white to to the right so then the equal 1467 00:53:33,599 --> 00:53:39,040 sign assignment is going to copy that 1468 00:53:35,680 --> 00:53:42,119 value from the right to the left thereby 1469 00:53:39,040 --> 00:53:44,319 updating the value inside of my name 1470 00:53:42,119 --> 00:53:46,240 variable so you can not only assign 1471 00:53:44,319 --> 00:53:48,680 values to variables you can absolutely 1472 00:53:46,240 --> 00:53:50,599 change the value of variables by just 1473 00:53:48,680 --> 00:53:52,160 using the assignment operator the equal 1474 00:53:50,599 --> 00:53:53,599 sign again and again and again and it 1475 00:53:52,160 --> 00:53:56,160 will just keep copying from right to 1476 00:53:53,599 --> 00:53:58,640 left whatever the new value should be so 1477 00:53:56,160 --> 00:53:59,480 now now if I rerun this program python 1478 00:53:58,640 --> 00:54:03,480 of 1479 00:53:59,480 --> 00:54:05,359 hello.py enter I have Davi oh let's do 1480 00:54:03,480 --> 00:54:08,000 it again space space space space space 1481 00:54:05,359 --> 00:54:11,040 daav ID in all lowercase space space 1482 00:54:08,000 --> 00:54:12,599 enter it's better it hasn't fixed my 1483 00:54:11,040 --> 00:54:15,000 capitalization so I'm still being a 1484 00:54:12,599 --> 00:54:17,640 little sloppy with the first D but it 1485 00:54:15,000 --> 00:54:19,799 has stripped off all of that extra space 1486 00:54:17,640 --> 00:54:22,440 super Minor Detail right like this isn't 1487 00:54:19,799 --> 00:54:24,200 all that exciting but it just speaks to 1488 00:54:22,440 --> 00:54:26,599 the power of what you can do with just a 1489 00:54:24,200 --> 00:54:28,640 single line of code now what else can I 1490 00:54:26,599 --> 00:54:30,839 do here well I could capitalize the 1491 00:54:28,640 --> 00:54:34,200 user's input let me go ahead and try 1492 00:54:30,839 --> 00:54:35,559 this it turns out that I could also uh 1493 00:54:34,200 --> 00:54:39,359 do this 1494 00:54:35,559 --> 00:54:42,040 name. capitalize so let me go ahead and 1495 00:54:39,359 --> 00:54:43,720 capitalize uh user's name and again I'm 1496 00:54:42,040 --> 00:54:45,440 making comments and there's no one right 1497 00:54:43,720 --> 00:54:46,839 way to write the comments I'm just using 1498 00:54:45,440 --> 00:54:49,040 some short English phrases here to 1499 00:54:46,839 --> 00:54:50,799 remind myself of what I'm doing what's 1500 00:54:49,040 --> 00:54:53,280 now going on here well let me go ahead 1501 00:54:50,799 --> 00:54:55,400 and run python of hello.py enter uh 1502 00:54:53,280 --> 00:54:57,520 space space space space space DAV ID 1503 00:54:55,400 --> 00:54:59,720 space space enter 1504 00:54:57,520 --> 00:55:01,359 okay now it's looking prettier right no 1505 00:54:59,720 --> 00:55:03,559 matter how the user typed in their name 1506 00:55:01,359 --> 00:55:05,559 even a little sloppily I'm now fixing 1507 00:55:03,559 --> 00:55:07,040 that but let's let's try something I'm 1508 00:55:05,559 --> 00:55:09,480 getting a little curious here how about 1509 00:55:07,040 --> 00:55:13,119 this uh space space space space space 1510 00:55:09,480 --> 00:55:17,400 David space maen I'll use my last name 1511 00:55:13,119 --> 00:55:19,799 now enter okay so ironically capitalize 1512 00:55:17,400 --> 00:55:22,280 is not really capitalizing everything we 1513 00:55:19,799 --> 00:55:24,599 want it's clearly capitalizing what just 1514 00:55:22,280 --> 00:55:26,520 the very first letter so it turns out 1515 00:55:24,599 --> 00:55:28,319 that again there's other functions in in 1516 00:55:26,520 --> 00:55:30,880 Python that come with strings and if we 1517 00:55:28,319 --> 00:55:33,559 poke around the documentation scrolling 1518 00:55:30,880 --> 00:55:35,280 through a URL like that I bet we'll find 1519 00:55:33,559 --> 00:55:37,799 another solution one of which is 1520 00:55:35,280 --> 00:55:40,720 actually this let's actually change this 1521 00:55:37,799 --> 00:55:42,960 to title there's yet another function 1522 00:55:40,720 --> 00:55:45,240 that come with strings called title that 1523 00:55:42,960 --> 00:55:47,319 do title based capitalization just like 1524 00:55:45,240 --> 00:55:50,160 a book or a person's name capitalizing 1525 00:55:47,319 --> 00:55:51,640 the first letter of each word and this 1526 00:55:50,160 --> 00:55:53,960 is just going to do a little more work 1527 00:55:51,640 --> 00:55:55,880 for us so let's go ahead and run this 1528 00:55:53,960 --> 00:55:56,880 and as an aside I'm kind of tired now at 1529 00:55:55,880 --> 00:55:59,480 this point 1530 00:55:56,880 --> 00:56:01,559 of typing python python python all the 1531 00:55:59,480 --> 00:56:03,920 time it turns out that when using a 1532 00:56:01,559 --> 00:56:05,559 command line interface like this you can 1533 00:56:03,920 --> 00:56:07,039 actually go back through all of your old 1534 00:56:05,559 --> 00:56:08,960 commands what I just did a moment ago 1535 00:56:07,039 --> 00:56:11,280 was I hit the up arrow that immediately 1536 00:56:08,960 --> 00:56:13,240 goes back through my history of all of 1537 00:56:11,280 --> 00:56:16,079 the commands I've ever typed so this is 1538 00:56:13,240 --> 00:56:18,039 just a faster way now for repeat myself 1539 00:56:16,079 --> 00:56:20,000 than typing everything manually let me 1540 00:56:18,039 --> 00:56:22,680 go ahead and hit enter uh space space 1541 00:56:20,000 --> 00:56:26,440 space space space DAV ID mailin space 1542 00:56:22,680 --> 00:56:28,880 space all lowercase enter now it's it's 1543 00:56:26,440 --> 00:56:30,319 looking better now I've capitalized 1544 00:56:28,880 --> 00:56:32,559 things and cleaned things up but what 1545 00:56:30,319 --> 00:56:34,520 about my code I've got like eight lines 1546 00:56:32,559 --> 00:56:36,400 of code now four of which are comments 1547 00:56:34,520 --> 00:56:38,240 four of which are actual code do I 1548 00:56:36,400 --> 00:56:40,839 really need this much well not 1549 00:56:38,240 --> 00:56:43,240 necessarily watch what I can also do in 1550 00:56:40,839 --> 00:56:45,799 Python let me not bother capitalizing 1551 00:56:43,240 --> 00:56:47,599 the user's name separately let me say 1552 00:56:45,799 --> 00:56:51,480 this and 1553 00:56:47,599 --> 00:56:54,119 capital uh capitalize users name I can 1554 00:56:51,480 --> 00:56:57,079 chain these functions together I can add 1555 00:56:54,119 --> 00:56:59,000 title to the end of this and now what's 1556 00:56:57,079 --> 00:57:01,039 happening well again with a line of code 1557 00:56:59,000 --> 00:57:03,079 like this you first focus on what's to 1558 00:57:01,039 --> 00:57:04,640 the right of the equal sign then we'll 1559 00:57:03,079 --> 00:57:06,680 get to the left of the equal sign what's 1560 00:57:04,640 --> 00:57:09,160 on the right of the equal sign this line 1561 00:57:06,680 --> 00:57:11,920 here well what does this mean get the 1562 00:57:09,160 --> 00:57:15,520 value of the name variable like daavid 1563 00:57:11,920 --> 00:57:17,440 space m n then strip off the white space 1564 00:57:15,520 --> 00:57:19,520 on the left and the right that is going 1565 00:57:17,440 --> 00:57:22,760 to return a value it's going to return 1566 00:57:19,520 --> 00:57:24,319 da ID space m n without any white space 1567 00:57:22,760 --> 00:57:26,440 to the left or right what do you want to 1568 00:57:24,319 --> 00:57:29,119 do with that return value you want 1569 00:57:26,440 --> 00:57:31,559 python to title case it that is go 1570 00:57:29,119 --> 00:57:33,880 through every word in that resulting 1571 00:57:31,559 --> 00:57:35,200 string and fix the first letter of the 1572 00:57:33,880 --> 00:57:37,280 first word the first letter of the 1573 00:57:35,200 --> 00:57:39,359 second word and so forth and then now we 1574 00:57:37,280 --> 00:57:42,839 can finish our thought copy the whole 1575 00:57:39,359 --> 00:57:44,559 thing from right to left into that same 1576 00:57:42,839 --> 00:57:46,559 name variable and you know what I can 1577 00:57:44,559 --> 00:57:49,480 take this even one step further why 1578 00:57:46,559 --> 00:57:51,720 don't we go ahead and do this if we want 1579 00:57:49,480 --> 00:57:55,599 let me get rid of all that and let me 1580 00:57:51,720 --> 00:57:57,440 just do strip and title all on that 1581 00:57:55,599 --> 00:58:00,200 first line and now we've gone from like 1582 00:57:57,440 --> 00:58:02,319 eight lines of code to four it's a lot 1583 00:58:00,200 --> 00:58:04,319 tighter it's a lot neater and even 1584 00:58:02,319 --> 00:58:07,240 though reasonable people might disagree 1585 00:58:04,319 --> 00:58:09,280 it's arguably better because it's just 1586 00:58:07,240 --> 00:58:10,920 easier to read fewer lines of code fewer 1587 00:58:09,280 --> 00:58:13,359 opportunities for mistakes it just 1588 00:58:10,920 --> 00:58:16,119 allows me to move on with my next 1589 00:58:13,359 --> 00:58:18,880 problem to solve all right let me pause 1590 00:58:16,119 --> 00:58:20,720 here and see if there's any questions on 1591 00:58:18,880 --> 00:58:23,599 these methods a method is a function 1592 00:58:20,720 --> 00:58:26,960 that's built in to a a type of value 1593 00:58:23,599 --> 00:58:29,680 like these functions are or on F strings 1594 00:58:26,960 --> 00:58:31,920 which we saw a moment ago yes hi thanks 1595 00:58:29,680 --> 00:58:34,599 David um so is there a way to remove the 1596 00:58:31,920 --> 00:58:37,000 spaces between the spaces that I might 1597 00:58:34,599 --> 00:58:38,559 have added a short answer no if you read 1598 00:58:37,000 --> 00:58:40,680 the documentation at that same URL 1599 00:58:38,559 --> 00:58:42,599 earlier you'll see that strip removes 1600 00:58:40,680 --> 00:58:44,119 from the left and the right but not in 1601 00:58:42,599 --> 00:58:45,960 between in fact there's two other 1602 00:58:44,119 --> 00:58:48,160 functions that come with strings one's 1603 00:58:45,960 --> 00:58:50,000 called L strip the other's called R 1604 00:58:48,160 --> 00:58:51,799 strip that allow you to do one or the 1605 00:58:50,000 --> 00:58:53,079 other if we want to start getting rid of 1606 00:58:51,799 --> 00:58:56,200 space in the middle we're going to have 1607 00:58:53,079 --> 00:58:58,920 to do a different trick Al together how 1608 00:58:56,200 --> 00:59:01,359 many functions can we combined like this 1609 00:58:58,920 --> 00:59:03,880 do stripe do title you have combined so 1610 00:59:01,359 --> 00:59:06,680 how many we can combine yeah a really 1611 00:59:03,880 --> 00:59:08,680 good question technically as many as you 1612 00:59:06,680 --> 00:59:10,640 want but at some point your codee's 1613 00:59:08,680 --> 00:59:11,880 going to start to look really really bad 1614 00:59:10,640 --> 00:59:13,480 right because the line of code's going 1615 00:59:11,880 --> 00:59:15,280 to get really really long it's 1616 00:59:13,480 --> 00:59:17,280 eventually going to maybe wrap around 1617 00:59:15,280 --> 00:59:18,880 again and again so at some point you 1618 00:59:17,280 --> 00:59:20,839 just kind of say like uhuh that's too 1619 00:59:18,880 --> 00:59:22,799 many and you start breaking it up into 1620 00:59:20,839 --> 00:59:25,160 multiple lines like I did maybe 1621 00:59:22,799 --> 00:59:26,680 reassigning the value to the variable as 1622 00:59:25,160 --> 00:59:28,599 needed and this is actually a good 1623 00:59:26,680 --> 00:59:30,920 question if I can pivot div off your 1624 00:59:28,599 --> 00:59:32,160 question I mean what do people think if 1625 00:59:30,920 --> 00:59:35,920 we could go ahead and put everyone's 1626 00:59:32,160 --> 00:59:39,559 hands down for a moment let me ask this 1627 00:59:35,920 --> 00:59:43,039 is the way I've done this now with strip 1628 00:59:39,559 --> 00:59:45,839 and title and input all in the same line 1629 00:59:43,039 --> 00:59:49,079 better than my previous approach in Zoom 1630 00:59:45,839 --> 00:59:51,799 you can use the yes icon or the no icon 1631 00:59:49,079 --> 00:59:54,760 if you think this version is better say 1632 00:59:51,799 --> 00:59:58,440 yes if you think this previous version 1633 00:59:54,760 --> 01:00:00,480 was better for instance this one here 1634 00:59:58,440 --> 01:00:03,640 where we had everything broken out say 1635 01:00:00,480 --> 01:00:05,799 no and then we'll see why in just a 1636 01:00:03,640 --> 01:00:08,160 moment I proposed earlier that 1637 01:00:05,799 --> 01:00:09,760 reasonable people can disagree and 1638 01:00:08,160 --> 01:00:12,440 that's absolutely the 1639 01:00:09,760 --> 01:00:14,720 case doing it one way or the other isn't 1640 01:00:12,440 --> 01:00:16,839 necessarily best at least if you can 1641 01:00:14,720 --> 01:00:18,440 justify it let me go back to the most 1642 01:00:16,839 --> 01:00:21,440 recent version 1643 01:00:18,440 --> 01:00:23,839 here all right so we're seeing a lot of 1644 01:00:21,440 --> 01:00:25,760 yeses and a lot of NOS why don't we go 1645 01:00:23,839 --> 01:00:28,599 ahead and and call on one of the yeses 1646 01:00:25,760 --> 01:00:30,240 if if we could someone who's voting yes 1647 01:00:28,599 --> 01:00:32,400 why do you think the current version of 1648 01:00:30,240 --> 01:00:35,680 this code is indeed better than the 1649 01:00:32,400 --> 01:00:37,839 previous longer version of the code I 1650 01:00:35,680 --> 01:00:39,680 think it's more readable so I can say 1651 01:00:37,839 --> 01:00:42,400 hey this is the name fun this is the 1652 01:00:39,680 --> 01:00:44,720 name variable it gets some input and 1653 01:00:42,400 --> 01:00:47,039 then remove the space and give it a 1654 01:00:44,720 --> 01:00:48,440 title and there you go you have a Hello 1655 01:00:47,039 --> 01:00:49,960 name yeah I think that's pretty 1656 01:00:48,440 --> 01:00:51,240 reasonable it's very readable at least 1657 01:00:49,960 --> 01:00:52,839 if you're in the habit as you are in 1658 01:00:51,240 --> 01:00:55,000 English of reading left to right it just 1659 01:00:52,839 --> 01:00:57,240 kind of flows very naturally as a result 1660 01:00:55,000 --> 01:00:58,760 the lines is not really that long it's 1661 01:00:57,240 --> 01:01:00,039 certainly fitting nicely onto the screen 1662 01:00:58,760 --> 01:01:01,760 so I think that's a good argument how 1663 01:01:00,039 --> 01:01:04,160 about a Counterpoint though someone who 1664 01:01:01,760 --> 01:01:07,480 voted no if we could call on someone who 1665 01:01:04,160 --> 01:01:11,960 thinks this is worse uh because it's not 1666 01:01:07,480 --> 01:01:15,799 avilable at all uh it seems like 1667 01:01:11,960 --> 01:01:18,359 uh it's a very long uh line so I think 1668 01:01:15,799 --> 01:01:20,000 it's better to separate yeah I I think 1669 01:01:18,359 --> 01:01:22,280 that's persuasive too right it's getting 1670 01:01:20,000 --> 01:01:23,880 a little longer and even though my 1671 01:01:22,280 --> 01:01:25,720 sentence here what's your name is 1672 01:01:23,880 --> 01:01:27,680 relatively short you could imagine that 1673 01:01:25,720 --> 01:01:29,559 this could get even uglier quickly if I 1674 01:01:27,680 --> 01:01:31,119 were asking a longer question of the 1675 01:01:29,559 --> 01:01:33,520 user that's going to make this line of 1676 01:01:31,119 --> 01:01:35,440 code even longer and therefore less 1677 01:01:33,520 --> 01:01:38,000 readable it might be less obvious to me 1678 01:01:35,440 --> 01:01:39,920 or my colleagues that I am calling strip 1679 01:01:38,000 --> 01:01:42,480 or that I am calling title it might be 1680 01:01:39,920 --> 01:01:44,119 kind of a unexpected surprise so I think 1681 01:01:42,480 --> 01:01:46,440 that's reasonable too in short there is 1682 01:01:44,119 --> 01:01:47,920 no right answer here and in fact part of 1683 01:01:46,440 --> 01:01:50,680 the process of getting better at 1684 01:01:47,920 --> 01:01:52,520 programming is getting your own sense of 1685 01:01:50,680 --> 01:01:54,240 style or working for a company where 1686 01:01:52,520 --> 01:01:55,400 they might prescribe which way is better 1687 01:01:54,240 --> 01:01:57,240 than the other because they just want 1688 01:01:55,400 --> 01:01:59,359 everyone doing the same thing even 1689 01:01:57,240 --> 01:02:01,760 though reasonable people might uh 1690 01:01:59,359 --> 01:02:03,960 disagree ultimately though so long as 1691 01:02:01,760 --> 01:02:06,240 you have what's a pretty good argument 1692 01:02:03,960 --> 01:02:07,880 in favor of one way or the other like 1693 01:02:06,240 --> 01:02:08,880 ultimately that's what's important if 1694 01:02:07,880 --> 01:02:10,200 you're just doing things because you 1695 01:02:08,880 --> 01:02:12,240 don't really know which one's better 1696 01:02:10,200 --> 01:02:13,960 that's not great but if if and when you 1697 01:02:12,240 --> 01:02:16,079 start to acquire opinions and if your 1698 01:02:13,960 --> 01:02:17,640 boss if your teacher if your colleague 1699 01:02:16,079 --> 01:02:19,480 your friend can challenge you and say 1700 01:02:17,640 --> 01:02:21,000 wait why did you do it like this they 1701 01:02:19,480 --> 01:02:22,480 might not agree with you but at least 1702 01:02:21,000 --> 01:02:25,359 have an answer and that should be 1703 01:02:22,480 --> 01:02:26,880 sufficiently persuasive in general now 1704 01:02:25,359 --> 01:02:28,920 strings come with a whole bunch of other 1705 01:02:26,880 --> 01:02:30,920 methods as well among which is one 1706 01:02:28,920 --> 01:02:33,079 called split which can as the name 1707 01:02:30,920 --> 01:02:35,319 suggests split a string into multiple 1708 01:02:33,079 --> 01:02:36,799 smaller substring so to speak for 1709 01:02:35,319 --> 01:02:38,520 instance if the human here is in the 1710 01:02:36,799 --> 01:02:40,559 habit of typing in their first name then 1711 01:02:38,520 --> 01:02:42,319 a space and then their last name and you 1712 01:02:40,559 --> 01:02:43,839 want to go ahead and greet them only by 1713 01:02:42,319 --> 01:02:45,559 first name well we could actually 1714 01:02:43,839 --> 01:02:47,599 leverage that single space between the 1715 01:02:45,559 --> 01:02:50,000 first name and last name and split that 1716 01:02:47,599 --> 01:02:51,760 string into two smaller substrings how 1717 01:02:50,000 --> 01:02:53,559 can we do this well let me go ahead and 1718 01:02:51,760 --> 01:02:56,319 in between these lines proactively 1719 01:02:53,559 --> 01:03:00,760 comment that we're about to split user's 1720 01:02:56,319 --> 01:03:02,599 name into first name and last name and 1721 01:03:00,760 --> 01:03:04,000 then let's go ahead and take that name 1722 01:03:02,599 --> 01:03:06,760 variable which currently contains 1723 01:03:04,000 --> 01:03:09,039 something like presumably David space Ma 1724 01:03:06,760 --> 01:03:11,119 and let me go ahead and call split and 1725 01:03:09,039 --> 01:03:13,240 pass in as the argument to split a 1726 01:03:11,119 --> 01:03:14,960 single white space thereby indicating 1727 01:03:13,240 --> 01:03:16,760 that I indeed want to split on that 1728 01:03:14,960 --> 01:03:19,480 character now it turns out split's going 1729 01:03:16,760 --> 01:03:21,039 to return a sequence of values ideally a 1730 01:03:19,480 --> 01:03:22,839 first name and then a last name and we 1731 01:03:21,039 --> 01:03:25,000 can actually in Python assign both of 1732 01:03:22,839 --> 01:03:27,240 those values from that sequence at once 1733 01:03:25,000 --> 01:03:29,559 to some variable for instance first 1734 01:03:27,240 --> 01:03:31,359 comma last equals and that's going to 1735 01:03:29,559 --> 01:03:32,880 have the effect from right to left of 1736 01:03:31,359 --> 01:03:34,839 putting the first such value in the 1737 01:03:32,880 --> 01:03:37,119 first variable the second such value in 1738 01:03:34,839 --> 01:03:39,319 the second variable so now on my last 1739 01:03:37,119 --> 01:03:41,079 line of code I can go in and say hello 1740 01:03:39,319 --> 01:03:43,839 not to the full name something like 1741 01:03:41,079 --> 01:03:45,680 David man I can just say hello comma 1742 01:03:43,839 --> 01:03:47,359 first all right let's go ahead and clear 1743 01:03:45,680 --> 01:03:49,559 my terminal window run python of 1744 01:03:47,359 --> 01:03:51,240 hello.py and hit enter I won't bother 1745 01:03:49,559 --> 01:03:53,079 with any leading Whit space this time 1746 01:03:51,240 --> 01:03:55,920 but let me go ahead and type in David 1747 01:03:53,079 --> 01:03:59,960 space maen and crossing my fingers is as 1748 01:03:55,920 --> 01:04:02,119 usual hello David is what we now see all 1749 01:03:59,960 --> 01:04:04,440 right so we've seen so much so many 1750 01:04:02,119 --> 01:04:06,720 examples thus far involving strings but 1751 01:04:04,440 --> 01:04:09,000 certainly programs uh and programming 1752 01:04:06,720 --> 01:04:10,799 languages can manipulate other types of 1753 01:04:09,000 --> 01:04:13,240 data as well let's go ahead and 1754 01:04:10,799 --> 01:04:15,319 transition then to another very common 1755 01:04:13,240 --> 01:04:17,720 type of data in Python in programming 1756 01:04:15,319 --> 01:04:20,480 more generally namely integers otherwise 1757 01:04:17,720 --> 01:04:23,119 known in python as int int so just as 1758 01:04:20,480 --> 01:04:25,440 stir St Str is short for string so is 1759 01:04:23,119 --> 01:04:27,520 INT in Python short for integer well 1760 01:04:25,440 --> 01:04:31,839 what's in an integer well just like in 1761 01:04:27,520 --> 01:04:33,440 math it's a number like -2 Nega 1 0 1 2 1762 01:04:31,839 --> 01:04:35,000 and all the way toward negative Infinity 1763 01:04:33,440 --> 01:04:37,200 all the way toward positive Infinity but 1764 01:04:35,000 --> 01:04:40,599 there's no decimal point in an integer 1765 01:04:37,200 --> 01:04:43,839 it's just a number like -2 Nega 1 0 1 1766 01:04:40,599 --> 01:04:46,319 and two onward that's an INT of course 1767 01:04:43,839 --> 01:04:47,960 in the world of mathematics there's lots 1768 01:04:46,319 --> 01:04:49,400 of symbols that we use and we've seen 1769 01:04:47,960 --> 01:04:51,680 plus before although we used it for 1770 01:04:49,400 --> 01:04:54,000 different purpose but python supports 1771 01:04:51,680 --> 01:04:56,240 these symbols and more and python allows 1772 01:04:54,000 --> 01:04:58,559 you to add numbers together plus 1773 01:04:56,240 --> 01:05:00,359 subtract numbers uh multiply numbers 1774 01:04:58,559 --> 01:05:02,000 divide numbers and the only one here 1775 01:05:00,359 --> 01:05:04,319 that might look a little strange to 1776 01:05:02,000 --> 01:05:06,559 people or unfamiliar is this percent 1777 01:05:04,319 --> 01:05:08,960 sign but it doesn't mean percent in this 1778 01:05:06,559 --> 01:05:10,880 context if you use a single percent sign 1779 01:05:08,960 --> 01:05:13,319 in a Python program that's actually the 1780 01:05:10,880 --> 01:05:15,559 so-called modulo operator the operator 1781 01:05:13,319 --> 01:05:18,200 that allows you to take the remainder 1782 01:05:15,559 --> 01:05:20,000 after dividing one number by another so 1783 01:05:18,200 --> 01:05:22,039 we'll see examples of that before long 1784 01:05:20,000 --> 01:05:24,440 but the first four of these are perhaps 1785 01:05:22,039 --> 01:05:27,400 quite quite familiar well it turns out 1786 01:05:24,440 --> 01:05:28,880 that in Python you cannot necessarily 1787 01:05:27,400 --> 01:05:32,680 you don't necessarily have to keep 1788 01:05:28,880 --> 01:05:35,000 writing code in a file like hello.py and 1789 01:05:32,680 --> 01:05:36,960 then running it in a terminal window one 1790 01:05:35,000 --> 01:05:38,799 of the features that many people like 1791 01:05:36,960 --> 01:05:40,680 about python is that it supports this a 1792 01:05:38,799 --> 01:05:42,720 so-called interactive mode like you can 1793 01:05:40,680 --> 01:05:45,599 start writing python code and 1794 01:05:42,720 --> 01:05:47,440 immediately execute each of those lines 1795 01:05:45,599 --> 01:05:49,079 interactively if especially if you don't 1796 01:05:47,440 --> 01:05:51,279 care about saving all of your lines of 1797 01:05:49,079 --> 01:05:53,119 code you just want to execute code and 1798 01:05:51,279 --> 01:05:54,640 get back some answers so for instance 1799 01:05:53,119 --> 01:05:57,480 let me go back to VSS code here and let 1800 01:05:54,640 --> 01:05:59,200 me close hello pi and let me click on 1801 01:05:57,480 --> 01:06:00,680 the Little Triangle over here in my 1802 01:05:59,200 --> 01:06:03,039 terminal window just to make it much 1803 01:06:00,680 --> 01:06:06,160 bigger just temporarily for a moment so 1804 01:06:03,039 --> 01:06:08,839 I'm not creating any piy file now I'm 1805 01:06:06,160 --> 01:06:11,160 just going to run python by itself at my 1806 01:06:08,839 --> 01:06:13,520 prompt and you'll see when I do this I 1807 01:06:11,160 --> 01:06:15,400 get some cryptic looking output and the 1808 01:06:13,520 --> 01:06:17,119 date and time at which the program was 1809 01:06:15,400 --> 01:06:20,760 last updated and so forth but I 1810 01:06:17,119 --> 01:06:23,799 ultimately get three triple uh brackets 1811 01:06:20,760 --> 01:06:26,160 like this this is the interactive mode 1812 01:06:23,799 --> 01:06:29,279 for python so I'm running the python 1813 01:06:26,160 --> 01:06:31,039 interpreter and anytime I type A Comm a 1814 01:06:29,279 --> 01:06:32,839 line of code in The Interpreter it's 1815 01:06:31,039 --> 01:06:34,520 going to execute it immediately I don't 1816 01:06:32,839 --> 01:06:36,359 have to keep running python again and 1817 01:06:34,520 --> 01:06:38,279 again it's as though in the human world 1818 01:06:36,359 --> 01:06:40,000 if you were standing next to a human who 1819 01:06:38,279 --> 01:06:41,559 speaks some other language and you're 1820 01:06:40,000 --> 01:06:43,319 just having a conversation with them 1821 01:06:41,559 --> 01:06:45,799 back and forth It's all happening the 1822 01:06:43,319 --> 01:06:47,400 translation immediately so what might I 1823 01:06:45,799 --> 01:06:50,160 do in interactive mode well I could do 1824 01:06:47,400 --> 01:06:52,000 something like 1 + one enter that's 1825 01:06:50,160 --> 01:06:53,720 actually code right you might not think 1826 01:06:52,000 --> 01:06:56,279 of it as code but if you know a bit of 1827 01:06:53,720 --> 01:06:59,079 arithmetic and you know uh numbers and 1828 01:06:56,279 --> 01:07:00,960 you know plus that's valid python code 1829 01:06:59,079 --> 01:07:02,599 and you can use Python really as a fancy 1830 01:07:00,960 --> 01:07:05,079 calculator but I could do other things 1831 01:07:02,599 --> 01:07:07,559 too if I want to print to myself hello 1832 01:07:05,079 --> 01:07:09,720 comma world I can also print out that 1833 01:07:07,559 --> 01:07:11,200 line of code there too hello world so 1834 01:07:09,720 --> 01:07:13,880 it's interactive in the sense that the 1835 01:07:11,200 --> 01:07:15,920 moment you execute a line of code boom 1836 01:07:13,880 --> 01:07:17,440 you see the result we're generally not 1837 01:07:15,920 --> 01:07:19,400 going to do that because at least when 1838 01:07:17,440 --> 01:07:21,279 teaching the language we tend to want to 1839 01:07:19,400 --> 01:07:23,520 do things incrementally and we want you 1840 01:07:21,279 --> 01:07:24,799 to be able to see where it is we came 1841 01:07:23,520 --> 01:07:26,400 from and we want to be able to try 1842 01:07:24,799 --> 01:07:28,200 things again in again especially if we 1843 01:07:26,400 --> 01:07:30,000 make mistakes but know that this is 1844 01:07:28,200 --> 01:07:32,559 indeed a feature of python this 1845 01:07:30,000 --> 01:07:34,480 so-called interactive mode but let's 1846 01:07:32,559 --> 01:07:35,960 focus for a moment now not just on that 1847 01:07:34,480 --> 01:07:38,279 interactivity but really on the fact 1848 01:07:35,960 --> 01:07:40,400 that python apparently supports integers 1849 01:07:38,279 --> 01:07:42,000 and Mathematics and some of those basic 1850 01:07:40,400 --> 01:07:44,319 operations and let's see if we can't 1851 01:07:42,000 --> 01:07:46,359 make maybe our our own little calculator 1852 01:07:44,319 --> 01:07:48,279 so let me go ahead and open up vs code 1853 01:07:46,359 --> 01:07:50,000 again and I'm going to shrink down my 1854 01:07:48,279 --> 01:07:53,119 terminal window and I'm going to create 1855 01:07:50,000 --> 01:07:55,559 a new file called calculator. piy so to 1856 01:07:53,119 --> 01:07:57,440 do that recall I can type code down here 1857 01:07:55,559 --> 01:08:00,880 here and the name of the file I want to 1858 01:07:57,440 --> 01:08:03,640 create Pi enter that gives me a new tab 1859 01:08:00,880 --> 01:08:05,559 up top so I have already closed hello.py 1860 01:08:03,640 --> 01:08:07,480 I'm now in calculator. piy and let's 1861 01:08:05,559 --> 01:08:09,440 just make a simple calculator that does 1862 01:08:07,480 --> 01:08:11,480 some addition for me but I'm going to do 1863 01:08:09,440 --> 01:08:13,480 it in a file so that we can iterate on 1864 01:08:11,480 --> 01:08:15,440 this and make changes For Better or For 1865 01:08:13,480 --> 01:08:17,080 Worse over time let me go ahead and 1866 01:08:15,440 --> 01:08:18,759 first declare a couple variables I'm 1867 01:08:17,080 --> 01:08:21,440 going to do the mathematical thing of 1868 01:08:18,759 --> 01:08:23,520 calling my first variable X my second 1869 01:08:21,440 --> 01:08:26,880 variable Y and then I'm going to give 1870 01:08:23,520 --> 01:08:28,040 myself a third variable Z equals x + y 1871 01:08:26,880 --> 01:08:31,319 and then I'm going to go ahead and print 1872 01:08:28,040 --> 01:08:33,600 out Z now this program admittedly not 1873 01:08:31,319 --> 01:08:34,719 very exciting or interesting in fact 1874 01:08:33,600 --> 01:08:36,799 it's a little less interesting than 1875 01:08:34,719 --> 01:08:39,199 printing stuff on the screen like before 1876 01:08:36,799 --> 01:08:40,880 with strings but we'll build on this and 1877 01:08:39,199 --> 01:08:43,199 see what other features exist in Python 1878 01:08:40,880 --> 01:08:45,400 that we can leverage so hopefully if 1879 01:08:43,199 --> 01:08:48,520 python knows its math as well as I do 1880 01:08:45,400 --> 01:08:52,319 when I run python of calculator. piy I 1881 01:08:48,520 --> 01:08:54,520 should see hopefully that 1 + 2 equals 1882 01:08:52,319 --> 01:08:56,560 indeed three all right so not that 1883 01:08:54,520 --> 01:08:58,400 surprising and not that that interesting 1884 01:08:56,560 --> 01:08:59,839 and honestly this isn't the most useful 1885 01:08:58,400 --> 01:09:03,560 program because it's always going to 1886 01:08:59,839 --> 01:09:05,319 calculate 1 + 2 equal 3 let's at least 1887 01:09:03,560 --> 01:09:07,159 make this program say a little more 1888 01:09:05,319 --> 01:09:08,880 interactive right we already know from 1889 01:09:07,159 --> 01:09:10,640 previous examples how we can get input 1890 01:09:08,880 --> 01:09:12,920 from the user let's bring back that 1891 01:09:10,640 --> 01:09:15,600 input function and let's do this let me 1892 01:09:12,920 --> 01:09:18,040 go ahead now and at the top of my code 1893 01:09:15,600 --> 01:09:19,960 let's change X to not be the number one 1894 01:09:18,040 --> 01:09:22,560 always let's change it to be whatever 1895 01:09:19,960 --> 01:09:25,679 the return value is of asking the user 1896 01:09:22,560 --> 01:09:27,159 for x and I can use any English or human 1897 01:09:25,679 --> 01:09:29,640 language I want here I'm going to say 1898 01:09:27,159 --> 01:09:31,400 what's X just like I asked before what's 1899 01:09:29,640 --> 01:09:33,799 your name and I'm going to do the same 1900 01:09:31,400 --> 01:09:35,400 thing for y I'm going to use input again 1901 01:09:33,799 --> 01:09:38,239 but this time change the question to be 1902 01:09:35,400 --> 01:09:39,520 what's why all right at this point I 1903 01:09:38,239 --> 01:09:42,719 think I'm going to leave the rest of the 1904 01:09:39,520 --> 01:09:45,319 code the same Z equals X Plus Y and then 1905 01:09:42,719 --> 01:09:47,319 print Z but what's nice now is that I 1906 01:09:45,319 --> 01:09:49,199 think I have a nice interactive 1907 01:09:47,319 --> 01:09:50,799 calculator right now it's not going to 1908 01:09:49,199 --> 01:09:52,960 do 1 plus two all the time it's going to 1909 01:09:50,799 --> 01:09:55,640 do whatever the user types plus whatever 1910 01:09:52,960 --> 01:09:57,400 the user types so let's try this let me 1911 01:09:55,640 --> 01:10:00,679 go ahead and run the program all right 1912 01:09:57,400 --> 01:10:03,440 let's do it one is going to be x two is 1913 01:10:00,679 --> 01:10:08,360 going to be Y and of course everyone in 1914 01:10:03,440 --> 01:10:13,199 agreement 1 + 2 equals 1915 01:10:08,360 --> 01:10:16,520 3 huh what's going on 1916 01:10:13,199 --> 01:10:19,560 there either your math class misled you 1917 01:10:16,520 --> 01:10:21,360 or I have misled you why don't we call 1918 01:10:19,560 --> 01:10:23,760 on someone here to see if you can't help 1919 01:10:21,360 --> 01:10:26,040 us reason through what the bug is what's 1920 01:10:23,760 --> 01:10:29,120 the mistake uh on jalli if I'm saying it 1921 01:10:26,040 --> 01:10:31,120 right I think the issue is is that it's 1922 01:10:29,120 --> 01:10:33,440 concatenating strings because you use 1923 01:10:31,120 --> 01:10:35,400 the plus operator instead of adding 1924 01:10:33,440 --> 01:10:37,760 perfect so perfect intuition we've seen 1925 01:10:35,400 --> 01:10:39,400 that plus is used a little differently 1926 01:10:37,760 --> 01:10:41,280 in the context of strings because it 1927 01:10:39,400 --> 01:10:43,360 concatenates that is it joins the two 1928 01:10:41,280 --> 01:10:44,560 strings and that seems to indeed be 1929 01:10:43,360 --> 01:10:46,800 what's happening here even though the 1930 01:10:44,560 --> 01:10:48,800 user types a number but the interesting 1931 01:10:46,800 --> 01:10:51,000 thing here is that when you get user 1932 01:10:48,800 --> 01:10:53,199 input because they're using a keyboard 1933 01:10:51,000 --> 01:10:55,520 on their Mac or PC or their phone it is 1934 01:10:53,199 --> 01:10:57,520 always going to be text it might look 1935 01:10:55,520 --> 01:11:00,960 like a number but by default it's coming 1936 01:10:57,520 --> 01:11:04,239 from the keyboard as a string that is as 1937 01:11:00,960 --> 01:11:05,920 text and so how do we go about re uh 1938 01:11:04,239 --> 01:11:08,400 resolving this if ultimately we don't 1939 01:11:05,920 --> 01:11:10,120 want to treat those inputs as strings we 1940 01:11:08,400 --> 01:11:11,960 want to treat them as actual numbers 1941 01:11:10,120 --> 01:11:14,719 well we need another function and it 1942 01:11:11,960 --> 01:11:16,679 turns out in Python that you can convert 1943 01:11:14,719 --> 01:11:18,400 sometimes from one type of data to 1944 01:11:16,679 --> 01:11:21,360 another type of data for instance from 1945 01:11:18,400 --> 01:11:23,840 string to int by doing something like 1946 01:11:21,360 --> 01:11:27,400 this let me go back into my code and let 1947 01:11:23,840 --> 01:11:30,600 me change X before adding it to Y to be 1948 01:11:27,400 --> 01:11:33,480 whatever the integer version of X is 1949 01:11:30,600 --> 01:11:36,199 plus whatever the integer version of Y 1950 01:11:33,480 --> 01:11:38,719 is so it turns out that int is not only 1951 01:11:36,199 --> 01:11:41,080 a type of data in Python it's also a 1952 01:11:38,719 --> 01:11:44,040 function and it's a function that if you 1953 01:11:41,080 --> 01:11:46,159 pass in an input like a string so long 1954 01:11:44,040 --> 01:11:49,280 as that string looks like a number like 1955 01:11:46,159 --> 01:11:50,719 one or like two it will convert it to an 1956 01:11:49,280 --> 01:11:53,719 actual number that you can perform 1957 01:11:50,719 --> 01:11:55,920 mathematics on instead so if I now go 1958 01:11:53,719 --> 01:11:58,040 back to my terminal window and run 1959 01:11:55,920 --> 01:11:59,800 Python and let me show you another trick 1960 01:11:58,040 --> 01:12:01,760 calculator is kind of a long word it's a 1961 01:11:59,800 --> 01:12:04,280 little tedious to type notice what I can 1962 01:12:01,760 --> 01:12:05,960 do in my terminal window in a command 1963 01:12:04,280 --> 01:12:09,360 line interface in general if I start 1964 01:12:05,960 --> 01:12:12,159 typing C for calculator I can actually 1965 01:12:09,360 --> 01:12:14,000 hit tab to finish my thought so 1966 01:12:12,159 --> 01:12:15,600 autocomplete is possible in a terminal 1967 01:12:14,000 --> 01:12:17,760 window like this type the first letter 1968 01:12:15,600 --> 01:12:19,400 or few letters and then boom with tab 1969 01:12:17,760 --> 01:12:21,040 it'll finish your thought for you or you 1970 01:12:19,400 --> 01:12:23,120 can go back in your history like I did 1971 01:12:21,040 --> 01:12:25,920 with the up and down arrows let me go 1972 01:12:23,120 --> 01:12:28,800 ahead and execute this what's X X1 1973 01:12:25,920 --> 01:12:30,600 what's X2 and there we go now we have a 1974 01:12:28,800 --> 01:12:33,560 general purpose calculator that's going 1975 01:12:30,600 --> 01:12:35,920 to support not just uh addition of one 1976 01:12:33,560 --> 01:12:38,000 and two but now any two integers that 1977 01:12:35,920 --> 01:12:39,920 the user types and let me now improve 1978 01:12:38,000 --> 01:12:42,480 this right we've seen how we can make 1979 01:12:39,920 --> 01:12:43,760 improvements to code and I don't know if 1980 01:12:42,480 --> 01:12:46,880 it's going to necessarily be better but 1981 01:12:43,760 --> 01:12:49,000 let's try this do I really need the Z 1982 01:12:46,880 --> 01:12:52,000 variable it's worth noting that I'm 1983 01:12:49,000 --> 01:12:53,800 creating a variable called c z and then 1984 01:12:52,000 --> 01:12:56,320 I'm immediately using it on the next 1985 01:12:53,800 --> 01:12:58,199 line of code now that's not that 1986 01:12:56,320 --> 01:13:00,040 compelling because if you're creating a 1987 01:12:58,199 --> 01:13:02,040 variable and then immediately using it 1988 01:13:00,040 --> 01:13:03,880 but never again using it did you really 1989 01:13:02,040 --> 01:13:06,440 need to take the time to introduce 1990 01:13:03,880 --> 01:13:08,840 another symbol and another variable just 1991 01:13:06,440 --> 01:13:11,239 to use it once and only once well maybe 1992 01:13:08,840 --> 01:13:15,159 not maybe we don't really need Z in this 1993 01:13:11,239 --> 01:13:18,440 way maybe I should go and do something 1994 01:13:15,159 --> 01:13:21,560 uh like this maybe I should get rid of Z 1995 01:13:18,440 --> 01:13:24,960 here maybe I should change this to be 1996 01:13:21,560 --> 01:13:27,320 int up here change this to be int up 1997 01:13:24,960 --> 01:13:28,960 here here doing something that's pretty 1998 01:13:27,320 --> 01:13:32,800 interesting now even though it's a bit 1999 01:13:28,960 --> 01:13:36,000 of new syntax notice that you can Nest 2000 01:13:32,800 --> 01:13:38,920 function so to speak you can put one 2001 01:13:36,000 --> 01:13:40,760 function call that is the use of a 2002 01:13:38,920 --> 01:13:43,440 function inside of the use of another 2003 01:13:40,760 --> 01:13:47,040 function so that the return value of the 2004 01:13:43,440 --> 01:13:49,480 inner function becomes the argument to 2005 01:13:47,040 --> 01:13:50,800 or the input to the outer function so 2006 01:13:49,480 --> 01:13:52,480 just like in math if you have 2007 01:13:50,800 --> 01:13:54,239 parentheses parentheses parentheses your 2008 01:13:52,480 --> 01:13:56,159 teacher probably taught you to focus on 2009 01:13:54,239 --> 01:13:57,960 what's inside the innermost parenthesis 2010 01:13:56,159 --> 01:13:59,159 first and then work your way out same 2011 01:13:57,960 --> 01:14:00,440 thing with programming that's what 2012 01:13:59,159 --> 01:14:02,120 Python's going to do it's going to look 2013 01:14:00,440 --> 01:14:04,560 at what's inside of the parenthesis 2014 01:14:02,120 --> 01:14:06,960 first it's going to get the answer and 2015 01:14:04,560 --> 01:14:09,040 then it's going to pass the return value 2016 01:14:06,960 --> 01:14:10,639 to the outermost function so what 2017 01:14:09,040 --> 01:14:13,159 happens on line one now is that the 2018 01:14:10,639 --> 01:14:16,199 input function gets called first then 2019 01:14:13,159 --> 01:14:19,320 the result of that quote unquote one 2020 01:14:16,199 --> 01:14:21,360 becomes the input to the int function 2021 01:14:19,320 --> 01:14:24,520 and same on line two the output of 2022 01:14:21,360 --> 01:14:28,000 what's y becomes the input to this int 2023 01:14:24,520 --> 01:14:31,159 function and now there is no Z I could 2024 01:14:28,000 --> 01:14:33,840 just do print x + y and because I've 2025 01:14:31,159 --> 01:14:36,679 taken the time to convert each of those 2026 01:14:33,840 --> 01:14:38,760 strings to an integer I think we're okay 2027 01:14:36,679 --> 01:14:42,400 so let me try this python of calculator. 2028 01:14:38,760 --> 01:14:45,960 piy enter one and two and we're still 2029 01:14:42,400 --> 01:14:47,480 getting three not 12 or not 12 one two 2030 01:14:45,960 --> 01:14:49,560 we're indeed getting three and we've 2031 01:14:47,480 --> 01:14:51,520 additionally gotten rid of the variable 2032 01:14:49,560 --> 01:14:53,560 because we didn't necessarily need it it 2033 01:14:51,520 --> 01:14:55,159 seems especially if only using it once 2034 01:14:53,560 --> 01:14:56,719 well here too let me put everyone's 2035 01:14:55,159 --> 01:15:00,120 hands down for just a moment and let me 2036 01:14:56,719 --> 01:15:04,760 ask as before this version now which 2037 01:15:00,120 --> 01:15:07,600 uses int around the invocations of input 2038 01:15:04,760 --> 01:15:09,440 and does not use Z is this better than 2039 01:15:07,600 --> 01:15:12,040 the previous version if you want to vote 2040 01:15:09,440 --> 01:15:15,080 yes go ahead or if you prefer the old 2041 01:15:12,040 --> 01:15:20,280 Way vote no the old way I'll undo all of 2042 01:15:15,080 --> 01:15:20,280 this as we vote instead looked like 2043 01:15:20,520 --> 01:15:24,639 this all right and let me go back to now 2044 01:15:22,840 --> 01:15:27,520 the newest version let's take a hand of 2045 01:15:24,639 --> 01:15:30,960 the is someone who thinks this latest 2046 01:15:27,520 --> 01:15:33,800 version is better I think this way is 2047 01:15:30,960 --> 01:15:37,000 better because it uh allows us to 2048 01:15:33,800 --> 01:15:40,960 immediately see what the X and Y 2049 01:15:37,000 --> 01:15:43,760 variables are with um integers and so we 2050 01:15:40,960 --> 01:15:47,320 know what to expect from them and also 2051 01:15:43,760 --> 01:15:49,880 the print argument is more U intuitive 2052 01:15:47,320 --> 01:15:52,199 we avoid too much clutter uh in the 2053 01:15:49,880 --> 01:15:54,000 codes I think those are all good reasons 2054 01:15:52,199 --> 01:15:55,639 it's nice and succinct the lines of code 2055 01:15:54,000 --> 01:15:57,560 are not very long 2056 01:15:55,639 --> 01:15:59,040 uh I don't need to know what Z is 2057 01:15:57,560 --> 01:16:00,920 because it doesn't exist it just see 2058 01:15:59,040 --> 01:16:03,320 print X Plus y I like that but someone 2059 01:16:00,920 --> 01:16:06,760 who prefers the older way where we did 2060 01:16:03,320 --> 01:16:09,080 have Z and we more explicitly passed 2061 01:16:06,760 --> 01:16:12,080 individual variables to the int function 2062 01:16:09,080 --> 01:16:15,320 yeah hi uh I think the earlier version 2063 01:16:12,080 --> 01:16:17,400 is better because when uh I mean if user 2064 01:16:15,320 --> 01:16:20,239 inputs something else other than in 2065 01:16:17,400 --> 01:16:23,360 let's say I mean let's say the type one 2066 01:16:20,239 --> 01:16:26,239 and two like so it be it will be easier 2067 01:16:23,360 --> 01:16:28,600 to debug this version or the this 2068 01:16:26,239 --> 01:16:30,840 version here or the old version the old 2069 01:16:28,600 --> 01:16:33,679 version okay that's fair and in fact I'm 2070 01:16:30,840 --> 01:16:36,639 I'm being very careful today as best I 2071 01:16:33,679 --> 01:16:38,600 can not to mess up I have thus far only 2072 01:16:36,639 --> 01:16:40,520 inputed integers when I'm expecting 2073 01:16:38,600 --> 01:16:41,679 integers and R is actually pointing to 2074 01:16:40,520 --> 01:16:43,440 something we'll come back to in the 2075 01:16:41,679 --> 01:16:45,560 coming weeks how do we actually handle 2076 01:16:43,440 --> 01:16:47,639 errors what if the user doesn't type in 2077 01:16:45,560 --> 01:16:49,080 the number one or the number two or a 2078 01:16:47,639 --> 01:16:52,320 number at all what if they type in a 2079 01:16:49,080 --> 01:16:53,760 word like cat c a t that's not a number 2080 01:16:52,320 --> 01:16:55,440 and I bet I can't convert it to an 2081 01:16:53,760 --> 01:16:56,719 integer but for today I'm not going to 2082 01:16:55,440 --> 01:16:58,800 focus on that I'm just going to hope 2083 01:16:56,719 --> 01:17:00,600 that the user cooperates but that's not 2084 01:16:58,800 --> 01:17:02,239 going to be the case and so perhaps one 2085 01:17:00,600 --> 01:17:04,159 way would set us up for more success 2086 01:17:02,239 --> 01:17:06,480 when it comes to handling those errors 2087 01:17:04,159 --> 01:17:08,360 now for today's purposes which is better 2088 01:17:06,480 --> 01:17:10,199 h i mean I like both and I think both of 2089 01:17:08,360 --> 01:17:12,520 you made very valid arguments in there 2090 01:17:10,199 --> 01:17:14,520 too so long as you have a justification 2091 01:17:12,520 --> 01:17:16,159 that feels pretty reasonable I mean 2092 01:17:14,520 --> 01:17:19,199 that's what ultimately matters but 2093 01:17:16,159 --> 01:17:22,040 acquiring again a sense of the tradeoffs 2094 01:17:19,199 --> 01:17:24,000 here well is this way better if so why 2095 01:17:22,040 --> 01:17:26,120 or why not just understanding what those 2096 01:17:24,000 --> 01:17:28,960 trade-offs are but generally speaking 2097 01:17:26,120 --> 01:17:31,199 prioritizing readability is a very good 2098 01:17:28,960 --> 01:17:33,159 thing making your code readable for 2099 01:17:31,199 --> 01:17:34,880 someone else is a very good thing and 2100 01:17:33,159 --> 01:17:36,159 very good for you too so that when you 2101 01:17:34,880 --> 01:17:37,960 wake up the next morning or you come 2102 01:17:36,159 --> 01:17:39,719 back the next week or the next year you 2103 01:17:37,960 --> 01:17:41,520 too can read your own code without 2104 01:17:39,719 --> 01:17:44,080 having to waste time trying to remember 2105 01:17:41,520 --> 01:17:45,920 what you did and simplicity tends to be 2106 01:17:44,080 --> 01:17:48,360 a good thing too keeping your code 2107 01:17:45,920 --> 01:17:49,840 simple so is as you get more comfortable 2108 01:17:48,360 --> 01:17:52,239 with programming you might be tempted to 2109 01:17:49,840 --> 01:17:54,040 try to like combine an entire program 2110 01:17:52,239 --> 01:17:55,760 into one long line for instance let me 2111 01:17:54,040 --> 01:17:57,040 do right just that that don't 2112 01:17:55,760 --> 01:17:59,320 technically speaking we don't really 2113 01:17:57,040 --> 01:18:01,920 need X in a variable we don't really 2114 01:17:59,320 --> 01:18:05,199 need Y in a variable we could also do 2115 01:18:01,920 --> 01:18:08,280 this I could just get rid of X and Y Al 2116 01:18:05,199 --> 01:18:10,480 together I could then now eliminate that 2117 01:18:08,280 --> 01:18:12,040 and make it just one line of code okay 2118 01:18:10,480 --> 01:18:14,000 so on some sense you might be inclined 2119 01:18:12,040 --> 01:18:17,120 to think wow that's really nice you made 2120 01:18:14,000 --> 01:18:18,880 it one simple line of code I would argue 2121 01:18:17,120 --> 01:18:20,800 this actually isn't that simple now I 2122 01:18:18,880 --> 01:18:23,040 think I'm starting to Nest too many 2123 01:18:20,800 --> 01:18:25,440 things I have to think about print and 2124 01:18:23,040 --> 01:18:27,320 int and input I then have to notice that 2125 01:18:25,440 --> 01:18:29,280 okay I've opened two parentheses I've 2126 01:18:27,320 --> 01:18:31,120 closed two of them there's a plus you're 2127 01:18:29,280 --> 01:18:33,080 making me think too much and anytime you 2128 01:18:31,120 --> 01:18:35,400 make me think you're wasting time and 2129 01:18:33,080 --> 01:18:37,000 anytime you complicate the look of the 2130 01:18:35,400 --> 01:18:39,239 code like this you're just going to 2131 01:18:37,000 --> 01:18:41,400 increase the probability of mistakes 2132 01:18:39,239 --> 01:18:43,400 syntactical mistakes or logical errors 2133 01:18:41,400 --> 01:18:45,199 in your code so of all the things we've 2134 01:18:43,400 --> 01:18:48,120 done this is the only one that I would 2135 01:18:45,199 --> 01:18:49,960 argue yes it's one line and it's nice 2136 01:18:48,120 --> 01:18:52,080 and compact it's just not readable 2137 01:18:49,960 --> 01:18:53,840 enough I would shy away from doing this 2138 01:18:52,080 --> 01:18:56,040 especially since two of those function 2139 01:18:53,840 --> 01:18:57,560 calls are getting input from the user 2140 01:18:56,040 --> 01:18:59,480 but there too reasonable people might 2141 01:18:57,560 --> 01:19:01,159 disagree but that's the kind of like 2142 01:18:59,480 --> 01:19:03,040 visceral reaction you should have 2143 01:19:01,159 --> 01:19:05,600 sometimes when code starts getting a 2144 01:19:03,040 --> 01:19:08,520 little too complicated a little too 2145 01:19:05,600 --> 01:19:10,520 clever perhaps for its own 2146 01:19:08,520 --> 01:19:12,600 good all right well it's not just 2147 01:19:10,520 --> 01:19:15,320 integers we have access to let me 2148 01:19:12,600 --> 01:19:17,560 propose that we transition from integers 2149 01:19:15,320 --> 01:19:20,880 to one more data type here namely a 2150 01:19:17,560 --> 01:19:23,320 float so again a string is a sequence of 2151 01:19:20,880 --> 01:19:26,080 text an INT is an integer like negative 2152 01:19:23,320 --> 01:19:28,520 1 0 and one a a float is a number with a 2153 01:19:26,080 --> 01:19:30,440 decimal point properly called a floating 2154 01:19:28,520 --> 01:19:32,080 point value and you can think of the 2155 01:19:30,440 --> 01:19:33,880 floating Point as being the decimal that 2156 01:19:32,080 --> 01:19:35,480 might be over here or over here with 2157 01:19:33,880 --> 01:19:37,360 some number of digits to the left or the 2158 01:19:35,480 --> 01:19:39,960 right mathematically it's a real number 2159 01:19:37,360 --> 01:19:41,800 a number that has a decimal point in it 2160 01:19:39,960 --> 01:19:44,000 so that's a third type of data that 2161 01:19:41,800 --> 01:19:45,760 python supports right now our calculator 2162 01:19:44,000 --> 01:19:47,880 is somewhat naively assuming that the 2163 01:19:45,760 --> 01:19:49,840 user is only going to type in integers 2164 01:19:47,880 --> 01:19:52,080 but if I want to support floating Point 2165 01:19:49,840 --> 01:19:53,800 values too I think I can just make a 2166 01:19:52,080 --> 01:19:56,320 couple of tweaks so I'm going to go back 2167 01:19:53,800 --> 01:19:58,920 to VSS code here and instead of just 2168 01:19:56,320 --> 01:20:01,000 converting the user's input X and Y to 2169 01:19:58,920 --> 01:20:02,480 integers on line one and two let's just 2170 01:20:01,000 --> 01:20:05,600 make a simple change let's actually 2171 01:20:02,480 --> 01:20:09,159 convert it to a float on the first line 2172 01:20:05,600 --> 01:20:10,520 and a float on the second line here now 2173 01:20:09,159 --> 01:20:13,560 I think if I go down to my terminal 2174 01:20:10,520 --> 01:20:16,159 window and run python of calculator. Pi 2175 01:20:13,560 --> 01:20:19,159 let's type in a number like 1.2 with a 2176 01:20:16,159 --> 01:20:21,719 decimal point and 3.4 with the decimal 2177 01:20:19,159 --> 01:20:23,199 point and there we go we have 4.6 as the 2178 01:20:21,719 --> 01:20:25,760 final answer so that wouldn't have 2179 01:20:23,199 --> 01:20:27,400 worked before if I were only expecting 2180 01:20:25,760 --> 01:20:29,480 integers from the user but now that I'm 2181 01:20:27,400 --> 01:20:31,480 support expecting floating Point values 2182 01:20:29,480 --> 01:20:34,440 and accommodating it I can actually now 2183 01:20:31,480 --> 01:20:35,960 do floating Point arithmetic as well but 2184 01:20:34,440 --> 01:20:39,800 suppose that I don't really want the 2185 01:20:35,960 --> 01:20:42,159 final answer to be a floating point 2186 01:20:39,800 --> 01:20:44,080 value like 4.6 I would be happy if we 2187 01:20:42,159 --> 01:20:46,199 just round to the nearest integer so I 2188 01:20:44,080 --> 01:20:47,719 want to support the user typing in 2189 01:20:46,199 --> 01:20:49,239 floating Point values with decimal 2190 01:20:47,719 --> 01:20:51,800 points but at the end of the day I just 2191 01:20:49,239 --> 01:20:54,159 want to round the result to the nearest 2192 01:20:51,800 --> 01:20:57,080 possible integer for instance well it 2193 01:20:54,159 --> 01:20:59,199 turns out out that here too python comes 2194 01:20:57,080 --> 01:21:01,080 with some functionality built in and in 2195 01:20:59,199 --> 01:21:03,040 fact if we return to this URL from 2196 01:21:01,080 --> 01:21:04,880 earlier where in all of the Python 2197 01:21:03,040 --> 01:21:07,360 built-in functions are listed there's 2198 01:21:04,880 --> 01:21:09,040 one called round which does exactly as 2199 01:21:07,360 --> 01:21:11,360 we would expect it takes as input a 2200 01:21:09,040 --> 01:21:13,440 number and then rounds it for us for 2201 01:21:11,360 --> 01:21:16,080 instance to the nearest digit to the 2202 01:21:13,440 --> 01:21:17,880 nearest integer but if we look a little 2203 01:21:16,080 --> 01:21:20,600 closer at that documentation as we can 2204 01:21:17,880 --> 01:21:22,520 here I'll provide an excerpt this is 2205 01:21:20,600 --> 01:21:24,719 what the function looks like in the 2206 01:21:22,520 --> 01:21:26,639 documentation and recall that earlier we 2207 01:21:24,719 --> 01:21:28,719 looked at the documentation for print 2208 01:21:26,639 --> 01:21:30,040 and this is similar in spirit that this 2209 01:21:28,719 --> 01:21:32,440 shows us not just the name of the 2210 01:21:30,040 --> 01:21:34,920 function but it's available parameters 2211 01:21:32,440 --> 01:21:36,520 that is inputs that we can provide when 2212 01:21:34,920 --> 01:21:38,600 using this function but this is a little 2213 01:21:36,520 --> 01:21:40,719 cryptic too just like Prince was and it 2214 01:21:38,600 --> 01:21:42,840 adds some syntax so let's see the name 2215 01:21:40,719 --> 01:21:45,480 of this function here is of course round 2216 01:21:42,840 --> 01:21:47,320 and its first argument is a number 2217 01:21:45,480 --> 01:21:49,000 notice this times there's no star 2218 01:21:47,320 --> 01:21:51,320 there's no star objects like there was 2219 01:21:49,000 --> 01:21:54,120 for print the round function takes just 2220 01:21:51,320 --> 01:21:57,199 one number as its first argument period 2221 01:21:54,120 --> 01:21:58,760 that's it positional parameter but 2222 01:21:57,199 --> 01:22:00,719 notice this syntax and this is a 2223 01:21:58,760 --> 01:22:02,920 convention in programming or technology 2224 01:22:00,719 --> 01:22:05,199 more generally generally speaking when 2225 01:22:02,920 --> 01:22:06,840 you see square brackets in documentation 2226 01:22:05,199 --> 01:22:09,080 like this this means that you're about 2227 01:22:06,840 --> 01:22:10,560 to see something optional and so what 2228 01:22:09,080 --> 01:22:13,199 this means is that if you want to 2229 01:22:10,560 --> 01:22:15,440 specify more precisely the number of 2230 01:22:13,199 --> 01:22:19,480 digits that you want the round function 2231 01:22:15,440 --> 01:22:21,920 to round to you can specify it here by 2232 01:22:19,480 --> 01:22:23,560 adding a comma and then that number so 2233 01:22:21,920 --> 01:22:26,440 if we read the documentation if you 2234 01:22:23,560 --> 01:22:28,480 don't specify a number of digits you 2235 01:22:26,440 --> 01:22:30,280 just specify the number to Round it 2236 01:22:28,480 --> 01:22:32,159 rounds to the nearest integer but 2237 01:22:30,280 --> 01:22:34,400 suppose you want to round to the 10's 2238 01:22:32,159 --> 01:22:36,400 place or the hundreds place that is one 2239 01:22:34,400 --> 01:22:38,880 or two digits after the decimal point 2240 01:22:36,400 --> 01:22:42,600 you could additionally pass in comma one 2241 01:22:38,880 --> 01:22:44,320 or comma 2 to be more precise so that's 2242 01:22:42,600 --> 01:22:45,960 what the documentation there is saying 2243 01:22:44,320 --> 01:22:48,679 let's see if we can't then translate 2244 01:22:45,960 --> 01:22:51,639 this to some actual code for us so if I 2245 01:22:48,679 --> 01:22:53,679 go back now to vs code and I consider 2246 01:22:51,639 --> 01:22:56,520 that I want to go ahead and round X and 2247 01:22:53,679 --> 01:23:00,639 Y I can do this in a couple of ways I 2248 01:22:56,520 --> 01:23:01,920 could do round X+ y but uh you know I'd 2249 01:23:00,639 --> 01:23:04,320 actually kind of prefer to break this 2250 01:23:01,920 --> 01:23:05,639 now out into two lines I don't have to 2251 01:23:04,320 --> 01:23:07,880 and reasonable people here might 2252 01:23:05,639 --> 01:23:09,719 disagree but I'd like to revert to a 2253 01:23:07,880 --> 01:23:11,800 scenario where I'm printing Z so that I 2254 01:23:09,719 --> 01:23:14,440 can just a little more clearly to myself 2255 01:23:11,800 --> 01:23:18,120 to others say Z equals the rounded 2256 01:23:14,440 --> 01:23:19,600 result of x + y it's not necessarily the 2257 01:23:18,120 --> 01:23:21,199 better way to do it but I'm a little 2258 01:23:19,600 --> 01:23:23,199 more comfortable with breaking out my 2259 01:23:21,199 --> 01:23:25,280 thoughts one at a time especially if I 2260 01:23:23,199 --> 01:23:27,239 want to start commenting of these chunks 2261 01:23:25,280 --> 01:23:29,000 of code all right let me go down to my 2262 01:23:27,239 --> 01:23:31,920 terminal window now and run python of 2263 01:23:29,000 --> 01:23:35,320 calculator. Pi what's X let's do 1.2 2264 01:23:31,920 --> 01:23:38,639 again then let's do 3.4 and now it was 2265 01:23:35,320 --> 01:23:40,199 previously 4.6 but now it's been rounded 2266 01:23:38,639 --> 01:23:43,120 up to the nearest integer which of 2267 01:23:40,199 --> 01:23:46,440 course is going to be five all right 2268 01:23:43,120 --> 01:23:48,239 what if I wanted to change this a little 2269 01:23:46,440 --> 01:23:50,920 further what if I wanted to support 2270 01:23:48,239 --> 01:23:52,600 maybe really big numbers big numbers 2271 01:23:50,920 --> 01:23:54,480 irrespective of rounding let's just do 2272 01:23:52,600 --> 01:23:56,520 something like this let me go ahead and 2273 01:23:54,480 --> 01:23:58,000 run python of calculator. Pi again and 2274 01:23:56,520 --> 01:24:02,199 let me just add 2275 01:23:58,000 --> 01:24:03,520 999 + 1 and notice I don't have to type 2276 01:24:02,199 --> 01:24:05,800 decimal points even though I'm 2277 01:24:03,520 --> 01:24:07,639 converting to float my program will just 2278 01:24:05,800 --> 01:24:09,239 allow me to type decimal points but I 2279 01:24:07,639 --> 01:24:11,400 don't need to oblige the answer of 2280 01:24:09,239 --> 01:24:14,120 course here should be and is in fact 2281 01:24:11,400 --> 01:24:16,840 1,000 whether or not we round so that's 2282 01:24:14,120 --> 01:24:20,360 just arithmetic with integers here but 2283 01:24:16,840 --> 01:24:23,320 in uh the us we tend to format long 2284 01:24:20,360 --> 01:24:25,800 numbers by putting commas uh after or 2285 01:24:23,320 --> 01:24:27,600 before every triple of digits other 2286 01:24:25,800 --> 01:24:29,280 countries flip it and they use periods 2287 01:24:27,600 --> 01:24:30,880 and commas instead that's a system 2288 01:24:29,280 --> 01:24:33,679 setting you can change that on your own 2289 01:24:30,880 --> 01:24:36,560 Mac or PC or device for python or any 2290 01:24:33,679 --> 01:24:38,360 language but for me I'm using the uh us 2291 01:24:36,560 --> 01:24:41,000 approach here which is periods for 2292 01:24:38,360 --> 01:24:42,920 decimal points and commas for separators 2293 01:24:41,000 --> 01:24:45,040 what if I wanted this to be outputed as 2294 01:24:42,920 --> 01:24:47,639 1 comma 2295 01:24:45,040 --> 01:24:49,880 0000 just to make it a little more clear 2296 01:24:47,639 --> 01:24:51,480 that it's 1,000 and not something like 2297 01:24:49,880 --> 01:24:56,119 100 that's even more useful when it's 2298 01:24:51,480 --> 01:24:57,199 like 1 million 1 comma 00 comma 00 0 2299 01:24:56,119 --> 01:24:59,119 wouldn't it be nice if we could 2300 01:24:57,199 --> 01:25:02,000 automatically output those numbers as 2301 01:24:59,119 --> 01:25:05,000 well well it turns out that we can there 2302 01:25:02,000 --> 01:25:07,840 is a way using python to actually 2303 01:25:05,000 --> 01:25:09,600 specify that we want to include commas 2304 01:25:07,840 --> 01:25:11,600 like this and here we have an 2305 01:25:09,600 --> 01:25:14,000 opportunity to bring back our old friend 2306 01:25:11,600 --> 01:25:16,159 the F string first let me do something 2307 01:25:14,000 --> 01:25:18,960 that's not that productive first let me 2308 01:25:16,159 --> 01:25:20,400 do this let me print out the value of Z 2309 01:25:18,960 --> 01:25:22,040 but wait a minute I can't just say quote 2310 01:25:20,400 --> 01:25:24,600 unquote Z because that's literally going 2311 01:25:22,040 --> 01:25:26,719 to print Z on the screen so let me wrap 2312 01:25:24,600 --> 01:25:28,960 it with those curly braces like I did 2313 01:25:26,719 --> 01:25:31,080 before but that two was not enough I 2314 01:25:28,960 --> 01:25:32,679 literally needed to add an F at the 2315 01:25:31,080 --> 01:25:35,239 beginning of my string to tell python 2316 01:25:32,679 --> 01:25:37,520 that this is an F string a format string 2317 01:25:35,239 --> 01:25:40,280 that now is going to print out not very 2318 01:25:37,520 --> 01:25:42,199 interestingly just the value of Z itself 2319 01:25:40,280 --> 01:25:44,280 so that I'm going to Great Lengths just 2320 01:25:42,199 --> 01:25:46,560 to print Z when really I could have just 2321 01:25:44,280 --> 01:25:49,280 passed Z as the sole argument but just 2322 01:25:46,560 --> 01:25:52,600 to ensure that I haven't broken it let's 2323 01:25:49,280 --> 01:25:54,360 do this again 999 + 1 enter okay it's 2324 01:25:52,600 --> 01:25:56,639 still a th so I didn't make anything 2325 01:25:54,360 --> 01:25:59,159 worse but notice and this syntax is 2326 01:25:56,639 --> 01:26:01,920 unfortunately a bit cryptic notice that 2327 01:25:59,159 --> 01:26:04,679 I can actually do this I can put a colon 2328 01:26:01,920 --> 01:26:06,840 after the Z and I can put a comma 2329 01:26:04,679 --> 01:26:08,719 thereafter this looks very cryptic 2330 01:26:06,840 --> 01:26:09,880 admittedly and even I have to constantly 2331 01:26:08,719 --> 01:26:12,199 look things like this up in the 2332 01:26:09,880 --> 01:26:14,600 documentation to remember the syntax but 2333 01:26:12,199 --> 01:26:17,000 here let me run it again python of 2334 01:26:14,600 --> 01:26:20,040 calculator. 2335 01:26:17,000 --> 01:26:22,159 9991 and now notice that the number has 2336 01:26:20,040 --> 01:26:23,800 been automatically formatted for me if I 2337 01:26:22,159 --> 01:26:25,840 were in a different country or local I 2338 01:26:23,800 --> 01:26:27,679 could abs absolutely override this to 2339 01:26:25,840 --> 01:26:29,679 use periods instead of commas or vice 2340 01:26:27,679 --> 01:26:31,320 versa but in this case here it's just 2341 01:26:29,679 --> 01:26:33,040 happening for me automatically so there 2342 01:26:31,320 --> 01:26:35,159 too we see a hint of what it means to 2343 01:26:33,040 --> 01:26:37,920 really format a string there's even more 2344 01:26:35,159 --> 01:26:40,159 power more powerful capabilities built 2345 01:26:37,920 --> 01:26:42,239 into that all right let me pause here to 2346 01:26:40,159 --> 01:26:47,480 see if there's any questions now on 2347 01:26:42,239 --> 01:26:50,159 floats on rounding or on this use of f 2348 01:26:47,480 --> 01:26:52,880 strings yes so I have a question so when 2349 01:26:50,159 --> 01:26:54,760 using floats um is it like a cap to how 2350 01:26:52,880 --> 01:26:56,920 many decimal points you can have 2351 01:26:54,760 --> 01:26:58,639 a really good question so floats yes and 2352 01:26:56,920 --> 01:27:01,880 this is a problem we'll revisit before 2353 01:26:58,639 --> 01:27:04,400 long floats cannot represent numbers 2354 01:27:01,880 --> 01:27:05,800 infinitely precisely in a nutshell 2355 01:27:04,400 --> 01:27:07,480 because computers only have so much 2356 01:27:05,800 --> 01:27:09,960 memory they only have a finite amount of 2357 01:27:07,480 --> 01:27:11,560 memory you and I only have a finite uh 2358 01:27:09,960 --> 01:27:13,400 amount of Hardware inside of the 2359 01:27:11,560 --> 01:27:15,440 computer so at some point they're going 2360 01:27:13,400 --> 01:27:17,239 to have to Round right now I'm rounding 2361 01:27:15,440 --> 01:27:18,719 automatically effectively computers will 2362 01:27:17,239 --> 01:27:20,760 eventually have to do that for us but 2363 01:27:18,719 --> 01:27:23,199 we'll see that as a fundamental problem 2364 01:27:20,760 --> 01:27:25,679 before long allow me to turn back just 2365 01:27:23,199 --> 01:27:27,320 for a few final examples on Flo before 2366 01:27:25,679 --> 01:27:29,040 we introduce a few final examples that 2367 01:27:27,320 --> 01:27:31,520 allow us not just to use functions but 2368 01:27:29,040 --> 01:27:34,520 to make our own let me propose that we 2369 01:27:31,520 --> 01:27:36,560 also try our hand at a bit of division 2370 01:27:34,520 --> 01:27:38,159 here let me propose that we modify this 2371 01:27:36,560 --> 01:27:40,440 calculator now to still take a couple of 2372 01:27:38,159 --> 01:27:42,360 floats but let's now just do something a 2373 01:27:40,440 --> 01:27:45,360 little simpler than uh a little 2374 01:27:42,360 --> 01:27:46,560 different from this just doing x ided y 2375 01:27:45,360 --> 01:27:48,040 and let me go ahead and get rid of my 2376 01:27:46,560 --> 01:27:50,920 format string and just keep it simple 2377 01:27:48,040 --> 01:27:52,239 for now printing out Z instead and what 2378 01:27:50,920 --> 01:27:55,159 are we going to see here well just some 2379 01:27:52,239 --> 01:27:58,199 simple division so python of calculat Pi 2380 01:27:55,159 --> 01:28:01,199 let's do something like 2 / 3 and of 2381 01:27:58,199 --> 01:28:03,080 course I get 66666 and to Ethan's 2382 01:28:01,199 --> 01:28:05,159 question a moment ago it does seem to be 2383 01:28:03,080 --> 01:28:07,719 finite it's not rounding in a weird way 2384 01:28:05,159 --> 01:28:10,800 here but I only seem to see so many 2385 01:28:07,719 --> 01:28:13,159 digits that's a uh an inevitability of 2386 01:28:10,800 --> 01:28:15,040 using a float in this way by contrast 2387 01:28:13,159 --> 01:28:17,360 just so you know integers nowadays in 2388 01:28:15,040 --> 01:28:19,320 Python can be as big as you want them to 2389 01:28:17,360 --> 01:28:21,400 be unlike other languages there is no 2390 01:28:19,320 --> 01:28:23,639 upper bound on how big an INT can be now 2391 01:28:21,400 --> 01:28:25,360 in Python but there is a bound on just 2392 01:28:23,639 --> 01:28:27,280 how precise prise a floating point value 2393 01:28:25,360 --> 01:28:29,239 can be all right now that I've got some 2394 01:28:27,280 --> 01:28:31,159 simple division working here let's go 2395 01:28:29,239 --> 01:28:34,280 ahead and round this it would be nice to 2396 01:28:31,159 --> 01:28:36,520 round this really long number 6666666 2397 01:28:34,280 --> 01:28:38,360 and so forth to maybe just two decimal 2398 01:28:36,520 --> 01:28:39,600 places we've seen how to do this with 2399 01:28:38,360 --> 01:28:41,760 round though at least in its 2400 01:28:39,600 --> 01:28:44,719 documentation let's just round this not 2401 01:28:41,760 --> 01:28:47,639 to the nearest int by passing in just x 2402 01:28:44,719 --> 01:28:49,520 / Y which is one argument once the math 2403 01:28:47,639 --> 01:28:51,360 is done inside of the parenthesis I 2404 01:28:49,520 --> 01:28:53,280 don't want to pass in just one argument 2405 01:28:51,360 --> 01:28:56,320 I want to pass in two so that I can 2406 01:28:53,280 --> 01:28:58,440 specify n digits number of digits which 2407 01:28:56,320 --> 01:29:00,440 recall was the second parameter for 2408 01:28:58,440 --> 01:29:02,280 round let me go ahead and run python of 2409 01:29:00,440 --> 01:29:06,320 calculator. Pi I'll do the same thing 2410 01:29:02,280 --> 01:29:08,280 two and then three 67 so here too we see 2411 01:29:06,320 --> 01:29:11,159 a way of rounding now not just to a 2412 01:29:08,280 --> 01:29:13,760 nearest integer but to a nearest number 2413 01:29:11,159 --> 01:29:15,840 of digits but there's another way to do 2414 01:29:13,760 --> 01:29:19,119 this here and in fact this evokes our 2415 01:29:15,840 --> 01:29:20,960 our uh F F string example again let me 2416 01:29:19,119 --> 01:29:22,880 go ahead and change this suppose that 2417 01:29:20,960 --> 01:29:24,440 you didn't remember the round function 2418 01:29:22,880 --> 01:29:26,440 or for some reason you didn't want to 2419 01:29:24,440 --> 01:29:29,000 use it you instead want to just use a 2420 01:29:26,440 --> 01:29:31,800 format string well let's go there let me 2421 01:29:29,000 --> 01:29:33,800 do quote unquote Z but let me surround 2422 01:29:31,800 --> 01:29:35,679 it with those curly braces let me add 2423 01:29:33,800 --> 01:29:37,360 the F at the beginning and again this is 2424 01:29:35,679 --> 01:29:39,679 not interesting yet this is just going 2425 01:29:37,360 --> 01:29:42,199 to print out Z but I'm adding a lot more 2426 01:29:39,679 --> 01:29:44,239 complexity to turn it into an F string 2427 01:29:42,199 --> 01:29:47,480 but notice I can do something else after 2428 01:29:44,239 --> 01:29:49,520 my variable name after the colon if this 2429 01:29:47,480 --> 01:29:51,600 were going to be a big integer I might 2430 01:29:49,520 --> 01:29:53,440 want to use a comma like before to 2431 01:29:51,600 --> 01:29:55,280 separate each triple of numbers with 2432 01:29:53,440 --> 01:29:58,239 commas but I don't I'm going to use a 2433 01:29:55,280 --> 01:30:01,280 different sequence uh of characters I'm 2434 01:29:58,239 --> 01:30:03,400 G to say 0 2f and this too is one of 2435 01:30:01,280 --> 01:30:05,000 these very cryptic things I have to 2436 01:30:03,400 --> 01:30:06,679 constantly look up because I forget if I 2437 01:30:05,000 --> 01:30:08,440 don't use it that often so don't be 2438 01:30:06,679 --> 01:30:10,639 intimidated if this looks especially 2439 01:30:08,440 --> 01:30:12,880 weird but this is according to the 2440 01:30:10,639 --> 01:30:15,239 documentation the way you specify using 2441 01:30:12,880 --> 01:30:17,320 an F string how many digits you want to 2442 01:30:15,239 --> 01:30:19,719 print so let me run this version of the 2443 01:30:17,320 --> 01:30:21,960 calculator type in two and then three we 2444 01:30:19,719 --> 01:30:23,600 get the exact same thing but again this 2445 01:30:21,960 --> 01:30:26,560 is just consistent with my claim that in 2446 01:30:23,600 --> 01:30:29,280 program we can so very often solve the 2447 01:30:26,560 --> 01:30:32,239 same problem in multiple ways this is 2448 01:30:29,280 --> 01:30:34,920 just now the F string approach to that 2449 01:30:32,239 --> 01:30:37,040 very same problem all right which one is 2450 01:30:34,920 --> 01:30:38,880 better it depends in this case they're 2451 01:30:37,040 --> 01:30:40,679 pretty equivalent you could imagine 2452 01:30:38,880 --> 01:30:42,480 though it being useful to use a function 2453 01:30:40,679 --> 01:30:44,639 sometime so that you can pass in an 2454 01:30:42,480 --> 01:30:46,600 argument like n digits as that second 2455 01:30:44,639 --> 01:30:48,199 argument or you can imagine just 2456 01:30:46,600 --> 01:30:51,639 deciding in advance that you want Point 2457 01:30:48,199 --> 01:30:54,159 2 and then writing it like this let's 2458 01:30:51,639 --> 01:30:55,880 transition now from focusing on string 2459 01:30:54,159 --> 01:30:58,040 and on integers and on floats to 2460 01:30:55,880 --> 01:30:59,920 focusing now on functions themselves we 2461 01:30:58,040 --> 01:31:02,480 began today by focusing on how you can 2462 01:30:59,920 --> 01:31:04,040 use functions that come with python but 2463 01:31:02,480 --> 01:31:06,080 wouldn't it be nice if you could invent 2464 01:31:04,040 --> 01:31:08,000 your own functions especially if to our 2465 01:31:06,080 --> 01:31:10,239 Point earlier you find yourself solving 2466 01:31:08,000 --> 01:31:12,040 the same kind of problem again and again 2467 01:31:10,239 --> 01:31:13,239 it's nice that python comes with the 2468 01:31:12,040 --> 01:31:14,639 print function because it's really 2469 01:31:13,239 --> 01:31:16,440 useful to be able to print things on the 2470 01:31:14,639 --> 01:31:17,719 screen but wouldn't it be nice if you 2471 01:31:16,440 --> 01:31:20,239 could print specific things on the 2472 01:31:17,719 --> 01:31:22,080 screen by just calling your own function 2473 01:31:20,239 --> 01:31:24,719 well let me propose that we do this let 2474 01:31:22,080 --> 01:31:27,880 me go back to VSS code here and let me 2475 01:31:24,719 --> 01:31:29,960 propose that we go back to hello.py I'm 2476 01:31:27,880 --> 01:31:31,760 going to reopen hello.py where we left 2477 01:31:29,960 --> 01:31:34,239 it before and I'm going to go ahead now 2478 01:31:31,760 --> 01:31:36,360 and propose that we consider how we can 2479 01:31:34,239 --> 01:31:38,760 start improving this further by making 2480 01:31:36,360 --> 01:31:41,840 our own function I have written so many 2481 01:31:38,760 --> 01:31:43,880 programs today that just say hello and 2482 01:31:41,840 --> 01:31:45,679 each time I'm using print but wouldn't 2483 01:31:43,880 --> 01:31:47,960 it have been nice if from the beginning 2484 01:31:45,679 --> 01:31:50,719 of today we could just call a function 2485 01:31:47,960 --> 01:31:52,800 called hello that just says hello for us 2486 01:31:50,719 --> 01:31:55,000 now the authors of python years ago 2487 01:31:52,800 --> 01:31:57,119 didn't think that we a special function 2488 01:31:55,000 --> 01:31:59,520 just to say hello but I would like that 2489 01:31:57,119 --> 01:32:00,639 to exist I'm saying hello so many times 2490 01:31:59,520 --> 01:32:02,679 I just want to be able to call a 2491 01:32:00,639 --> 01:32:04,159 function hello so I'm going to start 2492 01:32:02,679 --> 01:32:06,040 from scratch here I'm going to delete 2493 01:32:04,159 --> 01:32:08,480 all of my code from earlier and I'm 2494 01:32:06,040 --> 01:32:10,800 going to pretend for the moment that a 2495 01:32:08,480 --> 01:32:12,320 function called hello exists and I'm 2496 01:32:10,800 --> 01:32:13,719 going to do just as I did before I'm 2497 01:32:12,320 --> 01:32:16,080 going to get the user's name with the 2498 01:32:13,719 --> 01:32:18,800 input function asking what's your name 2499 01:32:16,080 --> 01:32:21,400 question mark and now I'm going to call 2500 01:32:18,800 --> 01:32:24,560 a function hello and then I'm going to 2501 01:32:21,400 --> 01:32:26,800 print out the user's name now I will 2502 01:32:24,560 --> 01:32:29,520 admit hello doesn't exist so bad things 2503 01:32:26,800 --> 01:32:31,320 are about to happen but let's see what 2504 01:32:29,520 --> 01:32:32,960 let me go down to my terminal window let 2505 01:32:31,320 --> 01:32:35,000 me run python of 2506 01:32:32,960 --> 01:32:37,199 hello.py I think the first Line's going 2507 01:32:35,000 --> 01:32:39,400 to be okay because that worked before 2508 01:32:37,199 --> 01:32:41,639 and indeed it's prompting me for my name 2509 01:32:39,400 --> 01:32:44,000 so let me type in David the second line 2510 01:32:41,639 --> 01:32:45,719 of code is apparently calling a function 2511 01:32:44,000 --> 01:32:47,360 that looks like it's called hello 2512 01:32:45,719 --> 01:32:48,840 because why is it a function it has a 2513 01:32:47,360 --> 01:32:50,280 parenthesis and a Clos parenthesis 2514 01:32:48,840 --> 01:32:51,920 immediately after it and that's what 2515 01:32:50,280 --> 01:32:54,119 every function we've used has looked 2516 01:32:51,920 --> 01:32:56,040 like but Python's not going to recognize 2517 01:32:54,119 --> 01:32:58,800 this one when I hit enter now I get a 2518 01:32:56,040 --> 01:33:01,360 name error name hello is not defined did 2519 01:32:58,800 --> 01:33:02,880 you mean help I didn't although it's 2520 01:33:01,360 --> 01:33:06,080 opportune that's what I need at this 2521 01:33:02,880 --> 01:33:08,520 point is some help but I am encountering 2522 01:33:06,080 --> 01:33:10,520 this error because why the function just 2523 01:33:08,520 --> 01:33:12,719 doesn't exist so how do I make this 2524 01:33:10,520 --> 01:33:16,639 function exist well I need to create it 2525 01:33:12,719 --> 01:33:19,679 myself using this keyword defa defa for 2526 01:33:16,639 --> 01:33:21,760 Define so here too just as stir is short 2527 01:33:19,679 --> 01:33:24,760 for string and int is short for integer 2528 01:33:21,760 --> 01:33:27,719 def is short for Define if and when you 2529 01:33:24,760 --> 01:33:30,320 want to Define create invent your own 2530 01:33:27,719 --> 01:33:32,880 functions you can do so using now this 2531 01:33:30,320 --> 01:33:35,560 keyword in Python so let me go back to 2532 01:33:32,880 --> 01:33:38,199 my code here and let me propose that we 2533 01:33:35,560 --> 01:33:40,400 Define this perhaps in this way at the 2534 01:33:38,199 --> 01:33:42,480 very top of my file I'm going to first 2535 01:33:40,400 --> 01:33:45,679 take a moment to define a function 2536 01:33:42,480 --> 01:33:48,880 called hello using def hello open 2537 01:33:45,679 --> 01:33:50,960 parenthesis close parenthesis colon what 2538 01:33:48,880 --> 01:33:54,199 this means now is that python is going 2539 01:33:50,960 --> 01:33:56,600 to treat every line of code that I IND 2540 01:33:54,199 --> 01:33:59,719 underneath this one as the meaning of 2541 01:33:56,600 --> 01:34:01,600 this new function hello So Def is 2542 01:33:59,719 --> 01:34:03,280 important as is the space I get to 2543 01:34:01,600 --> 01:34:04,960 choose the name of the function and I'm 2544 01:34:03,280 --> 01:34:06,679 choosing to call it hello the 2545 01:34:04,960 --> 01:34:07,840 parentheses with nothing inside means 2546 01:34:06,679 --> 01:34:09,880 that this function at the moment is not 2547 01:34:07,840 --> 01:34:12,719 going to take any inputs no arguments 2548 01:34:09,880 --> 01:34:14,639 there too the colon means stay tuned for 2549 01:34:12,719 --> 01:34:16,840 some indentation everything that's 2550 01:34:14,639 --> 01:34:18,440 indented beneath this line of code is 2551 01:34:16,840 --> 01:34:20,000 going to be part of this function it's 2552 01:34:18,440 --> 01:34:22,119 going to be a super short function one 2553 01:34:20,000 --> 01:34:24,320 line of code it's just going to print 2554 01:34:22,119 --> 01:34:27,040 out quote unquote hello 2555 01:34:24,320 --> 01:34:30,360 but now on lines one and two I have 2556 01:34:27,040 --> 01:34:32,040 invented my own function hello notice 2557 01:34:30,360 --> 01:34:33,840 these dots that have now magically 2558 01:34:32,040 --> 01:34:35,920 appeared here this is just a setting of 2559 01:34:33,840 --> 01:34:38,119 my text editor VSS code in this case 2560 01:34:35,920 --> 01:34:40,360 that's just making super explicit to me 2561 01:34:38,119 --> 01:34:42,320 that I've hit the space bar four times 2562 01:34:40,360 --> 01:34:44,199 or equivalently the Tab Key once which 2563 01:34:42,320 --> 01:34:46,400 is converted automatically to four 2564 01:34:44,199 --> 01:34:47,520 spaces generally speaking I'm going to 2565 01:34:46,400 --> 01:34:49,679 need to make sure that all of my 2566 01:34:47,520 --> 01:34:51,679 indented code lines up now so that 2567 01:34:49,679 --> 01:34:53,159 python knows that it's all part of the 2568 01:34:51,679 --> 01:34:55,920 same thing but it's easy in this case 2569 01:34:53,159 --> 01:34:58,360 cuz it's just a single line but now 2570 01:34:55,920 --> 01:35:01,080 thanks to lines one and two the function 2571 01:34:58,360 --> 01:35:03,520 hello will absolutely exist when I'm 2572 01:35:01,080 --> 01:35:05,000 ready to use it on line six so let me go 2573 01:35:03,520 --> 01:35:07,760 down to my terminal window and run 2574 01:35:05,000 --> 01:35:11,040 python of hello.py enter here comes my 2575 01:35:07,760 --> 01:35:13,960 name again and now when I hit enter I 2576 01:35:11,040 --> 01:35:15,679 now see hello David all right we've kind 2577 01:35:13,960 --> 01:35:18,320 of regressed though right this is not 2578 01:35:15,679 --> 01:35:21,199 nearly as pretty as it once was I think 2579 01:35:18,320 --> 01:35:23,760 we can probably do better than this by 2580 01:35:21,199 --> 01:35:26,440 improving things further why don't we 2581 01:35:23,760 --> 01:35:28,840 consider though how we might say 2582 01:35:26,440 --> 01:35:31,320 parameterize the same function that is 2583 01:35:28,840 --> 01:35:33,360 to say can we customize hello to maybe 2584 01:35:31,320 --> 01:35:35,679 take the user's name as input so that we 2585 01:35:33,360 --> 01:35:39,080 can say not only hello but the person's 2586 01:35:35,679 --> 01:35:40,920 name all on one line all in one breath 2587 01:35:39,080 --> 01:35:43,679 well I think we can do this let me 2588 01:35:40,920 --> 01:35:46,360 propose that we do this as follows let 2589 01:35:43,679 --> 01:35:48,679 me go ahead and up in my code let me 2590 01:35:46,360 --> 01:35:50,760 inside of these parentheses let me come 2591 01:35:48,679 --> 01:35:52,719 up with my own parameter name I have 2592 01:35:50,760 --> 01:35:54,400 complete Choice here and I'm going to 2593 01:35:52,719 --> 01:35:57,239 say that the name of of my parameter 2594 01:35:54,400 --> 01:36:00,199 will be the word two why because I want 2595 01:35:57,239 --> 01:36:02,480 my function to sound like the verb it 2596 01:36:00,199 --> 01:36:04,639 represents hello but who do you want to 2597 01:36:02,480 --> 01:36:07,000 say hello to well I'm going to call my 2598 01:36:04,639 --> 01:36:08,920 parameter for this function to just CU 2599 01:36:07,000 --> 01:36:11,080 in English it kind of sounds nice to me 2600 01:36:08,920 --> 01:36:13,320 hello to who do you want to say hello to 2601 01:36:11,080 --> 01:36:15,280 that's why I'm calling this parameter to 2602 01:36:13,320 --> 01:36:17,679 instead of something simpler like X or Y 2603 01:36:15,280 --> 01:36:19,880 or Z all right well what do I want to do 2604 01:36:17,679 --> 01:36:21,400 with the word to well I can do a couple 2605 01:36:19,880 --> 01:36:23,360 of different things we've seen like so 2606 01:36:21,400 --> 01:36:24,960 many different ways to implement hello 2607 01:36:23,360 --> 01:36:26,920 let me just add a comma there for 2608 01:36:24,960 --> 01:36:30,000 grammar's sake and then let me put the 2609 01:36:26,920 --> 01:36:32,119 word to after that as the second 2610 01:36:30,000 --> 01:36:33,480 argument to the function hello there's 2611 01:36:32,119 --> 01:36:35,360 other ways we can do this and we've seen 2612 01:36:33,480 --> 01:36:37,639 so many but this one looks a little 2613 01:36:35,360 --> 01:36:39,239 clear to me I'll say what's going to 2614 01:36:37,639 --> 01:36:42,600 happen next well I don't think I need 2615 01:36:39,239 --> 01:36:44,320 this extra print line here I think what 2616 01:36:42,600 --> 01:36:47,239 I'm going to do is this I'm going to go 2617 01:36:44,320 --> 01:36:49,320 ahead here and print out not the 2618 01:36:47,239 --> 01:36:53,600 person's name manually I'm going to 2619 01:36:49,320 --> 01:36:55,800 inste instead say hello parentheses name 2620 01:36:53,600 --> 01:36:57,920 so what am I now doing on lines one and 2621 01:36:55,800 --> 01:37:00,320 two I'm defining my very own function 2622 01:36:57,920 --> 01:37:02,639 called hello but this time that function 2623 01:37:00,320 --> 01:37:05,600 has been designed to take a parameter a 2624 01:37:02,639 --> 01:37:07,880 single parameter as input and I'm using 2625 01:37:05,600 --> 01:37:10,760 the value of that parameter which I 2626 01:37:07,880 --> 01:37:12,840 called two to plug into print so that I 2627 01:37:10,760 --> 01:37:14,800 see not only hello but also that 2628 01:37:12,840 --> 01:37:16,360 person's name what am I doing on line 2629 01:37:14,800 --> 01:37:18,520 five same as always I'm just getting the 2630 01:37:16,360 --> 01:37:21,520 user's name line six I'm not only 2631 01:37:18,520 --> 01:37:25,320 calling hello I'm passing as input the 2632 01:37:21,520 --> 01:37:27,080 name variable as an ARG argument so that 2633 01:37:25,320 --> 01:37:28,440 that's what gets passed into hello and 2634 01:37:27,080 --> 01:37:30,600 what's Happening Here is essentially 2635 01:37:28,440 --> 01:37:33,400 this even though the variable is called 2636 01:37:30,600 --> 01:37:36,440 name here when the function itself is 2637 01:37:33,400 --> 01:37:40,119 called the computer assumes that that 2638 01:37:36,440 --> 01:37:42,440 same value is now called two so name is 2639 01:37:40,119 --> 01:37:45,119 essentially copied to another variable 2640 01:37:42,440 --> 01:37:48,400 called two so that in the context of 2641 01:37:45,119 --> 01:37:50,560 hello I can say hello to that variable 2642 01:37:48,400 --> 01:37:52,440 instead and we'll see in a moment what 2643 01:37:50,560 --> 01:37:54,199 happens if we don't keep those uh 2644 01:37:52,440 --> 01:37:56,520 straight let me go ahead and run python 2645 01:37:54,199 --> 01:37:59,199 of hello.py enter what's your name and 2646 01:37:56,520 --> 01:38:01,080 now I'm crossing my fingers enter there 2647 01:37:59,199 --> 01:38:03,840 we go we're back in business but now I 2648 01:38:01,080 --> 01:38:05,560 have my own custom function called hello 2649 01:38:03,840 --> 01:38:07,639 that's allowing me to say hello to a 2650 01:38:05,560 --> 01:38:09,480 specific person and here's where now 2651 01:38:07,639 --> 01:38:11,040 things can get really fancy what if you 2652 01:38:09,480 --> 01:38:13,000 wanted your hello function to say hello 2653 01:38:11,040 --> 01:38:14,880 to someone specific but you know what if 2654 01:38:13,000 --> 01:38:16,199 you don't know who you want to say hello 2655 01:38:14,880 --> 01:38:18,880 to you want to say hello to the whole 2656 01:38:16,199 --> 01:38:20,880 world you can give parameters default 2657 01:38:18,880 --> 01:38:23,560 values we've seen that recall that with 2658 01:38:20,880 --> 01:38:25,280 print there was a default value for sep 2659 01:38:23,560 --> 01:38:28,480 for the separator there was a default 2660 01:38:25,280 --> 01:38:30,880 value for end the line ending we can do 2661 01:38:28,480 --> 01:38:33,760 that too and here's the syntax if you 2662 01:38:30,880 --> 01:38:35,920 want the value of this parameter by 2663 01:38:33,760 --> 01:38:38,000 default if not provided by the 2664 01:38:35,920 --> 01:38:41,440 programmer to be equal to quote unquote 2665 01:38:38,000 --> 01:38:43,320 world you literally do that in the same 2666 01:38:41,440 --> 01:38:44,639 line you're defining the function and 2667 01:38:43,320 --> 01:38:46,920 I'll admit it's starting to look more 2668 01:38:44,639 --> 01:38:49,000 cryptic but I'm still just defining a 2669 01:38:46,920 --> 01:38:51,679 function called hello it takes a 2670 01:38:49,000 --> 01:38:54,159 parameter called two but I'm assigning 2671 01:38:51,679 --> 01:38:56,639 it with the equal sign a default value 2672 01:38:54,159 --> 01:38:59,560 of quote unquote world just in case the 2673 01:38:56,639 --> 01:39:01,960 programmer doesn't call hello with an 2674 01:38:59,560 --> 01:39:04,840 argument and we can see this here let me 2675 01:39:01,960 --> 01:39:07,760 change my code to use hello in two ways 2676 01:39:04,840 --> 01:39:10,760 on line five I'm going to very simply 2677 01:39:07,760 --> 01:39:12,360 call hello no arguments then on line six 2678 01:39:10,760 --> 01:39:14,520 I'm going to get the name line seven I'm 2679 01:39:12,360 --> 01:39:16,360 going to call hello with an argument so 2680 01:39:14,520 --> 01:39:19,000 you'll see hello now being used in two 2681 01:39:16,360 --> 01:39:21,800 ways let me go ahead and run python of 2682 01:39:19,000 --> 01:39:24,360 hello.py I'll type in my name oh 2683 01:39:21,800 --> 01:39:26,440 interesting notice I already see hello 2684 01:39:24,360 --> 01:39:29,320 world but that's expected because line 2685 01:39:26,440 --> 01:39:30,960 five happens before line six but once I 2686 01:39:29,320 --> 01:39:33,199 type my name now the program is going to 2687 01:39:30,960 --> 01:39:37,199 be a little more polite and say hello to 2688 01:39:33,199 --> 01:39:40,080 me personally so there too we see with 2689 01:39:37,199 --> 01:39:42,800 relatively simple but new syntax how you 2690 01:39:40,080 --> 01:39:44,440 can Implement functionality very similar 2691 01:39:42,800 --> 01:39:46,480 in spirit to what the print function 2692 01:39:44,440 --> 01:39:49,440 gave us automatically now you have 2693 01:39:46,480 --> 01:39:51,400 control over doing that yourself but let 2694 01:39:49,440 --> 01:39:52,960 me now make this point too one of the 2695 01:39:51,400 --> 01:39:55,159 whole points of defining your own 2696 01:39:52,960 --> 01:39:56,840 function is one just to avoid having to 2697 01:39:55,159 --> 01:39:59,360 repeat yourself again and again you 2698 01:39:56,840 --> 01:40:01,040 don't have to actually keep Reinventing 2699 01:39:59,360 --> 01:40:02,480 the wheel and keep using the print 2700 01:40:01,040 --> 01:40:04,440 function again and again and again if 2701 01:40:02,480 --> 01:40:07,119 you just want to say hello wouldn't it 2702 01:40:04,440 --> 01:40:10,159 be nice now if I could kind of move this 2703 01:40:07,119 --> 01:40:12,080 code that I wrote for defining the hello 2704 01:40:10,159 --> 01:40:14,360 function and just to be dramatic I'm 2705 01:40:12,080 --> 01:40:17,080 going to hit enter a whole lot of times 2706 01:40:14,360 --> 01:40:20,000 50 lines down and put my definition of 2707 01:40:17,080 --> 01:40:21,880 hello way further down in this file why 2708 01:40:20,000 --> 01:40:24,280 well just in the spirit of out of sight 2709 01:40:21,880 --> 01:40:27,239 out of mind because if I now rewind to 2710 01:40:24,280 --> 01:40:29,080 the start of my program now you can sort 2711 01:40:27,239 --> 01:40:30,679 of take for granted that oh hello is a 2712 01:40:29,080 --> 01:40:32,400 function why because it's there on line 2713 01:40:30,679 --> 01:40:33,880 one and it has an open parenthesis and a 2714 01:40:32,400 --> 01:40:36,040 closed parenthesis which up until now 2715 01:40:33,880 --> 01:40:37,679 has meant call this function and then on 2716 01:40:36,040 --> 01:40:39,440 line two we're getting a variable from 2717 01:40:37,679 --> 01:40:41,960 the user by typing in their name and 2718 01:40:39,440 --> 01:40:44,000 then we're calling hello passing in that 2719 01:40:41,960 --> 01:40:46,199 value well at this point I can just take 2720 01:40:44,000 --> 01:40:48,199 for granted that hello exists even if 2721 01:40:46,199 --> 01:40:49,880 it's way down further in the file or as 2722 01:40:48,199 --> 01:40:52,280 we'll see in future weeks even if it's 2723 01:40:49,880 --> 01:40:53,960 in a different file altogether but 2724 01:40:52,280 --> 01:40:56,480 there's a problem here and let me go 2725 01:40:53,960 --> 01:40:59,000 ahead and run this version of 2726 01:40:56,480 --> 01:41:01,679 hello.py notice that as soon as I run 2727 01:40:59,000 --> 01:41:04,480 The Interpreter python of hello.py I see 2728 01:41:01,679 --> 01:41:07,080 a name error name hello is not defined 2729 01:41:04,480 --> 01:41:09,280 again did you mean help well again 2730 01:41:07,080 --> 01:41:11,639 fitting I do need some help here but I 2731 01:41:09,280 --> 01:41:13,320 didn't mean to call the function help 2732 01:41:11,639 --> 01:41:15,040 the problem here though is that python 2733 01:41:13,320 --> 01:41:17,719 is just taking me literally I have 2734 01:41:15,040 --> 01:41:20,080 defined my function hello all the way 2735 01:41:17,719 --> 01:41:22,159 down here but I'm trying to use it way 2736 01:41:20,080 --> 01:41:23,280 up here and that's not allowed Python's 2737 01:41:22,159 --> 01:41:25,080 interpreter is going to take you 2738 01:41:23,280 --> 01:41:27,679 literally and if you use a function it 2739 01:41:25,080 --> 01:41:29,719 must already exist by the time you are 2740 01:41:27,679 --> 01:41:31,800 calling it so how do I fix this well 2741 01:41:29,719 --> 01:41:34,280 apparently I can't do that I have to 2742 01:41:31,800 --> 01:41:36,719 Define any functions I want at the very 2743 01:41:34,280 --> 01:41:39,480 top of my file but that too could get me 2744 01:41:36,719 --> 01:41:41,280 into a bit of trouble eventually because 2745 01:41:39,480 --> 01:41:43,360 if I constantly have to define a 2746 01:41:41,280 --> 01:41:45,000 function above where I want to use it 2747 01:41:43,360 --> 01:41:46,480 you're kind of writing code in Reverse 2748 01:41:45,000 --> 01:41:48,040 you're constantly writing functions up 2749 01:41:46,480 --> 01:41:49,920 here up here up here as opposed to like 2750 01:41:48,040 --> 01:41:52,000 writing your code logically top to 2751 01:41:49,920 --> 01:41:54,320 bottom so let me fix this in a more 2752 01:41:52,000 --> 01:41:57,040 standard way which is to do this 2753 01:41:54,320 --> 01:41:59,840 generally speaking you do want to put 2754 01:41:57,040 --> 01:42:01,760 the main part of your code at the top of 2755 01:41:59,840 --> 01:42:05,239 your file and in fact I'm going to go so 2756 01:42:01,760 --> 01:42:06,960 far as to Define my function called main 2757 01:42:05,239 --> 01:42:08,840 it's not a requirement but it's indeed a 2758 01:42:06,960 --> 01:42:11,040 convention and this just connotes to the 2759 01:42:08,840 --> 01:42:13,400 reader that this is the main part of my 2760 01:42:11,040 --> 01:42:15,639 program I'm going to get rid of my empty 2761 01:42:13,400 --> 01:42:18,199 hello call now and only pass in one 2762 01:42:15,639 --> 01:42:20,719 version with hello name and then down 2763 01:42:18,199 --> 01:42:23,199 here a couple lines further down I'll 2764 01:42:20,719 --> 01:42:24,679 actually Define my hello function 2765 01:42:23,199 --> 01:42:26,599 unfortunately now that I've reordered 2766 01:42:24,679 --> 01:42:28,760 the functions in this way by putting the 2767 01:42:26,599 --> 01:42:30,760 main part of my code at the top and 2768 01:42:28,760 --> 01:42:32,679 hello at the bottom so that my logic 2769 01:42:30,760 --> 01:42:36,040 kind of flows top to bottom if I go 2770 01:42:32,679 --> 01:42:38,840 ahead and run python of hello.py enter 2771 01:42:36,040 --> 01:42:41,000 nothing whatsoever happens if I do it 2772 01:42:38,840 --> 01:42:43,119 again nothing whatsoever happens well 2773 01:42:41,000 --> 01:42:44,719 why in the world is this well just 2774 01:42:43,119 --> 01:42:46,719 because I've defined a function called 2775 01:42:44,719 --> 01:42:48,760 Main and I've defined a function called 2776 01:42:46,719 --> 01:42:51,800 hello doesn't mean that I've actually 2777 01:42:48,760 --> 01:42:54,719 called that is used either of them yes 2778 01:42:51,800 --> 01:42:57,159 I'm using hello in side of main but no 2779 01:42:54,719 --> 01:43:00,599 one is telling python to actually use or 2780 01:42:57,159 --> 01:43:02,760 call Main so in order to tidy this up 2781 01:43:00,599 --> 01:43:05,440 the last thing I need to do in this file 2782 01:43:02,760 --> 01:43:07,840 it seems is actually call my main 2783 01:43:05,440 --> 01:43:09,719 function and in fact by calling my main 2784 01:43:07,840 --> 01:43:11,560 function in this way it gets me out of 2785 01:43:09,719 --> 01:43:13,840 trouble because now I'm defining main 2786 01:43:11,560 --> 01:43:15,880 first but I'm not calling hello yet I'm 2787 01:43:13,840 --> 01:43:18,520 defining hello next but I'm not calling 2788 01:43:15,880 --> 01:43:21,199 hello next I only at the very end of 2789 01:43:18,520 --> 01:43:23,440 this file call Main which has the effect 2790 01:43:21,199 --> 01:43:25,159 of running this code up here which has 2791 01:43:23,440 --> 01:43:27,440 the effect of running this code down 2792 01:43:25,159 --> 01:43:30,199 here and it allows me therefore to 2793 01:43:27,440 --> 01:43:32,599 organize my file and Order My functions 2794 01:43:30,199 --> 01:43:35,199 in any way I want including main at the 2795 01:43:32,599 --> 01:43:37,199 very top and solving ultimately that 2796 01:43:35,199 --> 01:43:39,360 problem of python not knowing what's 2797 01:43:37,199 --> 01:43:42,159 going on now it's important to note that 2798 01:43:39,360 --> 01:43:44,760 I defined my function hello as taking an 2799 01:43:42,159 --> 01:43:46,480 argument to and then I passed into that 2800 01:43:44,760 --> 01:43:48,440 function the value of the variable that 2801 01:43:46,480 --> 01:43:50,440 I wanted to say hello to that is the 2802 01:43:48,440 --> 01:43:51,760 variable called name because suppose I 2803 01:43:50,440 --> 01:43:53,599 had done something a little bit 2804 01:43:51,760 --> 01:43:55,880 differently suppose that I hadn't 2805 01:43:53,599 --> 01:43:57,639 defined hello is taking an argument so I 2806 01:43:55,880 --> 01:44:00,920 just remove mention of two and its 2807 01:43:57,639 --> 01:44:03,800 default Value World and I go back up to 2808 01:44:00,920 --> 01:44:06,320 my main function and I just call hello 2809 01:44:03,800 --> 01:44:07,760 itself without passing in any arguments 2810 01:44:06,320 --> 01:44:10,199 and now let me go ahead and make one 2811 01:44:07,760 --> 01:44:12,239 more change one more mistake technically 2812 01:44:10,199 --> 01:44:15,159 let me go ahead and just try to naively 2813 01:44:12,239 --> 01:44:17,159 print out the value of name in the hello 2814 01:44:15,159 --> 01:44:19,199 function so now to be clear in my main 2815 01:44:17,159 --> 01:44:20,920 function on line two I'm defining my 2816 01:44:19,199 --> 01:44:22,639 variable called name and assigning it 2817 01:44:20,920 --> 01:44:24,400 the return value of the input function 2818 01:44:22,639 --> 01:44:27,159 from the user I'm then just calling 2819 01:44:24,400 --> 01:44:30,000 hello in my hello function which now no 2820 01:44:27,159 --> 01:44:32,480 longer takes any arguments I am calling 2821 01:44:30,000 --> 01:44:35,040 print passing in hello comma and then 2822 01:44:32,480 --> 01:44:36,920 immediately passing in name the variable 2823 01:44:35,040 --> 01:44:39,800 into which I got the user's input but 2824 01:44:36,920 --> 01:44:41,480 the catch is that name exists now only 2825 01:44:39,800 --> 01:44:43,199 in Maine and so watch what happens when 2826 01:44:41,480 --> 01:44:46,480 I try to run this version of the program 2827 01:44:43,199 --> 01:44:49,400 with python hello.py I hit enter I'm 2828 01:44:46,480 --> 01:44:52,440 prompted for my name DAV ID enter and ah 2829 01:44:49,400 --> 01:44:54,679 a name error name name quote unquote is 2830 01:44:52,440 --> 01:44:57,159 not defined so it turns out that this is 2831 01:44:54,679 --> 01:44:59,719 actually an issue of what's called scope 2832 01:44:57,159 --> 01:45:02,119 scope refers to a variable only existing 2833 01:44:59,719 --> 01:45:04,320 in the context in which you defined it 2834 01:45:02,119 --> 01:45:07,000 so in so far as I Define this variable 2835 01:45:04,320 --> 01:45:09,199 name in my main function I can only use 2836 01:45:07,000 --> 01:45:11,360 that variable in my name function I 2837 01:45:09,199 --> 01:45:13,840 can't use it as I've tried to here in my 2838 01:45:11,360 --> 01:45:16,480 hello function it doesn't exist in that 2839 01:45:13,840 --> 01:45:19,239 so-called scope and so this is why now 2840 01:45:16,480 --> 01:45:21,440 if I rewind and undo all of those 2841 01:45:19,239 --> 01:45:24,119 changes you'll see that I'm deliberately 2842 01:45:21,440 --> 01:45:26,280 passing main from my main function into 2843 01:45:24,119 --> 01:45:27,679 my hello function and now in the hello 2844 01:45:26,280 --> 01:45:29,880 function it technically has a different 2845 01:45:27,679 --> 01:45:31,639 name it's called two in that context but 2846 01:45:29,880 --> 01:45:33,480 that's fine it's completely up to each 2847 01:45:31,639 --> 01:45:35,320 individual function to name its own 2848 01:45:33,480 --> 01:45:37,320 variables or name its own arguments but 2849 01:45:35,320 --> 01:45:39,119 this is a way now that I'm handing to 2850 01:45:37,320 --> 01:45:41,719 the hello function the value of that 2851 01:45:39,119 --> 01:45:44,320 variable so it can be printed by hello 2852 01:45:41,719 --> 01:45:46,320 as well and there's one final flourish 2853 01:45:44,320 --> 01:45:47,920 we can add here now that we've 2854 01:45:46,320 --> 01:45:50,159 implemented hello you'll notice that 2855 01:45:47,920 --> 01:45:51,880 hello only has a so-called side effect 2856 01:45:50,159 --> 01:45:54,760 it only prints out something to the 2857 01:45:51,880 --> 01:45:57,639 screen well what if I also want my 2858 01:45:54,760 --> 01:46:00,320 function to not have a side effect per 2859 01:45:57,639 --> 01:46:03,280 se but actually hand me back a value 2860 01:46:00,320 --> 01:46:05,599 recall that the input function returns a 2861 01:46:03,280 --> 01:46:07,760 value the string that the user typed in 2862 01:46:05,599 --> 01:46:10,320 recall that the int function returns a 2863 01:46:07,760 --> 01:46:13,119 value the float function returns a value 2864 01:46:10,320 --> 01:46:16,040 that was passed into it well you can use 2865 01:46:13,119 --> 01:46:19,119 one final keyword here literally return 2866 01:46:16,040 --> 01:46:21,760 to return a value explicitly yourself in 2867 01:46:19,119 --> 01:46:24,280 fact let me go back to VSS code here and 2868 01:46:21,760 --> 01:46:26,800 I think we'll return our attention to 2869 01:46:24,280 --> 01:46:29,400 calculator. Pi and see if we can't 2870 01:46:26,800 --> 01:46:31,840 Implement one other version of calculate 2871 01:46:29,400 --> 01:46:34,520 calculator. pi that actually has our own 2872 01:46:31,840 --> 01:46:36,320 function that even returns a value so 2873 01:46:34,520 --> 01:46:38,719 I'm going to go ahead and open up uh 2874 01:46:36,320 --> 01:46:41,119 calculator. pi and I think this time I'm 2875 01:46:38,719 --> 01:46:43,000 going to throw everything away as before 2876 01:46:41,119 --> 01:46:45,360 and I'm just going to start practicing 2877 01:46:43,000 --> 01:46:47,080 what we're preaching here Define a 2878 01:46:45,360 --> 01:46:49,480 function called main which is now going 2879 01:46:47,080 --> 01:46:51,040 to be the main part of my function let's 2880 01:46:49,480 --> 01:46:54,560 go ahead and now declare a variable 2881 01:46:51,040 --> 01:46:57,119 called X and assign it to the converted 2882 01:46:54,560 --> 01:47:00,000 version of the user's input after asking 2883 01:46:57,119 --> 01:47:02,400 them what's X so again a line of code 2884 01:47:00,000 --> 01:47:04,800 quite like we've done before and suppose 2885 01:47:02,400 --> 01:47:06,320 now that what I want to do is square 2886 01:47:04,800 --> 01:47:07,800 this value I want to take the number 2887 01:47:06,320 --> 01:47:11,199 that the user typed in and raise it to 2888 01:47:07,800 --> 01:47:14,159 the power of two so 2 squar would be 4 3 2889 01:47:11,199 --> 01:47:16,000 squar would be 9 4 squar would be 16 and 2890 01:47:14,159 --> 01:47:17,760 so forth well how do I go about 2891 01:47:16,000 --> 01:47:19,520 implementing a function literally called 2892 01:47:17,760 --> 01:47:22,040 Square which actually doesn't come with 2893 01:47:19,520 --> 01:47:23,840 python built in well let me assume for 2894 01:47:22,040 --> 01:47:26,119 the moment that it does exist and let me 2895 01:47:23,840 --> 01:47:30,199 say something like this let me go ahead 2896 01:47:26,119 --> 01:47:33,119 and say that uh printing how about uh 2897 01:47:30,199 --> 01:47:37,159 X2 is 2898 01:47:33,119 --> 01:47:38,960 comma square of X so what have I done 2899 01:47:37,159 --> 01:47:41,280 I've defined a function called Main and 2900 01:47:38,960 --> 01:47:43,199 I've implemented two lines the first of 2901 01:47:41,280 --> 01:47:45,560 these lines prompts the user for a value 2902 01:47:43,199 --> 01:47:48,239 X and converts it to an INT and stores 2903 01:47:45,560 --> 01:47:51,560 it in a variable called X on line three 2904 01:47:48,239 --> 01:47:53,599 I then say x^2 is and then I pass a 2905 01:47:51,560 --> 01:47:56,239 second argument to the print function 2906 01:47:53,599 --> 01:47:58,960 whatever the return value is of a square 2907 01:47:56,239 --> 01:48:01,199 function but Square doesn't exist and 2908 01:47:58,960 --> 01:48:04,320 I'll show you this here if I now call 2909 01:48:01,199 --> 01:48:07,119 Main at the bottom and I run python of 2910 01:48:04,320 --> 01:48:11,440 calculator. 2911 01:48:07,119 --> 01:48:13,119 Pi I'll see that X is two and then I see 2912 01:48:11,440 --> 01:48:15,679 a whole bunch of Errors a name error 2913 01:48:13,119 --> 01:48:17,239 name square is not defined so this isn't 2914 01:48:15,679 --> 01:48:19,000 a typo here it's just the function 2915 01:48:17,239 --> 01:48:21,440 doesn't exist but I think I can make it 2916 01:48:19,000 --> 01:48:23,360 exist here let me go ahead and Define 2917 01:48:21,440 --> 01:48:25,280 another function called Square 2918 01:48:23,360 --> 01:48:27,199 this one's going to take in a number and 2919 01:48:25,280 --> 01:48:28,679 I'm going to call it generically n as 2920 01:48:27,199 --> 01:48:31,000 many a programmer would just to 2921 01:48:28,679 --> 01:48:34,159 represent any old number and then what 2922 01:48:31,000 --> 01:48:35,960 do I want to do in order to square n 2923 01:48:34,159 --> 01:48:38,280 well a numbered squared is really just 2924 01:48:35,960 --> 01:48:42,080 itself times itself so I'm going to do 2925 01:48:38,280 --> 01:48:44,440 this n * n but it's not enough just to 2926 01:48:42,080 --> 01:48:47,159 do the math yourself n * n you're going 2927 01:48:44,440 --> 01:48:50,159 to have to return the actual value n 2928 01:48:47,159 --> 01:48:52,119 times n and that's our new keyword here 2929 01:48:50,159 --> 01:48:55,760 when I now do this Watch What Happens 2930 01:48:52,119 --> 01:48:59,520 python of calculator. Pi enter X sh say 2931 01:48:55,760 --> 01:49:04,199 shall be 2 x^2 is 4 let me go ahead now 2932 01:48:59,520 --> 01:49:05,840 and say x is now three X2 is now 9 so 2933 01:49:04,199 --> 01:49:08,520 I've implemented my very own function 2934 01:49:05,840 --> 01:49:10,960 that Returns the square of a value and 2935 01:49:08,520 --> 01:49:13,360 because I'm using the return keyword 2936 01:49:10,960 --> 01:49:14,880 that ensures that I can pass the return 2937 01:49:13,360 --> 01:49:17,639 value of this just like the return value 2938 01:49:14,880 --> 01:49:20,119 of input or int or float to another 2939 01:49:17,639 --> 01:49:21,520 function like print instead and here too 2940 01:49:20,119 --> 01:49:23,560 there's going to be so many ways to 2941 01:49:21,520 --> 01:49:25,800 solve the same problem I can actually 2942 01:49:23,560 --> 01:49:27,960 raise n to the power of two we've not 2943 01:49:25,800 --> 01:49:30,760 seen the syntax before but if you use 2944 01:49:27,960 --> 01:49:32,560 two two asterisks like this two stars 2945 01:49:30,760 --> 01:49:34,840 that raises the thing on the left to the 2946 01:49:32,560 --> 01:49:37,080 power on the right or it turns out there 2947 01:49:34,840 --> 01:49:38,440 is in Python a function called pow for 2948 01:49:37,080 --> 01:49:40,440 raising something to the power that 2949 01:49:38,440 --> 01:49:42,599 takes two arguments the first of which 2950 01:49:40,440 --> 01:49:44,360 is the number the second of which is the 2951 01:49:42,599 --> 01:49:47,360 exponent so there too there's just so 2952 01:49:44,360 --> 01:49:50,320 many ways to actually solve that same 2953 01:49:47,360 --> 01:49:51,880 problem as well so ultimately what we 2954 01:49:50,320 --> 01:49:53,960 have we done here we first introduced 2955 01:49:51,880 --> 01:49:55,639 functions these or verbs many of which 2956 01:49:53,960 --> 01:49:57,840 come built into python that you can just 2957 01:49:55,639 --> 01:49:59,760 use in your own code we then introduced 2958 01:49:57,840 --> 01:50:01,040 variables via which you can store those 2959 01:49:59,760 --> 01:50:02,880 return values and then maybe do 2960 01:50:01,040 --> 01:50:04,440 something more with it at the end of the 2961 01:50:02,880 --> 01:50:06,400 day too you now have the ability to 2962 01:50:04,440 --> 01:50:08,400 create to invent your own functions to 2963 01:50:06,400 --> 01:50:10,239 solve simple problems like hello or in 2964 01:50:08,400 --> 01:50:12,080 the weeks to come much more 2965 01:50:10,239 --> 01:50:16,119 sophisticated more challenging more fun 2966 01:50:12,080 --> 01:50:16,119 problems as well 2967 01:50:19,070 --> 01:50:28,910 [Music] 2968 01:50:30,950 --> 01:50:37,810 [Music] 2969 01:50:39,920 --> 01:50:45,000 all right this is cs50's Introduction to 2970 01:50:42,960 --> 01:50:47,079 programming with python my name is David 2971 01:50:45,000 --> 01:50:49,159 men and this week we focus on 2972 01:50:47,079 --> 01:50:51,040 conditionals conditionals or conditional 2973 01:50:49,159 --> 01:50:53,760 statements in Python and in other 2974 01:50:51,040 --> 01:50:56,079 languages are this ability ility to ask 2975 01:50:53,760 --> 01:50:58,119 questions and answer those questions in 2976 01:50:56,079 --> 01:50:59,880 order to decide do you want to execute 2977 01:50:58,119 --> 01:51:01,800 this line of code or this line of code 2978 01:50:59,880 --> 01:51:03,800 or this other line of code instead they 2979 01:51:01,800 --> 01:51:05,679 allow you to take the proverbial Forks 2980 01:51:03,800 --> 01:51:08,199 in the road within your own code 2981 01:51:05,679 --> 01:51:10,119 logically so how might we go about 2982 01:51:08,199 --> 01:51:11,760 making some of these decisions well it 2983 01:51:10,119 --> 01:51:14,280 turns out that python comes with a lot 2984 01:51:11,760 --> 01:51:15,800 of built-in Syntax for instance here are 2985 01:51:14,280 --> 01:51:18,040 just some of the symbols you can use in 2986 01:51:15,800 --> 01:51:19,880 Python to ask questions admittedly 2987 01:51:18,040 --> 01:51:21,920 mathematical questions but we'll start 2988 01:51:19,880 --> 01:51:24,400 there if only to keep the example simply 2989 01:51:21,920 --> 01:51:26,320 simple early on this first symbol as you 2990 01:51:24,400 --> 01:51:28,520 might know for math represents greater 2991 01:51:26,320 --> 01:51:30,239 than the second symbol might not look 2992 01:51:28,520 --> 01:51:32,639 too familiar because we usually write it 2993 01:51:30,239 --> 01:51:34,400 all as one thing on a piece of paper but 2994 01:51:32,639 --> 01:51:36,360 on a keyboard if you want to say greater 2995 01:51:34,400 --> 01:51:38,760 than or equal to you'd use this symbol 2996 01:51:36,360 --> 01:51:41,560 Instead This of course means less than 2997 01:51:38,760 --> 01:51:43,520 this means less than or equal to and 2998 01:51:41,560 --> 01:51:45,280 this one's a bit of a curiosity we've 2999 01:51:43,520 --> 01:51:47,800 seen in our look at functions and 3000 01:51:45,280 --> 01:51:50,719 variables how we were able to assign 3001 01:51:47,800 --> 01:51:52,560 values to variables using a single equal 3002 01:51:50,719 --> 01:51:54,360 sign but that equal sign didn't repres 3003 01:51:52,560 --> 01:51:56,440 represent equality it represented 3004 01:51:54,360 --> 01:51:58,159 assignment from right to left that's 3005 01:51:56,440 --> 01:51:59,800 great because it solved that problem but 3006 01:51:58,159 --> 01:52:01,960 it kind of left us in a bit of a bind 3007 01:51:59,800 --> 01:52:04,239 because how do we now compare two things 3008 01:52:01,960 --> 01:52:06,159 left and right well in Python and in 3009 01:52:04,239 --> 01:52:08,440 many languages you actually use two 3010 01:52:06,159 --> 01:52:10,760 equal signs so two equal signs 3011 01:52:08,440 --> 01:52:13,000 represents equality comparing the thing 3012 01:52:10,760 --> 01:52:15,239 on the left and the right one equal sign 3013 01:52:13,000 --> 01:52:17,480 as always represents assignment copying 3014 01:52:15,239 --> 01:52:19,560 the thing from the right to the left 3015 01:52:17,480 --> 01:52:21,880 lastly this last symbol represents not 3016 01:52:19,560 --> 01:52:24,760 equal to so the exclamation point or 3017 01:52:21,880 --> 01:52:28,159 Bang uh followed by an equal sign means 3018 01:52:24,760 --> 01:52:30,760 not equal to some value next to it well 3019 01:52:28,159 --> 01:52:32,320 to ask the questions using these symbols 3020 01:52:30,760 --> 01:52:34,199 or any others we're going to need 3021 01:52:32,320 --> 01:52:36,840 another keyword in Python and that 3022 01:52:34,199 --> 01:52:38,840 keyword quite simply as in English is if 3023 01:52:36,840 --> 01:52:41,800 you can ask questions in Python code 3024 01:52:38,840 --> 01:52:44,719 along the lines of if the answer to this 3025 01:52:41,800 --> 01:52:46,800 question is true then go ahead and 3026 01:52:44,719 --> 01:52:48,679 execute this code for me so let's go 3027 01:52:46,800 --> 01:52:50,960 ahead and write some of these examples 3028 01:52:48,679 --> 01:52:52,239 here I'm going to go over to VSS code 3029 01:52:50,960 --> 01:52:55,239 and let's go ahead and create a program 3030 01:52:52,239 --> 01:52:57,560 for called compare. the goal of which is 3031 01:52:55,239 --> 01:52:59,760 simply to write code that compares 3032 01:52:57,560 --> 01:53:01,320 values and makes decisions based on 3033 01:52:59,760 --> 01:53:03,800 those values let's go ahead and type 3034 01:53:01,320 --> 01:53:06,079 code of compare. py in order to create a 3035 01:53:03,800 --> 01:53:07,440 brand new file called compare in which 3036 01:53:06,079 --> 01:53:08,960 we'll start to express some of this 3037 01:53:07,440 --> 01:53:10,679 logic all right well what do we want to 3038 01:53:08,960 --> 01:53:12,560 compare suppose we want to compare for 3039 01:53:10,679 --> 01:53:14,440 the sake of discussion just a couple of 3040 01:53:12,560 --> 01:53:17,639 integers but we'd like those integers to 3041 01:53:14,440 --> 01:53:19,880 come from the user so that we can make 3042 01:53:17,639 --> 01:53:22,040 uh decisions based on numbers we don't 3043 01:53:19,880 --> 01:53:23,520 know the values of in advance well let's 3044 01:53:22,040 --> 01:53:26,159 go ahead and do this as we've done in 3045 01:53:23,520 --> 01:53:29,040 the past let's declare a variable like X 3046 01:53:26,159 --> 01:53:32,000 let's assign it equal to the return 3047 01:53:29,040 --> 01:53:34,119 value of the int function and pass to 3048 01:53:32,000 --> 01:53:36,320 the int function the return value of the 3049 01:53:34,119 --> 01:53:38,719 input function asking the user a 3050 01:53:36,320 --> 01:53:40,599 question like what's X question mark As 3051 01:53:38,719 --> 01:53:43,800 we've done in the past let's do this one 3052 01:53:40,599 --> 01:53:47,239 more time with Y asking the user for the 3053 01:53:43,800 --> 01:53:49,800 value of y and again uh converting that 3054 01:53:47,239 --> 01:53:52,040 ultimately to an INT as well so at this 3055 01:53:49,800 --> 01:53:53,040 am of the story we have two variables X 3056 01:53:52,040 --> 01:53:54,960 and Y 3057 01:53:53,040 --> 01:53:56,280 Each of which has values and ideally we 3058 01:53:54,960 --> 01:53:58,520 should be able to now compare these 3059 01:53:56,280 --> 01:54:00,440 values so suppose I want to make a 3060 01:53:58,520 --> 01:54:02,599 decision based on the values of these 3061 01:54:00,440 --> 01:54:03,880 variables I'm going to use the keyword 3062 01:54:02,599 --> 01:54:05,760 if and I'm going to use some of those 3063 01:54:03,880 --> 01:54:08,480 mathematical symbols to actually ask the 3064 01:54:05,760 --> 01:54:11,320 question itself so how about this if x 3065 01:54:08,480 --> 01:54:13,920 is less than y then let's go ahead and 3066 01:54:11,320 --> 01:54:16,560 just print as much Out quote unquote X 3067 01:54:13,920 --> 01:54:18,639 is less than y so this isn't a very 3068 01:54:16,560 --> 01:54:20,880 interesting program yet I'm literally 3069 01:54:18,639 --> 01:54:22,920 just stating the obvious based on the 3070 01:54:20,880 --> 01:54:24,960 math but it's allowing me to introduce 3071 01:54:22,920 --> 01:54:27,440 some new syntax and exactly what is this 3072 01:54:24,960 --> 01:54:29,280 syntax well it's this not just the 3073 01:54:27,440 --> 01:54:31,840 keyword if which I've added here at the 3074 01:54:29,280 --> 01:54:34,639 start of line four but then I ask my 3075 01:54:31,840 --> 01:54:36,440 question here x less than y x is one 3076 01:54:34,639 --> 01:54:38,159 variable on the left Y is one variable 3077 01:54:36,440 --> 01:54:39,800 on the right and of course the less than 3078 01:54:38,159 --> 01:54:41,800 sign is expressing the mathematical 3079 01:54:39,800 --> 01:54:44,239 question I have what I've highlighted 3080 01:54:41,800 --> 01:54:46,280 here is technically called a Boolean 3081 01:54:44,239 --> 01:54:48,440 expression a Boolean expression named 3082 01:54:46,280 --> 01:54:51,199 after a mathematician named bull is 3083 01:54:48,440 --> 01:54:53,840 simply a question that has a yes or no 3084 01:54:51,199 --> 01:54:55,480 answer or technically a true or false 3085 01:54:53,840 --> 01:54:57,480 answer and that's nice because if 3086 01:54:55,480 --> 01:54:59,199 there's only two possible answers it's 3087 01:54:57,480 --> 01:55:01,400 very easy for me and in turn the 3088 01:54:59,199 --> 01:55:03,679 computer to make a decision do this or 3089 01:55:01,400 --> 01:55:06,079 don't do this thing now notice if you 3090 01:55:03,679 --> 01:55:08,000 come from other languages you might 3091 01:55:06,079 --> 01:55:09,800 notice that I have not typed any 3092 01:55:08,000 --> 01:55:11,320 parentheses they are not in fact 3093 01:55:09,800 --> 01:55:13,719 necessary at least in this case in 3094 01:55:11,320 --> 01:55:15,560 Python but I have typed a colon at the 3095 01:55:13,719 --> 01:55:18,040 end of the line and even more 3096 01:55:15,560 --> 01:55:19,960 importantly at the next line I have 3097 01:55:18,040 --> 01:55:21,880 begun my line with some indentation 3098 01:55:19,960 --> 01:55:23,400 hitting the space bar four times or just 3099 01:55:21,880 --> 01:55:25,480 hitting tab once which will 3100 01:55:23,400 --> 01:55:28,079 automatically be converted to the same 3101 01:55:25,480 --> 01:55:30,679 that indentation is what tells python 3102 01:55:28,079 --> 01:55:34,280 that line five should only be executed 3103 01:55:30,679 --> 01:55:37,880 if the answer to line Four's question is 3104 01:55:34,280 --> 01:55:39,960 in fact true so if x is less than y that 3105 01:55:37,880 --> 01:55:41,440 phrase will be printed thereafter well 3106 01:55:39,960 --> 01:55:43,920 let's add a few more lines of code how 3107 01:55:41,440 --> 01:55:45,840 about another question If X is greater 3108 01:55:43,920 --> 01:55:49,280 than y then let's go ahead and print 3109 01:55:45,840 --> 01:55:52,960 that X is greater than y and let's do 3110 01:55:49,280 --> 01:55:56,360 one final question if x equals y then 3111 01:55:52,960 --> 01:55:58,159 wait a minute what have I done wrong 3112 01:55:56,360 --> 01:56:01,840 here right a good eye here I don't want 3113 01:55:58,159 --> 01:56:04,079 to assign y to x if x equals equals y is 3114 01:56:01,840 --> 01:56:08,880 how I express equality let's go ahead 3115 01:56:04,079 --> 01:56:12,159 and print out X is equal to Y so I now 3116 01:56:08,880 --> 01:56:14,280 have a uh three conditions if you will 3117 01:56:12,159 --> 01:56:17,599 one question asking X less than y one 3118 01:56:14,280 --> 01:56:20,119 asking X greater than y one asking xals 3119 01:56:17,599 --> 01:56:21,440 equals y let's run the code well down 3120 01:56:20,119 --> 01:56:24,199 here in my terminal window I'm going to 3121 01:56:21,440 --> 01:56:26,840 run python of pair. pi and hit enter 3122 01:56:24,199 --> 01:56:29,679 what's X let's go with one what's y 3123 01:56:26,840 --> 01:56:31,920 let's go with two this should of course 3124 01:56:29,679 --> 01:56:35,760 execute that first line of code and tell 3125 01:56:31,920 --> 01:56:38,400 me indeed that X is less than y exactly 3126 01:56:35,760 --> 01:56:40,520 as I would expect there well what just 3127 01:56:38,400 --> 01:56:43,079 happened though in code well let's take 3128 01:56:40,520 --> 01:56:44,920 a look perhaps at this same code uh 3129 01:56:43,079 --> 01:56:47,360 visually particularly if you're a more 3130 01:56:44,920 --> 01:56:48,960 visual learner this I dare say is what 3131 01:56:47,360 --> 01:56:51,960 just happened so what we're looking at 3132 01:56:48,960 --> 01:56:54,040 here is a a flowchart it's a diagram of 3133 01:56:51,960 --> 01:56:55,920 this program's logic and more 3134 01:56:54,040 --> 01:56:58,239 technically it shows the program's 3135 01:56:55,920 --> 01:56:59,840 control flow that is the ability of you 3136 01:56:58,239 --> 01:57:02,040 and code to control the flow of a 3137 01:56:59,840 --> 01:57:03,679 program generally from top to bottom in 3138 01:57:02,040 --> 01:57:05,560 fact let me go ahead and zoom in on the 3139 01:57:03,679 --> 01:57:07,239 top of this flowchart and you'll see an 3140 01:57:05,560 --> 01:57:09,840 oval at the very top that says quite 3141 01:57:07,239 --> 01:57:12,079 literally start that is irrespective of 3142 01:57:09,840 --> 01:57:14,040 what shape or layout the diagram is is 3143 01:57:12,079 --> 01:57:15,920 where your own thinking and logic should 3144 01:57:14,040 --> 01:57:17,679 start when trying to wrap your mind 3145 01:57:15,920 --> 01:57:19,760 around this program notice that there's 3146 01:57:17,679 --> 01:57:21,480 an arrow from start to this diamond 3147 01:57:19,760 --> 01:57:24,560 shape and inside of that diamond is a 3148 01:57:21,480 --> 01:57:26,599 question a an expression X less than y 3149 01:57:24,560 --> 01:57:29,360 and this shape just means based on the 3150 01:57:26,599 --> 01:57:31,560 answer to that question go left or go 3151 01:57:29,360 --> 01:57:34,360 right specifically go left if the answer 3152 01:57:31,560 --> 01:57:37,440 is true or go right if the answer is 3153 01:57:34,360 --> 01:57:40,480 false well the inputs I typed were one 3154 01:57:37,440 --> 01:57:43,560 and two respectively for X and Y so of 3155 01:57:40,480 --> 01:57:46,199 course one is less than two so that's 3156 01:57:43,560 --> 01:57:49,960 why my program printed out quote unquote 3157 01:57:46,199 --> 01:57:52,400 X is less than y but recall the code the 3158 01:57:49,960 --> 01:57:55,440 code then proceeded to ask two more 3159 01:57:52,400 --> 01:57:57,960 questions is X greater than y is x equal 3160 01:57:55,440 --> 01:58:00,159 equal to Y well the flowchart depicts 3161 01:57:57,960 --> 01:58:02,119 those questions too notice that no 3162 01:58:00,159 --> 01:58:04,840 matter whether the question had an 3163 01:58:02,119 --> 01:58:07,280 answer of true or false the arrows both 3164 01:58:04,840 --> 01:58:09,520 converge back down to this second 3165 01:58:07,280 --> 01:58:11,840 diamond shape here and that second 3166 01:58:09,520 --> 01:58:13,840 diamond shape asks the second question X 3167 01:58:11,840 --> 01:58:15,639 greater than y that too has a true or 3168 01:58:13,840 --> 01:58:19,159 false answer so we go one way or the 3169 01:58:15,639 --> 01:58:21,119 other but if x is 1 and Y is 2 then no 3170 01:58:19,159 --> 01:58:23,480 the answer is false one is not greater 3171 01:58:21,119 --> 01:58:25,199 than y so so logically in the flowchart 3172 01:58:23,480 --> 01:58:27,880 you follow the false Arrow this time and 3173 01:58:25,199 --> 01:58:29,800 notice along that false Arrow you don't 3174 01:58:27,880 --> 01:58:32,119 print anything this time that's why we 3175 01:58:29,800 --> 01:58:33,320 only saw one print out on the screen now 3176 01:58:32,119 --> 01:58:35,040 there was still a third question and 3177 01:58:33,320 --> 01:58:38,480 this flowchart captures that as well the 3178 01:58:35,040 --> 01:58:40,480 third Diamond asks x equals equals y now 3179 01:58:38,480 --> 01:58:42,000 that to has a false answer in this case 3180 01:58:40,480 --> 01:58:44,800 because one of course does not equal 3181 01:58:42,000 --> 01:58:47,440 equal Y and so we again follow the third 3182 01:58:44,800 --> 01:58:49,840 false Branch here and that leads us of 3183 01:58:47,440 --> 01:58:52,480 course to stop and stop just indicates 3184 01:58:49,840 --> 01:58:54,840 that's it for the program so think 3185 01:58:52,480 --> 01:58:58,079 that's correct and that particular 3186 01:58:54,840 --> 01:59:00,880 flowchart does happen to represent the 3187 01:58:58,079 --> 01:59:02,440 actual code that I wrote so it's correct 3188 01:59:00,880 --> 01:59:03,760 it does what it's supposed to do it 3189 01:59:02,440 --> 01:59:06,719 answered the question correctly by 3190 01:59:03,760 --> 01:59:09,360 printing on the screen X less than y but 3191 01:59:06,719 --> 01:59:10,960 what is perhaps poorly designed about it 3192 01:59:09,360 --> 01:59:12,480 let's make this first distinction it's 3193 01:59:10,960 --> 01:59:13,960 not enough necessarily for the code that 3194 01:59:12,480 --> 01:59:15,840 you write to be correct and do what you 3195 01:59:13,960 --> 01:59:17,159 intend longer term especially as our 3196 01:59:15,840 --> 01:59:18,880 programs get longer and more 3197 01:59:17,159 --> 01:59:21,079 sophisticated more complicated we're 3198 01:59:18,880 --> 01:59:22,679 going to want them to be welld designed 3199 01:59:21,079 --> 01:59:25,239 too 3200 01:59:22,679 --> 01:59:27,440 thoughts on in what way this program is 3201 01:59:25,239 --> 01:59:29,920 arguably not welld 3202 01:59:27,440 --> 01:59:32,800 designed even though it's 3203 01:59:29,920 --> 01:59:35,000 correct let's see here uh khed if I'm 3204 01:59:32,800 --> 01:59:37,840 saying that right your thoughts too many 3205 01:59:35,000 --> 01:59:40,560 ifs I think is getting repetitive we can 3206 01:59:37,840 --> 01:59:42,400 make our code more concise maybe yeah it 3207 01:59:40,560 --> 01:59:45,320 seems a little repetitive I'm asking if 3208 01:59:42,400 --> 01:59:46,840 this if this if this and yet logically I 3209 01:59:45,320 --> 01:59:48,760 should know the answer to some of those 3210 01:59:46,840 --> 01:59:50,639 later questions once I figure one out 3211 01:59:48,760 --> 01:59:52,320 and in short if you look at this diagram 3212 01:59:50,639 --> 01:59:54,760 here notice that no matter matter 3213 01:59:52,320 --> 01:59:57,520 whether I go left or I go right I'm 3214 01:59:54,760 --> 01:59:59,560 always asking three questions no matter 3215 01:59:57,520 --> 02:00:02,159 what all of those arrows lead to the 3216 01:59:59,560 --> 02:00:04,320 first the second and the third Diamond 3217 02:00:02,159 --> 02:00:06,000 so I'm asking three questions no matter 3218 02:00:04,320 --> 02:00:07,520 whether any of those answers are true or 3219 02:00:06,000 --> 02:00:08,960 false well how might I go about 3220 02:00:07,520 --> 02:00:11,320 improving this well let me propose that 3221 02:00:08,960 --> 02:00:13,719 we introduce another keyword to our 3222 02:00:11,320 --> 02:00:15,679 python vocabulary namely L if and this 3223 02:00:13,719 --> 02:00:18,639 too is kind of a succinct one it's a 3224 02:00:15,679 --> 02:00:21,639 conjunction of else if in English which 3225 02:00:18,639 --> 02:00:24,199 allows us to ask a question that takes 3226 02:00:21,639 --> 02:00:26,639 into count whether or not a previous 3227 02:00:24,199 --> 02:00:28,159 question had a true or false answer well 3228 02:00:26,639 --> 02:00:30,599 what do I mean by that well let me go 3229 02:00:28,159 --> 02:00:34,079 back to my code here and let me propose 3230 02:00:30,599 --> 02:00:36,560 that we now improve upon this here by 3231 02:00:34,079 --> 02:00:38,920 asking ourselves ultimately how can we 3232 02:00:36,560 --> 02:00:42,040 ask fewer questions and let me go ahead 3233 02:00:38,920 --> 02:00:45,159 here and propose that instead of asking 3234 02:00:42,040 --> 02:00:47,520 if if if let's make these conditions 3235 02:00:45,159 --> 02:00:50,400 potentially mutually exclusive that is 3236 02:00:47,520 --> 02:00:53,040 to say don't keep answering questions 3237 02:00:50,400 --> 02:00:54,480 once we get back a true answer so I'm 3238 02:00:53,040 --> 02:00:56,880 going to change my code up here as 3239 02:00:54,480 --> 02:01:00,840 follows instead of asking if if if I'm 3240 02:00:56,880 --> 02:01:06,199 going to say if x less than y l if x 3241 02:01:00,840 --> 02:01:08,040 greater than y l if x equals equals y so 3242 02:01:06,199 --> 02:01:10,360 I'm going to implicitly just like an 3243 02:01:08,040 --> 02:01:12,599 English take into account that I'm only 3244 02:01:10,360 --> 02:01:15,480 going to keep a asking myself these 3245 02:01:12,599 --> 02:01:17,159 questions if I haven't yet gotten a true 3246 02:01:15,480 --> 02:01:21,440 response think about the logic here the 3247 02:01:17,159 --> 02:01:23,719 English if x is less than y on line four 3248 02:01:21,440 --> 02:01:26,159 print out out X is less than y well if 3249 02:01:23,719 --> 02:01:28,360 that's the case you're done logically 3250 02:01:26,159 --> 02:01:31,360 because if the English is saying if x 3251 02:01:28,360 --> 02:01:33,040 less than y else if x greater than y 3252 02:01:31,360 --> 02:01:34,960 those are going to be mutually exclusive 3253 02:01:33,040 --> 02:01:36,560 if the answer to the first question is 3254 02:01:34,960 --> 02:01:38,119 true you don't have to keep asking 3255 02:01:36,560 --> 02:01:40,239 questions to which you already logically 3256 02:01:38,119 --> 02:01:41,760 know the answer so let me go ahead now 3257 02:01:40,239 --> 02:01:43,440 and run this program and I think the 3258 02:01:41,760 --> 02:01:46,360 behavior is going to be the same python 3259 02:01:43,440 --> 02:01:49,760 of compare. Pi what's X let's do one 3260 02:01:46,360 --> 02:01:51,360 what's y let's do two x is less than y 3261 02:01:49,760 --> 02:01:53,119 now honestly I didn't really notice a 3262 02:01:51,360 --> 02:01:56,599 difference when I ran the program and 3263 02:01:53,119 --> 02:01:58,880 honestly my Mac my PC my phone nowadays 3264 02:01:56,599 --> 02:02:00,679 are so darn fast that these kinds of 3265 02:01:58,880 --> 02:02:03,159 improvements aren't going to necessarily 3266 02:02:00,679 --> 02:02:05,639 feel any faster until we're writing 3267 02:02:03,159 --> 02:02:07,280 bigger faster programs but it's laying 3268 02:02:05,639 --> 02:02:09,599 the foundation for writing better code 3269 02:02:07,280 --> 02:02:11,599 longer term now what is the Improvement 3270 02:02:09,599 --> 02:02:13,840 I've just made well if previously my 3271 02:02:11,599 --> 02:02:17,040 diagram looked like this which was 3272 02:02:13,840 --> 02:02:19,280 problematic in so far as I was asking 3273 02:02:17,040 --> 02:02:21,119 three questions no matter what even if I 3274 02:02:19,280 --> 02:02:23,079 already figur out what I want to print 3275 02:02:21,119 --> 02:02:26,159 on the screen this new version of the 3276 02:02:23,079 --> 02:02:27,400 program that says if L if L if might 3277 02:02:26,159 --> 02:02:29,400 look a little something like this 3278 02:02:27,400 --> 02:02:31,199 instead now it got a little wider that's 3279 02:02:29,400 --> 02:02:33,000 just because we drew the arrows to be a 3280 02:02:31,199 --> 02:02:34,840 bit wider here but let's focus on just 3281 02:02:33,000 --> 02:02:37,000 how many questions are getting asked let 3282 02:02:34,840 --> 02:02:39,400 me zoom in at the top as before and let 3283 02:02:37,000 --> 02:02:41,280 me propose that we note that the start 3284 02:02:39,400 --> 02:02:44,000 oval is at the very top and it's asking 3285 02:02:41,280 --> 02:02:46,400 us to ask one question first X less than 3286 02:02:44,000 --> 02:02:49,040 y is one less than two but notice here 3287 02:02:46,400 --> 02:02:52,320 let me zoom out if one is indeed less 3288 02:02:49,040 --> 02:02:55,960 than two we follow this long longer 3289 02:02:52,320 --> 02:02:58,719 Arrow the down Mark true we print out 3290 02:02:55,960 --> 02:03:00,679 quote unquote X is less than y but then 3291 02:02:58,719 --> 02:03:04,400 we immediately follow this next arrow 3292 02:03:00,679 --> 02:03:07,040 down to the icon that says stop so 3293 02:03:04,400 --> 02:03:09,400 that's what's implied by doing if L if L 3294 02:03:07,040 --> 02:03:11,239 if if we get back a true answer right 3295 02:03:09,400 --> 02:03:13,400 away to that first if we're going to 3296 02:03:11,239 --> 02:03:15,000 print out X is less than y and then stop 3297 02:03:13,400 --> 02:03:17,079 we're logically at the end of the 3298 02:03:15,000 --> 02:03:20,159 program so this picture is just 3299 02:03:17,079 --> 02:03:22,480 representing graphically what the code 3300 02:03:20,159 --> 02:03:24,280 is actually doing but suppose I typed in 3301 02:03:22,480 --> 02:03:27,840 something else suppose that my code 3302 02:03:24,280 --> 02:03:30,239 actually ran and I typed in two for x 3303 02:03:27,840 --> 02:03:32,239 and one for y that is to say the answer 3304 02:03:30,239 --> 02:03:34,079 to the first question is now false but 3305 02:03:32,239 --> 02:03:37,960 the answer to the second question is now 3306 02:03:34,079 --> 02:03:40,119 true because of course uh one uh two is 3307 02:03:37,960 --> 02:03:42,480 greater than one well let's go back to 3308 02:03:40,119 --> 02:03:44,480 the diagram same as before we start at 3309 02:03:42,480 --> 02:03:46,719 the very top where it says start the 3310 02:03:44,480 --> 02:03:49,880 very first question up here now X less 3311 02:03:46,719 --> 02:03:52,320 than y is an answer of false because no 3312 02:03:49,880 --> 02:03:54,159 two is not less than one so we follow 3313 02:03:52,320 --> 02:03:57,960 this arrow to the next question this 3314 02:03:54,159 --> 02:04:00,960 diamond is X greater than y well yes 2 3315 02:03:57,960 --> 02:04:03,920 is greater than 1 so now we follow this 3316 02:04:00,960 --> 02:04:06,719 left Arrow which is true we print out 3317 02:04:03,920 --> 02:04:09,440 quote unquote X is greater than y and 3318 02:04:06,719 --> 02:04:11,159 then stop so what's the Improvement well 3319 02:04:09,440 --> 02:04:12,960 in the first case we got lucky and we 3320 02:04:11,159 --> 02:04:15,239 only had to ask one question and boom 3321 02:04:12,960 --> 02:04:17,719 we're done this time we had to asked two 3322 02:04:15,239 --> 02:04:21,199 questions but then boom we're done only 3323 02:04:17,719 --> 02:04:23,760 if x happens to equal y do we actually 3324 02:04:21,199 --> 02:04:27,440 find our elves logically getting all the 3325 02:04:23,760 --> 02:04:30,320 way down to this final L if in my code 3326 02:04:27,440 --> 02:04:32,079 and pictorially only if x is equal to Y 3327 02:04:30,320 --> 02:04:34,239 do we find ourselves going all the way 3328 02:04:32,079 --> 02:04:38,719 down to the third Diamond the third 3329 02:04:34,239 --> 02:04:40,199 question asking is it equal to y or not 3330 02:04:38,719 --> 02:04:42,559 now hopefully the answer at that point 3331 02:04:40,199 --> 02:04:44,719 is not false we've included a false 3332 02:04:42,559 --> 02:04:47,199 Arrow just so that the program itself is 3333 02:04:44,719 --> 02:04:49,320 well defined but logically we shouldn't 3334 02:04:47,199 --> 02:04:51,360 actually be getting there anyway because 3335 02:04:49,320 --> 02:04:53,719 it's got to be less than or greater than 3336 02:04:51,360 --> 02:04:54,840 or equal to in this case well let me 3337 02:04:53,719 --> 02:04:56,880 pause here to see if there's any 3338 02:04:54,840 --> 02:04:59,639 questions now either on the code version 3339 02:04:56,880 --> 02:05:01,800 thereof here or on this diagramming of 3340 02:04:59,639 --> 02:05:06,520 that very same 3341 02:05:01,800 --> 02:05:09,960 logic questions here on this control 3342 02:05:06,520 --> 02:05:13,400 flow uh AR we supposed to put an else at 3343 02:05:09,960 --> 02:05:15,440 the end ah a good question and yes so 3344 02:05:13,400 --> 02:05:16,760 that's going to be my my third and Final 3345 02:05:15,440 --> 02:05:18,679 Approach and if you don't mind let's 3346 02:05:16,760 --> 02:05:20,639 pivot there right away identifying a 3347 02:05:18,679 --> 02:05:22,800 third keyword that indeed exists in 3348 02:05:20,639 --> 02:05:24,800 Python that allow ows us to be even 3349 02:05:22,800 --> 02:05:26,840 better at expressing this logic to 3350 02:05:24,800 --> 02:05:28,679 design this program even better and 3351 02:05:26,840 --> 02:05:31,079 that's going to solve a particular 3352 02:05:28,679 --> 02:05:33,719 problem so if I take us back to our code 3353 02:05:31,079 --> 02:05:37,159 here notice that what I've highlighted 3354 02:05:33,719 --> 02:05:39,239 earlier L ifx equals equals y it's not 3355 02:05:37,159 --> 02:05:41,400 wrong to ask that question in fact if 3356 02:05:39,239 --> 02:05:43,239 you're trying to be especially thorough 3357 02:05:41,400 --> 02:05:47,440 it makes perfect sense to check if x is 3358 02:05:43,239 --> 02:05:51,480 less than y greater than y or equal to Y 3359 02:05:47,440 --> 02:05:53,719 but why don't I need to ask this third 3360 02:05:51,480 --> 02:05:56,960 and and final question we don't need to 3361 02:05:53,719 --> 02:05:59,960 ask if x is equal to Y anymore because 3362 02:05:56,960 --> 02:06:04,159 logically if the two conditionals 3363 02:05:59,960 --> 02:06:05,800 evaluate to false there is only one um 3364 02:06:04,159 --> 02:06:08,520 conditional that will evaluate to true 3365 02:06:05,800 --> 02:06:10,119 and that is X is equal to Y exactly if 3366 02:06:08,520 --> 02:06:12,159 we're all pretty comfortable with math 3367 02:06:10,119 --> 02:06:13,960 and comparisons here of course X is 3368 02:06:12,159 --> 02:06:16,239 either going to be less than y greater 3369 02:06:13,960 --> 02:06:18,639 than y or equal to Y but once you rule 3370 02:06:16,239 --> 02:06:20,320 out the first two scenarios logically 3371 02:06:18,639 --> 02:06:22,159 it's got to be the case that X must 3372 02:06:20,320 --> 02:06:24,639 equal y if it wasn't the case that it's 3373 02:06:22,159 --> 02:06:26,920 less than or greater than so hope propos 3374 02:06:24,639 --> 02:06:28,440 that we use this other keyword else and 3375 02:06:26,920 --> 02:06:29,920 how do we use this well exactly as we 3376 02:06:28,440 --> 02:06:32,440 might in English let me go back to my 3377 02:06:29,920 --> 02:06:34,679 code here and instead of bothering to 3378 02:06:32,440 --> 02:06:36,280 ask the third and final question let's 3379 02:06:34,679 --> 02:06:39,000 not ask a question at all let's just 3380 02:06:36,280 --> 02:06:42,119 have this catchall so to speak a final 3381 02:06:39,000 --> 02:06:44,440 line of code that says else just assume 3382 02:06:42,119 --> 02:06:46,559 that X is equal to Y therefore printing 3383 02:06:44,440 --> 02:06:48,679 it as well so what's the upside of that 3384 02:06:46,559 --> 02:06:50,760 my code is still going to work exactly 3385 02:06:48,679 --> 02:06:52,559 the same and again my computer's so darn 3386 02:06:50,760 --> 02:06:55,079 fast I don't even notice that it's 3387 02:06:52,559 --> 02:06:56,559 working even faster than it was before 3388 02:06:55,079 --> 02:06:58,280 but we would notice these kinds of 3389 02:06:56,559 --> 02:07:00,239 things if we were doing a lot more work 3390 02:06:58,280 --> 02:07:03,000 a lot bigger programs here but let me 3391 02:07:00,239 --> 02:07:06,119 run python of compare. piy let's do for 3392 02:07:03,000 --> 02:07:08,800 instance one and two still works for 3393 02:07:06,119 --> 02:07:11,400 that let's do two and one still works 3394 02:07:08,800 --> 02:07:13,920 for that let's do one and one and it 3395 02:07:11,400 --> 02:07:16,159 indeed now works for that but in these 3396 02:07:13,920 --> 02:07:18,599 cases now let's consider the path we 3397 02:07:16,159 --> 02:07:21,800 just went down previously our diagram 3398 02:07:18,599 --> 02:07:24,239 when we had if L if L if in place looked 3399 02:07:21,800 --> 02:07:26,040 a little something like this and notice 3400 02:07:24,239 --> 02:07:28,800 that again we might have asked one 3401 02:07:26,040 --> 02:07:30,280 question or two or worst case three 3402 02:07:28,800 --> 02:07:33,159 whole questions but we can do better 3403 02:07:30,280 --> 02:07:35,159 than that using else as hope proposed we 3404 02:07:33,159 --> 02:07:36,599 can Whittle this diagram now down to 3405 02:07:35,159 --> 02:07:38,079 this and even though it looks like the 3406 02:07:36,599 --> 02:07:40,719 diagram is getting bigger notice that 3407 02:07:38,079 --> 02:07:42,520 it's having fewer uh building blocks 3408 02:07:40,719 --> 02:07:44,920 inside of it there's fewer arrows and 3409 02:07:42,520 --> 02:07:47,480 there's fewer nodes in this picture 3410 02:07:44,920 --> 02:07:49,199 let's start at the top now start leads 3411 02:07:47,480 --> 02:07:51,520 us to the first question still X less 3412 02:07:49,199 --> 02:07:53,280 than y if the answer is true great we 3413 02:07:51,520 --> 02:07:55,920 can say as much X is less than y and we 3414 02:07:53,280 --> 02:07:57,599 can stop if it's not true if it's false 3415 02:07:55,920 --> 02:08:00,119 we can ask the next question X is 3416 02:07:57,599 --> 02:08:02,119 greater than y true or false if it is 3417 02:08:00,119 --> 02:08:04,719 great we can print X as greater than y 3418 02:08:02,119 --> 02:08:07,159 and stop else if it's not the case that 3419 02:08:04,719 --> 02:08:10,520 X is greater than y the answer is false 3420 02:08:07,159 --> 02:08:12,800 we can just immediately logically say x 3421 02:08:10,520 --> 02:08:14,760 is equal to Y we don't have to add the 3422 02:08:12,800 --> 02:08:17,000 third question at all we can just 3423 02:08:14,760 --> 02:08:18,760 immediately conclude there so what's the 3424 02:08:17,000 --> 02:08:21,079 implication here you can see with these 3425 02:08:18,760 --> 02:08:23,400 pictures a relative decrease in the 3426 02:08:21,079 --> 02:08:25,320 comple it of a program the first one was 3427 02:08:23,400 --> 02:08:27,880 very long and stringy with lots and lots 3428 02:08:25,320 --> 02:08:29,400 of questions unnecessarily ultimately 3429 02:08:27,880 --> 02:08:32,000 the next one got a little shorter and 3430 02:08:29,400 --> 02:08:34,280 this one's even shorter still and again 3431 02:08:32,000 --> 02:08:36,559 the fewer lines of code you have the 3432 02:08:34,280 --> 02:08:38,079 less likely you are arguably to make any 3433 02:08:36,559 --> 02:08:40,440 mistakes the easier it is for other 3434 02:08:38,079 --> 02:08:42,920 people to read and so generally this 3435 02:08:40,440 --> 02:08:45,079 readability this simplification is 3436 02:08:42,920 --> 02:08:47,960 indeed a good thing well let's go ahead 3437 02:08:45,079 --> 02:08:50,040 and add another piece of uh capability 3438 02:08:47,960 --> 02:08:51,559 into Python and that's this one here 3439 02:08:50,040 --> 02:08:53,520 just like in English where you can ask 3440 02:08:51,559 --> 02:08:55,599 this question or this other question you 3441 02:08:53,520 --> 02:08:58,199 can say the same thing in Python using 3442 02:08:55,599 --> 02:09:01,000 literally this word or so let me go back 3443 02:08:58,199 --> 02:09:02,760 to my python code here and let's propose 3444 02:09:01,000 --> 02:09:05,000 how we might ask a couple of questions 3445 02:09:02,760 --> 02:09:07,840 at once this time perhaps this time 3446 02:09:05,000 --> 02:09:09,840 considering how we might ask not whether 3447 02:09:07,840 --> 02:09:11,960 or not it's greater than or equal to and 3448 02:09:09,840 --> 02:09:14,199 caring about the precise answer let's 3449 02:09:11,960 --> 02:09:17,840 take a a coarser approach here and let's 3450 02:09:14,199 --> 02:09:21,520 just try to determine is X greater is x 3451 02:09:17,840 --> 02:09:23,199 equal to y or not well let me go ahead 3452 02:09:21,520 --> 02:09:24,960 delete some of this code and change the 3453 02:09:23,199 --> 02:09:27,199 question we're asking let me do this 3454 02:09:24,960 --> 02:09:28,960 well if I care about whether it's equal 3455 02:09:27,199 --> 02:09:33,599 or not let's check the possible 3456 02:09:28,960 --> 02:09:35,880 scenarios if x is less than y or X is 3457 02:09:33,599 --> 02:09:40,559 greater than y let's go ahead and print 3458 02:09:35,880 --> 02:09:43,639 out X is not equal to Y now why is that 3459 02:09:40,559 --> 02:09:45,760 no pun intended if x is less than y well 3460 02:09:43,639 --> 02:09:47,599 it's obviously not equal if x is greater 3461 02:09:45,760 --> 02:09:52,639 than y it's obviously not equal so we 3462 02:09:47,599 --> 02:09:56,119 can conclude X is not equal to y so if 3463 02:09:52,639 --> 02:09:59,480 we instead want to make sure that it is 3464 02:09:56,119 --> 02:10:03,199 equal to we can just use uh hopes else 3465 02:09:59,480 --> 02:10:06,000 using print quote unquote X is equal to 3466 02:10:03,199 --> 02:10:08,079 Y and again why is this well if x is 3467 02:10:06,000 --> 02:10:10,119 less than y or X is greater than y 3468 02:10:08,079 --> 02:10:12,360 they're obviously not equal otherwise 3469 02:10:10,119 --> 02:10:13,840 logically they must be equal in fact so 3470 02:10:12,360 --> 02:10:16,639 let's run this let's go ahead and run 3471 02:10:13,840 --> 02:10:19,599 python of compare. Pi what's X One 3472 02:10:16,639 --> 02:10:22,239 what's Y 2 okay X is not equal to Y 3473 02:10:19,599 --> 02:10:25,320 let's do it again but two for x one for 3474 02:10:22,239 --> 02:10:29,119 Y X is not equal to Y and one third time 3475 02:10:25,320 --> 02:10:31,639 how about X is 1 and Y is One X is now 3476 02:10:29,119 --> 02:10:34,239 equal to Y now if we want to compare 3477 02:10:31,639 --> 02:10:35,639 that visually too let me propose that 3478 02:10:34,239 --> 02:10:37,960 the picture looks a little something 3479 02:10:35,639 --> 02:10:39,800 like this and again this is the exact 3480 02:10:37,960 --> 02:10:41,520 same thing logically but it's a pictoral 3481 02:10:39,800 --> 02:10:44,719 representation thereof what's the first 3482 02:10:41,520 --> 02:10:47,079 question well if x is less than y well 3483 02:10:44,719 --> 02:10:49,639 then we follow the true arrow and we say 3484 02:10:47,079 --> 02:10:52,960 quote unquote X is not equal to Y and 3485 02:10:49,639 --> 02:10:54,559 then we stop but what if X is not less 3486 02:10:52,960 --> 02:10:56,880 than y what if it's greater than y what 3487 02:10:54,559 --> 02:10:59,400 if it's 2 and one respectively then the 3488 02:10:56,880 --> 02:11:02,239 answer to x less than y's first question 3489 02:10:59,400 --> 02:11:05,199 is false so we go here we ask the second 3490 02:11:02,239 --> 02:11:08,239 question because of the or and that asks 3491 02:11:05,199 --> 02:11:10,559 is X greater than y if so notice this we 3492 02:11:08,239 --> 02:11:13,199 can kind of reuse some of the same parts 3493 02:11:10,559 --> 02:11:15,079 of this picture and just say X is not 3494 02:11:13,199 --> 02:11:18,040 equal to Y we don't need to add arrows 3495 02:11:15,079 --> 02:11:20,280 and add boxes unnecessarily we can reuse 3496 02:11:18,040 --> 02:11:22,239 lines of code uh picture parts of the 3497 02:11:20,280 --> 02:11:24,960 picture just as we have lines of code 3498 02:11:22,239 --> 02:11:26,960 and then we stop lastly we have the 3499 02:11:24,960 --> 02:11:29,079 following if we know that X is not less 3500 02:11:26,960 --> 02:11:31,400 than y we know that X is not greater 3501 02:11:29,079 --> 02:11:33,599 than y it must be the case that x equals 3502 02:11:31,400 --> 02:11:35,440 y we don't need to ask a third question 3503 02:11:33,599 --> 02:11:39,079 another diamond we can just immediately 3504 02:11:35,440 --> 02:11:41,800 print as much and then say uh stop as 3505 02:11:39,079 --> 02:11:44,679 well well what could I do here I bet I 3506 02:11:41,800 --> 02:11:47,119 could improve this code slightly and if 3507 02:11:44,679 --> 02:11:49,440 we really want to be nitpicky I would 3508 02:11:47,119 --> 02:11:51,400 argue that this is now really just a 3509 02:11:49,440 --> 02:11:53,920 minor refinement but it's a good habit 3510 02:11:51,400 --> 02:11:55,920 to get into thinking about could my code 3511 02:11:53,920 --> 02:11:58,599 be better could my code be 3512 02:11:55,920 --> 02:12:01,599 simpler could I improve this code 3513 02:11:58,599 --> 02:12:04,599 further it's subtle but could I improve 3514 02:12:01,599 --> 02:12:07,119 the design could I ask fewer questions 3515 02:12:04,599 --> 02:12:11,440 could I tighten it up so to 3516 02:12:07,119 --> 02:12:15,599 speak what do folks think you can ask if 3517 02:12:11,440 --> 02:12:19,760 x is just equal to Y then if you print x 3518 02:12:15,599 --> 02:12:21,480 equal to Y else X is not equal to Y 3519 02:12:19,760 --> 02:12:23,320 perfect recall one of the other symbols 3520 02:12:21,480 --> 02:12:25,199 we saw on the available list earlier we 3521 02:12:23,320 --> 02:12:27,320 can check not just less than or greater 3522 02:12:25,199 --> 02:12:29,400 than or equal to we can literally ask 3523 02:12:27,320 --> 02:12:31,840 the question is it not equal to why are 3524 02:12:29,400 --> 02:12:33,719 we wasting time asking if it's less than 3525 02:12:31,840 --> 02:12:35,520 or if it's greater than well if all you 3526 02:12:33,719 --> 02:12:37,639 care about is is it not equal I think we 3527 02:12:35,520 --> 02:12:40,280 can do exactly that let's just ask the 3528 02:12:37,639 --> 02:12:42,000 one simple question we do care about and 3529 02:12:40,280 --> 02:12:44,000 so let me go back up here and let me 3530 02:12:42,000 --> 02:12:45,920 just say not both of these questions 3531 02:12:44,000 --> 02:12:49,920 let's get rid of the or let's just say 3532 02:12:45,920 --> 02:12:52,960 if X is not equal to Y then go ahead and 3533 02:12:49,920 --> 02:12:54,719 print X is not equal to Y and that too I 3534 02:12:52,960 --> 02:12:57,000 think is going to work exactly the same 3535 02:12:54,719 --> 02:12:58,400 but the picture now looks a little bit 3536 02:12:57,000 --> 02:13:00,960 different notice that this was our 3537 02:12:58,400 --> 02:13:02,280 flowchart earlier that represented that 3538 02:13:00,960 --> 02:13:03,880 same logic and there's a bit of 3539 02:13:02,280 --> 02:13:05,360 complexity you got to go left you got to 3540 02:13:03,880 --> 02:13:07,400 go right based on the answer to these 3541 02:13:05,360 --> 02:13:09,079 couple of questions if we now take into 3542 02:13:07,400 --> 02:13:11,119 account what this version of the program 3543 02:13:09,079 --> 02:13:12,800 looks like it's even simpler perhaps the 3544 02:13:11,119 --> 02:13:14,679 simplest one we've seen yet when we 3545 02:13:12,800 --> 02:13:17,239 start off the program we ask just one 3546 02:13:14,679 --> 02:13:20,440 and only one question is X not equal to 3547 02:13:17,239 --> 02:13:23,480 Y and if so true we go ahead and print 3548 02:13:20,440 --> 02:13:25,559 out X X not equal to Y if the answer is 3549 02:13:23,480 --> 02:13:28,159 false then of course it must be equal to 3550 02:13:25,559 --> 02:13:30,159 Y so we say that instead and if we 3551 02:13:28,159 --> 02:13:32,280 really want we could invert this if I go 3552 02:13:30,159 --> 02:13:34,159 back here to my code and if for whatever 3553 02:13:32,280 --> 02:13:37,760 reason you just prefer to think in terms 3554 02:13:34,159 --> 02:13:40,840 of equal or not equal as opposed to not 3555 02:13:37,760 --> 02:13:43,599 equal or equal it's really uh up to you 3556 02:13:40,840 --> 02:13:45,520 we could change this to be equals equals 3557 02:13:43,599 --> 02:13:47,559 but I'm going to have to change my print 3558 02:13:45,520 --> 02:13:49,599 statements to be in the opposite order 3559 02:13:47,559 --> 02:13:51,559 so let me go ahead now and reverse these 3560 02:13:49,599 --> 02:13:53,960 two here and move 3561 02:13:51,559 --> 02:13:56,440 the second one first and the first one 3562 02:13:53,960 --> 02:13:58,040 second so now when I execute this code 3563 02:13:56,440 --> 02:14:00,320 I'm asking still just one question so 3564 02:13:58,040 --> 02:14:02,000 it's still just as good just as succinct 3565 02:14:00,320 --> 02:14:04,079 but now the diagram instead of looking 3566 02:14:02,000 --> 02:14:06,679 like this is going to change the not 3567 02:14:04,079 --> 02:14:08,880 equal to equal equal and we just need to 3568 02:14:06,679 --> 02:14:11,239 make sure that we print out the right 3569 02:14:08,880 --> 02:14:12,719 thing accordingly and again here too 3570 02:14:11,239 --> 02:14:14,559 just as the code is getting a little 3571 02:14:12,719 --> 02:14:16,760 more compact a little more compact with 3572 02:14:14,559 --> 02:14:19,440 fewer and fewer characters so are these 3573 02:14:16,760 --> 02:14:22,079 diagrams these flowcharts capturing the 3574 02:14:19,440 --> 02:14:24,159 relative simplification of each of those 3575 02:14:22,079 --> 02:14:26,119 programs too all right let me go ahead 3576 02:14:24,159 --> 02:14:28,239 and pause here to see if there's any 3577 02:14:26,119 --> 02:14:30,480 questions now on any of these versions 3578 02:14:28,239 --> 02:14:30,480 of 3579 02:14:31,239 --> 02:14:36,960 code yeah I have a couple of questions 3580 02:14:34,040 --> 02:14:39,920 uh what if indentation is not 3581 02:14:36,960 --> 02:14:42,480 used uh if indentation is not used your 3582 02:14:39,920 --> 02:14:44,360 program will not work so python is a 3583 02:14:42,480 --> 02:14:46,719 little different from a lot of languages 3584 02:14:44,360 --> 02:14:48,639 in that it enforces the indentation 3585 02:14:46,719 --> 02:14:50,079 requirement uh some of you who have been 3586 02:14:48,639 --> 02:14:51,760 programming for years might not 3587 02:14:50,079 --> 02:14:53,840 necessarily be in the best habit of 3588 02:14:51,760 --> 02:14:56,320 indenting your code properly and one of 3589 02:14:53,840 --> 02:14:58,760 the features arguably of python is that 3590 02:14:56,320 --> 02:15:01,239 it makes you indent your code or it will 3591 02:14:58,760 --> 02:15:04,400 not just work and I think did you have 3592 02:15:01,239 --> 02:15:05,480 one other question uh yeah uh is the 3593 02:15:04,400 --> 02:15:09,000 colon 3594 02:15:05,480 --> 02:15:11,920 necessary is the colon necessary yes the 3595 02:15:09,000 --> 02:15:14,159 colon 2 is necessary so with python what 3596 02:15:11,920 --> 02:15:16,000 you see is what you get here and indeed 3597 02:15:14,159 --> 02:15:18,280 it needs to be indented and the colon is 3598 02:15:16,000 --> 02:15:21,000 necessary python does not use in the 3599 02:15:18,280 --> 02:15:23,040 same way by Convention as C and C++ and 3600 02:15:21,000 --> 02:15:25,440 Java curly braces to canote blocks 3601 02:15:23,040 --> 02:15:27,480 instead it relies indeed on this 3602 02:15:25,440 --> 02:15:29,599 indentation well let me propose that we 3603 02:15:27,480 --> 02:15:31,520 introduce one other keyword here in 3604 02:15:29,599 --> 02:15:33,239 Python to see exactly how we might 3605 02:15:31,520 --> 02:15:34,840 combine additional thoughts and that's 3606 02:15:33,239 --> 02:15:37,920 going to be literally the word and a 3607 02:15:34,840 --> 02:15:39,840 conjunction of one or two or more 3608 02:15:37,920 --> 02:15:42,280 questions that we might want to ask at 3609 02:15:39,840 --> 02:15:44,719 once and let me propose here that we 3610 02:15:42,280 --> 02:15:46,719 explore this kind of logic by way of 3611 02:15:44,719 --> 02:15:48,559 another program Al together in VSS code 3612 02:15:46,719 --> 02:15:51,679 whereby I'll go ahead now and create a 3613 02:15:48,559 --> 02:15:53,400 new program say called grade. Pi let's 3614 02:15:51,679 --> 02:15:55,119 consider exactly what grade a student 3615 02:15:53,400 --> 02:15:57,400 should get based on their score on an 3616 02:15:55,119 --> 02:15:59,000 exam or a test or a quiz or some other 3617 02:15:57,400 --> 02:16:01,280 assignment like that I'm going to go 3618 02:15:59,000 --> 02:16:03,000 ahead and run code of grade. py to give 3619 02:16:01,280 --> 02:16:04,520 myself a new file and I'm going to go 3620 02:16:03,000 --> 02:16:06,440 ahead and start by just getting the user 3621 02:16:04,520 --> 02:16:08,119 score again on some assignment or test 3622 02:16:06,440 --> 02:16:10,880 or the like and I'm going to store it in 3623 02:16:08,119 --> 02:16:12,599 a variable called score equal the return 3624 02:16:10,880 --> 02:16:14,480 value of the int function which is going 3625 02:16:12,599 --> 02:16:16,800 to convert whatever the user's input is 3626 02:16:14,480 --> 02:16:18,599 when prompted for this score so again 3627 02:16:16,800 --> 02:16:21,000 the user should just Oblige by giving me 3628 02:16:18,599 --> 02:16:22,920 a number like zero or one or two or or 3629 02:16:21,000 --> 02:16:26,000 hopefully much higher than that like 997 3630 02:16:22,920 --> 02:16:28,320 98 99 100 assuming the test or 3631 02:16:26,000 --> 02:16:29,960 assessment is out of 100 percentage 3632 02:16:28,320 --> 02:16:33,000 points now how could I go about 3633 02:16:29,960 --> 02:16:35,040 assigning a grade to the student score 3634 02:16:33,000 --> 02:16:36,800 well in the US it's very commonly the 3635 02:16:35,040 --> 02:16:40,040 case that if you get between a 90 and 3636 02:16:36,800 --> 02:16:44,120 100 that's an A and if it's between an 3637 02:16:40,040 --> 02:16:46,439 80 and a 89 it's a b if it's 70 and 79 3638 02:16:44,120 --> 02:16:48,760 it's a c and so forth all the way down 3639 02:16:46,439 --> 02:16:50,399 to F which should be e but we'll see 3640 02:16:48,760 --> 02:16:52,000 that there's a bit of a jump so how 3641 02:16:50,399 --> 02:16:53,399 might I exess this well I can use 3642 02:16:52,000 --> 02:16:54,760 conditionals and I can ask a few 3643 02:16:53,399 --> 02:16:56,679 questions and then print out the 3644 02:16:54,760 --> 02:16:58,599 student's grade accordingly so let me 3645 02:16:56,679 --> 02:17:02,240 express it like this if the student 3646 02:16:58,599 --> 02:17:04,240 score is greater than or equal to 90 and 3647 02:17:02,240 --> 02:17:07,160 the student score is less than or equal 3648 02:17:04,240 --> 02:17:08,960 to 100 so it's in that range let's go 3649 02:17:07,160 --> 02:17:11,719 ahead and print out that their grade 3650 02:17:08,960 --> 02:17:16,359 shall be in a because they're in the 90s 3651 02:17:11,719 --> 02:17:18,880 above grades range L if the score is 3652 02:17:16,359 --> 02:17:21,359 greater than or equal to 80 and the 3653 02:17:18,880 --> 02:17:23,679 score is less than or equal to say 3654 02:17:21,359 --> 02:17:25,479 89 but here I have some options 3655 02:17:23,679 --> 02:17:27,080 logically I can actually express myself 3656 02:17:25,479 --> 02:17:28,359 in any number of ways and maybe just to 3657 02:17:27,080 --> 02:17:31,800 be a little cleaner I'm going to say in 3658 02:17:28,359 --> 02:17:34,120 score is less than 90 so I'm using less 3659 02:17:31,800 --> 02:17:35,880 than instead of less than or equal to so 3660 02:17:34,120 --> 02:17:37,679 I'm making sure that their boundaries 3661 02:17:35,880 --> 02:17:38,880 between these grades are correct then 3662 02:17:37,679 --> 02:17:43,000 I'm going to go ahead and give the 3663 02:17:38,880 --> 02:17:45,639 student a b if it's in the 80s L if 3664 02:17:43,000 --> 02:17:47,719 score is greater than or equal to 70 and 3665 02:17:45,639 --> 02:17:51,519 the score is less than 80 I'm going to 3666 02:17:47,719 --> 02:17:54,240 go ahead and give them a c l if the 3667 02:17:51,519 --> 02:17:56,359 score is greater than or equal to 60 and 3668 02:17:54,240 --> 02:17:58,639 the score is less than 70 I'm going to 3669 02:17:56,359 --> 02:18:00,040 go ahead and give them a d and here's 3670 02:17:58,639 --> 02:18:02,399 where it's a little anomalous at least 3671 02:18:00,040 --> 02:18:05,120 in some schools here else I'm going to 3672 02:18:02,399 --> 02:18:07,160 go ahead and give them uh an F so we're 3673 02:18:05,120 --> 02:18:09,760 skipping e Al together and we're going 3674 02:18:07,160 --> 02:18:11,559 to give an f instead for the grade so 3675 02:18:09,760 --> 02:18:13,719 that's the catchall and I think 3676 02:18:11,559 --> 02:18:15,120 logically I've gotten this correct at 3677 02:18:13,719 --> 02:18:17,280 least based on where I went to school 3678 02:18:15,120 --> 02:18:20,319 growing up such that it's going to give 3679 02:18:17,280 --> 02:18:22,200 an A or a b or a c or a d else it's 3680 02:18:20,319 --> 02:18:23,840 going to ass assume that you got an F 3681 02:18:22,200 --> 02:18:26,639 well let's try just a few of these here 3682 02:18:23,840 --> 02:18:29,080 let's run python of grade. Pi my score 3683 02:18:26,639 --> 02:18:31,120 is let's let's start strong 100 all 3684 02:18:29,080 --> 02:18:33,920 right I got an A didn't do as well the 3685 02:18:31,120 --> 02:18:36,240 next time maybe it's a 95 still an a 3686 02:18:33,920 --> 02:18:39,280 starting to slip further so I got an 89 3687 02:18:36,240 --> 02:18:41,000 the next time that's now say a b and 3688 02:18:39,280 --> 02:18:44,160 let's say I really had a bad week and 3689 02:18:41,000 --> 02:18:46,319 it's now like a 71 that's now A C or I 3690 02:18:44,160 --> 02:18:48,240 didn't even submited at all that's a an 3691 02:18:46,319 --> 02:18:50,040 F Al together all right so it seems to 3692 02:18:48,240 --> 02:18:51,800 work that's not really an exhaustive 3693 02:18:50,040 --> 02:18:54,559 test but at least based on some sampling 3694 02:18:51,800 --> 02:18:55,960 there my code seems to work as I expect 3695 02:18:54,559 --> 02:18:57,880 but let's see if we can't tighten this 3696 02:18:55,960 --> 02:18:59,040 up it's not wrong it's correct and 3697 02:18:57,880 --> 02:19:00,679 indeed according to my own 3698 02:18:59,040 --> 02:19:03,000 specifications I dare say this code is 3699 02:19:00,679 --> 02:19:05,240 correct but can we tighten it up can we 3700 02:19:03,000 --> 02:19:06,880 reduce the probability of bugs now or 3701 02:19:05,240 --> 02:19:08,719 down the line can we increase the 3702 02:19:06,880 --> 02:19:10,280 readability of it and can we increase 3703 02:19:08,719 --> 02:19:12,800 the efficiency of it can we get the 3704 02:19:10,280 --> 02:19:15,240 computer to have to answer fewer 3705 02:19:12,800 --> 02:19:16,639 questions and still get the same result 3706 02:19:15,240 --> 02:19:18,399 well let's see what we might do let me 3707 02:19:16,639 --> 02:19:19,719 just kind of switch things up if only to 3708 02:19:18,399 --> 02:19:22,519 demonstrate that we can use these 3709 02:19:19,719 --> 02:19:24,760 symbols in different ways is I could say 3710 02:19:22,519 --> 02:19:27,080 as I've done if score is greater than or 3711 02:19:24,760 --> 02:19:28,960 equal to 90 but I can actually do this I 3712 02:19:27,080 --> 02:19:32,479 can flip it around instead of saying 3713 02:19:28,960 --> 02:19:35,559 greater than or equal to let's say 90 is 3714 02:19:32,479 --> 02:19:38,920 less than or equal to score and here 3715 02:19:35,559 --> 02:19:41,080 let's say if 80 is less than or equal to 3716 02:19:38,920 --> 02:19:43,960 score and here 3717 02:19:41,080 --> 02:19:46,599 70 is less than or equal to score and 3718 02:19:43,960 --> 02:19:49,000 then lastly 60 is less than or equal to 3719 02:19:46,599 --> 02:19:50,720 score so it's the same thing logically 3720 02:19:49,000 --> 02:19:52,080 I'm just kind of switching things around 3721 02:19:50,720 --> 02:19:54,479 just like you could do on paper pencil 3722 02:19:52,080 --> 02:19:56,120 if you really wanted but now notice this 3723 02:19:54,479 --> 02:19:58,080 trick and this is not possible for those 3724 02:19:56,120 --> 02:20:01,080 of you who have programmed in C or C++ 3725 02:19:58,080 --> 02:20:03,800 or Java or other languages notice what I 3726 02:20:01,080 --> 02:20:05,640 can do here is actually combine these 3727 02:20:03,800 --> 02:20:08,520 ranges notice that I'm asking two 3728 02:20:05,640 --> 02:20:11,399 questions two Boolean Expressions is 90 3729 02:20:08,520 --> 02:20:13,960 less than or equal to score and is score 3730 02:20:11,399 --> 02:20:16,479 less than or equal to 100 well python 3731 02:20:13,960 --> 02:20:18,720 allows you to Nest these things like 3732 02:20:16,479 --> 02:20:21,120 this and chain them together and just 3733 02:20:18,720 --> 02:20:24,080 like you would on paper pencil the real 3734 02:20:21,120 --> 02:20:25,439 world you can encode in Python do this 3735 02:20:24,080 --> 02:20:27,080 which is just a little cleaner right 3736 02:20:25,439 --> 02:20:28,920 it's tightening up the code a little bit 3737 02:20:27,080 --> 02:20:31,160 it's fewer keystrokes it's faster to 3738 02:20:28,920 --> 02:20:34,040 type it's easier to read moving forward 3739 02:20:31,160 --> 02:20:36,000 so that's arguably better as well so 3740 02:20:34,040 --> 02:20:37,840 that's one Improvement it's largely 3741 02:20:36,000 --> 02:20:39,800 aesthetic in this case it's still asking 3742 02:20:37,840 --> 02:20:42,680 the same number of questions but it's 3743 02:20:39,800 --> 02:20:45,399 doing it a little more succinctly still 3744 02:20:42,680 --> 02:20:47,359 well what what more could I do here next 3745 02:20:45,399 --> 02:20:48,880 well you know what each time I'm 3746 02:20:47,359 --> 02:20:51,000 deciding these grades I don't think I 3747 02:20:48,880 --> 02:20:53,319 have to ask two questions I I don't have 3748 02:20:51,000 --> 02:20:55,359 to ask is it greater than 90 and less 3749 02:20:53,319 --> 02:20:58,760 than 100 is it greater than 80 and less 3750 02:20:55,359 --> 02:21:01,080 than 90 if I kind of rethink my logic I 3751 02:20:58,760 --> 02:21:03,479 can maybe do this better still let me 3752 02:21:01,080 --> 02:21:05,840 propose that we simplify this further 3753 02:21:03,479 --> 02:21:07,399 and just do this if we know the input 3754 02:21:05,840 --> 02:21:09,680 for the moment is going to be within 3755 02:21:07,399 --> 02:21:11,479 zero and 100 we can make some 3756 02:21:09,680 --> 02:21:13,840 assumptions we could say something like 3757 02:21:11,479 --> 02:21:17,640 if the score is greater than or equal to 3758 02:21:13,840 --> 02:21:19,920 90 well the student gets an A L if the 3759 02:21:17,640 --> 02:21:22,600 score is greater than or equal to 80 the 3760 02:21:19,920 --> 02:21:26,880 student gets a b l if score is greater 3761 02:21:22,600 --> 02:21:29,720 than or equal to 70 they get a c l if 3762 02:21:26,880 --> 02:21:34,359 the score is greater than or equal to 60 3763 02:21:29,720 --> 02:21:36,399 they get a d else they get an F so what 3764 02:21:34,359 --> 02:21:39,399 have I done here well instead of asking 3765 02:21:36,399 --> 02:21:41,240 two questions every time checking the 3766 02:21:39,399 --> 02:21:43,120 lower bound and the upper bound of that 3767 02:21:41,240 --> 02:21:45,200 range I'm kind of being a little more 3768 02:21:43,120 --> 02:21:47,720 clever here by asking if the score is 3769 02:21:45,200 --> 02:21:49,880 greater than 90 well they've obviously 3770 02:21:47,720 --> 02:21:51,120 gotten an A or better if your score is 3771 02:21:49,880 --> 02:21:52,920 greater than A8 3772 02:21:51,120 --> 02:21:55,760 well you either deserve an a if it's 3773 02:21:52,920 --> 02:21:59,399 really strong or a B if it's just above 3774 02:21:55,760 --> 02:22:00,880 80 but because of the if L if logic 3775 02:21:59,399 --> 02:22:03,120 we've already checked is the student 3776 02:22:00,880 --> 02:22:04,520 score greater than 90 and if it's not 3777 02:22:03,120 --> 02:22:06,800 then we're asking the question well is 3778 02:22:04,520 --> 02:22:09,399 it greater than 80 so you implicitly 3779 02:22:06,800 --> 02:22:12,359 know it's somewhere in the 80 to 89 3780 02:22:09,399 --> 02:22:15,080 range else you know it's in the 70 to 79 3781 02:22:12,359 --> 02:22:17,200 range else it's in the next range down 3782 02:22:15,080 --> 02:22:19,040 so it's a minor optimization that allows 3783 02:22:17,200 --> 02:22:20,920 us to ask fewer questions but again it's 3784 02:22:19,040 --> 02:22:23,000 making the code arguably a a little more 3785 02:22:20,920 --> 02:22:25,600 readable certainly more succinct and 3786 02:22:23,000 --> 02:22:29,359 then hopefully more maintainable longer 3787 02:22:25,600 --> 02:22:32,920 term any questions then on these 3788 02:22:29,359 --> 02:22:34,600 types of changes and this type of logic 3789 02:22:32,920 --> 02:22:37,800 with our 3790 02:22:34,600 --> 02:22:41,800 code uh what if we don't use l if at all 3791 02:22:37,800 --> 02:22:43,520 what if we uh write the code in F yeah 3792 02:22:41,800 --> 02:22:46,120 so that's a good question because it's 3793 02:22:43,520 --> 02:22:48,000 actually going to have an unintended 3794 02:22:46,120 --> 02:22:49,800 effect here let me get rid of the F 3795 02:22:48,000 --> 02:22:53,040 temporarily and just focus on a through 3796 02:22:49,800 --> 02:22:55,560 d if we revert to where we began today's 3797 02:22:53,040 --> 02:22:59,600 story with conditionals saying if if if 3798 02:22:55,560 --> 02:23:01,720 if now our cleverness here of using 3799 02:22:59,600 --> 02:23:03,920 broader strokes and not using in upper 3800 02:23:01,720 --> 02:23:07,280 and lower bound ranges is going to come 3801 02:23:03,920 --> 02:23:09,760 back to be a downside let me go ahead 3802 02:23:07,280 --> 02:23:13,880 and run python of grade. Pi and suppose 3803 02:23:09,760 --> 02:23:18,279 my score is uh 95 I am so darn excited I 3804 02:23:13,880 --> 02:23:21,760 want my a but nope I just got an A a b a 3805 02:23:18,279 --> 02:23:22,920 c and a d so logic that's broken things 3806 02:23:21,760 --> 02:23:25,960 because if you don't make these 3807 02:23:22,920 --> 02:23:27,880 conditions mutually exclusive every one 3808 02:23:25,960 --> 02:23:30,200 of those questions is going to get asked 3809 02:23:27,880 --> 02:23:33,399 and therefore answered and even if your 3810 02:23:30,200 --> 02:23:35,960 grade is above a 90 it's also logically 3811 02:23:33,399 --> 02:23:37,399 above an 80 above a 70 above a 60 and if 3812 02:23:35,960 --> 02:23:40,520 i' kept it in there I would have failed 3813 02:23:37,399 --> 02:23:43,080 as well with an F really good question 3814 02:23:40,520 --> 02:23:45,240 other questions here on this form of 3815 02:23:43,080 --> 02:23:47,080 logic like it would there be any I guess 3816 02:23:45,240 --> 02:23:48,840 better way to kind of clean up even just 3817 02:23:47,080 --> 02:23:50,080 this simple statement like we had before 3818 02:23:48,840 --> 02:23:53,640 the previous one that you had with the 3819 02:23:50,080 --> 02:23:56,520 El oh I I I like your enthusiasm for 3820 02:23:53,640 --> 02:23:58,840 simplifying things further I'm going to 3821 02:23:56,520 --> 02:24:01,680 go out on a limb here and say this is 3822 02:23:58,840 --> 02:24:04,800 about as good as it gets at least using 3823 02:24:01,680 --> 02:24:07,399 only conditional statements I can if my 3824 02:24:04,800 --> 02:24:08,960 mind wanders think of a slightly more 3825 02:24:07,399 --> 02:24:10,720 clever way to do this maybe with 3826 02:24:08,960 --> 02:24:12,040 something called a loop or another 3827 02:24:10,720 --> 02:24:13,920 programming construct we don't have that 3828 02:24:12,040 --> 02:24:15,439 yet in our vocabulary but yes there's 3829 02:24:13,920 --> 02:24:17,000 absolutely other ways to do it but I 3830 02:24:15,439 --> 02:24:19,040 think not yet if we want to restrict 3831 02:24:17,000 --> 02:24:22,040 ourselves to just words like if and or 3832 02:24:19,040 --> 02:24:24,240 and else uh and L if and and and the 3833 02:24:22,040 --> 02:24:26,520 like well let me propose that we pivot 3834 02:24:24,240 --> 02:24:28,279 now to use another approach here that 3835 02:24:26,520 --> 02:24:30,279 uses one other symbol that up until now 3836 02:24:28,279 --> 02:24:32,840 we've not really had occasion to use let 3837 02:24:30,279 --> 02:24:35,120 me propose that we Implement a program 3838 02:24:32,840 --> 02:24:36,720 uh that we'll call parity in mathematics 3839 02:24:35,120 --> 02:24:38,800 parity can refer to whether a number is 3840 02:24:36,720 --> 02:24:40,680 even or odd and that's kind of an 3841 02:24:38,800 --> 02:24:42,600 interesting question and turns out it 3842 02:24:40,680 --> 02:24:44,279 can be useful in other applications too 3843 02:24:42,600 --> 02:24:46,200 to I just ask the question is a given 3844 02:24:44,279 --> 02:24:48,560 number even or odd maybe that the user 3845 02:24:46,200 --> 02:24:52,240 typed in and let me go ahead and write a 3846 02:24:48,560 --> 02:24:55,040 new program called parity Pi via code 3847 02:24:52,240 --> 02:24:56,520 parody. Pi in my terminal and let me 3848 02:24:55,040 --> 02:24:59,040 propose that we use this as an 3849 02:24:56,520 --> 02:25:01,800 opportunity to introduce the last of 3850 02:24:59,040 --> 02:25:03,760 those arithmetic symbols at least most 3851 02:25:01,800 --> 02:25:05,720 of which we're familiar with addition 3852 02:25:03,760 --> 02:25:07,600 subtraction multiplication division but 3853 02:25:05,720 --> 02:25:09,160 there's been on this list before this 3854 02:25:07,600 --> 02:25:10,760 last one here a percent sign and it 3855 02:25:09,160 --> 02:25:12,720 doesn't mean percentage in this case 3856 02:25:10,760 --> 02:25:14,800 when used as an operator in programming 3857 02:25:12,720 --> 02:25:17,240 in Python rather it represents the 3858 02:25:14,800 --> 02:25:19,080 so-called modulo operator for modular 3859 02:25:17,240 --> 02:25:20,600 arithmetic or at least in our case we're 3860 02:25:19,080 --> 02:25:23,000 going to use it to calculate the 3861 02:25:20,600 --> 02:25:24,760 remainder when dividing one number by 3862 02:25:23,000 --> 02:25:28,279 another well what do I mean by that well 3863 02:25:24,760 --> 02:25:30,720 if you take a number like 1 divid 3 3 3864 02:25:28,279 --> 02:25:33,600 does not go into one eat cleanly so you 3865 02:25:30,720 --> 02:25:36,479 have a remainder of one two divided 3866 02:25:33,600 --> 02:25:38,760 three has a remainder of two three 3867 02:25:36,479 --> 02:25:41,960 divided by 3 has a remainder of zero 3868 02:25:38,760 --> 02:25:44,800 because it divides cleanly four divided 3869 02:25:41,960 --> 02:25:46,520 3 has a remainder of one because you can 3870 02:25:44,800 --> 02:25:48,120 divide it in once but then that leaves 3871 02:25:46,520 --> 02:25:50,840 one so it has a remainder of one and 3872 02:25:48,120 --> 02:25:52,520 then lastly something like five divided 3873 02:25:50,840 --> 02:25:54,240 by three has a remainder of course of 3874 02:25:52,520 --> 02:25:56,240 two so that's all we mean by remainder 3875 02:25:54,240 --> 02:25:58,560 how much is left over after dividing one 3876 02:25:56,240 --> 02:26:01,279 number by another well if I go back now 3877 02:25:58,560 --> 02:26:03,840 to my code and I consider how I might 3878 02:26:01,279 --> 02:26:06,120 implement the question is this number 3879 02:26:03,840 --> 02:26:08,399 even or odd let's consider how we might 3880 02:26:06,120 --> 02:26:10,200 Implement that since it's perhaps not 3881 02:26:08,399 --> 02:26:11,600 necessarily obvious how we can use this 3882 02:26:10,200 --> 02:26:13,479 additional building block but it turns 3883 02:26:11,600 --> 02:26:15,240 out it's going to be very useful longer 3884 02:26:13,479 --> 02:26:17,399 term well let's first just get a number 3885 02:26:15,240 --> 02:26:18,920 from the user in a variable called X and 3886 02:26:17,399 --> 02:26:21,200 I'm going to set that equal to the 3887 02:26:18,920 --> 02:26:23,600 conversion to int of whatever the user 3888 02:26:21,200 --> 02:26:25,520 inputs after asking them what's X 3889 02:26:23,600 --> 02:26:28,600 question mark and we've done that before 3890 02:26:25,520 --> 02:26:31,760 many times how do I now determine if x 3891 02:26:28,600 --> 02:26:34,240 is even or odd well it turns out if I 3892 02:26:31,760 --> 02:26:37,000 have access to a programmatic operator 3893 02:26:34,240 --> 02:26:38,479 that tells me the remainder I think I 3894 02:26:37,000 --> 02:26:40,520 can do this in fact let me just ask the 3895 02:26:38,479 --> 02:26:41,960 group and this is just from grade school 3896 02:26:40,520 --> 02:26:46,600 math perhaps what does it mean for a 3897 02:26:41,960 --> 02:26:52,240 number to be even to be clear a number 3898 02:26:46,600 --> 02:26:53,560 like 0 2 4 6 8 10 12 12 14 16 those are 3899 02:26:52,240 --> 02:26:55,359 all even numbers but what does that 3900 02:26:53,560 --> 02:26:58,560 really mean Elena if I'm saying that 3901 02:26:55,359 --> 02:27:03,000 right uh even numbers that can divide it 3902 02:26:58,560 --> 02:27:05,680 exactly by two for example 2 4 6 8 and 3903 02:27:03,000 --> 02:27:07,200 10 and perfect and we could go on all 3904 02:27:05,680 --> 02:27:08,640 day long literally since there's an 3905 02:27:07,200 --> 02:27:10,800 infinite number of those even numbers 3906 02:27:08,640 --> 02:27:13,160 but it's nice that you formulated it in 3907 02:27:10,800 --> 02:27:16,120 terms of a question that we can ask very 3908 02:27:13,160 --> 02:27:18,960 clearly is this number cleanly divided 3909 02:27:16,120 --> 02:27:21,520 by two that is can we divide it by two 3910 02:27:18,960 --> 02:27:23,000 with no remainder a remainder of zero 3911 02:27:21,520 --> 02:27:25,080 well that's perfect because if we have 3912 02:27:23,000 --> 02:27:27,000 this operator this percent sign that 3913 02:27:25,080 --> 02:27:29,000 allows us to answer just that what is 3914 02:27:27,000 --> 02:27:31,680 the remainder we can presumably check is 3915 02:27:29,000 --> 02:27:33,960 the remainder is zero or is it one do we 3916 02:27:31,680 --> 02:27:38,120 have nothing left over or do we have one 3917 02:27:33,960 --> 02:27:42,880 left over well let's ask that if x ided 3918 02:27:38,120 --> 02:27:44,840 by 2 has a remainder of zero as Elena 3919 02:27:42,880 --> 02:27:46,439 proposes let's go ahead and print out 3920 02:27:44,840 --> 02:27:48,840 something like quote unquote even and 3921 02:27:46,439 --> 02:27:50,399 just say as much to the user else I 3922 02:27:48,840 --> 02:27:53,279 think we can assume that if a number is 3923 02:27:50,399 --> 02:27:54,640 not even it's going to be odd if it's 3924 02:27:53,279 --> 02:27:56,520 indeed an integer so I'm going to go 3925 02:27:54,640 --> 02:27:58,680 ahead and print out quote unquote odd 3926 02:27:56,520 --> 02:28:00,760 instead and let's go ahead and now run 3927 02:27:58,680 --> 02:28:03,200 python of parody. piy in my prompt 3928 02:28:00,760 --> 02:28:05,520 what's X let's start with two two is in 3929 02:28:03,200 --> 02:28:07,680 fact even let's start with four four is 3930 02:28:05,520 --> 02:28:10,560 in fact even let's get thing let's get 3931 02:28:07,680 --> 02:28:11,920 interesting with three three is now odd 3932 02:28:10,560 --> 02:28:13,640 and I think we could do that all day 3933 02:28:11,920 --> 02:28:16,680 long and hopefully get back indeed 3934 02:28:13,640 --> 02:28:19,120 exactly that answer but what more could 3935 02:28:16,680 --> 02:28:21,000 we do here how could we improve upon 3936 02:28:19,120 --> 02:28:23,840 this well recall that we have the 3937 02:28:21,000 --> 02:28:25,399 ability to invent our own functions and 3938 02:28:23,840 --> 02:28:26,680 let me just propose for the sake of 3939 02:28:25,399 --> 02:28:28,319 discussion that we're going to 3940 02:28:26,680 --> 02:28:29,840 eventually find that it's useful to be 3941 02:28:28,319 --> 02:28:31,200 able to determine if a number is even or 3942 02:28:29,840 --> 02:28:33,680 odd and so we'd like to have that 3943 02:28:31,200 --> 02:28:35,479 functionality built in and I don't think 3944 02:28:33,680 --> 02:28:37,760 python has a function for telling me 3945 02:28:35,479 --> 02:28:41,040 just that but I can invent it using Code 3946 02:28:37,760 --> 02:28:43,760 like just this so let me go into my 3947 02:28:41,040 --> 02:28:47,000 earlier version here and let me propose 3948 02:28:43,760 --> 02:28:48,800 that we do this let me go ahead and 3949 02:28:47,000 --> 02:28:50,760 write a main function I'm going to get 3950 02:28:48,800 --> 02:28:52,479 back into that habit of defining a main 3951 02:28:50,760 --> 02:28:54,240 function to represent the main part of 3952 02:28:52,479 --> 02:28:55,920 my program and I'm going to do what I 3953 02:28:54,240 --> 02:28:58,600 did before I'm going to get an integer 3954 02:28:55,920 --> 02:29:01,160 from the user's input asking them what's 3955 02:28:58,600 --> 02:29:02,960 X question mark and then I'm going to 3956 02:29:01,160 --> 02:29:04,720 ask this question for the moment I'm 3957 02:29:02,960 --> 02:29:06,240 going to naively assume that the 3958 02:29:04,720 --> 02:29:08,520 function already exists but that's a 3959 02:29:06,240 --> 02:29:10,720 useful problem solving technique even if 3960 02:29:08,520 --> 02:29:12,600 I have no idea yet where I'm going with 3961 02:29:10,720 --> 02:29:14,640 this how I'm going to invent a function 3962 02:29:12,600 --> 02:29:15,840 that determines if a number is even I'm 3963 02:29:14,640 --> 02:29:18,040 just going to assume that there's a 3964 02:29:15,840 --> 02:29:21,920 function called is even and I'm going to 3965 02:29:18,040 --> 02:29:25,720 call it blindly like this if is even 3966 02:29:21,920 --> 02:29:28,439 passing in X then go ahead and print 3967 02:29:25,720 --> 02:29:32,000 quote unquote even so if this magical 3968 02:29:28,439 --> 02:29:34,680 function called is even returns true as 3969 02:29:32,000 --> 02:29:37,160 its return value I'm going to print out 3970 02:29:34,680 --> 02:29:39,640 that it's even else otherwise I'm going 3971 02:29:37,160 --> 02:29:41,560 to assume that it's of course odd now 3972 02:29:39,640 --> 02:29:44,760 the one problem with this program even 3973 02:29:41,560 --> 02:29:46,520 if I call Main over here is that is even 3974 02:29:44,760 --> 02:29:48,800 does not exist and this program would 3975 02:29:46,520 --> 02:29:50,760 break if I ran it right now but that's 3976 02:29:48,800 --> 02:29:52,960 okay I have the ability call to invent 3977 02:29:50,760 --> 02:29:56,160 my own function so let me Define with 3978 02:29:52,960 --> 02:29:58,560 def a function called is even I want 3979 02:29:56,160 --> 02:30:00,439 this function to take an argument and 3980 02:29:58,560 --> 02:30:02,680 I'm going to call it n just a number 3981 02:30:00,439 --> 02:30:04,319 generically I could call it X but again 3982 02:30:02,680 --> 02:30:05,840 I don't want to confuse myself as to 3983 02:30:04,319 --> 02:30:07,720 which X is which so I'm going to give it 3984 02:30:05,840 --> 02:30:09,399 a different name and that's fine I'm 3985 02:30:07,720 --> 02:30:12,240 just going to call it more generically n 3986 02:30:09,399 --> 02:30:16,080 for number and then I'm going to do this 3987 02:30:12,240 --> 02:30:19,439 I'm going to say if n percent 2 equals 3988 02:30:16,080 --> 02:30:22,600 equals z just like before then and 3989 02:30:19,439 --> 02:30:25,399 here's the magic you the programmer can 3990 02:30:22,600 --> 02:30:28,319 actually return what are called Boolean 3991 02:30:25,399 --> 02:30:32,040 values we've seen in Python that python 3992 02:30:28,319 --> 02:30:34,399 has stirs or strings ins or integers 3993 02:30:32,040 --> 02:30:36,479 Floats or floating Point values all of 3994 02:30:34,399 --> 02:30:38,840 which are different types of data in 3995 02:30:36,479 --> 02:30:41,920 python python also has a fourth data 3996 02:30:38,840 --> 02:30:43,399 type called bull for a Boolean value and 3997 02:30:41,920 --> 02:30:45,399 even though this is just adding to our 3998 02:30:43,399 --> 02:30:49,200 list the nice thing about bulls is that 3999 02:30:45,399 --> 02:30:51,359 they can only be true or false an INT 4000 02:30:49,200 --> 02:30:54,720 can be any number of infinite possible 4001 02:30:51,359 --> 02:30:57,479 values a bull can only be true or false 4002 02:30:54,720 --> 02:30:59,920 and it must be capital T and capital F 4003 02:30:57,479 --> 02:31:02,800 if you're writing itself so if I go back 4004 02:30:59,920 --> 02:31:06,479 now to my code and I consider exactly 4005 02:31:02,800 --> 02:31:10,680 what I want to return here well if x if 4006 02:31:06,479 --> 02:31:13,279 n% 2 equals equal Z that is if n / two 4007 02:31:10,680 --> 02:31:15,439 has a remainder of zero well I think 4008 02:31:13,279 --> 02:31:19,319 it's even to Elena your definition so 4009 02:31:15,439 --> 02:31:21,200 let's return true capital T else if it 4010 02:31:19,319 --> 02:31:22,560 doesn't have a remainder of zero I'm 4011 02:31:21,200 --> 02:31:24,720 pretty sure mathematically it's got to 4012 02:31:22,560 --> 02:31:26,720 have a remainder of one but it doesn't 4013 02:31:24,720 --> 02:31:30,000 matter I know it's not even so I'm going 4014 02:31:26,720 --> 02:31:32,880 to return false and we returned false 4015 02:31:30,000 --> 02:31:36,080 instead capital F and now that we've 4016 02:31:32,880 --> 02:31:38,200 defined both Main and is even and I'm 4017 02:31:36,080 --> 02:31:40,720 calling main at the bottom I think I've 4018 02:31:38,200 --> 02:31:43,160 got this right python of parody. Pi 4019 02:31:40,720 --> 02:31:45,920 enter what's X let's try something 4020 02:31:43,160 --> 02:31:48,760 simple like two and it's even let's do 4021 02:31:45,920 --> 02:31:51,720 it again what's X how about four even 4022 02:31:48,760 --> 02:31:54,000 once more what's X X how about three and 4023 02:31:51,720 --> 02:31:55,640 it's odd now what have I done here I've 4024 02:31:54,000 --> 02:31:58,720 just made the point that if I want to 4025 02:31:55,640 --> 02:32:00,240 create my own function called is even 4026 02:31:58,720 --> 02:32:01,760 that answers this question for me that I 4027 02:32:00,240 --> 02:32:04,640 can now use in this program and heck 4028 02:32:01,760 --> 02:32:07,000 maybe future programs that I write I now 4029 02:32:04,640 --> 02:32:09,040 have a function that no one gave me I 4030 02:32:07,000 --> 02:32:11,279 gave myself that I can use and reuse and 4031 02:32:09,040 --> 02:32:13,240 I can even perhaps share it with others 4032 02:32:11,279 --> 02:32:15,640 I'm using that function now on line 4033 02:32:13,240 --> 02:32:18,240 three just to make a decision I'm using 4034 02:32:15,640 --> 02:32:20,279 a conditional up there and my Boolean 4035 02:32:18,240 --> 02:32:22,439 expression something that's true or 4036 02:32:20,279 --> 02:32:25,479 false is going to be not something 4037 02:32:22,439 --> 02:32:27,880 explicit like X less than y or y greater 4038 02:32:25,479 --> 02:32:30,279 than x or the like it's going to be a 4039 02:32:27,880 --> 02:32:32,359 function call I'm using a function as my 4040 02:32:30,279 --> 02:32:34,200 Boolean expression but that's okay 4041 02:32:32,359 --> 02:32:38,319 because I know because I wrote it that 4042 02:32:34,200 --> 02:32:40,640 that function is even returns true or it 4043 02:32:38,319 --> 02:32:42,920 returns false and that's all I need in a 4044 02:32:40,640 --> 02:32:46,319 conditional to make a decision to print 4045 02:32:42,920 --> 02:32:48,359 even or print odd so let me pause here 4046 02:32:46,319 --> 02:32:50,399 to see if there's any questions now on 4047 02:32:48,359 --> 02:32:54,080 how I've implemented is 4048 02:32:50,399 --> 02:32:55,160 even using this bull hello hi David 4049 02:32:54,080 --> 02:32:57,399 first of all thank you for this 4050 02:32:55,160 --> 02:33:00,560 wonderful class uh did before yesterday 4051 02:32:57,399 --> 02:33:03,840 and today uh I have just one query like 4052 02:33:00,560 --> 02:33:06,680 bases on my background of java uh there 4053 02:33:03,840 --> 02:33:08,720 when we used to pass the arguments we 4054 02:33:06,680 --> 02:33:11,080 can also pass the address of the 4055 02:33:08,720 --> 02:33:14,120 variables so is there any sort of this 4056 02:33:11,080 --> 02:33:15,840 concept in Python uh short answer no 4057 02:33:14,120 --> 02:33:18,240 those who are unfamiliar with Java or 4058 02:33:15,840 --> 02:33:20,200 other languages or C or C++ there's 4059 02:33:18,240 --> 02:33:21,920 generally ways to pass values in 4060 02:33:20,200 --> 02:33:24,640 different mechanisms that allow you or 4061 02:33:21,920 --> 02:33:25,800 disallow you to change them in Python no 4062 02:33:24,640 --> 02:33:27,760 everything we're going to see is 4063 02:33:25,800 --> 02:33:30,160 actually in fact an object but more on 4064 02:33:27,760 --> 02:33:33,160 that down the line how about time for 4065 02:33:30,160 --> 02:33:36,399 one more question here on these bulls 4066 02:33:33,160 --> 02:33:39,200 and these is evens so I actually had a 4067 02:33:36,399 --> 02:33:41,160 question about um defining a function 4068 02:33:39,200 --> 02:33:43,800 okay if that's okay sure so if you 4069 02:33:41,160 --> 02:33:45,399 define one are you like within your code 4070 02:33:43,800 --> 02:33:48,479 like you made it up are you allowed to 4071 02:33:45,399 --> 02:33:50,439 use the dot operator like we did name. 4072 02:33:48,479 --> 02:33:52,520 strip and use it like that 4073 02:33:50,439 --> 02:33:54,720 good question if you've created your own 4074 02:33:52,520 --> 02:33:58,080 function can you use other functions 4075 02:33:54,720 --> 02:34:01,040 like strip ortitle or Capital eyes that 4076 02:33:58,080 --> 02:34:03,279 we've seen in the past um you can use 4077 02:34:01,040 --> 02:34:06,200 those on strings those functions come 4078 02:34:03,279 --> 02:34:08,359 with strings you can't necessarily use 4079 02:34:06,200 --> 02:34:10,600 them on your own functions unless your 4080 02:34:08,359 --> 02:34:13,080 function returns a string for the 4081 02:34:10,600 --> 02:34:15,080 examples you gave I'm returning a bull 4082 02:34:13,080 --> 02:34:16,359 bulls have no notion of white space to 4083 02:34:15,080 --> 02:34:18,279 the left or the right you can't call 4084 02:34:16,359 --> 02:34:19,600 strip you can't call capitalize but if 4085 02:34:18,279 --> 02:34:21,720 you were writing a different function 4086 02:34:19,600 --> 02:34:23,760 that that returns a string absolutely 4087 02:34:21,720 --> 02:34:25,359 you could use those functions as well 4088 02:34:23,760 --> 02:34:27,000 well let me turn our attention if I may 4089 02:34:25,359 --> 02:34:30,040 back to this example here and consider 4090 02:34:27,000 --> 02:34:32,120 as we now frequently do can we improve 4091 02:34:30,040 --> 02:34:34,920 on the design of this code can I make 4092 02:34:32,120 --> 02:34:36,479 this particular program better and I can 4093 02:34:34,920 --> 02:34:38,200 there's a couple of ways here and I'll 4094 02:34:36,479 --> 02:34:40,240 show you something that's now generally 4095 02:34:38,200 --> 02:34:42,120 known as something pythonic there's 4096 02:34:40,240 --> 02:34:44,279 actually this term of Art in the python 4097 02:34:42,120 --> 02:34:46,720 world where something is pythonic if 4098 02:34:44,279 --> 02:34:48,439 it's just the way you do things in 4099 02:34:46,720 --> 02:34:49,720 Python which is to say we've seen 4100 02:34:48,439 --> 02:34:51,840 already there's so many different ways 4101 02:34:49,720 --> 02:34:53,840 to solve certain problems and in the 4102 02:34:51,840 --> 02:34:56,319 python community of programmers there 4103 02:34:53,840 --> 02:34:58,600 tend to be some ways that are smiled 4104 02:34:56,319 --> 02:35:00,520 upon more than others and they tend to 4105 02:34:58,600 --> 02:35:02,720 relate to features that maybe only 4106 02:35:00,520 --> 02:35:04,080 python has but not other languages and 4107 02:35:02,720 --> 02:35:06,359 here's some syntax that you might not 4108 02:35:04,080 --> 02:35:08,160 have seen in languages like Java or C or 4109 02:35:06,359 --> 02:35:09,960 C++ if you've programmed before and if 4110 02:35:08,160 --> 02:35:12,840 you've never programmed before this too 4111 02:35:09,960 --> 02:35:16,479 is going to be new instead of asking a 4112 02:35:12,840 --> 02:35:18,720 question like this if else using four 4113 02:35:16,479 --> 02:35:21,160 lines in Python you can actually 4114 02:35:18,720 --> 02:35:23,960 collapse this into just just one more 4115 02:35:21,160 --> 02:35:28,240 elegant line if you will instead of 4116 02:35:23,960 --> 02:35:31,279 asking if n / 2 has a remainder of zero 4117 02:35:28,240 --> 02:35:34,000 return true else return false let me 4118 02:35:31,279 --> 02:35:39,680 delete all of that and just say this 4119 02:35:34,000 --> 02:35:43,840 return true if n / two has a remainder 4120 02:35:39,680 --> 02:35:45,399 of zero else return false now those of 4121 02:35:43,840 --> 02:35:46,840 you who do have prior programming 4122 02:35:45,399 --> 02:35:48,960 experience might actually think this is 4123 02:35:46,840 --> 02:35:51,200 kind of cool you can condense from four 4124 02:35:48,960 --> 02:35:53,120 lines into one on line that very same 4125 02:35:51,200 --> 02:35:55,120 thought and one of the reasons why 4126 02:35:53,120 --> 02:35:57,359 python is popular is that it does tend 4127 02:35:55,120 --> 02:35:59,080 to read rather like English it's not 4128 02:35:57,359 --> 02:36:01,880 quite as user friendly as most English 4129 02:35:59,080 --> 02:36:04,439 or most human languages but notice now 4130 02:36:01,880 --> 02:36:08,760 the line does rather say what you mean 4131 02:36:04,439 --> 02:36:11,439 return true if n / two has a remainder 4132 02:36:08,760 --> 02:36:13,200 of zero else false I mean that's pretty 4133 02:36:11,439 --> 02:36:15,920 darn close to something you might say 4134 02:36:13,200 --> 02:36:18,120 logically in English be it about even an 4135 02:36:15,920 --> 02:36:19,640 odd or really anything else so that 4136 02:36:18,120 --> 02:36:21,840 program is going to work exactly the 4137 02:36:19,640 --> 02:36:24,319 same python of parity. Pi let me type in 4138 02:36:21,840 --> 02:36:26,760 two it's still even let me type in three 4139 02:36:24,319 --> 02:36:28,960 it's still odd but I can refine this 4140 02:36:26,760 --> 02:36:30,479 even further and again consistent with 4141 02:36:28,960 --> 02:36:33,240 this idea of not just writing correct 4142 02:36:30,479 --> 02:36:36,200 code but writing better and better code 4143 02:36:33,240 --> 02:36:39,120 but still keeping it readable I can do 4144 02:36:36,200 --> 02:36:41,680 one even better than this notice this 4145 02:36:39,120 --> 02:36:44,479 value here is my Boolean expression and 4146 02:36:41,680 --> 02:36:48,840 it is going to evaluate to true or false 4147 02:36:44,479 --> 02:36:51,040 is n / two having a remainder of zero or 4148 02:36:48,840 --> 02:36:54,000 not like that is by definition a Boolean 4149 02:36:51,040 --> 02:36:56,640 expression it has a yes no answer a true 4150 02:36:54,000 --> 02:37:00,319 false answer well if your Boolean 4151 02:36:56,640 --> 02:37:03,279 expression itself has a true or false 4152 02:37:00,319 --> 02:37:07,800 answer why are you asking a question in 4153 02:37:03,279 --> 02:37:11,399 the first place why ask if why say else 4154 02:37:07,800 --> 02:37:14,000 just return the value of your own 4155 02:37:11,399 --> 02:37:16,439 Boolean expression and perhaps the 4156 02:37:14,000 --> 02:37:18,600 tightest version the most succinct and 4157 02:37:16,439 --> 02:37:20,560 still readable version of this code 4158 02:37:18,600 --> 02:37:24,680 would be to delete this whole line 4159 02:37:20,560 --> 02:37:29,120 pythonic though it is and just return n 4160 02:37:24,680 --> 02:37:31,600 modulo 2 equals equals 0 if it helps let 4161 02:37:29,120 --> 02:37:32,960 me add parentheses temporarily because 4162 02:37:31,600 --> 02:37:36,720 what's going to happen in parentheses 4163 02:37:32,960 --> 02:37:40,040 will happen first n / by two either does 4164 02:37:36,720 --> 02:37:42,520 or does not have a remainder of zero if 4165 02:37:40,040 --> 02:37:45,359 it does the answer is true if it doesn't 4166 02:37:42,520 --> 02:37:47,520 the answer is false so just return the 4167 02:37:45,359 --> 02:37:50,160 question if you will you don't need to 4168 02:37:47,520 --> 02:37:52,840 wrap it explicitly with an if and an 4169 02:37:50,160 --> 02:37:54,279 else and in fact because of order of 4170 02:37:52,840 --> 02:37:57,040 operations you don't even need the 4171 02:37:54,279 --> 02:38:00,520 parentheses so now this is perhaps the 4172 02:37:57,040 --> 02:38:02,800 most elegant way to implement this same 4173 02:38:00,520 --> 02:38:04,800 idea now which is better this is pretty 4174 02:38:02,800 --> 02:38:06,800 darn good and it's hard to take fault 4175 02:38:04,800 --> 02:38:09,319 with this because it's so very succinct 4176 02:38:06,800 --> 02:38:12,200 but it's perfectly okay and just as 4177 02:38:09,319 --> 02:38:14,240 correct to have an if and then an else 4178 02:38:12,200 --> 02:38:16,000 even though it might be four Total Lines 4179 02:38:14,240 --> 02:38:18,080 if that helps you think about your code 4180 02:38:16,000 --> 02:38:20,600 more clearly and it helps other people 4181 02:38:18,080 --> 02:38:22,399 reason about it as well so it turns out 4182 02:38:20,600 --> 02:38:24,120 there's another syntax that you can use 4183 02:38:22,399 --> 02:38:25,680 to implement the same idea of a 4184 02:38:24,120 --> 02:38:28,040 conditional whereby you do something 4185 02:38:25,680 --> 02:38:30,319 optionally based on the answer to some 4186 02:38:28,040 --> 02:38:32,160 Boolean expression and the keyword that 4187 02:38:30,319 --> 02:38:34,920 you can now use in recent versions of 4188 02:38:32,160 --> 02:38:36,359 python is called this match match is a 4189 02:38:34,920 --> 02:38:37,840 mechanism that if you've programmed 4190 02:38:36,359 --> 02:38:40,279 before is similar in spirit to something 4191 02:38:37,840 --> 02:38:42,359 called switch in other languages for 4192 02:38:40,279 --> 02:38:44,200 instance let me go ahead here and close 4193 02:38:42,359 --> 02:38:47,680 out parody. py and let me go ahead and 4194 02:38:44,200 --> 02:38:49,240 create a new file called house. py and 4195 02:38:47,680 --> 02:38:51,439 in house dopy I think what we're going 4196 02:38:49,240 --> 02:38:53,200 to do is try to implement a program that 4197 02:38:51,439 --> 02:38:54,880 prompts the user for their name and then 4198 02:38:53,200 --> 02:38:56,920 just outputs what house they're known to 4199 02:38:54,880 --> 02:38:58,600 be in in the World of Harry Potter so 4200 02:38:56,920 --> 02:39:00,200 for instance let me go ahead and do this 4201 02:38:58,600 --> 02:39:02,520 let me give myself a variable called 4202 02:39:00,200 --> 02:39:03,920 name set it equal to the return value of 4203 02:39:02,520 --> 02:39:05,960 the input function and I'll say 4204 02:39:03,920 --> 02:39:07,800 something like what's your name question 4205 02:39:05,960 --> 02:39:11,120 mark and then after that I'm just going 4206 02:39:07,800 --> 02:39:13,120 to use a traditional if L if else 4207 02:39:11,120 --> 02:39:15,359 construct to decide what house this 4208 02:39:13,120 --> 02:39:18,000 person is in so let me say if name 4209 02:39:15,359 --> 02:39:19,760 equals equals say Harry as in Harry 4210 02:39:18,000 --> 02:39:22,160 Potter well let's go ahead and print out 4211 02:39:19,760 --> 02:39:25,399 Harry's house which is Gryffindor in the 4212 02:39:22,160 --> 02:39:28,240 World of Harry Potter L if the name is 4213 02:39:25,399 --> 02:39:31,000 instead Hermione then go ahead and print 4214 02:39:28,240 --> 02:39:33,479 out also quote unquote Gryffindor as 4215 02:39:31,000 --> 02:39:35,720 she's in the same house too L if name 4216 02:39:33,479 --> 02:39:38,359 equals equals Ron let's go ahead and 4217 02:39:35,720 --> 02:39:40,240 similarly print out Gryffindor quote 4218 02:39:38,359 --> 02:39:42,520 unquote and let's make this a little 4219 02:39:40,240 --> 02:39:45,200 more interesting now L if name equals 4220 02:39:42,520 --> 02:39:47,080 quote unquote how about Draco Draco 4221 02:39:45,200 --> 02:39:49,920 Malfoy in the books Let's go ahead and 4222 02:39:47,080 --> 02:39:51,760 print out quote unquote Slytherin and 4223 02:39:49,920 --> 02:39:54,240 just in case someone else's name gets 4224 02:39:51,760 --> 02:39:56,000 inputed for now let's just suppose that 4225 02:39:54,240 --> 02:39:58,960 we don't recognize them and say by 4226 02:39:56,000 --> 02:40:00,359 default else print out quote unquote who 4227 02:39:58,960 --> 02:40:01,840 question mark just to convey that we 4228 02:40:00,359 --> 02:40:04,120 don't actually have a hard-coded 4229 02:40:01,840 --> 02:40:06,800 response to that particular name let me 4230 02:40:04,120 --> 02:40:09,160 go ahead now and run this as python of 4231 02:40:06,800 --> 02:40:10,960 house. py enter and I'll go ahead and 4232 02:40:09,160 --> 02:40:12,160 type in something like Harry and voila 4233 02:40:10,960 --> 02:40:14,479 we see that Harry is indeed in 4234 02:40:12,160 --> 02:40:16,720 Gryffindor let's run it one more time 4235 02:40:14,479 --> 02:40:19,080 python of Housey let's type in Draco 4236 02:40:16,720 --> 02:40:21,200 this time Slytherin and now let's type 4237 02:40:19,080 --> 02:40:23,600 in an unrecognized name let's go ahead 4238 02:40:21,200 --> 02:40:26,319 and rerun python of house. py and let's 4239 02:40:23,600 --> 02:40:28,120 go ahead and type in Padma enter and who 4240 02:40:26,319 --> 02:40:30,479 because we haven't actually hardcoded 4241 02:40:28,120 --> 02:40:32,760 with an L if condition in this case uh 4242 02:40:30,479 --> 02:40:34,200 what house Padma is meant to be in all 4243 02:40:32,760 --> 02:40:36,160 right well it turns out there's other 4244 02:40:34,200 --> 02:40:37,800 ways to implement this indeed there's 4245 02:40:36,160 --> 02:40:40,439 some redundancy here in that we're 4246 02:40:37,800 --> 02:40:42,359 checking if Harry or Hermione or Ron are 4247 02:40:40,439 --> 02:40:44,040 all in Gryffindor I feel like we can at 4248 02:40:42,359 --> 02:40:46,000 least tighten this code up a little bit 4249 02:40:44,040 --> 02:40:47,920 using techniques we've seen already so 4250 02:40:46,000 --> 02:40:49,920 let me go ahead and do this let me go up 4251 02:40:47,920 --> 02:40:52,160 here and instead do something like this 4252 02:40:49,920 --> 02:40:54,560 let's get rid of these two blocks of L 4253 02:40:52,160 --> 02:40:56,560 ifs leaving just Harry's for a moment 4254 02:40:54,560 --> 02:40:59,319 and let's use that or keyword again and 4255 02:40:56,560 --> 02:41:02,240 say or name equals equals quote unquote 4256 02:40:59,319 --> 02:41:05,040 Hermione or name equals quote unquote 4257 02:41:02,240 --> 02:41:07,359 Ron thereby consolidating all three 4258 02:41:05,040 --> 02:41:09,160 cases if you will into just one if 4259 02:41:07,359 --> 02:41:11,200 statement then we still have a separate 4260 02:41:09,160 --> 02:41:13,279 L if for Draco because he's not in fact 4261 02:41:11,200 --> 02:41:15,439 in Gryffindor and then the final El to 4262 02:41:13,279 --> 02:41:17,080 catch anyone else all right let me go 4263 02:41:15,439 --> 02:41:19,720 ahead now and run this version of the 4264 02:41:17,080 --> 02:41:22,080 program python of house.i I'll type in 4265 02:41:19,720 --> 02:41:24,080 hermion this time she too is still in 4266 02:41:22,080 --> 02:41:26,560 Gryffindor let me try it with Ron and 4267 02:41:24,080 --> 02:41:28,040 that too still seems to be correct well 4268 02:41:26,560 --> 02:41:29,439 it turns out there's another approach 4269 02:41:28,040 --> 02:41:31,960 alog together that can perhaps make your 4270 02:41:29,439 --> 02:41:34,399 code a little less verbose you could 4271 02:41:31,960 --> 02:41:35,680 imagine how complicated this code might 4272 02:41:34,399 --> 02:41:37,760 get if we had not just Harry and 4273 02:41:35,680 --> 02:41:39,600 Hermione and Ron but a whole bunch of 4274 02:41:37,760 --> 02:41:41,200 other names as well for Gryffindor for 4275 02:41:39,600 --> 02:41:43,040 Slytherin and for all of the other 4276 02:41:41,200 --> 02:41:45,160 Hogwart toes so you can imagine that 4277 02:41:43,040 --> 02:41:47,000 code is getting pretty unwieldy pretty 4278 02:41:45,160 --> 02:41:48,479 fast well it turns out another technique 4279 02:41:47,000 --> 02:41:50,240 you can use is indeed this keyword 4280 02:41:48,479 --> 02:41:51,960 called match which is very similar in 4281 02:41:50,240 --> 02:41:53,880 spirit but the syntax is different and 4282 02:41:51,960 --> 02:41:56,040 allows you to express the same ideas a 4283 02:41:53,880 --> 02:41:58,640 little more compactly so let me go back 4284 02:41:56,040 --> 02:42:00,800 to house dopy and let me propose that I 4285 02:41:58,640 --> 02:42:03,200 get rid of my current if L if else 4286 02:42:00,800 --> 02:42:05,720 approach and instead do this literally 4287 02:42:03,200 --> 02:42:07,640 use the keyword match and type the name 4288 02:42:05,720 --> 02:42:09,800 of the variable or value that we want to 4289 02:42:07,640 --> 02:42:11,800 match on and then I'm going to go ahead 4290 02:42:09,800 --> 02:42:14,000 and include a colon and then underneath 4291 02:42:11,800 --> 02:42:16,279 that I'm going to include literally a 4292 02:42:14,000 --> 02:42:18,000 keyword called case and the first case I 4293 02:42:16,279 --> 02:42:19,680 want to consider is going to be Harry 4294 02:42:18,000 --> 02:42:21,560 and I'm going to put Harry in quotes 4295 02:42:19,680 --> 02:42:23,160 because it's a string or a stir and I'm 4296 02:42:21,560 --> 02:42:25,439 going to have another colon at the end 4297 02:42:23,160 --> 02:42:26,880 of this line and indented under that one 4298 02:42:25,439 --> 02:42:28,520 I'm going to go ahead and for now print 4299 02:42:26,880 --> 02:42:30,560 out Gryffindor which of course is 4300 02:42:28,520 --> 02:42:32,439 Harry's house otherwise I'm going to 4301 02:42:30,560 --> 02:42:34,720 have another case for quote unquote 4302 02:42:32,439 --> 02:42:37,399 Hermione and similarly I'm going to have 4303 02:42:34,720 --> 02:42:39,800 under that indented print quote unquote 4304 02:42:37,399 --> 02:42:42,399 Gryffindor close quote now I'm going to 4305 02:42:39,800 --> 02:42:44,760 have another case for Ron also in quotes 4306 02:42:42,399 --> 02:42:47,000 with a colon now print quote unquote 4307 02:42:44,760 --> 02:42:49,399 Gryffindor and now I'm going to have a 4308 02:42:47,000 --> 02:42:50,640 other case for let's say Draco this one 4309 02:42:49,399 --> 02:42:53,920 gets a little more interesting because 4310 02:42:50,640 --> 02:42:55,279 Draco of course now is in Slytherin and 4311 02:42:53,920 --> 02:42:57,319 then I'm going to go ahead and leave it 4312 02:42:55,279 --> 02:42:58,960 as that for now so let me go ahead and 4313 02:42:57,319 --> 02:43:01,560 save this file and go back down to my 4314 02:42:58,960 --> 02:43:03,520 terminal window running python of house. 4315 02:43:01,560 --> 02:43:05,240 py enter and let's go ahead and try 4316 02:43:03,520 --> 02:43:06,960 Harry and he seems still to be in 4317 02:43:05,240 --> 02:43:09,600 Gryffindor let's run it again for 4318 02:43:06,960 --> 02:43:12,439 Hermione enter Gryffindor let's skip 4319 02:43:09,600 --> 02:43:14,120 ahead to Draco and type in draco's name 4320 02:43:12,439 --> 02:43:16,359 he's indeed in Slytherin now let's try 4321 02:43:14,120 --> 02:43:19,240 another name that we haven't uh handled 4322 02:43:16,359 --> 02:43:20,960 a case for like Padma again enter and 4323 02:43:19,240 --> 02:43:22,479 we're just ignored there's no output 4324 02:43:20,960 --> 02:43:24,560 whatsoever because there wasn't a case 4325 02:43:22,479 --> 02:43:27,439 for Padma now we could of course go back 4326 02:43:24,560 --> 02:43:29,560 in and explicitly add one for Padma but 4327 02:43:27,439 --> 02:43:31,279 what if we similarly to the else 4328 02:43:29,560 --> 02:43:33,040 construct just want kind of a catchall 4329 02:43:31,279 --> 02:43:35,080 that handles anyone whose name is not 4330 02:43:33,040 --> 02:43:37,200 explicitly specified Well turns out the 4331 02:43:35,080 --> 02:43:39,520 Syntax for that using this new match 4332 02:43:37,200 --> 02:43:42,080 statement is to still have another case 4333 02:43:39,520 --> 02:43:43,640 but then to use this single underscore 4334 02:43:42,080 --> 02:43:45,600 character which is used in other context 4335 02:43:43,640 --> 02:43:48,200 in Python but for here it's meant to say 4336 02:43:45,600 --> 02:43:50,319 whatever case has not yet been handled 4337 02:43:48,200 --> 02:43:52,920 go ahead and print out as we did before 4338 02:43:50,319 --> 02:43:55,000 for instance quote unquote who with a 4339 02:43:52,920 --> 02:43:57,960 question mark at the end now let's go 4340 02:43:55,000 --> 02:44:00,000 ahead and rerun this python of house.i 4341 02:43:57,960 --> 02:44:01,319 I'll type padma's name again and this 4342 02:44:00,000 --> 02:44:03,960 time I think we're at least going to get 4343 02:44:01,319 --> 02:44:05,399 an explicit response indicating who 4344 02:44:03,960 --> 02:44:07,880 whereas previously we did not have the 4345 02:44:05,399 --> 02:44:09,880 equivalent of that now I think we've 4346 02:44:07,880 --> 02:44:11,680 regressed a little bit we went from 4347 02:44:09,880 --> 02:44:13,319 tightening things up by putting Harry 4348 02:44:11,680 --> 02:44:15,800 and Hermione and Ron all in the same 4349 02:44:13,319 --> 02:44:17,840 line and the same if statement but here 4350 02:44:15,800 --> 02:44:19,399 we have now three case statements again 4351 02:44:17,840 --> 02:44:21,720 for all three of those well we can 4352 02:44:19,399 --> 02:44:23,160 tighten these this code up as well but 4353 02:44:21,720 --> 02:44:24,520 the syntax is going to be a little bit 4354 02:44:23,160 --> 02:44:26,600 different I'm going to go ahead and 4355 02:44:24,520 --> 02:44:29,120 delete these two middle cases for 4356 02:44:26,600 --> 02:44:31,120 hermion and Ron and then up here next to 4357 02:44:29,120 --> 02:44:32,880 Harry's name before the colon I'm going 4358 02:44:31,120 --> 02:44:35,720 to go ahead and use a single vertical 4359 02:44:32,880 --> 02:44:38,160 bar and then a quote unquote hermy then 4360 02:44:35,720 --> 02:44:40,160 another single bar and do quote unquote 4361 02:44:38,160 --> 02:44:42,120 Ron and this is how using this 4362 02:44:40,160 --> 02:44:45,000 relatively new match statement you can 4363 02:44:42,120 --> 02:44:47,800 say the equivalent of Harry or Hermione 4364 02:44:45,000 --> 02:44:50,120 or Ron but more concisely than you could 4365 02:44:47,800 --> 02:44:52,319 using an if statement alone as we 4366 02:44:50,120 --> 02:44:55,000 implemented it previously so now one 4367 02:44:52,319 --> 02:44:57,080 final run of the program with python of 4368 02:44:55,000 --> 02:44:59,080 house.i let's make sure that Harry is 4369 02:44:57,080 --> 02:45:00,880 still in Gryffindor let's make sure that 4370 02:44:59,080 --> 02:45:02,160 hermion is still in Gryffindor let's 4371 02:45:00,880 --> 02:45:04,120 make sure that Ron is still in 4372 02:45:02,160 --> 02:45:06,800 Gryffindor and indeed all three of them 4373 02:45:04,120 --> 02:45:07,960 are now as always with python and 4374 02:45:06,800 --> 02:45:09,479 programming more generally there's going 4375 02:45:07,960 --> 02:45:11,080 to be different ways you can solve these 4376 02:45:09,479 --> 02:45:13,359 problems this is just another tool in 4377 02:45:11,080 --> 02:45:15,080 your toolkit arguably it has tighten 4378 02:45:13,359 --> 02:45:16,720 things up arguably it's perhaps a little 4379 02:45:15,080 --> 02:45:19,000 more readable because there's a little 4380 02:45:16,720 --> 02:45:21,279 less syntax going on a little less 4381 02:45:19,000 --> 02:45:23,160 duplication of equal signs and ell if 4382 02:45:21,279 --> 02:45:24,920 and ell if and ell if all over the place 4383 02:45:23,160 --> 02:45:27,479 but ultimately this would be an equally 4384 02:45:24,920 --> 02:45:28,760 correct approach to that same problem 4385 02:45:27,479 --> 02:45:30,520 but it turns out with the match 4386 02:45:28,760 --> 02:45:32,600 statement you can do even more powerful 4387 02:45:30,520 --> 02:45:34,279 forms of matching as well here we've 4388 02:45:32,600 --> 02:45:37,319 used it simply to implement the same 4389 02:45:34,279 --> 02:45:38,960 idea as that if L if else construct and 4390 02:45:37,319 --> 02:45:41,000 it's worth noting if you've programmed 4391 02:45:38,960 --> 02:45:42,560 in some other language the syntax here 4392 02:45:41,000 --> 02:45:44,680 is indeed correct you do not need for 4393 02:45:42,560 --> 02:45:46,439 instance a break statement as has been 4394 02:45:44,680 --> 02:45:48,000 peppered throughout and you don't need 4395 02:45:46,439 --> 02:45:49,560 something like default or something 4396 02:45:48,000 --> 02:45:51,880 explicit you indeed just use this 4397 02:45:49,560 --> 02:45:55,120 underscore as your catchall at the end 4398 02:45:51,880 --> 02:45:58,600 of the match so just by adding in some 4399 02:45:55,120 --> 02:46:01,200 of these new keywords here like if and L 4400 02:45:58,600 --> 02:46:03,359 if and else we have now the ability to 4401 02:46:01,200 --> 02:46:05,920 ask questions about values we have the 4402 02:46:03,359 --> 02:46:08,080 ability to analyze input from users and 4403 02:46:05,920 --> 02:46:10,760 ultimately make decisions about it and 4404 02:46:08,080 --> 02:46:12,600 these then were our conditionals lying 4405 02:46:10,760 --> 02:46:14,479 ahead is going to be the ability for us 4406 02:46:12,600 --> 02:46:16,520 to not only use functions and variables 4407 02:46:14,479 --> 02:46:18,560 and also these conditionals but also 4408 02:46:16,520 --> 02:46:19,520 next Loops the ability to do something 4409 02:46:18,560 --> 02:46:22,520 now 4410 02:46:19,520 --> 02:46:22,520 again and 4411 02:46:27,670 --> 02:46:36,490 [Music] 4412 02:46:38,530 --> 02:46:45,399 [Music] 4413 02:46:46,600 --> 02:46:51,800 again all right this is cs50's 4414 02:46:49,920 --> 02:46:53,560 Introduction to programming with python 4415 02:46:51,800 --> 02:46:56,200 my name is David men and this week we 4416 02:46:53,560 --> 02:46:57,840 focus on Loops this ability in python 4417 02:46:56,200 --> 02:47:00,960 and a lot of other programming languages 4418 02:46:57,840 --> 02:47:02,920 to do something again and again a cycle 4419 02:47:00,960 --> 02:47:04,880 of sorts and let's see if we can't begin 4420 02:47:02,920 --> 02:47:07,240 by motivating exactly why we have this 4421 02:47:04,880 --> 02:47:09,760 ability to do things cyclically using 4422 02:47:07,240 --> 02:47:12,560 these Loops I'm going to go ahead here 4423 02:47:09,760 --> 02:47:15,319 and open up VSS code and in my terminal 4424 02:47:12,560 --> 02:47:19,399 window let's go ahead and create uh via 4425 02:47:15,319 --> 02:47:21,240 code cat. py a Python program that meows 4426 02:47:19,399 --> 02:47:23,640 like a cat and I'm going to go ahead 4427 02:47:21,240 --> 02:47:25,040 here in this code tab very simply 4428 02:47:23,640 --> 02:47:26,560 perhaps I'm going to start by 4429 02:47:25,040 --> 02:47:28,279 implementing this cat just by using 4430 02:47:26,560 --> 02:47:30,000 prints we're going to have this cat not 4431 02:47:28,279 --> 02:47:32,399 make audible sounds but just print meow 4432 02:47:30,000 --> 02:47:33,920 meow meow on the screen three times well 4433 02:47:32,399 --> 02:47:36,640 I think the simplest way I can do this 4434 02:47:33,920 --> 02:47:40,359 is just to print meow once and to print 4435 02:47:36,640 --> 02:47:42,520 meow again and to print meow One Last 4436 02:47:40,359 --> 02:47:44,600 Time on the screen and now let me go 4437 02:47:42,520 --> 02:47:48,120 down to my terminal window let me run 4438 02:47:44,600 --> 02:47:50,880 python of cat. py enter and meow meow 4439 02:47:48,120 --> 02:47:52,600 meow all right so this program works 4440 02:47:50,880 --> 02:47:54,520 this program indeed works if my goal is 4441 02:47:52,600 --> 02:47:56,560 to get the cat to meow three times and 4442 02:47:54,520 --> 02:47:58,600 let me propose just to help us wrap our 4443 02:47:56,560 --> 02:48:00,439 minds around what's going on inside of 4444 02:47:58,600 --> 02:48:03,080 the computer let me propose that we 4445 02:48:00,439 --> 02:48:04,920 consider this flowchart so as before we 4446 02:48:03,080 --> 02:48:06,479 have this flowchart that starts with a 4447 02:48:04,920 --> 02:48:08,880 of this oval which just means start 4448 02:48:06,479 --> 02:48:12,520 reading here and then notice it goes via 4449 02:48:08,880 --> 02:48:14,960 arrows to a meow meow meow and then it 4450 02:48:12,520 --> 02:48:17,720 stops it's perfectly correct and 4451 02:48:14,960 --> 02:48:20,760 honestly it's wonderfully simple but I 4452 02:48:17,720 --> 02:48:24,680 dare say we can find fault with my code 4453 02:48:20,760 --> 02:48:25,840 nonetheless why is my code arguably 4454 02:48:24,680 --> 02:48:27,840 poorly 4455 02:48:25,840 --> 02:48:29,560 designed now the answer is going to be 4456 02:48:27,840 --> 02:48:32,240 Loops in some way but let's see if we 4457 02:48:29,560 --> 02:48:36,200 can identify in what way the code is 4458 02:48:32,240 --> 02:48:38,200 actually poorly designed in some sense 4459 02:48:36,200 --> 02:48:41,640 let's see any thoughts 4460 02:48:38,200 --> 02:48:44,800 Alex okay so I mean repeating the same 4461 02:48:41,640 --> 02:48:47,200 action like three times or even more um 4462 02:48:44,800 --> 02:48:49,439 it's not a good habit yeah I'm just 4463 02:48:47,200 --> 02:48:51,880 repeating myself and honestly it's not 4464 02:48:49,439 --> 02:48:54,760 that big a deal if we go back to my code 4465 02:48:51,880 --> 02:48:56,760 here am I really uh doing such a bad 4466 02:48:54,760 --> 02:48:58,560 thing by just printing meow meow meow 4467 02:48:56,760 --> 02:49:00,399 three times not really but let's 4468 02:48:58,560 --> 02:49:03,279 consider The Logical extension of this 4469 02:49:00,399 --> 02:49:06,800 suppose I want to meow four times or 4470 02:49:03,279 --> 02:49:08,279 five times or 50 times or 500 times do 4471 02:49:06,800 --> 02:49:10,399 you really think even if you've never 4472 02:49:08,279 --> 02:49:11,720 programmed before is the solution to 4473 02:49:10,399 --> 02:49:14,600 this problem really going to be to hit 4474 02:49:11,720 --> 02:49:16,240 copy paste 50 times like probably not we 4475 02:49:14,600 --> 02:49:18,080 can probably do better than that and 4476 02:49:16,240 --> 02:49:20,840 Beyond it just being ugly at that point 4477 02:49:18,080 --> 02:49:22,399 having so many lines of identical code 4478 02:49:20,840 --> 02:49:23,880 just imagine if you wanted to change the 4479 02:49:22,399 --> 02:49:25,560 code maybe I changed my mind and I don't 4480 02:49:23,880 --> 02:49:27,399 want to make a cat I want to make a dog 4481 02:49:25,560 --> 02:49:29,080 so now it has to say woof woof woof 4482 02:49:27,399 --> 02:49:31,479 multiple times now I have to change that 4483 02:49:29,080 --> 02:49:33,399 in like 50 different places and yeah 4484 02:49:31,479 --> 02:49:35,040 sure I could do find and replace but 4485 02:49:33,399 --> 02:49:37,080 come on like we're programmers now 4486 02:49:35,040 --> 02:49:39,239 there's got to be a better way than just 4487 02:49:37,080 --> 02:49:41,359 repeating ourselves so I bet we can do 4488 02:49:39,239 --> 02:49:44,880 better than that if we think about a 4489 02:49:41,359 --> 02:49:46,920 little harder what we how we go about 4490 02:49:44,880 --> 02:49:49,239 structuring this program and we can do 4491 02:49:46,920 --> 02:49:51,439 that if we augment our vocabulary just a 4492 02:49:49,239 --> 02:49:53,399 little bit it turns out in Python and in 4493 02:49:51,439 --> 02:49:56,600 other languages too there's a keyword 4494 02:49:53,399 --> 02:49:58,279 called while and while is one way that 4495 02:49:56,600 --> 02:49:59,479 we can express what's called a loop a 4496 02:49:58,279 --> 02:50:02,279 block of code that's going to do 4497 02:49:59,479 --> 02:50:04,680 something again and again and again zero 4498 02:50:02,279 --> 02:50:08,319 times one time two times 50 times as 4499 02:50:04,680 --> 02:50:12,160 many times as we want but while rather 4500 02:50:08,319 --> 02:50:14,080 leaves to us the the particulars of how 4501 02:50:12,160 --> 02:50:16,160 we express ourselves to do something 4502 02:50:14,080 --> 02:50:18,479 again and again so let me go back over 4503 02:50:16,160 --> 02:50:21,520 to vs code here and let me propose that 4504 02:50:18,479 --> 02:50:24,880 I do this while is a construct that 4505 02:50:21,520 --> 02:50:26,479 allows me to ask a question again and 4506 02:50:24,880 --> 02:50:27,920 again and anytime we've seen a question 4507 02:50:26,479 --> 02:50:29,840 it's been in the form of a Boolean 4508 02:50:27,920 --> 02:50:32,920 expression a question to which the 4509 02:50:29,840 --> 02:50:35,160 answer is true or false well how could I 4510 02:50:32,920 --> 02:50:38,800 do this how could I print out meow three 4511 02:50:35,160 --> 02:50:41,560 times and ask three times a question to 4512 02:50:38,800 --> 02:50:43,479 which the answer is true or false well 4513 02:50:41,560 --> 02:50:45,160 what if I did some counting right like 4514 02:50:43,479 --> 02:50:47,359 literally on my fingers and if I'm 4515 02:50:45,160 --> 02:50:49,120 trying to count maybe down from three I 4516 02:50:47,359 --> 02:50:51,920 want to meow three times I can put three 4517 02:50:49,120 --> 02:50:53,720 fingers up and I can meow and then I can 4518 02:50:51,920 --> 02:50:55,359 put like one of the fingers down and 4519 02:50:53,720 --> 02:50:57,120 then meow and I can put one of the 4520 02:50:55,359 --> 02:50:59,319 fingers down and I can meow put one of 4521 02:50:57,120 --> 02:51:02,680 the fingers down and maybe the question 4522 02:50:59,319 --> 02:51:04,680 I can ask every time I meow is do I have 4523 02:51:02,680 --> 02:51:06,239 any fingers up still do I have any 4524 02:51:04,680 --> 02:51:08,160 fingers up still do I have any fingers 4525 02:51:06,239 --> 02:51:12,200 up still and if the answer is true keep 4526 02:51:08,160 --> 02:51:14,560 going if the answer is false stop so how 4527 02:51:12,200 --> 02:51:16,439 can I translate that to code well once 4528 02:51:14,560 --> 02:51:18,600 we've added this while keyword I think 4529 02:51:16,439 --> 02:51:21,000 we have all the building blocks already 4530 02:51:18,600 --> 02:51:23,040 let me propose that I do this let me 4531 02:51:21,000 --> 02:51:24,680 propose that I give myself a variable 4532 02:51:23,040 --> 02:51:26,160 and I'll call it I for integer but I 4533 02:51:24,680 --> 02:51:28,479 could call it anything I want and I'm 4534 02:51:26,160 --> 02:51:30,439 going to initialize it to three then I'm 4535 02:51:28,479 --> 02:51:32,760 going to use this new feature of python 4536 02:51:30,439 --> 02:51:34,920 while and I'm going to ask a question 4537 02:51:32,760 --> 02:51:38,439 the answer to which must be true or 4538 02:51:34,920 --> 02:51:41,800 false and I'm going to say while I does 4539 02:51:38,439 --> 02:51:45,080 not equal zero so I'm going to ask the 4540 02:51:41,800 --> 02:51:47,120 question while I does not equal zero do 4541 02:51:45,080 --> 02:51:49,080 the following notice the colon at the 4542 02:51:47,120 --> 02:51:50,840 end of the line notice my indentation 4543 02:51:49,080 --> 02:51:53,600 and just like with functions just like 4544 02:51:50,840 --> 02:51:56,399 with conditionals you indent the lines 4545 02:51:53,600 --> 02:51:59,040 that you only want to execute as part of 4546 02:51:56,399 --> 02:52:02,080 this other thing what do I want to do 4547 02:51:59,040 --> 02:52:06,319 while I does not equal zero well I think 4548 02:52:02,080 --> 02:52:09,439 I just want to meow but it's not enough 4549 02:52:06,319 --> 02:52:13,359 just to write this code if I were to 4550 02:52:09,439 --> 02:52:15,080 very dangerously run python of cat dopy 4551 02:52:13,359 --> 02:52:19,000 and hit enter right 4552 02:52:15,080 --> 02:52:21,760 now what might happen on the screen 4553 02:52:19,000 --> 02:52:24,359 whether you've programmed before or not 4554 02:52:21,760 --> 02:52:26,359 why is this a very bad thing potentially 4555 02:52:24,359 --> 02:52:28,479 it's not going to break things but it 4556 02:52:26,359 --> 02:52:29,560 might it might lose control of my 4557 02:52:28,479 --> 02:52:34,399 computer 4558 02:52:29,560 --> 02:52:38,080 somehow any thoughts uh yeah teimo hi uh 4559 02:52:34,399 --> 02:52:41,600 I think it's going to continue uh to 4560 02:52:38,080 --> 02:52:44,920 print out Mel since I is always equal to 4561 02:52:41,600 --> 02:52:47,319 three and the W is always true yeah 4562 02:52:44,920 --> 02:52:48,840 exactly if I'm initializing I to three 4563 02:52:47,319 --> 02:52:50,800 that is setting it equal to three on 4564 02:52:48,840 --> 02:52:53,040 line one then I'm asking the question 4565 02:52:50,800 --> 02:52:55,000 while I does not equal zero and that's 4566 02:52:53,040 --> 02:52:57,720 going to be true it does not equal zero 4567 02:52:55,000 --> 02:53:00,359 it obviously equals three print meow and 4568 02:52:57,720 --> 02:53:03,040 the way a while loop works is that the 4569 02:53:00,359 --> 02:53:06,080 python interpreter just keeps going back 4570 02:53:03,040 --> 02:53:09,239 and forth it goes from line one to line 4571 02:53:06,080 --> 02:53:11,279 two then to line three and then it goes 4572 02:53:09,239 --> 02:53:13,160 back to line two to ask the question 4573 02:53:11,279 --> 02:53:15,319 again if the answer still true it goes 4574 02:53:13,160 --> 02:53:17,040 to line three it then goes back to line 4575 02:53:15,319 --> 02:53:19,760 two if the answer is still true it goes 4576 02:53:17,040 --> 02:53:22,319 back to line three and to U's point if 4577 02:53:19,760 --> 02:53:25,520 you're never actually changing the value 4578 02:53:22,319 --> 02:53:27,920 of I it's always three you're just going 4579 02:53:25,520 --> 02:53:30,760 to be looping literally forever and this 4580 02:53:27,920 --> 02:53:32,040 is an accidental infinite Loop so we've 4581 02:53:30,760 --> 02:53:33,080 got to be smarter than that and I'm not 4582 02:53:32,040 --> 02:53:34,760 going to hit enter because I don't want 4583 02:53:33,080 --> 02:53:37,040 to lose control over my computer here 4584 02:53:34,760 --> 02:53:39,279 such that it's printing out meow forever 4585 02:53:37,040 --> 02:53:40,960 um fortunately if you ever do do that 4586 02:53:39,279 --> 02:53:44,439 and you find yourself in an accidental 4587 02:53:40,960 --> 02:53:46,359 infinite Loop control C for cancel or 4588 02:53:44,439 --> 02:53:47,960 interrupt is going to be your friend if 4589 02:53:46,359 --> 02:53:50,279 you ever seem to lose control you don't 4590 02:53:47,960 --> 02:53:52,680 need to like reboot or turn off the 4591 02:53:50,279 --> 02:53:54,239 computer you can just hit contr C in 4592 02:53:52,680 --> 02:53:56,680 your terminal window and that will 4593 02:53:54,239 --> 02:53:59,319 likely fix it all right well what do I 4594 02:53:56,680 --> 02:54:01,439 want to do then after meowing each time 4595 02:53:59,319 --> 02:54:04,080 I think what I'd like to do here is 4596 02:54:01,439 --> 02:54:07,520 maybe something like this let me update 4597 02:54:04,080 --> 02:54:11,319 I to equal whatever the current value is 4598 02:54:07,520 --> 02:54:14,720 uh uh minus one here whoops sorry minus 4599 02:54:11,319 --> 02:54:17,800 one so if I on each iteration am 4600 02:54:14,720 --> 02:54:20,920 updating I to be one less one less one 4601 02:54:17,800 --> 02:54:23,880 less it should eventually hit zero at 4602 02:54:20,920 --> 02:54:26,520 which point the answer to 9 2's question 4603 02:54:23,880 --> 02:54:27,600 will now be false so let's see if this 4604 02:54:26,520 --> 02:54:30,120 works I'm going to go down to my 4605 02:54:27,600 --> 02:54:33,960 terminal window and run python of caty 4606 02:54:30,120 --> 02:54:35,680 and I indeed get three meows why because 4607 02:54:33,960 --> 02:54:37,560 I've kind of wired this up kind of like 4608 02:54:35,680 --> 02:54:39,880 a machine in software if you will I've 4609 02:54:37,560 --> 02:54:42,600 set I equal to three then I keep asking 4610 02:54:39,880 --> 02:54:44,520 this question but I keep turning the 4611 02:54:42,600 --> 02:54:47,560 gears I keep changing the value of the 4612 02:54:44,520 --> 02:54:50,359 variable to make sure that ultimately it 4613 02:54:47,560 --> 02:54:53,600 is actually being decremented that is 4614 02:54:50,359 --> 02:54:55,359 decreased by one until we eventually hit 4615 02:54:53,600 --> 02:54:56,760 zero now for those of you who think a 4616 02:54:55,359 --> 02:54:58,920 little more graphically let me pull up 4617 02:54:56,760 --> 02:55:00,800 one of our usual flowcharts this is just 4618 02:54:58,920 --> 02:55:02,800 a representation graphically of the 4619 02:55:00,800 --> 02:55:05,000 exact same thing notice what's happening 4620 02:55:02,800 --> 02:55:08,520 I first start the program and then I 4621 02:55:05,000 --> 02:55:10,359 initialize I to three and then I ask the 4622 02:55:08,520 --> 02:55:12,359 first of my questions again the diamonds 4623 02:55:10,359 --> 02:55:13,960 always represent questions and the 4624 02:55:12,359 --> 02:55:16,720 answer is going to be true or false does 4625 02:55:13,960 --> 02:55:18,600 I not equal zero well it doesn't it 4626 02:55:16,720 --> 02:55:21,760 equals three so if I follow the true 4627 02:55:18,600 --> 02:55:25,279 line I meow and then I follow this arrow 4628 02:55:21,760 --> 02:55:27,160 and I update I to equal IUS one at this 4629 02:55:25,279 --> 02:55:29,680 point in the story I presumably equals 4630 02:55:27,160 --> 02:55:31,399 two mathematically I Follow the arrow 4631 02:55:29,680 --> 02:55:32,920 and there's the loop this is why it's 4632 02:55:31,399 --> 02:55:34,920 nice to see this graphically perhaps 4633 02:55:32,920 --> 02:55:36,920 because you can literally see the loop 4634 02:55:34,920 --> 02:55:40,040 back and forth now I ask the question 4635 02:55:36,920 --> 02:55:42,720 again does two not equal zero well it 4636 02:55:40,040 --> 02:55:45,720 does not equal zero it's two so we meow 4637 02:55:42,720 --> 02:55:48,560 again we change I from 2 to 1 well does 4638 02:55:45,720 --> 02:55:52,000 one not equal zero well obviously it is 4639 02:55:48,560 --> 02:55:55,680 not zero so we meow again we decrement I 4640 02:55:52,000 --> 02:55:59,080 again I is now zero does 0 not equal 4641 02:55:55,680 --> 02:56:02,239 zero no it equals zero so the answer is 4642 02:55:59,080 --> 02:56:04,600 false and we stop so there perhaps more 4643 02:56:02,239 --> 02:56:07,279 so than any of our flowcharts before do 4644 02:56:04,600 --> 02:56:09,080 you really see the structure of what's 4645 02:56:07,279 --> 02:56:10,239 Happening inside of the program and you 4646 02:56:09,080 --> 02:56:11,840 don't have to get into the habit of 4647 02:56:10,239 --> 02:56:13,880 making these charts or creating these 4648 02:56:11,840 --> 02:56:15,600 charts but just as a first pass at 4649 02:56:13,880 --> 02:56:17,760 what's going on inside of the computer 4650 02:56:15,600 --> 02:56:19,760 that's indeed one way to visualize it 4651 02:56:17,760 --> 02:56:21,080 instead well let me propose that like 4652 02:56:19,760 --> 02:56:22,680 always there's many different ways to 4653 02:56:21,080 --> 02:56:24,520 solve this problem and suppose you just 4654 02:56:22,680 --> 02:56:26,680 like to think a little differently maybe 4655 02:56:24,520 --> 02:56:28,760 you don't like starting at three and 4656 02:56:26,680 --> 02:56:30,279 then counting down to zero y maybe your 4657 02:56:28,760 --> 02:56:32,520 just brain doesn't work that way and you 4658 02:56:30,279 --> 02:56:34,760 prefer to count up instead of down 4659 02:56:32,520 --> 02:56:38,120 totally fine let me go ahead and change 4660 02:56:34,760 --> 02:56:40,880 my code here to set I equal to 1 instead 4661 02:56:38,120 --> 02:56:42,920 of three and here let me just change my 4662 02:56:40,880 --> 02:56:44,040 logic rather than checking for not equal 4663 02:56:42,920 --> 02:56:45,439 to zero like maybe you don't like 4664 02:56:44,040 --> 02:56:47,640 thinking terms of not because it's a 4665 02:56:45,439 --> 02:56:51,040 little confusing and it might be let's 4666 02:56:47,640 --> 02:56:53,000 just check that I is less than or equal 4667 02:56:51,040 --> 02:56:55,680 to three so we'll be a little more 4668 02:56:53,000 --> 02:56:58,200 explicit we'll count from one up through 4669 02:56:55,680 --> 02:57:00,239 three each time printing meow but I'm 4670 02:56:58,200 --> 02:57:01,880 going to need to change this line here 4671 02:57:00,239 --> 02:57:04,040 let me see if we can't call on someone 4672 02:57:01,880 --> 02:57:07,479 to change line four for me how do I want 4673 02:57:04,040 --> 02:57:11,239 to change line four to be 4674 02:57:07,479 --> 02:57:12,640 consistent with counting from one up to 4675 02:57:11,239 --> 02:57:14,399 and 4676 02:57:12,640 --> 02:57:20,120 through 4677 02:57:14,399 --> 02:57:22,560 three I would be plus one every time you 4678 02:57:20,120 --> 02:57:25,600 meow yeah exactly in this case we want 4679 02:57:22,560 --> 02:57:27,359 to add one not subtract one and in fact 4680 02:57:25,600 --> 02:57:29,080 if you think about this this two could 4681 02:57:27,359 --> 02:57:31,520 end very poorly right if you start 4682 02:57:29,080 --> 02:57:34,000 counting at one and you keep subtracting 4683 02:57:31,520 --> 02:57:35,160 one subtracting one subtracting one I 4684 02:57:34,000 --> 02:57:36,800 think we're going to find oursel with 4685 02:57:35,160 --> 02:57:39,000 the same problem which is that we're 4686 02:57:36,800 --> 02:57:40,920 never going to stop because we're going 4687 02:57:39,000 --> 02:57:42,600 to keep getting more and more negative 4688 02:57:40,920 --> 02:57:44,680 as opposed to ever getting up to the 4689 02:57:42,600 --> 02:57:48,200 number three so I think you're right I 4690 02:57:44,680 --> 02:57:50,760 need to change this to be IAL I + 1 and 4691 02:57:48,200 --> 02:57:53,040 now notice just for Clarity 2 the equal 4692 02:57:50,760 --> 02:57:55,160 sign is again our assignment operator 4693 02:57:53,040 --> 02:57:56,760 from right to left logically this might 4694 02:57:55,160 --> 02:57:59,520 otherwise strike you as strange like how 4695 02:57:56,760 --> 02:58:02,000 can I equal itself plus one well it 4696 02:57:59,520 --> 02:58:04,680 doesn't until you execute this code from 4697 02:58:02,000 --> 02:58:06,720 right to left you add one to I or You 4698 02:58:04,680 --> 02:58:08,600 Subtract one from I and then you update 4699 02:58:06,720 --> 02:58:10,200 the value of I on the left the 4700 02:58:08,600 --> 02:58:12,560 assignment copies the value from the 4701 02:58:10,200 --> 02:58:15,640 right to the left well how else might I 4702 02:58:12,560 --> 02:58:17,680 do this well I will say that most 4703 02:58:15,640 --> 02:58:19,880 programmers computer scientists more 4704 02:58:17,680 --> 02:58:21,800 generally tend to start counting from 4705 02:58:19,880 --> 02:58:23,880 zero it's a convention and it actually 4706 02:58:21,800 --> 02:58:25,680 has upsides even in Python and other 4707 02:58:23,880 --> 02:58:27,880 languages where generally speaking it's 4708 02:58:25,680 --> 02:58:29,520 a good thing to start counting from zero 4709 02:58:27,880 --> 02:58:31,880 instead of counting like we might in the 4710 02:58:29,520 --> 02:58:34,279 real world from one let's go ahead and 4711 02:58:31,880 --> 02:58:36,640 adopt that convention now let me set I 4712 02:58:34,279 --> 02:58:39,720 equal to zero and I need to make a 4713 02:58:36,640 --> 02:58:43,080 change now notice if I don't change my 4714 02:58:39,720 --> 02:58:45,399 logic this program just became buggy the 4715 02:58:43,080 --> 02:58:48,160 cat has a bug it's now meowing four 4716 02:58:45,399 --> 02:58:50,239 times if I run it as is but the easiest 4717 02:58:48,160 --> 02:58:53,239 fix here would be to change my 4718 02:58:50,239 --> 02:58:55,640 inequality to be this less than instead 4719 02:58:53,239 --> 02:58:58,040 of less than or equal to now I'm 4720 02:58:55,640 --> 02:59:00,520 starting at zero but I'm going up two 4721 02:58:58,040 --> 02:59:02,640 but not through three and even though 4722 02:59:00,520 --> 02:59:04,960 this might of all the things we've seen 4723 02:59:02,640 --> 02:59:07,120 thus far seem maybe the least familiar 4724 02:59:04,960 --> 02:59:09,479 most of us might start at one two then 4725 02:59:07,120 --> 02:59:12,359 three it's a good habit to get into now 4726 02:59:09,479 --> 02:59:14,800 start at zero and go up two but not 4727 02:59:12,359 --> 02:59:17,040 through the value that you care about 4728 02:59:14,800 --> 02:59:18,680 ultimately three in this case here well 4729 02:59:17,040 --> 02:59:20,520 let me tighten things up a bit here not 4730 02:59:18,680 --> 02:59:22,640 only will this now fix my counting 4731 02:59:20,520 --> 02:59:24,720 problem it now meows three times as 4732 02:59:22,640 --> 02:59:27,720 expected there's a more succinct way to 4733 02:59:24,720 --> 02:59:29,279 express I equals I + 1 and this is 4734 02:59:27,720 --> 02:59:32,720 because it's such a popular thing to do 4735 02:59:29,279 --> 02:59:35,760 in code you can instead just say i+ 4736 02:59:32,720 --> 02:59:37,600 equals 1 and that's it you don't need to 4737 02:59:35,760 --> 02:59:40,120 put everything on the right hand side 4738 02:59:37,600 --> 02:59:43,120 this is a special syntax that says the 4739 02:59:40,120 --> 02:59:45,279 exact same thing increment I but it does 4740 02:59:43,120 --> 02:59:46,760 it with a few fewer keystrokes it's just 4741 02:59:45,279 --> 02:59:48,399 a little more pleasant to type it's a 4742 02:59:46,760 --> 02:59:50,000 little faster to read it's it's just a 4743 02:59:48,399 --> 02:59:54,399 convention those of you who have 4744 02:59:50,000 --> 02:59:57,399 programmed in C C++ pyth uh not python C 4745 02:59:54,399 --> 03:00:01,160 C++ Java Java Script might have seen 4746 02:59:57,399 --> 03:00:03,120 plus plus before or minus minus sorry 4747 03:00:01,160 --> 03:00:05,000 python doesn't have it so you cannot use 4748 03:00:03,120 --> 03:00:06,359 that this is a succinct as your line of 4749 03:00:05,000 --> 03:00:09,319 code might 4750 03:00:06,359 --> 03:00:12,279 get all right let me pause here to see 4751 03:00:09,319 --> 03:00:15,359 then if there's any questions about 4752 03:00:12,279 --> 03:00:18,279 these implementations of while 4753 03:00:15,359 --> 03:00:23,319 Loops um can we use stuff like four 4754 03:00:18,279 --> 03:00:26,359 Loops which um have a certain I value 4755 03:00:23,319 --> 03:00:29,279 initialized to it at at the start and it 4756 03:00:26,359 --> 03:00:32,680 runs from the particular condition you 4757 03:00:29,279 --> 03:00:35,720 put into the um into the thing and 4758 03:00:32,680 --> 03:00:38,319 increment it as as you go along short 4759 03:00:35,720 --> 03:00:39,960 answer no you cannot do what you're 4760 03:00:38,319 --> 03:00:42,120 describing but there is another type of 4761 03:00:39,960 --> 03:00:44,040 for Loop that we will soon see but let's 4762 03:00:42,120 --> 03:00:49,279 come to that in just a moment other 4763 03:00:44,040 --> 03:00:51,880 questions on Loops using while here 4764 03:00:49,279 --> 03:00:54,120 so I had a question about the flowcharts 4765 03:00:51,880 --> 03:00:56,920 okay uh there were c yeah there were 4766 03:00:54,120 --> 03:01:00,399 certain symbols for the certain kind of 4767 03:00:56,920 --> 03:01:02,359 the statements uh sir they are they 4768 03:01:00,399 --> 03:01:05,000 certainly used for that kind of 4769 03:01:02,359 --> 03:01:08,200 statement that they are 4770 03:01:05,000 --> 03:01:09,359 put they are so I deliber use anyone I 4771 03:01:08,200 --> 03:01:11,840 deliberately use certain types of 4772 03:01:09,359 --> 03:01:14,200 symbols certain shapes here uh whereby 4773 03:01:11,840 --> 03:01:17,479 in oval is conventional for start and 4774 03:01:14,200 --> 03:01:20,040 stop I used rectangles for any statement 4775 03:01:17,479 --> 03:01:22,359 of code like an assignment or a printing 4776 03:01:20,040 --> 03:01:24,720 and so forth and I use diamonds to 4777 03:01:22,359 --> 03:01:27,439 represent uh questions that you might 4778 03:01:24,720 --> 03:01:29,040 ask uh conditions as we've seen um if 4779 03:01:27,439 --> 03:01:30,399 you're doing this for yourself if you're 4780 03:01:29,040 --> 03:01:31,680 just trying to make sense of your code 4781 03:01:30,399 --> 03:01:33,200 and writing it down you certainly don't 4782 03:01:31,680 --> 03:01:35,960 need to use these formal symbols but I 4783 03:01:33,200 --> 03:01:37,760 tried to be consistent with some PR best 4784 03:01:35,960 --> 03:01:39,319 practices and in fact let me come back 4785 03:01:37,760 --> 03:01:41,120 to the same picture because this was the 4786 03:01:39,319 --> 03:01:42,680 first version of our picture but we've 4787 03:01:41,120 --> 03:01:44,239 since modified our code a couple of 4788 03:01:42,680 --> 03:01:46,520 times this recall was the version where 4789 03:01:44,239 --> 03:01:48,560 the question we were asking was I not 4790 03:01:46,520 --> 03:01:50,640 equal to zero let me go ahead and just 4791 03:01:48,560 --> 03:01:52,880 change this code now to represent the 4792 03:01:50,640 --> 03:01:55,479 next version we did which recall changed 4793 03:01:52,880 --> 03:01:57,840 our logic to start counting from one it 4794 03:01:55,479 --> 03:01:59,680 changed our question to check is I less 4795 03:01:57,840 --> 03:02:01,880 than or equal to three but then 4796 03:01:59,680 --> 03:02:04,080 everything else was the same except for 4797 03:02:01,880 --> 03:02:06,120 the counting which is now Plus instead 4798 03:02:04,080 --> 03:02:09,640 of minus and then we refined it a little 4799 03:02:06,120 --> 03:02:12,319 bit further by counting now from zero up 4800 03:02:09,640 --> 03:02:14,520 two but not through three and we 4801 03:02:12,319 --> 03:02:16,279 tightened up this code here by just 4802 03:02:14,520 --> 03:02:18,160 incrementing one by using the slightly 4803 03:02:16,279 --> 03:02:19,800 more succinct syntax so at this point 4804 03:02:18,160 --> 03:02:21,279 these flowcharts might become less and 4805 03:02:19,800 --> 03:02:24,160 less useful for us because once you've 4806 03:02:21,279 --> 03:02:25,880 wrapped your mind around the concept and 4807 03:02:24,160 --> 03:02:28,120 hopefully the picture helps bring that 4808 03:02:25,880 --> 03:02:30,439 concept to life it's certainly fine to 4809 03:02:28,120 --> 03:02:32,279 focus entirely on the code and only 4810 03:02:30,439 --> 03:02:33,520 think about or even draw something like 4811 03:02:32,279 --> 03:02:35,479 this if you need to wrap your mind 4812 03:02:33,520 --> 03:02:37,640 around something more complicated than 4813 03:02:35,479 --> 03:02:40,080 you're used to well let me go ahead if I 4814 03:02:37,640 --> 03:02:43,399 may and propose that we transition to 4815 03:02:40,080 --> 03:02:46,040 another approach of types of Loops using 4816 03:02:43,399 --> 03:02:47,520 another keyword here namely a for Loop 4817 03:02:46,040 --> 03:02:49,279 and this is a word that does exist in 4818 03:02:47,520 --> 03:02:51,319 other languages but doesn't necessarily 4819 03:02:49,279 --> 03:02:53,439 have as many features as other languages 4820 03:02:51,319 --> 03:02:55,479 might use it for but there is a 4821 03:02:53,439 --> 03:02:57,439 different type of loop not a while loop 4822 03:02:55,479 --> 03:02:59,359 but a for Loop and a for Loop is going 4823 03:02:57,439 --> 03:03:01,520 to allow our allow us to express 4824 03:02:59,359 --> 03:03:03,279 ourselves a little differently but to do 4825 03:03:01,520 --> 03:03:05,800 so I'd propose that the easiest way is 4826 03:03:03,279 --> 03:03:08,319 if we introduce one other ID in Python 4827 03:03:05,800 --> 03:03:10,680 which is that of a list and here too no 4828 03:03:08,319 --> 03:03:12,800 pun intended we're adding to the list of 4829 03:03:10,680 --> 03:03:16,200 data types that python supports we've 4830 03:03:12,800 --> 03:03:18,640 seen stirs or strings ins or integers 4831 03:03:16,200 --> 03:03:21,399 Floats or floating point value use bulls 4832 03:03:18,640 --> 03:03:24,000 or Boolean Expressions python also has 4833 03:03:21,399 --> 03:03:25,399 lists which is another type of data but 4834 03:03:24,000 --> 03:03:27,640 wonderfully this one's probably pretty 4835 03:03:25,399 --> 03:03:29,560 familiar a list of things in the real 4836 03:03:27,640 --> 03:03:33,279 world is a list of things in Python it's 4837 03:03:29,560 --> 03:03:35,239 a way of containing multiple values all 4838 03:03:33,279 --> 03:03:37,560 in the same place all in the same 4839 03:03:35,239 --> 03:03:40,520 variable so what do I mean by this well 4840 03:03:37,560 --> 03:03:42,760 let me propose that we go back to our 4841 03:03:40,520 --> 03:03:44,560 VSS code here and let me kind of start 4842 03:03:42,760 --> 03:03:46,479 fresh with my code here and not use a 4843 03:03:44,560 --> 03:03:49,200 while loop at all but let me use this 4844 03:03:46,479 --> 03:03:51,399 new keyword for the way the for Loop 4845 03:03:49,200 --> 03:03:54,279 works is that it allows you to iterate 4846 03:03:51,399 --> 03:03:58,359 over a list of items so what does this 4847 03:03:54,279 --> 03:04:02,399 look like it might look like this for I 4848 03:03:58,359 --> 03:04:04,200 in the following list of items 0 1 2 4849 03:04:02,399 --> 03:04:06,479 this is my starting point and on each 4850 03:04:04,200 --> 03:04:08,880 iteration of this Loop that is on each 4851 03:04:06,479 --> 03:04:12,160 execution of this loop again and again I 4852 03:04:08,880 --> 03:04:14,040 want to print out meow now I'll admit I 4853 03:04:12,160 --> 03:04:15,680 kind of like the look of this code 4854 03:04:14,040 --> 03:04:17,720 already even though there's some new 4855 03:04:15,680 --> 03:04:19,080 syntax here because it's just short 4856 03:04:17,720 --> 03:04:21,040 order than the while loop right the 4857 03:04:19,080 --> 03:04:23,200 while loop had multiple lines a moment 4858 03:04:21,040 --> 03:04:25,359 ago and it was entirely up to me to 4859 03:04:23,200 --> 03:04:26,840 decide what i is I have to check a 4860 03:04:25,359 --> 03:04:28,720 condition I have to increment or 4861 03:04:26,840 --> 03:04:31,439 decrement I like I was doing a lot of 4862 03:04:28,720 --> 03:04:34,000 work relatively speaking to make that 4863 03:04:31,439 --> 03:04:36,040 thing turn to make that Loop go and go 4864 03:04:34,000 --> 03:04:38,279 it was very mechanical in a sense you 4865 03:04:36,040 --> 03:04:40,399 can kind of in your mind's eye maybe see 4866 03:04:38,279 --> 03:04:42,800 the gears turning as all of these 4867 03:04:40,399 --> 03:04:45,520 variables are uh changing and these 4868 03:04:42,800 --> 03:04:47,399 questions are being asked a for Loop 4869 03:04:45,520 --> 03:04:49,840 kind of simplifies all of that and it 4870 03:04:47,399 --> 03:04:52,319 just says if you want a variable like I 4871 03:04:49,840 --> 03:04:54,720 a number and you know in advance how 4872 03:04:52,319 --> 03:04:57,319 many times you want this Loop to execute 4873 03:04:54,720 --> 03:04:59,319 three times we'll just kind of specify 4874 03:04:57,319 --> 03:05:02,560 what it is you want I to take on as 4875 03:04:59,319 --> 03:05:04,359 values explicitly in this loop I will be 4876 03:05:02,560 --> 03:05:07,160 automatically initialized by python to 4877 03:05:04,359 --> 03:05:09,560 be zero then meow will be printed then 4878 03:05:07,160 --> 03:05:12,359 python will automatically update I to 4879 03:05:09,560 --> 03:05:15,239 equal 1 then meow will be printed then 4880 03:05:12,359 --> 03:05:17,279 python will automatically update I to B2 4881 03:05:15,239 --> 03:05:19,520 and meow will be printed and because 4882 03:05:17,279 --> 03:05:21,520 that's it for the values in that list 4883 03:05:19,520 --> 03:05:24,000 python will stop and it will only me 4884 03:05:21,520 --> 03:05:26,319 meow a total of three times what is the 4885 03:05:24,000 --> 03:05:29,040 list the list in this program is exactly 4886 03:05:26,319 --> 03:05:31,560 that 0 comma 1 comma 2 and notice the 4887 03:05:29,040 --> 03:05:34,040 square brackets those aren't parentheses 4888 03:05:31,560 --> 03:05:35,960 those are square brackets that represent 4889 03:05:34,040 --> 03:05:37,840 a list that's how you know visually as 4890 03:05:35,960 --> 03:05:39,840 the programmer that's how python knows 4891 03:05:37,840 --> 03:05:42,920 as the language that you intend for that 4892 03:05:39,840 --> 03:05:46,000 to be a list so let me go ahead and run 4893 03:05:42,920 --> 03:05:47,960 this python of cat. piy and it works 4894 03:05:46,000 --> 03:05:49,680 just the same but it's only two lines 4895 03:05:47,960 --> 03:05:53,720 it's pretty readable once you have 4896 03:05:49,680 --> 03:05:56,720 familiarity with that construct but to 4897 03:05:53,720 --> 03:05:59,880 my constant point about correctness not 4898 03:05:56,720 --> 03:06:02,080 necessarily being the same as design in 4899 03:05:59,880 --> 03:06:04,560 what sense is this program perhaps 4900 03:06:02,080 --> 03:06:06,279 poorly designed It's seems to work it 4901 03:06:04,560 --> 03:06:09,920 meows three 4902 03:06:06,279 --> 03:06:11,880 times but why might this not be the best 4903 03:06:09,920 --> 03:06:14,680 way to solve this problem even if you've 4904 03:06:11,880 --> 03:06:16,760 never programmed before again think 4905 03:06:14,680 --> 03:06:19,880 about Corner cases things that may or 4906 03:06:16,760 --> 03:06:21,600 may not happen think about extreme cases 4907 03:06:19,880 --> 03:06:24,960 that really test the quality of this 4908 03:06:21,600 --> 03:06:28,960 code okay I think that because like we 4909 03:06:24,960 --> 03:06:31,399 can we are saying 0 one two which is 4910 03:06:28,960 --> 03:06:34,960 three times and then like if you want to 4911 03:06:31,399 --> 03:06:37,000 print a million you say one two 4912 03:06:34,960 --> 03:06:38,399 three yeah exactly and that's what I 4913 03:06:37,000 --> 03:06:39,640 mean about thinking about the extreme 4914 03:06:38,399 --> 03:06:41,880 cases if you're trying to decide for 4915 03:06:39,640 --> 03:06:44,040 yourself if your own code is good or 4916 03:06:41,880 --> 03:06:45,960 someone else's code is good it might 4917 03:06:44,040 --> 03:06:47,840 look so at first glance but think about 4918 03:06:45,960 --> 03:06:49,920 the extreme well what if it's not three 4919 03:06:47,840 --> 03:06:52,560 things it's a million things I mean are 4920 03:06:49,920 --> 03:06:56,040 you really going to write out one Z 4921 03:06:52,560 --> 03:06:57,520 through a million or 0 through 9 uh you 4922 03:06:56,040 --> 03:06:59,960 know 4923 03:06:57,520 --> 03:07:02,600 999,000 uh 4924 03:06:59,960 --> 03:07:04,080 999,999 like no you're not going to 4925 03:07:02,600 --> 03:07:06,160 write that many numbers on the screen 4926 03:07:04,080 --> 03:07:08,760 there's got to be a better way so let's 4927 03:07:06,160 --> 03:07:10,720 do the better way from the get-go rather 4928 03:07:08,760 --> 03:07:13,399 than set the stage for doing something 4929 03:07:10,720 --> 03:07:16,359 poorly and the one way we can solve this 4930 03:07:13,399 --> 03:07:18,319 problem to improve the design is don't 4931 03:07:16,359 --> 03:07:20,960 just manually specify ify the list of 4932 03:07:18,319 --> 03:07:22,760 values use a function someone else's 4933 03:07:20,960 --> 03:07:24,359 function that comes with python that 4934 03:07:22,760 --> 03:07:25,960 gives you the list you want and the 4935 03:07:24,359 --> 03:07:28,319 easiest way to do that in Python is to 4936 03:07:25,960 --> 03:07:31,840 use a function called range that returns 4937 03:07:28,319 --> 03:07:34,120 to a range of values it expects as input 4938 03:07:31,840 --> 03:07:36,439 at least one argument and that number is 4939 03:07:34,120 --> 03:07:38,479 going to be the number of values you 4940 03:07:36,439 --> 03:07:41,040 want back those values are going to 4941 03:07:38,479 --> 03:07:43,720 start at zero and go to one to two and 4942 03:07:41,040 --> 03:07:46,479 so forth but they will go up to but not 4943 03:07:43,720 --> 03:07:48,840 through the number you specify so by 4944 03:07:46,479 --> 03:07:51,720 specifying range three you're 4945 03:07:48,840 --> 03:07:53,840 essentially being handed back one two 4946 03:07:51,720 --> 03:07:57,200 three values and by default those values 4947 03:07:53,840 --> 03:07:58,880 are zero one and two and that's it but 4948 03:07:57,200 --> 03:08:01,279 what's brilliant about this is that now 4949 03:07:58,880 --> 03:08:03,279 to Hope's point if I do want to meow a 4950 03:08:01,279 --> 03:08:06,600 million times I mean that is an angry 4951 03:08:03,279 --> 03:08:08,160 cat I can now do a million by just 4952 03:08:06,600 --> 03:08:11,200 typing a million I don't have to 4953 03:08:08,160 --> 03:08:14,359 literally type zero comma one comma 2 4954 03:08:11,200 --> 03:08:18,600 comma 3 comma four all the way up to 4955 03:08:14,359 --> 03:08:21,080 999,999 I just do this so that's to be a 4956 03:08:18,600 --> 03:08:23,200 better way long term so that's indeed 4957 03:08:21,080 --> 03:08:25,120 one Improvement we can indeed make here 4958 03:08:23,200 --> 03:08:26,960 still using a for Loop but now using 4959 03:08:25,120 --> 03:08:29,040 this range function and just to show you 4960 03:08:26,960 --> 03:08:30,960 something else that's pythonic this is 4961 03:08:29,040 --> 03:08:34,080 not strictly necessary but it's commonly 4962 03:08:30,960 --> 03:08:36,160 done there's a minor Improvement we can 4963 03:08:34,080 --> 03:08:38,760 make here even if we're just meowing 4964 03:08:36,160 --> 03:08:42,640 three times and notice that even though 4965 03:08:38,760 --> 03:08:45,560 I'm defining a variable I I'm not ever 4966 03:08:42,640 --> 03:08:47,960 using it and it's kind of necessary 4967 03:08:45,560 --> 03:08:49,840 logically because python Pres presumably 4968 03:08:47,960 --> 03:08:52,319 has to use something for counting right 4969 03:08:49,840 --> 03:08:53,880 it has to know what it's iterating over 4970 03:08:52,319 --> 03:08:56,040 but there's this convention in Python 4971 03:08:53,880 --> 03:08:58,439 where if you need a variable just 4972 03:08:56,040 --> 03:09:00,000 because the programming feature requires 4973 03:08:58,439 --> 03:09:02,080 it to do some kind of counting or 4974 03:09:00,000 --> 03:09:04,800 automatic updating but you the human 4975 03:09:02,080 --> 03:09:06,960 don't care about its value a pythonic 4976 03:09:04,800 --> 03:09:09,120 Improvement here would be to name that 4977 03:09:06,960 --> 03:09:11,479 variable a single underscore just 4978 03:09:09,120 --> 03:09:13,359 because it's not required it doesn't 4979 03:09:11,479 --> 03:09:15,160 change the correctness of the program 4980 03:09:13,359 --> 03:09:17,520 but it signals to yourself later it 4981 03:09:15,160 --> 03:09:20,000 signals to colleagues or teachers are 4982 03:09:17,520 --> 03:09:21,800 looking at your code too that yes it's a 4983 03:09:20,000 --> 03:09:23,279 variable but you don't care about its 4984 03:09:21,800 --> 03:09:25,760 name because you're not using it later 4985 03:09:23,279 --> 03:09:28,239 it's just necessary in order to use this 4986 03:09:25,760 --> 03:09:31,680 feature this Loop in this case here so 4987 03:09:28,239 --> 03:09:35,239 just a minor uh Improvement or change 4988 03:09:31,680 --> 03:09:37,120 there but to really get you intrigued by 4989 03:09:35,239 --> 03:09:39,239 what's possible in Python let's take 4990 03:09:37,120 --> 03:09:42,040 this one step further so if we really 4991 03:09:39,239 --> 03:09:43,920 want to be pythonic this one if you've 4992 03:09:42,040 --> 03:09:46,200 programmed before is kind of going to 4993 03:09:43,920 --> 03:09:49,359 blow your mind so to speak whereby if I 4994 03:09:46,200 --> 03:09:52,479 want the cat to meow three times what if 4995 03:09:49,359 --> 03:09:56,319 I actually do this print open 4996 03:09:52,479 --> 03:09:58,200 parenthesis quote unquote meow times 4997 03:09:56,319 --> 03:09:59,920 three all right you have to be kind of a 4998 03:09:58,200 --> 03:10:02,600 geek to think this is cool but this is 4999 03:09:59,920 --> 03:10:05,200 kind of cool so you can literally just 5000 03:10:02,600 --> 03:10:07,640 print what you want multiply it by the 5001 03:10:05,200 --> 03:10:11,279 number of times that you want it and you 5002 03:10:07,640 --> 03:10:14,120 will get back exactly that result now 5003 03:10:11,279 --> 03:10:16,000 I've kind of made a mistake here so 5004 03:10:14,120 --> 03:10:18,640 let's see what this does it's not quite 5005 03:10:16,000 --> 03:10:20,960 as beautiful as this code might look to 5006 03:10:18,640 --> 03:10:24,200 to to you to some of you to me let me 5007 03:10:20,960 --> 03:10:26,120 run python of cat dopy enter okay it's a 5008 03:10:24,200 --> 03:10:29,120 really like Hungry Cat or something it's 5009 03:10:26,120 --> 03:10:31,520 meowing really fast but I can fix this I 5010 03:10:29,120 --> 03:10:33,279 bet let's think about now some of the 5011 03:10:31,520 --> 03:10:35,399 basic building blocks we've discussed 5012 03:10:33,279 --> 03:10:37,760 the problem is clearly that literally 5013 03:10:35,399 --> 03:10:39,520 meow meow meow is being repeated three 5014 03:10:37,760 --> 03:10:42,160 times but it's not as pretty as I want 5015 03:10:39,520 --> 03:10:44,319 it I want it to be meow meow meow on 5016 03:10:42,160 --> 03:10:48,239 separate lines what might be a possible 5017 03:10:44,319 --> 03:10:50,760 solution here while still using this 5018 03:10:48,239 --> 03:10:53,439 multiplication operator and think back 5019 03:10:50,760 --> 03:10:55,479 we've used plus to concatenate strings 5020 03:10:53,439 --> 03:10:57,200 you can apparently use multiplication to 5021 03:10:55,479 --> 03:10:59,279 concatenate strings but more than once 5022 03:10:57,200 --> 03:11:01,000 again and again and again how could I 5023 03:10:59,279 --> 03:11:03,439 clean this up without reverting to my 5024 03:11:01,000 --> 03:11:05,920 for Loop or my while loop and still use 5025 03:11:03,439 --> 03:11:08,479 multiplication in this way uh we can use 5026 03:11:05,920 --> 03:11:11,279 a escape sequence which should did back 5027 03:11:08,479 --> 03:11:13,319 slash n amazing yes think back to back 5028 03:11:11,279 --> 03:11:15,560 sln which is the way you as the 5029 03:11:13,319 --> 03:11:17,840 programmer can express a new line in 5030 03:11:15,560 --> 03:11:19,560 code and I think 5031 03:11:17,840 --> 03:11:22,200 if I take your advice I put a back slash 5032 03:11:19,560 --> 03:11:25,040 n there inside of my quotes So that at 5033 03:11:22,200 --> 03:11:26,880 the end of every Meo W there's a new 5034 03:11:25,040 --> 03:11:29,080 line let's see how this looks Let Me 5035 03:11:26,880 --> 03:11:32,479 Clear My screen and run python of 5036 03:11:29,080 --> 03:11:34,680 caty okay so close I like this let me 5037 03:11:32,479 --> 03:11:35,920 call on someone else the only thing I 5038 03:11:34,680 --> 03:11:38,160 don't like and I know I'm being really 5039 03:11:35,920 --> 03:11:39,880 nitpicky now is that it's meow meow meow 5040 03:11:38,160 --> 03:11:41,720 on separate lines but there's kind of 5041 03:11:39,880 --> 03:11:42,800 this extra blank line which I'm just not 5042 03:11:41,720 --> 03:11:46,600 loving 5043 03:11:42,800 --> 03:11:51,200 aesthetically I think we can uh make end 5044 03:11:46,600 --> 03:11:52,840 equal to column uh column not back n 5045 03:11:51,200 --> 03:11:54,680 yeah so here too like all of these 5046 03:11:52,840 --> 03:11:56,520 things we've seen in past weeks are kind 5047 03:11:54,680 --> 03:11:58,960 of coming together right recall that the 5048 03:11:56,520 --> 03:12:01,640 print function lets you control what the 5049 03:11:58,960 --> 03:12:03,800 line ending is by default it's back 5050 03:12:01,640 --> 03:12:05,640 slash n itself which is why at the very 5051 03:12:03,800 --> 03:12:07,840 end of this print the cursor is being 5052 03:12:05,640 --> 03:12:09,960 moved again to the next line well we 5053 03:12:07,840 --> 03:12:12,439 need to just override that so let me go 5054 03:12:09,960 --> 03:12:15,479 into my code here and let me change this 5055 03:12:12,439 --> 03:12:18,479 to comma n equals quote unquote so that 5056 03:12:15,479 --> 03:12:21,640 it's no longer the default back sln it's 5057 03:12:18,479 --> 03:12:23,840 instead now going to be uh nothing 5058 03:12:21,640 --> 03:12:27,040 whatsoever that should eliminate then 5059 03:12:23,840 --> 03:12:28,680 hopefully that additional uh blank line 5060 03:12:27,040 --> 03:12:31,439 so let me run this one last time here 5061 03:12:28,680 --> 03:12:34,520 python of caty enter and there we have 5062 03:12:31,439 --> 03:12:36,399 it so now you know at least as 5063 03:12:34,520 --> 03:12:39,000 programming goes it's kind of cool that 5064 03:12:36,399 --> 03:12:40,840 I can distill this into a short line and 5065 03:12:39,000 --> 03:12:42,920 express myself all at once now to be 5066 03:12:40,840 --> 03:12:44,840 fair it's a little less readable like 5067 03:12:42,920 --> 03:12:46,800 now I've got back sln I've got time 5068 03:12:44,840 --> 03:12:48,920 three I've got n equals quote unquote so 5069 03:12:46,800 --> 03:12:50,600 you don't have to do things this way my 5070 03:12:48,920 --> 03:12:52,680 previous approach with a for Loop 5071 03:12:50,600 --> 03:12:54,760 totally fine my previous approach with a 5072 03:12:52,680 --> 03:12:57,880 while loop totally fine and in some 5073 03:12:54,760 --> 03:12:59,920 sense perfectly welld designed but this 5074 03:12:57,880 --> 03:13:01,920 is just yet another way to do it but 5075 03:12:59,920 --> 03:13:03,560 it's not a good thing if you or your 5076 03:13:01,920 --> 03:13:05,680 teacher your colleague your friend are 5077 03:13:03,560 --> 03:13:07,760 going to struggle to read your own code 5078 03:13:05,680 --> 03:13:11,239 but this is a feature of python that 5079 03:13:07,760 --> 03:13:12,760 some languages do not in fact have all 5080 03:13:11,239 --> 03:13:14,800 right well let me propose that things 5081 03:13:12,760 --> 03:13:17,319 get more interesting still if we're not 5082 03:13:14,800 --> 03:13:19,399 just swing three times only but we're 5083 03:13:17,319 --> 03:13:21,279 meowing some variable number of times 5084 03:13:19,399 --> 03:13:23,560 let's ask the user how many times this 5085 03:13:21,279 --> 03:13:26,680 cat should meow so let me clear the 5086 03:13:23,560 --> 03:13:29,120 screen here and let me figure out well 5087 03:13:26,680 --> 03:13:30,760 how do I get a number from the user the 5088 03:13:29,120 --> 03:13:33,000 catch here is that if I want the user to 5089 03:13:30,760 --> 03:13:35,520 give me a number I'm not doing math per 5090 03:13:33,000 --> 03:13:38,439 se I'm meowing and therefore the user 5091 03:13:35,520 --> 03:13:40,800 has to give me a positive value the user 5092 03:13:38,439 --> 03:13:43,040 has to give me a positive value so how 5093 03:13:40,800 --> 03:13:47,479 can I insist on this well if I just do 5094 03:13:43,040 --> 03:13:51,279 this n equals int of input uh what's n 5095 03:13:47,479 --> 03:13:55,640 question mark well I want to check like 5096 03:13:51,279 --> 03:13:57,960 I could say if n is less than Z like if 5097 03:13:55,640 --> 03:14:02,439 it's negative well I could do this well 5098 03:13:57,960 --> 03:14:04,840 then ask again int input what's n 5099 03:14:02,439 --> 03:14:06,800 question mark okay well what if the user 5100 03:14:04,840 --> 03:14:08,080 still doesn't give me a positive number 5101 03:14:06,800 --> 03:14:09,160 what if they're being really difficult 5102 03:14:08,080 --> 03:14:12,200 they're not paying attention and they 5103 03:14:09,160 --> 03:14:15,200 typed in two negative numbers well if n 5104 03:14:12,200 --> 03:14:17,479 is less than zero well let's do it again 5105 03:14:15,200 --> 03:14:20,160 n equals right this does not end well 5106 03:14:17,479 --> 03:14:21,880 you can't infinitely many times keep 5107 03:14:20,160 --> 03:14:23,520 checking is it negative is it negative 5108 03:14:21,880 --> 03:14:26,439 is it negative right the program would 5109 03:14:23,520 --> 03:14:28,479 never be done written so we can do this 5110 03:14:26,439 --> 03:14:30,840 I think better maybe with a loop so let 5111 03:14:28,479 --> 03:14:33,120 me propose this a very common Paradigm 5112 03:14:30,840 --> 03:14:36,720 in Python when you want to get user 5113 03:14:33,120 --> 03:14:38,520 input that matches a certain expectation 5114 03:14:36,720 --> 03:14:40,399 you have that it's all positive that 5115 03:14:38,520 --> 03:14:44,200 it's all negative or just something like 5116 03:14:40,399 --> 03:14:45,760 that you just immediately say while true 5117 03:14:44,200 --> 03:14:47,040 you deliberately and a little 5118 03:14:45,760 --> 03:14:49,359 dangerously but a very conv 5119 03:14:47,040 --> 03:14:50,640 intentionally induce an infinite Loop 5120 03:14:49,359 --> 03:14:52,520 now what is an infinite loop it's just 5121 03:14:50,640 --> 03:14:53,800 one that goes forever and we've seen how 5122 03:14:52,520 --> 03:14:56,200 that can happen accidentally 5123 03:14:53,800 --> 03:14:58,800 mathematically it's absolutely going to 5124 03:14:56,200 --> 03:15:01,319 happen when you say while true why well 5125 03:14:58,800 --> 03:15:03,359 the answer to the true question is 5126 03:15:01,319 --> 03:15:05,080 always true so this is a way of 5127 03:15:03,359 --> 03:15:06,960 deliberately inducing a loop that by 5128 03:15:05,080 --> 03:15:09,279 default is going to go forever so we're 5129 03:15:06,960 --> 03:15:11,040 going to need a way of breaking out of 5130 03:15:09,279 --> 03:15:13,160 this Loop when we have the number we 5131 03:15:11,040 --> 03:15:15,080 want the convention though inside of 5132 03:15:13,160 --> 03:15:16,600 this otherwise infinite Loop is to ask 5133 03:15:15,080 --> 03:15:17,479 the question you care about like give me 5134 03:15:16,600 --> 03:15:19,279 an in 5135 03:15:17,479 --> 03:15:21,920 by prompting the user for input like 5136 03:15:19,279 --> 03:15:25,279 what's n question mark and then just ask 5137 03:15:21,920 --> 03:15:27,319 your question so if n is less than zero 5138 03:15:25,279 --> 03:15:29,199 then I think we want python to just 5139 03:15:27,319 --> 03:15:31,600 continue to prompt the user again that 5140 03:15:29,199 --> 03:15:33,600 is we want the code to stay in the loop 5141 03:15:31,600 --> 03:15:35,120 recall the input function and hope that 5142 03:15:33,600 --> 03:15:37,000 the user gives us a better answer if 5143 03:15:35,120 --> 03:15:38,680 this time around it's less than zero so 5144 03:15:37,000 --> 03:15:40,960 let's just literally use Python's 5145 03:15:38,680 --> 03:15:44,040 keyword continue which says just that 5146 03:15:40,960 --> 03:15:45,880 continue to stay within this Loop else 5147 03:15:44,040 --> 03:15:47,600 if it's not less than zero let's go 5148 03:15:45,880 --> 03:15:49,199 ahead and just break out of the loop 5149 03:15:47,600 --> 03:15:51,600 altogether using another keyword in 5150 03:15:49,199 --> 03:15:54,080 Python break break will break you out of 5151 03:15:51,600 --> 03:15:56,399 the most recently begun Loop in this 5152 03:15:54,080 --> 03:15:59,199 case if it's not the case that n is less 5153 03:15:56,399 --> 03:16:01,160 than zero so this will work and it will 5154 03:15:59,199 --> 03:16:02,680 allow us to get a value that's zero or 5155 03:16:01,160 --> 03:16:04,640 greater from the user but I think we can 5156 03:16:02,680 --> 03:16:07,000 tighten it up further so it's to not 5157 03:16:04,640 --> 03:16:10,399 bother having an if and an else why 5158 03:16:07,000 --> 03:16:12,800 don't we instead just say if n is 5159 03:16:10,399 --> 03:16:14,239 greater than zero go ahead and break in 5160 03:16:12,800 --> 03:16:15,720 fact it's not that interesting a program 5161 03:16:14,239 --> 03:16:17,399 if we even allow the user to type in 5162 03:16:15,720 --> 03:16:19,720 zero so let's wait and until they give 5163 03:16:17,399 --> 03:16:22,720 us an integer that is greater than zero 5164 03:16:19,720 --> 03:16:26,760 and then break out of this Loop and what 5165 03:16:22,720 --> 03:16:30,600 can I now do down here for I in range of 5166 03:16:26,760 --> 03:16:32,560 whatever that value n is print meow and 5167 03:16:30,600 --> 03:16:34,000 honestly I don't need I here so let me 5168 03:16:32,560 --> 03:16:35,239 come back to that principle before and 5169 03:16:34,000 --> 03:16:37,600 let me just change it to an underscore 5170 03:16:35,239 --> 03:16:40,520 just to be pythonic if you will so 5171 03:16:37,600 --> 03:16:43,399 what's going on lines 1 through four 5172 03:16:40,520 --> 03:16:45,880 deliberately Implement an infinite Loop 5173 03:16:43,399 --> 03:16:48,840 that otherwise by default is going to go 5174 03:16:45,880 --> 03:16:50,880 forever but I'm asking a question inside 5175 03:16:48,840 --> 03:16:53,840 of that loop after getting an INT from 5176 03:16:50,880 --> 03:16:56,920 the user on line two I'm then checking 5177 03:16:53,840 --> 03:16:58,359 is it greater than zero or is it zero is 5178 03:16:56,920 --> 03:17:00,000 it negative none of which makes sense 5179 03:16:58,359 --> 03:17:02,680 for a meowing cat like I want the cat to 5180 03:17:00,000 --> 03:17:05,359 meow at least one time so if it is 5181 03:17:02,680 --> 03:17:07,120 greater than zero break and this break 5182 03:17:05,359 --> 03:17:09,239 statement even though it's indented 5183 03:17:07,120 --> 03:17:12,399 indented twice has the effect of 5184 03:17:09,239 --> 03:17:15,760 breaking out of the most recently begun 5185 03:17:12,399 --> 03:17:18,800 while loop so once the user gives you a 5186 03:17:15,760 --> 03:17:21,600 positive value then we get to line six 5187 03:17:18,800 --> 03:17:23,439 at which point we meow that many times 5188 03:17:21,600 --> 03:17:26,600 because of line six and seven so if I 5189 03:17:23,439 --> 03:17:28,120 run this now python of cat. Pi enter 5190 03:17:26,600 --> 03:17:30,840 well what's n let's start with three 5191 03:17:28,120 --> 03:17:32,160 where we begin meow meow meow well this 5192 03:17:30,840 --> 03:17:33,439 time let me go ahead and increase the 5193 03:17:32,160 --> 03:17:36,080 size of my terminal window just 5194 03:17:33,439 --> 03:17:39,399 temporarily let me run python of cat. 5195 03:17:36,080 --> 03:17:41,920 let me do it 10 times meow 10 times now 5196 03:17:39,399 --> 03:17:43,600 appears on the screen and the takeaways 5197 03:17:41,920 --> 03:17:45,439 here are not just that we can meow 10 5198 03:17:43,600 --> 03:17:47,920 times or do something again and again 5199 03:17:45,439 --> 03:17:49,720 but this is a very common Paradigm in 5200 03:17:47,920 --> 03:17:52,960 Python when you want to do something 5201 03:17:49,720 --> 03:17:55,720 again and again and again but only until 5202 03:17:52,960 --> 03:17:58,640 the user actually gives you a value that 5203 03:17:55,720 --> 03:18:00,080 you care about here and let me propose 5204 03:17:58,640 --> 03:18:01,439 actually now that we practice a little 5205 03:18:00,080 --> 03:18:05,000 more what we've been preaching 5206 03:18:01,439 --> 03:18:06,800 especially when it comes to say 5207 03:18:05,000 --> 03:18:08,800 especially when it comes to say writing 5208 03:18:06,800 --> 03:18:10,520 your own functions you know now that I'm 5209 03:18:08,800 --> 03:18:12,960 doing all this meowing it might be nice 5210 03:18:10,520 --> 03:18:15,199 to actually have a meow function that 5211 03:18:12,960 --> 03:18:16,399 the inventors of python didn't Envision 5212 03:18:15,199 --> 03:18:18,560 so let me do this let me actually get 5213 03:18:16,399 --> 03:18:20,960 rid of this code and let me go ahead and 5214 03:18:18,560 --> 03:18:23,279 do this let me go ahead and say Define a 5215 03:18:20,960 --> 03:18:26,040 main function as I've done before and 5216 03:18:23,279 --> 03:18:28,120 let me just blindly call meow 3 meow 5217 03:18:26,040 --> 03:18:30,640 doesn't exist yet but when it does 5218 03:18:28,120 --> 03:18:33,640 that'll be great so let me go ahead now 5219 03:18:30,640 --> 03:18:36,000 and Define meow so my meow function 5220 03:18:33,640 --> 03:18:38,600 should take as input a parameter called 5221 03:18:36,000 --> 03:18:41,319 n or anything I want and this part's 5222 03:18:38,600 --> 03:18:44,199 pretty easy now how do you meow in times 5223 03:18:41,319 --> 03:18:46,479 well for underscore in the range of n Go 5224 03:18:44,199 --> 03:18:48,439 ahead and just print meow so same code 5225 03:18:46,479 --> 03:18:50,960 AS before nothing new here I'm just 5226 03:18:48,439 --> 03:18:52,680 putting that logic inside of a meow 5227 03:18:50,960 --> 03:18:54,920 function that's going to have this side 5228 03:18:52,680 --> 03:18:56,399 effect of printing meow and now as 5229 03:18:54,920 --> 03:18:58,800 before let me go down here and let me 5230 03:18:56,399 --> 03:19:00,520 make sure I call Main and if I now run 5231 03:18:58,800 --> 03:19:03,479 this code python of 5232 03:19:00,520 --> 03:19:05,880 cat. meow meow meow it's always going to 5233 03:19:03,479 --> 03:19:07,520 do three because I've hardcoded the 5234 03:19:05,880 --> 03:19:10,840 three well let's make one Improvement 5235 03:19:07,520 --> 03:19:13,520 here let me go ahead now and maybe do 5236 03:19:10,840 --> 03:19:15,960 this uh let me ask the user for a number 5237 03:19:13,520 --> 03:19:18,439 so let's say something like this number 5238 03:19:15,960 --> 03:19:20,080 equals get number all right 5239 03:19:18,439 --> 03:19:21,960 unfortunately there is no function in 5240 03:19:20,080 --> 03:19:23,560 Python called get number that gets a 5241 03:19:21,960 --> 03:19:27,120 positive number from the user but I can 5242 03:19:23,560 --> 03:19:29,199 invent that so Define get number open 5243 03:19:27,120 --> 03:19:31,960 paren close per n and then inside of 5244 03:19:29,199 --> 03:19:34,399 this function let me do this while true 5245 03:19:31,960 --> 03:19:36,239 go ahead and get a number from the user 5246 03:19:34,399 --> 03:19:39,560 converting it to an INT asking them 5247 03:19:36,239 --> 03:19:42,120 what's n question mark and then if n is 5248 03:19:39,560 --> 03:19:44,560 what I want it's a greater than zero 5249 03:19:42,120 --> 03:19:47,960 value a positive number I don't want to 5250 03:19:44,560 --> 03:19:50,319 break this time necessarily 5251 03:19:47,960 --> 03:19:52,760 although I could I instead want to 5252 03:19:50,319 --> 03:19:55,080 return the value so I can actually do 5253 03:19:52,760 --> 03:19:57,520 this instead and this two is a feature 5254 03:19:55,080 --> 03:20:00,160 of python this ability not to just break 5255 03:19:57,520 --> 03:20:02,840 out of a block of code but also to 5256 03:20:00,160 --> 03:20:05,000 return a value in code to actually 5257 03:20:02,840 --> 03:20:08,279 return a value gives you the ability 5258 03:20:05,000 --> 03:20:10,040 ultimately to return explicitly a value 5259 03:20:08,279 --> 03:20:12,960 so that your function has not just a 5260 03:20:10,040 --> 03:20:15,040 side effect necessarily but it actually 5261 03:20:12,960 --> 03:20:17,120 hands back just like input does just 5262 03:20:15,040 --> 03:20:20,399 like int does just like float does an 5263 03:20:17,120 --> 03:20:22,279 actual value to the user now to be clear 5264 03:20:20,399 --> 03:20:24,279 I don't have to return n here I can 5265 03:20:22,279 --> 03:20:27,040 still break out of the loop as I've done 5266 03:20:24,279 --> 03:20:30,239 in the past with code like this but then 5267 03:20:27,040 --> 03:20:31,920 after the loop I still have to return n 5268 03:20:30,239 --> 03:20:34,439 and so what's happening here is that if 5269 03:20:31,920 --> 03:20:36,359 you use break to get out of the loop but 5270 03:20:34,439 --> 03:20:38,239 you need to hand back a value from a 5271 03:20:36,359 --> 03:20:40,720 function you still have to use the 5272 03:20:38,239 --> 03:20:43,319 return keyword now explicitly either in 5273 03:20:40,720 --> 03:20:47,520 the loop as I did or now outside of the 5274 03:20:43,319 --> 03:20:49,000 loop but still inside of the function 5275 03:20:47,520 --> 03:20:51,160 the last thing I'm going to do here now 5276 03:20:49,000 --> 03:20:53,160 is change that three which we hardcoded 5277 03:20:51,160 --> 03:20:54,920 earlier to actually be the value of the 5278 03:20:53,160 --> 03:20:57,080 variable we've gotten from the user so 5279 03:20:54,920 --> 03:21:00,319 that now down here if I run python of 5280 03:20:57,080 --> 03:21:02,680 cat. py enter what's N I can type in 5281 03:21:00,319 --> 03:21:06,560 three I get my three meows or if I only 5282 03:21:02,680 --> 03:21:08,319 want one I now get one meow instead all 5283 03:21:06,560 --> 03:21:11,560 right so if we now have this ability to 5284 03:21:08,319 --> 03:21:13,640 do things again and again in these Loops 5285 03:21:11,560 --> 03:21:16,040 let's see if we can't solve some other 5286 03:21:13,640 --> 03:21:18,199 problems via which to express ourselves 5287 03:21:16,040 --> 03:21:20,680 cyclically but get back some interesting 5288 03:21:18,199 --> 03:21:22,600 answers as well let me propose for 5289 03:21:20,680 --> 03:21:24,279 instance that we look a little more 5290 03:21:22,600 --> 03:21:25,760 closely at these lists it turns out that 5291 03:21:24,279 --> 03:21:27,960 in Python and really in programs in 5292 03:21:25,760 --> 03:21:29,439 general it's useful to have a list of 5293 03:21:27,960 --> 03:21:32,120 values because we're going to be able to 5294 03:21:29,439 --> 03:21:34,399 work with more and more data larger and 5295 03:21:32,120 --> 03:21:36,000 larger data sets so let me propose that 5296 03:21:34,399 --> 03:21:37,239 we come back to vs code here and let's 5297 03:21:36,000 --> 03:21:39,520 do something that's perhaps a little 5298 03:21:37,239 --> 03:21:41,399 familiar to some folks um the world of 5299 03:21:39,520 --> 03:21:44,160 Hogwarts and let me go ahead and code up 5300 03:21:41,399 --> 03:21:46,040 a file called Hogwarts and let's see if 5301 03:21:44,160 --> 03:21:48,160 we can't have a list of students at 5302 03:21:46,040 --> 03:21:51,199 Hogwarts here so I have a new tab called 5303 03:21:48,160 --> 03:21:53,520 hogw Works sty and let me go ahead and 5304 03:21:51,199 --> 03:21:55,319 propose that I just Define in this 5305 03:21:53,520 --> 03:21:56,520 program a list of students whose names I 5306 03:21:55,319 --> 03:21:58,880 know in advance so I'm not going to get 5307 03:21:56,520 --> 03:22:00,439 user input for now I'm just going to 5308 03:21:58,880 --> 03:22:02,560 know from the GetGo that the three 5309 03:22:00,439 --> 03:22:04,319 students I want to consider are these a 5310 03:22:02,560 --> 03:22:06,279 variable is going to be called students 5311 03:22:04,319 --> 03:22:08,319 it's going to equal as I've done in the 5312 03:22:06,279 --> 03:22:10,640 past a square bracket which means hey 5313 03:22:08,319 --> 03:22:12,560 here comes a list and those values are 5314 03:22:10,640 --> 03:22:15,239 going to be Hermione in quotes because 5315 03:22:12,560 --> 03:22:17,279 it's a string uh Harry in quotes cuz 5316 03:22:15,239 --> 03:22:19,080 it's a string and then WR in quotes 5317 03:22:17,279 --> 03:22:21,840 because it's a string as well so this is 5318 03:22:19,080 --> 03:22:23,319 a list of length three it's similar in 5319 03:22:21,840 --> 03:22:26,640 spirit to my list of length three 5320 03:22:23,319 --> 03:22:29,479 earlier but that had three ins 012 now I 5321 03:22:26,640 --> 03:22:32,199 have a list of three strings instead and 5322 03:22:29,479 --> 03:22:34,239 this isn't very useful at the moment but 5323 03:22:32,199 --> 03:22:37,160 let me just do something as a check for 5324 03:22:34,239 --> 03:22:39,920 myself let me print out each of these 5325 03:22:37,160 --> 03:22:43,880 students well wait a minute how do I 5326 03:22:39,920 --> 03:22:46,160 print the contents of a list well in the 5327 03:22:43,880 --> 03:22:47,439 past when we've printed a variable we've 5328 03:22:46,160 --> 03:22:49,199 just printed out the name of the 5329 03:22:47,439 --> 03:22:51,720 variable but I don't want to print out 5330 03:22:49,199 --> 03:22:53,880 all of Hermione and Harry and Ron all at 5331 03:22:51,720 --> 03:22:57,160 once maybe I want to print out Hermione 5332 03:22:53,880 --> 03:22:59,319 first then Harry then Ron so I need a 5333 03:22:57,160 --> 03:23:01,279 way to express more precisely which 5334 03:22:59,319 --> 03:23:04,040 value do I want from this list and the 5335 03:23:01,279 --> 03:23:06,279 way you do this in Python is you use 5336 03:23:04,040 --> 03:23:08,359 square brackets in another way if you 5337 03:23:06,279 --> 03:23:10,800 have a variable in this case called 5338 03:23:08,359 --> 03:23:13,080 students and you want to go inside of 5339 03:23:10,800 --> 03:23:15,479 that variable and get a specific value 5340 03:23:13,080 --> 03:23:17,640 that is to say you want to index into 5341 03:23:15,479 --> 03:23:20,160 the list you use square brackets this 5342 03:23:17,640 --> 03:23:22,720 way using numbers inside of the square 5343 03:23:20,160 --> 03:23:25,279 brackets and here's where we see that it 5344 03:23:22,720 --> 03:23:27,920 is useful to think and count in terms of 5345 03:23:25,279 --> 03:23:30,680 zero on up instead of one on up these 5346 03:23:27,920 --> 03:23:34,040 lists in Python are shall we say zero 5347 03:23:30,680 --> 03:23:36,359 indexed the first item in a list is at 5348 03:23:34,040 --> 03:23:38,279 location zero the second item in a 5349 03:23:36,359 --> 03:23:40,239 python list is at location one and the 5350 03:23:38,279 --> 03:23:42,479 third is at location two so you're 5351 03:23:40,239 --> 03:23:43,600 always kind of off by one mentally but 5352 03:23:42,479 --> 03:23:45,920 you get used to it if you've never 5353 03:23:43,600 --> 03:23:47,560 programmed before over time so let me 5354 03:23:45,920 --> 03:23:49,560 print out all three students so let me 5355 03:23:47,560 --> 03:23:51,600 print out students bracket zero then 5356 03:23:49,560 --> 03:23:54,160 students bracket one then lastly let me 5357 03:23:51,600 --> 03:23:56,199 print students bracket 2 and this is my 5358 03:23:54,160 --> 03:23:57,760 third and final line and of course if I 5359 03:23:56,199 --> 03:23:59,720 run this code it probably does what you 5360 03:23:57,760 --> 03:24:03,239 would guess if I run python of Hogwarts 5361 03:23:59,720 --> 03:24:05,359 stpy there's Hermione Harry and Rob each 5362 03:24:03,239 --> 03:24:07,040 on their own lines there but there's got 5363 03:24:05,359 --> 03:24:08,399 to be a better way right especially if I 5364 03:24:07,040 --> 03:24:09,960 don't know in advance who's going to be 5365 03:24:08,399 --> 03:24:12,080 in this list if next year there's some 5366 03:24:09,960 --> 03:24:14,199 new students at Hogwarts we can use a 5367 03:24:12,080 --> 03:24:16,560 loop to do something automatically 5368 03:24:14,199 --> 03:24:18,800 without having to manually type out zero 5369 03:24:16,560 --> 03:24:21,720 and then one and two well here's another 5370 03:24:18,800 --> 03:24:24,600 feature of python you can use a for Loop 5371 03:24:21,720 --> 03:24:26,520 not just to count from zero to 1 to two 5372 03:24:24,600 --> 03:24:28,880 you can use Python to just iterate over 5373 03:24:26,520 --> 03:24:33,120 anything not just numbers but strings so 5374 03:24:28,880 --> 03:24:35,680 I could actually do this for student in 5375 03:24:33,120 --> 03:24:38,560 students colon and then indented 5376 03:24:35,680 --> 03:24:40,640 underneath that I can say print student 5377 03:24:38,560 --> 03:24:43,960 now it doesn't matter if I have three 5378 03:24:40,640 --> 03:24:46,080 students or four or 400 this two lines 5379 03:24:43,960 --> 03:24:48,040 of code this Loop will print all of 5380 03:24:46,080 --> 03:24:50,720 those students for me one at a time so 5381 03:24:48,040 --> 03:24:52,680 if I now run python of Hogwarts there's 5382 03:24:50,720 --> 03:24:55,760 the same list but I don't need to know 5383 03:24:52,680 --> 03:24:57,720 in advance how long that actual list is 5384 03:24:55,760 --> 03:25:00,800 now notice I made a conscious decision 5385 03:24:57,720 --> 03:25:03,399 here I didn't call this variable 5386 03:25:00,800 --> 03:25:06,239 underscore because this time I'm using 5387 03:25:03,399 --> 03:25:08,520 the variable and while I could do this 5388 03:25:06,239 --> 03:25:10,279 now no no no no your code is getting way 5389 03:25:08,520 --> 03:25:12,600 too cryptic if you're naming the 5390 03:25:10,279 --> 03:25:14,160 variable underscore and you're using the 5391 03:25:12,600 --> 03:25:16,359 variable underscore now you're helping 5392 03:25:14,160 --> 03:25:18,640 no one now you're confusing the reader 5393 03:25:16,359 --> 03:25:21,000 yourself in the down the line you should 5394 03:25:18,640 --> 03:25:22,560 call your variables what they are so an 5395 03:25:21,000 --> 03:25:24,279 very appropriate name though I'm sure 5396 03:25:22,560 --> 03:25:26,319 you could come up with others would be 5397 03:25:24,279 --> 03:25:28,520 student and here you could say you would 5398 03:25:26,319 --> 03:25:30,800 say student as well if you'd prefer to 5399 03:25:28,520 --> 03:25:32,399 be more succinct it's not unreasonable 5400 03:25:30,800 --> 03:25:35,160 to do something succinct in a loop like 5401 03:25:32,399 --> 03:25:37,439 this for s in students using maybe the 5402 03:25:35,160 --> 03:25:39,439 same letter that the list itself begins 5403 03:25:37,439 --> 03:25:41,359 with but again why bother python is 5404 03:25:39,439 --> 03:25:43,800 meant to be more readable if you have a 5405 03:25:41,359 --> 03:25:46,399 list of students iterate over them one 5406 03:25:43,800 --> 03:25:48,760 student at a time let me pause here to 5407 03:25:46,399 --> 03:25:50,199 see if there's now questions about lists 5408 03:25:48,760 --> 03:25:52,640 as I've now defined them a list of 5409 03:25:50,199 --> 03:25:55,640 strings in this case or using a for Loop 5410 03:25:52,640 --> 03:25:59,040 now to iterate over and print each of 5411 03:25:55,640 --> 03:26:01,080 those names yeah uh so is it not 5412 03:25:59,040 --> 03:26:03,239 necessary to initiate student in this 5413 03:26:01,080 --> 03:26:05,160 case or we can just declare a variable 5414 03:26:03,239 --> 03:26:07,000 in the loop good question you do not 5415 03:26:05,160 --> 03:26:09,120 need to manually initialize it python 5416 03:26:07,000 --> 03:26:12,160 takes care of initializing the student 5417 03:26:09,120 --> 03:26:14,040 variable to Hermione first then Harry 5418 03:26:12,160 --> 03:26:15,560 second then Ron third unlike other 5419 03:26:14,040 --> 03:26:17,319 languages you don't need to initialize 5420 03:26:15,560 --> 03:26:19,520 it to something yourself it just exists 5421 03:26:17,319 --> 03:26:22,520 and it will work other questions on 5422 03:26:19,520 --> 03:26:24,840 loops and lists in this way since you 5423 03:26:22,520 --> 03:26:26,600 describe break so is there any concept 5424 03:26:24,840 --> 03:26:28,479 of continue so that we can skip a 5425 03:26:26,600 --> 03:26:30,359 particular case in Loops yes you can 5426 03:26:28,479 --> 03:26:31,920 continue using another syntax as well we 5427 03:26:30,359 --> 03:26:35,800 haven't shown that for now we focused 5428 03:26:31,920 --> 03:26:38,160 only on break H okay sure uh can can 5429 03:26:35,800 --> 03:26:40,160 this follow work with either hash tables 5430 03:26:38,160 --> 03:26:42,239 or different kind of fight tables or 5431 03:26:40,160 --> 03:26:43,800 arrays uh indeed so we're getting ahead 5432 03:26:42,239 --> 03:26:46,479 of ourselves there but there are yet 5433 03:26:43,800 --> 03:26:48,800 other types of data in Python and indeed 5434 03:26:46,479 --> 03:26:51,160 you can use a for Loop to iterate over 5435 03:26:48,800 --> 03:26:53,760 those as well anything that is iterable 5436 03:26:51,160 --> 03:26:55,600 so to speak is a piece of data that can 5437 03:26:53,760 --> 03:26:58,040 be used with a loop like this but more 5438 03:26:55,600 --> 03:27:00,359 on those more on those soon in fact let 5439 03:26:58,040 --> 03:27:02,359 me transition here to show just another 5440 03:27:00,359 --> 03:27:03,880 way of solving the same problem because 5441 03:27:02,359 --> 03:27:05,760 up until now when we've used Loops we 5442 03:27:03,880 --> 03:27:07,960 really have relied on numbers and that's 5443 03:27:05,760 --> 03:27:10,680 fine if you prefer to sort of stay in 5444 03:27:07,960 --> 03:27:13,680 that space suppose I did want to iterate 5445 03:27:10,680 --> 03:27:15,199 using numbers like I and 0 1 2 and so 5446 03:27:13,680 --> 03:27:17,479 forth let me propose that we could 5447 03:27:15,199 --> 03:27:19,760 change this code AS follows if you would 5448 03:27:17,479 --> 03:27:21,640 prefer to think about or if the program 5449 03:27:19,760 --> 03:27:23,560 you're trying to implement requires that 5450 03:27:21,640 --> 03:27:26,920 you use numbers like this you might do 5451 03:27:23,560 --> 03:27:29,680 this for I in well I don't want to just 5452 03:27:26,920 --> 03:27:32,800 say students because then I is not going 5453 03:27:29,680 --> 03:27:36,520 to be a number I is going to be 5454 03:27:32,800 --> 03:27:40,040 literally Hermione then Harry then Rob I 5455 03:27:36,520 --> 03:27:41,560 need to iterate from zero to one to two 5456 03:27:40,040 --> 03:27:44,760 right if I know a list with three 5457 03:27:41,560 --> 03:27:46,520 elements has these locations 0 1 2 I 5458 03:27:44,760 --> 03:27:48,800 need to create a loop somehow that 5459 03:27:46,520 --> 03:27:50,319 starts at zero and ends at two 5460 03:27:48,800 --> 03:27:52,880 previously when I wanted to do that I 5461 03:27:50,319 --> 03:27:55,239 needed range but this two is not going 5462 03:27:52,880 --> 03:27:57,680 to work I can't just say in the range of 5463 03:27:55,239 --> 03:27:59,840 students because students is not a 5464 03:27:57,680 --> 03:28:01,800 number it's not an integer so you can't 5465 03:27:59,840 --> 03:28:05,319 pass it to range range expects an 5466 03:28:01,800 --> 03:28:07,720 integer but there is a solution here it 5467 03:28:05,319 --> 03:28:11,040 turns out that there is a function in 5468 03:28:07,720 --> 03:28:13,439 Python called length or Len Len that 5469 03:28:11,040 --> 03:28:16,160 will tell you the length of a list and 5470 03:28:13,439 --> 03:28:17,760 other things down the line too and now I 5471 03:28:16,160 --> 03:28:19,720 think I can assemble these building 5472 03:28:17,760 --> 03:28:22,880 blocks in a way that can allow me to use 5473 03:28:19,720 --> 03:28:26,080 numbers in this way so range doesn't 5474 03:28:22,880 --> 03:28:27,399 take a list of strings it takes a number 5475 03:28:26,080 --> 03:28:30,000 and ideally that number is going to be 5476 03:28:27,399 --> 03:28:32,640 three so I get a range of values 0o 1 5477 03:28:30,000 --> 03:28:35,199 and two so I think I can Nest my 5478 03:28:32,640 --> 03:28:37,680 functions like this if I first get the 5479 03:28:35,199 --> 03:28:40,399 length of the student list that's going 5480 03:28:37,680 --> 03:28:43,279 to be three then I pass that return 5481 03:28:40,399 --> 03:28:45,120 value as the argument to range that's 5482 03:28:43,279 --> 03:28:47,560 going to give me back a range of value 5483 03:28:45,120 --> 03:28:49,160 zero then one than two and what that's 5484 03:28:47,560 --> 03:28:53,479 going to allow me to do then in code if 5485 03:28:49,160 --> 03:28:56,920 I want is not just this I could do print 5486 03:28:53,479 --> 03:28:59,479 now students bracket I and this is now 5487 03:28:56,920 --> 03:29:01,640 where the syntax we're seeing is getting 5488 03:28:59,479 --> 03:29:04,479 very expressive new and perhaps 5489 03:29:01,640 --> 03:29:07,279 unfamiliar but if I can do Open Bracket 5490 03:29:04,479 --> 03:29:09,520 zero close bracket or Open Bracket one 5491 03:29:07,279 --> 03:29:12,000 close bracket or Open Bracket 2 close 5492 03:29:09,520 --> 03:29:14,160 bracket turns out I can actually put a 5493 03:29:12,000 --> 03:29:15,840 variable in there and I can express any 5494 03:29:14,160 --> 03:29:17,520 number inside of those brackets so it's 5495 03:29:15,840 --> 03:29:20,359 to print these all out dynamically in a 5496 03:29:17,520 --> 03:29:23,760 loop let me do this python of Hogwarts 5497 03:29:20,359 --> 03:29:25,520 enter there's Hermione Harry and Ron and 5498 03:29:23,760 --> 03:29:27,279 now if I'm just curious I I just want to 5499 03:29:25,520 --> 03:29:29,120 poke around or maybe I want to do a 5500 03:29:27,279 --> 03:29:31,640 ranking like who are the top three 5501 03:29:29,120 --> 03:29:33,279 students in the school or in Gryffindor 5502 03:29:31,640 --> 03:29:35,640 well I can print multiple things at a 5503 03:29:33,279 --> 03:29:38,680 time we've seen let me print out not 5504 03:29:35,640 --> 03:29:41,199 just the students at location I but 5505 03:29:38,680 --> 03:29:43,479 rather let's print I first and then the 5506 03:29:41,199 --> 03:29:45,279 student at location I so two things to 5507 03:29:43,479 --> 03:29:46,840 print and we know that print can take 5508 03:29:45,279 --> 03:29:48,800 two arguments we've seen that before 5509 03:29:46,840 --> 03:29:51,359 they'll be separated by a space let me 5510 03:29:48,800 --> 03:29:53,080 go ahead and rerun this now I see that 5511 03:29:51,359 --> 03:29:55,359 okay hermion is the top student but 5512 03:29:53,080 --> 03:29:57,399 she's in zero place that's a little 5513 03:29:55,359 --> 03:29:59,680 weird like we don't need to show the 5514 03:29:57,399 --> 03:30:01,880 human using my program that we started 5515 03:29:59,680 --> 03:30:04,399 counting at zero I can clean this up I 5516 03:30:01,880 --> 03:30:06,239 can just add one to the eye up here and 5517 03:30:04,399 --> 03:30:08,399 now we see sort of a top three list of 5518 03:30:06,239 --> 03:30:10,399 students hermion is number one Harry's 5519 03:30:08,399 --> 03:30:12,359 number two and of course Ron is number 5520 03:30:10,399 --> 03:30:14,800 three so we can get access to all of 5521 03:30:12,359 --> 03:30:17,399 those same values as well all any 5522 03:30:14,800 --> 03:30:20,600 questions now on on these 5523 03:30:17,399 --> 03:30:23,439 lists any questions now on these 5524 03:30:20,600 --> 03:30:27,160 lists this length these ranges or 5525 03:30:23,439 --> 03:30:31,560 otherwise my question is uh for I in 5526 03:30:27,160 --> 03:30:32,840 range can you explain this once more uh 5527 03:30:31,560 --> 03:30:36,040 sure 5528 03:30:32,840 --> 03:30:39,680 still so let me rewind in time we 5529 03:30:36,040 --> 03:30:42,800 started off doing this for I in 5530 03:30:39,680 --> 03:30:45,319 012 and then we print it out meow three 5531 03:30:42,800 --> 03:30:47,640 times in that way the way that the for 5532 03:30:45,319 --> 03:30:49,520 Loop works is that it creates for you a 5533 03:30:47,640 --> 03:30:52,120 variable that I've called I but I could 5534 03:30:49,520 --> 03:30:53,880 call it anything I want it then assigns 5535 03:30:52,120 --> 03:30:56,680 I initially to the first thing in the 5536 03:30:53,880 --> 03:30:58,520 list it then automatically assigns I to 5537 03:30:56,680 --> 03:31:00,439 the next thing in the list and then it 5538 03:30:58,520 --> 03:31:02,199 assigns I to the third thing in the list 5539 03:31:00,439 --> 03:31:03,880 and each time it does all of the 5540 03:31:02,199 --> 03:31:06,479 indented code 5541 03:31:03,880 --> 03:31:07,960 underneath we realize though that this 5542 03:31:06,479 --> 03:31:10,040 is not going to scale well if I want to 5543 03:31:07,960 --> 03:31:12,640 do something like a million times so we 5544 03:31:10,040 --> 03:31:14,880 introduced range instead that has the 5545 03:31:12,640 --> 03:31:17,040 effect of doing the same thing it 5546 03:31:14,880 --> 03:31:19,120 returns to me a Range of values a list 5547 03:31:17,040 --> 03:31:21,640 of three things really so the behavior 5548 03:31:19,120 --> 03:31:23,760 is exactly the same if we now fast 5549 03:31:21,640 --> 03:31:26,080 forward to this Hogwarts example now 5550 03:31:23,760 --> 03:31:28,720 though what I'm doing is just combining 5551 03:31:26,080 --> 03:31:30,760 these smaller ideas I'm still creating a 5552 03:31:28,720 --> 03:31:33,319 for Loop I'm still creating a variable 5553 03:31:30,760 --> 03:31:35,720 called I I want to do it over a range of 5554 03:31:33,319 --> 03:31:37,920 values but how many values well if I use 5555 03:31:35,720 --> 03:31:40,160 the length function and pass to the 5556 03:31:37,920 --> 03:31:42,239 length function the list of values 5557 03:31:40,160 --> 03:31:44,880 lengths purpose in life is to tell me 5558 03:31:42,239 --> 03:31:47,439 how long is this list and it's three so 5559 03:31:44,880 --> 03:31:49,160 that's almost as though before I had 5560 03:31:47,439 --> 03:31:51,319 just done something like this but I 5561 03:31:49,160 --> 03:31:53,160 don't want to hard code three I want to 5562 03:31:51,319 --> 03:31:55,279 dynamically figure out how many students 5563 03:31:53,160 --> 03:31:57,439 are at Hogwarts so I'm just composing 5564 03:31:55,279 --> 03:32:00,239 composing composing or nesting all of 5565 03:31:57,439 --> 03:32:02,880 these various ideas all right if I may 5566 03:32:00,239 --> 03:32:05,199 let me transition now to hog in Hogwarts 5567 03:32:02,880 --> 03:32:06,960 still to introduce one final type of 5568 03:32:05,199 --> 03:32:09,720 data before we combine everything with a 5569 03:32:06,960 --> 03:32:12,600 few final programs it turns out in 5570 03:32:09,720 --> 03:32:14,840 Python there's not just strings not just 5571 03:32:12,600 --> 03:32:17,000 ins not just floating Point values not 5572 03:32:14,840 --> 03:32:19,120 just bulls not just list there are also 5573 03:32:17,000 --> 03:32:21,600 what are called dictionaries or dicts 5574 03:32:19,120 --> 03:32:25,520 which are a data structure that allows 5575 03:32:21,600 --> 03:32:27,279 you to associate one value with another 5576 03:32:25,520 --> 03:32:28,560 literally a dictionary like in the human 5577 03:32:27,279 --> 03:32:30,160 world if you were to open an a 5578 03:32:28,560 --> 03:32:31,600 dictionary be it in English or any other 5579 03:32:30,160 --> 03:32:34,439 human language what's inside of a 5580 03:32:31,600 --> 03:32:36,800 dictionary well it's a bunch of words 5581 03:32:34,439 --> 03:32:38,640 and definitions a computer scientist 5582 03:32:36,800 --> 03:32:41,040 though and a programmer would describe 5583 03:32:38,640 --> 03:32:43,760 those more generically as keys and 5584 03:32:41,040 --> 03:32:46,000 values something associated with 5585 03:32:43,760 --> 03:32:48,239 something else that's all a dictionary 5586 03:32:46,000 --> 03:32:49,760 is it allows you to associate something 5587 03:32:48,239 --> 03:32:51,560 with something else and notice this is 5588 03:32:49,760 --> 03:32:54,560 already more powerful more interesting 5589 03:32:51,560 --> 03:32:57,640 than a list a list is just a set of 5590 03:32:54,560 --> 03:32:59,800 multiple values but a dictionary is sort 5591 03:32:57,640 --> 03:33:02,319 of two-dimensional if you will just like 5592 03:32:59,800 --> 03:33:04,120 a human dictionary a book it Associates 5593 03:33:02,319 --> 03:33:06,120 something with something else like words 5594 03:33:04,120 --> 03:33:07,960 with their definitions now what does 5595 03:33:06,120 --> 03:33:11,920 this actually mean in practice well 5596 03:33:07,960 --> 03:33:15,840 suppose that we wanted to keep track of 5597 03:33:11,920 --> 03:33:17,800 who is in what house at Hogwarts well I 5598 03:33:15,840 --> 03:33:19,560 could do it using lists alone let me go 5599 03:33:17,800 --> 03:33:21,600 back to vs code here and let me just 5600 03:33:19,560 --> 03:33:23,040 temporarily but in a way that I'm not 5601 03:33:21,600 --> 03:33:25,319 going to like ultimately let me create 5602 03:33:23,040 --> 03:33:28,479 another variable called houses set it 5603 03:33:25,319 --> 03:33:31,239 equal to uh Gryffindor corresponding to 5604 03:33:28,479 --> 03:33:33,120 herm's house uh Gryffindor corresponding 5605 03:33:31,239 --> 03:33:34,920 to Harry's house and Gryffindor 5606 03:33:33,120 --> 03:33:36,680 corresponding to Ron's house and let's 5607 03:33:34,920 --> 03:33:38,120 add Draco in there so we now have four 5608 03:33:36,680 --> 03:33:41,199 instead of three students just so we 5609 03:33:38,120 --> 03:33:45,000 have a little variety and he was in uh 5610 03:33:41,199 --> 03:33:48,040 Slytherin so now we have two lists and 5611 03:33:45,000 --> 03:33:50,479 we could just agree amongst ourselves 5612 03:33:48,040 --> 03:33:53,960 that whoever is first in the students 5613 03:33:50,479 --> 03:33:56,680 variable lives in the first uh value in 5614 03:33:53,960 --> 03:33:58,720 houses whoever is second in students 5615 03:33:56,680 --> 03:34:01,080 lives in the second house whoever third 5616 03:33:58,720 --> 03:34:02,960 in students lives in the third house we 5617 03:34:01,080 --> 03:34:05,359 could do that but honestly that is going 5618 03:34:02,960 --> 03:34:07,319 to break down quickly when we have a lot 5619 03:34:05,359 --> 03:34:08,720 of students when we have a lot of houses 5620 03:34:07,319 --> 03:34:10,319 and what if we want to keep track of 5621 03:34:08,720 --> 03:34:12,239 more things than that what if we want to 5622 03:34:10,319 --> 03:34:14,560 keep track of every student's house and 5623 03:34:12,239 --> 03:34:16,239 the Patronis this uh this image that 5624 03:34:14,560 --> 03:34:18,199 they conjure up magically 5625 03:34:16,239 --> 03:34:20,000 well then we need a third list like this 5626 03:34:18,199 --> 03:34:22,080 is just going to get messy quickly if 5627 03:34:20,000 --> 03:34:25,199 we're just on the honor System using 5628 03:34:22,080 --> 03:34:27,560 multiple lists where everything lines up 5629 03:34:25,199 --> 03:34:29,560 logically it doesn't end up well when 5630 03:34:27,560 --> 03:34:31,439 your code gets more complicated but I do 5631 03:34:29,560 --> 03:34:33,439 want to implement this idea I want to 5632 03:34:31,439 --> 03:34:35,199 associate something with something a 5633 03:34:33,439 --> 03:34:36,560 student with a house a student with a 5634 03:34:35,199 --> 03:34:39,120 house a student with a house and so 5635 03:34:36,560 --> 03:34:41,640 forth so how can I go about doing this 5636 03:34:39,120 --> 03:34:44,279 well let me go back to my code here and 5637 03:34:41,640 --> 03:34:46,479 let me propose that we do this using a 5638 03:34:44,279 --> 03:34:49,000 python dictionary and this is the last 5639 03:34:46,479 --> 03:34:50,880 of the new syntax really that we'll see 5640 03:34:49,000 --> 03:34:53,279 here's the new syntax instead of using 5641 03:34:50,880 --> 03:34:56,000 square brackets we're going to use curly 5642 03:34:53,279 --> 03:34:58,199 braces for dictionaries as well we've 5643 03:34:56,000 --> 03:35:00,800 seen curly braces in the context of f 5644 03:34:58,199 --> 03:35:02,319 strings completely unrelated sometimes 5645 03:35:00,800 --> 03:35:04,120 you run out of keys on the keyboard and 5646 03:35:02,319 --> 03:35:06,520 the authors of a language need to start 5647 03:35:04,120 --> 03:35:08,199 reusing symbols in different ways that's 5648 03:35:06,520 --> 03:35:10,199 what's about to happen we're using curly 5649 03:35:08,199 --> 03:35:12,239 braces in a different way now so let me 5650 03:35:10,199 --> 03:35:15,160 create a variable called students and 5651 03:35:12,239 --> 03:35:17,479 let me go ahead and set it equal to open 5652 03:35:15,160 --> 03:35:20,439 curly brace and Clos curly brace this is 5653 03:35:17,479 --> 03:35:22,120 an empty dictionary at the moment and 5654 03:35:20,439 --> 03:35:23,520 here's how a dictionary works it allows 5655 03:35:22,120 --> 03:35:25,720 you to associate something with 5656 03:35:23,520 --> 03:35:27,640 something else and you do that like this 5657 03:35:25,720 --> 03:35:31,199 Hermione quote 5658 03:35:27,640 --> 03:35:32,239 unquote colon and then the value thereof 5659 03:35:31,199 --> 03:35:35,199 what do you want to associate with 5660 03:35:32,239 --> 03:35:37,520 Hermione well Gryffindor what do I want 5661 03:35:35,199 --> 03:35:40,199 to associate Harry with well I want to 5662 03:35:37,520 --> 03:35:42,160 associate him with Gryffindor what do I 5663 03:35:40,199 --> 03:35:44,840 want to associate Ron with well I want 5664 03:35:42,160 --> 03:35:46,520 to associate him with Gryffindor well 5665 03:35:44,840 --> 03:35:48,120 this is actually not going to this is 5666 03:35:46,520 --> 03:35:50,120 going to get very ugly quickly once we 5667 03:35:48,120 --> 03:35:51,239 add in Draco and Slytherin my code is 5668 03:35:50,120 --> 03:35:52,960 going to get too long it's going to 5669 03:35:51,239 --> 03:35:55,399 start wrapping so this is purely 5670 03:35:52,960 --> 03:35:57,239 aesthetic it is perfectly acceptable in 5671 03:35:55,399 --> 03:35:58,840 Python and other languages to format 5672 03:35:57,239 --> 03:36:00,560 your code a little more readily and just 5673 03:35:58,840 --> 03:36:02,680 add new lines if it makes it more 5674 03:36:00,560 --> 03:36:04,720 readable and one way of doing this might 5675 03:36:02,680 --> 03:36:06,960 be as follows I still have my curly 5676 03:36:04,720 --> 03:36:09,239 brace up here I still have my curly 5677 03:36:06,960 --> 03:36:12,080 brace down here but notice it's a little 5678 03:36:09,239 --> 03:36:14,960 more readable now in that I have my keys 5679 03:36:12,080 --> 03:36:16,479 on the left my something and my values 5680 03:36:14,960 --> 03:36:18,560 on the right my other something it's 5681 03:36:16,479 --> 03:36:20,199 just a little easier to skim top to 5682 03:36:18,560 --> 03:36:21,560 bottom you could format it differently 5683 03:36:20,199 --> 03:36:25,040 as well but I'm going to go ahead and 5684 03:36:21,560 --> 03:36:28,600 add in now uh Draco who lives of course 5685 03:36:25,040 --> 03:36:31,479 in in Slytherin so now I have each of 5686 03:36:28,600 --> 03:36:33,880 these keys on the left and values on the 5687 03:36:31,479 --> 03:36:36,040 right which is really again just a code 5688 03:36:33,880 --> 03:36:38,000 implementation of this idea a little 5689 03:36:36,040 --> 03:36:39,880 chart that you might write up with paper 5690 03:36:38,000 --> 03:36:42,319 pencil when associating something with 5691 03:36:39,880 --> 03:36:44,560 something else so how do I now use this 5692 03:36:42,319 --> 03:36:46,560 code in an interesting way the syntax is 5693 03:36:44,560 --> 03:36:49,520 almost the same if I want to print out 5694 03:36:46,560 --> 03:36:52,080 the very first student herm's house I 5695 03:36:49,520 --> 03:36:54,640 could do this print out the name of the 5696 03:36:52,080 --> 03:36:57,359 variable but I need to go inside of the 5697 03:36:54,640 --> 03:36:59,800 variable I need to index into it and 5698 03:36:57,359 --> 03:37:03,439 what's neat about dictionaries is that 5699 03:36:59,800 --> 03:37:07,720 whereas lists have locations that are 5700 03:37:03,439 --> 03:37:09,960 numeric zero 1 2 Hermione Harry Ron 5701 03:37:07,720 --> 03:37:13,520 respectively dictionaries allow you to 5702 03:37:09,960 --> 03:37:15,600 use actual words as your indices so to 5703 03:37:13,520 --> 03:37:18,239 speak your indexes to get inside of them 5704 03:37:15,600 --> 03:37:20,760 them so if you want to print out herm's 5705 03:37:18,239 --> 03:37:24,040 house the key you care about is quote 5706 03:37:20,760 --> 03:37:25,840 unquote Hermione and what this syntax 5707 03:37:24,040 --> 03:37:28,680 here will do notice it's not a number 5708 03:37:25,840 --> 03:37:30,960 zero or one or two it's literally herm's 5709 03:37:28,680 --> 03:37:33,520 name this is like going to the Chart 5710 03:37:30,960 --> 03:37:36,359 earlier and saying all right give me uh 5711 03:37:33,520 --> 03:37:38,000 Hermione is my key Gryffindor is the 5712 03:37:36,359 --> 03:37:39,960 value that's what we're doing here 5713 03:37:38,000 --> 03:37:42,080 syntactically we're looking up hermion 5714 03:37:39,960 --> 03:37:43,640 and getting the value thereof so if I go 5715 03:37:42,080 --> 03:37:45,600 back to my code that should print out 5716 03:37:43,640 --> 03:37:48,199 Gryffindor and if I do this a few times 5717 03:37:45,600 --> 03:37:50,120 students bracket quote unquote Harry 5718 03:37:48,199 --> 03:37:52,600 should give me Harry's house print 5719 03:37:50,120 --> 03:37:54,720 students Open Bracket Ron that should 5720 03:37:52,600 --> 03:37:57,080 give me Ron's house and then lastly if I 5721 03:37:54,720 --> 03:37:59,319 do this with students bracket Draco that 5722 03:37:57,080 --> 03:38:01,000 should give me draco's house now it's a 5723 03:37:59,319 --> 03:38:02,680 little manual still I'm bet we can 5724 03:38:01,000 --> 03:38:04,960 improve this but let me run python on 5725 03:38:02,680 --> 03:38:06,840 Hogwarts sty and we should see 5726 03:38:04,960 --> 03:38:09,040 Gryffindor Gryffindor Gryffindor 5727 03:38:06,840 --> 03:38:11,359 Slytherin which is exactly what we'd 5728 03:38:09,040 --> 03:38:13,160 expect now all we've done again is we've 5729 03:38:11,359 --> 03:38:15,479 just now moved from having just a simple 5730 03:38:13,160 --> 03:38:17,600 list of names to again sort of two Di 5731 03:38:15,479 --> 03:38:19,680 ions associating like we would on paper 5732 03:38:17,600 --> 03:38:22,720 pencil something with something else 5733 03:38:19,680 --> 03:38:24,319 keys with values respectively allow me 5734 03:38:22,720 --> 03:38:26,720 if you will even though I realize this 5735 03:38:24,319 --> 03:38:29,080 is getting a little fancy allow me to 5736 03:38:26,720 --> 03:38:32,120 escalate things slightly here and 5737 03:38:29,080 --> 03:38:35,040 transition from looking at just for 5738 03:38:32,120 --> 03:38:36,640 instance uh that pattern there just 5739 03:38:35,040 --> 03:38:38,000 hardcoding those values there to 5740 03:38:36,640 --> 03:38:40,040 actually printing these out more 5741 03:38:38,000 --> 03:38:41,640 dynamically let me go ahead and use our 5742 03:38:40,040 --> 03:38:44,800 Loop and this question came up earlier 5743 03:38:41,640 --> 03:38:47,439 as well let me go ahead and say for each 5744 03:38:44,800 --> 03:38:50,720 student 5745 03:38:47,439 --> 03:38:54,880 in students go ahead and print out for 5746 03:38:50,720 --> 03:38:56,520 instance the students variable at well 5747 03:38:54,880 --> 03:38:58,359 let's just say student first let's keep 5748 03:38:56,520 --> 03:38:59,800 it simple so this is not going to be 5749 03:38:58,359 --> 03:39:02,359 that interesting yet but when I run 5750 03:38:59,800 --> 03:39:05,359 python of Hogwarts upy and hit enter 5751 03:39:02,359 --> 03:39:07,640 notice what should I see let me take a 5752 03:39:05,359 --> 03:39:09,840 question here to see what am I going to 5753 03:39:07,640 --> 03:39:13,040 see when I hit enter now when I'm doing 5754 03:39:09,840 --> 03:39:15,760 for student in students yeah I think we 5755 03:39:13,040 --> 03:39:17,199 we we will only see Keys perfect so good 5756 03:39:15,760 --> 03:39:19,080 intuition it could have gone both ways 5757 03:39:17,199 --> 03:39:21,680 could have been values the houses but 5758 03:39:19,080 --> 03:39:24,760 when you use a for Loop in Python to 5759 03:39:21,680 --> 03:39:27,239 iterate over a dictionary by design it 5760 03:39:24,760 --> 03:39:30,439 iterates over all of the keys so we 5761 03:39:27,239 --> 03:39:32,960 should see I think Hermione Harry Ron 5762 03:39:30,439 --> 03:39:35,000 and Draco let me hit enter now enter and 5763 03:39:32,960 --> 03:39:37,199 indeed you're exactly right we see just 5764 03:39:35,000 --> 03:39:38,880 the keys but that's not really that 5765 03:39:37,199 --> 03:39:41,840 useful if what I really care about is 5766 03:39:38,880 --> 03:39:43,800 who lives where can I print out both 5767 03:39:41,840 --> 03:39:46,120 well I think I can let me go ahead and 5768 03:39:43,800 --> 03:39:49,319 do this let me print out not just the 5769 03:39:46,120 --> 03:39:52,720 students name the key but let me use the 5770 03:39:49,319 --> 03:39:54,560 key their name to index into the 5771 03:39:52,720 --> 03:39:55,880 dictionary right if I know the word in 5772 03:39:54,560 --> 03:39:57,760 the dictionary let me look up its 5773 03:39:55,880 --> 03:39:59,520 definition if I know the student's name 5774 03:39:57,760 --> 03:40:02,359 let me look up their house and the 5775 03:39:59,520 --> 03:40:05,160 Syntax for this just like a list is 5776 03:40:02,359 --> 03:40:07,880 students bracket and just like in the 5777 03:40:05,160 --> 03:40:11,479 past we used I when I was a number we 5778 03:40:07,880 --> 03:40:16,120 can also with a dictionary use a string 5779 03:40:11,479 --> 03:40:19,199 so if the student's name is the key then 5780 03:40:16,120 --> 03:40:23,040 this syntax students Open Bracket 5781 03:40:19,199 --> 03:40:24,840 student close bracket will go to hermion 5782 03:40:23,040 --> 03:40:27,000 location and get back her house we'll go 5783 03:40:24,840 --> 03:40:29,239 to Harry's location and get back his 5784 03:40:27,000 --> 03:40:33,160 house and so forth so if I do python of 5785 03:40:29,239 --> 03:40:34,439 Hogwarts enter now I see Hermione 5786 03:40:33,160 --> 03:40:36,479 Gryffindor Harry Gryffindor Ron 5787 03:40:34,439 --> 03:40:38,199 Gryffindor Draco Slytherin now it looks 5788 03:40:36,479 --> 03:40:39,720 like I've given them all new last names 5789 03:40:38,199 --> 03:40:41,399 but I can clean that up this is just a 5790 03:40:39,720 --> 03:40:43,399 print thing let's go ahead and change 5791 03:40:41,399 --> 03:40:46,560 our separator from the default space to 5792 03:40:43,399 --> 03:40:48,479 maybe a space comma and just using print 5793 03:40:46,560 --> 03:40:50,560 features now let me run the same program 5794 03:40:48,479 --> 03:40:52,199 again enter now I've just got some nice 5795 03:40:50,560 --> 03:40:54,439 pretty commas in there to make clear 5796 03:40:52,199 --> 03:40:56,160 that herm's last name is not in fact 5797 03:40:54,439 --> 03:40:58,560 Gryffindor but that's just a print 5798 03:40:56,160 --> 03:41:01,960 detail any questions then on these 5799 03:40:58,560 --> 03:41:04,600 dictionaries and what I've just 5800 03:41:01,960 --> 03:41:06,040 done questions on these dictionaries and 5801 03:41:04,600 --> 03:41:09,800 this 5802 03:41:06,040 --> 03:41:13,600 looping over them here um I just can't 5803 03:41:09,800 --> 03:41:16,720 get my head around the uh for student in 5804 03:41:13,600 --> 03:41:19,720 students does uh if I'm just correct me 5805 03:41:16,720 --> 03:41:23,520 if if I'm right does that mean it 5806 03:41:19,720 --> 03:41:27,720 Imports the list of students and uses 5807 03:41:23,520 --> 03:41:32,680 the indexes in other words herione Harry 5808 03:41:27,720 --> 03:41:35,080 and Ron as the indexes in the actual um 5809 03:41:32,680 --> 03:41:36,960 the list of students correct so this is 5810 03:41:35,080 --> 03:41:39,880 just a feature of python when you use a 5811 03:41:36,960 --> 03:41:41,800 for loop with a dictionary what happens 5812 03:41:39,880 --> 03:41:43,520 is this if this is the dictionary here 5813 03:41:41,800 --> 03:41:44,920 with the keys on top and the values on 5814 03:41:43,520 --> 03:41:46,720 bottom you get to choose what the 5815 03:41:44,920 --> 03:41:48,159 variable called I called my variable 5816 03:41:46,720 --> 03:41:49,840 student just because it makes sense 5817 03:41:48,159 --> 03:41:51,760 because I want one student at a time and 5818 03:41:49,840 --> 03:41:53,479 what the for Loop does just like it did 5819 03:41:51,760 --> 03:41:56,439 with numbers before the zero the one and 5820 03:41:53,479 --> 03:41:59,279 the two it allows me to for instance set 5821 03:41:56,439 --> 03:42:01,000 student equal initially to herm's name 5822 03:41:59,279 --> 03:42:03,439 and then the next iteration of the loop 5823 03:42:01,000 --> 03:42:06,239 the next cycle sets student equal to 5824 03:42:03,439 --> 03:42:07,920 Harry's name then Ron then Draco it just 5825 03:42:06,239 --> 03:42:10,399 kind of happens automatically like that 5826 03:42:07,920 --> 03:42:12,479 is what the python interpreter does for 5827 03:42:10,399 --> 03:42:14,640 you when it sees a for Loop like that so 5828 03:42:12,479 --> 03:42:16,560 it's very similar in spirit to iterating 5829 03:42:14,640 --> 03:42:18,319 with a for Loop Loop over a list but 5830 03:42:16,560 --> 03:42:21,199 rather than iterate over the numeric 5831 03:42:18,319 --> 03:42:24,640 location 012 it iterates over the 5832 03:42:21,199 --> 03:42:27,560 boldfaced keys in this representation 5833 03:42:24,640 --> 03:42:29,560 here graphically and allow me to give us 5834 03:42:27,560 --> 03:42:32,680 one other example on Hogwarts before we 5835 03:42:29,560 --> 03:42:34,399 look at one other familiar uh domain at 5836 03:42:32,680 --> 03:42:36,960 the risk of things escalating a little 5837 03:42:34,399 --> 03:42:39,000 bit let me propose that we continue the 5838 03:42:36,960 --> 03:42:41,960 story with one final Hogwarts example 5839 03:42:39,000 --> 03:42:44,520 like this what if we have more 5840 03:42:41,960 --> 03:42:46,080 information about each of our students 5841 03:42:44,520 --> 03:42:47,640 and this is kind kind of inevitable 5842 03:42:46,080 --> 03:42:49,319 right if you're implementing a program 5843 03:42:47,640 --> 03:42:51,560 that's a database with people or 5844 03:42:49,319 --> 03:42:53,960 customers or employees or anything else 5845 03:42:51,560 --> 03:42:55,840 you can imagine having a lot of data 5846 03:42:53,960 --> 03:42:57,720 about anything you're representing in 5847 03:42:55,840 --> 03:42:59,640 your program here for the sake of 5848 03:42:57,720 --> 03:43:02,120 discussion suppose that every student at 5849 03:42:59,640 --> 03:43:04,080 Hogwarts of course has a name they have 5850 03:43:02,120 --> 03:43:06,199 already a house but they also have a 5851 03:43:04,080 --> 03:43:08,120 Patronus for those unfamiliar this is 5852 03:43:06,199 --> 03:43:09,960 the animal or entity that comes out of 5853 03:43:08,120 --> 03:43:12,439 the end of their wand when they make a 5854 03:43:09,960 --> 03:43:14,600 Certain Magical spell the point here 5855 03:43:12,439 --> 03:43:18,000 being is that we want to associate not 5856 03:43:14,600 --> 03:43:20,720 just one one thing with the student but 5857 03:43:18,000 --> 03:43:23,479 multiple things as well their name their 5858 03:43:20,720 --> 03:43:25,560 house and their petronus in this case 5859 03:43:23,479 --> 03:43:28,239 well what might code like this look like 5860 03:43:25,560 --> 03:43:30,520 well let me go back to Hogwarts toy and 5861 03:43:28,239 --> 03:43:32,520 let me start fresh for just a moment and 5862 03:43:30,520 --> 03:43:34,800 let me propose that I enhance this with 5863 03:43:32,520 --> 03:43:37,920 a bit more data and this data is going 5864 03:43:34,800 --> 03:43:40,479 to look as follows my students variable 5865 03:43:37,920 --> 03:43:43,159 now I'm going to propose we think of it 5866 03:43:40,479 --> 03:43:45,600 as a list what if we have a list of 5867 03:43:43,159 --> 03:43:48,439 dictionaries as follows indeed I want to 5868 03:43:45,600 --> 03:43:50,399 literally implement this picture here so 5869 03:43:48,439 --> 03:43:52,880 notice that my previous picture just 5870 03:43:50,399 --> 03:43:55,920 represented a single dictionary but 5871 03:43:52,880 --> 03:43:58,520 suppose I wanted to compose a list of 5872 03:43:55,920 --> 03:44:00,720 dictionaries that is four students so a 5873 03:43:58,520 --> 03:44:03,560 list of four students and suppose that 5874 03:44:00,720 --> 03:44:07,760 each of those students is itself a 5875 03:44:03,560 --> 03:44:10,319 dictionary a collection of key value 5876 03:44:07,760 --> 03:44:12,760 pairs keys and values something and 5877 03:44:10,319 --> 03:44:15,239 something else well here's one other way 5878 03:44:12,760 --> 03:44:18,080 we can do this in code let me go back to 5879 03:44:15,239 --> 03:44:21,399 s code here and let me Define a variable 5880 03:44:18,080 --> 03:44:23,239 called students that is equal to a list 5881 03:44:21,399 --> 03:44:24,920 and I'm going to preemptively move my 5882 03:44:23,239 --> 03:44:26,560 cursor onto separate lines because I 5883 03:44:24,920 --> 03:44:29,239 know this is going to be long and I want 5884 03:44:26,560 --> 03:44:31,640 to fit all of the elements of this list 5885 03:44:29,239 --> 03:44:33,920 inside of it I'm now going to create a 5886 03:44:31,640 --> 03:44:35,399 dictionary one dictionary per student 5887 03:44:33,920 --> 03:44:37,800 and how do I create a dictionary I just 5888 03:44:35,399 --> 03:44:40,040 use those curly braces but it's up to me 5889 03:44:37,800 --> 03:44:42,159 to Define what those keys are and let me 5890 03:44:40,040 --> 03:44:44,080 propose that one key this time won't be 5891 03:44:42,159 --> 03:44:46,399 the student's name explicitly it will 5892 03:44:44,080 --> 03:44:48,640 literally be the word name and they're 5893 03:44:46,399 --> 03:44:50,399 going to have the name Hermione this 5894 03:44:48,640 --> 03:44:52,760 same student is going to have another 5895 03:44:50,399 --> 03:44:55,359 key called house and the value is going 5896 03:44:52,760 --> 03:44:57,040 to be Gryffindor and the same student's 5897 03:44:55,359 --> 03:44:59,399 going to have a third key called 5898 03:44:57,040 --> 03:45:01,640 petronis and the value of that is going 5899 03:44:59,399 --> 03:45:03,800 to be I had to look it up in otter 5900 03:45:01,640 --> 03:45:05,880 according to the book now I'm going to 5901 03:45:03,800 --> 03:45:07,560 create a second dictionary inside of 5902 03:45:05,880 --> 03:45:09,319 this list and again a dictionary is like 5903 03:45:07,560 --> 03:45:12,040 literally like the human dictionary of 5904 03:45:09,319 --> 03:45:14,319 words it's a book that contains keys and 5905 03:45:12,040 --> 03:45:16,000 values words and definitions what are 5906 03:45:14,319 --> 03:45:19,000 the three words I'm storing in each of 5907 03:45:16,000 --> 03:45:20,720 my dictionaries name house and petronis 5908 03:45:19,000 --> 03:45:23,560 what are the definitions of those words 5909 03:45:20,720 --> 03:45:26,120 for Hermione Hermione griffindor and 5910 03:45:23,560 --> 03:45:27,880 Otter respectively for Harry the 5911 03:45:26,120 --> 03:45:29,840 definitions are going to be different in 5912 03:45:27,880 --> 03:45:31,960 this new dictionary let me give myself 5913 03:45:29,840 --> 03:45:35,560 another pair of curly braces and say 5914 03:45:31,960 --> 03:45:37,840 this name quote unquote colon Harry uh 5915 03:45:35,560 --> 03:45:40,840 house here is again going to be 5916 03:45:37,840 --> 03:45:43,439 Gryffindor and this one I I knew his 5917 03:45:40,840 --> 03:45:46,600 Patronis is going to be in this case a 5918 03:45:43,439 --> 03:45:48,920 stag all right next a third dictionary 5919 03:45:46,600 --> 03:45:51,000 the name here will be Ron and I'm going 5920 03:45:48,920 --> 03:45:53,520 to go ahead and do that just like this 5921 03:45:51,000 --> 03:45:55,680 next I have the house and he too was 5922 03:45:53,520 --> 03:46:00,680 Gryffindor lastly had to look this one 5923 03:45:55,680 --> 03:46:02,520 up Ron's petronis was a Jack Russell 5924 03:46:00,680 --> 03:46:05,920 Terrier 5925 03:46:02,520 --> 03:46:07,640 lastly is Draco in a third in a fourth 5926 03:46:05,920 --> 03:46:09,600 dictionary now so another pair of curly 5927 03:46:07,640 --> 03:46:12,120 braces the name of the student is of 5928 03:46:09,600 --> 03:46:13,199 course Draco the house of this student 5929 03:46:12,120 --> 03:46:15,600 is 5930 03:46:13,199 --> 03:46:17,680 Slytherin and dra 5931 03:46:15,600 --> 03:46:20,399 interestingly enough at least according 5932 03:46:17,680 --> 03:46:21,880 to the internet has no Patronus was 5933 03:46:20,399 --> 03:46:23,840 never revealed in the books or the 5934 03:46:21,880 --> 03:46:26,359 movies so it turns out this is actually 5935 03:46:23,840 --> 03:46:28,439 a wonderful teachable moment there is a 5936 03:46:26,359 --> 03:46:32,239 special keyword in Python that is 5937 03:46:28,439 --> 03:46:34,920 literally none n o n e with the first 5938 03:46:32,239 --> 03:46:37,880 letter capitalized this represents 5939 03:46:34,920 --> 03:46:39,359 officially the absence of a value so I 5940 03:46:37,880 --> 03:46:41,439 could a little sloppily do something 5941 03:46:39,359 --> 03:46:43,720 like quote unquote but does that mean I 5942 03:46:41,439 --> 03:46:45,960 didn't get around to typing it or not 5943 03:46:43,720 --> 03:46:48,319 it's a little clear semantically to say 5944 03:46:45,960 --> 03:46:51,159 literally none a special keyword in 5945 03:46:48,319 --> 03:46:53,479 Python to make clear that I know uh 5946 03:46:51,159 --> 03:46:56,720 Draco has no Patronis it's not just an 5947 03:46:53,479 --> 03:46:58,920 oversight on my part now that I have 5948 03:46:56,720 --> 03:47:01,199 this what do I have in the computer's 5949 03:46:58,920 --> 03:47:03,520 memory I have a list how do I know it's 5950 03:47:01,199 --> 03:47:05,560 a list because I see a square bracket at 5951 03:47:03,520 --> 03:47:07,560 the beginning and another square bracket 5952 03:47:05,560 --> 03:47:09,319 at the end that's just my visual clue 5953 03:47:07,560 --> 03:47:11,479 okay I don't know necessarily what else 5954 03:47:09,319 --> 03:47:14,920 is going on here but there's a list of 5955 03:47:11,479 --> 03:47:17,479 something what is in that list well here 5956 03:47:14,920 --> 03:47:19,800 two the syntax is our clue because this 5957 03:47:17,479 --> 03:47:22,600 line two starts with a curly brace and 5958 03:47:19,800 --> 03:47:24,840 ends with a curly brace I just know that 5959 03:47:22,600 --> 03:47:27,000 is a dictionary a collection of key 5960 03:47:24,840 --> 03:47:28,720 value pairs now this all fit on my 5961 03:47:27,000 --> 03:47:30,680 screen perfectly so I didn't bother 5962 03:47:28,720 --> 03:47:32,040 moving all of the key value pairs onto 5963 03:47:30,680 --> 03:47:34,040 new lines it would have made it really 5964 03:47:32,040 --> 03:47:37,600 tall so I I kept it all together here 5965 03:47:34,040 --> 03:47:39,520 this time but how many keys does this 5966 03:47:37,600 --> 03:47:41,479 first dictionary have put another way in 5967 03:47:39,520 --> 03:47:43,760 her mayane physical dictionary how many 5968 03:47:41,479 --> 03:47:46,399 words are in that dictionary three the 5969 03:47:43,760 --> 03:47:48,600 words are name house and petronis what 5970 03:47:46,399 --> 03:47:50,920 are the three definitions or values of 5971 03:47:48,600 --> 03:47:53,399 those words in herm's dictionary 5972 03:47:50,920 --> 03:47:56,199 Hermione Gryffindor and Otter 5973 03:47:53,399 --> 03:48:00,479 respectively and the same story goes for 5974 03:47:56,199 --> 03:48:03,520 Harry then for Ron then for Draco I have 5975 03:48:00,479 --> 03:48:05,960 by Design chosen to give them 5976 03:48:03,520 --> 03:48:09,239 dictionaries that have all the same Keys 5977 03:48:05,960 --> 03:48:11,359 all the same names but they all have 5978 03:48:09,239 --> 03:48:13,840 unique values and that's my design 5979 03:48:11,359 --> 03:48:15,920 That's My Prerogative as a programmer so 5980 03:48:13,840 --> 03:48:18,080 why is this useful at the end of the day 5981 03:48:15,920 --> 03:48:20,680 now I have access to a whole collection 5982 03:48:18,080 --> 03:48:23,239 of interesting data about all of these 5983 03:48:20,680 --> 03:48:26,120 students and I can still do a loop I can 5984 03:48:23,239 --> 03:48:27,720 say for student and students that's 5985 03:48:26,120 --> 03:48:29,600 going to allow me to iterate over this 5986 03:48:27,720 --> 03:48:31,479 list of students and let me go ahead and 5987 03:48:29,600 --> 03:48:33,880 print out just one thing at a time let 5988 03:48:31,479 --> 03:48:36,120 me print out the current Student's name 5989 03:48:33,880 --> 03:48:38,279 so as complicated as the dictionary is 5990 03:48:36,120 --> 03:48:39,760 this should be pretty comfortable four 5991 03:48:38,279 --> 03:48:41,960 student and students is just going to 5992 03:48:39,760 --> 03:48:44,520 iterate over every student in the list 1 5993 03:48:41,960 --> 03:48:47,760 2 3 4 total the next line is just going 5994 03:48:44,520 --> 03:48:49,560 to print out the value of the name key 5995 03:48:47,760 --> 03:48:51,880 it's like opening a physical dictionary 5996 03:48:49,560 --> 03:48:53,960 looking up the word name and giving us 5997 03:48:51,880 --> 03:48:55,960 Hermione Harry Ron and Draco 5998 03:48:53,960 --> 03:48:57,800 respectively from each dictionary so if 5999 03:48:55,960 --> 03:49:00,319 I run this version of Hogwarts and hit 6000 03:48:57,800 --> 03:49:02,199 enter there I get all three of their 6001 03:49:00,319 --> 03:49:03,920 names but what if I want more 6002 03:49:02,199 --> 03:49:06,520 information than that I want both their 6003 03:49:03,920 --> 03:49:10,319 names and their houses well just add to 6004 03:49:06,520 --> 03:49:12,920 prints arguments student Open Bracket uh 6005 03:49:10,319 --> 03:49:15,239 House close bracket all right let's go 6006 03:49:12,920 --> 03:49:17,720 ahead and run this python of Hogwarts 6007 03:49:15,239 --> 03:49:19,479 dopy and hit enter so I now see Hermione 6008 03:49:17,720 --> 03:49:21,000 Gryffindor Harry Gryffindor and so forth 6009 03:49:19,479 --> 03:49:22,880 well we can aesthetically clean this up 6010 03:49:21,000 --> 03:49:25,239 a little bit by adding a separator with 6011 03:49:22,880 --> 03:49:27,120 print like a comma in a space just so 6012 03:49:25,239 --> 03:49:29,120 that when I run this again I now see 6013 03:49:27,120 --> 03:49:30,720 some commas separating these values but 6014 03:49:29,120 --> 03:49:32,399 recall that students have not just a 6015 03:49:30,720 --> 03:49:34,560 name not just a house but also that 6016 03:49:32,399 --> 03:49:38,399 Patronis so if we want to print out that 6017 03:49:34,560 --> 03:49:40,680 too we now have the syntax via which to 6018 03:49:38,399 --> 03:49:43,640 go into that same dictionary for each 6019 03:49:40,680 --> 03:49:45,439 student and output their Patronus as 6020 03:49:43,640 --> 03:49:47,720 well as their house and their name so if 6021 03:49:45,439 --> 03:49:50,800 I run this program one final time now I 6022 03:49:47,720 --> 03:49:53,159 see all of the data in this here 6023 03:49:50,800 --> 03:49:55,279 dictionary so this is a lot to absorb 6024 03:49:53,159 --> 03:49:57,479 all at once I'm sure it's the last of 6025 03:49:55,279 --> 03:49:59,319 our new data types on top of lists we 6026 03:49:57,479 --> 03:50:01,960 have these dictionaries but again a 6027 03:49:59,319 --> 03:50:04,560 dictionary at the end of the day is just 6028 03:50:01,960 --> 03:50:06,720 a collection of values similar to these 6029 03:50:04,560 --> 03:50:08,880 values here that allow you to associate 6030 03:50:06,720 --> 03:50:11,279 keys with values and the first version 6031 03:50:08,880 --> 03:50:13,479 of this program Associated literally the 6032 03:50:11,279 --> 03:50:15,239 students names with their houses but 6033 03:50:13,479 --> 03:50:17,120 then I realized in my next version wait 6034 03:50:15,239 --> 03:50:19,439 a minute what if every student has not 6035 03:50:17,120 --> 03:50:21,560 just a name in a house but a Patronis 6036 03:50:19,439 --> 03:50:25,279 let's actually standardize the names of 6037 03:50:21,560 --> 03:50:27,479 our keys to be name house and Patronus 6038 03:50:25,279 --> 03:50:29,239 and then the values of those keys can 6039 03:50:27,479 --> 03:50:32,439 actually be the data like Hermione 6040 03:50:29,239 --> 03:50:35,560 Gryffindor otter and so forth questions 6041 03:50:32,439 --> 03:50:38,680 now on these dictionaries and iteration 6042 03:50:35,560 --> 03:50:42,359 thereof I just was wondering if the 6043 03:50:38,680 --> 03:50:44,760 suppose the dictionary is very huge and 6044 03:50:42,359 --> 03:50:48,080 if I want to look up for a specific 6045 03:50:44,760 --> 03:50:50,840 student so how do I know uh where to 6046 03:50:48,080 --> 03:50:53,479 look that student from like can we sort 6047 03:50:50,840 --> 03:50:55,920 it out in alphabetical order or numeric 6048 03:50:53,479 --> 03:50:58,239 order or anything like that in short 6049 03:50:55,920 --> 03:51:00,359 answer yes one of the features of python 6050 03:50:58,239 --> 03:51:02,520 is that it makes these dictionaries very 6051 03:51:00,359 --> 03:51:04,800 highly performant for you that is even 6052 03:51:02,520 --> 03:51:06,520 if they're very large as they will be in 6053 03:51:04,800 --> 03:51:09,560 future weeks when we manipulate more 6054 03:51:06,520 --> 03:51:12,680 data python will find the data you care 6055 03:51:09,560 --> 03:51:14,159 about quickly for you and in fact that 6056 03:51:12,680 --> 03:51:15,920 is a feature of the language that is a 6057 03:51:14,159 --> 03:51:17,960 feature of a dictionary to get you the 6058 03:51:15,920 --> 03:51:19,800 data quickly and there are functions 6059 03:51:17,960 --> 03:51:21,600 that you can use you can sort the data 6060 03:51:19,800 --> 03:51:24,159 you can sift through it you can do very 6061 03:51:21,600 --> 03:51:28,040 performant operations as we eventually 6062 03:51:24,159 --> 03:51:30,199 will allow me then to propose as we wrap 6063 03:51:28,040 --> 03:51:32,239 up these Loops that we solve just a few 6064 03:51:30,199 --> 03:51:34,199 final problems that will perhaps evoke 6065 03:51:32,239 --> 03:51:36,120 fond memories of yester here at least 6066 03:51:34,199 --> 03:51:37,960 for me where in one of my favorite games 6067 03:51:36,120 --> 03:51:39,600 growing up was this one here on the 6068 03:51:37,960 --> 03:51:41,040 original Nintendo and this is a 6069 03:51:39,600 --> 03:51:44,040 two-dimensional world where the 6070 03:51:41,040 --> 03:51:46,279 characters move up down and right not so 6071 03:51:44,040 --> 03:51:48,359 much to the left in jumping over 6072 03:51:46,279 --> 03:51:49,840 pyramids and obstructions like these and 6073 03:51:48,359 --> 03:51:51,600 allow me to propose that we use this 6074 03:51:49,840 --> 03:51:53,600 just for inspiration not to do something 6075 03:51:51,600 --> 03:51:55,600 that's quite as colorful or graphical as 6076 03:51:53,600 --> 03:51:58,239 this but just to focus on for instance 6077 03:51:55,600 --> 03:52:00,720 this barrier in the middle of the world 6078 03:51:58,239 --> 03:52:03,600 here that Mario or Luigi had to jump 6079 03:52:00,720 --> 03:52:05,399 over and so this here seems to be like 6080 03:52:03,600 --> 03:52:06,840 three bricks stepped on top of one 6081 03:52:05,399 --> 03:52:08,600 another and we won't do things quite 6082 03:52:06,840 --> 03:52:10,600 graphically but let's just Implement a 6083 03:52:08,600 --> 03:52:13,000 very simple python based version of this 6084 03:52:10,600 --> 03:52:14,840 textually using maybe just hashes for 6085 03:52:13,000 --> 03:52:17,279 bricks because there's a pth pattern 6086 03:52:14,840 --> 03:52:19,399 here one on top of the other and I bet 6087 03:52:17,279 --> 03:52:21,199 we can solve this in any number of ways 6088 03:52:19,399 --> 03:52:23,840 well let me switch back over to vs code 6089 03:52:21,199 --> 03:52:26,960 here and let me propose that we create a 6090 03:52:23,840 --> 03:52:29,080 program called mario. using code in the 6091 03:52:26,960 --> 03:52:30,880 terminal window and then up here let me 6092 03:52:29,080 --> 03:52:33,319 start by implementing that same picture 6093 03:52:30,880 --> 03:52:36,279 as simply as I can printing out just 6094 03:52:33,319 --> 03:52:38,720 literally the hash and then the hash and 6095 03:52:36,279 --> 03:52:40,760 then a third final hash this is going to 6096 03:52:38,720 --> 03:52:43,720 be a very textual approximation of it 6097 03:52:40,760 --> 03:52:46,880 but I think if I run python mario. I've 6098 03:52:43,720 --> 03:52:49,800 got a very simple version of that same 6099 03:52:46,880 --> 03:52:51,520 column of bricks so to speak but you can 6100 03:52:49,800 --> 03:52:54,279 imagine that certainly in a game where 6101 03:52:51,520 --> 03:52:56,199 maybe these uh The Columns get higher or 6102 03:52:54,279 --> 03:52:57,720 lower it would be nice to write code 6103 03:52:56,199 --> 03:52:59,560 that's actually a little more Dynamic 6104 03:52:57,720 --> 03:53:01,520 than that and doesn't just use print 6105 03:52:59,560 --> 03:53:04,120 print print which is literally copy and 6106 03:53:01,520 --> 03:53:06,239 paste it would seem so let me at least 6107 03:53:04,120 --> 03:53:08,279 adopt some of today's Lessons Learned 6108 03:53:06,239 --> 03:53:11,439 and instead do something like this for 6109 03:53:08,279 --> 03:53:13,960 underscore in range of three let's now 6110 03:53:11,439 --> 03:53:15,800 print out just one of these at a time 6111 03:53:13,960 --> 03:53:17,640 but the fact that I've now used a three 6112 03:53:15,800 --> 03:53:19,640 to range means if I want to change it to 6113 03:53:17,640 --> 03:53:22,560 something bigger or smaller I change it 6114 03:53:19,640 --> 03:53:24,279 in one place not in three or more places 6115 03:53:22,560 --> 03:53:27,199 and this code two of course if I got it 6116 03:53:24,279 --> 03:53:30,040 right is just going to print out the 6117 03:53:27,199 --> 03:53:31,520 exact same thing so we're iterating here 6118 03:53:30,040 --> 03:53:33,560 but let's see if we can't now integrate 6119 03:53:31,520 --> 03:53:35,760 our discussion of writing functions of 6120 03:53:33,560 --> 03:53:37,600 our own to begin writing something a 6121 03:53:35,760 --> 03:53:39,720 little more Dynamic and solving more 6122 03:53:37,600 --> 03:53:41,479 complicated problems ultimately one of 6123 03:53:39,720 --> 03:53:43,319 the nice things about functions is that 6124 03:53:41,479 --> 03:53:45,399 they allow us to not just write code 6125 03:53:43,319 --> 03:53:48,040 that we can use and reuse they allow us 6126 03:53:45,399 --> 03:53:50,239 to create abstractions if you will an 6127 03:53:48,040 --> 03:53:52,399 abstraction is a simplification of a 6128 03:53:50,239 --> 03:53:54,159 potentially more complicated idea and 6129 03:53:52,399 --> 03:53:55,960 we've seen this a few times over the 6130 03:53:54,159 --> 03:53:58,399 course of the weeks for instance we had 6131 03:53:55,960 --> 03:54:00,080 a function called hello which granted 6132 03:53:58,399 --> 03:54:02,159 didn't do all that much it just printed 6133 03:54:00,080 --> 03:54:04,399 hello but it allowed me to think about 6134 03:54:02,159 --> 03:54:06,239 the function as exactly what it does not 6135 03:54:04,399 --> 03:54:08,680 generically printing something but 6136 03:54:06,239 --> 03:54:11,319 literally saying hello I've been able to 6137 03:54:08,680 --> 03:54:13,640 get a number using something similar by 6138 03:54:11,319 --> 03:54:15,279 defining my own function like get number 6139 03:54:13,640 --> 03:54:17,359 well let me go ahead and for instance 6140 03:54:15,279 --> 03:54:20,600 assume for the moment that I've had the 6141 03:54:17,359 --> 03:54:23,159 forethought to uh in my function main 6142 03:54:20,600 --> 03:54:25,680 use a function called print column that 6143 03:54:23,159 --> 03:54:28,720 seems as good a name as any to use a 6144 03:54:25,680 --> 03:54:30,880 function that prints a column of bricks 6145 03:54:28,720 --> 03:54:33,359 well how can I go about now implementing 6146 03:54:30,880 --> 03:54:36,040 this abstraction this simple idea print 6147 03:54:33,359 --> 03:54:37,800 column with actual code well we've seen 6148 03:54:36,040 --> 03:54:40,040 before with def we can do just that let 6149 03:54:37,800 --> 03:54:42,120 me Define a function called print column 6150 03:54:40,040 --> 03:54:43,880 let me accept as its input uh 6151 03:54:42,120 --> 03:54:46,239 generically speaking a parameter called 6152 03:54:43,880 --> 03:54:47,680 height I could call it n or H but I'll 6153 03:54:46,239 --> 03:54:49,840 be a little more explicit now with 6154 03:54:47,680 --> 03:54:52,359 height just so I remind myself what it's 6155 03:54:49,840 --> 03:54:54,520 doing and now I think I can just borrow 6156 03:54:52,359 --> 03:54:58,840 some of that same code from before for 6157 03:54:54,520 --> 03:55:01,640 underscore in range of height go ahead 6158 03:54:58,840 --> 03:55:03,399 and print out a single hash and then at 6159 03:55:01,640 --> 03:55:05,840 the end of this whole program let's just 6160 03:55:03,399 --> 03:55:07,640 call Main so I've kind of complicated 6161 03:55:05,840 --> 03:55:10,199 the code it doesn't do anything more 6162 03:55:07,640 --> 03:55:11,920 just yet but it's setting me up for 6163 03:55:10,199 --> 03:55:13,680 solving what I think are going to be 6164 03:55:11,920 --> 03:55:15,520 more sophisticated problems if I run 6165 03:55:13,680 --> 03:55:18,479 python of Mario up high we're back where 6166 03:55:15,520 --> 03:55:21,399 we began but I now have a function an 6167 03:55:18,479 --> 03:55:23,840 abstraction print column that's going to 6168 03:55:21,399 --> 03:55:26,800 allow me to think about printing some 6169 03:55:23,840 --> 03:55:28,399 chunk of the world of Mario at a time 6170 03:55:26,800 --> 03:55:31,159 and I can do this in different ways too 6171 03:55:28,399 --> 03:55:33,399 notice that if I really want I could do 6172 03:55:31,159 --> 03:55:35,479 something like this I could reimplement 6173 03:55:33,399 --> 03:55:37,600 now print column in different ways 6174 03:55:35,479 --> 03:55:39,920 especially if I am using print column 6175 03:55:37,600 --> 03:55:41,840 all over my code or maybe still a 6176 03:55:39,920 --> 03:55:43,800 colleague of mine a friend someone else 6177 03:55:41,840 --> 03:55:46,000 on the Internet is using my print column 6178 03:55:43,800 --> 03:55:47,880 function what's also nice about 6179 03:55:46,000 --> 03:55:49,960 functions you've written is you can 6180 03:55:47,880 --> 03:55:52,040 change the underlying implementation 6181 03:55:49,960 --> 03:55:54,319 details of them but so long as you don't 6182 03:55:52,040 --> 03:55:56,439 change the name of the function or its 6183 03:55:54,319 --> 03:55:58,640 parameters or what it returns if 6184 03:55:56,439 --> 03:56:00,600 anything no one else knows the 6185 03:55:58,640 --> 03:56:02,399 difference you can change the internal 6186 03:56:00,600 --> 03:56:04,040 implementation as much as you want if 6187 03:56:02,399 --> 03:56:06,439 you want to improve it or make fixes 6188 03:56:04,040 --> 03:56:08,199 over time so for instance another way we 6189 03:56:06,439 --> 03:56:09,800 could Implement print column recall 6190 03:56:08,199 --> 03:56:12,279 would be something like this a bit 6191 03:56:09,800 --> 03:56:13,479 clever with one hash and then a new line 6192 03:56:12,279 --> 03:56:15,560 and then maybe we could do 6193 03:56:13,479 --> 03:56:18,239 multiplication strings and then end this 6194 03:56:15,560 --> 03:56:19,680 line with quote unquote again it's okay 6195 03:56:18,239 --> 03:56:21,640 if you're not comfortable with this 6196 03:56:19,680 --> 03:56:23,960 syntax this was a more clever approach 6197 03:56:21,640 --> 03:56:27,159 we saw in the past but if I run python 6198 03:56:23,960 --> 03:56:28,920 of myoy here I'll still see a column of 6199 03:56:27,159 --> 03:56:32,000 three but what's important here is that 6200 03:56:28,920 --> 03:56:34,600 main does not need to know that the 6201 03:56:32,000 --> 03:56:38,000 underlying implementation of print 6202 03:56:34,600 --> 03:56:40,239 column has changed well let's transition 6203 03:56:38,000 --> 03:56:41,640 to a different dimension if you will and 6204 03:56:40,239 --> 03:56:43,279 rather than print out just these 6205 03:56:41,640 --> 03:56:45,439 vertical bricks let's fast forward in 6206 03:56:43,279 --> 03:56:47,760 the game to this part of the world here 6207 03:56:45,439 --> 03:56:49,439 at some part mar Mario encounters these 6208 03:56:47,760 --> 03:56:51,479 bricks in the sky that if he jumps up 6209 03:56:49,439 --> 03:56:53,800 underneath they become coins and so he 6210 03:56:51,479 --> 03:56:55,880 he gains to a score but let's go ahead 6211 03:56:53,800 --> 03:56:57,800 and focus only on those coins and let me 6212 03:56:55,880 --> 03:57:00,000 propose that we print out oh just these 6213 03:56:57,800 --> 03:57:02,439 four question marks here and let me go 6214 03:57:00,000 --> 03:57:04,199 back to VSS code here and let me propose 6215 03:57:02,439 --> 03:57:06,600 that within VSS code here just like 6216 03:57:04,199 --> 03:57:07,960 before we try to abstract this away so 6217 03:57:06,600 --> 03:57:10,479 let me go ahead and get rid of this 6218 03:57:07,960 --> 03:57:13,040 version cuz we're now going horizontal 6219 03:57:10,479 --> 03:57:16,439 instead of vertical with our output and 6220 03:57:13,040 --> 03:57:18,880 let me just say well print row four 6221 03:57:16,439 --> 03:57:20,439 times let me just abstract away the 6222 03:57:18,880 --> 03:57:22,399 problem at hand I don't know yet how I'm 6223 03:57:20,439 --> 03:57:24,520 going to print those four question marks 6224 03:57:22,399 --> 03:57:27,199 but let's call it print row four and 6225 03:57:24,520 --> 03:57:29,000 I'll assume I'll now solve this problem 6226 03:57:27,199 --> 03:57:31,040 let's now go down that rabbit hole of 6227 03:57:29,000 --> 03:57:33,359 solving the problem Define a function 6228 03:57:31,040 --> 03:57:35,239 called print row it's going to take a 6229 03:57:33,359 --> 03:57:37,760 width instead of a height because it's 6230 03:57:35,239 --> 03:57:40,040 horizontal instead of vertical and how 6231 03:57:37,760 --> 03:57:41,920 can I do this well now we have an 6232 03:57:40,040 --> 03:57:43,760 opportunity to do string multiplication 6233 03:57:41,920 --> 03:57:47,159 even more elegantly I can say quote 6234 03:57:43,760 --> 03:57:50,040 unquote question mark times with and 6235 03:57:47,159 --> 03:57:51,720 this is a very pretty pythonic way of 6236 03:57:50,040 --> 03:57:53,399 printing what could otherwise be a loop 6237 03:57:51,720 --> 03:57:55,520 and that's fine but this is going to go 6238 03:57:53,399 --> 03:57:58,319 ahead and print those question marks for 6239 03:57:55,520 --> 03:58:00,479 me let's do python of mario. enter and 6240 03:57:58,319 --> 03:58:01,800 now I've got four question marks it's 6241 03:58:00,479 --> 03:58:06,080 not nearly as pretty as the more 6242 03:58:01,800 --> 03:58:07,920 graphical version but it is at least uh 6243 03:58:06,080 --> 03:58:11,399 a building block toward having now a 6244 03:58:07,920 --> 03:58:13,720 reusable function like print row and why 6245 03:58:11,399 --> 03:58:15,640 am I doing all this like why are we over 6246 03:58:13,720 --> 03:58:17,199 engine engering the solution to these 6247 03:58:15,640 --> 03:58:19,800 problems by having print column and 6248 03:58:17,199 --> 03:58:22,000 print row well it's a useful problem 6249 03:58:19,800 --> 03:58:24,479 solving technique as soon as your world 6250 03:58:22,000 --> 03:58:26,479 does not look one-dimensional like this 6251 03:58:24,479 --> 03:58:29,199 or with the column version but what 6252 03:58:26,479 --> 03:58:31,000 about this later in Super Mario Brothers 6253 03:58:29,199 --> 03:58:32,560 does Mario have to jump down into this 6254 03:58:31,000 --> 03:58:34,920 world where there's a lot of these 6255 03:58:32,560 --> 03:58:36,880 underworld barriers and this one here 6256 03:58:34,920 --> 03:58:38,720 for instance looks like a square it's 6257 03:58:36,880 --> 03:58:41,080 two-dimensional there's a height and a 6258 03:58:38,720 --> 03:58:42,319 width to it and that is to say there's a 6259 03:58:41,080 --> 03:58:44,800 bunch of different ways we could 6260 03:58:42,319 --> 03:58:48,520 implement this thing if maybe for 6261 03:58:44,800 --> 03:58:51,319 discussion it's like a 3X3 grid a 3X3 6262 03:58:48,520 --> 03:58:53,239 square of sorts well how can we go about 6263 03:58:51,319 --> 03:58:55,720 solving this here problem well let me 6264 03:58:53,239 --> 03:58:57,760 propose we come back to vs code and let 6265 03:58:55,720 --> 03:59:01,520 me propose that we think about this in a 6266 03:58:57,760 --> 03:59:04,040 couple of different ways I could do this 6267 03:59:01,520 --> 03:59:06,520 H like this if I if I know where I'm 6268 03:59:04,040 --> 03:59:08,159 going you know maybe I'm a seasoned 6269 03:59:06,520 --> 03:59:10,479 programmer let me go ahead and do this 6270 03:59:08,159 --> 03:59:12,239 let me print out a square the width and 6271 03:59:10,479 --> 03:59:13,800 the height of which is three that's an 6272 03:59:12,239 --> 03:59:15,399 abstraction I'm just taking for granted 6273 03:59:13,800 --> 03:59:17,520 for moment that there is already a 6274 03:59:15,399 --> 03:59:19,479 function called print Square that's 6275 03:59:17,520 --> 03:59:21,760 going to be width three and height three 6276 03:59:19,479 --> 03:59:23,239 as well but someone's got to implement 6277 03:59:21,760 --> 03:59:24,960 this and at the moment there's only me 6278 03:59:23,239 --> 03:59:26,880 at the keyboard so let's go ahead and 6279 03:59:24,960 --> 03:59:28,560 Implement that square let me go ahead 6280 03:59:26,880 --> 03:59:31,239 and Define a function called print 6281 03:59:28,560 --> 03:59:34,319 square that takes in a specific size 6282 03:59:31,239 --> 03:59:35,840 both for height and for width and here's 6283 03:59:34,319 --> 03:59:37,600 where we have an opportunity to use some 6284 03:59:35,840 --> 03:59:40,080 of those loops and we can use those 6285 03:59:37,600 --> 03:59:43,359 Loops in a way we haven't yet if I want 6286 03:59:40,080 --> 03:59:45,720 to print out all of these rows but also 6287 03:59:43,359 --> 03:59:48,000 all of these columns I now have to think 6288 03:59:45,720 --> 03:59:50,359 not just cyclically like a loop allows 6289 03:59:48,000 --> 03:59:52,000 but I need to think two-dimensionally 6290 03:59:50,359 --> 03:59:53,840 and if you're familiar with like an old 6291 03:59:52,000 --> 03:59:56,120 school typewriter or even a printer 6292 03:59:53,840 --> 03:59:58,399 nowadays It generally prints from top to 6293 03:59:56,120 --> 04:00:01,760 bottom so even if you have multiple 6294 03:59:58,399 --> 04:00:03,359 columns you print out one line at a time 6295 04:00:01,760 --> 04:00:05,040 and while you're on that line the 6296 04:00:03,359 --> 04:00:06,840 printer or the typewriter prints from 6297 04:00:05,040 --> 04:00:08,520 left to right and that's kind of the 6298 04:00:06,840 --> 04:00:10,760 mental model to have with your black and 6299 04:00:08,520 --> 04:00:13,600 white terminal window all of the output 6300 04:00:10,760 --> 04:00:16,000 for every example thus far starts at the 6301 04:00:13,600 --> 04:00:18,000 top and goes down to the bottom from top 6302 04:00:16,000 --> 04:00:21,000 to bottom left to right so we have to 6303 04:00:18,000 --> 04:00:23,439 generate our output our Square in that 6304 04:00:21,000 --> 04:00:25,840 same way so let me propose that we do 6305 04:00:23,439 --> 04:00:27,960 this let me propose that we know we need 6306 04:00:25,840 --> 04:00:30,520 to iterate this many times three or more 6307 04:00:27,960 --> 04:00:33,920 generally size so let me do this for I 6308 04:00:30,520 --> 04:00:37,120 in the range of size what do I need to 6309 04:00:33,920 --> 04:00:41,359 do three times Well I want to print out 6310 04:00:37,120 --> 04:00:43,239 what one two three rows of bricks but 6311 04:00:41,359 --> 04:00:46,399 within each row of bricks what do I want 6312 04:00:43,239 --> 04:00:48,600 to print one two three bricks 6313 04:00:46,399 --> 04:00:50,800 specifically so if we go back to our 6314 04:00:48,600 --> 04:00:55,279 diagram here and I stipulate that it's 6315 04:00:50,800 --> 04:00:57,760 indeed meant to be a 3X3 Square three 6316 04:00:55,279 --> 04:01:00,159 wide and three tall what do I want to do 6317 04:00:57,760 --> 04:01:03,680 to print the first row I want to print 6318 04:01:00,159 --> 04:01:05,279 brick brick brick brick brick what do I 6319 04:01:03,680 --> 04:01:07,040 want to print on the second row brick 6320 04:01:05,279 --> 04:01:10,399 brick brick and the third row brick 6321 04:01:07,040 --> 04:01:12,800 brick brick so I'm doing three things 6322 04:01:10,399 --> 04:01:14,680 three times there's a lot of printing 6323 04:01:12,800 --> 04:01:17,199 that must happen so so let me go back to 6324 04:01:14,680 --> 04:01:19,640 my code here and let me propose now that 6325 04:01:17,199 --> 04:01:23,279 we think of this outer loop that I've 6326 04:01:19,640 --> 04:01:27,199 just started as representing each of our 6327 04:01:23,279 --> 04:01:29,399 rows for I in range of size is going to 6328 04:01:27,199 --> 04:01:33,439 ensure no matter what I do next that I 6329 04:01:29,399 --> 04:01:36,040 can print out one two three rows or more 6330 04:01:33,439 --> 04:01:38,600 generally size where size could be three 6331 04:01:36,040 --> 04:01:40,920 but it could be smaller or larger what 6332 04:01:38,600 --> 04:01:42,720 do I want to do on each of the rows well 6333 04:01:40,920 --> 04:01:45,479 just like an old school typewriter or 6334 04:01:42,720 --> 04:01:47,800 printer on each row I want to print out 6335 04:01:45,479 --> 04:01:49,800 brick brick brick brick brick brick 6336 04:01:47,800 --> 04:01:52,319 brick brick brick well that sounds like 6337 04:01:49,800 --> 04:01:55,080 a cycle some kind of loop so maybe I can 6338 04:01:52,319 --> 04:01:56,479 have inside of one Loop another loop I 6339 04:01:55,080 --> 04:01:58,439 don't want to use I again because I 6340 04:01:56,479 --> 04:02:00,560 don't want to use the same variable and 6341 04:01:58,439 --> 04:02:03,399 mess up my counting so I'm going to by 6342 04:02:00,560 --> 04:02:05,600 convention use J very common to use I 6343 04:02:03,399 --> 04:02:07,359 and then J maybe K but after that you 6344 04:02:05,600 --> 04:02:09,720 shouldn't keep nesting inside of each 6345 04:02:07,359 --> 04:02:12,359 other let me go ahead and say for J in 6346 04:02:09,720 --> 04:02:14,640 range of size two because it's a square 6347 04:02:12,359 --> 04:02:19,319 and then each of these rows let me print 6348 04:02:14,640 --> 04:02:23,120 out a single hash but no new line but 6349 04:02:19,319 --> 04:02:25,920 after each row let me print only a new 6350 04:02:23,120 --> 04:02:27,319 line so there's a lot going on here 6351 04:02:25,920 --> 04:02:30,439 especially if you've never touched 6352 04:02:27,319 --> 04:02:32,239 python let alone Loops but notice what 6353 04:02:30,439 --> 04:02:37,720 I've done here too and I'll add some 6354 04:02:32,239 --> 04:02:44,319 comments for clarity for each row in 6355 04:02:37,720 --> 04:02:47,800 square for each uh brick in row 6356 04:02:44,319 --> 04:02:49,880 print brick and here is where comments 6357 04:02:47,800 --> 04:02:51,880 and more generally pseudo code can 6358 04:02:49,880 --> 04:02:54,159 really help explain to yourself and 6359 04:02:51,880 --> 04:02:56,920 others what your lines of code are doing 6360 04:02:54,159 --> 04:02:59,520 on line eight I'm iterating from I 6361 04:02:56,920 --> 04:03:02,560 equals 0 on up to side so 6362 04:02:59,520 --> 04:03:05,319 012 on line 11 I'm doing the exact same 6363 04:03:02,560 --> 04:03:07,920 thing but using J from 012 but that's 6364 04:03:05,319 --> 04:03:10,880 good because I represents now each of my 6365 04:03:07,920 --> 04:03:12,920 rows and while I'm on each of those rows 6366 04:03:10,880 --> 04:03:16,520 inside of this outer loop I'm going to 6367 04:03:12,920 --> 04:03:18,640 do brick brick brick 1 two 3 1 2 3 1 2 3 6368 04:03:16,520 --> 04:03:20,880 but I don't want my cursor to keep 6369 04:03:18,640 --> 04:03:23,760 moving to the next line while I'm on a 6370 04:03:20,880 --> 04:03:25,960 row so I'm just overriding that line 6371 04:03:23,760 --> 04:03:29,880 ending but let me ask a question of the 6372 04:03:25,960 --> 04:03:32,479 group now why on line 16 do I have a 6373 04:03:29,880 --> 04:03:36,159 print here all by 6374 04:03:32,479 --> 04:03:40,199 itself why do I have a print all by 6375 04:03:36,159 --> 04:03:44,720 itself notice that it's below the inner 6376 04:03:40,199 --> 04:03:48,960 loop but inside of the Outer Loop so to 6377 04:03:44,720 --> 04:03:52,000 speak what is that loop on line 16 doing 6378 04:03:48,960 --> 04:03:55,439 ultimately every time you finish a line 6379 04:03:52,000 --> 04:04:00,560 you have to add a new line and at the 6380 04:03:55,439 --> 04:04:02,680 end of it so print it prints a new line 6381 04:04:00,560 --> 04:04:04,680 perfect I don't want a new line after 6382 04:04:02,680 --> 04:04:06,640 every brick I only want to do that at 6383 04:04:04,680 --> 04:04:08,920 the end of the row and that's why my 6384 04:04:06,640 --> 04:04:12,040 comments now are perhaps enlightening 6385 04:04:08,920 --> 04:04:14,840 notice that this Loop here is just 6386 04:04:12,040 --> 04:04:17,120 iterating for each brick in in the row 6387 04:04:14,840 --> 04:04:18,800 once I'm done with that inner loop so to 6388 04:04:17,120 --> 04:04:20,960 speak once I'm done with these 6389 04:04:18,800 --> 04:04:23,199 highlighted lines here to Evelyn's point 6390 04:04:20,960 --> 04:04:24,479 I need to print out one blank new line 6391 04:04:23,199 --> 04:04:26,800 and we've not done this before but when 6392 04:04:24,479 --> 04:04:29,080 you call print with no arguments all you 6393 04:04:26,800 --> 04:04:31,239 get is that automatic line ending the 6394 04:04:29,080 --> 04:04:34,359 back slash end where the cursor moves to 6395 04:04:31,239 --> 04:04:37,040 the next line so if I now roll go back 6396 04:04:34,359 --> 04:04:40,399 to my terminal window and run mario. I 6397 04:04:37,040 --> 04:04:41,760 think I should get a 3X3 square and it 6398 04:04:40,399 --> 04:04:43,159 doesn't quite look like a square on my 6399 04:04:41,760 --> 04:04:46,080 screen because these hashes are a little 6400 04:04:43,159 --> 04:04:48,640 taller they are wide but it is in fact 6401 04:04:46,080 --> 04:04:50,359 3x3 but let me propose as we've always 6402 04:04:48,640 --> 04:04:53,120 done here how we might tighten up this 6403 04:04:50,359 --> 04:04:55,359 code further just for clarity sake let 6404 04:04:53,120 --> 04:04:57,239 me get rid of my comments for a moment 6405 04:04:55,359 --> 04:05:00,080 just so we can see how many lines of 6406 04:04:57,239 --> 04:05:03,080 code we have total and let me propose 6407 04:05:00,080 --> 04:05:05,000 that we maybe do this let me propose 6408 04:05:03,080 --> 04:05:06,359 that you know what this inner loop 6409 04:05:05,000 --> 04:05:08,239 especially if you're having trouble 6410 04:05:06,359 --> 04:05:10,080 wrapping your mind around one Loop 6411 04:05:08,239 --> 04:05:11,720 inside of another loop you don't 6412 04:05:10,080 --> 04:05:14,439 strictly need it what if we do this 6413 04:05:11,720 --> 04:05:17,319 trick again what if we print out out 6414 04:05:14,439 --> 04:05:19,319 inside of the outer and only Loop each 6415 04:05:17,319 --> 04:05:21,800 of those hashes times the number of 6416 04:05:19,319 --> 04:05:23,720 times we want them right we draw 6417 04:05:21,800 --> 04:05:27,239 inspiration from an earlier approach and 6418 04:05:23,720 --> 04:05:29,960 we run python now of Mario same result 6419 04:05:27,239 --> 04:05:32,880 but now print square is really nice and 6420 04:05:29,960 --> 04:05:34,800 compact it has one explicit Loop and 6421 04:05:32,880 --> 04:05:37,439 it's still printing out using string 6422 04:05:34,800 --> 04:05:40,520 multiplication all of the hashes at once 6423 04:05:37,439 --> 04:05:42,640 on that row if you like abstraction and 6424 04:05:40,520 --> 04:05:44,520 you'd like to wrap your mind more around 6425 04:05:42,640 --> 04:05:46,600 what the code is doing well let's do 6426 04:05:44,520 --> 04:05:48,000 this if you're not quite clear on what's 6427 04:05:46,600 --> 04:05:50,199 going on let's propose that you 6428 04:05:48,000 --> 04:05:52,479 implement a function called print row 6429 04:05:50,199 --> 04:05:55,359 passing in size and let me propose that 6430 04:05:52,479 --> 04:05:59,279 this print row function it simply take 6431 04:05:55,359 --> 04:06:02,560 in that width and print out the 6432 04:05:59,279 --> 04:06:05,199 individual hash times that many times in 6433 04:06:02,560 --> 04:06:07,239 other words here's an opportunity for 6434 04:06:05,199 --> 04:06:09,000 abstraction whereby well what does it 6435 04:06:07,239 --> 04:06:11,040 mean to print a row well when you're 6436 04:06:09,000 --> 04:06:13,279 implementing print Square I don't really 6437 04:06:11,040 --> 04:06:15,319 care what it means to print a row I just 6438 04:06:13,279 --> 04:06:17,760 need to know that someone's taking care 6439 04:06:15,319 --> 04:06:20,159 of printing the row you can kind of pass 6440 04:06:17,760 --> 04:06:21,960 the buck to another function Al together 6441 04:06:20,159 --> 04:06:24,000 and how does print row work well it 6442 04:06:21,960 --> 04:06:26,439 could use a for Loop it could use this 6443 04:06:24,000 --> 04:06:28,640 string multiplication trick this is a 6444 04:06:26,439 --> 04:06:30,120 way to take a larger program and this is 6445 04:06:28,640 --> 04:06:33,439 probably the most complicated one we've 6446 04:06:30,120 --> 04:06:36,000 looked at thus far and to decompose it 6447 04:06:33,439 --> 04:06:40,159 into these smaller components that once 6448 04:06:36,000 --> 04:06:42,359 assembled achieve your final idea seeing 6449 04:06:40,159 --> 04:06:44,439 no questions that's the end of our look 6450 04:06:42,359 --> 04:06:46,239 at Loops in Python this ability to do 6451 04:06:44,439 --> 04:06:48,120 things cyclically again and again and 6452 04:06:46,239 --> 04:06:50,080 when we combine those with conditionals 6453 04:06:48,120 --> 04:06:51,560 this ability to ask and answer questions 6454 04:06:50,080 --> 04:06:53,920 and combine them with our functions and 6455 04:06:51,560 --> 04:06:55,960 variables we really now have most of the 6456 04:06:53,920 --> 04:06:57,560 building blocks we need to solve much 6457 04:06:55,960 --> 04:06:59,159 larger much more interesting much more 6458 04:06:57,560 --> 04:07:01,319 personal questions so in the weeks to 6459 04:06:59,159 --> 04:07:03,640 come we'll start to see exactly what 6460 04:07:01,319 --> 04:07:05,000 could go wrong though when we do so but 6461 04:07:03,640 --> 04:07:06,840 we'll introduce you to all the more 6462 04:07:05,000 --> 04:07:10,319 tools via which you can troubleshoot 6463 04:07:06,840 --> 04:07:10,319 those same problems 6464 04:07:14,420 --> 04:07:23,240 [Music] 6465 04:07:25,290 --> 04:07:32,149 [Music] 6466 04:07:34,359 --> 04:07:39,439 all right this is cs50's Introduction to 6467 04:07:37,520 --> 04:07:42,080 programming with python my name is David 6468 04:07:39,439 --> 04:07:44,000 men and this is our week on exceptions 6469 04:07:42,080 --> 04:07:46,439 exceptions in python as well as in other 6470 04:07:44,000 --> 04:07:48,319 programming languages refer to problems 6471 04:07:46,439 --> 04:07:50,439 in your code indeed when something is 6472 04:07:48,319 --> 04:07:52,119 exceptional in your program it actually 6473 04:07:50,439 --> 04:07:54,040 doesn't mean it's a good thing it means 6474 04:07:52,119 --> 04:07:56,040 something has gone wrong that ideally 6475 04:07:54,040 --> 04:07:57,720 you will somehow solve so what are some 6476 04:07:56,040 --> 04:07:59,319 of the things that can go wrong so I'm 6477 04:07:57,720 --> 04:08:01,560 going to go ahead and open up VSS code 6478 04:07:59,319 --> 04:08:02,800 on my computer here and in the terminal 6479 04:08:01,560 --> 04:08:05,319 window I'm going to go ahead and run 6480 04:08:02,800 --> 04:08:07,159 code of hello.py that's going to of 6481 04:08:05,319 --> 04:08:09,359 course open up a brand new tab for me 6482 04:08:07,159 --> 04:08:10,760 hello.py in which I can write my code 6483 04:08:09,359 --> 04:08:12,520 and let me go ahead and write some very 6484 04:08:10,760 --> 04:08:14,680 simple code just to say hello to the 6485 04:08:12,520 --> 04:08:19,199 world let's go ah head and say print 6486 04:08:14,680 --> 04:08:21,880 quote hello comma world and then let me 6487 04:08:19,199 --> 04:08:23,279 go ahead and I'm forgetting to close 6488 04:08:21,880 --> 04:08:24,800 that quote so a mistake that you 6489 04:08:23,279 --> 04:08:26,520 yourself might have already made or 6490 04:08:24,800 --> 04:08:28,040 might surely in the future make and it's 6491 04:08:26,520 --> 04:08:29,199 a little subtle because you might not 6492 04:08:28,040 --> 04:08:31,319 necessarily notice that you've just 6493 04:08:29,199 --> 04:08:33,600 missed that one character well let me go 6494 04:08:31,319 --> 04:08:35,319 ahead and somewhat optimistically go 6495 04:08:33,600 --> 04:08:38,560 down to my terminal window now and run 6496 04:08:35,319 --> 04:08:40,319 python of hello.py and hit enter and 6497 04:08:38,560 --> 04:08:41,960 that's the first of my errors my gosh 6498 04:08:40,319 --> 04:08:43,680 I've only written one line of code and I 6499 04:08:41,960 --> 04:08:45,600 seem to have more lines of error errors 6500 04:08:43,680 --> 04:08:47,560 on the screen but the Salient point is 6501 04:08:45,600 --> 04:08:50,199 this bottommost thing here notice where 6502 04:08:47,560 --> 04:08:51,960 it says syntax error a syntax error is a 6503 04:08:50,199 --> 04:08:53,960 problem with the code that you have 6504 04:08:51,960 --> 04:08:55,840 typed your syntax just like English and 6505 04:08:53,960 --> 04:08:57,920 other human languages have syntax 6506 04:08:55,840 --> 04:09:00,439 associated with them so does my code and 6507 04:08:57,920 --> 04:09:02,520 it's not quite correct something is ay I 6508 04:09:00,439 --> 04:09:04,199 didn't follow the instructions properly 6509 04:09:02,520 --> 04:09:06,560 and it does elaborate for me 6510 04:09:04,199 --> 04:09:08,560 unterminated string literal now that's a 6511 04:09:06,560 --> 04:09:10,760 bit Arcane that is a bit of a confusing 6512 04:09:08,560 --> 04:09:12,720 error message but unterminated would 6513 04:09:10,760 --> 04:09:15,199 generally mean that I started something 6514 04:09:12,720 --> 04:09:17,239 but didn't stop it I didn't terminate it 6515 04:09:15,199 --> 04:09:19,159 string of course is a sequence of text 6516 04:09:17,239 --> 04:09:21,600 like we've discussed before or stir in 6517 04:09:19,159 --> 04:09:23,080 Python and literal generally refers to 6518 04:09:21,600 --> 04:09:25,159 something that you literally typed it's 6519 04:09:23,080 --> 04:09:28,520 not a variable it's something like quote 6520 04:09:25,159 --> 04:09:31,040 unquote or just quote hello world so the 6521 04:09:28,520 --> 04:09:33,319 fix here of course is going to be to go 6522 04:09:31,040 --> 04:09:35,479 ahead and terminate that string and 6523 04:09:33,319 --> 04:09:37,439 actually close the quote and if I now go 6524 04:09:35,479 --> 04:09:40,720 back down into my terminal window and 6525 04:09:37,439 --> 04:09:42,840 rerun python of hello.py now I'm saying 6526 04:09:40,720 --> 04:09:45,520 hello to the world so the catch withd 6527 04:09:42,840 --> 04:09:48,159 syntax errors here is that syntax errors 6528 04:09:45,520 --> 04:09:49,880 are entirely on you to solve a syntax 6529 04:09:48,159 --> 04:09:51,159 error is a problem that you've got to go 6530 04:09:49,880 --> 04:09:53,560 back into your code and fix from the 6531 04:09:51,159 --> 04:09:55,960 Geto you can't just kind of hope that 6532 04:09:53,560 --> 04:09:57,680 it's going to resolve itself or expect 6533 04:09:55,960 --> 04:10:00,040 that other parts of your code will catch 6534 04:09:57,680 --> 04:10:02,040 it for you syntax errors just must be 6535 04:10:00,040 --> 04:10:03,720 fixed but there's a lot of other types 6536 04:10:02,040 --> 04:10:06,319 of errors in Python that might be 6537 04:10:03,720 --> 04:10:08,319 described as runtime errors that happen 6538 04:10:06,319 --> 04:10:10,080 while your code is running and it's 6539 04:10:08,319 --> 04:10:12,720 really up to you to write some 6540 04:10:10,080 --> 04:10:14,319 additional code defensively to detect 6541 04:10:12,720 --> 04:10:16,199 when those errors happen because you 6542 04:10:14,319 --> 04:10:18,040 don't necessarily know for instance what 6543 04:10:16,199 --> 04:10:19,640 input humans are going to type into your 6544 04:10:18,040 --> 04:10:21,880 program and so you better be ready 6545 04:10:19,640 --> 04:10:24,600 defensively to accommodate things that 6546 04:10:21,880 --> 04:10:26,640 they type or even mistype so for 6547 04:10:24,600 --> 04:10:28,920 instance let's go back over here to vs 6548 04:10:26,640 --> 04:10:30,760 code and let me propose that we take a 6549 04:10:28,920 --> 04:10:32,880 look at a a new file Al together I'm 6550 04:10:30,760 --> 04:10:36,520 going to close hello.py and I'm going to 6551 04:10:32,880 --> 04:10:38,800 write code of say number. piy so let's 6552 04:10:36,520 --> 04:10:39,960 play around with some numbers in Python 6553 04:10:38,800 --> 04:10:42,840 and the first thing I'm going to go 6554 04:10:39,960 --> 04:10:44,720 ahead here and do with number. py after 6555 04:10:42,840 --> 04:10:46,600 opening the this new tab is I think I'm 6556 04:10:44,720 --> 04:10:48,520 going to go ahead and print uh type up a 6557 04:10:46,600 --> 04:10:51,159 relatively simple program that maybe 6558 04:10:48,520 --> 04:10:52,960 prompts the user for an integer like X 6559 04:10:51,159 --> 04:10:54,560 and then just prints out what x is so 6560 04:10:52,960 --> 04:10:56,279 we're going to start super simple but 6561 04:10:54,560 --> 04:10:58,439 again in starting simple we'll be able 6562 04:10:56,279 --> 04:10:59,880 to really see where I've done something 6563 04:10:58,439 --> 04:11:02,279 wrong well here we go I'm going to go 6564 04:10:59,880 --> 04:11:05,760 ahead and say a variable called X is 6565 04:11:02,279 --> 04:11:08,159 going to get assigned the value of the 6566 04:11:05,760 --> 04:11:10,080 return value of input quote unquote 6567 04:11:08,159 --> 04:11:11,800 what's X question mark and I'm going to 6568 04:11:10,080 --> 04:11:13,800 include a space to move the cursor over 6569 04:11:11,800 --> 04:11:15,560 a little bit and then ultimately I'm 6570 04:11:13,800 --> 04:11:17,359 going to go ahead and oh wait a minute 6571 04:11:15,560 --> 04:11:19,840 if I'm wanting to get an INT from the 6572 04:11:17,359 --> 04:11:21,960 user recall that I need to do something 6573 04:11:19,840 --> 04:11:25,119 proactively I need to actually convert 6574 04:11:21,960 --> 04:11:26,880 that input to an integer using the int 6575 04:11:25,119 --> 04:11:29,279 function in Python so now I'm passing 6576 04:11:26,880 --> 04:11:31,680 the return value of input as the 6577 04:11:29,279 --> 04:11:33,840 argument to in and that will store in X 6578 04:11:31,680 --> 04:11:35,600 ultimately an integer not a string that 6579 04:11:33,840 --> 04:11:37,199 looks like an integer all right let me 6580 04:11:35,600 --> 04:11:38,560 go ahead now and just quite simply print 6581 04:11:37,199 --> 04:11:42,680 out what this is I'm going to go ahead 6582 04:11:38,560 --> 04:11:44,880 and print out uh quote unquote X is X 6583 04:11:42,680 --> 04:11:46,479 but I don't want to literally say x is X 6584 04:11:44,880 --> 04:11:48,359 I want to plug in the value of x so 6585 04:11:46,479 --> 04:11:50,560 maybe the easiest way to do that is to 6586 04:11:48,359 --> 04:11:52,359 surround it with curly braces and then 6587 04:11:50,560 --> 04:11:55,040 if I'm using these curly braces and I 6588 04:11:52,359 --> 04:11:57,279 want python to interpolate the value of 6589 04:11:55,040 --> 04:11:58,840 that variable that is substitute what x 6590 04:11:57,279 --> 04:12:00,680 actually is in between those curly 6591 04:11:58,840 --> 04:12:02,319 braces recall that I need to use a 6592 04:12:00,680 --> 04:12:05,239 format string or an F string by 6593 04:12:02,319 --> 04:12:06,640 prefixing this whole thing with an F now 6594 04:12:05,239 --> 04:12:08,159 that I've done that let's go ahead and 6595 04:12:06,640 --> 04:12:10,800 see what happens I'm going to go ahead 6596 04:12:08,159 --> 04:12:13,520 in my terminal window and run python of 6597 04:12:10,800 --> 04:12:15,159 number. Pi I hit enter and so far so 6598 04:12:13,520 --> 04:12:17,279 good all is well and being prompted for 6599 04:12:15,159 --> 04:12:19,920 X let me go ahead and type in a number 6600 04:12:17,279 --> 04:12:21,600 like 50 all right that seems to work 6601 04:12:19,920 --> 04:12:23,880 program seems to be 6602 04:12:21,600 --> 04:12:27,199 correct or is 6603 04:12:23,880 --> 04:12:29,600 it what could go wrong in this program 6604 04:12:27,199 --> 04:12:31,960 even though nothing did just go wrong 6605 04:12:29,600 --> 04:12:34,199 but if I run it and run it and run it 6606 04:12:31,960 --> 04:12:36,760 again during the running of my program 6607 04:12:34,199 --> 04:12:38,840 what could still go wrong especially if 6608 04:12:36,760 --> 04:12:41,159 I'm not the human interacting with it 6609 04:12:38,840 --> 04:12:44,119 but some other Human Instead any 6610 04:12:41,159 --> 04:12:46,640 volunteers here for this one 6611 04:12:44,119 --> 04:12:50,239 what could go wrong and in what way is 6612 04:12:46,640 --> 04:12:53,600 this program not really correct even 6613 04:12:50,239 --> 04:12:55,159 though at first glance it seems so what 6614 04:12:53,600 --> 04:13:00,000 what is an 6615 04:12:55,159 --> 04:13:03,600 inter we code in in a integrated 6616 04:13:00,000 --> 04:13:05,560 ID we can't code in a interpreter so I'm 6617 04:13:03,600 --> 04:13:06,840 not calling an integer I'm still having 6618 04:13:05,560 --> 04:13:08,800 trouble hearing you but what I think I 6619 04:13:06,840 --> 04:13:10,760 heard is that if the what the user types 6620 04:13:08,800 --> 04:13:14,319 in is not in fact an integer I can't 6621 04:13:10,760 --> 04:13:15,640 just blindly convert it to an int if I'm 6622 04:13:14,319 --> 04:13:17,720 not putting too many words into your 6623 04:13:15,640 --> 04:13:21,399 mouth I think what I should perhaps do 6624 04:13:17,720 --> 04:13:23,640 here is be a little defensive and let me 6625 04:13:21,399 --> 04:13:25,000 see if I can't simulate exactly the 6626 04:13:23,640 --> 04:13:27,560 problem that could go wrong here let me 6627 04:13:25,000 --> 04:13:29,439 go ahead and run again python of number. 6628 04:13:27,560 --> 04:13:31,279 piy let me try another number and in 6629 04:13:29,439 --> 04:13:33,319 fact when testing your code generally 6630 04:13:31,279 --> 04:13:35,680 it's a good idea to test Corner cases 6631 04:13:33,319 --> 04:13:38,920 maybe numbers that aren't quite as plain 6632 04:13:35,680 --> 04:13:40,040 as 50 or 49 or 51 let's choose some 6633 04:13:38,920 --> 04:13:41,920 numbers that might be a little more 6634 04:13:40,040 --> 04:13:44,439 interesting if only mathematically like 6635 04:13:41,920 --> 04:13:46,000 zero all right Z seems to work my code 6636 04:13:44,439 --> 04:13:47,960 still prints out that X is Zer what 6637 04:13:46,000 --> 04:13:49,479 might be another Corner case to consider 6638 04:13:47,960 --> 04:13:51,520 well let me go ahead and try a negative 6639 04:13:49,479 --> 04:13:54,319 number that too is pretty different in 6640 04:13:51,520 --> 04:13:56,080 spirit from 50 negative 1 okay that 6641 04:13:54,319 --> 04:13:57,680 works too well let me try it one more 6642 04:13:56,080 --> 04:13:59,680 time I've tried positive numbers 6643 04:13:57,680 --> 04:14:02,720 negative numbers zero let me try 6644 04:13:59,680 --> 04:14:04,800 something like a cat so literally C A 6645 04:14:02,720 --> 04:14:06,960 typing in a string that doesn't even 6646 04:14:04,800 --> 04:14:09,720 look like a number and yet let's see now 6647 04:14:06,960 --> 04:14:11,279 what happens when I hit enter all right 6648 04:14:09,720 --> 04:14:13,439 we'll see now we've got another kind of 6649 04:14:11,279 --> 04:14:15,399 error it's not a syntax error because I 6650 04:14:13,439 --> 04:14:18,119 didn't make a typographical mistake I 6651 04:14:15,399 --> 04:14:20,520 didn't forget some piece of syntax I 6652 04:14:18,119 --> 04:14:22,199 actually now have a error with one of my 6653 04:14:20,520 --> 04:14:24,399 values and it's a value I didn't even 6654 04:14:22,199 --> 04:14:27,239 anticipate the human me in this case 6655 04:14:24,399 --> 04:14:29,600 typed it in long after I wrote the code 6656 04:14:27,239 --> 04:14:31,439 so what does this refer to a value error 6657 04:14:29,600 --> 04:14:34,239 well let's see what the explanation is 6658 04:14:31,439 --> 04:14:36,279 invalid literal for INT with base 10 6659 04:14:34,239 --> 04:14:37,960 quote unquote cat now this to is a bit 6660 04:14:36,279 --> 04:14:39,359 of a mouthful and unfortunately in 6661 04:14:37,960 --> 04:14:41,359 python and a lot of programming 6662 04:14:39,359 --> 04:14:43,560 languages the error messages are written 6663 04:14:41,359 --> 04:14:44,680 for pretty comfortable program and of 6664 04:14:43,560 --> 04:14:46,439 course when you're learning programming 6665 04:14:44,680 --> 04:14:47,800 for the first time you might not be so 6666 04:14:46,439 --> 04:14:49,920 comfortable with the programming 6667 04:14:47,800 --> 04:14:51,720 language let alone the error messages 6668 04:14:49,920 --> 04:14:54,319 but let's see if we can't glean some 6669 04:14:51,720 --> 04:14:56,080 insight so invalid literal well again a 6670 04:14:54,319 --> 04:14:59,080 literal is just something that's been 6671 04:14:56,080 --> 04:15:01,159 typed in it would seem for INT what is 6672 04:14:59,080 --> 04:15:04,159 int exactly well int is the function I'm 6673 04:15:01,159 --> 04:15:05,880 using to convert the user's input to a 6674 04:15:04,159 --> 04:15:08,040 corresponding integer base 10 that 6675 04:15:05,880 --> 04:15:10,279 refers to the decimal system uh which is 6676 04:15:08,040 --> 04:15:11,880 this the default that Python's using and 6677 04:15:10,279 --> 04:15:13,399 it looks like at the end of the day what 6678 04:15:11,880 --> 04:15:16,680 python really doesn't like is that I 6679 04:15:13,399 --> 04:15:19,520 passed Cat quote unquote to the int 6680 04:15:16,680 --> 04:15:22,119 function so how do I go about actually 6681 04:15:19,520 --> 04:15:24,279 fixing this problem well I could just 6682 04:15:22,119 --> 04:15:25,600 add instructions in my program maybe I 6683 04:15:24,279 --> 04:15:28,000 could add a line of print telling the 6684 04:15:25,600 --> 04:15:30,439 user more explicitly be sure to type an 6685 04:15:28,000 --> 04:15:32,600 integer or please don't type cap please 6686 04:15:30,439 --> 04:15:34,119 don't type strings of course the user 6687 04:15:32,600 --> 04:15:36,080 might still not oblig they might not be 6688 04:15:34,119 --> 04:15:37,680 reading the instructions so that too is 6689 04:15:36,080 --> 04:15:39,680 probably not an effective strategy what 6690 04:15:37,680 --> 04:15:41,680 we really want to do is write our code 6691 04:15:39,680 --> 04:15:43,159 with error handling in mind we want to 6692 04:15:41,680 --> 04:15:44,920 write lines of code that not only 6693 04:15:43,159 --> 04:15:47,880 accomplish the problems we care about 6694 04:15:44,920 --> 04:15:50,119 but that also handle errors that might 6695 04:15:47,880 --> 04:15:51,960 unexpectedly happen and in general when 6696 04:15:50,119 --> 04:15:53,640 programming programming defensively 6697 04:15:51,960 --> 04:15:55,159 assume that the users aren't going to be 6698 04:15:53,640 --> 04:15:57,279 paying attention or Worse they're 6699 04:15:55,159 --> 04:15:59,119 malicious they're trying to crash your 6700 04:15:57,279 --> 04:16:01,319 program so we want to handle as many 6701 04:15:59,119 --> 04:16:03,359 errors as we can now how do we go about 6702 04:16:01,319 --> 04:16:05,880 doing that in Python well it turns out 6703 04:16:03,359 --> 04:16:08,080 whether you want to catch a value error 6704 04:16:05,880 --> 04:16:10,159 or other types of errors as well though 6705 04:16:08,080 --> 04:16:12,159 not syntax error python actually has 6706 04:16:10,159 --> 04:16:14,600 this keyword called try and it's sort of 6707 04:16:12,159 --> 04:16:16,560 aptly named if you want to try to do 6708 04:16:14,600 --> 04:16:19,040 something in Python you can literally 6709 04:16:16,560 --> 04:16:21,080 use this keyword and you can check 6710 04:16:19,040 --> 04:16:23,159 whether or not something exceptional 6711 04:16:21,080 --> 04:16:25,399 something erroneous has happened so 6712 04:16:23,159 --> 04:16:28,760 using both try and this other keyword 6713 04:16:25,399 --> 04:16:31,080 except can I go and try to do something 6714 04:16:28,760 --> 04:16:33,119 except if something goes wrong I can do 6715 04:16:31,080 --> 04:16:36,119 something else instead so let's consider 6716 04:16:33,119 --> 04:16:37,920 how can I go about trying to convert the 6717 04:16:36,119 --> 04:16:39,760 user's input to an INT except if 6718 04:16:37,920 --> 04:16:42,159 something goes wrong well let me go back 6719 04:16:39,760 --> 04:16:44,880 to my code here and let me propose that 6720 04:16:42,159 --> 04:16:47,040 I now modify this example as follows let 6721 04:16:44,880 --> 04:16:49,640 me go ahead and above my first line of 6722 04:16:47,040 --> 04:16:52,080 code I literally write try and a colon 6723 04:16:49,640 --> 04:16:53,560 telling python try to do the following 6724 04:16:52,080 --> 04:16:55,720 I'm going to go ahead and indent my 6725 04:16:53,560 --> 04:16:57,840 existing lines of codes here by the same 6726 04:16:55,720 --> 04:16:59,560 number of spaces four in this case and 6727 04:16:57,840 --> 04:17:02,199 then I'm going to add one more new line 6728 04:16:59,560 --> 04:17:04,319 down here that literally says accept 6729 04:17:02,199 --> 04:17:06,000 value error and notice it's important 6730 04:17:04,319 --> 04:17:08,520 that I've capitalized the V and I've 6731 04:17:06,000 --> 04:17:10,520 capitalized the E these uh symbols are 6732 04:17:08,520 --> 04:17:13,359 case sensitive and this is now an 6733 04:17:10,520 --> 04:17:16,159 opportunity after this colon to tell 6734 04:17:13,359 --> 04:17:19,119 python what I want to do in exceptional 6735 04:17:16,159 --> 04:17:21,199 cases when the number or the input from 6736 04:17:19,119 --> 04:17:22,880 the user is not in fact a number and I'm 6737 04:17:21,199 --> 04:17:26,000 going to say something plain like print 6738 04:17:22,880 --> 04:17:28,040 quote unquote X is not an integer I'm at 6739 04:17:26,000 --> 04:17:30,319 least going to tell the user roughly 6740 04:17:28,040 --> 04:17:32,000 what the problem actually is so notice 6741 04:17:30,319 --> 04:17:34,520 another detail the indentation is 6742 04:17:32,000 --> 04:17:36,680 important because I have try on line one 6743 04:17:34,520 --> 04:17:38,279 and I've indented lines two and three 6744 04:17:36,680 --> 04:17:41,080 those are the two lines of code that I'm 6745 04:17:38,279 --> 04:17:43,439 trying except if I see a value error 6746 04:17:41,080 --> 04:17:45,920 line five because it's indented is what 6747 04:17:43,439 --> 04:17:47,960 is going to get executed in cases of 6748 04:17:45,920 --> 04:17:50,640 those errors let me go ahead now back to 6749 04:17:47,960 --> 04:17:54,720 my terminal window and run python of 6750 04:17:50,640 --> 04:17:57,319 hello of python of number. piy enter and 6751 04:17:54,720 --> 04:17:58,840 let's go ahead and type in 50 again 6752 04:17:57,319 --> 04:18:00,720 still seems to work and of course I'm 6753 04:17:58,840 --> 04:18:02,399 trying and succeeding let me go ahead 6754 04:18:00,720 --> 04:18:04,359 and try once more this time though with 6755 04:18:02,399 --> 04:18:07,080 the word cat or really anything that's 6756 04:18:04,359 --> 04:18:09,680 not a decimal number and now you'll see 6757 04:18:07,080 --> 04:18:11,319 much more cleanly X is not an integer 6758 04:18:09,680 --> 04:18:13,040 I'm not seeing some scary error message 6759 04:18:11,319 --> 04:18:15,199 that I of a user am have going to have 6760 04:18:13,040 --> 04:18:16,760 no idea how to handle now you the 6761 04:18:15,199 --> 04:18:18,560 programmer have anticipated that 6762 04:18:16,760 --> 04:18:20,439 something exceptional can happen and 6763 04:18:18,560 --> 04:18:23,520 you've gone about actually handling the 6764 04:18:20,439 --> 04:18:25,840 error for the user giving them an 6765 04:18:23,520 --> 04:18:27,239 appropriate error message instead let me 6766 04:18:25,840 --> 04:18:29,960 pause here and see are there any 6767 04:18:27,239 --> 04:18:33,199 questions now on what we've just done by 6768 04:18:29,960 --> 04:18:37,000 introducing try and accept to handle 6769 04:18:33,199 --> 04:18:39,040 this value error is value error the only 6770 04:18:37,000 --> 04:18:41,000 type of error you can get or the other 6771 04:18:39,040 --> 04:18:42,399 types is value error the only thing you 6772 04:18:41,000 --> 04:18:44,080 can catch there are other errors as well 6773 04:18:42,399 --> 04:18:45,800 and we'll a few of them today and 6774 04:18:44,080 --> 04:18:47,239 there's many many more honestly that if 6775 04:18:45,800 --> 04:18:48,880 you continue programming and programming 6776 04:18:47,239 --> 04:18:50,680 in Python you're going to see a lot of 6777 04:18:48,880 --> 04:18:52,920 them over the the weeks the months the 6778 04:18:50,680 --> 04:18:54,720 years to come but the technique for 6779 04:18:52,920 --> 04:18:57,720 handling them is going to be largely the 6780 04:18:54,720 --> 04:19:00,840 same other questions on try accept or 6781 04:18:57,720 --> 04:19:03,840 these exceptions more generally uh yes 6782 04:19:00,840 --> 04:19:05,560 sir actually to use the accept log you 6783 04:19:03,840 --> 04:19:07,359 need to know the type of error right 6784 04:19:05,560 --> 04:19:09,600 like here you knew it was a value error 6785 04:19:07,359 --> 04:19:11,920 what what if you can't anticipate this 6786 04:19:09,600 --> 04:19:14,239 particular type of the error a really 6787 04:19:11,920 --> 04:19:17,119 good question so I'm being very good 6788 04:19:14,239 --> 04:19:19,279 about catching so to speak the very 6789 04:19:17,119 --> 04:19:20,680 error that I know might happen I don't 6790 04:19:19,279 --> 04:19:22,119 know when it might happen because it's 6791 04:19:20,680 --> 04:19:24,119 going to depend on the user but I know 6792 04:19:22,119 --> 04:19:26,960 what kind of error will happen from the 6793 04:19:24,119 --> 04:19:28,920 int function there is a way in Python 6794 04:19:26,960 --> 04:19:31,080 where you can say except if anything 6795 04:19:28,920 --> 04:19:33,479 goes wrong and you can literally omit 6796 04:19:31,080 --> 04:19:35,439 value error and just catch everything 6797 04:19:33,479 --> 04:19:37,720 the problem with that is that it 6798 04:19:35,439 --> 04:19:39,080 sometimes hides other bugs in your code 6799 04:19:37,720 --> 04:19:40,640 because you don't necessarily know 6800 04:19:39,080 --> 04:19:42,279 what's going wrong and if you don't 6801 04:19:40,640 --> 04:19:44,680 necessarily know what's going wrong how 6802 04:19:42,279 --> 04:19:46,680 can you possibly handle it correctly so 6803 04:19:44,680 --> 04:19:48,399 bad practice and it put another way it's 6804 04:19:46,680 --> 04:19:50,439 lazy to do that to just say catch 6805 04:19:48,399 --> 04:19:52,000 everything and I'll deal with it here so 6806 04:19:50,439 --> 04:19:54,279 a much better practice would be to 6807 04:19:52,000 --> 04:19:56,560 figure out what kind of Errors could 6808 04:19:54,279 --> 04:19:58,960 happen and include mention of them 6809 04:19:56,560 --> 04:20:00,720 explicitly as I've done now with that 6810 04:19:58,960 --> 04:20:02,159 said if you read Python's official 6811 04:20:00,720 --> 04:20:04,920 documentation as you'll eventually 6812 04:20:02,159 --> 04:20:07,439 invariably do it is not great about 6813 04:20:04,920 --> 04:20:11,119 telling you proactively what kinds of 6814 04:20:07,439 --> 04:20:13,720 Errors can be raised in this way so it's 6815 04:20:11,119 --> 04:20:15,720 a bit of contradictory advice you should 6816 04:20:13,720 --> 04:20:17,479 do it this way but it's not always 6817 04:20:15,720 --> 04:20:19,439 obvious what you should be checking for 6818 04:20:17,479 --> 04:20:20,840 but you get better at it with practice 6819 04:20:19,439 --> 04:20:22,880 and some of the times the documentation 6820 04:20:20,840 --> 04:20:24,600 does spell out what could go wrong let 6821 04:20:22,880 --> 04:20:26,800 me turn our attention now back to this 6822 04:20:24,600 --> 04:20:29,520 and point out that even though this is 6823 04:20:26,800 --> 04:20:31,040 better code it is more correct in the 6824 04:20:29,520 --> 04:20:33,640 sense that I'm not just leaving it to 6825 04:20:31,040 --> 04:20:35,279 the user to see some really ugly default 6826 04:20:33,640 --> 04:20:36,840 python error message that most people 6827 04:20:35,279 --> 04:20:38,600 are going to have no idea what to do 6828 04:20:36,840 --> 04:20:40,920 with I'm at least handling it more 6829 04:20:38,600 --> 04:20:42,199 elegantly and I'm printing out X is not 6830 04:20:40,920 --> 04:20:43,199 an integer so it's at least more 6831 04:20:42,199 --> 04:20:45,080 instructive 6832 04:20:43,199 --> 04:20:47,680 but this isn't necessarily the best way 6833 04:20:45,080 --> 04:20:49,960 to implement this code why well here too 6834 04:20:47,680 --> 04:20:52,080 I'm actually still being a little lazy 6835 04:20:49,960 --> 04:20:54,439 so notice that I'm trying to do not one 6836 04:20:52,080 --> 04:20:56,159 line of code but two lines of code and 6837 04:20:54,439 --> 04:20:57,920 this isn't a huge deal because we're 6838 04:20:56,159 --> 04:21:00,279 only talking about two lines of code but 6839 04:20:57,920 --> 04:21:02,600 in the interest of PR uh preaching best 6840 04:21:00,279 --> 04:21:06,239 practices you should really only be 6841 04:21:02,600 --> 04:21:08,680 trying to do the one or very few lines 6842 04:21:06,239 --> 04:21:11,119 of code that can actually raise an 6843 04:21:08,680 --> 04:21:14,560 exception that can actually fail in some 6844 04:21:11,119 --> 04:21:16,960 way I am pretty sure that calling print 6845 04:21:14,560 --> 04:21:19,359 here is not going to raise a value error 6846 04:21:16,960 --> 04:21:21,960 whether X is an INT or a string or a 6847 04:21:19,359 --> 04:21:23,560 float or anything else the format string 6848 04:21:21,960 --> 04:21:26,279 feature of python is going to handle 6849 04:21:23,560 --> 04:21:28,119 printing it just fine so really what I'm 6850 04:21:26,279 --> 04:21:30,880 going to do is this I'm going to move 6851 04:21:28,119 --> 04:21:32,920 this line three down to the bottom of my 6852 04:21:30,880 --> 04:21:34,840 code I no longer need to indent it I'm 6853 04:21:32,920 --> 04:21:38,399 just going to execute it at the bottom 6854 04:21:34,840 --> 04:21:40,600 of my file here unfortunately by doing 6855 04:21:38,399 --> 04:21:42,680 this I've done a good thing by now only 6856 04:21:40,600 --> 04:21:45,199 trying to do the minimal amount of work 6857 04:21:42,680 --> 04:21:48,239 necessary that might raise the exception 6858 04:21:45,199 --> 04:21:50,359 a value error but I fear I've introduced 6859 04:21:48,239 --> 04:21:52,439 a new mistake well let's see what is now 6860 04:21:50,359 --> 04:21:55,040 in correct let me go ahead and again run 6861 04:21:52,439 --> 04:21:57,319 python of number. enter let me go ahead 6862 04:21:55,040 --> 04:21:59,040 and do it correctly with 50 and all 6863 04:21:57,319 --> 04:22:00,880 seems to be well but again let's try 6864 04:21:59,040 --> 04:22:02,960 those Corner cases the zeros the 6865 04:22:00,880 --> 04:22:05,199 negative numbers or in this case the cat 6866 04:22:02,960 --> 04:22:07,880 let me go ahead and type in C A again 6867 04:22:05,199 --> 04:22:09,720 enter now I have a name error so now 6868 04:22:07,880 --> 04:22:11,760 it's yet another type of error in my 6869 04:22:09,720 --> 04:22:13,840 code that I've introduced here and what 6870 04:22:11,760 --> 04:22:16,359 is this name error mean well just as a 6871 04:22:13,840 --> 04:22:18,159 value error refers to that the value of 6872 04:22:16,359 --> 04:22:20,680 some variable the value that someone has 6873 04:22:18,159 --> 04:22:22,920 typed in is incorrect name error tends 6874 04:22:20,680 --> 04:22:25,239 to refer to your code like you're doing 6875 04:22:22,920 --> 04:22:27,479 something with the name of a variable 6876 04:22:25,239 --> 04:22:28,840 that you shouldn't and why might that be 6877 04:22:27,479 --> 04:22:31,600 well let me turn our attention back to 6878 04:22:28,840 --> 04:22:33,479 the code here and consider what is it 6879 04:22:31,600 --> 04:22:36,000 complaining about well the name error is 6880 04:22:33,479 --> 04:22:39,040 what I see down here and it's telling me 6881 04:22:36,000 --> 04:22:40,640 name quote unquote X is not defined and 6882 04:22:39,040 --> 04:22:42,920 notice if I look further here it is 6883 04:22:40,640 --> 04:22:46,319 mentioning line six so I know the 6884 04:22:42,920 --> 04:22:49,199 problem is with my code on line six and 6885 04:22:46,319 --> 04:22:52,920 that worked a moment ago and I'm 6886 04:22:49,199 --> 04:22:56,399 defining X on line two but let me ask 6887 04:22:52,920 --> 04:23:00,800 the group here why does X not in fact 6888 04:22:56,399 --> 04:23:02,840 exist on line six why is it not defined 6889 04:23:00,800 --> 04:23:05,680 even though I'm pretty sure I was 6890 04:23:02,840 --> 04:23:09,399 intending to Define it on line two maybe 6891 04:23:05,680 --> 04:23:12,600 the scope of the variable is between the 6892 04:23:09,399 --> 04:23:15,000 tri block so good terminology scope 6893 04:23:12,600 --> 04:23:17,359 refers to the portion of code in which a 6894 04:23:15,000 --> 04:23:19,000 variable exists that to though isn't 6895 04:23:17,359 --> 04:23:21,600 quite right in Python that would be true 6896 04:23:19,000 --> 04:23:24,399 in cc++ in Java where indentation or 6897 04:23:21,600 --> 04:23:26,880 curly braces tend to define the scope of 6898 04:23:24,399 --> 04:23:30,359 a variable but again here in general and 6899 04:23:26,880 --> 04:23:31,760 this worked a moment ago X exists once 6900 04:23:30,359 --> 04:23:34,199 it's defined on line two because 6901 04:23:31,760 --> 04:23:37,399 remember I printed out X is 50 a little 6902 04:23:34,199 --> 04:23:41,760 bit ago let's try one more hypothesis 6903 04:23:37,399 --> 04:23:43,080 here one more hand why is X somehow 6904 04:23:41,760 --> 04:23:45,600 still not defined 6905 04:23:43,080 --> 04:23:47,800 um yeah so is it because it's loo 6906 04:23:45,600 --> 04:23:50,000 variable meaning that like it doesn't 6907 04:23:47,800 --> 04:23:52,920 Define outside of scope CU like what 6908 04:23:50,000 --> 04:23:56,239 people have mentioned it's it as it 6909 04:23:52,920 --> 04:23:57,960 promps it input in try right but outside 6910 04:23:56,239 --> 04:23:59,720 of it it's undefined so still good 6911 04:23:57,960 --> 04:24:01,560 instincts in good terminology too 6912 04:23:59,720 --> 04:24:03,399 there's this notion of local variables 6913 04:24:01,560 --> 04:24:05,399 which tend to exist inside of functions 6914 04:24:03,399 --> 04:24:07,880 for instance Global variables which tend 6915 04:24:05,399 --> 04:24:09,800 to exist in entire files in this case 6916 04:24:07,880 --> 04:24:11,880 too though that's not quite the case 6917 04:24:09,800 --> 04:24:13,760 What's Happening Here boils down to 6918 04:24:11,880 --> 04:24:15,800 order of operations let me come back to 6919 04:24:13,760 --> 04:24:17,680 the code here and recall that anytime 6920 04:24:15,800 --> 04:24:19,560 we've discussed the assignment operator 6921 04:24:17,680 --> 04:24:21,560 the single equal sign that copies a 6922 04:24:19,560 --> 04:24:23,239 value from the right to the left but 6923 04:24:21,560 --> 04:24:25,720 consider for a moment at what point 6924 04:24:23,239 --> 04:24:27,800 something is going wrong well the input 6925 04:24:25,720 --> 04:24:29,479 function is probably working just fine 6926 04:24:27,800 --> 04:24:32,479 because we've used that a lot now to get 6927 04:24:29,479 --> 04:24:34,920 users input it always returns a string 6928 04:24:32,479 --> 04:24:37,199 or a stir in Python but what could be 6929 04:24:34,920 --> 04:24:41,239 going wrong well if I'm passing that 6930 04:24:37,199 --> 04:24:44,159 string to the int function as its 6931 04:24:41,239 --> 04:24:45,920 argument it's probably the int function 6932 04:24:44,159 --> 04:24:47,920 that's airing and indeed if you think 6933 04:24:45,920 --> 04:24:49,680 back earlier when we had the value error 6934 04:24:47,920 --> 04:24:52,760 it was in fact the int function that did 6935 04:24:49,680 --> 04:24:54,840 not like quote unquote cat as input so 6936 04:24:52,760 --> 04:24:57,319 this is all to say that this portion of 6937 04:24:54,840 --> 04:24:59,640 my code highlighted now to the right of 6938 04:24:57,319 --> 04:25:01,600 the equal sign that's the code that's 6939 04:24:59,640 --> 04:25:04,439 creating a problem that's the code that 6940 04:25:01,600 --> 04:25:07,439 was creating a value error and in this 6941 04:25:04,439 --> 04:25:09,319 case we're catching the value error but 6942 04:25:07,439 --> 04:25:11,960 because the value error is happening on 6943 04:25:09,319 --> 04:25:14,319 the right of the equal sign there's no 6944 04:25:11,960 --> 04:25:16,720 value being copied to the left the error 6945 04:25:14,319 --> 04:25:19,520 is interrupting that whole process so 6946 04:25:16,720 --> 04:25:22,040 even though we see x equals dot dot dot 6947 04:25:19,520 --> 04:25:23,840 on line two the portion of that line to 6948 04:25:22,040 --> 04:25:26,000 the left of the equal sign isn't getting 6949 04:25:23,840 --> 04:25:28,840 evaluated ultimately because the value 6950 04:25:26,000 --> 04:25:31,319 error is happening too soon and so when 6951 04:25:28,840 --> 04:25:32,840 we finally get down to line six even 6952 04:25:31,319 --> 04:25:34,520 though it looked like I was defining on 6953 04:25:32,840 --> 04:25:36,720 line two and I would have defined X on 6954 04:25:34,520 --> 04:25:38,159 line two if all had gone well we didn't 6955 04:25:36,720 --> 04:25:39,760 get to the part where the value is 6956 04:25:38,159 --> 04:25:42,640 copied from right to left because the 6957 04:25:39,760 --> 04:25:45,239 value error happened first so this code 6958 04:25:42,640 --> 04:25:47,520 is just incorrect now so how do I go 6959 04:25:45,239 --> 04:25:49,080 about solving something like this well 6960 04:25:47,520 --> 04:25:52,279 it turns out that there's another 6961 04:25:49,080 --> 04:25:54,040 feature of the try and accept syntax 6962 04:25:52,279 --> 04:25:56,680 that python supports which is that it 6963 04:25:54,040 --> 04:25:58,760 also supports the keyword Els now we've 6964 04:25:56,680 --> 04:26:01,199 seen Els before if you think back to our 6965 04:25:58,760 --> 04:26:04,239 discussion of conditionals we saw if we 6966 04:26:01,199 --> 04:26:06,159 saw L if we saw Els which was kind of 6967 04:26:04,239 --> 04:26:08,359 this catch all what you should do in the 6968 04:26:06,159 --> 04:26:10,080 event that nothing else is relevant 6969 04:26:08,359 --> 04:26:13,000 that's kind of the same intuition here 6970 04:26:10,080 --> 04:26:15,880 for the TR accept feature of py 6971 04:26:13,000 --> 04:26:18,479 what you can do is this you can try to 6972 04:26:15,880 --> 04:26:20,479 do the following as I've done except if 6973 04:26:18,479 --> 04:26:23,840 this goes wrong but if nothing goes 6974 04:26:20,479 --> 04:26:26,199 wrong else go ahead and do this so this 6975 04:26:23,840 --> 04:26:29,000 is one way I can solve this same problem 6976 04:26:26,199 --> 04:26:31,439 now no matter what now python is going 6977 04:26:29,000 --> 04:26:33,600 to try to execute line two if something 6978 04:26:31,439 --> 04:26:35,880 goes wrong it's going to execute lines 6979 04:26:33,600 --> 04:26:39,520 three and four to handle that value 6980 04:26:35,880 --> 04:26:42,239 error however if you try and this code 6981 04:26:39,520 --> 04:26:44,279 succeeds then there is no exception to 6982 04:26:42,239 --> 04:26:46,479 to handle so you're then going to 6983 04:26:44,279 --> 04:26:47,800 execute this line here so it's a little 6984 04:26:46,479 --> 04:26:50,760 confusing perhaps in that we're now 6985 04:26:47,800 --> 04:26:54,040 using Els both for conditionals if L if 6986 04:26:50,760 --> 04:26:56,319 L if L if Els and we're also using Els 6987 04:26:54,040 --> 04:26:57,760 with these Tri accept blocks but that's 6988 04:26:56,319 --> 04:27:00,159 okay that's part of the language that's 6989 04:26:57,760 --> 04:27:03,119 one of the features so now if I rerun 6990 04:27:00,159 --> 04:27:04,960 this code in my terminal window python 6991 04:27:03,119 --> 04:27:08,960 of number. piy let's do something 6992 04:27:04,960 --> 04:27:11,199 correct like 50 I see that X is 50 so 6993 04:27:08,960 --> 04:27:13,359 line one is executed we're trying to do 6994 04:27:11,199 --> 04:27:14,640 the following line two is executed 6995 04:27:13,359 --> 04:27:16,479 because the conversion happened 6996 04:27:14,640 --> 04:27:19,080 successfully and the number 50 gets 6997 04:27:16,479 --> 04:27:21,000 copied from right to left the exception 6998 04:27:19,080 --> 04:27:23,040 does not happen so we ignore lines three 6999 04:27:21,000 --> 04:27:26,319 and four we jump immediately to line 7000 04:27:23,040 --> 04:27:28,040 five and six which prints out the result 7001 04:27:26,319 --> 04:27:30,680 by contrast though let's do this one 7002 04:27:28,040 --> 04:27:32,680 last time python of number. piy let's 7003 04:27:30,680 --> 04:27:35,439 type in cat or again any other word and 7004 04:27:32,680 --> 04:27:38,720 hit enter now we don't see what x is 7005 04:27:35,439 --> 04:27:41,239 rather we see quote unquote X is not an 7006 04:27:38,720 --> 04:27:44,000 integer which is what's being handled in 7007 04:27:41,239 --> 04:27:45,800 my except Clause all right let me pause 7008 04:27:44,000 --> 04:27:47,920 here because that's a lot of new syntax 7009 04:27:45,800 --> 04:27:51,920 and see here if there's any questions on 7010 04:27:47,920 --> 04:27:55,560 try on accept on else name error or 7011 04:27:51,920 --> 04:27:57,439 value error can you please repeat try 7012 04:27:55,560 --> 04:27:59,640 function repeat the name error what's 7013 04:27:57,439 --> 04:28:01,880 the problem with the name error yes yes 7014 04:27:59,640 --> 04:28:04,159 yeah so let's let's just rewind a couple 7015 04:28:01,880 --> 04:28:06,479 of lines here before I fix this problem 7016 04:28:04,159 --> 04:28:09,640 by now getting rid of the Els a moment 7017 04:28:06,479 --> 04:28:12,199 ago we had code that looked like this 7018 04:28:09,640 --> 04:28:14,279 whereby I was getting a name error 7019 04:28:12,199 --> 04:28:16,680 python of number. piy enter typing in 7020 04:28:14,279 --> 04:28:18,800 cat that looked like this where name X 7021 04:28:16,680 --> 04:28:21,040 is not defined and the problem was on 7022 04:28:18,800 --> 04:28:23,199 line six according to this output in 7023 04:28:21,040 --> 04:28:24,520 Python well let's think about this now 7024 04:28:23,199 --> 04:28:27,159 deductively let's try a different 7025 04:28:24,520 --> 04:28:29,399 approach on line six I'm seeing an error 7026 04:28:27,159 --> 04:28:31,479 that name X is not defined okay Python's 7027 04:28:29,399 --> 04:28:33,840 already telling me X does not exist at 7028 04:28:31,479 --> 04:28:36,600 that point so how could that possibly be 7029 04:28:33,840 --> 04:28:39,359 well where should X be defined well 7030 04:28:36,600 --> 04:28:42,319 presumably X is defined on line two up 7031 04:28:39,359 --> 04:28:44,279 here so what could go wrong well if the 7032 04:28:42,319 --> 04:28:47,119 user has inputed something that doesn't 7033 04:28:44,279 --> 04:28:50,560 look like a number like the word cat 7034 04:28:47,119 --> 04:28:54,199 passing cat the return value of input as 7035 04:28:50,560 --> 04:28:56,040 the argument to int to convert the word 7036 04:28:54,199 --> 04:28:59,720 to an INT makes no sense you can't 7037 04:28:56,040 --> 04:29:03,760 convert a cat C A to an integer at all 7038 04:28:59,720 --> 04:29:06,560 so the int function is raising a value 7039 04:29:03,760 --> 04:29:09,040 error at that point and the error is 7040 04:29:06,560 --> 04:29:12,239 being handled with this code here but 7041 04:29:09,040 --> 04:29:13,960 notice this line six is not indented 7042 04:29:12,239 --> 04:29:17,119 it's left aligned with the rest of my 7043 04:29:13,960 --> 04:29:18,840 code which means no matter what line six 7044 04:29:17,119 --> 04:29:21,439 is going to execute it's going to 7045 04:29:18,840 --> 04:29:24,159 execute whether I typed in 50 or I typed 7046 04:29:21,439 --> 04:29:26,640 in cat but if I typed in cat again X 7047 04:29:24,159 --> 04:29:29,199 never gets a value so it's not defined 7048 04:29:26,640 --> 04:29:31,319 here on line six so when I introduced 7049 04:29:29,199 --> 04:29:32,880 finally the Els statement that makes 7050 04:29:31,319 --> 04:29:36,560 sure that these things are mutually 7051 04:29:32,880 --> 04:29:41,119 exclusive I only execute the Els if I 7052 04:29:36,560 --> 04:29:43,600 tried and succeeded up above well let me 7053 04:29:41,119 --> 04:29:46,159 propose that we we refine this just a 7054 04:29:43,600 --> 04:29:48,359 little bit further as well and consider 7055 04:29:46,159 --> 04:29:51,399 how we might improve this example a 7056 04:29:48,359 --> 04:29:54,199 little bit more it's a little it's a 7057 04:29:51,399 --> 04:29:56,439 little unfriendly of me to be rejecting 7058 04:29:54,199 --> 04:29:58,119 the user's input after they fail to 7059 04:29:56,439 --> 04:29:59,720 provide an integer and just quitting the 7060 04:29:58,119 --> 04:30:02,239 program really right it'd be more 7061 04:29:59,720 --> 04:30:04,720 userfriendly if I just prompt or 7062 04:30:02,239 --> 04:30:07,680 reprompt the user again and again and in 7063 04:30:04,720 --> 04:30:09,199 the chat if you could what's the feature 7064 04:30:07,680 --> 04:30:11,680 of python that you can use if you want 7065 04:30:09,199 --> 04:30:13,800 to do something again and again and 7066 04:30:11,680 --> 04:30:15,239 again until such time as the user 7067 04:30:13,800 --> 04:30:18,359 cooperates and gives you what you're 7068 04:30:15,239 --> 04:30:20,199 looking for like a number so yeah loop 7069 04:30:18,359 --> 04:30:22,600 loop loop so a loop is something that 7070 04:30:20,199 --> 04:30:24,600 happens again and again and again and 7071 04:30:22,600 --> 04:30:27,239 maybe we can use that same mechanism a 7072 04:30:24,600 --> 04:30:28,960 loop in order to prompt the user for x 7073 04:30:27,239 --> 04:30:30,319 and if they don't give us a number 7074 04:30:28,960 --> 04:30:32,199 prompt them again and if they don't 7075 04:30:30,319 --> 04:30:33,560 prompt them again and again and again we 7076 04:30:32,199 --> 04:30:35,720 don't need to just quit out of the 7077 04:30:33,560 --> 04:30:38,560 program so quickly so let me propose 7078 04:30:35,720 --> 04:30:40,800 this let me propose here that I improve 7079 04:30:38,560 --> 04:30:42,760 this code by deliberately doing this let 7080 04:30:40,800 --> 04:30:45,119 me induce a 7081 04:30:42,760 --> 04:30:47,520 infinite loop at the very top of my code 7082 04:30:45,119 --> 04:30:49,439 with while true recall that the while 7083 04:30:47,520 --> 04:30:51,760 keyword induces a loop a cycle that 7084 04:30:49,439 --> 04:30:53,359 behaves like this and it asks a question 7085 04:30:51,760 --> 04:30:55,640 a Boolean expression that needs to 7086 04:30:53,359 --> 04:30:57,399 evaluate either to true or false well if 7087 04:30:55,640 --> 04:30:59,479 I want this thing to Loop Forever at 7088 04:30:57,399 --> 04:31:02,119 least initially we'll just say while 7089 04:30:59,479 --> 04:31:03,760 true because true is true so this has 7090 04:31:02,119 --> 04:31:06,000 the effect of doing something no matter 7091 04:31:03,760 --> 04:31:08,080 what forever unless we break out of it 7092 04:31:06,000 --> 04:31:11,319 early now I'm going to go ahead and do 7093 04:31:08,080 --> 04:31:14,359 this I'm going to go ahead and move my 7094 04:31:11,319 --> 04:31:17,399 triac C code indented underneath this 7095 04:31:14,359 --> 04:31:19,680 Loop so that I'm trying to get an X if I 7096 04:31:17,399 --> 04:31:22,600 have a value error instead I print that 7097 04:31:19,680 --> 04:31:26,080 X is not an integer but this time what 7098 04:31:22,600 --> 04:31:29,239 do I want to do if the user does try and 7099 04:31:26,080 --> 04:31:31,920 succeed in giving me a number well I can 7100 04:31:29,239 --> 04:31:34,359 do this I can just break out of my code 7101 04:31:31,920 --> 04:31:36,399 here and down here now I can use that 7102 04:31:34,359 --> 04:31:38,920 same line of code from before an F 7103 04:31:36,399 --> 04:31:43,119 string that says X is and then in curly 7104 04:31:38,920 --> 04:31:45,199 braces X again so what's going on here I 7105 04:31:43,119 --> 04:31:47,359 think this codee now because I've added 7106 04:31:45,199 --> 04:31:50,399 the loop is going to have the effect of 7107 04:31:47,359 --> 04:31:53,040 trying at least once maybe a second time 7108 04:31:50,399 --> 04:31:55,640 maybe a third time maybe 500 times until 7109 04:31:53,040 --> 04:31:57,680 the user finally gives me what I want 7110 04:31:55,640 --> 04:32:00,159 which is an integer and once they do 7111 04:31:57,680 --> 04:32:02,399 once there's no value error happening 7112 04:32:00,159 --> 04:32:04,840 then I break out of the loop and line 7113 04:32:02,399 --> 04:32:06,640 nine executes as I would hope so let me 7114 04:32:04,840 --> 04:32:10,159 go ahead and try executing this version 7115 04:32:06,640 --> 04:32:11,600 python of number. piy enter what's X let 7116 04:32:10,159 --> 04:32:15,080 me go ahead and type in the easy thing 7117 04:32:11,600 --> 04:32:17,080 first 50 x is 50 what just happened in 7118 04:32:15,080 --> 04:32:19,359 terms of the control flow of this 7119 04:32:17,080 --> 04:32:21,319 program the flow of my logic well I 7120 04:32:19,359 --> 04:32:22,880 first found myself on line one inside of 7121 04:32:21,319 --> 04:32:25,319 a loop hopefully I'll get out of this 7122 04:32:22,880 --> 04:32:28,080 Loop what did I then do on lines two and 7123 04:32:25,319 --> 04:32:30,040 three I tried to get input from the user 7124 04:32:28,080 --> 04:32:31,880 and convert it to an INT well I was a 7125 04:32:30,040 --> 04:32:33,720 nice guy this time and I typed in 50 7126 04:32:31,880 --> 04:32:35,319 which looks like and is a number so the 7127 04:32:33,720 --> 04:32:38,800 int function converted it just fine and 7128 04:32:35,319 --> 04:32:40,560 stored it from right to left in X except 7129 04:32:38,800 --> 04:32:41,840 value error there is no value error 7130 04:32:40,560 --> 04:32:43,399 because if I typed in a number there's 7131 04:32:41,840 --> 04:32:46,399 there's nothing exceptional happening 7132 04:32:43,399 --> 04:32:49,080 this is a boring good execution of my 7133 04:32:46,399 --> 04:32:51,600 program so what happens I break out of 7134 04:32:49,080 --> 04:32:54,040 the loop so again the else Clause is 7135 04:32:51,600 --> 04:32:56,119 associated with the try not with the 7136 04:32:54,040 --> 04:32:58,080 accept and once I'm out of the loop of 7137 04:32:56,119 --> 04:32:59,760 course I'm just printing out what x is 7138 04:32:58,080 --> 04:33:02,800 well let's try the other scenario that 7139 04:32:59,760 --> 04:33:06,080 might happen python of number. piy enter 7140 04:33:02,800 --> 04:33:09,840 what's X let's try cat or any other word 7141 04:33:06,080 --> 04:33:12,080 enter ah this is now a new feature I'm 7142 04:33:09,840 --> 04:33:14,039 being informed what I did wrong X is not 7143 04:33:12,080 --> 04:33:16,240 an integer so I'm getting some useful 7144 04:33:14,039 --> 04:33:18,639 user feedback but notice again I'm 7145 04:33:16,240 --> 04:33:21,840 prompted what's X well let me try typing 7146 04:33:18,639 --> 04:33:25,240 in dog X is not an integer what's X let 7147 04:33:21,840 --> 04:33:27,279 me try bird enter X is not an integer 7148 04:33:25,240 --> 04:33:29,561 what's X and suffice it to say this will 7149 04:33:27,279 --> 04:33:32,959 happen now forever if I'm in an infinite 7150 04:33:29,561 --> 04:33:34,959 Loop until I try and succeed at which 7151 04:33:32,959 --> 04:33:37,359 point I break out so let's try again 50 7152 04:33:34,959 --> 04:33:40,480 enter now I'm out of the loop and I'm 7153 04:33:37,359 --> 04:33:42,639 printing out what x actually is all 7154 04:33:40,480 --> 04:33:45,160 right let me pause here and see if there 7155 04:33:42,639 --> 04:33:46,920 are any questions the logic is almost 7156 04:33:45,160 --> 04:33:49,760 the same but what is different now is 7157 04:33:46,920 --> 04:33:52,039 I'm in a loop and I'm using the keyword 7158 04:33:49,760 --> 04:33:54,840 break in Python to deliberately break 7159 04:33:52,039 --> 04:33:57,600 out of the loop when I'm ready to once 7160 04:33:54,840 --> 04:34:02,359 the user has cooperated do we really 7161 04:33:57,600 --> 04:34:04,760 need to break can't we just print or 7162 04:34:02,359 --> 04:34:06,400 what what keeps us from just printing uh 7163 04:34:04,760 --> 04:34:08,119 good question so let me try that 7164 04:34:06,400 --> 04:34:09,760 couldn't I just print well let's see 7165 04:34:08,119 --> 04:34:12,359 what happens if I do that let me move 7166 04:34:09,760 --> 04:34:14,520 this print line at the end in into my 7167 04:34:12,359 --> 04:34:16,359 Loop here thereby shortening the program 7168 04:34:14,520 --> 04:34:18,799 and in general that's been a good thing 7169 04:34:16,359 --> 04:34:22,080 python of number. piy enter let me go 7170 04:34:18,799 --> 04:34:26,119 ahead and type in 50 okay X is 50 what's 7171 04:34:22,080 --> 04:34:28,480 x uh okay maybe it's 49 x is 49 uh okay 7172 04:34:26,119 --> 04:34:30,000 maybe 48 unfortunately I think you're 7173 04:34:28,480 --> 04:34:31,799 you're laughing you see it I never break 7174 04:34:30,000 --> 04:34:33,400 out of the loop which maybe that's a 7175 04:34:31,799 --> 04:34:35,039 feature maybe you want this to be your 7176 04:34:33,400 --> 04:34:37,320 program but I didn't I'd eventually like 7177 04:34:35,039 --> 04:34:39,359 this game to stop so I need to break out 7178 04:34:37,320 --> 04:34:41,039 in that way but I can do it a little 7179 04:34:39,359 --> 04:34:43,959 differently and let me propose that we 7180 04:34:41,039 --> 04:34:46,199 modify this a little bit but first any 7181 04:34:43,959 --> 04:34:50,799 other questions on this syntax here let 7182 04:34:46,199 --> 04:34:54,799 me rewind to the prior 7183 04:34:50,799 --> 04:34:57,561 version he uh can I use break uh all in 7184 04:34:54,799 --> 04:35:00,639 exception except in else for example in 7185 04:34:57,561 --> 04:35:03,320 another uh print and when you use print 7186 04:35:00,639 --> 04:35:05,520 in the else you can use print together 7187 04:35:03,320 --> 04:35:07,879 with break or something like this yeah 7188 04:35:05,520 --> 04:35:10,199 you so you can use break inside of Loops 7189 04:35:07,879 --> 04:35:12,719 to break out of loops and you can use it 7190 04:35:10,199 --> 04:35:14,879 inside of a conditional like an if an L 7191 04:35:12,719 --> 04:35:17,480 if or an else you can do it inside of a 7192 04:35:14,879 --> 04:35:18,920 try accept else statement too anytime 7193 04:35:17,480 --> 04:35:21,160 you're in a loop that you want to break 7194 04:35:18,920 --> 04:35:22,561 out of you can use this keyword break 7195 04:35:21,160 --> 04:35:24,400 I'm using it in the context of 7196 04:35:22,561 --> 04:35:25,879 exceptions but it's not restricted to 7197 04:35:24,400 --> 04:35:28,119 that and let me show you too it doesn't 7198 04:35:25,879 --> 04:35:30,680 even have to be in the Els if I wanted 7199 04:35:28,119 --> 04:35:33,240 to I could actually do this I could get 7200 04:35:30,680 --> 04:35:35,439 rid of my elt and I could go back to 7201 04:35:33,240 --> 04:35:39,080 line three add another line that's 7202 04:35:35,439 --> 04:35:41,840 indented line four and break out here 7203 04:35:39,080 --> 04:35:45,000 now why is this logically okay well well 7204 04:35:41,840 --> 04:35:47,080 consider what I'm now trying to do I'm 7205 04:35:45,000 --> 04:35:49,080 trying to execute line three and 7206 04:35:47,080 --> 04:35:51,400 converting the user's input to an INT 7207 04:35:49,080 --> 04:35:53,879 and I'm trying to store the result from 7208 04:35:51,400 --> 04:35:55,920 right to left in X if something goes 7209 04:35:53,879 --> 04:35:58,680 wrong the code we've already seen is 7210 04:35:55,920 --> 04:36:02,039 immediately going to jump to line five 7211 04:35:58,680 --> 04:36:04,400 and then six to handle the exception but 7212 04:36:02,039 --> 04:36:06,799 if nothing goes wrong my code presumably 7213 04:36:04,400 --> 04:36:09,160 should just keep on executing line by 7214 04:36:06,799 --> 04:36:10,639 line so I could technically logically 7215 04:36:09,160 --> 04:36:13,080 put the break here and watch what 7216 04:36:10,639 --> 04:36:16,920 happens when I run this version python 7217 04:36:13,080 --> 04:36:19,840 of number. Pi 50 enter it worked I broke 7218 04:36:16,920 --> 04:36:21,879 out of the loop now which way is better 7219 04:36:19,840 --> 04:36:23,279 honestly I think it could go either way 7220 04:36:21,879 --> 04:36:25,520 at this point this program is so 7221 04:36:23,279 --> 04:36:28,160 relatively short that even though I'm 7222 04:36:25,520 --> 04:36:29,959 trying to do two things now one of which 7223 04:36:28,160 --> 04:36:31,879 the break is not going to fail like you 7224 04:36:29,959 --> 04:36:33,240 either break or you don't there's no 7225 04:36:31,879 --> 04:36:35,840 piece of data from the user that's going 7226 04:36:33,240 --> 04:36:37,320 to influence that we don't strictly need 7227 04:36:35,840 --> 04:36:38,920 to have those two lines of code there 7228 04:36:37,320 --> 04:36:40,639 but it's only two lines so I think it's 7229 04:36:38,920 --> 04:36:42,279 okay and if you recall our discussion in 7230 04:36:40,639 --> 04:36:44,920 the past not just of correctness does 7231 04:36:42,279 --> 04:36:46,480 the code work as it should but design I 7232 04:36:44,920 --> 04:36:48,520 think you could argue it either way if 7233 04:36:46,480 --> 04:36:50,279 you prefer the readability of this and 7234 04:36:48,520 --> 04:36:52,320 the fact that you don't have an El 7235 04:36:50,279 --> 04:36:54,359 that's fine if though you prefer to 7236 04:36:52,320 --> 04:36:56,279 minimize just how many lines of code 7237 04:36:54,359 --> 04:36:58,359 you're trying to execute in case 7238 04:36:56,279 --> 04:37:00,760 something goes wrong the else is a 7239 04:36:58,359 --> 04:37:02,600 reasonable approach too well allow me to 7240 04:37:00,760 --> 04:37:04,160 propose too now that we refine this 7241 04:37:02,600 --> 04:37:07,719 further I think we're at the point where 7242 04:37:04,160 --> 04:37:10,320 it's pretty darn correct but suppose now 7243 04:37:07,719 --> 04:37:12,320 that I find myself today and tomorrow 7244 04:37:10,320 --> 04:37:13,920 trying to get numbers from the user 7245 04:37:12,320 --> 04:37:15,439 quite a bit it would be nice as we've 7246 04:37:13,920 --> 04:37:18,039 seen to maybe just invent my own 7247 04:37:15,439 --> 04:37:19,840 function get int to get an integer from 7248 04:37:18,039 --> 04:37:21,520 the user both today and tomorrow and 7249 04:37:19,840 --> 04:37:23,240 Beyond and heck maybe I can even share 7250 04:37:21,520 --> 04:37:24,959 that function with other people if they 7251 04:37:23,240 --> 04:37:27,320 want to write programs that get integers 7252 04:37:24,959 --> 04:37:29,000 from users so how might I go about doing 7253 04:37:27,320 --> 04:37:30,439 this well let me go ahead and propose 7254 04:37:29,000 --> 04:37:32,840 that we do this let me get rid of the 7255 04:37:30,439 --> 04:37:35,719 print line but keep most of my Loop here 7256 04:37:32,840 --> 04:37:37,840 let me Define a function called get int 7257 04:37:35,719 --> 04:37:39,240 that takes no arguments for now and I'm 7258 04:37:37,840 --> 04:37:41,959 going to go ahead and indent all of the 7259 04:37:39,240 --> 04:37:45,080 code I already wrote underneath get in 7260 04:37:41,959 --> 04:37:48,000 so now I have a function called get int 7261 04:37:45,080 --> 04:37:49,840 that tries to do the following try to 7262 04:37:48,000 --> 04:37:51,279 get an in from the user if something 7263 04:37:49,840 --> 04:37:53,439 goes wrong and there's a value error 7264 04:37:51,279 --> 04:37:56,799 yell at them with X is not an integer 7265 04:37:53,439 --> 04:37:58,600 else break but it's not just breaking 7266 04:37:56,799 --> 04:38:01,199 that I want to do here now that I'm in a 7267 04:37:58,600 --> 04:38:03,119 function recall our discussion of return 7268 04:38:01,199 --> 04:38:05,119 values if you're inventing your own 7269 04:38:03,119 --> 04:38:06,439 function whose purpose in life isn't 7270 04:38:05,119 --> 04:38:09,561 just a print something on the screen 7271 04:38:06,439 --> 04:38:12,240 like a side effect but is to hand back a 7272 04:38:09,561 --> 04:38:13,840 value to hand you back value like on 7273 04:38:12,240 --> 04:38:15,920 that same Post-It note from our 7274 04:38:13,840 --> 04:38:18,680 discussion of functions well you need to 7275 04:38:15,920 --> 04:38:20,240 return X explicitly how do I now use 7276 04:38:18,680 --> 04:38:21,959 this function well as soon as we start 7277 04:38:20,240 --> 04:38:23,639 making our own functions it tends to be 7278 04:38:21,959 --> 04:38:25,600 convenient to Define our own main 7279 04:38:23,639 --> 04:38:26,840 function as well that's the main part of 7280 04:38:25,600 --> 04:38:29,799 our program and I'm going to keep this 7281 04:38:26,840 --> 04:38:31,760 simple I'm now going to say x equals get 7282 04:38:29,799 --> 04:38:33,439 int and then on the next line I'm going 7283 04:38:31,760 --> 04:38:36,920 to do that print from before quote 7284 04:38:33,439 --> 04:38:39,119 unquote X is in curly braces X and at 7285 04:38:36,920 --> 04:38:40,920 the very bottom of my program recall I'm 7286 04:38:39,119 --> 04:38:43,199 going to call Main so that no matter 7287 04:38:40,920 --> 04:38:45,080 what I'm invoking my main function after 7288 04:38:43,199 --> 04:38:47,520 everything's been defined well let's see 7289 04:38:45,080 --> 04:38:51,000 how this works let me go ahead and run 7290 04:38:47,520 --> 04:38:53,760 python of number. Pi enter let's type in 7291 04:38:51,000 --> 04:38:55,840 50 and it seems to work as before let's 7292 04:38:53,760 --> 04:38:58,439 go ahead and run it again typing in cat 7293 04:38:55,840 --> 04:39:00,680 C A this time X is not an integer and 7294 04:38:58,439 --> 04:39:02,959 I'm being prompted dog and I'm being 7295 04:39:00,680 --> 04:39:06,160 prompted bird and I'm being prompted 7296 04:39:02,959 --> 04:39:08,639 fine fine fine 50 that's an INT and so 7297 04:39:06,160 --> 04:39:10,320 it is printed so what's worth noting 7298 04:39:08,639 --> 04:39:11,920 here well I'm manifesting a couple of 7299 04:39:10,320 --> 04:39:13,879 good properties here one 7300 04:39:11,920 --> 04:39:16,320 I've kind of abstracted away this notion 7301 04:39:13,879 --> 04:39:18,080 of an getting an integer and even though 7302 04:39:16,320 --> 04:39:19,520 I just artificially hit enter a whole 7303 04:39:18,080 --> 04:39:20,840 bunch of times just to hide that 7304 04:39:19,520 --> 04:39:22,000 function for now it needs to be there 7305 04:39:20,840 --> 04:39:24,000 but we don't need to see it at this 7306 04:39:22,000 --> 04:39:25,920 point notice that now this entire 7307 04:39:24,000 --> 04:39:28,680 program really boils down to just these 7308 04:39:25,920 --> 04:39:30,561 three lines of code now why because I've 7309 04:39:28,680 --> 04:39:32,400 abstracted away that whole process of 7310 04:39:30,561 --> 04:39:35,439 getting an INT from the user into this 7311 04:39:32,400 --> 04:39:37,000 new function of my own called get int 7312 04:39:35,439 --> 04:39:39,240 but can I improve upon this well let me 7313 04:39:37,000 --> 04:39:40,638 go ahead and undo all of those blank 7314 04:39:39,240 --> 04:39:42,840 lines and pull this up just so we can 7315 04:39:40,638 --> 04:39:44,958 see more on the screen at once can I 7316 04:39:42,840 --> 04:39:47,360 tighten up my implementation of get int 7317 04:39:44,958 --> 04:39:49,000 it is correct I claim this is correct 7318 04:39:47,360 --> 04:39:51,280 it's handling errors and it's returning 7319 04:39:49,000 --> 04:39:54,080 X but I don't strictly speaking need to 7320 04:39:51,280 --> 04:39:56,280 write the code as long what else could I 7321 04:39:54,080 --> 04:39:58,840 do well let me propose that if all 7322 04:39:56,280 --> 04:40:00,798 you're doing on this line 13 is breaking 7323 04:39:58,840 --> 04:40:03,560 and then immediately after that per the 7324 04:40:00,798 --> 04:40:06,040 indentation you're executing return X on 7325 04:40:03,560 --> 04:40:07,718 line 14 why are you wasting everyone's 7326 04:40:06,040 --> 04:40:10,560 time once you know you're ready to 7327 04:40:07,718 --> 04:40:13,080 return the value you could just return X 7328 04:40:10,560 --> 04:40:16,360 and so in my else I could break out and 7329 04:40:13,080 --> 04:40:18,920 return a value so here too return is 7330 04:40:16,360 --> 04:40:22,040 used to return values from functions 7331 04:40:18,920 --> 04:40:24,680 break is used to break out of Loops but 7332 04:40:22,040 --> 04:40:26,520 it turns out that return is sort of 7333 04:40:24,680 --> 04:40:28,920 stronger than break it will not only 7334 04:40:26,520 --> 04:40:31,600 break you out of a loop it will also 7335 04:40:28,920 --> 04:40:34,480 return a value for you so it's doing two 7336 04:40:31,600 --> 04:40:39,480 things for once if you will but can I 7337 04:40:34,480 --> 04:40:41,718 make this even more compacts if if if my 7338 04:40:39,480 --> 04:40:43,160 goal is to just tighten the code up even 7339 04:40:41,718 --> 04:40:45,360 though it's already correct can anyone 7340 04:40:43,160 --> 04:40:47,200 think of a further refinement whether 7341 04:40:45,360 --> 04:40:49,878 you've programmed in Python before or 7342 04:40:47,200 --> 04:40:52,280 not can I shorten this implementation 7343 04:40:49,878 --> 04:40:53,718 further just a little bit if only to 7344 04:40:52,280 --> 04:40:55,958 decrease the probability that I've made 7345 04:40:53,718 --> 04:40:57,680 a mistake by having fewer lines and just 7346 04:40:55,958 --> 04:41:00,280 make it a little easier to read because 7347 04:40:57,680 --> 04:41:02,560 it's shorter any suggestions for 7348 04:41:00,280 --> 04:41:04,878 tightening up my implementation of get 7349 04:41:02,560 --> 04:41:09,120 int you can just return the value on the 7350 04:41:04,878 --> 04:41:11,718 try function when you're trying uh at 7351 04:41:09,120 --> 04:41:14,680 you take you take the input X and then 7352 04:41:11,718 --> 04:41:16,320 done X good we can just return x a 7353 04:41:14,680 --> 04:41:18,000 little higher up and let me correct 7354 04:41:16,320 --> 04:41:19,718 folks as we go it's not a tri function 7355 04:41:18,000 --> 04:41:21,600 it would be a tri statement technically 7356 04:41:19,718 --> 04:41:23,360 a function typically has a parenthesis 7357 04:41:21,600 --> 04:41:25,680 and another one in this case it's just a 7358 04:41:23,360 --> 04:41:27,638 statement so but we can do exactly that 7359 04:41:25,680 --> 04:41:29,878 I don't technically need the else if I 7360 04:41:27,638 --> 04:41:33,520 really want I could do this right after 7361 04:41:29,878 --> 04:41:35,638 line nine I could return X here or 7362 04:41:33,520 --> 04:41:37,560 recall our discussion of defining 7363 04:41:35,638 --> 04:41:39,240 variables unnecessarily sometimes like 7364 04:41:37,560 --> 04:41:40,560 why Define a variable here if you're 7365 04:41:39,240 --> 04:41:43,040 immediately going to use it here and 7366 04:41:40,560 --> 04:41:45,480 then never again so we could avoid a new 7367 04:41:43,040 --> 04:41:48,240 line here and I could avoid even 7368 04:41:45,480 --> 04:41:51,320 defining X explicitly I could just say 7369 04:41:48,240 --> 04:41:53,320 something like this I could return int 7370 04:41:51,320 --> 04:41:57,040 input quote unquote what's X I can do it 7371 04:41:53,320 --> 04:41:58,638 all at once now which is better I don't 7372 04:41:57,040 --> 04:42:00,520 know I mean again this is where 7373 04:41:58,638 --> 04:42:02,120 reasonable people might disagree I'd 7374 04:42:00,520 --> 04:42:04,200 argue that on the one hand we're 7375 04:42:02,120 --> 04:42:06,240 tightening up the code we're using fewer 7376 04:42:04,200 --> 04:42:08,200 lines it's easier to read lower 7377 04:42:06,240 --> 04:42:09,798 probability that I've made a mistake on 7378 04:42:08,200 --> 04:42:11,798 the other hand it's a little more 7379 04:42:09,798 --> 04:42:13,680 complicated to understand perhaps it's a 7380 04:42:11,798 --> 04:42:15,560 little less obvious where I'm returning 7381 04:42:13,680 --> 04:42:17,040 from so I think arguments can be made 7382 04:42:15,560 --> 04:42:18,600 either way at the end of the day what's 7383 04:42:17,040 --> 04:42:20,760 important is that you've done this 7384 04:42:18,600 --> 04:42:22,440 consciously you've made a decision to do 7385 04:42:20,760 --> 04:42:24,600 it this way or this way and you can 7386 04:42:22,440 --> 04:42:26,638 justify it in your mind not that your 7387 04:42:24,600 --> 04:42:28,360 answer is uh it worked so I left it 7388 04:42:26,638 --> 04:42:30,000 alone like have a good reason come up 7389 04:42:28,360 --> 04:42:32,520 with a good reason and that will come 7390 04:42:30,000 --> 04:42:34,280 with experience and practice well let me 7391 04:42:32,520 --> 04:42:37,000 propose too that we make one other 7392 04:42:34,280 --> 04:42:38,360 refinement here suppose that you're 7393 04:42:37,000 --> 04:42:40,080 finding your programs to be a little 7394 04:42:38,360 --> 04:42:41,920 noisy and it's a little obnoxious that 7395 04:42:40,080 --> 04:42:43,958 you keep telling the user X is not an 7396 04:42:41,920 --> 04:42:45,560 integer X is not an integer X is not an 7397 04:42:43,958 --> 04:42:48,840 integer what if you want to make things 7398 04:42:45,560 --> 04:42:51,840 a little gentler and just prompt the 7399 04:42:48,840 --> 04:42:54,560 user again with the same words what's x 7400 04:42:51,840 --> 04:42:56,798 what is X what's X again and again well 7401 04:42:54,560 --> 04:42:58,840 you can do that as well and it turns out 7402 04:42:56,798 --> 04:43:02,280 that if you want to handle an exception 7403 04:42:58,840 --> 04:43:04,718 in Python but you want to pass on doing 7404 04:43:02,280 --> 04:43:06,480 anything with it so you want to catch it 7405 04:43:04,718 --> 04:43:08,040 but you essentially want to ignore it 7406 04:43:06,480 --> 04:43:10,160 you don't want to print anything you 7407 04:43:08,040 --> 04:43:12,360 don't want to quit the program you just 7408 04:43:10,160 --> 04:43:14,000 want to silent ently ignore it like if 7409 04:43:12,360 --> 04:43:15,440 you're talking in a gr full of people 7410 04:43:14,000 --> 04:43:17,600 and you're it's your turn to talk and 7411 04:43:15,440 --> 04:43:19,360 you're just like pass they're still 7412 04:43:17,600 --> 04:43:21,400 calling on you but you're not doing or 7413 04:43:19,360 --> 04:43:23,760 saying anything more well we can add 7414 04:43:21,400 --> 04:43:26,280 this keyword to our code here let me go 7415 04:43:23,760 --> 04:43:28,560 back to my program here and instead of 7416 04:43:26,280 --> 04:43:30,958 printing out again and again X is not an 7417 04:43:28,560 --> 04:43:33,600 integer I could just do this I could 7418 04:43:30,958 --> 04:43:35,280 pass on handling the error further I'm 7419 04:43:33,600 --> 04:43:36,840 still catching it so the user is not 7420 04:43:35,280 --> 04:43:38,680 going to see a scary message even 7421 04:43:36,840 --> 04:43:41,520 mentioning value error my code is 7422 04:43:38,680 --> 04:43:42,958 catching it but I'm passing on saying 7423 04:43:41,520 --> 04:43:44,440 anything about it I'm going to stay in 7424 04:43:42,958 --> 04:43:45,760 the loop I'm going to stay in the loop 7425 04:43:44,440 --> 04:43:47,560 and keep prompting and repr prompting 7426 04:43:45,760 --> 04:43:49,440 the user so now the effect looks a 7427 04:43:47,560 --> 04:43:52,840 little something like this python of 7428 04:43:49,440 --> 04:43:55,400 number. piy let's type in cat what's X 7429 04:43:52,840 --> 04:43:57,798 again let's type in dog what's X again 7430 04:43:55,400 --> 04:43:59,240 type in bird so it's just a little maybe 7431 04:43:57,798 --> 04:44:01,200 more user friendly and that you're just 7432 04:43:59,240 --> 04:44:03,160 reminding the user what you want maybe 7433 04:44:01,200 --> 04:44:05,560 it's worse maybe it would be helpful to 7434 04:44:03,160 --> 04:44:07,360 tell the user why you're prompting them 7435 04:44:05,560 --> 04:44:09,638 again and again it's not obvious so it 7436 04:44:07,360 --> 04:44:11,958 could go both ways but again it's just 7437 04:44:09,638 --> 04:44:14,200 another mechanism now for handling these 7438 04:44:11,958 --> 04:44:16,280 errors we use the accept keyword to 7439 04:44:14,200 --> 04:44:18,160 catch a specific error but we don't have 7440 04:44:16,280 --> 04:44:20,878 to handle it more than that we can just 7441 04:44:18,160 --> 04:44:22,718 pass on doing something further let me 7442 04:44:20,878 --> 04:44:27,000 pause here and see if there's any 7443 04:44:22,718 --> 04:44:29,520 questions now on try accept else or 7444 04:44:27,000 --> 04:44:32,320 pass okay yeah know I was just kind of 7445 04:44:29,520 --> 04:44:35,000 curious I guess about uh the idea of 7446 04:44:32,320 --> 04:44:37,840 when you were indenting with uh the get 7447 04:44:35,000 --> 04:44:39,200 in function for example um because I'm 7448 04:44:37,840 --> 04:44:40,560 noticing you know obviously going 7449 04:44:39,200 --> 04:44:42,798 through it with the whole logic and 7450 04:44:40,560 --> 04:44:44,600 breakdown the entire uh the entire 7451 04:44:42,798 --> 04:44:45,920 function you know while true do this but 7452 04:44:44,600 --> 04:44:48,320 I'm just kind of curious on elaborating 7453 04:44:45,920 --> 04:44:50,560 with the indentations for the uh code 7454 04:44:48,320 --> 04:44:52,680 more yeah so the indentation is 7455 04:44:50,560 --> 04:44:55,480 deliberate logically some languages 7456 04:44:52,680 --> 04:44:57,160 don't require as rigorous indentation 7457 04:44:55,480 --> 04:44:58,760 you can use curly braces or other 7458 04:44:57,160 --> 04:45:01,080 symbology to make clear what is 7459 04:44:58,760 --> 04:45:03,920 associated with what in general anytime 7460 04:45:01,080 --> 04:45:06,520 you indent something in Python on this 7461 04:45:03,920 --> 04:45:08,560 line so rather anytime you write a code 7462 04:45:06,520 --> 04:45:11,120 a line of code in Python that's here and 7463 04:45:08,560 --> 04:45:12,760 the lines below it are somehow indented 7464 04:45:11,120 --> 04:45:14,878 that means that those lines are somehow 7465 04:45:12,760 --> 04:45:17,040 associated with that first line and 7466 04:45:14,878 --> 04:45:20,360 presumably those indented lines should 7467 04:45:17,040 --> 04:45:23,440 only be executed if the first line told 7468 04:45:20,360 --> 04:45:25,560 the uh uh told the computer to do so so 7469 04:45:23,440 --> 04:45:27,360 concretely what does this mean on line 7470 04:45:25,560 --> 04:45:30,000 six here we're defining a function 7471 04:45:27,360 --> 04:45:32,760 called get int that takes no arguments 7472 04:45:30,000 --> 04:45:35,600 colon everything that's indented by at 7473 04:45:32,760 --> 04:45:38,160 least four spaces Hereafter is part of 7474 04:45:35,600 --> 04:45:40,040 that function why that's just the design 7475 04:45:38,160 --> 04:45:41,878 of the Python language frankly I think 7476 04:45:40,040 --> 04:45:44,600 the designers got tired of seeing really 7477 04:45:41,878 --> 04:45:47,878 ugly code in languages like C and C++ 7478 04:45:44,600 --> 04:45:51,320 and Java uh that uh don't necessarily 7479 04:45:47,878 --> 04:45:52,920 enforce uh indentation to this extent so 7480 04:45:51,320 --> 04:45:54,360 now it's baked into the language and my 7481 04:45:52,920 --> 04:45:55,878 chronology might be a little off there 7482 04:45:54,360 --> 04:45:58,120 but there's been many languages that are 7483 04:45:55,878 --> 04:45:59,920 looser than python when it comes to 7484 04:45:58,120 --> 04:46:02,600 indentation the indentation is 7485 04:45:59,920 --> 04:46:04,280 Meaningful on line 72 notice that 7486 04:46:02,600 --> 04:46:06,000 because the while true is indented by 7487 04:46:04,280 --> 04:46:08,520 four spaces that just means it's part of 7488 04:46:06,000 --> 04:46:10,560 the get in function but notice below the 7489 04:46:08,520 --> 04:46:12,680 while true statement there's eight 7490 04:46:10,560 --> 04:46:14,080 there's 12 there's eight there's 12 7491 04:46:12,680 --> 04:46:16,200 spaces here and I'm just quickly 7492 04:46:14,080 --> 04:46:17,840 counting the dots that means that all of 7493 04:46:16,200 --> 04:46:20,440 the lines I've just highlighted are 7494 04:46:17,840 --> 04:46:22,680 inside of that while loop while true 7495 04:46:20,440 --> 04:46:24,638 means to execute lines 8 through 11 7496 04:46:22,680 --> 04:46:28,120 potentially again and again and again 7497 04:46:24,638 --> 04:46:30,958 and now lastly on line eight because we 7498 04:46:28,120 --> 04:46:32,920 have try and indented below it is line 7499 04:46:30,958 --> 04:46:35,320 nine that just means that what you 7500 04:46:32,920 --> 04:46:37,840 should try is what's on line nine and 7501 04:46:35,320 --> 04:46:40,400 similarly on line 10 below it we have 7502 04:46:37,840 --> 04:46:43,240 indented line 11 you should only pass 7503 04:46:40,400 --> 04:46:45,558 when there is an exception of a value 7504 04:46:43,240 --> 04:46:47,680 error so the indentation just means what 7505 04:46:45,558 --> 04:46:50,080 is associated with what and once you get 7506 04:46:47,680 --> 04:46:51,840 comfortable with that you'll see that it 7507 04:46:50,080 --> 04:46:53,958 helps the indentation alone helps 7508 04:46:51,840 --> 04:46:56,200 explain the logic of your program and it 7509 04:46:53,958 --> 04:46:58,000 has a wonderful side effect that for 7510 04:46:56,200 --> 04:46:59,718 yourself the next morning for your 7511 04:46:58,000 --> 04:47:02,320 colleagues your family your friends your 7512 04:46:59,718 --> 04:47:04,600 teachers your code is much more readable 7513 04:47:02,320 --> 04:47:07,280 as a result it's not one big mess of a 7514 04:47:04,600 --> 04:47:12,000 blob of text other questions now on try 7515 04:47:07,280 --> 04:47:15,878 except else or pass yeah thanks um two 7516 04:47:12,000 --> 04:47:19,878 question uh question one um uh once you 7517 04:47:15,878 --> 04:47:22,240 say pass can the caller still um learn 7518 04:47:19,878 --> 04:47:25,320 anything about this error um through a 7519 04:47:22,240 --> 04:47:28,160 system variable or whatever and question 7520 04:47:25,320 --> 04:47:31,958 two problem set zero referenced some 7521 04:47:28,160 --> 04:47:34,040 string Methods including is numeric is 7522 04:47:31,958 --> 04:47:38,160 it any different 7523 04:47:34,040 --> 04:47:40,120 to um go via isomeric here good question 7524 04:47:38,160 --> 04:47:41,520 so on the first question if I'm handling 7525 04:47:40,120 --> 04:47:43,200 the error in this way the caller is not 7526 04:47:41,520 --> 04:47:45,000 going to know anything about it that's 7527 04:47:43,200 --> 04:47:47,440 the point of my handling it so that 7528 04:47:45,000 --> 04:47:49,480 Maine or other callers don't know that 7529 04:47:47,440 --> 04:47:51,638 anything technically went wrong on the 7530 04:47:49,480 --> 04:47:53,120 second question is numeric is another 7531 04:47:51,638 --> 04:47:55,360 function that you can call that can look 7532 04:47:53,120 --> 04:47:58,040 at a string and determine is this in 7533 04:47:55,360 --> 04:48:00,680 fact a number I could use a mechanism 7534 04:47:58,040 --> 04:48:03,080 like that I could use a conditional if 7535 04:48:00,680 --> 04:48:04,878 this looks like a number then pass it to 7536 04:48:03,080 --> 04:48:06,878 the int function and go ahead and 7537 04:48:04,878 --> 04:48:09,240 convert it to an integer that's totally 7538 04:48:06,878 --> 04:48:12,080 fine I would generally say that the 7539 04:48:09,240 --> 04:48:14,798 pythonic way of doing things is often 7540 04:48:12,080 --> 04:48:17,160 For Better or For Worse to try things 7541 04:48:14,798 --> 04:48:19,600 hope they work but if they don't handle 7542 04:48:17,160 --> 04:48:23,040 the exception so other languages are 7543 04:48:19,600 --> 04:48:25,360 more in favor of checking if if if if L 7544 04:48:23,040 --> 04:48:27,878 if else and all of these conditionals 7545 04:48:25,360 --> 04:48:30,160 python tends to be a little more of the 7546 04:48:27,878 --> 04:48:31,958 mindset eh try it but just make sure 7547 04:48:30,160 --> 04:48:34,040 you're handling the error so this would 7548 04:48:31,958 --> 04:48:35,480 be the pythonic way of doing it your way 7549 04:48:34,040 --> 04:48:38,440 though checking with a conditional is it 7550 04:48:35,480 --> 04:48:40,280 a number first is totally reasonable too 7551 04:48:38,440 --> 04:48:42,400 if you want to go that way well let me 7552 04:48:40,280 --> 04:48:44,440 propose some final refinements to this 7553 04:48:42,400 --> 04:48:47,760 program that really just kind of tighten 7554 04:48:44,440 --> 04:48:49,600 things up one additional step to improve 7555 04:48:47,760 --> 04:48:51,798 the implementation of this get in 7556 04:48:49,600 --> 04:48:53,878 function let me propose that we not 7557 04:48:51,798 --> 04:48:56,240 hardc code so to speak that is type 7558 04:48:53,878 --> 04:48:58,360 manually X all over the place let's make 7559 04:48:56,240 --> 04:49:01,000 this function get int a little more 7560 04:48:58,360 --> 04:49:03,320 reusable right now notice that I'm just 7561 04:49:01,000 --> 04:49:06,400 kind of using the honor System that well 7562 04:49:03,320 --> 04:49:09,520 main is defining a variable called X and 7563 04:49:06,400 --> 04:49:12,080 get int is asking for a variable called 7564 04:49:09,520 --> 04:49:14,840 X but it would be nice if the caller 7565 04:49:12,080 --> 04:49:17,080 main doesn't have to know what the call 7566 04:49:14,840 --> 04:49:19,120 is naming its variables and vice versa 7567 04:49:17,080 --> 04:49:21,120 so caller to call a function means to 7568 04:49:19,120 --> 04:49:23,480 use it the caller is the function that's 7569 04:49:21,120 --> 04:49:25,680 using it the call E is just the function 7570 04:49:23,480 --> 04:49:28,360 being called it would be nice if I'm not 7571 04:49:25,680 --> 04:49:30,920 just hoping that X is the same in both 7572 04:49:28,360 --> 04:49:35,440 places so let me propose this let me 7573 04:49:30,920 --> 04:49:38,878 propose that we actually add a parameter 7574 04:49:35,440 --> 04:49:41,638 to get int like this what's X that is to 7575 04:49:38,878 --> 04:49:43,760 say if main wants to use the in function 7576 04:49:41,638 --> 04:49:45,920 well then main should probably tell the 7577 04:49:43,760 --> 04:49:48,200 get in function what prompt to show the 7578 04:49:45,920 --> 04:49:50,320 user just like the input function recall 7579 04:49:48,200 --> 04:49:53,240 that comes with python it's up to you to 7580 04:49:50,320 --> 04:49:55,680 pass in a prompt that the user then sees 7581 04:49:53,240 --> 04:49:58,000 when the human is asked for input so how 7582 04:49:55,680 --> 04:49:59,718 do I make this work here I can go down 7583 04:49:58,000 --> 04:50:02,320 to my definition of get int and I can 7584 04:49:59,718 --> 04:50:04,120 say all right get int is going to take a 7585 04:50:02,320 --> 04:50:06,040 parameter now called prompt I could call 7586 04:50:04,120 --> 04:50:08,080 it anything I want but prompt in English 7587 04:50:06,040 --> 04:50:09,480 is pretty self-explanatory it means what 7588 04:50:08,080 --> 04:50:11,840 do you want the message the user will 7589 04:50:09,480 --> 04:50:14,520 see and now down here when I actually 7590 04:50:11,840 --> 04:50:17,040 use input I don't have to presumptuously 7591 04:50:14,520 --> 04:50:19,878 say what's X because what if the program 7592 04:50:17,040 --> 04:50:22,360 the caller wants to ask for y or Z or 7593 04:50:19,878 --> 04:50:25,080 some other variable I can just pass to 7594 04:50:22,360 --> 04:50:27,878 input whatever prompt the caller has 7595 04:50:25,080 --> 04:50:30,080 provided so now I'm making more reusable 7596 04:50:27,878 --> 04:50:32,240 code it still works just the same I 7597 04:50:30,080 --> 04:50:33,920 haven't changed the functionality per se 7598 04:50:32,240 --> 04:50:36,120 but now it's a little more dynamic 7599 04:50:33,920 --> 04:50:38,760 because now get int doesn't have to know 7600 04:50:36,120 --> 04:50:40,878 or care what variable is being asked for 7601 04:50:38,760 --> 04:50:42,760 what's being asked for it just needs to 7602 04:50:40,878 --> 04:50:45,200 know what prompt it should show to the 7603 04:50:42,760 --> 04:50:47,920 user so if I now run this program down 7604 04:50:45,200 --> 04:50:50,638 here again prompt number. piy enter 7605 04:50:47,920 --> 04:50:52,718 what's x 50 still seems to work let's 7606 04:50:50,638 --> 04:50:54,958 run it again let's type in cat it still 7607 04:50:52,718 --> 04:50:56,798 seems to work and if I type in cat dog 7608 04:50:54,958 --> 04:50:58,600 bird or anything else it will keep 7609 04:50:56,798 --> 04:51:01,040 prompting me with that same prompt 7610 04:50:58,600 --> 04:51:03,520 making this code therefore all the more 7611 04:51:01,040 --> 04:51:06,040 usable now it turns out too you can even 7612 04:51:03,520 --> 04:51:08,638 raise exceptions yourself using Python's 7613 04:51:06,040 --> 04:51:10,958 raise keyword but more on that another 7614 04:51:08,638 --> 04:51:12,440 time so in the coming days the coming 7615 04:51:10,958 --> 04:51:14,320 weeks the coming months as you write 7616 04:51:12,440 --> 04:51:16,160 more code in Python you'll see that 7617 04:51:14,320 --> 04:51:18,200 errors are inevitable sometimes there's 7618 04:51:16,160 --> 04:51:19,958 syntax errors which you got to just fix 7619 04:51:18,200 --> 04:51:22,080 if you even want to run your program at 7620 04:51:19,958 --> 04:51:23,558 all but they could be name errors for 7621 04:51:22,080 --> 04:51:25,798 instance variables that you meant to 7622 04:51:23,558 --> 04:51:27,200 Define but somehow didn't value errors 7623 04:51:25,798 --> 04:51:29,080 where maybe the user didn't cooperate 7624 04:51:27,200 --> 04:51:31,520 and provided you with something that you 7625 04:51:29,080 --> 04:51:34,120 weren't expecting or a whole list of 7626 04:51:31,520 --> 04:51:35,798 other possible errors or exceptions but 7627 04:51:34,120 --> 04:51:37,878 now hopefully you know how you can 7628 04:51:35,798 --> 04:51:39,958 handle these errors and respond to them 7629 04:51:37,878 --> 04:51:41,040 in any way you like this then was our 7630 04:51:39,958 --> 04:51:44,240 look at except 7631 04:51:41,040 --> 04:51:44,240 and we'll see you next 7632 04:51:49,830 --> 04:51:58,660 [Music] 7633 04:52:00,700 --> 04:52:07,570 [Music] 7634 04:52:08,798 --> 04:52:13,920 time all right this is cs50's 7635 04:52:11,958 --> 04:52:15,480 Introduction to programming with python 7636 04:52:13,920 --> 04:52:18,240 my name is David Meen and this is our 7637 04:52:15,480 --> 04:52:20,440 week on libraries so libraries are 7638 04:52:18,240 --> 04:52:22,160 generally files of code that other 7639 04:52:20,440 --> 04:52:24,638 people have written that you can use in 7640 04:52:22,160 --> 04:52:26,120 your own programs or a libraries code 7641 04:52:24,638 --> 04:52:27,798 that you've written that you can use in 7642 04:52:26,120 --> 04:52:30,440 your own program but maybe not just this 7643 04:52:27,798 --> 04:52:32,878 program but another and another as well 7644 04:52:30,440 --> 04:52:35,240 so python supports exactly this idea 7645 04:52:32,878 --> 04:52:37,160 this ability to share code with others 7646 04:52:35,240 --> 04:52:39,000 share code across your own projects and 7647 04:52:37,160 --> 04:52:41,400 it does so by way of what it calls 7648 04:52:39,000 --> 04:52:44,160 module a module in python is just a 7649 04:52:41,400 --> 04:52:46,320 library that typically has one or more 7650 04:52:44,160 --> 04:52:48,558 functions or other features built into 7651 04:52:46,320 --> 04:52:50,680 it generally the purpose of a library or 7652 04:52:48,558 --> 04:52:53,080 a module specifically is to encourage 7653 04:52:50,680 --> 04:52:55,480 reusability of code if you find yourself 7654 04:52:53,080 --> 04:52:57,480 using the same types of functions again 7655 04:52:55,480 --> 04:52:59,718 and again the same functionality if you 7656 04:52:57,480 --> 04:53:02,360 find yourself copying and pasting from 7657 04:52:59,718 --> 04:53:04,520 an old project into your new project 7658 04:53:02,360 --> 04:53:06,600 odds are there's an opportunity there to 7659 04:53:04,520 --> 04:53:08,000 factor out that code that you keep 7660 04:53:06,600 --> 04:53:10,680 copying and pasting that you keep 7661 04:53:08,000 --> 04:53:12,958 reusing and put it into a library that 7662 04:53:10,680 --> 04:53:14,840 you can then load into your programs 7663 04:53:12,958 --> 04:53:16,080 moving forward so as to not just copy 7664 04:53:14,840 --> 04:53:18,480 and paste it and have all these 7665 04:53:16,080 --> 04:53:20,280 different copies all over so what are 7666 04:53:18,480 --> 04:53:22,480 some of the modules or libraries that 7667 04:53:20,280 --> 04:53:24,878 python comes with well python comes with 7668 04:53:22,480 --> 04:53:26,840 a random Library literally which is to 7669 04:53:24,878 --> 04:53:28,920 say that when you install the python 7670 04:53:26,840 --> 04:53:30,638 interpreter on your Mac or PC or 7671 04:53:28,920 --> 04:53:32,280 somewhere in the cloud not only do you 7672 04:53:30,638 --> 04:53:34,718 get python you get a whole bunch of 7673 04:53:32,280 --> 04:53:36,000 modules as well now these modules 7674 04:53:34,718 --> 04:53:38,160 provide you with functions that you 7675 04:53:36,000 --> 04:53:40,798 don't have access to just by default 7676 04:53:38,160 --> 04:53:42,798 like you do print and input print and 7677 04:53:40,798 --> 04:53:45,320 input and other such functions just work 7678 04:53:42,798 --> 04:53:47,680 in Python but sometimes functions are 7679 04:53:45,320 --> 04:53:49,718 tucked away in these modules so you have 7680 04:53:47,680 --> 04:53:52,120 to be more deliberate about loading them 7681 04:53:49,718 --> 04:53:53,600 into the computer's memory so somewhere 7682 04:53:52,120 --> 04:53:55,760 on the computer's hard drive once you've 7683 04:53:53,600 --> 04:53:59,200 installed python there is also it turns 7684 04:53:55,760 --> 04:54:00,958 out a file probably called random. py 7685 04:53:59,200 --> 04:54:03,200 that someone else wrote probably long 7686 04:54:00,958 --> 04:54:05,200 ago but that you have access to and in 7687 04:54:03,200 --> 04:54:07,120 that random. piy file there's probably 7688 04:54:05,200 --> 04:54:10,480 one or more functions that you yourself 7689 04:54:07,120 --> 04:54:12,798 can use in order to do things randomly 7690 04:54:10,480 --> 04:54:14,760 that is to say how could you flip a coin 7691 04:54:12,798 --> 04:54:17,600 in a program in Python how could you 7692 04:54:14,760 --> 04:54:19,120 pick a a random number between 1 and 10 7693 04:54:17,600 --> 04:54:21,120 in Python well you need a bit of 7694 04:54:19,120 --> 04:54:23,080 Randomness and while you could figure 7695 04:54:21,120 --> 04:54:25,360 out mathematically how to write 7696 04:54:23,080 --> 04:54:26,958 functions like that yourself it's a lot 7697 04:54:25,360 --> 04:54:28,440 easier to stand on the shoulders of 7698 04:54:26,958 --> 04:54:30,520 others who've already solved that 7699 04:54:28,440 --> 04:54:33,360 problem for you so you can focus on the 7700 04:54:30,520 --> 04:54:36,040 problem that you yourself want to solve 7701 04:54:33,360 --> 04:54:37,798 so for documentation on most any python 7702 04:54:36,040 --> 04:54:39,920 module you go to the official python 7703 04:54:37,798 --> 04:54:41,878 docs and you go to a URL like this where 7704 04:54:39,920 --> 04:54:43,760 the documentation for that specific 7705 04:54:41,878 --> 04:54:45,320 module lives and within the 7706 04:54:43,760 --> 04:54:47,040 documentation you'll see a list of the 7707 04:54:45,320 --> 04:54:49,360 functions or other functionality that 7708 04:54:47,040 --> 04:54:52,798 some module provides but how do you go 7709 04:54:49,360 --> 04:54:54,360 about loading a module into your own 7710 04:54:52,798 --> 04:54:56,440 program so that you can use the 7711 04:54:54,360 --> 04:54:58,878 functions in that module well we need a 7712 04:54:56,440 --> 04:55:02,080 new keyword in Python and namely it's 7713 04:54:58,878 --> 04:55:05,440 import the import keyword in Python 7714 04:55:02,080 --> 04:55:09,040 allows you to import the contents of the 7715 04:55:05,440 --> 04:55:10,558 functions from some module in Python 7716 04:55:09,040 --> 04:55:12,798 well how might I go about using using 7717 04:55:10,558 --> 04:55:15,160 this in practice well let me propose 7718 04:55:12,798 --> 04:55:17,040 that there exists in that random module 7719 04:55:15,160 --> 04:55:19,600 this function among others so I have 7720 04:55:17,040 --> 04:55:22,600 copied and pasted from the documentation 7721 04:55:19,600 --> 04:55:25,558 uh this uh summary of a function called 7722 04:55:22,600 --> 04:55:28,638 choice now the function exists in the 7723 04:55:25,558 --> 04:55:31,320 random module so to speak not a random 7724 04:55:28,638 --> 04:55:33,160 module the random module and so 7725 04:55:31,320 --> 04:55:36,120 generally the documentation describes it 7726 04:55:33,160 --> 04:55:37,718 fully like this random. choice is how 7727 04:55:36,120 --> 04:55:39,680 you would technically call this function 7728 04:55:37,718 --> 04:55:42,000 though we'll see alternatives to that in 7729 04:55:39,680 --> 04:55:44,920 parenthesis there is a parameter called 7730 04:55:42,000 --> 04:55:47,280 seq for sequence and sequence generally 7731 04:55:44,920 --> 04:55:49,120 means a list or something that is list 7732 04:55:47,280 --> 04:55:50,760 like if you have a list of numbers or 7733 04:55:49,120 --> 04:55:52,958 strings or anything else and the 7734 04:55:50,760 --> 04:55:54,840 documentation elaborates well how can I 7735 04:55:52,958 --> 04:55:56,718 go about using this function to solve 7736 04:55:54,840 --> 04:55:58,798 perhaps a a familiar problem well let me 7737 04:55:56,718 --> 04:56:00,520 go ahead and open up vs code here and 7738 04:55:58,798 --> 04:56:03,160 let me propose that we Implement a 7739 04:56:00,520 --> 04:56:06,240 program that simulates flipping a coin a 7740 04:56:03,160 --> 04:56:09,280 coin that in the US heads heads or tails 7741 04:56:06,240 --> 04:56:12,040 the idea of which is to pick a decision 7742 04:56:09,280 --> 04:56:14,840 with 50/50 probability 50% probability 7743 04:56:12,040 --> 04:56:16,840 of heads 50% probability of Tails or you 7744 04:56:14,840 --> 04:56:18,680 can use some other mechanism like that 7745 04:56:16,840 --> 04:56:21,400 well let me go ahead and open a program 7746 04:56:18,680 --> 04:56:22,958 with code called generate. piy because I 7747 04:56:21,400 --> 04:56:25,000 want to start generating a whole bunch 7748 04:56:22,958 --> 04:56:26,920 of random information the first of which 7749 04:56:25,000 --> 04:56:29,480 is just going to be a coin toss now how 7750 04:56:26,920 --> 04:56:32,120 do I go about using that function well I 7751 04:56:29,480 --> 04:56:33,600 first have to import the random Library 7752 04:56:32,120 --> 04:56:36,160 so literally the first or among the 7753 04:56:33,600 --> 04:56:38,400 first lines of my file should be import 7754 04:56:36,160 --> 04:56:40,240 random and that just gives me access to 7755 04:56:38,400 --> 04:56:43,120 all of the functions in that specific 7756 04:56:40,240 --> 04:56:46,600 specific module now suppose I want to 7757 04:56:43,120 --> 04:56:48,920 flip a coin well I can do random. Choice 7758 04:56:46,600 --> 04:56:50,680 per the documentation a moment ago and 7759 04:56:48,920 --> 04:56:52,360 that again takes a sequence what's a 7760 04:56:50,680 --> 04:56:54,480 sequence it's a list or something that's 7761 04:56:52,360 --> 04:56:56,480 list like and we know about lists we've 7762 04:56:54,480 --> 04:56:58,080 used lists to iterate over numbers we've 7763 04:56:56,480 --> 04:57:00,120 used list to iterate over students at 7764 04:56:58,080 --> 04:57:02,680 Hogwarts let's go ahead now and list 7765 04:57:00,120 --> 04:57:06,160 iterate over just a list of two sides of 7766 04:57:02,680 --> 04:57:07,760 a coin heads quote unquote or tails now 7767 04:57:06,160 --> 04:57:10,240 I could call these anything I want these 7768 04:57:07,760 --> 04:57:11,600 are my strings I just want to simulate 7769 04:57:10,240 --> 04:57:14,120 tossing a coin so I'm just going to say 7770 04:57:11,600 --> 04:57:16,558 in all lower case heads and tails but 7771 04:57:14,120 --> 04:57:17,920 notice the syntax I have heads and tails 7772 04:57:16,558 --> 04:57:19,878 in double quotes that's because they're 7773 04:57:17,920 --> 04:57:21,558 strings I could also use single quotes 7774 04:57:19,878 --> 04:57:23,000 so long as I'm consistent there's a 7775 04:57:21,558 --> 04:57:25,718 comma between them which means the list 7776 04:57:23,000 --> 04:57:27,638 has two elements there's square brackets 7777 04:57:25,718 --> 04:57:29,718 to the right and the left which 7778 04:57:27,638 --> 04:57:31,718 indicates that this is indeed a list 7779 04:57:29,718 --> 04:57:33,760 that's the syntax recall for defining a 7780 04:57:31,718 --> 04:57:35,160 list in Python and then lastly there's 7781 04:57:33,760 --> 04:57:37,120 something more familiar there's the 7782 04:57:35,160 --> 04:57:38,120 parentheses outside of those square 7783 04:57:37,120 --> 04:57:40,320 brackets but those are just the 7784 04:57:38,120 --> 04:57:42,958 parentheses that belong to the choice 7785 04:57:40,320 --> 04:57:45,558 function and specify where its parameter 7786 04:57:42,958 --> 04:57:49,000 gets passed in but again unlike ped 7787 04:57:45,558 --> 04:57:51,000 functions I have to specify what module 7788 04:57:49,000 --> 04:57:53,680 this function is in at least for now and 7789 04:57:51,000 --> 04:57:55,360 so I do random. choice to call this 7790 04:57:53,680 --> 04:57:57,520 specific function all right well it's 7791 04:57:55,360 --> 04:57:59,718 one thing to flip a coin picking between 7792 04:57:57,520 --> 04:58:02,000 those with 50% probability and that's 7793 04:57:59,718 --> 04:58:04,080 what random. choice does it takes in a 7794 04:58:02,000 --> 04:58:06,638 list and it returns to one of those 7795 04:58:04,080 --> 04:58:08,080 values randomly with equal probability 7796 04:58:06,638 --> 04:58:10,520 because I've passed in two items I've 7797 04:58:08,080 --> 04:58:13,160 got a 50/50 chance if I passed in three 7798 04:58:10,520 --> 04:58:15,200 items it'd be a 33% chance for each of 7799 04:58:13,160 --> 04:58:17,160 those items and so forth python does the 7800 04:58:15,200 --> 04:58:18,680 math for you but I want to store the 7801 04:58:17,160 --> 04:58:21,160 value of this in a variable so let's 7802 04:58:18,680 --> 04:58:23,000 Define a variable called coin equals 7803 04:58:21,160 --> 04:58:24,920 whatever the return value is so this is 7804 04:58:23,000 --> 04:58:27,558 indeed like flipping a coin I'm going to 7805 04:58:24,920 --> 04:58:29,320 store in a variable called coin whatever 7806 04:58:27,558 --> 04:58:31,200 that value is heads or tails and now 7807 04:58:29,320 --> 04:58:33,520 just so I can see what's going on let's 7808 04:58:31,200 --> 04:58:35,600 go ahead and print out the value of that 7809 04:58:33,520 --> 04:58:37,200 string coin all right let me go ahead 7810 04:58:35,600 --> 04:58:41,240 now and run this program in my terminal 7811 04:58:37,200 --> 04:58:42,840 window python of generate. P enter and 7812 04:58:41,240 --> 04:58:44,920 it looks like the first coin toss was 7813 04:58:42,840 --> 04:58:47,080 the heads let's go ahead and run it 7814 04:58:44,920 --> 04:58:48,600 again and it looks like it was heads 7815 04:58:47,080 --> 04:58:50,280 again maybe you want to chime into the 7816 04:58:48,600 --> 04:58:52,000 chat here if I run it a third time 7817 04:58:50,280 --> 04:58:54,320 what's it going to be this time if you 7818 04:58:52,000 --> 04:58:56,958 want to type your thoughts in the 7819 04:58:54,320 --> 04:58:59,718 chat you might think there's a bug here 7820 04:58:56,958 --> 04:59:01,718 but this is probability in action if I 7821 04:58:59,718 --> 04:59:04,080 go ahead and hit enter a third time 7822 04:59:01,718 --> 04:59:06,360 there it's actually now tails and again 7823 04:59:04,080 --> 04:59:08,958 tails and again tails and again tails 7824 04:59:06,360 --> 04:59:11,000 and again tails and again heads now if 7825 04:59:08,958 --> 04:59:13,240 we did this in infinite number of times 7826 04:59:11,000 --> 04:59:15,360 it would indeed work out to be 50/50 if 7827 04:59:13,240 --> 04:59:17,240 we only do it a few times it might not 7828 04:59:15,360 --> 04:59:19,360 work out as cleanly but that's how 7829 04:59:17,240 --> 04:59:21,680 probabilities indeed work all right so 7830 04:59:19,360 --> 04:59:23,080 I've got that now working could I have 7831 04:59:21,680 --> 04:59:24,760 implemented this in a different way well 7832 04:59:23,080 --> 04:59:27,878 let me show you an alternative to 7833 04:59:24,760 --> 04:59:30,200 actually using the import keyword alone 7834 04:59:27,878 --> 04:59:33,160 and let me introduce the keyword from in 7835 04:59:30,200 --> 04:59:35,160 Python so from is a keyword in Python 7836 04:59:33,160 --> 04:59:37,600 that you can use when importing 7837 04:59:35,160 --> 04:59:39,440 functions from a module but it allows 7838 04:59:37,600 --> 04:59:41,760 you to be a little more specific than 7839 04:59:39,440 --> 04:59:43,360 import Al Lo so if I go back to my code 7840 04:59:41,760 --> 04:59:45,920 here it's worth noting that what 7841 04:59:43,360 --> 04:59:48,200 technically I'm doing here by importing 7842 04:59:45,920 --> 04:59:50,840 random is I'm technically importing 7843 04:59:48,200 --> 04:59:53,638 everything that's in that module so not 7844 04:59:50,840 --> 04:59:55,680 just the function called random. choice 7845 04:59:53,638 --> 04:59:57,160 but a few other functions as well so 7846 04:59:55,680 --> 04:59:59,120 instead of using this line of code at 7847 04:59:57,160 --> 05:00:00,920 the top of my file import random which 7848 04:59:59,120 --> 05:00:03,520 will technically give me access to all 7849 05:00:00,920 --> 05:00:05,840 of the contents there in a downside of 7850 05:00:03,520 --> 05:00:08,558 that is that I have to type in random. 7851 05:00:05,840 --> 05:00:10,638 choice random. this random. that because 7852 05:00:08,558 --> 05:00:12,558 all of the functions I'm calling have to 7853 05:00:10,638 --> 05:00:14,558 be associated with the scope of that 7854 05:00:12,558 --> 05:00:16,958 module well suppose that I just want to 7855 05:00:14,558 --> 05:00:18,798 call the function as its name choice I 7856 05:00:16,958 --> 05:00:22,360 can do that as well let me replace this 7857 05:00:18,798 --> 05:00:24,798 first line here with from random import 7858 05:00:22,360 --> 05:00:27,840 choice and what this does effectively is 7859 05:00:24,798 --> 05:00:30,760 it loads the functions name Choice into 7860 05:00:27,840 --> 05:00:33,040 my current name space into the scope of 7861 05:00:30,760 --> 05:00:35,320 the file I'm working in what that means 7862 05:00:33,040 --> 05:00:37,760 is that I now know longer have to 7863 05:00:35,320 --> 05:00:40,040 specify Which choice function I mean I 7864 05:00:37,760 --> 05:00:42,120 can just say choice and so it loads it 7865 05:00:40,040 --> 05:00:44,480 into the local namespace that is into my 7866 05:00:42,120 --> 05:00:47,440 local vocabulary if you will so I can 7867 05:00:44,480 --> 05:00:50,480 just now say choice this might be 7868 05:00:47,440 --> 05:00:53,000 advantageous in what cases do you think 7869 05:00:50,480 --> 05:00:55,680 when might you want to import the name 7870 05:00:53,000 --> 05:00:57,958 of the function explicitly like this as 7871 05:00:55,680 --> 05:01:00,200 opposed to just saying random. choice 7872 05:00:57,958 --> 05:01:02,958 random. choice throughout your code when 7873 05:01:00,200 --> 05:01:07,120 calling a function any instincts here 7874 05:01:02,958 --> 05:01:09,440 for this alternative import using from 7875 05:01:07,120 --> 05:01:12,558 um hello I'm Mohammed from Egypt and 7876 05:01:09,440 --> 05:01:14,920 maybe if we have a variable that its 7877 05:01:12,558 --> 05:01:16,840 name is basically like choice if I have 7878 05:01:14,920 --> 05:01:19,000 a variable called the choice so I need 7879 05:01:16,840 --> 05:01:22,240 to differentiate Which choice I choose 7880 05:01:19,000 --> 05:01:23,798 so I'm gonna choose random DOTA Choice 7881 05:01:22,240 --> 05:01:26,000 yeah really good instincts by using the 7882 05:01:23,798 --> 05:01:27,680 first approach by just importing random 7883 05:01:26,000 --> 05:01:30,400 you're making sure that all of its 7884 05:01:27,680 --> 05:01:33,120 contents are associated with are scoped 7885 05:01:30,400 --> 05:01:34,798 to the random module so that you can 7886 05:01:33,120 --> 05:01:36,798 have your own choice function you can 7887 05:01:34,798 --> 05:01:38,840 have your own choice variable you can 7888 05:01:36,798 --> 05:01:40,600 use the same names as all of the 7889 05:01:38,840 --> 05:01:42,480 functions or variables that are stored 7890 05:01:40,600 --> 05:01:44,320 inside of that file without them 7891 05:01:42,480 --> 05:01:46,638 colliding so to speak and this is a good 7892 05:01:44,320 --> 05:01:48,480 thing in older languages it was the case 7893 05:01:46,638 --> 05:01:50,120 that if you imported someone's Library 7894 05:01:48,480 --> 05:01:52,280 you better hope that you're not using 7895 05:01:50,120 --> 05:01:54,040 the same functions or variables as they 7896 05:01:52,280 --> 05:01:56,080 are because you might in fact have some 7897 05:01:54,040 --> 05:01:57,878 kind of conflict Python and certain 7898 05:01:56,080 --> 05:01:59,878 other languages allow you to scope the 7899 05:01:57,878 --> 05:02:01,760 names of those functions and variables 7900 05:01:59,878 --> 05:02:03,958 to the file or the module that they come 7901 05:02:01,760 --> 05:02:06,680 from so that's a good thing but honestly 7902 05:02:03,958 --> 05:02:08,680 this is such a short program or 7903 05:02:06,680 --> 05:02:11,240 equivalently maybe I'm using the choice 7904 05:02:08,680 --> 05:02:13,520 function in so many places calling 7905 05:02:11,240 --> 05:02:15,080 random. choice random. choice random. 7906 05:02:13,520 --> 05:02:17,680 choice it's just making my code longer 7907 05:02:15,080 --> 05:02:20,280 and longer and longer marginally so but 7908 05:02:17,680 --> 05:02:22,520 it just getting ugly and annoying I can 7909 05:02:20,280 --> 05:02:24,440 simply import choice and now tighten up 7910 05:02:22,520 --> 05:02:26,200 my code a little bit so as with so many 7911 05:02:24,440 --> 05:02:28,080 decisions in the past there's not 7912 05:02:26,200 --> 05:02:29,798 necessarily one right approach or 7913 05:02:28,080 --> 05:02:31,760 another it depends but I think for those 7914 05:02:29,798 --> 05:02:34,120 very reasons sometimes it's better to do 7915 05:02:31,760 --> 05:02:36,760 what we did the first time which is only 7916 05:02:34,120 --> 05:02:39,120 import the module so as to retain the 7917 05:02:36,760 --> 05:02:40,878 scope therein well let me propose that 7918 05:02:39,120 --> 05:02:43,200 we transition to to another function 7919 05:02:40,878 --> 05:02:44,320 that comes with Python's random module 7920 05:02:43,200 --> 05:02:47,040 and that's this here from the 7921 05:02:44,320 --> 05:02:49,320 documentation Rand int it's a bit hard 7922 05:02:47,040 --> 05:02:50,920 to say but it implies get back a random 7923 05:02:49,320 --> 05:02:54,080 int and if you read the documentation 7924 05:02:50,920 --> 05:02:56,520 it's a random int that's between A and B 7925 05:02:54,080 --> 05:02:59,120 inclusive so if you were to pass in one 7926 05:02:56,520 --> 05:03:01,480 for a and 10 for B you would get back a 7927 05:02:59,120 --> 05:03:03,480 number between one and 10 inclusive 7928 05:03:01,480 --> 05:03:06,320 including the one and including the 10 7929 05:03:03,480 --> 05:03:08,280 potentially each with a 10% probability 7930 05:03:06,320 --> 05:03:09,840 so how might I go about using a program 7931 05:03:08,280 --> 05:03:12,240 like this well let me come back to my 7932 05:03:09,840 --> 05:03:14,120 generate. piy file and why don't we go 7933 05:03:12,240 --> 05:03:15,480 ahead and try generating a random number 7934 05:03:14,120 --> 05:03:16,798 between 1 and 10 you might do this 7935 05:03:15,480 --> 05:03:17,878 frequently in the real world when you 7936 05:03:16,798 --> 05:03:19,160 just want someone to pick a random 7937 05:03:17,878 --> 05:03:21,160 number you tell them as much and the 7938 05:03:19,160 --> 05:03:23,040 human responds let's get the computer to 7939 05:03:21,160 --> 05:03:24,798 do the same here let me go ahead and 7940 05:03:23,040 --> 05:03:26,878 delete my two lines of code at the 7941 05:03:24,798 --> 05:03:28,320 bottom but keep my import random and 7942 05:03:26,878 --> 05:03:30,320 let's go ahead and Define a variable 7943 05:03:28,320 --> 05:03:33,440 this time called number set it equal to 7944 05:03:30,320 --> 05:03:37,120 the return value of random. randint and 7945 05:03:33,440 --> 05:03:39,440 now pass in a a value of one and B a 7946 05:03:37,120 --> 05:03:41,638 value of 10 and now let's go ahead and 7947 05:03:39,440 --> 05:03:43,680 print the number I'm going to go ahead 7948 05:03:41,638 --> 05:03:46,440 in my terminal window and run python of 7949 05:03:43,680 --> 05:03:49,000 generate. Pi and hit enter 7950 05:03:46,440 --> 05:03:55,240 four python of generate. Pi and hit 7951 05:03:49,000 --> 05:03:57,760 enter eight again nine again s again 10 7952 05:03:55,240 --> 05:03:59,558 again two again and we can do this all 7953 05:03:57,760 --> 05:04:01,840 day long and if we add all of those up 7954 05:03:59,558 --> 05:04:04,360 they should end up being with 10% 7955 05:04:01,840 --> 05:04:05,558 probability each now how might you use 7956 05:04:04,360 --> 05:04:07,080 this information well maybe we're 7957 05:04:05,558 --> 05:04:09,878 playing a guessing game or maybe we're 7958 05:04:07,080 --> 05:04:11,840 trying to randomize the behavior of some 7959 05:04:09,878 --> 05:04:13,958 character in the game you can imagine 7960 05:04:11,840 --> 05:04:15,718 using very simple building blocks like 7961 05:04:13,958 --> 05:04:17,360 this just kind of spicing up your 7962 05:04:15,718 --> 05:04:19,558 program by getting it to do things a 7963 05:04:17,360 --> 05:04:22,000 little less predictably because you're 7964 05:04:19,558 --> 05:04:23,320 choosing these values seemingly randomly 7965 05:04:22,000 --> 05:04:25,000 and you're deferring to python to 7966 05:04:23,320 --> 05:04:27,680 actually do the generation of these 7967 05:04:25,000 --> 05:04:29,798 numbers uh using its own algorithms and 7968 05:04:27,680 --> 05:04:31,320 its own math well what more could we do 7969 05:04:29,798 --> 05:04:32,718 here let me propose that we introduce 7970 05:04:31,320 --> 05:04:34,320 another function that comes from this 7971 05:04:32,718 --> 05:04:36,400 random Library yet another that you 7972 05:04:34,320 --> 05:04:38,520 yourself have don't have to implement 7973 05:04:36,400 --> 05:04:40,920 Shuffle if you read the documentation 7974 05:04:38,520 --> 05:04:42,760 for Shuffle in the same random module 7975 05:04:40,920 --> 05:04:44,840 you'll see that it takes in a list for 7976 05:04:42,760 --> 05:04:47,240 instance of values and just shuffles 7977 05:04:44,840 --> 05:04:49,200 them up it randomizes them like a a deck 7978 05:04:47,240 --> 05:04:50,798 of cards here you might shuffle them so 7979 05:04:49,200 --> 05:04:53,440 it's to put them into seemingly random 7980 05:04:50,798 --> 05:04:55,400 order well how do I use this based on 7981 05:04:53,440 --> 05:04:57,520 this function's name well let me propose 7982 05:04:55,400 --> 05:04:59,280 that we go back to vs code here and let 7983 05:04:57,520 --> 05:05:01,360 me go ahead and this time do the 7984 05:04:59,280 --> 05:05:03,360 following because I need to shuffle 7985 05:05:01,360 --> 05:05:05,160 something like a deck of cards let me go 7986 05:05:03,360 --> 05:05:07,360 ahead and not just import random but let 7987 05:05:05,160 --> 05:05:09,280 me give myself a variable called cards 7988 05:05:07,360 --> 05:05:11,080 that's going to be of type list and just 7989 05:05:09,280 --> 05:05:13,600 so I have something to shuffle I don't 7990 05:05:11,080 --> 05:05:15,920 need all 52 cards in a typical deck I'm 7991 05:05:13,600 --> 05:05:18,160 just going to shuffle three cards a jack 7992 05:05:15,920 --> 05:05:19,600 a queen and a king I could call those 7993 05:05:18,160 --> 05:05:21,718 strings anything I want but I just 7994 05:05:19,600 --> 05:05:23,558 wanted a list of some values so as to 7995 05:05:21,718 --> 05:05:25,760 shuffle them up that is randomize the 7996 05:05:23,558 --> 05:05:27,280 order therein well how does this now 7997 05:05:25,760 --> 05:05:29,760 work if you read the documentation for 7998 05:05:27,280 --> 05:05:33,120 random. Shuffle you'll see that it 7999 05:05:29,760 --> 05:05:34,840 shuffles the argument in place that is 8000 05:05:33,120 --> 05:05:37,280 unlike many of the functions we've seen 8001 05:05:34,840 --> 05:05:39,638 it doesn't return to a value that 8002 05:05:37,280 --> 05:05:42,320 contains the shuffled cards in this case 8003 05:05:39,638 --> 05:05:44,480 it actually shuffles the list it's given 8004 05:05:42,320 --> 05:05:46,360 itself so what this means for my code is 8005 05:05:44,480 --> 05:05:50,120 that I need to do something like this 8006 05:05:46,360 --> 05:05:52,798 random. Shuffle and pass in the variable 8007 05:05:50,120 --> 05:05:55,000 containing those cards and then on a 8008 05:05:52,798 --> 05:05:57,600 final line here how might I go about 8009 05:05:55,000 --> 05:06:00,080 printing the cards well I could do this 8010 05:05:57,600 --> 05:06:01,718 and I could say print cards but if I do 8011 05:06:00,080 --> 05:06:03,400 that I'm actually going to see python 8012 05:06:01,718 --> 05:06:06,000 Syntax for lists and it's just going to 8013 05:06:03,400 --> 05:06:07,600 format in its own way using commas and 8014 05:06:06,000 --> 05:06:09,240 the like I want to print these cards out 8015 05:06:07,600 --> 05:06:10,878 one at a time just because I think it'll 8016 05:06:09,240 --> 05:06:12,920 look a a little better so we can use 8017 05:06:10,878 --> 05:06:16,638 some of our syntax from loops and say 8018 05:06:12,920 --> 05:06:19,320 something like this for card in cards go 8019 05:06:16,638 --> 05:06:21,600 ahead and print out the current card so 8020 05:06:19,320 --> 05:06:23,840 what's now Happening Here line three I'm 8021 05:06:21,600 --> 05:06:27,600 defining a list of three cards in this 8022 05:06:23,840 --> 05:06:29,638 order Jack queen king I'm then shuffling 8023 05:06:27,600 --> 05:06:31,798 those same cards on line four and then 8024 05:06:29,638 --> 05:06:34,718 on line five I'm using a for Loop for 8025 05:06:31,798 --> 05:06:37,040 each of the cards in that list print it 8026 05:06:34,718 --> 05:06:39,760 out one at a time and because I'm using 8027 05:06:37,040 --> 05:06:41,160 print one line at a time well let's see 8028 05:06:39,760 --> 05:06:42,240 the results down here in my terminal 8029 05:06:41,160 --> 05:06:46,160 window I'm going to run python of 8030 05:06:42,240 --> 05:06:47,920 generate. and hit enter queen king Jack 8031 05:06:46,160 --> 05:06:49,920 seemingly shuffled cuz that's not the 8032 05:06:47,920 --> 05:06:53,600 order I defined earlier let's do it 8033 05:06:49,920 --> 05:06:55,320 again queen king Jack H okay that 8034 05:06:53,600 --> 05:06:57,600 happens to be the same but let's see 8035 05:06:55,320 --> 05:07:00,240 this could just be bad chance there we 8036 05:06:57,600 --> 05:07:01,798 go Jack queen king doesn't look like 8037 05:07:00,240 --> 05:07:04,760 it's shuffled but at least we're getting 8038 05:07:01,798 --> 05:07:08,120 back different orderings now again jack 8039 05:07:04,760 --> 05:07:09,600 queen king hm not so good Jack queen 8040 05:07:08,120 --> 05:07:11,320 king not so good this is someone you you 8041 05:07:09,600 --> 05:07:13,600 probably want to play against with cards 8042 05:07:11,320 --> 05:07:15,400 Queen Jack King there we go but of 8043 05:07:13,600 --> 05:07:17,600 course we only have three cards here so 8044 05:07:15,400 --> 05:07:19,040 there's not that many permutations we 8045 05:07:17,600 --> 05:07:21,000 might see and if we do this over time we 8046 05:07:19,040 --> 05:07:23,600 will see all of them but if we had of 8047 05:07:21,000 --> 05:07:26,200 course 13 or 52 cards we'd see a lot 8048 05:07:23,600 --> 05:07:28,280 more permutations instead so we have now 8049 05:07:26,200 --> 05:07:30,200 these three ways to Generate random 8050 05:07:28,280 --> 05:07:32,040 information one is simple coin toss if 8051 05:07:30,200 --> 05:07:34,000 you want to start some kind of athletic 8052 05:07:32,040 --> 05:07:35,638 event one pick a number between one and 8053 05:07:34,000 --> 05:07:37,760 10 if you want to decide something based 8054 05:07:35,638 --> 05:07:39,718 on that and now using Shuffle we can 8055 05:07:37,760 --> 05:07:41,638 even take in a list of things and 8056 05:07:39,718 --> 05:07:44,440 shuffle them about so that we get some 8057 05:07:41,638 --> 05:07:46,000 kind of random Behavior let me pause 8058 05:07:44,440 --> 05:07:50,480 here and see if there's any questions 8059 05:07:46,000 --> 05:07:51,480 yet on random on modules or any of these 8060 05:07:50,480 --> 05:07:54,120 three 8061 05:07:51,480 --> 05:07:55,558 functions yeah uh can we increase or 8062 05:07:54,120 --> 05:07:57,718 decrease the 8063 05:07:55,558 --> 05:08:00,878 probability uh of 8064 05:07:57,718 --> 05:08:03,480 costs if you want to for example there 8065 05:08:00,878 --> 05:08:05,840 is three there is a 33% chance of 8066 05:08:03,480 --> 05:08:08,080 probability so is there any chance to 8067 05:08:05,840 --> 05:08:10,360 increase or decrease the probability can 8068 05:08:08,080 --> 05:08:12,718 you set these probabilities not using 8069 05:08:10,360 --> 05:08:14,840 these same functions uh can you set the 8070 05:08:12,718 --> 05:08:16,480 probabilities but you can absolutely 8071 05:08:14,840 --> 05:08:18,320 Implement some of your own functions or 8072 05:08:16,480 --> 05:08:20,200 use more sophisticated functions that do 8073 05:08:18,320 --> 05:08:22,200 exist in this library and others to 8074 05:08:20,200 --> 05:08:23,760 exercise more control these are meant to 8075 05:08:22,200 --> 05:08:25,160 be very userfriendly and simple 8076 05:08:23,760 --> 05:08:27,000 functions certainly the ones we looked 8077 05:08:25,160 --> 05:08:28,920 at that give you equal probability for 8078 05:08:27,000 --> 05:08:30,680 all of those but absolutely you could 8079 05:08:28,920 --> 05:08:32,280 skew things though hopefully if you're 8080 05:08:30,680 --> 05:08:33,878 implementing a gambling game or the like 8081 05:08:32,280 --> 05:08:36,760 you're not actually making some cards 8082 05:08:33,878 --> 05:08:39,558 more probable than others allow me to 8083 05:08:36,760 --> 05:08:41,400 turn back now to our implementation here 8084 05:08:39,558 --> 05:08:42,798 of this Randomness and consider how we 8085 05:08:41,400 --> 05:08:44,798 might leverage other types of 8086 05:08:42,798 --> 05:08:47,160 functionality that aren't necessarily in 8087 05:08:44,798 --> 05:08:48,920 this specific Library here well it turns 8088 05:08:47,160 --> 05:08:51,040 out that python also comes with a 8089 05:08:48,920 --> 05:08:52,920 statistics library and this contains all 8090 05:08:51,040 --> 05:08:55,400 sorts of functions for doing things more 8091 05:08:52,920 --> 05:08:58,760 statistical in nature namely calculating 8092 05:08:55,400 --> 05:09:00,480 means or medians or modes or other uh 8093 05:08:58,760 --> 05:09:03,040 aspects of a data set that you might 8094 05:09:00,480 --> 05:09:04,840 want to analyze so how might we use the 8095 05:09:03,040 --> 05:09:06,000 statistics module on python well we 8096 05:09:04,840 --> 05:09:08,200 might first just take a look at its 8097 05:09:06,000 --> 05:09:09,958 documentation like any other module on 8098 05:09:08,200 --> 05:09:11,680 Python and we'll see Within that library 8099 05:09:09,958 --> 05:09:13,400 that there's a whole bunch of functions 8100 05:09:11,680 --> 05:09:15,360 and one of those functions is one that's 8101 05:09:13,400 --> 05:09:17,480 quite simple it's average a function 8102 05:09:15,360 --> 05:09:19,520 that allows you to calculate the average 8103 05:09:17,480 --> 05:09:21,160 of some numbers that you've passed in 8104 05:09:19,520 --> 05:09:23,360 let me go ahead and nvs code in my 8105 05:09:21,160 --> 05:09:25,680 terminal window open up a new file 8106 05:09:23,360 --> 05:09:27,280 called average. piy and at the top of 8107 05:09:25,680 --> 05:09:29,400 this file I'm going to import a 8108 05:09:27,280 --> 05:09:32,080 different Library this time namely the 8109 05:09:29,400 --> 05:09:33,558 statistics module in Python and now I'm 8110 05:09:32,080 --> 05:09:36,360 going to go ahead and call a function 8111 05:09:33,558 --> 05:09:38,558 that I know comes in that module namely 8112 05:09:36,360 --> 05:09:41,080 mean for the average of some values and 8113 05:09:38,558 --> 05:09:43,760 I'm going to call Stat statistics. mean 8114 05:09:41,080 --> 05:09:45,840 and I'm going to pass into this function 8115 05:09:43,760 --> 05:09:47,160 mean a list of some values and let's 8116 05:09:45,840 --> 05:09:49,320 suppose that I'm quickly trying to 8117 05:09:47,160 --> 05:09:51,360 calculate what my current grade average 8118 05:09:49,320 --> 05:09:53,638 is in school and I did really well on my 8119 05:09:51,360 --> 05:09:55,360 first test and I got 100% And on my 8120 05:09:53,638 --> 05:09:57,718 second I did well but not as well and I 8121 05:09:55,360 --> 05:09:59,280 got a 90 and ironically I'm not very 8122 05:09:57,718 --> 05:10:01,360 good with math so I'd like to figure out 8123 05:09:59,280 --> 05:10:03,160 what my average now is between those two 8124 05:10:01,360 --> 05:10:06,360 tests so let me go ahead now and in this 8125 05:10:03,160 --> 05:10:08,480 list type in the number 100 comma 90 8126 05:10:06,360 --> 05:10:11,798 thereby passing in a list of two values 8127 05:10:08,480 --> 05:10:13,400 to ins one 190 and in outside of those 8128 05:10:11,798 --> 05:10:15,320 are the parentheses because of course 8129 05:10:13,400 --> 05:10:17,080 this is now the argument I'm passing to 8130 05:10:15,320 --> 05:10:19,958 the function called mean and this 8131 05:10:17,080 --> 05:10:21,558 function mean is in the module called 8132 05:10:19,958 --> 05:10:23,160 statistics well it's not that 8133 05:10:21,558 --> 05:10:25,080 interesting to just calculate the mean 8134 05:10:23,160 --> 05:10:27,000 if I don't actually see what it is so 8135 05:10:25,080 --> 05:10:29,320 let me additionally pass the return 8136 05:10:27,000 --> 05:10:31,360 value of that mean function to the print 8137 05:10:29,320 --> 05:10:33,360 function as usual let me now in my 8138 05:10:31,360 --> 05:10:35,760 terminal window and vs code Type in 8139 05:10:33,360 --> 05:10:38,240 Python of average. piy and hit enter and 8140 05:10:35,760 --> 05:10:40,638 voila as you might expect my average is 8141 05:10:38,240 --> 05:10:42,440 95% so the difference here is that I'm 8142 05:10:40,638 --> 05:10:44,280 just using a different module that still 8143 05:10:42,440 --> 05:10:46,760 comes with python but I need to import 8144 05:10:44,280 --> 05:10:48,638 it instead of for instance the random 8145 05:10:46,760 --> 05:10:50,200 module instead and this time I know from 8146 05:10:48,638 --> 05:10:52,840 the documentation that there exists a 8147 05:10:50,200 --> 05:10:54,840 function called mean well it turns out 8148 05:10:52,840 --> 05:10:56,840 there's even more functionality that 8149 05:10:54,840 --> 05:10:59,360 comes with python and that comes with 8150 05:10:56,840 --> 05:11:01,240 other modules in Python and there's this 8151 05:10:59,360 --> 05:11:03,040 feature generally known as commandline 8152 05:11:01,240 --> 05:11:05,320 arguments this is a feature not just of 8153 05:11:03,040 --> 05:11:07,920 python but of languages more generally 8154 05:11:05,320 --> 05:11:10,718 that allow you to provide input not when 8155 05:11:07,920 --> 05:11:13,160 prompted inside of a program as happens 8156 05:11:10,718 --> 05:11:15,718 whenever we call the python function 8157 05:11:13,160 --> 05:11:17,440 input but rather there's this feature 8158 05:11:15,718 --> 05:11:19,600 command line arguments of programs that 8159 05:11:17,440 --> 05:11:22,320 allows you to provide arguments that is 8160 05:11:19,600 --> 05:11:24,120 input to the program just when you're 8161 05:11:22,320 --> 05:11:25,558 executing it at the command line so up 8162 05:11:24,120 --> 05:11:27,878 until now for instance Rec call that 8163 05:11:25,558 --> 05:11:30,920 we've generally run python of something. 8164 05:11:27,878 --> 05:11:33,320 py for instance python of hello.py and 8165 05:11:30,920 --> 05:11:35,840 I've never once really executed any 8166 05:11:33,320 --> 05:11:39,240 words or phrases after the name of the 8167 05:11:35,840 --> 05:11:41,000 file but I could in fact when you're 8168 05:11:39,240 --> 05:11:43,320 running programs in a command-like 8169 05:11:41,000 --> 05:11:45,638 environment like we are you can provide 8170 05:11:43,320 --> 05:11:48,040 any number of words or numbers or 8171 05:11:45,638 --> 05:11:50,000 phrases after the command that you're 8172 05:11:48,040 --> 05:11:52,600 typing and all of those will somehow be 8173 05:11:50,000 --> 05:11:54,638 passed in as inputs to the program 8174 05:11:52,600 --> 05:11:57,798 itself you don't have to prompt the user 8175 05:11:54,638 --> 05:11:59,958 for one thing at a time by manually 8176 05:11:57,798 --> 05:12:01,558 calling that input function so what does 8177 05:11:59,958 --> 05:12:04,160 this mean in real terms well let me go 8178 05:12:01,558 --> 05:12:07,080 ahead back into VSS code here and let me 8179 05:12:04,160 --> 05:12:09,520 propose that we consider how we might 8180 05:12:07,080 --> 05:12:11,798 leverage a certain module I'm going to 8181 05:12:09,520 --> 05:12:14,520 go ahead and create a file called uh 8182 05:12:11,798 --> 05:12:16,480 name. pi and I'd like to use a new 8183 05:12:14,520 --> 05:12:17,760 module this time that's going to give me 8184 05:12:16,480 --> 05:12:20,080 access 8185 05:12:17,760 --> 05:12:21,878 to values that have been typed at that 8186 05:12:20,080 --> 05:12:23,400 command line but what's this module 8187 05:12:21,878 --> 05:12:26,120 going to be well this one's going to be 8188 05:12:23,400 --> 05:12:27,718 called CIS and CIS short for system 8189 05:12:26,120 --> 05:12:30,160 contains a whole lot of functionality 8190 05:12:27,718 --> 05:12:32,080 that's specific to the system itself and 8191 05:12:30,160 --> 05:12:33,958 the commands that you and I are typing 8192 05:12:32,080 --> 05:12:36,160 the documentation for this module is at 8193 05:12:33,958 --> 05:12:38,040 this URL here and it lists all of the 8194 05:12:36,160 --> 05:12:40,280 various functions and variables and the 8195 05:12:38,040 --> 05:12:41,600 like that come with that module but 8196 05:12:40,280 --> 05:12:43,878 we're going to focus on something a 8197 05:12:41,600 --> 05:12:46,400 little more specific namely this thing 8198 05:12:43,878 --> 05:12:49,080 here it turns out in the CIS module in 8199 05:12:46,400 --> 05:12:52,360 Python there is a variable that just 8200 05:12:49,080 --> 05:12:54,440 magically exists for you called argv it 8201 05:12:52,360 --> 05:12:56,920 stands for argument Vector which is a 8202 05:12:54,440 --> 05:12:59,080 fancy way of describing the list of all 8203 05:12:56,920 --> 05:13:02,240 of the words that the human typed in at 8204 05:12:59,080 --> 05:13:04,120 their prompt before they hit enter all 8205 05:13:02,240 --> 05:13:07,638 of those are seemingly magically 8206 05:13:04,120 --> 05:13:11,400 provided to you via python in a variable 8207 05:13:07,638 --> 05:13:13,120 called cis.org V this variable is a list 8208 05:13:11,400 --> 05:13:14,280 which means that the first element is 8209 05:13:13,120 --> 05:13:15,558 going to be the first word that you 8210 05:13:14,280 --> 05:13:16,878 typed the second element is going to be 8211 05:13:15,558 --> 05:13:19,200 the second word that you typed and so 8212 05:13:16,878 --> 05:13:21,360 forth and by way of this list then can 8213 05:13:19,200 --> 05:13:23,000 you figure out what words did the human 8214 05:13:21,360 --> 05:13:25,480 actually type at the prompt and maybe 8215 05:13:23,000 --> 05:13:27,440 use that to influence the behavior of 8216 05:13:25,480 --> 05:13:29,360 your own program so what does this mean 8217 05:13:27,440 --> 05:13:31,878 now in real terms well in this new tab 8218 05:13:29,360 --> 05:13:34,840 called name. piy let me go ahead and 8219 05:13:31,878 --> 05:13:37,520 import CIS within that CIS module is 8220 05:13:34,840 --> 05:13:39,520 going to give me access to cy. RV but 8221 05:13:37,520 --> 05:13:41,680 how might I want to use it well let's do 8222 05:13:39,520 --> 05:13:44,760 this instead of writing a hello world 8223 05:13:41,680 --> 05:13:47,400 program that all of these times has just 8224 05:13:44,760 --> 05:13:49,240 looked for the return value of input to 8225 05:13:47,400 --> 05:13:51,280 figure out what the user wants me to 8226 05:13:49,240 --> 05:13:53,400 print let's go ahead and just expect the 8227 05:13:51,280 --> 05:13:55,600 user to tell us when they run the Python 8228 05:13:53,400 --> 05:13:57,160 program itself what their name is and 8229 05:13:55,600 --> 05:13:59,320 suppose this time I'd like to generate a 8230 05:13:57,160 --> 05:14:01,360 whole bunch of name tags initially just 8231 05:13:59,320 --> 05:14:02,920 one and in the US here it's very common 8232 05:14:01,360 --> 05:14:05,160 to wear a sticker on your lapel that 8233 05:14:02,920 --> 05:14:07,040 says hello my name is David so I want to 8234 05:14:05,160 --> 05:14:08,680 print out some text that resembles that 8235 05:14:07,040 --> 05:14:10,520 the idea being maybe I could enhance 8236 05:14:08,680 --> 05:14:11,920 this program someday to even send that 8237 05:14:10,520 --> 05:14:14,280 text straight to the printer and 8238 05:14:11,920 --> 05:14:15,840 dynamically generate those name tags 8239 05:14:14,280 --> 05:14:17,760 well let me go ahead now and do this let 8240 05:14:15,840 --> 05:14:19,320 me go ahead and print out as always 8241 05:14:17,760 --> 05:14:20,600 hello but I'll say a little something 8242 05:14:19,320 --> 05:14:23,040 more this time to make things more 8243 05:14:20,600 --> 05:14:26,480 interesting hello my name is quote 8244 05:14:23,040 --> 05:14:28,840 unquote and then after that I normally 8245 05:14:26,480 --> 05:14:31,120 have been in the habit of calling input 8246 05:14:28,840 --> 05:14:33,440 storing the return value in a variable 8247 05:14:31,120 --> 05:14:35,240 and passing in the name of that variable 8248 05:14:33,440 --> 05:14:40,638 here but I'm going to instead jump right 8249 05:14:35,240 --> 05:14:42,120 to this sis. RV bracket1 and that's it 8250 05:14:40,638 --> 05:14:44,480 I'm going to have a program here that 8251 05:14:42,120 --> 05:14:48,120 says hello my name is followed by 8252 05:14:44,480 --> 05:14:50,360 whatever is in sis. arv bracket one and 8253 05:14:48,120 --> 05:14:52,200 notice sis. argv again is a list and 8254 05:14:50,360 --> 05:14:54,240 recall from our discussion of loops and 8255 05:14:52,200 --> 05:14:57,120 in turn lists we use this square bracket 8256 05:14:54,240 --> 05:14:58,920 notation to get at the various elements 8257 05:14:57,120 --> 05:15:01,000 inside of a list all right let me go 8258 05:14:58,920 --> 05:15:03,638 down now into my terminal window and run 8259 05:15:01,000 --> 05:15:05,520 python of name. py but this time rather 8260 05:15:03,638 --> 05:15:07,320 than just hit enter and wait for the 8261 05:15:05,520 --> 05:15:09,360 program to prompt me for my name let me 8262 05:15:07,320 --> 05:15:11,400 proactively just tell this prr program 8263 05:15:09,360 --> 05:15:14,360 what my name is at the so-called command 8264 05:15:11,400 --> 05:15:16,718 line here we go David separated with a 8265 05:15:14,360 --> 05:15:19,958 space from the name of the file so that 8266 05:15:16,718 --> 05:15:23,080 now when I execute python name. py David 8267 05:15:19,958 --> 05:15:25,878 I see on the screen voila hello my name 8268 05:15:23,080 --> 05:15:27,878 is David So based on this demonstration 8269 05:15:25,878 --> 05:15:29,798 alone I think we can infer exactly 8270 05:15:27,878 --> 05:15:32,480 what's going on in cy. RGV even though 8271 05:15:29,798 --> 05:15:34,718 it sounds certainly at first glance uh 8272 05:15:32,480 --> 05:15:38,440 rather complicated here let's look up at 8273 05:15:34,718 --> 05:15:44,400 cy. Arvy I'm going to bracket one here 8274 05:15:38,440 --> 05:15:47,680 so clearly cy. RV bracket one is storing 8275 05:15:44,400 --> 05:15:49,760 David but it's one in the past when we 8276 05:15:47,680 --> 05:15:52,080 looked at Loops recall that we said that 8277 05:15:49,760 --> 05:15:54,798 they were zero indexed that is the first 8278 05:15:52,080 --> 05:15:57,520 element is zero the next element is one 8279 05:15:54,798 --> 05:15:59,520 the next element is two and so forth and 8280 05:15:57,520 --> 05:16:01,760 yet here I am treating it as though my 8281 05:15:59,520 --> 05:16:04,718 name is at the start of the list one 8282 05:16:01,760 --> 05:16:09,120 well let me ask this question what is 8283 05:16:04,718 --> 05:16:13,680 probably insist. arv of zero what is 8284 05:16:09,120 --> 05:16:16,680 probably insist. Arvy of zero the very 8285 05:16:13,680 --> 05:16:21,280 first element actually in that list oh 8286 05:16:16,680 --> 05:16:24,440 yeah uh I think uh it's like in C uh the 8287 05:16:21,280 --> 05:16:26,200 name of program indeed it's indeed like 8288 05:16:24,440 --> 05:16:28,480 in C and other language is the name of 8289 05:16:26,200 --> 05:16:31,040 the program well if we consider what it 8290 05:16:28,480 --> 05:16:31,920 was I typed I certainly typed python 8291 05:16:31,040 --> 05:16:33,440 because that's the name of my 8292 05:16:31,920 --> 05:16:35,240 interpreter and we don't really need to 8293 05:16:33,440 --> 05:16:37,280 know that because we're using python 8294 05:16:35,240 --> 05:16:39,718 itself but after that I did type two 8295 05:16:37,280 --> 05:16:41,680 things I typed name. as I've done so 8296 05:16:39,718 --> 05:16:43,680 many times anytime I want python to 8297 05:16:41,680 --> 05:16:45,638 interpret a program I've written and it 8298 05:16:43,680 --> 05:16:48,878 turns out by convention what python does 8299 05:16:45,638 --> 05:16:51,160 is it stores in cy. arv the name of the 8300 05:16:48,878 --> 05:16:53,958 file that you're executing or 8301 05:16:51,160 --> 05:16:56,200 interpreting followed by any number of 8302 05:16:53,958 --> 05:16:58,000 other words that you type so all this 8303 05:16:56,200 --> 05:16:59,760 time we could have been accessing the 8304 05:16:58,000 --> 05:17:01,798 name of the program which frankly isn't 8305 05:16:59,760 --> 05:17:04,360 all that interesting but we can also now 8306 05:17:01,798 --> 05:17:07,558 access words that are typed after that 8307 05:17:04,360 --> 05:17:09,718 prompt as well but of course if I don't 8308 05:17:07,558 --> 05:17:11,440 type anything in 8309 05:17:09,718 --> 05:17:12,840 what might happen here this might be 8310 05:17:11,440 --> 05:17:14,480 naive of me to assume that there's 8311 05:17:12,840 --> 05:17:17,200 always going to be something at location 8312 05:17:14,480 --> 05:17:20,080 one in cy. RV let me go ahead and try 8313 05:17:17,200 --> 05:17:21,680 this python name. pi and no I'm not 8314 05:17:20,080 --> 05:17:23,680 giving you my name because at this point 8315 05:17:21,680 --> 05:17:26,160 I might not even know that you want my 8316 05:17:23,680 --> 05:17:29,000 name to be typed so let me hit enter now 8317 05:17:26,160 --> 05:17:31,400 and uhoh we see now an error a so-called 8318 05:17:29,000 --> 05:17:33,520 exception in Python this one's a new one 8319 05:17:31,400 --> 05:17:36,638 this one's an index error that 8320 05:17:33,520 --> 05:17:37,920 elaborates list index out of range and 8321 05:17:36,638 --> 05:17:40,080 turns out this is actually one of the 8322 05:17:37,920 --> 05:17:42,760 most common mistakes in programming 8323 05:17:40,080 --> 05:17:44,878 whether using a list in python or arrays 8324 05:17:42,760 --> 05:17:47,080 or vectors in other languages is to try 8325 05:17:44,878 --> 05:17:49,240 to access some element that does not 8326 05:17:47,080 --> 05:17:51,280 exist you try to go too far to the left 8327 05:17:49,240 --> 05:17:54,360 or you try to go too far to the right in 8328 05:17:51,280 --> 05:17:56,958 this uh in this object that is just a 8329 05:17:54,360 --> 05:17:58,798 list of some values so of course the 8330 05:17:56,958 --> 05:17:59,760 mistake here is that I'm assuming 8331 05:17:58,798 --> 05:18:02,798 there's going to be something at 8332 05:17:59,760 --> 05:18:04,480 location one when really it's location 8333 05:18:02,798 --> 05:18:06,600 zero that's the only one that has a 8334 05:18:04,480 --> 05:18:09,240 value but fixing this is not going to 8335 05:18:06,600 --> 05:18:11,160 amount to doing bracket zero because now 8336 05:18:09,240 --> 05:18:14,240 if I go ahead and rerun this program 8337 05:18:11,160 --> 05:18:16,840 with no other words after name. it says 8338 05:18:14,240 --> 05:18:18,558 hello my name is name. which is fine if 8339 05:18:16,840 --> 05:18:20,480 we're making a name tag for the program 8340 05:18:18,558 --> 05:18:23,040 but that's not of course what my goal 8341 05:18:20,480 --> 05:18:25,760 here is instead so if the fix is not 8342 05:18:23,040 --> 05:18:28,120 just to change the one to a zero how 8343 05:18:25,760 --> 05:18:31,600 else might I handle this 8344 05:18:28,120 --> 05:18:33,440 error how else might I handle this error 8345 05:18:31,600 --> 05:18:35,600 this index error that happens if the 8346 05:18:33,440 --> 05:18:37,760 user just doesn't remember to or doesn't 8347 05:18:35,600 --> 05:18:40,798 know to type their actual name at the 8348 05:18:37,760 --> 05:18:45,200 prompt we could always put an exception 8349 05:18:40,798 --> 05:18:48,200 into the program saying if there is um 8350 05:18:45,200 --> 05:18:50,040 if there's nothing at location one we 8351 05:18:48,200 --> 05:18:52,240 just come out the say okay we haven't 8352 05:18:50,040 --> 05:18:54,320 got a parameter or something but if 8353 05:18:52,240 --> 05:18:56,878 there is we continue along with the 8354 05:18:54,320 --> 05:18:59,200 program perfect so if I might simplify 8355 05:18:56,878 --> 05:19:00,600 we can try to execute this line of code 8356 05:18:59,200 --> 05:19:03,120 except if there's an error we'll deal 8357 05:19:00,600 --> 05:19:04,920 with it in some other way now ideally 8358 05:19:03,120 --> 05:19:06,480 and once I'm a strong enough programmer 8359 05:19:04,920 --> 05:19:08,600 I would have anticipated this and 8360 05:19:06,480 --> 05:19:09,718 written the following code from the get 8361 05:19:08,600 --> 05:19:11,400 go but when you're learning it's 8362 05:19:09,718 --> 05:19:13,120 certainly reasonable to see an error oh 8363 05:19:11,400 --> 05:19:14,798 I didn't realize I should detect that 8364 05:19:13,120 --> 05:19:15,878 and then go back and improve your code 8365 05:19:14,798 --> 05:19:17,878 but of course if you read the 8366 05:19:15,878 --> 05:19:19,480 documentation you ingrain some of the 8367 05:19:17,878 --> 05:19:21,718 Lessons Learned From the Past you'll get 8368 05:19:19,480 --> 05:19:23,680 into the habit of trying and checking 8369 05:19:21,718 --> 05:19:25,680 for some of these exceptions yourself so 8370 05:19:23,680 --> 05:19:27,798 let me solve this in one possible way as 8371 05:19:25,680 --> 05:19:29,520 you proposed here let's try to handle 8372 05:19:27,798 --> 05:19:31,360 this exception as follows let me go 8373 05:19:29,520 --> 05:19:34,160 ahead now and instead of just blindly 8374 05:19:31,360 --> 05:19:37,240 calling this print line let me try to 8375 05:19:34,160 --> 05:19:39,160 print out hello my name is such and such 8376 05:19:37,240 --> 05:19:42,080 except if there is an issue 8377 05:19:39,160 --> 05:19:43,920 specifically an index error then what do 8378 05:19:42,080 --> 05:19:46,680 I want to go ahead and do I'm going to 8379 05:19:43,920 --> 05:19:48,558 say something like two few arguments I 8380 05:19:46,680 --> 05:19:50,440 could be more explanatory than that but 8381 05:19:48,558 --> 05:19:52,280 for now I'm just going to explain to the 8382 05:19:50,440 --> 05:19:55,080 user that they gave me too few arguments 8383 05:19:52,280 --> 05:19:57,240 too few words at the prompt so now it's 8384 05:19:55,080 --> 05:19:58,798 still not going to work in quite the way 8385 05:19:57,240 --> 05:20:00,320 I want I'm still not going to be able to 8386 05:19:58,798 --> 05:20:01,600 generate their name tag but at least 8387 05:20:00,320 --> 05:20:03,440 they're not going to see some cryptic 8388 05:20:01,600 --> 05:20:05,520 error message and think that they 8389 05:20:03,440 --> 05:20:08,000 themselves broke the program let me go 8390 05:20:05,520 --> 05:20:10,200 ahead now and run python of.pi enter and 8391 05:20:08,000 --> 05:20:12,718 too few ARG ments okay let me go ahead 8392 05:20:10,200 --> 05:20:15,200 now and do python of name. and type in 8393 05:20:12,718 --> 05:20:17,760 my name David and now we're back in 8394 05:20:15,200 --> 05:20:20,718 business and I see that my name is on 8395 05:20:17,760 --> 05:20:23,080 the screen too but strictly speaking I 8396 05:20:20,718 --> 05:20:25,320 don't have to try to do this I could 8397 05:20:23,080 --> 05:20:27,360 actually be a little more defensive in 8398 05:20:25,320 --> 05:20:29,878 writing this code and maybe I could 8399 05:20:27,360 --> 05:20:32,680 check whether or not the user has indeed 8400 05:20:29,878 --> 05:20:35,000 provided a name or multiple names at the 8401 05:20:32,680 --> 05:20:37,520 prompt so as to give them more refined 8402 05:20:35,000 --> 05:20:39,638 error messages as well so how might I do 8403 05:20:37,520 --> 05:20:41,760 this well let me go and and undo the 8404 05:20:39,638 --> 05:20:43,920 exception handling I've added and why 8405 05:20:41,760 --> 05:20:46,040 don't I instead more modestly try to do 8406 05:20:43,920 --> 05:20:49,878 this let me go ahead and introduce a 8407 05:20:46,040 --> 05:20:53,920 conditional here if the length of cy. 8408 05:20:49,878 --> 05:20:56,240 argv is less than two or equivalently 8409 05:20:53,920 --> 05:20:58,920 equal to just one value but I'll just 8410 05:20:56,240 --> 05:21:02,600 stick with less than two for now then go 8411 05:20:58,920 --> 05:21:04,600 ahead and print out two few arguments so 8412 05:21:02,600 --> 05:21:07,240 I want ultimately two arguments I want 8413 05:21:04,600 --> 05:21:08,840 the name of the program at location zero 8414 05:21:07,240 --> 05:21:10,600 and I want the name of the human at 8415 05:21:08,840 --> 05:21:12,520 location one so that's a total of two 8416 05:21:10,600 --> 05:21:14,360 arguments so if I have fewer than two 8417 05:21:12,520 --> 05:21:18,360 arguments let's tell the user with this 8418 05:21:14,360 --> 05:21:20,480 print line L if the length of cy. RGV is 8419 05:21:18,360 --> 05:21:22,120 say greater than two like they typed in 8420 05:21:20,480 --> 05:21:24,958 too many words at the prompt well let's 8421 05:21:22,120 --> 05:21:28,000 tell them print quote unquote too many 8422 05:21:24,958 --> 05:21:30,160 arguments else if they did get it right 8423 05:21:28,000 --> 05:21:32,480 and they gave me exactly two arguments 8424 05:21:30,160 --> 05:21:34,160 else let's go ahead and print what I 8425 05:21:32,480 --> 05:21:35,878 actually care about all right let me go 8426 05:21:34,160 --> 05:21:39,120 down to my terminal window here and run 8427 05:21:35,878 --> 05:21:40,878 python of name. and voila uh oh a 8428 05:21:39,120 --> 05:21:42,878 completely different type of error this 8429 05:21:40,878 --> 05:21:45,080 one a syntax error which we've seen in 8430 05:21:42,878 --> 05:21:47,360 the past now a syntax error recall is 8431 05:21:45,080 --> 05:21:50,360 May aopa like I messed up here and I 8432 05:21:47,360 --> 05:21:52,440 wrote invalid syntax and so no amount of 8433 05:21:50,360 --> 05:21:53,840 conditionals or exception handling is 8434 05:21:52,440 --> 05:21:55,440 really going to catch this one I need to 8435 05:21:53,840 --> 05:21:57,080 go back and just get my program to work 8436 05:21:55,440 --> 05:22:00,680 because it's not running at all well let 8437 05:21:57,080 --> 05:22:03,200 me go up here and see line four is the 8438 05:22:00,680 --> 05:22:05,958 issue and indeed it looks like I have an 8439 05:22:03,200 --> 05:22:08,040 unterminated string here I need to go 8440 05:22:05,958 --> 05:22:09,638 ahead and now add this double quote so 8441 05:22:08,040 --> 05:22:11,680 let me go ahead now when with that red 8442 05:22:09,638 --> 05:22:13,958 herring gone let me rerun python of 8443 05:22:11,680 --> 05:22:16,200 name. piy and hit enter and now we see 8444 05:22:13,958 --> 05:22:18,080 too few arguments okay maybe it wants my 8445 05:22:16,200 --> 05:22:21,320 full name let me go ahead now and run 8446 05:22:18,080 --> 05:22:23,600 python of name. py David maen typing in 8447 05:22:21,320 --> 05:22:25,760 both words after the name of the file 8448 05:22:23,600 --> 05:22:27,878 and hit enter and now of course it's too 8449 05:22:25,760 --> 05:22:30,440 many arguments fine now I'll oblige and 8450 05:22:27,878 --> 05:22:32,840 do python of name. py and just David and 8451 05:22:30,440 --> 05:22:34,920 there we have it my name tag printed on 8452 05:22:32,840 --> 05:22:36,958 the screen so strictly speaking we don't 8453 05:22:34,920 --> 05:22:38,718 have to handle exceptions if we can be a 8454 05:22:36,958 --> 05:22:40,600 little smarter about it and just check 8455 05:22:38,718 --> 05:22:42,480 for the things that we're worried about 8456 05:22:40,600 --> 05:22:44,120 especially if we want to give the user 8457 05:22:42,480 --> 05:22:45,958 more refined advice we don't want to 8458 05:22:44,120 --> 05:22:47,840 just tell them no something went wrong 8459 05:22:45,958 --> 05:22:50,440 or we don't want to pass we want to tell 8460 05:22:47,840 --> 05:22:52,400 them no that's too few or no that's too 8461 05:22:50,440 --> 05:22:55,320 many we have conditionals in our 8462 05:22:52,400 --> 05:22:57,320 vocabulary already via which we can now 8463 05:22:55,320 --> 05:22:59,320 Express that well let me pause here and 8464 05:22:57,320 --> 05:23:01,240 see if there's any questions now on how 8465 05:22:59,320 --> 05:23:03,638 we handled the error before with the 8466 05:23:01,240 --> 05:23:06,760 index error or how now we're just 8467 05:23:03,638 --> 05:23:09,080 proactively avoiding all index errors Al 8468 05:23:06,760 --> 05:23:11,080 together by just checking first first is 8469 05:23:09,080 --> 05:23:14,320 it too few is it tooo many or is it 8470 05:23:11,080 --> 05:23:16,480 exactly what we want hi thank you um so 8471 05:23:14,320 --> 05:23:19,798 I was wondering you you touched upon 8472 05:23:16,480 --> 05:23:23,558 kind of using your full name um could we 8473 05:23:19,798 --> 05:23:26,400 could we then um is there a way going 8474 05:23:23,558 --> 05:23:28,160 forwards that perhaps we uh have people 8475 05:23:26,400 --> 05:23:30,000 that want their full names and want 8476 05:23:28,160 --> 05:23:32,280 their just their first name that we 8477 05:23:30,000 --> 05:23:34,760 separate that into like oh this person 8478 05:23:32,280 --> 05:23:35,680 has full name this person has just the 8479 05:23:34,760 --> 05:23:39,160 one 8480 05:23:35,680 --> 05:23:41,000 name absolutely and allow me to is uh 8481 05:23:39,160 --> 05:23:43,600 allow me to propose we come back to that 8482 05:23:41,000 --> 05:23:45,480 support for multiple names um but indeed 8483 05:23:43,600 --> 05:23:48,280 we could do that and I should note too 8484 05:23:45,480 --> 05:23:50,440 though we can support full names right 8485 05:23:48,280 --> 05:23:53,040 now if I do this instead of typing in 8486 05:23:50,440 --> 05:23:55,280 David space mailin which is problematic 8487 05:23:53,040 --> 05:23:58,320 because again by definition of how argv 8488 05:23:55,280 --> 05:24:01,200 Works each word ends up in a specific 8489 05:23:58,320 --> 05:24:02,878 location in the list but if I add quotes 8490 05:24:01,200 --> 05:24:05,400 single quotes or double quotes at the 8491 05:24:02,878 --> 05:24:07,718 command line now python will view this 8492 05:24:05,400 --> 05:24:09,200 as two total things the name of the file 8493 05:24:07,718 --> 05:24:11,120 and this full name name and now when I 8494 05:24:09,200 --> 05:24:13,240 hit enter I don't see the quotes the 8495 05:24:11,120 --> 05:24:15,120 whole thing is passed in as my full name 8496 05:24:13,240 --> 05:24:17,000 and if I want to adapt this further for 8497 05:24:15,120 --> 05:24:19,600 multiple people we'll be able to do that 8498 05:24:17,000 --> 05:24:22,280 as well other questions now on this 8499 05:24:19,600 --> 05:24:26,798 version with if L if else or on accept 8500 05:24:22,280 --> 05:24:29,480 before hi I want to I want to ask you uh 8501 05:24:26,798 --> 05:24:31,878 can we use multiple else statements can 8502 05:24:29,480 --> 05:24:33,798 you use multiple El's statements no else 8503 05:24:31,878 --> 05:24:36,480 is the last catchall statement that you 8504 05:24:33,798 --> 05:24:38,520 can have you can have multiple L if 8505 05:24:36,480 --> 05:24:40,920 statements in the middle but not 8506 05:24:38,520 --> 05:24:40,920 multiple 8507 05:24:41,400 --> 05:24:45,600 elses all right all right well let's 8508 05:24:44,040 --> 05:24:47,440 turn our attention back now to this code 8509 05:24:45,600 --> 05:24:48,920 and see if we can't refine it a bit more 8510 05:24:47,440 --> 05:24:50,840 by adding in some additional 8511 05:24:48,920 --> 05:24:53,040 functionality that we get with modules 8512 05:24:50,840 --> 05:24:54,520 like the CIS module one of the things I 8513 05:24:53,040 --> 05:24:56,878 don't love about this version of the 8514 05:24:54,520 --> 05:24:59,440 code even though arguably it is now 8515 05:24:56,878 --> 05:25:01,160 correct is that the essence of my 8516 05:24:59,440 --> 05:25:03,798 program which is just to print out the 8517 05:25:01,160 --> 05:25:06,600 name tag is kind of relegated to this 8518 05:25:03,798 --> 05:25:09,200 else clause and that's fine logically 8519 05:25:06,600 --> 05:25:11,120 it's correct but generally speaking 8520 05:25:09,200 --> 05:25:14,440 there's something nice about keeping all 8521 05:25:11,120 --> 05:25:16,718 of your error handling separate from the 8522 05:25:14,440 --> 05:25:18,920 code that you really care about having 8523 05:25:16,718 --> 05:25:20,718 all of these ifs L ifs perhaps at the 8524 05:25:18,920 --> 05:25:22,480 top of your code that are checking to 8525 05:25:20,718 --> 05:25:24,840 make sure that all of the data is as 8526 05:25:22,480 --> 05:25:27,760 expected but then it would be nice if 8527 05:25:24,840 --> 05:25:29,920 only for design sake not to sort of hide 8528 05:25:27,760 --> 05:25:31,798 in this El statement the actual code 8529 05:25:29,920 --> 05:25:33,878 that you care about I would prefer for 8530 05:25:31,798 --> 05:25:37,440 instance to do something logically like 8531 05:25:33,878 --> 05:25:40,120 this I could check for errors up top and 8532 05:25:37,440 --> 05:25:41,440 then down here print the name tags it 8533 05:25:40,120 --> 05:25:43,840 would be nice if those are sort of 8534 05:25:41,440 --> 05:25:45,920 distinct blocks of code all of which are 8535 05:25:43,840 --> 05:25:48,760 here left aligned but there's a problem 8536 05:25:45,920 --> 05:25:51,680 with what I've just done here logically 8537 05:25:48,760 --> 05:25:55,320 what bug did I just introduce by getting 8538 05:25:51,680 --> 05:25:58,240 rid of the Els and introducing line 10 8539 05:25:55,320 --> 05:26:01,280 on its own with no indentation outside 8540 05:25:58,240 --> 05:26:04,120 of the conditional what bug have I just 8541 05:26:01,280 --> 05:26:07,440 introduced what mistake to be 8542 05:26:04,120 --> 05:26:10,000 clear um name error ironically it's a 8543 05:26:07,440 --> 05:26:12,558 name error but not a name error 8544 05:26:10,000 --> 05:26:15,680 exception it's an error with my name 8545 05:26:12,558 --> 05:26:18,120 but I think you're Frozen for me it's 8546 05:26:15,680 --> 05:26:19,798 going to raise an exception because even 8547 05:26:18,120 --> 05:26:22,360 though I'm checking the length of 8548 05:26:19,798 --> 05:26:24,280 cis.org V up top and even though I'm 8549 05:26:22,360 --> 05:26:26,280 checking it again for being greater than 8550 05:26:24,280 --> 05:26:28,718 two not just less than two but greater 8551 05:26:26,280 --> 05:26:30,760 I'm still then blindly and incorrectly 8552 05:26:28,718 --> 05:26:33,878 assuming it's now going to exist so just 8553 05:26:30,760 --> 05:26:36,160 to be clear if I run python of name. and 8554 05:26:33,878 --> 05:26:38,280 I don't type any arguments I've got too 8555 05:26:36,160 --> 05:26:41,160 few I think I'm going to see that I have 8556 05:26:38,280 --> 05:26:42,958 have too few but I'm also going to see 8557 05:26:41,160 --> 05:26:44,600 that same exception at the very top of 8558 05:26:42,958 --> 05:26:46,718 my terminal Windows output there's my 8559 05:26:44,600 --> 05:26:49,400 error message to few arguments but again 8560 05:26:46,718 --> 05:26:52,600 on line 10 I blindly proceed to still 8561 05:26:49,400 --> 05:26:55,080 index into my list at location one which 8562 05:26:52,600 --> 05:26:56,760 does not exist so it turns out there's a 8563 05:26:55,080 --> 05:26:58,120 better way to handle errors like this 8564 05:26:56,760 --> 05:27:00,520 especially if you're writing a program 8565 05:26:58,120 --> 05:27:03,320 in Python that's just meant to run 8566 05:27:00,520 --> 05:27:06,320 briefly and then exit anyway but maybe 8567 05:27:03,320 --> 05:27:08,480 we could start to exit prematurely if 8568 05:27:06,320 --> 05:27:10,160 the program itself just can't proceed if 8569 05:27:08,480 --> 05:27:12,520 the user has not given us the data we 8570 05:27:10,160 --> 05:27:15,440 want perhaps we should just exit the 8571 05:27:12,520 --> 05:27:17,440 program earlier than we might otherwise 8572 05:27:15,440 --> 05:27:19,040 so let me go ahead and do this let me go 8573 05:27:17,440 --> 05:27:21,320 ahead and remove my comments so as to 8574 05:27:19,040 --> 05:27:24,878 focus only on the code here and let me 8575 05:27:21,320 --> 05:27:26,878 propose that instead of just printing 8576 05:27:24,878 --> 05:27:28,558 quote unquote twoo few arguments I'm 8577 05:27:26,878 --> 05:27:30,480 going to use one other function that 8578 05:27:28,558 --> 05:27:33,878 comes with the CIS module I'm going to 8579 05:27:30,480 --> 05:27:35,920 go ahead and call cy. exit and as the 8580 05:27:33,878 --> 05:27:37,520 name suggests it's going to do exactly 8581 05:27:35,920 --> 05:27:40,638 that with the system's help it's going 8582 05:27:37,520 --> 05:27:43,320 to exit my program then and there on 8583 05:27:40,638 --> 05:27:44,958 line 4 why is that okay well if you gave 8584 05:27:43,320 --> 05:27:47,160 me too few arguments I have nothing more 8585 05:27:44,958 --> 05:27:49,440 to say to you the user I might as well 8586 05:27:47,160 --> 05:27:51,280 exit a bit prematurely and I can do this 8587 05:27:49,440 --> 05:27:53,718 as well on line six let's go ahead and 8588 05:27:51,280 --> 05:27:55,878 not just print that but sis. exit quote 8589 05:27:53,718 --> 05:27:58,360 unquote too many arguments print out 8590 05:27:55,878 --> 05:28:00,480 that message and just exit right there 8591 05:27:58,360 --> 05:28:03,558 now I can trust that by the time I get 8592 05:28:00,480 --> 05:28:05,878 to line eight every error condition has 8593 05:28:03,558 --> 05:28:08,680 been checked for and so it's safe for me 8594 05:28:05,878 --> 05:28:12,400 to assume that there is in fact and a 8595 05:28:08,680 --> 05:28:15,320 item at location one in cy. argv so let 8596 05:28:12,400 --> 05:28:18,680 me go ahead now and run this python of 8597 05:28:15,320 --> 05:28:20,920 name. py enter too few arguments but I'm 8598 05:28:18,680 --> 05:28:22,798 back at my prompt nothing more has 8599 05:28:20,920 --> 05:28:26,360 happened let me run it again python 8600 05:28:22,798 --> 05:28:28,360 of.pie David maen with no quotes enter 8601 05:28:26,360 --> 05:28:31,520 too many arguments is now printed here 8602 05:28:28,360 --> 05:28:34,920 finally python of name. py just David 8603 05:28:31,520 --> 05:28:37,160 enter hello my name is David so we have 8604 05:28:34,920 --> 05:28:39,240 then insist two forms of functionality 8605 05:28:37,160 --> 05:28:41,558 now we have access to this variable sis. 8606 05:28:39,240 --> 05:28:43,240 arv this argument Vector that gives me 8607 05:28:41,558 --> 05:28:45,120 all of the words that were typed at the 8608 05:28:43,240 --> 05:28:47,440 prompt including the program's own file 8609 05:28:45,120 --> 05:28:49,000 name and it turns out if we read further 8610 05:28:47,440 --> 05:28:50,878 in the documentation there's an exit 8611 05:28:49,000 --> 05:28:53,240 function that can take different types 8612 05:28:50,878 --> 05:28:55,240 of inputs but if I pass it a string like 8613 05:28:53,240 --> 05:28:57,878 this it will indeed print that string 8614 05:28:55,240 --> 05:29:01,320 for me and then exit from my program 8615 05:28:57,878 --> 05:29:04,680 then and there questions now on exiting 8616 05:29:01,320 --> 05:29:06,520 from programs like this to be clear all 8617 05:29:04,680 --> 05:29:08,600 of this time once python gets to the 8618 05:29:06,520 --> 05:29:11,120 bottom of your file it's going exit 8619 05:29:08,600 --> 05:29:13,280 anyway so I'm using cy. exit now just to 8620 05:29:11,120 --> 05:29:15,798 make sure that I exit earlier than 8621 05:29:13,280 --> 05:29:18,160 otherwise um my question is about the 8622 05:29:15,798 --> 05:29:22,280 cis.org 8623 05:29:18,160 --> 05:29:25,520 arv so is that capable of accepting or 8624 05:29:22,280 --> 05:29:29,160 taking multiple elements at once let's 8625 05:29:25,520 --> 05:29:33,958 say for example uh python name thatp 8626 05:29:29,160 --> 05:29:36,760 David Malon I'm a male uh 20 years old 8627 05:29:33,958 --> 05:29:39,320 and if let's say I only want to access 8628 05:29:36,760 --> 05:29:43,280 your name which is at the first index 8629 05:29:39,320 --> 05:29:48,638 and then your your your age is pro say 8630 05:29:43,280 --> 05:29:51,600 at the sixth index can I say sis. RV one 8631 05:29:48,638 --> 05:29:56,240 and another one for six to access what I 8632 05:29:51,600 --> 05:29:58,638 just want is that possible for CIS RB uh 8633 05:29:56,240 --> 05:30:00,440 short answer yes I think if I understand 8634 05:29:58,638 --> 05:30:02,360 your question correctly whereby you're 8635 05:30:00,440 --> 05:30:03,840 proposing to have many words at the end 8636 05:30:02,360 --> 05:30:06,558 of the command and you want to access 8637 05:30:03,840 --> 05:30:08,840 those individual words absolutely at 8638 05:30:06,558 --> 05:30:10,760 some point it gets a little fragile I 8639 05:30:08,840 --> 05:30:13,360 would say if you're typing so many words 8640 05:30:10,760 --> 05:30:15,280 at the prompt that the order really 8641 05:30:13,360 --> 05:30:16,400 matters and so it turns out there's a 8642 05:30:15,280 --> 05:30:17,840 lot of programs and there's 8643 05:30:16,400 --> 05:30:21,360 functionality in Python that can allow 8644 05:30:17,840 --> 05:30:24,000 you to provide those values like name or 8645 05:30:21,360 --> 05:30:27,200 age or any number of other fields in any 8646 05:30:24,000 --> 05:30:29,080 order you want but pass in a bit more 8647 05:30:27,200 --> 05:30:30,558 information textually that tells the 8648 05:30:29,080 --> 05:30:33,040 program how you want to use it so in 8649 05:30:30,558 --> 05:30:36,120 short what you're describing is possible 8650 05:30:33,040 --> 05:30:38,320 and let me do a small incarnation of it 8651 05:30:36,120 --> 05:30:40,638 as follows let me propose that we go 8652 05:30:38,320 --> 05:30:42,440 back to my code here and let's propose 8653 05:30:40,638 --> 05:30:44,638 that we actually now want to support 8654 05:30:42,440 --> 05:30:46,400 multiple values at the prompt so there's 8655 05:30:44,638 --> 05:30:47,760 going to be no such thing as too many 8656 05:30:46,400 --> 05:30:50,080 arguments suppose that I want to 8657 05:30:47,760 --> 05:30:52,160 generate name tags not just for David 8658 05:30:50,080 --> 05:30:54,240 but for David for Carter for Rong Shin 8659 05:30:52,160 --> 05:30:56,080 for others in the group who all want 8660 05:30:54,240 --> 05:30:57,280 their name tags as well so I'm going to 8661 05:30:56,080 --> 05:30:59,200 go ahead and do this I'm going to get 8662 05:30:57,280 --> 05:31:01,040 rid of my L if condition because I don't 8663 05:30:59,200 --> 05:31:02,520 want to limit the maximum number of 8664 05:31:01,040 --> 05:31:06,240 words that are typed at the prompt 8665 05:31:02,520 --> 05:31:09,160 anymore I instead want to iterate over 8666 05:31:06,240 --> 05:31:14,080 every name at the prompt so I'm going to 8667 05:31:09,160 --> 05:31:18,120 say this for Argin sis. argv go ahead 8668 05:31:14,080 --> 05:31:20,040 and print out this time ARG so what am I 8669 05:31:18,120 --> 05:31:21,920 doing here well even though the syntax 8670 05:31:20,040 --> 05:31:24,280 is a little different the idea is the 8671 05:31:21,920 --> 05:31:27,400 same as before when we've had Loops I'm 8672 05:31:24,280 --> 05:31:30,320 using a for Loop to iterate over a list 8673 05:31:27,400 --> 05:31:32,958 the list in question here is cy. argv 8674 05:31:30,320 --> 05:31:34,600 ARG is a variable that I'm creating on 8675 05:31:32,958 --> 05:31:36,200 the Fly the for Loop is going to make 8676 05:31:34,600 --> 05:31:38,520 sure that the first time through this 8677 05:31:36,200 --> 05:31:40,080 Loop AR is set to the first word on the 8678 05:31:38,520 --> 05:31:41,480 command line the second time through the 8679 05:31:40,080 --> 05:31:42,958 loop Python's going to make sure that 8680 05:31:41,480 --> 05:31:44,240 ARG is now set to the second thing on 8681 05:31:42,958 --> 05:31:46,360 the command line and so forth that's 8682 05:31:44,240 --> 05:31:48,120 just how a for Loop works it updates the 8683 05:31:46,360 --> 05:31:50,520 variable for us I don't have to call it 8684 05:31:48,120 --> 05:31:52,760 ARG I could call it name so long as I 8685 05:31:50,520 --> 05:31:54,440 change it to name in both places but ARG 8686 05:31:52,760 --> 05:31:57,240 is reasonable if I'm iterating over 8687 05:31:54,440 --> 05:31:59,400 arguments more generally if I now run 8688 05:31:57,240 --> 05:32:02,400 this program though unfortunately 8689 05:31:59,400 --> 05:32:06,400 there's a little bit of a bug even if I 8690 05:32:02,400 --> 05:32:08,480 type in David and Carter and wrong Shin 8691 05:32:06,400 --> 05:32:09,760 I'm not going to get just just three 8692 05:32:08,480 --> 05:32:13,280 name 8693 05:32:09,760 --> 05:32:15,558 tags in your mind does anyone see the 8694 05:32:13,280 --> 05:32:18,480 bug I'm about to trip over it's not a 8695 05:32:15,558 --> 05:32:20,760 huge deal if I've got enough name tags 8696 05:32:18,480 --> 05:32:22,240 to go around but I'm going to be wasting 8697 05:32:20,760 --> 05:32:24,958 one because this is going to print not 8698 05:32:22,240 --> 05:32:26,840 three but four name tags whereby the 8699 05:32:24,958 --> 05:32:28,958 first contains the name of the program 8700 05:32:26,840 --> 05:32:30,638 itself maybe not a big deal maybe that's 8701 05:32:28,958 --> 05:32:32,400 the sticker we don't bother handing out 8702 05:32:30,638 --> 05:32:35,558 but it's wasteful and it it does look 8703 05:32:32,400 --> 05:32:38,520 wrong so how could we get access to not 8704 05:32:35,558 --> 05:32:40,718 all four elements of argv but just a a 8705 05:32:38,520 --> 05:32:42,718 slice of Arvy and this is actually a 8706 05:32:40,718 --> 05:32:45,360 technical term in Python and some other 8707 05:32:42,718 --> 05:32:47,680 languages to take a slice of a list 8708 05:32:45,360 --> 05:32:49,718 means to take a subset of it maybe from 8709 05:32:47,680 --> 05:32:52,718 the beginning maybe the middle maybe the 8710 05:32:49,718 --> 05:32:54,760 end but a slice is a subset of a data 8711 05:32:52,718 --> 05:32:57,440 structure like a list well how do I 8712 05:32:54,760 --> 05:32:59,240 actually do this in code well in Python 8713 05:32:57,440 --> 05:33:01,480 it's actually very easy to take a slice 8714 05:32:59,240 --> 05:33:03,718 of a list that is a subset thereof you 8715 05:33:01,480 --> 05:33:06,440 can simply do this at the end of the 8716 05:33:03,718 --> 05:33:08,480 list name cy. Arvy in this case you can 8717 05:33:06,440 --> 05:33:10,638 use square brackets and then in those 8718 05:33:08,480 --> 05:33:13,440 square brackets you can specify the 8719 05:33:10,638 --> 05:33:15,920 start and the end of the list that you 8720 05:33:13,440 --> 05:33:18,840 want to retain I want to start at 8721 05:33:15,920 --> 05:33:21,080 element one not zero I want to start at 8722 05:33:18,840 --> 05:33:22,680 element one and I want to just go to the 8723 05:33:21,080 --> 05:33:24,200 end so I'm actually going to Omit a 8724 05:33:22,680 --> 05:33:26,240 second number altogether it's not 8725 05:33:24,200 --> 05:33:28,200 necessary to have a second number but I 8726 05:33:26,240 --> 05:33:30,200 do need that colon because this is going 8727 05:33:28,200 --> 05:33:31,558 to give me a slice of the list it's 8728 05:33:30,200 --> 05:33:34,480 going to give me a slice of the list 8729 05:33:31,558 --> 05:33:36,480 that starts at location one not zero and 8730 05:33:34,480 --> 05:33:38,440 the colon and then a blank just means 8731 05:33:36,480 --> 05:33:40,440 it's going to give me everything else so 8732 05:33:38,440 --> 05:33:42,240 this is equivalently going to slice off 8733 05:33:40,440 --> 05:33:44,040 the first element of the list and give 8734 05:33:42,240 --> 05:33:46,440 me a new list that contains just those 8735 05:33:44,040 --> 05:33:48,480 three human names not the name of the 8736 05:33:46,440 --> 05:33:50,638 file itself let me try running this 8737 05:33:48,480 --> 05:33:53,558 again I'm going to run python of name. 8738 05:33:50,638 --> 05:33:55,280 py David Carter wrong Shin this time 8739 05:33:53,558 --> 05:33:58,120 hopefully I'm going to get three and 8740 05:33:55,280 --> 05:34:00,920 only three name tags hitting enter and 8741 05:33:58,120 --> 05:34:03,280 indeed I've done now just this so again 8742 05:34:00,920 --> 05:34:05,120 using some relatively simple syntax in 8743 05:34:03,280 --> 05:34:06,878 Python we can use square brackets not 8744 05:34:05,120 --> 05:34:09,040 just to go to specific elements like 8745 05:34:06,878 --> 05:34:11,480 bracket zero or or bracket one we can 8746 05:34:09,040 --> 05:34:13,958 also get subsets of the list slices of 8747 05:34:11,480 --> 05:34:16,000 the list by doing bracket something 8748 05:34:13,958 --> 05:34:17,680 colon Something where each of those 8749 05:34:16,000 --> 05:34:19,240 somethings is a number the beginning or 8750 05:34:17,680 --> 05:34:21,878 the end and they're optional depending 8751 05:34:19,240 --> 05:34:25,400 on whether you want all of them or just 8752 05:34:21,878 --> 05:34:28,120 some any questions now on this version 8753 05:34:25,400 --> 05:34:29,798 which adds the loop and these slices 8754 05:34:28,120 --> 05:34:32,360 with that new 8755 05:34:29,798 --> 05:34:36,240 syntax can we slice starting from the 8756 05:34:32,360 --> 05:34:38,040 end of the argument argument Vector you 8757 05:34:36,240 --> 05:34:40,600 can you can slice something from the end 8758 05:34:38,040 --> 05:34:42,480 of the argument vector and this might uh 8759 05:34:40,600 --> 05:34:46,200 this might blow one's mind a little bit 8760 05:34:42,480 --> 05:34:48,080 let me go ahead and do this uh let's see 8761 05:34:46,200 --> 05:34:49,958 let me go ahead and do negative one at 8762 05:34:48,080 --> 05:34:51,920 the end using a negative number here and 8763 05:34:49,958 --> 05:34:54,440 running the same command we've just 8764 05:34:51,920 --> 05:34:56,520 uninvited wrong Shin from receiving a 8765 05:34:54,440 --> 05:34:58,760 name tag here so if you use a negative 8766 05:34:56,520 --> 05:35:01,400 number it has the effect of counting to 8767 05:34:58,760 --> 05:35:03,400 the uh in the other direction from the 8768 05:35:01,400 --> 05:35:06,680 end of the list a good question there 8769 05:35:03,400 --> 05:35:08,360 other questions now on slices on looping 8770 05:35:06,680 --> 05:35:11,840 over cis.org 8771 05:35:08,360 --> 05:35:13,520 V hi uh so I remember very early on uh 8772 05:35:11,840 --> 05:35:16,280 when we were talking about uh only 8773 05:35:13,520 --> 05:35:20,558 having two decimal places in uh in an um 8774 05:35:16,280 --> 05:35:23,480 float value um does this is is that in 8775 05:35:20,558 --> 05:35:25,558 the same vein like um because we use the 8776 05:35:23,480 --> 05:35:28,638 the colon 8777 05:35:25,558 --> 05:35:31,558 2f uh so that's is that the same thing 8778 05:35:28,638 --> 05:35:35,040 then uh why would the F be included then 8779 05:35:31,558 --> 05:35:36,638 in the point 2f as opposed to here when 8780 05:35:35,040 --> 05:35:39,200 you just have the 8781 05:35:36,638 --> 05:35:40,840 numbers a really good question and it's 8782 05:35:39,200 --> 05:35:43,558 just the short answer is that context 8783 05:35:40,840 --> 05:35:45,638 matters so there's only so many keyo 8784 05:35:43,558 --> 05:35:47,280 keys on our keyboard and so we sometimes 8785 05:35:45,638 --> 05:35:49,840 use the same symbols for different 8786 05:35:47,280 --> 05:35:52,600 things so what you're alluding to is the 8787 05:35:49,840 --> 05:35:55,000 format code in in F string for actually 8788 05:35:52,600 --> 05:35:57,280 formatting a number using a colon using 8789 05:35:55,000 --> 05:35:59,920 a period using a number using the letter 8790 05:35:57,280 --> 05:36:02,680 F and so forth and that is very specific 8791 05:35:59,920 --> 05:36:04,718 to the F string feature of python this 8792 05:36:02,680 --> 05:36:06,920 case has nothing to do with any of that 8793 05:36:04,718 --> 05:36:09,040 syntax per se this is just using a colon 8794 05:36:06,920 --> 05:36:11,000 in a different context to solve this 8795 05:36:09,040 --> 05:36:12,798 problem to implement a slice the authors 8796 05:36:11,000 --> 05:36:14,638 of python could have chosen another 8797 05:36:12,798 --> 05:36:16,200 symbol but honestly looking down at my 8798 05:36:14,638 --> 05:36:18,280 keyboard here we don't have that many to 8799 05:36:16,200 --> 05:36:19,798 choose from that are easy to type so 8800 05:36:18,280 --> 05:36:22,240 sometimes they have different meanings a 8801 05:36:19,798 --> 05:36:24,680 good question as well allow me to 8802 05:36:22,240 --> 05:36:27,120 propose now that we take things further 8803 05:36:24,680 --> 05:36:29,240 and move away from using only those 8804 05:36:27,120 --> 05:36:31,760 modules those libraries that python 8805 05:36:29,240 --> 05:36:33,920 comes with to talk about more generally 8806 05:36:31,760 --> 05:36:36,080 packages that exist one of the reasons 8807 05:36:33,920 --> 05:36:37,760 that python is so popular and Powerful 8808 05:36:36,080 --> 05:36:40,360 these days is that there's a lot of 8809 05:36:37,760 --> 05:36:42,840 third-party libraries out there as well 8810 05:36:40,360 --> 05:36:46,360 otherwise known as packages strictly 8811 05:36:42,840 --> 05:36:49,360 speaking python itself has a term of art 8812 05:36:46,360 --> 05:36:51,080 called a package which is a module 8813 05:36:49,360 --> 05:36:53,760 essentially that's implemented in a 8814 05:36:51,080 --> 05:36:56,040 folder not just a file but a folder but 8815 05:36:53,760 --> 05:36:58,840 more generally a package is a 8816 05:36:56,040 --> 05:37:01,200 third-party library that you that I can 8817 05:36:58,840 --> 05:37:03,480 install on our own Mac or PC or our 8818 05:37:01,200 --> 05:37:05,558 Cloud Server and gain access to even 8819 05:37:03,480 --> 05:37:07,958 more functionality that other people 8820 05:37:05,558 --> 05:37:09,558 have implemented for us now one of the 8821 05:37:07,958 --> 05:37:12,958 locations you can get all of these 8822 05:37:09,558 --> 05:37:15,520 packages is called the pii uh website 8823 05:37:12,958 --> 05:37:18,000 the python package index which lives at 8824 05:37:15,520 --> 05:37:20,080 this URL here and this is a website that 8825 05:37:18,000 --> 05:37:22,080 is searchable via the command line as 8826 05:37:20,080 --> 05:37:24,080 well as via the web that allows you to 8827 05:37:22,080 --> 05:37:26,240 download and install all sorts of 8828 05:37:24,080 --> 05:37:29,360 packages even cs50 has some of its own 8829 05:37:26,240 --> 05:37:30,680 packages um in services like these now 8830 05:37:29,360 --> 05:37:31,878 there's a fun one out there that's a 8831 05:37:30,680 --> 05:37:33,280 throwback to a command that's been 8832 05:37:31,878 --> 05:37:36,798 around for years in command line 8833 05:37:33,280 --> 05:37:39,440 environments called cow c is a package 8834 05:37:36,798 --> 05:37:41,958 in Python that allows you to have a cow 8835 05:37:39,440 --> 05:37:44,040 say something on your screen if curious 8836 05:37:41,958 --> 05:37:47,280 to read up on it its own documentation 8837 05:37:44,040 --> 05:37:49,718 is on p.org specifically at this URL 8838 05:37:47,280 --> 05:37:51,760 here but how do you actually get the 8839 05:37:49,718 --> 05:37:53,200 package into your system well 8840 05:37:51,760 --> 05:37:56,040 technically you could figure out how to 8841 05:37:53,200 --> 05:37:57,558 download the file and maybe unzip it and 8842 05:37:56,040 --> 05:37:59,718 put it into the right location on your 8843 05:37:57,558 --> 05:38:01,798 Mac or PC but nowadays a lot of 8844 05:37:59,718 --> 05:38:03,878 languages python among them has what's 8845 05:38:01,798 --> 05:38:06,680 called its own package manager this one 8846 05:38:03,878 --> 05:38:08,200 here called pip which is just one so pip 8847 05:38:06,680 --> 05:38:10,480 is a program 8848 05:38:08,200 --> 05:38:12,878 that generally comes with python itself 8849 05:38:10,480 --> 05:38:15,080 nowadays that allows you to install 8850 05:38:12,878 --> 05:38:17,120 packages onto your own Macs or PCS or 8851 05:38:15,080 --> 05:38:19,120 Cloud environment by just running a 8852 05:38:17,120 --> 05:38:22,040 command and then voila you have access 8853 05:38:19,120 --> 05:38:24,200 to a whole new library in Python that 8854 05:38:22,040 --> 05:38:27,280 didn't come with python itself but now 8855 05:38:24,200 --> 05:38:28,958 it's available on your system for you 8856 05:38:27,280 --> 05:38:30,200 let's go back to vs code here and in my 8857 05:38:28,958 --> 05:38:33,878 terminal window I'm going to go ahead 8858 05:38:30,200 --> 05:38:35,638 and type pip install cow now what's 8859 05:38:33,878 --> 05:38:38,080 going on here pip is the command the 8860 05:38:35,638 --> 05:38:40,400 package manager and I want to install 8861 05:38:38,080 --> 05:38:42,878 what package the package called cow I'm 8862 05:38:40,400 --> 05:38:44,360 going to go ahead and hit enter here and 8863 05:38:42,878 --> 05:38:46,558 after a little bit of output it has 8864 05:38:44,360 --> 05:38:48,840 successfully installed C now what does 8865 05:38:46,558 --> 05:38:51,200 that mean that means I can now go about 8866 05:38:48,840 --> 05:38:52,840 importing this into my own code well 8867 05:38:51,200 --> 05:38:54,200 let's go ahead and see what this means 8868 05:38:52,840 --> 05:38:57,040 let me go ahead and create a new file 8869 05:38:54,200 --> 05:38:58,920 with code called say dopy because I want 8870 05:38:57,040 --> 05:39:01,040 something to be said on the screen and 8871 05:38:58,920 --> 05:39:04,040 in my new tab here I'm going to go ahead 8872 05:39:01,040 --> 05:39:06,878 and import C which presumably is now 8873 05:39:04,040 --> 05:39:08,440 installed I'm now going to import CIS as 8874 05:39:06,878 --> 05:39:10,320 well because I'd like to use some 8875 05:39:08,440 --> 05:39:12,040 command line arguments in this program 8876 05:39:10,320 --> 05:39:14,000 just so that I can run it quickly and 8877 05:39:12,040 --> 05:39:16,440 without using the input function I can 8878 05:39:14,000 --> 05:39:18,280 get the user's name immediately from The 8879 05:39:16,440 --> 05:39:19,798 Prompt and let me go ahead and do this 8880 05:39:18,280 --> 05:39:21,520 I'm going to do a bit of error checking 8881 05:39:19,798 --> 05:39:23,320 proactively this time and rather than 8882 05:39:21,520 --> 05:39:25,120 use less than or greater than I'm this 8883 05:39:23,320 --> 05:39:29,240 time going to say if the length of 8884 05:39:25,120 --> 05:39:31,000 cis.org V does uh does equal two so if 8885 05:39:29,240 --> 05:39:33,400 the human is provided just the name of 8886 05:39:31,000 --> 05:39:35,638 the program and their own first name 8887 05:39:33,400 --> 05:39:38,240 we're good to go I'm going to do the 8888 05:39:35,638 --> 05:39:42,360 following I'm going to call a function 8889 05:39:38,240 --> 05:39:45,200 called cow in the package called coway 8890 05:39:42,360 --> 05:39:47,920 and I'm going to pass in a string hello 8891 05:39:45,200 --> 05:39:49,400 comma and then as in the past I'm going 8892 05:39:47,920 --> 05:39:50,920 to pass in just one string because 8893 05:39:49,400 --> 05:39:52,878 according to its documentation it's not 8894 05:39:50,920 --> 05:39:54,958 like print I can't pass in comma this 8895 05:39:52,878 --> 05:39:56,718 comma that I can only pass in one string 8896 05:39:54,958 --> 05:40:01,840 so I'm going to concatenate the contents 8897 05:39:56,718 --> 05:40:04,520 of sis. argv bracket1 so long as then I 8898 05:40:01,840 --> 05:40:06,798 type in my name David after the name of 8899 05:40:04,520 --> 05:40:09,600 this program it should end up in cy. 8900 05:40:06,798 --> 05:40:11,558 arv1 one in which case this line five of 8901 05:40:09,600 --> 05:40:13,760 code should concatenate hello with my 8902 05:40:11,558 --> 05:40:16,000 name with a space in between and 8903 05:40:13,760 --> 05:40:18,120 apparently a cow is going to say it so 8904 05:40:16,000 --> 05:40:20,320 let's see what happens here let me go 8905 05:40:18,120 --> 05:40:22,478 ahead and clear my screen and increase 8906 05:40:20,320 --> 05:40:25,520 the size of my terminal window let me go 8907 05:40:22,478 --> 05:40:28,718 ahead and run python of say. py and type 8908 05:40:25,520 --> 05:40:31,000 my name David and enter there is the 8909 05:40:28,718 --> 05:40:33,000 program called coway it literally has a 8910 05:40:31,000 --> 05:40:35,080 cow say something on the screen and this 8911 05:40:33,000 --> 05:40:37,000 is a throwback to a program from yester 8912 05:40:35,080 --> 05:40:39,558 year that tended to come with a lot of 8913 05:40:37,000 --> 05:40:42,040 syst sys um this is otherwise known as 8914 05:40:39,558 --> 05:40:44,558 asky art it's a textual way using just 8915 05:40:42,040 --> 05:40:46,760 keys on your keyboard to print pictures 8916 05:40:44,558 --> 05:40:48,600 of sorts on the screen now we can really 8917 05:40:46,760 --> 05:40:50,440 go down the rabbit hole here and there's 8918 05:40:48,600 --> 05:40:52,360 questionable academic value of doing so 8919 05:40:50,440 --> 05:40:54,920 so I'll do so just once turns out the 8920 05:40:52,360 --> 05:40:56,920 coway package comes with other functions 8921 05:40:54,920 --> 05:40:59,840 as well one of those functions for 8922 05:40:56,920 --> 05:41:01,558 instance is T-Rex and if I now increase 8923 05:40:59,840 --> 05:41:03,120 the size of my terminal window we'll 8924 05:41:01,558 --> 05:41:05,798 perhaps see where we're going with this 8925 05:41:03,120 --> 05:41:07,478 let me now run again python of.pi this 8926 05:41:05,798 --> 05:41:09,958 time let me not provide my name just to 8927 05:41:07,478 --> 05:41:12,558 see if it's broken it's still okay 8928 05:41:09,958 --> 05:41:15,760 because we have that if condition if the 8929 05:41:12,558 --> 05:41:17,600 length of cy. RGV equals equals two and 8930 05:41:15,760 --> 05:41:19,160 only if it equals equals 2 do we do 8931 05:41:17,600 --> 05:41:20,920 anything that's why we're not seeing 8932 05:41:19,160 --> 05:41:24,478 anything here let me go ahead and 8933 05:41:20,920 --> 05:41:27,440 cooperate now say. piy space David and 8934 05:41:24,478 --> 05:41:31,558 it's no longer a cow but if I zoom out 8935 05:41:27,440 --> 05:41:32,920 on my screen a T-Rex why just because 8936 05:41:31,558 --> 05:41:34,478 these are the things you can do once you 8937 05:41:32,920 --> 05:41:35,760 know how to program you can even package 8938 05:41:34,478 --> 05:41:38,798 them up and make them freely available 8939 05:41:35,760 --> 05:41:40,920 to others as open source software for us 8940 05:41:38,798 --> 05:41:42,878 it's demonstrative of a feature more 8941 05:41:40,920 --> 05:41:44,718 generally here namely being able to 8942 05:41:42,878 --> 05:41:47,280 install these thirdparty packages and 8943 05:41:44,718 --> 05:41:48,638 how you might do so in Python now I'll 8944 05:41:47,280 --> 05:41:50,680 leave this up on the screen for a moment 8945 05:41:48,638 --> 05:41:54,040 and see if there's any questions about 8946 05:41:50,680 --> 05:41:55,440 cows or Tyrannosaurus Rexes or packages 8947 05:41:54,040 --> 05:41:57,680 more 8948 05:41:55,440 --> 05:41:59,120 generally I'm really qualified to speak 8949 05:41:57,680 --> 05:42:02,798 to just one of 8950 05:41:59,120 --> 05:42:04,920 those hi um I've got two questions it's 8951 05:42:02,798 --> 05:42:07,840 a bit earlier than what it's supposed to 8952 05:42:04,920 --> 05:42:12,718 be um so the first question 8953 05:42:07,840 --> 05:42:17,558 is the the packages that you calling um 8954 05:42:12,718 --> 05:42:21,878 U to uh use in the program are they the 8955 05:42:17,558 --> 05:42:26,520 same as um let's say because I'm doing 8956 05:42:21,878 --> 05:42:30,440 Java um the same as calling a class of a 8957 05:42:26,520 --> 05:42:34,120 Java file in order to use its 8958 05:42:30,440 --> 05:42:36,600 functions and my second question is 8959 05:42:34,120 --> 05:42:40,400 what's the actual purpose of using 8960 05:42:36,600 --> 05:42:43,638 command arguments as you used because 8961 05:42:40,400 --> 05:42:48,040 it's not really the best way 8962 05:42:43,638 --> 05:42:52,080 to uh as you say be user friendly where 8963 05:42:48,040 --> 05:42:54,638 as in let's say the person who's using 8964 05:42:52,080 --> 05:42:57,040 the program doesn't know what it what 8965 05:42:54,638 --> 05:42:59,200 they want what the the program's asking 8966 05:42:57,040 --> 05:43:01,400 them really good questions the first 8967 05:42:59,200 --> 05:43:03,638 question about the comparison with Java 8968 05:43:01,400 --> 05:43:05,520 python packages are similar to Java 8969 05:43:03,638 --> 05:43:06,840 packages where you have something do 8970 05:43:05,520 --> 05:43:08,558 something do something at the top of 8971 05:43:06,840 --> 05:43:10,878 your program that gives you access to a 8972 05:43:08,558 --> 05:43:12,760 class or something else python itself 8973 05:43:10,878 --> 05:43:15,478 supports classes more on those down the 8974 05:43:12,760 --> 05:43:17,440 road and you can do very similar things 8975 05:43:15,478 --> 05:43:20,160 in python as you can do with Java but 8976 05:43:17,440 --> 05:43:22,798 the analog really is python packages to 8977 05:43:20,160 --> 05:43:25,160 Java packages here as for command line 8978 05:43:22,798 --> 05:43:26,440 arguments you ask a good question why do 8979 05:43:25,160 --> 05:43:28,400 we use them especially if they're a 8980 05:43:26,440 --> 05:43:30,760 little less user friendly they're a 8981 05:43:28,400 --> 05:43:33,440 little less user friendly to people who 8982 05:43:30,760 --> 05:43:35,000 aren't in this Zoom to be honest you and 8983 05:43:33,440 --> 05:43:36,478 I as we learn more and more about 8984 05:43:35,000 --> 05:43:38,400 programming and more about command line 8985 05:43:36,478 --> 05:43:41,240 arguments I dare say will become more 8986 05:43:38,400 --> 05:43:43,200 comfortable with and tend to prefer the 8987 05:43:41,240 --> 05:43:44,878 ability to customize commands using 8988 05:43:43,200 --> 05:43:47,000 these commandline arguments why 8989 05:43:44,878 --> 05:43:48,080 productivity it tends to make you faster 8990 05:43:47,000 --> 05:43:49,760 because you get into the habit of 8991 05:43:48,080 --> 05:43:51,958 knowing exactly how you can configure 8992 05:43:49,760 --> 05:43:54,280 your software without having to manually 8993 05:43:51,958 --> 05:43:56,798 answer questions and case in point all 8994 05:43:54,280 --> 05:43:59,558 of this time uh have we been running 8995 05:43:56,798 --> 05:44:01,400 python of something. py you could 8996 05:43:59,558 --> 05:44:03,920 imagine not doing that you could imagine 8997 05:44:01,400 --> 05:44:05,280 typing only python hitting enter and 8998 05:44:03,920 --> 05:44:06,558 then you're prompted for the name of the 8999 05:44:05,280 --> 05:44:08,878 file you want to run so you type in 9000 05:44:06,558 --> 05:44:10,920 something piie and then it runs not a 9001 05:44:08,878 --> 05:44:12,440 big deal but I I would argue that over 9002 05:44:10,920 --> 05:44:14,240 time you're going to get a little tired 9003 05:44:12,440 --> 05:44:16,080 of that tedium and you would much prefer 9004 05:44:14,240 --> 05:44:17,878 to just automate the command again and 9005 05:44:16,080 --> 05:44:19,798 again and again especially with little 9006 05:44:17,878 --> 05:44:21,958 conveniences like being able to hit up 9007 05:44:19,798 --> 05:44:24,200 and down in your keyboard history so as 9008 05:44:21,958 --> 05:44:26,360 to rerun those same commands automation 9009 05:44:24,200 --> 05:44:28,760 is Big too if you emerge from a class 9010 05:44:26,360 --> 05:44:30,680 like this and start using python to 9011 05:44:28,760 --> 05:44:32,240 automate processes at work or for 9012 05:44:30,680 --> 05:44:34,000 personal projects or the like the 9013 05:44:32,240 --> 05:44:35,878 ability to specify all of your inputs on 9014 05:44:34,000 --> 05:44:38,280 the one line just means you can get work 9015 05:44:35,878 --> 05:44:40,360 done more quickly so so hands down 9016 05:44:38,280 --> 05:44:43,600 absolutely using commandline arguments 9017 05:44:40,360 --> 05:44:45,320 is a more Arcane uh feature of systems 9018 05:44:43,600 --> 05:44:47,360 that most of us are no longer as 9019 05:44:45,320 --> 05:44:49,080 familiar with because of Windows and Mac 9020 05:44:47,360 --> 05:44:51,558 OS and other operating systems that have 9021 05:44:49,080 --> 05:44:53,360 buttons and goys and menus but the more 9022 05:44:51,558 --> 05:44:55,440 comfortable get you get with programming 9023 05:44:53,360 --> 05:44:57,360 I dare say the more you will tend to 9024 05:44:55,440 --> 05:45:00,680 prefer these capabilities because they 9025 05:44:57,360 --> 05:45:02,760 allow you to do things more quickly with 9026 05:45:00,680 --> 05:45:06,440 that said allow me to propose that we 9027 05:45:02,760 --> 05:45:08,760 take a turn toward yet another package 9028 05:45:06,440 --> 05:45:11,120 that's particularly popular and just as 9029 05:45:08,760 --> 05:45:13,718 easy to install all toward an end of 9030 05:45:11,120 --> 05:45:15,920 using apis now apis are not something 9031 05:45:13,718 --> 05:45:18,440 that's python specific more generally an 9032 05:45:15,920 --> 05:45:21,160 API is an application programming 9033 05:45:18,440 --> 05:45:23,878 interface and it can refer to python 9034 05:45:21,160 --> 05:45:26,240 files and functions but often apis 9035 05:45:23,878 --> 05:45:28,718 really refer to third-party services 9036 05:45:26,240 --> 05:45:31,878 that you and I can write code that talk 9037 05:45:28,718 --> 05:45:33,840 to many apis but not all live on the 9038 05:45:31,878 --> 05:45:35,558 internet these days so that so long as 9039 05:45:33,840 --> 05:45:37,440 you have a browser or so long as you 9040 05:45:35,558 --> 05:45:38,840 have some experience with Python 9041 05:45:37,440 --> 05:45:41,160 Programming or programming in any 9042 05:45:38,840 --> 05:45:44,080 language you can write code that in 9043 05:45:41,160 --> 05:45:47,440 effect pretends to be a browser connects 9044 05:45:44,080 --> 05:45:49,000 to that thirdparty API on a server and 9045 05:45:47,440 --> 05:45:51,320 download some data that you can then 9046 05:45:49,000 --> 05:45:53,558 incorporate into your own program now 9047 05:45:51,320 --> 05:45:55,360 how do you do this well python has a 9048 05:45:53,558 --> 05:45:58,280 very popular package that you can 9049 05:45:55,360 --> 05:46:01,040 install via pip called requests the 9050 05:45:58,280 --> 05:46:03,840 requests Library allows you to make web 9051 05:46:01,040 --> 05:46:06,520 requests internet requests using python 9052 05:46:03,840 --> 05:46:08,920 code essentially as though you were a 9053 05:46:06,520 --> 05:46:10,840 browser yourself you can automate 9054 05:46:08,920 --> 05:46:14,000 therefore the retrieval of URLs that 9055 05:46:10,840 --> 05:46:15,680 start with HTTP or https the 9056 05:46:14,000 --> 05:46:17,200 documentation for this library is at a 9057 05:46:15,680 --> 05:46:18,878 URL like this but it too can be 9058 05:46:17,200 --> 05:46:20,240 installed at the command line and even 9059 05:46:18,878 --> 05:46:22,600 though it's third party it's one of the 9060 05:46:20,240 --> 05:46:24,958 most popular and commonly used packages 9061 05:46:22,600 --> 05:46:27,478 out there in Python and this too is one 9062 05:46:24,958 --> 05:46:29,440 of the reasons again that python is so 9063 05:46:27,478 --> 05:46:31,680 popular there's just so many solutions 9064 05:46:29,440 --> 05:46:33,638 to problems that you and I have or are 9065 05:46:31,680 --> 05:46:35,320 invariably going to have when we write 9066 05:46:33,638 --> 05:46:37,680 projects of our own there's just a 9067 05:46:35,320 --> 05:46:39,718 really vibrant EOS system a really 9068 05:46:37,680 --> 05:46:41,760 Vibrant Community of Open Source 9069 05:46:39,718 --> 05:46:43,600 software that's that easy for us to 9070 05:46:41,760 --> 05:46:46,080 install let me go back to my terminal 9071 05:46:43,600 --> 05:46:47,840 window now and run pip install requests 9072 05:46:46,080 --> 05:46:49,478 in order to install this package on my 9073 05:46:47,840 --> 05:46:51,320 own system and after some lines of 9074 05:46:49,478 --> 05:46:53,360 output I'll see that it's successfully 9075 05:46:51,320 --> 05:46:56,120 installed now let's go ahead and create 9076 05:46:53,360 --> 05:46:58,840 a new file here for instance 9077 05:46:56,120 --> 05:47:00,878 itunes. it turns out that Apple has its 9078 05:46:58,840 --> 05:47:02,000 own API for their iTunes service the 9079 05:47:00,878 --> 05:47:03,638 software that provides you with the 9080 05:47:02,000 --> 05:47:05,840 ability to download and search for music 9081 05:47:03,638 --> 05:47:07,520 and songs and other information as well 9082 05:47:05,840 --> 05:47:09,520 and it turns out that let me go back 9083 05:47:07,520 --> 05:47:11,638 over to my computer here and open up a 9084 05:47:09,520 --> 05:47:15,760 browser like Chrome and let me go ahead 9085 05:47:11,638 --> 05:47:17,520 and visit this URL here https col 9086 05:47:15,760 --> 05:47:20,920 itunes.com 9087 05:47:17,520 --> 05:47:24,120 search question mark entity equals song 9088 05:47:20,920 --> 05:47:26,878 Ampersand limit equals 1 Ampersand term 9089 05:47:24,120 --> 05:47:28,760 equals Weezer now I constructed this URL 9090 05:47:26,878 --> 05:47:31,360 manually by reading the documentation 9091 05:47:28,760 --> 05:47:33,600 for Apple's API application programming 9092 05:47:31,360 --> 05:47:35,240 interface for iTunes and what they told 9093 05:47:33,600 --> 05:47:37,200 me is that if I want to search for 9094 05:47:35,240 --> 05:47:39,680 information about songs in their 9095 05:47:37,200 --> 05:47:41,680 database I should specify entity equals 9096 05:47:39,680 --> 05:47:43,520 song so that it's songs and not albums 9097 05:47:41,680 --> 05:47:45,200 or artists or something like that if I 9098 05:47:43,520 --> 05:47:47,200 just want to get back information on one 9099 05:47:45,200 --> 05:47:49,240 song I'm going to provide limit equals 9100 05:47:47,200 --> 05:47:51,520 one and if the band I want to search for 9101 05:47:49,240 --> 05:47:54,878 the artist is Weezer I should specify 9102 05:47:51,520 --> 05:47:57,320 term equals Weezer so with this if I go 9103 05:47:54,878 --> 05:47:58,958 ahead and hit enter and visit this URL I 9104 05:47:57,320 --> 05:48:01,240 actually end up with a text file in my 9105 05:47:58,958 --> 05:48:02,878 downloads folder on my Mac if I go ahead 9106 05:48:01,240 --> 05:48:04,478 and open that text file that my browser 9107 05:48:02,878 --> 05:48:05,958 just downloaded we'll see all of this 9108 05:48:04,478 --> 05:48:07,798 text here which at first glance might 9109 05:48:05,958 --> 05:48:09,958 look a c bit cryptic but it actually 9110 05:48:07,798 --> 05:48:11,760 follows a pattern notice this curly 9111 05:48:09,958 --> 05:48:13,958 brace at the start and notice this 9112 05:48:11,760 --> 05:48:16,200 closed curly brace at the end notice 9113 05:48:13,958 --> 05:48:18,600 this open square bracket here and notice 9114 05:48:16,200 --> 05:48:21,120 this closed square bracket here and in 9115 05:48:18,600 --> 05:48:23,120 between those pieces of syntax are a 9116 05:48:21,120 --> 05:48:25,440 whole bunch of strings and values in 9117 05:48:23,120 --> 05:48:27,240 fact a whole bunch of key value pairs 9118 05:48:25,440 --> 05:48:29,718 what we're looking at here is a standard 9119 05:48:27,240 --> 05:48:32,080 text format known as Json JavaScript 9120 05:48:29,718 --> 05:48:33,600 object notation which yes is technically 9121 05:48:32,080 --> 05:48:35,840 related to yet another programming 9122 05:48:33,600 --> 05:48:38,120 language called JavaScript but Json 9123 05:48:35,840 --> 05:48:41,040 itself is typ typically used nowadays as 9124 05:48:38,120 --> 05:48:43,520 a language agnostic format for 9125 05:48:41,040 --> 05:48:45,240 exchanging data between computers by 9126 05:48:43,520 --> 05:48:47,120 language agnostic I mean you don't have 9127 05:48:45,240 --> 05:48:49,520 to use JavaScript you can use python or 9128 05:48:47,120 --> 05:48:51,478 any other language to read Json or write 9129 05:48:49,520 --> 05:48:53,600 it as well and it's a completely 9130 05:48:51,478 --> 05:48:56,040 text-based format which means that if I 9131 05:48:53,600 --> 05:48:58,240 visit that URL with my browser what gets 9132 05:48:56,040 --> 05:49:00,760 downloaded is just a bunch of text but 9133 05:48:58,240 --> 05:49:03,520 that text is formatted in a standard way 9134 05:49:00,760 --> 05:49:05,878 using curly braces and square brackets 9135 05:49:03,520 --> 05:49:07,520 using quotes and some colons that 9136 05:49:05,878 --> 05:49:09,680 ultimately contain contains all of the 9137 05:49:07,520 --> 05:49:12,120 information in Apple's database on 9138 05:49:09,680 --> 05:49:14,600 Weezer song at least the first one CU I 9139 05:49:12,120 --> 05:49:16,760 limited it to one in their database and 9140 05:49:14,600 --> 05:49:19,000 that's an API an application programming 9141 05:49:16,760 --> 05:49:21,400 interface a mechanism whereby I can 9142 05:49:19,000 --> 05:49:24,718 access data on someone else's server and 9143 05:49:21,400 --> 05:49:26,680 somehow integrate it into my own program 9144 05:49:24,718 --> 05:49:28,160 now of course my browser Chrome is not 9145 05:49:26,680 --> 05:49:30,120 something I wrote I should actually 9146 05:49:28,160 --> 05:49:32,280 write some python code that perhaps 9147 05:49:30,120 --> 05:49:34,478 pretends to be a browser to grab the 9148 05:49:32,280 --> 05:49:36,080 same data so let's do that let me go 9149 05:49:34,478 --> 05:49:39,200 back to vs code here and let me write a 9150 05:49:36,080 --> 05:49:41,160 program with code itunes. and we're 9151 05:49:39,200 --> 05:49:45,080 going to write some code via which I can 9152 05:49:41,160 --> 05:49:47,878 then use the iTunes API and in turn 9153 05:49:45,080 --> 05:49:49,680 python to get information about any band 9154 05:49:47,878 --> 05:49:52,718 that I might want I'm going to go here 9155 05:49:49,680 --> 05:49:54,240 and import first the requests Library 9156 05:49:52,718 --> 05:49:57,200 which I installed earlier in order to 9157 05:49:54,240 --> 05:49:59,600 make those HTTP requests I'm going to go 9158 05:49:57,200 --> 05:50:01,040 ahead and import the CIS Library via 9159 05:49:59,600 --> 05:50:02,638 which I'll have the ability to use 9160 05:50:01,040 --> 05:50:04,520 command line arguments like 9161 05:50:02,638 --> 05:50:06,798 specification of the band that I want to 9162 05:50:04,520 --> 05:50:08,520 search for if not Weezer and then down 9163 05:50:06,798 --> 05:50:11,798 here I'm going to go ahead and insert 9164 05:50:08,520 --> 05:50:16,040 some error checking to say if the length 9165 05:50:11,798 --> 05:50:17,798 of cy. argv does not equal to so if the 9166 05:50:16,040 --> 05:50:19,638 user does not provide me with the name 9167 05:50:17,798 --> 05:50:22,080 of the file they want to run and the 9168 05:50:19,638 --> 05:50:24,320 name of a band and that's it you know 9169 05:50:22,080 --> 05:50:26,280 what let's just go ahead and exit for 9170 05:50:24,320 --> 05:50:27,478 now I could provide a more explanatory 9171 05:50:26,280 --> 05:50:29,400 message but for now I'm going to keep 9172 05:50:27,478 --> 05:50:31,400 things simple and just exit the program 9173 05:50:29,400 --> 05:50:34,878 prematurely so that I can trust 9174 05:50:31,400 --> 05:50:37,320 Hereafter that cy. arv has what I want 9175 05:50:34,878 --> 05:50:39,600 and now I have the opportunity to use 9176 05:50:37,320 --> 05:50:41,320 the requests library to write some 9177 05:50:39,600 --> 05:50:44,160 python code that effectively is 9178 05:50:41,320 --> 05:50:47,160 pretending to be a web browser so as to 9179 05:50:44,160 --> 05:50:49,600 connect to that same https URL on 9180 05:50:47,160 --> 05:50:51,360 Apple's own server so now that I've 9181 05:50:49,600 --> 05:50:53,520 guaranteed that the user has typed in 9182 05:50:51,360 --> 05:50:55,680 not just the name of the file but also 9183 05:50:53,520 --> 05:50:58,360 the name of a band at the prompt giving 9184 05:50:55,680 --> 05:51:01,000 me a length of two for cis.org V let's 9185 05:50:58,360 --> 05:51:03,200 go ahead and execute requests.get which 9186 05:51:01,000 --> 05:51:05,040 is a function inside of the requests 9187 05:51:03,200 --> 05:51:07,200 package that will literally get some 9188 05:51:05,040 --> 05:51:08,958 response from a server and the URL that 9189 05:51:07,200 --> 05:51:10,718 I want to get is the exactly the same as 9190 05:51:08,958 --> 05:51:15,080 before 9191 05:51:10,718 --> 05:51:17,798 https itunes.com search question mark 9192 05:51:15,080 --> 05:51:20,680 entity equals song Ampersand limit 9193 05:51:17,798 --> 05:51:22,760 equals 1 Ampersand term equals 9194 05:51:20,680 --> 05:51:24,600 previously Weezer but let's make this 9195 05:51:22,760 --> 05:51:26,920 program a little interactive and 9196 05:51:24,600 --> 05:51:28,760 actually allow the human to specify at 9197 05:51:26,920 --> 05:51:30,478 the command line what artists they'd 9198 05:51:28,760 --> 05:51:33,200 like to search for so I'm going to go 9199 05:51:30,478 --> 05:51:35,840 ahead and close my quote early and just 9200 05:51:33,200 --> 05:51:37,120 append using the concatenation operator 9201 05:51:35,840 --> 05:51:40,920 as in the past 9202 05:51:37,120 --> 05:51:42,920 sis. Arvy bracket1 and now it'd actually 9203 05:51:40,920 --> 05:51:44,638 be nice to store the response from the 9204 05:51:42,920 --> 05:51:47,520 server in a variable so I'm going to go 9205 05:51:44,638 --> 05:51:49,120 ahead and say response equals and to 9206 05:51:47,520 --> 05:51:50,360 store all of the response that comes 9207 05:51:49,120 --> 05:51:52,920 back from the server in a variable 9208 05:51:50,360 --> 05:51:54,478 called response down here now I'd like 9209 05:51:52,920 --> 05:51:56,600 to just understand what the server is 9210 05:51:54,478 --> 05:51:58,320 returning to me to make sure I know how 9211 05:51:56,600 --> 05:51:59,718 next to proceed so this isn't going to 9212 05:51:58,320 --> 05:52:02,958 be very pretty yet but I'm going to go 9213 05:51:59,718 --> 05:52:05,120 ahead and print out response. Json which 9214 05:52:02,958 --> 05:52:07,160 ensures that the data I'm getting back 9215 05:52:05,120 --> 05:52:10,240 is formatted on my screen as is exactly 9216 05:52:07,160 --> 05:52:12,558 that Json the same text format as we saw 9217 05:52:10,240 --> 05:52:14,400 on my screen it's not a useful program 9218 05:52:12,558 --> 05:52:16,320 yet I'm really just learning along the 9219 05:52:14,400 --> 05:52:18,798 way but let me go ahead now and increase 9220 05:52:16,320 --> 05:52:21,400 the size of my terminal window and run 9221 05:52:18,798 --> 05:52:24,520 python of itunes. and type in the name 9222 05:52:21,400 --> 05:52:26,478 of a band like Weezer and hit enter and 9223 05:52:24,520 --> 05:52:28,958 what we see on the screen formatted 9224 05:52:26,478 --> 05:52:31,320 almost the same as before is exactly 9225 05:52:28,958 --> 05:52:33,638 that same text but what you'll see here 9226 05:52:31,320 --> 05:52:36,520 is that this has been standardized now 9227 05:52:33,638 --> 05:52:38,360 as a python dictionary what indeed 9228 05:52:36,520 --> 05:52:40,478 Apple's returning is technically 9229 05:52:38,360 --> 05:52:43,558 adjacent response JavaScript object 9230 05:52:40,478 --> 05:52:46,400 notation but python the request library 9231 05:52:43,558 --> 05:52:48,120 is converting it to a python dictionary 9232 05:52:46,400 --> 05:52:50,600 which happens to use wonderfully 9233 05:52:48,120 --> 05:52:52,478 coincidentally almost the same syntax it 9234 05:52:50,600 --> 05:52:54,600 uses curly braces to represent the 9235 05:52:52,478 --> 05:52:56,718 dictionary here and a closed curly brace 9236 05:52:54,600 --> 05:52:59,200 to represent the end of it here for any 9237 05:52:56,718 --> 05:53:01,280 lists therein it uses a square bracket 9238 05:52:59,200 --> 05:53:04,000 here and a closed square bracket down 9239 05:53:01,280 --> 05:53:05,840 here it uses quotes single quotes in 9240 05:53:04,000 --> 05:53:08,798 this case or equivalently double quotes 9241 05:53:05,840 --> 05:53:11,680 to represent the keys in that dictionary 9242 05:53:08,798 --> 05:53:13,798 and after a colon it stores the value of 9243 05:53:11,680 --> 05:53:16,400 that key and so you'll see that indeed 9244 05:53:13,798 --> 05:53:18,680 we have a result count key whose value 9245 05:53:16,400 --> 05:53:21,958 is one but then a more interesting 9246 05:53:18,680 --> 05:53:25,080 result key called results whose value is 9247 05:53:21,958 --> 05:53:26,958 this entire list of data now honestly 9248 05:53:25,080 --> 05:53:28,360 this is such a big blob of text that 9249 05:53:26,958 --> 05:53:30,240 it's going to take me forever to wrap my 9250 05:53:28,360 --> 05:53:32,520 mind around what I'm seeing so let me 9251 05:53:30,240 --> 05:53:34,840 propose temporarily we use another 9252 05:53:32,520 --> 05:53:36,840 library in Python that will allow me to 9253 05:53:34,840 --> 05:53:39,120 format my data a little little more 9254 05:53:36,840 --> 05:53:41,718 cleanly it turns out that python also 9255 05:53:39,120 --> 05:53:44,240 comes with a special Library uh called 9256 05:53:41,718 --> 05:53:46,558 Json that allows you to manipulate Json 9257 05:53:44,240 --> 05:53:48,120 data and even just printy print it that 9258 05:53:46,558 --> 05:53:50,200 is format it in a way that's going to be 9259 05:53:48,120 --> 05:53:52,878 way easier for you and I to understand 9260 05:53:50,200 --> 05:53:55,400 so let me go back to my code here let me 9261 05:53:52,878 --> 05:53:57,600 shrink my terminal window and let me 9262 05:53:55,400 --> 05:54:00,000 propose that just temporarily again we 9263 05:53:57,600 --> 05:54:02,200 do this let me import this additional 9264 05:54:00,000 --> 05:54:03,840 Library Json which comes with python so 9265 05:54:02,200 --> 05:54:06,680 I don't need to install it manually with 9266 05:54:03,840 --> 05:54:08,920 Pip and let me go ahead now and not just 9267 05:54:06,680 --> 05:54:11,520 print out response. Json which was that 9268 05:54:08,920 --> 05:54:13,520 Big Blob of hard to understand text let 9269 05:54:11,520 --> 05:54:18,200 me go ahead and use one other function 9270 05:54:13,520 --> 05:54:21,160 here called json. dumps for dump string 9271 05:54:18,200 --> 05:54:23,558 and pass to that function that response. 9272 05:54:21,160 --> 05:54:26,080 Json return value so again I'm just 9273 05:54:23,558 --> 05:54:28,120 introducing another function who I claim 9274 05:54:26,080 --> 05:54:30,360 it has a purpose in life of pretty 9275 05:54:28,120 --> 05:54:32,200 printing nicely formatting on the screen 9276 05:54:30,360 --> 05:54:33,920 the exact same information and I know 9277 05:54:32,200 --> 05:54:35,600 this from the documentation having done 9278 05:54:33,920 --> 05:54:37,760 this before but I'd like things to be 9279 05:54:35,600 --> 05:54:39,718 nicely into Ed and according to the 9280 05:54:37,760 --> 05:54:42,798 documentation if I pass in a named 9281 05:54:39,718 --> 05:54:44,400 parameter of indent equals 2 that's 9282 05:54:42,798 --> 05:54:46,400 going to indent everything at least two 9283 05:54:44,400 --> 05:54:48,080 spaces I could do four or something else 9284 05:54:46,400 --> 05:54:50,478 but it's going to be enough to help me 9285 05:54:48,080 --> 05:54:52,000 wrap my mind around what the data is I'm 9286 05:54:50,478 --> 05:54:54,080 getting back because again I'm just 9287 05:54:52,000 --> 05:54:55,638 learning along with you so let me 9288 05:54:54,080 --> 05:54:58,080 increase the size of my terminal window 9289 05:54:55,638 --> 05:54:59,798 again let me run python of itunes. and 9290 05:54:58,080 --> 05:55:02,958 again let's search for Weezer and hit 9291 05:54:59,798 --> 05:55:04,718 enter and now notice it's still a little 9292 05:55:02,958 --> 05:55:07,798 bit cryptic because there's a lot going 9293 05:55:04,718 --> 05:55:10,760 on here but my gosh I can totally read 9294 05:55:07,798 --> 05:55:12,440 this more easily now notice now that I 9295 05:55:10,760 --> 05:55:14,798 still see the first curly brace which 9296 05:55:12,440 --> 05:55:17,160 means hey this is a dictionary in Python 9297 05:55:14,798 --> 05:55:19,240 a collection of keys and values the 9298 05:55:17,160 --> 05:55:20,878 first key is called result count it 9299 05:55:19,240 --> 05:55:22,280 happens to be displayed in double quotes 9300 05:55:20,878 --> 05:55:23,878 now but that's just an issue of 9301 05:55:22,280 --> 05:55:26,320 formatting it could be double or single 9302 05:55:23,878 --> 05:55:29,280 so long as we're consistent the value of 9303 05:55:26,320 --> 05:55:31,080 that key is one why well I told the URL 9304 05:55:29,280 --> 05:55:33,080 to only limit the responses to one 9305 05:55:31,080 --> 05:55:35,400 Weezer song so I've gotten a result set 9306 05:55:33,080 --> 05:55:36,798 of one if I increase that limit I could 9307 05:55:35,400 --> 05:55:38,360 probably get more 9308 05:55:36,798 --> 05:55:40,400 then the interesting part of this 9309 05:55:38,360 --> 05:55:43,080 response is really the data itself 9310 05:55:40,400 --> 05:55:46,478 notice in the res results key here 9311 05:55:43,080 --> 05:55:48,798 there's a really big value the value is 9312 05:55:46,478 --> 05:55:51,600 a python list as 9313 05:55:48,798 --> 05:55:53,798 implied by this square bracket what does 9314 05:55:51,600 --> 05:55:55,840 this list contain well I know from 9315 05:55:53,798 --> 05:55:58,080 skimming it earlier that this contains 9316 05:55:55,840 --> 05:56:01,958 one dictionary and that's why we see 9317 05:55:58,080 --> 05:56:03,718 another curly brace here so again if 9318 05:56:01,958 --> 05:56:05,718 this gets a little more complicated keep 9319 05:56:03,718 --> 05:56:08,520 in mind that a dictionary is just a 9320 05:56:05,718 --> 05:56:11,280 collection of key value Pairs and python 9321 05:56:08,520 --> 05:56:14,160 uses curly braces to indicate as much it 9322 05:56:11,280 --> 05:56:16,920 is perfectly reasonable for a dictionary 9323 05:56:14,160 --> 05:56:19,680 to be inside of another dictionary if 9324 05:56:16,920 --> 05:56:21,558 the value of some key itself is another 9325 05:56:19,680 --> 05:56:22,798 dictionary so this is a common Paradigm 9326 05:56:21,558 --> 05:56:24,958 and even though it might seem a bit 9327 05:56:22,798 --> 05:56:27,280 cryptic it's just something that allows 9328 05:56:24,958 --> 05:56:29,440 us to associate more keys with more 9329 05:56:27,280 --> 05:56:31,000 values now most of this information I 9330 05:56:29,440 --> 05:56:33,478 probably don't care about for instance 9331 05:56:31,000 --> 05:56:36,680 according to Apple the unique identifier 9332 05:56:33,478 --> 05:56:39,080 for Weezer is apparently 115,000 9333 05:56:36,680 --> 05:56:40,680 234 that might be useful if I'm making 9334 05:56:39,080 --> 05:56:42,958 my own database and I want this to be 9335 05:56:40,680 --> 05:56:45,400 searchable but for today's purposes all 9336 05:56:42,958 --> 05:56:48,280 I care about is the name of the track 9337 05:56:45,400 --> 05:56:50,320 otherwise called track name as key and 9338 05:56:48,280 --> 05:56:52,600 the first song and only song because we 9339 05:56:50,320 --> 05:56:54,600 limited it to one that we got back from 9340 05:56:52,600 --> 05:56:57,958 iTunes here is the song that you might 9341 05:56:54,600 --> 05:57:00,600 know by Weezer called Say It Ain't So so 9342 05:56:57,958 --> 05:57:03,240 now I have a bit of a clue if my goal 9343 05:57:00,600 --> 05:57:05,360 here is to implement a program called 9344 05:57:03,240 --> 05:57:07,200 itunes. that doesn't just dump the 9345 05:57:05,360 --> 05:57:09,478 response from the which is admittedly 9346 05:57:07,200 --> 05:57:12,200 very cryptic but to print out all of the 9347 05:57:09,478 --> 05:57:15,280 songs that iTunes has for the band 9348 05:57:12,200 --> 05:57:17,638 called Weezer maybe I can iterate over 9349 05:57:15,280 --> 05:57:20,478 this somehow so let me backtrack here's 9350 05:57:17,638 --> 05:57:23,798 the key called track name it is inside 9351 05:57:20,478 --> 05:57:26,798 of a dictionary that is the value of 9352 05:57:23,798 --> 05:57:28,360 results here so how can I go about 9353 05:57:26,798 --> 05:57:30,718 getting this well let me go ahead and 9354 05:57:28,360 --> 05:57:33,080 try this let me go ahead and Shrink my 9355 05:57:30,718 --> 05:57:35,200 terminal window back down and let me 9356 05:57:33,080 --> 05:57:37,200 propose now for one final flourish we 9357 05:57:35,200 --> 05:57:38,558 don't just lazily print out the contents 9358 05:57:37,200 --> 05:57:40,760 of that response because that's not 9359 05:57:38,558 --> 05:57:43,240 interesting or pretty for anyone let's 9360 05:57:40,760 --> 05:57:45,040 do this let me go ahead and create a new 9361 05:57:43,240 --> 05:57:47,280 variable just for the sake of discussion 9362 05:57:45,040 --> 05:57:50,600 called o for object and I'm going to go 9363 05:57:47,280 --> 05:57:54,878 ahead and call uh o equals response. 9364 05:57:50,600 --> 05:57:56,798 Json just to store that Json response 9365 05:57:54,878 --> 05:57:58,680 specifically in a variable called o but 9366 05:57:56,798 --> 05:58:03,080 I could name it anything I want and now 9367 05:57:58,680 --> 05:58:06,920 I'm going to do this for each result in 9368 05:58:03,080 --> 05:58:10,320 that object's key called result 9369 05:58:06,920 --> 05:58:12,798 go ahead and print out that results 9370 05:58:10,320 --> 05:58:15,080 track name and notice I have used 9371 05:58:12,798 --> 05:58:17,478 exactly the same capitalization track 9372 05:58:15,080 --> 05:58:19,160 name has a capital N results is all 9373 05:58:17,478 --> 05:58:21,840 lowercase and let me rewind before we 9374 05:58:19,160 --> 05:58:24,478 run the actual program in line eight we 9375 05:58:21,840 --> 05:58:26,000 are making an HTTP request using python 9376 05:58:24,478 --> 05:58:28,240 to the server just like you and I as 9377 05:58:26,000 --> 05:58:29,920 humans type URLs into a browser and hit 9378 05:58:28,240 --> 05:58:33,280 enter this is the python equivalent 9379 05:58:29,920 --> 05:58:34,878 there of I am then on line 10 just 9380 05:58:33,280 --> 05:58:36,600 grabbing from that variable that 9381 05:58:34,878 --> 05:58:39,280 contains the server's respon 9382 05:58:36,600 --> 05:58:41,680 the Json object that I care about the 9383 05:58:39,280 --> 05:58:43,798 thing between those curly braces at the 9384 05:58:41,680 --> 05:58:45,718 very top and the bottom but because 9385 05:58:43,798 --> 05:58:48,160 we've poked around and because I read 9386 05:58:45,718 --> 05:58:51,600 the documentation earlier I know that 9387 05:58:48,160 --> 05:58:53,718 that object has a key called results and 9388 05:58:51,600 --> 05:58:55,760 that results key again is a list now at 9389 05:58:53,718 --> 05:58:58,240 the moment that list contains only one 9390 05:58:55,760 --> 05:59:00,958 song Say It Ain't So because I limited 9391 05:58:58,240 --> 05:59:02,280 my response to one but even so my Loop 9392 05:59:00,958 --> 05:59:03,878 will work it's just going to iterate 9393 05:59:02,280 --> 05:59:06,280 once and each time through that loop 9394 05:59:03,878 --> 05:59:08,600 it's going to print the current results 9395 05:59:06,280 --> 05:59:10,200 track name if I want to make this even 9396 05:59:08,600 --> 05:59:12,040 more interesting let me change this 9397 05:59:10,200 --> 05:59:15,000 limit now from one to 50 so I'll at 9398 05:59:12,040 --> 05:59:16,600 least get back 50 track names instead 9399 05:59:15,000 --> 05:59:18,840 let me go ahead now and increase the 9400 05:59:16,600 --> 05:59:21,440 size of my terminal once more and go 9401 05:59:18,840 --> 05:59:23,798 ahead now and run python of itunes. 9402 05:59:21,440 --> 05:59:27,760 searching again for a band like Weezer 9403 05:59:23,798 --> 05:59:30,160 and here we go and voila there are 50 9404 05:59:27,760 --> 05:59:32,600 songs that iTunes has for Weezer and if 9405 05:59:30,160 --> 05:59:35,000 we scroll back up to the top here we'll 9406 05:59:32,600 --> 05:59:37,080 see that the very first one there is 9407 05:59:35,000 --> 05:59:39,478 indeed say it ain't so but now we got 9408 05:59:37,080 --> 05:59:41,200 undone The Sweater Song Buddy Holly 9409 05:59:39,478 --> 05:59:42,878 apparently another rendition of Say It 9410 05:59:41,200 --> 05:59:44,958 Ain't So perhaps from another album 9411 05:59:42,878 --> 05:59:48,840 another Buddy Holly undone my name is 9412 05:59:44,958 --> 05:59:51,200 Jonas and so forth questions now on this 9413 05:59:48,840 --> 05:59:55,080 program which integrates python with a 9414 05:59:51,200 --> 05:59:58,360 real world third party 9415 05:59:55,080 --> 06:00:01,520 API yeah hi uh can we use breake instead 9416 05:59:58,360 --> 06:00:03,920 of system. exit exit good question but 9417 06:00:01,520 --> 06:00:06,000 no um break again is used to break out 9418 06:00:03,920 --> 06:00:08,600 of things like Loops like we saw ear 9419 06:00:06,000 --> 06:00:11,400 clear cy. exit is used to break out of 9420 06:00:08,600 --> 06:00:13,240 the whole program itself use break for 9421 06:00:11,400 --> 06:00:15,240 Loops for now and use cy. exit to 9422 06:00:13,240 --> 06:00:17,280 terminate the whole program good 9423 06:00:15,240 --> 06:00:19,840 question other questions now on this 9424 06:00:17,280 --> 06:00:22,760 program are others from where we bring 9425 06:00:19,840 --> 06:00:25,080 the name of the key results from where 9426 06:00:22,760 --> 06:00:27,718 do we get the name of the key uh results 9427 06:00:25,080 --> 06:00:30,200 itself yeah can we change the results 9428 06:00:27,718 --> 06:00:32,120 name you cannot so we could in our 9429 06:00:30,200 --> 06:00:34,160 program so the keys that come back in 9430 06:00:32,120 --> 06:00:37,040 that Json response to be clear come from 9431 06:00:34,160 --> 06:00:39,520 itunes. apple.com some engineer some 9432 06:00:37,040 --> 06:00:41,200 team of Engineers decided for us what 9433 06:00:39,520 --> 06:00:43,478 all of those keys would be called 9434 06:00:41,200 --> 06:00:45,878 including track name results result 9435 06:00:43,478 --> 06:00:48,000 count and everything else you and I can 9436 06:00:45,878 --> 06:00:49,760 absolutely store those same values in 9437 06:00:48,000 --> 06:00:51,798 variables just like I'm doing here with 9438 06:00:49,760 --> 06:00:53,600 o just like I'm doing here with result 9439 06:00:51,798 --> 06:00:56,478 you can rename those keys anything you 9440 06:00:53,600 --> 06:00:59,280 want using python variables but the Json 9441 06:00:56,478 --> 06:01:02,760 response is coming from that thirdparty 9442 06:00:59,280 --> 06:01:06,400 server other questions yes sir sir uh I 9443 06:01:02,760 --> 06:01:11,120 have a question related to to C package 9444 06:01:06,400 --> 06:01:14,958 so like uh yes so sir what sort of ask 9445 06:01:11,120 --> 06:01:17,240 Graphics is it capable of outputting the 9446 06:01:14,958 --> 06:01:20,200 coway package um I would refer you to 9447 06:01:17,240 --> 06:01:21,878 the URL in the slides earlier uh if only 9448 06:01:20,200 --> 06:01:23,958 because it's more thorough they have not 9449 06:01:21,878 --> 06:01:25,920 just cows but Tyrannosaurus Rexes and 9450 06:01:23,958 --> 06:01:27,440 several other animals as well I should 9451 06:01:25,920 --> 06:01:29,040 emphasize that this is not a package I 9452 06:01:27,440 --> 06:01:30,400 suspect you will use much in the real 9453 06:01:29,040 --> 06:01:32,440 world it's really just meant to be 9454 06:01:30,400 --> 06:01:34,360 representative of the types of packages 9455 06:01:32,440 --> 06:01:36,360 you can install but allow me to refer to 9456 06:01:34,360 --> 06:01:39,478 the documentation for what more is there 9457 06:01:36,360 --> 06:01:41,478 but aski artart uh is the all we had 9458 06:01:39,478 --> 06:01:44,320 before there were emojis let alone gifs 9459 06:01:41,478 --> 06:01:46,718 and jpegs and pings but it's what's is 9460 06:01:44,320 --> 06:01:49,600 immortalized in C well allow me to 9461 06:01:46,718 --> 06:01:52,360 transition us back now to one final 9462 06:01:49,600 --> 06:01:54,920 capability of python which is that you 9463 06:01:52,360 --> 06:01:57,638 yourselves have the ability to make your 9464 06:01:54,920 --> 06:02:00,040 own libraries up until now we've been 9465 06:01:57,638 --> 06:02:03,000 writing all of our functions in our one 9466 06:02:00,040 --> 06:02:05,558 file hello pi and everything since and 9467 06:02:03,000 --> 06:02:08,360 now that we've introduced modules in 9468 06:02:05,558 --> 06:02:10,478 Python like random and statistics we can 9469 06:02:08,360 --> 06:02:12,240 import those that come with python but 9470 06:02:10,478 --> 06:02:14,200 that's other people's code as well and 9471 06:02:12,240 --> 06:02:16,280 we've now used Pip this package manager 9472 06:02:14,200 --> 06:02:18,040 to install third- party packages as well 9473 06:02:16,280 --> 06:02:20,718 in the system and using other people's 9474 06:02:18,040 --> 06:02:22,440 code still but to come full circle what 9475 06:02:20,718 --> 06:02:24,798 if you yourself find yourself 9476 06:02:22,440 --> 06:02:26,760 implementing the same kinds of functions 9477 06:02:24,798 --> 06:02:28,920 again and again or you find yourself 9478 06:02:26,760 --> 06:02:31,160 opening up old programs copying and 9479 06:02:28,920 --> 06:02:32,638 pasting code you wrote into new programs 9480 06:02:31,160 --> 06:02:35,040 because you have the same problem yet 9481 06:02:32,638 --> 06:02:37,478 again a good practice would be to 9482 06:02:35,040 --> 06:02:40,680 somehow bundle up that code you keep 9483 06:02:37,478 --> 06:02:42,558 reusing and make your own python module 9484 06:02:40,680 --> 06:02:45,478 or package you can keep it local on your 9485 06:02:42,558 --> 06:02:46,878 own Mac or PC or Cloud Server or you can 9486 06:02:45,478 --> 06:02:48,718 go through the steps of actually 9487 06:02:46,878 --> 06:02:50,240 bundling it up making it free and open 9488 06:02:48,718 --> 06:02:53,558 source and putting it on something like 9489 06:02:50,240 --> 06:02:54,878 pii for others to use as well okay I'm 9490 06:02:53,558 --> 06:02:57,200 going to go ahead and run code of 9491 06:02:54,878 --> 06:02:58,878 sayings. py to create a brand new file 9492 06:02:57,200 --> 06:03:01,200 called sayings dopy which is going to be 9493 06:02:58,878 --> 06:03:03,000 my own sayings module and I'm going to 9494 06:03:01,200 --> 06:03:04,520 define a couple of simple functions in 9495 06:03:03,000 --> 06:03:06,280 there I'm going to define a hello 9496 06:03:04,520 --> 06:03:08,600 function that's going to take name 9497 06:03:06,280 --> 06:03:11,400 parameter is input and that function is 9498 06:03:08,600 --> 06:03:13,280 simply going to print out an F string 9499 06:03:11,400 --> 06:03:15,638 that contains hello comma and then in 9500 06:03:13,280 --> 06:03:17,718 curly BRAC whatever that person's name 9501 06:03:15,638 --> 06:03:19,600 actually is then I'm going to go ahead 9502 06:03:17,718 --> 06:03:22,920 and Define one other function a goodbye 9503 06:03:19,600 --> 06:03:25,240 function that has def goodby also takes 9504 06:03:22,920 --> 06:03:27,558 a name as its input and then that prints 9505 06:03:25,240 --> 06:03:30,400 out by contrast an F string that says 9506 06:03:27,558 --> 06:03:33,000 goodbye comma and then in curly brace's 9507 06:03:30,400 --> 06:03:34,638 name and now just for good measure just 9508 06:03:33,000 --> 06:03:36,320 so I can be sure that these functions 9509 06:03:34,638 --> 06:03:38,240 are working as expected I'm going to go 9510 06:03:36,320 --> 06:03:40,400 ahead and Define a main function in here 9511 06:03:38,240 --> 06:03:41,878 too just for the purposes of testing and 9512 06:03:40,400 --> 06:03:44,558 I'm going to go ahead and Define a main 9513 06:03:41,878 --> 06:03:48,478 function that simply does a couple of 9514 06:03:44,558 --> 06:03:50,878 tests for instance it calls uh hello of 9515 06:03:48,478 --> 06:03:53,040 quote unquote worlds shall we say and 9516 06:03:50,878 --> 06:03:55,400 then it's going to call goodbye of quote 9517 06:03:53,040 --> 06:03:56,718 unquote world as well and hopefully what 9518 06:03:55,400 --> 06:03:58,558 I'll see on the screen then is hello 9519 06:03:56,718 --> 06:04:00,520 world and goodbye world when I run this 9520 06:03:58,558 --> 06:04:02,360 program of course as always I need to 9521 06:04:00,520 --> 06:04:04,040 explicitly tell python to call that 9522 06:04:02,360 --> 06:04:05,718 function so I'm going to call Main at 9523 06:04:04,040 --> 06:04:07,600 the very bottom of this file all right 9524 06:04:05,718 --> 06:04:10,798 all right let's try it out python of 9525 06:04:07,600 --> 06:04:12,600 sayings. py enter and indeed I see Hello 9526 06:04:10,798 --> 06:04:14,320 World and goodbye world and so I think 9527 06:04:12,600 --> 06:04:16,718 it's reasonable for me to assume that 9528 06:04:14,320 --> 06:04:18,840 these functions albeit simple are pretty 9529 06:04:16,718 --> 06:04:20,760 correct at this point but now suppose 9530 06:04:18,840 --> 06:04:22,320 that I want to use these functions as 9531 06:04:20,760 --> 06:04:25,240 though I've indeed created my own 9532 06:04:22,320 --> 06:04:27,040 Library my own python module that makes 9533 06:04:25,240 --> 06:04:28,680 available a hello function for me or 9534 06:04:27,040 --> 06:04:30,878 anyone else who wants to use it or a 9535 06:04:28,680 --> 06:04:33,638 goodbye function as well well let me go 9536 06:04:30,878 --> 06:04:35,920 ahead and open up again say. py but 9537 06:04:33,638 --> 06:04:38,558 start fresh and rather than have the C 9538 06:04:35,920 --> 06:04:41,240 say anything let me go ahead and have my 9539 06:04:38,558 --> 06:04:43,878 own Library do the talking so I'm going 9540 06:04:41,240 --> 06:04:45,240 to go ahead and as before import CIS so 9541 06:04:43,878 --> 06:04:48,080 that I have access to command line 9542 06:04:45,240 --> 06:04:50,840 arguments and from my own module called 9543 06:04:48,080 --> 06:04:53,160 sayings I'm going to import hello so 9544 06:04:50,840 --> 06:04:56,120 because I created a file called sayings. 9545 06:04:53,160 --> 06:04:58,240 py I can say from sayings and it's 9546 06:04:56,120 --> 06:05:00,000 inferred by python that I mean sayings. 9547 06:04:58,240 --> 06:05:01,760 py at least in this current directory 9548 06:05:00,000 --> 06:05:03,680 but I specifically going to import just 9549 06:05:01,760 --> 06:05:05,798 one of the functions for now namely 9550 06:05:03,680 --> 06:05:08,120 hello and now I can do something like 9551 06:05:05,798 --> 06:05:10,040 this if the user obliges by giving me 9552 06:05:08,120 --> 06:05:12,320 two command line arguments which I can 9553 06:05:10,040 --> 06:05:15,080 check by just checking the length of cy. 9554 06:05:12,320 --> 06:05:17,558 argv I'm going to then go ahead and call 9555 06:05:15,080 --> 06:05:20,320 this new hello function passing as its 9556 06:05:17,558 --> 06:05:21,920 input assist. arv bracket one which 9557 06:05:20,320 --> 06:05:23,240 should hopefully be the person's name 9558 06:05:21,920 --> 06:05:25,280 which I'm going to expect them to type 9559 06:05:23,240 --> 06:05:27,478 at the prompt so here we go I'm going to 9560 06:05:25,280 --> 06:05:30,798 go down to my terminal window run python 9561 06:05:27,478 --> 06:05:32,240 of s.p and my own name because I want my 9562 06:05:30,798 --> 06:05:33,920 own name to end up in the command line 9563 06:05:32,240 --> 06:05:35,878 arguments and therefore be part of the 9564 06:05:33,920 --> 06:05:37,920 hello so when I hit enter and just a 9565 06:05:35,878 --> 06:05:42,080 moment I should hopefully see hello 9566 06:05:37,920 --> 06:05:44,798 comma David so here we go enter and huh 9567 06:05:42,080 --> 06:05:48,760 I see Hello World Goodbye World and then 9568 06:05:44,798 --> 06:05:51,000 I see hello David so why is this 9569 06:05:48,760 --> 06:05:52,920 happening well it turns out even though 9570 06:05:51,000 --> 06:05:56,360 I've done everything according to our 9571 06:05:52,920 --> 06:05:58,400 own past practice it's not really the 9572 06:05:56,360 --> 06:06:00,840 right way to go about calling Maine 9573 06:05:58,400 --> 06:06:02,520 after all if I'm blindly calling Maine 9574 06:06:00,840 --> 06:06:04,400 here at the bottom of my file that means 9575 06:06:02,520 --> 06:06:06,160 whenever this file is loaded by python 9576 06:06:04,400 --> 06:06:08,638 Maine is going to get called and 9577 06:06:06,160 --> 06:06:11,000 unfortunately that's true even if I'm 9578 06:06:08,638 --> 06:06:13,718 importing this file or just a function 9579 06:06:11,000 --> 06:06:15,798 from this file as I am here in my s.p 9580 06:06:13,718 --> 06:06:18,120 program this is to say on line three 9581 06:06:15,798 --> 06:06:20,320 here when I say from sayings import 9582 06:06:18,120 --> 06:06:22,958 hello this effectively tells python to 9583 06:06:20,320 --> 06:06:24,718 go find that module sayings. py read it 9584 06:06:22,958 --> 06:06:26,400 from top to bottom left to right and 9585 06:06:24,718 --> 06:06:28,400 then import specifically the hello 9586 06:06:26,400 --> 06:06:30,160 function unfortunately by the time 9587 06:06:28,400 --> 06:06:32,600 python has read the file from top to 9588 06:06:30,160 --> 06:06:35,120 bottom left to right that last line of 9589 06:06:32,600 --> 06:06:37,840 code recall is to call Maine Maine gets 9590 06:06:35,120 --> 06:06:40,120 called no matter what so really the 9591 06:06:37,840 --> 06:06:42,000 right way to go about using a main 9592 06:06:40,120 --> 06:06:43,558 function which does solve that problem 9593 06:06:42,000 --> 06:06:45,280 of ensuring that we can order our 9594 06:06:43,558 --> 06:06:47,040 functions however we want and all the 9595 06:06:45,280 --> 06:06:49,000 functions will be defined at the time 9596 06:06:47,040 --> 06:06:50,878 they're invoked I shouldn't be 9597 06:06:49,000 --> 06:06:52,680 unconditionally calling main at the 9598 06:06:50,878 --> 06:06:54,600 bottom of this or really any of my 9599 06:06:52,680 --> 06:06:57,160 programs I should instead use this 9600 06:06:54,600 --> 06:06:59,680 technique I should say if underscore 9601 06:06:57,160 --> 06:07:02,000 underscore name underscore underscore 9602 06:06:59,680 --> 06:07:05,878 equals equals quote unquote underscore 9603 06:07:02,000 --> 06:07:08,558 uncore maincore uncore close quote then 9604 06:07:05,878 --> 06:07:10,600 and only then should you actually call 9605 06:07:08,558 --> 06:07:12,638 Main well it turns out that this 9606 06:07:10,600 --> 06:07:14,718 variable is a special symbol in Python 9607 06:07:12,638 --> 06:07:16,638 underscore uncore name underscore 9608 06:07:14,718 --> 06:07:18,520 underscore and notice that vs code 9609 06:07:16,638 --> 06:07:20,120 because of its font isn't quite showing 9610 06:07:18,520 --> 06:07:21,718 those two underscores but they're indeed 9611 06:07:20,120 --> 06:07:23,360 there to the left and the right this is 9612 06:07:21,718 --> 06:07:25,920 a special variable whose value is 9613 06:07:23,360 --> 06:07:29,478 automatically set by python to be quote 9614 06:07:25,920 --> 06:07:32,080 unquote main when you run a file from 9615 06:07:29,478 --> 06:07:35,080 the command line as by running python of 9616 06:07:32,080 --> 06:07:36,680 sayings. piy so Watch What Happens now 9617 06:07:35,080 --> 06:07:40,280 with this additional conditional in 9618 06:07:36,680 --> 06:07:44,400 sayings. py if I run python of sayings. 9619 06:07:40,280 --> 06:07:47,240 py it still works as before because name 9620 06:07:44,400 --> 06:07:50,840 will be automatically set to underscore 9621 06:07:47,240 --> 06:07:53,520 uncore maincore uncore when I run this 9622 06:07:50,840 --> 06:07:56,478 file using python ofs sayings. py but 9623 06:07:53,520 --> 06:07:58,120 notice this name is not going to be set 9624 06:07:56,478 --> 06:07:59,478 to quote unquote main it's going to be 9625 06:07:58,120 --> 06:08:02,000 set to something else technically the 9626 06:07:59,478 --> 06:08:04,920 name of the module when I instead import 9627 06:08:02,000 --> 06:08:06,760 the file like I do here so this 9628 06:08:04,920 --> 06:08:09,200 highlighted of code even though it will 9629 06:08:06,760 --> 06:08:11,280 cause python to go find sayings. py read 9630 06:08:09,200 --> 06:08:13,200 it from top to bottom left to right it's 9631 06:08:11,280 --> 06:08:14,558 going to ignore the call to main this 9632 06:08:13,200 --> 06:08:16,160 time because it's wrapped in that 9633 06:08:14,558 --> 06:08:18,718 conditional in this case when I'm 9634 06:08:16,160 --> 06:08:20,760 importing a file and not running it 9635 06:08:18,718 --> 06:08:23,440 directly at the command line Maine will 9636 06:08:20,760 --> 06:08:25,680 not get called by definition of name's 9637 06:08:23,440 --> 06:08:27,958 value so let me go ahead and try this 9638 06:08:25,680 --> 06:08:30,000 instead of running python of sayings. py 9639 06:08:27,958 --> 06:08:32,000 which is the module which contains that 9640 06:08:30,000 --> 06:08:34,958 conditional main let me go ahead here 9641 06:08:32,000 --> 06:08:37,878 and run python of say. py which is the 9642 06:08:34,958 --> 06:08:40,520 program here before me that Imports 9643 06:08:37,878 --> 06:08:42,120 hello from sayings but because of that 9644 06:08:40,520 --> 06:08:46,360 conditional it's not going to say hello 9645 06:08:42,120 --> 06:08:47,878 to anyone else except me in this case 9646 06:08:46,360 --> 06:08:49,520 all right we're here at the end of our 9647 06:08:47,878 --> 06:08:51,478 week it's only appropriate I think to 9648 06:08:49,520 --> 06:08:53,280 import something other than hello why 9649 06:08:51,478 --> 06:08:55,680 don't I go ahead and import not hello 9650 06:08:53,280 --> 06:08:58,080 but goodbye from here let me go ahead 9651 06:08:55,680 --> 06:09:00,400 and call goodbye instead of hello and 9652 06:08:58,080 --> 06:09:02,160 this time when I run python of sayy I'm 9653 06:09:00,400 --> 06:09:04,160 not going to type my own name allow me 9654 06:09:02,160 --> 06:09:06,440 if I may to type in the whole world so 9655 06:09:04,160 --> 06:09:08,760 that our final sentiment today is 9656 06:09:06,440 --> 06:09:13,320 goodbye World indeed that's it for this 9657 06:09:08,760 --> 06:09:13,320 week we will see you next time 9658 06:09:17,870 --> 06:09:26,720 [Music] 9659 06:09:28,740 --> 06:09:35,609 [Music] 9660 06:09:37,878 --> 06:09:42,520 all right this is cs50's Introduction to 9661 06:09:40,680 --> 06:09:45,440 programming with python my name is David 9662 06:09:42,520 --> 06:09:47,040 men and this is our week on unit tests 9663 06:09:45,440 --> 06:09:48,638 up until now we've been writing a lot of 9664 06:09:47,040 --> 06:09:50,718 code and you might have been testing 9665 06:09:48,638 --> 06:09:52,320 your code by running your program and 9666 06:09:50,718 --> 06:09:53,718 passing in some sample inputs and 9667 06:09:52,320 --> 06:09:55,600 running it again and passing in some 9668 06:09:53,718 --> 06:09:57,638 sample inputs or you might have been 9669 06:09:55,600 --> 06:09:59,360 waiting for us to test your code instead 9670 06:09:57,638 --> 06:10:01,040 but it's actually much better practice 9671 06:09:59,360 --> 06:10:04,160 to get into the Habit sooner rather than 9672 06:10:01,040 --> 06:10:06,240 later of testing your own code using 9673 06:10:04,160 --> 06:10:07,798 Code of your own in fact whether you're 9674 06:10:06,240 --> 06:10:09,718 writing a personal project or working in 9675 06:10:07,798 --> 06:10:11,000 industry it's very common nowadays to 9676 06:10:09,718 --> 06:10:12,878 not only write code to solve the 9677 06:10:11,000 --> 06:10:15,400 problems that you want to solve but also 9678 06:10:12,878 --> 06:10:17,120 to write a little extra code to test the 9679 06:10:15,400 --> 06:10:18,760 code that you wrote and that's what 9680 06:10:17,120 --> 06:10:20,920 we're going to focus on today writing 9681 06:10:18,760 --> 06:10:22,680 our own test so as to be all the more 9682 06:10:20,920 --> 06:10:24,558 confident all the more certain that the 9683 06:10:22,680 --> 06:10:26,840 problems we have been trying to solve 9684 06:10:24,558 --> 06:10:29,840 are in fact solved correctly so let's 9685 06:10:26,840 --> 06:10:32,280 rewind a few weeks now to a program we 9686 06:10:29,840 --> 06:10:34,878 wrote a while back namely to to 9687 06:10:32,280 --> 06:10:37,160 calculate uh numbers and specifically we 9688 06:10:34,878 --> 06:10:39,840 left off with this calculator on trying 9689 06:10:37,160 --> 06:10:42,840 to compute the power of a number like X 9690 06:10:39,840 --> 06:10:44,638 squar or uh where X might be two or 9691 06:10:42,840 --> 06:10:46,840 three or some other number as well well 9692 06:10:44,638 --> 06:10:48,798 let me go ahead and resurrect that file 9693 06:10:46,840 --> 06:10:52,320 by going into my terminal window here 9694 06:10:48,798 --> 06:10:54,478 and running again code of calculator. Pi 9695 06:10:52,320 --> 06:10:56,558 and let me go ahead and pick up where we 9696 06:10:54,478 --> 06:10:58,760 left off way back when by defining a 9697 06:10:56,558 --> 06:11:00,200 main function here and then in my main 9698 06:10:58,760 --> 06:11:03,440 function I did something like this I 9699 06:11:00,200 --> 06:11:06,878 said x equals int of input and I asked 9700 06:11:03,440 --> 06:11:08,638 the user what's X question mark and then 9701 06:11:06,878 --> 06:11:12,320 I immediately went ahead and printed out 9702 06:11:08,638 --> 06:11:14,360 something like x^2 is and then I passed 9703 06:11:12,320 --> 06:11:15,840 in as a second argument to print the 9704 06:11:14,360 --> 06:11:18,760 result of calling a function called 9705 06:11:15,840 --> 06:11:21,000 Square passing in that value X now of 9706 06:11:18,760 --> 06:11:22,958 course I haven't yet implemented the 9707 06:11:21,000 --> 06:11:24,638 square function so let's define that as 9708 06:11:22,958 --> 06:11:27,080 well let me go down a couple of lines 9709 06:11:24,638 --> 06:11:29,200 and Define square and it takes an 9710 06:11:27,080 --> 06:11:31,160 argument recall a parameter that at the 9711 06:11:29,200 --> 06:11:32,400 time I called n for number so I'll do 9712 06:11:31,160 --> 06:11:35,280 that again though I could technically 9713 06:11:32,400 --> 06:11:38,840 choose any name for this variable and I 9714 06:11:35,280 --> 06:11:41,000 call did this I returned n * n and there 9715 06:11:38,840 --> 06:11:42,958 were multiple ways to do this the 9716 06:11:41,000 --> 06:11:45,120 squaring a number is multiplying it by 9717 06:11:42,958 --> 06:11:46,280 itself so I could also use other syntax 9718 06:11:45,120 --> 06:11:48,558 here but this is what we ultimately 9719 06:11:46,280 --> 06:11:50,638 settled on and then recall that I 9720 06:11:48,558 --> 06:11:52,558 ultimately called Main in order to kick 9721 06:11:50,638 --> 06:11:54,798 off the process of running this program 9722 06:11:52,558 --> 06:11:57,200 so just as a test manually let me go 9723 06:11:54,798 --> 06:11:59,638 ahead and run python of calculator. piy 9724 06:11:57,200 --> 06:12:02,718 and hit enter what's X let's start with 9725 06:11:59,638 --> 06:12:04,200 two all right x^2 is 4 I think that's 9726 06:12:02,718 --> 06:12:07,000 correct so let's run it again just for 9727 06:12:04,200 --> 06:12:10,558 good measure of calculator. Pi let's 9728 06:12:07,000 --> 06:12:12,080 type in three for X this time x^2 is 9 9729 06:12:10,558 --> 06:12:13,520 and I think that's correct and I might 9730 06:12:12,080 --> 06:12:15,760 be feeling pretty good at this point and 9731 06:12:13,520 --> 06:12:17,440 I go off and submit my code to a course 9732 06:12:15,760 --> 06:12:19,760 or I post it on the internet for others 9733 06:12:17,440 --> 06:12:21,760 to use but I haven't really methodically 9734 06:12:19,760 --> 06:12:23,160 tested this code and it's not 9735 06:12:21,760 --> 06:12:24,440 necessarily the case that it works 9736 06:12:23,160 --> 06:12:26,558 entirely in fact I haven't really 9737 06:12:24,440 --> 06:12:28,160 considered a number of corner cases I 9738 06:12:26,558 --> 06:12:31,000 went with some pretty obvious numbers 9739 06:12:28,160 --> 06:12:32,600 like two and three but what about zero 9740 06:12:31,000 --> 06:12:34,160 what about negative numbers what about 9741 06:12:32,600 --> 06:12:35,718 any number of other infinite numbers 9742 06:12:34,160 --> 06:12:37,040 well we're not going to test infinite 9743 06:12:35,718 --> 06:12:38,878 number of inputs to this because the 9744 06:12:37,040 --> 06:12:41,200 program would never halt but we should 9745 06:12:38,878 --> 06:12:43,798 test some representative inputs 9746 06:12:41,200 --> 06:12:45,440 ultimately but before we do that let's 9747 06:12:43,798 --> 06:12:47,638 get into the habit of making sure that 9748 06:12:45,440 --> 06:12:49,840 Maine isn't always called let's adopt 9749 06:12:47,638 --> 06:12:52,440 this habit again of doing if underscore 9750 06:12:49,840 --> 06:12:55,360 uncore name underscore underscore equals 9751 06:12:52,440 --> 06:12:58,360 equals quote unquote underscore uncore 9752 06:12:55,360 --> 06:13:00,558 maincore underscore only then should we 9753 06:12:58,360 --> 06:13:03,120 execute Main and I'm doing this now 9754 06:13:00,558 --> 06:13:06,280 proactively because I want to make sure 9755 06:13:03,120 --> 06:13:08,040 that when I import my Square function 9756 06:13:06,280 --> 06:13:09,600 perhaps from another library from 9757 06:13:08,040 --> 06:13:11,520 another file treating it as though it's 9758 06:13:09,600 --> 06:13:14,400 a library I want to make sure that main 9759 06:13:11,520 --> 06:13:17,000 is not just automatically called itself 9760 06:13:14,400 --> 06:13:18,798 now what do I want to do from here now 9761 06:13:17,000 --> 06:13:21,080 that I've modified this program as 9762 06:13:18,798 --> 06:13:22,600 follows well let's go ahead and write a 9763 06:13:21,080 --> 06:13:24,958 completely different program whose sole 9764 06:13:22,600 --> 06:13:27,280 purpose in life is to now test this 9765 06:13:24,958 --> 06:13:30,400 program so I've got my actual calculator 9766 06:13:27,280 --> 06:13:32,440 in calculator. I've readed myself to 9767 06:13:30,400 --> 06:13:35,200 call Main conditionally so that I can 9768 06:13:32,440 --> 06:13:37,040 safely import one or more things from 9769 06:13:35,200 --> 06:13:38,680 this file in another file well what 9770 06:13:37,040 --> 06:13:39,920 should that other file be well by 9771 06:13:38,680 --> 06:13:42,200 convention I'm going to create a file 9772 06:13:39,920 --> 06:13:43,958 that's called test underscore and then 9773 06:13:42,200 --> 06:13:45,958 because the thing I'm testing is this 9774 06:13:43,958 --> 06:13:48,840 calculator itself let's call this file 9775 06:13:45,958 --> 06:13:50,718 test calculator. piy that's going to 9776 06:13:48,840 --> 06:13:52,440 give me a new tab in which I can write a 9777 06:13:50,718 --> 06:13:54,878 brand new program whose purpose in life 9778 06:13:52,440 --> 06:13:56,600 is now specifically to test that program 9779 06:13:54,878 --> 06:13:58,798 but really that program's specific 9780 06:13:56,600 --> 06:14:00,958 functionality built into that program is 9781 06:13:58,798 --> 06:14:03,478 the square function let's focus on 9782 06:14:00,958 --> 06:14:05,520 testing that function all right so how 9783 06:14:03,478 --> 06:14:07,520 do I access that function in this 9784 06:14:05,520 --> 06:14:09,478 program well recall that I can import a 9785 06:14:07,520 --> 06:14:11,240 function from another file as though 9786 06:14:09,478 --> 06:14:13,558 it's a library of my own a so-called 9787 06:14:11,240 --> 06:14:17,160 module so I'm going to do this from 9788 06:14:13,558 --> 06:14:19,280 calculator import Square I could go 9789 06:14:17,160 --> 06:14:22,000 ahead and just import Square itself but 9790 06:14:19,280 --> 06:14:24,160 then I would have to prefix my use of 9791 06:14:22,000 --> 06:14:25,400 square recall by saying calculator dot 9792 06:14:24,160 --> 06:14:27,638 everywhere and it's just a little 9793 06:14:25,400 --> 06:14:29,958 cleaner to just import the one function 9794 06:14:27,638 --> 06:14:32,000 and now let me go ahead and do this let 9795 06:14:29,958 --> 06:14:34,600 me go ahead and Define a function called 9796 06:14:32,000 --> 06:14:36,760 test Square this two is a convention if 9797 06:14:34,600 --> 06:14:38,920 you want to test a function called 9798 06:14:36,760 --> 06:14:41,440 Square your function for testing should 9799 06:14:38,920 --> 06:14:42,760 be called testore Square or 9800 06:14:41,440 --> 06:14:44,440 alternatively you could do Square 9801 06:14:42,760 --> 06:14:46,360 underscore test but I'll adopt this 9802 06:14:44,440 --> 06:14:48,958 convention here now what kind of tests 9803 06:14:46,360 --> 06:14:51,520 can we do well I don't dislike the test 9804 06:14:48,958 --> 06:14:54,160 I ran earlier testing xals 2 and x 9805 06:14:51,520 --> 06:14:55,718 equals 3 but every time I uh want to 9806 06:14:54,160 --> 06:14:56,920 test my program previously I would have 9807 06:14:55,718 --> 06:14:58,120 to do that manually and that's going to 9808 06:14:56,920 --> 06:15:00,000 get tedious it's not going to be easy 9809 06:14:58,120 --> 06:15:01,400 for someone else to test it and if I'm 9810 06:15:00,000 --> 06:15:03,120 actually working in the real world it 9811 06:15:01,400 --> 06:15:05,200 would be nice if I could automatically 9812 06:15:03,120 --> 06:15:07,638 have my program tested again and again 9813 06:15:05,200 --> 06:15:09,478 by having some automated process run my 9814 06:15:07,638 --> 06:15:11,840 own code so let's do that and take the 9815 06:15:09,478 --> 06:15:13,798 human ultimately out of the equation so 9816 06:15:11,840 --> 06:15:16,080 how might I go about testing the square 9817 06:15:13,798 --> 06:15:18,240 function that I've now imported per line 9818 06:15:16,080 --> 06:15:21,400 one well in my test Square function why 9819 06:15:18,240 --> 06:15:24,200 don't I do this if uh the result of 9820 06:15:21,400 --> 06:15:25,920 calling square of two does not equal 9821 06:15:24,200 --> 06:15:27,760 four why don't we go ahead and print an 9822 06:15:25,920 --> 06:15:30,600 error message because I know that in the 9823 06:15:27,760 --> 06:15:33,478 real world 2 squared should equal four 9824 06:15:30,600 --> 06:15:35,240 so if square of two does not equal four 9825 06:15:33,478 --> 06:15:37,160 there's a bug in my program there's a 9826 06:15:35,240 --> 06:15:38,440 bug in my function I've made a mistake 9827 06:15:37,160 --> 06:15:41,718 so let me go ahead and print something 9828 06:15:38,440 --> 06:15:43,600 like that so I or someone else knows 2^2 9829 06:15:41,718 --> 06:15:45,638 was not four for instance so I could 9830 06:15:43,600 --> 06:15:47,200 print out anything here what should I 9831 06:15:45,638 --> 06:15:49,400 maybe next test well let's do more than 9832 06:15:47,200 --> 06:15:53,280 one test let's say if the square of 9833 06:15:49,400 --> 06:15:56,120 three does not equal 3^2 9 then let's go 9834 06:15:53,280 --> 06:15:58,638 ahead and print out that 3^ SAR was not 9835 06:15:56,120 --> 06:16:00,878 9 so I haven't done any more testing 9836 06:15:58,638 --> 06:16:05,440 than I did earlier but I've baked those 9837 06:16:00,878 --> 06:16:07,878 two tests xal 2 and xal 3 into my own 9838 06:16:05,440 --> 06:16:09,958 code here so I can now run those tests 9839 06:16:07,878 --> 06:16:12,160 automatically if you will now it's not 9840 06:16:09,958 --> 06:16:14,558 enough to just Define a function called 9841 06:16:12,160 --> 06:16:16,160 test Square I actually if I want to run 9842 06:16:14,558 --> 06:16:17,600 this function need to call it somehow 9843 06:16:16,160 --> 06:16:19,798 and our convention for doing that is the 9844 06:16:17,600 --> 06:16:22,120 same as always in this function here in 9845 06:16:19,798 --> 06:16:23,878 this file two let me Define Main and 9846 06:16:22,120 --> 06:16:27,080 Main's sole purpose in life is going to 9847 06:16:23,878 --> 06:16:29,200 be to test square and now at the bottom 9848 06:16:27,080 --> 06:16:31,320 of this file as before let me go ahead 9849 06:16:29,200 --> 06:16:33,400 and adopt my Convention of if underscore 9850 06:16:31,320 --> 06:16:35,718 uncore name underscore uncore equals 9851 06:16:33,400 --> 06:16:39,200 equals quote unquote underscore uncore 9852 06:16:35,718 --> 06:16:40,520 maincore uncore then go ahead and call 9853 06:16:39,200 --> 06:16:42,160 Main so a lot of this is just 9854 06:16:40,520 --> 06:16:43,920 boilerplate like we've seen this before 9855 06:16:42,160 --> 06:16:45,920 defining a main function and calling a 9856 06:16:43,920 --> 06:16:47,280 function to kick off some process now 9857 06:16:45,920 --> 06:16:48,798 adding the conditional at the bottom of 9858 06:16:47,280 --> 06:16:50,718 the file to make sure I'm only 9859 06:16:48,798 --> 06:16:52,718 conditionally calling main just in case 9860 06:16:50,718 --> 06:16:55,040 I import anything from this file 9861 06:16:52,718 --> 06:16:57,160 elsewhere so let's see let's go ahead 9862 06:16:55,040 --> 06:17:00,478 and test my code now let me go ahead and 9863 06:16:57,160 --> 06:17:03,760 run test calculator with python and hit 9864 06:17:00,478 --> 06:17:07,200 enter and nothing outputs nothing 9865 06:17:03,760 --> 06:17:09,160 outputs but I think it's okay I think no 9866 06:17:07,200 --> 06:17:11,000 output is good because look at my test 9867 06:17:09,160 --> 06:17:14,280 Square function I'm not printing 9868 06:17:11,000 --> 06:17:15,760 anything if all seems well so let's 9869 06:17:14,280 --> 06:17:17,558 let's demonstrate as much by going back 9870 06:17:15,760 --> 06:17:19,680 to my calculator and let me break it let 9871 06:17:17,558 --> 06:17:21,000 me introduce a bug maybe I didn't even 9872 06:17:19,680 --> 06:17:22,558 get it right the first time maybe my 9873 06:17:21,000 --> 06:17:24,958 code originally looked like this I 9874 06:17:22,558 --> 06:17:27,120 wasn't thinking I forgot my squares and 9875 06:17:24,958 --> 06:17:30,478 so I thought that the square of a number 9876 06:17:27,120 --> 06:17:31,920 is n plus n instead of n * n so a 9877 06:17:30,478 --> 06:17:34,000 reasonable mistake to make perhaps 9878 06:17:31,920 --> 06:17:35,160 arithmetically let me now go back to my 9879 06:17:34,000 --> 06:17:37,080 test calculator which which I'm not 9880 06:17:35,160 --> 06:17:39,878 going to change but I am going to rerun 9881 06:17:37,080 --> 06:17:42,520 it python of test calculator. Pi going 9882 06:17:39,878 --> 06:17:45,160 to cross my fingers here but for not I'm 9883 06:17:42,520 --> 06:17:49,520 going to see immediately that 3^ SAR was 9884 06:17:45,160 --> 06:17:51,360 not n now what is it well let's see when 9885 06:17:49,520 --> 06:17:53,000 your tests fail how can we put our 9886 06:17:51,360 --> 06:17:54,400 finger on what's wrong well it's a 9887 06:17:53,000 --> 06:17:57,040 little interesting that I completely 9888 06:17:54,400 --> 06:17:59,558 broke my Square function and yet only 9889 06:17:57,040 --> 06:18:03,080 one of these tests is failing it looks 9890 06:17:59,558 --> 06:18:04,840 like this test lines 9 and 10 is fine 9891 06:18:03,080 --> 06:18:08,000 because I'm not seeing that output but 9892 06:18:04,840 --> 06:18:10,320 of course these two lines this test is 9893 06:18:08,000 --> 06:18:13,760 failing because 3^ s is not n when I'm 9894 06:18:10,320 --> 06:18:17,400 using plus so just to be clear here why 9895 06:18:13,760 --> 06:18:19,400 is my function only partially broken 9896 06:18:17,400 --> 06:18:22,040 just to be clear why am I seeing only 9897 06:18:19,400 --> 06:18:24,000 one error instead of two even though the 9898 06:18:22,040 --> 06:18:27,200 square function is now mathematically 9899 06:18:24,000 --> 06:18:28,400 broken because 2 plus two is four no 9900 06:18:27,200 --> 06:18:30,638 yeah I mean it's as simple as that I 9901 06:18:28,400 --> 06:18:32,638 just got lucky that 2+ 2 is the same 9902 06:18:30,638 --> 06:18:34,080 thing as 2 * 2 so this is one of those 9903 06:18:32,638 --> 06:18:35,360 Corner cases and this is why it's good 9904 06:18:34,080 --> 06:18:37,280 to be in the habit of not just testing 9905 06:18:35,360 --> 06:18:38,920 one thing but test several and make sure 9906 06:18:37,280 --> 06:18:41,320 you're covering your bases so to speak 9907 06:18:38,920 --> 06:18:43,120 so I got lucky here and that explains 9908 06:18:41,320 --> 06:18:45,080 why I'm seeing only one error even 9909 06:18:43,120 --> 06:18:46,798 though the function itself is flawed but 9910 06:18:45,080 --> 06:18:49,080 let me propose that there's another way 9911 06:18:46,798 --> 06:18:51,320 we could do this because honestly if I 9912 06:18:49,080 --> 06:18:53,920 extrapolate from this simple example 9913 06:18:51,320 --> 06:18:57,558 running not just two tests but three or 9914 06:18:53,920 --> 06:18:59,638 four or 10 or 20 tests you can imagine 9915 06:18:57,558 --> 06:19:01,280 that my God the code is going to get so 9916 06:18:59,638 --> 06:19:03,000 much more complicated than the function 9917 06:19:01,280 --> 06:19:05,400 itself I mean already look in 9918 06:19:03,000 --> 06:19:07,718 calculator. the function in question is 9919 06:19:05,400 --> 06:19:10,320 two lines long and yet in test 9920 06:19:07,718 --> 06:19:12,360 calculator the fun code in question is 9921 06:19:10,320 --> 06:19:14,200 five lines long like I've written more 9922 06:19:12,360 --> 06:19:16,958 code to test my code than I actually 9923 06:19:14,200 --> 06:19:19,600 wrote original code so the fewer lines 9924 06:19:16,958 --> 06:19:21,478 of code we can write when testing code I 9925 06:19:19,600 --> 06:19:22,958 think the more likely you and I are to 9926 06:19:21,478 --> 06:19:24,760 do it because it's going to be literally 9927 06:19:22,958 --> 06:19:26,600 a little less work and just fewer 9928 06:19:24,760 --> 06:19:28,878 opportunities for mistakes so what's 9929 06:19:26,600 --> 06:19:31,440 another approach I can take here well it 9930 06:19:28,878 --> 06:19:33,120 turns out in Python there is another 9931 06:19:31,440 --> 06:19:35,200 keyword that we haven't yet used which 9932 06:19:33,120 --> 06:19:37,520 is this here assert 9933 06:19:35,200 --> 06:19:39,280 assert is a keyword in Python and some 9934 06:19:37,520 --> 06:19:41,200 other languages as well that allow you 9935 06:19:39,280 --> 06:19:43,240 to do exactly that as in English to 9936 06:19:41,200 --> 06:19:45,558 assert that something is true to sort of 9937 06:19:43,240 --> 06:19:48,200 boldly claim that something is true and 9938 06:19:45,558 --> 06:19:49,600 if it is nothing's going to happen no 9939 06:19:48,200 --> 06:19:51,760 errors are going to appear on the screen 9940 06:19:49,600 --> 06:19:54,000 but if you assert something in Python 9941 06:19:51,760 --> 06:19:56,360 and it is not true that is the thing 9942 06:19:54,000 --> 06:19:58,280 you're insert asserting a Boolean 9943 06:19:56,360 --> 06:20:00,478 expression is false you're actually 9944 06:19:58,280 --> 06:20:02,958 going to see some kind of error on the 9945 06:20:00,478 --> 06:20:05,040 screen so let's go ahead and try this 9946 06:20:02,958 --> 06:20:06,840 new keyword as follows let me go back to 9947 06:20:05,040 --> 06:20:09,718 my code here and just to make it a 9948 06:20:06,840 --> 06:20:12,080 little simpler let me propose that I I 9949 06:20:09,718 --> 06:20:15,920 use this new keyword as follows let me 9950 06:20:12,080 --> 06:20:18,440 simply assert that the square of two 9951 06:20:15,920 --> 06:20:20,520 should equal four so I've changed my 9952 06:20:18,440 --> 06:20:23,200 logic instead of checking for not equals 9953 06:20:20,520 --> 06:20:25,478 I'm now asserting very loudly that it 9954 06:20:23,200 --> 06:20:27,280 should equal four and then on one 9955 06:20:25,478 --> 06:20:30,000 additional line let me do the other test 9956 06:20:27,280 --> 06:20:34,040 assert that the square of 3 equals 9957 06:20:30,000 --> 06:20:36,160 equals 9 and that's it no if no indented 9958 06:20:34,040 --> 06:20:38,320 print I'm just going to assert more 9959 06:20:36,160 --> 06:20:41,040 simply these two things that I want to 9960 06:20:38,320 --> 06:20:43,600 be true well let me go ahead now with 9961 06:20:41,040 --> 06:20:46,160 calculator. pi still broken I'm still 9962 06:20:43,600 --> 06:20:48,320 using plus accidentally instead of 9963 06:20:46,160 --> 06:20:51,400 multiplication let me go ahead now and 9964 06:20:48,320 --> 06:20:53,200 run python of test calculator. Pi 9965 06:20:51,400 --> 06:20:55,200 crossing my fingers as always but it's 9966 06:20:53,200 --> 06:20:57,040 not going to go well this time a whole 9967 06:20:55,200 --> 06:20:59,240 lot of Errors seem to appear on the 9968 06:20:57,040 --> 06:21:01,600 screen and if I scroll up here for this 9969 06:20:59,240 --> 06:21:04,680 traceback we'll see that the thing that 9970 06:21:01,600 --> 06:21:06,760 failed was this line here assert Square 9971 06:21:04,680 --> 06:21:07,958 of three equals equals 9 now 9972 06:21:06,760 --> 06:21:09,878 unfortunately when you're using the 9973 06:21:07,958 --> 06:21:12,240 assert keyword it's not terribly 9974 06:21:09,878 --> 06:21:13,798 userfriendly it shows you the files and 9975 06:21:12,240 --> 06:21:15,400 the line numbers involved but it does 9976 06:21:13,798 --> 06:21:17,520 show you the specific line of code that 9977 06:21:15,400 --> 06:21:19,718 failed the assertion that failed so to 9978 06:21:17,520 --> 06:21:22,040 speak it's now kind of up to you and me 9979 06:21:19,718 --> 06:21:24,040 to infer from this well wait a minute 9980 06:21:22,040 --> 06:21:26,120 why is the square of three not equal to 9981 06:21:24,040 --> 06:21:27,558 9 so it's not super user friendly but 9982 06:21:26,120 --> 06:21:28,920 honestly it was like half as much code 9983 06:21:27,558 --> 06:21:30,638 for me to write it's just two lines 9984 06:21:28,920 --> 06:21:32,840 instead of those previous four but 9985 06:21:30,638 --> 06:21:35,080 notice this little Remnant down here 9986 06:21:32,840 --> 06:21:38,080 this was an assertion error and we have 9987 06:21:35,080 --> 06:21:40,200 seen errors before we've seen errors 9988 06:21:38,080 --> 06:21:42,638 before when we've made other mistakes in 9989 06:21:40,200 --> 06:21:46,478 our code and in the past what was our 9990 06:21:42,638 --> 06:21:49,840 solution for catching those 9991 06:21:46,478 --> 06:21:51,520 errors how do we catch errors that seem 9992 06:21:49,840 --> 06:21:54,760 to resemble this even though we've not 9993 06:21:51,520 --> 06:21:56,600 seen this one before um try and accept 9994 06:21:54,760 --> 06:21:58,958 yeah in Python we can use the try and 9995 06:21:56,600 --> 06:22:01,120 accept keywords to try to do something 9996 06:21:58,958 --> 06:22:03,718 optimistically except if something goes 9997 06:22:01,120 --> 06:22:05,600 wrong do something else instead so this 9998 06:22:03,718 --> 06:22:07,558 is a step forward and that I can at 9999 06:22:05,600 --> 06:22:08,958 least catch this error but it's going to 10000 06:22:07,558 --> 06:22:10,520 be perhaps a step backward and that I'm 10001 06:22:08,958 --> 06:22:13,240 going to end up writing I'll admit in 10002 06:22:10,520 --> 06:22:14,798 advance a little more code uh instead so 10003 06:22:13,240 --> 06:22:17,200 let me go ahead and try this let me go 10004 06:22:14,798 --> 06:22:19,718 back into my code here and instead of 10005 06:22:17,200 --> 06:22:23,040 just asserting blindly let me go ahead 10006 06:22:19,718 --> 06:22:25,520 is to proposed and try to do this first 10007 06:22:23,040 --> 06:22:28,878 assertion except if there is an 10008 06:22:25,520 --> 06:22:30,558 assertion error like we saw a moment ago 10009 06:22:28,878 --> 06:22:32,680 then go ahead and print out something 10010 06:22:30,558 --> 06:22:34,958 more userfriendly that explains what 10011 06:22:32,680 --> 06:22:38,000 actually failed 2 squar 10012 06:22:34,958 --> 06:22:40,600 is uh was not four and let me go ahead 10013 06:22:38,000 --> 06:22:43,600 similarly and try to assert that the 10014 06:22:40,600 --> 06:22:46,280 square of 3 equals 9 except if there's 10015 06:22:43,600 --> 06:22:47,520 an assertion error there in which case 10016 06:22:46,280 --> 06:22:51,478 I'm going to print out more user 10017 06:22:47,520 --> 06:22:53,120 friendly 3^ squar was not n so I've 10018 06:22:51,478 --> 06:22:54,840 taken a step forward but also a step 10019 06:22:53,120 --> 06:22:57,040 back because now I have more code but I 10020 06:22:54,840 --> 06:22:58,958 have at least introduced assertions and 10021 06:22:57,040 --> 06:23:00,120 exceptions in a manner consistent with 10022 06:22:58,958 --> 06:23:02,600 how we've seen it in the past when 10023 06:23:00,120 --> 06:23:04,200 something goes wrong you actually see an 10024 06:23:02,600 --> 06:23:06,080 exception raised well let me go ahead 10025 06:23:04,200 --> 06:23:08,920 and run this version of the program now 10026 06:23:06,080 --> 06:23:11,878 instead python of test calculator. 10027 06:23:08,920 --> 06:23:13,840 crossing my fingers all right it still 10028 06:23:11,878 --> 06:23:15,320 failed because I'm seeing output but 10029 06:23:13,840 --> 06:23:17,920 we're back to at least userfriendly 10030 06:23:15,320 --> 06:23:21,320 output so that's at least progress in 10031 06:23:17,920 --> 06:23:22,840 some way here but it's again more code 10032 06:23:21,320 --> 06:23:24,760 than might have been ideal and in fact 10033 06:23:22,840 --> 06:23:26,478 if we continue this further what if we 10034 06:23:24,760 --> 06:23:29,558 actually want to add additional test 10035 06:23:26,478 --> 06:23:31,600 cases here as well well it seems like we 10036 06:23:29,558 --> 06:23:33,440 might end up writing way more code than 10037 06:23:31,600 --> 06:23:35,798 would be ideal for instance I'm testing 10038 06:23:33,440 --> 06:23:37,638 two and three now I should probably test 10039 06:23:35,798 --> 06:23:39,798 some negative numbers as well so why 10040 06:23:37,638 --> 06:23:42,040 don't I go ahead and add in for instance 10041 06:23:39,798 --> 06:23:44,798 let me go ahead and copy and paste this 10042 06:23:42,040 --> 06:23:47,558 let me try to assert that the square of 10043 06:23:44,798 --> 06:23:49,558 -2 equals equals 4 which should be the 10044 06:23:47,558 --> 06:23:52,160 case mathematically and if not let me go 10045 06:23:49,558 --> 06:23:53,878 ahead and change this to say -22 was not 10046 06:23:52,160 --> 06:23:56,000 four and you know what let me go ahead 10047 06:23:53,878 --> 06:23:57,638 and copy paste this again test another 10048 06:23:56,000 --> 06:23:59,478 negative number just for good measure 10049 06:23:57,638 --> 06:24:02,840 let's test the square ofg -3 which 10050 06:23:59,478 --> 06:24:07,080 should equal 9 but if it doesn't let's 10051 06:24:02,840 --> 06:24:08,558 go ahead and say that -32 was not 9 and 10052 06:24:07,080 --> 06:24:10,718 just to think aloud here what might be 10053 06:24:08,558 --> 06:24:12,680 another good value to test I've tried 10054 06:24:10,718 --> 06:24:14,280 two I've tried three I've tried ne-2 10055 06:24:12,680 --> 06:24:15,920 I've tried negative3 I can't try in 10056 06:24:14,280 --> 06:24:17,080 infinite numbers but there's at least 10057 06:24:15,920 --> 06:24:18,920 something that's a little different in 10058 06:24:17,080 --> 06:24:21,040 between those values let's try zero zero 10059 06:24:18,920 --> 06:24:23,400 is an interesting case too just in case 10060 06:24:21,040 --> 06:24:25,120 something might be wrong and Y zero I'm 10061 06:24:23,400 --> 06:24:27,520 just going with instincts here right 10062 06:24:25,120 --> 06:24:28,920 odds are positive numbers are generally 10063 06:24:27,520 --> 06:24:30,400 going to behave the same negative 10064 06:24:28,920 --> 06:24:32,440 numbers might generally behave the same 10065 06:24:30,400 --> 06:24:34,878 zero might be a little anomalous there's 10066 06:24:32,440 --> 06:24:36,440 no uh science to it necessarily 10067 06:24:34,878 --> 06:24:37,840 but rather considering for yourself 10068 06:24:36,440 --> 06:24:40,000 based on your own experience like what 10069 06:24:37,840 --> 06:24:41,638 are the potential Corner cases based on 10070 06:24:40,000 --> 06:24:43,040 the function you're trying to test I'm 10071 06:24:41,638 --> 06:24:45,120 trying to test something mathematical so 10072 06:24:43,040 --> 06:24:46,718 I want to test representative values so 10073 06:24:45,120 --> 06:24:49,040 let me go ahead and paste in one more 10074 06:24:46,718 --> 06:24:51,958 try accept block let's assert that the 10075 06:24:49,040 --> 06:24:54,320 square of zero should equal zero and if 10076 06:24:51,958 --> 06:24:57,878 not I'll say something explanatory like 10077 06:24:54,320 --> 06:25:00,958 0^ squar was not zero now if I go ahead 10078 06:24:57,878 --> 06:25:03,718 and run this python of test calculator. 10079 06:25:00,958 --> 06:25:05,360 piy and hit enter now I see multiple 10080 06:25:03,718 --> 06:25:08,320 errors and and this is interesting it's 10081 06:25:05,360 --> 06:25:09,878 a bit of a clue because notice that some 10082 06:25:08,320 --> 06:25:13,680 but not all of these assertions are 10083 06:25:09,878 --> 06:25:16,638 failing the one for 2^ SAR is apparently 10084 06:25:13,680 --> 06:25:19,638 okay as we noted earlier recall that 2^ 10085 06:25:16,638 --> 06:25:21,200 SAR happens to be 2 plus 2 so that bug 10086 06:25:19,638 --> 06:25:22,718 doesn't really throw off our test but 10087 06:25:21,200 --> 06:25:24,200 it's a good thing we tested for three 10088 06:25:22,718 --> 06:25:25,920 it's a good thing we tested for neg -2 10089 06:25:24,200 --> 06:25:28,000 and neg3 because all of those tests 10090 06:25:25,920 --> 06:25:30,878 caught this error the zero test did not 10091 06:25:28,000 --> 06:25:34,440 notice because 0 squared is of course 0 10092 06:25:30,878 --> 06:25:36,280 but 0 + 0 is 0 so we're getting lucky or 10093 06:25:34,440 --> 06:25:37,958 unlucky there depending on how you you 10094 06:25:36,280 --> 06:25:40,840 view the glass is half full or half 10095 06:25:37,958 --> 06:25:43,200 empty here we at least by way of having 10096 06:25:40,840 --> 06:25:45,958 multiple tests caught this mistake 10097 06:25:43,200 --> 06:25:49,080 somehow so it would be nice though if we 10098 06:25:45,958 --> 06:25:50,718 weren't writing so much darn code here 10099 06:25:49,080 --> 06:25:53,798 right because notice what I've done I 10100 06:25:50,718 --> 06:25:56,000 have try except try except I have all of 10101 06:25:53,798 --> 06:25:57,680 these assertions I have a main function 10102 06:25:56,000 --> 06:25:59,680 I have this if conditional at the bottom 10103 06:25:57,680 --> 06:26:03,000 of my file I mean honestly who's going 10104 06:25:59,680 --> 06:26:05,280 to want to write 31 lines of code now 10105 06:26:03,000 --> 06:26:06,920 just to test a two line function right 10106 06:26:05,280 --> 06:26:09,320 no one's going to write test code like 10107 06:26:06,920 --> 06:26:12,320 this if we're all writing so much more 10108 06:26:09,320 --> 06:26:14,160 code to do the actual testing so people 10109 06:26:12,320 --> 06:26:15,600 have solved this problem if you are in 10110 06:26:14,160 --> 06:26:17,000 the habit of testing your code a lot or 10111 06:26:15,600 --> 06:26:18,240 wanting to if I'm in the habit of 10112 06:26:17,000 --> 06:26:19,520 wanting to test my code a lot if 10113 06:26:18,240 --> 06:26:21,478 everyone else in the real world is in 10114 06:26:19,520 --> 06:26:23,280 this habit of wanting to test their code 10115 06:26:21,478 --> 06:26:26,120 why don't we create tools that make it a 10116 06:26:23,280 --> 06:26:28,360 little easier to do so and in fact there 10117 06:26:26,120 --> 06:26:30,440 is a mechanism for doing this whereby we 10118 06:26:28,360 --> 06:26:33,798 can use a tool that's popularly called 10119 06:26:30,440 --> 06:26:35,558 pest so py test is a third-party program 10120 06:26:33,798 --> 06:26:38,120 that you can downloaded install that 10121 06:26:35,558 --> 06:26:40,160 will automate the testing of your code 10122 06:26:38,120 --> 06:26:42,240 so long as you write the tests but 10123 06:26:40,160 --> 06:26:44,280 what's nice about this library and 10124 06:26:42,240 --> 06:26:45,680 others like it is that it adopts some 10125 06:26:44,280 --> 06:26:48,000 conventions so that you don't have to 10126 06:26:45,680 --> 06:26:49,958 write as many lines of code yourself 10127 06:26:48,000 --> 06:26:52,040 manually they do some of that 10128 06:26:49,958 --> 06:26:53,600 automatically for you now this is a 10129 06:26:52,040 --> 06:26:55,920 thirdparty library there's other 10130 06:26:53,600 --> 06:26:57,920 libraries for unit tests uh so to speak 10131 06:26:55,920 --> 06:26:59,798 that is testing units of your code uh 10132 06:26:57,920 --> 06:27:01,760 some of them come with python itself 10133 06:26:59,798 --> 06:27:03,280 we're proposing that we look at py test 10134 06:27:01,760 --> 06:27:05,120 today because it's actually a little 10135 06:27:03,280 --> 06:27:06,958 simpler than the unit testing Frameworks 10136 06:27:05,120 --> 06:27:09,000 that come with python itself and what do 10137 06:27:06,958 --> 06:27:11,440 we mean by unit testing unit testing is 10138 06:27:09,000 --> 06:27:13,798 just a formal way of describing testing 10139 06:27:11,440 --> 06:27:15,320 individual units of your program what 10140 06:27:13,798 --> 06:27:17,520 are those individual units they're 10141 06:27:15,320 --> 06:27:19,840 typically functions so unit tests are 10142 06:27:17,520 --> 06:27:22,240 typically tests for functions that you 10143 06:27:19,840 --> 06:27:24,680 have written now what does this mean in 10144 06:27:22,240 --> 06:27:27,600 practice here well let me go back to my 10145 06:27:24,680 --> 06:27:29,760 VSS code here and let me propose that we 10146 06:27:27,600 --> 06:27:31,600 simplify my test calculator 10147 06:27:29,760 --> 06:27:34,958 significantly I'm going to go ahead and 10148 06:27:31,600 --> 06:27:37,080 delete all of these tests which were 10149 06:27:34,958 --> 06:27:39,040 um which we're accumulating to like 31 10150 06:27:37,080 --> 06:27:41,360 lines of code and let's see if we can 10151 06:27:39,040 --> 06:27:44,280 distill the tests to their Essence using 10152 06:27:41,360 --> 06:27:46,440 p test from my same calculator program 10153 06:27:44,280 --> 06:27:47,798 let me still import Square so I do still 10154 06:27:46,440 --> 06:27:49,840 need that line of code so that I can 10155 06:27:47,798 --> 06:27:51,360 test that specific function now I'm 10156 06:27:49,840 --> 06:27:53,240 going to go ahead and Define a function 10157 06:27:51,360 --> 06:27:54,798 just like I did before as follows I'm 10158 06:27:53,240 --> 06:27:56,840 going to define a function called test 10159 06:27:54,798 --> 06:27:58,718 Square Again by convention test 10160 06:27:56,840 --> 06:28:00,478 underscore and the name of the function 10161 06:27:58,718 --> 06:28:02,360 you want to test though it doesn't have 10162 06:28:00,478 --> 06:28:03,760 to be that way and now I'm going to go 10163 06:28:02,360 --> 06:28:05,680 ahead and make a few assertions I'm 10164 06:28:03,760 --> 06:28:07,478 going to assert that the square of two 10165 06:28:05,680 --> 06:28:10,718 should equal four I'm going to assert 10166 06:28:07,478 --> 06:28:13,280 that the square of three should equal 9 10167 06:28:10,718 --> 06:28:16,000 I'm going to assert that the square of 10168 06:28:13,280 --> 06:28:18,920 -2 should equal 4 and I'm going to 10169 06:28:16,000 --> 06:28:21,160 insert that the square of -3 should 10170 06:28:18,920 --> 06:28:23,798 equal 9 and lastly for now I'm going to 10171 06:28:21,160 --> 06:28:26,040 assert that the square of 0 should equal 10172 06:28:23,798 --> 06:28:28,638 zero so I'm still using the assert 10173 06:28:26,040 --> 06:28:30,160 keyword as I introduced earlier and even 10174 06:28:28,638 --> 06:28:31,680 though it was a little tedious to type 10175 06:28:30,160 --> 06:28:33,760 those I mean it's only eight lines of 10176 06:28:31,680 --> 06:28:36,280 code now and they're so easy to type 10177 06:28:33,760 --> 06:28:38,840 it's try and accept and all of this 10178 06:28:36,280 --> 06:28:42,718 wouldn't it be nice if something else 10179 06:28:38,840 --> 06:28:45,240 someone else handled the try the accept 10180 06:28:42,718 --> 06:28:47,120 the printing all of the standardization 10181 06:28:45,240 --> 06:28:49,280 of actually running these tests and 10182 06:28:47,120 --> 06:28:51,798 that's where indeed P test comes into 10183 06:28:49,280 --> 06:28:53,718 play per the documentation for py test 10184 06:28:51,798 --> 06:28:55,600 which can itself be installed with Pip 10185 06:28:53,718 --> 06:28:57,718 install py test which we've used to 10186 06:28:55,600 --> 06:28:59,478 install other libraries in the past you 10187 06:28:57,718 --> 06:29:02,280 can look at the documentation here for 10188 06:28:59,478 --> 06:29:04,200 all of its formal usage but fortunately 10189 06:29:02,280 --> 06:29:05,760 pest is pretty userfriendly 10190 06:29:04,200 --> 06:29:07,520 testing Frameworks go and it actually 10191 06:29:05,760 --> 06:29:09,400 allows us to Dive Right In by just 10192 06:29:07,520 --> 06:29:11,320 running P test on the code that we've 10193 06:29:09,400 --> 06:29:13,520 written so if I go back to vs code here 10194 06:29:11,320 --> 06:29:15,558 and look at my test calculator. piy 10195 06:29:13,520 --> 06:29:18,280 which notice has no main function 10196 06:29:15,558 --> 06:29:20,958 anymore it has no conditional it has no 10197 06:29:18,280 --> 06:29:23,718 tries it has no accepts it has no prints 10198 06:29:20,958 --> 06:29:25,680 it just has my few assertions Pi test 10199 06:29:23,718 --> 06:29:27,360 and other libraries like it are going to 10200 06:29:25,680 --> 06:29:30,878 automate the process of running these 10201 06:29:27,360 --> 06:29:33,200 tests for me and informing me on the 10202 06:29:30,878 --> 06:29:35,638 screen whether or not any of those tests 10203 06:29:33,200 --> 06:29:36,760 failed so so let me go ahead and do this 10204 06:29:35,638 --> 06:29:38,240 I'm going to go ahead and increase the 10205 06:29:36,760 --> 06:29:39,840 size of my terminal window for a moment 10206 06:29:38,240 --> 06:29:41,840 just so we can see more on the screen 10207 06:29:39,840 --> 06:29:44,558 and I'm going to run not python as I've 10208 06:29:41,840 --> 06:29:46,718 been doing I'm going to run Pi test 10209 06:29:44,558 --> 06:29:48,878 which again is this third party tool for 10210 06:29:46,718 --> 06:29:52,120 running tests in your code I'm going to 10211 06:29:48,878 --> 06:29:54,000 run Pi test of testore calculator so 10212 06:29:52,120 --> 06:29:56,240 that same file I'm going to cross my 10213 06:29:54,000 --> 06:29:59,520 fingers as always and hit enter and 10214 06:29:56,240 --> 06:30:01,520 we'll see that ah something has failed 10215 06:29:59,520 --> 06:30:03,360 now admittedly even though I do think 10216 06:30:01,520 --> 06:30:06,040 you'll find that Pi test is relatively 10217 06:30:03,360 --> 06:30:08,040 simple to use its output at least at 10218 06:30:06,040 --> 06:30:10,080 first glance is not necessarily super 10219 06:30:08,040 --> 06:30:11,718 user friendly so what are we seeing here 10220 06:30:10,080 --> 06:30:14,360 we'll notice at the very top of my 10221 06:30:11,718 --> 06:30:17,160 window is the command that I ran after 10222 06:30:14,360 --> 06:30:19,840 my prompt right below that is a single F 10223 06:30:17,160 --> 06:30:21,798 in red which means fail so not very 10224 06:30:19,840 --> 06:30:24,280 encouraging I tried really hard here but 10225 06:30:21,798 --> 06:30:25,958 fail is my grade on this program but 10226 06:30:24,280 --> 06:30:28,200 let's see exactly what happened well if 10227 06:30:25,958 --> 06:30:30,240 I look at this excerpt here under 10228 06:30:28,200 --> 06:30:31,878 failures you'll see that test square is 10229 06:30:30,240 --> 06:30:32,920 the function that failed all right that 10230 06:30:31,878 --> 06:30:35,920 makes sense because that's the only one 10231 06:30:32,920 --> 06:30:38,398 I wrote and you'll see here somewhat uh 10232 06:30:35,920 --> 06:30:40,240 Arcane output describing what the error 10233 06:30:38,398 --> 06:30:42,360 was so what you're seeing here is the 10234 06:30:40,240 --> 06:30:43,878 first line of output equals equals 4 10235 06:30:42,360 --> 06:30:45,760 which was fine there's no red error 10236 06:30:43,878 --> 06:30:47,440 message below that so that one's okay 10237 06:30:45,760 --> 06:30:50,360 but this line of code here assert that 10238 06:30:47,440 --> 06:30:52,120 square of three equals equals 9 pi test 10239 06:30:50,360 --> 06:30:55,600 did not like that assertion because it 10240 06:30:52,120 --> 06:30:58,080 didn't end up being true in fact per the 10241 06:30:55,600 --> 06:31:00,520 red e at the start of this line You'll 10242 06:30:58,080 --> 06:31:04,240 see that I'm effectively trying to 10243 06:31:00,520 --> 06:31:06,000 assert that 6 equals equals 9 now where 10244 06:31:04,240 --> 06:31:08,280 did the six come from okay wait a minute 10245 06:31:06,000 --> 06:31:10,718 if my test involves this notice that 10246 06:31:08,280 --> 06:31:12,878 where 6 equals square of three this is 10247 06:31:10,718 --> 06:31:15,360 saying that because I've called Square 10248 06:31:12,878 --> 06:31:18,000 passing in a value of three it turns out 10249 06:31:15,360 --> 06:31:20,398 its return value is six and of course 10250 06:31:18,000 --> 06:31:23,878 mathematically six does not equal equal 10251 06:31:20,398 --> 06:31:26,398 9 so that's why this is failing now Pi 10252 06:31:23,878 --> 06:31:29,520 test is not as user friendly as telling 10253 06:31:26,398 --> 06:31:31,600 you exactly why the bug is there or how 10254 06:31:29,520 --> 06:31:33,520 to fix it this is really just a clue to 10255 06:31:31,600 --> 06:31:35,600 you what must be wrong what you're 10256 06:31:33,520 --> 06:31:37,520 seeing here is a clue that the first 10257 06:31:35,600 --> 06:31:39,718 test passed because there's no red error 10258 06:31:37,520 --> 06:31:43,160 below that line of code but this test 10259 06:31:39,718 --> 06:31:46,558 failed somehow or other your Square 10260 06:31:43,160 --> 06:31:49,000 function is returning six when passed in 10261 06:31:46,558 --> 06:31:50,558 three instead of nine so at this point 10262 06:31:49,000 --> 06:31:52,638 you sort of put your detective hat on 10263 06:31:50,558 --> 06:31:54,920 you go back to your actual code and you 10264 06:31:52,638 --> 06:31:57,478 think about in calculator to Pi how in 10265 06:31:54,920 --> 06:32:00,920 the world is line seven of my square 10266 06:31:57,478 --> 06:32:02,558 function returning six instead of nine 10267 06:32:00,920 --> 06:32:03,920 and at this point odds are the light 10268 06:32:02,558 --> 06:32:06,160 bulb would go off above your head 10269 06:32:03,920 --> 06:32:08,920 proverbially and you would see oh I'm 10270 06:32:06,160 --> 06:32:10,638 using addition instead of multiplication 10271 06:32:08,920 --> 06:32:12,000 but what P test has done for us is 10272 06:32:10,638 --> 06:32:14,718 automate the process of at least 10273 06:32:12,000 --> 06:32:16,558 pointing out that error for us and if I 10274 06:32:14,718 --> 06:32:18,360 now go in and fix this let me go ahead 10275 06:32:16,558 --> 06:32:22,200 and the light bulb has gone off I change 10276 06:32:18,360 --> 06:32:23,680 the plus to a uh to multiply now I'm 10277 06:32:22,200 --> 06:32:25,558 going to go ahead and after clearing my 10278 06:32:23,680 --> 06:32:29,000 screen I'm going to run not python but 10279 06:32:25,558 --> 06:32:31,398 Pi test of test calculator. Pi crossing 10280 06:32:29,000 --> 06:32:33,360 my fingers again and now it's green and 10281 06:32:31,398 --> 06:32:36,120 I see just a DOT which indicates that my 10282 06:32:33,360 --> 06:32:39,000 one and only only test passed I'm good 10283 06:32:36,120 --> 06:32:41,040 100% success with my test now after 10284 06:32:39,000 --> 06:32:44,120 fixing that bug all right let me pause 10285 06:32:41,040 --> 06:32:47,440 here and see if there's any questions so 10286 06:32:44,120 --> 06:32:49,200 my question is what if a user uh instead 10287 06:32:47,440 --> 06:32:51,878 of because we are taking input from the 10288 06:32:49,200 --> 06:32:54,920 user what if the user is uh somewhat 10289 06:32:51,878 --> 06:32:57,638 malicious and types in a string instead 10290 06:32:54,920 --> 06:33:00,478 of an integer or maybe he types in a 10291 06:32:57,638 --> 06:33:02,718 float or some other data type yeah so 10292 06:33:00,478 --> 06:33:04,920 what if the user like we've seen in past 10293 06:33:02,718 --> 06:33:06,478 examples types in instead of a number 10294 06:33:04,920 --> 06:33:08,718 when we're expecting an integer how do 10295 06:33:06,478 --> 06:33:10,958 we test for something like that at the 10296 06:33:08,718 --> 06:33:14,080 moment I'm admittedly not testing user 10297 06:33:10,958 --> 06:33:15,760 input if I go back to my code here 10298 06:33:14,080 --> 06:33:17,320 notice that my calculator function of 10299 06:33:15,760 --> 06:33:19,320 course has the square function that we 10300 06:33:17,320 --> 06:33:21,878 keep testing and retesting but notice 10301 06:33:19,320 --> 06:33:23,878 that all of the user input is currently 10302 06:33:21,878 --> 06:33:26,638 relegated to my main function and 10303 06:33:23,878 --> 06:33:28,478 admittedly as of now I am not testing my 10304 06:33:26,638 --> 06:33:30,360 main function so they could be one of 10305 06:33:28,478 --> 06:33:32,200 those bugs and in fact there would be 10306 06:33:30,360 --> 06:33:35,160 because if the user types in a string 10307 06:33:32,200 --> 06:33:37,840 like cat instead of an integer like two 10308 06:33:35,160 --> 06:33:40,240 or three then line two recall would 10309 06:33:37,840 --> 06:33:41,958 actually raise a value error exception 10310 06:33:40,240 --> 06:33:44,000 so we've seen that before so when it 10311 06:33:41,958 --> 06:33:46,440 comes to testing your code this is 10312 06:33:44,000 --> 06:33:48,520 actually a good reason for having 10313 06:33:46,440 --> 06:33:50,160 multiple functions in your program 10314 06:33:48,520 --> 06:33:52,080 rather than putting all of your logic in 10315 06:33:50,160 --> 06:33:54,040 just the file itself rather than putting 10316 06:33:52,080 --> 06:33:56,040 all of the logic in just main it's 10317 06:33:54,040 --> 06:33:58,240 actually really good really helpful 10318 06:33:56,040 --> 06:34:00,478 practice to break your ideas up into 10319 06:33:58,240 --> 06:34:02,360 smaller bite-sized functions that 10320 06:34:00,478 --> 06:34:05,840 themselves are testable and what do I 10321 06:34:02,360 --> 06:34:07,878 mean here Square is perfectly testable 10322 06:34:05,840 --> 06:34:11,280 why because it takes as input a 10323 06:34:07,878 --> 06:34:13,240 parameter called n and it returns as 10324 06:34:11,280 --> 06:34:15,280 output an integer which is going to be 10325 06:34:13,240 --> 06:34:17,080 the square thereof hopefully it has a 10326 06:34:15,280 --> 06:34:19,000 well-defined input and a well-defined 10327 06:34:17,080 --> 06:34:21,840 output it is therefore completely within 10328 06:34:19,000 --> 06:34:24,478 your control in your test program to 10329 06:34:21,840 --> 06:34:28,638 pass in those values now I will say if 10330 06:34:24,478 --> 06:34:30,478 you want to test whether Square behaves 10331 06:34:28,638 --> 06:34:32,638 properly when past something like a 10332 06:34:30,478 --> 06:34:34,920 string like quote unquote cat we could 10333 06:34:32,638 --> 06:34:38,080 absolutely do something like this assert 10334 06:34:34,920 --> 06:34:39,558 that the square of uh quote unquote cat 10335 06:34:38,080 --> 06:34:41,760 it's not going to equal something you 10336 06:34:39,558 --> 06:34:43,920 can actually using different syntax 10337 06:34:41,760 --> 06:34:45,840 assert that a specific exception will be 10338 06:34:43,920 --> 06:34:48,040 raised so if we were actually going to 10339 06:34:45,840 --> 06:34:49,920 go back into our Square function improve 10340 06:34:48,040 --> 06:34:52,160 it and deliberately raise an exception 10341 06:34:49,920 --> 06:34:54,200 we could test for that too but for now 10342 06:34:52,160 --> 06:34:56,718 I'm deliberately only testing the square 10343 06:34:54,200 --> 06:34:58,440 function I'm not testing for specific 10344 06:34:56,718 --> 06:35:00,440 user input but that's another problem to 10345 06:34:58,440 --> 06:35:04,798 be solved other questions 10346 06:35:00,440 --> 06:35:07,240 now on unit tests uh do use the units 10347 06:35:04,798 --> 06:35:11,200 test to test the code 10348 06:35:07,240 --> 06:35:13,120 for the C cs50 check so check 50 is 10349 06:35:11,200 --> 06:35:15,760 similar in spirit cheze 50 is a tool 10350 06:35:13,120 --> 06:35:18,478 that we cs50 wrote that is essentially 10351 06:35:15,760 --> 06:35:20,520 doing something like pie test for the 10352 06:35:18,478 --> 06:35:23,878 evaluation of students code it is 10353 06:35:20,520 --> 06:35:25,878 similar in spirit but think of cze 50 as 10354 06:35:23,878 --> 06:35:27,000 being an alternative to P test if you 10355 06:35:25,878 --> 06:35:29,958 will but it works a little bit 10356 06:35:27,000 --> 06:35:31,718 differently but same idea pie test and 10357 06:35:29,958 --> 06:35:33,520 unit testing more generally is a 10358 06:35:31,718 --> 06:35:34,920 technique that is independent of cs50 10359 06:35:33,520 --> 06:35:37,120 and is something that you can and should 10360 06:35:34,920 --> 06:35:39,040 be doing on your own code both in or 10361 06:35:37,120 --> 06:35:40,638 outside of this class how about one 10362 06:35:39,040 --> 06:35:45,520 other question here 10363 06:35:40,638 --> 06:35:47,440 on on um on our uh unit tests uh my 10364 06:35:45,520 --> 06:35:50,878 question is instead of writing four 10365 06:35:47,440 --> 06:35:53,320 times like s square of 2al 4 uh instead 10366 06:35:50,878 --> 06:35:55,520 of that can we write if is uh I is 10367 06:35:53,320 --> 06:35:58,760 equals to in square brackets the numbers 10368 06:35:55,520 --> 06:36:00,718 we want instead of writing four lines a 10369 06:35:58,760 --> 06:36:03,120 really good question absolutely right 10370 06:36:00,718 --> 06:36:05,280 now if I go back to test calculator. 10371 06:36:03,120 --> 06:36:07,120 it's in pretty manual I mean it took me 10372 06:36:05,280 --> 06:36:08,878 a while to say and to type out those 10373 06:36:07,120 --> 06:36:11,398 several lines and you could imagine 10374 06:36:08,878 --> 06:36:13,440 writing some kind of loop to just assert 10375 06:36:11,398 --> 06:36:15,120 in a loop that this equals that that 10376 06:36:13,440 --> 06:36:17,120 this equals that and so forth using a 10377 06:36:15,120 --> 06:36:18,798 list or using maybe a list or a 10378 06:36:17,120 --> 06:36:20,920 dictionary or some structure like that 10379 06:36:18,798 --> 06:36:22,398 so yes you can absolutely automate some 10380 06:36:20,920 --> 06:36:23,840 of these tests by not just doing the 10381 06:36:22,398 --> 06:36:25,600 same thing again and again you can still 10382 06:36:23,840 --> 06:36:28,160 use all of the syntax of python to do 10383 06:36:25,600 --> 06:36:30,360 loops but generally speaking your test 10384 06:36:28,160 --> 06:36:33,680 should be pretty simple and in fact let 10385 06:36:30,360 --> 06:36:35,760 me propose that we improve upon even 10386 06:36:33,680 --> 06:36:38,840 this design further because at the 10387 06:36:35,760 --> 06:36:41,040 moment what's not really ideal when I 10388 06:36:38,840 --> 06:36:43,920 run all of this uh when I run all of 10389 06:36:41,040 --> 06:36:45,680 these tests when my uh function is buggy 10390 06:36:43,920 --> 06:36:47,760 is notice the output that I got let me 10391 06:36:45,680 --> 06:36:50,478 reintroduce that same bug by changing my 10392 06:36:47,760 --> 06:36:52,280 multiplication back to addition let me 10393 06:36:50,478 --> 06:36:54,718 increase the size of my terminal window 10394 06:36:52,280 --> 06:36:56,840 again and let me run Pi test again of 10395 06:36:54,718 --> 06:36:59,320 test calculator. Pi so this is the 10396 06:36:56,840 --> 06:37:01,120 version of my code now that has the bug 10397 06:36:59,320 --> 06:37:04,360 again so I'm going to see that big 10398 06:37:01,120 --> 06:37:07,040 massive failure where this failure has 10399 06:37:04,360 --> 06:37:09,120 been displayed to me but this is not as 10400 06:37:07,040 --> 06:37:11,600 helpful as it could be right because I 10401 06:37:09,120 --> 06:37:13,958 have all of those other tests in my code 10402 06:37:11,600 --> 06:37:15,600 recall that I had what 1 2 3 four five 10403 06:37:13,958 --> 06:37:17,638 separate tests and it I'm only seeing 10404 06:37:15,600 --> 06:37:19,520 the output of the first now why is that 10405 06:37:17,638 --> 06:37:22,000 well if we go back to my code here 10406 06:37:19,520 --> 06:37:24,360 you'll see that the first assertion 10407 06:37:22,000 --> 06:37:26,398 that's failing namely this one here that 10408 06:37:24,360 --> 06:37:28,558 assert of square of three equals equals 10409 06:37:26,398 --> 06:37:31,120 9 the other tests aren't even getting 10410 06:37:28,558 --> 06:37:32,958 run and that's not a big deal in the 10411 06:37:31,120 --> 06:37:34,478 sense that my code is buggy so one or 10412 06:37:32,958 --> 06:37:36,558 more of them are probably going to fail 10413 06:37:34,478 --> 06:37:38,520 anyway but wouldn't it be nice to know 10414 06:37:36,558 --> 06:37:40,320 which of them are going to fail and in 10415 06:37:38,520 --> 06:37:42,080 fact it's ideal to run as many tests all 10416 06:37:40,320 --> 06:37:44,798 at once as possible to give you as many 10417 06:37:42,080 --> 06:37:46,600 Clues as possible to finding your bug so 10418 06:37:44,798 --> 06:37:49,320 let me propose that we improve the 10419 06:37:46,600 --> 06:37:51,840 design of my testing code now still 10420 06:37:49,320 --> 06:37:54,120 using pi test as follows instead of 10421 06:37:51,840 --> 06:37:56,558 having one big function called test 10422 06:37:54,120 --> 06:37:58,718 square that tests the entire function 10423 06:37:56,558 --> 06:38:01,000 itself with so many different inputs 10424 06:37:58,718 --> 06:38:03,200 let's break down my tests into different 10425 06:38:01,000 --> 06:38:05,558 categories and here too there's no one 10426 06:38:03,200 --> 06:38:07,200 right way to do this but my mind is 10427 06:38:05,558 --> 06:38:09,080 thinking that I should maybe test 10428 06:38:07,200 --> 06:38:10,840 positive numbers separately test 10429 06:38:09,080 --> 06:38:12,638 negative numbers separately and test 10430 06:38:10,840 --> 06:38:14,558 zero separately I could think of other 10431 06:38:12,638 --> 06:38:16,280 ways I could test even numbers I could 10432 06:38:14,558 --> 06:38:18,798 test odd numbers or maybe some other 10433 06:38:16,280 --> 06:38:20,958 pattern alt together but separating this 10434 06:38:18,798 --> 06:38:22,440 big test into multiple tests is probably 10435 06:38:20,958 --> 06:38:25,000 going to yield more clues for me when 10436 06:38:22,440 --> 06:38:26,760 something goes wrong so let me do this 10437 06:38:25,000 --> 06:38:29,600 let me go ahead and rename this function 10438 06:38:26,760 --> 06:38:31,440 to test positive initially and let me 10439 06:38:29,600 --> 06:38:33,680 include in that function only those 10440 06:38:31,440 --> 06:38:36,240 first two tests let me then create 10441 06:38:33,680 --> 06:38:38,840 another function here called test 10442 06:38:36,240 --> 06:38:42,000 negative and in this function let me 10443 06:38:38,840 --> 06:38:45,280 test only -2 and -3 then down here let 10444 06:38:42,000 --> 06:38:47,920 me do one more def of test zero and I'll 10445 06:38:45,280 --> 06:38:50,558 just run one test in there so I have the 10446 06:38:47,920 --> 06:38:52,798 same assertions the same five but I've 10447 06:38:50,558 --> 06:38:55,360 now divided them up among three separate 10448 06:38:52,798 --> 06:38:57,398 functions what's nice about Pi test and 10449 06:38:55,360 --> 06:38:59,478 other unit testing Frameworks is that 10450 06:38:57,398 --> 06:39:01,478 all three of these test functions will 10451 06:38:59,478 --> 06:39:04,160 be run automatically even if one of them 10452 06:39:01,478 --> 06:39:06,398 fails the others will be attempting 10453 06:39:04,160 --> 06:39:08,600 that means that if one or two or three 10454 06:39:06,398 --> 06:39:10,920 of them fail I'll have one or two or 10455 06:39:08,600 --> 06:39:12,920 three Clues now for helping me find that 10456 06:39:10,920 --> 06:39:14,478 mistake so let me go ahead and again 10457 06:39:12,920 --> 06:39:16,798 increase the size of my terminal window 10458 06:39:14,478 --> 06:39:18,958 just so we can see more on the screen my 10459 06:39:16,798 --> 06:39:20,878 calculator still has the bug using 10460 06:39:18,958 --> 06:39:22,840 addition instead of multiplication let 10461 06:39:20,878 --> 06:39:25,920 me go ahead and run not python but again 10462 06:39:22,840 --> 06:39:27,958 Pi test of test calculator. piy crossing 10463 06:39:25,920 --> 06:39:30,120 my fingers as always and now oh my God 10464 06:39:27,958 --> 06:39:32,638 there's even more errors on the screen 10465 06:39:30,120 --> 06:39:34,280 but this in itself is more helpful let's 10466 06:39:32,638 --> 06:39:36,200 work through them from top to bottom so 10467 06:39:34,280 --> 06:39:37,798 under failures here in all caps which I 10468 06:39:36,200 --> 06:39:39,240 know is not very encouraging to see 10469 06:39:37,798 --> 06:39:40,638 failure when you're just trying to solve 10470 06:39:39,240 --> 06:39:43,000 a problem but that's what these 10471 06:39:40,638 --> 06:39:45,080 Frameworks do under failures the first 10472 06:39:43,000 --> 06:39:47,120 function that failed is test positive 10473 06:39:45,080 --> 06:39:49,680 but here too we see the same clue as 10474 06:39:47,120 --> 06:39:51,760 before the first one two the square of 10475 06:39:49,680 --> 06:39:53,958 two equals equals 4 that one's fine it's 10476 06:39:51,760 --> 06:39:55,840 not airing with any red errors but the 10477 06:39:53,958 --> 06:39:58,240 next one is failing so I know that 10478 06:39:55,840 --> 06:39:59,920 square is broken when I pass in three 10479 06:39:58,240 --> 06:40:01,440 all right what about down here it looks 10480 06:39:59,920 --> 06:40:03,680 like unfortunately my test negative 10481 06:40:01,440 --> 06:40:06,798 function is failing to why well when I 10482 06:40:03,680 --> 06:40:09,520 pass in oh this is interesting here now 10483 06:40:06,798 --> 06:40:11,000 -2 doesn't even work so I got lucky with 10484 06:40:09,520 --> 06:40:13,360 positive two but negative -2 isn't 10485 06:40:11,000 --> 06:40:16,920 working so that's a bit of a clue but in 10486 06:40:13,360 --> 06:40:19,760 total only two tests failed so notice at 10487 06:40:16,920 --> 06:40:21,958 the very bottom this summary two failed 10488 06:40:19,760 --> 06:40:24,478 and one passed what's the other one what 10489 06:40:21,958 --> 06:40:27,558 was the third one test zero so test zero 10490 06:40:24,478 --> 06:40:29,240 is passing these two are failing and so 10491 06:40:27,558 --> 06:40:31,120 that kind of leads me logically 10492 06:40:29,240 --> 06:40:32,920 mathematically if you will to the source 10493 06:40:31,120 --> 06:40:34,240 of the bug and just to be clear too if 10494 06:40:32,920 --> 06:40:36,120 you have a lot of tests this little 10495 06:40:34,240 --> 06:40:39,120 oneline output is helpful even though 10496 06:40:36,120 --> 06:40:41,360 also a bit discouraging fail fail and 10497 06:40:39,120 --> 06:40:43,558 Dot means pass so there are the three 10498 06:40:41,360 --> 06:40:46,000 tests just depicted graphically a little 10499 06:40:43,558 --> 06:40:49,440 bit differently well let me rewind now 10500 06:40:46,000 --> 06:40:51,600 and go back into calculator. Pi let's 10501 06:40:49,440 --> 06:40:53,600 fix that bug because let's suppose that 10502 06:40:51,600 --> 06:40:54,920 I've deduced okay I'm using addition I 10503 06:40:53,600 --> 06:40:57,120 should have been using multiplication 10504 06:40:54,920 --> 06:40:58,958 all this time let me now after fixing 10505 06:40:57,120 --> 06:41:01,360 the bug yet again let me go back to my 10506 06:40:58,958 --> 06:41:03,760 big terminal let me run Pi test of test 10507 06:41:01,360 --> 06:41:06,600 calculator. Pi hitting enter crossing my 10508 06:41:03,760 --> 06:41:08,958 fingers now and dot dot dot means all is 10509 06:41:06,600 --> 06:41:11,558 well 100% of my tests passed all three 10510 06:41:08,958 --> 06:41:14,958 of them so now I'm good it doesn't 10511 06:41:11,558 --> 06:41:16,878 necessarily mean that my code is 100% 10512 06:41:14,958 --> 06:41:20,040 correct but it does mean that it has 10513 06:41:16,878 --> 06:41:21,840 passed 100% of my current tests and so 10514 06:41:20,040 --> 06:41:24,360 it would probably behoove us to think a 10515 06:41:21,840 --> 06:41:26,240 little harder about maybe we should test 10516 06:41:24,360 --> 06:41:27,680 bigger numbers maybe we should test even 10517 06:41:26,240 --> 06:41:29,840 smaller numbers maybe we should test 10518 06:41:27,680 --> 06:41:31,638 strings or something else the onus is 10519 06:41:29,840 --> 06:41:33,798 ultimately on you to decide what you're 10520 06:41:31,638 --> 06:41:35,320 going to test but in the real world 10521 06:41:33,798 --> 06:41:37,200 you're going to be very unhappy with 10522 06:41:35,320 --> 06:41:39,638 yourself or someone else maybe your boss 10523 06:41:37,200 --> 06:41:41,600 is going to be very unhappy with you if 10524 06:41:39,638 --> 06:41:43,280 you did not catch a bug in your code 10525 06:41:41,600 --> 06:41:46,240 which you could have caught had you just 10526 06:41:43,280 --> 06:41:47,478 written a test to try that kind of input 10527 06:41:46,240 --> 06:41:49,638 all right let me pause again and see if 10528 06:41:47,478 --> 06:41:53,360 there's any questions now on unit 10529 06:41:49,638 --> 06:41:55,320 testings with P test um so if you wanted 10530 06:41:53,360 --> 06:41:58,280 to test like someone suggested before 10531 06:41:55,320 --> 06:42:00,440 user input as well as testing your 10532 06:41:58,280 --> 06:42:02,280 function do you do that within the same 10533 06:42:00,440 --> 06:42:03,760 file or do you make separate files for 10534 06:42:02,280 --> 06:42:05,080 different types of test 10535 06:42:03,760 --> 06:42:07,360 really good question you could 10536 06:42:05,080 --> 06:42:09,040 absolutely make separate files to test 10537 06:42:07,360 --> 06:42:10,398 different types of things or if you 10538 06:42:09,040 --> 06:42:12,520 don't have that many you can keep them 10539 06:42:10,398 --> 06:42:14,600 all in the same file at the moment I've 10540 06:42:12,520 --> 06:42:16,080 been storing all of my tests in one file 10541 06:42:14,600 --> 06:42:17,840 for convenience and there's not terribly 10542 06:42:16,080 --> 06:42:19,878 many of them but we'll take a look in a 10543 06:42:17,840 --> 06:42:21,840 bit at an example that allows me to put 10544 06:42:19,878 --> 06:42:24,680 them into a folder and even run P test 10545 06:42:21,840 --> 06:42:26,840 on a whole folder of tests as well so 10546 06:42:24,680 --> 06:42:31,160 that's possible other questions on unit 10547 06:42:26,840 --> 06:42:33,360 testing so I've got two questions um so 10548 06:42:31,160 --> 06:42:35,040 a couple while ago you just used um an 10549 06:42:33,360 --> 06:42:37,360 exception called 10550 06:42:35,040 --> 06:42:40,878 assertion um I'm not sure what was oh 10551 06:42:37,360 --> 06:42:44,478 yeah assertion error um what exactly 10552 06:42:40,878 --> 06:42:48,000 does that particular error catch and my 10553 06:42:44,478 --> 06:42:51,718 second question is does the assert 10554 06:42:48,000 --> 06:42:54,120 keyword um stand out to the compiler and 10555 06:42:51,718 --> 06:42:57,760 exactly tell them to assert this 10556 06:42:54,120 --> 06:42:59,718 particular um line of code indeed the 10557 06:42:57,760 --> 06:43:02,040 assert keyword we're seeing and the 10558 06:42:59,718 --> 06:43:04,718 assertion error we saw earlier are 10559 06:43:02,040 --> 06:43:06,558 intertwined so when you use assert and 10560 06:43:04,718 --> 06:43:08,760 the assertion fails because whatever 10561 06:43:06,558 --> 06:43:11,638 Boolean expression you're using is not 10562 06:43:08,760 --> 06:43:13,840 true it's false an assertion error by 10563 06:43:11,638 --> 06:43:16,240 definition of python will be raised so 10564 06:43:13,840 --> 06:43:18,520 those two work in conjunction those 10565 06:43:16,240 --> 06:43:21,080 errors those assertion errors are still 10566 06:43:18,520 --> 06:43:24,360 being raised by my code here when any of 10567 06:43:21,080 --> 06:43:26,478 these lines of code fail however pest 10568 06:43:24,360 --> 06:43:28,840 this third party library is handling the 10569 06:43:26,478 --> 06:43:30,878 process of catching those exceptions 10570 06:43:28,840 --> 06:43:33,080 automatically for me so as to give me 10571 06:43:30,878 --> 06:43:34,558 the standard output so we started to 10572 06:43:33,080 --> 06:43:36,600 today's Story by really implementing 10573 06:43:34,558 --> 06:43:38,440 unit testing myself I wrote all of the 10574 06:43:36,600 --> 06:43:40,638 code myself I wrote main I did my 10575 06:43:38,440 --> 06:43:42,240 conditional I did try except honestly 10576 06:43:40,638 --> 06:43:43,718 it's going to get incredibly painful to 10577 06:43:42,240 --> 06:43:45,440 write tests long term if you and I have 10578 06:43:43,718 --> 06:43:46,558 to write that much code every time 10579 06:43:45,440 --> 06:43:49,080 especially when our function is this 10580 06:43:46,558 --> 06:43:51,200 small uh so pie test and unit testing 10581 06:43:49,080 --> 06:43:54,280 Frameworks like it just automate so much 10582 06:43:51,200 --> 06:43:57,240 of that essentially P test adds the try 10583 06:43:54,280 --> 06:43:59,200 the accept the if the prints for you so 10584 06:43:57,240 --> 06:44:01,558 you can just focus on the essence of the 10585 06:43:59,200 --> 06:44:03,638 tests which really are these inputs and 10586 06:44:01,558 --> 06:44:06,320 outputs how about time for one other 10587 06:44:03,638 --> 06:44:09,958 question here on unit testing as well 10588 06:44:06,320 --> 06:44:13,760 sir uh when we uh enter minus 6 or 10589 06:44:09,958 --> 06:44:16,320 minus5 uh the uh square or Square uh 10590 06:44:13,760 --> 06:44:19,760 square root of the that uh number comes 10591 06:44:16,320 --> 06:44:22,520 up but when we put 6.6 or 5.6 something 10592 06:44:19,760 --> 06:44:26,478 like that integer then 10593 06:44:22,520 --> 06:44:29,160 uh line shows error so what's happening 10594 06:44:26,478 --> 06:44:31,120 there so if I'm deliberately testing 10595 06:44:29,160 --> 06:44:33,360 integers right now in large part because 10596 06:44:31,120 --> 06:44:34,840 I only want pow to operate on inte ERS 10597 06:44:33,360 --> 06:44:36,520 and that might be conveyed in Python's 10598 06:44:34,840 --> 06:44:38,600 documentation or my own documentation 10599 06:44:36,520 --> 06:44:40,760 for that function if we were to pass in 10600 06:44:38,600 --> 06:44:43,440 something else like a float it turns out 10601 06:44:40,760 --> 06:44:45,638 that floating Point values in Python and 10602 06:44:43,440 --> 06:44:48,040 other languages are actually very hard 10603 06:44:45,638 --> 06:44:50,440 if not impossible to represent 100% 10604 06:44:48,040 --> 06:44:52,760 precisely and so if you are trying to 10605 06:44:50,440 --> 06:44:54,920 compare it against some other value they 10606 06:44:52,760 --> 06:44:56,478 might be slight rounding errors as a 10607 06:44:54,920 --> 06:44:58,040 result I'm just inferring from what 10608 06:44:56,478 --> 06:44:59,638 you've described but I'm very 10609 06:44:58,040 --> 06:45:02,120 deliberately now testing this function 10610 06:44:59,638 --> 06:45:04,080 with only the inputs that I would expect 10611 06:45:02,120 --> 06:45:06,878 it might indeed throw other errors if 10612 06:45:04,080 --> 06:45:08,520 other inputs are passed all right allow 10613 06:45:06,878 --> 06:45:10,478 me to propose that we consider what 10614 06:45:08,520 --> 06:45:12,878 should happen if Square isn't actually 10615 06:45:10,478 --> 06:45:15,680 passed a number for instance if I go 10616 06:45:12,878 --> 06:45:17,320 back to calculator. Pi and suppose that 10617 06:45:15,680 --> 06:45:19,000 I or perhaps someone else using my 10618 06:45:17,320 --> 06:45:21,160 Square function simply forgets to 10619 06:45:19,000 --> 06:45:23,840 convert the return value of input from a 10620 06:45:21,160 --> 06:45:26,040 stir to an INT as by modifying line two 10621 06:45:23,840 --> 06:45:28,398 here well now something's definitely 10622 06:45:26,040 --> 06:45:30,600 going to go wrong if I type in a stir 10623 06:45:28,398 --> 06:45:32,718 instead of what appears to be an INT for 10624 06:45:30,600 --> 06:45:35,798 instance if I clear my terminal here run 10625 06:45:32,718 --> 06:45:39,120 pip Pyon of calculator. Pi and hit enter 10626 06:45:35,798 --> 06:45:41,160 let's type in cat as our value for x and 10627 06:45:39,120 --> 06:45:43,200 of course this raises Now a type error 10628 06:45:41,160 --> 06:45:45,080 why can't multiply sequence by non-int 10629 06:45:43,200 --> 06:45:47,520 of type stir what does that mean well 10630 06:45:45,080 --> 06:45:49,320 you can't do cat times cat because 10631 06:45:47,520 --> 06:45:50,840 indeed square is expecting that n will 10632 06:45:49,320 --> 06:45:52,680 be some number but that doesn't 10633 06:45:50,840 --> 06:45:54,680 necessarily mean that square itself is 10634 06:45:52,680 --> 06:45:56,958 buggy but this does mean that if I 10635 06:45:54,680 --> 06:45:58,600 expect a type error to be raised let's 10636 06:45:56,958 --> 06:46:01,398 test for that too so that I know the 10637 06:45:58,600 --> 06:46:04,040 behavior indeed works as expected so let 10638 06:46:01,398 --> 06:46:06,958 me go back to test calculator p and let 10639 06:46:04,040 --> 06:46:09,798 me go and add a fourth test down here 10640 06:46:06,958 --> 06:46:11,360 how about Define testore and I'll call 10641 06:46:09,798 --> 06:46:13,080 this tester because I'm going to 10642 06:46:11,360 --> 06:46:16,080 specifically and deliberately pass in a 10643 06:46:13,080 --> 06:46:18,680 stir for testing and I want to in spirit 10644 06:46:16,080 --> 06:46:21,600 assert that passing in something like 10645 06:46:18,680 --> 06:46:23,680 cat to square will raise a type error 10646 06:46:21,600 --> 06:46:25,520 but we don't use the assert keyword for 10647 06:46:23,680 --> 06:46:27,280 that rather we need this let me go to 10648 06:46:25,520 --> 06:46:30,000 the top of this file and let me 10649 06:46:27,280 --> 06:46:31,718 additionally import the pest Library 10650 06:46:30,000 --> 06:46:34,240 itself because it turns out there's a 10651 06:46:31,718 --> 06:46:36,920 function in that Library called raises 10652 06:46:34,240 --> 06:46:39,080 that allows me to express that I expect 10653 06:46:36,920 --> 06:46:42,240 an exception to be raised and I can 10654 06:46:39,080 --> 06:46:44,000 express that as follows with pest. 10655 06:46:42,240 --> 06:46:46,478 raises and then in parenthesis I can 10656 06:46:44,000 --> 06:46:48,440 pass in the type of exception I expect 10657 06:46:46,478 --> 06:46:50,878 which is going to be a type error in 10658 06:46:48,440 --> 06:46:53,000 this case and now when do I expect that 10659 06:46:50,878 --> 06:46:54,478 type error to be raised whenever I do 10660 06:46:53,000 --> 06:46:56,680 something like calling square and 10661 06:46:54,478 --> 06:46:59,000 passing in not a number but something 10662 06:46:56,680 --> 06:47:01,440 like cat so now if I go back to my 10663 06:46:59,000 --> 06:47:03,920 terminal window run Pi test of test 10664 06:47:01,440 --> 06:47:07,920 calculator. piy this time having four 10665 06:47:03,920 --> 06:47:10,440 tests I should see that all four now are 10666 06:47:07,920 --> 06:47:12,558 successful all right let's now consider 10667 06:47:10,440 --> 06:47:14,878 how we could test code that doesn't just 10668 06:47:12,558 --> 06:47:17,040 expect numbers as input but actually 10669 06:47:14,878 --> 06:47:19,360 strings and let me rewind Us in time 10670 06:47:17,040 --> 06:47:21,240 here in VSS code to that very first 10671 06:47:19,360 --> 06:47:23,840 program rewrote a few different versions 10672 06:47:21,240 --> 06:47:25,638 of in hello.py that ultimately looked a 10673 06:47:23,840 --> 06:47:28,360 little something like this I had a main 10674 06:47:25,638 --> 06:47:30,440 function that prompted the user for the 10675 06:47:28,360 --> 06:47:32,878 value of a variable by asking them 10676 06:47:30,440 --> 06:47:34,240 what's your name question mark and then 10677 06:47:32,878 --> 06:47:37,760 we went ahead and did something like 10678 06:47:34,240 --> 06:47:40,320 hello open pen name passing that user's 10679 06:47:37,760 --> 06:47:42,558 name into a function called hello now 10680 06:47:40,320 --> 06:47:45,200 that function hello recall ultimately 10681 06:47:42,558 --> 06:47:47,240 looked like this we defined hello as 10682 06:47:45,200 --> 06:47:49,920 taking a parameter called two the 10683 06:47:47,240 --> 06:47:52,878 default value of which was world and 10684 06:47:49,920 --> 06:47:55,120 that function very simply printed hello 10685 06:47:52,878 --> 06:47:57,120 followed by a comma and then whatever 10686 06:47:55,120 --> 06:47:59,240 the name that had been passed in and 10687 06:47:57,120 --> 06:48:01,080 then we ultimately called main but for 10688 06:47:59,240 --> 06:48:04,000 now onward I'm going to always add this 10689 06:48:01,080 --> 06:48:06,558 if conditional if name equals equals 10690 06:48:04,000 --> 06:48:08,280 underscore uncore main then and only 10691 06:48:06,558 --> 06:48:10,000 then do I want to call Main so that's 10692 06:48:08,280 --> 06:48:12,558 essentially what this program looked 10693 06:48:10,000 --> 06:48:14,680 like in its last Incarnation how do we 10694 06:48:12,558 --> 06:48:16,320 go about testing it well here again too 10695 06:48:14,680 --> 06:48:18,280 I'm not going to test the user's input 10696 06:48:16,320 --> 06:48:21,160 per se in main I'm going to focus really 10697 06:48:18,280 --> 06:48:22,680 on the module the module of code here 10698 06:48:21,160 --> 06:48:24,798 that's of Interest which is the hello 10699 06:48:22,680 --> 06:48:27,798 function itself how can I go about 10700 06:48:24,798 --> 06:48:29,920 testing the hello function well 10701 06:48:27,798 --> 06:48:33,000 unfortunately even if I start by doing 10702 06:48:29,920 --> 06:48:35,160 something like code of test hello.py 10703 06:48:33,000 --> 06:48:37,680 let me go about and start writing a test 10704 06:48:35,160 --> 06:48:40,280 program I could import from my hello 10705 06:48:37,680 --> 06:48:42,718 program a function called hello so a bit 10706 06:48:40,280 --> 06:48:44,478 strange to see from Hello import hello 10707 06:48:42,718 --> 06:48:46,798 but notice that on this line here I'm 10708 06:48:44,478 --> 06:48:49,398 importing from the module that is the 10709 06:48:46,798 --> 06:48:53,200 file called hello.py the function called 10710 06:48:49,398 --> 06:48:57,280 hello and how do I go about testing this 10711 06:48:53,200 --> 06:49:00,520 well if I have a function like Define uh 10712 06:48:57,280 --> 06:49:02,840 test argument like this well let me Sue 10713 06:49:00,520 --> 06:49:06,718 this so if I were toine a function like 10714 06:49:02,840 --> 06:49:09,280 like Define test hello what could I do 10715 06:49:06,718 --> 06:49:14,760 well I could call hello with quote 10716 06:49:09,280 --> 06:49:18,760 unquote say uh David and then check if 10717 06:49:14,760 --> 06:49:20,920 it equals what hello comma David so 10718 06:49:18,760 --> 06:49:23,958 would this work this approach here if 10719 06:49:20,920 --> 06:49:25,520 I've written a test called test hello 10720 06:49:23,958 --> 06:49:27,638 that calls hello with an argument of 10721 06:49:25,520 --> 06:49:29,920 David and then tests its return value 10722 06:49:27,638 --> 06:49:33,320 just like we've done for our calculator 10723 06:49:29,920 --> 06:49:35,120 would this work as written 10724 06:49:33,320 --> 06:49:37,000 and let me go back to in just a moment 10725 06:49:35,120 --> 06:49:39,280 the version of hello that we're testing 10726 06:49:37,000 --> 06:49:43,478 so you can see that function hello 10727 06:49:39,280 --> 06:49:45,398 here's the test here is the actual code 10728 06:49:43,478 --> 06:49:48,360 would this test now 10729 06:49:45,398 --> 06:49:50,558 work any thoughts uh I think the problem 10730 06:49:48,360 --> 06:49:54,040 is that in the first version in 10731 06:49:50,558 --> 06:49:56,240 hello.py you're using the toe argument 10732 06:49:54,040 --> 06:49:58,760 that you first declare when you declare 10733 06:49:56,240 --> 06:50:03,320 the function instead of using the 10734 06:49:58,760 --> 06:50:05,320 name okay I that is actually uh not a 10735 06:50:03,320 --> 06:50:07,958 bug here so let me stipulate that in 10736 06:50:05,320 --> 06:50:09,398 hello.py this code actually does work as 10737 06:50:07,958 --> 06:50:11,320 intended and let me go ahead and test it 10738 06:50:09,398 --> 06:50:14,718 manually just to demonstrate as much let 10739 06:50:11,320 --> 06:50:17,478 me run python of hello.py typing in as 10740 06:50:14,718 --> 06:50:19,638 my name David and I see in fact that it 10741 06:50:17,478 --> 06:50:21,958 says hello David if though I were to 10742 06:50:19,638 --> 06:50:24,360 change this program and get rid of the 10743 06:50:21,958 --> 06:50:26,398 name argument get rid of the name 10744 06:50:24,360 --> 06:50:28,920 variable and just call hello again 10745 06:50:26,398 --> 06:50:30,398 running python of hello.py this time I'm 10746 06:50:28,920 --> 06:50:32,398 not even prompted because I got rid of 10747 06:50:30,398 --> 06:50:35,478 my input call but it does pre behave as 10748 06:50:32,398 --> 06:50:37,478 I expect it does say hello world so let 10749 06:50:35,478 --> 06:50:41,000 me stipulate that this code in its 10750 06:50:37,478 --> 06:50:43,760 current form is actually correct but my 10751 06:50:41,000 --> 06:50:45,360 test is not going to work as I'd hoped 10752 06:50:43,760 --> 06:50:48,600 and there's a subtle difference between 10753 06:50:45,360 --> 06:50:50,478 hello versus my pow function that expl 10754 06:50:48,600 --> 06:50:52,558 versus my there's a subtle difference 10755 06:50:50,478 --> 06:50:54,240 between my hello function and my Square 10756 06:50:52,558 --> 06:50:57,478 function that 10757 06:50:54,240 --> 06:51:00,200 explains why might this test not work as 10758 06:50:57,478 --> 06:51:02,920 intended um because it's not returning a 10759 06:51:00,200 --> 06:51:05,000 value yeah exactly recall our discussion 10760 06:51:02,920 --> 06:51:07,120 early on about functions functions can 10761 06:51:05,000 --> 06:51:08,840 either return a value like my Square 10762 06:51:07,120 --> 06:51:10,920 function hands you back the square of 10763 06:51:08,840 --> 06:51:13,120 some value or they can have side effects 10764 06:51:10,920 --> 06:51:14,798 sort of visual uh artifacts that might 10765 06:51:13,120 --> 06:51:16,398 happen on the screen like printing 10766 06:51:14,798 --> 06:51:19,000 something out on the screen and by 10767 06:51:16,398 --> 06:51:21,040 definition that's how Print Works notice 10768 06:51:19,000 --> 06:51:22,600 that hello it is short but it's 10769 06:51:21,040 --> 06:51:24,398 implemented ultimately using the print 10770 06:51:22,600 --> 06:51:26,638 function which does not return a value 10771 06:51:24,398 --> 06:51:28,200 as I'm using it here it instead has this 10772 06:51:26,638 --> 06:51:30,718 side effect of printing something onto 10773 06:51:28,200 --> 06:51:33,600 the screen so it is not correct in my 10774 06:51:30,718 --> 06:51:37,280 test function to check if the return 10775 06:51:33,600 --> 06:51:39,240 value of hello equals equals hello David 10776 06:51:37,280 --> 06:51:40,638 because again hello is not returning 10777 06:51:39,240 --> 06:51:43,200 anything it's printing something with 10778 06:51:40,638 --> 06:51:46,240 that side effect but notice literally it 10779 06:51:43,200 --> 06:51:48,680 has no return keyword unlike my Square 10780 06:51:46,240 --> 06:51:51,160 function which did so here's an 10781 06:51:48,680 --> 06:51:53,840 opportunity too to perhaps change how I 10782 06:51:51,160 --> 06:51:55,958 go about implementing my actual 10783 06:51:53,840 --> 06:51:57,958 functions it turns out that as your 10784 06:51:55,958 --> 06:52:00,000 programs get more and more sophisticated 10785 06:51:57,958 --> 06:52:02,320 more and more complicated it tends to be 10786 06:52:00,000 --> 06:52:04,360 best practiced not to have side effects 10787 06:52:02,320 --> 06:52:06,520 if if you can avoid it especially if you 10788 06:52:04,360 --> 06:52:08,638 want your code to be testable and in 10789 06:52:06,520 --> 06:52:11,320 fact I'm going to propose that we change 10790 06:52:08,638 --> 06:52:13,760 my hello program to now work as follows 10791 06:52:11,320 --> 06:52:16,638 let me go ahead and change this function 10792 06:52:13,760 --> 06:52:18,840 to not print hello and then that name 10793 06:52:16,638 --> 06:52:20,638 let me go ahead and literally return 10794 06:52:18,840 --> 06:52:24,000 maybe an F string which will clean this 10795 06:52:20,638 --> 06:52:26,798 up a little bit hello comma 2 close 10796 06:52:24,000 --> 06:52:28,558 quote at the end so my syntax here is 10797 06:52:26,798 --> 06:52:30,478 just the familiar F string or format 10798 06:52:28,558 --> 06:52:33,320 string it's going to return hello world 10799 06:52:30,478 --> 06:52:35,398 or hello David or hello whoever name is 10800 06:52:33,320 --> 06:52:38,398 passed in as that argument but I'm 10801 06:52:35,398 --> 06:52:41,080 returning it now I'm not printing it out 10802 06:52:38,398 --> 06:52:43,638 so what needs to change up here well I 10803 06:52:41,080 --> 06:52:46,680 could do something like this I could say 10804 06:52:43,638 --> 06:52:49,798 something like output equals hello and 10805 06:52:46,680 --> 06:52:51,080 then print output in my main function or 10806 06:52:49,798 --> 06:52:52,558 I can simplify that because I don't 10807 06:52:51,080 --> 06:52:55,000 really need that variable I could 10808 06:52:52,558 --> 06:52:57,240 instead just do this I could still call 10809 06:52:55,000 --> 06:53:00,160 hello but I could immediately print out 10810 06:52:57,240 --> 06:53:03,120 the result and this version of my hello 10811 06:53:00,160 --> 06:53:05,120 program now is actually more test able 10812 06:53:03,120 --> 06:53:06,920 why because these assert statements that 10813 06:53:05,120 --> 06:53:10,240 we're using and we've seen th far for 10814 06:53:06,920 --> 06:53:13,080 our tests are really designed to test 10815 06:53:10,240 --> 06:53:15,760 arguments into functions and return 10816 06:53:13,080 --> 06:53:17,440 values there from not testing side 10817 06:53:15,760 --> 06:53:18,878 effects so if you're doing equals equals 10818 06:53:17,440 --> 06:53:20,160 you're looking for a return value 10819 06:53:18,878 --> 06:53:22,760 something that's handed back from the 10820 06:53:20,160 --> 06:53:24,558 function so that's fine if I modify the 10821 06:53:22,760 --> 06:53:27,718 design of my program now not to just 10822 06:53:24,558 --> 06:53:30,040 print hello but to return the string the 10823 06:53:27,718 --> 06:53:32,798 sentence the phrase that I want to 10824 06:53:30,040 --> 06:53:34,638 construct I can leave it to the caller 10825 06:53:32,798 --> 06:53:36,920 that is the function who's using this 10826 06:53:34,638 --> 06:53:38,760 hello function to handle the actual 10827 06:53:36,920 --> 06:53:41,478 printing now what does this mean in my 10828 06:53:38,760 --> 06:53:43,080 code well it means now if my hello.py 10829 06:53:41,478 --> 06:53:45,558 looks like this and hello is indeed 10830 06:53:43,080 --> 06:53:48,760 returning a value in my test hello 10831 06:53:45,558 --> 06:53:51,080 function I can test it exactly like this 10832 06:53:48,760 --> 06:53:53,478 so let me go ahead and run Pi test of 10833 06:53:51,080 --> 06:53:56,440 test hello.py crossing my fingers as 10834 06:53:53,478 --> 06:53:57,958 always and voila one passed so I passed 10835 06:53:56,440 --> 06:54:01,040 this test because apparently the return 10836 06:53:57,958 --> 06:54:03,600 value of hello does indeed equal hello 10837 06:54:01,040 --> 06:54:05,958 comma David well let's test the scenario 10838 06:54:03,600 --> 06:54:08,320 what if I P call hello without any 10839 06:54:05,958 --> 06:54:10,080 arguments let's assert that calling 10840 06:54:08,320 --> 06:54:12,920 hello with nothing in those parentheses 10841 06:54:10,080 --> 06:54:14,798 similarly equals hello comma but world 10842 06:54:12,920 --> 06:54:18,240 the default value let me now go ahead 10843 06:54:14,798 --> 06:54:21,680 and run Pi test of test hello.py and 10844 06:54:18,240 --> 06:54:23,160 that too passes entirely but there too 10845 06:54:21,680 --> 06:54:25,520 suppose that I had made some mistake 10846 06:54:23,160 --> 06:54:27,280 suppose that there were a bug in my code 10847 06:54:25,520 --> 06:54:29,240 it might not be best practice to combine 10848 06:54:27,280 --> 06:54:31,040 multiple tests in this one function so 10849 06:54:29,240 --> 06:54:33,160 let's make it more clear what might pass 10850 06:54:31,040 --> 06:54:35,878 or fail let's call the first function 10851 06:54:33,160 --> 06:54:37,638 test the default uh to this function and 10852 06:54:35,878 --> 06:54:39,600 let's only include this first line of 10853 06:54:37,638 --> 06:54:41,878 code and then let's go ahead and Define 10854 06:54:39,600 --> 06:54:44,398 another function like test argument to 10855 06:54:41,878 --> 06:54:46,160 test this other line of code here so now 10856 06:54:44,398 --> 06:54:47,680 I have two different tests Each of which 10857 06:54:46,160 --> 06:54:49,600 is testing something a little 10858 06:54:47,680 --> 06:54:52,040 fundamentally different so now when I 10859 06:54:49,600 --> 06:54:55,520 run my code it's still not broken if I 10860 06:54:52,040 --> 06:54:58,360 run Pi test of test hello.py enter I've 10861 06:54:55,520 --> 06:55:00,760 now passed two tests and that's just as 10862 06:54:58,360 --> 06:55:02,920 good as before but if I did have a bug 10863 06:55:00,760 --> 06:55:05,000 having two tests instead of one would 10864 06:55:02,920 --> 06:55:09,080 indeed give me perhaps a bit more of a 10865 06:55:05,000 --> 06:55:11,360 hint as to what's wrong questions now on 10866 06:55:09,080 --> 06:55:13,320 this testing of return values when these 10867 06:55:11,360 --> 06:55:16,320 return values are now strings instead of 10868 06:55:13,320 --> 06:55:19,320 integers and why we've done this so my 10869 06:55:16,320 --> 06:55:23,320 question is uh about function inside the 10870 06:55:19,320 --> 06:55:26,558 function uh can we test that too or 10871 06:55:23,320 --> 06:55:29,798 recursion we we we have't 10872 06:55:26,558 --> 06:55:31,080 seen if you have if you have a recursive 10873 06:55:29,798 --> 06:55:33,080 function which we've not discussed in 10874 06:55:31,080 --> 06:55:36,080 this class yes you can absolutely test 10875 06:55:33,080 --> 06:55:37,718 those two uh by simply calling them 10876 06:55:36,080 --> 06:55:39,600 exactly in this way recursion does not 10877 06:55:37,718 --> 06:55:40,958 affect this process all right how about 10878 06:55:39,600 --> 06:55:43,680 one more question here on unit test 10879 06:55:40,958 --> 06:55:48,120 before we look at one final example when 10880 06:55:43,680 --> 06:55:52,478 testing our uh arguments like uh can we 10881 06:55:48,120 --> 06:55:55,760 use something like a Loops or inside of 10882 06:55:52,478 --> 06:55:57,478 assert or for the values absolutely you 10883 06:55:55,760 --> 06:55:59,360 can absolutely use a loop to test 10884 06:55:57,478 --> 06:56:01,680 multiple values in this case for 10885 06:55:59,360 --> 06:56:05,000 instance I could do something like this 10886 06:56:01,680 --> 06:56:06,558 I could say for name in The Following 10887 06:56:05,000 --> 06:56:11,680 list of 10888 06:56:06,558 --> 06:56:14,320 Hermione uh say Harry and Ron I could 10889 06:56:11,680 --> 06:56:18,878 then within this Loop assert that hello 10890 06:56:14,320 --> 06:56:22,440 of that given name equals equals say the 10891 06:56:18,878 --> 06:56:25,840 format string of hello comma name and 10892 06:56:22,440 --> 06:56:28,680 then run all of these here at once by 10893 06:56:25,840 --> 06:56:30,558 running again Pi test of test hello.py 10894 06:56:28,680 --> 06:56:31,958 it's still going to be just one test 10895 06:56:30,558 --> 06:56:33,240 within that function but if there's 10896 06:56:31,958 --> 06:56:34,958 something interesting about those 10897 06:56:33,240 --> 06:56:36,840 several strings that makes it compelling 10898 06:56:34,958 --> 06:56:39,000 to test all of them you can absolutely 10899 06:56:36,840 --> 06:56:41,320 automate the tests in that way with that 10900 06:56:39,000 --> 06:56:44,160 said each of your test should ideally be 10901 06:56:41,320 --> 06:56:45,600 pretty simple and pretty small why 10902 06:56:44,160 --> 06:56:47,520 because you don't want to write so much 10903 06:56:45,600 --> 06:56:49,680 code so much complicated code that your 10904 06:56:47,520 --> 06:56:51,320 tests might be flawed what we don't want 10905 06:56:49,680 --> 06:56:53,160 to have to do is write tests for our 10906 06:56:51,320 --> 06:56:54,718 tests and tests for our test for our 10907 06:56:53,160 --> 06:56:57,080 tests because it would never end so 10908 06:56:54,718 --> 06:56:58,558 keeping tests nice and simple is really 10909 06:56:57,080 --> 06:57:00,360 the goal so that a reasonable human 10910 06:56:58,558 --> 06:57:03,240 yourself included can eyeball them and 10911 06:57:00,360 --> 06:57:05,520 just claim yeah that is correct we don't 10912 06:57:03,240 --> 06:57:07,080 need tests for our tests all right how 10913 06:57:05,520 --> 06:57:08,680 about one other feature suppose that we 10914 06:57:07,080 --> 06:57:10,440 don't have just one test but many 10915 06:57:08,680 --> 06:57:11,958 different tests instead and we want to 10916 06:57:10,440 --> 06:57:14,200 start to organize those tests into 10917 06:57:11,958 --> 06:57:16,000 multiple files and even a folder well P 10918 06:57:14,200 --> 06:57:18,200 test and other Frameworks support that 10919 06:57:16,000 --> 06:57:21,000 Paradigm as well in fact let me go ahead 10920 06:57:18,200 --> 06:57:23,160 and test hello.py using a folder of 10921 06:57:21,000 --> 06:57:24,398 tests with technically just one test but 10922 06:57:23,160 --> 06:57:26,478 it would be representative of having 10923 06:57:24,398 --> 06:57:28,440 even more in that folder I'm going to go 10924 06:57:26,478 --> 06:57:31,680 ahead and create a new folder called 10925 06:57:28,440 --> 06:57:34,240 test using makeer at my command line and 10926 06:57:31,680 --> 06:57:35,520 then Within that file I'm within that 10927 06:57:34,240 --> 06:57:38,160 and then within that folder I'm going to 10928 06:57:35,520 --> 06:57:40,558 go ahead and create a file called test 10929 06:57:38,160 --> 06:57:42,080 hello.py within this file meanwhile I'm 10930 06:57:40,558 --> 06:57:44,600 going to test the same things I'm going 10931 06:57:42,080 --> 06:57:46,718 to go ahead and from Hello import 10932 06:57:44,600 --> 06:57:49,638 hello and I'm going to go ahead and 10933 06:57:46,718 --> 06:57:52,160 Define a function like test default that 10934 06:57:49,638 --> 06:57:54,478 simply tests the scenario where hello 10935 06:57:52,160 --> 06:57:56,360 with no arguments returns hello comma 10936 06:57:54,478 --> 06:57:58,520 world and I'm going to have that other 10937 06:57:56,360 --> 06:58:00,320 function where I test that an argument 10938 06:57:58,520 --> 06:58:02,440 is passed and in this case I'll choose 10939 06:58:00,320 --> 06:58:05,760 an argument like asserting that hello 10940 06:58:02,440 --> 06:58:08,798 quote unquote David equals indeed hello 10941 06:58:05,760 --> 06:58:10,360 comma not world but David So in this 10942 06:58:08,798 --> 06:58:12,280 case I've just recreated the same test 10943 06:58:10,360 --> 06:58:15,360 as earlier but they're in a file now in 10944 06:58:12,280 --> 06:58:17,920 a folder called test well P test allows 10945 06:58:15,360 --> 06:58:20,160 me to run these here too but to do so I 10946 06:58:17,920 --> 06:58:23,200 actually need to create one other file 10947 06:58:20,160 --> 06:58:26,240 within my test directory I need to 10948 06:58:23,200 --> 06:58:29,558 create a file called uncore uncore init 10949 06:58:26,240 --> 06:58:33,080 uncore uncore dopy which has the effect 10950 06:58:29,558 --> 06:58:35,958 even if this file is empty of ing python 10951 06:58:33,080 --> 06:58:38,958 to treat that folder as not just a 10952 06:58:35,958 --> 06:58:41,240 module but a package so to speak a 10953 06:58:38,958 --> 06:58:43,360 package is a python module or multiple 10954 06:58:41,240 --> 06:58:46,160 modules that are organized inside of a 10955 06:58:43,360 --> 06:58:48,120 folder and this file underscore uncore 10956 06:58:46,160 --> 06:58:50,200 init underscore uncore Pi is just a 10957 06:58:48,120 --> 06:58:52,558 visual indicator to python that indeed 10958 06:58:50,200 --> 06:58:54,398 it should treat that folder as a package 10959 06:58:52,558 --> 06:58:56,080 if I had more code in this folder I 10960 06:58:54,398 --> 06:58:57,680 could do even more things with this file 10961 06:58:56,080 --> 06:58:59,718 but for now it's just a cluee that it's 10962 06:58:57,680 --> 06:59:02,558 indeed meant to be a package and not 10963 06:58:59,718 --> 06:59:05,360 just a module or file alone what I can 10964 06:59:02,558 --> 06:59:07,600 now do in closing is run P test not even 10965 06:59:05,360 --> 06:59:11,840 on that specific file but on a whole 10966 06:59:07,600 --> 06:59:13,760 folder of tests so if I run Pest of test 10967 06:59:11,840 --> 06:59:15,798 where the test is the name of that 10968 06:59:13,760 --> 06:59:17,520 folder pest will automatically search 10969 06:59:15,798 --> 06:59:19,280 through that folder looking for all 10970 06:59:17,520 --> 06:59:21,798 possible tests granted there's just 10971 06:59:19,280 --> 06:59:24,200 those two in this one file but when I 10972 06:59:21,798 --> 06:59:26,680 run it now with enter I'll still pass 10973 06:59:24,200 --> 06:59:28,558 those tests I'll still get 100% And I 10974 06:59:26,680 --> 06:59:30,360 now have a mechanism ultimately for 10975 06:59:28,558 --> 06:59:32,120 testing my own code so whether you're 10976 06:59:30,360 --> 06:59:33,878 writing functions that return integers 10977 06:59:32,120 --> 06:59:35,520 or something else functions that have 10978 06:59:33,878 --> 06:59:36,958 side effects that could be Rewritten as 10979 06:59:35,520 --> 06:59:39,320 functions that return values you now 10980 06:59:36,958 --> 06:59:41,240 have a mechanism to not just wait for 10981 06:59:39,320 --> 06:59:42,920 one someone like us to test your code 10982 06:59:41,240 --> 06:59:44,558 and not just test your code manually 10983 06:59:42,920 --> 06:59:46,120 again and again which might get tedious 10984 06:59:44,558 --> 06:59:48,080 and you might make mistakes by not 10985 06:59:46,120 --> 06:59:50,000 including some possible inputs we now 10986 06:59:48,080 --> 06:59:52,000 have an automated mechanism for testing 10987 06:59:50,000 --> 06:59:53,280 one's own code that's going to be even 10988 06:59:52,000 --> 06:59:55,000 more powerful when you start 10989 06:59:53,280 --> 06:59:57,398 collaborating with others so that you 10990 06:59:55,000 --> 06:59:59,398 can write tests that ensure that if they 10991 06:59:57,398 --> 07:00:01,240 make a change to the same code they 10992 06:59:59,398 --> 07:00:02,958 haven't broken the code that you've 10993 07:00:01,240 --> 07:00:07,120 written all right that's it for this 10994 07:00:02,958 --> 07:00:07,120 week we'll see you next time 10995 07:00:11,710 --> 07:00:20,540 [Music] 10996 07:00:22,570 --> 07:00:29,439 [Music] 10997 07:00:32,398 --> 07:00:37,120 all right this is cs50's Introduction to 10998 07:00:35,080 --> 07:00:39,718 programming with python my name is David 10999 07:00:37,120 --> 07:00:42,000 men and this is our week on file IO 11000 07:00:39,718 --> 07:00:44,040 input and output of files so up until 11001 07:00:42,000 --> 07:00:45,680 now most every program we've written 11002 07:00:44,040 --> 07:00:48,320 just stores all the information that it 11003 07:00:45,680 --> 07:00:50,320 collects in memory that is in variables 11004 07:00:48,320 --> 07:00:51,798 or inside of the program itself a 11005 07:00:50,320 --> 07:00:53,798 downside of which is that as soon as the 11006 07:00:51,798 --> 07:00:55,600 program exits anything you typed in 11007 07:00:53,798 --> 07:00:58,200 anything that you did with that program 11008 07:00:55,600 --> 07:01:00,440 is lost now with files of course on your 11009 07:00:58,200 --> 07:01:02,840 Mac or PC you can hang on to information 11010 07:01:00,440 --> 07:01:05,120 long term and file IO within the context 11011 07:01:02,840 --> 07:01:06,878 of programming is all about writing code 11012 07:01:05,120 --> 07:01:09,000 that can read from that is load 11013 07:01:06,878 --> 07:01:12,000 information from or write to that is 11014 07:01:09,000 --> 07:01:13,600 save information to files themselves so 11015 07:01:12,000 --> 07:01:15,958 let's see if we can't transition then 11016 07:01:13,600 --> 07:01:17,878 from only using memory and variables and 11017 07:01:15,958 --> 07:01:19,718 the like to actually writing code that 11018 07:01:17,878 --> 07:01:22,760 save some files for us and therefore 11019 07:01:19,718 --> 07:01:24,398 data persistently well to do this let me 11020 07:01:22,760 --> 07:01:26,440 propose that we first consider a 11021 07:01:24,398 --> 07:01:28,240 familiar data structure a familiar type 11022 07:01:26,440 --> 07:01:30,240 of variable that we've seen before that 11023 07:01:28,240 --> 07:01:32,240 of a list and using lists we've been 11024 07:01:30,240 --> 07:01:33,958 able to store more than one piece of 11025 07:01:32,240 --> 07:01:35,840 information in the past using one 11026 07:01:33,958 --> 07:01:37,840 variable we typically store one value 11027 07:01:35,840 --> 07:01:40,080 but if that variable is a list we can 11028 07:01:37,840 --> 07:01:41,520 store multiple values unfortunately 11029 07:01:40,080 --> 07:01:43,638 lists are stored in the computer's 11030 07:01:41,520 --> 07:01:45,840 memory and so once your program exits 11031 07:01:43,638 --> 07:01:47,558 even the contents of those disappear but 11032 07:01:45,840 --> 07:01:49,798 let's at least give ourselves a starting 11033 07:01:47,558 --> 07:01:51,160 point so I'm over here in vs code and 11034 07:01:49,798 --> 07:01:54,920 I'm going to go ahead and create a 11035 07:01:51,160 --> 07:01:56,638 simple program using Code of names. py a 11036 07:01:54,920 --> 07:01:58,718 program that just collects people's 11037 07:01:56,638 --> 07:02:00,638 names students names if you will and I'm 11038 07:01:58,718 --> 07:02:02,200 going to do it super simply initially in 11039 07:02:00,638 --> 07:02:04,000 a manner consistent with what we've done 11040 07:02:02,200 --> 07:02:05,638 in the past to get user input and print 11041 07:02:04,000 --> 07:02:08,638 it back out I'm going to say something 11042 07:02:05,638 --> 07:02:11,798 like this name equals input quote 11043 07:02:08,638 --> 07:02:14,240 unquote what's your name thereby storing 11044 07:02:11,798 --> 07:02:16,920 in a variable called name the return 11045 07:02:14,240 --> 07:02:18,280 value of input as always and as always 11046 07:02:16,920 --> 07:02:20,200 I'm going to go ahead and very simply 11047 07:02:18,280 --> 07:02:22,558 print out a nice F string that says 11048 07:02:20,200 --> 07:02:24,600 hello comma and then in curly brace's 11049 07:02:22,558 --> 07:02:26,840 name to print out hello David hello 11050 07:02:24,600 --> 07:02:28,478 world however happens to be using the 11051 07:02:26,840 --> 07:02:29,878 program let me go ahead and run this 11052 07:02:28,478 --> 07:02:31,878 just to remind myself what I should 11053 07:02:29,878 --> 07:02:33,680 expect and if I run python of names. 11054 07:02:31,878 --> 07:02:36,200 high and hit enter type in my name like 11055 07:02:33,680 --> 07:02:38,440 David of course I now see hello comma 11056 07:02:36,200 --> 07:02:40,320 David suppose though that we wanted to 11057 07:02:38,440 --> 07:02:42,320 add support not just for one name but 11058 07:02:40,320 --> 07:02:43,878 multiple names maybe three names for the 11059 07:02:42,320 --> 07:02:46,920 sake of discussion so that we can begin 11060 07:02:43,878 --> 07:02:49,000 to accumulate some amount of information 11061 07:02:46,920 --> 07:02:50,840 in the program such that it's really 11062 07:02:49,000 --> 07:02:53,478 going to be a downside if we keep 11063 07:02:50,840 --> 07:02:56,040 throwing it away once the program exits 11064 07:02:53,478 --> 07:02:58,520 well let me go back into names. up here 11065 07:02:56,040 --> 07:03:00,920 at top let me proactively give myself a 11066 07:02:58,520 --> 07:03:03,160 variable this time called names plural 11067 07:03:00,920 --> 07:03:04,520 and set it equal to an empty list recall 11068 07:03:03,160 --> 07:03:06,200 that the square bracket notation 11069 07:03:04,520 --> 07:03:08,398 especially if nothing's inside of it 11070 07:03:06,200 --> 07:03:10,798 just means give me an empty list that we 11071 07:03:08,398 --> 07:03:12,638 can add things to over time well what do 11072 07:03:10,798 --> 07:03:14,638 we want to add to it well let's add 11073 07:03:12,638 --> 07:03:16,680 three names each from the user and let 11074 07:03:14,638 --> 07:03:19,798 me say something like this uh for 11075 07:03:16,680 --> 07:03:22,760 underscore in range of three let me go 11076 07:03:19,798 --> 07:03:24,680 ahead and prompt the user with the input 11077 07:03:22,760 --> 07:03:27,638 function and getting their name in this 11078 07:03:24,680 --> 07:03:31,840 variable and then using list syntax I 11079 07:03:27,638 --> 07:03:34,958 can say names. append name to that list 11080 07:03:31,840 --> 07:03:37,760 list and now I have in that list that 11081 07:03:34,958 --> 07:03:39,760 given name one two three of them other 11082 07:03:37,760 --> 07:03:41,680 points to note is I could use a variable 11083 07:03:39,760 --> 07:03:44,000 here like I which is conventional but if 11084 07:03:41,680 --> 07:03:45,360 I'm not actually using I explicitly on 11085 07:03:44,000 --> 07:03:47,160 any subsequent lines I might as well 11086 07:03:45,360 --> 07:03:49,080 just use underscore which is a pythonic 11087 07:03:47,160 --> 07:03:51,040 convention and actually if I want to 11088 07:03:49,080 --> 07:03:53,280 clean this up a little bit right now 11089 07:03:51,040 --> 07:03:55,120 notice that my name variable doesn't 11090 07:03:53,280 --> 07:03:56,320 really need to exist because I'm 11091 07:03:55,120 --> 07:03:58,680 assigning it a value and then 11092 07:03:56,320 --> 07:04:00,680 immediately appending it well I could 11093 07:03:58,680 --> 07:04:03,200 tighten this up further by just getting 11094 07:04:00,680 --> 07:04:05,360 rid of that variable Al together and 11095 07:04:03,200 --> 07:04:07,680 just appending immediately the return 11096 07:04:05,360 --> 07:04:09,760 value of input I think we could go both 11097 07:04:07,680 --> 07:04:11,160 ways in terms of design here on the one 11098 07:04:09,760 --> 07:04:12,840 hand it's a pretty short line and it's 11099 07:04:11,160 --> 07:04:14,638 readable on the other hand if I were to 11100 07:04:12,840 --> 07:04:16,320 eventually change this phrase to be not 11101 07:04:14,638 --> 07:04:18,080 what's your name but something longer we 11102 07:04:16,320 --> 07:04:19,638 might want to break it out again into 11103 07:04:18,080 --> 07:04:22,160 two lines but for now I think it's 11104 07:04:19,638 --> 07:04:23,718 pretty readable now later in the program 11105 07:04:22,160 --> 07:04:25,680 let's just go ahead and print out those 11106 07:04:23,718 --> 07:04:27,920 same names but let's sort them 11107 07:04:25,680 --> 07:04:30,320 alphabetically so that it makes sense to 11108 07:04:27,920 --> 07:04:31,958 be gathering them all together then 11109 07:04:30,320 --> 07:04:33,638 sorting them and printing them so how 11110 07:04:31,958 --> 07:04:35,840 can I do that well in Python the 11111 07:04:33,638 --> 07:04:37,878 simplest way to sort a list in a loop is 11112 07:04:35,840 --> 07:04:41,320 probably to do something like this for 11113 07:04:37,878 --> 07:04:42,878 name in names but wait let's sort the 11114 07:04:41,320 --> 07:04:45,160 names first recall that there's a 11115 07:04:42,878 --> 07:04:47,878 function called sorted which will return 11116 07:04:45,160 --> 07:04:50,478 a sorted version of that list now let's 11117 07:04:47,878 --> 07:04:54,200 go ahead and print out uh an F string 11118 07:04:50,478 --> 07:04:56,160 that says again hello bracket name close 11119 07:04:54,200 --> 07:04:59,920 quote all right let me go ahead and run 11120 07:04:56,160 --> 07:05:02,000 this so Python ofn names. and let me go 11121 07:04:59,920 --> 07:05:05,680 ahead and type in a few names this how 11122 07:05:02,000 --> 07:05:08,040 about hermion how about Harry how about 11123 07:05:05,680 --> 07:05:10,798 Ron and notice that they're not quite in 11124 07:05:08,040 --> 07:05:12,760 alphabetical order but when I hit enter 11125 07:05:10,798 --> 07:05:15,200 and that Loop kicks in it's going to 11126 07:05:12,760 --> 07:05:18,360 print out hello Harry hello Hermione 11127 07:05:15,200 --> 07:05:20,520 hello Ron in sorted order but of course 11128 07:05:18,360 --> 07:05:22,600 now if I run this program again all of 11129 07:05:20,520 --> 07:05:24,080 the names are lost and if this is a 11130 07:05:22,600 --> 07:05:25,398 bigger program than this that might 11131 07:05:24,080 --> 07:05:27,398 actually be pretty painful to have to 11132 07:05:25,398 --> 07:05:29,558 re-input the same information again and 11133 07:05:27,398 --> 07:05:31,718 again and again wouldn't it be nice like 11134 07:05:29,558 --> 07:05:33,920 most any program today on a phone or or 11135 07:05:31,718 --> 07:05:37,680 a laptop or desktop or Cloud to be able 11136 07:05:33,920 --> 07:05:39,718 to save this information somehow instead 11137 07:05:37,680 --> 07:05:41,638 and that's where file IO comes in and 11138 07:05:39,718 --> 07:05:43,760 that's where Files come in they are a 11139 07:05:41,638 --> 07:05:46,040 way of storing information persistently 11140 07:05:43,760 --> 07:05:48,680 on your own phone or Mac or PC or some 11141 07:05:46,040 --> 07:05:50,200 Cloud servers uh disk so that they're 11142 07:05:48,680 --> 07:05:52,760 there when you come back and run the 11143 07:05:50,200 --> 07:05:56,200 program again so how can we go about 11144 07:05:52,760 --> 07:05:58,600 saving all three of these names on in a 11145 07:05:56,200 --> 07:06:00,680 file as opposed to having to type them 11146 07:05:58,600 --> 07:06:02,398 again and again let me go ahead and 11147 07:06:00,680 --> 07:06:04,558 simplify this file and again give myself 11148 07:06:02,398 --> 07:06:08,280 just a single variable called name and 11149 07:06:04,558 --> 07:06:10,160 set the return value of input equal to 11150 07:06:08,280 --> 07:06:12,920 that variable so what's your name as 11151 07:06:10,160 --> 07:06:15,040 before quote unquote and now let me go 11152 07:06:12,920 --> 07:06:17,120 ahead and let me do something more with 11153 07:06:15,040 --> 07:06:19,080 this value instead of just adding it to 11154 07:06:17,120 --> 07:06:21,000 a list or printing it immediately out 11155 07:06:19,080 --> 07:06:23,240 let's save the value of the person's 11156 07:06:21,000 --> 07:06:25,040 name that's just been typed in to a file 11157 07:06:23,240 --> 07:06:26,718 well how do we go about doing that well 11158 07:06:25,040 --> 07:06:28,520 in Python there's this function called 11159 07:06:26,718 --> 07:06:31,240 open whose purpose in life is to do just 11160 07:06:28,520 --> 07:06:33,280 that to open a file but to open it up 11161 07:06:31,240 --> 07:06:35,320 Pro grammatically so that you the 11162 07:06:33,280 --> 07:06:38,120 programmer can actually read information 11163 07:06:35,320 --> 07:06:39,878 from it or write information to it so 11164 07:06:38,120 --> 07:06:41,440 open is like the programmer's equivalent 11165 07:06:39,878 --> 07:06:44,040 of like double clicking on an icon on 11166 07:06:41,440 --> 07:06:45,440 your Mac or PC but it's a programmer's 11167 07:06:44,040 --> 07:06:47,398 technique because it's going to allow 11168 07:06:45,440 --> 07:06:50,638 you to specify exactly what you want to 11169 07:06:47,398 --> 07:06:52,878 read from or right to that file formally 11170 07:06:50,638 --> 07:06:54,600 its documentation is here and you'll see 11171 07:06:52,878 --> 07:06:56,000 that its usage is relatively 11172 07:06:54,600 --> 07:06:57,478 straightforward it minimally just 11173 07:06:56,000 --> 07:06:59,958 requires the name of the file that we 11174 07:06:57,478 --> 07:07:02,040 want to open and optionally how we want 11175 07:06:59,958 --> 07:07:04,120 to open it so let me go back back to vs 11176 07:07:02,040 --> 07:07:06,320 code here and let me propose now that I 11177 07:07:04,120 --> 07:07:08,760 do this I'm going to go ahead and call 11178 07:07:06,320 --> 07:07:11,398 this function called open passing in an 11179 07:07:08,760 --> 07:07:13,718 argument for names.txt which is the name 11180 07:07:11,398 --> 07:07:15,600 of the file I would like to store all of 11181 07:07:13,718 --> 07:07:17,080 these names in I could call it anything 11182 07:07:15,600 --> 07:07:18,878 I want but because it's going to be just 11183 07:07:17,080 --> 07:07:21,520 text it's conventional to call it 11184 07:07:18,878 --> 07:07:23,718 something. txt but I'm also going to 11185 07:07:21,520 --> 07:07:26,120 tell the open function that I plan to 11186 07:07:23,718 --> 07:07:27,600 write to this file so as a second 11187 07:07:26,120 --> 07:07:30,478 argument to open I'm going to put 11188 07:07:27,600 --> 07:07:32,520 literally quote unquote W for right and 11189 07:07:30,478 --> 07:07:34,080 that's going to tell open to open the 11190 07:07:32,520 --> 07:07:35,958 file in a way that's going to allow me 11191 07:07:34,080 --> 07:07:37,760 to change the content and better yet if 11192 07:07:35,958 --> 07:07:40,920 it doesn't even exist yet it's going to 11193 07:07:37,760 --> 07:07:43,478 create the file for me now open returns 11194 07:07:40,920 --> 07:07:45,478 what's called a file handle a special 11195 07:07:43,478 --> 07:07:47,000 value that allows me to access that file 11196 07:07:45,478 --> 07:07:49,080 subsequently so I'm going to go ahead 11197 07:07:47,000 --> 07:07:51,478 and sign it equal to a variable like 11198 07:07:49,080 --> 07:07:54,040 file and now I'm going to go ahead and 11199 07:07:51,478 --> 07:07:56,398 quite simply write this person's name to 11200 07:07:54,040 --> 07:07:59,878 that file so I'm going to literally type 11201 07:07:56,398 --> 07:08:02,840 file which is the variable uh linking to 11202 07:07:59,878 --> 07:08:04,520 that file WR which is a function 11203 07:08:02,840 --> 07:08:06,878 otherwise known as a method that comes 11204 07:08:04,520 --> 07:08:09,680 with open files that allows me to write 11205 07:08:06,878 --> 07:08:10,878 that name to the file and then lastly 11206 07:08:09,680 --> 07:08:12,760 I'm going to quite simply going to go 11207 07:08:10,878 --> 07:08:15,680 ahead and say file. close which will 11208 07:08:12,760 --> 07:08:16,958 close and effectively save the file so 11209 07:08:15,680 --> 07:08:18,520 these three lines of code here are 11210 07:08:16,958 --> 07:08:20,160 essentially the programmers equivalent 11211 07:08:18,520 --> 07:08:22,320 to like double clicking an icon on your 11212 07:08:20,160 --> 07:08:24,080 Mac or PC making some changes in 11213 07:08:22,320 --> 07:08:26,040 Microsoft Word or some other program and 11214 07:08:24,080 --> 07:08:29,000 going to file save we're doing that all 11215 07:08:26,040 --> 07:08:31,760 in code with just these three lines here 11216 07:08:29,000 --> 07:08:35,558 well let's see now how this works let me 11217 07:08:31,760 --> 07:08:39,040 go ahead now and run python of names. 11218 07:08:35,558 --> 07:08:43,398 piy and enter let's type in a name I'll 11219 07:08:39,040 --> 07:08:46,040 type in her Mayan enter all right where 11220 07:08:43,398 --> 07:08:49,360 did she end up well let me go ahead now 11221 07:08:46,040 --> 07:08:51,798 and type code of names.txt which is a 11222 07:08:49,360 --> 07:08:53,920 file that happens now to exist because I 11223 07:08:51,798 --> 07:08:56,120 opened it in right mode and if I open 11224 07:08:53,920 --> 07:08:58,080 this in a tab we'll see there is 11225 07:08:56,120 --> 07:09:00,280 Hermione well let's go ahead and run 11226 07:08:58,080 --> 07:09:04,000 names. py once more I'm going to go 11227 07:09:00,280 --> 07:09:06,280 ahead and run python of names. py enter 11228 07:09:04,000 --> 07:09:07,878 and this time I'll type in Harry let me 11229 07:09:06,280 --> 07:09:10,360 go ahead and run it one more time and 11230 07:09:07,878 --> 07:09:13,000 this time I'll type in Ron and now let 11231 07:09:10,360 --> 07:09:16,958 me go up to names. text where hopefully 11232 07:09:13,000 --> 07:09:18,798 I'll see all three of them here but no 11233 07:09:16,958 --> 07:09:22,040 I've just actually seen 11234 07:09:18,798 --> 07:09:24,000 Ron What might explain what happened to 11235 07:09:22,040 --> 07:09:25,958 Hermione and Harry even though I'm 11236 07:09:24,000 --> 07:09:28,160 pretty sure I ran the program three 11237 07:09:25,958 --> 07:09:31,520 times and I definitely wrote the code 11238 07:09:28,160 --> 07:09:33,878 that writes their name to that file 11239 07:09:31,520 --> 07:09:35,798 what's going on here do you think I 11240 07:09:33,878 --> 07:09:38,240 think because we are not appending them 11241 07:09:35,798 --> 07:09:40,760 we should append the names uh since we 11242 07:09:38,240 --> 07:09:43,600 are writing directly it is erasing the 11243 07:09:40,760 --> 07:09:47,520 old content and it is replacing with the 11244 07:09:43,600 --> 07:09:49,840 last uh um set of characters that we 11245 07:09:47,520 --> 07:09:51,798 mentioned exactly unfortunately quote 11246 07:09:49,840 --> 07:09:53,718 unquote W is a little dangerous not only 11247 07:09:51,798 --> 07:09:56,120 will it create the file for you it will 11248 07:09:53,718 --> 07:09:57,920 also recreate the file for you every 11249 07:09:56,120 --> 07:09:59,478 time you open the file in that mode so 11250 07:09:57,920 --> 07:10:01,798 if you open the file once and write 11251 07:09:59,478 --> 07:10:03,200 Hermione that worked just fine as we saw 11252 07:10:01,798 --> 07:10:05,320 but if you do it again for Harry if you 11253 07:10:03,200 --> 07:10:07,160 do it again for Ron the code is working 11254 07:10:05,320 --> 07:10:09,760 but each time it's opening the file and 11255 07:10:07,160 --> 07:10:11,478 recreating it with brand new contents so 11256 07:10:09,760 --> 07:10:13,200 we had one version with Hermione one 11257 07:10:11,478 --> 07:10:15,440 version with Harry and one final version 11258 07:10:13,200 --> 07:10:17,718 with Ron but ideally I think we probably 11259 07:10:15,440 --> 07:10:19,840 want to be appending as bashall says 11260 07:10:17,718 --> 07:10:22,160 each of those names to the file not just 11261 07:10:19,840 --> 07:10:23,878 clobbering that is overwriting the file 11262 07:10:22,160 --> 07:10:26,280 each time so how can I do this it's 11263 07:10:23,878 --> 07:10:27,920 actually a relatively easy fix let me go 11264 07:10:26,280 --> 07:10:29,718 ahead and do this as follows I'm going 11265 07:10:27,920 --> 07:10:32,280 to first remove the old version of 11266 07:10:29,718 --> 07:10:34,440 names. text and now I'm going to change 11267 07:10:32,280 --> 07:10:37,398 my code to do this I'm going to change 11268 07:10:34,440 --> 07:10:39,760 the W quote unquote to just a quote 11269 07:10:37,398 --> 07:10:41,320 unquote a for aend which means to add to 11270 07:10:39,760 --> 07:10:43,360 the bottom to the bottom to the bottom 11271 07:10:41,320 --> 07:10:46,920 again and again now let me go ahead and 11272 07:10:43,360 --> 07:10:49,280 rerun python of names. piy enter I'll 11273 07:10:46,920 --> 07:10:52,120 again start from scratch with hermion 11274 07:10:49,280 --> 07:10:56,558 because I'm creating the file new notice 11275 07:10:52,120 --> 07:10:59,360 that if I now do code of names.txt enter 11276 07:10:56,558 --> 07:11:01,320 we do see that hermion is back so we've 11277 07:10:59,360 --> 07:11:03,160 after removing the file it did get Rec 11278 07:11:01,320 --> 07:11:04,878 created even though I'm using a pend 11279 07:11:03,160 --> 07:11:07,760 which is good but now let's see what 11280 07:11:04,878 --> 07:11:10,080 happens when I go back to my terminal 11281 07:11:07,760 --> 07:11:12,440 and this time I run python of names. py 11282 07:11:10,080 --> 07:11:14,680 again this time typing in Harry and let 11283 07:11:12,440 --> 07:11:16,840 me run it one more time this time typing 11284 07:11:14,680 --> 07:11:18,718 in Ron so hopefully this time in that 11285 07:11:16,840 --> 07:11:22,398 second tab names. text I should now see 11286 07:11:18,718 --> 07:11:26,000 all three of them but but but but this 11287 07:11:22,398 --> 07:11:27,680 doesn't look ideal what have I clearly 11288 07:11:26,000 --> 07:11:30,000 done 11289 07:11:27,680 --> 07:11:31,520 wrong something tells me even though all 11290 07:11:30,000 --> 07:11:33,478 three names are there it's not going to 11291 07:11:31,520 --> 07:11:37,080 be easy to read those back unless you 11292 07:11:33,478 --> 07:11:40,798 know where each name ends and Begins the 11293 07:11:37,080 --> 07:11:43,000 English format is not correct like the 11294 07:11:40,798 --> 07:11:46,120 English format is not correct like it's 11295 07:11:43,000 --> 07:11:49,080 say correct it's concatenating them it 11296 07:11:46,120 --> 07:11:51,120 is it's it's in can it's well it appears 11297 07:11:49,080 --> 07:11:53,520 to be concatenating but technically 11298 07:11:51,120 --> 07:11:56,080 speaking it's just a pending to the file 11299 07:11:53,520 --> 07:11:57,840 first Hermione then Harry then Ron it 11300 07:11:56,080 --> 07:11:59,398 has the effect of combining them back to 11301 07:11:57,840 --> 07:12:01,600 back but it's not concatenating per se 11302 07:11:59,398 --> 07:12:04,040 it really is just a pending let's go to 11303 07:12:01,600 --> 07:12:07,280 another hand here what really have I 11304 07:12:04,040 --> 07:12:10,398 done wrong or equivalently how might I 11305 07:12:07,280 --> 07:12:12,200 fix it would be nice if there were some 11306 07:12:10,398 --> 07:12:15,360 kind of gaps between each of the names 11307 07:12:12,200 --> 07:12:19,080 so we could read them more cleanly Hello 11308 07:12:15,360 --> 07:12:21,718 uh we should uh add new line before we 11309 07:12:19,080 --> 07:12:23,680 uh write new name good we want to add a 11310 07:12:21,718 --> 07:12:25,680 new line ourselves so whereas print by 11311 07:12:23,680 --> 07:12:28,200 default recall always outputs 11312 07:12:25,680 --> 07:12:30,160 automatically a line ending of back sln 11313 07:12:28,200 --> 07:12:32,680 unless we override it with the named 11314 07:12:30,160 --> 07:12:34,320 parameter called n and right does not do 11315 07:12:32,680 --> 07:12:36,600 that right takes you literally and if 11316 07:12:34,320 --> 07:12:38,558 you say WR Hermione that's it you're 11317 07:12:36,600 --> 07:12:41,040 getting the H through the E if you say 11318 07:12:38,558 --> 07:12:43,080 right hairry you get the H through the Y 11319 07:12:41,040 --> 07:12:45,798 you don't get any extra new lines 11320 07:12:43,080 --> 07:12:47,638 automatically so if you want to have a 11321 07:12:45,798 --> 07:12:49,398 new line at the end of each of these 11322 07:12:47,638 --> 07:12:51,718 names we've got to do that manually so 11323 07:12:49,398 --> 07:12:54,200 let me again Clos names. text and let me 11324 07:12:51,718 --> 07:12:55,958 remove the current file and let me go 11325 07:12:54,200 --> 07:12:57,398 back up to my code here and I can fix 11326 07:12:55,958 --> 07:12:58,878 this in any number of ways but I'm just 11327 07:12:57,398 --> 07:13:01,398 going to go ahead and do this I'm going 11328 07:12:58,878 --> 07:13:04,320 to write out an F string that contains 11329 07:13:01,398 --> 07:13:06,000 name and back sln at the end we could do 11330 07:13:04,320 --> 07:13:07,878 this in different ways we could manually 11331 07:13:06,000 --> 07:13:09,398 print just the new line or some other 11332 07:13:07,878 --> 07:13:11,120 technique but I'm going to go ahead and 11333 07:13:09,398 --> 07:13:12,840 use my f strings as I'm in the habit of 11334 07:13:11,120 --> 07:13:14,958 doing and just print the name and the 11335 07:13:12,840 --> 07:13:16,638 new line all at once I'm going to go 11336 07:13:14,958 --> 07:13:19,558 ahead now and down to my terminal window 11337 07:13:16,638 --> 07:13:21,520 run python of names. py again enter 11338 07:13:19,558 --> 07:13:23,680 we'll type in Hermione I'm going to run 11339 07:13:21,520 --> 07:13:26,320 it again type in Harry I'm going to type 11340 07:13:23,680 --> 07:13:29,320 it again and this time Ron now I'm going 11341 07:13:26,320 --> 07:13:32,398 to run code of names.txt and open that 11342 07:13:29,320 --> 07:13:33,958 file and now it looks like the file is a 11343 07:13:32,398 --> 07:13:36,320 bit cleaner indeed I have each of the 11344 07:13:33,958 --> 07:13:38,878 name on its own line as well as a line 11345 07:13:36,320 --> 07:13:41,520 ending which ensures that uh we can 11346 07:13:38,878 --> 07:13:44,200 separate one from the other now if I 11347 07:13:41,520 --> 07:13:46,240 were you know writing code I bet I could 11348 07:13:44,200 --> 07:13:48,040 parse that is read the previous file by 11349 07:13:46,240 --> 07:13:49,320 looking at differences between lowercase 11350 07:13:48,040 --> 07:13:51,440 and uppercase letters but that's going 11351 07:13:49,320 --> 07:13:54,040 to get messy quickly generally speaking 11352 07:13:51,440 --> 07:13:55,760 when storing data longterm in a file you 11353 07:13:54,040 --> 07:13:58,478 should probably do it somehow cleanly 11354 07:13:55,760 --> 07:14:00,320 like doing one name at a time well let's 11355 07:13:58,478 --> 07:14:02,000 now go back and I I'll propose that this 11356 07:14:00,320 --> 07:14:04,160 code is now working correctly but we can 11357 07:14:02,000 --> 07:14:06,160 design it a little bit better it turns 11358 07:14:04,160 --> 07:14:08,718 out that it's all too easy when writing 11359 07:14:06,160 --> 07:14:10,478 code to sometimes forget to close files 11360 07:14:08,718 --> 07:14:12,200 and sometimes this isn't necessarily a 11361 07:14:10,478 --> 07:14:13,920 big deal but sometimes it can create 11362 07:14:12,200 --> 07:14:15,440 problems files could get corrupted or 11363 07:14:13,920 --> 07:14:17,280 accidentally deleted or the like 11364 07:14:15,440 --> 07:14:18,840 depending on what happens in your code 11365 07:14:17,280 --> 07:14:21,878 so it turns out that you don't strictly 11366 07:14:18,840 --> 07:14:23,958 need to call close on the file yourself 11367 07:14:21,878 --> 07:14:27,080 if you take another approach instead 11368 07:14:23,958 --> 07:14:30,080 more pythonic when M uh manipulating 11369 07:14:27,080 --> 07:14:33,360 files is to do this to introduce this 11370 07:14:30,080 --> 07:14:35,718 other keyword called quite simply with 11371 07:14:33,360 --> 07:14:38,000 that allows you to specify that in this 11372 07:14:35,718 --> 07:14:40,760 context I want you to open and 11373 07:14:38,000 --> 07:14:43,080 automatically close some file so how do 11374 07:14:40,760 --> 07:14:44,920 we use with it simply looks like this 11375 07:14:43,080 --> 07:14:47,160 let me go back to my code here I've 11376 07:14:44,920 --> 07:14:48,958 gotten rid of the close line and I'm now 11377 07:14:47,160 --> 07:14:51,638 just going to say this instead instead 11378 07:14:48,958 --> 07:14:55,080 of saying file equals open I'm going to 11379 07:14:51,638 --> 07:14:57,120 say with open then the same arguments as 11380 07:14:55,080 --> 07:14:58,798 before and somewhat curiously I'm going 11381 07:14:57,120 --> 07:15:00,798 to put the variable at the end of the 11382 07:14:58,798 --> 07:15:03,398 line why that's just the way this is 11383 07:15:00,798 --> 07:15:05,600 done you say with you call the function 11384 07:15:03,398 --> 07:15:07,320 in question and then you say as and 11385 07:15:05,600 --> 07:15:09,680 specify the name of the variable that 11386 07:15:07,320 --> 07:15:11,240 should be assigned the return value of 11387 07:15:09,680 --> 07:15:13,478 open then I'm going to go ahead and 11388 07:15:11,240 --> 07:15:15,680 indent the line underneath so that the 11389 07:15:13,478 --> 07:15:18,000 line of code that's writing the name is 11390 07:15:15,680 --> 07:15:20,000 now in the context of this withth 11391 07:15:18,000 --> 07:15:22,440 statement which just ensures that 11392 07:15:20,000 --> 07:15:25,240 automatically if I had more code in this 11393 07:15:22,440 --> 07:15:27,320 file down below no longer indented the 11394 07:15:25,240 --> 07:15:29,558 file would be automatically closed as 11395 07:15:27,320 --> 07:15:31,360 soon as line four is done executing so 11396 07:15:29,558 --> 07:15:32,798 it doesn't change what has just happen 11397 07:15:31,360 --> 07:15:34,600 but it does automate the process of at 11398 07:15:32,798 --> 07:15:35,958 least closing things for us just to 11399 07:15:34,600 --> 07:15:39,600 ensure I don't forget and so that 11400 07:15:35,958 --> 07:15:42,120 something doesn't go wrong but suppose 11401 07:15:39,600 --> 07:15:43,840 now that I wanted to read these names 11402 07:15:42,120 --> 07:15:45,760 from the file all I've done thus far is 11403 07:15:43,840 --> 07:15:47,760 write code that writes names to the file 11404 07:15:45,760 --> 07:15:49,600 but let's assume now that we have all of 11405 07:15:47,760 --> 07:15:51,478 these names in the file and heck let's 11406 07:15:49,600 --> 07:15:53,320 go ahead and add one more let me go 11407 07:15:51,478 --> 07:15:56,360 ahead and run this one more time python 11408 07:15:53,320 --> 07:15:58,320 of names. py and let's let in Draco to 11409 07:15:56,360 --> 07:16:01,120 the mix so now that we have all four of 11410 07:15:58,320 --> 07:16:03,160 these names here how might we want to re 11411 07:16:01,120 --> 07:16:05,120 them back well let me propose that we go 11412 07:16:03,160 --> 07:16:06,558 into names. now or we could create 11413 07:16:05,120 --> 07:16:08,160 another program Al together but I'm 11414 07:16:06,558 --> 07:16:10,478 going to keep reusing the same name just 11415 07:16:08,160 --> 07:16:12,360 to keep us focused on this and now I'm 11416 07:16:10,478 --> 07:16:16,398 going to write code that reads an 11417 07:16:12,360 --> 07:16:18,920 existing file with Hermione Harry Ron 11418 07:16:16,398 --> 07:16:20,680 and Draco together and how do I do this 11419 07:16:18,920 --> 07:16:23,638 well it's similar in spirit I'm going to 11420 07:16:20,680 --> 07:16:24,878 start this time with with open and then 11421 07:16:23,638 --> 07:16:26,600 the first argument is going to be the 11422 07:16:24,878 --> 07:16:28,680 name of the file that I want to open as 11423 07:16:26,600 --> 07:16:31,240 before and I'm going to open it this 11424 07:16:28,680 --> 07:16:33,638 time in read mode quote unquote r and to 11425 07:16:31,240 --> 07:16:36,478 read a file just means to load it not to 11426 07:16:33,638 --> 07:16:38,878 save it and I'm going to name the return 11427 07:16:36,478 --> 07:16:40,320 value file and now I'm going to do this 11428 07:16:38,878 --> 07:16:42,080 and there's a number of ways I can do 11429 07:16:40,320 --> 07:16:43,840 this but one way to read all of the 11430 07:16:42,080 --> 07:16:45,760 lines from the file at once would be 11431 07:16:43,840 --> 07:16:48,680 this let me declare a variable called 11432 07:16:45,760 --> 07:16:50,638 lines let me access that file and call a 11433 07:16:48,680 --> 07:16:52,718 function or a method that comes with it 11434 07:16:50,638 --> 07:16:54,958 called read lines so if you read the 11435 07:16:52,718 --> 07:16:57,160 documentation on file IO in Python 11436 07:16:54,958 --> 07:16:59,040 you'll see that open files come with a 11437 07:16:57,160 --> 07:17:01,398 special method whose purpose in life is 11438 07:16:59,040 --> 07:17:04,200 to read all the lines from the file 11439 07:17:01,398 --> 07:17:06,080 and return them to me as a list so what 11440 07:17:04,200 --> 07:17:08,320 this line two is doing is it's reading 11441 07:17:06,080 --> 07:17:10,958 all of the lines from that file storing 11442 07:17:08,320 --> 07:17:12,600 them in a variable called lines now 11443 07:17:10,958 --> 07:17:14,398 suppose I want to iterate over all of 11444 07:17:12,600 --> 07:17:17,440 those lines and print out each of those 11445 07:17:14,398 --> 07:17:20,638 names for line in lines this is just a 11446 07:17:17,440 --> 07:17:22,760 standard for Loop in Python lines is a 11447 07:17:20,638 --> 07:17:24,638 list line is the variable that will be 11448 07:17:22,760 --> 07:17:26,398 automatically be set to each of those 11449 07:17:24,638 --> 07:17:30,120 lines let me go ahead and print out 11450 07:17:26,398 --> 07:17:33,280 something like oh hello uh comma and 11451 07:17:30,120 --> 07:17:35,558 then I'll print out the line itself all 11452 07:17:33,280 --> 07:17:38,600 right so let me go to my terminal window 11453 07:17:35,558 --> 07:17:41,160 run python of names. py now I have not 11454 07:17:38,600 --> 07:17:43,520 deleted names.txt so it still contains 11455 07:17:41,160 --> 07:17:46,638 all four of those names and hit enter 11456 07:17:43,520 --> 07:17:50,160 and okay it's not bad but it's a little 11457 07:17:46,638 --> 07:17:52,280 ugly here what's going on when I ran 11458 07:17:50,160 --> 07:17:54,240 names. py it's saying hello to hermion 11459 07:17:52,280 --> 07:17:57,120 to Harry to Ron to Draco but there's 11460 07:17:54,240 --> 07:18:00,840 these gaps now between the 11461 07:17:57,120 --> 07:18:02,798 lines what's explains that symptom if if 11462 07:18:00,840 --> 07:18:05,280 nothing else it just looks ugly it 11463 07:18:02,798 --> 07:18:08,320 happens because in the text file we have 11464 07:18:05,280 --> 07:18:11,760 a new line symbols uh in between those 11465 07:18:08,320 --> 07:18:14,760 names and the print always adds another 11466 07:18:11,760 --> 07:18:17,320 new line at the end so you you use the 11467 07:18:14,760 --> 07:18:19,160 same symbol twice perfect and here's a 11468 07:18:17,320 --> 07:18:20,760 good example of a bug a mistake in a 11469 07:18:19,160 --> 07:18:23,120 program but if you just think about 11470 07:18:20,760 --> 07:18:25,520 those first principles like how do each 11471 07:18:23,120 --> 07:18:26,920 of the lines of code work that I'm using 11472 07:18:25,520 --> 07:18:28,520 you should be able to reason exactly as 11473 07:18:26,920 --> 07:18:29,798 Rafal did there to say that all right 11474 07:18:28,520 --> 07:18:32,080 well one of those new lines is coming 11475 07:18:29,798 --> 07:18:33,958 from the file after each name and then 11476 07:18:32,080 --> 07:18:36,040 of course print all of these Weeks Later 11477 07:18:33,958 --> 07:18:38,000 is still giving us for free that extra 11478 07:18:36,040 --> 07:18:40,240 new line so there's a couple possible 11479 07:18:38,000 --> 07:18:41,840 solutions I could certainly do this 11480 07:18:40,240 --> 07:18:43,840 which we've done in the past and pass in 11481 07:18:41,840 --> 07:18:46,798 a named argument to print like end 11482 07:18:43,840 --> 07:18:48,440 equals quote unquote and that's fine I 11483 07:18:46,798 --> 07:18:50,440 would argue a little better than that 11484 07:18:48,440 --> 07:18:53,240 might actually be to do this to strip 11485 07:18:50,440 --> 07:18:55,240 off of the end of the line the actual 11486 07:18:53,240 --> 07:18:57,200 new line itself so that print is 11487 07:18:55,240 --> 07:18:59,478 handling the printing of everything the 11488 07:18:57,200 --> 07:19:01,360 person's name as well as the new line 11489 07:18:59,478 --> 07:19:03,360 but you're just stripping off what is 11490 07:19:01,360 --> 07:19:05,798 really just an implementation detail in 11491 07:19:03,360 --> 07:19:08,040 the file we chose to use new lines in my 11492 07:19:05,798 --> 07:19:10,320 text file to separate one name from 11493 07:19:08,040 --> 07:19:12,360 another so arguably it should be a 11494 07:19:10,320 --> 07:19:14,718 little cleaner in terms of design to 11495 07:19:12,360 --> 07:19:16,840 strip that off and then let print print 11496 07:19:14,718 --> 07:19:18,360 out what is really just now a name but 11497 07:19:16,840 --> 07:19:21,718 that's ultimately a design decision the 11498 07:19:18,360 --> 07:19:24,680 effect is going to be exactly the same 11499 07:19:21,718 --> 07:19:27,120 well if I'm going to open this file and 11500 07:19:24,680 --> 07:19:28,718 read all the lines and then iterate over 11501 07:19:27,120 --> 07:19:30,440 all of those lines and print them each 11502 07:19:28,718 --> 07:19:32,440 out I could actually combine this into 11503 07:19:30,440 --> 07:19:34,080 one thing because right now I'm doing 11504 07:19:32,440 --> 07:19:36,680 twice as much work I'm reading all of 11505 07:19:34,080 --> 07:19:39,440 the lines then I'm iterating over all of 11506 07:19:36,680 --> 07:19:41,240 the lines just to print out each of them 11507 07:19:39,440 --> 07:19:42,840 well in Python with files you can 11508 07:19:41,240 --> 07:19:45,080 actually do this I'm going to erase 11509 07:19:42,840 --> 07:19:47,718 almost all of these lines now keeping 11510 07:19:45,080 --> 07:19:49,638 only the width statement at top and 11511 07:19:47,718 --> 07:19:53,798 inside of this width statement I'm going 11512 07:19:49,638 --> 07:19:56,440 to say this for line in file go ahead 11513 07:19:53,798 --> 07:19:58,718 and print out quote unquote hello comma 11514 07:19:56,440 --> 07:20:00,040 and then line. rstrip so I'm going to 11515 07:19:58,718 --> 07:20:01,200 take the approach of stripping off the 11516 07:20:00,040 --> 07:20:03,798 end of the line 11517 07:20:01,200 --> 07:20:06,600 but notice how elegant this is so to 11518 07:20:03,798 --> 07:20:08,398 speak I've opened the file in line one 11519 07:20:06,600 --> 07:20:10,240 and if I want to iterate over every line 11520 07:20:08,398 --> 07:20:12,600 in the file I don't have to very 11521 07:20:10,240 --> 07:20:14,320 explicitly load all read all the lines 11522 07:20:12,600 --> 07:20:16,200 then iterate over all of the lines I can 11523 07:20:14,320 --> 07:20:18,718 combine this into one thought it in 11524 07:20:16,200 --> 07:20:20,240 Python you can simply say for line in 11525 07:20:18,718 --> 07:20:21,718 file and that's going to have the effect 11526 07:20:20,240 --> 07:20:23,958 of giving you a for Loop that iterates 11527 07:20:21,718 --> 07:20:26,200 over every line in the file one at a 11528 07:20:23,958 --> 07:20:28,680 time and on each iteration updating the 11529 07:20:26,200 --> 07:20:32,360 value of this variable line to be 11530 07:20:28,680 --> 07:20:34,440 Hermione then Harry then Ron than Draco 11531 07:20:32,360 --> 07:20:35,958 so this again is one of the appealing 11532 07:20:34,440 --> 07:20:38,280 aspects of python is that it reads 11533 07:20:35,958 --> 07:20:41,200 rather like English for line and file 11534 07:20:38,280 --> 07:20:43,320 print this it's a little more compact 11535 07:20:41,200 --> 07:20:45,878 when written this way well what if 11536 07:20:43,320 --> 07:20:47,440 though I don't want quite this Behavior 11537 07:20:45,878 --> 07:20:50,398 because notice now if I run python of 11538 07:20:47,440 --> 07:20:52,398 names. piy it's correct I'm seeing each 11539 07:20:50,398 --> 07:20:55,120 of the names and each of the hos and 11540 07:20:52,398 --> 07:20:58,000 there's no Extra Spaces in between but 11541 07:20:55,120 --> 07:21:00,240 just to be difficult I'd really like us 11542 07:20:58,000 --> 07:21:02,680 to be sorting these hellos really I'd 11543 07:21:00,240 --> 07:21:04,878 like to Draco first then Harry then 11544 07:21:02,680 --> 07:21:07,040 Hermione then Ron no matter what order 11545 07:21:04,878 --> 07:21:08,638 they appear in the file so I could go in 11546 07:21:07,040 --> 07:21:09,958 of course to the file and manually 11547 07:21:08,638 --> 07:21:11,920 change the file but if that file is 11548 07:21:09,958 --> 07:21:13,520 changing over time based on who is 11549 07:21:11,920 --> 07:21:15,040 typing their name into the program 11550 07:21:13,520 --> 07:21:16,558 that's not really a good solution in 11551 07:21:15,040 --> 07:21:18,398 code I should be able to load the file 11552 07:21:16,558 --> 07:21:22,000 no matter what it looks like and just 11553 07:21:18,398 --> 07:21:25,478 sort it all at once now here is a reason 11554 07:21:22,000 --> 07:21:27,958 to not do what I've just done I can't 11555 07:21:25,478 --> 07:21:30,000 iterate over each line in the file and 11556 07:21:27,958 --> 07:21:32,040 print it out but sort everything in 11557 07:21:30,000 --> 07:21:34,398 advance right logically if I'm looking 11558 07:21:32,040 --> 07:21:37,000 at each line one at a time and printing 11559 07:21:34,398 --> 07:21:38,760 it out it's too late to sort I really 11560 07:21:37,000 --> 07:21:41,638 need to read all of the lines first 11561 07:21:38,760 --> 07:21:43,080 without printing them sort them then 11562 07:21:41,638 --> 07:21:44,760 print them so we have to take a step 11563 07:21:43,080 --> 07:21:47,000 back in order to add now this new 11564 07:21:44,760 --> 07:21:49,760 feature so how can I do this well let me 11565 07:21:47,000 --> 07:21:51,840 combine some ideas from before let me go 11566 07:21:49,760 --> 07:21:54,200 ahead and start fresh with this let me 11567 07:21:51,840 --> 07:21:56,600 give myself a list called names and 11568 07:21:54,200 --> 07:21:58,600 assign it in empty list just so I have a 11569 07:21:56,600 --> 07:22:01,040 variable in which to accumulate all of 11570 07:21:58,600 --> 07:22:04,000 these lines and now let me open the file 11571 07:22:01,040 --> 07:22:05,440 with open quote unquote names. text and 11572 07:22:04,000 --> 07:22:06,840 it turns out I can tighten this up a 11573 07:22:05,440 --> 07:22:08,878 little bit it turns out if you're 11574 07:22:06,840 --> 07:22:11,200 opening a file to read it you don't need 11575 07:22:08,878 --> 07:22:13,160 to specify quote unquote r that is the 11576 07:22:11,200 --> 07:22:15,120 implicit default so you can tighten 11577 07:22:13,160 --> 07:22:16,878 things up by just saying open names. 11578 07:22:15,120 --> 07:22:18,440 text and you'll be able to read the file 11579 07:22:16,878 --> 07:22:21,000 but not write it I'm going to give 11580 07:22:18,440 --> 07:22:23,000 myself a variable called file as before 11581 07:22:21,000 --> 07:22:25,360 I am going to iterate over the file in 11582 07:22:23,000 --> 07:22:27,878 the same way for line in file but 11583 07:22:25,360 --> 07:22:30,280 instead of printing each line I'm going 11584 07:22:27,878 --> 07:22:32,958 to do this I'm going to take my name's 11585 07:22:30,280 --> 07:22:35,520 list list and append to it and this is 11586 07:22:32,958 --> 07:22:38,080 appending to a list in memory not 11587 07:22:35,520 --> 07:22:40,120 appending to the file itself I'm going 11588 07:22:38,080 --> 07:22:42,120 to go ahead and append the current line 11589 07:22:40,120 --> 07:22:43,958 but I'm going to strip off the new line 11590 07:22:42,120 --> 07:22:47,240 at the end so that all I'm adding to 11591 07:22:43,958 --> 07:22:49,000 this list is each of the students names 11592 07:22:47,240 --> 07:22:51,520 now I can use that familiar technique 11593 07:22:49,000 --> 07:22:53,200 from before let me go outside of this 11594 07:22:51,520 --> 07:22:55,200 with statement because now I've read the 11595 07:22:53,200 --> 07:22:57,920 entire file presumably so by the time 11596 07:22:55,200 --> 07:22:59,360 I'm done with lines four and five again 11597 07:22:57,920 --> 07:23:01,638 and again and again for each line in the 11598 07:22:59,360 --> 07:23:03,440 file I'm done with the file it can close 11599 07:23:01,638 --> 07:23:06,478 I now have all of the students names in 11600 07:23:03,440 --> 07:23:10,680 this list variable let me do this for 11601 07:23:06,478 --> 07:23:13,318 name in not just names but the sorted 11602 07:23:10,680 --> 07:23:15,718 names using our python function sorted 11603 07:23:13,318 --> 07:23:18,440 which does just that and do print quote 11604 07:23:15,718 --> 07:23:21,600 unquote with an FST string hello comma 11605 07:23:18,440 --> 07:23:24,520 and now I'll plug in bracket name so now 11606 07:23:21,600 --> 07:23:26,080 what have I done I'm creating a list at 11607 07:23:24,520 --> 07:23:28,798 the beginning just so I have a place to 11608 07:23:26,080 --> 07:23:30,638 gather my data I then on lines 3 through 11609 07:23:28,798 --> 07:23:32,958 five iterate over the file from Top top 11610 07:23:30,638 --> 07:23:34,360 to bottom reading in each line one at a 11611 07:23:32,958 --> 07:23:35,958 time stripping off the new line and 11612 07:23:34,360 --> 07:23:38,200 adding just the students name to this 11613 07:23:35,958 --> 07:23:40,798 list and the reason I'm doing that is so 11614 07:23:38,200 --> 07:23:42,360 that on line seven I can sort all of 11615 07:23:40,798 --> 07:23:45,200 those names now that they're all in 11616 07:23:42,360 --> 07:23:47,160 memory and print them in order I need to 11617 07:23:45,200 --> 07:23:49,120 load them all into memory before I can 11618 07:23:47,160 --> 07:23:50,920 sort them otherwise I'd be printing them 11619 07:23:49,120 --> 07:23:53,318 out prematurely and Draco would end up 11620 07:23:50,920 --> 07:23:55,120 last instead of first so let me go ahead 11621 07:23:53,318 --> 07:23:58,240 in my terminal window and run python of 11622 07:23:55,120 --> 07:24:01,398 names. py now and hit enter and there we 11623 07:23:58,240 --> 07:24:03,280 go the same list of four hellos but now 11624 07:24:01,398 --> 07:24:05,240 they're sorted and this is a very common 11625 07:24:03,280 --> 07:24:06,840 technique when dealing with files and 11626 07:24:05,240 --> 07:24:09,478 information more generally if you want 11627 07:24:06,840 --> 07:24:11,760 to change that data in some way like 11628 07:24:09,478 --> 07:24:13,280 sorting it creating some kind of 11629 07:24:11,760 --> 07:24:15,680 variable at the top of your program like 11630 07:24:13,280 --> 07:24:17,958 a list adding or appending information 11631 07:24:15,680 --> 07:24:19,840 to it just to collect it in one place 11632 07:24:17,958 --> 07:24:22,280 and then do something interesting with 11633 07:24:19,840 --> 07:24:24,360 that collection that list is exactly 11634 07:24:22,280 --> 07:24:26,160 what I've done here now I should note 11635 07:24:24,360 --> 07:24:28,120 that if we just want to sort the file we 11636 07:24:26,160 --> 07:24:30,160 can actually do this even more simply in 11637 07:24:28,120 --> 07:24:32,920 Python particularly by not bothering 11638 07:24:30,160 --> 07:24:34,398 with this names list nor the second for 11639 07:24:32,920 --> 07:24:36,398 Loop and let me go ahead and instead 11640 07:24:34,398 --> 07:24:38,200 just do more simply this let me go ahead 11641 07:24:36,398 --> 07:24:40,360 and tell python that we want the file 11642 07:24:38,200 --> 07:24:42,318 itself to be sorted using that same 11643 07:24:40,360 --> 07:24:44,680 sorted function but this time on the 11644 07:24:42,318 --> 07:24:46,040 file itself and then inside of that for 11645 07:24:44,680 --> 07:24:48,718 Loop let's just go ahead and print right 11646 07:24:46,040 --> 07:24:50,760 away our hello comma followed by the 11647 07:24:48,718 --> 07:24:53,478 line itself but still stripping off of 11648 07:24:50,760 --> 07:24:55,280 the end of it any white space therein if 11649 07:24:53,478 --> 07:24:57,360 we go ahead and run this same program 11650 07:24:55,280 --> 07:24:59,120 now with python of names. py and hit 11651 07:24:57,360 --> 07:25:01,080 enter we get the same result but of 11652 07:24:59,120 --> 07:25:02,718 course it's a lot more compact 11653 07:25:01,080 --> 07:25:05,120 but for the sake of discussion let's 11654 07:25:02,718 --> 07:25:06,760 assume that we do actually want to 11655 07:25:05,120 --> 07:25:08,478 potentially make some changes to the 11656 07:25:06,760 --> 07:25:10,520 data as we iterate over it so let me 11657 07:25:08,478 --> 07:25:12,558 undo those changes leave things as is 11658 07:25:10,520 --> 07:25:14,600 whereby now we'll continue to accumulate 11659 07:25:12,558 --> 07:25:16,040 all of the names first into a list maybe 11660 07:25:14,600 --> 07:25:17,718 do something to them maybe forcing them 11661 07:25:16,040 --> 07:25:20,798 to uppercase or lower case or the like 11662 07:25:17,718 --> 07:25:22,040 and then sort and print out each item 11663 07:25:20,798 --> 07:25:24,280 let me pause and see if there's any 11664 07:25:22,040 --> 07:25:27,958 questions now on file IO reading or 11665 07:25:24,280 --> 07:25:30,840 writing or now accumulating all of these 11666 07:25:27,958 --> 07:25:33,760 values in some list hi it's is there a 11667 07:25:30,840 --> 07:25:36,958 way to sort the files but instead if you 11668 07:25:33,760 --> 07:25:39,798 want it from alphabetically from A to Z 11669 07:25:36,958 --> 07:25:41,398 is there a way to reverse it from Z to A 11670 07:25:39,798 --> 07:25:42,798 is there like a little extension that 11671 07:25:41,398 --> 07:25:45,120 you can add to the end to do that or 11672 07:25:42,798 --> 07:25:46,920 would you have to create a new function 11673 07:25:45,120 --> 07:25:49,600 if you wanted to reverse the contents of 11674 07:25:46,920 --> 07:25:51,718 the file yeah so if you instead of 11675 07:25:49,600 --> 07:25:53,920 sorting them from a to z in ascending 11676 07:25:51,718 --> 07:25:57,000 order if you wanted them in descending 11677 07:25:53,920 --> 07:25:59,280 order is there an extension for that 11678 07:25:57,000 --> 07:26:00,958 there is indeed and as always the 11679 07:25:59,280 --> 07:26:02,798 documentation is your friend so if the 11680 07:26:00,958 --> 07:26:04,120 goal is to sort them not in alphabetical 11681 07:26:02,798 --> 07:26:06,040 order which is the default but maybe 11682 07:26:04,120 --> 07:26:07,760 reverse alphabetical order you can take 11683 07:26:06,040 --> 07:26:09,718 a look for instance at the formal python 11684 07:26:07,760 --> 07:26:11,558 documentation there and what you'll see 11685 07:26:09,718 --> 07:26:13,718 is this summary you'll see that the 11686 07:26:11,558 --> 07:26:15,760 sorted function takes a first argument 11687 07:26:13,718 --> 07:26:17,200 generally known as an iterable and 11688 07:26:15,760 --> 07:26:19,240 something that's iterable means that you 11689 07:26:17,200 --> 07:26:21,398 can iterate over it that is you can Loop 11690 07:26:19,240 --> 07:26:23,240 over it one thing at a time what the 11691 07:26:21,398 --> 07:26:25,280 rest of this line here means is that you 11692 07:26:23,240 --> 07:26:27,318 can specify a key like how you want to 11693 07:26:25,280 --> 07:26:29,680 sort it but more on that later but this 11694 07:26:27,318 --> 07:26:31,840 last named parameter here is reverse and 11695 07:26:29,680 --> 07:26:34,398 by default per the documentation it's 11696 07:26:31,840 --> 07:26:36,200 false it will not be reversed by default 11697 07:26:34,398 --> 07:26:38,360 but if we change that to true I bet we 11698 07:26:36,200 --> 07:26:40,318 can do that so let me go back to vs code 11699 07:26:38,360 --> 07:26:42,558 here and do just that let me go ahead 11700 07:26:40,318 --> 07:26:45,080 and pass in a second argument to sorted 11701 07:26:42,558 --> 07:26:47,520 in addition to this iterable which is my 11702 07:26:45,080 --> 07:26:49,958 names list iterable again in the sense 11703 07:26:47,520 --> 07:26:53,040 that it can be looped over and let me 11704 07:26:49,958 --> 07:26:55,280 pass in Reverse equals true thereby 11705 07:26:53,040 --> 07:26:58,040 overwriting the default of false let me 11706 07:26:55,280 --> 07:27:00,240 now run python of names. piy and now 11707 07:26:58,040 --> 07:27:02,398 Ron's at the top and draco's at the 11708 07:27:00,240 --> 07:27:03,798 bottom so there too whenever you have a 11709 07:27:02,398 --> 07:27:05,840 question like that moving forward 11710 07:27:03,798 --> 07:27:07,600 consider what does the documentation say 11711 07:27:05,840 --> 07:27:09,160 and see if there's a germ of an idea 11712 07:27:07,600 --> 07:27:11,200 there because oddar if you have some 11713 07:27:09,160 --> 07:27:14,398 problem oddar some programmer before you 11714 07:27:11,200 --> 07:27:17,638 has had the same question other thoughts 11715 07:27:14,398 --> 07:27:21,000 uh can we limit uh number uh numbers of 11716 07:27:17,638 --> 07:27:24,160 names and the second question uh can we 11717 07:27:21,000 --> 07:27:25,440 find specific name in least really good 11718 07:27:24,160 --> 07:27:27,120 question can we limit the number of the 11719 07:27:25,440 --> 07:27:30,240 names in the file and can we find a 11720 07:27:27,120 --> 07:27:32,760 specific one we absolutely could if we 11721 07:27:30,240 --> 07:27:35,600 were to write code we could for instance 11722 07:27:32,760 --> 07:27:37,840 open the file first count how many lines 11723 07:27:35,600 --> 07:27:40,040 are already there and then if there's 11724 07:27:37,840 --> 07:27:42,160 too many already we could just exit with 11725 07:27:40,040 --> 07:27:43,520 cy. exit or some other message to 11726 07:27:42,160 --> 07:27:46,000 indicate to the user that sorry the 11727 07:27:43,520 --> 07:27:48,080 class is full as for finding someone 11728 07:27:46,000 --> 07:27:50,840 specifically absolutely you could 11729 07:27:48,080 --> 07:27:52,558 imagine opening the file iterating over 11730 07:27:50,840 --> 07:27:54,718 it with a for loop again and again and 11731 07:27:52,558 --> 07:27:57,840 then adding a conditional like if the 11732 07:27:54,718 --> 07:27:59,478 current line equals equals Harry then we 11733 07:27:57,840 --> 07:28:00,638 found the chosen run and you can print 11734 07:27:59,478 --> 07:28:02,160 something like that so you can 11735 07:28:00,638 --> 07:28:04,318 absolutely combine these ideas with 11736 07:28:02,160 --> 07:28:06,440 previous ideas like conditionals to ask 11737 07:28:04,318 --> 07:28:11,160 those same questions how about one other 11738 07:28:06,440 --> 07:28:15,160 question on file IO uh so I just thought 11739 07:28:11,160 --> 07:28:19,958 about um this function like uh read all 11740 07:28:15,160 --> 07:28:23,280 lines and uh it looks like it's uh like 11741 07:28:19,958 --> 07:28:26,600 separate all the lines by this special 11742 07:28:23,280 --> 07:28:30,280 character back sln but it looks like we 11743 07:28:26,600 --> 07:28:34,240 don't need it character and we we always 11744 07:28:30,280 --> 07:28:37,718 strip it uh and uh it looks like some 11745 07:28:34,240 --> 07:28:41,680 bad design of function why why wouldn't 11746 07:28:37,718 --> 07:28:44,160 we just strip it inside this function a 11747 07:28:41,680 --> 07:28:46,478 really good question so we are in my 11748 07:28:44,160 --> 07:28:48,958 examples thus far using our strip to 11749 07:28:46,478 --> 07:28:51,000 reverse uh to strip from the end of the 11750 07:28:48,958 --> 07:28:53,280 line all of this white space you might 11751 07:28:51,000 --> 07:28:55,680 not want to do that in this case I am 11752 07:28:53,280 --> 07:28:57,558 stripping it away because I know that 11753 07:28:55,680 --> 07:28:59,718 each of those lines isn't some generic 11754 07:28:57,558 --> 07:29:02,600 line of text each line really represents 11755 07:28:59,718 --> 07:29:04,440 a name that I have put there myself I'm 11756 07:29:02,600 --> 07:29:06,760 using the new line just to separate one 11757 07:29:04,440 --> 07:29:08,600 value from another in other scenarios 11758 07:29:06,760 --> 07:29:10,318 you might very well want to keep that 11759 07:29:08,600 --> 07:29:12,318 line ending because it's a very long 11760 07:29:10,318 --> 07:29:13,558 series of text or a paragraph or 11761 07:29:12,318 --> 07:29:15,398 something like that where you want to 11762 07:29:13,558 --> 07:29:17,558 keep it distinct from the others but 11763 07:29:15,398 --> 07:29:20,440 it's just a convention we have to use 11764 07:29:17,558 --> 07:29:22,520 something presumably to separate one uh 11765 07:29:20,440 --> 07:29:24,440 chunk of text from another there are 11766 07:29:22,520 --> 07:29:26,638 other functions in Python that will in 11767 07:29:24,440 --> 07:29:29,040 fact handle the removal of that white 11768 07:29:26,638 --> 07:29:30,520 space for you read lines though does 11769 07:29:29,040 --> 07:29:33,440 literally that though it reads all of 11770 07:29:30,520 --> 07:29:35,760 the lines as is well allow me to turn 11771 07:29:33,440 --> 07:29:38,160 our attention back to where we left off 11772 07:29:35,760 --> 07:29:40,798 here which is just names to propose that 11773 07:29:38,160 --> 07:29:42,718 with names. text we have an ability it 11774 07:29:40,798 --> 07:29:44,478 seems to store each of these names 11775 07:29:42,718 --> 07:29:45,798 pretty straightforwardly but what if we 11776 07:29:44,478 --> 07:29:47,760 wanted to keep track of other 11777 07:29:45,798 --> 07:29:50,840 information as well suppose that we 11778 07:29:47,760 --> 07:29:54,080 wanted to store information including a 11779 07:29:50,840 --> 07:29:56,280 student's uh name and their house at 11780 07:29:54,080 --> 07:29:58,600 Hogwarts be it Gryffindor or Slytherin 11781 07:29:56,280 --> 07:30:00,398 or something else well where do we go 11782 07:29:58,600 --> 07:30:01,920 about putting that you know Hermione 11783 07:30:00,398 --> 07:30:03,798 lives in Gryffindor so we could do 11784 07:30:01,920 --> 07:30:05,920 something like this in our text file 11785 07:30:03,798 --> 07:30:08,040 Harry lives in Gryffindor so we could do 11786 07:30:05,920 --> 07:30:10,280 that Ron lives in Gryffindor so we could 11787 07:30:08,040 --> 07:30:12,958 do that and Draco lives in Slytherin so 11788 07:30:10,280 --> 07:30:15,360 we could do that but I worry 11789 07:30:12,958 --> 07:30:17,440 here but I worry now that we're mixing 11790 07:30:15,360 --> 07:30:19,920 apples and oranges so to speak like some 11791 07:30:17,440 --> 07:30:21,798 lines are names some lines are houses so 11792 07:30:19,920 --> 07:30:23,440 this probably isn't the best design if 11793 07:30:21,798 --> 07:30:25,718 only because it's confusing or it's 11794 07:30:23,440 --> 07:30:27,638 ambiguous so maybe what we could do is 11795 07:30:25,718 --> 07:30:30,000 Adopt A convention and indeed this is in 11796 07:30:27,638 --> 07:30:32,760 fact what a lot of programmers do they 11797 07:30:30,000 --> 07:30:34,280 change this file not to be names. text 11798 07:30:32,760 --> 07:30:37,958 but instead let me create a new file 11799 07:30:34,280 --> 07:30:39,840 called names. CSV CSV stands for comma 11800 07:30:37,958 --> 07:30:42,200 separated values and it's a very common 11801 07:30:39,840 --> 07:30:44,520 convention to store multiple pieces of 11802 07:30:42,200 --> 07:30:46,558 information that are related in the same 11803 07:30:44,520 --> 07:30:48,718 file and so to do this I'm going to 11804 07:30:46,558 --> 07:30:51,040 separate each of these types of data not 11805 07:30:48,718 --> 07:30:53,120 with another new line but simply with a 11806 07:30:51,040 --> 07:30:55,040 comma I'm going to keep each student on 11807 07:30:53,120 --> 07:30:57,120 their own line but I'm going to separate 11808 07:30:55,040 --> 07:30:59,718 the information about each student using 11809 07:30:57,120 --> 07:31:01,398 a comma instead and so now we sort of 11810 07:30:59,718 --> 07:31:04,240 have a a two-dimensional file if you 11811 07:31:01,398 --> 07:31:05,920 will row by row we have our students but 11812 07:31:04,240 --> 07:31:07,638 if you think of these commas as 11813 07:31:05,920 --> 07:31:09,120 representing a column even though it's 11814 07:31:07,638 --> 07:31:11,120 not perfectly straight because of the 11815 07:31:09,120 --> 07:31:13,200 lengths of these names it's a little ra 11816 07:31:11,120 --> 07:31:15,280 it's a little uh Jagged you can think of 11817 07:31:13,200 --> 07:31:17,558 these commas as representing a column 11818 07:31:15,280 --> 07:31:19,478 and it turns out these CSV files are 11819 07:31:17,558 --> 07:31:21,398 very commonly used when you use 11820 07:31:19,478 --> 07:31:23,080 something like Microsoft Excel Apple 11821 07:31:21,398 --> 07:31:24,878 numbers or Google spreadsheets and you 11822 07:31:23,080 --> 07:31:28,360 want to export the data to share with 11823 07:31:24,878 --> 07:31:31,478 someone else as a CSV file or conversely 11824 07:31:28,360 --> 07:31:33,520 if you want to import a CSV file into 11825 07:31:31,478 --> 07:31:35,760 your preferred spreadsheet software like 11826 07:31:33,520 --> 07:31:38,160 Excel or numbers or Google spreadsheets 11827 07:31:35,760 --> 07:31:40,718 you can do that as well so CSV is a very 11828 07:31:38,160 --> 07:31:43,398 common very simple text format that just 11829 07:31:40,718 --> 07:31:45,000 separates values with commas and 11830 07:31:43,398 --> 07:31:47,120 different types of values ultimately 11831 07:31:45,000 --> 07:31:49,798 with new lines as well let me go ahead 11832 07:31:47,120 --> 07:31:51,840 and run code of students. CSV to create 11833 07:31:49,798 --> 07:31:53,878 a brand new file that's initially empty 11834 07:31:51,840 --> 07:31:56,240 and we'll add to it those same names but 11835 07:31:53,878 --> 07:31:58,638 also some other information as well so 11836 07:31:56,240 --> 07:32:01,240 if I now have this new file students. 11837 07:31:58,638 --> 07:32:03,000 CSV inside of which is one column of 11838 07:32:01,240 --> 07:32:05,200 names so to speak and one column of 11839 07:32:03,000 --> 07:32:07,478 houses how do I go about changing my 11840 07:32:05,200 --> 07:32:09,080 code to read not just those names but 11841 07:32:07,478 --> 07:32:11,040 also those names and houses so that 11842 07:32:09,080 --> 07:32:13,440 they're not all on one line we somehow 11843 07:32:11,040 --> 07:32:15,000 have access to both type of value 11844 07:32:13,440 --> 07:32:17,120 separately well let me go ahead and 11845 07:32:15,000 --> 07:32:20,080 create a new program here called uh 11846 07:32:17,120 --> 07:32:22,440 students. py and in this program let's 11847 07:32:20,080 --> 07:32:25,000 go about reading not a text file per se 11848 07:32:22,440 --> 07:32:27,558 but a specific type of text file a CSV a 11849 07:32:25,000 --> 07:32:29,000 comma separated values file and to do 11850 07:32:27,558 --> 07:32:31,840 this I'm going to use similar code as 11851 07:32:29,000 --> 07:32:34,878 before I'm going to say with open quotee 11852 07:32:31,840 --> 07:32:36,520 unquote students. CSV I'm not going to 11853 07:32:34,878 --> 07:32:38,040 bother specifying quote unquote R 11854 07:32:36,520 --> 07:32:40,000 because again that's the default but I'm 11855 07:32:38,040 --> 07:32:42,360 going to give myself a variable name of 11856 07:32:40,000 --> 07:32:45,398 file and then in this file I'm going to 11857 07:32:42,360 --> 07:32:48,160 go ahead and do this for line in file as 11858 07:32:45,398 --> 07:32:51,040 before and now I have to be a bit clever 11859 07:32:48,160 --> 07:32:53,280 here let me go back to students. CSV 11860 07:32:51,040 --> 07:32:55,398 looking at this file and it seems that 11861 07:32:53,280 --> 07:32:58,360 on my loop on each iteration I'm going 11862 07:32:55,398 --> 07:32:59,878 to get access to the whole line of text 11863 07:32:58,360 --> 07:33:01,638 I'm not going to automatically get 11864 07:32:59,878 --> 07:33:03,878 access to just Hermione or just 11865 07:33:01,638 --> 07:33:06,680 Gryffindor recall that the loop is going 11866 07:33:03,878 --> 07:33:08,798 to give me each full line of text so 11867 07:33:06,680 --> 07:33:11,398 logically what would you propose that we 11868 07:33:08,798 --> 07:33:13,240 do inside of a for Loop that's reading a 11869 07:33:11,398 --> 07:33:15,240 whole line of text at once but we now 11870 07:33:13,240 --> 07:33:17,600 want to get access to the individual 11871 07:33:15,240 --> 07:33:20,040 values like Hermione and Gryffindor 11872 07:33:17,600 --> 07:33:22,040 Harry and Gryffindor how do we go about 11873 07:33:20,040 --> 07:33:23,760 taking one line of text and gaining 11874 07:33:22,040 --> 07:33:25,638 access to those individual values do you 11875 07:33:23,760 --> 07:33:27,318 think just instinctively even if you're 11876 07:33:25,638 --> 07:33:30,360 not sure what the name of the functions 11877 07:33:27,318 --> 07:33:32,080 would be you can access access as you 11878 07:33:30,360 --> 07:33:34,718 would as if you were using a dictionary 11879 07:33:32,080 --> 07:33:36,318 like using a key and value so ideally we 11880 07:33:34,718 --> 07:33:38,200 would access it using it a key and value 11881 07:33:36,318 --> 07:33:40,000 but at this point in the story all we 11882 07:33:38,200 --> 07:33:42,840 have is this Loop and this Loop is 11883 07:33:40,000 --> 07:33:44,520 giving me one line of text at is a time 11884 07:33:42,840 --> 07:33:46,040 I'm the programmer now I have to solve 11885 07:33:44,520 --> 07:33:47,958 this there is no dictionary yet in 11886 07:33:46,040 --> 07:33:51,520 question how about another suggestion 11887 07:33:47,958 --> 07:33:54,200 here um so you can somehow split the two 11888 07:33:51,520 --> 07:33:56,080 words based on the comma yeah even if 11889 07:33:54,200 --> 07:33:57,760 you're not quite sure what function is 11890 07:33:56,080 --> 07:33:59,440 going to do this intuitively you want to 11891 07:33:57,760 --> 07:34:01,920 take this whole line of text hermion 11892 07:33:59,440 --> 07:34:04,398 comma Gryffindor Harry comma Gryffindor 11893 07:34:01,920 --> 07:34:06,360 and so forth and split that line into 11894 07:34:04,398 --> 07:34:07,840 two pieces if you will and it turns out 11895 07:34:06,360 --> 07:34:10,120 wonderfully the function we'll use is 11896 07:34:07,840 --> 07:34:12,240 actually called split that can split on 11897 07:34:10,120 --> 07:34:14,040 any characters but you can tell it what 11898 07:34:12,240 --> 07:34:16,600 character to use so I'm going to go back 11899 07:34:14,040 --> 07:34:18,160 into students. py and inside of this 11900 07:34:16,600 --> 07:34:20,080 Loop I'm going to go ahead and do this 11901 07:34:18,160 --> 07:34:22,040 I'm going to take the current line I'm 11902 07:34:20,080 --> 07:34:24,680 going to remove the white space at the 11903 07:34:22,040 --> 07:34:26,440 end as always using rst strip here and 11904 07:34:24,680 --> 07:34:29,080 then whatever the result of that is I'm 11905 07:34:26,440 --> 07:34:32,478 going to now call split and quote 11906 07:34:29,080 --> 07:34:35,558 unquote comma so the split function or 11907 07:34:32,478 --> 07:34:38,920 method comes with strings stirs in 11908 07:34:35,558 --> 07:34:40,878 Python any stir has this method built in 11909 07:34:38,920 --> 07:34:43,440 and if you pass in an argument like a 11910 07:34:40,878 --> 07:34:46,360 comma what this stri split function will 11911 07:34:43,440 --> 07:34:49,040 do is split that current string into one 11912 07:34:46,360 --> 07:34:52,000 two three maybe more pieces by looking 11913 07:34:49,040 --> 07:34:54,958 for that character again and again 11914 07:34:52,000 --> 07:34:57,040 ultimately strip uh ultimately split is 11915 07:34:54,958 --> 07:34:59,000 going to return to us a list of all of 11916 07:34:57,040 --> 07:35:01,478 the individual parts to the left and to 11917 07:34:59,000 --> 07:35:03,440 the right of those commas so I can give 11918 07:35:01,478 --> 07:35:05,120 myself a variable called row here and 11919 07:35:03,440 --> 07:35:07,000 this is a common Paradigm when you know 11920 07:35:05,120 --> 07:35:09,638 you're iterating over a file 11921 07:35:07,000 --> 07:35:13,398 specifically a CSV it's common to think 11922 07:35:09,638 --> 07:35:15,398 of each uh line of it as being a row and 11923 07:35:13,398 --> 07:35:17,958 each of the values therein separated by 11924 07:35:15,398 --> 07:35:19,760 commas as columns so to speak so I'm 11925 07:35:17,958 --> 07:35:21,398 going to deliberately name my variable 11926 07:35:19,760 --> 07:35:23,878 row just to be consistent with that 11927 07:35:21,398 --> 07:35:25,920 convention and now what do I want to 11928 07:35:23,878 --> 07:35:29,638 print well I'm going to go ahead and say 11929 07:35:25,920 --> 07:35:33,718 this print how about the following uh in 11930 07:35:29,638 --> 07:35:35,840 F string that starts with curly braces 11931 07:35:33,718 --> 07:35:37,718 well how do I get access to the first 11932 07:35:35,840 --> 07:35:39,958 thing in that row well the row is going 11933 07:35:37,718 --> 07:35:41,840 to have how many parts two because if 11934 07:35:39,958 --> 07:35:43,878 I'm splitting on commas and there's one 11935 07:35:41,840 --> 07:35:45,878 comma per line that's going to give me a 11936 07:35:43,878 --> 07:35:48,958 left part and a right part like hermion 11937 07:35:45,878 --> 07:35:51,360 and Gryffindor Harry and Gryffindor when 11938 07:35:48,958 --> 07:35:53,680 I have a list like row how do I get 11939 07:35:51,360 --> 07:35:57,798 access to individual values well I can 11940 07:35:53,680 --> 07:35:59,360 do this I can say Row Bracket zero and 11941 07:35:57,798 --> 07:36:00,798 that's going to go to the first element 11942 07:35:59,360 --> 07:36:03,200 of the list which should hopefully be 11943 07:36:00,798 --> 07:36:05,120 the student's name then after that I'm 11944 07:36:03,200 --> 07:36:08,520 going to say is in and I'm going to have 11945 07:36:05,120 --> 07:36:10,398 another curly brace here for Row Bracket 11946 07:36:08,520 --> 07:36:12,318 one and then I'm going to close my whole 11947 07:36:10,398 --> 07:36:13,958 quote so it looks a little cryptic at 11948 07:36:12,318 --> 07:36:16,280 first glance but most of this is just F 11949 07:36:13,958 --> 07:36:18,240 string syntax with curly braces to plug 11950 07:36:16,280 --> 07:36:21,000 in values and what values am I plugging 11951 07:36:18,240 --> 07:36:24,040 in well row again is a list and it has 11952 07:36:21,000 --> 07:36:26,318 two elements presumably Hermione in one 11953 07:36:24,040 --> 07:36:29,240 and Gryffindor in the other and so forth 11954 07:36:26,318 --> 07:36:31,718 so bracket zero is the first element cuz 11955 07:36:29,240 --> 07:36:33,958 remember we start indexing at zero in 11956 07:36:31,718 --> 07:36:36,398 Python and one is going to be the second 11957 07:36:33,958 --> 07:36:40,680 element so let me go ahead and run this 11958 07:36:36,398 --> 07:36:44,798 now and see what happens python of uh 11959 07:36:40,680 --> 07:36:46,398 students. py enter and we see hermion is 11960 07:36:44,798 --> 07:36:48,440 in Gryffindor Harry's in Gryffindor Ron 11961 07:36:46,398 --> 07:36:51,200 is in Gryffindor and Draco is in 11962 07:36:48,440 --> 07:36:54,718 Slytherin so we have now implemented our 11963 07:36:51,200 --> 07:36:57,558 own code from scratch that actually 11964 07:36:54,718 --> 07:37:00,318 parses that is reads and interprets a 11965 07:36:57,558 --> 07:37:01,878 CSV file ultimately here 11966 07:37:00,318 --> 07:37:03,558 now let me pause to see if there's any 11967 07:37:01,878 --> 07:37:06,638 questions but we'll make this even 11968 07:37:03,558 --> 07:37:08,558 easier to read in just a moment any 11969 07:37:06,638 --> 07:37:11,638 questions on what we've just done here 11970 07:37:08,558 --> 07:37:14,920 by splitting by comma so my question is 11971 07:37:11,638 --> 07:37:18,000 uh can we uh edit any line of code 11972 07:37:14,920 --> 07:37:20,958 anytime we want or uh the only option 11973 07:37:18,000 --> 07:37:23,600 that we have is to append uh the lines 11974 07:37:20,958 --> 07:37:27,280 or uh let's say if we want to let's say 11975 07:37:23,600 --> 07:37:30,160 change Harry's uh house to let's say 11976 07:37:27,280 --> 07:37:31,840 Slytherin or some other house 11977 07:37:30,160 --> 07:37:34,440 yeah a really good question what if you 11978 07:37:31,840 --> 07:37:37,520 want to in Python change a line in the 11979 07:37:34,440 --> 07:37:39,000 file and not just uh a pen to the end 11980 07:37:37,520 --> 07:37:40,878 you would have to implement that logic 11981 07:37:39,000 --> 07:37:43,760 yourself so for instance you could 11982 07:37:40,878 --> 07:37:45,920 imagine now opening the file and reading 11983 07:37:43,760 --> 07:37:48,000 all of the contents in then maybe 11984 07:37:45,920 --> 07:37:49,638 iterating over each of those lines and 11985 07:37:48,000 --> 07:37:51,798 as soon as you see that the current name 11986 07:37:49,638 --> 07:37:54,958 equals equals Harry you could maybe 11987 07:37:51,798 --> 07:37:57,280 change his house to slitherin and then 11988 07:37:54,958 --> 07:37:59,240 it would be up to you though to write 11989 07:37:57,280 --> 07:38:00,840 all of those changes back to the file so 11990 07:37:59,240 --> 07:38:03,080 in that case you might want to in 11991 07:38:00,840 --> 07:38:05,600 simplest form read the file once and let 11992 07:38:03,080 --> 07:38:08,040 it close then open it again but open for 11993 07:38:05,600 --> 07:38:10,318 writing and change the whole file it's 11994 07:38:08,040 --> 07:38:12,280 not really possible or easy to go in and 11995 07:38:10,318 --> 07:38:14,958 change just part of the file though you 11996 07:38:12,280 --> 07:38:16,360 can do it it's easier to actually read 11997 07:38:14,958 --> 07:38:18,478 the whole file make your changes in 11998 07:38:16,360 --> 07:38:20,360 memory then write the whole file out but 11999 07:38:18,478 --> 07:38:22,760 for larger files where that might be 12000 07:38:20,360 --> 07:38:25,360 quite slow you can be more clever than 12001 07:38:22,760 --> 07:38:26,920 that well let me propose now that we 12002 07:38:25,360 --> 07:38:28,360 clean this up a little bit because I 12003 07:38:26,920 --> 07:38:30,840 actually think this is a little cryptic 12004 07:38:28,360 --> 07:38:33,120 to read Row Bracket Z Row Bracket one 12005 07:38:30,840 --> 07:38:35,760 it's it's not that well written at the 12006 07:38:33,120 --> 07:38:38,318 moment I would say but it turns out that 12007 07:38:35,760 --> 07:38:40,760 when you have a variable that's a list 12008 07:38:38,318 --> 07:38:42,840 like row you don't have to throw all of 12009 07:38:40,760 --> 07:38:45,160 those variables into a list you can 12010 07:38:42,840 --> 07:38:47,440 actually unpack that whole sequence at 12011 07:38:45,160 --> 07:38:50,160 once that is to say if you know that a 12012 07:38:47,440 --> 07:38:51,840 function like split returns a list but 12013 07:38:50,160 --> 07:38:54,680 you know in advance that it's going to 12014 07:38:51,840 --> 07:38:56,440 return two values in a list the first 12015 07:38:54,680 --> 07:38:58,520 and the second you don't have to throw 12016 07:38:56,440 --> 07:39:01,000 them all into a variable that itself is 12017 07:38:58,520 --> 07:39:03,280 a list you can actually unpack them 12018 07:39:01,000 --> 07:39:05,798 simultaneously into two variables doing 12019 07:39:03,280 --> 07:39:08,000 name comma house so this is a nice 12020 07:39:05,798 --> 07:39:11,680 python technique to not only create but 12021 07:39:08,000 --> 07:39:14,120 assign automatically in parallel two 12022 07:39:11,680 --> 07:39:15,798 variables at once rather than just one 12023 07:39:14,120 --> 07:39:17,920 so this will have the effect of putting 12024 07:39:15,798 --> 07:39:19,000 the name in the left Hermione and it 12025 07:39:17,920 --> 07:39:20,638 will have the effect of putting 12026 07:39:19,000 --> 07:39:22,878 Gryffindor the house in the right 12027 07:39:20,638 --> 07:39:24,440 variable and we now no longer have a row 12028 07:39:22,878 --> 07:39:26,040 we can now make our code a little more 12029 07:39:24,440 --> 07:39:28,760 readable by now literally just saying 12030 07:39:26,040 --> 07:39:30,398 name down here and for instance house 12031 07:39:28,760 --> 07:39:33,200 down here so just a little more readable 12032 07:39:30,398 --> 07:39:34,798 even though functionally the code now is 12033 07:39:33,200 --> 07:39:37,760 exactly the 12034 07:39:34,798 --> 07:39:39,318 same all right so this now works and 12035 07:39:37,760 --> 07:39:41,920 I'll confirm as much by just running it 12036 07:39:39,318 --> 07:39:44,718 once more python of students. py enter 12037 07:39:41,920 --> 07:39:46,440 and we see that the text is as intended 12038 07:39:44,718 --> 07:39:49,318 but suppose for the sake of discussion 12039 07:39:46,440 --> 07:39:51,240 that I'd like to sort this list of 12040 07:39:49,318 --> 07:39:53,638 output I'd like to say hello again to 12041 07:39:51,240 --> 07:39:56,520 Draco first then hello to Harry then 12042 07:39:53,638 --> 07:39:57,840 Hermione then Ron how can I go about 12043 07:39:56,520 --> 07:39:59,600 doing this well let's take some 12044 07:39:57,840 --> 07:40:01,718 inspiration from the previous example 12045 07:39:59,600 --> 07:40:04,318 where we were only dealing with names 12046 07:40:01,718 --> 07:40:07,000 and instead do it with these full 12047 07:40:04,318 --> 07:40:08,680 phrases so and so is in house well let 12048 07:40:07,000 --> 07:40:10,398 me go ahead and do this I'm going to go 12049 07:40:08,680 --> 07:40:13,440 ahead and start scratch and give myself 12050 07:40:10,398 --> 07:40:16,440 a list uh called students equal to an 12051 07:40:13,440 --> 07:40:20,160 empty list initially and then with open 12052 07:40:16,440 --> 07:40:23,958 students. CSV as file I'm going to go 12053 07:40:20,160 --> 07:40:25,478 ahead and say this for line in file and 12054 07:40:23,958 --> 07:40:27,558 then below this I'm going to do exactly 12055 07:40:25,478 --> 07:40:29,520 as before name comma house equals the 12056 07:40:27,558 --> 07:40:32,040 current line stripping off the white 12057 07:40:29,520 --> 07:40:34,440 space at the end splitting it on a comma 12058 07:40:32,040 --> 07:40:38,680 so that's exact same as before but this 12059 07:40:34,440 --> 07:40:40,398 time before I go about uh printing the 12060 07:40:38,680 --> 07:40:42,200 sentence I'm going to store it 12061 07:40:40,398 --> 07:40:43,920 temporarily in a list so that I can 12062 07:40:42,200 --> 07:40:45,920 accumulate all of these sentences and 12063 07:40:43,920 --> 07:40:49,160 then sort them later so let me go ahead 12064 07:40:45,920 --> 07:40:52,040 and do this students which is my list do 12065 07:40:49,160 --> 07:40:53,520 append let me append the actual sentence 12066 07:40:52,040 --> 07:40:57,318 I want to show on the screen so another 12067 07:40:53,520 --> 07:40:59,000 F string so name is in house just as 12068 07:40:57,318 --> 07:41:01,440 before but notice I'm not printing that 12069 07:40:59,000 --> 07:41:04,600 sent sentence I'm appending it to my 12070 07:41:01,440 --> 07:41:06,600 list not a file but to my list why am I 12071 07:41:04,600 --> 07:41:08,958 doing this well just because as before I 12072 07:41:06,600 --> 07:41:12,000 want to do this for student in the 12073 07:41:08,958 --> 07:41:15,240 sorted students I want to go ahead and 12074 07:41:12,000 --> 07:41:18,440 print out student like this let me go 12075 07:41:15,240 --> 07:41:20,520 ahead and run python of students. py and 12076 07:41:18,440 --> 07:41:22,318 hit enter now and I think we'll see 12077 07:41:20,520 --> 07:41:24,798 indeed Draco is now first Harry is 12078 07:41:22,318 --> 07:41:27,958 second hermion is third and Ron is 12079 07:41:24,798 --> 07:41:30,680 fourth but this is arguably a little 12080 07:41:27,958 --> 07:41:32,798 sloppy right it seems a little hackish 12081 07:41:30,680 --> 07:41:34,760 that I'm constructing these sentences 12082 07:41:32,798 --> 07:41:37,760 and even though I'm technically want to 12083 07:41:34,760 --> 07:41:40,040 sort by name I'm technically sorting by 12084 07:41:37,760 --> 07:41:42,000 these whole English sentences so it's 12085 07:41:40,040 --> 07:41:44,160 not wrong it's achieving the intended 12086 07:41:42,000 --> 07:41:45,520 result but it's not really welld 12087 07:41:44,160 --> 07:41:47,240 designed because I'm just kind of 12088 07:41:45,520 --> 07:41:48,558 getting lucky that English is reading 12089 07:41:47,240 --> 07:41:51,160 from left to right and therefore when I 12090 07:41:48,558 --> 07:41:52,760 print this out it's sorting properly it 12091 07:41:51,160 --> 07:41:55,160 would be better really to come up with a 12092 07:41:52,760 --> 07:41:57,958 technique for sorting by the students 12093 07:41:55,160 --> 07:42:00,958 names not by some English sentence that 12094 07:41:57,958 --> 07:42:02,920 I've constructed here online six so to 12095 07:42:00,958 --> 07:42:05,318 achieve this I'm going to need to make 12096 07:42:02,920 --> 07:42:07,680 my life more complicated for a moment 12097 07:42:05,318 --> 07:42:10,440 and I'm going to need to collect 12098 07:42:07,680 --> 07:42:12,318 information about each student before I 12099 07:42:10,440 --> 07:42:14,520 bother assembling that sentence so let 12100 07:42:12,318 --> 07:42:16,558 me propose that we do this let me go 12101 07:42:14,520 --> 07:42:19,120 ahead and undo these last few lines of 12102 07:42:16,558 --> 07:42:21,680 code so that we currently have two 12103 07:42:19,120 --> 07:42:23,000 variables name and house Each of which 12104 07:42:21,680 --> 07:42:24,558 has name and the student's house 12105 07:42:23,000 --> 07:42:27,240 respectively and we still have our 12106 07:42:24,558 --> 07:42:29,200 Global variable students but let me do 12107 07:42:27,240 --> 07:42:31,040 this recall that python supports 12108 07:42:29,200 --> 07:42:33,080 dictionaries and dictionaries are just 12109 07:42:31,040 --> 07:42:35,040 collections of keys and values so you 12110 07:42:33,080 --> 07:42:37,760 can associate something with something 12111 07:42:35,040 --> 07:42:40,200 else like a name with Hermione like a 12112 07:42:37,760 --> 07:42:42,200 house with Gryffindor that really is a 12113 07:42:40,200 --> 07:42:44,718 dictionary so let me do this let me 12114 07:42:42,200 --> 07:42:47,478 temporarily create a dictionary that 12115 07:42:44,718 --> 07:42:49,680 stores this Association of name with 12116 07:42:47,478 --> 07:42:52,280 house let me go ahead and do this let me 12117 07:42:49,680 --> 07:42:53,760 say that the student here is going to be 12118 07:42:52,280 --> 07:42:55,120 represented initially by an empty 12119 07:42:53,760 --> 07:42:56,600 dictionary and just like you can create 12120 07:42:55,120 --> 07:42:57,958 an empty list with square brackets you 12121 07:42:56,600 --> 07:43:00,360 can create an empty dictionary with 12122 07:42:57,958 --> 07:43:03,120 curly braces so give me an empty 12123 07:43:00,360 --> 07:43:05,558 dictionary that will soon have two keys 12124 07:43:03,120 --> 07:43:07,798 name and house how do I do that well I 12125 07:43:05,558 --> 07:43:11,638 could do it this way student Open 12126 07:43:07,798 --> 07:43:13,760 Bracket name equals the student's name 12127 07:43:11,638 --> 07:43:16,760 that we got from the line student 12128 07:43:13,760 --> 07:43:19,600 bracket house equals the house that we 12129 07:43:16,760 --> 07:43:23,600 got from the line and now I'm going to 12130 07:43:19,600 --> 07:43:25,920 append to the students list plural that 12131 07:43:23,600 --> 07:43:27,638 particular student now why have I done 12132 07:43:25,920 --> 07:43:29,600 this I've admittedly made my code more 12133 07:43:27,638 --> 07:43:31,680 complicated it's more lines of code 12134 07:43:29,600 --> 07:43:34,080 but I've now collected all of the 12135 07:43:31,680 --> 07:43:36,478 information I have about students while 12136 07:43:34,080 --> 07:43:39,000 still keeping track what's a name what's 12137 07:43:36,478 --> 07:43:41,558 a house the list meanwhile has all of 12138 07:43:39,000 --> 07:43:43,520 the students names and houses together 12139 07:43:41,558 --> 07:43:45,600 now why have I done this well let me for 12140 07:43:43,520 --> 07:43:48,200 the moment just do something simple let 12141 07:43:45,600 --> 07:43:51,000 me do for student in students and let me 12142 07:43:48,200 --> 07:43:54,920 very Simply Now say print the following 12143 07:43:51,000 --> 07:43:59,878 F string the current student with this 12144 07:43:54,920 --> 07:44:03,200 name uh is in this current student 12145 07:43:59,878 --> 07:44:04,958 house and now notice one detail inside 12146 07:44:03,200 --> 07:44:07,798 of this F string I'm using my curly 12147 07:44:04,958 --> 07:44:09,240 braces as always I'm using inside of 12148 07:44:07,798 --> 07:44:12,040 those curly braces the name of a 12149 07:44:09,240 --> 07:44:14,040 variable as always but then I'm using 12150 07:44:12,040 --> 07:44:16,718 not bracket zero or one because these 12151 07:44:14,040 --> 07:44:20,398 are dictionaries now not list but why am 12152 07:44:16,718 --> 07:44:22,478 I using single quotes to surround house 12153 07:44:20,398 --> 07:44:27,398 and to surround 12154 07:44:22,478 --> 07:44:29,878 name why single quotes inside of this F 12155 07:44:27,398 --> 07:44:34,600 string 12156 07:44:29,878 --> 07:44:37,520 to access those keys yes um because you 12157 07:44:34,600 --> 07:44:41,040 have double quotes in that in that line 12158 07:44:37,520 --> 07:44:42,878 12 and so you have to tell p python to 12159 07:44:41,040 --> 07:44:44,520 differentiate exactly because I'm 12160 07:44:42,878 --> 07:44:46,840 already using double quotes outside of 12161 07:44:44,520 --> 07:44:48,760 the F string if I want to put quotes 12162 07:44:46,840 --> 07:44:50,798 around any strings on the inside which I 12163 07:44:48,760 --> 07:44:53,160 do need to do for dictionaries because 12164 07:44:50,798 --> 07:44:55,798 recall when you index into a dictionary 12165 07:44:53,160 --> 07:44:58,160 you don't use numbers like lists 0 1 two 12166 07:44:55,798 --> 07:44:59,680 onward you instead use strings which 12167 07:44:58,160 --> 07:45:01,680 need to be quoted but if you're already 12168 07:44:59,680 --> 07:45:03,240 using double quotes it's easiest to then 12169 07:45:01,680 --> 07:45:05,360 use single quotes on the inside so 12170 07:45:03,240 --> 07:45:07,840 python doesn't get confused about what 12171 07:45:05,360 --> 07:45:10,360 lines up with what so at the moment when 12172 07:45:07,840 --> 07:45:12,478 I run this program it's going to print 12173 07:45:10,360 --> 07:45:16,120 out those hellos but they're not yet 12174 07:45:12,478 --> 07:45:18,840 sorted in fact what I now have is a list 12175 07:45:16,120 --> 07:45:20,398 of dictionaries and nothing is yet 12176 07:45:18,840 --> 07:45:22,200 sorted but let me tighten up the code 12177 07:45:20,398 --> 07:45:24,478 too to point out that it doesn't need to 12178 07:45:22,200 --> 07:45:26,360 be quite as verbose if you're in the 12179 07:45:24,478 --> 07:45:27,680 habit of creating an empty dictionary 12180 07:45:26,360 --> 07:45:30,160 like this on line six and then 12181 07:45:27,680 --> 07:45:32,240 immediately putting in Keys name and 12182 07:45:30,160 --> 07:45:34,080 house each with two values name and 12183 07:45:32,240 --> 07:45:35,558 house respectively you can actually do 12184 07:45:34,080 --> 07:45:38,200 this all at once so let me show you a 12185 07:45:35,558 --> 07:45:40,360 slightly different syntax I can do this 12186 07:45:38,200 --> 07:45:42,240 give me a variable called student and 12187 07:45:40,360 --> 07:45:43,680 let me use curly braces on the right 12188 07:45:42,240 --> 07:45:45,920 hand side here but instead of leaving 12189 07:45:43,680 --> 07:45:48,798 them empty let's just Define those keys 12190 07:45:45,920 --> 07:45:51,680 and those values now quote unquote name 12191 07:45:48,798 --> 07:45:54,160 will be name and quote unquote house 12192 07:45:51,680 --> 07:45:57,080 will be house this achieves the exact 12193 07:45:54,160 --> 07:45:59,638 same effect in one line instead of three 12194 07:45:57,080 --> 07:46:01,718 it creates a new non dictionary 12195 07:45:59,638 --> 07:46:03,718 containing a name key the value of which 12196 07:46:01,718 --> 07:46:05,360 is the student's name and a house key 12197 07:46:03,718 --> 07:46:07,240 the value of which is the student's 12198 07:46:05,360 --> 07:46:09,558 house nothing else needs to change that 12199 07:46:07,240 --> 07:46:12,000 will still just work so that if I again 12200 07:46:09,558 --> 07:46:13,798 run python of students. I'm still seeing 12201 07:46:12,000 --> 07:46:17,120 those greetings but they're still not 12202 07:46:13,798 --> 07:46:19,718 quite actually sorted well what might I 12203 07:46:17,120 --> 07:46:22,798 go about doing here in order to what 12204 07:46:19,718 --> 07:46:25,360 could I do to improve upon this further 12205 07:46:22,798 --> 07:46:28,558 well we need some mechanism now of 12206 07:46:25,360 --> 07:46:32,000 sorting those students but unfortunately 12207 07:46:28,558 --> 07:46:34,680 you can't do this we can't sort all of 12208 07:46:32,000 --> 07:46:36,600 the students now because those students 12209 07:46:34,680 --> 07:46:38,680 are not names like they were before they 12210 07:46:36,600 --> 07:46:40,680 aren't sentences like they were before 12211 07:46:38,680 --> 07:46:42,840 each of the students is a dictionary and 12212 07:46:40,680 --> 07:46:46,240 it's nonobvious how you would sort a a 12213 07:46:42,840 --> 07:46:48,520 dictionary inside of a list so ideally 12214 07:46:46,240 --> 07:46:51,520 what do we want to do if at the moment 12215 07:46:48,520 --> 07:46:53,718 we hit hit line nine we have a list of 12216 07:46:51,520 --> 07:46:56,080 all of these students and inside of that 12217 07:46:53,718 --> 07:46:58,240 list is one dictionary per student and 12218 07:46:56,080 --> 07:46:59,440 each of those dictionaries has two keys 12219 07:46:58,240 --> 07:47:00,798 name and house 12220 07:46:59,440 --> 07:47:04,718 wouldn't it be nice if there were a way 12221 07:47:00,798 --> 07:47:07,240 in code to tell python sort this list by 12222 07:47:04,718 --> 07:47:08,878 looking at this key in each dictionary 12223 07:47:07,240 --> 07:47:11,760 because that would give this the ability 12224 07:47:08,878 --> 07:47:13,840 to sort either by name or even by house 12225 07:47:11,760 --> 07:47:17,000 or even by any other field that we add 12226 07:47:13,840 --> 07:47:19,520 to that file so it turns out we can do 12227 07:47:17,000 --> 07:47:21,718 this we can tell the sorted function not 12228 07:47:19,520 --> 07:47:24,478 just to reverse things or not it takes 12229 07:47:21,718 --> 07:47:27,440 another positional it takes another 12230 07:47:24,478 --> 07:47:30,558 named parameter called key where you can 12231 07:47:27,440 --> 07:47:32,798 specify what key should be used in order 12232 07:47:30,558 --> 07:47:34,840 to sort some list of dictionaries and 12233 07:47:32,798 --> 07:47:36,398 I'm going to propose that we do this I'm 12234 07:47:34,840 --> 07:47:39,520 going to first Define a function 12235 07:47:36,398 --> 07:47:41,760 temporarily for now called get name and 12236 07:47:39,520 --> 07:47:44,558 this function's purpose in life given a 12237 07:47:41,760 --> 07:47:47,080 student is to quite simply return the 12238 07:47:44,558 --> 07:47:49,440 student's name from that particular 12239 07:47:47,080 --> 07:47:51,240 dictionary so if student is a dictionary 12240 07:47:49,440 --> 07:47:53,200 this is going to return literally the 12241 07:47:51,240 --> 07:47:56,000 student's name and that's it that's the 12242 07:47:53,200 --> 07:47:58,080 sole purpose of this function in life 12243 07:47:56,000 --> 07:48:00,000 what do I now want to do well now that I 12244 07:47:58,080 --> 07:48:02,478 have a function that given a student 12245 07:48:00,000 --> 07:48:05,360 will return to me the student's name I 12246 07:48:02,478 --> 07:48:08,120 can do this I can change sorted to say 12247 07:48:05,360 --> 07:48:11,360 use a key that's equal to whatever the 12248 07:48:08,120 --> 07:48:14,478 return value of get name is and this now 12249 07:48:11,360 --> 07:48:18,478 is a feature of python python allows you 12250 07:48:14,478 --> 07:48:20,760 to pass functions as arguments in two 12251 07:48:18,478 --> 07:48:23,478 other functions so get name is a 12252 07:48:20,760 --> 07:48:26,798 function sorted is a function and I'm 12253 07:48:23,478 --> 07:48:31,000 passing in get name to sorted as the 12254 07:48:26,798 --> 07:48:32,840 value of that key parameter now why am I 12255 07:48:31,000 --> 07:48:35,240 doing that well if you think of the get 12256 07:48:32,840 --> 07:48:37,360 name function as just a bunch a block of 12257 07:48:35,240 --> 07:48:38,920 code that will get the name of a student 12258 07:48:37,360 --> 07:48:41,160 that's handy because that's the 12259 07:48:38,920 --> 07:48:42,760 capability that sorted needs when given 12260 07:48:41,160 --> 07:48:45,240 a list of students Each of which is a 12261 07:48:42,760 --> 07:48:46,638 dictionary sorted needs to know how do I 12262 07:48:45,240 --> 07:48:48,280 get the name of the student in order to 12263 07:48:46,638 --> 07:48:49,760 do alphabetical sorting for you the 12264 07:48:48,280 --> 07:48:51,240 authors of python didn't know that we 12265 07:48:49,760 --> 07:48:52,798 were going to be creating students here 12266 07:48:51,240 --> 07:48:55,080 in this class so they couldn't have 12267 07:48:52,798 --> 07:48:56,760 anticipated writing code in advance that 12268 07:48:55,080 --> 07:48:59,240 specifically sorts on a field called 12269 07:48:56,760 --> 07:49:02,440 student let alone called name name let 12270 07:48:59,240 --> 07:49:05,040 alone house so what did they do they 12271 07:49:02,440 --> 07:49:07,680 instead built into the sorted function 12272 07:49:05,040 --> 07:49:09,680 this named parameter key that allows us 12273 07:49:07,680 --> 07:49:12,440 all these years later to tell their 12274 07:49:09,680 --> 07:49:15,160 function sorted how to sort this list of 12275 07:49:12,440 --> 07:49:18,000 dictionaries so now watch what happens 12276 07:49:15,160 --> 07:49:21,558 if I run python of students. py and hit 12277 07:49:18,000 --> 07:49:23,638 enter I now have a sorted list of output 12278 07:49:21,558 --> 07:49:26,398 why because now that list of 12279 07:49:23,638 --> 07:49:29,440 dictionaries has all been sorted by the 12280 07:49:26,398 --> 07:49:31,080 student's name I can further do this if 12281 07:49:29,440 --> 07:49:33,080 as before we want to reverse the whole 12282 07:49:31,080 --> 07:49:34,878 thing by saying reverse equals true we 12283 07:49:33,080 --> 07:49:37,160 can do that too let me rerun python of 12284 07:49:34,878 --> 07:49:39,240 students. and hit enter now it's revers 12285 07:49:37,160 --> 07:49:41,240 now it's Ron than hermion Harry and 12286 07:49:39,240 --> 07:49:43,798 Draco but we can do something different 12287 07:49:41,240 --> 07:49:46,840 as well what if I want to sort for 12288 07:49:43,798 --> 07:49:48,478 instance by house name reversed I could 12289 07:49:46,840 --> 07:49:50,760 do this I could change this function 12290 07:49:48,478 --> 07:49:52,798 from get name to get house I could 12291 07:49:50,760 --> 07:49:54,718 change the implementation up here to be 12292 07:49:52,798 --> 07:49:57,040 get house and I can return not the 12293 07:49:54,718 --> 07:50:00,440 student's name but the student's house 12294 07:49:57,040 --> 07:50:03,718 and so now notice if I run python of 12295 07:50:00,440 --> 07:50:07,080 students. piy enter notice now it is 12296 07:50:03,718 --> 07:50:09,840 sorted by house in reverse order 12297 07:50:07,080 --> 07:50:12,080 Slytherin is first and then Gryffindor 12298 07:50:09,840 --> 07:50:14,760 if I get rid of the reverse but keep the 12299 07:50:12,080 --> 07:50:18,040 get house and rerun this program now 12300 07:50:14,760 --> 07:50:20,318 it's sorted by house Gryffindor is first 12301 07:50:18,040 --> 07:50:22,160 and Slytherin is last and the upside now 12302 07:50:20,318 --> 07:50:24,798 of this is because I'm using this list 12303 07:50:22,160 --> 07:50:27,000 of dictionaries and keeping the students 12304 07:50:24,798 --> 07:50:29,000 data together until the last minute when 12305 07:50:27,000 --> 07:50:31,000 I'm finally doing the printing I now 12306 07:50:29,000 --> 07:50:33,200 have full control over the information 12307 07:50:31,000 --> 07:50:34,718 itself and I can sort by this or that I 12308 07:50:33,200 --> 07:50:36,878 don't have to constru construct those 12309 07:50:34,718 --> 07:50:39,240 sentences in advance like I rather hack 12310 07:50:36,878 --> 07:50:41,200 asly did the first time all right that 12311 07:50:39,240 --> 07:50:44,680 was a lot let me pause here to see if 12312 07:50:41,200 --> 07:50:47,240 there are questions so when when we 12313 07:50:44,680 --> 07:50:52,318 sorting the files should we every time 12314 07:50:47,240 --> 07:50:55,000 should we use the uh Loops or like a 12315 07:50:52,318 --> 07:50:59,318 like a d dictionary or or any kind of 12316 07:50:55,000 --> 07:51:03,240 list can we sort by just sorting now 12317 07:50:59,318 --> 07:51:05,638 looping or any kind of stuff a good 12318 07:51:03,240 --> 07:51:07,920 question and the short answer with 12319 07:51:05,638 --> 07:51:10,478 python alone you're the programmer you 12320 07:51:07,920 --> 07:51:12,558 need to do the Sorting with libraries 12321 07:51:10,478 --> 07:51:14,680 and other techniques absolutely you can 12322 07:51:12,558 --> 07:51:16,680 do more of this automatically because 12323 07:51:14,680 --> 07:51:18,120 someone else has written that code what 12324 07:51:16,680 --> 07:51:19,840 we're doing at the moment is doing 12325 07:51:18,120 --> 07:51:21,160 everything from scratch ourselves but 12326 07:51:19,840 --> 07:51:23,440 absolutely with other functions or 12327 07:51:21,160 --> 07:51:26,040 libraries some of this could be made uh 12328 07:51:23,440 --> 07:51:29,280 more uh easily done some of this could 12329 07:51:26,040 --> 07:51:32,200 be made uh easier other questions 12330 07:51:29,280 --> 07:51:34,360 on this technique here it equal to the 12331 07:51:32,200 --> 07:51:39,240 returned value of the 12332 07:51:34,360 --> 07:51:41,478 function can it be equal to just 12333 07:51:39,240 --> 07:51:45,200 a a variable 12334 07:51:41,478 --> 07:51:47,520 or a value it well yes it should equal a 12335 07:51:45,200 --> 07:51:50,520 value so I'm spec and I should clarify 12336 07:51:47,520 --> 07:51:52,638 actually since this was not obvious so 12337 07:51:50,520 --> 07:51:55,520 when you pass in a function like get 12338 07:51:52,638 --> 07:51:58,040 name or get house to the sorted function 12339 07:51:55,520 --> 07:52:01,558 as the value of key that function is 12340 07:51:58,040 --> 07:52:04,440 automatic ially called by the get by the 12341 07:52:01,558 --> 07:52:07,280 sorted function for you on each of the 12342 07:52:04,440 --> 07:52:09,638 dictionaries in the list and it uses the 12343 07:52:07,280 --> 07:52:12,600 return value of get name or get house to 12344 07:52:09,638 --> 07:52:14,958 decide what strings to actually use to 12345 07:52:12,600 --> 07:52:17,558 compare in order to decide which is 12346 07:52:14,958 --> 07:52:19,718 alphabetically correct so this function 12347 07:52:17,558 --> 07:52:22,680 which you pass just by name you do not 12348 07:52:19,718 --> 07:52:24,600 pass in parentheses at the end is called 12349 07:52:22,680 --> 07:52:27,440 by the sorted function in order to 12350 07:52:24,600 --> 07:52:29,200 figure out for you how to compare these 12351 07:52:27,440 --> 07:52:33,000 same values 12352 07:52:29,200 --> 07:52:36,398 how can we use nested dictionaries I 12353 07:52:33,000 --> 07:52:38,200 have read about nested dictionaries what 12354 07:52:36,398 --> 07:52:40,760 is the difference between Ned 12355 07:52:38,200 --> 07:52:44,760 dictionaries and dictionary inside a 12356 07:52:40,760 --> 07:52:47,478 list I think it is sure um uh so we are 12357 07:52:44,760 --> 07:52:49,318 using a list of dictionaries why because 12358 07:52:47,478 --> 07:52:51,040 each of those dictionaries represents a 12359 07:52:49,318 --> 07:52:52,920 student and a student has a name in a 12360 07:52:51,040 --> 07:52:54,920 house and we want to I claim maintain 12361 07:52:52,920 --> 07:52:56,160 that Association and it's a list of 12362 07:52:54,920 --> 07:52:58,680 students because we've got multiple 12363 07:52:56,160 --> 07:53:00,680 students four in this case you could 12364 07:52:58,680 --> 07:53:02,200 create a a structure that is a 12365 07:53:00,680 --> 07:53:04,040 dictionary of dictionaries but I would 12366 07:53:02,200 --> 07:53:05,478 argue it just doesn't solve a problem I 12367 07:53:04,040 --> 07:53:08,040 don't need a dictionary of dictionary I 12368 07:53:05,478 --> 07:53:10,638 need a list of key value pairs right now 12369 07:53:08,040 --> 07:53:13,638 that's all so let me propose if we go 12370 07:53:10,638 --> 07:53:16,040 back to students. py here and we revert 12371 07:53:13,638 --> 07:53:18,798 back to the approach where we have get 12372 07:53:16,040 --> 07:53:20,878 name as the function both used and 12373 07:53:18,798 --> 07:53:23,318 defined here and that function Returns 12374 07:53:20,878 --> 07:53:25,718 the student's name what happens to be 12375 07:53:23,318 --> 07:53:28,760 clear is that the sorted function will 12376 07:53:25,718 --> 07:53:31,478 use the value of key get name in in this 12377 07:53:28,760 --> 07:53:33,520 case calling that function on every 12378 07:53:31,478 --> 07:53:36,120 dictionary in the list that it's 12379 07:53:33,520 --> 07:53:38,718 supposed to sort and that function get 12380 07:53:36,120 --> 07:53:40,558 name Returns the string that sorted 12381 07:53:38,718 --> 07:53:42,600 we'll actually use to decide whether 12382 07:53:40,558 --> 07:53:44,958 things go in this order left right or in 12383 07:53:42,600 --> 07:53:47,318 this order right left it alphabetizes 12384 07:53:44,958 --> 07:53:49,520 things based on that return value so 12385 07:53:47,318 --> 07:53:51,440 notice that I'm not calling the function 12386 07:53:49,520 --> 07:53:53,398 get name here with parenthesis I'm 12387 07:53:51,440 --> 07:53:56,318 passing it in only by its name so that 12388 07:53:53,398 --> 07:53:59,120 the sorted function can call that get 12389 07:53:56,318 --> 07:54:01,080 name function for me now it's turns out 12390 07:53:59,120 --> 07:54:02,558 as always if you're defining something 12391 07:54:01,080 --> 07:54:05,760 be it a variable or in this case a 12392 07:54:02,558 --> 07:54:08,040 function and then immediately using it 12393 07:54:05,760 --> 07:54:10,200 but never once again needing the name of 12394 07:54:08,040 --> 07:54:12,398 that function like get name we can 12395 07:54:10,200 --> 07:54:14,398 actually tighten this code up further I 12396 07:54:12,398 --> 07:54:16,760 can actually do this I can get rid of 12397 07:54:14,398 --> 07:54:18,398 the get name function Al together just 12398 07:54:16,760 --> 07:54:21,040 like I could get rid of a variable that 12399 07:54:18,398 --> 07:54:24,240 isn't strictly necessary and instead of 12400 07:54:21,040 --> 07:54:26,398 passing key the name of a function I can 12401 07:54:24,240 --> 07:54:29,120 actually Pass Key what's called in a 12402 07:54:26,398 --> 07:54:31,360 Lambda function which is an a function a 12403 07:54:29,120 --> 07:54:32,878 function that just has no name why 12404 07:54:31,360 --> 07:54:34,478 because you don't need to give it a name 12405 07:54:32,878 --> 07:54:36,240 if you're only going to call it in one 12406 07:54:34,478 --> 07:54:38,840 place and the Syntax for this in 12407 07:54:36,240 --> 07:54:41,958 Python's a little weird but if I do key 12408 07:54:38,840 --> 07:54:43,760 equals literally the word Lambda then 12409 07:54:41,958 --> 07:54:45,718 something like student which is the name 12410 07:54:43,760 --> 07:54:48,120 of the parameter I expect this function 12411 07:54:45,718 --> 07:54:51,200 to take and then I don't even type the 12412 07:54:48,120 --> 07:54:53,760 return key i instead just say student 12413 07:54:51,200 --> 07:54:56,398 bracket name so what am I doing here 12414 07:54:53,760 --> 07:54:58,878 with my code this code here that I've 12415 07:54:56,398 --> 07:55:01,600 highlighted is equivalent to to the get 12416 07:54:58,878 --> 07:55:03,080 name function I implemented a moment ago 12417 07:55:01,600 --> 07:55:05,120 the syntax is admittedly a little 12418 07:55:03,080 --> 07:55:07,398 different I don't use def I didn't even 12419 07:55:05,120 --> 07:55:09,398 give it a name like get name i instead 12420 07:55:07,398 --> 07:55:11,878 I'm using this other keyword in Python 12421 07:55:09,398 --> 07:55:14,160 called Lambda which says Hey python here 12422 07:55:11,878 --> 07:55:16,600 comes a function but it has no name it's 12423 07:55:14,160 --> 07:55:18,440 Anonymous that function takes a 12424 07:55:16,600 --> 07:55:20,958 parameter I could call it anything I 12425 07:55:18,440 --> 07:55:23,920 want I'm calling it student why because 12426 07:55:20,958 --> 07:55:26,680 this function that's passed in as key is 12427 07:55:23,920 --> 07:55:28,520 called on every one of the students in 12428 07:55:26,680 --> 07:55:30,638 that list every one of the dictionaries 12429 07:55:28,520 --> 07:55:32,840 in that list what do I want this 12430 07:55:30,638 --> 07:55:35,200 Anonymous function to return well given 12431 07:55:32,840 --> 07:55:37,638 a student I want to index into that 12432 07:55:35,200 --> 07:55:40,120 dictionary and access their name so that 12433 07:55:37,638 --> 07:55:42,478 the string Hermione and Harry and Ron 12434 07:55:40,120 --> 07:55:44,398 and Draco is ultimately returned and 12435 07:55:42,478 --> 07:55:47,040 that's what the sorted function uses to 12436 07:55:44,398 --> 07:55:49,160 decide how to sort these bigger 12437 07:55:47,040 --> 07:55:52,280 dictionaries that have other Keys like 12438 07:55:49,160 --> 07:55:54,040 house as well so if I now go back to my 12439 07:55:52,280 --> 07:55:56,360 terminal window and run python of 12440 07:55:54,040 --> 07:55:58,920 students. it still seems to work the 12441 07:55:56,360 --> 07:56:00,638 same but it's arguably a little better 12442 07:55:58,920 --> 07:56:02,360 design because I didn't waste lines of 12443 07:56:00,638 --> 07:56:04,558 Code by defining some other function 12444 07:56:02,360 --> 07:56:07,040 calling it in one and only one place 12445 07:56:04,558 --> 07:56:09,200 I've done it all sort of in one breath 12446 07:56:07,040 --> 07:56:10,360 if you will all right let me pause here 12447 07:56:09,200 --> 07:56:13,760 to see if there's any questions 12448 07:56:10,360 --> 07:56:16,478 specifically about Lambda or Anonymous 12449 07:56:13,760 --> 07:56:19,240 functions and this tightening up of the 12450 07:56:16,478 --> 07:56:22,798 code and I had one question like whether 12451 07:56:19,240 --> 07:56:25,040 we could Define Lambda twice can you you 12452 07:56:22,798 --> 07:56:27,318 can use Lambda twice you can create as 12453 07:56:25,040 --> 07:56:29,600 many Anonymous functions as you'd like 12454 07:56:27,318 --> 07:56:31,240 and you generally use them in context 12455 07:56:29,600 --> 07:56:34,080 like this where you want to pass to some 12456 07:56:31,240 --> 07:56:35,840 other function uh a function that itself 12457 07:56:34,080 --> 07:56:37,798 does not need a name so you can 12458 07:56:35,840 --> 07:56:39,958 absolutely use it in more than one place 12459 07:56:37,798 --> 07:56:41,840 I just have only one use case for it how 12460 07:56:39,958 --> 07:56:44,080 about one other question on Lambda or 12461 07:56:41,840 --> 07:56:45,760 Anonymous functions specifically what 12462 07:56:44,080 --> 07:56:49,520 what if our 12463 07:56:45,760 --> 07:56:52,920 Lambda would take more than one line for 12464 07:56:49,520 --> 07:56:55,240 example if sure if your Lambda function 12465 07:56:52,920 --> 07:56:58,440 takes multiple parameters that is fine 12466 07:56:55,240 --> 07:57:00,200 you can simply specify commas follow by 12467 07:56:58,440 --> 07:57:03,280 the names of those parameters maybe X 12468 07:57:00,200 --> 07:57:04,958 and Y or so forth after the name student 12469 07:57:03,280 --> 07:57:07,000 so here too Lambda looks a little 12470 07:57:04,958 --> 07:57:08,360 different from DEA in that you don't 12471 07:57:07,000 --> 07:57:09,718 have parentheses you don't have the 12472 07:57:08,360 --> 07:57:11,638 keyword def you don't have a function 12473 07:57:09,718 --> 07:57:13,600 name but ultimately they achieve that 12474 07:57:11,638 --> 07:57:16,120 same effect they create a function 12475 07:57:13,600 --> 07:57:18,920 anonymously and allow you to pass it in 12476 07:57:16,120 --> 07:57:21,478 for instance as some value here so let's 12477 07:57:18,920 --> 07:57:23,600 now change students. CSV to contain not 12478 07:57:21,478 --> 07:57:25,878 students houses at Hogwarts but their 12479 07:57:23,600 --> 07:57:28,798 homes where they grew up so Draco for 12480 07:57:25,878 --> 07:57:32,280 instance grew up in Malfoy Manor uh Ron 12481 07:57:28,798 --> 07:57:37,240 grew up in the burrow uh Harry grew up 12482 07:57:32,280 --> 07:57:39,080 in uh number four privet drive and 12483 07:57:37,240 --> 07:57:41,000 according to the internet no one knows 12484 07:57:39,080 --> 07:57:42,440 where hermion grew up the movies 12485 07:57:41,000 --> 07:57:43,958 apparently took certain liberties with 12486 07:57:42,440 --> 07:57:45,558 where she grew up so for this purpose 12487 07:57:43,958 --> 07:57:47,440 we're actually going to remove Hermione 12488 07:57:45,558 --> 07:57:49,398 because it is unknown exactly where she 12489 07:57:47,440 --> 07:57:52,478 was born so we still have some three 12490 07:57:49,398 --> 07:57:56,200 students but if anyone can spot the 12491 07:57:52,478 --> 07:57:58,160 potential problem now how might this be 12492 07:57:56,200 --> 07:57:59,718 a bad thing well let's go and try and 12493 07:57:58,160 --> 07:58:02,120 run our own code here let me go back to 12494 07:57:59,718 --> 07:58:03,798 students. py here and let me propose 12495 07:58:02,120 --> 07:58:05,478 that I just change my semantics because 12496 07:58:03,798 --> 07:58:07,638 I'm now not thinking about Hogwarts 12497 07:58:05,478 --> 07:58:09,318 houses but the students own home so I'm 12498 07:58:07,638 --> 07:58:11,920 just going to change some variables I'm 12499 07:58:09,318 --> 07:58:14,160 going to change this house to a home 12500 07:58:11,920 --> 07:58:15,878 this house to a home as well as this one 12501 07:58:14,160 --> 07:58:17,680 here I'm still going to sort the 12502 07:58:15,878 --> 07:58:20,160 students by name but I'm going to say 12503 07:58:17,680 --> 07:58:22,680 that they're not in a house but rather 12504 07:58:20,160 --> 07:58:24,680 from a home so I've just Chang the names 12505 07:58:22,680 --> 07:58:26,840 of my variables in my grammar in English 12506 07:58:24,680 --> 07:58:29,080 here ultimately to print out that for 12507 07:58:26,840 --> 07:58:31,718 instance Harry is from number four 12508 07:58:29,080 --> 07:58:33,798 privet drive and so forth but let's see 12509 07:58:31,718 --> 07:58:36,638 what happens here when I run python of 12510 07:58:33,798 --> 07:58:39,680 this version of students. having changed 12511 07:58:36,638 --> 07:58:41,360 students. CSV to contain those homes and 12512 07:58:39,680 --> 07:58:45,398 not houses 12513 07:58:41,360 --> 07:58:48,840 enter huh our first value error like the 12514 07:58:45,398 --> 07:58:51,318 program just doesn't work What might 12515 07:58:48,840 --> 07:58:54,318 explain this value error the explanation 12516 07:58:51,318 --> 07:58:56,478 of which rather cryptically is too many 12517 07:58:54,318 --> 07:59:00,318 values to unpack and the line in 12518 07:58:56,478 --> 07:59:02,638 question is this one involving split how 12519 07:59:00,318 --> 07:59:05,240 did all of a sudden after all of these 12520 07:59:02,638 --> 07:59:08,440 successful runs of this program did line 12521 07:59:05,240 --> 07:59:10,958 five suddenly now break in the line in 12522 07:59:08,440 --> 07:59:12,520 students that says we you have three 12523 07:59:10,958 --> 07:59:15,760 values there's a line that you have 12524 07:59:12,520 --> 07:59:17,558 three values and and students yeah I 12525 07:59:15,760 --> 07:59:19,798 spent a lot of time trying to figure out 12526 07:59:17,558 --> 07:59:21,680 where uh every student should be from so 12527 07:59:19,798 --> 07:59:23,478 that we could create this problem for us 12528 07:59:21,680 --> 07:59:26,558 and wonderfully like the first sentence 12529 07:59:23,478 --> 07:59:28,520 of the book is number four privet drive 12530 07:59:26,558 --> 07:59:31,200 and so the fact that that address has a 12531 07:59:28,520 --> 07:59:33,200 comma in it is problematic why because 12532 07:59:31,200 --> 07:59:35,558 you and I decided some time ago to just 12533 07:59:33,200 --> 07:59:41,080 standardize on commas CSV comma 12534 07:59:35,558 --> 07:59:42,600 separated values to denote the uh uh we 12535 07:59:41,080 --> 07:59:45,318 standardized on commas in order to 12536 07:59:42,600 --> 07:59:48,000 delineate one value from another and if 12537 07:59:45,318 --> 07:59:50,478 we have commas grammatically in the 12538 07:59:48,000 --> 07:59:52,680 student's home we're clearly confusing 12539 07:59:50,478 --> 07:59:55,398 it as this special symbol and the split 12540 07:59:52,680 --> 07:59:58,120 function is now for just Harry trying to 12541 07:59:55,398 --> 07:59:59,920 split it into three values not just two 12542 07:59:58,120 --> 08:00:02,318 and that's why there's too many values 12543 07:59:59,920 --> 08:00:05,558 to unpack because we're only trying to 12544 08:00:02,318 --> 08:00:07,398 assign two variables name and house now 12545 08:00:05,558 --> 08:00:09,478 what could we do here well we could just 12546 08:00:07,398 --> 08:00:11,638 change our approach for instance like 12547 08:00:09,478 --> 08:00:14,920 one Paradigm that is not uncommon is to 12548 08:00:11,638 --> 08:00:17,398 use something uh a little more um a 12549 08:00:14,920 --> 08:00:19,160 little less common like a vertical bar 12550 08:00:17,398 --> 08:00:21,520 so I could go in and change all of my 12551 08:00:19,160 --> 08:00:23,240 commas to Vertical bars that too could 12552 08:00:21,520 --> 08:00:25,280 eventually come back to bite Us in that 12553 08:00:23,240 --> 08:00:27,318 if my file eventually has vertical bars 12554 08:00:25,280 --> 08:00:29,200 somewhere it might still break so maybe 12555 08:00:27,318 --> 08:00:30,920 that's not the best approach I could 12556 08:00:29,200 --> 08:00:33,240 maybe do something like this I could 12557 08:00:30,920 --> 08:00:36,318 escape the data as I've done in the past 12558 08:00:33,240 --> 08:00:39,040 and maybe I could put quotes around any 12559 08:00:36,318 --> 08:00:41,360 English string that itself contains a 12560 08:00:39,040 --> 08:00:44,160 comma and that's fine I could do that 12561 08:00:41,360 --> 08:00:46,040 but then my code students. py is going 12562 08:00:44,160 --> 08:00:48,798 to have to change too because I can't 12563 08:00:46,040 --> 08:00:51,040 just naively split on a comma Now I'm 12564 08:00:48,798 --> 08:00:52,958 going to have to be smarter about it I'm 12565 08:00:51,040 --> 08:00:55,360 going to have to take into account split 12566 08:00:52,958 --> 08:00:57,160 only on the commas that are not inside 12567 08:00:55,360 --> 08:00:59,440 of quotes and oh it's getting 12568 08:00:57,160 --> 08:01:01,000 complicated fast and at this point you 12569 08:00:59,440 --> 08:01:02,360 need to take a step back and consider 12570 08:01:01,000 --> 08:01:04,600 you know what if we're having this 12571 08:01:02,360 --> 08:01:06,760 problem odds are many other people 12572 08:01:04,600 --> 08:01:09,398 before us have had this same problem it 12573 08:01:06,760 --> 08:01:12,160 is incredibly common to store data in 12574 08:01:09,398 --> 08:01:15,120 files it is incredibly common to use CSV 12575 08:01:12,160 --> 08:01:17,360 files specifically and so you know what 12576 08:01:15,120 --> 08:01:20,680 why don't we see if there's a library in 12577 08:01:17,360 --> 08:01:23,478 Python that exists to read Andor write 12578 08:01:20,680 --> 08:01:25,240 CSV files rather than reinvent a wheel 12579 08:01:23,478 --> 08:01:27,160 so to speak let's see if we can write 12580 08:01:25,240 --> 08:01:28,760 better code by standing on the shoulders 12581 08:01:27,160 --> 08:01:30,878 of others who have come before us 12582 08:01:28,760 --> 08:01:32,478 programmers passed and actually use 12583 08:01:30,878 --> 08:01:34,840 their code to do the reading and writing 12584 08:01:32,478 --> 08:01:37,718 of csvs so we can focus on the part of 12585 08:01:34,840 --> 08:01:39,360 our problem that you and I care about so 12586 08:01:37,718 --> 08:01:42,040 let's propose that we go back to our 12587 08:01:39,360 --> 08:01:44,600 code here and see how we might use the 12588 08:01:42,040 --> 08:01:48,558 CSV Library indeed within python there 12589 08:01:44,600 --> 08:01:50,760 is a module called CSV the documentation 12590 08:01:48,558 --> 08:01:52,718 for it is at this URL here in Python's 12591 08:01:50,760 --> 08:01:54,798 official documentation but there's a few 12592 08:01:52,718 --> 08:01:57,398 functions that are pretty readily 12593 08:01:54,798 --> 08:01:59,878 accessible if we just Dive Right In and 12594 08:01:57,398 --> 08:02:02,200 let me OS that we do this let me go back 12595 08:01:59,878 --> 08:02:04,478 to my code here and instead of 12596 08:02:02,200 --> 08:02:06,520 Reinventing this wheel and reading the 12597 08:02:04,478 --> 08:02:08,718 file line by line and splitting on 12598 08:02:06,520 --> 08:02:11,240 commas and dealing now with quotes and 12599 08:02:08,718 --> 08:02:14,160 privet drives and so forth let's do this 12600 08:02:11,240 --> 08:02:17,638 instead at the start of my program let 12601 08:02:14,160 --> 08:02:19,718 me go up and import the CSV module let's 12602 08:02:17,638 --> 08:02:21,718 use this library that someone else has 12603 08:02:19,718 --> 08:02:23,878 written that's dealing with all of these 12604 08:02:21,718 --> 08:02:26,360 Corner cases if you will I'm still going 12605 08:02:23,878 --> 08:02:28,120 to give myself a list initially empty in 12606 08:02:26,360 --> 08:02:30,160 which to store all these students but 12607 08:02:28,120 --> 08:02:33,200 I'm going to change my Approach here now 12608 08:02:30,160 --> 08:02:36,200 just a little bit when I open this file 12609 08:02:33,200 --> 08:02:38,200 with width let me go in here and change 12610 08:02:36,200 --> 08:02:43,160 this a little bit I'm going to go in 12611 08:02:38,200 --> 08:02:46,318 here now and say this uh reader equals 12612 08:02:43,160 --> 08:02:48,000 csvreader passing in file as input so it 12613 08:02:46,318 --> 08:02:50,440 turns out if you read the documentation 12614 08:02:48,000 --> 08:02:52,680 for the CSV module it comes with a 12615 08:02:50,440 --> 08:02:55,398 function called reader whose purpose in 12616 08:02:52,680 --> 08:02:57,520 life is to read a CSV file for you and 12617 08:02:55,398 --> 08:02:59,558 figure out where are the commas where 12618 08:02:57,520 --> 08:03:01,318 are the quotes where are all the the 12619 08:02:59,558 --> 08:03:03,398 potential Corner cases and just deal 12620 08:03:01,318 --> 08:03:05,000 with them for you you can override 12621 08:03:03,398 --> 08:03:06,878 certain defaults or assumptions in case 12622 08:03:05,000 --> 08:03:08,760 you're using not a comma but a pipe or 12623 08:03:06,878 --> 08:03:11,080 something else but by default I think 12624 08:03:08,760 --> 08:03:13,520 it's just going to work now how do I 12625 08:03:11,080 --> 08:03:15,398 iterate over a reader and not the raw 12626 08:03:13,520 --> 08:03:17,958 file itself it's almost the same the 12627 08:03:15,398 --> 08:03:20,958 library allows you still to do this for 12628 08:03:17,958 --> 08:03:23,120 each row in the reader so you're not 12629 08:03:20,958 --> 08:03:24,798 iterating over the file directly now 12630 08:03:23,120 --> 08:03:26,798 you're iterating over the reader which 12631 08:03:24,798 --> 08:03:29,520 is again going to handle all of the 12632 08:03:26,798 --> 08:03:31,318 parsing of comma in new lines and more 12633 08:03:29,520 --> 08:03:33,520 for each row in the reader what am I 12634 08:03:31,318 --> 08:03:35,760 going to do well at the moment I'm going 12635 08:03:33,520 --> 08:03:38,760 to do this I'm going to append to my 12636 08:03:35,760 --> 08:03:41,280 students list the following dictionary a 12637 08:03:38,760 --> 08:03:44,318 dictionary that has a name whose value 12638 08:03:41,280 --> 08:03:47,360 is the current Row's First Column and 12639 08:03:44,318 --> 08:03:49,840 whose house or rather home now is the 12640 08:03:47,360 --> 08:03:52,600 Row's second column now it's worth 12641 08:03:49,840 --> 08:03:54,840 noting that the reader for each line in 12642 08:03:52,600 --> 08:03:57,160 the file indeed returns to me a row but 12643 08:03:54,840 --> 08:03:58,520 it returns to me a row that's a list 12644 08:03:57,160 --> 08:04:00,160 which is to say say that the first 12645 08:03:58,520 --> 08:04:02,440 element of that list is going to be the 12646 08:04:00,160 --> 08:04:03,958 student's name as before the second 12647 08:04:02,440 --> 08:04:07,958 element of that list is going to be the 12648 08:04:03,958 --> 08:04:09,558 student's home uh as now before but if I 12649 08:04:07,958 --> 08:04:11,600 want to access each of those elements 12650 08:04:09,558 --> 08:04:13,398 remember that lists are zero indexed we 12651 08:04:11,600 --> 08:04:15,120 start counting at zero and then one 12652 08:04:13,398 --> 08:04:16,558 rather than one and then two so if I 12653 08:04:15,120 --> 08:04:18,360 want to get at the student's name I use 12654 08:04:16,558 --> 08:04:20,680 Row Bracket zero and if I want to get at 12655 08:04:18,360 --> 08:04:22,920 the student's home I use Row Bracket one 12656 08:04:20,680 --> 08:04:26,000 but in my four Loop we can do that same 12657 08:04:22,920 --> 08:04:28,398 unpacking as before if I know this CSV 12658 08:04:26,000 --> 08:04:31,840 is only going to have two columns I 12659 08:04:28,398 --> 08:04:34,360 could even do this for name home in 12660 08:04:31,840 --> 08:04:36,478 reader and now I don't need to use list 12661 08:04:34,360 --> 08:04:40,120 notation I can unpack things all at once 12662 08:04:36,478 --> 08:04:42,240 and say name here and home here the rest 12663 08:04:40,120 --> 08:04:44,280 of my code can stay exactly the same 12664 08:04:42,240 --> 08:04:45,878 because what am I doing now on line 8 12665 08:04:44,280 --> 08:04:48,080 I'm still constructing the same 12666 08:04:45,878 --> 08:04:50,398 dictionary as before albeit for homes 12667 08:04:48,080 --> 08:04:52,520 instead of houses and I'm grabbing those 12668 08:04:50,398 --> 08:04:54,840 values now not from the file itself and 12669 08:04:52,520 --> 08:04:56,478 my use of split but the reader and again 12670 08:04:54,840 --> 08:04:58,200 what the reader is going to do is figure 12671 08:04:56,478 --> 08:05:00,440 out where are those commas where are the 12672 08:04:58,200 --> 08:05:02,558 quotes and just solve that problem for 12673 08:05:00,440 --> 08:05:04,958 you so let me go now down to my terminal 12674 08:05:02,558 --> 08:05:07,958 window and run python of students. and 12675 08:05:04,958 --> 08:05:10,558 hit enter and now we see successfully 12676 08:05:07,958 --> 08:05:12,840 sorted no less that Draco is from Mal 12677 08:05:10,558 --> 08:05:16,318 for Manor Harry is from number four 12678 08:05:12,840 --> 08:05:19,478 comma Private Drive and Ron is from the 12679 08:05:16,318 --> 08:05:24,478 burrow questions now on this technique 12680 08:05:19,478 --> 08:05:26,160 of using CSV reader from that CSV module 12681 08:05:24,478 --> 08:05:28,440 which again is just getting us out of 12682 08:05:26,160 --> 08:05:30,000 the business of reading each line our in 12683 08:05:28,440 --> 08:05:32,440 Reading each of those commas and 12684 08:05:30,000 --> 08:05:34,958 splitting so my question is related to 12685 08:05:32,440 --> 08:05:37,718 something a bit bit in the past um I 12686 08:05:34,958 --> 08:05:41,120 recognize that you are reading a file 12687 08:05:37,718 --> 08:05:43,280 every time you well you we're we're 12688 08:05:41,120 --> 08:05:46,920 assuming that we have the CSV file to 12689 08:05:43,280 --> 08:05:51,120 hand already in this case um is it 12690 08:05:46,920 --> 08:05:55,160 possible to make a file readable and 12691 08:05:51,120 --> 08:05:58,398 writable so in in in in case if you want 12692 08:05:55,160 --> 08:06:00,718 you could you could write stuff to the 12693 08:05:58,398 --> 08:06:02,958 but then at the same time you could have 12694 08:06:00,718 --> 08:06:05,318 another function that reads through the 12695 08:06:02,958 --> 08:06:06,920 file and as changes to it as you go 12696 08:06:05,318 --> 08:06:09,520 along a really good question and the 12697 08:06:06,920 --> 08:06:11,558 short answer is yes however historically 12698 08:06:09,520 --> 08:06:13,440 the mental model for a file is that of a 12699 08:06:11,558 --> 08:06:15,840 cassette tape years ago not really in 12700 08:06:13,440 --> 08:06:17,520 use anymore but cassette tapes are 12701 08:06:15,840 --> 08:06:18,638 sequential whereby they start at the 12702 08:06:17,520 --> 08:06:20,718 beginning and if you want to get to the 12703 08:06:18,638 --> 08:06:22,440 end you kind of have to uh unwind the 12704 08:06:20,718 --> 08:06:24,160 tape to get to that point the closest 12705 08:06:22,440 --> 08:06:26,000 analog nowadays would be something like 12706 08:06:24,160 --> 08:06:27,760 Netflix or any streaming service where 12707 08:06:26,000 --> 08:06:29,440 there's a scrubber that you have to go 12708 08:06:27,760 --> 08:06:31,040 left to right you can't just jump there 12709 08:06:29,440 --> 08:06:33,200 or jump there you don't have Random 12710 08:06:31,040 --> 08:06:35,558 Access so the problem with files if you 12711 08:06:33,200 --> 08:06:37,360 want to read and write them you or some 12712 08:06:35,558 --> 08:06:38,718 Library needs to keep track of where you 12713 08:06:37,360 --> 08:06:40,718 are in the file so that if you're 12714 08:06:38,718 --> 08:06:41,840 reading from the top and then you write 12715 08:06:40,718 --> 08:06:43,798 at the bottom and you want to start 12716 08:06:41,840 --> 08:06:45,440 reading again you seek back to the 12717 08:06:43,798 --> 08:06:46,958 beginning so it's not something we'll do 12718 08:06:45,440 --> 08:06:49,798 here in class it's more involved but 12719 08:06:46,958 --> 08:06:51,798 it's absolutely doable for our purposes 12720 08:06:49,798 --> 08:06:53,120 we'll generally recommend read the file 12721 08:06:51,798 --> 08:06:54,878 and then if you want to change it write 12722 08:06:53,120 --> 08:06:57,360 it back out rather than trying to make 12723 08:06:54,878 --> 08:06:59,240 more peac mail changes which is good if 12724 08:06:57,360 --> 08:07:01,520 the though the file is massive and it 12725 08:06:59,240 --> 08:07:03,798 would just be very expensive TimeWise to 12726 08:07:01,520 --> 08:07:09,080 change the whole thing other questions 12727 08:07:03,798 --> 08:07:13,478 on this CSV reader is possible to write 12728 08:07:09,080 --> 08:07:15,638 uh a paragraph in that file absolutely 12729 08:07:13,478 --> 08:07:17,878 right now I'm writing very small strings 12730 08:07:15,638 --> 08:07:19,958 just names or houses as I did before but 12731 08:07:17,878 --> 08:07:24,398 you can absolutely write as much text as 12732 08:07:19,958 --> 08:07:28,520 you want indeed other questions on CSV 12733 08:07:24,398 --> 08:07:32,478 reader can user choose 12734 08:07:28,520 --> 08:07:36,440 himself a key like input key will be a 12735 08:07:32,478 --> 08:07:38,000 name or home so short answer yes we 12736 08:07:36,440 --> 08:07:40,798 could absolutely write a program that 12737 08:07:38,000 --> 08:07:42,398 prompts the user for a name and a home a 12738 08:07:40,798 --> 08:07:43,878 name and a home and we could write out 12739 08:07:42,398 --> 08:07:47,120 those values and in a moment we'll see 12740 08:07:43,878 --> 08:07:49,318 how you can write to a CSV file for now 12741 08:07:47,120 --> 08:07:52,160 I'm assuming as the programmer who 12742 08:07:49,318 --> 08:07:53,638 created students. CSV that I know what 12743 08:07:52,160 --> 08:07:55,398 the columns are going to be and 12744 08:07:53,638 --> 08:07:57,680 therefore I'm naming my variables 12745 08:07:55,398 --> 08:08:00,558 accordingly however this is a good seg 12746 08:07:57,680 --> 08:08:02,558 way to one final feature of reading csvs 12747 08:08:00,558 --> 08:08:05,240 which is that you don't have to rely on 12748 08:08:02,558 --> 08:08:07,440 either getting a row as a list and using 12749 08:08:05,240 --> 08:08:09,240 bracket zero or bracket one and you 12750 08:08:07,440 --> 08:08:11,398 don't have to unpack things manually in 12751 08:08:09,240 --> 08:08:13,478 this way we could actually be smarter 12752 08:08:11,398 --> 08:08:16,080 and start storing the names of these 12753 08:08:13,478 --> 08:08:17,798 columns in the CSV file itself and in 12754 08:08:16,080 --> 08:08:20,240 fact if any of you have ever opened a 12755 08:08:17,798 --> 08:08:22,360 spreadsheet file before be it in Excel 12756 08:08:20,240 --> 08:08:24,280 Apple Numbers Google spreadsheets or the 12757 08:08:22,360 --> 08:08:26,798 like odds are you've noticed that the 12758 08:08:24,280 --> 08:08:28,760 first row very frequently is a little 12759 08:08:26,798 --> 08:08:30,318 different it actually is boldface 12760 08:08:28,760 --> 08:08:32,398 sometimes or it actually contains the 12761 08:08:30,318 --> 08:08:34,798 names of those columns the names of 12762 08:08:32,398 --> 08:08:37,280 those attributes below and we can do 12763 08:08:34,798 --> 08:08:39,040 this here in students. CSV I don't have 12764 08:08:37,280 --> 08:08:41,160 to just keep assuming that the student's 12765 08:08:39,040 --> 08:08:43,878 name is first and that the student's 12766 08:08:41,160 --> 08:08:46,718 home is second I can explicitly bake 12767 08:08:43,878 --> 08:08:48,558 that information into the file just to 12768 08:08:46,718 --> 08:08:50,558 reduce the probability of mistakes down 12769 08:08:48,558 --> 08:08:54,240 the road I can literally use the first 12770 08:08:50,558 --> 08:08:57,160 row of this file and say name comma home 12771 08:08:54,240 --> 08:08:58,558 so notice that name is not literally 12772 08:08:57,160 --> 08:09:00,200 something some 's name and home is not 12773 08:08:58,558 --> 08:09:03,638 literally someone's home it is literally 12774 08:09:00,200 --> 08:09:05,638 the words name and home separated by a 12775 08:09:03,638 --> 08:09:09,000 comma and if I now go back into 12776 08:09:05,638 --> 08:09:11,718 students. py and don't use CSV reader 12777 08:09:09,000 --> 08:09:15,200 but instead I use a dictionary reader I 12778 08:09:11,718 --> 08:09:16,920 can actually treat my CSV file even more 12779 08:09:15,200 --> 08:09:19,638 flexibly not just for this but for other 12780 08:09:16,920 --> 08:09:22,478 examples too let me do this instead of 12781 08:09:19,638 --> 08:09:25,478 using a CSV reader let me use a CSV dict 12782 08:09:22,478 --> 08:09:28,638 reader which will now iterate over the 12783 08:09:25,478 --> 08:09:31,920 file top to bottom loading in each line 12784 08:09:28,638 --> 08:09:34,680 of text not as a list of columns but as 12785 08:09:31,920 --> 08:09:36,000 a dictionary of columns what's nice 12786 08:09:34,680 --> 08:09:38,798 about this is that it's going to give me 12787 08:09:36,000 --> 08:09:40,920 automatic access now to those columns 12788 08:09:38,798 --> 08:09:43,840 names I'm going to revert to just saying 12789 08:09:40,920 --> 08:09:46,280 for Row in reader and now I'm going to 12790 08:09:43,840 --> 08:09:49,398 append a name and a home but how am I 12791 08:09:46,280 --> 08:09:52,398 going to get access to the current rows 12792 08:09:49,398 --> 08:09:54,440 name and the current rows home well 12793 08:09:52,398 --> 08:09:56,160 earlier I used bracket zero for the 12794 08:09:54,440 --> 08:09:58,718 first and bracket one for the second 12795 08:09:56,160 --> 08:10:01,000 when I was using a reader a reader 12796 08:09:58,718 --> 08:10:03,840 returns lists a dict reader or 12797 08:10:01,000 --> 08:10:07,160 dictionary reader returns dictionaries 12798 08:10:03,840 --> 08:10:09,318 one at a time and so if I want to access 12799 08:10:07,160 --> 08:10:11,840 the current Row's name I can say row 12800 08:10:09,318 --> 08:10:14,718 quote unquote name I can say here for 12801 08:10:11,840 --> 08:10:16,520 home row quote unquote home and I now 12802 08:10:14,718 --> 08:10:18,040 have access to those same values the 12803 08:10:16,520 --> 08:10:20,920 only change I had to make to be clear 12804 08:10:18,040 --> 08:10:23,680 was in my CSV file I had to include on 12805 08:10:20,920 --> 08:10:26,120 the very first row little hints as to 12806 08:10:23,680 --> 08:10:28,000 what these columns are and if I now run 12807 08:10:26,120 --> 08:10:30,318 this code I think it's should behave 12808 08:10:28,000 --> 08:10:32,638 pretty much the same python of students. 12809 08:10:30,318 --> 08:10:35,760 and indeed we get the same sentences but 12810 08:10:32,638 --> 08:10:38,280 now my code is more robust against 12811 08:10:35,760 --> 08:10:40,638 changes in this data if I were to open 12812 08:10:38,280 --> 08:10:42,440 the CSV file in Excel or Google 12813 08:10:40,638 --> 08:10:44,398 spreadsheets or apple numbers and for 12814 08:10:42,440 --> 08:10:45,920 whatever reason change the columns 12815 08:10:44,398 --> 08:10:47,398 around maybe this is a file that you're 12816 08:10:45,920 --> 08:10:49,360 sharing with someone else and just 12817 08:10:47,398 --> 08:10:51,000 because they decide to sort things 12818 08:10:49,360 --> 08:10:53,798 differently left or right by moving the 12819 08:10:51,000 --> 08:10:55,840 columns around previously my code would 12820 08:10:53,798 --> 08:10:58,558 have broken because I was assuming that 12821 08:10:55,840 --> 08:11:02,160 name is always first and home is always 12822 08:10:58,558 --> 08:11:03,920 second but if I did this be it manually 12823 08:11:02,160 --> 08:11:06,520 in one of those programs or here home 12824 08:11:03,920 --> 08:11:08,318 comma name and suppose I reversed all of 12825 08:11:06,520 --> 08:11:12,440 this the home comes first followed by 12826 08:11:08,318 --> 08:11:15,760 Harry the burrow then by Ron and then 12827 08:11:12,440 --> 08:11:17,760 lastly Maloy Manor then Draco notice 12828 08:11:15,760 --> 08:11:19,240 that my file is now completely flipped 12829 08:11:17,760 --> 08:11:21,520 the First Column is now the second and 12830 08:11:19,240 --> 08:11:24,318 the second's the first but I took care 12831 08:11:21,520 --> 08:11:27,080 to update the header of that file the 12832 08:11:24,318 --> 08:11:28,520 first row notice my python code I'm not 12833 08:11:27,080 --> 08:11:31,318 going to going to touch it at all I'm 12834 08:11:28,520 --> 08:11:34,240 going to rerun python of students. py 12835 08:11:31,318 --> 08:11:35,958 and hit enter and it still just works 12836 08:11:34,240 --> 08:11:37,680 and this too is an example of like 12837 08:11:35,958 --> 08:11:39,878 coding defensively like what if someone 12838 08:11:37,680 --> 08:11:41,718 changes your CSV file your data file 12839 08:11:39,878 --> 08:11:44,040 ideally that won't happen but even if it 12840 08:11:41,718 --> 08:11:46,798 does now because I'm using a dictionary 12841 08:11:44,040 --> 08:11:49,120 reader that's going to infer from that 12842 08:11:46,798 --> 08:11:51,798 first row for me what the columns are 12843 08:11:49,120 --> 08:11:54,318 called my code just keeps working and so 12844 08:11:51,798 --> 08:11:57,318 it keeps getting if you will better and 12845 08:11:54,318 --> 08:11:59,920 better any questions now on this 12846 08:11:57,318 --> 08:12:02,200 approach yeah what is the importance of 12847 08:11:59,920 --> 08:12:04,440 new line CSV file what's the importance 12848 08:12:02,200 --> 08:12:06,558 of the new line in the CSV file it's 12849 08:12:04,440 --> 08:12:08,200 partly a convention in the world of text 12850 08:12:06,558 --> 08:12:11,000 files we humans have just been for 12851 08:12:08,200 --> 08:12:13,680 decades in the habit of storing um data 12852 08:12:11,000 --> 08:12:16,120 line by line it's visually convenient 12853 08:12:13,680 --> 08:12:17,840 it's just easy to extract from the file 12854 08:12:16,120 --> 08:12:20,958 because you just look for the new lines 12855 08:12:17,840 --> 08:12:23,080 so the new line just separates some data 12856 08:12:20,958 --> 08:12:25,398 from some other data we could use any 12857 08:12:23,080 --> 08:12:27,000 other symbol on the keyboard but it's 12858 08:12:25,398 --> 08:12:29,160 just common to hit enter to just move 12859 08:12:27,000 --> 08:12:31,680 the data to the next line just a 12860 08:12:29,160 --> 08:12:34,558 convention other questions it seems to 12861 08:12:31,680 --> 08:12:36,878 be working fine if you just have name 12862 08:12:34,558 --> 08:12:39,638 and home I'm wondering what will happen 12863 08:12:36,878 --> 08:12:44,760 if you want to put in more 12864 08:12:39,638 --> 08:12:48,000 data um say you wanted to add the house 12865 08:12:44,760 --> 08:12:49,920 to both the name and the home sure if 12866 08:12:48,000 --> 08:12:52,760 you wanted to add the house back so if I 12867 08:12:49,920 --> 08:12:55,318 go in here and add house last and I go 12868 08:12:52,760 --> 08:12:58,600 here and say uh Gryffindor for Harry 12869 08:12:55,318 --> 08:13:01,160 Gryffindor for Ron and Slither in for 12870 08:12:58,600 --> 08:13:03,280 Draco now I have three columns 12871 08:13:01,160 --> 08:13:05,280 effectively if you will home on the left 12872 08:13:03,280 --> 08:13:07,520 name in the middle house on the right 12873 08:13:05,280 --> 08:13:09,280 each separated by commas with weird 12874 08:13:07,520 --> 08:13:11,798 things like number four comma privet 12875 08:13:09,280 --> 08:13:13,798 Drive still quoted notice if I go back 12876 08:13:11,798 --> 08:13:16,478 to students. py and I don't change the 12877 08:13:13,798 --> 08:13:18,878 code at all and run python of students 12878 08:13:16,478 --> 08:13:20,718 dopy it still just works and this is 12879 08:13:18,878 --> 08:13:23,200 what's so powerful about a dictionary 12880 08:13:20,718 --> 08:13:25,638 reader it can change over time it can 12881 08:13:23,200 --> 08:13:28,160 have more and more columns your existing 12882 08:13:25,638 --> 08:13:30,080 code is not going to break your code 12883 08:13:28,160 --> 08:13:31,520 would break would be much more fragile 12884 08:13:30,080 --> 08:13:33,160 so to speak if you were making 12885 08:13:31,520 --> 08:13:34,600 assumptions like the first column's 12886 08:13:33,160 --> 08:13:36,398 always going to be name the second 12887 08:13:34,600 --> 08:13:38,638 column's always going to be house things 12888 08:13:36,398 --> 08:13:42,120 will break fast if those assumptions 12889 08:13:38,638 --> 08:13:44,240 break down so not a problem in this case 12890 08:13:42,120 --> 08:13:46,318 well let me propose that besides reading 12891 08:13:44,240 --> 08:13:48,478 csvs let's at least take a peek at how 12892 08:13:46,318 --> 08:13:50,160 we might write a CSV too if you're 12893 08:13:48,478 --> 08:13:52,080 writing a program in which you want to 12894 08:13:50,160 --> 08:13:54,558 store not just students names but maybe 12895 08:13:52,080 --> 08:13:56,798 their homes as well in a file how can we 12896 08:13:54,558 --> 08:13:59,798 keep adding to this file let me go ahead 12897 08:13:56,798 --> 08:14:02,638 and delete the contents of students. CSV 12898 08:13:59,798 --> 08:14:05,760 and just read a single simple row name 12899 08:14:02,638 --> 08:14:08,000 comma home so as to anticipate inserting 12900 08:14:05,760 --> 08:14:09,958 more names and homes into this file and 12901 08:14:08,000 --> 08:14:12,040 then let me go to students. py and let 12902 08:14:09,958 --> 08:14:13,398 me just start fresh so as to write out 12903 08:14:12,040 --> 08:14:15,760 data this time I'm still going to go 12904 08:14:13,398 --> 08:14:18,360 ahead and import CSV I'm going to go 12905 08:14:15,760 --> 08:14:21,240 ahead now and prompt the user for their 12906 08:14:18,360 --> 08:14:23,440 name so input quote unquote what's your 12907 08:14:21,240 --> 08:14:25,558 name question mark and I'm going to go 12908 08:14:23,440 --> 08:14:28,160 ahead and prompt the user for their home 12909 08:14:25,558 --> 08:14:31,680 so home equals input quote unquote 12910 08:14:28,160 --> 08:14:33,398 where's your home question mark now I'm 12911 08:14:31,680 --> 08:14:35,520 going to go ahead and open the file but 12912 08:14:33,398 --> 08:14:38,520 this time for writing instead of reading 12913 08:14:35,520 --> 08:14:41,200 as follows with open quote unquote 12914 08:14:38,520 --> 08:14:43,280 students. CSV I'm going to open it in 12915 08:14:41,200 --> 08:14:45,478 append mode so that I keep adding more 12916 08:14:43,280 --> 08:14:47,200 and more students and homes to the file 12917 08:14:45,478 --> 08:14:48,760 rather than just overwriting the entire 12918 08:14:47,200 --> 08:14:51,280 file itself and I'm going to use a 12919 08:14:48,760 --> 08:14:52,798 variable name of file I'm then going to 12920 08:14:51,280 --> 08:14:54,638 go ahead and give myself a variable 12921 08:14:52,798 --> 08:14:56,558 called writer and I'm going to set it 12922 08:14:54,638 --> 08:14:59,878 equal to the return value of another 12923 08:14:56,558 --> 08:15:03,000 function in the CSV module called CSV do 12924 08:14:59,878 --> 08:15:06,318 writer and that writer uh function takes 12925 08:15:03,000 --> 08:15:08,200 as its sole argument the file variable 12926 08:15:06,318 --> 08:15:11,160 there now I'm going to go ahead and just 12927 08:15:08,200 --> 08:15:13,680 do this I'm going to say writer. WR row 12928 08:15:11,160 --> 08:15:16,318 and I'm going to pass into WR Row the 12929 08:15:13,680 --> 08:15:18,080 line that I want to write to the file 12930 08:15:16,318 --> 08:15:21,160 specifically as a list so I'm going to 12931 08:15:18,080 --> 08:15:22,318 give this a list of name comma home 12932 08:15:21,160 --> 08:15:24,000 which of course are the contents of 12933 08:15:22,318 --> 08:15:25,840 those variables now I'm going to go 12934 08:15:24,000 --> 08:15:28,840 ahead and save the file I'm going to go 12935 08:15:25,840 --> 08:15:30,840 ahead and rerun python of students. hit 12936 08:15:28,840 --> 08:15:33,238 enter and what's your name well let me 12937 08:15:30,840 --> 08:15:35,238 go ahead and type in Harry as my name 12938 08:15:33,238 --> 08:15:39,238 and number 12939 08:15:35,238 --> 08:15:41,398 four comma Private Drive enter now 12940 08:15:39,238 --> 08:15:44,238 notice that input itself did have a 12941 08:15:41,398 --> 08:15:46,040 comma and so if I go to my CSV file now 12942 08:15:44,238 --> 08:15:48,160 notice that it's automatically been 12943 08:15:46,040 --> 08:15:50,160 quoted for me so that subsequent reads 12944 08:15:48,160 --> 08:15:52,760 from this file don't confuse that comma 12945 08:15:50,160 --> 08:15:54,398 with the actual comma between Harry and 12946 08:15:52,760 --> 08:15:56,040 his home well let me go ahead and run it 12947 08:15:54,398 --> 08:15:58,718 a couple of more times let me go ahead 12948 08:15:56,040 --> 08:16:00,840 and rerun python of students. py let me 12949 08:15:58,718 --> 08:16:03,280 go ahead and input this time Ron and his 12950 08:16:00,840 --> 08:16:05,638 home as the burrow let's go back to 12951 08:16:03,280 --> 08:16:07,680 students. CSV to see what it looks like 12952 08:16:05,638 --> 08:16:09,558 now we see Ron comma the burough has 12953 08:16:07,680 --> 08:16:12,718 been added automatically to the file and 12954 08:16:09,558 --> 08:16:14,958 let's do one more python of students. 12955 08:16:12,718 --> 08:16:17,478 enter let's go ahead and give draco's 12956 08:16:14,958 --> 08:16:19,798 name and his home which would be Malfoy 12957 08:16:17,478 --> 08:16:22,238 Manor enter and if we go back to 12958 08:16:19,798 --> 08:16:24,200 students. CSV now we see that Draco is 12959 08:16:22,238 --> 08:16:25,840 in the file itself and the library took 12960 08:16:24,200 --> 08:16:28,040 care of not only writing each of those 12961 08:16:25,840 --> 08:16:30,520 rows per the function name it also 12962 08:16:28,040 --> 08:16:32,040 handled the escaping so to speak of any 12963 08:16:30,520 --> 08:16:34,680 strings that themselves contained a 12964 08:16:32,040 --> 08:16:36,120 comma like Harry's own home well it 12965 08:16:34,680 --> 08:16:38,000 turns out there's yet another way we 12966 08:16:36,120 --> 08:16:40,200 could implement this same program 12967 08:16:38,000 --> 08:16:41,798 without having to worry about precisely 12968 08:16:40,200 --> 08:16:44,238 that order again and again and just 12969 08:16:41,798 --> 08:16:46,160 passing in a list it turns out if we're 12970 08:16:44,238 --> 08:16:47,638 keeping track of what's the name and 12971 08:16:46,160 --> 08:16:49,520 what's the home we could use something 12972 08:16:47,638 --> 08:16:51,238 like a dictionary to associate those 12973 08:16:49,520 --> 08:16:52,760 keys with those values so let me go 12974 08:16:51,238 --> 08:16:54,680 ahead and back up and remove these 12975 08:16:52,760 --> 08:16:57,238 students from the file leaving only the 12976 08:16:54,680 --> 08:16:59,360 header row again name comma home and let 12977 08:16:57,238 --> 08:17:01,798 me go over to students. py and this time 12978 08:16:59,360 --> 08:17:04,238 instead of using CSV writer I'm going to 12979 08:17:01,798 --> 08:17:05,920 go ahead and use CSV do dict writer 12980 08:17:04,238 --> 08:17:07,798 which is a dictionary writer that's 12981 08:17:05,920 --> 08:17:10,760 going to open the file in much the same 12982 08:17:07,798 --> 08:17:13,638 way but rather than write a row as this 12983 08:17:10,760 --> 08:17:15,840 list of name comma home what I'm now 12984 08:17:13,638 --> 08:17:19,280 going to do is follows I'm going to 12985 08:17:15,840 --> 08:17:21,680 first uh output an actual dictionary the 12986 08:17:19,280 --> 08:17:23,160 first key of which is Name colon and 12987 08:17:21,680 --> 08:17:24,760 then the value thereof is going to be 12988 08:17:23,160 --> 08:17:26,878 the name that was typed in and I'm going 12989 08:17:24,760 --> 08:17:28,280 to pass in a key of Home quote unquote 12990 08:17:26,878 --> 08:17:30,798 the value of which of course is the home 12991 08:17:28,280 --> 08:17:33,238 that was typed in but with dict writer I 12992 08:17:30,798 --> 08:17:35,558 do need to give it a hint as to the 12993 08:17:33,238 --> 08:17:37,520 order in which those columns are when 12994 08:17:35,558 --> 08:17:40,120 writing it out so that subsequently they 12995 08:17:37,520 --> 08:17:42,718 could be read even if those orderings 12996 08:17:40,120 --> 08:17:45,000 change let me go ahead and pass in field 12997 08:17:42,718 --> 08:17:47,680 names which is a second argument to dict 12998 08:17:45,000 --> 08:17:49,440 writer equals and then a list of the 12999 08:17:47,680 --> 08:17:52,638 actual columns that I know are in this 13000 08:17:49,440 --> 08:17:54,318 file which of course are name comma home 13001 08:17:52,638 --> 08:17:57,080 those times in quotes because that's 13002 08:17:54,318 --> 08:17:58,718 indeed the string names of the column so 13003 08:17:57,080 --> 08:18:01,000 to speak that I intend to write to in 13004 08:17:58,718 --> 08:18:03,238 that file all right now let me go ahead 13005 08:18:01,000 --> 08:18:05,840 and go to my terminal window run python 13006 08:18:03,238 --> 08:18:08,080 of students. py this time I'll type in 13007 08:18:05,840 --> 08:18:12,478 Harry's name again I'll again type in 13008 08:18:08,080 --> 08:18:14,718 number four comma Private Drive enter 13009 08:18:12,478 --> 08:18:16,878 let's now go back to students. CSV and 13010 08:18:14,718 --> 08:18:19,280 voila Perry's back in the file and it's 13011 08:18:16,878 --> 08:18:21,318 properly escaped or quoted I'm sure then 13012 08:18:19,280 --> 08:18:23,798 if we do this again with Ron and the 13013 08:18:21,318 --> 08:18:27,558 burrow and let's go ahead and run it one 13014 08:18:23,798 --> 08:18:30,238 third time with Draco and Malfoy Manor 13015 08:18:27,558 --> 08:18:32,760 enter let's go back to students. CSV and 13016 08:18:30,238 --> 08:18:35,040 Via this dictionary writer we now have 13017 08:18:32,760 --> 08:18:38,478 all three of those students as well so 13018 08:18:35,040 --> 08:18:40,958 whereas with CSV writer the onus is on 13019 08:18:38,478 --> 08:18:43,080 us to pass in a list of all of the 13020 08:18:40,958 --> 08:18:45,080 values we want to put from left to right 13021 08:18:43,080 --> 08:18:46,520 with a dictionary writer technically 13022 08:18:45,080 --> 08:18:48,520 they could be in any order in the 13023 08:18:46,520 --> 08:18:51,638 dictionary in fact I could just have 13024 08:18:48,520 --> 08:18:53,958 correctly done this passing in home 13025 08:18:51,638 --> 08:18:55,958 followed by name but it's a dictionary 13026 08:18:53,958 --> 08:18:57,680 and so the ordering in this case does 13027 08:18:55,958 --> 08:18:59,120 not matter so long as the key is there 13028 08:18:57,680 --> 08:19:01,238 and the value is there and because I 13029 08:18:59,120 --> 08:19:04,040 have passed in field names as the second 13030 08:19:01,238 --> 08:19:06,718 argument to dict writer it ensures that 13031 08:19:04,040 --> 08:19:10,280 the library knows exactly which column 13032 08:19:06,718 --> 08:19:12,920 contains name or home respectively are 13033 08:19:10,280 --> 08:19:16,680 there any questions now on dictionary 13034 08:19:12,920 --> 08:19:20,398 reading dictionary writing or csvs more 13035 08:19:16,680 --> 08:19:23,200 generally inia any specific specific 13036 08:19:20,398 --> 08:19:26,120 situation for me to use single quotation 13037 08:19:23,200 --> 08:19:28,718 or double quotation because uh after the 13038 08:19:26,120 --> 08:19:31,958 print we use single quotation to 13039 08:19:28,718 --> 08:19:35,680 represent the key of the dictionary but 13040 08:19:31,958 --> 08:19:36,878 after the reading or writing we use the 13041 08:19:35,680 --> 08:19:39,280 double 13042 08:19:36,878 --> 08:19:41,238 quotation it's a a good question in 13043 08:19:39,280 --> 08:19:43,680 Python you can generally use double 13044 08:19:41,238 --> 08:19:45,360 quotes or you can use single quotes and 13045 08:19:43,680 --> 08:19:47,440 it doesn't matter you should just be 13046 08:19:45,360 --> 08:19:50,200 self-consistent so that stylistically 13047 08:19:47,440 --> 08:19:52,000 your code looks the same all throughout 13048 08:19:50,200 --> 08:19:54,238 sometimes though it is necessary to 13049 08:19:52,000 --> 08:19:56,718 alternate if you're already using double 13050 08:19:54,238 --> 08:19:59,238 quotes as I was earlier for a long f 13051 08:19:56,718 --> 08:20:00,760 string but inside that F string I was 13052 08:19:59,238 --> 08:20:03,200 interpolating the values of some 13053 08:20:00,760 --> 08:20:05,798 variables using curly braces and those 13054 08:20:03,200 --> 08:20:08,398 variables were dictionaries and in order 13055 08:20:05,798 --> 08:20:10,840 to index into a dictionary you use 13056 08:20:08,398 --> 08:20:12,360 square brackets and then quotes but if 13057 08:20:10,840 --> 08:20:14,160 you're already using double quotes out 13058 08:20:12,360 --> 08:20:17,600 here you should generally use single 13059 08:20:14,160 --> 08:20:19,478 quotes here or vice versa but otherwise 13060 08:20:17,600 --> 08:20:20,760 I'm in the habit of using double quotes 13061 08:20:19,478 --> 08:20:22,878 everywhere others are in the habit of 13062 08:20:20,760 --> 08:20:24,558 using single quotes everywhere it only 13063 08:20:22,878 --> 08:20:28,080 matters sometimes if one might be 13064 08:20:24,558 --> 08:20:30,680 confused for the other 13065 08:20:28,080 --> 08:20:33,760 other questions on dictionary writing or 13066 08:20:30,680 --> 08:20:38,520 reading uh yeah d uh my question is can 13067 08:20:33,760 --> 08:20:40,520 we use multiple CSV files in any program 13068 08:20:38,520 --> 08:20:41,958 absolutely you can use as many CSV files 13069 08:20:40,520 --> 08:20:44,520 as you want and it's just one of the 13070 08:20:41,958 --> 08:20:48,160 formats that you can use to save data 13071 08:20:44,520 --> 08:20:50,798 other questions on csvs or file IO 13072 08:20:48,160 --> 08:20:53,478 thanks for taking my question uh so when 13073 08:20:50,798 --> 08:20:57,080 you're reading from the file the um you 13074 08:20:53,478 --> 08:20:59,718 had the um uh as a as a dictionary you 13075 08:20:57,080 --> 08:21:01,080 had the fields called um couldn't you 13076 08:20:59,718 --> 08:21:02,558 just call when you're reading could 13077 08:21:01,080 --> 08:21:04,520 couldn't you just call the row in the 13078 08:21:02,558 --> 08:21:10,080 previous version of the of the students 13079 08:21:04,520 --> 08:21:11,280 uh P file um when you're reading the uh 13080 08:21:10,080 --> 08:21:16,398 when you're reading each row you are 13081 08:21:11,280 --> 08:21:16,398 splitting out the um the fields by 13082 08:21:16,760 --> 08:21:21,440 name yeah so when you're pending to the 13083 08:21:19,360 --> 08:21:24,238 uh to the students list can you just 13084 08:21:21,440 --> 08:21:28,000 call the uh for row and reader students. 13085 08:21:24,238 --> 08:21:30,840 append row rather than uh rather than 13086 08:21:28,000 --> 08:21:34,558 naming each of the fields oh very clever 13087 08:21:30,840 --> 08:21:38,520 uh short answer yes in so far as dict 13088 08:21:34,558 --> 08:21:40,600 reader returns one dictionary at a time 13089 08:21:38,520 --> 08:21:42,840 when you Loop over it row is already 13090 08:21:40,600 --> 08:21:45,280 going to be a dictionary so yes you 13091 08:21:42,840 --> 08:21:47,798 could actually get away with doing this 13092 08:21:45,280 --> 08:21:50,280 and the effect would really be the same 13093 08:21:47,798 --> 08:21:52,718 in this case good observation how about 13094 08:21:50,280 --> 08:21:56,558 one more question on 13095 08:21:52,718 --> 08:21:59,440 csvs yeah uh when reading in csvs from 13096 08:21:56,558 --> 08:22:01,840 my past work with data a lot of things 13097 08:21:59,440 --> 08:22:03,558 can go wrong I don't know if it's a fair 13098 08:22:01,840 --> 08:22:06,318 question that you can answer in a few 13099 08:22:03,558 --> 08:22:09,760 sentences but are there any best 13100 08:22:06,318 --> 08:22:12,840 practices to double check that sort of 13101 08:22:09,760 --> 08:22:14,920 no mistakes occurred it's a really good 13102 08:22:12,840 --> 08:22:18,000 question and I would say in general if 13103 08:22:14,920 --> 08:22:20,680 you're using code to generate the csvs 13104 08:22:18,000 --> 08:22:22,440 and to read the csvs and you're using a 13105 08:22:20,680 --> 08:22:24,760 good Library theoretically nothing 13106 08:22:22,440 --> 08:22:27,238 should go wrong it should be 100% 13107 08:22:24,760 --> 08:22:29,558 correct if the libraries are 100% 13108 08:22:27,238 --> 08:22:31,440 correct uh you and I tend to be the 13109 08:22:29,558 --> 08:22:34,238 problem like when you let a human touch 13110 08:22:31,440 --> 08:22:36,040 the CSV or when Excel or apple numbers 13111 08:22:34,238 --> 08:22:37,520 or some other tools involve that might 13112 08:22:36,040 --> 08:22:40,600 not be aligned with your codes 13113 08:22:37,520 --> 08:22:42,878 expectations things then yes can break 13114 08:22:40,600 --> 08:22:44,680 um the goal really sometimes honestly 13115 08:22:42,878 --> 08:22:47,040 the solution is manual fixes you go in 13116 08:22:44,680 --> 08:22:49,120 and fix the CSV or you have a lot of 13117 08:22:47,040 --> 08:22:51,120 error checking or you have a lot of try 13118 08:22:49,120 --> 08:22:53,200 except just to tolerate mistakes in the 13119 08:22:51,120 --> 08:22:55,798 data but generally I would say if you're 13120 08:22:53,200 --> 08:22:58,318 using CSV or any file format internally 13121 08:22:55,798 --> 08:23:00,000 to a program to both read and write it 13122 08:22:58,318 --> 08:23:02,000 you shouldn't have concerns there you 13123 08:23:00,000 --> 08:23:03,440 and I the humans are the problem 13124 08:23:02,000 --> 08:23:05,478 generally speaking and not the 13125 08:23:03,440 --> 08:23:07,680 programmers the users of those files 13126 08:23:05,478 --> 08:23:10,120 instead all right allow me to propose 13127 08:23:07,680 --> 08:23:11,878 that we leave csvs behind but to note 13128 08:23:10,120 --> 08:23:14,200 that they're not the only file format 13129 08:23:11,878 --> 08:23:16,360 you can use in order to read or write 13130 08:23:14,200 --> 08:23:19,238 data in fact they're a popular format as 13131 08:23:16,360 --> 08:23:21,040 is just raw text files. txt files but 13132 08:23:19,238 --> 08:23:23,000 you can store data really any way that 13133 08:23:21,040 --> 08:23:24,638 you want we've just picked csvs because 13134 08:23:23,000 --> 08:23:26,760 it's representative of how you might 13135 08:23:24,638 --> 08:23:28,798 read and write from a file and do so in 13136 08:23:26,760 --> 08:23:31,520 a structured way where you can somehow 13137 08:23:28,798 --> 08:23:33,360 have multiple Keys multiple values all 13138 08:23:31,520 --> 08:23:34,958 in the same file without having to 13139 08:23:33,360 --> 08:23:38,040 resort to what would be otherwise known 13140 08:23:34,958 --> 08:23:39,958 as a binary file so a binary file is a 13141 08:23:38,040 --> 08:23:42,238 file that's really just zeros and ones 13142 08:23:39,958 --> 08:23:44,398 and they can be laid out in any pattern 13143 08:23:42,238 --> 08:23:46,600 you might want particularly if you want 13144 08:23:44,398 --> 08:23:49,040 to store not textual information but 13145 08:23:46,600 --> 08:23:51,600 maybe graphical or audio or video 13146 08:23:49,040 --> 08:23:53,520 information as well so it turns out that 13147 08:23:51,600 --> 08:23:55,600 python is really good when it comes to 13148 08:23:53,520 --> 08:23:57,558 having libraries for really everything 13149 08:23:55,600 --> 08:24:00,000 and in fact there's a popular Library 13150 08:23:57,558 --> 08:24:02,920 called pillow that allows you to 13151 08:24:00,000 --> 08:24:05,318 navigate image files as well and to 13152 08:24:02,920 --> 08:24:08,318 perform operations on image files you 13153 08:24:05,318 --> 08:24:10,360 can apply filters aot Instagram you can 13154 08:24:08,318 --> 08:24:12,360 uh animate them as well and so what I 13155 08:24:10,360 --> 08:24:14,120 thought we'd do is leave behind text 13156 08:24:12,360 --> 08:24:17,080 files for now and Tackle one more 13157 08:24:14,120 --> 08:24:19,798 demonstration this time focusing on uh 13158 08:24:17,080 --> 08:24:21,718 this particular library and image files 13159 08:24:19,798 --> 08:24:24,200 instead so let me propose that we go 13160 08:24:21,718 --> 08:24:26,718 over here to VSS code and create a 13161 08:24:24,200 --> 08:24:28,798 program ultimately that creates an anim 13162 08:24:26,718 --> 08:24:30,718 GIF these things are everywhere nowadays 13163 08:24:28,798 --> 08:24:32,318 in the form of memes and animations and 13164 08:24:30,718 --> 08:24:34,878 stickers and the like and an animated 13165 08:24:32,318 --> 08:24:37,600 gif is really just an image file that 13166 08:24:34,878 --> 08:24:39,760 has multiple images inside of it and 13167 08:24:37,600 --> 08:24:42,558 your computer or your phone shows you 13168 08:24:39,760 --> 08:24:45,398 those images one after another sometimes 13169 08:24:42,558 --> 08:24:47,000 on an endless loop again and again and 13170 08:24:45,398 --> 08:24:48,760 so long as there's enough images it 13171 08:24:47,000 --> 08:24:50,680 creates the illusion of Animation 13172 08:24:48,760 --> 08:24:52,680 because your mind and mind kind of fills 13173 08:24:50,680 --> 08:24:54,360 in the gaps visually and just assumes 13174 08:24:52,680 --> 08:24:57,040 that if something is moving even though 13175 08:24:54,360 --> 08:24:59,200 you're only seeing one frame per second 13176 08:24:57,040 --> 08:25:01,280 or some sequence thereof it looks like 13177 08:24:59,200 --> 08:25:03,558 an animation so it's like a simplistic 13178 08:25:01,280 --> 08:25:05,600 version of a video file well let me 13179 08:25:03,558 --> 08:25:08,558 propose that we start with maybe a 13180 08:25:05,600 --> 08:25:10,120 couple of uh costumes from another 13181 08:25:08,558 --> 08:25:11,958 popular programming language and let me 13182 08:25:10,120 --> 08:25:14,080 go ahead and open up my first costume 13183 08:25:11,958 --> 08:25:15,680 here number one so suppose here that 13184 08:25:14,080 --> 08:25:18,680 this is a costume or really just a 13185 08:25:15,680 --> 08:25:20,718 static image here costume 1.f and it's 13186 08:25:18,680 --> 08:25:23,080 just a static picture of a cat no 13187 08:25:20,718 --> 08:25:26,440 movement at all let me go ahead now and 13188 08:25:23,080 --> 08:25:28,638 open up a second one costume 2.gif that 13189 08:25:26,440 --> 08:25:30,638 looks a little bit different notice and 13190 08:25:28,638 --> 08:25:33,160 I'll go back and forth this cat's legs 13191 08:25:30,638 --> 08:25:35,798 are a little bit aligned differently so 13192 08:25:33,160 --> 08:25:38,040 that this was version one and this was 13193 08:25:35,798 --> 08:25:39,680 version two now these cats come from a 13194 08:25:38,040 --> 08:25:41,638 programming language from MIT called 13195 08:25:39,680 --> 08:25:44,160 scratch that allows you very graphically 13196 08:25:41,638 --> 08:25:47,040 to animate all this and more but we'll 13197 08:25:44,160 --> 08:25:50,000 use just these two static images costume 13198 08:25:47,040 --> 08:25:52,040 one and costume 2 to create our own 13199 08:25:50,000 --> 08:25:54,440 animated gif that after this you could 13200 08:25:52,040 --> 08:25:57,160 text to a friend or message them um much 13201 08:25:54,440 --> 08:25:59,798 like any meme online well let me propose 13202 08:25:57,160 --> 08:26:01,318 that we create this animated gif not by 13203 08:25:59,798 --> 08:26:02,840 just using some off-the-shelf program 13204 08:26:01,318 --> 08:26:05,878 that we downloaded but by writing our 13205 08:26:02,840 --> 08:26:08,040 own code let me go ahead and run code of 13206 08:26:05,878 --> 08:26:10,120 costumes. and create our very own 13207 08:26:08,040 --> 08:26:13,000 program that's going to take as input 13208 08:26:10,120 --> 08:26:15,440 two or even more image files and then 13209 08:26:13,000 --> 08:26:17,318 generate an animated gif from them by 13210 08:26:15,440 --> 08:26:20,520 essentially creating this animated gif 13211 08:26:17,318 --> 08:26:22,520 by toggling back and forth endlessly 13212 08:26:20,520 --> 08:26:24,160 between those two images well how am I 13213 08:26:22,520 --> 08:26:26,600 going to do this well let's assume that 13214 08:26:24,160 --> 08:26:28,478 this will be a program called costumes. 13215 08:26:26,600 --> 08:26:30,680 that expects uh two command line 13216 08:26:28,478 --> 08:26:32,398 arguments the names of the files the 13217 08:26:30,680 --> 08:26:34,440 individual costumes that we want to 13218 08:26:32,398 --> 08:26:35,840 animate back and forth so to do that I'm 13219 08:26:34,440 --> 08:26:38,920 going to import CIS so that we 13220 08:26:35,840 --> 08:26:40,718 ultimately have access to cis.org V I'm 13221 08:26:38,920 --> 08:26:43,000 then from this pillow Library going to 13222 08:26:40,718 --> 08:26:46,840 import support for images specifically 13223 08:26:43,000 --> 08:26:49,080 so from pil import image capital i as 13224 08:26:46,840 --> 08:26:50,680 per the library's documentation now I'm 13225 08:26:49,080 --> 08:26:52,558 going to give myself an empty list 13226 08:26:50,680 --> 08:26:54,638 called images just so I have a list in 13227 08:26:52,558 --> 08:26:57,718 which to store one or two or or more of 13228 08:26:54,638 --> 08:27:02,160 these images and now let me do this for 13229 08:26:57,718 --> 08:27:04,600 each argument in cy. argv I'm going to 13230 08:27:02,160 --> 08:27:08,920 go ahead and create a new image variable 13231 08:27:04,600 --> 08:27:11,600 set it equal to this image uh doop 13232 08:27:08,920 --> 08:27:14,360 function passing in ARG now what is this 13233 08:27:11,600 --> 08:27:16,638 doing I proposing that eventually I want 13234 08:27:14,360 --> 08:27:18,440 to be able to run python of costumes. 13235 08:27:16,638 --> 08:27:21,638 piy and then as command line argument 13236 08:27:18,440 --> 08:27:23,558 specify costume 1.f space costume 2. so 13237 08:27:21,638 --> 08:27:26,440 I want to take in those file names from 13238 08:27:23,558 --> 08:27:29,200 the command line as my arguments so what 13239 08:27:26,440 --> 08:27:31,760 am I doing here well I'm iterating over 13240 08:27:29,200 --> 08:27:33,878 sis. argv all of the words in my command 13241 08:27:31,760 --> 08:27:35,558 line arguments I'm creating a variable 13242 08:27:33,878 --> 08:27:37,478 called image and I'm passing to this 13243 08:27:35,558 --> 08:27:40,318 function image. open from the pillow 13244 08:27:37,478 --> 08:27:42,360 library that specific argument and that 13245 08:27:40,318 --> 08:27:44,318 library is essentially going to open 13246 08:27:42,360 --> 08:27:46,238 that image in a way that gives me a lot 13247 08:27:44,318 --> 08:27:48,718 of functionality for manipulating it 13248 08:27:46,238 --> 08:27:54,360 like animating now I'm going to go ahead 13249 08:27:48,718 --> 08:27:56,478 and uh pen to my images list that 13250 08:27:54,360 --> 08:27:58,000 particular image and that's it so this 13251 08:27:56,478 --> 08:27:59,558 Loop's purpose in life is just to 13252 08:27:58,000 --> 08:28:02,718 iterate over the command line arguments 13253 08:27:59,558 --> 08:28:04,080 and open those images using this Library 13254 08:28:02,718 --> 08:28:05,958 the last line is pretty s 13255 08:28:04,080 --> 08:28:07,478 straightforward I'm going to say this 13256 08:28:05,958 --> 08:28:09,360 I'm going to grab the first of those 13257 08:28:07,478 --> 08:28:11,840 images which is going to be in my list 13258 08:28:09,360 --> 08:28:14,718 at location zero and I'm going to save 13259 08:28:11,840 --> 08:28:16,440 it to disk that is I'm going to save 13260 08:28:14,718 --> 08:28:19,160 this file now in the past when we use 13261 08:28:16,440 --> 08:28:21,360 csvs or text files I had to do the file 13262 08:28:19,160 --> 08:28:23,238 opening I had to do the file writing 13263 08:28:21,360 --> 08:28:24,718 maybe even the closing I don't need to 13264 08:28:23,238 --> 08:28:26,798 do that with this Library the pillow 13265 08:28:24,718 --> 08:28:29,120 library takes care of the opening the 13266 08:28:26,798 --> 08:28:31,478 closing and the saving for me by just 13267 08:28:29,120 --> 08:28:33,120 calling save I'm going to call this save 13268 08:28:31,478 --> 08:28:35,040 function and just to leave space because 13269 08:28:33,120 --> 08:28:37,120 I have a number of arguments to pass I'm 13270 08:28:35,040 --> 08:28:38,760 going to move to another line so it fits 13271 08:28:37,120 --> 08:28:42,080 I'm going to pass in the name of the 13272 08:28:38,760 --> 08:28:44,718 file that I want to create costume. GIF 13273 08:28:42,080 --> 08:28:47,120 that will be the name of my animated gif 13274 08:28:44,718 --> 08:28:50,160 I'm going to tell this library to save 13275 08:28:47,120 --> 08:28:51,878 all of the frames that I passed to it so 13276 08:28:50,160 --> 08:28:54,238 the First costume the second costume and 13277 08:28:51,878 --> 08:28:56,638 even more if I gave them I'm going to 13278 08:28:54,238 --> 08:29:00,920 then append to this first image 13279 08:28:56,638 --> 08:29:03,160 the images zero uh the following images 13280 08:29:00,920 --> 08:29:05,080 equals this list of images and this is a 13281 08:29:03,160 --> 08:29:07,798 bit clever but I'm going to do this I 13282 08:29:05,080 --> 08:29:10,398 want to append the next image there 13283 08:29:07,798 --> 08:29:12,798 images one and now I want to specify a 13284 08:29:10,398 --> 08:29:15,160 duration of 200 Mill seconds for each of 13285 08:29:12,798 --> 08:29:17,638 these frames and I want this to Loop 13286 08:29:15,160 --> 08:29:20,238 forever and if you specify Loop equals 13287 08:29:17,638 --> 08:29:22,440 zero that is Time Zero it means it's 13288 08:29:20,238 --> 08:29:24,558 just not going to Loop an finite number 13289 08:29:22,440 --> 08:29:26,920 of times but an infinite number of times 13290 08:29:24,558 --> 08:29:31,120 instead and I need to do do one other 13291 08:29:26,920 --> 08:29:32,878 thing recall that sis. argv contains not 13292 08:29:31,120 --> 08:29:35,638 just the words I typed after my 13293 08:29:32,878 --> 08:29:38,478 program's name but what else does cy. 13294 08:29:35,638 --> 08:29:40,200 argv contain if you think back to our 13295 08:29:38,478 --> 08:29:43,280 discussion of command line 13296 08:29:40,200 --> 08:29:45,638 arguments what else is in sis. RGV 13297 08:29:43,280 --> 08:29:50,160 besides the words I'm about to type like 13298 08:29:45,638 --> 08:29:52,080 costume 1.f and costume 2 yeah so we'll 13299 08:29:50,160 --> 08:29:54,840 actually get in the the original name of 13300 08:29:52,080 --> 08:29:57,318 the program we want to run the costume 13301 08:29:54,840 --> 08:29:59,200 at p and we'll get the original name of 13302 08:29:57,318 --> 08:30:01,718 the program costumes. in this case which 13303 08:29:59,200 --> 08:30:04,558 is not a gif obviously so remember that 13304 08:30:01,718 --> 08:30:07,318 using slices in Python we can do this if 13305 08:30:04,558 --> 08:30:09,280 cy. Arvy is a list and we want to get a 13306 08:30:07,318 --> 08:30:12,318 slice of that list everything after the 13307 08:30:09,280 --> 08:30:15,680 first element we can do one colon which 13308 08:30:12,318 --> 08:30:17,600 says start at location one not zero and 13309 08:30:15,680 --> 08:30:19,600 take a slice all the way to the end so 13310 08:30:17,600 --> 08:30:21,318 give me everything except the first 13311 08:30:19,600 --> 08:30:24,398 thing in that list which to McKenzie's 13312 08:30:21,318 --> 08:30:26,360 point is the name of the program now if 13313 08:30:24,398 --> 08:30:28,558 I haven't made any mistakes let's see 13314 08:30:26,360 --> 08:30:30,318 what happens I'm going to run python of 13315 08:30:28,558 --> 08:30:32,080 costumes. piy and now I'm going to 13316 08:30:30,318 --> 08:30:36,718 specify the two images that I want to 13317 08:30:32,080 --> 08:30:39,478 animate so costume 1.f and costume 13318 08:30:36,718 --> 08:30:41,680 2.if what is the code now going to do 13319 08:30:39,478 --> 08:30:43,680 well to recap we're using the Cy library 13320 08:30:41,680 --> 08:30:45,680 to access those command line arguments 13321 08:30:43,680 --> 08:30:47,920 we're using the pillow library to treat 13322 08:30:45,680 --> 08:30:49,200 those files as images and with all the 13323 08:30:47,920 --> 08:30:51,638 functionality that comes with that 13324 08:30:49,200 --> 08:30:53,760 Library I'm using this images list just 13325 08:30:51,638 --> 08:30:55,958 to accumulate all of these images one at 13326 08:30:53,760 --> 08:30:58,520 a time from the command line and in 13327 08:30:55,958 --> 08:31:00,440 lines 7 through n I'm just using a loop 13328 08:30:58,520 --> 08:31:02,878 to iterate over all of them and just add 13329 08:31:00,440 --> 08:31:05,080 them to this list after opening them 13330 08:31:02,878 --> 08:31:06,638 with the library and the last step which 13331 08:31:05,080 --> 08:31:08,638 is really just one line of code broken 13332 08:31:06,638 --> 08:31:10,840 on to three so that it all fits I'm 13333 08:31:08,638 --> 08:31:13,840 going to save the first image but I'm 13334 08:31:10,840 --> 08:31:16,120 asking the library to append this other 13335 08:31:13,840 --> 08:31:17,840 image to it as well not bracket zero but 13336 08:31:16,120 --> 08:31:20,200 bracket one and if I had more I could 13337 08:31:17,840 --> 08:31:22,600 express those as well I want to save all 13338 08:31:20,200 --> 08:31:25,080 of these files together I want to pause 13339 08:31:22,600 --> 08:31:27,440 200 milliseconds a fifth of a second in 13340 08:31:25,080 --> 08:31:31,478 between each frame and I want it to Loop 13341 08:31:27,440 --> 08:31:35,318 infinitely many times so now if I cross 13342 08:31:31,478 --> 08:31:37,080 my fingers as always hit enter nothing 13343 08:31:35,318 --> 08:31:40,920 bad happened and that's almost always a 13344 08:31:37,080 --> 08:31:44,718 good thing let me now run code of 13345 08:31:40,920 --> 08:31:46,840 costumes. GIF to open up in VSS code the 13346 08:31:44,718 --> 08:31:51,080 final image and what I think I should 13347 08:31:46,840 --> 08:31:52,798 see is a very happy cat and indeed so 13348 08:31:51,080 --> 08:31:55,120 now we've seen not only that we can read 13349 08:31:52,798 --> 08:31:57,920 and write files be it textually we can 13350 08:31:55,120 --> 08:31:59,638 read and now write files that are binary 13351 08:31:57,920 --> 08:32:01,600 zeros and ones we've just scratched the 13352 08:31:59,638 --> 08:32:03,478 surface this is using the library called 13353 08:32:01,600 --> 08:32:05,000 pillow but ultimately this is going to 13354 08:32:03,478 --> 08:32:07,558 give us the ability to read and write 13355 08:32:05,000 --> 08:32:09,558 files however we want so we've now seen 13356 08:32:07,558 --> 08:32:11,878 that via file.io we can manipulate not 13357 08:32:09,558 --> 08:32:14,238 just textual files be it txt files or 13358 08:32:11,878 --> 08:32:16,120 csvs but even binary files as well in 13359 08:32:14,238 --> 08:32:17,680 this case they happen to be images but 13360 08:32:16,120 --> 08:32:20,360 if we dived in deeper we could find 13361 08:32:17,680 --> 08:32:22,040 explore audio and video and so much more 13362 08:32:20,360 --> 08:32:24,840 all by way of these simple Primitives 13363 08:32:22,040 --> 08:32:26,920 this ability somehow to read and write 13364 08:32:24,840 --> 08:32:30,558 files that's that's it for now we'll see 13365 08:32:26,920 --> 08:32:30,558 you next time 13366 08:32:35,330 --> 08:32:45,179 [Music] 13367 08:32:47,200 --> 08:32:54,070 [Music] 13368 08:32:56,440 --> 08:33:01,238 all right this is cs50's Introduction to 13369 08:32:59,360 --> 08:33:03,280 programming with python my name is David 13370 08:33:01,238 --> 08:33:05,878 men and this is our week on regular 13371 08:33:03,280 --> 08:33:08,238 Expressions so a regular expression 13372 08:33:05,878 --> 08:33:10,280 otherwise known as a Rex is really just 13373 08:33:08,238 --> 08:33:12,360 a pattern and indeed it's quite common 13374 08:33:10,280 --> 08:33:14,958 in programming to want to use patterns 13375 08:33:12,360 --> 08:33:16,920 to match on some kind of data often user 13376 08:33:14,958 --> 08:33:18,958 input for instance if the user types in 13377 08:33:16,920 --> 08:33:21,000 an email address whether to your program 13378 08:33:18,958 --> 08:33:22,280 or a website or an app on your phone you 13379 08:33:21,000 --> 08:33:24,238 might ideally want to be able to 13380 08:33:22,280 --> 08:33:25,760 validate that they did indeed type in an 13381 08:33:24,238 --> 08:33:27,600 email address and not something compl 13382 08:33:25,760 --> 08:33:28,958 completely different so using regular 13383 08:33:27,600 --> 08:33:31,440 Expressions we're going to have the new 13384 08:33:28,958 --> 08:33:33,878 found capability to Define patterns in 13385 08:33:31,440 --> 08:33:35,398 our code to compare them against data 13386 08:33:33,878 --> 08:33:37,280 that we're receiving from someone else 13387 08:33:35,398 --> 08:33:38,840 whether it's just a validated or heck 13388 08:33:37,280 --> 08:33:40,638 even if we want to clean up a whole lot 13389 08:33:38,840 --> 08:33:43,318 of data that itself might be messy 13390 08:33:40,638 --> 08:33:45,120 because it too came from us humans 13391 08:33:43,318 --> 08:33:47,760 before though we use these regular 13392 08:33:45,120 --> 08:33:50,958 Expressions let me propose that we solve 13393 08:33:47,760 --> 08:33:52,760 a few problems using just some simpler 13394 08:33:50,958 --> 08:33:55,040 syntax and see what kind of limitations 13395 08:33:52,760 --> 08:33:57,200 we run up against let me propose that I 13396 08:33:55,040 --> 08:33:59,520 open up via code here and let me create 13397 08:33:57,200 --> 08:34:01,160 a file called validate dopy the goal at 13398 08:33:59,520 --> 08:34:03,160 hand being to validate how about just 13399 08:34:01,160 --> 08:34:04,878 that a user's email address they've come 13400 08:34:03,160 --> 08:34:06,280 to your app they've come to your website 13401 08:34:04,878 --> 08:34:09,120 they type in their email address and we 13402 08:34:06,280 --> 08:34:11,280 want to say yes or no this email address 13403 08:34:09,120 --> 08:34:14,680 looks valid all right let me go ahead 13404 08:34:11,280 --> 08:34:17,040 and type code of validate dopy to create 13405 08:34:14,680 --> 08:34:19,120 a new tab here and then within this tab 13406 08:34:17,040 --> 08:34:21,318 let me go ahead and start writing some 13407 08:34:19,120 --> 08:34:22,958 code how about that keeps things simple 13408 08:34:21,318 --> 08:34:24,920 initially first let me go ahead and 13409 08:34:22,958 --> 08:34:27,958 prompt the user for their email address 13410 08:34:24,920 --> 08:34:30,318 and I'll store return value of input in 13411 08:34:27,958 --> 08:34:32,958 a variable called email asking them 13412 08:34:30,318 --> 08:34:34,318 what's your email question mark I'm 13413 08:34:32,958 --> 08:34:36,360 going to go ahead and preemptively at 13414 08:34:34,318 --> 08:34:39,000 least clean up the user's input a little 13415 08:34:36,360 --> 08:34:41,440 bit by minimally just calling strip at 13416 08:34:39,000 --> 08:34:43,478 the end of my call to input because 13417 08:34:41,440 --> 08:34:46,440 recall that input returns a string or a 13418 08:34:43,478 --> 08:34:48,160 stir stirs come with some built-in 13419 08:34:46,440 --> 08:34:50,000 methods or functions one of which is 13420 08:34:48,160 --> 08:34:52,238 strip which has the effect of stripping 13421 08:34:50,000 --> 08:34:54,520 off any leading white space to the left 13422 08:34:52,238 --> 08:34:55,878 or any trailing white space to the right 13423 08:34:54,520 --> 08:34:57,520 so that's just going to go ahead and at 13424 08:34:55,878 --> 08:34:59,318 least avoid the human having 13425 08:34:57,520 --> 08:35:01,040 accidentally typed in a space character 13426 08:34:59,318 --> 08:35:02,760 we're going to throw it away just in 13427 08:35:01,040 --> 08:35:06,680 case now I'm going to do something 13428 08:35:02,760 --> 08:35:08,200 simple for a user's input to be an email 13429 08:35:06,680 --> 08:35:10,160 address I think we can all agree that 13430 08:35:08,200 --> 08:35:12,160 it's got to minimally have an at sign 13431 08:35:10,160 --> 08:35:14,000 somewhere in it so let's start simple if 13432 08:35:12,160 --> 08:35:16,680 the user has typed in something with an 13433 08:35:14,000 --> 08:35:18,798 at sign let's very generously just say 13434 08:35:16,680 --> 08:35:20,840 Okay valid looks like an email address 13435 08:35:18,798 --> 08:35:23,040 and if we're missing that at sign let's 13436 08:35:20,840 --> 08:35:24,440 say invalid because clearly it's not an 13437 08:35:23,040 --> 08:35:26,000 email address it's not going to be the 13438 08:35:24,440 --> 08:35:27,680 best version of my code yet but we'll 13439 08:35:26,000 --> 08:35:31,080 start simple so I'm going to ask the 13440 08:35:27,680 --> 08:35:33,398 question if there is an at symbol in the 13441 08:35:31,080 --> 08:35:35,478 user's email address go ahead and print 13442 08:35:33,398 --> 08:35:37,398 out for instance quote unquote valid 13443 08:35:35,478 --> 08:35:39,318 else if there's not now I'm pretty 13444 08:35:37,398 --> 08:35:42,638 confident that the email address is in 13445 08:35:39,318 --> 08:35:46,120 fact invalid now what is this code doing 13446 08:35:42,638 --> 08:35:48,160 well if at sign in email is a pythonic 13447 08:35:46,120 --> 08:35:52,000 way of asking is this string quote 13448 08:35:48,160 --> 08:35:53,478 unquote at in this other string email no 13449 08:35:52,000 --> 08:35:54,718 matter where it is at the beginning the 13450 08:35:53,478 --> 08:35:56,200 middle of the end it's going to 13451 08:35:54,718 --> 08:35:58,318 automatically SE search through the 13452 08:35:56,200 --> 08:35:59,798 entire string for you automatically I 13453 08:35:58,318 --> 08:36:01,878 could do this more verbosely and I could 13454 08:35:59,798 --> 08:36:04,040 use a for Loop or a while loop and look 13455 08:36:01,878 --> 08:36:05,878 at every character in The user's email 13456 08:36:04,040 --> 08:36:07,200 address looking to see if it's an at 13457 08:36:05,878 --> 08:36:09,040 sign but this is one of the things 13458 08:36:07,200 --> 08:36:11,798 that's nice about python you can do more 13459 08:36:09,040 --> 08:36:13,920 with less so just by saying if at quote 13460 08:36:11,798 --> 08:36:15,638 unquote in email we're achieving that 13461 08:36:13,920 --> 08:36:18,080 same result we're going to get back true 13462 08:36:15,638 --> 08:36:20,520 if it's somewhere in there thus valid or 13463 08:36:18,080 --> 08:36:22,520 false if it is not well let me go ahead 13464 08:36:20,520 --> 08:36:25,120 now and run this program in my terminal 13465 08:36:22,520 --> 08:36:26,160 window with python of validate dopy and 13466 08:36:25,120 --> 08:36:29,718 I'm going to go head and give it my 13467 08:36:26,160 --> 08:36:32,238 email address maen harvard.edu enter and 13468 08:36:29,718 --> 08:36:34,040 indeed it's valid looks valid is valid 13469 08:36:32,238 --> 08:36:36,840 but of course this program is 13470 08:36:34,040 --> 08:36:39,080 technically broken it's buggy what would 13471 08:36:36,840 --> 08:36:41,160 be an example input if someone might 13472 08:36:39,080 --> 08:36:43,238 like to volunteer and answer here that 13473 08:36:41,160 --> 08:36:45,760 would be considered valid but you and I 13474 08:36:43,238 --> 08:36:47,478 know it really isn't valid yeah thank 13475 08:36:45,760 --> 08:36:49,920 you uh well for instance you can type 13476 08:36:47,478 --> 08:36:53,318 just two science science and that's it 13477 08:36:49,920 --> 08:36:56,120 and it still be valid still be valid 13478 08:36:53,318 --> 08:36:58,558 according to your program but this 13479 08:36:56,120 --> 08:37:00,478 exactly we've set a very low bar here in 13480 08:36:58,558 --> 08:37:02,398 fact if I go ahead and rerun python of 13481 08:37:00,478 --> 08:37:05,160 validate dopy and I'll just type in one 13482 08:37:02,398 --> 08:37:06,600 at sign that's it no username no domain 13483 08:37:05,160 --> 08:37:08,920 name this doesn't really look like an 13484 08:37:06,600 --> 08:37:10,238 email address but unfortunately my code 13485 08:37:08,920 --> 08:37:11,958 thinks it in fact is because it's 13486 08:37:10,238 --> 08:37:14,080 obviously just looking for an at sign 13487 08:37:11,958 --> 08:37:16,478 alone well how could we improve this 13488 08:37:14,080 --> 08:37:18,160 well minimally an email address I I 13489 08:37:16,478 --> 08:37:19,878 think tends to have though this is not 13490 08:37:18,160 --> 08:37:22,318 actually a requirement tends to have an 13491 08:37:19,878 --> 08:37:24,558 at sign and a single dot at least maybe 13492 08:37:22,318 --> 08:37:27,040 somewhere in the domain name so mailin 13493 08:37:24,558 --> 08:37:28,600 Harvard Dot edu so let's check for that 13494 08:37:27,040 --> 08:37:30,600 dot as well though again strictly 13495 08:37:28,600 --> 08:37:32,280 speaking doesn't even have to be that 13496 08:37:30,600 --> 08:37:33,718 case but I'm going for my own email 13497 08:37:32,280 --> 08:37:35,440 address at least for now as our test 13498 08:37:33,718 --> 08:37:37,680 case so let me go ahead and change my 13499 08:37:35,440 --> 08:37:42,520 code now and say not only if at is an 13500 08:37:37,680 --> 08:37:44,638 email but also uh dot is an email as 13501 08:37:42,520 --> 08:37:47,318 well so I'm asking now two questions I 13502 08:37:44,638 --> 08:37:50,040 have two Boolean Expressions if at an 13503 08:37:47,318 --> 08:37:52,120 email and I'm anding them together 13504 08:37:50,040 --> 08:37:54,040 logically this is a logical and so to 13505 08:37:52,120 --> 08:37:56,878 speak so if it's the case that at is an 13506 08:37:54,040 --> 08:37:58,680 email and Dot is an email okay now I'm 13507 08:37:56,878 --> 08:38:00,360 going to go ahead and say valid all 13508 08:37:58,680 --> 08:38:02,080 right this would still seem to work for 13509 08:38:00,360 --> 08:38:04,638 my email address let me go ahead and run 13510 08:38:02,080 --> 08:38:07,318 python of validate dopy uh maen 13511 08:38:04,638 --> 08:38:09,638 harvard.edu enter and that of course is 13512 08:38:07,318 --> 08:38:11,440 valid as expected but here too we can be 13513 08:38:09,638 --> 08:38:13,760 a little adversarial and type in 13514 08:38:11,440 --> 08:38:15,558 something nonsensical like at Dot and 13515 08:38:13,760 --> 08:38:17,718 unfortunately that too is going to be 13516 08:38:15,558 --> 08:38:19,798 mistaken as valid even though there's 13517 08:38:17,718 --> 08:38:21,280 still no username domain name or 13518 08:38:19,798 --> 08:38:24,398 anything like that so I think we need to 13519 08:38:21,280 --> 08:38:28,000 be a little more methodical here in fact 13520 08:38:24,398 --> 08:38:30,200 notice that if if I do this like this uh 13521 08:38:28,000 --> 08:38:32,440 the at sign can be anywhere and the dot 13522 08:38:30,200 --> 08:38:33,680 can be anywhere but if I'm assuming the 13523 08:38:32,440 --> 08:38:36,200 user is going to have a traditional 13524 08:38:33,680 --> 08:38:38,558 domain name like harvard.edu or 13525 08:38:36,200 --> 08:38:41,160 gmail.com I really want to look for the 13526 08:38:38,558 --> 08:38:44,080 dot in the domain name only not 13527 08:38:41,160 --> 08:38:46,040 necessarily just the username so let me 13528 08:38:44,080 --> 08:38:48,680 go ahead and do this let me go ahead and 13529 08:38:46,040 --> 08:38:51,878 introduce a bit more logic here and 13530 08:38:48,680 --> 08:38:53,000 instead do this let me go ahead and do 13531 08:38:51,878 --> 08:38:56,120 uh 13532 08:38:53,000 --> 08:38:59,040 email.it of quote unquote at sign so 13533 08:38:56,120 --> 08:39:01,160 email again is a string or a stir stirs 13534 08:38:59,040 --> 08:39:03,200 come with methods not just strip but 13535 08:39:01,160 --> 08:39:05,398 also another one called split that is 13536 08:39:03,200 --> 08:39:07,160 the name applies will split one stir 13537 08:39:05,398 --> 08:39:11,360 into multiple ones if you give it a 13538 08:39:07,160 --> 08:39:12,840 character or more to split on so this is 13539 08:39:11,360 --> 08:39:14,558 hopefully going to return to me two 13540 08:39:12,840 --> 08:39:17,040 parts from a traditional email address 13541 08:39:14,558 --> 08:39:19,160 the username and the domain name and it 13542 08:39:17,040 --> 08:39:22,398 turns out I can unpack that sequence of 13543 08:39:19,160 --> 08:39:25,440 respon is by doing this username comma 13544 08:39:22,398 --> 08:39:27,478 domain equals this I could store it in a 13545 08:39:25,440 --> 08:39:29,440 list or some other structure but if I 13546 08:39:27,478 --> 08:39:31,000 already know in advance what kinds of 13547 08:39:29,440 --> 08:39:32,718 values I'm expecting a username and 13548 08:39:31,000 --> 08:39:34,160 hopefully a domain I'm going to go ahead 13549 08:39:32,718 --> 08:39:36,478 and do it like this instead and just 13550 08:39:34,160 --> 08:39:38,200 Define two variables at once on one line 13551 08:39:36,478 --> 08:39:40,160 of code and now I'm going to be a little 13552 08:39:38,200 --> 08:39:44,440 more precise if 13553 08:39:40,160 --> 08:39:47,318 username uh uh if username then I'm 13554 08:39:44,440 --> 08:39:49,798 going to go ahead and say print valid 13555 08:39:47,318 --> 08:39:52,040 else I'm going to go ahead and say print 13556 08:39:49,798 --> 08:39:53,600 invalid now this isn't good enough but 13557 08:39:52,040 --> 08:39:55,080 I'm at least checking for the presence 13558 08:39:53,600 --> 08:39:56,958 of a username now and you might not have 13559 08:39:55,080 --> 08:39:59,520 seen this before but if you simply ask a 13560 08:39:56,958 --> 08:40:02,478 question like if username and username 13561 08:39:59,520 --> 08:40:04,680 is a string well usern if username is 13562 08:40:02,478 --> 08:40:07,238 going to give me a true answer if 13563 08:40:04,680 --> 08:40:09,718 username is anything except none or 13564 08:40:07,238 --> 08:40:12,160 quote unquote nothing so there's a 13565 08:40:09,718 --> 08:40:14,080 truthy value here whereby if username 13566 08:40:12,160 --> 08:40:15,958 has at least one character that's going 13567 08:40:14,080 --> 08:40:18,318 to be considered true but if username 13568 08:40:15,958 --> 08:40:21,398 has no characters it's going to be 13569 08:40:18,318 --> 08:40:22,638 considered a false value effectively but 13570 08:40:21,398 --> 08:40:24,360 this isn't good enough I don't want to 13571 08:40:22,638 --> 08:40:27,360 just check for username I want to also 13572 08:40:24,360 --> 08:40:29,878 check that it's the case that dot is in 13573 08:40:27,360 --> 08:40:32,000 the domain name as well so notice here 13574 08:40:29,878 --> 08:40:34,638 there's a bit of potential confusion 13575 08:40:32,000 --> 08:40:37,520 with the English language here I seem to 13576 08:40:34,638 --> 08:40:39,680 be saying if username and Dot in domain 13577 08:40:37,520 --> 08:40:43,000 as though I'm asking the question if the 13578 08:40:39,680 --> 08:40:44,440 username and the dot are in the domain 13579 08:40:43,000 --> 08:40:46,558 but that's not what this means these are 13580 08:40:44,440 --> 08:40:48,440 two separate Boolean Expressions if 13581 08:40:46,558 --> 08:40:52,000 username and 13582 08:40:48,440 --> 08:40:53,520 separately if dot in domain and if I 13583 08:40:52,000 --> 08:40:55,680 parenthesize this we could make that 13584 08:40:53,520 --> 08:40:57,440 even more clear by putting parenthesis 13585 08:40:55,680 --> 08:40:58,798 there parentheses here so just to be 13586 08:40:57,440 --> 08:41:00,398 clear it's really two Boolean 13587 08:40:58,798 --> 08:41:02,958 Expressions that we're anding together 13588 08:41:00,398 --> 08:41:05,718 not one longer english-like sentence now 13589 08:41:02,958 --> 08:41:08,558 if I go ahead and run this python of 13590 08:41:05,718 --> 08:41:10,680 validate dopy enter I'll do my own email 13591 08:41:08,558 --> 08:41:14,280 address again maen harvard.edu and 13592 08:41:10,680 --> 08:41:15,958 that's valid and it looks like I could 13593 08:41:14,280 --> 08:41:19,200 tolerate something like this if I do 13594 08:41:15,958 --> 08:41:21,318 mailin at just say Harvard I think at 13595 08:41:19,200 --> 08:41:23,718 the moment this is going to be invalid 13596 08:41:21,318 --> 08:41:25,558 now maybe the top level domain Harvard 13597 08:41:23,718 --> 08:41:26,920 exists but at the moment it looks like 13598 08:41:25,558 --> 08:41:29,280 we're looking for something more we're 13599 08:41:26,920 --> 08:41:31,840 looking for a top level domain too like 13600 08:41:29,280 --> 08:41:35,200 edu so for now we'll just consider this 13601 08:41:31,840 --> 08:41:37,840 to be invalid but it's not just that we 13602 08:41:35,200 --> 08:41:39,280 want to do it's not just that we want to 13603 08:41:37,840 --> 08:41:40,840 check for the presence of a username and 13604 08:41:39,280 --> 08:41:42,478 the presence of a dot let's be more 13605 08:41:40,840 --> 08:41:43,798 specific let's start to now narrow the 13606 08:41:42,478 --> 08:41:46,080 scope of this program not just to be 13607 08:41:43,798 --> 08:41:48,558 about generic emails more generally but 13608 08:41:46,080 --> 08:41:50,558 about edu addresses so specifically for 13609 08:41:48,558 --> 08:41:52,600 someone in a US University for instance 13610 08:41:50,558 --> 08:41:55,280 whose email address tends to end with 13611 08:41:52,600 --> 08:41:57,360 doedu I can be a little more precise and 13612 08:41:55,280 --> 08:41:59,120 you might recall this function already 13613 08:41:57,360 --> 08:42:01,638 instead of just saying is there a DOT 13614 08:41:59,120 --> 08:42:05,840 somewhere in domain let me instead say 13615 08:42:01,638 --> 08:42:08,280 and the domain ends with quote unquote. 13616 08:42:05,840 --> 08:42:10,200 edu so now we're being even more precise 13617 08:42:08,280 --> 08:42:11,958 we want there to be minimally a username 13618 08:42:10,200 --> 08:42:14,318 that's not empty it's not just quote 13619 08:42:11,958 --> 08:42:17,558 unquote nothing and we want the domain 13620 08:42:14,318 --> 08:42:19,680 name to actually end with doedu let me 13621 08:42:17,558 --> 08:42:20,760 go ahead and run python of validate dopy 13622 08:42:19,680 --> 08:42:22,478 and just to make sure I haven't made 13623 08:42:20,760 --> 08:42:24,520 things even worse let me at least chest 13624 08:42:22,478 --> 08:42:26,638 my own email address which does seem to 13625 08:42:24,520 --> 08:42:28,318 be valid now it seems that I minimally 13626 08:42:26,638 --> 08:42:30,280 need to provide a username because we 13627 08:42:28,318 --> 08:42:32,440 definitely do have that check in place 13628 08:42:30,280 --> 08:42:34,920 so I'm going to go ahead and say Ma and 13629 08:42:32,440 --> 08:42:36,958 now I'm going to go ahead and say at and 13630 08:42:34,920 --> 08:42:39,798 it looks like I could be a little 13631 08:42:36,958 --> 08:42:40,958 malicious here just say mailen at.edu as 13632 08:42:39,798 --> 08:42:43,478 though minimally meeting the 13633 08:42:40,958 --> 08:42:45,238 requirements of this of this pattern and 13634 08:42:43,478 --> 08:42:47,878 that of course is considered valid but 13635 08:42:45,238 --> 08:42:50,798 I'm pretty sure there's no one at mail 13636 08:42:47,878 --> 08:42:52,558 at.edu we need to have some domain name 13637 08:42:50,798 --> 08:42:54,398 in there so we're still not being quite 13638 08:42:52,558 --> 08:42:56,478 as generous now we could absolutely 13639 08:42:54,398 --> 08:42:57,840 continue to iter at on this program and 13640 08:42:56,478 --> 08:42:59,238 we could add some more Boolean 13641 08:42:57,840 --> 08:43:01,318 Expressions we could maybe use some 13642 08:42:59,238 --> 08:43:02,680 other python methods for checking more 13643 08:43:01,318 --> 08:43:04,398 precisely as there's something to the 13644 08:43:02,680 --> 08:43:06,318 left of the dot to the right of the dot 13645 08:43:04,398 --> 08:43:08,040 we could use split multiple times but 13646 08:43:06,318 --> 08:43:10,360 honestly this just escalates quickly 13647 08:43:08,040 --> 08:43:12,520 like you end up having to write a lot of 13648 08:43:10,360 --> 08:43:15,360 code just to express something that's 13649 08:43:12,520 --> 08:43:18,080 relatively simple in spirit just format 13650 08:43:15,360 --> 08:43:20,238 this like an email address so how can we 13651 08:43:18,080 --> 08:43:23,080 go about improving this well it turns 13652 08:43:20,238 --> 08:43:26,040 out in Python there's a library for 13653 08:43:23,080 --> 08:43:28,478 regular Expressions it's called ccin re 13654 08:43:26,040 --> 08:43:31,360 and in the re Library you have a lot of 13655 08:43:28,478 --> 08:43:34,120 capabilities to Define and check for and 13656 08:43:31,360 --> 08:43:36,600 even replace patterns again a regular 13657 08:43:34,120 --> 08:43:38,398 expression is a pattern and this Library 13658 08:43:36,600 --> 08:43:40,000 the re library in Python is going to let 13659 08:43:38,398 --> 08:43:41,718 us to Define some of these patterns like 13660 08:43:40,000 --> 08:43:44,000 a pattern for an email address and then 13661 08:43:41,718 --> 08:43:45,920 use some built-in functions to actually 13662 08:43:44,000 --> 08:43:47,878 validate a user's input against that 13663 08:43:45,920 --> 08:43:50,000 pattern or even use these patterns to 13664 08:43:47,878 --> 08:43:51,798 change the user's input or extract 13665 08:43:50,000 --> 08:43:54,520 partial information there from we'll see 13666 08:43:51,798 --> 08:43:56,440 examples of all this and more so what 13667 08:43:54,520 --> 08:43:57,760 can should I do with this Library well 13668 08:43:56,440 --> 08:43:59,440 first and foremost it comes with a lot 13669 08:43:57,760 --> 08:44:01,718 of functionality here is the URL for 13670 08:43:59,440 --> 08:44:03,160 instance to the official documentation 13671 08:44:01,718 --> 08:44:04,958 and let me propose that we focus on 13672 08:44:03,160 --> 08:44:07,200 using one of the most versatile 13673 08:44:04,958 --> 08:44:10,558 functions in the library library namely 13674 08:44:07,200 --> 08:44:12,638 this search re. search is the name of 13675 08:44:10,558 --> 08:44:14,680 the function in the re module that 13676 08:44:12,638 --> 08:44:16,600 allows you to pass in a few arguments 13677 08:44:14,680 --> 08:44:19,160 the first is going to be a pattern that 13678 08:44:16,600 --> 08:44:21,718 you want to search for in for instance a 13679 08:44:19,160 --> 08:44:23,398 string that came from a user the string 13680 08:44:21,718 --> 08:44:24,718 arguments here is going to be the actual 13681 08:44:23,398 --> 08:44:26,238 string that you want to search for that 13682 08:44:24,718 --> 08:44:27,878 pattern and then there's a third 13683 08:44:26,238 --> 08:44:30,558 argument optionally that's a whole bunch 13684 08:44:27,878 --> 08:44:32,638 of flags a flag in general is like a a 13685 08:44:30,558 --> 08:44:34,120 parameter you can pass in to modify the 13686 08:44:32,638 --> 08:44:35,600 behavior of the function but initially 13687 08:44:34,120 --> 08:44:36,958 we're not even going to use this we're 13688 08:44:35,600 --> 08:44:39,718 just going to pass in a couple of 13689 08:44:36,958 --> 08:44:43,120 arguments instead so let me go ahead and 13690 08:44:39,718 --> 08:44:45,878 employ this re Library this regular 13691 08:44:43,120 --> 08:44:47,478 expression library and just improve on 13692 08:44:45,878 --> 08:44:49,238 this design incrementally so we're not 13693 08:44:47,478 --> 08:44:51,520 going to solve this problem all at once 13694 08:44:49,238 --> 08:44:53,840 but we'll take some incremental steps 13695 08:44:51,520 --> 08:44:55,440 I'm going to go back to VSS code here 13696 08:44:53,840 --> 08:44:57,280 and I'm going to go ahead now and get 13697 08:44:55,440 --> 08:44:59,238 rid of most of this code but I'm going 13698 08:44:57,280 --> 08:45:02,360 to go into the top of my file and first 13699 08:44:59,238 --> 08:45:04,318 and all import this re Library so import 13700 08:45:02,360 --> 08:45:06,360 re gives me access to that function and 13701 08:45:04,318 --> 08:45:07,920 more now after I've gotten the user's 13702 08:45:06,360 --> 08:45:09,878 input in the same way as before 13703 08:45:07,920 --> 08:45:11,718 stripping off any leading or trailing 13704 08:45:09,878 --> 08:45:14,200 whites space I'm just going to use this 13705 08:45:11,718 --> 08:45:15,638 function super trivially for now even 13706 08:45:14,200 --> 08:45:19,638 though this isn't really a big step 13707 08:45:15,638 --> 08:45:22,760 forward I'm going to say if re. search 13708 08:45:19,638 --> 08:45:24,600 contains quote unquote at in the email 13709 08:45:22,760 --> 08:45:25,638 address then let's go ahead and print 13710 08:45:24,600 --> 08:45:27,958 valid 13711 08:45:25,638 --> 08:45:30,200 else let's go ahead and print invalid at 13712 08:45:27,958 --> 08:45:32,200 the moment this is really no better than 13713 08:45:30,200 --> 08:45:35,360 my very first version where I was just 13714 08:45:32,200 --> 08:45:37,680 asking python if at sign in the email 13715 08:45:35,360 --> 08:45:40,360 address but now I'm at least beginning 13716 08:45:37,680 --> 08:45:41,958 to use this Library by using its own re. 13717 08:45:40,360 --> 08:45:44,840 search function which for now you can 13718 08:45:41,958 --> 08:45:47,680 assume returns a a True Value 13719 08:45:44,840 --> 08:45:49,680 effectively if indeed the at sign is an 13720 08:45:47,680 --> 08:45:51,520 email just to make sure that this 13721 08:45:49,680 --> 08:45:53,638 version does work as I expect let me go 13722 08:45:51,520 --> 08:45:55,638 ahead and run python of validate dopy 13723 08:45:53,638 --> 08:45:58,200 and enter I'll type in in my actual 13724 08:45:55,638 --> 08:46:00,440 email address and we're back in business 13725 08:45:58,200 --> 08:46:02,200 but of course this is not great because 13726 08:46:00,440 --> 08:46:04,520 if I similarly run this version of the 13727 08:46:02,200 --> 08:46:06,040 program and just type in an at sign not 13728 08:46:04,520 --> 08:46:08,718 an email address and yet my code of 13729 08:46:06,040 --> 08:46:10,638 course thinks it is valid so how can I 13730 08:46:08,718 --> 08:46:13,558 do better than this well we need a bit 13731 08:46:10,638 --> 08:46:16,000 more vocabulary in the realm of regular 13732 08:46:13,558 --> 08:46:17,360 expressions in order to be able to 13733 08:46:16,000 --> 08:46:19,840 express ourselves a little more 13734 08:46:17,360 --> 08:46:21,478 precisely really the pattern I want to 13735 08:46:19,840 --> 08:46:23,080 ultimately Define is going to be 13736 08:46:21,478 --> 08:46:26,000 something like I want there to be 13737 08:46:23,080 --> 08:46:27,520 something to the left then an sign then 13738 08:46:26,000 --> 08:46:29,520 something to the right and that 13739 08:46:27,520 --> 08:46:31,520 something to the right should end with 13740 08:46:29,520 --> 08:46:34,160 edu but should also have something 13741 08:46:31,520 --> 08:46:36,920 before the edu like Harvard or Yale or 13742 08:46:34,160 --> 08:46:38,680 any other school in the US as well well 13743 08:46:36,920 --> 08:46:41,238 how can I go about doing this well it 13744 08:46:38,680 --> 08:46:43,318 turns out that in the world of regular 13745 08:46:41,238 --> 08:46:45,120 Expressions whether in python or a lot 13746 08:46:43,318 --> 08:46:46,840 of other languages as well there's 13747 08:46:45,120 --> 08:46:49,238 certain symbols that you can use to 13748 08:46:46,840 --> 08:46:51,718 define patterns at the moment I've just 13749 08:46:49,238 --> 08:46:54,318 used literal raw text if I go back to my 13750 08:46:51,718 --> 08:46:57,238 code here this technically qualifies as 13751 08:46:54,318 --> 08:46:59,840 a regular expression I've passed in a 13752 08:46:57,238 --> 08:47:01,958 quoted string inside of which is an at 13753 08:46:59,840 --> 08:47:03,680 sign now that's not a very interesting 13754 08:47:01,958 --> 08:47:05,238 pattern it's just an at sign but it 13755 08:47:03,680 --> 08:47:07,080 turns out that once you have access to 13756 08:47:05,238 --> 08:47:09,318 regular expressions or a library that 13757 08:47:07,080 --> 08:47:12,318 offers that feature you can more 13758 08:47:09,318 --> 08:47:14,160 powerfully express yourself as follows 13759 08:47:12,318 --> 08:47:16,398 let me reveal that the pattern that you 13760 08:47:14,160 --> 08:47:18,238 passed to ar. search can take a whole 13761 08:47:16,398 --> 08:47:20,318 bunch of special symbols and here's just 13762 08:47:18,238 --> 08:47:22,638 some of them in the examples we're about 13763 08:47:20,318 --> 08:47:25,120 to see in the patterns we're about to 13764 08:47:22,638 --> 08:47:27,600 Define here are the special symbols you 13765 08:47:25,120 --> 08:47:29,760 can use a single period a DOT to just 13766 08:47:27,600 --> 08:47:32,000 represent any character except a new 13767 08:47:29,760 --> 08:47:33,558 line a blank line so that is to say if I 13768 08:47:32,000 --> 08:47:35,600 don't really care what letters of the 13769 08:47:33,558 --> 08:47:37,080 alphabet are in the user's username I 13770 08:47:35,600 --> 08:47:39,798 just want there to be one or more 13771 08:47:37,080 --> 08:47:41,920 characters uh in the user's name dot 13772 08:47:39,798 --> 08:47:43,798 allows me to express a through z 13773 08:47:41,920 --> 08:47:47,040 uppercase and lowercase and a bunch of 13774 08:47:43,798 --> 08:47:49,760 other letters as well star is going to 13775 08:47:47,040 --> 08:47:52,680 mean in single asterisk zero or more 13776 08:47:49,760 --> 08:47:54,398 repetitions so if I say something star 13777 08:47:52,680 --> 08:47:56,718 that means that I'm willing to accept 13778 08:47:54,398 --> 08:48:00,200 either zero repetitions that is nothing 13779 08:47:56,718 --> 08:48:03,160 at all or more repetitions one or two or 13780 08:48:00,200 --> 08:48:05,000 three or 300 if you see a plus in my 13781 08:48:03,160 --> 08:48:06,638 patterns that's going to mean one or 13782 08:48:05,000 --> 08:48:08,280 more repetitions that is to say there's 13783 08:48:06,638 --> 08:48:10,440 got to be at least one character there 13784 08:48:08,280 --> 08:48:13,280 one symbol and then there's optionally 13785 08:48:10,440 --> 08:48:15,478 more after that and then you can say 13786 08:48:13,280 --> 08:48:17,878 zero or one repetition you can use a 13787 08:48:15,478 --> 08:48:19,798 single question mark after a symbol and 13788 08:48:17,878 --> 08:48:22,600 that will say I want zero of this 13789 08:48:19,798 --> 08:48:24,478 character or one but that's all I'll 13790 08:48:22,600 --> 08:48:26,558 expect and then lastly there's going to 13791 08:48:24,478 --> 08:48:28,398 be a to specify a specific number of 13792 08:48:26,558 --> 08:48:29,920 symbols if you use these curly braces 13793 08:48:28,398 --> 08:48:31,958 and a number represented here 13794 08:48:29,920 --> 08:48:34,478 symbolically as M you can specify that 13795 08:48:31,958 --> 08:48:36,440 you want M repetitions be it one or two 13796 08:48:34,478 --> 08:48:38,200 or three or 300 you can specify the 13797 08:48:36,440 --> 08:48:40,080 number of repetitions yourself and if 13798 08:48:38,200 --> 08:48:42,318 you want a range of repetitions like you 13799 08:48:40,080 --> 08:48:44,478 want this few characters or this many 13800 08:48:42,318 --> 08:48:47,318 characters you can use curly braces and 13801 08:48:44,478 --> 08:48:49,760 two numbers inside called here M and N 13802 08:48:47,318 --> 08:48:51,520 which would be a range of M through n 13803 08:48:49,760 --> 08:48:53,920 repetitions now what does all of this 13804 08:48:51,520 --> 08:48:56,238 mean well let me go back to vs code here 13805 08:48:53,920 --> 08:48:58,120 and let me propose that we iterate on 13806 08:48:56,238 --> 08:48:59,840 this solution further it's not 13807 08:48:58,120 --> 08:49:01,558 sufficient to just check for the at sign 13808 08:48:59,840 --> 08:49:03,558 we know that already we minimally want 13809 08:49:01,558 --> 08:49:05,478 something to the left and to the right 13810 08:49:03,558 --> 08:49:07,798 so how can I represent that I don't 13811 08:49:05,478 --> 08:49:09,718 really care what the user's username is 13812 08:49:07,798 --> 08:49:12,360 or what letters of the alphabet are in 13813 08:49:09,718 --> 08:49:14,120 it be it Ma or anyone else's so what I'm 13814 08:49:12,360 --> 08:49:16,318 going to do to the left of this equal 13815 08:49:14,120 --> 08:49:19,398 sign is I'm going to use a single period 13816 08:49:16,318 --> 08:49:21,760 the dot that again indicates any 13817 08:49:19,398 --> 08:49:23,520 character except for a new line but I 13818 08:49:21,760 --> 08:49:25,478 don't just want a single character 13819 08:49:23,520 --> 08:49:28,798 otherwise the P person username could 13820 08:49:25,478 --> 08:49:31,478 only be a at such and such or B at such 13821 08:49:28,798 --> 08:49:32,840 and such I want it to be multiple such 13822 08:49:31,478 --> 08:49:35,120 characters so I'm going to initially use 13823 08:49:32,840 --> 08:49:36,478 a star so dot star means give me 13824 08:49:35,120 --> 08:49:38,920 something to the left and I'm going to 13825 08:49:36,478 --> 08:49:41,440 do another one do star something to the 13826 08:49:38,920 --> 08:49:43,000 right now this isn't perfect but it's at 13827 08:49:41,440 --> 08:49:44,798 least a step forward because now what 13828 08:49:43,000 --> 08:49:46,680 I'm going to go ahead and do is this I'm 13829 08:49:44,798 --> 08:49:48,160 going to rerun python to validate dopy 13830 08:49:46,680 --> 08:49:49,478 I'm going to keep testing my own email 13831 08:49:48,160 --> 08:49:52,238 address just to make sure I haven't made 13832 08:49:49,478 --> 08:49:53,840 things worse and that's now okay I'm now 13833 08:49:52,238 --> 08:49:58,398 going to go ahead and type in some other 13834 08:49:53,840 --> 08:50:00,440 input like how about just uh maen at 13835 08:49:58,398 --> 08:50:02,798 with no domain name whatsoever and you 13836 08:50:00,440 --> 08:50:06,760 would think this is going to be invalid 13837 08:50:02,798 --> 08:50:08,798 but but but it's still considered valid 13838 08:50:06,760 --> 08:50:13,440 but why is that if I go back to this 13839 08:50:08,798 --> 08:50:17,558 chart why is maen at with no domain now 13840 08:50:13,440 --> 08:50:21,080 considered valid what's my mistake here 13841 08:50:17,558 --> 08:50:23,160 by having used doar at. Star as my 13842 08:50:21,080 --> 08:50:26,638 regular expression or Rex because you're 13843 08:50:23,160 --> 08:50:28,878 using the star instead of the plus sign 13844 08:50:26,638 --> 08:50:31,600 exactly the star again means zero or 13845 08:50:28,878 --> 08:50:33,558 more repetitions so r. search is 13846 08:50:31,600 --> 08:50:35,440 perfectly happy to accept nothing after 13847 08:50:33,558 --> 08:50:37,718 the equ after the at sign because that 13848 08:50:35,440 --> 08:50:39,600 would be zero repetitions so I think I 13849 08:50:37,718 --> 08:50:41,600 minimally need to evolve this and go 13850 08:50:39,600 --> 08:50:45,120 back to my code here and let me go ahead 13851 08:50:41,600 --> 08:50:48,160 and change this from Star to plus and 13852 08:50:45,120 --> 08:50:50,798 let me change the ending from Star to 13853 08:50:48,160 --> 08:50:52,600 plus so that now when I run my code here 13854 08:50:50,798 --> 08:50:54,280 let me go ahead and run python of 13855 08:50:52,600 --> 08:50:56,920 validate dopy I'm going to test my email 13856 08:50:54,280 --> 08:50:58,718 address as always still working now let 13857 08:50:56,920 --> 08:51:00,638 me go ahead and type in that same thing 13858 08:50:58,718 --> 08:51:03,558 from before that was accidentally 13859 08:51:00,638 --> 08:51:05,600 considered valid now I hit enter finally 13860 08:51:03,558 --> 08:51:07,958 it's invalid so now we're making some 13861 08:51:05,600 --> 08:51:09,958 progress on being a little more precise 13862 08:51:07,958 --> 08:51:12,000 as to what it is we're doing now I'll 13863 08:51:09,958 --> 08:51:14,160 note here like with almost everything in 13864 08:51:12,000 --> 08:51:16,200 programming python included there's 13865 08:51:14,160 --> 08:51:19,878 often multiple ways to solve the same 13866 08:51:16,200 --> 08:51:22,440 problem and does anyone see away in my 13867 08:51:19,878 --> 08:51:25,638 code here that I could make a slight 13868 08:51:22,440 --> 08:51:29,200 tweak if I forgot that the plus operator 13869 08:51:25,638 --> 08:51:31,638 exists and go back to using a star if I 13870 08:51:29,200 --> 08:51:34,680 allowed you only to use dots and only 13871 08:51:31,638 --> 08:51:39,360 Stars could you recreate the notion of 13872 08:51:34,680 --> 08:51:40,680 plus yes um use another dot dot dot star 13873 08:51:39,360 --> 08:51:42,520 yeah because if a DOT means any 13874 08:51:40,680 --> 08:51:44,718 character we'll just use a DOT and then 13875 08:51:42,520 --> 08:51:47,040 when you want to say or more use another 13876 08:51:44,718 --> 08:51:50,318 Dot and then the star so equivalent to 13877 08:51:47,040 --> 08:51:51,878 dot plus would have been dot dot star 13878 08:51:50,318 --> 08:51:53,840 because the first dot means any 13879 08:51:51,878 --> 08:51:56,200 character and the second pair of 13880 08:51:53,840 --> 08:51:57,958 characters Dot star means zero or more 13881 08:51:56,200 --> 08:51:59,638 other characters and to be clear it does 13882 08:51:57,958 --> 08:52:01,920 not have to be the same character just 13883 08:51:59,638 --> 08:52:05,080 by doing Dot or dot star does not mean 13884 08:52:01,920 --> 08:52:08,558 your whole username needs to be a or AA 13885 08:52:05,080 --> 08:52:12,080 or A AA or A A AA it can vary with each 13886 08:52:08,558 --> 08:52:14,398 symbol it just means zero or more of any 13887 08:52:12,080 --> 08:52:15,878 character back to back so I could do 13888 08:52:14,398 --> 08:52:18,000 this on both the left and the right 13889 08:52:15,878 --> 08:52:19,680 which one is better you know it depends 13890 08:52:18,000 --> 08:52:21,478 I think uh an argument could be made 13891 08:52:19,680 --> 08:52:22,958 that this is even more clear because 13892 08:52:21,478 --> 08:52:24,680 it's obvious now that there's a DOT 13893 08:52:22,958 --> 08:52:26,318 which means any character and then 13894 08:52:24,680 --> 08:52:28,238 there's the dot star but if you're in 13895 08:52:26,318 --> 08:52:30,000 the habit of doing this frequently one 13896 08:52:28,238 --> 08:52:32,200 of the reasons things like the plus 13897 08:52:30,000 --> 08:52:33,920 exist is just to consolidate your code 13898 08:52:32,200 --> 08:52:35,160 into something a little more succinct 13899 08:52:33,920 --> 08:52:37,000 and if you're familiar with seeing the 13900 08:52:35,160 --> 08:52:38,878 plus now maybe this is more readable to 13901 08:52:37,000 --> 08:52:40,520 you so again just like with python more 13902 08:52:38,878 --> 08:52:41,958 generally you're going to often see 13903 08:52:40,520 --> 08:52:43,520 different ways to express the same 13904 08:52:41,958 --> 08:52:45,878 patterns and reasonable people might 13905 08:52:43,520 --> 08:52:48,798 agree or disagree as to which way is 13906 08:52:45,878 --> 08:52:50,878 better than another well let me propose 13907 08:52:48,798 --> 08:52:52,638 to that we can think about both of these 13908 08:52:50,878 --> 08:52:54,080 models a little more graphically if this 13909 08:52:52,638 --> 08:52:56,120 looks a little cryptic to you let me go 13910 08:52:54,080 --> 08:52:58,280 ahead and rewind to the previous 13911 08:52:56,120 --> 08:53:00,958 incarnation of this regular expression 13912 08:52:58,280 --> 08:53:04,238 which was just a single dot star this 13913 08:53:00,958 --> 08:53:05,878 regular expression doar at dostar means 13914 08:53:04,238 --> 08:53:08,238 what again it means zero or more 13915 08:53:05,878 --> 08:53:09,878 characters followed by a literal at sign 13916 08:53:08,238 --> 08:53:11,360 followed by zero or more other 13917 08:53:09,878 --> 08:53:13,878 characters now when you pass this 13918 08:53:11,360 --> 08:53:16,120 pattern in as an argument to re. search 13919 08:53:13,878 --> 08:53:18,680 it's going to read it from left to right 13920 08:53:16,120 --> 08:53:20,878 and then use it to try to match against 13921 08:53:18,680 --> 08:53:23,840 the input email in this case that the 13922 08:53:20,878 --> 08:53:26,558 user typed in now how is the computer 13923 08:53:23,840 --> 08:53:28,840 how is r . search going to keep track of 13924 08:53:26,558 --> 08:53:30,718 whether or not the user's email matches 13925 08:53:28,840 --> 08:53:32,638 this pattern well it turns out that it's 13926 08:53:30,718 --> 08:53:34,120 going to be using a machine of sorts 13927 08:53:32,638 --> 08:53:36,398 implemented in software known as a 13928 08:53:34,120 --> 08:53:38,878 finite State machine or more formally a 13929 08:53:36,398 --> 08:53:40,398 non-deterministic finite automaton and 13930 08:53:38,878 --> 08:53:43,360 the way it works if we depict this 13931 08:53:40,398 --> 08:53:46,120 graphically is as follows the re. search 13932 08:53:43,360 --> 08:53:47,760 function starts over here in a so-called 13933 08:53:46,120 --> 08:53:49,680 start State that's the sort of condition 13934 08:53:47,760 --> 08:53:51,718 in which it begins and then it's going 13935 08:53:49,680 --> 08:53:53,680 to read the user's email address from 13936 08:53:51,718 --> 08:53:55,478 left to right and it's going to decide 13937 08:53:53,680 --> 08:53:58,160 whether or not to stay in this first 13938 08:53:55,478 --> 08:54:00,238 state or transition to the next state so 13939 08:53:58,160 --> 08:54:02,558 for instance in this first state as the 13940 08:54:00,238 --> 08:54:05,200 user reading my email address mailin at 13941 08:54:02,558 --> 08:54:07,760 harvard.edu it's going to follow this 13942 08:54:05,200 --> 08:54:09,798 curved edge up and around to itself a 13943 08:54:07,760 --> 08:54:11,200 reflexive Edge and it's labeled dot 13944 08:54:09,798 --> 08:54:13,760 because dot again just means any 13945 08:54:11,200 --> 08:54:15,558 character so as the function is reading 13946 08:54:13,760 --> 08:54:18,638 my email address mailin at harvard.edu 13947 08:54:15,558 --> 08:54:25,080 from left to right it's going to follow 13948 08:54:18,638 --> 08:54:26,958 these transitions as follows m a l a n 13949 08:54:25,080 --> 08:54:29,040 and then it's hopefully going to follow 13950 08:54:26,958 --> 08:54:31,000 this transition to the second state 13951 08:54:29,040 --> 08:54:32,958 because there's a literal at sign both 13952 08:54:31,000 --> 08:54:34,360 in this machine as well as in my email 13953 08:54:32,958 --> 08:54:41,238 address then it's going to try to read 13954 08:54:34,360 --> 08:54:44,040 the rest of my address h a r v a d do 13955 08:54:41,238 --> 08:54:46,280 du and that's it and then the computer's 13956 08:54:44,040 --> 08:54:48,478 going to check did it end up in a an 13957 08:54:46,280 --> 08:54:50,040 accept state a final State that's 13958 08:54:48,478 --> 08:54:52,000 actually depicted here pictorially a 13959 08:54:50,040 --> 08:54:53,520 little differently with double circles 13960 08:54:52,000 --> 08:54:56,120 one inside of the other and that just 13961 08:54:53,520 --> 08:54:59,120 means that if the computer finds itself 13962 08:54:56,120 --> 08:55:01,958 in that second accept state after having 13963 08:54:59,120 --> 08:55:04,840 read all of the users input it is indeed 13964 08:55:01,958 --> 08:55:06,520 a valid email address if by some chance 13965 08:55:04,840 --> 08:55:08,160 the machine somehow ended up stuck in 13966 08:55:06,520 --> 08:55:09,760 that first state which does not have 13967 08:55:08,160 --> 08:55:11,840 double circles and is therefore not an 13968 08:55:09,760 --> 08:55:14,840 accept state the computer would conclude 13969 08:55:11,840 --> 08:55:17,120 this is an invalid email address instead 13970 08:55:14,840 --> 08:55:19,638 by contrast if we go back to my other 13971 08:55:17,120 --> 08:55:21,680 version of the code where I instead had 13972 08:55:19,638 --> 08:55:23,478 Plus on both the left and the right 13973 08:55:21,680 --> 08:55:25,558 recall that re. search is going to use 13974 08:55:23,478 --> 08:55:27,840 one of these St machines in order to 13975 08:55:25,558 --> 08:55:29,958 decide from left to right whether or not 13976 08:55:27,840 --> 08:55:32,520 to accept the user's input like me 13977 08:55:29,958 --> 08:55:34,920 harbor. edu can we get from the start 13978 08:55:32,520 --> 08:55:37,318 state so to speak to an accept state to 13979 08:55:34,920 --> 08:55:39,798 decide Yep this was in fact meeting the 13980 08:55:37,318 --> 08:55:42,080 pattern well let's propose that this 13981 08:55:39,798 --> 08:55:43,958 non-deterministic finite automaton look 13982 08:55:42,080 --> 08:55:46,280 like this instead we're going to start 13983 08:55:43,958 --> 08:55:48,120 as before in the leftmost start State 13984 08:55:46,280 --> 08:55:50,238 and we're going to necessarily consume 13985 08:55:48,120 --> 08:55:51,760 one character per this first Edge which 13986 08:55:50,238 --> 08:55:53,520 is labeled with a DOT to indicate that 13987 08:55:51,760 --> 08:55:56,958 we can consume any one character like 13988 08:55:53,520 --> 08:55:58,318 the m in maen harvard.edu then we can 13989 08:55:56,958 --> 08:56:01,798 spend some time consuming more 13990 08:55:58,318 --> 08:56:05,360 characters before the at sign so the a l 13991 08:56:01,798 --> 08:56:07,000 a n then we can consume the at sign then 13992 08:56:05,360 --> 08:56:08,878 we can consume at least one more 13993 08:56:07,000 --> 08:56:11,920 character because recall that the Rex 13994 08:56:08,878 --> 08:56:14,040 has dot plus this time and then we can 13995 08:56:11,920 --> 08:56:16,238 consume even more characters if we want 13996 08:56:14,040 --> 08:56:21,238 so if we first consume the H in 13997 08:56:16,238 --> 08:56:27,120 harvard.edu that then leaves the a r v a 13998 08:56:21,238 --> 08:56:28,638 r d and then Dot e du and now here too 13999 08:56:27,120 --> 08:56:30,878 we're at the end of the story but we're 14000 08:56:28,638 --> 08:56:33,398 in an accept state because that circle 14001 08:56:30,878 --> 08:56:35,160 at the end has two circles total which 14002 08:56:33,398 --> 08:56:37,600 means that if the computer if this 14003 08:56:35,160 --> 08:56:39,318 function finds itself in that accept 14004 08:56:37,600 --> 08:56:42,718 state after reading the entirety of the 14005 08:56:39,318 --> 08:56:45,040 user's input it is too in fact a valid 14006 08:56:42,718 --> 08:56:46,798 email address if by contrast we had 14007 08:56:45,040 --> 08:56:49,200 gotten stuck in one of those other 14008 08:56:46,798 --> 08:56:51,238 states unable to follow a transition one 14009 08:56:49,200 --> 08:56:53,558 of those edges and therefore unable to 14010 08:56:51,238 --> 08:56:55,200 make progress in the user's input from 14011 08:56:53,558 --> 08:56:57,200 left to right then we would have to 14012 08:56:55,200 --> 08:56:59,718 conclude that that email address is in 14013 08:56:57,200 --> 08:57:01,638 fact invalid well how can we go upon 14014 08:56:59,718 --> 08:57:03,398 improving this code further let me 14015 08:57:01,638 --> 08:57:05,920 propose now that we check not only for a 14016 08:57:03,398 --> 08:57:07,360 username and also something after the 14017 08:57:05,920 --> 08:57:09,558 username like a domain name but 14018 08:57:07,360 --> 08:57:12,318 minimally required that the string ends 14019 08:57:09,558 --> 08:57:14,478 with doedu as well well I think I could 14020 08:57:12,318 --> 08:57:16,000 do this fairly straightforward not only 14021 08:57:14,478 --> 08:57:18,360 do I want there to be something after 14022 08:57:16,000 --> 08:57:20,878 the at sign like the domain like Harvard 14023 08:57:18,360 --> 08:57:23,360 I want the whole thing to end with 14024 08:57:20,878 --> 08:57:26,280 edu but there's a little bit of danger 14025 08:57:23,360 --> 08:57:28,600 here what have I done wrong by 14026 08:57:26,280 --> 08:57:33,958 implementing my regular expression now 14027 08:57:28,600 --> 08:57:36,760 in this way by using plus at. plus. edu 14028 08:57:33,958 --> 08:57:39,878 what could go wrong with this 14029 08:57:36,760 --> 08:57:41,920 version uh the dot is an dot means 14030 08:57:39,878 --> 08:57:43,600 something else in this context where it 14031 08:57:41,920 --> 08:57:45,280 means zero or more repetitions of a 14032 08:57:43,600 --> 08:57:48,000 character which is why it will interpret 14033 08:57:45,280 --> 08:57:50,760 it differently exactly even though I 14034 08:57:48,000 --> 08:57:53,200 mean for it to mean literally doedu a 14035 08:57:50,760 --> 08:57:55,160 period and then edu unfortunately in the 14036 08:57:53,200 --> 08:57:57,238 world of regular expression dot means 14037 08:57:55,160 --> 08:58:00,520 any character which means that this 14038 08:57:57,238 --> 08:58:04,398 string could technically end in a edu or 14039 08:58:00,520 --> 08:58:07,360 B edu or cedu and so forth but that's 14040 08:58:04,398 --> 08:58:09,440 not in fact that I want so any instincts 14041 08:58:07,360 --> 08:58:11,040 now as to how I could fix this problem 14042 08:58:09,440 --> 08:58:12,920 and let me demonstrate the problem more 14043 08:58:11,040 --> 08:58:14,958 clearly let me go ahead and run this 14044 08:58:12,920 --> 08:58:18,120 code here let me go ahead and type in 14045 08:58:14,958 --> 08:58:20,520 maen harvard.edu and as always this does 14046 08:58:18,120 --> 08:58:23,558 in fact work but Watch What Happens here 14047 08:58:20,520 --> 08:58:27,520 let me go ahead and do Ma at Harvard and 14048 08:58:23,558 --> 08:58:30,478 then uh M at Harvard question mark edu 14049 08:58:27,520 --> 08:58:32,160 enter that too is valid so I could put 14050 08:58:30,478 --> 08:58:34,000 any character there and it's still going 14051 08:58:32,160 --> 08:58:37,000 to be accepted but I don't want question 14052 08:58:34,000 --> 08:58:39,478 mark edu I want edu literally any 14053 08:58:37,000 --> 08:58:41,920 instincts then for how we can solve this 14054 08:58:39,478 --> 08:58:44,238 problem here how can I get this new 14055 08:58:41,920 --> 08:58:45,840 function re. search and a regular 14056 08:58:44,238 --> 08:58:48,520 expression more generally to literally 14057 08:58:45,840 --> 08:58:51,478 mean a dot might you think can you use 14058 08:58:48,520 --> 08:58:53,318 the uh Escape character the backslash 14059 08:58:51,478 --> 08:58:54,920 indeed the so-called Escape character 14060 08:58:53,318 --> 08:58:56,318 which we've seen before for outside of 14061 08:58:54,920 --> 08:58:59,200 the context of regular Expressions when 14062 08:58:56,318 --> 08:59:01,040 we talked about new lines back sln was a 14063 08:58:59,200 --> 08:59:02,638 way of telling the computer I want a new 14064 08:59:01,040 --> 08:59:04,160 line but without actually literally 14065 08:59:02,638 --> 08:59:06,200 hitting enter and moving the cursor 14066 08:59:04,160 --> 08:59:08,520 yourself and you don't want a literal n 14067 08:59:06,200 --> 08:59:10,760 on the screen so back sln was a way to 14068 08:59:08,520 --> 08:59:12,680 escape n and convey that you want a new 14069 08:59:10,760 --> 08:59:14,680 line it turns out regular Expressions 14070 08:59:12,680 --> 08:59:16,638 use a similar technique to solve this 14071 08:59:14,680 --> 08:59:18,920 problem here in fact let me go into my 14072 08:59:16,638 --> 08:59:21,520 regular expression and before that final 14073 08:59:18,920 --> 08:59:23,280 dot let me put a single backslash in the 14074 08:59:21,520 --> 08:59:24,878 world of regular Expressions this is a 14075 08:59:23,280 --> 08:59:27,200 so-called special special sequence and 14076 08:59:24,878 --> 08:59:29,120 it indicates per this backslash and a 14077 08:59:27,200 --> 08:59:31,200 single dot that I literally want to 14078 08:59:29,120 --> 08:59:33,958 match on a DOT it's not that I want to 14079 08:59:31,200 --> 08:59:37,360 match on any character and then edu I 14080 08:59:33,958 --> 08:59:40,120 want to match on a DOT or a period edu 14081 08:59:37,360 --> 08:59:42,638 but we don't want python to misinterpret 14082 08:59:40,120 --> 08:59:44,280 this backslash is beginning a an escape 14083 08:59:42,638 --> 08:59:45,878 sequence something special like backs 14084 08:59:44,280 --> 08:59:47,440 slash n which even though we as the 14085 08:59:45,878 --> 08:59:49,558 programmer might type two characters 14086 08:59:47,440 --> 08:59:52,160 backs slash n it really is interpreted 14087 08:59:49,558 --> 08:59:54,160 by python as a single new line we don't 14088 08:59:52,160 --> 08:59:56,080 want any kind of misinterpretation like 14089 08:59:54,160 --> 08:59:57,398 that here so it turns out there's one 14090 08:59:56,080 --> 08:59:59,160 other thing we should do for regular 14091 08:59:57,398 --> 09:00:01,478 expressions like this that have a 14092 08:59:59,160 --> 09:00:03,478 backslash used in this way I want to 14093 09:00:01,478 --> 09:00:05,600 specify to python that I want this 14094 09:00:03,478 --> 09:00:08,120 string this regular expression in double 14095 09:00:05,600 --> 09:00:09,760 quotes to be treated as a raw string 14096 09:00:08,120 --> 09:00:11,478 literally putting an r at the beginning 14097 09:00:09,760 --> 09:00:13,398 of the string to indicate to python that 14098 09:00:11,478 --> 09:00:15,920 you should not try to interpret any 14099 09:00:13,398 --> 09:00:17,760 backslashes in the usual way I want to 14100 09:00:15,920 --> 09:00:19,878 literally pass the backslash and the dot 14101 09:00:17,760 --> 09:00:22,318 and the edu into this particular 14102 09:00:19,878 --> 09:00:24,398 function search in this case so it's 14103 09:00:22,318 --> 09:00:26,238 similar in spirit to using that f at the 14104 09:00:24,398 --> 09:00:28,040 beginning of a format string which of 14105 09:00:26,238 --> 09:00:30,080 course tells python to format the string 14106 09:00:28,040 --> 09:00:31,798 in a certain way plugging in variables 14107 09:00:30,080 --> 09:00:34,718 that might be between curly braces but 14108 09:00:31,798 --> 09:00:37,638 in this case r indicates a raw string 14109 09:00:34,718 --> 09:00:39,478 that I want passed in exactly as is now 14110 09:00:37,638 --> 09:00:42,120 it's only strictly necessary if you are 14111 09:00:39,478 --> 09:00:43,760 in fact using backslashes to indicate 14112 09:00:42,120 --> 09:00:45,718 that you want some special sequence like 14113 09:00:43,760 --> 09:00:47,360 backs slash dot but in general it's 14114 09:00:45,718 --> 09:00:49,440 probably a good habit to get into to 14115 09:00:47,360 --> 09:00:50,760 just use raw strings for all of your 14116 09:00:49,440 --> 09:00:52,478 regular Expressions so that if you 14117 09:00:50,760 --> 09:00:54,280 eventually go back in make a change make 14118 09:00:52,478 --> 09:00:56,558 an addition you don't accident acally 14119 09:00:54,280 --> 09:00:58,478 introduce a backslash and then forget 14120 09:00:56,558 --> 09:01:00,638 that that might have some special or 14121 09:00:58,478 --> 09:01:01,920 misinterpreted meaning well let me go 14122 09:01:00,638 --> 09:01:03,878 ahead and try this new regular 14123 09:01:01,920 --> 09:01:07,398 expression I'll clear my terminal window 14124 09:01:03,878 --> 09:01:09,718 run python of validate run python of 14125 09:01:07,398 --> 09:01:11,360 validate dopy and then I'll type in my 14126 09:01:09,718 --> 09:01:14,040 email address correctly mailen 14127 09:01:11,360 --> 09:01:15,920 harvard.edu and that's fortunately still 14128 09:01:14,040 --> 09:01:18,520 valid Let Me Clear My screen and run it 14129 09:01:15,920 --> 09:01:21,160 one more time python of validate dopie 14130 09:01:18,520 --> 09:01:24,120 and this time let's mistype it as mailen 14131 09:01:21,160 --> 09:01:25,558 Harvard questionmark edu where by 14132 09:01:24,120 --> 09:01:27,798 there's obviously not a DOT there but 14133 09:01:25,558 --> 09:01:29,840 there is some other Single Character 14134 09:01:27,798 --> 09:01:32,040 that last time was misinterpreted as 14135 09:01:29,840 --> 09:01:34,638 valid but this time now that I've 14136 09:01:32,040 --> 09:01:37,680 improved my regular expression it's 14137 09:01:34,638 --> 09:01:40,478 discovered as indeed invalid any 14138 09:01:37,680 --> 09:01:42,798 questions now on this technique for 14139 09:01:40,478 --> 09:01:44,718 matching something to the left of the at 14140 09:01:42,798 --> 09:01:47,440 sign something to the right and now 14141 09:01:44,718 --> 09:01:49,878 ending with edu explicitly um what 14142 09:01:47,440 --> 09:01:52,360 happens when 14143 09:01:49,878 --> 09:01:53,958 that a good question and you kind of 14144 09:01:52,360 --> 09:01:57,040 called me out here well when in doubt 14145 09:01:53,958 --> 09:01:59,080 let's try let me go ahead and do python 14146 09:01:57,040 --> 09:02:02,680 validate dopy 14147 09:01:59,080 --> 09:02:05,200 mailin harvard.edu which ALS so is 14148 09:02:02,680 --> 09:02:07,760 incorrect unfortunately my code thinks 14149 09:02:05,200 --> 09:02:09,798 it's valid so another problem to solve 14150 09:02:07,760 --> 09:02:12,280 but a shortcoming for now other 14151 09:02:09,798 --> 09:02:16,478 questions on these regular Expressions 14152 09:02:12,280 --> 09:02:19,200 thus far can you use curly brackets M 14153 09:02:16,478 --> 09:02:20,920 instead of back can you use curly 14154 09:02:19,200 --> 09:02:22,558 brackets instead of backslash not in 14155 09:02:20,920 --> 09:02:24,840 this case if you want a literal dot 14156 09:02:22,558 --> 09:02:26,680 backslash Dot is the way to do it 14157 09:02:24,840 --> 09:02:29,600 literally how about one other question 14158 09:02:26,680 --> 09:02:33,160 on regular Expressions is this the same 14159 09:02:29,600 --> 09:02:35,878 thing that Google forms uses in order to 14160 09:02:33,160 --> 09:02:38,680 categorize data in let's say some if 14161 09:02:35,878 --> 09:02:42,080 you've got multiple people sending in 14162 09:02:38,680 --> 09:02:44,440 requests about some feedback do they 14163 09:02:42,080 --> 09:02:46,600 categorize the data that they get using 14164 09:02:44,440 --> 09:02:48,238 this particular regular expression thing 14165 09:02:46,600 --> 09:02:50,680 indeed if you've ever used Google forms 14166 09:02:48,238 --> 09:02:52,840 to not just submit it but to create a 14167 09:02:50,680 --> 09:02:55,080 Google form one of the menu options is 14168 09:02:52,840 --> 09:02:56,760 for response validation in English at 14169 09:02:55,080 --> 09:02:58,798 least and what that allows you to do is 14170 09:02:56,760 --> 09:03:02,520 specify that the user has to input an 14171 09:02:58,798 --> 09:03:04,318 email address or a URL uh or a string of 14172 09:03:02,520 --> 09:03:05,878 some length but there's an even more 14173 09:03:04,318 --> 09:03:07,440 powerful feature that some of you may 14174 09:03:05,878 --> 09:03:09,160 not have ever noticed and indeed if 14175 09:03:07,440 --> 09:03:11,280 you'd like to open up Google forms 14176 09:03:09,160 --> 09:03:13,478 create a new form temporarily and poke 14177 09:03:11,280 --> 09:03:15,520 around you will actually see in English 14178 09:03:13,478 --> 09:03:17,160 at least quote unquote regular 14179 09:03:15,520 --> 09:03:19,120 expression mentioned as one of the 14180 09:03:17,160 --> 09:03:21,520 mechanisms you can use to validate your 14181 09:03:19,120 --> 09:03:23,798 users's input into your Google form so 14182 09:03:21,520 --> 09:03:25,638 in fact after today you can start 14183 09:03:23,798 --> 09:03:27,398 avoiding these specific dropdowns of 14184 09:03:25,638 --> 09:03:29,958 like email address or URL or the like 14185 09:03:27,398 --> 09:03:32,318 and you can express your own patterns 14186 09:03:29,958 --> 09:03:34,920 precisely as well regular Expressions 14187 09:03:32,318 --> 09:03:37,360 can even be used in VSS code itself if 14188 09:03:34,920 --> 09:03:39,398 you go and find or do a find and replace 14189 09:03:37,360 --> 09:03:41,558 in VSS code you can of course just type 14190 09:03:39,398 --> 09:03:44,238 in words like you could into Microsoft 14191 09:03:41,558 --> 09:03:46,120 Word or Google Docs you can also type if 14192 09:03:44,238 --> 09:03:48,160 you check the right box regular 14193 09:03:46,120 --> 09:03:51,600 expressions and start searching for 14194 09:03:48,160 --> 09:03:54,238 patterns not literally specific values 14195 09:03:51,600 --> 09:03:56,280 well let me propose that we now enhance 14196 09:03:54,238 --> 09:03:58,280 this implementation further by 14197 09:03:56,280 --> 09:04:00,840 introducing a few other symbols because 14198 09:03:58,280 --> 09:04:03,000 right now with my code I keep saying 14199 09:04:00,840 --> 09:04:06,040 that I want my email address to end with 14200 09:04:03,000 --> 09:04:08,238 edu and start with a username but I'm 14201 09:04:06,040 --> 09:04:10,160 being a little too generous this does in 14202 09:04:08,238 --> 09:04:13,760 fact work as expected for my own email 14203 09:04:10,160 --> 09:04:17,318 address maen harvard.edu but what if I 14204 09:04:13,760 --> 09:04:20,440 type in a sentence like my email address 14205 09:04:17,318 --> 09:04:22,280 is maen harvard.edu and suppose I've 14206 09:04:20,440 --> 09:04:24,360 typed that into the program or I've 14207 09:04:22,280 --> 09:04:28,798 typed that into a Google form 14208 09:04:24,360 --> 09:04:32,000 is this going to be considered valid or 14209 09:04:28,798 --> 09:04:34,680 invalid well let's consider it's got the 14210 09:04:32,000 --> 09:04:36,920 at sign so we're good there it's got one 14211 09:04:34,680 --> 09:04:39,398 or more characters to the left of the at 14212 09:04:36,920 --> 09:04:41,600 sign it's got one or more characters to 14213 09:04:39,398 --> 09:04:45,120 the right of the at sign it's got a 14214 09:04:41,600 --> 09:04:47,000 literal doedu somewhere in there to the 14215 09:04:45,120 --> 09:04:48,638 right of the at sign and granted there's 14216 09:04:47,000 --> 09:04:50,520 more stuff to the right there's 14217 09:04:48,638 --> 09:04:52,920 literally this period at the end of my 14218 09:04:50,520 --> 09:04:55,040 English sentence but that's okay because 14219 09:04:52,920 --> 09:04:57,760 at the moment my expression is not so 14220 09:04:55,040 --> 09:05:01,200 precise as to say the pattern must start 14221 09:04:57,760 --> 09:05:03,558 with the username and end with the doedu 14222 09:05:01,200 --> 09:05:05,238 technically it's left unsaid what more 14223 09:05:03,558 --> 09:05:07,718 can be to the left and what more can be 14224 09:05:05,238 --> 09:05:09,398 to the right so when I hit enter now 14225 09:05:07,718 --> 09:05:11,520 you'll see that that whole sentence in 14226 09:05:09,398 --> 09:05:13,160 English is valid and that's obviously 14227 09:05:11,520 --> 09:05:15,958 not what you want in fact consider the 14228 09:05:13,160 --> 09:05:18,318 case of using Google forms or Office 365 14229 09:05:15,958 --> 09:05:20,478 to collect data from users if you don't 14230 09:05:18,318 --> 09:05:22,280 validate your input your users might 14231 09:05:20,478 --> 09:05:24,200 very well type in a full sentence or 14232 09:05:22,280 --> 09:05:25,958 some else with a typographic IAL error 14233 09:05:24,200 --> 09:05:28,120 not an actual email so if you're just 14234 09:05:25,958 --> 09:05:29,398 trying to copy all of the results that 14235 09:05:28,120 --> 09:05:31,398 have been typed into your form so you 14236 09:05:29,398 --> 09:05:33,160 can paste them into Gmail or some email 14237 09:05:31,398 --> 09:05:34,360 program it's going to break because 14238 09:05:33,160 --> 09:05:35,920 you're going to accidentally paste 14239 09:05:34,360 --> 09:05:37,958 something like a whole English sentence 14240 09:05:35,920 --> 09:05:39,958 into the program instead of just an 14241 09:05:37,958 --> 09:05:42,160 email address which is what your mailer 14242 09:05:39,958 --> 09:05:43,718 expects so how can I be more precise 14243 09:05:42,160 --> 09:05:46,440 well let me propose we introduce a few 14244 09:05:43,718 --> 09:05:48,600 more symbols as well it turns out in the 14245 09:05:46,440 --> 09:05:50,798 context of a regular expression one of 14246 09:05:48,600 --> 09:05:53,200 these patterns you can use the carrot 14247 09:05:50,798 --> 09:05:55,000 symbol the little triangular Mark to 14248 09:05:53,200 --> 09:05:57,638 repres presentent that you want this 14249 09:05:55,000 --> 09:05:59,878 pattern to match the start of the string 14250 09:05:57,638 --> 09:06:02,440 specifically not anywhere but the start 14251 09:05:59,878 --> 09:06:04,478 of the user string by contrast you can 14252 09:06:02,440 --> 09:06:06,520 use a dollar sign in your regular 14253 09:06:04,478 --> 09:06:08,438 expression to say that you want to match 14254 09:06:06,520 --> 09:06:10,078 the end of the string or technically 14255 09:06:08,438 --> 09:06:11,520 just before the new line at the end of 14256 09:06:10,078 --> 09:06:13,278 the string but for all intents and 14257 09:06:11,520 --> 09:06:15,438 purposes think of carrot as meaning 14258 09:06:13,278 --> 09:06:18,438 start of the string and dollar sign as 14259 09:06:15,438 --> 09:06:20,598 meaning end of the string it is a weird 14260 09:06:18,438 --> 09:06:22,160 thing that one is a carrot and one is a 14261 09:06:20,598 --> 09:06:23,878 dollar sign these are not really things 14262 09:06:22,160 --> 09:06:25,680 that I think of as opposites like a 14263 09:06:23,878 --> 09:06:27,160 parenthesis or something like that but 14264 09:06:25,680 --> 09:06:29,558 those are the symbols the world chose 14265 09:06:27,160 --> 09:06:32,122 many years ago so let me go back to VSS 14266 09:06:29,558 --> 09:06:35,000 code now and let me add this feature to 14267 09:06:32,122 --> 09:06:37,040 my code here let me specify that yes I 14268 09:06:35,000 --> 09:06:39,960 do want to search for this pattern but I 14269 09:06:37,040 --> 09:06:41,918 want the user's input to start with this 14270 09:06:39,960 --> 09:06:43,160 pattern and end with this pattern so 14271 09:06:41,918 --> 09:06:45,558 even though it's going to start looking 14272 09:06:43,160 --> 09:06:47,840 even more cryptic I put a carrot symbol 14273 09:06:45,558 --> 09:06:50,000 here at the beginning and I put a dollar 14274 09:06:47,840 --> 09:06:52,000 sign here at the end that does not mean 14275 09:06:50,000 --> 09:06:53,918 I want the user to type a carrot symbol 14276 09:06:52,000 --> 09:06:57,122 or a dollar sign this is special 14277 09:06:53,918 --> 09:06:58,840 symbology that indicates to re. search 14278 09:06:57,122 --> 09:07:01,640 that it should only look for now an 14279 09:06:58,840 --> 09:07:03,758 exact match against this pattern so if I 14280 09:07:01,640 --> 09:07:05,238 now go back to my terminal window and 14281 09:07:03,758 --> 09:07:07,480 I'll leave the previous result on the 14282 09:07:05,238 --> 09:07:10,480 screen let me type the exact same thing 14283 09:07:07,480 --> 09:07:13,640 my email address is ma at harvard.edu 14284 09:07:10,480 --> 09:07:16,278 enter sorry period and now I'm going to 14285 09:07:13,640 --> 09:07:18,598 go ahead and hit enter now that's 14286 09:07:16,278 --> 09:07:19,960 considered invalid but let me clear the 14287 09:07:18,598 --> 09:07:21,800 screen and just to make sure I didn't 14288 09:07:19,960 --> 09:07:25,598 break things let me type in just my 14289 09:07:21,800 --> 09:07:27,918 email address and that two is valid any 14290 09:07:25,598 --> 09:07:30,438 questions now on this version of my 14291 09:07:27,918 --> 09:07:33,598 regular expression which note goes 14292 09:07:30,438 --> 09:07:36,078 further to specify even more precisely 14293 09:07:33,598 --> 09:07:36,918 that I want it to match at the start and 14294 09:07:36,078 --> 09:07:41,000 the 14295 09:07:36,918 --> 09:07:44,160 end any questions on this one here okay 14296 09:07:41,000 --> 09:07:47,918 you have slash and do edu and then the 14297 09:07:44,160 --> 09:07:51,040 dollar sign but the dot is like one of 14298 09:07:47,918 --> 09:07:54,558 the regular expression right it normally 14299 09:07:51,040 --> 09:07:57,438 is but this backslash that I Deli put 14300 09:07:54,558 --> 09:08:00,398 before this period here is an escape 14301 09:07:57,438 --> 09:08:02,360 character it is a way of telling re. 14302 09:08:00,398 --> 09:08:05,200 search that I don't want any character 14303 09:08:02,360 --> 09:08:06,558 there I literally want a period there 14304 09:08:05,200 --> 09:08:08,718 and it's the only way you can 14305 09:08:06,558 --> 09:08:11,278 distinguish one from the other if I got 14306 09:08:08,718 --> 09:08:13,278 rid of that slash this would mean that 14307 09:08:11,278 --> 09:08:15,758 the email address just has to end with 14308 09:08:13,278 --> 09:08:18,320 any character then an e then a d then a 14309 09:08:15,758 --> 09:08:21,800 u i don't want that I want literally a 14310 09:08:18,320 --> 09:08:23,918 period Then the E then the D then the U 14311 09:08:21,800 --> 09:08:25,758 this is actually common convention in 14312 09:08:23,918 --> 09:08:27,640 programming and technology in general if 14313 09:08:25,758 --> 09:08:29,200 you and I decide on a convention whereby 14314 09:08:27,640 --> 09:08:31,238 we're using some character on the 14315 09:08:29,200 --> 09:08:33,238 keyboard to mean something special 14316 09:08:31,238 --> 09:08:35,558 invariably we create a future problem 14317 09:08:33,238 --> 09:08:37,758 for oursel when we want to literally use 14318 09:08:35,558 --> 09:08:40,000 that same character and so the solution 14319 09:08:37,758 --> 09:08:41,840 in general to that problem is to somehow 14320 09:08:40,000 --> 09:08:43,520 escape the character so that it's clear 14321 09:08:41,840 --> 09:08:45,758 to the computer that it's not that 14322 09:08:43,520 --> 09:08:47,840 special symbol it's literally the symbol 14323 09:08:45,758 --> 09:08:51,040 it sees so we don't even love it we 14324 09:08:47,840 --> 09:08:54,758 don't need another another slash before 14325 09:08:51,040 --> 09:08:57,398 the dollar sign no uh because in this 14326 09:08:54,758 --> 09:08:59,718 case dollar sign means something special 14327 09:08:57,398 --> 09:09:01,718 per this chart here dollar sign by 14328 09:08:59,718 --> 09:09:04,000 itself does not mean US dollars or 14329 09:09:01,718 --> 09:09:06,918 currency it literally means match the 14330 09:09:04,000 --> 09:09:09,680 end of the string if however I wanted 14331 09:09:06,918 --> 09:09:11,398 the user to literally type in a dollar 14332 09:09:09,680 --> 09:09:13,438 sign at the end of their input the 14333 09:09:11,398 --> 09:09:15,840 solution would be the same I would put a 14334 09:09:13,438 --> 09:09:17,558 backslash before the dollar sign which 14335 09:09:15,840 --> 09:09:20,520 means my email address would have to be 14336 09:09:17,558 --> 09:09:22,718 something like mait harvard.edu dollar 14337 09:09:20,520 --> 09:09:25,598 sign which is obviously not correct too 14338 09:09:22,718 --> 09:09:27,918 so back slashes just allow you to tell 14339 09:09:25,598 --> 09:09:30,320 the computer to not treat those symbols 14340 09:09:27,918 --> 09:09:33,000 specially like meaning something special 14341 09:09:30,320 --> 09:09:35,438 but to treat them literally instead how 14342 09:09:33,000 --> 09:09:37,758 about one other question here on regular 14343 09:09:35,438 --> 09:09:41,000 Expressions you said you said one 14344 09:09:37,758 --> 09:09:42,840 represents to to make it one plus then 14345 09:09:41,000 --> 09:09:46,320 you say one was to make it one with 14346 09:09:42,840 --> 09:09:47,558 nothing sure so let me rewind in time I 14347 09:09:46,320 --> 09:09:49,360 think what you're referring to was one 14348 09:09:47,558 --> 09:09:51,800 of our earlier versions that initially 14349 09:09:49,360 --> 09:09:54,598 looked like this which just meant Zero 14350 09:09:51,800 --> 09:09:57,278 or more characters then an at sign than 14351 09:09:54,598 --> 09:10:00,480 zero or more other characters we then 14352 09:09:57,278 --> 09:10:02,238 evolved that to be this Plus on both 14353 09:10:00,480 --> 09:10:04,598 sides which means one or more characters 14354 09:10:02,238 --> 09:10:06,758 on the left then an at sign then one or 14355 09:10:04,598 --> 09:10:08,680 more characters on the right and if I'm 14356 09:10:06,758 --> 09:10:10,398 interpreting your question correctly one 14357 09:10:08,680 --> 09:10:12,558 of the points I made earlier was that if 14358 09:10:10,398 --> 09:10:14,758 you didn't use Plus or forgot that it 14359 09:10:12,558 --> 09:10:16,878 exists you could equivalently achieve 14360 09:10:14,758 --> 09:10:19,800 the exact same result with two dots and 14361 09:10:16,878 --> 09:10:21,918 a star because the first dot means any 14362 09:10:19,800 --> 09:10:25,200 character it's got to be there the 14363 09:10:21,918 --> 09:10:27,398 second dot star means zero or more other 14364 09:10:25,200 --> 09:10:29,360 characters and same on the right so it's 14365 09:10:27,398 --> 09:10:32,278 just another way of expressing the same 14366 09:10:29,360 --> 09:10:35,320 idea one or more can be represented like 14367 09:10:32,278 --> 09:10:37,878 this with do do star or you can just use 14368 09:10:35,320 --> 09:10:39,800 the handier syntax of plus which means 14369 09:10:37,878 --> 09:10:41,238 the same thing all right so I dare say 14370 09:10:39,800 --> 09:10:43,122 there's still some problems with the 14371 09:10:41,238 --> 09:10:44,758 regular expression in this current form 14372 09:10:43,122 --> 09:10:46,000 because even though now we're starting 14373 09:10:44,758 --> 09:10:48,078 to look for the username at the 14374 09:10:46,000 --> 09:10:50,200 beginning of the string from the user 14375 09:10:48,078 --> 09:10:52,480 and we're looking for the edu literally 14376 09:10:50,200 --> 09:10:55,200 at the end of the string from the user 14377 09:10:52,480 --> 09:10:57,078 those dots are a little too encompassing 14378 09:10:55,200 --> 09:11:00,000 right now I am allowed to type in more 14379 09:10:57,078 --> 09:11:02,040 than the single at sign why because at 14380 09:11:00,000 --> 09:11:03,878 is a character and Dot means any 14381 09:11:02,040 --> 09:11:05,878 character so honestly I can have as many 14382 09:11:03,878 --> 09:11:08,122 at signs as this thing at the moment as 14383 09:11:05,878 --> 09:11:11,000 I want for instance if I run python of 14384 09:11:08,122 --> 09:11:13,718 validate dopy mailin harvard.edu still 14385 09:11:11,000 --> 09:11:15,878 works as expected but if I also run 14386 09:11:13,718 --> 09:11:19,398 python to validate dopy and incorrectly 14387 09:11:15,878 --> 09:11:22,200 do maen harvard.edu that should be 14388 09:11:19,398 --> 09:11:23,960 invalid but it's considered valid 14389 09:11:22,200 --> 09:11:26,918 instead so I I think we need to be a 14390 09:11:23,960 --> 09:11:29,040 little more restrictive when it comes to 14391 09:11:26,918 --> 09:11:31,640 that dot and we can't just say oh any 14392 09:11:29,040 --> 09:11:34,320 old character there is fine we need to 14393 09:11:31,640 --> 09:11:36,438 be more specific well it turns out that 14394 09:11:34,320 --> 09:11:39,398 regular Expressions also support this 14395 09:11:36,438 --> 09:11:41,878 syntax you can use square brackets 14396 09:11:39,398 --> 09:11:45,000 inside of your pattern and inside of 14397 09:11:41,878 --> 09:11:46,960 those square brackets include one or 14398 09:11:45,000 --> 09:11:48,040 more characters that you want to look 14399 09:11:46,960 --> 09:11:50,718 for 14400 09:11:48,040 --> 09:11:52,878 specifically alternatively you can 14401 09:11:50,718 --> 09:11:55,078 inside of those square brackets put a 14402 09:11:52,878 --> 09:11:56,640 car symbol which unfortunately in this 14403 09:11:55,078 --> 09:11:58,360 context means something completely 14404 09:11:56,640 --> 09:12:00,598 different from match the start of the 14405 09:11:58,360 --> 09:12:02,640 string but this would be the compliment 14406 09:12:00,598 --> 09:12:04,960 operator inside of these square brackets 14407 09:12:02,640 --> 09:12:07,238 which means you cannot match any of 14408 09:12:04,960 --> 09:12:09,278 these characters so things are about to 14409 09:12:07,238 --> 09:12:11,040 look even more cryptic now but that's 14410 09:12:09,278 --> 09:12:13,558 why we're focusing on regular 14411 09:12:11,040 --> 09:12:16,238 Expressions on their own here if I don't 14412 09:12:13,558 --> 09:12:19,000 want to allow any character which is 14413 09:12:16,238 --> 09:12:21,238 what a DOT is let me go ahead and I 14414 09:12:19,000 --> 09:12:25,160 could just say well I only want to 14415 09:12:21,238 --> 09:12:26,960 support a or B's or C's or D's or E's or 14416 09:12:25,160 --> 09:12:29,000 FS or G's I could type in the whole 14417 09:12:26,960 --> 09:12:30,718 alphabet here plus some numbers to 14418 09:12:29,000 --> 09:12:33,078 actually include all of the letters that 14419 09:12:30,718 --> 09:12:35,718 I do want to allow but honestly a little 14420 09:12:33,078 --> 09:12:39,320 simpler would be this I could use a 14421 09:12:35,718 --> 09:12:41,840 carrot symbol and then an at sign which 14422 09:12:39,320 --> 09:12:45,078 has the effect of saying this is the set 14423 09:12:41,840 --> 09:12:47,398 of characters that has everything except 14424 09:12:45,078 --> 09:12:49,840 an at sign and I can do the same thing 14425 09:12:47,398 --> 09:12:53,398 over here instead of a DOT to the right 14426 09:12:49,840 --> 09:12:56,438 of the at sign I can do Open Bracket 14427 09:12:53,398 --> 09:12:58,398 carrot at sign and I admit things are 14428 09:12:56,438 --> 09:13:00,278 starting to escalate quickly here but 14429 09:12:58,398 --> 09:13:03,238 let's start from the left and go to the 14430 09:13:00,278 --> 09:13:04,960 right this carrot outside of the square 14431 09:13:03,238 --> 09:13:07,040 brackets at the very start of my string 14432 09:13:04,960 --> 09:13:09,078 as before means match from the start of 14433 09:13:07,040 --> 09:13:10,640 the string and let's Jump Ahead the 14434 09:13:09,078 --> 09:13:12,640 dollar sign all the way at the end of 14435 09:13:10,640 --> 09:13:14,598 the regular expression means match at 14436 09:13:12,640 --> 09:13:16,000 the end of the string so if we can 14437 09:13:14,598 --> 09:13:18,000 mentally tick those off as 14438 09:13:16,000 --> 09:13:20,320 straightforward let's now focus on 14439 09:13:18,000 --> 09:13:22,520 everything else in the middle well to 14440 09:13:20,320 --> 09:13:26,398 the left here we have new syntax a 14441 09:13:22,520 --> 09:13:28,878 square bracket another carrot an at sign 14442 09:13:26,398 --> 09:13:31,238 and a Clos square bracket and then a 14443 09:13:28,878 --> 09:13:33,640 plus the plus means the same thing as 14444 09:13:31,238 --> 09:13:36,078 always it means one or more of the 14445 09:13:33,640 --> 09:13:38,718 things to the left what is the thing to 14446 09:13:36,078 --> 09:13:40,718 the left well this is the new syntax 14447 09:13:38,718 --> 09:13:43,278 inside of square brackets here I have a 14448 09:13:40,718 --> 09:13:46,238 carrot symbol and then an at sign that 14449 09:13:43,278 --> 09:13:48,680 just means any character except an at 14450 09:13:46,238 --> 09:13:51,398 sign it's a weird syntax but this is how 14451 09:13:48,680 --> 09:13:54,200 we can express that simple idea any 14452 09:13:51,398 --> 09:13:55,960 character on the keyboard EX except for 14453 09:13:54,200 --> 09:13:57,238 an at sign and heck even other 14454 09:13:55,960 --> 09:14:00,160 characters that aren't physically on 14455 09:13:57,238 --> 09:14:02,278 your keyboard but that nonetheless exist 14456 09:14:00,160 --> 09:14:04,000 then we have a literal at sign then we 14457 09:14:02,278 --> 09:14:06,480 have another one of these same things 14458 09:14:04,000 --> 09:14:08,320 square bracket carrot at close bracket 14459 09:14:06,480 --> 09:14:10,960 which means any character except an at 14460 09:14:08,320 --> 09:14:13,878 sign then one or more of those things 14461 09:14:10,960 --> 09:14:16,840 followed by literally a period 14462 09:14:13,878 --> 09:14:19,520 U so now let me go ahead and do this 14463 09:14:16,840 --> 09:14:21,278 again let me rerun python of validate 14464 09:14:19,520 --> 09:14:23,558 dopy and test my own email address to 14465 09:14:21,278 --> 09:14:25,200 make sure I've not made things work and 14466 09:14:23,558 --> 09:14:26,800 we're good now let me go ahead and clear 14467 09:14:25,200 --> 09:14:28,680 my screen and run python of validate 14468 09:14:26,800 --> 09:14:32,122 dopy again and do 14469 09:14:28,680 --> 09:14:34,320 mailin harvard.edu crossing my fingers 14470 09:14:32,122 --> 09:14:37,520 this time and finally this now is 14471 09:14:34,320 --> 09:14:39,840 invalid why I'm allowing myself to have 14472 09:14:37,520 --> 09:14:42,320 one at sign in the middle of the user's 14473 09:14:39,840 --> 09:14:45,160 input but everything to the left per 14474 09:14:42,320 --> 09:14:47,960 this new syntax cannot be an at sign it 14475 09:14:45,160 --> 09:14:49,758 can be anything but one or more times 14476 09:14:47,960 --> 09:14:52,320 and everything to the right of the at 14477 09:14:49,758 --> 09:14:55,122 sign can be anything but an at sign one 14478 09:14:52,320 --> 09:14:58,520 or more time followed by lastly a 14479 09:14:55,122 --> 09:15:01,122 literal. edu so again the new syntax is 14480 09:14:58,520 --> 09:15:03,278 quite simply this square brackets allow 14481 09:15:01,122 --> 09:15:04,878 you to specify a set of characters that 14482 09:15:03,278 --> 09:15:07,640 you literally type out at your keyboard 14483 09:15:04,878 --> 09:15:09,718 a bcde e f or the complement the 14484 09:15:07,640 --> 09:15:12,360 opposite the carrot symbol which means 14485 09:15:09,718 --> 09:15:13,558 not and then the one or more symbols you 14486 09:15:12,360 --> 09:15:16,520 want to 14487 09:15:13,558 --> 09:15:19,360 exclude questions now on this syntax 14488 09:15:16,520 --> 09:15:21,878 here so right after add sign can we use 14489 09:15:19,360 --> 09:15:24,398 the curly brackets M uh one so that we 14490 09:15:21,878 --> 09:15:26,558 can only have one repetition of the ad 14491 09:15:24,398 --> 09:15:28,758 symbol absolutely so we could do this 14492 09:15:26,558 --> 09:15:30,758 let me go ahead and pull a VSS code and 14493 09:15:28,758 --> 09:15:32,200 let me delete the current form of a 14494 09:15:30,758 --> 09:15:35,758 regular expression and go back to where 14495 09:15:32,200 --> 09:15:38,000 we began which was justar at and star I 14496 09:15:35,758 --> 09:15:40,918 could absolutely do something like this 14497 09:15:38,000 --> 09:15:43,360 and require that I want at least one of 14498 09:15:40,918 --> 09:15:45,598 any character here and then I could do 14499 09:15:43,360 --> 09:15:47,598 something more to have any more as well 14500 09:15:45,598 --> 09:15:49,398 so the curly brace syntax which we saw 14501 09:15:47,598 --> 09:15:51,598 on the slide earlier but didn't yet use 14502 09:15:49,398 --> 09:15:53,558 absolutely can be used to specify a 14503 09:15:51,598 --> 09:15:55,398 specific number of characters but 14504 09:15:53,558 --> 09:15:58,000 honestly this is more verbose than is 14505 09:15:55,398 --> 09:16:00,160 necessary the best solution arguably or 14506 09:15:58,000 --> 09:16:02,278 the simplest at least ultimately is just 14507 09:16:00,160 --> 09:16:03,918 to say do plus but there too another 14508 09:16:02,278 --> 09:16:06,480 example of how you can solve the same 14509 09:16:03,918 --> 09:16:08,160 problem multiple ways let me go back to 14510 09:16:06,480 --> 09:16:11,078 where the regular expression just was 14511 09:16:08,160 --> 09:16:14,360 and take other questions as well 14512 09:16:11,078 --> 09:16:17,918 questions on these sets of characters or 14513 09:16:14,360 --> 09:16:20,278 complimenting that set so can you use 14514 09:16:17,918 --> 09:16:22,238 that same syntax to say that you don't 14515 09:16:20,278 --> 09:16:23,878 want a certain character throughout the 14516 09:16:22,238 --> 09:16:26,840 whole stream 14517 09:16:23,878 --> 09:16:28,558 you could it's going to be uh you could 14518 09:16:26,840 --> 09:16:31,480 absolutely use the same character to 14519 09:16:28,558 --> 09:16:33,238 exclude a um you could absolutely use 14520 09:16:31,480 --> 09:16:35,598 the syntax to exclude a certain 14521 09:16:33,238 --> 09:16:37,040 character from the entire string but it 14522 09:16:35,598 --> 09:16:39,078 would be a little harder right now 14523 09:16:37,040 --> 09:16:41,718 because we're still requiring edu at the 14524 09:16:39,078 --> 09:16:44,718 end but yes 14525 09:16:41,718 --> 09:16:48,480 absolutely other questions what happens 14526 09:16:44,718 --> 09:16:50,840 if the user inputs edu in the beginning 14527 09:16:48,480 --> 09:16:53,078 of the thinging a good question what 14528 09:16:50,840 --> 09:16:54,278 happens if the user types in doedu the 14529 09:16:53,078 --> 09:16:56,040 beginning of the screen well let me go 14530 09:16:54,278 --> 09:16:57,680 back to VSS code here and let's try to 14531 09:16:56,040 --> 09:16:59,398 solve this in two different ways first 14532 09:16:57,680 --> 09:17:01,878 let's look at the regular expression and 14533 09:16:59,398 --> 09:17:04,078 see if we can infer if that's going to 14534 09:17:01,878 --> 09:17:07,200 be tolerated well according to the 14535 09:17:04,078 --> 09:17:09,398 current cryptic regular expression I'm 14536 09:17:07,200 --> 09:17:11,598 saying that you can have any character 14537 09:17:09,398 --> 09:17:14,398 except the at sign so that would work I 14538 09:17:11,598 --> 09:17:17,160 could have the dot for the edu but then 14539 09:17:14,398 --> 09:17:19,520 I have to have an at sign so that 14540 09:17:17,160 --> 09:17:21,918 wouldn't really work because if I'm just 14541 09:17:19,520 --> 09:17:23,840 typing in.edu we're not going to pass 14542 09:17:21,918 --> 09:17:25,960 that constraint so now let me try this 14543 09:17:23,840 --> 09:17:28,398 in uh by running the program let me type 14544 09:17:25,960 --> 09:17:32,878 in just literally doedu that doesn't 14545 09:17:28,398 --> 09:17:36,960 work but but but I could do this doedu 14546 09:17:32,878 --> 09:17:43,398 at.edu that too is invalid but let me do 14547 09:17:36,960 --> 09:17:45,040 this uhedu at something. edu that passes 14548 09:17:43,398 --> 09:17:47,160 so it's starting to get a little weird 14549 09:17:45,040 --> 09:17:49,078 now maybe it's valid maybe it's not but 14550 09:17:47,160 --> 09:17:51,800 I think we'll eventually be more precise 14551 09:17:49,078 --> 09:17:53,558 too how about one more question on this 14552 09:17:51,800 --> 09:17:55,718 regular expression 14553 09:17:53,558 --> 09:17:59,640 and these complimenting of sets can we 14554 09:17:55,718 --> 09:18:01,520 use uh another domain name as a string 14555 09:17:59,640 --> 09:18:03,238 input can you use another domain name 14556 09:18:01,520 --> 09:18:04,718 absolutely I'm using my own just for the 14557 09:18:03,238 --> 09:18:07,398 sake of demonstration but you could 14558 09:18:04,718 --> 09:18:09,640 absolutely use any domain or top level 14559 09:18:07,398 --> 09:18:11,320 domain and I'm using doedu which is very 14560 09:18:09,640 --> 09:18:14,480 us-centric but this would absolutely 14561 09:18:11,320 --> 09:18:17,000 work exactly the same for any top level 14562 09:18:14,480 --> 09:18:19,078 domain all right let me go ahead now and 14563 09:18:17,000 --> 09:18:20,640 propose that we improve this regular 14564 09:18:19,078 --> 09:18:23,360 expression further because if I pull it 14565 09:18:20,640 --> 09:18:25,238 up again in V vs code here you'll see 14566 09:18:23,360 --> 09:18:27,398 that I'm being a little too tolerant 14567 09:18:25,238 --> 09:18:29,278 still it turns out that there are 14568 09:18:27,398 --> 09:18:31,718 certain requirements for someone's 14569 09:18:29,278 --> 09:18:33,598 username and domain name in an email 14570 09:18:31,718 --> 09:18:35,360 address there is an official standard in 14571 09:18:33,598 --> 09:18:37,878 the world for what an email address can 14572 09:18:35,360 --> 09:18:40,878 be and what characters can be in it and 14573 09:18:37,878 --> 09:18:42,718 this is way to accommodating of all the 14574 09:18:40,878 --> 09:18:45,160 characters in the world except for the 14575 09:18:42,718 --> 09:18:46,398 at symbol so let's actually narrow the 14576 09:18:45,160 --> 09:18:48,718 definition of what we're going to 14577 09:18:46,398 --> 09:18:51,320 tolerate in usernames and companies like 14578 09:18:48,718 --> 09:18:52,918 Gmail could certainly do this as well 14579 09:18:51,320 --> 09:18:55,398 suppose that it's not just that I want 14580 09:18:52,918 --> 09:18:58,040 to exclude at sign suppose that I only 14581 09:18:55,398 --> 09:19:00,122 want to allow for say characters that 14582 09:18:58,040 --> 09:19:02,558 normally appear in words like letters of 14583 09:19:00,122 --> 09:19:04,918 the alphabet A through Z be it uppercase 14584 09:19:02,558 --> 09:19:06,520 or lowercase maybe some numbers in heck 14585 09:19:04,918 --> 09:19:09,040 maybe even an underscore could be 14586 09:19:06,520 --> 09:19:11,278 allowed too well we can use this same 14587 09:19:09,040 --> 09:19:14,320 square bracket syntax to specify a set 14588 09:19:11,278 --> 09:19:17,480 of characters as follows I could do a b 14589 09:19:14,320 --> 09:19:18,560 c d e f g h i j oh my God this is going 14590 09:19:17,480 --> 09:19:21,160 to take forever I'm going to have to 14591 09:19:18,560 --> 09:19:23,276 type out all 26 letters of the alphabet 14592 09:19:21,160 --> 09:19:24,916 both lowercase and uppercase so let me 14593 09:19:23,276 --> 09:19:27,040 stop doing that there's a better way 14594 09:19:24,916 --> 09:19:30,000 already if you want to specify Within 14595 09:19:27,040 --> 09:19:32,680 These square brackets a range of letters 14596 09:19:30,000 --> 09:19:36,120 you can actually just do a hyphen if you 14597 09:19:32,680 --> 09:19:38,040 literally do a hyphen Z in these square 14598 09:19:36,120 --> 09:19:40,436 brackets the computer is going to know 14599 09:19:38,040 --> 09:19:42,960 you mean a thusy you do not need to type 14600 09:19:40,436 --> 09:19:45,276 26 letters of the alphabet if you want 14601 09:19:42,960 --> 09:19:47,596 to include uppercase letters as well you 14602 09:19:45,276 --> 09:19:50,320 just do the same no spaces no commas you 14603 09:19:47,596 --> 09:19:53,400 literally just keep typing a through 14604 09:19:50,320 --> 09:19:57,200 capital Z so I have little a hyphen 14605 09:19:53,400 --> 09:19:59,200 little Z big a hyphen big Z no spaces no 14606 09:19:57,200 --> 09:20:01,080 commas no separators you just keep 14607 09:19:59,200 --> 09:20:03,680 specifying those ranges if I 14608 09:20:01,080 --> 09:20:05,800 additionally want numbers I could do 0 1 14609 09:20:03,680 --> 09:20:08,680 2 3 4 NOP you don't need to type in all 14610 09:20:05,800 --> 09:20:11,200 10 decimal digits you can just say 0 14611 09:20:08,680 --> 09:20:13,320 through n using a hyphen as well and if 14612 09:20:11,200 --> 09:20:15,040 you now want to support underscores as 14613 09:20:13,320 --> 09:20:17,000 well which is pretty common in usernames 14614 09:20:15,040 --> 09:20:19,360 for email addresses you can literally 14615 09:20:17,000 --> 09:20:22,160 just type in underscore at the at the 14616 09:20:19,360 --> 09:20:24,840 end notice that all of these characters 14617 09:20:22,160 --> 09:20:27,160 are in inside of square brackets which 14618 09:20:24,840 --> 09:20:29,680 just again means here is a set of 14619 09:20:27,160 --> 09:20:32,520 characters that I want to allow I have 14620 09:20:29,680 --> 09:20:34,240 not used a carrot symbol at the 14621 09:20:32,520 --> 09:20:36,436 beginning of this whole thing because I 14622 09:20:34,240 --> 09:20:38,960 don't want to complement it complement 14623 09:20:36,436 --> 09:20:40,560 it with an E not complement it with an i 14624 09:20:38,960 --> 09:20:42,800 I want don't want to complement it by 14625 09:20:40,560 --> 09:20:45,480 making it the opposite I literally want 14626 09:20:42,800 --> 09:20:46,840 to accept only these characters I'm 14627 09:20:45,480 --> 09:20:49,640 going to go ahead and do the same thing 14628 09:20:46,840 --> 09:20:52,000 on the right if I want to require that 14629 09:20:49,640 --> 09:20:53,800 the domain name similarly come from this 14630 09:20:52,000 --> 09:20:55,596 set of characters which admittedly is a 14631 09:20:53,800 --> 09:20:57,400 little too narrow but it's familiar for 14632 09:20:55,596 --> 09:20:59,436 now so we'll keep it simple I'm going to 14633 09:20:57,400 --> 09:21:02,480 go ahead and paste that exact same set 14634 09:20:59,436 --> 09:21:05,720 of characters over there to the right 14635 09:21:02,480 --> 09:21:07,560 and so now it's much more restrictive 14636 09:21:05,720 --> 09:21:09,276 now I'm going to go ahead and run python 14637 09:21:07,560 --> 09:21:11,436 of validate I'm going to test my own 14638 09:21:09,276 --> 09:21:13,200 email address and we're still good I'm 14639 09:21:11,436 --> 09:21:16,840 going to clear my screen and run it once 14640 09:21:13,200 --> 09:21:19,916 more this time trying to break it let me 14641 09:21:16,840 --> 09:21:24,240 go ahead and do something like how about 14642 09:21:19,916 --> 09:21:27,040 davidor maen harvard. e do you enter but 14643 09:21:24,240 --> 09:21:29,756 that too is going to be valid but if I 14644 09:21:27,040 --> 09:21:34,080 do something completely wrong again like 14645 09:21:29,756 --> 09:21:36,160 ma harvard.edu that's still going to be 14646 09:21:34,080 --> 09:21:38,160 invalid why because my regular 14647 09:21:36,160 --> 09:21:40,276 expression currently only allows for a 14648 09:21:38,160 --> 09:21:42,520 single at in the middle because 14649 09:21:40,276 --> 09:21:45,360 everything to the left must be alpha 14650 09:21:42,520 --> 09:21:48,000 numeric alphabetical or numeric or an 14651 09:21:45,360 --> 09:21:51,596 underscore the same thing to the right 14652 09:21:48,000 --> 09:21:53,436 followed by the edu now honestly this is 14653 09:21:51,596 --> 09:21:55,480 a regular expression that you might be 14654 09:21:53,436 --> 09:21:57,800 in the habit of typing in the real world 14655 09:21:55,480 --> 09:21:59,800 as in as cryptic as this might look this 14656 09:21:57,800 --> 09:22:01,120 is the world of regular Expressions so 14657 09:21:59,800 --> 09:22:03,720 you'll get more comfortable with this 14658 09:22:01,120 --> 09:22:06,120 syntax over time but thankfully some of 14659 09:22:03,720 --> 09:22:08,756 these patterns are so common that there 14660 09:22:06,120 --> 09:22:11,080 are builtin shortcuts for representing 14661 09:22:08,756 --> 09:22:13,160 some of the same information that is to 14662 09:22:11,080 --> 09:22:15,000 say you don't have to constantly type 14663 09:22:13,160 --> 09:22:16,480 out all of the symbols that you want to 14664 09:22:15,000 --> 09:22:18,400 include because odds are some other 14665 09:22:16,480 --> 09:22:20,400 programmer has had the same problem so 14666 09:22:18,400 --> 09:22:22,200 built into regular Expressions 14667 09:22:20,400 --> 09:22:25,160 themselves are some additional patterns 14668 09:22:22,200 --> 09:22:28,000 you use and in fact I can go ahead and 14669 09:22:25,160 --> 09:22:30,240 get rid of this entire set a through z 14670 09:22:28,000 --> 09:22:32,360 lowercase A through Z uppercase 0 14671 09:22:30,240 --> 09:22:35,916 through 9 and an underscore and just 14672 09:22:32,360 --> 09:22:38,480 replace it with a single back slw back 14673 09:22:35,916 --> 09:22:41,200 slw in this case represents a word 14674 09:22:38,480 --> 09:22:45,320 character which is commonly known as a 14675 09:22:41,200 --> 09:22:47,080 alpha numeric symbol or the underscore 14676 09:22:45,320 --> 09:22:48,436 as well I'm going to do the same thing 14677 09:22:47,080 --> 09:22:50,720 over here I'm going to highlight the 14678 09:22:48,436 --> 09:22:52,756 entire set of square brackets delete it 14679 09:22:50,720 --> 09:22:55,320 and replace it with a single backs slash 14680 09:22:52,756 --> 09:22:56,520 W and now I feel like we're making 14681 09:22:55,320 --> 09:22:58,240 progress because even though it's 14682 09:22:56,520 --> 09:23:01,640 cryptic and what if it looked way 14683 09:22:58,240 --> 09:23:02,720 cryptic a little bit ago um and even 14684 09:23:01,640 --> 09:23:04,800 though it would have looked even more 14685 09:23:02,720 --> 09:23:06,596 cryptic a little bit ago now it's at 14686 09:23:04,800 --> 09:23:08,916 least starting to read a little more 14687 09:23:06,596 --> 09:23:10,360 friendly the carrot on the left means 14688 09:23:08,916 --> 09:23:14,040 start matching at the beginning of the 14689 09:23:10,360 --> 09:23:16,720 string back slw means any word character 14690 09:23:14,040 --> 09:23:19,040 the plus means one or more at symbol 14691 09:23:16,720 --> 09:23:21,560 literally then another word character 14692 09:23:19,040 --> 09:23:24,040 one or more then a literal dot then 14693 09:23:21,560 --> 09:23:26,320 literally EDU U and then match at the 14694 09:23:24,040 --> 09:23:27,916 very end of the string and that's it so 14695 09:23:26,320 --> 09:23:30,840 there's more of these two and we won't 14696 09:23:27,916 --> 09:23:33,480 use them all here but here is a partial 14697 09:23:30,840 --> 09:23:35,960 list of the patterns you can use within 14698 09:23:33,480 --> 09:23:38,596 a regular expression one you have back 14699 09:23:35,960 --> 09:23:41,800 SL D for any decimal digit decimal digit 14700 09:23:38,596 --> 09:23:44,160 meaning 0 through n commonly done here 14701 09:23:41,800 --> 09:23:46,400 too is if you want to do the opposite of 14702 09:23:44,160 --> 09:23:49,160 that the complement so to speak you can 14703 09:23:46,400 --> 09:23:51,480 do back slash capital D which is 14704 09:23:49,160 --> 09:23:54,480 anything that's not a decimal digit so 14705 09:23:51,480 --> 09:23:57,560 it might be letter and punctuation and 14706 09:23:54,480 --> 09:23:59,360 other symbols as well Meanwhile Back SLS 14707 09:23:57,560 --> 09:24:01,160 means Whit space characters like a 14708 09:23:59,360 --> 09:24:03,756 single hit of the space or maybe hitting 14709 09:24:01,160 --> 09:24:06,436 tab on the keyboard that's whites space 14710 09:24:03,756 --> 09:24:08,680 back slash capital S is the opposite or 14711 09:24:06,436 --> 09:24:11,400 complement of that anything that's not a 14712 09:24:08,680 --> 09:24:14,276 whit space character back slw we've seen 14713 09:24:11,400 --> 09:24:16,160 a word character as well as numbers and 14714 09:24:14,276 --> 09:24:18,120 the underscore and if you want the 14715 09:24:16,160 --> 09:24:20,756 complement or opposite of that you can 14716 09:24:18,120 --> 09:24:22,916 use back SL capital W to give you 14717 09:24:20,756 --> 09:24:24,520 everything but a word character 14718 09:24:22,916 --> 09:24:25,960 again these are just common patterns 14719 09:24:24,520 --> 09:24:28,120 that so many people were presumably 14720 09:24:25,960 --> 09:24:30,640 using in yester year that it's now baked 14721 09:24:28,120 --> 09:24:32,840 into the regular expression syntax so 14722 09:24:30,640 --> 09:24:36,276 that you can more succinctly express 14723 09:24:32,840 --> 09:24:39,520 your same ideas any questions then on 14724 09:24:36,276 --> 09:24:43,040 this approach here where we're now using 14725 09:24:39,520 --> 09:24:45,680 backw to represent my word 14726 09:24:43,040 --> 09:24:47,276 character uh so what I want to ask about 14727 09:24:45,680 --> 09:24:48,520 uh was the uh actually the previous 14728 09:24:47,276 --> 09:24:51,360 approach like the square bracket 14729 09:24:48,520 --> 09:24:53,680 approach could we accept like uh lists 14730 09:24:51,360 --> 09:24:55,840 in there yes we'll see this before long 14731 09:24:53,680 --> 09:24:59,596 but suppose you wanted to tolerate not 14732 09:24:55,840 --> 09:25:02,480 just edu but maybe edu or do you could 14733 09:24:59,596 --> 09:25:04,480 do this you could introduce parentheses 14734 09:25:02,480 --> 09:25:08,080 and then you can or those together I 14735 09:25:04,480 --> 09:25:11,436 could say Comm or edu I could also add 14736 09:25:08,080 --> 09:25:14,680 in something like in the US or gov or 14737 09:25:11,436 --> 09:25:16,400 net or anything else or org or the like 14738 09:25:14,680 --> 09:25:18,436 and each of the vertical bars here means 14739 09:25:16,400 --> 09:25:20,596 something special it means or and the 14740 09:25:18,436 --> 09:25:22,916 parentheses simply group things together 14741 09:25:20,596 --> 09:25:26,800 formally you have this syntax here 14742 09:25:22,916 --> 09:25:28,916 A or B A or vertical Bar B means a has 14743 09:25:26,800 --> 09:25:31,360 to match or B has to match where A and B 14744 09:25:28,916 --> 09:25:33,000 can be any other patterns you want in 14745 09:25:31,360 --> 09:25:35,480 parentheses you can group those things 14746 09:25:33,000 --> 09:25:37,916 together so just like math you can uh 14747 09:25:35,480 --> 09:25:39,840 combine ideas into one phrase and do 14748 09:25:37,916 --> 09:25:41,960 this thing or the other um and there's 14749 09:25:39,840 --> 09:25:43,756 other syntax as well that we'll soon see 14750 09:25:41,960 --> 09:25:46,840 other questions on these regular 14751 09:25:43,756 --> 09:25:49,840 expressions in this syntax here what if 14752 09:25:46,840 --> 09:25:51,800 we put spaces in the expression sure so 14753 09:25:49,840 --> 09:25:54,720 if you want spaces in there you can't 14754 09:25:51,800 --> 09:25:56,840 use back slw alone because that is only 14755 09:25:54,720 --> 09:25:59,596 a word character which is alphabetical 14756 09:25:56,840 --> 09:26:01,436 numerical or the underscore but you 14757 09:25:59,596 --> 09:26:03,480 could do this you could go back to this 14758 09:26:01,436 --> 09:26:05,480 approach whereby you use uh square 14759 09:26:03,480 --> 09:26:09,436 brackets and you could say A through Z 14760 09:26:05,480 --> 09:26:11,240 or a through z or 0 through n or 14761 09:26:09,436 --> 09:26:13,560 underscore or I'm going to hit the space 14762 09:26:11,240 --> 09:26:15,120 bar a single space you can put a literal 14763 09:26:13,560 --> 09:26:16,960 space inside of the square brackets 14764 09:26:15,120 --> 09:26:20,040 which will allow you then to detect a 14765 09:26:16,960 --> 09:26:22,756 space alternatively I could still use 14766 09:26:20,040 --> 09:26:25,000 back slw but I could combine it as 14767 09:26:22,756 --> 09:26:27,640 follows I could say give me a back slw 14768 09:26:25,000 --> 09:26:30,200 or a back SL s because recall that back 14769 09:26:27,640 --> 09:26:32,080 SLS is wh space so it's even more than a 14770 09:26:30,200 --> 09:26:33,960 single space it could be a tab but by 14771 09:26:32,080 --> 09:26:35,560 putting those things in parentheses now 14772 09:26:33,960 --> 09:26:38,240 you can match either the thing on the 14773 09:26:35,560 --> 09:26:40,360 left or the thing on the right one or 14774 09:26:38,240 --> 09:26:43,480 more times how about one other question 14775 09:26:40,360 --> 09:26:43,480 on these regular 14776 09:26:43,596 --> 09:26:49,840 Expressions perfect so I was going to 14777 09:26:45,560 --> 09:26:53,560 ask um does the back slw um include a 14778 09:26:49,840 --> 09:26:56,276 DOT uh because no nope it only includes 14779 09:26:53,560 --> 09:26:58,916 letters numbers uh and underscore that 14780 09:26:56,276 --> 09:27:01,276 is it and I was wondering you gave an 14781 09:26:58,916 --> 09:27:05,160 example at the beginning that had uh 14782 09:27:01,276 --> 09:27:08,360 spaces like this is my email so on so um 14783 09:27:05,160 --> 09:27:10,160 I don't think our current version even 14784 09:27:08,360 --> 09:27:12,200 quite quite a long while ago stopped 14785 09:27:10,160 --> 09:27:13,960 accepting it was that because of the 14786 09:27:12,200 --> 09:27:16,916 carrot uh 14787 09:27:13,960 --> 09:27:19,360 or because of something no the reason I 14788 09:27:16,916 --> 09:27:21,436 was handling spaces and other English 14789 09:27:19,360 --> 09:27:24,400 words when I typed out my email address 14790 09:27:21,436 --> 09:27:27,560 is mailing at doedu was because we were 14791 09:27:24,400 --> 09:27:31,040 using initially star or plus which is 14792 09:27:27,560 --> 09:27:33,480 any character uh and even after that we 14793 09:27:31,040 --> 09:27:36,276 said anything except the at sign which 14794 09:27:33,480 --> 09:27:39,320 includes spaces only once I started 14795 09:27:36,276 --> 09:27:41,680 using square brackets and a through z 14796 09:27:39,320 --> 09:27:43,560 and 0 through 9 and underscore did we 14797 09:27:41,680 --> 09:27:46,000 finally get to the point where we would 14798 09:27:43,560 --> 09:27:48,160 reject whitespace and in fact I can run 14799 09:27:46,000 --> 09:27:50,160 this here let me go into the current 14800 09:27:48,160 --> 09:27:52,520 version of my code in VSS code which is 14801 09:27:50,160 --> 09:27:55,160 using again the back slw's for word 14802 09:27:52,520 --> 09:27:57,360 characters let me run python of validate 14803 09:27:55,160 --> 09:28:00,916 and incorrectly type in something like 14804 09:27:57,360 --> 09:28:03,720 my email address is mailen harvard.edu 14805 09:28:00,916 --> 09:28:06,160 period which has spaces to the left of 14806 09:28:03,720 --> 09:28:08,480 my username and that is now invalid 14807 09:28:06,160 --> 09:28:10,720 because space is not a word character 14808 09:28:08,480 --> 09:28:12,520 yorgo notes too that technically I'm not 14809 09:28:10,720 --> 09:28:14,240 allowing dots and some of you might be 14810 09:28:12,520 --> 09:28:16,720 thinking wait a minute my gmail address 14811 09:28:14,240 --> 09:28:19,560 has a dot in it that's something we're 14812 09:28:16,720 --> 09:28:22,200 going to still have to fix a back slw is 14813 09:28:19,560 --> 09:28:24,560 not the end all here it's just allowing 14814 09:28:22,200 --> 09:28:27,240 us to express our previous solution a 14815 09:28:24,560 --> 09:28:29,080 little more succinctly now one thing 14816 09:28:27,240 --> 09:28:31,480 we're still not handling quite properly 14817 09:28:29,080 --> 09:28:33,840 is uppercase versus lowercase the back 14818 09:28:31,480 --> 09:28:35,720 slw technically does handle lowercase 14819 09:28:33,840 --> 09:28:38,400 letters and uppercase because it's the 14820 09:28:35,720 --> 09:28:40,720 exact same thing as that set from before 14821 09:28:38,400 --> 09:28:43,520 which had little a through little Z and 14822 09:28:40,720 --> 09:28:45,320 big a through big Z but watch this let 14823 09:28:43,520 --> 09:28:47,520 me go ahead in my current form run 14824 09:28:45,320 --> 09:28:49,840 python to validate dopy and just because 14825 09:28:47,520 --> 09:28:53,160 my caps slot key is down maen 14826 09:28:49,840 --> 09:28:55,560 harvard.edu shouting my email address 14827 09:28:53,160 --> 09:28:57,160 it's going to be okay in terms of the ma 14828 09:28:55,560 --> 09:28:59,360 it's going to be okay in terms of the 14829 09:28:57,160 --> 09:29:02,276 Harvard because those are matching the 14830 09:28:59,360 --> 09:29:05,560 back slw which does include lowercase 14831 09:29:02,276 --> 09:29:08,360 and uppercase but I'm about to see 14832 09:29:05,560 --> 09:29:11,120 invalid why why is mailing at 14833 09:29:08,360 --> 09:29:13,916 harvard.edu 14834 09:29:11,120 --> 09:29:15,436 invalid when it's in all caps here even 14835 09:29:13,916 --> 09:29:19,276 though I'm using 14836 09:29:15,436 --> 09:29:22,200 backw yeah so you are asking for the 14837 09:29:19,276 --> 09:29:25,120 domain. edu in lowercase and you're 14838 09:29:22,200 --> 09:29:27,360 typing it in an uppercase exactly I'm 14839 09:29:25,120 --> 09:29:29,320 typing in my email address in all 14840 09:29:27,360 --> 09:29:31,560 uppercase but I'm looking for literally 14841 09:29:29,320 --> 09:29:33,160 edu and as I see you with airpods and so 14842 09:29:31,560 --> 09:29:34,720 many of you with headphones I apologize 14843 09:29:33,160 --> 09:29:36,640 for yelling into my microphone just now 14844 09:29:34,720 --> 09:29:39,756 to make this point but let's see if we 14845 09:29:36,640 --> 09:29:43,000 can't fix that well if my pattern on 14846 09:29:39,756 --> 09:29:44,960 line five is expecting it to be 14847 09:29:43,000 --> 09:29:46,640 lowercase there's actually a few ways I 14848 09:29:44,960 --> 09:29:48,840 can solve this one would be something 14849 09:29:46,640 --> 09:29:51,200 we've seen before I could just force the 14850 09:29:48,840 --> 09:29:53,560 user's input to all lowercase and I 14851 09:29:51,200 --> 09:29:55,520 could put on the end of my first line 14852 09:29:53,560 --> 09:29:57,840 lower and actually force it all to 14853 09:29:55,520 --> 09:29:59,756 lowercase alternatively I could do that 14854 09:29:57,840 --> 09:30:01,916 a little later instead of passing an 14855 09:29:59,756 --> 09:30:03,800 email I could pass in the lowercase 14856 09:30:01,916 --> 09:30:05,916 version of email because email addresses 14857 09:30:03,800 --> 09:30:07,560 should in fact be case insensitive so 14858 09:30:05,916 --> 09:30:09,720 that would work too but there's another 14859 09:30:07,560 --> 09:30:12,596 mechanism here which is worth seeing it 14860 09:30:09,720 --> 09:30:16,000 turns out that that function before 14861 09:30:12,596 --> 09:30:18,080 called re. search supports recall a 14862 09:30:16,000 --> 09:30:20,200 third argument as well these so-called 14863 09:30:18,080 --> 09:30:21,640 flags and flags are configuration 14864 09:30:20,200 --> 09:30:23,480 options typically to a function that 14865 09:30:21,640 --> 09:30:25,436 allow you to configure it a little 14866 09:30:23,480 --> 09:30:28,480 differently and how might I go about 14867 09:30:25,436 --> 09:30:30,640 configuring this call to re. search a 14868 09:30:28,480 --> 09:30:32,916 little bit differently in so far as I'm 14869 09:30:30,640 --> 09:30:34,756 currently only passing in two arguments 14870 09:30:32,916 --> 09:30:37,000 well it turns out that some of the flags 14871 09:30:34,756 --> 09:30:39,360 you can pass into this function are 14872 09:30:37,000 --> 09:30:43,160 these it turns out that the regular 14873 09:30:39,360 --> 09:30:45,400 expression library in Python AKA re 14874 09:30:43,160 --> 09:30:47,320 comes with a few built-in variables so 14875 09:30:45,400 --> 09:30:51,120 to speak things that you can think of as 14876 09:30:47,320 --> 09:30:53,916 constants that have meaning to re. 14877 09:30:51,120 --> 09:30:56,800 search and they do so as follows if you 14878 09:30:53,916 --> 09:30:58,916 pass in as a flag re. ignore case what 14879 09:30:56,800 --> 09:31:00,680 re. search is going to do is ignore the 14880 09:30:58,916 --> 09:31:02,200 case of the user's input it can be 14881 09:31:00,680 --> 09:31:04,200 uppercase lower case a combination 14882 09:31:02,200 --> 09:31:06,436 thereof the case is going to be ignored 14883 09:31:04,200 --> 09:31:07,680 it will be treated case insensitively 14884 09:31:06,436 --> 09:31:09,720 and you can do other things too that we 14885 09:31:07,680 --> 09:31:11,520 won't do here but if you want to handle 14886 09:31:09,720 --> 09:31:13,276 the user's input that maybe spans 14887 09:31:11,520 --> 09:31:15,276 multiple lines maybe they didn't just 14888 09:31:13,276 --> 09:31:17,360 type in an email address but an entire 14889 09:31:15,276 --> 09:31:19,120 paragraph of text and you want to match 14890 09:31:17,360 --> 09:31:22,000 different lines of that text that is 14891 09:31:19,120 --> 09:31:24,800 multiple lines another flag is for re 14892 09:31:22,000 --> 09:31:27,080 multi-line for just that or re doall 14893 09:31:24,800 --> 09:31:30,160 whereby you can con uh you can configure 14894 09:31:27,080 --> 09:31:32,520 the dot to rep to recognize not just any 14895 09:31:30,160 --> 09:31:35,000 character except new lines but any 14896 09:31:32,520 --> 09:31:36,756 character plus new lines as well but for 14897 09:31:35,000 --> 09:31:38,840 now let me go ahead and just make use of 14898 09:31:36,756 --> 09:31:42,120 this first one let me pass in a third 14899 09:31:38,840 --> 09:31:46,276 argument to re. search which is 14900 09:31:42,120 --> 09:31:47,960 re. uh ignore case let me now reun the 14901 09:31:46,276 --> 09:31:50,276 program without clearing my screen 14902 09:31:47,960 --> 09:31:52,680 python of validate dopy let me type in 14903 09:31:50,276 --> 09:31:56,120 again in all caps effective ly shouting 14904 09:31:52,680 --> 09:31:58,560 ma harvard.edu enter and now it's 14905 09:31:56,120 --> 09:32:00,480 considered valid because I'm telling re. 14906 09:31:58,560 --> 09:32:02,800 search specifically to ignore the case 14907 09:32:00,480 --> 09:32:04,436 of the input and that two here is fine 14908 09:32:02,800 --> 09:32:06,560 and why might I do this approach rather 14909 09:32:04,436 --> 09:32:08,560 than call do lower in one of those other 14910 09:32:06,560 --> 09:32:10,360 locations if I don't actually want to 14911 09:32:08,560 --> 09:32:12,436 change the user's input for whatever 14912 09:32:10,360 --> 09:32:15,160 reason I can still treat it case 14913 09:32:12,436 --> 09:32:18,360 insensitively without actually changing 14914 09:32:15,160 --> 09:32:20,276 the value of that variable itself are 14915 09:32:18,360 --> 09:32:22,400 any final questions now on this 14916 09:32:20,276 --> 09:32:26,160 validation of email 14917 09:32:22,400 --> 09:32:29,520 addresses uh so the pattern is a string 14918 09:32:26,160 --> 09:32:31,960 right M uh can we use an F string you 14919 09:32:29,520 --> 09:32:33,756 can you yes you can use an F string so 14920 09:32:31,960 --> 09:32:36,120 that you could plug in for instance the 14921 09:32:33,756 --> 09:32:38,840 value of a variable and pass it into the 14922 09:32:36,120 --> 09:32:41,320 function other questions on this access 14923 09:32:38,840 --> 09:32:43,720 W character could we take it as an input 14924 09:32:41,320 --> 09:32:45,120 from the user technically yes that's not 14925 09:32:43,720 --> 09:32:46,960 a problem we're trying to solve right 14926 09:32:45,120 --> 09:32:48,720 now we want the user to provide literal 14927 09:32:46,960 --> 09:32:51,160 input like their email address not 14928 09:32:48,720 --> 09:32:52,840 necessarily a regular expression but you 14929 09:32:51,160 --> 09:32:54,596 could imagine building software that 14930 09:32:52,840 --> 09:32:56,320 asks the user especially if they're more 14931 09:32:54,596 --> 09:32:58,520 advanced users to type in a regular 14932 09:32:56,320 --> 09:33:00,080 expression for some reason to validate 14933 09:32:58,520 --> 09:33:01,960 something else against that and in fact 14934 09:33:00,080 --> 09:33:03,800 that's what Google's doing if you play 14935 09:33:01,960 --> 09:33:06,240 around with Google forms and create a 14936 09:33:03,800 --> 09:33:09,160 form with response validation and select 14937 09:33:06,240 --> 09:33:10,880 regular expression Google lets you and I 14938 09:33:09,160 --> 09:33:12,320 type in our own regular Expressions 14939 09:33:10,880 --> 09:33:14,360 would be a per which would be a perfect 14940 09:33:12,320 --> 09:33:16,720 example of that all right well let me 14941 09:33:14,360 --> 09:33:19,880 propose that we try to solve one other 14942 09:33:16,720 --> 09:33:22,400 problem here whereby if I go into the 14943 09:33:19,880 --> 09:33:24,480 same version as before which is now 14944 09:33:22,400 --> 09:33:26,320 ignoring case but I type in one of my 14945 09:33:24,480 --> 09:33:28,640 other email addresses let me go ahead 14946 09:33:26,320 --> 09:33:30,400 and run python of validate dopy and this 14947 09:33:28,640 --> 09:33:32,880 time let me type in not mailen 14948 09:33:30,400 --> 09:33:34,436 harvard.edu which I use primarily but my 14949 09:33:32,880 --> 09:33:37,276 another email address of mine maen 14950 09:33:34,436 --> 09:33:39,756 cs50.h harvard.edu which forwards to the 14951 09:33:37,276 --> 09:33:43,200 same let me go ahead and hit enter now 14952 09:33:39,756 --> 09:33:45,200 and huh invalid even though I'm pretty 14953 09:33:43,200 --> 09:33:47,000 sure that is in fact my email address 14954 09:33:45,200 --> 09:33:51,240 well let's put our finger on the reason 14955 09:33:47,000 --> 09:33:54,756 why why at the moment is mail at cs50.h 14956 09:33:51,240 --> 09:33:57,320 harvard. edu being considered invalid 14957 09:33:54,756 --> 09:34:00,840 even though I'm pretty sure I send and 14958 09:33:57,320 --> 09:34:00,840 receive email from that address 14959 09:34:01,520 --> 09:34:10,640 too why might that be because there is a 14960 09:34:05,400 --> 09:34:14,360 DOT that has come after the ad symbol 14961 09:34:10,640 --> 09:34:16,160 exactly there's a DOT after my cs50 and 14962 09:34:14,360 --> 09:34:18,520 I'm not expecting any dots there I'm 14963 09:34:16,160 --> 09:34:22,116 expecting only again word characters 14964 09:34:18,520 --> 09:34:24,436 which is a through z 0-9 and under score 14965 09:34:22,116 --> 09:34:26,116 so I'm going to have to retool here but 14966 09:34:24,436 --> 09:34:28,436 how could I go about doing this well it 14967 09:34:26,116 --> 09:34:29,960 turns out theoretically there could be 14968 09:34:28,436 --> 09:34:31,840 other email addresses even though they'd 14969 09:34:29,960 --> 09:34:34,840 be getting a little excessively long for 14970 09:34:31,840 --> 09:34:36,680 instance mailin at something. cs50.h 14971 09:34:34,840 --> 09:34:38,960 harvard.edu which is not technically 14972 09:34:36,680 --> 09:34:40,880 exist but it could you can have of 14973 09:34:38,960 --> 09:34:42,720 course multiple dots in a domain name 14974 09:34:40,880 --> 09:34:44,960 like we see here wouldn't it be nice if 14975 09:34:42,720 --> 09:34:47,240 we could handle that as well well let me 14976 09:34:44,960 --> 09:34:49,916 propose that we modify my regular 14977 09:34:47,240 --> 09:34:52,680 expression as follows it turns out that 14978 09:34:49,916 --> 09:34:55,436 you can group ideas together and you can 14979 09:34:52,680 --> 09:34:58,436 not only ask whether or not this pattern 14980 09:34:55,436 --> 09:35:01,720 matches or this one using syntax like a 14981 09:34:58,436 --> 09:35:04,080 vertical Bar B which means either A or B 14982 09:35:01,720 --> 09:35:06,116 you can also group things together and 14983 09:35:04,080 --> 09:35:08,276 then apply some other operator to them 14984 09:35:06,116 --> 09:35:10,360 as well in fact let me go back to VSS 14985 09:35:08,276 --> 09:35:13,916 code here and let me propose that if I 14986 09:35:10,360 --> 09:35:16,916 want to tolerate a subdomain like cs50 14987 09:35:13,916 --> 09:35:19,040 that may or may not be there let me go 14988 09:35:16,916 --> 09:35:20,960 ahead and change it as follows I could 14989 09:35:19,040 --> 09:35:23,480 naively do this if I want to support 14990 09:35:20,960 --> 09:35:26,436 subdomain I could say well let's allow 14991 09:35:23,480 --> 09:35:28,960 for otherw characters plus and then a 14992 09:35:26,436 --> 09:35:30,916 literal Dot and notice I'll highlight in 14993 09:35:28,960 --> 09:35:33,000 blue here what I've just added 14994 09:35:30,916 --> 09:35:35,960 everything else is the same but I'm now 14995 09:35:33,000 --> 09:35:38,240 adding room for another sequence of one 14996 09:35:35,960 --> 09:35:42,480 or more word characters and then a 14997 09:35:38,240 --> 09:35:44,640 literal dot so this now I think if I 14998 09:35:42,480 --> 09:35:48,596 rerun python of validate dopy will work 14999 09:35:44,640 --> 09:35:50,640 for Ma at cs50.h harvard.edu enter 15000 09:35:48,596 --> 09:35:53,200 unfortunately does anyone see where this 15001 09:35:50,640 --> 09:35:55,400 is going let me rerun python of validate 15002 09:35:53,200 --> 09:35:57,400 dopy and type in as I keep doing maen 15003 09:35:55,400 --> 09:36:00,320 harvard.edu which up until now has kept 15004 09:35:57,400 --> 09:36:04,240 working despite all of my changes but 15005 09:36:00,320 --> 09:36:07,116 now finally I've broken my own email 15006 09:36:04,240 --> 09:36:08,680 address so logically what's the solution 15007 09:36:07,116 --> 09:36:10,436 here well there's a bunch of ways we 15008 09:36:08,680 --> 09:36:12,400 could solve this I could maybe start 15009 09:36:10,436 --> 09:36:14,720 using two regular expressions and 15010 09:36:12,400 --> 09:36:19,680 support you uh email addresses of the 15011 09:36:14,720 --> 09:36:23,116 form username at domain. TLD or username 15012 09:36:19,680 --> 09:36:25,960 at subdomain dodoma TLD where TLD just 15013 09:36:23,116 --> 09:36:27,680 means top level domain like edu or I 15014 09:36:25,960 --> 09:36:30,040 could maybe just modify this one because 15015 09:36:27,680 --> 09:36:31,756 I'd prefer not to have like two uh 15016 09:36:30,040 --> 09:36:35,040 regular expressions or one that's twice 15017 09:36:31,756 --> 09:36:37,680 as big why don't I just specify to re. 15018 09:36:35,040 --> 09:36:40,480 search that part of this pattern is 15019 09:36:37,680 --> 09:36:43,276 optional what was the symbol we saw 15020 09:36:40,480 --> 09:36:46,240 earlier that allows you to specify that 15021 09:36:43,276 --> 09:36:49,116 the thing before it is technically 15022 09:36:46,240 --> 09:36:51,720 optional the straight bar we are using 15023 09:36:49,116 --> 09:36:53,756 the Straight bar as a 15024 09:36:51,720 --> 09:36:56,080 optional make the opt the argument 15025 09:36:53,756 --> 09:36:58,200 optional so we could we could use a 15026 09:36:56,080 --> 09:37:00,436 vertical bar and some parentheses and 15027 09:36:58,200 --> 09:37:02,360 say either there's something here or 15028 09:37:00,436 --> 09:37:03,880 there's nothing we could do that in 15029 09:37:02,360 --> 09:37:06,916 parenthesis but I think there's actually 15030 09:37:03,880 --> 09:37:09,880 an even easier way uh actually is a 15031 09:37:06,916 --> 09:37:12,160 question mark indeed question mark think 15032 09:37:09,880 --> 09:37:14,916 back to this summary here of our first 15033 09:37:12,160 --> 09:37:17,160 set of symbols whereby we had not just 15034 09:37:14,916 --> 09:37:19,200 Dot and star and plus but also a 15035 09:37:17,160 --> 09:37:22,200 question mark which means literally zero 15036 09:37:19,200 --> 09:37:25,116 or one repetitions which affect ly means 15037 09:37:22,200 --> 09:37:28,436 optional it's either there one or it's 15038 09:37:25,116 --> 09:37:30,560 not zero now how can I translate to that 15039 09:37:28,436 --> 09:37:33,560 to this code here well let me go ahead 15040 09:37:30,560 --> 09:37:35,960 and Surround this part of my pattern 15041 09:37:33,560 --> 09:37:37,840 with parentheses which doesn't mean I 15042 09:37:35,960 --> 09:37:40,080 want literally a parenthesis in the 15043 09:37:37,840 --> 09:37:42,520 user's input I just want to group these 15044 09:37:40,080 --> 09:37:44,240 characters together and in fact this now 15045 09:37:42,520 --> 09:37:46,040 will still work I've only added 15046 09:37:44,240 --> 09:37:48,240 parentheses around the new part for the 15047 09:37:46,040 --> 09:37:51,560 subdomain let me run python of validate 15048 09:37:48,240 --> 09:37:54,160 dopy let me run maen cs50.h harvard.edu 15049 09:37:51,560 --> 09:37:56,680 enter that's still valid but to be clear 15050 09:37:54,160 --> 09:38:00,720 if I rerun it again for ma harvard.edu 15051 09:37:56,680 --> 09:38:03,240 that is still invalid but not if I go in 15052 09:38:00,720 --> 09:38:06,360 here and say after the parentheses which 15053 09:38:03,240 --> 09:38:09,360 now is one logical unit it's one big 15054 09:38:06,360 --> 09:38:12,400 group of ideas together I add a single 15055 09:38:09,360 --> 09:38:14,916 question mark there this will now tell 15056 09:38:12,400 --> 09:38:18,160 re. search that that whole thing in 15057 09:38:14,916 --> 09:38:21,480 parentheses can either be there once or 15058 09:38:18,160 --> 09:38:23,436 be there not at all zero times so what 15059 09:38:21,480 --> 09:38:25,360 does this translate into when I run it 15060 09:38:23,436 --> 09:38:28,560 well let me go ahead and rerun it with 15061 09:38:25,360 --> 09:38:31,596 maen cs50.h harvard.edu so that the 15062 09:38:28,560 --> 09:38:33,320 subdomain is there that works as before 15063 09:38:31,596 --> 09:38:35,400 let me clear my screen and run it again 15064 09:38:33,320 --> 09:38:37,596 python of validate dopy with ma 15065 09:38:35,400 --> 09:38:40,560 harvard.edu which used to work then 15066 09:38:37,596 --> 09:38:44,756 broke is are we back in business now we 15067 09:38:40,560 --> 09:38:46,720 are that's now valid again questions now 15068 09:38:44,756 --> 09:38:49,116 on this approach where we've use not 15069 09:38:46,720 --> 09:38:51,840 just the question mark But the 15070 09:38:49,116 --> 09:38:54,680 parenthesis as well okay yeah you works 15071 09:38:51,840 --> 09:38:57,640 for zero or one repetition what if you 15072 09:38:54,680 --> 09:39:01,200 have more what if you have more that's 15073 09:38:57,640 --> 09:39:03,800 okay that's where you could do star star 15074 09:39:01,200 --> 09:39:07,000 is zero or more which gives you all the 15075 09:39:03,800 --> 09:39:09,596 flexibility in the world yeah so I was 15076 09:39:07,000 --> 09:39:12,640 just asking that uh uh with question 15077 09:39:09,596 --> 09:39:14,840 mark there's only one repetition allow 15078 09:39:12,640 --> 09:39:18,240 it means zero or one repetition so it's 15079 09:39:14,840 --> 09:39:20,200 either not there or it is there and so 15080 09:39:18,240 --> 09:39:21,880 that's why this pattern now if I go back 15081 09:39:20,200 --> 09:39:23,916 to my code even though again it 15082 09:39:21,880 --> 09:39:26,436 admittedly looks cryptic let me 15083 09:39:23,916 --> 09:39:29,000 highlight everything after the at sign 15084 09:39:26,436 --> 09:39:31,276 and before the dollar sign this now 15085 09:39:29,000 --> 09:39:34,960 represents a domain name like 15086 09:39:31,276 --> 09:39:37,680 harvard.edu or a subdomain within the 15087 09:39:34,960 --> 09:39:40,720 domain name why well this part to the 15088 09:39:37,680 --> 09:39:43,560 right is the same as always backw plus 15089 09:39:40,720 --> 09:39:47,200 means something like Harvard or Yale 15090 09:39:43,560 --> 09:39:49,800 back.edu means literally doedu so the 15091 09:39:47,200 --> 09:39:51,840 new part is this in parentheses I have 15092 09:39:49,800 --> 09:39:55,160 another set of back 15093 09:39:51,840 --> 09:39:57,680 w+ back SL do now but it's all in 15094 09:39:55,160 --> 09:39:59,520 parentheses I'm now having a question 15095 09:39:57,680 --> 09:40:02,000 mark right after that which means that 15096 09:39:59,520 --> 09:40:04,320 whole thing in parenthesis either can be 15097 09:40:02,000 --> 09:40:06,840 there or it can't be there it's either 15098 09:40:04,320 --> 09:40:09,000 of those that are acceptable so a 15099 09:40:06,840 --> 09:40:11,200 question mark effectively make something 15100 09:40:09,000 --> 09:40:13,040 optional it would not be correct to 15101 09:40:11,200 --> 09:40:14,960 remove the parentheses because what 15102 09:40:13,040 --> 09:40:17,436 would this mean if I remove the 15103 09:40:14,960 --> 09:40:20,080 parentheses that would mean that only 15104 09:40:17,436 --> 09:40:22,520 this dot is optional which isn't really 15105 09:40:20,080 --> 09:40:25,400 what we want to express I want the 15106 09:40:22,520 --> 09:40:28,080 subdomain like cs50 and the additional 15107 09:40:25,400 --> 09:40:31,160 dot to be what's there or not there how 15108 09:40:28,080 --> 09:40:33,756 about one other question on Rex is here 15109 09:40:31,160 --> 09:40:35,720 can they use this for the usernames 15110 09:40:33,756 --> 09:40:36,880 absolutely we still have other problems 15111 09:40:35,720 --> 09:40:39,276 right we're not solving all of the 15112 09:40:36,880 --> 09:40:41,596 problems today just yet but absolutely 15113 09:40:39,276 --> 09:40:43,800 right now we are not letting you have a 15114 09:40:41,596 --> 09:40:45,436 period in your username and again some 15115 09:40:43,800 --> 09:40:47,000 of you with Gmail accounts or other 15116 09:40:45,436 --> 09:40:48,360 accounts you probably have not just 15117 09:40:47,000 --> 09:40:50,840 underscores numbers and letters you 15118 09:40:48,360 --> 09:40:53,680 might have periods too well we could fix 15119 09:40:50,840 --> 09:40:55,400 that not using question mark here per se 15120 09:40:53,680 --> 09:40:58,400 but now that we have these parentheses 15121 09:40:55,400 --> 09:41:01,480 at our disposal what I could do is this 15122 09:40:58,400 --> 09:41:03,756 I could use parentheses to surround the 15123 09:41:01,480 --> 09:41:06,000 back slw to say any word character which 15124 09:41:03,756 --> 09:41:08,436 is the same thing again as a letter or a 15125 09:41:06,000 --> 09:41:11,520 number or an underscore but I could also 15126 09:41:08,436 --> 09:41:14,520 or in using a vertical bar something 15127 09:41:11,520 --> 09:41:16,596 else like a literal dot now a literal 15128 09:41:14,520 --> 09:41:18,160 dot needs to be escaped otherwise it 15129 09:41:16,596 --> 09:41:20,756 represents any character which would be 15130 09:41:18,160 --> 09:41:22,720 a regression a step back but now notice 15131 09:41:20,756 --> 09:41:25,756 what I've done in parentheses I'm 15132 09:41:22,720 --> 09:41:27,840 telling re. search that those first few 15133 09:41:25,756 --> 09:41:30,560 characters in your email address that is 15134 09:41:27,840 --> 09:41:33,276 your username has to be a word character 15135 09:41:30,560 --> 09:41:36,116 Like A through Z uppercase or lowercase 15136 09:41:33,276 --> 09:41:38,320 or 0 through n or an underscore or a 15137 09:41:36,116 --> 09:41:40,720 literal dot we could do this differently 15138 09:41:38,320 --> 09:41:43,400 too I could get rid of the parentheses 15139 09:41:40,720 --> 09:41:46,000 and the or and I could just use a set of 15140 09:41:43,400 --> 09:41:49,916 characters I could again manually say a 15141 09:41:46,000 --> 09:41:52,276 through z a through z 0 through 9 15142 09:41:49,916 --> 09:41:55,240 underscore and then I could do a literal 15143 09:41:52,276 --> 09:41:56,276 dot with a back slash period and now I 15144 09:41:55,240 --> 09:41:57,960 technically don't even need the 15145 09:41:56,276 --> 09:41:59,720 uppercase because I'm already telling 15146 09:41:57,960 --> 09:42:01,880 the computer to ignore case I can just 15147 09:41:59,720 --> 09:42:03,436 pick one or the other which one is 15148 09:42:01,880 --> 09:42:05,080 better is really up to you whichever one 15149 09:42:03,436 --> 09:42:07,916 you think is more readable would 15150 09:42:05,080 --> 09:42:10,480 generally be the better design all right 15151 09:42:07,916 --> 09:42:14,840 let me propose that I rewind this in 15152 09:42:10,480 --> 09:42:16,720 time to where we left off which was here 15153 09:42:14,840 --> 09:42:19,000 and let me propose that there are indeed 15154 09:42:16,720 --> 09:42:21,200 still limitations of this solution not 15155 09:42:19,000 --> 09:42:22,680 just with the username not just with the 15156 09:42:21,200 --> 09:42:25,000 domain name we're still being a little 15157 09:42:22,680 --> 09:42:27,000 too restrictive so would you like to see 15158 09:42:25,000 --> 09:42:29,480 the official regular expression that at 15159 09:42:27,000 --> 09:42:31,400 least browsers use nowadays whenever you 15160 09:42:29,480 --> 09:42:33,916 type in an email address to a web form 15161 09:42:31,400 --> 09:42:35,756 and the web form the browser tells you 15162 09:42:33,916 --> 09:42:40,680 yes or no your email address is 15163 09:42:35,756 --> 09:42:43,640 syntactically valid ready ready here is 15164 09:42:40,680 --> 09:42:45,756 and this isn't even officially the right 15165 09:42:43,640 --> 09:42:47,560 regular expression it's a simplified 15166 09:42:45,756 --> 09:42:50,200 version that browsers use because it 15167 09:42:47,560 --> 09:42:54,000 catches most mistakes but not all here 15168 09:42:50,200 --> 09:42:56,720 we go this is the regular expression for 15169 09:42:54,000 --> 09:42:59,800 a valid email address at least as 15170 09:42:56,720 --> 09:43:02,916 browsers nowadays Implement them now 15171 09:42:59,800 --> 09:43:05,040 it's crazy cryptic at first glance but 15172 09:43:02,916 --> 09:43:07,400 not and it's wrapping onto many lines 15173 09:43:05,040 --> 09:43:10,360 but it's just one pattern but just 15174 09:43:07,400 --> 09:43:12,720 notice the now familiar symbols there is 15175 09:43:10,360 --> 09:43:15,400 the carrot symbol at the very top there 15176 09:43:12,720 --> 09:43:17,360 is the dollar sign at the very end there 15177 09:43:15,400 --> 09:43:19,160 is a square bracket over here and then 15178 09:43:17,360 --> 09:43:21,240 some of these ranges plus other 15179 09:43:19,160 --> 09:43:23,116 characters turns out you don't normally 15180 09:43:21,240 --> 09:43:24,640 see these characters in email addresses 15181 09:43:23,116 --> 09:43:26,720 it looks like you're swearing at someone 15182 09:43:24,640 --> 09:43:28,680 in their username but they're valid 15183 09:43:26,720 --> 09:43:30,160 characters they're valid officially that 15184 09:43:28,680 --> 09:43:32,640 doesn't mean that Gmail is going to 15185 09:43:30,160 --> 09:43:34,360 allow you to put dollar signs and other 15186 09:43:32,640 --> 09:43:36,720 punctuation in your username but 15187 09:43:34,360 --> 09:43:38,756 officially some servers might allow that 15188 09:43:36,720 --> 09:43:40,916 so if you really want to validate a 15189 09:43:38,756 --> 09:43:43,276 user's email address you would actually 15190 09:43:40,916 --> 09:43:45,916 come up with or copy paste something 15191 09:43:43,276 --> 09:43:47,720 like this but honestly this looks so 15192 09:43:45,916 --> 09:43:49,880 cryptic and if you were to type it out 15193 09:43:47,720 --> 09:43:52,116 manually you are so likely to make a 15194 09:43:49,880 --> 09:43:55,116 mistake what's the better solution here 15195 09:43:52,116 --> 09:43:57,756 instead this is where P past week's 15196 09:43:55,116 --> 09:44:00,240 libraries are your friend surely someone 15197 09:43:57,756 --> 09:44:02,560 else on the internet a programmer more 15198 09:44:00,240 --> 09:44:05,360 experienced than you even has come up 15199 09:44:02,560 --> 09:44:07,276 with code that validates email addresses 15200 09:44:05,360 --> 09:44:08,880 properly using this regular expression 15201 09:44:07,276 --> 09:44:10,800 or even something more sophisticated 15202 09:44:08,880 --> 09:44:13,276 than that so generally if the problem at 15203 09:44:10,800 --> 09:44:15,756 hand is to validate input that is pretty 15204 09:44:13,276 --> 09:44:17,116 conventional an email address a URL 15205 09:44:15,756 --> 09:44:19,560 something where there's an official 15206 09:44:17,116 --> 09:44:22,320 definition that's independent of you 15207 09:44:19,560 --> 09:44:24,800 yourself find a the popular library that 15208 09:44:22,320 --> 09:44:26,960 you're comfortable using and use it in 15209 09:44:24,800 --> 09:44:29,436 your code to validate email addresses 15210 09:44:26,960 --> 09:44:31,596 this is not a wheel necessarily that you 15211 09:44:29,436 --> 09:44:33,640 yourself should invent we've used email 15212 09:44:31,596 --> 09:44:35,680 addresses though to iteratively start 15213 09:44:33,640 --> 09:44:37,560 from something simple too simple and 15214 09:44:35,680 --> 09:44:39,080 build on top of that so you could 15215 09:44:37,560 --> 09:44:40,480 certainly imagine using regular 15216 09:44:39,080 --> 09:44:42,596 Expressions still to validate things 15217 09:44:40,480 --> 09:44:45,116 that aren't email addresses but are data 15218 09:44:42,596 --> 09:44:47,320 that are important to you so we at least 15219 09:44:45,116 --> 09:44:48,880 now have these building blocks now 15220 09:44:47,320 --> 09:44:50,240 besides the regular Expressions 15221 09:44:48,880 --> 09:44:52,756 themselves it turns out there's other 15222 09:44:50,240 --> 09:44:54,640 functions and Python's re library for 15223 09:44:52,756 --> 09:44:56,480 regular Expressions among them is this 15224 09:44:54,640 --> 09:44:58,960 function here re. match which is 15225 09:44:56,480 --> 09:45:00,680 actually very similar to re. search 15226 09:44:58,960 --> 09:45:02,276 except you don't have to specify the 15227 09:45:00,680 --> 09:45:04,000 carrot symbol at the very beginning of 15228 09:45:02,276 --> 09:45:06,960 your Rex if you want a match from the 15229 09:45:04,000 --> 09:45:08,960 start of a string re. match by Design 15230 09:45:06,960 --> 09:45:10,840 will automatically start matching from 15231 09:45:08,960 --> 09:45:13,240 the start of the string for you similar 15232 09:45:10,840 --> 09:45:14,960 in spirit is re. full match which does 15233 09:45:13,240 --> 09:45:16,436 the same thing but not only matches at 15234 09:45:14,960 --> 09:45:18,276 the start of the string but the end of 15235 09:45:16,436 --> 09:45:20,596 the string so that you too don't need to 15236 09:45:18,276 --> 09:45:22,960 type in the carrot symbol or the dollar 15237 09:45:20,596 --> 09:45:25,000 sign as well but let's go ahead and 15238 09:45:22,960 --> 09:45:26,800 transition back now to some actual code 15239 09:45:25,000 --> 09:45:28,960 whereby we solve a different problem in 15240 09:45:26,800 --> 09:45:30,720 spirit rather than just validate the 15241 09:45:28,960 --> 09:45:32,680 users's input and make sure it looks the 15242 09:45:30,720 --> 09:45:34,596 way we want let's just assume that the 15243 09:45:32,680 --> 09:45:36,560 users are not going to type in data 15244 09:45:34,596 --> 09:45:38,400 exactly as we want and so we're going to 15245 09:45:36,560 --> 09:45:40,200 have to clean up their input this 15246 09:45:38,400 --> 09:45:42,720 happens so often when you're using like 15247 09:45:40,200 --> 09:45:44,960 a Google form or Office 365 form or 15248 09:45:42,720 --> 09:45:47,240 anything else to collect user input no 15249 09:45:44,960 --> 09:45:49,040 matter what your form question says your 15250 09:45:47,240 --> 09:45:50,680 users are not necessarily going to 15251 09:45:49,040 --> 09:45:52,116 follow those directions they might go 15252 09:45:50,680 --> 09:45:54,080 ahead and type in something that's a 15253 09:45:52,116 --> 09:45:56,040 little differently formatted than you 15254 09:45:54,080 --> 09:45:58,640 might like now you could certainly go 15255 09:45:56,040 --> 09:46:00,400 through the results and download a CSV 15256 09:45:58,640 --> 09:46:02,400 or open the Google spreadsheet or 15257 09:46:00,400 --> 09:46:04,520 equivalent in Excel and just clean up 15258 09:46:02,400 --> 09:46:06,596 all the data manually but if you've got 15259 09:46:04,520 --> 09:46:09,276 lots of submissions dozens hundreds 15260 09:46:06,596 --> 09:46:11,116 thousands of rows in your data set doing 15261 09:46:09,276 --> 09:46:12,916 things manually might not be very fun it 15262 09:46:11,116 --> 09:46:15,640 might be much more effective to write 15263 09:46:12,916 --> 09:46:18,276 code as in Python that can allow you to 15264 09:46:15,640 --> 09:46:21,480 clean up that data and any future data 15265 09:46:18,276 --> 09:46:23,640 as well so let me propose that we go 15266 09:46:21,480 --> 09:46:25,360 ahead here and close validate dopy and 15267 09:46:23,640 --> 09:46:27,800 let's go ahead and create a new program 15268 09:46:25,360 --> 09:46:30,200 Al together called format. the goal of 15269 09:46:27,800 --> 09:46:32,276 which is to reformat the user's input in 15270 09:46:30,200 --> 09:46:35,320 the format we expect I'm going to go 15271 09:46:32,276 --> 09:46:37,116 ahead and run code of format. py and 15272 09:46:35,320 --> 09:46:39,880 let's suppose that the data we're going 15273 09:46:37,116 --> 09:46:42,116 to reformat is the user's name so not 15274 09:46:39,880 --> 09:46:43,360 email address but name this time and 15275 09:46:42,116 --> 09:46:46,640 we're going to hope that they type in 15276 09:46:43,360 --> 09:46:48,160 their name properly like David ma but 15277 09:46:46,640 --> 09:46:49,800 some users might be in the habit for 15278 09:46:48,160 --> 09:46:51,640 whatever reason of typing their name 15279 09:46:49,800 --> 09:46:55,880 backwards if you will with the comma 15280 09:46:51,640 --> 09:46:58,436 such as men comma David instead now it's 15281 09:46:55,880 --> 09:47:00,360 fine because both are clearly as 15282 09:46:58,436 --> 09:47:02,480 readable to the human but if you want to 15283 09:47:00,360 --> 09:47:04,916 standardize how those names are stored 15284 09:47:02,480 --> 09:47:06,720 in your system perhaps a database or CSV 15285 09:47:04,916 --> 09:47:08,880 file or something else it would be nice 15286 09:47:06,720 --> 09:47:10,520 to at least standardize or canonicalize 15287 09:47:08,880 --> 09:47:12,640 the format in which you're storing your 15288 09:47:10,520 --> 09:47:14,596 data so that if you print out the user's 15289 09:47:12,640 --> 09:47:17,596 name it's always the same format David 15290 09:47:14,596 --> 09:47:20,040 Ma and there's no commas or backwards to 15291 09:47:17,596 --> 09:47:21,596 it so let's go ahead and do something 15292 09:47:20,040 --> 09:47:23,756 familiar let's go and give myself a 15293 09:47:21,596 --> 09:47:25,400 variable called name and set it equal to 15294 09:47:23,756 --> 09:47:27,560 the return value of input asking the 15295 09:47:25,400 --> 09:47:29,480 user as we've done many times what's 15296 09:47:27,560 --> 09:47:31,276 your name question mark I'm going to go 15297 09:47:29,480 --> 09:47:33,596 ahead and proactively at least clean up 15298 09:47:31,276 --> 09:47:34,960 some messiness as we keep doing here by 15299 09:47:33,596 --> 09:47:36,480 just stripping off any leading or 15300 09:47:34,960 --> 09:47:38,560 trailing whites space just in case the 15301 09:47:36,480 --> 09:47:40,916 user accidentally hits the space bar we 15302 09:47:38,560 --> 09:47:43,276 don't want that ultimately in our data 15303 09:47:40,916 --> 09:47:44,640 set and now let me go ahead and do this 15304 09:47:43,276 --> 09:47:46,520 as we've done before let me just go 15305 09:47:44,640 --> 09:47:48,960 ahead quickly and print out just to make 15306 09:47:46,520 --> 09:47:51,080 sure I'm off to the right start hello 15307 09:47:48,960 --> 09:47:54,116 and then in curly brace's name so making 15308 09:47:51,080 --> 09:47:55,480 an F string to format hello comma name 15309 09:47:54,116 --> 09:47:58,360 now let me go ahead and clear my screen 15310 09:47:55,480 --> 09:48:00,116 and run python of format. let me behave 15311 09:47:58,360 --> 09:48:02,680 and type in my name as I normally would 15312 09:48:00,116 --> 09:48:04,756 David space ma enter and I think the 15313 09:48:02,680 --> 09:48:07,080 output looks pretty good it looks as 15314 09:48:04,756 --> 09:48:09,436 expected grammatically let me now go 15315 09:48:07,080 --> 09:48:10,640 ahead though and play this game again 15316 09:48:09,436 --> 09:48:11,960 but this time maybe because I'm not 15317 09:48:10,640 --> 09:48:14,520 thinking or I'm just in the habit of 15318 09:48:11,960 --> 09:48:17,360 doing last name comma first I do ma 15319 09:48:14,520 --> 09:48:19,800 comma David and hit enter all right well 15320 09:48:17,360 --> 09:48:21,640 this now is is weird even though the 15321 09:48:19,800 --> 09:48:24,160 program is just spitting out exactly 15322 09:48:21,640 --> 09:48:25,840 what I typed in arguably this is not 15323 09:48:24,160 --> 09:48:29,040 close to correct at least grammatically 15324 09:48:25,840 --> 09:48:30,596 it should really say hello David ma now 15325 09:48:29,040 --> 09:48:32,520 maybe I could have some if conditions 15326 09:48:30,596 --> 09:48:34,596 and I could just reject the user's input 15327 09:48:32,520 --> 09:48:36,880 if they type a comma or get their names 15328 09:48:34,596 --> 09:48:38,756 backwards somehow but that's going to be 15329 09:48:36,880 --> 09:48:41,200 uh too little too late if the user has 15330 09:48:38,756 --> 09:48:43,360 already submitted a form online and I 15331 09:48:41,200 --> 09:48:44,960 already have the data and now I need to 15332 09:48:43,360 --> 09:48:46,680 go in and clean it up and it's not going 15333 09:48:44,960 --> 09:48:48,680 to be fun to go through manually in 15334 09:48:46,680 --> 09:48:51,400 Google spreadsheets or apple numbers or 15335 09:48:48,680 --> 09:48:53,000 Microsoft Excel and manually fix a lot 15336 09:48:51,400 --> 09:48:54,840 of people's names to get rid of the 15337 09:48:53,000 --> 09:48:58,000 commas and move the first name before 15338 09:48:54,840 --> 09:48:59,800 the last as is conventional in the US so 15339 09:48:58,000 --> 09:49:01,756 let's do this it could be a little 15340 09:48:59,800 --> 09:49:02,756 fragile but let's like let's start to 15341 09:49:01,756 --> 09:49:05,360 express ourselves a little 15342 09:49:02,756 --> 09:49:08,756 programmatically here and ask this if 15343 09:49:05,360 --> 09:49:10,680 there is a comma in the person's name 15344 09:49:08,756 --> 09:49:12,756 which is pythonic I'm just asking the 15345 09:49:10,680 --> 09:49:14,720 question is this shorter string in this 15346 09:49:12,756 --> 09:49:16,840 longer string then let me go ahead and 15347 09:49:14,720 --> 09:49:20,200 do this let me go ahead and grab that 15348 09:49:16,840 --> 09:49:21,360 name in the variable split on not just 15349 09:49:20,200 --> 09:49:23,560 the Comm 15350 09:49:21,360 --> 09:49:25,596 but the space after assuming the human 15351 09:49:23,560 --> 09:49:27,200 typed in a space after their name and 15352 09:49:25,596 --> 09:49:29,800 let me go ahead and store the result of 15353 09:49:27,200 --> 09:49:32,840 that splitting of ma comma David into 15354 09:49:29,800 --> 09:49:34,916 two variables let's do last comma first 15355 09:49:32,840 --> 09:49:37,840 again unpacking the sequence of values 15356 09:49:34,916 --> 09:49:39,320 that comes back now let me go ahead and 15357 09:49:37,840 --> 09:49:41,276 reformat the name so I'm going to 15358 09:49:39,320 --> 09:49:43,880 forcibly change the user's name to be as 15359 09:49:41,276 --> 09:49:47,840 I expect so name is actually going to be 15360 09:49:43,880 --> 09:49:50,320 this format string first name then last 15361 09:49:47,840 --> 09:49:52,480 name both in curly braces but formatted 15362 09:49:50,320 --> 09:49:55,116 together with a single space so that I'm 15363 09:49:52,480 --> 09:49:57,560 overriding the user's input and updating 15364 09:49:55,116 --> 09:49:59,000 my name variable accordingly for the 15365 09:49:57,560 --> 09:50:01,160 moment to be clear this program is 15366 09:49:59,000 --> 09:50:03,520 interactive like the users like me are 15367 09:50:01,160 --> 09:50:05,880 typing their name into the program but 15368 09:50:03,520 --> 09:50:07,756 imagine the data already is in a CSV 15369 09:50:05,880 --> 09:50:09,840 file it came in from some process like a 15370 09:50:07,756 --> 09:50:11,916 Google form or something else online you 15371 09:50:09,840 --> 09:50:14,040 could imagine writing code similar to 15372 09:50:11,916 --> 09:50:16,520 this but that maybe goes and reads that 15373 09:50:14,040 --> 09:50:19,080 file into memory first maybe it's a CSV 15374 09:50:16,520 --> 09:50:20,840 via CSV reader or a dict reader and then 15375 09:50:19,080 --> 09:50:22,160 iterating over each of those names but 15376 09:50:20,840 --> 09:50:24,640 we'll keep it simple and just do one 15377 09:50:22,160 --> 09:50:26,240 name at a time but now what's kind of 15378 09:50:24,640 --> 09:50:28,160 interesting here is if I go back to my 15379 09:50:26,240 --> 09:50:30,720 terminal window and clear it and run 15380 09:50:28,160 --> 09:50:32,640 python of format. piy and hit enter I'm 15381 09:50:30,720 --> 09:50:35,276 going to type in David space ma as 15382 09:50:32,640 --> 09:50:37,276 before and I think we're still good but 15383 09:50:35,276 --> 09:50:41,400 I'm also going to go ahead and do this 15384 09:50:37,276 --> 09:50:43,680 python of format. ma comma David with a 15385 09:50:41,400 --> 09:50:47,000 space in between crossing my fingers and 15386 09:50:43,680 --> 09:50:50,360 hit enter and voila that now has been 15387 09:50:47,000 --> 09:50:53,200 fixed such a simple thing to be sure but 15388 09:50:50,360 --> 09:50:55,596 it is so commonly necessary to clean up 15389 09:50:53,200 --> 09:50:58,916 users input here we see at least one way 15390 09:50:55,596 --> 09:51:01,116 to do so pretty easily now to be fair 15391 09:50:58,916 --> 09:51:03,400 there's some problems here and in fact 15392 09:51:01,116 --> 09:51:05,720 can someone imagine a scenario in which 15393 09:51:03,400 --> 09:51:09,000 this code really doesn't fix the user's 15394 09:51:05,720 --> 09:51:12,916 input what could still go wrong even 15395 09:51:09,000 --> 09:51:15,400 with this fix in my code any thoughts if 15396 09:51:12,916 --> 09:51:17,560 they type their in their name comma and 15397 09:51:15,400 --> 09:51:19,596 then sign them oh and then something 15398 09:51:17,560 --> 09:51:21,720 else yeah so let me let me try this for 15399 09:51:19,596 --> 09:51:24,520 instance let me go ahead and run a 15400 09:51:21,720 --> 09:51:28,040 program and uh I am the only David men 15401 09:51:24,520 --> 09:51:30,320 that I know but suppose I were uh uh 15402 09:51:28,040 --> 09:51:31,916 let's say junior like this and it's 15403 09:51:30,320 --> 09:51:33,400 common in English at least to sometimes 15404 09:51:31,916 --> 09:51:34,520 put a comma there you don't necessarily 15405 09:51:33,400 --> 09:51:37,160 need the comma but I'm one of those 15406 09:51:34,520 --> 09:51:39,720 people who uses a comma that's now 15407 09:51:37,160 --> 09:51:41,756 really really broken so I've broken some 15408 09:51:39,720 --> 09:51:43,400 assumption there and so that could 15409 09:51:41,756 --> 09:51:44,680 certainly go wrong here what else well 15410 09:51:43,400 --> 09:51:47,840 let me go ahead and run this again and 15411 09:51:44,680 --> 09:51:49,436 if I did ma comma David no space because 15412 09:51:47,840 --> 09:51:51,240 I'm being a little sloppy I'm not paying 15413 09:51:49,436 --> 09:51:53,400 attention which is going to happen when 15414 09:51:51,240 --> 09:51:55,596 you have lots of users ultimately well 15415 09:51:53,400 --> 09:51:58,640 this really broke now notice I have a 15416 09:51:55,596 --> 09:52:01,360 value error an actual exception why well 15417 09:51:58,640 --> 09:52:03,560 because split is supposed to be 15418 09:52:01,360 --> 09:52:06,200 splitting the string into two strings by 15419 09:52:03,560 --> 09:52:08,080 looking for the comma and a space but if 15420 09:52:06,200 --> 09:52:10,200 there is no comma in space it can't 15421 09:52:08,080 --> 09:52:12,840 split it into two things and the fact 15422 09:52:10,200 --> 09:52:15,480 that I have two variables on the left 15423 09:52:12,840 --> 09:52:17,840 but I'm only getting back one thing on 15424 09:52:15,480 --> 09:52:20,040 the right means that I can't do this 15425 09:52:17,840 --> 09:52:21,800 code quite as this so it's fragile to be 15426 09:52:20,040 --> 09:52:23,680 sure but wouldn't it be nice if we could 15427 09:52:21,800 --> 09:52:25,916 at least improve it for instance we now 15428 09:52:23,680 --> 09:52:28,000 know some regular expression syntax what 15429 09:52:25,916 --> 09:52:30,720 if I at least wanted to make this space 15430 09:52:28,000 --> 09:52:32,276 optional well I could use my new found 15431 09:52:30,720 --> 09:52:34,680 regular expression syntax and put a 15432 09:52:32,276 --> 09:52:37,360 question mark question mark means zero 15433 09:52:34,680 --> 09:52:39,240 or one of the things to the left what's 15434 09:52:37,360 --> 09:52:41,080 the thing to the left it's literally a 15435 09:52:39,240 --> 09:52:43,320 space I don't even need parentheses if 15436 09:52:41,080 --> 09:52:45,320 there's just one thing there so that 15437 09:52:43,320 --> 09:52:47,640 would be the start of a pattern that 15438 09:52:45,320 --> 09:52:49,800 says I must have a comma and then I may 15439 09:52:47,640 --> 09:52:52,560 or may not have a space zero or one 15440 09:52:49,800 --> 09:52:56,000 spaces there after unfortunately the 15441 09:52:52,560 --> 09:52:59,040 version of split that's built into the 15442 09:52:56,000 --> 09:53:00,880 stir variable as in this case doesn't 15443 09:52:59,040 --> 09:53:02,480 support regular Expressions if we want 15444 09:53:00,880 --> 09:53:04,756 our regular Expressions we need to go 15445 09:53:02,480 --> 09:53:07,276 use that Library here so let me go ahead 15446 09:53:04,756 --> 09:53:09,680 and do this let me go in and leave this 15447 09:53:07,276 --> 09:53:12,320 code AS is but go up to the top now and 15448 09:53:09,680 --> 09:53:14,880 import re to import the library for 15449 09:53:12,320 --> 09:53:17,160 regular expressions and now let me go 15450 09:53:14,880 --> 09:53:19,480 ahead and start changing my Approach 15451 09:53:17,160 --> 09:53:21,040 here I'm going to go ahead and do this 15452 09:53:19,480 --> 09:53:23,560 I'm going to use the same function 15453 09:53:21,040 --> 09:53:26,756 called re. search and I'm going to 15454 09:53:23,560 --> 09:53:29,520 search for a pattern that I think will 15455 09:53:26,756 --> 09:53:31,320 be last comma first so let me use my new 15456 09:53:29,520 --> 09:53:33,720 found regular expression syntax and 15457 09:53:31,320 --> 09:53:37,560 represent a pattern for something like 15458 09:53:33,720 --> 09:53:40,400 ma comma space David how can I do this 15459 09:53:37,560 --> 09:53:43,840 well inside of my quotes for re. search 15460 09:53:40,400 --> 09:53:46,240 I'm going to have something so plus 15461 09:53:43,840 --> 09:53:48,680 sorry I'm going to have something so 15462 09:53:46,240 --> 09:53:50,160 plus then I'm going to have a comma then 15463 09:53:48,680 --> 09:53:53,040 I'm going to have a space then I'm going 15464 09:53:50,160 --> 09:53:55,360 to have something plus now I'm going to 15465 09:53:53,040 --> 09:53:56,880 preemptively refine this a little bit I 15466 09:53:55,360 --> 09:53:58,360 want this whole pattern to start 15467 09:53:56,880 --> 09:54:00,116 matching at the beginning of the user's 15468 09:53:58,360 --> 09:54:02,480 input so I'm going to add the carrot 15469 09:54:00,116 --> 09:54:04,560 right away and I want the end of the 15470 09:54:02,480 --> 09:54:06,520 user's input to be matched as well so 15471 09:54:04,560 --> 09:54:08,960 that I'm literally expecting any 15472 09:54:06,520 --> 09:54:11,080 character one or more times then a comma 15473 09:54:08,960 --> 09:54:14,200 then a space then any other character 15474 09:54:11,080 --> 09:54:16,116 one or more times and then that is it 15475 09:54:14,200 --> 09:54:19,360 and I'm going to pass in the name 15476 09:54:16,116 --> 09:54:23,000 variable as before now when we've used 15477 09:54:19,360 --> 09:54:25,360 re do search in the past we really used 15478 09:54:23,000 --> 09:54:28,436 it just to answer a question does the 15479 09:54:25,360 --> 09:54:32,040 user's input match the following pattern 15480 09:54:28,436 --> 09:54:34,000 or not true or false effectively but re. 15481 09:54:32,040 --> 09:54:36,116 search is actually more powerful than 15482 09:54:34,000 --> 09:54:38,916 that you can actually get back more 15483 09:54:36,116 --> 09:54:40,756 information and you can do this you can 15484 09:54:38,916 --> 09:54:43,040 specify a variable and then an 15485 09:54:40,756 --> 09:54:45,800 assignment operator and get back more 15486 09:54:43,040 --> 09:54:48,200 precise answers to what has been found 15487 09:54:45,800 --> 09:54:50,480 when searched for but what is it you 15488 09:54:48,200 --> 09:54:52,160 want to get back well it turns out 15489 09:54:50,480 --> 09:54:54,276 there's this other feature of regular 15490 09:54:52,160 --> 09:54:56,640 Expressions which allow you to use 15491 09:54:54,276 --> 09:54:59,640 parentheses not just to group things 15492 09:54:56,640 --> 09:55:02,360 together but to capture them it turns 15493 09:54:59,640 --> 09:55:04,640 out when you specify parentheses in a 15494 09:55:02,360 --> 09:55:06,960 regular expression unbeknownst to us up 15495 09:55:04,640 --> 09:55:10,400 until now everything in the parentheses 15496 09:55:06,960 --> 09:55:13,560 will be returned to you as a return 15497 09:55:10,400 --> 09:55:16,276 value from the re. search function it's 15498 09:55:13,560 --> 09:55:18,720 going to allow you to extract specific 15499 09:55:16,276 --> 09:55:20,720 amounts of information from the user's 15500 09:55:18,720 --> 09:55:23,596 own input you can reverse this process 15501 09:55:20,720 --> 09:55:25,680 too by using the non-capturing version 15502 09:55:23,596 --> 09:55:27,480 as well you can use parentheses and then 15503 09:55:25,680 --> 09:55:28,840 literally a question mark and a colon 15504 09:55:27,480 --> 09:55:30,480 and then some other stuff and that will 15505 09:55:28,840 --> 09:55:32,200 say don't bother capturing this I just 15506 09:55:30,480 --> 09:55:34,000 want to group things but for now we're 15507 09:55:32,200 --> 09:55:35,960 going to use just the parentheses 15508 09:55:34,000 --> 09:55:37,916 themselves so how am I going to do this 15509 09:55:35,960 --> 09:55:41,680 well if I want to get back the user's 15510 09:55:37,916 --> 09:55:46,756 last name and first name I think what I 15511 09:55:41,680 --> 09:55:49,276 want to capture is the plus here and the 15512 09:55:46,756 --> 09:55:51,640 plus here so I've deliberately 15513 09:55:49,276 --> 09:55:53,400 surrounded in par parentheses the dot 15514 09:55:51,640 --> 09:55:55,680 plus both to the left and the right of 15515 09:55:53,400 --> 09:55:57,240 the comma not because I'm grouping them 15516 09:55:55,680 --> 09:55:58,840 together per se I'm not adding a 15517 09:55:57,240 --> 09:56:02,436 question mark I'm not adding of another 15518 09:55:58,840 --> 09:56:05,480 Plus or a star I'm using parentheses now 15519 09:56:02,436 --> 09:56:07,400 for capturing purposes why well I'm 15520 09:56:05,480 --> 09:56:09,960 going to do this next I'm going to still 15521 09:56:07,400 --> 09:56:13,276 ask a Boolean question like if there are 15522 09:56:09,960 --> 09:56:17,756 matches then do this so if matches is 15523 09:56:13,276 --> 09:56:19,800 not effectively false like none I do 15524 09:56:17,756 --> 09:56:22,756 expect I've gotten back some matches and 15525 09:56:19,800 --> 09:56:26,040 watch what I can do now I can do last 15526 09:56:22,756 --> 09:56:28,000 comma first equals whatever matches in 15527 09:56:26,040 --> 09:56:30,320 and get back all of the groups of 15528 09:56:28,000 --> 09:56:31,800 matches then go ahead and update name 15529 09:56:30,320 --> 09:56:35,200 just like before with a format string 15530 09:56:31,800 --> 09:56:36,916 and do first and then last in curly 15531 09:56:35,200 --> 09:56:38,720 braces as well and then at the very 15532 09:56:36,916 --> 09:56:42,596 bottom just like before print out for 15533 09:56:38,720 --> 09:56:46,000 instance hello comma name so the new 15534 09:56:42,596 --> 09:56:49,520 code now is everything highlighted here 15535 09:56:46,000 --> 09:56:51,800 I'm using re search to search for 15536 09:56:49,520 --> 09:56:54,560 whether the US user typed their name in 15537 09:56:51,800 --> 09:56:57,756 last comma first format but I am more 15538 09:56:54,560 --> 09:57:00,000 powerfully using re. search to capture 15539 09:56:57,756 --> 09:57:02,240 some of the user's input what's going to 15540 09:57:00,000 --> 09:57:05,080 get captured anything I surround it in 15541 09:57:02,240 --> 09:57:07,680 parentheses will be returned to me as 15542 09:57:05,080 --> 09:57:09,880 return values how do you get at those 15543 09:57:07,680 --> 09:57:11,916 return values you ask the variable to 15544 09:57:09,880 --> 09:57:14,320 which you assigned them for all of the 15545 09:57:11,916 --> 09:57:16,916 groups all of the groups of parentheses 15546 09:57:14,320 --> 09:57:18,960 that were captured so let me go ahead 15547 09:57:16,916 --> 09:57:22,080 and do this let me go ahead now and run 15548 09:57:18,960 --> 09:57:24,680 python of format stop Pi enter and I'm 15549 09:57:22,080 --> 09:57:28,436 going to type my name as usual in this 15550 09:57:24,680 --> 09:57:30,596 case nothing happens with this if 15551 09:57:28,436 --> 09:57:34,560 condition why because I did not type a 15552 09:57:30,596 --> 09:57:36,800 comma and so this search does not find a 15553 09:57:34,560 --> 09:57:38,480 comma so there are no matches so we 15554 09:57:36,800 --> 09:57:41,116 immediately just print out hello name 15555 09:57:38,480 --> 09:57:43,436 nothing interesting or new there but if 15556 09:57:41,116 --> 09:57:45,596 I now go ahead and clear my screen and 15557 09:57:43,436 --> 09:57:48,880 run python a format up high and do maen 15558 09:57:45,596 --> 09:57:50,840 commas space David enter we've 15559 09:57:48,880 --> 09:57:52,360 reformatted my name 15560 09:57:50,840 --> 09:57:54,720 well how did this work let me be a 15561 09:57:52,360 --> 09:57:56,596 little more explicit now it turns out I 15562 09:57:54,720 --> 09:57:59,880 don't have to just say matches. groups I 15563 09:57:56,596 --> 09:58:01,596 can get specific groups back that I want 15564 09:57:59,880 --> 09:58:04,840 so let me change my code a little bit 15565 09:58:01,596 --> 09:58:08,560 more let me go ahead now and just say 15566 09:58:04,840 --> 09:58:11,000 this let's update name uh to well 15567 09:58:08,560 --> 09:58:13,680 actually let's do this let's say that 15568 09:58:11,000 --> 09:58:16,560 the last name is going to be in the 15569 09:58:13,680 --> 09:58:18,596 matches but specifically group one the 15570 09:58:16,560 --> 09:58:20,436 first name is going to be in the matches 15571 09:58:18,596 --> 09:58:22,480 but specifically group two why one and 15572 09:58:20,436 --> 09:58:24,640 two because this is the first set of 15573 09:58:22,480 --> 09:58:26,360 parentheses to the left of the comma 15574 09:58:24,640 --> 09:58:28,400 this is the second set of parentheses to 15575 09:58:26,360 --> 09:58:30,560 the right of the comma and based on the 15576 09:58:28,400 --> 09:58:32,720 input this would be the user's last name 15577 09:58:30,560 --> 09:58:35,680 in this scenario me this would be the 15578 09:58:32,720 --> 09:58:38,436 user's first name David in this scenario 15579 09:58:35,680 --> 09:58:41,040 that's why I'm using group one for the 15580 09:58:38,436 --> 09:58:42,756 last name and group two for the first 15581 09:58:41,040 --> 09:58:47,360 name and now I'm going to go ahead and 15582 09:58:42,756 --> 09:58:52,320 say name equals uh F string again uh 15583 09:58:47,360 --> 09:58:54,436 first and then last done and let me 15584 09:58:52,320 --> 09:58:56,116 refine this one last step before we take 15585 09:58:54,436 --> 09:58:58,240 questions I don't really need these 15586 09:58:56,116 --> 09:58:59,560 variables if I'm immediately using them 15587 09:58:58,240 --> 09:59:01,000 let's just go ahead and tighten this up 15588 09:58:59,560 --> 09:59:03,596 further as we've done in the past for 15589 09:59:01,000 --> 09:59:05,560 design sake if I want to make the name 15590 09:59:03,596 --> 09:59:07,320 the concatenation of the person's first 15591 09:59:05,560 --> 09:59:12,520 name and last name let's just do this 15592 09:59:07,320 --> 09:59:16,116 matches. group two first plus a space 15593 09:59:12,520 --> 09:59:18,276 plus matches. group one so it's just up 15594 09:59:16,116 --> 09:59:20,680 to me to know from left to right this is 15595 09:59:18,276 --> 09:59:23,400 group one this is group two so group one 15596 09:59:20,680 --> 09:59:25,840 is last group two is first so if I want 15597 09:59:23,400 --> 09:59:28,680 to flip them around and update the value 15598 09:59:25,840 --> 09:59:31,640 of name I can explicitly get group two 15599 09:59:28,680 --> 09:59:35,520 first concatenate using plus a single 15600 09:59:31,640 --> 09:59:38,320 space and then concatenate on group one 15601 09:59:35,520 --> 09:59:39,960 all right that was a lot let me pause to 15602 09:59:38,320 --> 09:59:41,880 see if there are questions the key 15603 09:59:39,960 --> 09:59:44,400 difference here is we're still using re. 15604 09:59:41,880 --> 09:59:46,640 search the exact same way but now I'm 15605 09:59:44,400 --> 09:59:48,916 using its return value not just to 15606 09:59:46,640 --> 09:59:51,160 answer a question true or false but to 15607 09:59:48,916 --> 09:59:54,276 actually get back specific matches 15608 09:59:51,160 --> 09:59:56,680 anything I captured so to speak with 15609 09:59:54,276 --> 09:59:59,320 parentheses why is it here we're using 15610 09:59:56,680 --> 10:00:01,276 one and two instead of Z and one really 15611 09:59:59,320 --> 10:00:02,960 good question caping the first a good 15612 10:00:01,276 --> 10:00:05,000 observation in almost every other 15613 10:00:02,960 --> 10:00:07,400 context we've started counting at zero 15614 10:00:05,000 --> 10:00:09,520 and one instead of one and two it turns 15615 10:00:07,400 --> 10:00:11,840 out there's something else in location 15616 10:00:09,520 --> 10:00:13,640 zero when it comes back from re. search 15617 10:00:11,840 --> 10:00:15,596 related to the string itself so 15618 10:00:13,640 --> 10:00:18,560 according to the documentation of this 15619 10:00:15,596 --> 10:00:21,000 function only one is the first set of 15620 10:00:18,560 --> 10:00:23,276 parentheses and two is the second set 15621 10:00:21,000 --> 10:00:25,960 and onward from there just a different 15622 10:00:23,276 --> 10:00:29,840 convention here other questions uh what 15623 10:00:25,960 --> 10:00:33,520 if we write nothing like white space 15624 10:00:29,840 --> 10:00:36,436 comma whes space uh how how we check um 15625 10:00:33,520 --> 10:00:37,800 true of condition before I answer 15626 10:00:36,436 --> 10:00:39,320 directly let me just run this and make 15627 10:00:37,800 --> 10:00:41,680 sure I've not broken anything further 15628 10:00:39,320 --> 10:00:44,200 let me run python of format. let me type 15629 10:00:41,680 --> 10:00:46,240 in David space maen the right way let me 15630 10:00:44,200 --> 10:00:48,596 run it once more let me type it Ma comma 15631 10:00:46,240 --> 10:00:50,640 David the wrong way that we're fixing 15632 10:00:48,596 --> 10:00:52,320 and we're still good but I think it will 15633 10:00:50,640 --> 10:00:56,040 still break let me run it a third time 15634 10:00:52,320 --> 10:00:59,276 with me comma David with no space and 15635 10:00:56,040 --> 10:01:03,276 now it's still broken why because I'm 15636 10:00:59,276 --> 10:01:04,960 still looking for comma space now how 15637 10:01:03,276 --> 10:01:06,720 can I fix that one way I could do that 15638 10:01:04,960 --> 10:01:08,680 is to add a question mark here which 15639 10:01:06,720 --> 10:01:11,116 again is zero or more of the thing 15640 10:01:08,680 --> 10:01:13,000 before so if I have a space and then a 15641 10:01:11,116 --> 10:01:15,756 question mark literally no need for any 15642 10:01:13,000 --> 10:01:19,520 parentheses then I can literally 15643 10:01:15,756 --> 10:01:22,160 tolerate both ma comma space David or ma 15644 10:01:19,520 --> 10:01:24,116 comma David so let's try again before 15645 10:01:22,160 --> 10:01:27,436 this did not work let's do me comma 15646 10:01:24,116 --> 10:01:29,200 David with no space now it does actually 15647 10:01:27,436 --> 10:01:31,520 work so we can tolerate different 15648 10:01:29,200 --> 10:01:34,240 amounts of white space if I am a little 15649 10:01:31,520 --> 10:01:36,000 more precise with my formula let me go 15650 10:01:34,240 --> 10:01:38,116 ahead and try once more let me very 15651 10:01:36,000 --> 10:01:40,000 weirdly but possibly hit the space bar a 15652 10:01:38,116 --> 10:01:43,160 few too many times so now they're really 15653 10:01:40,000 --> 10:01:45,080 separated this again is uh not going to 15654 10:01:43,160 --> 10:01:47,756 work quite right because it's going to 15655 10:01:45,080 --> 10:01:50,200 consume all of that white space so now I 15656 10:01:47,756 --> 10:01:52,320 might want to strip left and right any 15657 10:01:50,200 --> 10:01:54,960 of the leading white space on the result 15658 10:01:52,320 --> 10:01:58,756 or what I could do here is say this 15659 10:01:54,960 --> 10:02:02,360 instead of zero or one I could use a 15660 10:01:58,756 --> 10:02:04,640 star here so space star and now if I run 15661 10:02:02,360 --> 10:02:06,960 this once more with ma comma space space 15662 10:02:04,640 --> 10:02:08,960 space David enter now we've cleaned up 15663 10:02:06,960 --> 10:02:11,160 things further so you can imagine 15664 10:02:08,960 --> 10:02:12,596 depending on how messy the data is that 15665 10:02:11,160 --> 10:02:14,160 you're cleaning up your regular 15666 10:02:12,596 --> 10:02:16,160 Expressions might need to get more and 15667 10:02:14,160 --> 10:02:18,276 more sophisticated it really depends on 15668 10:02:16,160 --> 10:02:21,040 just how many problems we want to solve 15669 10:02:18,276 --> 10:02:23,436 at once well allow me to propose that we 15670 10:02:21,040 --> 10:02:25,480 Forge ahead further just to clean this 15671 10:02:23,436 --> 10:02:28,520 up even more so using a feature that's 15672 10:02:25,480 --> 10:02:30,560 actually relatively new to python itself 15673 10:02:28,520 --> 10:02:32,436 it is very common when using regular 15674 10:02:30,560 --> 10:02:35,360 Expressions to do exactly what I've done 15675 10:02:32,436 --> 10:02:38,276 here to call a function like re. search 15676 10:02:35,360 --> 10:02:39,916 with capturing parentheses inside such 15677 10:02:38,276 --> 10:02:41,400 that you get back a return value that 15678 10:02:39,916 --> 10:02:42,880 I'm calling matches you could call it 15679 10:02:41,400 --> 10:02:45,040 something else but I'm calling it by 15680 10:02:42,880 --> 10:02:47,840 default matches and then notice on the 15681 10:02:45,040 --> 10:02:49,080 next line I'm saying if matches wouldn't 15682 10:02:47,840 --> 10:02:50,276 it be nice if I could just tighten 15683 10:02:49,080 --> 10:02:53,116 things up further 15684 10:02:50,276 --> 10:02:56,276 and do these all on the same line well 15685 10:02:53,116 --> 10:02:58,560 you can sort of let me go ahead and do 15686 10:02:56,276 --> 10:03:00,436 this let me get rid of this if and let 15687 10:02:58,560 --> 10:03:03,436 me just try to say something like this 15688 10:03:00,436 --> 10:03:08,276 if matches equals re search and then 15689 10:03:03,436 --> 10:03:11,200 colon so combining my if condition into 15690 10:03:08,276 --> 10:03:14,596 just one line instead of those two um in 15691 10:03:11,200 --> 10:03:16,000 C or C++ or Java you would actually do 15692 10:03:14,596 --> 10:03:17,520 something like this surrounding the 15693 10:03:16,000 --> 10:03:19,840 whole thing with parentheses sometimes 15694 10:03:17,520 --> 10:03:22,320 double sets to suppress any warnings if 15695 10:03:19,840 --> 10:03:26,000 you want to do two things at once if you 15696 10:03:22,320 --> 10:03:28,436 want to not only assign the return value 15697 10:03:26,000 --> 10:03:31,080 of re. search to a variable called 15698 10:03:28,436 --> 10:03:34,116 matches but you want to subsequently ask 15699 10:03:31,080 --> 10:03:36,320 a Boolean question is this effectively 15700 10:03:34,116 --> 10:03:38,596 true or false that's what I was doing a 15701 10:03:36,320 --> 10:03:40,400 moment ago let me undo this a moment ago 15702 10:03:38,596 --> 10:03:42,800 I was getting back the return value and 15703 10:03:40,400 --> 10:03:45,080 assigning it to matches and then I was 15704 10:03:42,800 --> 10:03:47,480 asking the question well it turns out 15705 10:03:45,080 --> 10:03:49,560 this need to have two lines of code 15706 10:03:47,480 --> 10:03:51,560 presumably rubbed people wrong for too 15707 10:03:49,560 --> 10:03:53,596 long long in Python and so you can now 15708 10:03:51,560 --> 10:03:56,720 combine these two kinds of lines into 15709 10:03:53,596 --> 10:03:59,240 one but you need a new operator you 15710 10:03:56,720 --> 10:04:01,840 cannot just say if matches equals re 15711 10:03:59,240 --> 10:04:05,276 search and then an cin at the end you 15712 10:04:01,840 --> 10:04:09,200 instead need to do this you need to do 15713 10:04:05,276 --> 10:04:11,680 colon equals if and only if you want to 15714 10:04:09,200 --> 10:04:14,360 assign something from right to left and 15715 10:04:11,680 --> 10:04:17,116 you want to ask an if or an L if 15716 10:04:14,360 --> 10:04:18,840 question on the same line This is 15717 10:04:17,116 --> 10:04:20,160 affectionately known as you can see here 15718 10:04:18,840 --> 10:04:22,360 as the wall 15719 10:04:20,160 --> 10:04:25,116 operator and it's new to python in 15720 10:04:22,360 --> 10:04:27,480 recent years and it both allows you to 15721 10:04:25,116 --> 10:04:31,436 assign a value as I'm doing from right 15722 10:04:27,480 --> 10:04:33,080 to left and ask a Boolean question about 15723 10:04:31,436 --> 10:04:35,840 it like I'm doing with the if or 15724 10:04:33,080 --> 10:04:38,680 equivalently L if does anyone know why 15725 10:04:35,840 --> 10:04:41,756 this is called The Walrus operator if 15726 10:04:38,680 --> 10:04:44,400 you kind of look at it like this perhaps 15727 10:04:41,756 --> 10:04:46,240 if you're familiar with walruses it kind 15728 10:04:44,400 --> 10:04:47,880 of sort of looks like a walrus so a 15729 10:04:46,240 --> 10:04:49,720 minor detail but a relatively new 15730 10:04:47,880 --> 10:04:51,720 feature of python that honestly you'll 15731 10:04:49,720 --> 10:04:53,400 probably continue to see online and in 15732 10:04:51,720 --> 10:04:55,596 source code and in textbooks and so 15733 10:04:53,400 --> 10:04:57,520 forth increasingly so now that it does 15734 10:04:55,596 --> 10:04:59,596 exist it does not change the logic at 15735 10:04:57,520 --> 10:05:01,880 all if I run python of format. piy and 15736 10:04:59,596 --> 10:05:03,800 type maen commas space David it still 15737 10:05:01,880 --> 10:05:06,400 fixes things but it's tightened up my 15738 10:05:03,800 --> 10:05:09,000 code just a bit more all right let's go 15739 10:05:06,400 --> 10:05:11,680 ahead and look at one final problem to 15740 10:05:09,000 --> 10:05:14,040 solve that of extracting information now 15741 10:05:11,680 --> 10:05:15,880 as well so at this point we've now 15742 10:05:14,040 --> 10:05:17,480 validated the user's input by checking 15743 10:05:15,880 --> 10:05:20,436 whether or not it meets a certain 15744 10:05:17,480 --> 10:05:22,276 pattern we've cleaned up the users input 15745 10:05:20,436 --> 10:05:24,040 by checking against a pattern whether it 15746 10:05:22,276 --> 10:05:25,756 matches or not and if it does match we 15747 10:05:24,040 --> 10:05:27,200 kind of reorganize some of the users 15748 10:05:25,756 --> 10:05:29,320 information so we can clean up their 15749 10:05:27,200 --> 10:05:30,880 input and standardize the format in 15750 10:05:29,320 --> 10:05:32,916 which we're storing or printing it in 15751 10:05:30,880 --> 10:05:35,240 this case let's do one final example 15752 10:05:32,916 --> 10:05:37,680 where we're very specifically extracting 15753 10:05:35,240 --> 10:05:39,880 information in order to answer some 15754 10:05:37,680 --> 10:05:42,116 question so let me propose this let me 15755 10:05:39,880 --> 10:05:43,680 go ahead and close format. and create a 15756 10:05:42,116 --> 10:05:46,160 new file called 15757 10:05:43,680 --> 10:05:48,916 twitter. the goal of which is to prompt 15758 10:05:46,160 --> 10:05:52,720 users for the URL of their Twitter 15759 10:05:48,916 --> 10:05:55,640 profile and extract from it infer from 15760 10:05:52,720 --> 10:05:57,160 that URL what is the user's username now 15761 10:05:55,640 --> 10:05:58,756 why might you want to do this well one 15762 10:05:57,160 --> 10:06:00,756 you might want users to be able to just 15763 10:05:58,756 --> 10:06:03,276 very easily copy and paste the URL from 15764 10:06:00,756 --> 10:06:05,880 their own Twitter profile into your form 15765 10:06:03,276 --> 10:06:09,360 into your app so that you can figure out 15766 10:06:05,880 --> 10:06:11,400 what their uh username is or you might 15767 10:06:09,360 --> 10:06:12,960 have a form that asks the user for their 15768 10:06:11,400 --> 10:06:14,680 Twitter username and because people 15769 10:06:12,960 --> 10:06:16,756 aren't necessarily paying very close 15770 10:06:14,680 --> 10:06:19,000 attention some people type their 15771 10:06:16,756 --> 10:06:21,436 username some people type their whole 15772 10:06:19,000 --> 10:06:22,680 URL or something else altogether it 15773 10:06:21,436 --> 10:06:24,560 would be nice now that you're a 15774 10:06:22,680 --> 10:06:26,320 programmer to just be more tolerant of 15775 10:06:24,560 --> 10:06:28,400 different types of input and just take 15776 10:06:26,320 --> 10:06:30,680 on the burden of canonicalizing 15777 10:06:28,400 --> 10:06:32,680 standardizing the data but being 15778 10:06:30,680 --> 10:06:34,480 flexible with the users it's arguably a 15779 10:06:32,680 --> 10:06:36,880 better user experience if you just let 15780 10:06:34,480 --> 10:06:39,480 me copy paste or type in what I want you 15781 10:06:36,880 --> 10:06:41,960 clean it up you're the programmer not me 15782 10:06:39,480 --> 10:06:43,520 LS for a better experience perhaps well 15783 10:06:41,960 --> 10:06:45,680 let me go ahead and do this with 15784 10:06:43,520 --> 10:06:48,596 twitter. let me first go ahead and 15785 10:06:45,680 --> 10:06:50,640 prompt the user here for a value for a 15786 10:06:48,596 --> 10:06:52,596 variable that I'll call you URL and just 15787 10:06:50,640 --> 10:06:54,320 ask them to input the URL of their 15788 10:06:52,596 --> 10:06:56,040 Twitter profile I'm going to go ahead 15789 10:06:54,320 --> 10:06:57,480 and strip off any leading or trailing 15790 10:06:56,040 --> 10:06:58,880 whitespace just in case users 15791 10:06:57,480 --> 10:07:01,000 accidentally hit the space bar that's 15792 10:06:58,880 --> 10:07:03,480 like literally the least I can do quite 15793 10:07:01,000 --> 10:07:08,160 easily but now let's go ahead and do 15794 10:07:03,480 --> 10:07:10,116 this suppose that the users address is 15795 10:07:08,160 --> 10:07:11,720 the following let me print out what they 15796 10:07:10,116 --> 10:07:13,880 type in and let me clear my screen and 15797 10:07:11,720 --> 10:07:16,520 run python of twitter. I'm going to go 15798 10:07:13,880 --> 10:07:18,116 ahead and type in for instance 15799 10:07:16,520 --> 10:07:20,640 https 15800 10:07:18,116 --> 10:07:23,080 twitter.com David J ma which happens to 15801 10:07:20,640 --> 10:07:24,400 be my own Twitter username for now we're 15802 10:07:23,080 --> 10:07:25,916 just going to print it back onto the 15803 10:07:24,400 --> 10:07:28,240 screen just to make sure I've not messed 15804 10:07:25,916 --> 10:07:30,040 up yet okay so I've printed back out the 15805 10:07:28,240 --> 10:07:33,756 exact same URL but the goal at hand is 15806 10:07:30,040 --> 10:07:36,116 to extract the username only now let me 15807 10:07:33,756 --> 10:07:39,080 just ask perhaps a straightforward 15808 10:07:36,116 --> 10:07:43,040 question logically what do I need to do 15809 10:07:39,080 --> 10:07:45,880 to get at the user's username well um we 15810 10:07:43,040 --> 10:07:48,436 just ignore what's before the username 15811 10:07:45,880 --> 10:07:50,116 and then just extract the username 15812 10:07:48,436 --> 10:07:52,080 perfect yeah I mean it is simple as that 15813 10:07:50,116 --> 10:07:53,880 if you know the usernames at the end 15814 10:07:52,080 --> 10:07:55,400 well let's just somehow ignore 15815 10:07:53,880 --> 10:07:57,080 everything to the beginning well what's 15816 10:07:55,400 --> 10:07:58,360 at the beginning well it's a URL so 15817 10:07:57,080 --> 10:08:03,240 we're probably going to need to ignore 15818 10:07:58,360 --> 10:08:05,240 an https a colon a twitter.com and a 15819 10:08:03,240 --> 10:08:07,840 slash so we just want to throw all of 15820 10:08:05,240 --> 10:08:09,480 that away why because if it's a URL We 15821 10:08:07,840 --> 10:08:11,916 Know by how Twitter works that the 15822 10:08:09,480 --> 10:08:14,436 username comes at the end so let's use 15823 10:08:11,916 --> 10:08:15,640 that very simple idea to get at the 15824 10:08:14,436 --> 10:08:17,400 information we want well I'm going to 15825 10:08:15,640 --> 10:08:18,756 try this a few different ways let me go 15826 10:08:17,400 --> 10:08:20,400 back into my program here and instead of 15827 10:08:18,756 --> 10:08:22,756 just printing it out which was just to 15828 10:08:20,400 --> 10:08:25,240 see what's going on let me do this let 15829 10:08:22,756 --> 10:08:29,240 me create a new variable called username 15830 10:08:25,240 --> 10:08:32,480 and let me call url. replace it turns 15831 10:08:29,240 --> 10:08:34,680 out that if URL is a string or a stir in 15832 10:08:32,480 --> 10:08:37,880 Python it again comes with multiple 15833 10:08:34,680 --> 10:08:40,000 methods like strip uh and split and 15834 10:08:37,880 --> 10:08:42,240 others as well one of which is called 15835 10:08:40,000 --> 10:08:44,200 replace and replace will do just that 15836 10:08:42,240 --> 10:08:46,436 you pass a two arguments the first of 15837 10:08:44,200 --> 10:08:48,320 which is what do you want to replace the 15838 10:08:46,436 --> 10:08:50,520 second argument is what do you want to 15839 10:08:48,320 --> 10:08:52,276 replace it with so if I want to get rid 15840 10:08:50,520 --> 10:08:53,840 of as I've been proposed really just 15841 10:08:52,276 --> 10:08:56,960 everything before the username that is 15842 10:08:53,840 --> 10:09:00,436 the Twitter URL or the beginning thereof 15843 10:08:56,960 --> 10:09:02,480 let's just say this go ahead and replace 15844 10:09:00,436 --> 10:09:05,040 https 15845 10:09:02,480 --> 10:09:07,276 twitter.com close quote that's what I 15846 10:09:05,040 --> 10:09:08,640 want to replace and comma second 15847 10:09:07,276 --> 10:09:10,640 argument what do you want to replace it 15848 10:09:08,640 --> 10:09:13,080 with nothing so I'm literally going to 15849 10:09:10,640 --> 10:09:14,880 pass in quote unquote to effectively do 15850 10:09:13,080 --> 10:09:16,400 a find and replace that's what the 15851 10:09:14,880 --> 10:09:18,160 replace method does just like you can do 15852 10:09:16,400 --> 10:09:20,116 it in Microsoft Word or Google Docs this 15853 10:09:18,160 --> 10:09:23,116 is the programmer's way of doing find 15854 10:09:20,116 --> 10:09:25,160 and replace now let me go ahead and 15855 10:09:23,116 --> 10:09:27,720 print out just the username so I'll use 15856 10:09:25,160 --> 10:09:30,000 an F string like this I'll say username 15857 10:09:27,720 --> 10:09:32,080 colon and then in curly braces username 15858 10:09:30,000 --> 10:09:33,520 just to format it nicely all right let 15859 10:09:32,080 --> 10:09:37,436 me go ahead and clear my screen and run 15860 10:09:33,520 --> 10:09:39,730 python of twitter. enter URL here we go 15861 10:09:37,436 --> 10:09:40,960 https 15862 10:09:39,730 --> 10:09:45,520 [Music] 15863 10:09:40,960 --> 10:09:47,756 twitter.com davidj maen enter okay now 15864 10:09:45,520 --> 10:09:51,160 we've made some progress done for the 15865 10:09:47,756 --> 10:09:54,080 day right well what is suboptimal about 15866 10:09:51,160 --> 10:09:58,080 this can anyone critique or find fault 15867 10:09:54,080 --> 10:10:00,520 with my program it is working now but 15868 10:09:58,080 --> 10:10:02,436 it's a little fragile I bet we could 15869 10:10:00,520 --> 10:10:04,720 contrive some scenarios where I think it 15870 10:10:02,436 --> 10:10:07,480 works but it doesn't well I have a few 15871 10:10:04,720 --> 10:10:11,160 ideas actually well first of all uh if 15872 10:10:07,480 --> 10:10:14,200 we if we don't specify https it will 15873 10:10:11,160 --> 10:10:17,116 broken secondly if we have slash at the 15874 10:10:14,200 --> 10:10:19,640 end it also will be broken if we if we 15875 10:10:17,116 --> 10:10:22,596 have like question mark up the after 15876 10:10:19,640 --> 10:10:24,436 question mark it also w't work so lot of 15877 10:10:22,596 --> 10:10:26,480 scenar actually oh my God I mean here we 15878 10:10:24,436 --> 10:10:27,916 are I was pretending to think I was done 15879 10:10:26,480 --> 10:10:30,000 but my God like Alex gave us a whole 15880 10:10:27,916 --> 10:10:32,520 laundry list of like problems and just 15881 10:10:30,000 --> 10:10:34,880 to recap then what if it's not https 15882 10:10:32,520 --> 10:10:36,596 it's HTTP slightly less secure but I 15883 10:10:34,880 --> 10:10:38,480 should still be able to tolerate that 15884 10:10:36,596 --> 10:10:39,840 programmatically uh what if the protocol 15885 10:10:38,480 --> 10:10:42,200 is not there what if the user just typed 15886 10:10:39,840 --> 10:10:44,160 twitter.com davidj maen it would be nice 15887 10:10:42,200 --> 10:10:46,080 to tolerate that rather than show an 15888 10:10:44,160 --> 10:10:48,116 error and make me type in the protocol 15889 10:10:46,080 --> 10:10:50,320 why it's not good user experience what 15890 10:10:48,116 --> 10:10:52,320 if it had a flash at the end of the 15891 10:10:50,320 --> 10:10:54,360 username or a question mark If you think 15892 10:10:52,320 --> 10:10:56,400 about URLs you've seen on the web 15893 10:10:54,360 --> 10:10:58,040 there's very commonly more information 15894 10:10:56,400 --> 10:11:00,080 especially if it's been shared on social 15895 10:10:58,040 --> 10:11:01,756 media there might be HTTP parameters so 15896 10:11:00,080 --> 10:11:05,000 to speak just stuff there that we don't 15897 10:11:01,756 --> 10:11:06,756 want there could be a www. twitter.com 15898 10:11:05,000 --> 10:11:09,436 which I'm also not expecting but does 15899 10:11:06,756 --> 10:11:11,000 work if you go to that URL too so 15900 10:11:09,436 --> 10:11:12,960 there's just so many things that can go 15901 10:11:11,000 --> 10:11:15,360 wrong and even if I come back to my 15902 10:11:12,960 --> 10:11:17,840 contrived example as earlier what if I 15903 10:11:15,360 --> 10:11:20,000 run this program and say this uh my 15904 10:11:17,840 --> 10:11:21,520 username is H H 15905 10:11:20,000 --> 10:11:26,240 gtps 15906 10:11:21,520 --> 10:11:29,200 twitter.com davidj maen enter well that 15907 10:11:26,240 --> 10:11:31,160 too just just didn't really work it got 15908 10:11:29,200 --> 10:11:33,080 rid of the U 15909 10:11:31,160 --> 10:11:35,916 actually okay actually that kind of 15910 10:11:33,080 --> 10:11:38,000 worked but the goal here is to actually 15911 10:11:35,916 --> 10:11:40,080 get the user's username not an English 15912 10:11:38,000 --> 10:11:42,116 sentence describing the user's username 15913 10:11:40,080 --> 10:11:43,840 so I would argue that even though I just 15914 10:11:42,116 --> 10:11:46,320 accidentally created perfectly correct 15915 10:11:43,840 --> 10:11:48,320 English grammar I did not extract the 15916 10:11:46,320 --> 10:11:51,116 Twitter username correctly I don't want 15917 10:11:48,320 --> 10:11:53,360 words like my username is as part of my 15918 10:11:51,116 --> 10:11:55,160 input so how can we go about improving 15919 10:11:53,360 --> 10:11:56,640 this and maybe chipping away at some of 15920 10:11:55,160 --> 10:11:58,720 those problems one by one well let me 15921 10:11:56,640 --> 10:12:01,276 clear my screen here let me come back up 15922 10:11:58,720 --> 10:12:03,560 to my code and let me not just replace 15923 10:12:01,276 --> 10:12:05,160 it but let me do something else instead 15924 10:12:03,560 --> 10:12:06,800 I'm going to go ahead and instead of 15925 10:12:05,160 --> 10:12:09,720 using replace I'm going to use another 15926 10:12:06,800 --> 10:12:12,200 function called remove prefix a prefix 15927 10:12:09,720 --> 10:12:14,916 is a string or a substring that comes at 15928 10:12:12,200 --> 10:12:16,520 the start of another so if I remove 15929 10:12:14,916 --> 10:12:18,640 prefix I don't need a second argument 15930 10:12:16,520 --> 10:12:20,800 for this function I just need one what 15931 10:12:18,640 --> 10:12:23,520 prefix do you want to remove so this 15932 10:12:20,800 --> 10:12:25,116 will at least now fix the problem I just 15933 10:12:23,520 --> 10:12:27,040 described of typing in like a whole 15934 10:12:25,116 --> 10:12:29,400 sentence where the URL is there but it's 15935 10:12:27,040 --> 10:12:32,080 not the beginning it's only at the end 15936 10:12:29,400 --> 10:12:34,000 so here this still is not correct but we 15937 10:12:32,080 --> 10:12:36,200 don't create this weird looking output 15938 10:12:34,000 --> 10:12:39,916 that just removes the URL part of the 15939 10:12:36,200 --> 10:12:43,800 input uh my username is 15940 10:12:39,916 --> 10:12:47,320 htps twitter.com davidj maen a moment 15941 10:12:43,800 --> 10:12:49,840 ago it did remove the URL and left only 15942 10:12:47,320 --> 10:12:52,276 the David J ma this is not perfect still 15943 10:12:49,840 --> 10:12:54,360 but at least now it does not weirdly 15944 10:12:52,276 --> 10:12:56,640 remove the URL and then leave the 15945 10:12:54,360 --> 10:12:58,200 English it's just leaving it alone so 15946 10:12:56,640 --> 10:13:00,080 maybe I could handle this better but at 15947 10:12:58,200 --> 10:13:01,756 least it's removing it from the part of 15948 10:13:00,080 --> 10:13:04,000 the string I might 15949 10:13:01,756 --> 10:13:05,880 anticipate well what else could we do 15950 10:13:04,000 --> 10:13:08,640 here well it turns out that like regular 15951 10:13:05,880 --> 10:13:10,680 Expressions just let us express patterns 15952 10:13:08,640 --> 10:13:12,160 much more precisely we could spend all 15953 10:13:10,680 --> 10:13:14,200 day using a whole bunch of different 15954 10:13:12,160 --> 10:13:16,680 python functions like remove prefix or 15955 10:13:14,200 --> 10:13:19,520 remove and strip and others and kind of 15956 10:13:16,680 --> 10:13:21,200 make our way to the right solution but a 15957 10:13:19,520 --> 10:13:23,240 regular expression just allows you to 15958 10:13:21,200 --> 10:13:25,800 more succinctly if admittedly more 15959 10:13:23,240 --> 10:13:27,800 cryptically Express these kinds of 15960 10:13:25,800 --> 10:13:29,756 patterns and goals and we've seen from 15961 10:13:27,800 --> 10:13:32,720 parentheses which can be used not just 15962 10:13:29,756 --> 10:13:35,160 to group symbols together as sets but to 15963 10:13:32,720 --> 10:13:38,640 capture information as well we have a 15964 10:13:35,160 --> 10:13:41,240 very powerful tool now in our toolkit so 15965 10:13:38,640 --> 10:13:44,640 let me do this let me go ahead and start 15966 10:13:41,240 --> 10:13:46,400 fresh here and import the re Library as 15967 10:13:44,640 --> 10:13:48,560 before at the very top of my program I'm 15968 10:13:46,400 --> 10:13:50,596 still going to get the user's URL via 15969 10:13:48,560 --> 10:13:53,320 the same l of code but I'm now going to 15970 10:13:50,596 --> 10:13:55,840 use another function as well it turns 15971 10:13:53,320 --> 10:13:58,520 out that there's not just re. search or 15972 10:13:55,840 --> 10:14:01,596 rd. match or re. full match there's also 15973 10:13:58,520 --> 10:14:04,040 re. sub in the regular expression 15974 10:14:01,596 --> 10:14:05,840 Library where sub here means substitute 15975 10:14:04,040 --> 10:14:07,560 and it takes more arguments but they're 15976 10:14:05,840 --> 10:14:09,960 fairly straightforward the first 15977 10:14:07,560 --> 10:14:11,596 argument to re.sub is the pattern the 15978 10:14:09,960 --> 10:14:14,720 regular expression that you want to look 15979 10:14:11,596 --> 10:14:16,800 for then you have a replacement string 15980 10:14:14,720 --> 10:14:18,880 what do you want to replace that pattern 15981 10:14:16,800 --> 10:14:21,116 with and where do you want to do all 15982 10:14:18,880 --> 10:14:23,480 that well you pass in the string that 15983 10:14:21,116 --> 10:14:24,916 you want to do the substitution on then 15984 10:14:23,480 --> 10:14:26,480 there's some other arguments that I'll 15985 10:14:24,916 --> 10:14:28,400 wave my hands at for now among them are 15986 10:14:26,480 --> 10:14:30,240 the same flags and also a count like how 15987 10:14:28,400 --> 10:14:32,276 many times do you want to do find and 15988 10:14:30,240 --> 10:14:34,276 replace do you want it to do all or do 15989 10:14:32,276 --> 10:14:35,960 you want to do it just one or so forth 15990 10:14:34,276 --> 10:14:37,640 you can have further control there too 15991 10:14:35,960 --> 10:14:39,720 just like you would in Google Docs or 15992 10:14:37,640 --> 10:14:42,320 Microsoft Word well let me go back to my 15993 10:14:39,720 --> 10:14:44,640 code here and let me do this I'm going 15994 10:14:42,320 --> 10:14:47,720 to go ahead and call re not search but 15995 10:14:44,640 --> 10:14:51,756 re.sub for substitute I'm going to pass 15996 10:14:47,720 --> 10:14:53,880 in the following regular expression 15997 10:14:51,756 --> 10:14:56,320 https 15998 10:14:53,880 --> 10:14:58,480 twitter.com uh Slash and then I'm going 15999 10:14:56,320 --> 10:15:01,116 to close my quote and now what do I want 16000 10:14:58,480 --> 10:15:03,360 to replace that with well like before 16001 10:15:01,116 --> 10:15:04,720 with the simple stir replace function I 16002 10:15:03,360 --> 10:15:07,436 want to replace it with nothing just get 16003 10:15:04,720 --> 10:15:09,040 rid of it alt together but what uh 16004 10:15:07,436 --> 10:15:12,756 string do I want to pass in to do this 16005 10:15:09,040 --> 10:15:15,276 to the URL from the user and now let me 16006 10:15:12,756 --> 10:15:18,116 go ahead and assign the return value of 16007 10:15:15,276 --> 10:15:20,520 re sub to a variable called username so 16008 10:15:18,116 --> 10:15:23,116 re sub purpose in life is again to 16009 10:15:20,520 --> 10:15:24,480 substitute some value for some regular 16010 10:15:23,116 --> 10:15:26,960 expression some number of times it 16011 10:15:24,480 --> 10:15:29,160 essentially is find and replace using 16012 10:15:26,960 --> 10:15:31,436 regular expressions and it returns to 16013 10:15:29,160 --> 10:15:33,840 you the resulting string once you've 16014 10:15:31,436 --> 10:15:35,320 done all those substitutions so now the 16015 10:15:33,840 --> 10:15:37,640 very last line of my code can be the 16016 10:15:35,320 --> 10:15:40,200 same as before print and I'll use an F 16017 10:15:37,640 --> 10:15:42,200 string username colon and then in curly 16018 10:15:40,200 --> 10:15:45,160 braces username so I can print out 16019 10:15:42,200 --> 10:15:46,560 literally just that all right let's try 16020 10:15:45,160 --> 10:15:49,360 this and see what happens I'll clear my 16021 10:15:46,560 --> 10:15:51,436 terminal window run python of twitter. 16022 10:15:49,360 --> 10:15:53,000 and here we go 16023 10:15:51,436 --> 10:15:54,680 https 16024 10:15:53,000 --> 10:15:58,080 twitter.com 16025 10:15:54,680 --> 10:16:01,000 davidj cross my fingers and hit enter 16026 10:15:58,080 --> 10:16:03,276 okay now we're in business but it is 16027 10:16:01,000 --> 10:16:04,160 still a little fragile and so let me ask 16028 10:16:03,276 --> 10:16:07,080 the 16029 10:16:04,160 --> 10:16:09,040 group what problem should I now further 16030 10:16:07,080 --> 10:16:10,680 chip away at they've been said before 16031 10:16:09,040 --> 10:16:13,320 but let's be clear what's one or more 16032 10:16:10,680 --> 10:16:17,436 problems that still remain the protocols 16033 10:16:13,320 --> 10:16:20,320 and the uh domain prefixes for good the 16034 10:16:17,436 --> 10:16:24,000 protocol so HTTP versus https maybe the 16035 10:16:20,320 --> 10:16:25,756 subdomain www should it be there or not 16036 10:16:24,000 --> 10:16:27,596 and there's a few other mistakes here 16037 10:16:25,756 --> 10:16:29,480 too let me actually stay with the group 16038 10:16:27,596 --> 10:16:33,720 what are some other shortcomings of this 16039 10:16:29,480 --> 10:16:36,276 current solution um if we use a phrase 16040 10:16:33,720 --> 10:16:39,436 like you do before we are going to have 16041 10:16:36,276 --> 10:16:42,276 the same problem because it's not taken 16042 10:16:39,436 --> 10:16:44,640 account in the first part of the the 16043 10:16:42,276 --> 10:16:47,080 text example good I might still allow 16044 10:16:44,640 --> 10:16:48,680 for like some words uh some English to 16045 10:16:47,080 --> 10:16:50,800 the left of the URL because I didn't use 16046 10:16:48,680 --> 10:16:52,360 like my carrot symbol so I'll fix that 16047 10:16:50,800 --> 10:16:55,560 and any final observations on 16048 10:16:52,360 --> 10:16:58,436 shortcomings here uh well it could be a 16049 10:16:55,560 --> 10:17:00,596 HTTP or they could be like less than two 16050 10:16:58,436 --> 10:17:01,800 slashes okay so it could be HTP and I 16051 10:17:00,596 --> 10:17:03,756 think that was mentioned too in terms of 16052 10:17:01,800 --> 10:17:06,080 protocol there could be fewer than two 16053 10:17:03,756 --> 10:17:08,240 slashes that I'm not going to worry 16054 10:17:06,080 --> 10:17:10,560 about if the user gives me one slash 16055 10:17:08,240 --> 10:17:12,436 instead of two that's really user error 16056 10:17:10,560 --> 10:17:14,840 and I could be tolerant of it but you 16057 10:17:12,436 --> 10:17:16,360 know what at that point I'm okay yelling 16058 10:17:14,840 --> 10:17:17,916 at them with an error message saying 16059 10:17:16,360 --> 10:17:19,436 please fix your input otherwise we could 16060 10:17:17,916 --> 10:17:22,080 be here all day long trying to handle 16061 10:17:19,436 --> 10:17:24,360 all possible typos for now I think in 16062 10:17:22,080 --> 10:17:27,000 the interest of usability or user 16063 10:17:24,360 --> 10:17:29,320 experience ux let's at least be tolerant 16064 10:17:27,000 --> 10:17:31,480 of all possible valid inputs or 16065 10:17:29,320 --> 10:17:33,160 reasonable inputs if you will so let me 16066 10:17:31,480 --> 10:17:34,880 go here and let me start chipping away 16067 10:17:33,160 --> 10:17:38,560 at these here what are some problems we 16068 10:17:34,880 --> 10:17:40,756 can solve well let me propose that we 16069 10:17:38,560 --> 10:17:42,276 first address the issue of matching from 16070 10:17:40,756 --> 10:17:44,436 the beginning of the string so let me 16071 10:17:42,276 --> 10:17:47,200 add the carrot to the beginning and let 16072 10:17:44,436 --> 10:17:48,276 me add not a dollar sign at the end 16073 10:17:47,200 --> 10:17:49,756 though right because I don't want to 16074 10:17:48,276 --> 10:17:52,040 match all the way to the end because I 16075 10:17:49,756 --> 10:17:54,596 want to tolerate a username there so I 16076 10:17:52,040 --> 10:17:57,000 think we just want the carrot symbol 16077 10:17:54,596 --> 10:17:59,080 there there's a subtle bug that no one 16078 10:17:57,000 --> 10:18:02,000 yet mentioned and let me just kind of 16079 10:17:59,080 --> 10:18:04,000 highlight it and see if it jumps out at 16080 10:18:02,000 --> 10:18:08,116 you now it's a little subtle here on my 16081 10:18:04,000 --> 10:18:11,436 screen I've highlighted in blue a final 16082 10:18:08,116 --> 10:18:14,916 bug here maybe some Smiles on the screen 16083 10:18:11,436 --> 10:18:17,800 yeah can we take one hand here why am I 16084 10:18:14,916 --> 10:18:20,200 highlighting the dot in twitter.com even 16085 10:18:17,800 --> 10:18:22,720 though it definitely should be there so 16086 10:18:20,200 --> 10:18:25,480 the dot without a backlash mean any 16087 10:18:22,720 --> 10:18:27,560 character is up a new line yeah exactly 16088 10:18:25,480 --> 10:18:30,080 it's not it's means any character so I 16089 10:18:27,560 --> 10:18:33,680 could type in something like Twitter uh 16090 10:18:30,080 --> 10:18:35,596 question markc or Twitter anything com 16091 10:18:33,680 --> 10:18:38,000 and that would actually be tolerate it's 16092 10:18:35,596 --> 10:18:40,756 not really that bad cuz why would the 16093 10:18:38,000 --> 10:18:42,360 user do that but if I want to be correct 16094 10:18:40,756 --> 10:18:44,520 and I want to be able to test my own 16095 10:18:42,360 --> 10:18:46,596 code properly I should really get this 16096 10:18:44,520 --> 10:18:48,480 detail right so that's an easy fix too 16097 10:18:46,596 --> 10:18:50,400 but it's a common mistake anytime you're 16098 10:18:48,480 --> 10:18:53,200 writing regular Expressions that happen 16099 10:18:50,400 --> 10:18:56,240 to involve special symbols like dots in 16100 10:18:53,200 --> 10:18:58,276 a URL or domain name a dollar sign in 16101 10:18:56,240 --> 10:19:00,436 something involving currency remember 16102 10:18:58,276 --> 10:19:02,800 you might indeed Need to Escape it with 16103 10:19:00,436 --> 10:19:05,080 a backslash like this here all right let 16104 10:19:02,800 --> 10:19:07,916 me ask the group about the protocol 16105 10:19:05,080 --> 10:19:09,960 specifically https is a good thing in 16106 10:19:07,916 --> 10:19:12,116 the world it means secure there is 16107 10:19:09,960 --> 10:19:14,560 encryption being used so generally you 16108 10:19:12,116 --> 10:19:18,480 like to see https but you still see 16109 10:19:14,560 --> 10:19:21,080 people typing or copy pasting HTTP What 16110 10:19:18,480 --> 10:19:24,756 would be the simplest fix here to 16111 10:19:21,080 --> 10:19:27,800 tolerate as has been proposed both HTTP 16112 10:19:24,756 --> 10:19:30,436 and https I'm going to propose that I 16113 10:19:27,800 --> 10:19:34,596 could do this I could do HTTP vertical 16114 10:19:30,436 --> 10:19:36,480 bar or https which again Means A or B 16115 10:19:34,596 --> 10:19:38,800 but I think I can be smarter than that I 16116 10:19:36,480 --> 10:19:41,276 can keep my code a little more succinct 16117 10:19:38,800 --> 10:19:44,360 any recommendations here for 16118 10:19:41,276 --> 10:19:47,360 tolerating HTTP or 16119 10:19:44,360 --> 10:19:49,160 https we could try to put an question 16120 10:19:47,360 --> 10:19:51,080 mark behind the 16121 10:19:49,160 --> 10:19:52,480 perfect just use a question mark right 16122 10:19:51,080 --> 10:19:53,800 like both of those would be viable 16123 10:19:52,480 --> 10:19:55,520 Solutions if you want to be super 16124 10:19:53,800 --> 10:19:58,916 explicit in your code fine use 16125 10:19:55,520 --> 10:20:00,756 parentheses and say HTTP or https so 16126 10:19:58,916 --> 10:20:02,640 that you the reader your boss your 16127 10:20:00,756 --> 10:20:05,000 teacher just know exactly what you're 16128 10:20:02,640 --> 10:20:06,960 doing but you know if you keep taking 16129 10:20:05,000 --> 10:20:09,200 the more of a Bose approach all the time 16130 10:20:06,960 --> 10:20:10,640 it might actually become less readable 16131 10:20:09,200 --> 10:20:12,800 certainly once your regular Expressions 16132 10:20:10,640 --> 10:20:14,436 get this big instead of this big so 16133 10:20:12,800 --> 10:20:15,880 let's save space where we can and I 16134 10:20:14,436 --> 10:20:17,680 would argue that this is pretty 16135 10:20:15,880 --> 10:20:19,680 reasonable so long as you're in the 16136 10:20:17,680 --> 10:20:21,276 habit of reading regular expressions and 16137 10:20:19,680 --> 10:20:23,200 know that question mark does not mean a 16138 10:20:21,276 --> 10:20:25,596 literal question mark but it means zero 16139 10:20:23,200 --> 10:20:28,880 or one of the thing before I think we've 16140 10:20:25,596 --> 10:20:31,000 effectively made the S optional here now 16141 10:20:28,880 --> 10:20:34,436 what else can I do well suppose we want 16142 10:20:31,000 --> 10:20:36,800 to tolerate the www dot which may or may 16143 10:20:34,436 --> 10:20:40,436 not be there uh but it will work if you 16144 10:20:36,800 --> 10:20:43,200 go to a browser I could do this 16145 10:20:40,436 --> 10:20:44,680 www. uh wait I want a backs slash there 16146 10:20:43,200 --> 10:20:46,756 so I don't repeat the same mistake as 16147 10:20:44,680 --> 10:20:50,000 before but this is no good either 16148 10:20:46,756 --> 10:20:52,200 because I want to tolerate www being 16149 10:20:50,000 --> 10:20:54,040 there or not being there and now I've 16150 10:20:52,200 --> 10:20:56,680 just required that it be there but I 16151 10:20:54,040 --> 10:20:59,116 think I can take the same approach any 16152 10:20:56,680 --> 10:21:02,276 recommendations how do I make the www 16153 10:20:59,116 --> 10:21:06,200 dot optional just to hammer this home we 16154 10:21:02,276 --> 10:21:09,116 can like group uh make a 16155 10:21:06,200 --> 10:21:11,200 and question mark perfect so question 16156 10:21:09,116 --> 10:21:12,640 mark is the short answer again but we 16157 10:21:11,200 --> 10:21:15,040 have to be a little smarter this time as 16158 10:21:12,640 --> 10:21:17,000 Maria's noted we need parentheses now 16159 10:21:15,040 --> 10:21:19,720 because if I just put a question mark 16160 10:21:17,000 --> 10:21:21,276 after the dot that just means the dot is 16161 10:21:19,720 --> 10:21:24,560 optional and that's wrong because we 16162 10:21:21,276 --> 10:21:27,436 don't want the user to type in wwwt w i 16163 10:21:24,560 --> 10:21:29,916 TT e r we want the dot to be there or 16164 10:21:27,436 --> 10:21:32,240 just not at all with no www so we need 16165 10:21:29,916 --> 10:21:34,480 to group this whole thing together put a 16166 10:21:32,240 --> 10:21:38,040 parenthesis there and then a parenthesis 16167 10:21:34,480 --> 10:21:40,640 not after the third W after the dot so 16168 10:21:38,040 --> 10:21:43,200 that that whole thing is either there or 16169 10:21:40,640 --> 10:21:44,840 it's not there and what else could we 16170 10:21:43,200 --> 10:21:46,436 still do here you know there's going to 16171 10:21:44,840 --> 10:21:47,800 be one other thing we should tolerate 16172 10:21:46,436 --> 10:21:50,200 and it's been said before and I'll pluck 16173 10:21:47,800 --> 10:21:51,880 this one off what about the protocol 16174 10:21:50,200 --> 10:21:55,040 like what if the user just doesn't type 16175 10:21:51,880 --> 10:21:58,960 or doesn't copy paste the HTTP colon 16176 10:21:55,040 --> 10:22:00,800 slash or an https colon right honestly 16177 10:21:58,960 --> 10:22:02,960 you and I are not in the habit generally 16178 10:22:00,800 --> 10:22:05,040 of even typing the protocol anymore 16179 10:22:02,960 --> 10:22:07,680 nowadays you just let the browser figure 16180 10:22:05,040 --> 10:22:09,840 it out for you and automatically add it 16181 10:22:07,680 --> 10:22:11,840 instead so this one's going to look like 16182 10:22:09,840 --> 10:22:15,436 more of a mouthful but if I want this 16183 10:22:11,840 --> 10:22:17,480 whole thing here in blue to be optional 16184 10:22:15,436 --> 10:22:19,360 it's actually the same solution as Maria 16185 10:22:17,480 --> 10:22:21,520 offered a moment ago I'm going to go 16186 10:22:19,360 --> 10:22:24,000 ahead and put a parenthesis over here 16187 10:22:21,520 --> 10:22:27,240 and a parenthesis after the two slashes 16188 10:22:24,000 --> 10:22:29,160 and then a question mark so it's to make 16189 10:22:27,240 --> 10:22:31,880 that whole thing optional as well and 16190 10:22:29,160 --> 10:22:34,880 this is okay it's totally fine to make 16191 10:22:31,880 --> 10:22:37,800 this whole thing optional or inside of 16192 10:22:34,880 --> 10:22:39,916 it this little thing just the S optional 16193 10:22:37,800 --> 10:22:41,680 as well so long as I'm applying the same 16194 10:22:39,916 --> 10:22:43,640 principles again and again either on a 16195 10:22:41,680 --> 10:22:46,756 small scale or a bigger scale it's 16196 10:22:43,640 --> 10:22:48,756 totally fine to Nest one of these inside 16197 10:22:46,756 --> 10:22:51,640 of the other 16198 10:22:48,756 --> 10:22:53,960 questions now on any of these 16199 10:22:51,640 --> 10:22:57,116 refinements to this parsing this 16200 10:22:53,960 --> 10:23:01,756 analyzing of Twitter what if we put a 16201 10:22:57,116 --> 10:23:04,116 vertical bar besides this www do what if 16202 10:23:01,756 --> 10:23:06,080 we use a a vertical bar there so we 16203 10:23:04,116 --> 10:23:09,000 could do something like that too we 16204 10:23:06,080 --> 10:23:12,640 could do something like this uh instead 16205 10:23:09,000 --> 10:23:14,756 of the question mark I could do www. or 16206 10:23:12,640 --> 10:23:17,276 nothing and just leave that in the 16207 10:23:14,756 --> 10:23:18,680 parenthesis that too would be fine I 16208 10:23:17,276 --> 10:23:20,560 personally tend not to like that because 16209 10:23:18,680 --> 10:23:22,040 it's a little less obvious to me wait a 16210 10:23:20,560 --> 10:23:23,800 minute is that deliberate or did I 16211 10:23:22,040 --> 10:23:25,720 forget to finish my thought by putting 16212 10:23:23,800 --> 10:23:28,276 something after the vertical bar but 16213 10:23:25,720 --> 10:23:30,400 that too would be allowed there as well 16214 10:23:28,276 --> 10:23:32,000 if that's what you mean other questions 16215 10:23:30,400 --> 10:23:35,756 on where we left things here where we 16216 10:23:32,000 --> 10:23:39,480 made the protocol optional too what 16217 10:23:35,756 --> 10:23:41,080 coulden if we have parenthesis and then 16218 10:23:39,480 --> 10:23:43,000 inside we have another parenthesis and 16219 10:23:41,080 --> 10:23:44,840 another parenthesis to feel with each 16220 10:23:43,000 --> 10:23:47,680 other if you have parentheses inside of 16221 10:23:44,840 --> 10:23:49,916 parentheses that too is totally fine and 16222 10:23:47,680 --> 10:23:52,756 indeed that should be one of the 16223 10:23:49,916 --> 10:23:54,436 reassuring lessons today as complicated 16224 10:23:52,756 --> 10:23:56,720 as each of these regular Expressions has 16225 10:23:54,436 --> 10:23:58,720 admittedly gotten I'm just applying the 16226 10:23:56,720 --> 10:24:01,840 exact same principles in the exact same 16227 10:23:58,720 --> 10:24:03,320 syntax again and again so it's totally 16228 10:24:01,840 --> 10:24:04,720 fine to have parentheses inside of 16229 10:24:03,320 --> 10:24:06,480 parentheses if they're each solving 16230 10:24:04,720 --> 10:24:08,680 different problems and in fact the 16231 10:24:06,480 --> 10:24:11,916 lesson I would really emphasize the most 16232 10:24:08,680 --> 10:24:14,756 today is that you will not be happy if 16233 10:24:11,916 --> 10:24:16,916 you try to write out a whole complicated 16234 10:24:14,756 --> 10:24:19,160 regular expression all at once like if 16235 10:24:16,916 --> 10:24:20,916 you're anything like me you will fail 16236 10:24:19,160 --> 10:24:22,436 and you will have trouble finding the 16237 10:24:20,916 --> 10:24:24,436 mistake because my God look at these 16238 10:24:22,436 --> 10:24:26,916 things they are even to me all these 16239 10:24:24,436 --> 10:24:28,520 years later cryptic the better way I 16240 10:24:26,916 --> 10:24:31,000 would argue whether you're new to 16241 10:24:28,520 --> 10:24:33,560 programming or as old to it as I am is 16242 10:24:31,000 --> 10:24:35,080 to just take these baby steps these 16243 10:24:33,560 --> 10:24:36,960 incremental steps where you do something 16244 10:24:35,080 --> 10:24:39,200 simple you make sure it works you add 16245 10:24:36,960 --> 10:24:41,240 one more feature make sure it works add 16246 10:24:39,200 --> 10:24:42,756 one more feature make sure it works and 16247 10:24:41,240 --> 10:24:45,276 hopefully by the end because you've done 16248 10:24:42,756 --> 10:24:47,520 each of those steps one at a time the 16249 10:24:45,276 --> 10:24:49,000 whole thing will make sense to you but 16250 10:24:47,520 --> 10:24:52,756 you'll also have got gotten each of 16251 10:24:49,000 --> 10:24:55,756 those steps correct um at each turn so 16252 10:24:52,756 --> 10:24:57,596 please do avoid the inclination to try 16253 10:24:55,756 --> 10:24:59,400 to come up with long sophisticated 16254 10:24:57,596 --> 10:25:01,596 regular Expressions all at once because 16255 10:24:59,400 --> 10:25:03,080 it's just not a good use of a time if 16256 10:25:01,596 --> 10:25:04,720 you then stare at it trying to find a 16257 10:25:03,080 --> 10:25:06,436 mistake that you could have caught if 16258 10:25:04,720 --> 10:25:08,360 you did things more incrementally 16259 10:25:06,436 --> 10:25:10,436 instead all right there Still Remains 16260 10:25:08,360 --> 10:25:12,276 arguably at least one problem with this 16261 10:25:10,436 --> 10:25:15,480 solution in that even though I'm calling 16262 10:25:12,276 --> 10:25:18,320 re.sub to substitute the URL with 16263 10:25:15,480 --> 10:25:20,080 nothing quote unquote I then on my final 16264 10:25:18,320 --> 10:25:21,880 line of code line six I'm just blindly 16265 10:25:20,080 --> 10:25:23,400 assuming that it all worked and I'm 16266 10:25:21,880 --> 10:25:25,840 going to go ahead and print out the 16267 10:25:23,400 --> 10:25:27,276 username but what if the user if I clear 16268 10:25:25,840 --> 10:25:30,000 my screen here and run python of 16269 10:25:27,276 --> 10:25:31,680 twitter. doesn't even type a Twitter URL 16270 10:25:30,000 --> 10:25:33,320 what if they do something like 16271 10:25:31,680 --> 10:25:35,720 https 16272 10:25:33,320 --> 10:25:39,200 www.google.com slash like completely 16273 10:25:35,720 --> 10:25:41,240 unrelatedly for whatever reason enter 16274 10:25:39,200 --> 10:25:43,520 that is not their Twitter username so we 16275 10:25:41,240 --> 10:25:45,640 need to have some conditional logic I 16276 10:25:43,520 --> 10:25:48,520 would argue so that for this program's 16277 10:25:45,640 --> 10:25:50,436 sake we're only printing out or in a 16278 10:25:48,520 --> 10:25:53,116 backend system we're only saving into 16279 10:25:50,436 --> 10:25:55,360 our database or a CSV file the username 16280 10:25:53,116 --> 10:25:58,756 if we actually matched the proper 16281 10:25:55,360 --> 10:26:01,480 pattern so rather than use re.sub which 16282 10:25:58,756 --> 10:26:03,200 is useful for cleaning up data as we've 16283 10:26:01,480 --> 10:26:05,720 done here to get rid of something we 16284 10:26:03,200 --> 10:26:09,756 don't want there why don't we go back to 16285 10:26:05,720 --> 10:26:11,840 re. search where we began today and use 16286 10:26:09,756 --> 10:26:13,800 it to solve the same problem but in a 16287 10:26:11,840 --> 10:26:15,680 way that's conditional whereby I can 16288 10:26:13,800 --> 10:26:18,360 confidently say yes or no at the end of 16289 10:26:15,680 --> 10:26:20,240 my program here's the username or here 16290 10:26:18,360 --> 10:26:22,360 it is not so let me go ahead now and 16291 10:26:20,240 --> 10:26:24,596 I'll clear my terminal window here I'm 16292 10:26:22,360 --> 10:26:26,520 going to keep most of uh the I'm going 16293 10:26:24,596 --> 10:26:28,720 to keep the first two lines the same 16294 10:26:26,520 --> 10:26:31,000 where I import re and I get the URL from 16295 10:26:28,720 --> 10:26:33,840 the user but this time let's do this 16296 10:26:31,000 --> 10:26:36,400 let's this time search for using re. 16297 10:26:33,840 --> 10:26:37,640 search instead of re.sub the following 16298 10:26:36,400 --> 10:26:40,276 I'm going to start matching at the 16299 10:26:37,640 --> 10:26:42,756 beginning of the UR of the string 16300 10:26:40,276 --> 10:26:45,560 https uh question mark to make the S 16301 10:26:42,756 --> 10:26:48,640 optional colon SL slash then I'm G to 16302 10:26:45,560 --> 10:26:50,720 make my uh www 16303 10:26:48,640 --> 10:26:53,436 uh optional by putting that in question 16304 10:26:50,720 --> 10:26:55,400 marks there then a twitter.com with a 16305 10:26:53,436 --> 10:26:59,116 literal dot there so I'll stay ahead of 16306 10:26:55,400 --> 10:27:00,880 that issue too then a slash and then 16307 10:26:59,116 --> 10:27:03,720 well this is where David J ma is 16308 10:27:00,880 --> 10:27:05,276 supposed to go how do I detect this well 16309 10:27:03,720 --> 10:27:08,320 I think I'll just tolerate anything at 16310 10:27:05,276 --> 10:27:10,960 the end of the URL here all right dollar 16311 10:27:08,320 --> 10:27:12,436 sign at the very end close quote for the 16312 10:27:10,960 --> 10:27:14,116 moment I'm going to stipulate that we're 16313 10:27:12,436 --> 10:27:16,400 not going to worry about question marks 16314 10:27:14,116 --> 10:27:18,400 at the end or hashes like for fragment 16315 10:27:16,400 --> 10:27:20,800 IDs and URLs we're going to assume for 16316 10:27:18,400 --> 10:27:23,436 Simplicity now that the URL just ends 16317 10:27:20,800 --> 10:27:24,960 with the username alone now what am I 16318 10:27:23,436 --> 10:27:26,560 going to do well I want to search for 16319 10:27:24,960 --> 10:27:30,080 this URL specifically and I'm going to 16320 10:27:26,560 --> 10:27:31,756 ignore case so rei. ignore case uh uh 16321 10:27:30,080 --> 10:27:35,596 applying that same lesson learned from 16322 10:27:31,756 --> 10:27:37,680 before rei. search recall will return to 16323 10:27:35,596 --> 10:27:39,520 you the matches you've captured well 16324 10:27:37,680 --> 10:27:42,480 what do I want to capture well I want to 16325 10:27:39,520 --> 10:27:45,560 capture everything to the right of the 16326 10:27:42,480 --> 10:27:48,520 twitter.com URL here so let me surround 16327 10:27:45,560 --> 10:27:50,960 what should be the user's username with 16328 10:27:48,520 --> 10:27:52,720 parentheses not for making them optional 16329 10:27:50,960 --> 10:27:55,756 but to say capture this set of 16330 10:27:52,720 --> 10:27:58,116 characters Now ar. search recall returns 16331 10:27:55,756 --> 10:27:59,596 an answer matches will be my variable 16332 10:27:58,116 --> 10:28:03,640 name again but I could call it anything 16333 10:27:59,596 --> 10:28:06,040 I want and then I can do this if matches 16334 10:28:03,640 --> 10:28:09,040 now I know I can do this let's print out 16335 10:28:06,040 --> 10:28:12,320 the format string username colon and 16336 10:28:09,040 --> 10:28:14,360 then uh what do I want to print out well 16337 10:28:12,320 --> 10:28:17,800 I think I want to print out matches. 16338 10:28:14,360 --> 10:28:19,916 group one for my matched username all 16339 10:28:17,800 --> 10:28:22,080 right so what am I doing just to recap 16340 10:28:19,916 --> 10:28:24,200 line one I'm importing the library line 16341 10:28:22,080 --> 10:28:26,960 two I'm getting the URL from the user so 16342 10:28:24,200 --> 10:28:30,200 nothing new there line five I'm 16343 10:28:26,960 --> 10:28:32,720 searching the user's URL as indicated 16344 10:28:30,200 --> 10:28:35,596 here as the second argument for this 16345 10:28:32,720 --> 10:28:40,116 regular expression this pattern I have 16346 10:28:35,596 --> 10:28:42,320 surrounded the plus with parentheses so 16347 10:28:40,116 --> 10:28:44,960 that they are captured ultimately so I 16348 10:28:42,320 --> 10:28:48,116 can't extract in this final scenario the 16349 10:28:44,960 --> 10:28:51,360 user's username if I indeed got a match 16350 10:28:48,116 --> 10:28:54,000 and matches is non none it is actually 16351 10:28:51,360 --> 10:28:56,520 containing some match then and only then 16352 10:28:54,000 --> 10:28:59,116 print out username in this way let me 16353 10:28:56,520 --> 10:29:02,360 try this now if I run python of twitter. 16354 10:28:59,116 --> 10:29:05,200 and type in HTTPS 16355 10:29:02,360 --> 10:29:07,200 www.google.com now nothing gets printed 16356 10:29:05,200 --> 10:29:09,080 so I've at least solved the mistake we 16357 10:29:07,200 --> 10:29:11,560 just saw where I was just assuming that 16358 10:29:09,080 --> 10:29:13,880 my code worked now I'm making sure that 16359 10:29:11,560 --> 10:29:16,720 I have searched for and found the 16360 10:29:13,880 --> 10:29:20,520 Twitter URL prefix all right well let's 16361 10:29:16,720 --> 10:29:24,480 run this for real now python of twitter. 16362 10:29:20,520 --> 10:29:27,916 https twitter.com davidj maen but note I 16363 10:29:24,480 --> 10:29:30,116 could use HTTP I could use www I'm just 16364 10:29:27,916 --> 10:29:32,800 going to go ahead here and hit 16365 10:29:30,116 --> 10:29:36,436 enter huh 16366 10:29:32,800 --> 10:29:39,116 none what has gone 16367 10:29:36,436 --> 10:29:43,360 wrong this one's a bit more 16368 10:29:39,116 --> 10:29:45,880 subtle but why does matches. group one 16369 10:29:43,360 --> 10:29:48,040 contain nothing wait a minute let me 16370 10:29:45,880 --> 10:29:50,080 maybe I maybe I did this wrong Maybe 16371 10:29:48,040 --> 10:29:53,160 maybe do we need the www let me run it 16372 10:29:50,080 --> 10:29:59,480 again so here we go https let add it 16373 10:29:53,160 --> 10:29:59,480 www. twitter.com davidj mail all right 16374 10:29:59,840 --> 10:30:06,756 enter what is going on we have to say 16375 10:30:03,720 --> 10:30:09,040 group group I have to say group two well 16376 10:30:06,756 --> 10:30:11,720 wait all right because we had the the 16377 10:30:09,040 --> 10:30:14,000 subdomain was optional and to make it 16378 10:30:11,720 --> 10:30:16,480 optional I needed to use parentheses 16379 10:30:14,000 --> 10:30:19,756 here and so I then said zero or one okay 16380 10:30:16,480 --> 10:30:22,400 so that means that actually I'm 16381 10:30:19,756 --> 10:30:25,240 unintentionally but by Design capturing 16382 10:30:22,400 --> 10:30:28,040 the www dot or none of it if it wasn't 16383 10:30:25,240 --> 10:30:29,320 there before but I have a second match 16384 10:30:28,040 --> 10:30:30,960 over here because I have a second set of 16385 10:30:29,320 --> 10:30:33,360 parentheses so I think yep let me change 16386 10:30:30,960 --> 10:30:36,520 matches group one to matches group two 16387 10:30:33,360 --> 10:30:41,000 and let's rerun this python of twitter. 16388 10:30:36,520 --> 10:30:45,880 https www. Twitter let's do this uh 16389 10:30:41,000 --> 10:30:48,116 twitter.com David J ma enter and now 16390 10:30:45,880 --> 10:30:50,000 we've got access to the username let me 16391 10:30:48,116 --> 10:30:53,360 go ahead and tighten it up a little bit 16392 10:30:50,000 --> 10:30:54,916 further uh if you like uh our new friend 16393 10:30:53,360 --> 10:30:57,596 uh it's hard not to like if we like our 16394 10:30:54,916 --> 10:30:59,116 old friend the wallus uh operator let's 16395 10:30:57,596 --> 10:31:01,320 go ahead and add this just to tighten 16396 10:30:59,116 --> 10:31:03,040 things up let me go back to vs code here 16397 10:31:01,320 --> 10:31:04,596 and let me get rid of the unnecessary 16398 10:31:03,040 --> 10:31:07,360 condition there and combine it up here 16399 10:31:04,596 --> 10:31:08,916 if matches equals that but let's change 16400 10:31:07,360 --> 10:31:10,840 the single assignment operator to the 16401 10:31:08,916 --> 10:31:13,560 Wallace operator now I've tightened 16402 10:31:10,840 --> 10:31:16,116 things up further but I bet I bet I bet 16403 10:31:13,560 --> 10:31:18,436 there might be another solution here and 16404 10:31:16,116 --> 10:31:20,840 indeed it turns out 16405 10:31:18,436 --> 10:31:23,840 that we can come back to this final set 16406 10:31:20,840 --> 10:31:25,560 of syntax recall that when we introduced 16407 10:31:23,840 --> 10:31:27,916 these parentheses we did it so that we 16408 10:31:25,560 --> 10:31:29,436 could do a or b for instance with the 16409 10:31:27,916 --> 10:31:32,116 vertical bar though you can even combine 16410 10:31:29,436 --> 10:31:35,040 more than just one bar we use the group 16411 10:31:32,116 --> 10:31:36,840 to combine ideas like the www do and 16412 10:31:35,040 --> 10:31:39,640 then there's this admittedly weird 16413 10:31:36,840 --> 10:31:42,680 syntax at the bottom here up until now 16414 10:31:39,640 --> 10:31:44,560 not used there is a non capturing 16415 10:31:42,680 --> 10:31:46,276 version of parentheses if you want to 16416 10:31:44,560 --> 10:31:48,640 use parentheses logically because you 16417 10:31:46,276 --> 10:31:50,720 need to but you don't want to bother 16418 10:31:48,640 --> 10:31:52,640 capturing the result and this would 16419 10:31:50,720 --> 10:31:55,436 arguably be a better solution here 16420 10:31:52,640 --> 10:31:57,160 because yes if I go back to vs code I do 16421 10:31:55,436 --> 10:31:59,720 need to surround the 16422 10:31:57,160 --> 10:32:02,116 www.t with parenthesis at least as I've 16423 10:31:59,720 --> 10:32:04,200 written my Rex here because I wanted to 16424 10:32:02,116 --> 10:32:07,116 put the question mark after it but I 16425 10:32:04,200 --> 10:32:09,160 don't need the www dot coming back in 16426 10:32:07,116 --> 10:32:11,200 fact let's only extract the data we care 16427 10:32:09,160 --> 10:32:13,200 about just so there's no confusion down 16428 10:32:11,200 --> 10:32:16,320 the road for me or my colleagues or my 16429 10:32:13,200 --> 10:32:18,680 teachers so what could I do well the 16430 10:32:16,320 --> 10:32:21,596 syntax per this slide is to use a 16431 10:32:18,680 --> 10:32:23,680 question mark and a colon immediately 16432 10:32:21,596 --> 10:32:25,640 after the open parenthesis it looks 16433 10:32:23,680 --> 10:32:27,116 weird admittedly those of you who have 16434 10:32:25,640 --> 10:32:29,000 prior programming experience might 16435 10:32:27,116 --> 10:32:31,880 recognize the syntax from Turner 16436 10:32:29,000 --> 10:32:34,880 operators doing an if else allinone line 16437 10:32:31,880 --> 10:32:37,200 a question mark colon at the beginning 16438 10:32:34,880 --> 10:32:39,560 of that parenthetical means yes I'm 16439 10:32:37,200 --> 10:32:42,200 using parentheses to group these things 16440 10:32:39,560 --> 10:32:44,560 together but no you do not need to 16441 10:32:42,200 --> 10:32:47,480 capture them instead so I can change my 16442 10:32:44,560 --> 10:32:49,160 code back now to matches. group one I'll 16443 10:32:47,480 --> 10:32:52,880 clear my screen here run python of 16444 10:32:49,160 --> 10:32:56,800 twitter. I'll again run here uh 16445 10:32:52,880 --> 10:33:00,436 https twitter.com davidj maen with or 16446 10:32:56,800 --> 10:33:04,880 without the www and now I indeed get 16447 10:33:00,436 --> 10:33:08,200 back that username any questions then on 16448 10:33:04,880 --> 10:33:11,360 these final 16449 10:33:08,200 --> 10:33:13,480 techniques so first of all could we move 16450 10:33:11,360 --> 10:33:15,916 the carrot right at the beginning of 16451 10:33:13,480 --> 10:33:17,520 Twitter and then just start reading from 16452 10:33:15,916 --> 10:33:20,080 there and then get rid of everything 16453 10:33:17,520 --> 10:33:23,320 else before that the kind of 16454 10:33:20,080 --> 10:33:26,400 WWE uh issues that we had and then my 16455 10:33:23,320 --> 10:33:29,960 second question is how would we um use 16456 10:33:26,400 --> 10:33:32,960 kind of I guess it either a list or a a 16457 10:33:29,960 --> 10:33:36,160 dictionary to to sort the do kind of 16458 10:33:32,960 --> 10:33:39,040 thing because we have dood UK and that 16459 10:33:36,160 --> 10:33:41,320 kind of St how would we bring that into 16460 10:33:39,040 --> 10:33:43,640 uh the re function a good question but 16461 10:33:41,320 --> 10:33:45,960 no if I move the carrot before 16462 10:33:43,640 --> 10:33:48,400 twitter.com and throw away the protocol 16463 10:33:45,960 --> 10:33:51,080 and the www then then the user is going 16464 10:33:48,400 --> 10:33:53,880 to have to type in literally 16465 10:33:51,080 --> 10:33:55,160 twitter.com username they can't even 16466 10:33:53,880 --> 10:33:57,756 type in that other stuff so that would 16467 10:33:55,160 --> 10:34:01,040 be a regression a step back as for the 16468 10:33:57,756 --> 10:34:02,756 do and the.org and.edu and so forth the 16469 10:34:01,040 --> 10:34:04,960 short answer is there's many different 16470 10:34:02,756 --> 10:34:07,680 solutions here if I wanted to be 16471 10:34:04,960 --> 10:34:09,756 stringent about do and suppose that 16472 10:34:07,680 --> 10:34:11,840 Twitter probably owns multiple domain 16473 10:34:09,756 --> 10:34:14,200 names even though they tend to use just 16474 10:34:11,840 --> 10:34:16,360 this one suppose they have uh something 16475 10:34:14,200 --> 10:34:17,916 like.org as well you could use more 16476 10:34:16,360 --> 10:34:20,800 parentheses here and do something like 16477 10:34:17,916 --> 10:34:22,880 this Comm or org I'd probably want to go 16478 10:34:20,800 --> 10:34:24,720 in and add a question mark colon to make 16479 10:34:22,880 --> 10:34:27,720 it non-capturing because I don't care 16480 10:34:24,720 --> 10:34:30,200 which it is I just want to tolerate both 16481 10:34:27,720 --> 10:34:32,040 alternatively we could capture that we 16482 10:34:30,200 --> 10:34:35,480 could do something like this where we do 16483 10:34:32,040 --> 10:34:37,596 dot plus so as to actually capture that 16484 10:34:35,480 --> 10:34:43,200 and then we could do something like this 16485 10:34:37,596 --> 10:34:45,680 if matches. group one now equals equals 16486 10:34:43,200 --> 10:34:48,040 Comm then we could support this so you 16487 10:34:45,680 --> 10:34:50,160 could imagine factoring out the logic 16488 10:34:48,040 --> 10:34:52,480 just by extracting the top level domain 16489 10:34:50,160 --> 10:34:54,116 or TLD and then just using python code 16490 10:34:52,480 --> 10:34:56,916 maybe a list maybe a dictionary to 16491 10:34:54,116 --> 10:34:59,240 validate elsewhere outside of the redx 16492 10:34:56,916 --> 10:35:01,160 if it's in fact what you expect for now 16493 10:34:59,240 --> 10:35:04,116 though we kept things simple we focused 16494 10:35:01,160 --> 10:35:05,800 only on the Doom in this case let's make 16495 10:35:04,116 --> 10:35:07,360 one final change to this program so that 16496 10:35:05,800 --> 10:35:09,640 we're being a little more specific with 16497 10:35:07,360 --> 10:35:11,080 the definition of a Twitter username it 16498 10:35:09,640 --> 10:35:12,880 turns out that we're being a little too 16499 10:35:11,080 --> 10:35:15,240 generous over here whereby we're 16500 10:35:12,880 --> 10:35:17,160 accepting one or more of any character I 16501 10:35:15,240 --> 10:35:18,916 check the documentation for Twitter and 16502 10:35:17,160 --> 10:35:22,916 Twitter only only supports letters of 16503 10:35:18,916 --> 10:35:25,596 the alphabet A through Z numbers 0-9 or 16504 10:35:22,916 --> 10:35:27,840 underscore so not just dot which is 16505 10:35:25,596 --> 10:35:29,640 literally anything so let me go ahead 16506 10:35:27,840 --> 10:35:32,800 and be more precise here at the end of 16507 10:35:29,640 --> 10:35:35,436 my string let me go ahead and say this 16508 10:35:32,800 --> 10:35:37,756 set of symbols in square brackets I'm 16509 10:35:35,436 --> 10:35:40,276 going to go ahead and say a through z uh 16510 10:35:37,756 --> 10:35:42,040 0 through 9 and an underscore because 16511 10:35:40,276 --> 10:35:43,680 again those are the only valid symbols I 16512 10:35:42,040 --> 10:35:46,400 don't need to bother with an uppercase a 16513 10:35:43,680 --> 10:35:48,720 or a lowercase C because we're using re. 16514 10:35:46,400 --> 10:35:51,240 ignore case over here but I want to make 16515 10:35:48,720 --> 10:35:53,840 sure now that I tolerate not only one or 16516 10:35:51,240 --> 10:35:55,560 more of these symbols here but also 16517 10:35:53,840 --> 10:35:57,436 maybe some other stuff at the end of the 16518 10:35:55,560 --> 10:35:59,800 URL I'm now going to be okay with there 16519 10:35:57,436 --> 10:36:01,840 being a slash or a question mark or a 16520 10:35:59,800 --> 10:36:04,360 hash at the end of the URL all of which 16521 10:36:01,840 --> 10:36:06,800 are valid symbols in a URL but I know 16522 10:36:04,360 --> 10:36:09,080 from the Twitter's documentation are not 16523 10:36:06,800 --> 10:36:10,520 part of the username all right now I'm 16524 10:36:09,080 --> 10:36:14,276 going to go ahead and run python of 16525 10:36:10,520 --> 10:36:16,080 twitter. one final time typing in 16526 10:36:14,276 --> 10:36:19,040 HTTPS 16527 10:36:16,080 --> 10:36:20,960 twitter.com David M maybe with maybe 16528 10:36:19,040 --> 10:36:23,000 without a trailing slash but hopefully 16529 10:36:20,960 --> 10:36:25,480 with my biggest fingers crossed here I'm 16530 10:36:23,000 --> 10:36:28,000 going to go ahead now and hit enter and 16531 10:36:25,480 --> 10:36:30,276 thankfully my username is indeed David J 16532 10:36:28,000 --> 10:36:32,240 Ma so what more is there in the world of 16533 10:36:30,276 --> 10:36:34,640 regular expressions and this own Library 16534 10:36:32,240 --> 10:36:36,880 not just re. search and also re.sub 16535 10:36:34,640 --> 10:36:39,436 there's other functions too there's re 16536 10:36:36,880 --> 10:36:41,320 dosit via which you can split a string 16537 10:36:39,436 --> 10:36:43,756 not using a specific character or 16538 10:36:41,320 --> 10:36:46,360 characters like a comma and a space but 16539 10:36:43,756 --> 10:36:48,560 multiple characters as well and there's 16540 10:36:46,360 --> 10:36:51,040 even functions like re . findall which 16541 10:36:48,560 --> 10:36:52,880 can allow you to search for multiple 16542 10:36:51,040 --> 10:36:54,436 copies of the same pattern in different 16543 10:36:52,880 --> 10:36:56,480 places in a string so that you can 16544 10:36:54,436 --> 10:36:58,520 perhaps and manipulate more than just 16545 10:36:56,480 --> 10:37:00,680 one so at the end of the day now you've 16546 10:36:58,520 --> 10:37:02,480 really learned a whole other language 16547 10:37:00,680 --> 10:37:03,800 like that of regular expressions and 16548 10:37:02,480 --> 10:37:06,276 we've used them in Python but these 16549 10:37:03,800 --> 10:37:08,916 regular Expressions actually exist in so 16550 10:37:06,276 --> 10:37:11,756 many languages too among them JavaScript 16551 10:37:08,916 --> 10:37:13,840 and Java and Ruby and more so with this 16552 10:37:11,756 --> 10:37:15,320 new language even though it's admittedly 16553 10:37:13,840 --> 10:37:17,040 cryptic when you use it for the first 16554 10:37:15,320 --> 10:37:19,000 time you have this new found ability to 16555 10:37:17,040 --> 10:37:21,480 express these patterns that again you 16556 10:37:19,000 --> 10:37:24,480 can use to validate data to clean up 16557 10:37:21,480 --> 10:37:26,720 data or even extract data and from any 16558 10:37:24,480 --> 10:37:28,916 data set you might have in mind that's 16559 10:37:26,720 --> 10:37:31,916 it for this week we will see you next 16560 10:37:28,916 --> 10:37:31,916 time 16561 10:37:35,160 --> 10:37:45,000 [Music] 16562 10:37:47,030 --> 10:37:53,910 [Music] 16563 10:37:55,800 --> 10:38:00,276 all right this is cs50's Introduction to 16564 10:37:58,400 --> 10:38:01,640 programming with python my name is David 16565 10:38:00,276 --> 10:38:04,756 men and this is our week on 16566 10:38:01,640 --> 10:38:05,880 objectoriented programming or oop it 16567 10:38:04,756 --> 10:38:07,720 turns out that in the world of 16568 10:38:05,880 --> 10:38:09,400 programming there's different paradigms 16569 10:38:07,720 --> 10:38:11,596 of programming languages there's 16570 10:38:09,400 --> 10:38:13,240 different ways of solving problems with 16571 10:38:11,596 --> 10:38:15,080 code and it's a little hard to see this 16572 10:38:13,240 --> 10:38:17,080 at first if you've only learned one 16573 10:38:15,080 --> 10:38:19,200 language but over time if and when you 16574 10:38:17,080 --> 10:38:20,720 learn other languages besides python 16575 10:38:19,200 --> 10:38:22,200 you'll start to notice certain patterns 16576 10:38:20,720 --> 10:38:24,756 and certain capabilities of some 16577 10:38:22,200 --> 10:38:26,480 languages but not another thus far 16578 10:38:24,756 --> 10:38:28,320 within the world of python you and I 16579 10:38:26,480 --> 10:38:30,240 have largely been writing code that's 16580 10:38:28,320 --> 10:38:31,756 procedural in nature whereby we're 16581 10:38:30,240 --> 10:38:33,756 writing procedures we're writing 16582 10:38:31,756 --> 10:38:36,200 functions and we're sort of doing things 16583 10:38:33,756 --> 10:38:37,916 top to bottom everything is step by step 16584 10:38:36,200 --> 10:38:39,840 by step as you would expect in general 16585 10:38:37,916 --> 10:38:41,480 from an algorithm but along the way 16586 10:38:39,840 --> 10:38:43,756 we've actually dabbled in another 16587 10:38:41,480 --> 10:38:46,276 Paradigm known as functional programming 16588 10:38:43,756 --> 10:38:48,200 with python whereby we've been able to 16589 10:38:46,276 --> 10:38:50,680 pass functions around we even had an 16590 10:38:48,200 --> 10:38:52,880 anonymous function some weeks ago and 16591 10:38:50,680 --> 10:38:54,436 that's evidence of features of a 16592 10:38:52,880 --> 10:38:55,756 functional programming language even 16593 10:38:54,436 --> 10:38:58,040 though we've just scratched the surface 16594 10:38:55,756 --> 10:38:59,840 thereof today we focus on another 16595 10:38:58,040 --> 10:39:02,040 Paradigm and this one in more detail 16596 10:38:59,840 --> 10:39:03,680 namely objectoriented programming and 16597 10:39:02,040 --> 10:39:05,080 now while some of you might have prior 16598 10:39:03,680 --> 10:39:07,360 programming experience and have learned 16599 10:39:05,080 --> 10:39:10,200 languages like Java which are by Design 16600 10:39:07,360 --> 10:39:11,960 fundamentally objectoriented python 16601 10:39:10,200 --> 10:39:14,240 indeed allows you a bit of flexibility 16602 10:39:11,960 --> 10:39:17,360 when it comes to how you solve problems 16603 10:39:14,240 --> 10:39:19,320 with code but it turns out oop object 16604 10:39:17,360 --> 10:39:21,720 ented programming is a pretty compelling 16605 10:39:19,320 --> 10:39:23,840 solution to problems that you invariably 16606 10:39:21,720 --> 10:39:26,436 encounter as your programs get longer 16607 10:39:23,840 --> 10:39:28,436 larger and more complicated so indeed 16608 10:39:26,436 --> 10:39:31,160 oop for our purposes is going to be a 16609 10:39:28,436 --> 10:39:33,116 solution to a problem that builds on so 16610 10:39:31,160 --> 10:39:35,320 many of the lessons past so let's go 16611 10:39:33,116 --> 10:39:38,000 ahead and do this let's start by writing 16612 10:39:35,320 --> 10:39:39,960 a program very procedurally by opening 16613 10:39:38,000 --> 10:39:43,080 up VSS code here I'm going to go ahead 16614 10:39:39,960 --> 10:39:44,680 and create a program called student. and 16615 10:39:43,080 --> 10:39:47,596 in this program I want to do something 16616 10:39:44,680 --> 10:39:49,520 relatively simple initially uh as we 16617 10:39:47,596 --> 10:39:52,080 might have done some weeks ago now where 16618 10:39:49,520 --> 10:39:53,840 I just ask a user for their name and 16619 10:39:52,080 --> 10:39:56,200 maybe in the context of the Harry Potter 16620 10:39:53,840 --> 10:39:58,560 Universe their house and just print out 16621 10:39:56,200 --> 10:40:00,520 where that student is from and let's 16622 10:39:58,560 --> 10:40:02,560 gradually enhance this program by adding 16623 10:40:00,520 --> 10:40:05,116 more and more features to it and see if 16624 10:40:02,560 --> 10:40:06,480 we don't stumble upon problems that up 16625 10:40:05,116 --> 10:40:08,720 until now we might not have had very 16626 10:40:06,480 --> 10:40:10,520 elegant well-designed solutions to but 16627 10:40:08,720 --> 10:40:12,116 if we introduce explicitly 16628 10:40:10,520 --> 10:40:14,160 object-oriented programming as a 16629 10:40:12,116 --> 10:40:16,360 programming technique I bet we can clean 16630 10:40:14,160 --> 10:40:18,160 up our code and set the stage for 16631 10:40:16,360 --> 10:40:20,116 writing even more sophisticated programs 16632 10:40:18,160 --> 10:40:22,480 longer programs down the line so in 16633 10:40:20,116 --> 10:40:24,840 student. piy let me go ahead and do a 16634 10:40:22,480 --> 10:40:26,756 name variable setting it equal to the 16635 10:40:24,840 --> 10:40:29,040 return value of input and just prompt 16636 10:40:26,756 --> 10:40:30,560 the user for their name like this and 16637 10:40:29,040 --> 10:40:32,640 then let me go ahead and do the same for 16638 10:40:30,560 --> 10:40:34,960 a house variable and prompt the user for 16639 10:40:32,640 --> 10:40:37,000 their house using input like this and 16640 10:40:34,960 --> 10:40:39,000 let's do something super simple now 16641 10:40:37,000 --> 10:40:41,880 let's just go ahead and print out an F 16642 10:40:39,000 --> 10:40:44,240 string that says something like name 16643 10:40:41,880 --> 10:40:45,840 from house just so that I can confirm 16644 10:40:44,240 --> 10:40:47,960 that the contents of these variables are 16645 10:40:45,840 --> 10:40:49,320 indeed as I expect I'm not do any error 16646 10:40:47,960 --> 10:40:50,596 checking or trimming or anything like 16647 10:40:49,320 --> 10:40:52,276 that for now I'm really just going to 16648 10:40:50,596 --> 10:40:54,160 spit back out whatever the user just 16649 10:40:52,276 --> 10:40:57,080 typed in all right let me go ahead and 16650 10:40:54,160 --> 10:41:00,000 run python of studenty let's use our 16651 10:40:57,080 --> 10:41:02,040 go-to like Harry as in Harry Potter from 16652 10:41:00,000 --> 10:41:04,000 Gryffindor and when I hit enter now 16653 10:41:02,040 --> 10:41:06,116 let's see if I see that Harry from 16654 10:41:04,000 --> 10:41:07,880 Gryffindor is indeed the case all right 16655 10:41:06,116 --> 10:41:09,960 so I think we have a working program at 16656 10:41:07,880 --> 10:41:11,640 this point but let's now introduce some 16657 10:41:09,960 --> 10:41:13,276 of those Lessons Learned way back from 16658 10:41:11,640 --> 10:41:16,200 week zero where we started writing our 16659 10:41:13,276 --> 10:41:18,276 own functions not necessarily because it 16660 10:41:16,200 --> 10:41:20,640 solves the problem more correctly I dare 16661 10:41:18,276 --> 10:41:22,756 say this is correct as is but it begins 16662 10:41:20,640 --> 10:41:25,040 to give us building blocks that we can 16663 10:41:22,756 --> 10:41:27,480 extend so as to solve more complicated 16664 10:41:25,040 --> 10:41:29,680 programs so let me go back up to 16665 10:41:27,480 --> 10:41:31,916 student. and let's go ahead now and do 16666 10:41:29,680 --> 10:41:33,596 this let's put the entire logic I just 16667 10:41:31,916 --> 10:41:35,520 wrote inside of our typical method 16668 10:41:33,596 --> 10:41:37,320 called Main and let me indent those 16669 10:41:35,520 --> 10:41:40,160 three lines so that at least they're now 16670 10:41:37,320 --> 10:41:42,560 combined into one main method but 16671 10:41:40,160 --> 10:41:44,680 instead of using input on line two and 16672 10:41:42,560 --> 10:41:45,916 input on line three why don't we go 16673 10:41:44,680 --> 10:41:48,160 ahead and assume for the moment that 16674 10:41:45,916 --> 10:41:49,640 we've got some function called get name 16675 10:41:48,160 --> 10:41:51,080 in the world and let's go ahead and 16676 10:41:49,640 --> 10:41:52,756 assume we've got another function like 16677 10:41:51,080 --> 10:41:55,080 get house in the world that don't take 16678 10:41:52,756 --> 10:41:56,916 parameters but their purpose in life is 16679 10:41:55,080 --> 10:41:59,320 by their Nam going to be to get the 16680 10:41:56,916 --> 10:42:01,160 user's name and to get their user house 16681 10:41:59,320 --> 10:42:04,040 respectively and then I'm going to print 16682 10:42:01,160 --> 10:42:05,276 out the exact same F string as before I 16683 10:42:04,040 --> 10:42:07,240 of course need to implement these 16684 10:42:05,276 --> 10:42:08,916 functions now so let me go lower in my 16685 10:42:07,240 --> 10:42:11,400 file and Define a function called get 16686 10:42:08,916 --> 10:42:12,360 uncore name nothing in these parentheses 16687 10:42:11,400 --> 10:42:14,080 because it's not going to take a 16688 10:42:12,360 --> 10:42:16,596 parameter and I'm going to go ahead and 16689 10:42:14,080 --> 10:42:18,756 do something like name equals input 16690 10:42:16,596 --> 10:42:20,000 quote unquote name just like before and 16691 10:42:18,756 --> 10:42:22,160 then I'm going to go ahead and return 16692 10:42:20,000 --> 10:42:24,436 name so it's a super simple function but 16693 10:42:22,160 --> 10:42:26,240 it's a an abstraction I now have a 16694 10:42:24,436 --> 10:42:27,640 function called get name whose 16695 10:42:26,240 --> 10:42:29,276 implementation details I don't have to 16696 10:42:27,640 --> 10:42:31,080 care about anymore I just know that the 16697 10:42:29,276 --> 10:42:33,000 function exists and I can tighten this 16698 10:42:31,080 --> 10:42:35,160 up in fact I don't really need a name 16699 10:42:33,000 --> 10:42:36,720 variable on line 8 if I'm immediately 16700 10:42:35,160 --> 10:42:38,840 going to return that same name variable 16701 10:42:36,720 --> 10:42:40,240 on line nine so let me just tighten this 16702 10:42:38,840 --> 10:42:42,000 up a little bit even though it doesn't 16703 10:42:40,240 --> 10:42:44,436 change the functionality and just 16704 10:42:42,000 --> 10:42:47,640 immediately return the return value of 16705 10:42:44,436 --> 10:42:50,200 the inputs uh function call here let's 16706 10:42:47,640 --> 10:42:51,756 do something very similar now for get 16707 10:42:50,200 --> 10:42:53,320 house which will similarly take no 16708 10:42:51,756 --> 10:42:55,480 arguments I'm going to go ahead and 16709 10:42:53,320 --> 10:42:57,320 return the return value of input this 16710 10:42:55,480 --> 10:42:59,680 time prompting the user for their house 16711 10:42:57,320 --> 10:43:01,880 and I need one final detail at the very 16712 10:42:59,680 --> 10:43:04,720 bottom let's continue our habit of doing 16713 10:43:01,880 --> 10:43:07,400 if the name of this file equals equals 16714 10:43:04,720 --> 10:43:09,560 quote unquote main then let's go ahead 16715 10:43:07,400 --> 10:43:11,200 and actually call Main and recall that 16716 10:43:09,560 --> 10:43:13,080 we have that in place so that if this 16717 10:43:11,200 --> 10:43:14,960 eventually becomes part of a module a 16718 10:43:13,080 --> 10:43:18,276 library of sorts I don't accidentally 16719 10:43:14,960 --> 10:43:20,880 call Main blindly I only do it if I mean 16720 10:43:18,276 --> 10:43:23,200 to run main from the command line on 16721 10:43:20,880 --> 10:43:25,360 this file all right so if I didn't make 16722 10:43:23,200 --> 10:43:27,436 any mistakes here let me go ahead and in 16723 10:43:25,360 --> 10:43:31,040 my terminal window again run python of 16724 10:43:27,436 --> 10:43:34,116 student. enter let's type in Harry enter 16725 10:43:31,040 --> 10:43:36,640 let's type in Gryffindor enter and we're 16726 10:43:34,116 --> 10:43:39,000 set Harry from Gryffindor seems to still 16727 10:43:36,640 --> 10:43:41,680 be working so we haven't really solved 16728 10:43:39,000 --> 10:43:43,800 the problem anymore correctly but I've 16729 10:43:41,680 --> 10:43:45,276 laid the foundation to maybe now do some 16730 10:43:43,800 --> 10:43:48,160 more interesting things because I've 16731 10:43:45,276 --> 10:43:50,360 have these building blocks in place 16732 10:43:48,160 --> 10:43:52,000 all right but let me propose that we 16733 10:43:50,360 --> 10:43:54,596 could be doing this a little bit 16734 10:43:52,000 --> 10:43:55,960 differently get name get house is fine 16735 10:43:54,596 --> 10:43:58,200 but at the end of the day I'm really 16736 10:43:55,960 --> 10:44:00,400 trying to get a student from the user I 16737 10:43:58,200 --> 10:44:03,040 want their name and their house not just 16738 10:44:00,400 --> 10:44:05,756 one or the other so maybe it would be a 16739 10:44:03,040 --> 10:44:08,000 little cleaner still to define a 16740 10:44:05,756 --> 10:44:10,400 function called get student and let get 16741 10:44:08,000 --> 10:44:13,040 student do all of this work for us now 16742 10:44:10,400 --> 10:44:14,916 theoretically get student could call get 16743 10:44:13,040 --> 10:44:16,596 name and could call get house but 16744 10:44:14,916 --> 10:44:19,160 because these functions are so short I 16745 10:44:16,596 --> 10:44:20,756 think I'm okay with just defining one 16746 10:44:19,160 --> 10:44:22,596 function called get student that 16747 10:44:20,756 --> 10:44:24,040 similarly won't take any arguments but 16748 10:44:22,596 --> 10:44:26,200 it's going to do two things it's going 16749 10:44:24,040 --> 10:44:28,320 to get the student's name by prompting 16750 10:44:26,200 --> 10:44:29,840 them with input as before and it's going 16751 10:44:28,320 --> 10:44:34,276 to get the student house by also 16752 10:44:29,840 --> 10:44:36,480 prompting them as before and then now hm 16753 10:44:34,276 --> 10:44:38,116 I want to return the student but I think 16754 10:44:36,480 --> 10:44:40,160 I might have painted myself into a 16755 10:44:38,116 --> 10:44:42,400 corner here because I now have two 16756 10:44:40,160 --> 10:44:44,400 variables name and house and yet up 16757 10:44:42,400 --> 10:44:47,080 until now we've pretty much returned one 16758 10:44:44,400 --> 10:44:49,160 or the other we've returned one value so 16759 10:44:47,080 --> 10:44:51,160 any suggestions for how we can perhaps 16760 10:44:49,160 --> 10:44:54,040 solve this problem that I just created 16761 10:44:51,160 --> 10:44:57,400 for myself whereby I want to return 16762 10:44:54,040 --> 10:44:59,960 really a student but I currently have a 16763 10:44:57,400 --> 10:45:02,400 name variable and a house variable I'd 16764 10:44:59,960 --> 10:45:04,916 minimally like to return both of those I 16765 10:45:02,400 --> 10:45:07,240 believe that we can return a dictionary 16766 10:45:04,916 --> 10:45:09,080 includes the name and the house yeah so 16767 10:45:07,240 --> 10:45:11,560 we absolutely could return a dictionary 16768 10:45:09,080 --> 10:45:13,960 a dict object in Python whereby maybe 16769 10:45:11,560 --> 10:45:15,880 one key is name one key is house and the 16770 10:45:13,960 --> 10:45:18,240 values thereof are exactly the values of 16771 10:45:15,880 --> 10:45:20,080 these variables we could totally do that 16772 10:45:18,240 --> 10:45:21,640 uh I worry that that might be getting a 16773 10:45:20,080 --> 10:45:24,596 little complicated I wonder if there's a 16774 10:45:21,640 --> 10:45:26,720 simpler way instead any other instincts 16775 10:45:24,596 --> 10:45:29,080 even if you're not sure it would work 16776 10:45:26,720 --> 10:45:30,916 return both name and house return both 16777 10:45:29,080 --> 10:45:32,480 name and house I I like the sound of 16778 10:45:30,916 --> 10:45:33,960 that it sounds simple I don't have to 16779 10:45:32,480 --> 10:45:36,520 figure out what a dictionary is going to 16780 10:45:33,960 --> 10:45:38,200 look like and in fact this too would be 16781 10:45:36,520 --> 10:45:40,320 a valid approach even if you've not seen 16782 10:45:38,200 --> 10:45:43,276 this before it turns out in Python that 16783 10:45:40,320 --> 10:45:45,200 you can kind of return multiple values 16784 10:45:43,276 --> 10:45:46,436 but that's a bit of a white lie or we 16785 10:45:45,200 --> 10:45:48,080 could take Muhammad's approach of 16786 10:45:46,436 --> 10:45:50,080 actually return rning a dictionary and 16787 10:45:48,080 --> 10:45:51,720 putting multiple keys there in so here 16788 10:45:50,080 --> 10:45:53,276 again we have yet another example of how 16789 10:45:51,720 --> 10:45:54,756 you can solve the same problem in at 16790 10:45:53,276 --> 10:45:57,596 least two ways and I dare say we're 16791 10:45:54,756 --> 10:45:59,640 about to see even more so one way you 16792 10:45:57,596 --> 10:46:02,640 could solve this problem whereby you 16793 10:45:59,640 --> 10:46:05,116 want to return multiple values would be 16794 10:46:02,640 --> 10:46:08,116 to do something like this I could go 16795 10:46:05,116 --> 10:46:10,560 ahead and literally return not just name 16796 10:46:08,116 --> 10:46:12,160 but I could put a comma and also return 16797 10:46:10,560 --> 10:46:14,000 house this is not necessarily something 16798 10:46:12,160 --> 10:46:15,480 you can do in other languages if you 16799 10:46:14,000 --> 10:46:17,680 have programmed in other languages 16800 10:46:15,480 --> 10:46:20,400 before it depends on the language but it 16801 10:46:17,680 --> 10:46:22,520 looks like thanks to this comma maybe I 16802 10:46:20,400 --> 10:46:25,116 can in fact return two values as 16803 10:46:22,520 --> 10:46:27,520 actually proposed well if I'm returning 16804 10:46:25,116 --> 10:46:29,756 two values in this way on line 10 how do 16805 10:46:27,520 --> 10:46:31,880 I get both values at the same time well 16806 10:46:29,756 --> 10:46:34,720 there's a couple of ways let me go up to 16807 10:46:31,880 --> 10:46:36,160 my main function I know minimally I'm 16808 10:46:34,720 --> 10:46:38,276 going to have to change the get name and 16809 10:46:36,160 --> 10:46:41,436 get house to get student but what am I 16810 10:46:38,276 --> 10:46:43,560 going to store the return value in I 16811 10:46:41,436 --> 10:46:45,400 think I could actually do this and we 16812 10:46:43,560 --> 10:46:47,200 have seen this technique before where 16813 10:46:45,400 --> 10:46:49,360 you can unpack so to speak speak 16814 10:46:47,200 --> 10:46:51,640 sequences of values that are coming back 16815 10:46:49,360 --> 10:46:53,840 and indeed consider this to be exactly 16816 10:46:51,640 --> 10:46:55,520 that name comma house is some kind of 16817 10:46:53,840 --> 10:46:57,916 sequence that I'm returning of values 16818 10:46:55,520 --> 10:46:59,596 name comma house so if I want to unpack 16819 10:46:57,916 --> 10:47:01,960 those and store the return values in two 16820 10:46:59,596 --> 10:47:03,960 separate variables I can in fact use the 16821 10:47:01,960 --> 10:47:06,480 commas on the left hand side of my 16822 10:47:03,960 --> 10:47:08,640 assignment operator the equal sign to do 16823 10:47:06,480 --> 10:47:11,320 just that now to be clear I don't need 16824 10:47:08,640 --> 10:47:13,480 to call these variables name and house 16825 10:47:11,320 --> 10:47:16,000 here I could simplify this and use just 16826 10:47:13,480 --> 10:47:19,240 n here and H here and then I could 16827 10:47:16,000 --> 10:47:22,116 return just n and H but I would argue 16828 10:47:19,240 --> 10:47:24,000 that's not very uh clear to the reader 16829 10:47:22,116 --> 10:47:25,480 as to what's going on so I think in this 16830 10:47:24,000 --> 10:47:27,320 case even though it's a coincidence that 16831 10:47:25,480 --> 10:47:29,960 I've used the same variable names in get 16832 10:47:27,320 --> 10:47:31,436 student and get Main and in Maine it's a 16833 10:47:29,960 --> 10:47:33,596 little more readable to someone like me 16834 10:47:31,436 --> 10:47:35,680 so I'm going to leave it as is well 16835 10:47:33,596 --> 10:47:37,160 let's go ahead and see now if this works 16836 10:47:35,680 --> 10:47:39,360 let me clear my screen down here and run 16837 10:47:37,160 --> 10:47:41,320 python of student. enter let's again 16838 10:47:39,360 --> 10:47:44,276 type in Harry let's again type in 16839 10:47:41,320 --> 10:47:46,960 Gryffindor enter and voila we still see 16840 10:47:44,276 --> 10:47:49,116 that Harry is from Gryffindor but what 16841 10:47:46,960 --> 10:47:51,360 are we actually doing here what are we 16842 10:47:49,116 --> 10:47:53,880 actually doing by returning this value 16843 10:47:51,360 --> 10:47:56,880 well it turns out that what we've just 16844 10:47:53,880 --> 10:48:00,160 done is used a tupple a tupple is 16845 10:47:56,880 --> 10:48:02,916 another type of data in Python that's a 16846 10:48:00,160 --> 10:48:05,000 collection of values X comma y or X 16847 10:48:02,916 --> 10:48:07,436 comma y comma Z it's similar in spirit 16848 10:48:05,000 --> 10:48:09,840 to a list in that sense but it's 16849 10:48:07,436 --> 10:48:11,880 immutable it's not mutable now what does 16850 10:48:09,840 --> 10:48:13,680 that mean a list as we've seen it before 16851 10:48:11,880 --> 10:48:15,800 is a data structure in Python that you 16852 10:48:13,680 --> 10:48:18,000 can change the values of you can go into 16853 10:48:15,800 --> 10:48:19,320 bracket zero for the first location and 16854 10:48:18,000 --> 10:48:21,080 change the value there you can go to 16855 10:48:19,320 --> 10:48:23,200 bracket one bracket two bracket three 16856 10:48:21,080 --> 10:48:25,080 and actually change the values in lists 16857 10:48:23,200 --> 10:48:27,040 but if you have no intention of changing 16858 10:48:25,080 --> 10:48:29,640 the values of variables and you want to 16859 10:48:27,040 --> 10:48:31,200 return effectively multiple values you 16860 10:48:29,640 --> 10:48:33,916 don't have to even return it as a list 16861 10:48:31,200 --> 10:48:36,080 you can return it as a tle instead just 16862 10:48:33,916 --> 10:48:38,800 by using a comma and it turns out we can 16863 10:48:36,080 --> 10:48:41,436 make explicit that here's the white lie 16864 10:48:38,800 --> 10:48:43,916 I'm not actually returning two values 16865 10:48:41,436 --> 10:48:45,800 per se whenever you use a comma in this 16866 10:48:43,916 --> 10:48:48,436 way on line nine you're actually 16867 10:48:45,800 --> 10:48:51,480 returning one one value which is a 16868 10:48:48,436 --> 10:48:52,916 tupple inside of that tupple now are two 16869 10:48:51,480 --> 10:48:55,320 values so it's similar in spirit to 16870 10:48:52,916 --> 10:48:58,000 returning one list with two things here 16871 10:48:55,320 --> 10:48:59,840 I'm returning one tupple with two things 16872 10:48:58,000 --> 10:49:01,680 and the mere fact that I've used a comma 16873 10:48:59,840 --> 10:49:03,436 and nothing else tells python that I 16874 10:49:01,680 --> 10:49:05,200 indeed want to return a tle but there's 16875 10:49:03,436 --> 10:49:07,680 more explicit syntax that we can use 16876 10:49:05,200 --> 10:49:10,520 instead I can actually more verbosely 16877 10:49:07,680 --> 10:49:12,756 put explicit parentheses around the 16878 10:49:10,520 --> 10:49:14,480 values of this tupple just to make more 16879 10:49:12,756 --> 10:49:16,400 clear to me to the reader that this 16880 10:49:14,480 --> 10:49:18,560 isn't two values per se this is one 16881 10:49:16,400 --> 10:49:20,200 value with two things inside of it and 16882 10:49:18,560 --> 10:49:22,320 what I can actually do then too is I 16883 10:49:20,200 --> 10:49:23,960 don't have to unpack this up here so to 16884 10:49:22,320 --> 10:49:26,680 speak I can actually go up here and 16885 10:49:23,960 --> 10:49:29,436 maybe give a more apt name like student 16886 10:49:26,680 --> 10:49:30,916 and I can name the value or rather name 16887 10:49:29,436 --> 10:49:33,240 the variable in which I'm storing the 16888 10:49:30,916 --> 10:49:35,680 return value of get student as quote 16889 10:49:33,240 --> 10:49:37,360 unquote student so maybe this is a 16890 10:49:35,680 --> 10:49:39,916 little better design now because I'm 16891 10:49:37,360 --> 10:49:41,880 sort of abstracting away what a student 16892 10:49:39,916 --> 10:49:44,000 is it's implemented at the moment as a 16893 10:49:41,880 --> 10:49:46,756 tupple with two values but at least now 16894 10:49:44,000 --> 10:49:49,040 I have a variable called what I mean a 16895 10:49:46,756 --> 10:49:51,116 student but there's going to be a catch 16896 10:49:49,040 --> 10:49:53,560 on line three I still want to print out 16897 10:49:51,116 --> 10:49:55,400 that Student's name and their house but 16898 10:49:53,560 --> 10:49:56,880 I don't have a name variable anymore and 16899 10:49:55,400 --> 10:49:59,040 I don't have a house and I also don't 16900 10:49:56,880 --> 10:50:02,360 have a dictionary as was proposed 16901 10:49:59,040 --> 10:50:05,116 earlier so I can't even go at those keys 16902 10:50:02,360 --> 10:50:07,320 by name but what a tupple is it's very 16903 10:50:05,116 --> 10:50:09,400 similar in spirit to a list but it is 16904 10:50:07,320 --> 10:50:11,480 indeed just immutable and what I mean by 16905 10:50:09,400 --> 10:50:14,360 that is I can still index into it 16906 10:50:11,480 --> 10:50:17,480 numerically by saying student square 16907 10:50:14,360 --> 10:50:19,276 bracket Z for the item in the first 16908 10:50:17,480 --> 10:50:20,960 location in that Tuple and then over 16909 10:50:19,276 --> 10:50:23,320 here instead of house I can say student 16910 10:50:20,960 --> 10:50:25,360 bracket one student bracket one is going 16911 10:50:23,320 --> 10:50:26,960 to give me the second location in that 16912 10:50:25,360 --> 10:50:28,960 tupple let me go ahead and clear my 16913 10:50:26,960 --> 10:50:31,596 terminal window again run python of 16914 10:50:28,960 --> 10:50:34,680 student. let's type in Harry let's type 16915 10:50:31,596 --> 10:50:37,320 in Gryffindor enter and we still have 16916 10:50:34,680 --> 10:50:40,320 some working code let me pause here now 16917 10:50:37,320 --> 10:50:43,640 and see if there are any questions on 16918 10:50:40,320 --> 10:50:46,640 this technique of returning a tupple and 16919 10:50:43,640 --> 10:50:48,756 indexing into it in this way I guess 16920 10:50:46,640 --> 10:50:52,080 what's a like a actual use case where 16921 10:50:48,756 --> 10:50:53,916 you would use a tupple versus you know a 16922 10:50:52,080 --> 10:50:55,276 list or something else that's similar 16923 10:50:53,916 --> 10:50:57,320 it's a really good question when would 16924 10:50:55,276 --> 10:50:59,480 you use a tuple versus a list when you 16925 10:50:57,320 --> 10:51:01,436 want to program defensively or in 16926 10:50:59,480 --> 10:51:03,436 general when you know that the values in 16927 10:51:01,436 --> 10:51:05,040 this variable shouldn't change so why 16928 10:51:03,436 --> 10:51:06,916 would you use a data type that allows 16929 10:51:05,040 --> 10:51:09,680 them to be changed it just invites 16930 10:51:06,916 --> 10:51:11,520 mistakes bugs down the line either by 16931 10:51:09,680 --> 10:51:13,880 you or colleagues who are interacting 16932 10:51:11,520 --> 10:51:15,916 with your code so tupple is just another 16933 10:51:13,880 --> 10:51:17,800 way where you can increase the 16934 10:51:15,916 --> 10:51:19,880 probability of correctness by just not 16935 10:51:17,800 --> 10:51:21,960 letting anyone yourself included change 16936 10:51:19,880 --> 10:51:24,320 the contents therein so it's just 16937 10:51:21,960 --> 10:51:27,040 another tool in your toolkit but let's 16938 10:51:24,320 --> 10:51:28,800 make clear then what I mean by immutable 16939 10:51:27,040 --> 10:51:31,040 again I claim that immutable means that 16940 10:51:28,800 --> 10:51:32,960 you cannot change the value well let's 16941 10:51:31,040 --> 10:51:35,160 go ahead and try to do this let me go 16942 10:51:32,960 --> 10:51:38,276 ahead and run this program once more as 16943 10:51:35,160 --> 10:51:42,596 is python of student. let me go ahead 16944 10:51:38,276 --> 10:51:44,160 and type in for instance uh how about uh 16945 10:51:42,596 --> 10:51:45,960 padma's name and I'm going to go ahead 16946 10:51:44,160 --> 10:51:47,880 and say that padma's in Gryffindor as in 16947 10:51:45,960 --> 10:51:50,320 the movies and we see Padma from 16948 10:51:47,880 --> 10:51:52,200 Gryffindor but technically I went down 16949 10:51:50,320 --> 10:51:54,080 this rabbit hole and looking at Harry 16950 10:51:52,200 --> 10:51:56,680 Potter more closely technically in the 16951 10:51:54,080 --> 10:51:58,000 books Padma I believe was from Ravenclaw 16952 10:51:56,680 --> 10:51:59,880 so this is actually a mistake or an 16953 10:51:58,000 --> 10:52:01,756 inconsistency between the movies and the 16954 10:51:59,880 --> 10:52:04,040 books let's see if we can't fix this 16955 10:52:01,756 --> 10:52:06,520 inconsistency in our code so how about 16956 10:52:04,040 --> 10:52:08,640 we do this if the student's name that's 16957 10:52:06,520 --> 10:52:11,436 inputed equals Padma why don't we 16958 10:52:08,640 --> 10:52:13,720 override whatever the uh whatever the 16959 10:52:11,436 --> 10:52:17,116 house is and change it to be properly 16960 10:52:13,720 --> 10:52:19,080 Gryffindor let me go ahead and do if 16961 10:52:17,116 --> 10:52:20,400 student now if I want to get at padma's 16962 10:52:19,080 --> 10:52:22,320 name I'm going to have to do student 16963 10:52:20,400 --> 10:52:24,400 bracket zero I have to know what 16964 10:52:22,320 --> 10:52:27,680 location the name is in in this tupple 16965 10:52:24,400 --> 10:52:29,400 but if that in value equals equals Padma 16966 10:52:27,680 --> 10:52:31,160 let's go ahead with this if statement 16967 10:52:29,400 --> 10:52:34,240 and make a change let's change the 16968 10:52:31,160 --> 10:52:36,360 students F uh bracket one value so the 16969 10:52:34,240 --> 10:52:37,880 second value if we're zero indexing 16970 10:52:36,360 --> 10:52:39,800 let's change it to be another house in 16971 10:52:37,880 --> 10:52:42,756 the World of Harry Potter called 16972 10:52:39,800 --> 10:52:44,276 Ravenclaw so I'm just fixing maybe the 16973 10:52:42,756 --> 10:52:46,560 user's input they watch the movie so 16974 10:52:44,276 --> 10:52:49,116 they typee in Padma Gryffindor but mm- 16975 10:52:46,560 --> 10:52:50,880 the books it was Padma from Ravenclaw 16976 10:52:49,116 --> 10:52:53,720 all right let me go ahead and go down to 16977 10:52:50,880 --> 10:52:55,880 my terminal window clear my uh terminal 16978 10:52:53,720 --> 10:52:58,160 and do python of student. enter I'm 16979 10:52:55,880 --> 10:52:59,880 going to do Harry as well as Gryffindor 16980 10:52:58,160 --> 10:53:02,160 just to demonstrate that that is still 16981 10:52:59,880 --> 10:53:03,680 working as intended Let Me Clear My 16982 10:53:02,160 --> 10:53:06,640 screen again though and run python of 16983 10:53:03,680 --> 10:53:08,360 studenty on Padma and I'll put her too 16984 10:53:06,640 --> 10:53:11,560 in Gryffindor as in the movies and hit 16985 10:53:08,360 --> 10:53:13,240 enter and now I just see a big mess of 16986 10:53:11,560 --> 10:53:15,360 errors on the screen some kind of 16987 10:53:13,240 --> 10:53:17,040 exception has been thrown and indeed a 16988 10:53:15,360 --> 10:53:18,680 type error has happened happened I'm 16989 10:53:17,040 --> 10:53:21,800 using a data type wherein there's an 16990 10:53:18,680 --> 10:53:24,800 error and what is that error well tupple 16991 10:53:21,800 --> 10:53:27,240 object does not support item assignment 16992 10:53:24,800 --> 10:53:29,480 it's a little arcany expressed that is 16993 10:53:27,240 --> 10:53:30,916 that's not really very user friendly but 16994 10:53:29,480 --> 10:53:32,640 if you think about what those words mean 16995 10:53:30,916 --> 10:53:34,480 tupple object does not support item 16996 10:53:32,640 --> 10:53:37,040 assignment so assignment is copying from 16997 10:53:34,480 --> 10:53:39,800 right to left so somehow that's invalid 16998 10:53:37,040 --> 10:53:43,400 and here is a manifestation of the 16999 10:53:39,800 --> 10:53:45,960 immutability of tuples you cannot change 17000 10:53:43,400 --> 10:53:48,000 location zero or one or anything inside 17001 10:53:45,960 --> 10:53:51,320 that is a feature that is the design of 17002 10:53:48,000 --> 10:53:52,916 a tuple so if I want to override that I 17003 10:53:51,320 --> 10:53:54,240 think I'm going to have to use a 17004 10:53:52,916 --> 10:53:56,520 different type of data that we've used 17005 10:53:54,240 --> 10:53:58,800 before namely a list and that's fine if 17006 10:53:56,520 --> 10:54:01,080 you want to enable yourself and 17007 10:53:58,800 --> 10:54:03,360 colleagues using your code to change the 17008 10:54:01,080 --> 10:54:06,116 contents of that container well we can 17009 10:54:03,360 --> 10:54:08,276 go ahead and return not a tupple using 17010 10:54:06,116 --> 10:54:10,400 explicit parentheses or no parentheses 17011 10:54:08,276 --> 10:54:12,040 just the comma but I can use square 17012 10:54:10,400 --> 10:54:13,916 brackets and if I'm using square 17013 10:54:12,040 --> 10:54:17,360 brackets on the left and the right this 17014 10:54:13,916 --> 10:54:19,800 is indeed explicitly a list same idea 17015 10:54:17,360 --> 10:54:22,320 but it's mutable that is to say you can 17016 10:54:19,800 --> 10:54:24,756 change the contents of a list so making 17017 10:54:22,320 --> 10:54:27,240 no other changes just returning a list 17018 10:54:24,756 --> 10:54:29,640 with square brackets instead of a tuple 17019 10:54:27,240 --> 10:54:31,200 with parentheses or just the comma let 17020 10:54:29,640 --> 10:54:34,596 me go ahead now and run python of 17021 10:54:31,200 --> 10:54:37,320 student. enter let me type in Harry and 17022 10:54:34,596 --> 10:54:39,800 Gryffindor again that's still working 17023 10:54:37,320 --> 10:54:42,560 good to see let me run this once more 17024 10:54:39,800 --> 10:54:45,080 and type in Padma and Gryffindor as in 17025 10:54:42,560 --> 10:54:47,720 the movies but no now we've corrected it 17026 10:54:45,080 --> 10:54:48,840 to be Padma from Raven claw as in the 17027 10:54:47,720 --> 10:54:52,000 books 17028 10:54:48,840 --> 10:54:54,560 instead any questions now on tupples 17029 10:54:52,000 --> 10:54:56,840 versus lists or this idea of 17030 10:54:54,560 --> 10:55:01,040 immutability versus 17031 10:54:56,840 --> 10:55:04,680 mutability uh can we use a nested tle in 17032 10:55:01,040 --> 10:55:06,480 Pyon like a a nested lists absolutely 17033 10:55:04,680 --> 10:55:08,360 you can have not only nested lists in 17034 10:55:06,480 --> 10:55:10,400 Python where one of the elements in a 17035 10:55:08,360 --> 10:55:12,000 list could be another list so you have 17036 10:55:10,400 --> 10:55:13,756 some square brackets out here you might 17037 10:55:12,000 --> 10:55:15,240 have some other square brackets inside 17038 10:55:13,756 --> 10:55:17,596 you can absolutely do the same with a 17039 10:55:15,240 --> 10:55:19,596 tupple as well there's no constraint on 17040 10:55:17,596 --> 10:55:21,360 the types of values you can put in there 17041 10:55:19,596 --> 10:55:24,080 we've not had occasion to do that in 17042 10:55:21,360 --> 10:55:26,276 this case I'm just returning a simple uh 17043 10:55:24,080 --> 10:55:28,400 simple tupple with two elements but yes 17044 10:55:26,276 --> 10:55:31,596 you could absolutely do that too other 17045 10:55:28,400 --> 10:55:34,360 questions on tles versus lists okay for 17046 10:55:31,596 --> 10:55:37,680 example um when I see the square bracket 17047 10:55:34,360 --> 10:55:39,960 um is it mainly used for the list oh a 17048 10:55:37,680 --> 10:55:43,360 really good question uh sort of so when 17049 10:55:39,960 --> 10:55:44,916 you create a value like a list you use 17050 10:55:43,360 --> 10:55:46,400 square brackets and that would indeed be 17051 10:55:44,916 --> 10:55:48,960 a visual indicator that this is 17052 10:55:46,400 --> 10:55:50,640 definitely a list uh if you instead see 17053 10:55:48,960 --> 10:55:52,276 parentheses that's a visual indicator 17054 10:55:50,640 --> 10:55:55,000 when creating a value that it's 17055 10:55:52,276 --> 10:55:58,480 definitely a tupple however somewhat 17056 10:55:55,000 --> 10:56:01,000 confusingly both lists and topples use 17057 10:55:58,480 --> 10:56:03,200 square brackets when you access the 17058 10:56:01,000 --> 10:56:05,756 contents of them when you index into 17059 10:56:03,200 --> 10:56:08,160 them at location zero or location one 17060 10:56:05,756 --> 10:56:10,640 you always use square brackets so that's 17061 10:56:08,160 --> 10:56:12,596 the distinction there good question 17062 10:56:10,640 --> 10:56:14,756 allow me to propose now if I may that we 17063 10:56:12,596 --> 10:56:16,436 solve this problem yet another way and 17064 10:56:14,756 --> 10:56:18,840 let's see if we're either making things 17065 10:56:16,436 --> 10:56:21,000 Better or For Worse than us recall that 17066 10:56:18,840 --> 10:56:22,800 dictionaries or dict objects also exist 17067 10:56:21,000 --> 10:56:25,240 in python and a dictionary is this 17068 10:56:22,800 --> 10:56:27,360 collection of keys and values and the 17069 10:56:25,240 --> 10:56:28,756 upside in particular of a dictionary is 17070 10:56:27,360 --> 10:56:30,680 that they have better semantics right 17071 10:56:28,756 --> 10:56:32,200 you don't just have to assume that a 17072 10:56:30,680 --> 10:56:34,040 name is always going to be at location 17073 10:56:32,200 --> 10:56:35,596 zero house is always going to be at 17074 10:56:34,040 --> 10:56:37,520 location one I mean that's the kind of 17075 10:56:35,596 --> 10:56:40,000 thing especially if you had three four 17076 10:56:37,520 --> 10:56:41,880 or more values eventually you or someone 17077 10:56:40,000 --> 10:56:43,756 is going to get confused and forget what 17078 10:56:41,880 --> 10:56:46,360 the order is and you're going to write 17079 10:56:43,756 --> 10:56:47,520 buggy code so a dictionary is a little 17080 10:56:46,360 --> 10:56:49,916 more powerful and that you can 17081 10:56:47,520 --> 10:56:52,680 semantically associate Keys like little 17082 10:56:49,916 --> 10:56:54,756 descriptions with the values those keys 17083 10:56:52,680 --> 10:56:56,080 and those values respectively so let me 17084 10:56:54,756 --> 10:56:57,960 go ahead and do this and we can do this 17085 10:56:56,080 --> 10:56:59,916 in a few different ways but let me 17086 10:56:57,960 --> 10:57:02,480 propose that we focus on get student 17087 10:56:59,916 --> 10:57:05,640 here and let's go ahead and do this let 17088 10:57:02,480 --> 10:57:07,840 me go ahead and uh in delete the 17089 10:57:05,640 --> 10:57:09,756 implementation of get student as is let 17090 10:57:07,840 --> 10:57:11,880 me create a student variable and 17091 10:57:09,756 --> 10:57:14,360 initialize it to an empty dictionary and 17092 10:57:11,880 --> 10:57:16,240 I can do that with just two curly braces 17093 10:57:14,360 --> 10:57:18,800 here and then let me go ahead and set 17094 10:57:16,240 --> 10:57:20,080 two keys inside of that dictionary 17095 10:57:18,800 --> 10:57:22,640 inside of the student there will be 17096 10:57:20,080 --> 10:57:24,200 quote unquote a name key and the value 17097 10:57:22,640 --> 10:57:26,080 of that is going to be whatever the 17098 10:57:24,200 --> 10:57:28,596 return value of input is when I prompt 17099 10:57:26,080 --> 10:57:30,880 the user for their name and then the 17100 10:57:28,596 --> 10:57:32,240 house key inside of that same student 17101 10:57:30,880 --> 10:57:34,880 dictionary is going to be the return 17102 10:57:32,240 --> 10:57:36,800 value of whatever the user types in for 17103 10:57:34,880 --> 10:57:40,276 their house and lastly I'm going to go 17104 10:57:36,800 --> 10:57:43,000 ahead and return student so now I am 17105 10:57:40,276 --> 10:57:45,320 literally returning one thing still but 17106 10:57:43,000 --> 10:57:47,276 this time it's a dict rather than a 17107 10:57:45,320 --> 10:57:49,436 tupple rather than a list but there's 17108 10:57:47,276 --> 10:57:51,000 still two things in it technically four 17109 10:57:49,436 --> 10:57:54,160 things if you count the keys and the 17110 10:57:51,000 --> 10:57:55,560 values but there's two key value pairs 17111 10:57:54,160 --> 10:57:57,200 now my code up here is going to have to 17112 10:57:55,560 --> 10:57:59,640 change a little bit and let's simplify 17113 10:57:57,200 --> 10:58:01,960 this and remove for instance now the the 17114 10:57:59,640 --> 10:58:03,840 Padma if statement just to focus on 17115 10:58:01,960 --> 10:58:05,880 what's changing at hand and let me go 17116 10:58:03,840 --> 10:58:08,200 ahead now and leave line two alone I'm 17117 10:58:05,880 --> 10:58:09,756 still going to have a student variable 17118 10:58:08,200 --> 10:58:12,360 that gets assigned the return value of 17119 10:58:09,756 --> 10:58:16,116 get student but what I want to do here 17120 10:58:12,360 --> 10:58:18,800 now is actually access the keys in 17121 10:58:16,116 --> 10:58:20,880 inside of that dictionary not by numeric 17122 10:58:18,800 --> 10:58:24,640 index which was for tuples and lists 17123 10:58:20,880 --> 10:58:26,520 zero and one but by way of the keys now 17124 10:58:24,640 --> 10:58:28,240 normally I might be in the habit as I 17125 10:58:26,520 --> 10:58:31,040 personally am of using double quotes 17126 10:58:28,240 --> 10:58:34,160 quote unquote name inside of there and 17127 10:58:31,040 --> 10:58:36,800 quote unquote house inside of there but 17128 10:58:34,160 --> 10:58:39,080 before I even run this code and show you 17129 10:58:36,800 --> 10:58:41,000 a mistake see an error on the screen 17130 10:58:39,080 --> 10:58:44,276 does anyone want to call out what I have 17131 10:58:41,000 --> 10:58:46,680 done wrong here this is just an F string 17132 10:58:44,276 --> 10:58:48,560 I just want to print out the value of 17133 10:58:46,680 --> 10:58:51,400 the name key the value of the house key 17134 10:58:48,560 --> 10:58:51,400 in this dictionary 17135 10:58:52,436 --> 10:58:56,840 but your your audio was a little garbled 17136 10:58:55,000 --> 10:58:58,596 for us but I think I heard double quotes 17137 10:58:56,840 --> 10:59:00,720 and single quotes so I'm going to assume 17138 10:58:58,596 --> 10:59:02,360 that indeed you've identified precisely 17139 10:59:00,720 --> 10:59:04,000 the issue I'm just going to confuse 17140 10:59:02,360 --> 10:59:06,240 python right now even though this is an 17141 10:59:04,000 --> 10:59:08,880 F string inside of Double quotes 17142 10:59:06,240 --> 10:59:10,880 prefixed with an F I can't actually use 17143 10:59:08,880 --> 10:59:11,756 my double quotes inside my double quotes 17144 10:59:10,880 --> 10:59:13,520 because that's going to potentially 17145 10:59:11,756 --> 10:59:15,840 confuse python indeed if I run this 17146 10:59:13,520 --> 10:59:18,200 program now python of student. py and 17147 10:59:15,840 --> 10:59:20,116 hit enter I get a syntax error so the 17148 10:59:18,200 --> 10:59:21,596 program didn't even run fully it just 17149 10:59:20,116 --> 10:59:24,116 couldn't be understood because it got 17150 10:59:21,596 --> 10:59:25,960 confused by those double quotes So the 17151 10:59:24,116 --> 10:59:28,320 simplest fix here would indeed just be 17152 10:59:25,960 --> 10:59:31,320 to use not double quotes but single 17153 10:59:28,320 --> 10:59:33,240 quotes around the keys or conversely 17154 10:59:31,320 --> 10:59:34,840 flip the double quotes on the outside to 17155 10:59:33,240 --> 10:59:36,200 single quotes then use double quotes on 17156 10:59:34,840 --> 10:59:38,436 the inside you just want to be 17157 10:59:36,200 --> 10:59:40,160 consistent so a subtle detail but again 17158 10:59:38,436 --> 10:59:43,040 this is now specific to dictionary 17159 10:59:40,160 --> 10:59:45,520 syntax this isn't fundamental to how 17160 10:59:43,040 --> 10:59:47,200 we're solving this current problem at 17161 10:59:45,520 --> 10:59:48,680 hand all right well let's go ahead and 17162 10:59:47,200 --> 10:59:50,800 try this let me go ahead now and run 17163 10:59:48,680 --> 10:59:52,560 python of student. let's go ahead and 17164 10:59:50,800 --> 10:59:54,960 type in Harry let's type in Gryffindor 17165 10:59:52,560 --> 10:59:57,436 and hopefully Harry is back from 17166 10:59:54,960 --> 10:59:59,840 Gryffindor no syntax errors no other 17167 10:59:57,436 --> 11:00:01,596 errors I think I'm back in business here 17168 10:59:59,840 --> 11:00:04,400 and what I do like to be clear about 17169 11:00:01,596 --> 11:00:06,320 using a dictionary is that it is 17170 11:00:04,400 --> 11:00:08,560 allowing me just better semantics again 17171 11:00:06,320 --> 11:00:12,080 I don't have to remember memorize 17172 11:00:08,560 --> 11:00:15,200 document that zero is name one is house 17173 11:00:12,080 --> 11:00:16,756 instead name is name and house is house 17174 11:00:15,200 --> 11:00:18,640 it's just a little clear a little more 17175 11:00:16,756 --> 11:00:20,720 expressive so that's generally a good 17176 11:00:18,640 --> 11:00:22,400 thing especially if we stored more data 17177 11:00:20,720 --> 11:00:24,840 about students than just their name in 17178 11:00:22,400 --> 11:00:26,960 their house if you had three Fields four 17179 11:00:24,840 --> 11:00:28,360 five 10 different fields no one's going 17180 11:00:26,960 --> 11:00:30,840 to want to remember or be able to 17181 11:00:28,360 --> 11:00:33,160 remember forever which is zero which is 17182 11:00:30,840 --> 11:00:35,880 one which is two and so forth better to 17183 11:00:33,160 --> 11:00:37,680 introduce uh names like name and house 17184 11:00:35,880 --> 11:00:39,596 in this case but let me tighten this up 17185 11:00:37,680 --> 11:00:41,360 further in indeed I'm typically in the 17186 11:00:39,596 --> 11:00:43,160 habit of not introducing variables 17187 11:00:41,360 --> 11:00:45,916 unnecessarily unless they make the code 17188 11:00:43,160 --> 11:00:47,800 more readable and an alternative way to 17189 11:00:45,916 --> 11:00:49,720 format the same code would be this 17190 11:00:47,800 --> 11:00:52,520 strictly speaking I don't need to create 17191 11:00:49,720 --> 11:00:55,720 an empty dictionary then add one key to 17192 11:00:52,520 --> 11:00:57,680 it then add a second key to it and then 17193 11:00:55,720 --> 11:01:00,480 return that dictionary I can actually 17194 11:00:57,680 --> 11:01:02,560 consolidate this all into one statement 17195 11:01:00,480 --> 11:01:05,640 if you will let me go ahead and do this 17196 11:01:02,560 --> 11:01:09,320 let me go ahead and say name equals 17197 11:01:05,640 --> 11:01:10,800 inputs return value house equals inputs 17198 11:01:09,320 --> 11:01:12,480 return value and then instead of 17199 11:01:10,800 --> 11:01:13,640 returning any variable name student 17200 11:01:12,480 --> 11:01:16,276 which I'm going to propose doesn't need 17201 11:01:13,640 --> 11:01:18,276 to exist anymore let me just create and 17202 11:01:16,276 --> 11:01:20,960 return the dictionary all at once let me 17203 11:01:18,276 --> 11:01:22,960 do quote unquote name in lower case here 17204 11:01:20,960 --> 11:01:25,116 and then the variable it's storing the 17205 11:01:22,960 --> 11:01:27,000 user's name then quote unquote house as 17206 11:01:25,116 --> 11:01:29,200 my second key the value of which is 17207 11:01:27,000 --> 11:01:31,116 going to be house the variable now is 17208 11:01:29,200 --> 11:01:32,680 this better maybe maybe not maybe the 17209 11:01:31,116 --> 11:01:34,560 first wave was a little more readable 17210 11:01:32,680 --> 11:01:36,080 and that's totally fine to create 17211 11:01:34,560 --> 11:01:38,560 variables if they improve the 17212 11:01:36,080 --> 11:01:40,436 readability of your code but just know 17213 11:01:38,560 --> 11:01:42,160 that you can also create and return a 17214 11:01:40,436 --> 11:01:44,480 dictionary on the fly like this so to 17215 11:01:42,160 --> 11:01:46,596 speak all in one line and I think it's 17216 11:01:44,480 --> 11:01:48,320 arguably pretty reasonable in this why 17217 11:01:46,596 --> 11:01:49,720 it's just pretty short I probably 17218 11:01:48,320 --> 11:01:51,520 wouldn't do this if it got longer and 17219 11:01:49,720 --> 11:01:53,360 longer and longer I might minimally then 17220 11:01:51,520 --> 11:01:55,436 start moving my key value pairs to 17221 11:01:53,360 --> 11:01:58,160 separate lines but this would just be a 17222 11:01:55,436 --> 11:02:00,276 slightly more compact way of doing this 17223 11:01:58,160 --> 11:02:02,276 as well but let me propose we do one 17224 11:02:00,276 --> 11:02:05,240 more change let's go ahead and introduce 17225 11:02:02,276 --> 11:02:07,080 that same special casing of Padma to fix 17226 11:02:05,240 --> 11:02:09,160 her house from Gryffindor for instance 17227 11:02:07,080 --> 11:02:11,480 to Ravenclaw how do we do this with 17228 11:02:09,160 --> 11:02:15,200 dictionaries well dictionaries like 17229 11:02:11,480 --> 11:02:17,160 lists are mutable you can change what is 17230 11:02:15,200 --> 11:02:18,520 in them just just like you can lists and 17231 11:02:17,160 --> 11:02:20,360 how do you do that is just a little 17232 11:02:18,520 --> 11:02:23,276 different syntactically so let's go back 17233 11:02:20,360 --> 11:02:27,000 into Main and do this fix if the student 17234 11:02:23,276 --> 11:02:31,000 variable has a name key that equals 17235 11:02:27,000 --> 11:02:35,276 equals Padma then indented go ahead and 17236 11:02:31,000 --> 11:02:37,520 change the value of the house key inside 17237 11:02:35,276 --> 11:02:41,080 of that student dictionary to be quote 17238 11:02:37,520 --> 11:02:42,756 unquote Ravenclaw instead so very 17239 11:02:41,080 --> 11:02:45,040 similar in spirit to what we did with a 17240 11:02:42,756 --> 11:02:47,240 list but instead of using location zero 17241 11:02:45,040 --> 11:02:49,320 and one we're much more clearly 17242 11:02:47,240 --> 11:02:51,680 explicitly semantically using quote 17243 11:02:49,320 --> 11:02:54,000 unquote name and quote unquote house 17244 11:02:51,680 --> 11:02:56,436 because you index into lists and topples 17245 11:02:54,000 --> 11:02:59,080 using numbers but you index into 17246 11:02:56,436 --> 11:03:00,756 dictionaries using strings as I've done 17247 11:02:59,080 --> 11:03:04,000 here all right let me go ahead and run 17248 11:03:00,756 --> 11:03:06,840 python of studenty we'll again do Harry 17249 11:03:04,000 --> 11:03:08,520 from Gryffindor and I think all as well 17250 11:03:06,840 --> 11:03:10,596 let me run it one more time this time 17251 11:03:08,520 --> 11:03:13,756 with Padma who in the movies is from 17252 11:03:10,596 --> 11:03:16,840 Gryffindor but should really be from 17253 11:03:13,756 --> 11:03:20,116 Ravenclaw are any questions then on this 17254 11:03:16,840 --> 11:03:21,880 progression from tuples to lists to 17255 11:03:20,116 --> 11:03:24,360 dictionaries we haven't necessarily 17256 11:03:21,880 --> 11:03:27,040 introduced anything new other than those 17257 11:03:24,360 --> 11:03:29,200 tupples which have been available to us 17258 11:03:27,040 --> 11:03:31,640 all this time but the goal at the moment 17259 11:03:29,200 --> 11:03:33,720 is just to demonstrate this distinction 17260 11:03:31,640 --> 11:03:35,916 among these different data types and how 17261 11:03:33,720 --> 11:03:38,756 they each work a little bit differently 17262 11:03:35,916 --> 11:03:42,240 what if a a combination of lists is 17263 11:03:38,756 --> 11:03:46,596 there in a tle so is the list like we 17264 11:03:42,240 --> 11:03:49,276 can change the list because tle are imut 17265 11:03:46,596 --> 11:03:51,116 but lists are mutable correct you can 17266 11:03:49,276 --> 11:03:53,040 change the contents of lists and you can 17267 11:03:51,116 --> 11:03:55,240 put most anything you want in them other 17268 11:03:53,040 --> 11:03:57,276 lists or strings as I've done integers 17269 11:03:55,240 --> 11:03:59,080 or anything else tuples you can do the 17270 11:03:57,276 --> 11:04:01,080 exact same thing but you cannot change 17271 11:03:59,080 --> 11:04:03,560 them once you've created them a 17272 11:04:01,080 --> 11:04:06,560 dictionary is more like a list in that 17273 11:04:03,560 --> 11:04:09,400 it is mutable you can change it but the 17274 11:04:06,560 --> 11:04:11,480 way you index into a dictionary is by 17275 11:04:09,400 --> 11:04:14,160 way of these Keys these strings as we 17276 11:04:11,480 --> 11:04:16,880 keep seeing rather than by numbers those 17277 11:04:14,160 --> 11:04:19,080 numeric indices 17278 11:04:16,880 --> 11:04:21,520 all right well let me propose that there 17279 11:04:19,080 --> 11:04:23,800 is yet another way of solving this 17280 11:04:21,520 --> 11:04:25,880 problem and indeed I would argue that 17281 11:04:23,800 --> 11:04:27,840 there's now an opportunity to hand even 17282 11:04:25,880 --> 11:04:30,240 though this program isn't particularly 17283 11:04:27,840 --> 11:04:33,080 complicated all I'm doing is collecting 17284 11:04:30,240 --> 11:04:34,800 a name from the user and a uh house from 17285 11:04:33,080 --> 11:04:36,400 the user you could imagine wanting 17286 11:04:34,800 --> 11:04:38,480 longer term to collect even more 17287 11:04:36,400 --> 11:04:40,200 information like the students's Patronis 17288 11:04:38,480 --> 11:04:41,800 or magical spell or a whole bunch of 17289 11:04:40,200 --> 11:04:44,200 other information that might belong in a 17290 11:04:41,800 --> 11:04:47,080 student and right now we're just kind of 17291 11:04:44,200 --> 11:04:49,520 using these very general purpose data 17292 11:04:47,080 --> 11:04:51,680 types in Python a tuple to combine some 17293 11:04:49,520 --> 11:04:54,116 values together a list to do the same 17294 11:04:51,680 --> 11:04:55,800 but let us change it later a dictionary 17295 11:04:54,116 --> 11:04:58,040 which is more powerful because it's a 17296 11:04:55,800 --> 11:05:00,720 little more structured it does have keys 17297 11:04:58,040 --> 11:05:02,480 and it has values not just values but 17298 11:05:00,720 --> 11:05:04,116 you know what this we wouldn't have to 17299 11:05:02,480 --> 11:05:06,520 be having this conversation if the 17300 11:05:04,116 --> 11:05:09,116 authors of python had just given us a 17301 11:05:06,520 --> 11:05:10,880 data type called student right wouldn't 17302 11:05:09,116 --> 11:05:12,640 it have been nice if there were just a 17303 11:05:10,880 --> 11:05:14,800 type of variable I could create in my 17304 11:05:12,640 --> 11:05:16,040 code called student then we wouldn't 17305 11:05:14,800 --> 11:05:18,680 have to figure out well do we use a 17306 11:05:16,040 --> 11:05:20,400 tuple or a list or a dictionary but 17307 11:05:18,680 --> 11:05:22,840 that's pretty reasonable right you could 17308 11:05:20,400 --> 11:05:25,560 imagine just a how slippery of a slope 17309 11:05:22,840 --> 11:05:27,520 that is so to speak if the creators of a 17310 11:05:25,560 --> 11:05:29,640 language had to anticipate all the 17311 11:05:27,520 --> 11:05:31,276 possible types of data that programmers 17312 11:05:29,640 --> 11:05:33,320 like you and me want to store in your 17313 11:05:31,276 --> 11:05:35,436 programs so they just gave us these 17314 11:05:33,320 --> 11:05:37,596 general purpose tools but they gave us 17315 11:05:35,436 --> 11:05:40,160 another general purpose tool that's 17316 11:05:37,596 --> 11:05:42,200 going to allow us to create our own data 17317 11:05:40,160 --> 11:05:46,000 types as well and actually give them 17318 11:05:42,200 --> 11:05:49,520 names and that uh terminology is a class 17319 11:05:46,000 --> 11:05:52,116 a class is kind of like a blueprint for 17320 11:05:49,520 --> 11:05:54,040 pieces of data objects so to speak a 17321 11:05:52,116 --> 11:05:56,320 class is kind of like a mold that you 17322 11:05:54,040 --> 11:05:58,640 can define and give a name and when you 17323 11:05:56,320 --> 11:06:01,320 use that mold or you use that blueprint 17324 11:05:58,640 --> 11:06:04,040 you get types of data that are designed 17325 11:06:01,320 --> 11:06:07,000 exactly as you want so in short classes 17326 11:06:04,040 --> 11:06:09,240 allow you to invent your own data types 17327 11:06:07,000 --> 11:06:11,436 in Python and give them a name and this 17328 11:06:09,240 --> 11:06:14,000 is a primary feature uh of 17329 11:06:11,436 --> 11:06:15,840 objectoriented programming to be able to 17330 11:06:14,000 --> 11:06:18,160 create your own objects in this way and 17331 11:06:15,840 --> 11:06:20,720 in the case of python and classes even 17332 11:06:18,160 --> 11:06:22,560 give them some custom names so what does 17333 11:06:20,720 --> 11:06:25,040 this mean in real terms well let me go 17334 11:06:22,560 --> 11:06:26,680 ahead and come back to vs code here and 17335 11:06:25,040 --> 11:06:28,680 let me propose that we introduce a 17336 11:06:26,680 --> 11:06:30,680 little bit of new syntax I'm going to go 17337 11:06:28,680 --> 11:06:32,756 ahead and clear my terminal window first 17338 11:06:30,680 --> 11:06:34,480 I'm going to go to the top of my file 17339 11:06:32,756 --> 11:06:36,320 and I'm just going to start a thought 17340 11:06:34,480 --> 11:06:39,360 but not finish it yet I'm going to use 17341 11:06:36,320 --> 11:06:41,840 this new keyword for classes called 17342 11:06:39,360 --> 11:06:43,596 literally class so indeed the new 17343 11:06:41,840 --> 11:06:45,640 keyword we're going to have here and if 17344 11:06:43,596 --> 11:06:47,116 I go back to our slides here this this 17345 11:06:45,640 --> 11:06:48,800 would be the official URL where you can 17346 11:06:47,116 --> 11:06:51,916 read up more on this particular feature 17347 11:06:48,800 --> 11:06:54,520 of python in the official tutorial class 17348 11:06:51,916 --> 11:06:56,400 is a new keyword we can use now this is 17349 11:06:54,520 --> 11:06:57,960 coincidentally related to students 17350 11:06:56,400 --> 11:06:59,200 because students take classes but it has 17351 11:06:57,960 --> 11:07:01,480 nothing to do with the fact that we're 17352 11:06:59,200 --> 11:07:03,480 dealing with students class is a general 17353 11:07:01,480 --> 11:07:05,320 purpose term in a lot of languages 17354 11:07:03,480 --> 11:07:07,400 python among them that allow you to 17355 11:07:05,320 --> 11:07:10,640 Define these custom containers with 17356 11:07:07,400 --> 11:07:12,436 custom names for pieces of data so let's 17357 11:07:10,640 --> 11:07:14,116 go back to VSS code let's use this new 17358 11:07:12,436 --> 11:07:16,596 keyword and let me propose that we 17359 11:07:14,116 --> 11:07:18,400 create a class called student and by 17360 11:07:16,596 --> 11:07:20,200 convention I'm going to use a capital S 17361 11:07:18,400 --> 11:07:23,480 here and I'm going to go ahead and with 17362 11:07:20,200 --> 11:07:24,840 a colon get to later the implementation 17363 11:07:23,480 --> 11:07:26,840 of this class so I'm just going to use 17364 11:07:24,840 --> 11:07:28,520 dot dot dot which is a valid placeholder 17365 11:07:26,840 --> 11:07:30,000 for now that just indicates to me that 17366 11:07:28,520 --> 11:07:33,116 I'm going to come back to implementing 17367 11:07:30,000 --> 11:07:36,640 this later but as of now it does in fact 17368 11:07:33,116 --> 11:07:39,240 exist I now have a student uh class 17369 11:07:36,640 --> 11:07:42,000 defined for me that I can now use in my 17370 11:07:39,240 --> 11:07:44,276 code here how am I going to use it well 17371 11:07:42,000 --> 11:07:46,840 first of all let me go down to get 17372 11:07:44,276 --> 11:07:49,400 student and let me change this code to 17373 11:07:46,840 --> 11:07:51,436 no longer use a dictionary but to use 17374 11:07:49,400 --> 11:07:52,960 this class I'm going to do this I'm 17375 11:07:51,436 --> 11:07:54,800 going to give myself a variable called 17376 11:07:52,960 --> 11:07:57,916 student as I've done before but I'm 17377 11:07:54,800 --> 11:08:00,880 going to set it equal to Capital student 17378 11:07:57,916 --> 11:08:02,436 open parenthesis close parenthesis so 17379 11:08:00,880 --> 11:08:05,160 I'm going to do what appears to be 17380 11:08:02,436 --> 11:08:07,960 calling a function and that function 17381 11:08:05,160 --> 11:08:10,000 student with a capital S notice matches 17382 11:08:07,960 --> 11:08:12,160 the name that I gave this class at the 17383 11:08:10,000 --> 11:08:13,640 top of my file all right what do I next 17384 11:08:12,160 --> 11:08:15,640 want to do I'm going to go ahead and 17385 11:08:13,640 --> 11:08:17,880 give this student a name now if if I 17386 11:08:15,640 --> 11:08:21,520 were still using a dictionary I would 17387 11:08:17,880 --> 11:08:23,000 say student quote unquote name using 17388 11:08:21,520 --> 11:08:25,520 square brackets but this is not a 17389 11:08:23,000 --> 11:08:27,640 dictionary it turns out classes have 17390 11:08:25,520 --> 11:08:29,436 what for now we'll call attributes 17391 11:08:27,640 --> 11:08:31,400 properties of sorts that allow you to 17392 11:08:29,436 --> 11:08:33,520 specify values inside of them in the 17393 11:08:31,400 --> 11:08:35,436 Syntax for that happens to be a DOT 17394 11:08:33,520 --> 11:08:37,360 we've seen dots before we've used it in 17395 11:08:35,436 --> 11:08:39,276 the context of modules and libraries 17396 11:08:37,360 --> 11:08:41,160 more generally this is another similar 17397 11:08:39,276 --> 11:08:43,320 INSP Spirit use of a DOT that allows you 17398 11:08:41,160 --> 11:08:46,436 to get at something inside of something 17399 11:08:43,320 --> 11:08:49,320 else so student. name is going to be the 17400 11:08:46,436 --> 11:08:50,840 syntax I use for giving this student a 17401 11:08:49,320 --> 11:08:53,840 name and that name is going to be 17402 11:08:50,840 --> 11:08:55,080 whatever the return value of name is and 17403 11:08:53,840 --> 11:08:57,480 then I'm going to go ahead and say 17404 11:08:55,080 --> 11:08:59,800 student.h house to give another 17405 11:08:57,480 --> 11:09:01,720 attribute called house and give that the 17406 11:08:59,800 --> 11:09:03,640 return value of input here prompting the 17407 11:09:01,720 --> 11:09:06,320 user for house and then as before I'm 17408 11:09:03,640 --> 11:09:09,080 just going to return student but now 17409 11:09:06,320 --> 11:09:10,680 what's really powerful about class and 17410 11:09:09,080 --> 11:09:13,040 objectoriented programming more 17411 11:09:10,680 --> 11:09:14,916 generally is that I've created this 17412 11:09:13,040 --> 11:09:17,916 custom data type called literally 17413 11:09:14,916 --> 11:09:19,916 student capital S I've stored one such 17414 11:09:17,916 --> 11:09:21,680 student in a variable like I can always 17415 11:09:19,916 --> 11:09:23,560 do in a variable called student 17416 11:09:21,680 --> 11:09:25,116 lowercase s but I could call it anything 17417 11:09:23,560 --> 11:09:27,200 I want I just makes sense to call it 17418 11:09:25,116 --> 11:09:29,276 student as well but lowercase for 17419 11:09:27,200 --> 11:09:31,436 clarity and then I'm returning that 17420 11:09:29,276 --> 11:09:34,560 variable and because of my syntax in 17421 11:09:31,436 --> 11:09:38,320 lines 14 and 15 that has the result of 17422 11:09:34,560 --> 11:09:41,320 putting inside of that class a name 17423 11:09:38,320 --> 11:09:43,400 attribute and a house attribute I just 17424 11:09:41,320 --> 11:09:45,080 need to make one more change up here I'm 17425 11:09:43,400 --> 11:09:46,916 going to go ahead and remove our Padma 17426 11:09:45,080 --> 11:09:49,400 code just so we can focus only on what's 17427 11:09:46,916 --> 11:09:50,960 new rather than fixing her house and I'm 17428 11:09:49,400 --> 11:09:52,800 going to go in here and change the 17429 11:09:50,960 --> 11:09:55,640 syntax that previously was for 17430 11:09:52,800 --> 11:09:58,116 dictionaries again dictionaries use 17431 11:09:55,640 --> 11:10:00,080 square brackets and then strings in 17432 11:09:58,116 --> 11:10:02,160 quotes either single quotes or double 17433 11:10:00,080 --> 11:10:03,400 quotes depending on the context here 17434 11:10:02,160 --> 11:10:06,480 though I'm going to change this to be 17435 11:10:03,400 --> 11:10:09,560 student. name and over here I'm going to 17436 11:10:06,480 --> 11:10:11,000 change it to be student. house and 17437 11:10:09,560 --> 11:10:12,720 that's just going to be my new syntax 17438 11:10:11,000 --> 11:10:15,560 for getting the contents of what appears 17439 11:10:12,720 --> 11:10:18,560 to be a class called student let me go 17440 11:10:15,560 --> 11:10:20,520 ahead and rerun python of student. by 17441 11:10:18,560 --> 11:10:22,240 enter let's type in Harry's name as 17442 11:10:20,520 --> 11:10:24,596 before let's put him in Gryffindor 17443 11:10:22,240 --> 11:10:27,480 crossing our fingers as we often do and 17444 11:10:24,596 --> 11:10:30,160 Harry is indeed from 17445 11:10:27,480 --> 11:10:32,320 Gryffindor what though have I done let's 17446 11:10:30,160 --> 11:10:35,240 introduce one other bit of terminology 17447 11:10:32,320 --> 11:10:37,680 here it turns out that I can create a 17448 11:10:35,240 --> 11:10:40,240 class using that class keyword but 17449 11:10:37,680 --> 11:10:42,320 anytime you use a class you're creating 17450 11:10:40,240 --> 11:10:44,680 what are called objects and here is the 17451 11:10:42,320 --> 11:10:47,320 word objects as in objectoriented 17452 11:10:44,680 --> 11:10:48,756 programming or oop let me go back to my 17453 11:10:47,320 --> 11:10:50,720 code here and even though I haven't 17454 11:10:48,756 --> 11:10:52,400 really implemented much of it at all I 17455 11:10:50,720 --> 11:10:54,720 literally just left it with a dot dot 17456 11:10:52,400 --> 11:10:57,116 dot that's enough code lines one and two 17457 11:10:54,720 --> 11:10:59,560 to just invent a new data type called 17458 11:10:57,116 --> 11:11:01,520 student capital s that may or may not 17459 11:10:59,560 --> 11:11:03,560 have some future functionality as well 17460 11:11:01,520 --> 11:11:07,160 that's enough to create a class what 17461 11:11:03,560 --> 11:11:09,360 though am I doing on line 11 on line 11 17462 11:11:07,160 --> 11:11:12,596 what I'm technically doing is creating 17463 11:11:09,360 --> 11:11:15,240 an object of that class so this too is 17464 11:11:12,596 --> 11:11:17,560 another term of art you create objects 17465 11:11:15,240 --> 11:11:18,916 from classes so if we go back to that 17466 11:11:17,560 --> 11:11:21,520 metaphor that a class is like a 17467 11:11:18,916 --> 11:11:24,560 blueprint for a house or a class is like 17468 11:11:21,520 --> 11:11:26,916 a mold an object is when you use that 17469 11:11:24,560 --> 11:11:28,720 blueprint to build a specific house or 17470 11:11:26,916 --> 11:11:30,840 something that comes out of in plaster 17471 11:11:28,720 --> 11:11:34,080 the mold when you actually use that mold 17472 11:11:30,840 --> 11:11:36,640 to create such an object so a class is 17473 11:11:34,080 --> 11:11:39,596 again the definition of a new data type 17474 11:11:36,640 --> 11:11:42,360 the object is the Incarnation of or 17475 11:11:39,596 --> 11:11:44,596 technically instantiation of and another 17476 11:11:42,360 --> 11:11:47,276 term for objects would actually be an 17477 11:11:44,596 --> 11:11:49,080 instance you have instances of classes 17478 11:11:47,276 --> 11:11:50,436 as well so that's a lot of vocabulary 17479 11:11:49,080 --> 11:11:52,320 but at the end of the day it just boils 17480 11:11:50,436 --> 11:11:54,400 down to this you can Define your own 17481 11:11:52,320 --> 11:11:56,520 class which is really your own data type 17482 11:11:54,400 --> 11:11:58,800 you can then store attributes inside of 17483 11:11:56,520 --> 11:12:00,520 it using this dot notation here and then 17484 11:11:58,800 --> 11:12:03,520 you can access those same attributes 17485 11:12:00,520 --> 11:12:06,320 using Code like this here and now I have 17486 11:12:03,520 --> 11:12:08,200 a proper student data type and I don't 17487 11:12:06,320 --> 11:12:10,040 have to kind of hack something together 17488 11:12:08,200 --> 11:12:12,960 using a tupple or a list or even a 17489 11:12:10,040 --> 11:12:14,720 dictionary I now have a proper data type 17490 11:12:12,960 --> 11:12:18,116 called student that the authors of 17491 11:12:14,720 --> 11:12:21,080 python didn't give me I gave myself any 17492 11:12:18,116 --> 11:12:22,916 questions now on classes this new 17493 11:12:21,080 --> 11:12:26,116 keyword class or this idea of these 17494 11:12:22,916 --> 11:12:30,916 objects or instances thereof is the 17495 11:12:26,116 --> 11:12:32,480 class object mutable or immutable a good 17496 11:12:30,916 --> 11:12:34,080 question and we've clearly laid the 17497 11:12:32,480 --> 11:12:36,116 stage for having that conversation about 17498 11:12:34,080 --> 11:12:38,800 every data type now we will see that 17499 11:12:36,116 --> 11:12:41,040 they are mutable but you can make them 17500 11:12:38,800 --> 11:12:43,360 immutable so you can get the best of 17501 11:12:41,040 --> 11:12:44,840 both worlds Now by writing some actual 17502 11:12:43,360 --> 11:12:47,000 code and we'll write more code than the 17503 11:12:44,840 --> 11:12:49,240 DOT dot dot in just a bit other 17504 11:12:47,000 --> 11:12:51,160 questions on classes or these objects 17505 11:12:49,240 --> 11:12:53,880 thereof then what would be the 17506 11:12:51,160 --> 11:12:55,680 properties of those glasses uh so at the 17507 11:12:53,880 --> 11:12:57,360 moment the properties of or the 17508 11:12:55,680 --> 11:13:00,200 attributes of as I've been calling them 17509 11:12:57,360 --> 11:13:01,720 thus far would just be name and house it 17510 11:13:00,200 --> 11:13:04,080 turns out that there may very well be 17511 11:13:01,720 --> 11:13:06,160 other attributes built into classes that 17512 11:13:04,080 --> 11:13:07,800 we may see before long but for now the 17513 11:13:06,160 --> 11:13:10,200 only two attributes that I care about 17514 11:13:07,800 --> 11:13:13,000 are the ones that I myself created 17515 11:13:10,200 --> 11:13:14,800 namely name and house are again what I 17516 11:13:13,000 --> 11:13:16,080 would call attributes and in a little 17517 11:13:14,800 --> 11:13:17,880 bit we're going to start calling those 17518 11:13:16,080 --> 11:13:20,640 same attributes more technically 17519 11:13:17,880 --> 11:13:22,640 instance variables name and house as 17520 11:13:20,640 --> 11:13:25,520 I've presented them here in VSS code are 17521 11:13:22,640 --> 11:13:29,436 really just variables called name and 17522 11:13:25,520 --> 11:13:32,880 called house inside of an object whose 17523 11:13:29,436 --> 11:13:34,916 type is student all right so what more 17524 11:13:32,880 --> 11:13:37,960 can we do with these classes well again 17525 11:13:34,916 --> 11:13:40,400 online 11 is where we're instantiating 17526 11:13:37,960 --> 11:13:42,960 an object of the student class and 17527 11:13:40,400 --> 11:13:45,116 assigning it to a student variable we're 17528 11:13:42,960 --> 11:13:47,160 then adding attributes name and house 17529 11:13:45,116 --> 11:13:48,960 respectively on lines 12 and 13 17530 11:13:47,160 --> 11:13:51,160 currently both of those have values that 17531 11:13:48,960 --> 11:13:53,080 are technically strings or stirs because 17532 11:13:51,160 --> 11:13:54,400 that's what the return value of input is 17533 11:13:53,080 --> 11:13:55,960 but those attributes values could 17534 11:13:54,400 --> 11:13:57,680 actually be any data type we're just 17535 11:13:55,960 --> 11:13:59,400 keeping things simple and focusing on 17536 11:13:57,680 --> 11:14:01,840 defining students in terms of two 17537 11:13:59,400 --> 11:14:04,160 strings name and house and then on line 17538 11:14:01,840 --> 11:14:06,520 14 we're returning that variable we're 17539 11:14:04,160 --> 11:14:08,880 returning that object to main so that we 17540 11:14:06,520 --> 11:14:10,640 can actually print out who is from what 17541 11:14:08,880 --> 11:14:12,360 house well let's go ahead and add a bit 17542 11:14:10,640 --> 11:14:15,200 more functionality here because right 17543 11:14:12,360 --> 11:14:17,756 now on lines 12 and 13 this is a little 17544 11:14:15,200 --> 11:14:19,720 manual and it's a little reckless of me 17545 11:14:17,756 --> 11:14:22,480 to just be putting anything I want 17546 11:14:19,720 --> 11:14:24,000 inside of this student object it turns 17547 11:14:22,480 --> 11:14:26,240 out with classes unlike with 17548 11:14:24,000 --> 11:14:28,916 dictionaries we can actually standardize 17549 11:14:26,240 --> 11:14:31,200 all the more what those attributes can 17550 11:14:28,916 --> 11:14:33,596 be and how what kinds of values you can 17551 11:14:31,200 --> 11:14:35,320 set them to so let me go ahead and do 17552 11:14:33,596 --> 11:14:38,320 this let me propose that it would 17553 11:14:35,320 --> 11:14:40,756 actually be really nice if instead of 17554 11:14:38,320 --> 11:14:42,840 doing this here let me go ahead and 17555 11:14:40,756 --> 11:14:44,756 simplify my code as follows let me go 17556 11:14:42,840 --> 11:14:46,320 ahead and give myself a local variable 17557 11:14:44,756 --> 11:14:48,160 called name and set it equal to the 17558 11:14:46,320 --> 11:14:49,960 return value of input like we've done 17559 11:14:48,160 --> 11:14:51,720 many times now already let me give 17560 11:14:49,960 --> 11:14:53,400 myself one other variable for now called 17561 11:14:51,720 --> 11:14:55,800 house and set it equal to the return 17562 11:14:53,400 --> 11:14:58,800 value of input as well prompting the 17563 11:14:55,800 --> 11:15:00,960 user for their house and now instead of 17564 11:14:58,800 --> 11:15:04,116 creating a student object from my 17565 11:15:00,960 --> 11:15:06,680 student class and then manually putting 17566 11:15:04,116 --> 11:15:09,000 the name attribute inside of it and the 17567 11:15:06,680 --> 11:15:11,240 house attribute inside of it let me 17568 11:15:09,000 --> 11:15:14,160 actually do something more powerful let 17569 11:15:11,240 --> 11:15:16,720 me do this let me call that student 17570 11:15:14,160 --> 11:15:19,200 function which is identical to the class 17571 11:15:16,720 --> 11:15:21,800 name just by defining a class you get a 17572 11:15:19,200 --> 11:15:23,560 function whose name is identical to the 17573 11:15:21,800 --> 11:15:25,756 class name with the capital letter 17574 11:15:23,560 --> 11:15:28,040 included but instead of just doing open 17575 11:15:25,756 --> 11:15:30,640 parenthesis close parenthesis let me 17576 11:15:28,040 --> 11:15:33,276 pass in the name that I want to fill 17577 11:15:30,640 --> 11:15:35,320 this this object with and the house that 17578 11:15:33,276 --> 11:15:36,960 I want to put in that object as well and 17579 11:15:35,320 --> 11:15:41,276 now let me set the return value as 17580 11:15:36,960 --> 11:15:43,040 before to be student equals like this so 17581 11:15:41,276 --> 11:15:44,320 what have I done that's different 17582 11:15:43,040 --> 11:15:45,720 fundamentally I'm still getting user 17583 11:15:44,320 --> 11:15:48,400 input in the same same way I'm using 17584 11:15:45,720 --> 11:15:49,916 input on line 11 and input on line 12 17585 11:15:48,400 --> 11:15:52,880 and I just so happen to be storing those 17586 11:15:49,916 --> 11:15:54,436 return values in local variables but now 17587 11:15:52,880 --> 11:15:56,880 now we're setting the stage for the more 17588 11:15:54,436 --> 11:15:58,320 powerful features of classes and 17589 11:15:56,880 --> 11:16:00,276 object-oriented programming more 17590 11:15:58,320 --> 11:16:03,200 generally notice that I'm deliberately 17591 11:16:00,276 --> 11:16:06,480 passing to this capital S student 17592 11:16:03,200 --> 11:16:09,000 function name comma house I'm passing in 17593 11:16:06,480 --> 11:16:10,200 arguments to the function now the 17594 11:16:09,000 --> 11:16:12,916 student class is not going to know what 17595 11:16:10,200 --> 11:16:15,520 to do with those yet but now I'm sort of 17596 11:16:12,916 --> 11:16:17,360 standardizing how I'm passing data into 17597 11:16:15,520 --> 11:16:19,520 this student class and ultimately it's 17598 11:16:17,360 --> 11:16:21,200 going to give me an opportunity to error 17599 11:16:19,520 --> 11:16:22,960 check those inputs to make sure that the 17600 11:16:21,200 --> 11:16:24,680 name is valid that it has a value and 17601 11:16:22,960 --> 11:16:26,276 it's not just the user hitting enter 17602 11:16:24,680 --> 11:16:28,596 it's going to allow me to ensure that 17603 11:16:26,276 --> 11:16:31,000 it's a valid house that it's Gryffindor 17604 11:16:28,596 --> 11:16:33,080 or Hufflepuff or Ravenclaw or Slytherin 17605 11:16:31,000 --> 11:16:35,400 or not just hitting enter or some random 17606 11:16:33,080 --> 11:16:37,756 value that the user types in because I'm 17607 11:16:35,400 --> 11:16:40,436 passing name and house to the student 17608 11:16:37,756 --> 11:16:41,800 class this particular function I'm going 17609 11:16:40,436 --> 11:16:44,000 to have more control over the 17610 11:16:41,800 --> 11:16:46,040 correctness of my data so let's now go 17611 11:16:44,000 --> 11:16:48,640 up to the student class which up until 17612 11:16:46,040 --> 11:16:51,560 now I left as just dot dot dot it turns 17613 11:16:48,640 --> 11:16:54,800 out that in the context of classes there 17614 11:16:51,560 --> 11:16:56,560 are a number of not just uh attributes 17615 11:16:54,800 --> 11:17:00,400 or instance variables that you can put 17616 11:16:56,560 --> 11:17:03,276 inside but also methods classes come 17617 11:17:00,400 --> 11:17:05,480 with certain methods or functions inside 17618 11:17:03,276 --> 11:17:07,916 of them that you can Define and they 17619 11:17:05,480 --> 11:17:10,680 just behave in a special way by nature 17620 11:17:07,916 --> 11:17:13,560 of how python works these functions 17621 11:17:10,680 --> 11:17:15,360 allow you to determine behavior in a 17622 11:17:13,560 --> 11:17:17,596 standard way they are indeed special 17623 11:17:15,360 --> 11:17:19,360 methods in that sense now what do I mean 17624 11:17:17,596 --> 11:17:22,080 by this well let me go back to vs code 17625 11:17:19,360 --> 11:17:25,640 here and let me propose that I start to 17626 11:17:22,080 --> 11:17:28,520 define a standard function called uh 17627 11:17:25,640 --> 11:17:31,840 underscore underscore or Dunder as it's 17628 11:17:28,520 --> 11:17:33,200 abbreviated in it underscore underscore 17629 11:17:31,840 --> 11:17:36,240 and then I'm going to go ahead and do 17630 11:17:33,200 --> 11:17:38,720 open parenthesis and then I'm going to 17631 11:17:36,240 --> 11:17:41,000 put in here literally the word self more 17632 11:17:38,720 --> 11:17:42,596 on that in just a moment but now inside 17633 11:17:41,000 --> 11:17:46,956 of this function I'm going to have an 17634 11:17:42,596 --> 11:17:49,840 opportunity to customize is this uh 17635 11:17:46,956 --> 11:17:52,800 classes objects that is to say this 17636 11:17:49,840 --> 11:17:56,040 underscore uncore init method or Dunder 17637 11:17:52,800 --> 11:17:58,116 init method is specifically known as an 17638 11:17:56,040 --> 11:18:00,000 instance method and it's called exactly 17639 11:17:58,116 --> 11:18:03,240 this this is designed by the authors of 17640 11:18:00,000 --> 11:18:06,276 python and if you want to initialize the 17641 11:18:03,240 --> 11:18:07,880 contents of an object from a class you 17642 11:18:06,276 --> 11:18:10,240 define this method and we'll see what 17643 11:18:07,880 --> 11:18:12,400 it's about to do here let me go back to 17644 11:18:10,240 --> 11:18:17,756 vs code and let me do something like 17645 11:18:12,400 --> 11:18:20,720 this self. name equals name and self. 17646 11:18:17,756 --> 11:18:23,116 house equals house but I don't want to 17647 11:18:20,720 --> 11:18:26,276 just init this object very generically I 17648 11:18:23,116 --> 11:18:29,400 want this method called in it to take in 17649 11:18:26,276 --> 11:18:31,640 not just self but name comma house as 17650 11:18:29,400 --> 11:18:33,160 well now what in the world is going on 17651 11:18:31,640 --> 11:18:35,080 because there's a lot of weird syntax 17652 11:18:33,160 --> 11:18:37,596 here there's this Dunder init method 17653 11:18:35,080 --> 11:18:39,480 double underscore init double underscore 17654 11:18:37,596 --> 11:18:41,436 there's all of a sudden this parameter 17655 11:18:39,480 --> 11:18:44,756 called self and then there's this new 17656 11:18:41,436 --> 11:18:46,680 syntax self. name and self. house now 17657 11:18:44,756 --> 11:18:48,916 you're seeing really a manifestation of 17658 11:18:46,680 --> 11:18:50,160 objectoriented programming it's not all 17659 11:18:48,916 --> 11:18:51,436 that different fundamentally from what 17660 11:18:50,160 --> 11:18:53,916 we've been doing for weeks with 17661 11:18:51,436 --> 11:18:56,000 dictionaries by adding keys to 17662 11:18:53,916 --> 11:19:00,680 dictionaries but in this case we're 17663 11:18:56,000 --> 11:19:03,116 adding variables to objects AKA instance 17664 11:19:00,680 --> 11:19:04,640 variables to objects now what's going on 17665 11:19:03,116 --> 11:19:06,840 let's do this in Reverse let's go back 17666 11:19:04,640 --> 11:19:09,680 to the line of code we wrote earlier on 17667 11:19:06,840 --> 11:19:13,000 line 15 I am treating the name of this 17668 11:19:09,680 --> 11:19:16,400 class student with a capital S as a 17669 11:19:13,000 --> 11:19:18,520 function and I am passing in two values 17670 11:19:16,400 --> 11:19:20,640 name and house what I've highlighted 17671 11:19:18,520 --> 11:19:23,080 here on the screen on line 15 is 17672 11:19:20,640 --> 11:19:25,320 generally known as a Constructor call 17673 11:19:23,080 --> 11:19:29,160 this is a line of code that is going to 17674 11:19:25,320 --> 11:19:32,320 construct a student object for me using 17675 11:19:29,160 --> 11:19:35,800 synonyms it is going to instantiate a 17676 11:19:32,320 --> 11:19:37,436 student object for me and again how is 17677 11:19:35,800 --> 11:19:39,276 it going to create that object it's 17678 11:19:37,436 --> 11:19:41,680 going to use the student class as a 17679 11:19:39,276 --> 11:19:44,000 template as a mold of sorts so that 17680 11:19:41,680 --> 11:19:45,560 every student is structured the same 17681 11:19:44,000 --> 11:19:47,436 every student is going to have a name 17682 11:19:45,560 --> 11:19:50,436 every student's going to have a house 17683 11:19:47,436 --> 11:19:52,916 but because I can pass in arguments to 17684 11:19:50,436 --> 11:19:55,800 this student function capital S I'm 17685 11:19:52,916 --> 11:19:58,956 going to be able to customize the 17686 11:19:55,800 --> 11:20:00,520 contents of that object so if you think 17687 11:19:58,956 --> 11:20:02,560 about the real world if you've ever been 17688 11:20:00,520 --> 11:20:05,680 on a street or a neighborhood where all 17689 11:20:02,560 --> 11:20:07,520 of the houses kind of look the same but 17690 11:20:05,680 --> 11:20:08,916 they're might be painted differently 17691 11:20:07,520 --> 11:20:10,756 they might be decorated a little bit 17692 11:20:08,916 --> 11:20:12,320 differently on the outside all of those 17693 11:20:10,756 --> 11:20:14,956 houses might have been built using the 17694 11:20:12,320 --> 11:20:17,200 exact same blueprint sort of a mold if 17695 11:20:14,956 --> 11:20:19,800 you will but then you can specialize 17696 11:20:17,200 --> 11:20:21,160 exactly the finer points of those houses 17697 11:20:19,800 --> 11:20:22,880 by painting the outside a different 17698 11:20:21,160 --> 11:20:25,916 color or planting different trees you 17699 11:20:22,880 --> 11:20:29,560 can style them differently similar uh in 17700 11:20:25,916 --> 11:20:31,480 spirit here we have a student blueprint 17701 11:20:29,560 --> 11:20:33,436 that's always going to have now a name 17702 11:20:31,480 --> 11:20:35,276 and a house but it's up to you and me to 17703 11:20:33,436 --> 11:20:38,040 pass in any name in any house that we 17704 11:20:35,276 --> 11:20:39,916 want now where is this function the fact 17705 11:20:38,040 --> 11:20:41,360 that I'm calling student capital S and 17706 11:20:39,916 --> 11:20:43,080 then a parenthesis and a Clos 17707 11:20:41,360 --> 11:20:44,200 parenthesis with arguments inside 17708 11:20:43,080 --> 11:20:46,116 suggest that there's a function 17709 11:20:44,200 --> 11:20:48,480 somewhere in the world that has been 17710 11:20:46,116 --> 11:20:50,840 defined with def that's going to be 17711 11:20:48,480 --> 11:20:53,320 called well as you might have guessed by 17712 11:20:50,840 --> 11:20:56,040 now the function that will always be 17713 11:20:53,320 --> 11:20:59,240 called by definition of how python 17714 11:20:56,040 --> 11:21:02,116 classes work is a function called double 17715 11:20:59,240 --> 11:21:04,000 underscore in it double underscore why 17716 11:21:02,116 --> 11:21:06,360 it's a crazy name but it's what the 17717 11:21:04,000 --> 11:21:07,840 authors of python chose to just 17718 11:21:06,360 --> 11:21:10,720 implement the 17719 11:21:07,840 --> 11:21:13,000 initialization of an object in Python 17720 11:21:10,720 --> 11:21:15,040 now the only weird thing especially 17721 11:21:13,000 --> 11:21:17,956 weird thing I will admit is this it 17722 11:21:15,040 --> 11:21:21,000 would be way clearer to me too if the 17723 11:21:17,956 --> 11:21:22,800 only two parameters for in it were just 17724 11:21:21,000 --> 11:21:24,800 name comma house right that's how we've 17725 11:21:22,800 --> 11:21:27,200 defined every function thus far in the 17726 11:21:24,800 --> 11:21:29,276 class you just specify the parameters 17727 11:21:27,200 --> 11:21:30,956 that you want the function to accept and 17728 11:21:29,276 --> 11:21:33,680 indeed that lines up with what I'm doing 17729 11:21:30,956 --> 11:21:37,276 on line 15 I am only passing in two 17730 11:21:33,680 --> 11:21:39,596 things to the student function but it 17731 11:21:37,276 --> 11:21:41,040 turns out that the authors of python 17732 11:21:39,596 --> 11:21:43,240 need to give us a little bit of help 17733 11:21:41,040 --> 11:21:46,560 here because suppose that you pass in 17734 11:21:43,240 --> 11:21:48,720 name and house to this init method and a 17735 11:21:46,560 --> 11:21:50,800 method is just a function inside of a 17736 11:21:48,720 --> 11:21:52,880 class what are you going to do with the 17737 11:21:50,800 --> 11:21:54,800 name in the house like literally where 17738 11:21:52,880 --> 11:21:57,680 are you going to put them if you want to 17739 11:21:54,800 --> 11:21:59,436 remember the name in the house for this 17740 11:21:57,680 --> 11:22:01,640 student you've got to be able to store 17741 11:21:59,436 --> 11:22:04,276 those values somewhere and how do you 17742 11:22:01,640 --> 11:22:05,800 store them in the current object that 17743 11:22:04,276 --> 11:22:08,160 has just been 17744 11:22:05,800 --> 11:22:09,596 instantiated well the authors of python 17745 11:22:08,160 --> 11:22:12,480 decided that the convention is going to 17746 11:22:09,596 --> 11:22:15,320 be that this init method also semi 17747 11:22:12,480 --> 11:22:17,596 secretly takes a third argument that has 17748 11:22:15,320 --> 11:22:19,040 to come first by convention it's called 17749 11:22:17,596 --> 11:22:20,480 self but you could call it technically 17750 11:22:19,040 --> 11:22:23,240 anything you want but the convention is 17751 11:22:20,480 --> 11:22:25,756 to always call it self and self as its 17752 11:22:23,240 --> 11:22:28,756 name implies gives you access to the 17753 11:22:25,756 --> 11:22:31,880 current object that was just created 17754 11:22:28,756 --> 11:22:34,080 what does that mean again now on line 14 17755 11:22:31,880 --> 11:22:35,916 now that it's moved down a little bit 17756 11:22:34,080 --> 11:22:38,320 this line here is a Constructor it 17757 11:22:35,916 --> 11:22:40,160 constructs a student object but there's 17758 11:22:38,320 --> 11:22:42,596 nothing in that object initially there's 17759 11:22:40,160 --> 11:22:44,956 no name there's no house but the object 17760 11:22:42,596 --> 11:22:46,880 exists in the computer's memory it's up 17761 11:22:44,956 --> 11:22:48,596 to now you to store the name and the 17762 11:22:46,880 --> 11:22:50,400 house inside of that object how do you 17763 11:22:48,596 --> 11:22:52,840 do that well python will just 17764 11:22:50,400 --> 11:22:55,160 automatically call this init method for 17765 11:22:52,840 --> 11:22:59,276 you and it's going to automatically pass 17766 11:22:55,160 --> 11:23:01,560 in a reference to a an argument that 17767 11:22:59,276 --> 11:23:04,276 represents the current object that it 17768 11:23:01,560 --> 11:23:05,840 just constructed in memory for you and 17769 11:23:04,276 --> 11:23:07,880 it's up to you to populate it with 17770 11:23:05,840 --> 11:23:09,756 values and what this means is that 17771 11:23:07,880 --> 11:23:13,116 inside of your init method you can 17772 11:23:09,756 --> 11:23:16,320 literally do self. name to create a new 17773 11:23:13,116 --> 11:23:18,320 attribute AKA an instance variable 17774 11:23:16,320 --> 11:23:20,560 inside of that otherwise empty object 17775 11:23:18,320 --> 11:23:22,956 and put this name inside of it it allows 17776 11:23:20,560 --> 11:23:24,756 you to do self. house and store that 17777 11:23:22,956 --> 11:23:26,436 value of house now you could call these 17778 11:23:24,756 --> 11:23:28,800 things anything you want they could be n 17779 11:23:26,436 --> 11:23:32,360 they could be H as before but that's 17780 11:23:28,800 --> 11:23:33,956 really not very self uh explanatory much 17781 11:23:32,360 --> 11:23:37,080 better to do this kind of convention 17782 11:23:33,956 --> 11:23:39,680 self. name equals name self. house 17783 11:23:37,080 --> 11:23:42,560 equals house and this is like installing 17784 11:23:39,680 --> 11:23:45,320 into the otherwise empty object the 17785 11:23:42,560 --> 11:23:47,756 value name and house and storing them in 17786 11:23:45,320 --> 11:23:49,916 really identically named instance 17787 11:23:47,756 --> 11:23:52,596 variables in the object and again an 17788 11:23:49,916 --> 11:23:54,956 object is just an instance of a class 17789 11:23:52,596 --> 11:23:56,916 now I know that was a lot of vocabulary 17790 11:23:54,956 --> 11:23:59,640 that's a lot of weird syntax so any 17791 11:23:56,916 --> 11:24:01,956 questions on this init method whose 17792 11:23:59,640 --> 11:24:04,400 purpose in life again is to initialize 17793 11:24:01,956 --> 11:24:06,160 an otherwise empty object when you first 17794 11:24:04,400 --> 11:24:08,596 create it so what is the difference 17795 11:24:06,160 --> 11:24:11,560 between the init method and default 17796 11:24:08,596 --> 11:24:13,436 Constructor a good question so in other 17797 11:24:11,560 --> 11:24:15,840 languages if you programed before for 17798 11:24:13,436 --> 11:24:18,240 instance Java there are functions that 17799 11:24:15,840 --> 11:24:19,720 are explicitly called Constructors that 17800 11:24:18,240 --> 11:24:21,956 indeed construct an object they 17801 11:24:19,720 --> 11:24:23,596 initialize it with values python 17802 11:24:21,956 --> 11:24:26,080 technically calls this init method the 17803 11:24:23,596 --> 11:24:29,596 initialization method it initializes the 17804 11:24:26,080 --> 11:24:32,040 value it's on line 14 uh line 15 now of 17805 11:24:29,596 --> 11:24:34,360 my code if I scroll back down that I'm 17806 11:24:32,040 --> 11:24:36,520 technically constructing the object it 17807 11:24:34,360 --> 11:24:38,040 turns out there's another special method 17808 11:24:36,520 --> 11:24:40,160 in Python that we won't talk about in 17809 11:24:38,040 --> 11:24:42,956 detail today called underscore 17810 11:24:40,160 --> 11:24:44,560 underscore new underscore underscore 17811 11:24:42,956 --> 11:24:46,756 that actually handles the process of 17812 11:24:44,560 --> 11:24:48,956 creating an empty object in memory for 17813 11:24:46,756 --> 11:24:50,916 us but generally speaking you the 17814 11:24:48,956 --> 11:24:52,800 programmer don't need to manipulate the 17815 11:24:50,916 --> 11:24:55,116 new function it just works for you 17816 11:24:52,800 --> 11:24:57,116 instead you define your own init method 17817 11:24:55,116 --> 11:24:59,956 here an init function inside of your 17818 11:24:57,116 --> 11:25:02,200 class and that method initializes the 17819 11:24:59,956 --> 11:25:03,436 contents of the object so there's 17820 11:25:02,200 --> 11:25:05,320 technically a distinction between 17821 11:25:03,436 --> 11:25:07,276 constructing the object with new and 17822 11:25:05,320 --> 11:25:09,040 initializing it within it but in the 17823 11:25:07,276 --> 11:25:11,756 world of python you pretty much only 17824 11:25:09,040 --> 11:25:14,040 worry about the init method python 17825 11:25:11,756 --> 11:25:16,560 generally does the other part for you a 17826 11:25:14,040 --> 11:25:19,560 good question others uh what about if 17827 11:25:16,560 --> 11:25:21,480 you want to store more than one name or 17828 11:25:19,560 --> 11:25:23,480 more than one house a good question if 17829 11:25:21,480 --> 11:25:24,916 you want to store more than one name or 17830 11:25:23,480 --> 11:25:26,880 more than one house you can do this in 17831 11:25:24,916 --> 11:25:29,080 different ways you could create other 17832 11:25:26,880 --> 11:25:33,000 attributes technically called instance 17833 11:25:29,080 --> 11:25:35,080 variables like self. name one self. name 17834 11:25:33,000 --> 11:25:36,720 two but we've seen in the past that that 17835 11:25:35,080 --> 11:25:38,436 is not a very good design just to have 17836 11:25:36,720 --> 11:25:40,520 multiple variables to store multiple 17837 11:25:38,436 --> 11:25:43,560 things maybe instead you have an 17838 11:25:40,520 --> 11:25:46,200 instance variable called self. names 17839 11:25:43,560 --> 11:25:48,720 plural and you set it equal to a list of 17840 11:25:46,200 --> 11:25:49,880 names or a list of houses now in this 17841 11:25:48,720 --> 11:25:51,000 case I don't think that really solves 17842 11:25:49,880 --> 11:25:53,360 the problem because I'm trying to 17843 11:25:51,000 --> 11:25:55,000 implement a student singular so it 17844 11:25:53,360 --> 11:25:56,800 doesn't really make sense to have 17845 11:25:55,000 --> 11:25:58,360 multiple first names maybe a nickname 17846 11:25:56,800 --> 11:26:00,276 maybe a last name so we could add those 17847 11:25:58,360 --> 11:26:02,560 to but I don't think we need multiple 17848 11:26:00,276 --> 11:26:04,360 names per se and in this case multiple 17849 11:26:02,560 --> 11:26:05,840 houses but absolutely you could do that 17850 11:26:04,360 --> 11:26:09,040 using some of our familiar building 17851 11:26:05,840 --> 11:26:11,080 blocks like lists other questions how 17852 11:26:09,040 --> 11:26:13,320 are classes or objects represented in 17853 11:26:11,080 --> 11:26:15,320 memory how are classes and objects 17854 11:26:13,320 --> 11:26:17,880 represented in memory so the class is 17855 11:26:15,320 --> 11:26:19,560 technically just code it is the code on 17856 11:26:17,880 --> 11:26:22,276 the top of my file lines one through 17857 11:26:19,560 --> 11:26:24,800 four that defines that blueprint that 17858 11:26:22,276 --> 11:26:26,680 template if you will um objects are 17859 11:26:24,800 --> 11:26:28,200 stored in the computer's memory by 17860 11:26:26,680 --> 11:26:29,436 taking up some number of bytes so you're 17861 11:26:28,200 --> 11:26:31,880 probably familiar with bytes or 17862 11:26:29,436 --> 11:26:33,956 kilobytes or megabytes there's some 17863 11:26:31,880 --> 11:26:36,520 chunk of bytes probably all in the same 17864 11:26:33,956 --> 11:26:38,956 location in the computer's memory or Ram 17865 11:26:36,520 --> 11:26:41,756 where those V where those objects are 17866 11:26:38,956 --> 11:26:43,640 stored but that's what python the 17867 11:26:41,756 --> 11:26:45,400 program handles for you python The 17868 11:26:43,640 --> 11:26:47,116 Interpreter figures out where in the 17869 11:26:45,400 --> 11:26:48,640 computer's memory to put it you and I 17870 11:26:47,116 --> 11:26:50,560 the programmers get to think and solve 17871 11:26:48,640 --> 11:26:52,560 problems at this level python The 17872 11:26:50,560 --> 11:26:54,520 Interpreter handles those lower level 17873 11:26:52,560 --> 11:26:57,320 details for you how about one final 17874 11:26:54,520 --> 11:26:59,916 question on classes and objects now my 17875 11:26:57,320 --> 11:27:02,560 question is if we can the same do the 17876 11:26:59,916 --> 11:27:04,916 same thing with the dictionary so I to 17877 11:27:02,560 --> 11:27:05,916 use classes good question if you can do 17878 11:27:04,916 --> 11:27:07,756 the same things as you can with 17879 11:27:05,916 --> 11:27:09,040 dictionaries why should you use classes 17880 11:27:07,756 --> 11:27:10,840 because we are just scratching the 17881 11:27:09,040 --> 11:27:13,400 surface now of what you can do with 17882 11:27:10,840 --> 11:27:15,080 classes allow me to go back now to my 17883 11:27:13,400 --> 11:27:17,520 keyboard and show you more of what you 17884 11:27:15,080 --> 11:27:20,640 can do with classes but in short you can 17885 11:27:17,520 --> 11:27:22,756 do much more with classes you can ensure 17886 11:27:20,640 --> 11:27:24,840 the correctness of your data much more 17887 11:27:22,756 --> 11:27:26,520 with classes you can error check things 17888 11:27:24,840 --> 11:27:29,040 and generally you can design more 17889 11:27:26,520 --> 11:27:31,160 complicated software more effectively 17890 11:27:29,040 --> 11:27:32,916 and we'll continue to see today features 17891 11:27:31,160 --> 11:27:34,756 of python and object-oriented 17892 11:27:32,916 --> 11:27:37,916 programming more generally that allows 17893 11:27:34,756 --> 11:27:40,480 us to do just that so let me propose in 17894 11:27:37,916 --> 11:27:42,680 fact that first let's just tighten up 17895 11:27:40,480 --> 11:27:44,840 this current implementation which again 17896 11:27:42,680 --> 11:27:46,956 has us with an init method that just 17897 11:27:44,840 --> 11:27:48,840 declares two instance variables self. 17898 11:27:46,956 --> 11:27:51,276 name and self. house which again just 17899 11:27:48,840 --> 11:27:53,276 creates those variables inside of the 17900 11:27:51,276 --> 11:27:55,560 otherwise empty object and assigns them 17901 11:27:53,276 --> 11:27:57,436 values name and house respectively let 17902 11:27:55,560 --> 11:27:58,800 me go ahead and just do one little thing 17903 11:27:57,436 --> 11:28:01,116 here I don't really need the student 17904 11:27:58,800 --> 11:28:03,000 variable let me just tighten this up so 17905 11:28:01,116 --> 11:28:05,360 that each time we improve or change the 17906 11:28:03,000 --> 11:28:07,520 code we're focusing really on just the 17907 11:28:05,360 --> 11:28:09,276 minimal changes alone so I've not 17908 11:28:07,520 --> 11:28:10,640 fundamentally done anything different I 17909 11:28:09,276 --> 11:28:13,436 just got rid of the variable name and 17910 11:28:10,640 --> 11:28:15,200 I'm just returning the return value of 17911 11:28:13,436 --> 11:28:17,040 this student function that's 17912 11:28:15,200 --> 11:28:18,756 constructing my new object for me so I'm 17913 11:28:17,040 --> 11:28:21,480 just tightening things up as we've done 17914 11:28:18,756 --> 11:28:24,200 many times in the past well what if 17915 11:28:21,480 --> 11:28:26,116 something goes wrong when in creating 17916 11:28:24,200 --> 11:28:28,080 this student for instance what if the 17917 11:28:26,116 --> 11:28:30,320 user does not give us a name and they 17918 11:28:28,080 --> 11:28:31,800 just hit enter when prompted for name 17919 11:28:30,320 --> 11:28:33,956 like I don't want to put in my 17920 11:28:31,800 --> 11:28:36,080 computer's memory a sort of bogus 17921 11:28:33,956 --> 11:28:38,436 student object that has no name right 17922 11:28:36,080 --> 11:28:39,956 I'd ideally like to check for errors 17923 11:28:38,436 --> 11:28:41,680 before I even create it so I don't 17924 11:28:39,956 --> 11:28:43,756 create a nameless student it would just 17925 11:28:41,680 --> 11:28:46,596 be weird and probably a bug to have an 17926 11:28:43,756 --> 11:28:47,880 object that has no name similarly I 17927 11:28:46,596 --> 11:28:50,560 don't want the user to be able to type 17928 11:28:47,880 --> 11:28:52,520 in something random as their house at 17929 11:28:50,560 --> 11:28:54,320 least in the World of Harry Potter 17930 11:28:52,520 --> 11:28:56,000 there's really only four houses at 17931 11:28:54,320 --> 11:28:58,240 Hogwarts at least or there's again 17932 11:28:56,000 --> 11:29:00,680 Gryffindor and Hufflepuff and Ravenclaw 17933 11:28:58,240 --> 11:29:03,276 and Slytherin a list of four valid 17934 11:29:00,680 --> 11:29:05,560 houses it would be nice if I somehow 17935 11:29:03,276 --> 11:29:08,916 validated that the user's input is 17936 11:29:05,560 --> 11:29:10,956 indeed in that list now I could do all 17937 11:29:08,916 --> 11:29:13,560 of that validation in my get student 17938 11:29:10,956 --> 11:29:16,200 function I could check is the name empty 17939 11:29:13,560 --> 11:29:18,560 if so so don't create the student object 17940 11:29:16,200 --> 11:29:21,160 is the house one of those four houses if 17941 11:29:18,560 --> 11:29:23,240 not don't create the student object but 17942 11:29:21,160 --> 11:29:25,200 that would be rather decoupled from the 17943 11:29:23,240 --> 11:29:27,480 student itself right get student 17944 11:29:25,200 --> 11:29:30,800 currently exists as just my own function 17945 11:29:27,480 --> 11:29:32,800 in my student. py file but classes and 17946 11:29:30,800 --> 11:29:36,436 really object-oriented programming more 17947 11:29:32,800 --> 11:29:39,720 generally encourages you to encapsulate 17948 11:29:36,436 --> 11:29:42,200 inside of a class all functionality 17949 11:29:39,720 --> 11:29:44,400 related to that class so if you want to 17950 11:29:42,200 --> 11:29:46,800 validate that a name exists if you want 17951 11:29:44,400 --> 11:29:49,680 to validate that a house is correct that 17952 11:29:46,800 --> 11:29:52,320 belongs just uh fundamentally in the 17953 11:29:49,680 --> 11:29:54,400 class called student itself not in some 17954 11:29:52,320 --> 11:29:56,276 random function that you wrote elsewhere 17955 11:29:54,400 --> 11:29:58,400 again this is just methodology because 17956 11:29:56,276 --> 11:30:00,040 again if we think about writing code 17957 11:29:58,400 --> 11:30:02,000 that gets longer and longer more and 17958 11:30:00,040 --> 11:30:03,840 more complicated it should make just 17959 11:30:02,000 --> 11:30:06,640 intuitive sense that if you keep all the 17960 11:30:03,840 --> 11:30:08,320 house and all of the Stu all of the name 17961 11:30:06,640 --> 11:30:10,240 and all of the house related code in the 17962 11:30:08,320 --> 11:30:12,040 student it's just better organization 17963 11:30:10,240 --> 11:30:13,436 right keep all of the related code 17964 11:30:12,040 --> 11:30:15,240 together and that's probably going to 17965 11:30:13,436 --> 11:30:17,000 set you up for more success and indeed 17966 11:30:15,240 --> 11:30:19,480 that's part of this methodology of 17967 11:30:17,000 --> 11:30:23,560 objectoriented programming let me go 17968 11:30:19,480 --> 11:30:27,276 ahead now and change my students classes 17969 11:30:23,560 --> 11:30:30,000 init method to do this if the name is 17970 11:30:27,276 --> 11:30:31,800 blank so if not name and we've seen this 17971 11:30:30,000 --> 11:30:34,916 kind of syntax before if you say in 17972 11:30:31,800 --> 11:30:37,480 Python pythonic if not name that's like 17973 11:30:34,916 --> 11:30:39,840 doing something like this if name equals 17974 11:30:37,480 --> 11:30:41,520 equals quote unquote but I can do this a 17975 11:30:39,840 --> 11:30:43,200 little more elegantly just say if not 17976 11:30:41,520 --> 11:30:47,276 name would be the more pythonic way to 17977 11:30:43,200 --> 11:30:48,680 do it well I want to return an error 17978 11:30:47,276 --> 11:30:51,436 like I might want to do something like 17979 11:30:48,680 --> 11:30:54,240 this print missing name but this is not 17980 11:30:51,436 --> 11:30:56,436 good enough it does not suffice to just 17981 11:30:54,240 --> 11:30:58,080 print out missing name and then let the 17982 11:30:56,436 --> 11:30:59,880 rest of the code go through all right 17983 11:30:58,080 --> 11:31:01,400 well what could I do instead in the past 17984 11:30:59,880 --> 11:31:03,756 we've seen another technique I could do 17985 11:31:01,400 --> 11:31:05,320 cy. exit and I could say something like 17986 11:31:03,756 --> 11:31:07,520 missing name and I could go up here and 17987 11:31:05,320 --> 11:31:10,160 I could import CIS but this is a really 17988 11:31:07,520 --> 11:31:12,596 obnoxious solution to the problem just 17989 11:31:10,160 --> 11:31:15,480 because you or maybe a colleague messed 17990 11:31:12,596 --> 11:31:17,240 up and called a fun with an invalid name 17991 11:31:15,480 --> 11:31:20,800 you're going to quit my whole program 17992 11:31:17,240 --> 11:31:22,680 like that's really really extreme of a 17993 11:31:20,800 --> 11:31:24,160 response and you probably don't want to 17994 11:31:22,680 --> 11:31:25,840 do that if your program's in the middle 17995 11:31:24,160 --> 11:31:27,480 of running you might want to clean some 17996 11:31:25,840 --> 11:31:29,240 stuff up you might want to save files 17997 11:31:27,480 --> 11:31:31,276 you don't want to just exit a program 17998 11:31:29,240 --> 11:31:33,276 sometimes in some arbitrary line just 17999 11:31:31,276 --> 11:31:35,596 because input was invalid so I don't 18000 11:31:33,276 --> 11:31:38,436 think we want to do that either but we 18001 11:31:35,596 --> 11:31:40,400 do now have a mechanism for signaling 18002 11:31:38,436 --> 11:31:41,640 errors unfortunately I can't do 18003 11:31:40,400 --> 11:31:44,560 something like this I could try 18004 11:31:41,640 --> 11:31:45,880 returning none and say uh this student 18005 11:31:44,560 --> 11:31:48,880 does not exist I'm going to hand you 18006 11:31:45,880 --> 11:31:50,436 back none instead but it's too late if 18007 11:31:48,880 --> 11:31:53,360 we scroll back down to where I'm 18008 11:31:50,436 --> 11:31:55,116 creating the student it's on line 17 now 18009 11:31:53,360 --> 11:31:57,520 where I've highlighted this code the 18010 11:31:55,116 --> 11:31:59,680 student has already been created there 18011 11:31:57,520 --> 11:32:02,200 is an object somewhere in the computer's 18012 11:31:59,680 --> 11:32:04,000 memory that's structured as a student it 18013 11:32:02,200 --> 11:32:06,800 just doesn't have any values inside of 18014 11:32:04,000 --> 11:32:09,160 it but it's too late therefore to return 18015 11:32:06,800 --> 11:32:11,160 none that ship has sailed the object 18016 11:32:09,160 --> 11:32:12,756 exists you can't just suddenly say nope 18017 11:32:11,160 --> 11:32:14,680 nope there is no object there is an 18018 11:32:12,756 --> 11:32:17,116 object it's up to to you to Signal an 18019 11:32:14,680 --> 11:32:18,880 error and how do you signal an error 18020 11:32:17,116 --> 11:32:20,436 well we've actually seen this before but 18021 11:32:18,880 --> 11:32:23,000 we haven't had occasion to create our 18022 11:32:20,436 --> 11:32:25,680 own errors it turns out in Python 18023 11:32:23,000 --> 11:32:28,400 there's another keyword related to 18024 11:32:25,680 --> 11:32:30,276 exceptions that python itself uses to 18025 11:32:28,400 --> 11:32:31,916 raise all of those exceptions we've 18026 11:32:30,276 --> 11:32:35,080 talked about in the past when you've 18027 11:32:31,916 --> 11:32:37,360 caught things like value errors or other 18028 11:32:35,080 --> 11:32:40,116 such exceptions that come with python 18029 11:32:37,360 --> 11:32:42,800 well it turns out you the programmer can 18030 11:32:40,116 --> 11:32:44,560 raise that is create your own exceptions 18031 11:32:42,800 --> 11:32:45,916 when something just really goes wrong 18032 11:32:44,560 --> 11:32:48,080 not wrong enough that you want to quit 18033 11:32:45,916 --> 11:32:49,956 and exit the whole program but enough 18034 11:32:48,080 --> 11:32:52,276 that you need to somehow alert the 18035 11:32:49,956 --> 11:32:54,916 programmer that there has been an error 18036 11:32:52,276 --> 11:32:56,956 something exceptional in a very bad way 18037 11:32:54,916 --> 11:33:00,320 something exceptional has happened and 18038 11:32:56,956 --> 11:33:03,040 let them try to catch that exception as 18039 11:33:00,320 --> 11:33:06,040 needed so let me go back to vs code here 18040 11:33:03,040 --> 11:33:08,320 and propose that if the user passes in 18041 11:33:06,040 --> 11:33:10,360 an invalid name it's just empty so 18042 11:33:08,320 --> 11:33:13,400 there's not a name well what I really 18043 11:33:10,360 --> 11:33:16,000 want to do is this I want to raise a 18044 11:33:13,400 --> 11:33:18,360 value error and we've seen the value 18045 11:33:16,000 --> 11:33:20,320 errors before we've created value errors 18046 11:33:18,360 --> 11:33:22,596 accidentally before and generally you 18047 11:33:20,320 --> 11:33:24,756 and I have tried to catch them if they 18048 11:33:22,596 --> 11:33:26,720 happen well the flip side of this 18049 11:33:24,756 --> 11:33:28,560 feature of exceptions in a language like 18050 11:33:26,720 --> 11:33:30,400 python is that you the programmer can 18051 11:33:28,560 --> 11:33:32,880 also raise exceptions when something 18052 11:33:30,400 --> 11:33:34,480 exceptional happens and you can even be 18053 11:33:32,880 --> 11:33:36,080 more precise you don't have to raise a 18054 11:33:34,480 --> 11:33:37,956 generic value error and let the 18055 11:33:36,080 --> 11:33:40,116 programmer figure out what went wrong 18056 11:33:37,956 --> 11:33:42,276 you can treat value error and all 18057 11:33:40,116 --> 11:33:44,916 exceptions in Python like functions and 18058 11:33:42,276 --> 11:33:47,520 actually pass to them an explanatory 18059 11:33:44,916 --> 11:33:48,956 message like quote unquote missing name 18060 11:33:47,520 --> 11:33:50,436 so that at least the programmer when 18061 11:33:48,956 --> 11:33:52,640 they encounter this error knows oh I 18062 11:33:50,436 --> 11:33:55,916 messed up I didn't make sure that the 18063 11:33:52,640 --> 11:33:58,040 user has a name and now what do you want 18064 11:33:55,916 --> 11:34:00,000 to do instead well now if you're the 18065 11:33:58,040 --> 11:34:04,116 programmer you could do something like 18066 11:34:00,000 --> 11:34:07,320 this you could try to create a student 18067 11:34:04,116 --> 11:34:09,080 except if there's a value error then you 18068 11:34:07,320 --> 11:34:11,116 could handle it in some way and I'm 18069 11:34:09,080 --> 11:34:12,916 going to wave my hand with a dot dot dot 18070 11:34:11,116 --> 11:34:15,116 at how you would handle it but you would 18071 11:34:12,916 --> 11:34:17,400 handle it using try and accept just like 18072 11:34:15,116 --> 11:34:19,436 we have in the past and that would allow 18073 11:34:17,400 --> 11:34:21,240 you the programmer to try to create the 18074 11:34:19,436 --> 11:34:24,276 student but if something goes wrong okay 18075 11:34:21,240 --> 11:34:26,080 okay I'll handle it nonetheless so 18076 11:34:24,276 --> 11:34:28,596 what's new here again is this raise 18077 11:34:26,080 --> 11:34:31,000 keyword that just lets you and I 18078 11:34:28,596 --> 11:34:32,880 actually raise our own exceptions to 18079 11:34:31,000 --> 11:34:35,080 Signal these errors well let me go back 18080 11:34:32,880 --> 11:34:37,360 to my code here and I'm just going to go 18081 11:34:35,080 --> 11:34:39,400 ahead and not bother trying or catching 18082 11:34:37,360 --> 11:34:41,436 this error for now we'll just focus on 18083 11:34:39,400 --> 11:34:43,720 raising it and assume that from our week 18084 11:34:41,436 --> 11:34:46,040 on exceptions you could add try and 18085 11:34:43,720 --> 11:34:48,000 accept as needed in places let me go 18086 11:34:46,040 --> 11:34:49,956 back to the code here and propose that 18087 11:34:48,000 --> 11:34:51,880 something else could go wrong with house 18088 11:34:49,956 --> 11:34:53,800 right if there is a name we're good but 18089 11:34:51,880 --> 11:34:55,800 if we're given a house but it's invalid 18090 11:34:53,800 --> 11:34:58,276 we should probably raise an exception 18091 11:34:55,800 --> 11:35:01,640 for that too so what if we do this if 18092 11:34:58,276 --> 11:35:04,720 house is not in the list containing 18093 11:35:01,640 --> 11:35:07,756 Gryffindor quote unquote uh Hufflepuff 18094 11:35:04,720 --> 11:35:11,000 quote unquote uh let's see Ravenclaw 18095 11:35:07,756 --> 11:35:13,640 quote unquote or uh Slytherin quote 18096 11:35:11,000 --> 11:35:15,276 unquote then with my colon let's ra 18097 11:35:13,640 --> 11:35:17,160 raise another type of value error but 18098 11:35:15,276 --> 11:35:19,756 rather than raise a generic value error 18099 11:35:17,160 --> 11:35:23,480 let's pass in an argument quote unquote 18100 11:35:19,756 --> 11:35:25,800 invalid house and so here we now see a 18101 11:35:23,480 --> 11:35:28,320 capability that we can do with classes 18102 11:35:25,800 --> 11:35:31,400 that we can't with dictionaries if you 18103 11:35:28,320 --> 11:35:33,400 add an attribute to a dictionary a key 18104 11:35:31,400 --> 11:35:35,720 to a dictionary it's going in no matter 18105 11:35:33,400 --> 11:35:37,720 what even if the name is empty even if 18106 11:35:35,720 --> 11:35:39,080 the house is a completely random string 18107 11:35:37,720 --> 11:35:41,160 of text that's not one of these four 18108 11:35:39,080 --> 11:35:43,640 houses it's going into that dictionary 18109 11:35:41,160 --> 11:35:46,640 but with the class and by way of this 18110 11:35:43,640 --> 11:35:48,956 init method you and I can now control 18111 11:35:46,640 --> 11:35:50,916 exactly what's going to be installed if 18112 11:35:48,956 --> 11:35:53,360 you will inside of this object you have 18113 11:35:50,916 --> 11:35:55,560 a little more control now over 18114 11:35:53,360 --> 11:35:57,956 correctness and so now let me go ahead 18115 11:35:55,560 --> 11:36:00,240 and uh scroll back down to my terminal 18116 11:35:57,956 --> 11:36:02,320 window and clear it let me run python of 18117 11:36:00,240 --> 11:36:05,160 student. let me type in something like 18118 11:36:02,320 --> 11:36:06,596 Harry let me type in Gryffindor enter 18119 11:36:05,160 --> 11:36:09,000 and we see that indeed Harry is from 18120 11:36:06,596 --> 11:36:11,080 Gryffindor what if I made a mistake 18121 11:36:09,000 --> 11:36:13,040 though what if I ran python of student. 18122 11:36:11,080 --> 11:36:15,916 and typed Harry as the name but at this 18123 11:36:13,040 --> 11:36:17,596 time typed in number four Private Drive 18124 11:36:15,916 --> 11:36:19,956 which is where he grew up instead of his 18125 11:36:17,596 --> 11:36:23,240 proper Hogwarts house let me hit enter 18126 11:36:19,956 --> 11:36:25,320 now and now you see a value error but 18127 11:36:23,240 --> 11:36:28,276 this isn't one that python generated for 18128 11:36:25,320 --> 11:36:30,000 us per se I raised this error and 18129 11:36:28,276 --> 11:36:31,680 therefore if I went in and wrote more 18130 11:36:30,000 --> 11:36:35,360 code in my get student function I could 18131 11:36:31,680 --> 11:36:37,400 also catch this error with our usual try 18132 11:36:35,360 --> 11:36:40,040 except syntax so all we have now is not 18133 11:36:37,400 --> 11:36:42,480 just classes in our toolkit but even 18134 11:36:40,040 --> 11:36:44,720 more Powers when it comes to exceptions 18135 11:36:42,480 --> 11:36:48,080 and not just catching them ourselves but 18136 11:36:44,720 --> 11:36:52,480 raising them ourselves too any questions 18137 11:36:48,080 --> 11:36:54,560 now on this use of class isn't in it and 18138 11:36:52,480 --> 11:36:56,680 now this ability to raise exceptions 18139 11:36:54,560 --> 11:37:00,040 when something goes wrong inside of the 18140 11:36:56,680 --> 11:37:02,720 initialization so what if user has a 18141 11:37:00,040 --> 11:37:04,640 middle name name middle name and last 18142 11:37:02,720 --> 11:37:07,040 name how would you fix that a good 18143 11:37:04,640 --> 11:37:08,916 question if you wanted the user to if 18144 11:37:07,040 --> 11:37:10,840 you wanted the student to have a first 18145 11:37:08,916 --> 11:37:13,040 name middle name and last name we could 18146 11:37:10,840 --> 11:37:15,240 do this in a bunch of different ways the 18147 11:37:13,040 --> 11:37:17,116 simplest though if Let Me Clear My 18148 11:37:15,240 --> 11:37:19,436 screen here and let me just temporarily 18149 11:37:17,116 --> 11:37:22,436 do this let me propose that the init 18150 11:37:19,436 --> 11:37:25,080 method take in a first argument a middle 18151 11:37:22,436 --> 11:37:27,080 argument and a last argument and then 18152 11:37:25,080 --> 11:37:29,756 what I think I would do down here is 18153 11:37:27,080 --> 11:37:31,276 ultimately have first equals first and 18154 11:37:29,756 --> 11:37:35,276 then I would do the same thing for 18155 11:37:31,276 --> 11:37:38,360 middle and last so middle and middle and 18156 11:37:35,276 --> 11:37:41,480 then last and last and then what I would 18157 11:37:38,360 --> 11:37:43,680 have to do here is when I actually ask 18158 11:37:41,480 --> 11:37:45,276 the user for their name I might need to 18159 11:37:43,680 --> 11:37:47,080 really go all out I might need to ask 18160 11:37:45,276 --> 11:37:49,040 them first for their first name and 18161 11:37:47,080 --> 11:37:51,080 store that in a variable called First 18162 11:37:49,040 --> 11:37:52,720 and therefore pass in first I might 18163 11:37:51,080 --> 11:37:55,276 similarly need to ask them for their 18164 11:37:52,720 --> 11:37:56,840 middle name and store that in a variable 18165 11:37:55,276 --> 11:37:59,200 and then pass in a second argument 18166 11:37:56,840 --> 11:38:00,916 middle and then lastly if you will let 18167 11:37:59,200 --> 11:38:03,360 me go ahead and create a third variable 18168 11:38:00,916 --> 11:38:06,360 called last get the input for their last 18169 11:38:03,360 --> 11:38:08,800 name and pass that in as well I could 18170 11:38:06,360 --> 11:38:10,480 instead just use one input and just ask 18171 11:38:08,800 --> 11:38:13,720 them for their whole name so type in 18172 11:38:10,480 --> 11:38:15,880 David uh ma enter or David J me all 18173 11:38:13,720 --> 11:38:18,240 three of them and maybe I could use 18174 11:38:15,880 --> 11:38:19,916 Python split function maybe a regular 18175 11:38:18,240 --> 11:38:21,116 expression to tease it apart that's 18176 11:38:19,916 --> 11:38:22,360 probably going to be messy because 18177 11:38:21,116 --> 11:38:24,080 there's going to be people who don't 18178 11:38:22,360 --> 11:38:26,080 have just two or three names they might 18179 11:38:24,080 --> 11:38:27,916 have four or five so maybe sometimes 18180 11:38:26,080 --> 11:38:29,436 it's better to have multiple prompts but 18181 11:38:27,916 --> 11:38:32,400 that's not a problem because with a 18182 11:38:29,436 --> 11:38:34,200 class we have the expressiveness to take 18183 11:38:32,400 --> 11:38:35,956 in more arguments if we want we could 18184 11:38:34,200 --> 11:38:37,116 even take a list if we wanted but I 18185 11:38:35,956 --> 11:38:38,956 think we'd probably want to have even 18186 11:38:37,116 --> 11:38:42,320 more error checking then not just for 18187 11:38:38,956 --> 11:38:44,116 name but for first and then maybe for 18188 11:38:42,320 --> 11:38:45,880 middle and then maybe for last so it 18189 11:38:44,116 --> 11:38:47,916 just is more and more code though there 18190 11:38:45,880 --> 11:38:50,276 would be ways to perhaps consolidate 18191 11:38:47,916 --> 11:38:53,080 that too let me undo all of that and see 18192 11:38:50,276 --> 11:38:55,520 if there are other questions now on 18193 11:38:53,080 --> 11:38:56,880 classes I assume this is classes are 18194 11:38:55,520 --> 11:38:58,596 something I might do at the beginning of 18195 11:38:56,880 --> 11:39:01,080 a project can I just put them in a 18196 11:38:58,596 --> 11:39:04,360 different file and import them into my 18197 11:39:01,080 --> 11:39:05,840 project or or or my main code as needed 18198 11:39:04,360 --> 11:39:07,360 absolutely a really good question you 18199 11:39:05,840 --> 11:39:10,116 could imagine wanting to use this 18200 11:39:07,360 --> 11:39:12,040 student class not just in studenty but 18201 11:39:10,116 --> 11:39:14,160 in other files or other projects of 18202 11:39:12,040 --> 11:39:17,160 yours and absolutely you can create your 18203 11:39:14,160 --> 11:39:19,200 own library of classes by putting the 18204 11:39:17,160 --> 11:39:20,956 student class in your own module or 18205 11:39:19,200 --> 11:39:22,756 package per our discussion in the past 18206 11:39:20,956 --> 11:39:24,320 about libraries more generally and 18207 11:39:22,756 --> 11:39:26,436 absolutely you can do that and later 18208 11:39:24,320 --> 11:39:28,640 today will we see that we've actually 18209 11:39:26,436 --> 11:39:30,596 been using classes you and I before in 18210 11:39:28,640 --> 11:39:32,560 thirdparty library so you too can 18211 11:39:30,596 --> 11:39:36,160 absolutely do the same how about one 18212 11:39:32,560 --> 11:39:39,000 more question on classes can you have 18213 11:39:36,160 --> 11:39:41,360 optional variables in classes and two 18214 11:39:39,000 --> 11:39:43,596 can you have your own error names like 18215 11:39:41,360 --> 11:39:47,116 let's be egotistic and say I when AR 18216 11:39:43,596 --> 11:39:49,956 raise Eric eror short answer yes so you 18217 11:39:47,116 --> 11:39:51,480 can uh these init functions are just 18218 11:39:49,956 --> 11:39:52,560 like python functions more generally 18219 11:39:51,480 --> 11:39:53,320 even though they're special and that 18220 11:39:52,560 --> 11:39:55,756 they're going to get called 18221 11:39:53,320 --> 11:39:57,276 automatically by python 4 you but if you 18222 11:39:55,756 --> 11:39:58,720 wanted to make house optional you could 18223 11:39:57,276 --> 11:40:02,840 do something like this you could give it 18224 11:39:58,720 --> 11:40:04,680 a default value in the init functions uh 18225 11:40:02,840 --> 11:40:06,880 signature so to speak in that first line 18226 11:40:04,680 --> 11:40:09,040 of code on line two and that would allow 18227 11:40:06,880 --> 11:40:10,436 me to not have to pass in house in this 18228 11:40:09,040 --> 11:40:12,080 case I'm going to continue to always 18229 11:40:10,436 --> 11:40:14,000 pass in name and house but you could 18230 11:40:12,080 --> 11:40:15,720 make things optional and yes to your 18231 11:40:14,000 --> 11:40:17,880 second question if you wanted to have 18232 11:40:15,720 --> 11:40:20,560 your own error message like an Eric 18233 11:40:17,880 --> 11:40:23,520 error you could actually create your own 18234 11:40:20,560 --> 11:40:25,000 Eric error exception and we'll see in a 18235 11:40:23,520 --> 11:40:26,916 little bit that there's actually a whole 18236 11:40:25,000 --> 11:40:30,320 Suite of exceptions that exist and you 18237 11:40:26,916 --> 11:40:33,276 too can invent those as well let me 18238 11:40:30,320 --> 11:40:36,080 propose though that we now introduce one 18239 11:40:33,276 --> 11:40:38,080 other aspect of this whereby we try 18240 11:40:36,080 --> 11:40:39,640 printing out what a student looks like 18241 11:40:38,080 --> 11:40:41,596 at the moment if I scroll back down to 18242 11:40:39,640 --> 11:40:43,560 my main function I'm still printing the 18243 11:40:41,596 --> 11:40:45,560 student's name and house very manually 18244 11:40:43,560 --> 11:40:47,480 I'm going inside of the object doing 18245 11:40:45,560 --> 11:40:49,116 student. name and I'm going inside of 18246 11:40:47,480 --> 11:40:51,596 the object again and getting student. 18247 11:40:49,116 --> 11:40:53,800 house just to see where uh the student 18248 11:40:51,596 --> 11:40:55,756 is from but wouldn't it be nice if I 18249 11:40:53,800 --> 11:40:59,040 could just print the student like I've 18250 11:40:55,756 --> 11:41:01,520 been printing for weeks any int or float 18251 11:40:59,040 --> 11:41:03,080 or stir or any other data type well 18252 11:41:01,520 --> 11:41:05,276 let's see what happens if I just try 18253 11:41:03,080 --> 11:41:06,916 printing the student instead of manually 18254 11:41:05,276 --> 11:41:08,880 going inside and trying to create that 18255 11:41:06,916 --> 11:41:10,240 sentence myself well in my terminal 18256 11:41:08,880 --> 11:41:12,956 window let me go ahead and run python of 18257 11:41:10,240 --> 11:41:15,116 student. py again let me type in Harry 18258 11:41:12,956 --> 11:41:18,560 let me type in Gryffindor and we voila 18259 11:41:15,116 --> 11:41:21,240 Harry whoa okay main student object at o 18260 11:41:18,560 --> 11:41:24,276 x102 733 18261 11:41:21,240 --> 11:41:25,840 e80 well what is going on well if you 18262 11:41:24,276 --> 11:41:27,320 were to run the same code you might 18263 11:41:25,840 --> 11:41:29,200 actually see something different on your 18264 11:41:27,320 --> 11:41:30,916 computer in terms of that number but 18265 11:41:29,200 --> 11:41:34,080 what you're really seeing is the 18266 11:41:30,916 --> 11:41:36,000 underlying representation as a string of 18267 11:41:34,080 --> 11:41:37,756 this specific object in particular 18268 11:41:36,000 --> 11:41:42,200 you're seeing where in the computer's 18269 11:41:37,756 --> 11:41:43,840 memory it is this number o x102 733 e80 18270 11:41:42,200 --> 11:41:46,360 refers to essentially a specific 18271 11:41:43,840 --> 11:41:48,276 location in the computer's memory or Ram 18272 11:41:46,360 --> 11:41:50,840 that's not really that interesting for 18273 11:41:48,276 --> 11:41:52,916 me or you or generally speaking 18274 11:41:50,840 --> 11:41:56,436 programmers but it's just a default way 18275 11:41:52,916 --> 11:42:00,000 of describing via print what this thing 18276 11:41:56,436 --> 11:42:02,320 uh is but I can override this as well it 18277 11:42:00,000 --> 11:42:04,040 turns out that there are other special 18278 11:42:02,320 --> 11:42:06,320 methods in Python when it comes to 18279 11:42:04,040 --> 11:42:08,720 classes not just underscore underscore 18280 11:42:06,320 --> 11:42:11,320 in it uncore underscore But continuing 18281 11:42:08,720 --> 11:42:14,360 in that same pattern underscore uncore 18282 11:42:11,320 --> 11:42:16,720 stir underscore underscore so this too 18283 11:42:14,360 --> 11:42:20,320 is a special method that if you define 18284 11:42:16,720 --> 11:42:23,160 it inside of your class python will just 18285 11:42:20,320 --> 11:42:26,200 automatically call this function for you 18286 11:42:23,160 --> 11:42:29,276 anytime some other function wants to see 18287 11:42:26,200 --> 11:42:31,800 your object as a string print wants to 18288 11:42:29,276 --> 11:42:33,640 see your fun your object as a string but 18289 11:42:31,800 --> 11:42:34,956 by default if you don't have this method 18290 11:42:33,640 --> 11:42:37,160 defined in your class it's going to 18291 11:42:34,956 --> 11:42:39,160 print out that very ugly esoteric 18292 11:42:37,160 --> 11:42:42,520 Incarnation thereof where it says main. 18293 11:42:39,160 --> 11:42:44,436 student object at Ox dot dot dot well 18294 11:42:42,520 --> 11:42:47,040 how can I then Define my own stir 18295 11:42:44,436 --> 11:42:49,520 function well here back in VSS code let 18296 11:42:47,040 --> 11:42:52,916 me propose that I go in and Define not 18297 11:42:49,520 --> 11:42:54,800 just underscore underscore uh in it but 18298 11:42:52,916 --> 11:42:57,840 let me Define a second function in this 18299 11:42:54,800 --> 11:43:00,160 class here as follows def underscore 18300 11:42:57,840 --> 11:43:01,436 underscore stir underscore underscore 18301 11:43:00,160 --> 11:43:03,080 there are indeed two even though the 18302 11:43:01,436 --> 11:43:04,880 font in VSS code is putting the two 18303 11:43:03,080 --> 11:43:07,000 underscore so close it just looks like a 18304 11:43:04,880 --> 11:43:08,320 longer underscore there are indeed two 18305 11:43:07,000 --> 11:43:11,800 there on the left and the right just 18306 11:43:08,320 --> 11:43:13,756 like for in it this one only takes one 18307 11:43:11,800 --> 11:43:15,840 argument that by convention is always 18308 11:43:13,756 --> 11:43:18,560 called self so that you have access to 18309 11:43:15,840 --> 11:43:21,160 it and then indented below that after a 18310 11:43:18,560 --> 11:43:23,596 colon I'm going to go ahead and create a 18311 11:43:21,160 --> 11:43:25,680 format string and return it so let me go 18312 11:43:23,596 --> 11:43:28,436 ahead and return how about something 18313 11:43:25,680 --> 11:43:30,240 generic first like a student so I'm not 18314 11:43:28,436 --> 11:43:32,320 going to bother even trying to figure 18315 11:43:30,240 --> 11:43:33,800 out what this Student's name or house is 18316 11:43:32,320 --> 11:43:36,956 I'm just going to always return a 18317 11:43:33,800 --> 11:43:40,480 student let me go back now to my earlier 18318 11:43:36,956 --> 11:43:41,916 code which has print student on line 16 18319 11:43:40,480 --> 11:43:45,000 Let Me Clear My terminal window and 18320 11:43:41,916 --> 11:43:47,200 rerun python of student upy enter type 18321 11:43:45,000 --> 11:43:49,720 in Harry type in Gryffindor last time I 18322 11:43:47,200 --> 11:43:52,520 saw that very cryptic output this time I 18323 11:43:49,720 --> 11:43:55,160 see more generically a student you know 18324 11:43:52,520 --> 11:43:58,240 more readable but not very enlightening 18325 11:43:55,160 --> 11:44:01,640 which student is this well notice that 18326 11:43:58,240 --> 11:44:04,480 the uh double underscore stur method 18327 11:44:01,640 --> 11:44:06,720 takes in this self argument by default 18328 11:44:04,480 --> 11:44:09,520 it's just the way the python authors 18329 11:44:06,720 --> 11:44:12,480 designed this method it will always be 18330 11:44:09,520 --> 11:44:14,756 passed a reference to the current 18331 11:44:12,480 --> 11:44:16,916 student object what do I mean by that 18332 11:44:14,756 --> 11:44:19,240 when this line of code on line six is 18333 11:44:16,916 --> 11:44:21,436 called print because it's hoping it's 18334 11:44:19,240 --> 11:44:23,880 going to get a string is going to 18335 11:44:21,436 --> 11:44:26,436 trigger the underscore uncore stir 18336 11:44:23,880 --> 11:44:28,436 underscore uncore method to be called 18337 11:44:26,436 --> 11:44:30,480 and python for you automatically is 18338 11:44:28,436 --> 11:44:32,720 going to pass into that method a 18339 11:44:30,480 --> 11:44:35,480 reference to the object that's trying to 18340 11:44:32,720 --> 11:44:37,596 be printed so that you the programmer 18341 11:44:35,480 --> 11:44:39,840 can do something like this here's an F 18342 11:44:37,596 --> 11:44:41,640 string with double quotes as usual I'm 18343 11:44:39,840 --> 11:44:45,400 going to use some curly braces and say 18344 11:44:41,640 --> 11:44:47,756 print out self. name name from self 18345 11:44:45,400 --> 11:44:50,720 house so there's nothing new in what 18346 11:44:47,756 --> 11:44:52,596 I've just done it's just an F string an 18347 11:44:50,720 --> 11:44:54,840 F on the beginning two double quotes a 18348 11:44:52,596 --> 11:44:58,040 couple of pairs of curly braces but 18349 11:44:54,840 --> 11:45:01,080 because automatically this stir method 18350 11:44:58,040 --> 11:45:03,520 gets past self so to speak a reference 18351 11:45:01,080 --> 11:45:05,116 to the current object I can go inside of 18352 11:45:03,520 --> 11:45:07,160 that object and grab the name I can go 18353 11:45:05,116 --> 11:45:09,520 inside that object again and grab the 18354 11:45:07,160 --> 11:45:11,360 house so now when I go back to my 18355 11:45:09,520 --> 11:45:13,560 terminal window previously it just 18356 11:45:11,360 --> 11:45:16,640 printed out a student but but now if I 18357 11:45:13,560 --> 11:45:18,756 run python of student. py enter type in 18358 11:45:16,640 --> 11:45:21,800 Harry type in Gryffindor and one more 18359 11:45:18,756 --> 11:45:24,276 time hit enter Harry is again from 18360 11:45:21,800 --> 11:45:27,200 Gryffindor but if I run this yet again 18361 11:45:24,276 --> 11:45:30,520 let's for instance do Draco is from 18362 11:45:27,200 --> 11:45:33,320 Slytherin enter Draco from Slytherin now 18363 11:45:30,520 --> 11:45:37,520 it's customized to the specific object 18364 11:45:33,320 --> 11:45:42,240 that we're trying to print questions on 18365 11:45:37,520 --> 11:45:43,596 this function here this thunder stir 18366 11:45:42,240 --> 11:45:45,880 method 18367 11:45:43,596 --> 11:45:48,800 is there anything else that the uncore 18368 11:45:45,880 --> 11:45:49,756 uncore stir method can do um the other 18369 11:45:48,800 --> 11:45:51,880 question is what's the difference 18370 11:45:49,756 --> 11:45:54,880 between stir and repper a good question 18371 11:45:51,880 --> 11:45:56,720 so there are many other methods that 18372 11:45:54,880 --> 11:45:58,000 come with python classes that start with 18373 11:45:56,720 --> 11:45:59,436 underscore underscore we're just 18374 11:45:58,000 --> 11:46:01,320 scratching the surface and we'll pretty 18375 11:45:59,436 --> 11:46:02,800 much Focus primarily on these but yes 18376 11:46:01,320 --> 11:46:04,840 there are many others and we'll see at 18377 11:46:02,800 --> 11:46:06,916 least one other in just a little bit 18378 11:46:04,840 --> 11:46:09,160 there is an among the others is indeed 18379 11:46:06,916 --> 11:46:11,480 one called uh repper which is a 18380 11:46:09,160 --> 11:46:15,116 representation of the Python object 18381 11:46:11,480 --> 11:46:17,160 generally speaking the _ uncore rcore 18382 11:46:15,116 --> 11:46:19,276 uncore method is meant for developers 18383 11:46:17,160 --> 11:46:21,436 eyes it typically has more information 18384 11:46:19,276 --> 11:46:23,800 than Harry from Gryffindor it would also 18385 11:46:21,436 --> 11:46:26,040 say what type of object it is like a 18386 11:46:23,800 --> 11:46:27,916 student capital S whereas underscore 18387 11:46:26,040 --> 11:46:30,320 uncore stir underscore uncore is 18388 11:46:27,916 --> 11:46:31,880 generally meant for users uh the users 18389 11:46:30,320 --> 11:46:33,956 of the program and it's meant to be even 18390 11:46:31,880 --> 11:46:36,560 more userfriendly but both of those can 18391 11:46:33,956 --> 11:46:38,520 be overridden as you see fit well let me 18392 11:46:36,560 --> 11:46:40,720 propose now that we pick up where we've 18393 11:46:38,520 --> 11:46:42,560 left off on student and just add even 18394 11:46:40,720 --> 11:46:44,916 more functionality but not just these 18395 11:46:42,560 --> 11:46:46,880 speci methods like double underscore 18396 11:46:44,916 --> 11:46:48,880 init and double underscore stir like 18397 11:46:46,880 --> 11:46:50,560 let's create our own methods because 18398 11:46:48,880 --> 11:46:52,840 there in lies the real power and 18399 11:46:50,560 --> 11:46:54,560 flexibility of classes if you and I as 18400 11:46:52,840 --> 11:46:56,400 the programmers can invent new 18401 11:46:54,560 --> 11:46:58,560 functionality that's specific to 18402 11:46:56,400 --> 11:47:00,840 students for instance uh students at 18403 11:46:58,560 --> 11:47:02,680 Hogwarts over the time in in school 18404 11:47:00,840 --> 11:47:05,480 learn how to cast a certain type of 18405 11:47:02,680 --> 11:47:06,956 spell so when they say expecto patronum 18406 11:47:05,480 --> 11:47:08,436 something comes out of their wand that 18407 11:47:06,956 --> 11:47:10,040 typically resembles an animal or 18408 11:47:08,436 --> 11:47:11,916 something like that it's a special spell 18409 11:47:10,040 --> 11:47:13,916 that they have to practice and practice 18410 11:47:11,916 --> 11:47:15,800 so let's see if if we can't store not 18411 11:47:13,916 --> 11:47:18,560 just a student's name and their house 18412 11:47:15,800 --> 11:47:20,720 but also their Patronus what actually 18413 11:47:18,560 --> 11:47:22,000 they conjure when using this spell well 18414 11:47:20,720 --> 11:47:25,200 let me go ahead and clear my terminal 18415 11:47:22,000 --> 11:47:28,040 window and in the top of my code here in 18416 11:47:25,200 --> 11:47:30,160 the init method of student let me go 18417 11:47:28,040 --> 11:47:31,956 ahead and start expecting a third 18418 11:47:30,160 --> 11:47:33,756 argument in addition to self which 18419 11:47:31,956 --> 11:47:36,116 automatically gets passed in called 18420 11:47:33,756 --> 11:47:38,720 petronis and I'm not going to worry uh 18421 11:47:36,116 --> 11:47:41,040 for now on validating the petronis from 18422 11:47:38,720 --> 11:47:43,116 an official list of valid patronises or 18423 11:47:41,040 --> 11:47:45,840 petroni I'm instead going to go ahead 18424 11:47:43,116 --> 11:47:48,200 and just blindly assign it to self. 18425 11:47:45,840 --> 11:47:50,160 Patronis equals petronis and we're going 18426 11:47:48,200 --> 11:47:52,160 to let the user type whatever they want 18427 11:47:50,160 --> 11:47:54,276 for now but I could certainly add more 18428 11:47:52,160 --> 11:47:56,680 error checking if I wanted to limit the 18429 11:47:54,276 --> 11:47:59,320 patronises to a specific list of them 18430 11:47:56,680 --> 11:48:02,116 here let me go ahead now and prompt the 18431 11:47:59,320 --> 11:48:04,436 user for this petronis as by in my get 18432 11:48:02,116 --> 11:48:06,320 student method uh get student function 18433 11:48:04,436 --> 11:48:08,200 defining a variable called petronis or 18434 11:48:06,320 --> 11:48:10,756 anything else prompting the user for 18435 11:48:08,200 --> 11:48:12,880 input for their petronis and now I'm 18436 11:48:10,756 --> 11:48:15,800 going to go ahead and pass in that third 18437 11:48:12,880 --> 11:48:17,800 variable here so again similar in spirit 18438 11:48:15,800 --> 11:48:19,320 to just adding more and more attributes 18439 11:48:17,800 --> 11:48:21,200 to the class I'm going to pass in all 18440 11:48:19,320 --> 11:48:22,680 three of these values instead of just 18441 11:48:21,200 --> 11:48:24,240 two I'm not going to do anything 18442 11:48:22,680 --> 11:48:26,040 interesting with that value yet but just 18443 11:48:24,240 --> 11:48:28,640 to make sure I haven't made things worse 18444 11:48:26,040 --> 11:48:31,360 by breaking my code let me run python of 18445 11:48:28,640 --> 11:48:33,360 studenty I'll type in Harry I'll type in 18446 11:48:31,360 --> 11:48:36,276 Gryffindor and it turns out his Patronis 18447 11:48:33,360 --> 11:48:37,840 was a stag and hit enter I haven't seen 18448 11:48:36,276 --> 11:48:40,080 what his Patronus is in my output 18449 11:48:37,840 --> 11:48:41,916 because I didn't change my stir method 18450 11:48:40,080 --> 11:48:43,880 yet but at least I don't have any syntax 18451 11:48:41,916 --> 11:48:47,160 error so at least I've not made anything 18452 11:48:43,880 --> 11:48:48,916 worse but suppose now I want to have 18453 11:48:47,160 --> 11:48:51,880 functionality not just for initializing 18454 11:48:48,916 --> 11:48:54,480 a student and printing out a student if 18455 11:48:51,880 --> 11:48:56,520 my class is really meant to be a student 18456 11:48:54,480 --> 11:48:59,240 what I can do is not just remember 18457 11:48:56,520 --> 11:49:01,720 information about data about students 18458 11:48:59,240 --> 11:49:04,520 what's powerful about classes unlike 18459 11:49:01,720 --> 11:49:07,400 dictionaries alone is that classes can 18460 11:49:04,520 --> 11:49:09,240 have not just variables or instance 18461 11:49:07,400 --> 11:49:11,520 variables so to speak those attributes 18462 11:49:09,240 --> 11:49:15,000 we keep creating they can also have 18463 11:49:11,520 --> 11:49:16,840 functions built in AKA methods when a 18464 11:49:15,000 --> 11:49:18,720 function is inside of a class it's 18465 11:49:16,840 --> 11:49:20,956 called a method but it's still just a 18466 11:49:18,720 --> 11:49:23,840 function at this point we've seen two 18467 11:49:20,956 --> 11:49:25,320 functions already two methods called uh 18468 11:49:23,840 --> 11:49:27,756 double underscore init and double 18469 11:49:25,320 --> 11:49:30,000 underscore stir but those are special 18470 11:49:27,756 --> 11:49:31,840 methods in that they just work if you 18471 11:49:30,000 --> 11:49:33,840 define them python calls them 18472 11:49:31,840 --> 11:49:35,840 automatically for you but what if you 18473 11:49:33,840 --> 11:49:38,116 wanted to create more functionality for 18474 11:49:35,840 --> 11:49:40,240 a student so that your class really 18475 11:49:38,116 --> 11:49:42,880 represents this real world or maybe 18476 11:49:40,240 --> 11:49:45,000 fantasy world notion of a student where 18477 11:49:42,880 --> 11:49:47,276 students not only have names and houses 18478 11:49:45,000 --> 11:49:49,840 and patronises they also have 18479 11:49:47,276 --> 11:49:53,436 functionality they have actions they can 18480 11:49:49,840 --> 11:49:56,240 perform like casting a charm a spell 18481 11:49:53,436 --> 11:49:59,240 magically could we Implement therefore a 18482 11:49:56,240 --> 11:50:02,160 function called charm that actually uh 18483 11:49:59,240 --> 11:50:04,040 uses uh their magical knowledge well 18484 11:50:02,160 --> 11:50:05,916 let's go ahead and Define our very own 18485 11:50:04,040 --> 11:50:08,200 function as follows Let Me Clear My 18486 11:50:05,916 --> 11:50:10,756 terminal window scroll back up to my 18487 11:50:08,200 --> 11:50:12,840 student class and instead of creating 18488 11:50:10,756 --> 11:50:15,040 yet another function that's special with 18489 11:50:12,840 --> 11:50:18,040 double underscores I'm going to invent 18490 11:50:15,040 --> 11:50:20,800 my own function or method inside of this 18491 11:50:18,040 --> 11:50:22,680 class I want to give uh Harry and 18492 11:50:20,800 --> 11:50:25,320 Hermione and and all of the other 18493 11:50:22,680 --> 11:50:26,680 students the ability to cast charms so 18494 11:50:25,320 --> 11:50:29,080 I'm going to define a function that I 18495 11:50:26,680 --> 11:50:31,040 can completely on my own called charm I 18496 11:50:29,080 --> 11:50:32,916 could call this function anything I want 18497 11:50:31,040 --> 11:50:35,116 but because it's a method inside of a 18498 11:50:32,916 --> 11:50:37,436 class the convention is that it's always 18499 11:50:35,116 --> 11:50:39,840 going to take at least one argument 18500 11:50:37,436 --> 11:50:42,880 called self by convention so that you 18501 11:50:39,840 --> 11:50:44,956 have access to the current object even 18502 11:50:42,880 --> 11:50:46,400 if you don't plan to use it per se all 18503 11:50:44,956 --> 11:50:48,560 right let me go ahead and propose that 18504 11:50:46,400 --> 11:50:51,240 we Implement charm in such a way that 18505 11:50:48,560 --> 11:50:54,520 the method returns an emoji that's 18506 11:50:51,240 --> 11:50:56,040 appropriate for each student's petronis 18507 11:50:54,520 --> 11:50:57,880 all right how to implement this well 18508 11:50:56,040 --> 11:51:01,040 inside of the charm method let's go 18509 11:50:57,880 --> 11:51:02,640 ahead and match on self. Patronis which 18510 11:51:01,040 --> 11:51:04,436 is the instance variable containing a 18511 11:51:02,640 --> 11:51:07,160 string that represents each student's 18512 11:51:04,436 --> 11:51:09,596 Patronis and in the case that it matches 18513 11:51:07,160 --> 11:51:12,080 a stag for instance for Harry let's go 18514 11:51:09,596 --> 11:51:15,240 ahead and return maybe the closest Emoji 18515 11:51:12,080 --> 11:51:17,840 this horse here how about in the case of 18516 11:51:15,240 --> 11:51:21,080 an otter well in that case let's go 18517 11:51:17,840 --> 11:51:23,200 ahead and return oh maybe the closest 18518 11:51:21,080 --> 11:51:26,200 match to the otter which might be this 18519 11:51:23,200 --> 11:51:29,436 Emoji here and let's see in the case of 18520 11:51:26,200 --> 11:51:33,040 a for Fon rather than Herm a Jack 18521 11:51:29,436 --> 11:51:35,276 Russell Terrier let's go ahead and 18522 11:51:33,040 --> 11:51:37,520 return how about don't have as many 18523 11:51:35,276 --> 11:51:39,800 options here why don't we go ahead and 18524 11:51:37,520 --> 11:51:43,360 return the cutest available dog in that 18525 11:51:39,800 --> 11:51:46,520 case and in the case of 18526 11:51:43,360 --> 11:51:48,116 no Patronis recognized as might cover 18527 11:51:46,520 --> 11:51:50,276 someone like Draco let's go ahead and 18528 11:51:48,116 --> 11:51:52,560 use a default case using the underscore 18529 11:51:50,276 --> 11:51:54,520 as as in the past and let's go ahead and 18530 11:51:52,560 --> 11:51:56,240 return for this oh what should happen if 18531 11:51:54,520 --> 11:51:58,160 someone doesn't have a petronis why 18532 11:51:56,240 --> 11:52:01,040 don't we just see a magical wand that 18533 11:51:58,160 --> 11:52:02,520 seems to fizzle out as in this case all 18534 11:52:01,040 --> 11:52:04,080 right well now rather than just print 18535 11:52:02,520 --> 11:52:05,800 the student let's go about printing 18536 11:52:04,080 --> 11:52:08,000 their actual Patronis so I'm going to go 18537 11:52:05,800 --> 11:52:09,916 down to my main function here I'm going 18538 11:52:08,000 --> 11:52:11,956 to still get a student using the get 18539 11:52:09,916 --> 11:52:14,080 student function but rather than print 18540 11:52:11,956 --> 11:52:17,520 student let's go ahead and declare 18541 11:52:14,080 --> 11:52:19,956 expecto patronum printing out just that 18542 11:52:17,520 --> 11:52:22,720 as pure text and now let's go ahead and 18543 11:52:19,956 --> 11:52:25,720 print out not the student but rather the 18544 11:52:22,720 --> 11:52:27,160 return value of their own charm Method 18545 11:52:25,720 --> 11:52:29,200 All right so let me go back down to my 18546 11:52:27,160 --> 11:52:32,160 terminal window and run python of 18547 11:52:29,200 --> 11:52:35,240 student. py and enter name let's start 18548 11:52:32,160 --> 11:52:39,000 with Harry he lives in Gryffindor uh 18549 11:52:35,240 --> 11:52:41,480 petronis is a stag and let's see expecto 18550 11:52:39,000 --> 11:52:44,240 patronum and of course we see the Stag 18551 11:52:41,480 --> 11:52:46,040 emoji what about someone like Draco who 18552 11:52:44,240 --> 11:52:47,840 at least in the books doesn't have a 18553 11:52:46,040 --> 11:52:50,240 known petronis well let's go ahead and 18554 11:52:47,840 --> 11:52:53,080 clear my terminal window rerun python of 18555 11:52:50,240 --> 11:52:56,480 student. and this time let's type in 18556 11:52:53,080 --> 11:52:58,160 Draco for name Slytherin for house and 18557 11:52:56,480 --> 11:53:00,720 Patronis is unknown so I'm just going to 18558 11:52:58,160 --> 11:53:04,360 go ahead and hit enter and now expect o 18559 11:53:00,720 --> 11:53:07,400 patronum and just kind of sizzles 18560 11:53:04,360 --> 11:53:12,240 instead questions now on what I've done 18561 11:53:07,400 --> 11:53:14,720 by implementing this charm method can we 18562 11:53:12,240 --> 11:53:16,720 uh like call a method outside the 18563 11:53:14,720 --> 11:53:18,596 function absolutely and we're seeing 18564 11:53:16,720 --> 11:53:21,320 that already if I scroll back down to my 18565 11:53:18,596 --> 11:53:22,840 main function which is outside of the 18566 11:53:21,320 --> 11:53:24,756 class because it's all the way down in 18567 11:53:22,840 --> 11:53:27,800 the file it's all left align just like 18568 11:53:24,756 --> 11:53:30,596 the class notice on line 28 I'm calling 18569 11:53:27,800 --> 11:53:32,880 student. charm and I'm accessing a 18570 11:53:30,596 --> 11:53:35,520 method that's inside of the student 18571 11:53:32,880 --> 11:53:36,800 object even though my main function is 18572 11:53:35,520 --> 11:53:39,756 outside of the 18573 11:53:36,800 --> 11:53:43,640 class and what's different between our 18574 11:53:39,756 --> 11:53:45,640 init function or method and our stir 18575 11:53:43,640 --> 11:53:48,040 method that we've seen before those are 18576 11:53:45,640 --> 11:53:49,596 called automatically when you try to 18577 11:53:48,040 --> 11:53:51,720 create a student or when you try to 18578 11:53:49,596 --> 11:53:54,080 print a student for the first time we're 18579 11:53:51,720 --> 11:53:56,200 now seeing a method that I invented 18580 11:53:54,080 --> 11:53:58,400 inside of the student class that I can 18581 11:53:56,200 --> 11:54:00,596 call anywhere I want and if I'm calling 18582 11:53:58,400 --> 11:54:02,276 it outside of the class like I am here I 18583 11:54:00,596 --> 11:54:04,240 just use the name of the variable 18584 11:54:02,276 --> 11:54:06,956 containing that student object and I 18585 11:54:04,240 --> 11:54:09,756 just do charm just like I could access 18586 11:54:06,956 --> 11:54:13,000 the individual attributes or in instance 18587 11:54:09,756 --> 11:54:16,560 variables inside of that object as well 18588 11:54:13,000 --> 11:54:20,720 other questions on classes and this new 18589 11:54:16,560 --> 11:54:22,436 method charm in a parentheses you are 18590 11:54:20,720 --> 11:54:25,080 you put self supposed to be like a 18591 11:54:22,436 --> 11:54:28,000 initializer but like in the top part you 18592 11:54:25,080 --> 11:54:30,520 didn't you didn't um Define it the same 18593 11:54:28,000 --> 11:54:32,320 way would you have to put the class on 18594 11:54:30,520 --> 11:54:34,400 why you didn't put the class right there 18595 11:54:32,320 --> 11:54:36,360 so notice the indentation here so on 18596 11:54:34,400 --> 11:54:38,436 line one I've of course said class 18597 11:54:36,360 --> 11:54:40,276 student colon and then everything below 18598 11:54:38,436 --> 11:54:42,800 that is indented at the moment that 18599 11:54:40,276 --> 11:54:44,756 means that my init method my my stir 18600 11:54:42,800 --> 11:54:47,840 method and this new charm method are all 18601 11:54:44,756 --> 11:54:49,916 inside of part of that class by 18602 11:54:47,840 --> 11:54:52,916 convention then each of these methods 18603 11:54:49,916 --> 11:54:55,276 inside of a class should expect that 18604 11:54:52,916 --> 11:54:57,800 python will automatically pass in at 18605 11:54:55,276 --> 11:55:00,640 least one argument to every method in a 18606 11:54:57,800 --> 11:55:03,200 class and that argument will always be a 18607 11:55:00,640 --> 11:55:06,116 reference to the current object the 18608 11:55:03,200 --> 11:55:08,640 Harry object or the Draco object that is 18609 11:55:06,116 --> 11:55:11,480 currently trying to cast a charm or be 18610 11:55:08,640 --> 11:55:13,720 printed so whenever you create a method 18611 11:55:11,480 --> 11:55:15,520 inside of a class you should always have 18612 11:55:13,720 --> 11:55:17,840 it take at least one argument called 18613 11:55:15,520 --> 11:55:20,200 self and then zero or more other 18614 11:55:17,840 --> 11:55:22,080 arguments that are entirely up to you in 18615 11:55:20,200 --> 11:55:24,956 it for instance takes three more name 18616 11:55:22,080 --> 11:55:27,240 house Patronis stir takes zero more 18617 11:55:24,956 --> 11:55:29,596 charm takes zero more but the convention 18618 11:55:27,240 --> 11:55:31,956 is to always call that default argument 18619 11:55:29,596 --> 11:55:34,956 self and python just automatically gives 18620 11:55:31,956 --> 11:55:37,520 you access to the current 18621 11:55:34,956 --> 11:55:40,880 object other questions how about one 18622 11:55:37,520 --> 11:55:42,840 more on classes and charms sir I just 18623 11:55:40,880 --> 11:55:46,000 wanted to ask that uh you you have put 18624 11:55:42,840 --> 11:55:48,560 the emojis in double quotes So does it 18625 11:55:46,000 --> 11:55:51,520 take the Emojis as a form of strings or 18626 11:55:48,560 --> 11:55:54,680 something else yes if unfamiliar an 18627 11:55:51,520 --> 11:55:56,756 emoji is just a character it's part of a 18628 11:55:54,680 --> 11:55:59,680 mapping of numbers to letters known as 18629 11:55:56,756 --> 11:56:02,160 Unicode and so whenever you see these 18630 11:55:59,680 --> 11:56:04,756 emoji on the screen like the horse or 18631 11:56:02,160 --> 11:56:06,480 the otter or the dog here specifically 18632 11:56:04,756 --> 11:56:08,520 that's really just like a key from your 18633 11:56:06,480 --> 11:56:09,800 keyboard you and I on Max and PCs can't 18634 11:56:08,520 --> 11:56:11,640 typically type it because you see 18635 11:56:09,800 --> 11:56:14,560 English characters or some other human 18636 11:56:11,640 --> 11:56:17,520 language but Emoji are increasingly 18637 11:56:14,560 --> 11:56:19,916 available uh via menus and drop down and 18638 11:56:17,520 --> 11:56:22,276 in my case copy paste on Macs and PCs 18639 11:56:19,916 --> 11:56:23,720 and Android devices and iPhones they are 18640 11:56:22,276 --> 11:56:25,276 just characters even though they look 18641 11:56:23,720 --> 11:56:27,520 like pictures you can think of it like a 18642 11:56:25,276 --> 11:56:29,116 graphical font almost so they're just 18643 11:56:27,520 --> 11:56:30,916 text and indeed if you put them between 18644 11:56:29,116 --> 11:56:33,596 double quotes or single quotes you can 18645 11:56:30,916 --> 11:56:36,560 print Emoji just like you can any other 18646 11:56:33,596 --> 11:56:40,436 human character as well well let me 18647 11:56:36,560 --> 11:56:42,956 propose now that we remove this Patronis 18648 11:56:40,436 --> 11:56:44,800 code just to simplify our world and 18649 11:56:42,956 --> 11:56:46,840 focus on some of the other core 18650 11:56:44,800 --> 11:56:48,436 capabilities of classes so at the risk 18651 11:56:46,840 --> 11:56:51,040 of disappointing I'm going to get rid of 18652 11:56:48,436 --> 11:56:52,680 all of these beautiful emoji and charms 18653 11:56:51,040 --> 11:56:55,000 and I'm going to go ahead and stop 18654 11:56:52,680 --> 11:56:57,160 asking the user now for their petronis 18655 11:56:55,000 --> 11:56:59,800 and I'm going to stop passing it into in 18656 11:56:57,160 --> 11:57:02,480 it here and I'm going to stop uh doing 18657 11:56:59,800 --> 11:57:05,596 this here and I'm going to instead just 18658 11:57:02,480 --> 11:57:07,840 go ahead and restore our use of print 18659 11:57:05,596 --> 11:57:10,160 student here and I'm going to go ahead 18660 11:57:07,840 --> 11:57:12,560 and get rid of petronis down here so 18661 11:57:10,160 --> 11:57:14,560 essentially undo all of the fun charm we 18662 11:57:12,560 --> 11:57:18,276 just created so we're now back at the 18663 11:57:14,560 --> 11:57:21,160 point in the story where we have a 18664 11:57:18,276 --> 11:57:23,720 student class with only two methods in 18665 11:57:21,160 --> 11:57:25,400 it and stir the first of those takes of 18666 11:57:23,720 --> 11:57:27,720 course self as the first argument as it 18667 11:57:25,400 --> 11:57:30,080 always will plus two more now name and 18668 11:57:27,720 --> 11:57:32,480 house no more Patronis we're validating 18669 11:57:30,080 --> 11:57:34,276 name up here we're validating house down 18670 11:57:32,480 --> 11:57:36,200 here and then we're assigning name and 18671 11:57:34,276 --> 11:57:38,640 house respectively to two instance 18672 11:57:36,200 --> 11:57:40,916 variables called name and house also but 18673 11:57:38,640 --> 11:57:42,640 we used self to get access to the 18674 11:57:40,916 --> 11:57:44,800 current object to store store those 18675 11:57:42,640 --> 11:57:47,080 values therein we then still have our 18676 11:57:44,800 --> 11:57:49,200 stir method here which takes one 18677 11:57:47,080 --> 11:57:50,956 argument by default self and that's it 18678 11:57:49,200 --> 11:57:53,000 and that function is going to be called 18679 11:57:50,956 --> 11:57:55,680 automatically anytime you want to 18680 11:57:53,000 --> 11:57:58,240 convert a student object to a string 18681 11:57:55,680 --> 11:57:59,720 just like print might want to do here so 18682 11:57:58,240 --> 11:58:01,160 let me go ahead and just make sure I 18683 11:57:59,720 --> 11:58:03,840 haven't broken anything let me run 18684 11:58:01,160 --> 11:58:06,520 python of studenty I'll type in Harry 18685 11:58:03,840 --> 11:58:08,520 I'll type in Gryffindor enter okay we're 18686 11:58:06,520 --> 11:58:10,596 back in business gone are the charms and 18687 11:58:08,520 --> 11:58:13,200 patronises but at least I'm back to a 18688 11:58:10,596 --> 11:58:16,360 situation where I have names and houses 18689 11:58:13,200 --> 11:58:19,840 but it turns out at the moment our use 18690 11:58:16,360 --> 11:58:22,360 of classes is not very robust even 18691 11:58:19,840 --> 11:58:25,200 though we have this mechanism very 18692 11:58:22,360 --> 11:58:27,400 cleverly if I may in our init method of 18693 11:58:25,200 --> 11:58:29,520 making sure that we're validating name 18694 11:58:27,400 --> 11:58:32,200 and house making sure that name is not 18695 11:58:29,520 --> 11:58:34,840 blank and making sure that house is a 18696 11:58:32,200 --> 11:58:37,560 valid house among those four Hogwarts 18697 11:58:34,840 --> 11:58:39,720 houses it turns out that classes will 18698 11:58:37,560 --> 11:58:42,320 still let me get at those attributes 18699 11:58:39,720 --> 11:58:45,080 those so-called instance variables using 18700 11:58:42,320 --> 11:58:46,680 notation anyway let me scroll down then 18701 11:58:45,080 --> 11:58:49,560 and try to do this a little 18702 11:58:46,680 --> 11:58:51,596 adversarially suppose that on line 16 I 18703 11:58:49,560 --> 11:58:54,240 go ahead and call get student which 18704 11:58:51,596 --> 11:58:56,436 exists as before and then I store the 18705 11:58:54,240 --> 11:59:00,080 return value in a student variable again 18706 11:58:56,436 --> 11:59:02,436 on line 16 that will ensure that get 18707 11:59:00,080 --> 11:59:05,160 student gets called which calls input 18708 11:59:02,436 --> 11:59:07,240 and input and then it calls the student 18709 11:59:05,160 --> 11:59:09,800 Constructor which invokes automatically 18710 11:59:07,240 --> 11:59:12,240 this init method so by way of how we've 18711 11:59:09,800 --> 11:59:14,240 laid out my code we're going to ensure 18712 11:59:12,240 --> 11:59:16,080 that name is not blank and house is 18713 11:59:14,240 --> 11:59:18,680 definitely one of those four values my 18714 11:59:16,080 --> 11:59:22,200 error correction or error checking is in 18715 11:59:18,680 --> 11:59:24,680 place but if I'm a little adversarial I 18716 11:59:22,200 --> 11:59:26,680 can still circumvent it suppose that 18717 11:59:24,680 --> 11:59:28,596 fine I'm G to you're going to require me 18718 11:59:26,680 --> 11:59:30,680 to type in Harry and griffindor I'm 18719 11:59:28,596 --> 11:59:33,520 going to go ahead and type in student.h 18720 11:59:30,680 --> 11:59:35,436 house equals quote unquote number four 18721 11:59:33,520 --> 11:59:38,000 private drive and you're not going to be 18722 11:59:35,436 --> 11:59:40,720 able to stop me why well it turns out 18723 11:59:38,000 --> 11:59:42,756 with classes and objects thereof you and 18724 11:59:40,720 --> 11:59:44,480 I can still access those instance 18725 11:59:42,756 --> 11:59:46,080 variables using this familiar dot 18726 11:59:44,480 --> 11:59:48,000 notation that's how we began the story 18727 11:59:46,080 --> 11:59:50,480 of classes just setting these attributes 18728 11:59:48,000 --> 11:59:52,360 ourselves but you can also read these 18729 11:59:50,480 --> 11:59:54,480 attributes themselves and change them 18730 11:59:52,360 --> 11:59:57,560 later if you want and this will 18731 11:59:54,480 --> 11:59:59,360 effectively circumvent the if condition 18732 11:59:57,560 --> 12:00:02,360 and the other if condition in our init 18733 11:59:59,360 --> 12:00:05,080 method because that is only called when 18734 12:00:02,360 --> 12:00:06,680 you first create the student object 18735 12:00:05,080 --> 12:00:09,880 there's nothing stopping me at the 18736 12:00:06,680 --> 12:00:12,956 moment from just changing the house or 18737 12:00:09,880 --> 12:00:14,520 the name after so if I now now clear my 18738 12:00:12,956 --> 12:00:17,080 terminal window and run python of 18739 12:00:14,520 --> 12:00:19,200 studenty I'll still type in Harry and 18740 12:00:17,080 --> 12:00:21,116 Gryffindor to meet my requirements that 18741 12:00:19,200 --> 12:00:23,160 the house be one of those four but when 18742 12:00:21,116 --> 12:00:26,000 it's printed notice I've still 18743 12:00:23,160 --> 12:00:27,756 overridden it so it seems that while 18744 12:00:26,000 --> 12:00:30,320 classes do allow us a little more 18745 12:00:27,756 --> 12:00:33,080 control over the data we're storing it 18746 12:00:30,320 --> 12:00:35,400 doesn't necessarily prevent the user be 18747 12:00:33,080 --> 12:00:37,436 it or rather the programmer be it myself 18748 12:00:35,400 --> 12:00:40,240 or maybe a colleague from still kind of 18749 12:00:37,436 --> 12:00:42,080 messing things up so here too in the 18750 12:00:40,240 --> 12:00:44,040 spirit of programming a little more 18751 12:00:42,080 --> 12:00:48,200 defensively allow me to introduce 18752 12:00:44,040 --> 12:00:51,320 another feature of python as well namely 18753 12:00:48,200 --> 12:00:54,080 properties so a property is really just 18754 12:00:51,320 --> 12:00:56,480 an attribute that has even more defense 18755 12:00:54,080 --> 12:00:59,320 mechanisms put into place a little more 18756 12:00:56,480 --> 12:01:01,956 functionality implemented by you to 18757 12:00:59,320 --> 12:01:03,880 prevent programmers like me and you from 18758 12:01:01,956 --> 12:01:05,956 messing things up like these attributes 18759 12:01:03,880 --> 12:01:07,880 so again a property is going to be an 18760 12:01:05,956 --> 12:01:10,480 attribute that you and I just have more 18761 12:01:07,880 --> 12:01:12,880 control over how we just write a little 18762 12:01:10,480 --> 12:01:14,840 more code using some python conventions 18763 12:01:12,880 --> 12:01:17,480 and how we're going to do that is going 18764 12:01:14,840 --> 12:01:19,916 to use in just a moment a feature a 18765 12:01:17,480 --> 12:01:21,720 keyword known as app property which is 18766 12:01:19,916 --> 12:01:23,480 technically a function property is a 18767 12:01:21,720 --> 12:01:26,436 function in Python but we're about to 18768 12:01:23,480 --> 12:01:28,360 see some new at syntax that allows you 18769 12:01:26,436 --> 12:01:30,480 to decorate functions and this to is a 18770 12:01:28,360 --> 12:01:33,520 term of Art in the world of python you 18771 12:01:30,480 --> 12:01:35,400 can have decorators which are functions 18772 12:01:33,520 --> 12:01:37,200 that modify the behavior of other 18773 12:01:35,400 --> 12:01:39,240 functions if you will and we'll leave it 18774 12:01:37,200 --> 12:01:40,916 at that without going too much into the 18775 12:01:39,240 --> 12:01:43,040 weeds and we'll see by example how you 18776 12:01:40,916 --> 12:01:45,320 can use these decor Ator specifically to 18777 12:01:43,040 --> 12:01:48,800 define properties so let me go back to 18778 12:01:45,320 --> 12:01:52,480 vs code here and let me propose that I 18779 12:01:48,800 --> 12:01:56,480 do this I'm going to go ahead and create 18780 12:01:52,480 --> 12:02:01,400 how about a property called house as 18781 12:01:56,480 --> 12:02:03,400 follows inside of my uh student class 18782 12:02:01,400 --> 12:02:05,276 I'm going to go ahead and below my init 18783 12:02:03,400 --> 12:02:08,116 method and below my stir method I'm 18784 12:02:05,276 --> 12:02:10,240 going to go ahead and Define a function 18785 12:02:08,116 --> 12:02:13,200 called house that takes as it always 18786 12:02:10,240 --> 12:02:16,200 must one argument at least called self 18787 12:02:13,200 --> 12:02:19,160 and what I'm going to do now is return 18788 12:02:16,200 --> 12:02:21,756 uh self. house so I'm just going to 18789 12:02:19,160 --> 12:02:25,320 define a method called House whose sole 18790 12:02:21,756 --> 12:02:27,480 purpose in life is to return the value 18791 12:02:25,320 --> 12:02:30,436 of house but I'm going to Define one 18792 12:02:27,480 --> 12:02:32,480 other method curiously also called house 18793 12:02:30,436 --> 12:02:36,116 but that's going to take into as 18794 12:02:32,480 --> 12:02:39,276 arguments two values self as always and 18795 12:02:36,116 --> 12:02:42,400 also a value called house and I'm going 18796 12:02:39,276 --> 12:02:45,400 to now do this uh I'm going to say self 18797 12:02:42,400 --> 12:02:48,276 rather I'm going to do self. house 18798 12:02:45,400 --> 12:02:49,640 equals house now what have I done well 18799 12:02:48,276 --> 12:02:51,680 let me just temporarily add some 18800 12:02:49,640 --> 12:02:53,400 comments here in a moment we're going to 18801 12:02:51,680 --> 12:02:55,560 start referring to this generally as a 18802 12:02:53,400 --> 12:02:57,436 getter and down here I'm going to refer 18803 12:02:55,560 --> 12:02:58,800 to this as a Setter and this is 18804 12:02:57,436 --> 12:03:00,200 terminology you frequently see in the 18805 12:02:58,800 --> 12:03:02,116 world of java if some of you have 18806 12:03:00,200 --> 12:03:05,080 programmed in Java before but as the 18807 12:03:02,116 --> 12:03:09,480 names imply a getter is a function for a 18808 12:03:05,080 --> 12:03:12,116 class that gets some attribute a Setter 18809 12:03:09,480 --> 12:03:14,640 is a function in some class that sets 18810 12:03:12,116 --> 12:03:16,640 some value and now even though we're not 18811 12:03:14,640 --> 12:03:18,400 done and there's a bit of a mistake in 18812 12:03:16,640 --> 12:03:20,116 the code I've already written 18813 12:03:18,400 --> 12:03:22,880 intuitively what we're going to do is 18814 12:03:20,116 --> 12:03:25,400 this we're trying to prevent programmers 18815 12:03:22,880 --> 12:03:27,320 myself included from circumventing my 18816 12:03:25,400 --> 12:03:30,240 error checking that I put into place for 18817 12:03:27,320 --> 12:03:31,840 name and house how can I do that well we 18818 12:03:30,240 --> 12:03:33,240 don't have that many building blocks in 18819 12:03:31,840 --> 12:03:35,480 programming we have things like 18820 12:03:33,240 --> 12:03:37,956 variables for data and we have functions 18821 12:03:35,480 --> 12:03:41,040 for actions well why don't we do this 18822 12:03:37,956 --> 12:03:43,200 why don't we somehow require that in 18823 12:03:41,040 --> 12:03:45,680 order to access an attribute you go 18824 12:03:43,200 --> 12:03:47,720 through some function and let's require 18825 12:03:45,680 --> 12:03:50,000 that in order to set some attribute you 18826 12:03:47,720 --> 12:03:51,840 go through some function and 18827 12:03:50,000 --> 12:03:55,000 conventionally those functions are 18828 12:03:51,840 --> 12:03:57,200 called a getter function and a Setter 18829 12:03:55,000 --> 12:03:58,956 function and why are we using functions 18830 12:03:57,200 --> 12:04:01,480 or in this case methods inside of a 18831 12:03:58,956 --> 12:04:03,400 class well once you have functions those 18832 12:04:01,480 --> 12:04:05,400 are just actions or verbs that you and I 18833 12:04:03,400 --> 12:04:07,360 can create ourselves we can put any 18834 12:04:05,400 --> 12:04:09,360 error correction I want in these 18835 12:04:07,360 --> 12:04:12,160 functions because it's code that's going 18836 12:04:09,360 --> 12:04:16,116 to get executed top to bottom so so how 18837 12:04:12,160 --> 12:04:18,916 can I now prevent the user from setting 18838 12:04:16,116 --> 12:04:21,520 the house to an invalid value let me 18839 12:04:18,916 --> 12:04:24,000 borrow some logic from before rather 18840 12:04:21,520 --> 12:04:26,560 than blindly do this just set self. 18841 12:04:24,000 --> 12:04:28,640 house equal to the house value that's 18842 12:04:26,560 --> 12:04:31,640 passed in let's add our eror checking 18843 12:04:28,640 --> 12:04:35,520 there so if house is not in the 18844 12:04:31,640 --> 12:04:41,040 following list of Gryffindor or 18845 12:04:35,520 --> 12:04:44,116 Hufflepuff or slyther or Ravenclaw or 18846 12:04:41,040 --> 12:04:46,160 slythering in just as before let's go 18847 12:04:44,116 --> 12:04:47,880 ahead and raise a value error just to 18848 12:04:46,160 --> 12:04:49,956 signify that uh-uh something has gone 18849 12:04:47,880 --> 12:04:52,680 wrong I'll be more explicit I'll include 18850 12:04:49,956 --> 12:04:55,276 a message like invalid house quote 18851 12:04:52,680 --> 12:04:59,200 unquote otherwise I'm going to proceed 18852 12:04:55,276 --> 12:05:00,880 on now line 21 to set self. houseo house 18853 12:04:59,200 --> 12:05:03,560 so I've just copied if you will or 18854 12:05:00,880 --> 12:05:06,200 retyped my error checking inside of this 18855 12:05:03,560 --> 12:05:08,880 so-called Setter function now why have I 18856 12:05:06,200 --> 12:05:11,436 done that well to be clear whenever the 18857 12:05:08,880 --> 12:05:12,360 user or the programmer writes code like 18858 12:05:11,436 --> 12:05:15,840 this 18859 12:05:12,360 --> 12:05:19,040 student. housee equals what's about to 18860 12:05:15,840 --> 12:05:20,956 happen magically is python will not just 18861 12:05:19,040 --> 12:05:23,080 let the programmer access student.h 18862 12:05:20,956 --> 12:05:26,240 housee directly that attribute that 18863 12:05:23,080 --> 12:05:29,276 instance variable AKA self. house it's 18864 12:05:26,240 --> 12:05:31,916 instead going to magically automatically 18865 12:05:29,276 --> 12:05:34,560 call this Setter function for me how 18866 12:05:31,916 --> 12:05:37,116 does python no to do that well if it 18867 12:05:34,560 --> 12:05:40,880 sees that on the leftand side there is 18868 12:05:37,116 --> 12:05:44,200 self. housee where house is the name of 18869 12:05:40,880 --> 12:05:46,640 the getter or Setter and then it sees an 18870 12:05:44,200 --> 12:05:48,640 equal sign indicating assignment that's 18871 12:05:46,640 --> 12:05:50,680 just enough of a visual clue to say wait 18872 12:05:48,640 --> 12:05:53,436 a minute I'm not going to let you access 18873 12:05:50,680 --> 12:05:55,840 that attribute directly I'm going to use 18874 12:05:53,436 --> 12:05:57,480 the setter instead why because the equal 18875 12:05:55,840 --> 12:05:59,520 sign means I'm trying to set I'm trying 18876 12:05:57,480 --> 12:06:02,116 to assign a value from right to left 18877 12:05:59,520 --> 12:06:04,160 into that attribute so what Python's 18878 12:06:02,116 --> 12:06:06,160 going to do automatically is call this 18879 12:06:04,160 --> 12:06:08,040 function for me and that's amazing 18880 12:06:06,160 --> 12:06:10,840 because now I can execute code an 18881 12:06:08,040 --> 12:06:13,880 algorithm to check do I want to let the 18882 12:06:10,840 --> 12:06:16,360 user the programmer set that attribute 18883 12:06:13,880 --> 12:06:17,756 to that value if not I'm going to raise 18884 12:06:16,360 --> 12:06:20,640 a value error and you're just not going 18885 12:06:17,756 --> 12:06:23,116 to be able to do it if so fine I'll go 18886 12:06:20,640 --> 12:06:24,916 ahead and set it for you but in order to 18887 12:06:23,116 --> 12:06:26,320 do this we need a little more syntax and 18888 12:06:24,916 --> 12:06:28,640 I'm going to get rid of my comment and 18889 12:06:26,320 --> 12:06:31,756 I'm going to use that decorator I need 18890 12:06:28,640 --> 12:06:33,680 to tell python to treat this method as a 18891 12:06:31,756 --> 12:06:36,000 getter and then the Syntax for the 18892 12:06:33,680 --> 12:06:39,080 setter is a little different you now say 18893 12:06:36,000 --> 12:06:41,116 house. Setter I wish one was getter and 18894 12:06:39,080 --> 12:06:43,240 the other was Setter that's not the way 18895 12:06:41,116 --> 12:06:46,360 they designed it when you want to define 18896 12:06:43,240 --> 12:06:49,116 a getter you just say at property above 18897 12:06:46,360 --> 12:06:51,680 the function and you name the function 18898 12:06:49,116 --> 12:06:54,436 exactly like you would like the property 18899 12:06:51,680 --> 12:06:56,720 to be called quote unquote house once 18900 12:06:54,436 --> 12:06:58,436 you do that you can now use a new 18901 12:06:56,720 --> 12:07:00,640 decorator that sort of automatically 18902 12:06:58,436 --> 12:07:02,596 created for you called at house because 18903 12:07:00,640 --> 12:07:05,560 I called it house and then you literally 18904 12:07:02,596 --> 12:07:08,956 say at house. Setter and this whole line 18905 12:07:05,560 --> 12:07:11,956 on line 17 is a clue to python that here 18906 12:07:08,956 --> 12:07:14,116 comes a function whose name is identical 18907 12:07:11,956 --> 12:07:15,640 but notice that it takes two arguments 18908 12:07:14,116 --> 12:07:17,840 both self so you have access to the 18909 12:07:15,640 --> 12:07:19,596 contents of the object and house which 18910 12:07:17,840 --> 12:07:21,680 is just going to be a stir that comes 18911 12:07:19,596 --> 12:07:25,200 from the programmer from like the human 18912 12:07:21,680 --> 12:07:28,640 input return value so that you can set 18913 12:07:25,200 --> 12:07:31,436 that value as well but there's one fix I 18914 12:07:28,640 --> 12:07:34,480 need to make now here everything else I 18915 12:07:31,436 --> 12:07:38,880 think is still good however watch this I 18916 12:07:34,480 --> 12:07:41,800 no longer need this error check here why 18917 12:07:38,880 --> 12:07:44,400 because if I scroll back down to my code 18918 12:07:41,800 --> 12:07:49,116 here I claimed a moment ago that code 18919 12:07:44,400 --> 12:07:51,080 like this with uh student.h house equals 18920 12:07:49,116 --> 12:07:54,480 is going to automatically get python to 18921 12:07:51,080 --> 12:07:58,040 call my Setter for me guess what even up 18922 12:07:54,480 --> 12:08:01,040 here in my init method calling self. 18923 12:07:58,040 --> 12:08:03,680 housee equals is also going to call my 18924 12:08:01,040 --> 12:08:06,520 Setter method which is amazing because 18925 12:08:03,680 --> 12:08:09,720 now I can keep all of my error checking 18926 12:08:06,520 --> 12:08:12,240 in one place in the setter and it will 18927 12:08:09,720 --> 12:08:14,200 now get called either E when I create 18928 12:08:12,240 --> 12:08:17,520 the object for the first time because of 18929 12:08:14,200 --> 12:08:19,956 in it or even if the you the programmer 18930 12:08:17,520 --> 12:08:22,400 tries to circumvent that init method and 18931 12:08:19,956 --> 12:08:24,840 change the value of this attribute my 18932 12:08:22,400 --> 12:08:28,040 Setter will also get called my Setter 18933 12:08:24,840 --> 12:08:32,160 will get called anytime I access do 18934 12:08:28,040 --> 12:08:36,200 house but there's one fix I need to make 18935 12:08:32,160 --> 12:08:39,520 unfortunately I have collided names 18936 12:08:36,200 --> 12:08:41,720 right now if we go up here on line five 18937 12:08:39,520 --> 12:08:44,116 this is an instance variable it's a 18938 12:08:41,720 --> 12:08:46,320 string inside of myself inside of the 18939 12:08:44,116 --> 12:08:49,080 current student object called name and 18940 12:08:46,320 --> 12:08:51,596 this is another instance variable called 18941 12:08:49,080 --> 12:08:54,400 House unfortunately if I have an 18942 12:08:51,596 --> 12:08:57,080 instance variable called name and house 18943 12:08:54,400 --> 12:08:59,116 I cannot also have functions called 18944 12:08:57,080 --> 12:09:01,320 house they're going to collide you got 18945 12:08:59,116 --> 12:09:03,596 to decide do you want the variable to be 18946 12:09:01,320 --> 12:09:05,560 called house or do you want the function 18947 12:09:03,596 --> 12:09:07,160 to be called House unfortunately you 18948 12:09:05,560 --> 12:09:09,240 can't have both because now Python's 18949 12:09:07,160 --> 12:09:11,680 going to confuse one for the other so 18950 12:09:09,240 --> 12:09:15,520 the conventional fix for this is to do 18951 12:09:11,680 --> 12:09:18,276 this to have the setter not store the 18952 12:09:15,520 --> 12:09:20,320 value that's passed in in self. house 18953 12:09:18,276 --> 12:09:22,436 but to use an almost identical name but 18954 12:09:20,320 --> 12:09:24,436 to use a little indicator that you means 18955 12:09:22,436 --> 12:09:25,800 you know you're doing this correctly you 18956 12:09:24,436 --> 12:09:28,756 typically by convention put an 18957 12:09:25,800 --> 12:09:31,160 underscore in front of the instance 18958 12:09:28,756 --> 12:09:34,276 variable's name and when you return it 18959 12:09:31,160 --> 12:09:37,276 up here you similarly put an underscore 18960 12:09:34,276 --> 12:09:40,640 so now technically my instance variable 18961 12:09:37,276 --> 12:09:41,956 is called underscore house but my 18962 12:09:40,640 --> 12:09:44,720 property 18963 12:09:41,956 --> 12:09:48,560 which is a fancier attribute if you will 18964 12:09:44,720 --> 12:09:51,080 is called house alone huge amount of 18965 12:09:48,560 --> 12:09:53,276 syntax I know but it's a very powerful 18966 12:09:51,080 --> 12:09:55,436 feature and again this is why you can 18967 12:09:53,276 --> 12:09:57,640 graduate from dictionaries alone and 18968 12:09:55,436 --> 12:09:59,480 have so much more functionality at your 18969 12:09:57,640 --> 12:10:00,956 disposal let me go ahead and clear my 18970 12:09:59,480 --> 12:10:04,080 terminal window and run python of 18971 12:10:00,956 --> 12:10:06,240 student. enter name all right let's go 18972 12:10:04,080 --> 12:10:08,240 ahead and type in Harry let's go ahead 18973 12:10:06,240 --> 12:10:11,640 and type in Gryffindor crossing my 18974 12:10:08,240 --> 12:10:14,200 fingers as always and now look inval 18975 12:10:11,640 --> 12:10:17,720 house this is a good thing why because 18976 12:10:14,200 --> 12:10:20,880 notice in my main function I'm still 18977 12:10:17,720 --> 12:10:23,276 trying maliciously if you will to change 18978 12:10:20,880 --> 12:10:24,756 Harry's house to not be one of the four 18979 12:10:23,276 --> 12:10:26,720 valid ones I'm trying to change it to 18980 12:10:24,756 --> 12:10:29,400 his childhood home of number four 18981 12:10:26,720 --> 12:10:31,360 private drive but because python knows 18982 12:10:29,400 --> 12:10:34,520 that wait a minute you're trying to 18983 12:10:31,360 --> 12:10:37,436 assign that is set a value and that 18984 12:10:34,520 --> 12:10:39,080 value AKA house is now defined as a 18985 12:10:37,436 --> 12:10:41,520 property you're going to have to go 18986 12:10:39,080 --> 12:10:44,276 through the setter function instead to 18987 12:10:41,520 --> 12:10:47,320 even let you change that value and 18988 12:10:44,276 --> 12:10:49,756 because I have this raise value error if 18989 12:10:47,320 --> 12:10:51,240 the house is not as intended you're not 18990 12:10:49,756 --> 12:10:53,520 going to be allowed to change it to an 18991 12:10:51,240 --> 12:10:55,480 invalid value so I'm protecting the data 18992 12:10:53,520 --> 12:10:58,116 on the way in through the init method 18993 12:10:55,480 --> 12:11:00,320 and I'm even defending the data if you 18994 12:10:58,116 --> 12:11:02,360 try to override it there so I think the 18995 12:11:00,320 --> 12:11:04,480 only solution for me the programmer is 18996 12:11:02,360 --> 12:11:06,040 don't try to break my own code let me 18997 12:11:04,480 --> 12:11:08,080 remove that line because it's just not 18998 12:11:06,040 --> 12:11:10,596 going to work let me run python of 18999 12:11:08,080 --> 12:11:12,956 studenty and again type in Harry type in 19000 12:11:10,596 --> 12:11:14,800 Gryffindor enter and Harry is indeed 19001 12:11:12,956 --> 12:11:18,956 from Gryffindor if I did something 19002 12:11:14,800 --> 12:11:22,320 incorrect like Harry from number four 19003 12:11:18,956 --> 12:11:24,520 Private Drive enter we're again going to 19004 12:11:22,320 --> 12:11:27,320 see the value error because my code just 19005 12:11:24,520 --> 12:11:31,480 doesn't let that value in Via manual 19006 12:11:27,320 --> 12:11:33,480 input now or via that adversarial change 19007 12:11:31,480 --> 12:11:36,880 all right that was a lot but any 19008 12:11:33,480 --> 12:11:39,320 question on 19009 12:11:36,880 --> 12:11:41,360 properties uh while we are using gets 19010 12:11:39,320 --> 12:11:44,680 and Setters it's just for the purpose so 19011 12:11:41,360 --> 12:11:47,640 that we can find that um that fun that 19012 12:11:44,680 --> 12:11:48,800 method that function in in our code the 19013 12:11:47,640 --> 12:11:50,320 reason that I'm going through the 19014 12:11:48,800 --> 12:11:53,276 trouble of defining this getter or 19015 12:11:50,320 --> 12:11:55,880 Setter is because I want to make sure 19016 12:11:53,276 --> 12:11:57,560 that programmers cannot do things like 19017 12:11:55,880 --> 12:12:00,520 this if I'm going through the trouble of 19018 12:11:57,560 --> 12:12:02,436 validating the attributes for these 19019 12:12:00,520 --> 12:12:04,160 student objects I don't want you to be 19020 12:12:02,436 --> 12:12:06,880 able to go in there and just change them 19021 12:12:04,160 --> 12:12:08,360 at will I want to have some control over 19022 12:12:06,880 --> 12:12:09,840 that object so that you can just trust 19023 12:12:08,360 --> 12:12:12,520 that it's going to be correct as 19024 12:12:09,840 --> 12:12:14,640 designed so using a getter and Setter 19025 12:12:12,520 --> 12:12:16,400 really just enables python to 19026 12:12:14,640 --> 12:12:19,480 automatically detect when you're trying 19027 12:12:16,400 --> 12:12:21,560 to manually set a value the equal sign 19028 12:12:19,480 --> 12:12:23,160 and the dot as I've highlighted here is 19029 12:12:21,560 --> 12:12:24,320 enough of a clue to python to realize 19030 12:12:23,160 --> 12:12:26,680 wait a minute you're trying to set a 19031 12:12:24,320 --> 12:12:28,720 value let me see if this class has a 19032 12:12:26,680 --> 12:12:29,956 Setter defined and if so I'm going to 19033 12:12:28,720 --> 12:12:32,436 call that and I'm not just going to 19034 12:12:29,956 --> 12:12:35,520 blindly assign the value from right to 19035 12:12:32,436 --> 12:12:38,360 left so it's just giving me more control 19036 12:12:35,520 --> 12:12:41,596 other questions on properties when we 19037 12:12:38,360 --> 12:12:44,916 use a gets we just have just one 19038 12:12:41,596 --> 12:12:47,680 argument and if we use Setters is always 19039 12:12:44,916 --> 12:12:49,320 going to be two arguments is that normal 19040 12:12:47,680 --> 12:12:52,000 correct it's always going to be one 19041 12:12:49,320 --> 12:12:54,560 argument self for the getter two 19042 12:12:52,000 --> 12:12:56,680 arguments for the setter self and 19043 12:12:54,560 --> 12:12:58,400 something else and the intuition for 19044 12:12:56,680 --> 12:13:00,000 that is if you're getting a value you 19045 12:12:58,400 --> 12:13:01,916 don't need to pass anything else in 19046 12:13:00,000 --> 12:13:03,480 because you already know the object it's 19047 12:13:01,916 --> 12:13:04,880 called student in this case so you're 19048 12:13:03,480 --> 12:13:07,200 just going to get the value of that 19049 12:13:04,880 --> 12:13:08,880 property but if you want to set the 19050 12:13:07,200 --> 12:13:10,880 property to something else you got to 19051 12:13:08,880 --> 12:13:12,520 pass in that argument you've got to pass 19052 12:13:10,880 --> 12:13:15,276 in the value to which you want to set it 19053 12:13:12,520 --> 12:13:18,756 so it's always zero or one however you 19054 12:13:15,276 --> 12:13:21,880 see it as one or two because again any 19055 12:13:18,756 --> 12:13:24,040 function inside of a class AKA a method 19056 12:13:21,880 --> 12:13:26,360 is going to be automatically passed self 19057 12:13:24,040 --> 12:13:28,800 so that you have access to that current 19058 12:13:26,360 --> 12:13:32,480 object in memory how about one other 19059 12:13:28,800 --> 12:13:35,400 question on properties why didn't we use 19060 12:13:32,480 --> 12:13:37,240 the same underscore house in init meod a 19061 12:13:35,400 --> 12:13:39,680 good question so even though I'm using 19062 12:13:37,240 --> 12:13:41,436 the underscore house here in my Setter 19063 12:13:39,680 --> 12:13:44,276 and the underscore house here in my 19064 12:13:41,436 --> 12:13:47,080 getter I deliberately did not use it up 19065 12:13:44,276 --> 12:13:50,436 here the reason for that is that by 19066 12:13:47,080 --> 12:13:52,160 using self. house and this equal sign 19067 12:13:50,436 --> 12:13:54,400 that's the same pattern that I want 19068 12:13:52,160 --> 12:13:57,116 python to recognize I want python to 19069 12:13:54,400 --> 12:13:59,160 automatically call the setter even when 19070 12:13:57,116 --> 12:14:01,800 I'm passing in the house via the init 19071 12:13:59,160 --> 12:14:04,436 method if I were to change this to do 19072 12:14:01,800 --> 12:14:06,640 this that would circumvent the setter 19073 12:14:04,436 --> 12:14:09,276 and now there's no error checking in in 19074 12:14:06,640 --> 12:14:11,360 it whatsoever so it's such a fine line 19075 12:14:09,276 --> 12:14:13,276 the only thing standing between us and 19076 12:14:11,360 --> 12:14:14,880 error checking or no error checking is 19077 12:14:13,276 --> 12:14:16,916 the presence or absence of this 19078 12:14:14,880 --> 12:14:19,276 underscore but that's typically the 19079 12:14:16,916 --> 12:14:21,040 convention by not using the underscore 19080 12:14:19,276 --> 12:14:22,956 there make sure that even that 19081 12:14:21,040 --> 12:14:24,720 assignment goes through the setter so 19082 12:14:22,956 --> 12:14:26,560 that honestly I don't have to copy paste 19083 12:14:24,720 --> 12:14:28,596 the same error checking in two places I 19084 12:14:26,560 --> 12:14:30,800 can put it just in the setter so it's 19085 12:14:28,596 --> 12:14:32,480 better design and that's why I manually 19086 12:14:30,800 --> 12:14:35,200 retyped it at first but then I deleted 19087 12:14:32,480 --> 12:14:37,000 it from in it well allow me to propose 19088 12:14:35,200 --> 12:14:39,640 that we make one other change to this 19089 12:14:37,000 --> 12:14:42,040 file might as well go ahead and Define a 19090 12:14:39,640 --> 12:14:43,916 property for name as well and let me go 19091 12:14:42,040 --> 12:14:46,040 ahead and do this maybe above the house 19092 12:14:43,916 --> 12:14:48,160 property just to keep things uh in the 19093 12:14:46,040 --> 12:14:50,520 same order as I defined them earlier let 19094 12:14:48,160 --> 12:14:52,276 me give myself another property this 19095 12:14:50,520 --> 12:14:54,040 one's going to be called name it's going 19096 12:14:52,276 --> 12:14:55,956 to take one argument called self as 19097 12:14:54,040 --> 12:14:58,596 always and this one very similarly is 19098 12:14:55,956 --> 12:15:00,080 just going to return self. uncore name 19099 12:14:58,596 --> 12:15:02,520 so I'm going to anticipate that I'm 19100 12:15:00,080 --> 12:15:04,080 going to have to rename name also so 19101 12:15:02,520 --> 12:15:06,040 that I don't have that same Collision as 19102 12:15:04,080 --> 12:15:09,200 before but now let me go ahead and 19103 12:15:06,040 --> 12:15:11,916 Define another uh setter this one for 19104 12:15:09,200 --> 12:15:14,916 name so the convention is at name. 19105 12:15:11,916 --> 12:15:17,320 Setter why name because the property I 19106 12:15:14,916 --> 12:15:18,956 just created is called name so the 19107 12:15:17,320 --> 12:15:21,160 getter and Setter sort of work in 19108 12:15:18,956 --> 12:15:23,520 conjunction in that in this way if you 19109 12:15:21,160 --> 12:15:25,520 will let me go down under ATN name 19110 12:15:23,520 --> 12:15:27,520 Setter and Define another function also 19111 12:15:25,520 --> 12:15:29,276 called name but the key thing here is 19112 12:15:27,520 --> 12:15:31,436 that it's not identical it's not the 19113 12:15:29,276 --> 12:15:33,720 exact same function name and the exact 19114 12:15:31,436 --> 12:15:35,880 same number of arguments the setter 19115 12:15:33,720 --> 12:15:37,200 again takes a second argument and I can 19116 12:15:35,880 --> 12:15:38,720 call it anything I want but I'm going to 19117 12:15:37,200 --> 12:15:40,916 call it name because that's what's being 19118 12:15:38,720 --> 12:15:43,436 passed in and I'm going to air put my 19119 12:15:40,916 --> 12:15:45,200 error checking here if not name just 19120 12:15:43,436 --> 12:15:47,276 like we used to do let's go ahead and 19121 12:15:45,200 --> 12:15:50,400 raise a value error and let's put an 19122 12:15:47,276 --> 12:15:53,040 explanatory message like uh Missing name 19123 12:15:50,400 --> 12:15:57,480 quote unquote otherwise let's go ahead 19124 12:15:53,040 --> 12:16:00,480 and update self. uncore name to equal 19125 12:15:57,480 --> 12:16:02,680 name and I don't have to change in it 19126 12:16:00,480 --> 12:16:05,720 except to get rid of this duplicate 19127 12:16:02,680 --> 12:16:09,240 error checking now because again if I 19128 12:16:05,720 --> 12:16:11,520 use self. name equals here and self. 19129 12:16:09,240 --> 12:16:13,200 house equals here with no underscore for 19130 12:16:11,520 --> 12:16:16,400 both of those assignments are going to 19131 12:16:13,200 --> 12:16:17,840 go through my two Setter functions now 19132 12:16:16,400 --> 12:16:19,720 before we run this let me go ahead and 19133 12:16:17,840 --> 12:16:21,276 remove this adversarial code which we 19134 12:16:19,720 --> 12:16:23,276 know won't work because we're catching 19135 12:16:21,276 --> 12:16:25,956 it let me go back down to my terminal 19136 12:16:23,276 --> 12:16:27,360 window and run python of studenty enter 19137 12:16:25,956 --> 12:16:30,000 let's type in Harry let's type in 19138 12:16:27,360 --> 12:16:31,640 Gryffindor and that seems to work let's 19139 12:16:30,000 --> 12:16:34,560 try though again to run python of 19140 12:16:31,640 --> 12:16:37,840 studenty with Harry from number four 19141 12:16:34,560 --> 12:16:39,956 privet drive this will not work a value 19142 12:16:37,840 --> 12:16:42,200 error with invalid house because that's 19143 12:16:39,956 --> 12:16:43,720 not one of the four WS houses and now 19144 12:16:42,200 --> 12:16:45,436 for good measure let's run it one more 19145 12:16:43,720 --> 12:16:47,640 time and let's not even give it a name 19146 12:16:45,436 --> 12:16:49,200 let's just hit enter when prompted I can 19147 12:16:47,640 --> 12:16:51,240 type anything for the house I'll go 19148 12:16:49,200 --> 12:16:53,560 ahead and still give it Gryffindor enter 19149 12:16:51,240 --> 12:16:56,880 now we get another value error but this 19150 12:16:53,560 --> 12:16:58,320 one is for missing name so we seem now 19151 12:16:56,880 --> 12:17:00,880 to have all the more of a defense 19152 12:16:58,320 --> 12:17:02,680 mechanism in place to ensure that name 19153 12:17:00,880 --> 12:17:05,000 is as we expect it's got to have some 19154 12:17:02,680 --> 12:17:06,480 value that's not blank and house is as 19155 12:17:05,000 --> 12:17:09,880 we expect it's got to have one of those 19156 12:17:06,480 --> 12:17:12,040 four values but at the risk of bursting 19157 12:17:09,880 --> 12:17:15,320 everyone's bubble and making you wonder 19158 12:17:12,040 --> 12:17:18,720 why did we just go through all of that 19159 12:17:15,320 --> 12:17:22,320 unfortunately python really focuses on 19160 12:17:18,720 --> 12:17:24,276 conventions not hard constraints and by 19161 12:17:22,320 --> 12:17:26,560 that I mean this if I go back into my 19162 12:17:24,276 --> 12:17:29,200 main function after I've gotten a 19163 12:17:26,560 --> 12:17:31,276 student online 30 and I try to 19164 12:17:29,200 --> 12:17:33,360 adversarially do something like this 19165 12:17:31,276 --> 12:17:36,480 student. housee equals quote unquote 19166 12:17:33,360 --> 12:17:39,000 number four Private Drive we know this 19167 12:17:36,480 --> 12:17:41,436 won't work because my Setter for house 19168 12:17:39,000 --> 12:17:42,680 is going to catch this watch again again 19169 12:17:41,436 --> 12:17:45,240 python of 19170 12:17:42,680 --> 12:17:47,116 studenty uh let's type in Harry let's 19171 12:17:45,240 --> 12:17:50,160 type in Gryffindor which will at least 19172 12:17:47,116 --> 12:17:53,800 pass our check that's induced by in it 19173 12:17:50,160 --> 12:17:55,480 but line 31 is going to trigger the same 19174 12:17:53,800 --> 12:17:58,756 Setter to be called and we're going to 19175 12:17:55,480 --> 12:18:00,720 raise a value error saying invalid house 19176 12:17:58,756 --> 12:18:03,200 unfortunately and if some of you are 19177 12:18:00,720 --> 12:18:05,800 already thinking a little adversarially 19178 12:18:03,200 --> 12:18:09,400 tragically look what you can do you can 19179 12:18:05,800 --> 12:18:11,840 change house to beore house why well the 19180 12:18:09,400 --> 12:18:14,800 instance variable is now called 19181 12:18:11,840 --> 12:18:17,320 underscore house the property is called 19182 12:18:14,800 --> 12:18:19,756 house no underscore but the underlying 19183 12:18:17,320 --> 12:18:22,320 attribute implemented as an instance 19184 12:18:19,756 --> 12:18:26,560 variable is still called underscore 19185 12:18:22,320 --> 12:18:28,560 house and tragically python of student. 19186 12:18:26,560 --> 12:18:30,800 let's type in Harry let's type in 19187 12:18:28,560 --> 12:18:34,160 Gryffindor which is correct but Watch 19188 12:18:30,800 --> 12:18:37,240 What Happens now oh my God we slip 19189 12:18:34,160 --> 12:18:39,436 through so what was the point of all of 19190 12:18:37,240 --> 12:18:41,480 this emphasis from me on doing things 19191 12:18:39,436 --> 12:18:43,560 the right way the python iic Way by 19192 12:18:41,480 --> 12:18:46,276 having this getter and Setter well 19193 12:18:43,560 --> 12:18:48,680 unlike languages like Java that just 19194 12:18:46,276 --> 12:18:50,640 prevent you from doing things like this 19195 12:18:48,680 --> 12:18:52,596 python itself allows you to specify that 19196 12:18:50,640 --> 12:18:54,840 certain instance variables can be public 19197 12:18:52,596 --> 12:18:57,480 and accessible to anyone's code or 19198 12:18:54,840 --> 12:18:59,000 protected or private which means that no 19199 12:18:57,480 --> 12:19:01,956 one else should be able to change these 19200 12:18:59,000 --> 12:19:04,160 values in the world of python it's just 19201 12:19:01,956 --> 12:19:05,880 the honor System it's not baked into the 19202 12:19:04,160 --> 12:19:07,720 language itself that there's a notion of 19203 12:19:05,880 --> 12:19:09,800 visibility public or private or even 19204 12:19:07,720 --> 12:19:11,240 somewhere in between protected instead 19205 12:19:09,800 --> 12:19:14,596 you're on the honor system and the 19206 12:19:11,240 --> 12:19:17,400 convention generally is if a instance 19207 12:19:14,596 --> 12:19:19,436 variable starts with an underscore 19208 12:19:17,400 --> 12:19:21,360 please don't touch it like just don't 19209 12:19:19,436 --> 12:19:23,436 like that's on you if you touch that 19210 12:19:21,360 --> 12:19:25,040 variable and break things the underscore 19211 12:19:23,436 --> 12:19:27,200 is meant to signify a convention that 19212 12:19:25,040 --> 12:19:28,596 this is meant to be private but it 19213 12:19:27,200 --> 12:19:29,680 really just means please don't touch 19214 12:19:28,596 --> 12:19:31,520 this sometimes if there's two 19215 12:19:29,680 --> 12:19:33,240 underscores which you can use two that's 19216 12:19:31,520 --> 12:19:35,240 an even greater effort by programmers to 19217 12:19:33,240 --> 12:19:36,800 say really don't touch this but 19218 12:19:35,240 --> 12:19:39,436 technically speaking there's nothing 19219 12:19:36,800 --> 12:19:41,360 stopping you or me from circumventing 19220 12:19:39,436 --> 12:19:43,116 all of these mechanis Ms these 19221 12:19:41,360 --> 12:19:45,200 properties these Getters and Setters 19222 12:19:43,116 --> 12:19:47,200 were ultimately just on the honor System 19223 12:19:45,200 --> 12:19:49,680 not to do so when we see instance 19224 12:19:47,200 --> 12:19:51,756 variables prefixed with one or perhaps 19225 12:19:49,680 --> 12:19:54,000 even two underscores all right so this 19226 12:19:51,756 --> 12:19:56,400 is a lot all at once this introduction 19227 12:19:54,000 --> 12:19:58,756 to object-oriented programming but it 19228 12:19:56,400 --> 12:20:01,640 might come as quite a surprise that even 19229 12:19:58,756 --> 12:20:04,800 though we might had have identified oop 19230 12:20:01,640 --> 12:20:07,840 by name in weeks past we've all been 19231 12:20:04,800 --> 12:20:09,756 using classes and objects for weeks now 19232 12:20:07,840 --> 12:20:11,160 in this class in fact if you think back 19233 12:20:09,756 --> 12:20:13,040 on one of the very first things we did 19234 12:20:11,160 --> 12:20:15,680 in this class we used integers and just 19235 12:20:13,040 --> 12:20:18,116 got integers from the user but if you 19236 12:20:15,680 --> 12:20:20,640 haven't already if you go and dig into 19237 12:20:18,116 --> 12:20:23,116 the documentation for integers which 19238 12:20:20,640 --> 12:20:27,160 again lives at this URL here you would 19239 12:20:23,116 --> 12:20:30,240 actually find that int itself is and has 19240 12:20:27,160 --> 12:20:32,320 been for weeks a class and in fact this 19241 12:20:30,240 --> 12:20:35,756 is the signature of the Constructor call 19242 12:20:32,320 --> 12:20:38,400 for an INT whereby you pass in X like a 19243 12:20:35,756 --> 12:20:40,680 number quote unquote 50 or quote unquote 19244 12:20:38,400 --> 12:20:43,640 something else you pass in optionally 19245 12:20:40,680 --> 12:20:46,480 the base 10 for decimal two for binary 19246 12:20:43,640 --> 12:20:48,560 or anything else and that int function 19247 12:20:46,480 --> 12:20:53,160 will actually return to you all this 19248 12:20:48,560 --> 12:20:55,956 time an object of type int that is to 19249 12:20:53,160 --> 12:20:57,680 say int is a class it is a template a 19250 12:20:55,956 --> 12:20:59,640 blueprint for creating integers in 19251 12:20:57,680 --> 12:21:01,436 memory and anytime you and I have 19252 12:20:59,640 --> 12:21:04,360 converted a string for instance to an 19253 12:21:01,436 --> 12:21:06,880 INT you and I have been creating an 19254 12:21:04,360 --> 12:21:09,320 object of type int that was calling 19255 12:21:06,880 --> 12:21:11,116 apparently the underscore underscore in 19256 12:21:09,320 --> 12:21:13,000 it underscore underscore method that 19257 12:21:11,116 --> 12:21:15,640 someone else the authors of python wrote 19258 12:21:13,000 --> 12:21:18,320 to give us back that proper integer 19259 12:21:15,640 --> 12:21:20,480 besides that if you can believe it stirs 19260 12:21:18,320 --> 12:21:22,320 strings in Python have been classes 19261 12:21:20,480 --> 12:21:24,080 since the first week of this class as 19262 12:21:22,320 --> 12:21:26,480 well if you look up the documentation 19263 12:21:24,080 --> 12:21:28,520 for a stir which lives at a similar URL 19264 12:21:26,480 --> 12:21:31,436 there you will find that when you 19265 12:21:28,520 --> 12:21:34,400 instantiate that is create a stir it 19266 12:21:31,436 --> 12:21:36,160 takes optionally a parameter called 19267 12:21:34,400 --> 12:21:38,200 object here the default value of which 19268 12:21:36,160 --> 12:21:40,040 is just quote unquote which allows you 19269 12:21:38,200 --> 12:21:41,840 to create in effect an empty string a 19270 12:21:40,040 --> 12:21:44,116 blank string string if you will but 19271 12:21:41,840 --> 12:21:46,520 anytime you and I have created stirs or 19272 12:21:44,116 --> 12:21:49,480 even used explicitly this stir function 19273 12:21:46,520 --> 12:21:52,240 you are getting back an object of type 19274 12:21:49,480 --> 12:21:54,360 stir anytime you and I have forced a 19275 12:21:52,240 --> 12:21:57,320 string to lowercase per the 19276 12:21:54,360 --> 12:22:00,200 documentation using syntax like this you 19277 12:21:57,320 --> 12:22:03,276 and I have been taking an object of type 19278 12:22:00,200 --> 12:22:06,840 stir and forcing it all to lowercase by 19279 12:22:03,276 --> 12:22:09,800 calling a method called Lower a method 19280 12:22:06,840 --> 12:22:11,916 that the authors of python built into 19281 12:22:09,800 --> 12:22:13,800 the stir class but it's been there from 19282 12:22:11,916 --> 12:22:15,560 the gecko so this notion of method is 19283 12:22:13,800 --> 12:22:17,040 not even new today you would have been 19284 12:22:15,560 --> 12:22:19,040 doing it for this long if you've ever 19285 12:22:17,040 --> 12:22:21,116 called strip to remove the leading and 19286 12:22:19,040 --> 12:22:23,240 the trailing Whit space from a string in 19287 12:22:21,116 --> 12:22:25,680 Python you are calling another method 19288 12:22:23,240 --> 12:22:27,116 that came with python written by the 19289 12:22:25,680 --> 12:22:29,160 authors of python and even though we 19290 12:22:27,116 --> 12:22:33,276 didn't call it a class at the time a 19291 12:22:29,160 --> 12:22:35,956 stir all this time has been a class and 19292 12:22:33,276 --> 12:22:38,116 instances of strings are themselves 19293 12:22:35,956 --> 12:22:40,040 objects and those objects come therefore 19294 12:22:38,116 --> 12:22:41,956 with these functions built in AKA 19295 12:22:40,040 --> 12:22:44,360 methods that allow us to do things like 19296 12:22:41,956 --> 12:22:46,400 force to lowercase and strip Whit space 19297 12:22:44,360 --> 12:22:48,880 from the beginning and end let's do 19298 12:22:46,400 --> 12:22:52,160 another list anytime you've created a 19299 12:22:48,880 --> 12:22:54,720 list either uh either syntactically with 19300 12:22:52,160 --> 12:22:56,360 square brackets or literally with l i s 19301 12:22:54,720 --> 12:22:58,240 open parenthesis closed parenthesis 19302 12:22:56,360 --> 12:22:59,916 which is also possible you have been 19303 12:22:58,240 --> 12:23:02,240 using a class if you go to the 19304 12:22:59,916 --> 12:23:04,560 documentation for list at this similar 19305 12:23:02,240 --> 12:23:07,116 URL here or more specifically the 19306 12:23:04,560 --> 12:23:10,040 tutorial on lists here in Python you 19307 12:23:07,116 --> 12:23:12,560 will see that a list is and has been 19308 12:23:10,040 --> 12:23:16,756 since the early weeks of this class A 19309 12:23:12,560 --> 12:23:19,276 Class itself and that clist class takes 19310 12:23:16,756 --> 12:23:21,320 as part of its uh initialization in 19311 12:23:19,276 --> 12:23:23,596 optional iterable something that can be 19312 12:23:21,320 --> 12:23:26,200 iterated over like one comma 2 comma 19313 12:23:23,596 --> 12:23:28,840 three or some list of values and you can 19314 12:23:26,200 --> 12:23:31,160 then get back a list containing those 19315 12:23:28,840 --> 12:23:33,160 same iterable values if you've ever 19316 12:23:31,160 --> 12:23:35,080 appended something to a list in this 19317 12:23:33,160 --> 12:23:37,916 class as I have myself in the past 19318 12:23:35,080 --> 12:23:39,916 you've been using a method called aend 19319 12:23:37,916 --> 12:23:42,000 that comes with the list class that per 19320 12:23:39,916 --> 12:23:45,040 the X takes an argument that allows you 19321 12:23:42,000 --> 12:23:48,040 to append something to the current list 19322 12:23:45,040 --> 12:23:49,560 AKA self in the context of that method 19323 12:23:48,040 --> 12:23:52,560 we can do this all day long if you've 19324 12:23:49,560 --> 12:23:54,400 used a dictionary or a dict in Python 19325 12:23:52,560 --> 12:23:56,756 I've actually all this time been calling 19326 12:23:54,400 --> 12:23:59,560 them dict objects and that's for a 19327 12:23:56,756 --> 12:24:00,956 reason dict itself is a class in Python 19328 12:23:59,560 --> 12:24:03,116 if you pull up its official 19329 12:24:00,956 --> 12:24:06,276 documentation here and you'll see that 19330 12:24:03,116 --> 12:24:07,880 it is defined indeed as itself a class 19331 12:24:06,276 --> 12:24:09,520 and that class comes with methods as 19332 12:24:07,880 --> 12:24:11,560 well and so anytime we've manipulated 19333 12:24:09,520 --> 12:24:14,680 dictionaries we've been in underneath 19334 12:24:11,560 --> 12:24:16,200 the hood using all of those same methods 19335 12:24:14,680 --> 12:24:18,756 and in fact we can see this if we're 19336 12:24:16,200 --> 12:24:21,160 really curious let me go back over here 19337 12:24:18,756 --> 12:24:23,160 to VSS code and let me go ahead and 19338 12:24:21,160 --> 12:24:25,080 create a new file that very simply does 19339 12:24:23,160 --> 12:24:26,560 something like play around with data 19340 12:24:25,080 --> 12:24:29,480 types and let me go ahead and create a 19341 12:24:26,560 --> 12:24:32,276 new file for instance called say uh 19342 12:24:29,480 --> 12:24:35,800 type. piy just so that I can poke around 19343 12:24:32,276 --> 12:24:37,160 inside of some values and in type. pi 19344 12:24:35,800 --> 12:24:39,400 I'm just going to go ahead and do this 19345 12:24:37,160 --> 12:24:42,000 I'm going to print out whatever the type 19346 12:24:39,400 --> 12:24:43,640 is of say the number 50 and this is a 19347 12:24:42,000 --> 12:24:45,756 function you've not necessarily seen me 19348 12:24:43,640 --> 12:24:47,520 use already and it's not one you would 19349 12:24:45,756 --> 12:24:49,596 frequently use in your own code there 19350 12:24:47,520 --> 12:24:51,880 are other ways to te detect if you need 19351 12:24:49,596 --> 12:24:55,276 to what the type is of a variable but in 19352 12:24:51,880 --> 12:24:57,360 this case type of 50 is just going to 19353 12:24:55,276 --> 12:24:59,596 tell me and then print out what the data 19354 12:24:57,360 --> 12:25:01,276 type is of that value now hopefully all 19355 12:24:59,596 --> 12:25:03,596 of us could guess that 50 is indeed 19356 12:25:01,276 --> 12:25:05,160 going to be an integer that is an INT 19357 12:25:03,596 --> 12:25:06,720 but we can see it in this way and this 19358 12:25:05,160 --> 12:25:07,880 too is what's powerful about knowing a 19359 12:25:06,720 --> 12:25:09,956 bit of programming if you want to know 19360 12:25:07,880 --> 12:25:12,116 the answer to a question just try it out 19361 12:25:09,956 --> 12:25:15,276 like am here so let me go ahead and run 19362 12:25:12,116 --> 12:25:17,560 python of type. py enter and there it is 19363 12:25:15,276 --> 12:25:20,480 when you print out the type of the 19364 12:25:17,560 --> 12:25:23,000 number 50 you'll see on the screen in 19365 12:25:20,480 --> 12:25:24,680 this cryptic syntax class quote unquote 19366 12:25:23,000 --> 12:25:26,720 int this is not something that you 19367 12:25:24,680 --> 12:25:28,400 probably want to show to the user but if 19368 12:25:26,720 --> 12:25:30,400 you yourself just want to poke around 19369 12:25:28,400 --> 12:25:32,520 and see what's going on or maybe use 19370 12:25:30,400 --> 12:25:34,680 that information somehow it's certainly 19371 12:25:32,520 --> 12:25:36,520 at your disposal to use with this type 19372 12:25:34,680 --> 12:25:38,916 function for that let's change it around 19373 12:25:36,520 --> 12:25:41,880 a little bit instead of passing is the 19374 12:25:38,916 --> 12:25:43,800 argument to type 50 as an INT let's type 19375 12:25:41,880 --> 12:25:46,436 something also familiar like hello comma 19376 12:25:43,800 --> 12:25:48,040 World in double or single quotes let me 19377 12:25:46,436 --> 12:25:50,276 go back to my terminal window clear the 19378 12:25:48,040 --> 12:25:53,436 screen and run python of typey again and 19379 12:25:50,276 --> 12:25:56,360 now voila there it is all this time a 19380 12:25:53,436 --> 12:25:57,956 stir is also a class we can do this a 19381 12:25:56,360 --> 12:26:00,640 few more times for instance let's go 19382 12:25:57,956 --> 12:26:03,400 ahead and change hello world to just an 19383 12:26:00,640 --> 12:26:05,040 empty list open square bracket close 19384 12:26:03,400 --> 12:26:07,040 square bracket and this is starting to 19385 12:26:05,040 --> 12:26:08,956 look a little cryptic but again notice 19386 12:26:07,040 --> 12:26:11,480 what I'm doing in square brackets is an 19387 12:26:08,956 --> 12:26:13,800 empty list we've done that before that 19388 12:26:11,480 --> 12:26:16,520 is the sole argument to this new type 19389 12:26:13,800 --> 12:26:18,596 function and that's just being passed to 19390 12:26:16,520 --> 12:26:21,480 the print function so that the return 19391 12:26:18,596 --> 12:26:23,560 value of type is the argument to print 19392 12:26:21,480 --> 12:26:26,720 so if I now run this code python of 19393 12:26:23,560 --> 12:26:29,400 type. piy there it is a list is a class 19394 12:26:26,720 --> 12:26:31,040 two you might recall that I said that 19395 12:26:29,400 --> 12:26:33,240 you can also create an empty list by 19396 12:26:31,040 --> 12:26:35,596 literally doing list open parenthesis 19397 12:26:33,240 --> 12:26:38,040 close parenthesis this is a bit of an 19398 12:26:35,596 --> 12:26:41,400 inconsistency as we can now identify 19399 12:26:38,040 --> 12:26:43,360 that int and stir and Now list they're 19400 12:26:41,400 --> 12:26:45,916 technically all lowercase and I went to 19401 12:26:43,360 --> 12:26:48,840 Great Lengths of creating my student 19402 12:26:45,916 --> 12:26:52,040 class to have that capital S that's a 19403 12:26:48,840 --> 12:26:55,400 convention because int and stir and list 19404 12:26:52,040 --> 12:26:57,436 and others come with python they decided 19405 12:26:55,400 --> 12:26:59,596 to make their built-in data types even 19406 12:26:57,436 --> 12:27:01,436 though their classes all lowercase but 19407 12:26:59,596 --> 12:27:02,840 the convention the recommendation in the 19408 12:27:01,436 --> 12:27:05,276 python Community when creating your 19409 12:27:02,840 --> 12:27:07,160 classes is indeed to capitalize the 19410 12:27:05,276 --> 12:27:10,320 first letter as I did in something like 19411 12:27:07,160 --> 12:27:11,956 student capital S but list open 19412 12:27:10,320 --> 12:27:13,956 parenthesis closed parenthesis is 19413 12:27:11,956 --> 12:27:16,116 identical to really just two empty 19414 12:27:13,956 --> 12:27:18,640 square brackets if I clear my screen and 19415 12:27:16,116 --> 12:27:20,756 run type dopy again you see the exact 19416 12:27:18,640 --> 12:27:23,436 same thing the class is called list 19417 12:27:20,756 --> 12:27:25,880 let's do one more let me change list to 19418 12:27:23,436 --> 12:27:27,840 be not square brackets but curly braces 19419 12:27:25,880 --> 12:27:30,160 we've done this before anytime I've done 19420 12:27:27,840 --> 12:27:32,400 two curly braces with nothing in between 19421 12:27:30,160 --> 12:27:35,116 this of course is an empty dictionary or 19422 12:27:32,400 --> 12:27:36,800 a dict object in Python well we can see 19423 12:27:35,116 --> 12:27:39,436 that now let me clear my screen run 19424 12:27:36,800 --> 12:27:41,840 python of type. enter and there it is 19425 12:27:39,436 --> 12:27:43,956 class dick it's been there this whole 19426 12:27:41,840 --> 12:27:46,840 time we just didn't call it a class 19427 12:27:43,956 --> 12:27:48,956 until today I can similarly do this one 19428 12:27:46,840 --> 12:27:50,596 explicitly instead of two curly braces 19429 12:27:48,956 --> 12:27:52,200 let's write out dict with two 19430 12:27:50,596 --> 12:27:54,756 parentheses now we have a lot of 19431 12:27:52,200 --> 12:27:56,480 parentheses again like with list but 19432 12:27:54,756 --> 12:27:59,320 this is just making even more clear that 19433 12:27:56,480 --> 12:28:02,840 the type of a dict object is indeed the 19434 12:27:59,320 --> 12:28:05,276 class dict itself so this is to say that 19435 12:28:02,840 --> 12:28:07,400 as new as a lot of today's ID and syntax 19436 12:28:05,276 --> 12:28:09,680 might be you've actually been using it 19437 12:28:07,400 --> 12:28:12,160 perhaps unbeknownst to you for weeks now 19438 12:28:09,680 --> 12:28:13,520 we now just have terminology to describe 19439 12:28:12,160 --> 12:28:16,116 what it is we've been doing all this 19440 12:28:13,520 --> 12:28:18,800 time and you now have the expressiveness 19441 12:28:16,116 --> 12:28:20,680 with some practice to create your own 19442 12:28:18,800 --> 12:28:22,480 classes inside of which are your own 19443 12:28:20,680 --> 12:28:25,720 instance variables perhaps wrapped with 19444 12:28:22,480 --> 12:28:28,240 those properties and your own instance 19445 12:28:25,720 --> 12:28:30,680 methods but it turns out there's other 19446 12:28:28,240 --> 12:28:32,596 types of methods in the world thus far 19447 12:28:30,680 --> 12:28:35,160 I've been deliberate in calling all of 19448 12:28:32,596 --> 12:28:38,360 our variables instance variables and all 19449 12:28:35,160 --> 12:28:40,800 of our methods uh instance methods it 19450 12:28:38,360 --> 12:28:43,800 turns out there's other types of 19451 12:28:40,800 --> 12:28:46,000 variables and methods out there and one 19452 12:28:43,800 --> 12:28:49,436 of those is called class methods it 19453 12:28:46,000 --> 12:28:52,480 turns out that sometimes it's not really 19454 12:28:49,436 --> 12:28:55,596 necessary or sensible to associate a 19455 12:28:52,480 --> 12:28:58,916 function with objects of a class but 19456 12:28:55,596 --> 12:29:00,916 rather with the class itself an instance 19457 12:28:58,916 --> 12:29:03,320 or an object of a class is a very 19458 12:29:00,916 --> 12:29:04,916 specific Incarnation thereof again on 19459 12:29:03,320 --> 12:29:06,640 that neighborhood that has a lot of 19460 12:29:04,916 --> 12:29:08,080 identical looking buildings but they're 19461 12:29:06,640 --> 12:29:10,360 all a little bit different because of 19462 12:29:08,080 --> 12:29:12,916 different paint and such sometimes times 19463 12:29:10,360 --> 12:29:15,480 you might have functionality related to 19464 12:29:12,916 --> 12:29:17,560 each of those houses that isn't distinct 19465 12:29:15,480 --> 12:29:19,520 or unique for any of the houses it's 19466 12:29:17,560 --> 12:29:22,276 functionality that's going to be exactly 19467 12:29:19,520 --> 12:29:23,956 the same no matter the house in question 19468 12:29:22,276 --> 12:29:25,756 same in the world of object-oriented 19469 12:29:23,956 --> 12:29:27,596 programming sometimes you want some 19470 12:29:25,756 --> 12:29:29,880 functionality some action to be 19471 12:29:27,596 --> 12:29:32,916 associated with the class itself no 19472 12:29:29,880 --> 12:29:35,800 matter what the specific objects own 19473 12:29:32,916 --> 12:29:38,560 values or instance variables are and for 19474 12:29:35,800 --> 12:29:40,956 that we have a keyword called at class 19475 12:29:38,560 --> 12:29:43,276 method this is another de cator really 19476 12:29:40,956 --> 12:29:46,520 another function that you can use to 19477 12:29:43,276 --> 12:29:48,956 specify that this method is not by 19478 12:29:46,520 --> 12:29:51,040 default implicitly an instance method 19479 12:29:48,956 --> 12:29:53,320 that has access to self the object 19480 12:29:51,040 --> 12:29:55,200 itself this is a class method that's not 19481 12:29:53,320 --> 12:29:57,800 going to have access to self but it does 19482 12:29:55,200 --> 12:29:59,596 know what class it's inside so what do I 19483 12:29:57,800 --> 12:30:01,560 mean by this well let me go back to VSS 19484 12:29:59,596 --> 12:30:04,200 code here and let me propose that we 19485 12:30:01,560 --> 12:30:06,400 create a new file this time implementing 19486 12:30:04,200 --> 12:30:08,436 the notion of a the Sorting Hat from the 19487 12:30:06,400 --> 12:30:10,240 World of Harry Potter as well to stay on 19488 12:30:08,436 --> 12:30:13,000 theme I'm going to go ahead and run code 19489 12:30:10,240 --> 12:30:14,916 of hat. py and in hat. py let's 19490 12:30:13,000 --> 12:30:17,000 implement the notion of this Sorting Hat 19491 12:30:14,916 --> 12:30:19,916 if unfamiliar in the books and in the 19492 12:30:17,000 --> 12:30:21,916 films there is literally a pointy hat 19493 12:30:19,916 --> 12:30:24,720 that when a student put it on their head 19494 12:30:21,916 --> 12:30:26,400 that Sorting Hat so to speak decides 19495 12:30:24,720 --> 12:30:28,520 what house the student is in whether 19496 12:30:26,400 --> 12:30:30,520 it's Gryffindor or something else so 19497 12:30:28,520 --> 12:30:33,520 let's Implement and code this notion of 19498 12:30:30,520 --> 12:30:35,360 a Sorting Hat such that when we pass to 19499 12:30:33,520 --> 12:30:37,596 the Sorting Hat the name of a student 19500 12:30:35,360 --> 12:30:39,756 like quote unquote Harry this Sorting 19501 12:30:37,596 --> 12:30:42,000 Hat implemented in code will tell us 19502 12:30:39,756 --> 12:30:43,916 what what house that student should be 19503 12:30:42,000 --> 12:30:47,400 in all right well let's go ahead and do 19504 12:30:43,916 --> 12:30:50,880 this in hat. py first let's go ahead and 19505 12:30:47,400 --> 12:30:52,916 define a class called hat and then let's 19506 12:30:50,880 --> 12:30:54,240 get back to implementing it itself and I 19507 12:30:52,916 --> 12:30:56,116 find this to be a helpful technique not 19508 12:30:54,240 --> 12:30:58,560 just with teaching but when writing code 19509 12:30:56,116 --> 12:31:00,240 like I know I want a ha class I don't 19510 12:30:58,560 --> 12:31:01,560 necessarily know what I want it to do 19511 12:31:00,240 --> 12:31:03,640 yet so I'm going to create this sort of 19512 12:31:01,560 --> 12:31:06,400 placeholder dot dot dot so I'll come 19513 12:31:03,640 --> 12:31:08,360 back to that let's now try to use this 19514 12:31:06,400 --> 12:31:11,160 class as though it existed and from 19515 12:31:08,360 --> 12:31:12,756 there I perhaps can realize exactly what 19516 12:31:11,160 --> 12:31:15,116 functionality that class needs to have 19517 12:31:12,756 --> 12:31:16,880 to support my use case let me go ahead 19518 12:31:15,116 --> 12:31:20,596 and create a variable called hat in all 19519 12:31:16,880 --> 12:31:23,240 lowercase and instantiate a hat object 19520 12:31:20,596 --> 12:31:25,880 so no matter what the Hat class ends up 19521 12:31:23,240 --> 12:31:28,320 looking like this is the common Syntax 19522 12:31:25,880 --> 12:31:31,116 for instantiating an object of a certain 19523 12:31:28,320 --> 12:31:34,200 class in the past we saw student all 19524 12:31:31,116 --> 12:31:35,956 lowercase equals Capital student open 19525 12:31:34,200 --> 12:31:37,596 parenthesis closed parenthesis and then 19526 12:31:35,956 --> 12:31:40,320 eventually we added in things like name 19527 12:31:37,596 --> 12:31:42,520 and house for now let's assume that the 19528 12:31:40,320 --> 12:31:44,520 hat is much simpler than a student and 19529 12:31:42,520 --> 12:31:46,116 it only has sorting capabilities so I'm 19530 12:31:44,520 --> 12:31:49,160 not going to even pass any arguments 19531 12:31:46,116 --> 12:31:53,040 there too indeed let me assume that the 19532 12:31:49,160 --> 12:31:55,840 Sorting Hat has one Function One method 19533 12:31:53,040 --> 12:31:59,756 inside of it called sort and so if I do 19534 12:31:55,840 --> 12:32:02,800 hat. sort quote unquote Harry let's 19535 12:31:59,756 --> 12:32:05,596 propose that that prints out what house 19536 12:32:02,800 --> 12:32:08,276 that student should be in so that's it 19537 12:32:05,596 --> 12:32:10,360 I'm going to encapsulate that is tuck 19538 12:32:08,276 --> 12:32:12,916 away inside of a hat class all of this 19539 12:32:10,360 --> 12:32:15,880 requisite functionality and I'm going to 19540 12:32:12,916 --> 12:32:18,400 print out on the screen what hat uh what 19541 12:32:15,880 --> 12:32:20,116 house Harry belongs in all right now I 19542 12:32:18,400 --> 12:32:21,160 think I need to get into the weeds of 19543 12:32:20,116 --> 12:32:23,800 actually 19544 12:32:21,160 --> 12:32:26,276 initializing this class well let me go 19545 12:32:23,800 --> 12:32:29,720 ahead and do this if I don't care to 19546 12:32:26,276 --> 12:32:32,560 parameterize hat I just want to for 19547 12:32:29,720 --> 12:32:35,160 instance uh sort values let's go ahead 19548 12:32:32,560 --> 12:32:37,276 and Define this function sort first so 19549 12:32:35,160 --> 12:32:39,276 let's define sort as taking a first 19550 12:32:37,276 --> 12:32:41,560 argument self which is always going to 19551 12:32:39,276 --> 12:32:43,680 be the case when defining an instance 19552 12:32:41,560 --> 12:32:45,596 method as before but the sort method 19553 12:32:43,680 --> 12:32:48,640 clearly takes one argument from the 19554 12:32:45,596 --> 12:32:50,200 programmer me namely the student's name 19555 12:32:48,640 --> 12:32:52,640 and again we've seen this dichotomy 19556 12:32:50,200 --> 12:32:55,000 before even though I'm trying to pass in 19557 12:32:52,640 --> 12:32:57,240 one argument when I Define the method 19558 12:32:55,000 --> 12:32:59,160 it's got to take that many arguments 19559 12:32:57,240 --> 12:33:01,200 plus one more self which is always going 19560 12:32:59,160 --> 12:33:04,276 to be automatically passed in by python 19561 12:33:01,200 --> 12:33:05,756 first all right what do I want to do 19562 12:33:04,276 --> 12:33:08,720 well let's go ahead and do something 19563 12:33:05,756 --> 12:33:11,596 like this uh print quote unquote or 19564 12:33:08,720 --> 12:33:15,400 rather print this name how about quote 19565 12:33:11,596 --> 12:33:16,916 unquote is in quote unquote some house 19566 12:33:15,400 --> 12:33:18,400 I'm going to again use some placeholder 19567 12:33:16,916 --> 12:33:20,400 code for myself because I'm not quite 19568 12:33:18,400 --> 12:33:22,520 sure how to finish implementing this 19569 12:33:20,400 --> 12:33:24,916 Sorting Hat but I think that's enough to 19570 12:33:22,520 --> 12:33:27,596 just test where my code is at now let me 19571 12:33:24,916 --> 12:33:30,160 go ahead and run python of hat. py and 19572 12:33:27,596 --> 12:33:32,240 hit enter and it looks like indeed Harry 19573 12:33:30,160 --> 12:33:34,000 is in some house we're not done yet 19574 12:33:32,240 --> 12:33:36,756 because it's clearly not doing anything 19575 12:33:34,000 --> 12:33:39,400 interesting but it at least is running 19576 12:33:36,756 --> 12:33:43,840 correctly with no errors well let's go 19577 12:33:39,400 --> 12:33:45,116 ahead now and decide where uh what house 19578 12:33:43,840 --> 12:33:46,596 Harry should actually be in by 19579 12:33:45,116 --> 12:33:49,276 introducing a bit of Randomness and 19580 12:33:46,596 --> 12:33:50,956 choosing a house randomly well I can do 19581 12:33:49,276 --> 12:33:53,916 this in a few ways let me go ahead and 19582 12:33:50,956 --> 12:33:56,040 do this I need to have a list of houses 19583 12:33:53,916 --> 12:33:57,276 somewhere so where can I put that I 19584 12:33:56,040 --> 12:33:58,916 could solve this problem in different 19585 12:33:57,276 --> 12:34:01,116 ways let me propose that I do this let 19586 12:33:58,916 --> 12:34:03,200 me Define a method called in it as I've 19587 12:34:01,116 --> 12:34:05,436 done before that takes in self but no 19588 12:34:03,200 --> 12:34:07,840 other arguments and whenever the Sorting 19589 12:34:05,436 --> 12:34:11,360 Hat is instantiated let's do this let's 19590 12:34:07,840 --> 12:34:15,200 create a houses instant variable plural 19591 12:34:11,360 --> 12:34:19,240 that equals this list Gryffindor comma 19592 12:34:15,200 --> 12:34:21,240 Hufflepuff comma uh Ravenclaw comma 19593 12:34:19,240 --> 12:34:23,596 Slytherin so the exact same list that 19594 12:34:21,240 --> 12:34:25,680 we've used before and I'm storing it in 19595 12:34:23,596 --> 12:34:28,160 an instance variable inside of this 19596 12:34:25,680 --> 12:34:30,880 class I'm not taking any arguments 19597 12:34:28,160 --> 12:34:33,880 Beyond self in it but I just need this 19598 12:34:30,880 --> 12:34:36,116 list of values somewhere for instance so 19599 12:34:33,880 --> 12:34:38,956 what can I do here well let me go ahead 19600 12:34:36,116 --> 12:34:40,880 and replace some house with the actual 19601 12:34:38,956 --> 12:34:43,040 house well what could I do here well I 19602 12:34:40,880 --> 12:34:45,200 want to put a house there well let's go 19603 12:34:43,040 --> 12:34:46,596 ahead and create a variable called house 19604 12:34:45,200 --> 12:34:49,520 and if you think back to our discussion 19605 12:34:46,596 --> 12:34:52,320 of libraries in the random module there 19606 12:34:49,520 --> 12:34:55,880 is a function called choice that if you 19607 12:34:52,320 --> 12:34:58,360 pass in a list of choices like self. 19608 12:34:55,880 --> 12:35:00,560 houses that will pick a random house out 19609 12:34:58,360 --> 12:35:02,560 of those four and then on line seven I 19610 12:35:00,560 --> 12:35:04,080 can pass it in if I want to tighten this 19611 12:35:02,560 --> 12:35:06,200 up let me just go ahead and highlight 19612 12:35:04,080 --> 12:35:08,160 that code get rid of the variable is 19613 12:35:06,200 --> 12:35:09,880 technically unnecessary and because the 19614 12:35:08,160 --> 12:35:12,040 line of code is still pretty short I'm 19615 12:35:09,880 --> 12:35:13,840 okay with just putting it all in one 19616 12:35:12,040 --> 12:35:16,200 line but I could certainly use the 19617 12:35:13,840 --> 12:35:19,640 variable like I did a moment ago so what 19618 12:35:16,200 --> 12:35:23,756 have I done in my init function I have 19619 12:35:19,640 --> 12:35:25,956 defined a initialization of the object 19620 12:35:23,756 --> 12:35:28,160 that stores and self. houses the list of 19621 12:35:25,956 --> 12:35:30,000 four houses and then in sort I'm 19622 12:35:28,160 --> 12:35:32,560 accessing that same list but I'm 19623 12:35:30,000 --> 12:35:34,756 randomly choosing the set of houses 19624 12:35:32,560 --> 12:35:37,200 there now why have I done it in this way 19625 12:35:34,756 --> 12:35:38,916 this to is General convention anytime 19626 12:35:37,200 --> 12:35:41,560 you have a list of things that who knows 19627 12:35:38,916 --> 12:35:43,916 maybe we'll change over time places like 19628 12:35:41,560 --> 12:35:45,320 Harvard have constructed new houses over 19629 12:35:43,916 --> 12:35:47,240 the years so you might have to change 19630 12:35:45,320 --> 12:35:49,320 the list of available houses it didn't 19631 12:35:47,240 --> 12:35:51,000 happen in seven books or eight films of 19632 12:35:49,320 --> 12:35:53,240 Harry Potter but you could imagine maybe 19633 12:35:51,000 --> 12:35:55,880 Hogwarts eventually has a fifth house so 19634 12:35:53,240 --> 12:35:58,240 there's generally some value in putting 19635 12:35:55,880 --> 12:36:00,000 list of constants toward the top of your 19636 12:35:58,240 --> 12:36:02,720 file toward the top of the class so it's 19637 12:36:00,000 --> 12:36:04,116 just obvious what the list of values is 19638 12:36:02,720 --> 12:36:06,680 you don't want to necessarily tuck it 19639 12:36:04,116 --> 12:36:08,116 away in some function like sort 19640 12:36:06,680 --> 12:36:10,360 especially if you might want to use that 19641 12:36:08,116 --> 12:36:12,360 function in sorry if especially if you 19642 12:36:10,360 --> 12:36:14,000 want to use that list in multiple 19643 12:36:12,360 --> 12:36:15,596 functions not just sort but if I kept 19644 12:36:14,000 --> 12:36:17,360 adding to this class you might want to 19645 12:36:15,596 --> 12:36:20,000 use that same list of houses in multiple 19646 12:36:17,360 --> 12:36:23,880 functions so let's keep it in the object 19647 12:36:20,000 --> 12:36:25,160 Itself by storing it in self. houses all 19648 12:36:23,880 --> 12:36:27,040 right well we're about to change the 19649 12:36:25,160 --> 12:36:29,520 course of history here perhaps let me do 19650 12:36:27,040 --> 12:36:31,880 python of hat. and I think we're about 19651 12:36:29,520 --> 12:36:33,000 to assign Harry to one of those four 19652 12:36:31,880 --> 12:36:37,080 houses 19653 12:36:33,000 --> 12:36:39,560 randomly huh name error name random is 19654 12:36:37,080 --> 12:36:42,360 not defined well wait a minute where did 19655 12:36:39,560 --> 12:36:45,160 did I go wrong here thinking back to our 19656 12:36:42,360 --> 12:36:48,640 class on libraries why did my code break 19657 12:36:45,160 --> 12:36:52,560 and not tell me where Harry is to be you 19658 12:36:48,640 --> 12:36:54,360 do not import the random Library exactly 19659 12:36:52,560 --> 12:36:56,360 if the random library or module is 19660 12:36:54,360 --> 12:36:58,596 something I want to use I need to tell 19661 12:36:56,360 --> 12:37:01,956 python that at the top of my file so let 19662 12:36:58,596 --> 12:37:03,596 me go up here and do import uh random 19663 12:37:01,956 --> 12:37:05,436 and then below that let me go ahead and 19664 12:37:03,596 --> 12:37:08,320 clear my terminal window and try again 19665 12:37:05,436 --> 12:37:11,720 python of haty crossing my fingers 19666 12:37:08,320 --> 12:37:14,320 seeing where hair is going to end up and 19667 12:37:11,720 --> 12:37:15,880 okay Harry as of now is officially in 19668 12:37:14,320 --> 12:37:18,436 Hufflepuff despite what everything 19669 12:37:15,880 --> 12:37:19,880 you've read or seen well let's run this 19670 12:37:18,436 --> 12:37:22,000 again let me clear my window and run 19671 12:37:19,880 --> 12:37:23,880 python of hatai and now he's in 19672 12:37:22,000 --> 12:37:26,360 Ravenclaw that's consistent with using 19673 12:37:23,880 --> 12:37:28,000 random let's clear that and run it again 19674 12:37:26,360 --> 12:37:29,436 he's still in Ravenclaw but that could 19675 12:37:28,000 --> 12:37:31,560 happen even though there's four choices 19676 12:37:29,436 --> 12:37:33,116 let's do it again Hufflepuff back in 19677 12:37:31,560 --> 12:37:35,360 Hufflepuff we can't seem to get the 19678 12:37:33,116 --> 12:37:38,240 right answer so to speak now he's in 19679 12:37:35,360 --> 12:37:39,520 Gryffindor albeit randomly so we seem to 19680 12:37:38,240 --> 12:37:41,596 have a program that based on these 19681 12:37:39,520 --> 12:37:44,276 Limited Test seems to indeed be 19682 12:37:41,596 --> 12:37:46,956 assigning Harry to a house randomly now 19683 12:37:44,276 --> 12:37:48,756 I'm somewhat lazily just letting sort 19684 12:37:46,956 --> 12:37:51,116 print out this value I could do 19685 12:37:48,756 --> 12:37:54,160 something else like return a string and 19686 12:37:51,116 --> 12:37:56,916 then let me on line 13 do the printing 19687 12:37:54,160 --> 12:37:59,880 for me but for now I think we have an 19688 12:37:56,916 --> 12:38:01,680 example of a class called hat that 19689 12:37:59,880 --> 12:38:03,480 nonetheless applies some of our lessons 19690 12:38:01,680 --> 12:38:05,596 learned thus far today where I've 19691 12:38:03,480 --> 12:38:07,880 created a class because a Sorting Hat is 19692 12:38:05,596 --> 12:38:10,160 frankly well a I was about to say real 19693 12:38:07,880 --> 12:38:12,360 world entity but really A Fant FY World 19694 12:38:10,160 --> 12:38:15,000 entity and indeed that's a perhaps 19695 12:38:12,360 --> 12:38:17,800 common puristic or mental model to have 19696 12:38:15,000 --> 12:38:20,040 when should you use a class to represent 19697 12:38:17,800 --> 12:38:22,360 something in your code very often when 19698 12:38:20,040 --> 12:38:25,880 you're trying to represent some real 19699 12:38:22,360 --> 12:38:27,800 world entity or fantasy world entity 19700 12:38:25,880 --> 12:38:30,916 like a student which is something in the 19701 12:38:27,800 --> 12:38:32,956 real world like a Sorting Hat which okay 19702 12:38:30,916 --> 12:38:35,240 doesn't exist but hats certainly do so 19703 12:38:32,956 --> 12:38:36,680 quite reasonable to have a class for hat 19704 12:38:35,240 --> 12:38:39,680 and that's not always the case that 19705 12:38:36,680 --> 12:38:42,520 classes represent real world entities 19706 12:38:39,680 --> 12:38:45,680 but indeed we've seen thus far that int 19707 12:38:42,520 --> 12:38:47,000 and stir and list and dict these are all 19708 12:38:45,680 --> 12:38:48,880 structures that you might have in the 19709 12:38:47,000 --> 12:38:50,956 real world we have integers and strings 19710 12:38:48,880 --> 12:38:52,520 of text and other things so it rather 19711 12:38:50,956 --> 12:38:55,000 makes sense to represent even those 19712 12:38:52,520 --> 12:38:57,480 things more technically using a class as 19713 12:38:55,000 --> 12:38:59,756 well you could use just a dictionary to 19714 12:38:57,480 --> 12:39:03,000 represent a student or a hat but again 19715 12:38:59,756 --> 12:39:05,800 with classes come all this and even more 19716 12:39:03,000 --> 12:39:08,840 functionality but I honestly am not 19717 12:39:05,800 --> 12:39:11,756 using classes in really the the right 19718 12:39:08,840 --> 12:39:13,756 way here here why well in the World of 19719 12:39:11,756 --> 12:39:16,840 Harry Potter there really is only to my 19720 12:39:13,756 --> 12:39:19,080 knowledge one Sorting Hat and yet here I 19721 12:39:16,840 --> 12:39:21,880 have gone and implemented a class called 19722 12:39:19,080 --> 12:39:24,560 hat and again a class is like a 19723 12:39:21,880 --> 12:39:27,000 blueprint a template a mold that allows 19724 12:39:24,560 --> 12:39:29,040 you to create one or more objects 19725 12:39:27,000 --> 12:39:30,320 thereof now most of my programs thus far 19726 12:39:29,040 --> 12:39:32,436 have been pretty simple and I've just 19727 12:39:30,320 --> 12:39:34,160 created one student but certainly if I 19728 12:39:32,436 --> 12:39:36,480 spent more time in wrote more code you 19729 12:39:34,160 --> 12:39:38,520 could imagine writing one program that 19730 12:39:36,480 --> 12:39:40,840 has a list of students many more 19731 12:39:38,520 --> 12:39:42,956 students than than just the one we keep 19732 12:39:40,840 --> 12:39:44,880 demonstrating yet it would be a little 19733 12:39:42,956 --> 12:39:46,800 weird it's a little inconsistent with 19734 12:39:44,880 --> 12:39:49,560 the real or the Fantasy World of Harry 19735 12:39:46,800 --> 12:39:51,956 Potter to instantiate one two three or 19736 12:39:49,560 --> 12:39:54,480 more sorting hats there really is just 19737 12:39:51,956 --> 12:39:55,916 one really one Singleton if you will 19738 12:39:54,480 --> 12:39:58,000 which is a term of Art in a lot of 19739 12:39:55,916 --> 12:39:59,680 contexts of programming so let me 19740 12:39:58,000 --> 12:40:01,640 propose that we actually improve the 19741 12:39:59,680 --> 12:40:04,520 design of the Sorting Hat so that we 19742 12:40:01,640 --> 12:40:06,596 don't have to instantiate a Sorting Hat 19743 12:40:04,520 --> 12:40:08,480 because right now this is kind of 19744 12:40:06,596 --> 12:40:11,200 allowing me to do something like hat one 19745 12:40:08,480 --> 12:40:13,240 equals hat hat two equals hat hat three 19746 12:40:11,200 --> 12:40:15,800 equals and so forth I don't really need 19747 12:40:13,240 --> 12:40:18,276 that capability I really just need to 19748 12:40:15,800 --> 12:40:20,080 represent the Sorting Hat with a class 19749 12:40:18,276 --> 12:40:21,756 but I don't really need to instantiate 19750 12:40:20,080 --> 12:40:25,276 it why because it already exists I need 19751 12:40:21,756 --> 12:40:26,880 just one so it turns out in Python that 19752 12:40:25,276 --> 12:40:29,320 up until now we've been using as I keep 19753 12:40:26,880 --> 12:40:31,596 calling them instance methods writing 19754 12:40:29,320 --> 12:40:34,240 functions inside of classes that are 19755 12:40:31,596 --> 12:40:36,320 automatically p a reference to self the 19756 12:40:34,240 --> 12:40:38,560 current object but sometimes you just 19757 12:40:36,320 --> 12:40:40,560 don't need that sometimes it suffices to 19758 12:40:38,560 --> 12:40:42,756 just know what the classes and assume 19759 12:40:40,560 --> 12:40:44,956 that there might not even be any objects 19760 12:40:42,756 --> 12:40:48,040 of that class so in this sense you can 19761 12:40:44,956 --> 12:40:50,560 use a class really as a container for 19762 12:40:48,040 --> 12:40:53,680 data Andor functionality that is just 19763 12:40:50,560 --> 12:40:56,240 somehow conceptually related things 19764 12:40:53,680 --> 12:40:58,160 related to a sorting hats and there's 19765 12:40:56,240 --> 12:41:00,360 this other decorator or function called 19766 12:40:58,160 --> 12:41:02,480 class method that allows us to do just 19767 12:41:00,360 --> 12:41:04,840 this so let me go back to my code here 19768 12:41:02,480 --> 12:41:08,480 and let me propose that if I'm not going 19769 12:41:04,840 --> 12:41:10,116 to instantiate multiple houses I don't 19770 12:41:08,480 --> 12:41:11,200 really need this this in it method 19771 12:41:10,116 --> 12:41:13,880 because that's really meant to 19772 12:41:11,200 --> 12:41:16,436 initialize specific objects from that 19773 12:41:13,880 --> 12:41:18,560 blueprint that template that mold so let 19774 12:41:16,436 --> 12:41:20,956 me get rid of this but if I get rid of 19775 12:41:18,560 --> 12:41:23,320 this I no longer have access to self but 19776 12:41:20,956 --> 12:41:26,360 that's okay because it turns out in 19777 12:41:23,320 --> 12:41:28,560 addition to their existing class methods 19778 12:41:26,360 --> 12:41:31,956 there are also what we might call class 19779 12:41:28,560 --> 12:41:34,560 variables and class variables exist 19780 12:41:31,956 --> 12:41:37,800 within the class itself and there's just 19781 12:41:34,560 --> 12:41:39,916 one copy of that variable for all of the 19782 12:41:37,800 --> 12:41:42,720 objects thereof they all share if you 19783 12:41:39,916 --> 12:41:45,160 will the same variable be it an INT or 19784 12:41:42,720 --> 12:41:48,880 stir or in this case a list so what I've 19785 12:41:45,160 --> 12:41:53,240 done here is Define inside of my hat 19786 12:41:48,880 --> 12:41:55,276 class in a class variable called houses 19787 12:41:53,240 --> 12:41:57,160 I don't say self because self is no 19788 12:41:55,276 --> 12:42:00,080 longer relevant self refers to specific 19789 12:41:57,160 --> 12:42:02,880 objects I want a variable inside of this 19790 12:42:00,080 --> 12:42:05,200 class AKA a class variable that equals 19791 12:42:02,880 --> 12:42:09,360 that list because it's inside of this 19792 12:42:05,200 --> 12:42:11,160 hat now class I can use that list in any 19793 12:42:09,360 --> 12:42:13,000 of my functions I've only got one now 19794 12:42:11,160 --> 12:42:14,916 called sort but if I had more it would 19795 12:42:13,000 --> 12:42:17,756 be accessible to all of those methods as 19796 12:42:14,916 --> 12:42:20,160 well and with sort it also doesn't 19797 12:42:17,756 --> 12:42:22,000 really make sense to sort within a 19798 12:42:20,160 --> 12:42:23,956 specific sorting ha because again there 19799 12:42:22,000 --> 12:42:26,160 I only want there to be one so I can 19800 12:42:23,956 --> 12:42:29,160 actually specify that this is a class 19801 12:42:26,160 --> 12:42:31,880 method by saying at class method and I 19802 12:42:29,160 --> 12:42:34,480 don't pass in self anymore I actually by 19803 12:42:31,880 --> 12:42:37,200 convention pass in the a reference to 19804 12:42:34,480 --> 12:42:41,756 the class itself it's typically written 19805 12:42:37,200 --> 12:42:43,880 as CLS y well if you wrote C ass that 19806 12:42:41,756 --> 12:42:46,160 would actually conflict with the keyword 19807 12:42:43,880 --> 12:42:48,400 class that we keep using up here so the 19808 12:42:46,160 --> 12:42:50,400 world realized that oops we uh can't 19809 12:42:48,400 --> 12:42:52,880 reuse that same phrase here so let's 19810 12:42:50,400 --> 12:42:55,080 just call this class this is useful in 19811 12:42:52,880 --> 12:42:57,720 some context including this one why well 19812 12:42:55,080 --> 12:43:00,916 we notice what I can now do I can now 19813 12:42:57,720 --> 12:43:03,560 change self to be just class why because 19814 12:43:00,916 --> 12:43:06,360 house is now not an instance variable 19815 12:43:03,560 --> 12:43:09,240 accessible via self. houses it is now a 19816 12:43:06,360 --> 12:43:12,520 class variable accessible via class 19817 12:43:09,240 --> 12:43:15,160 ouses or technically CLS do houses in 19818 12:43:12,520 --> 12:43:18,560 this case but now the final flourish is 19819 12:43:15,160 --> 12:43:22,320 this now I don't have to instantiate any 19820 12:43:18,560 --> 12:43:24,560 hat objects as I used to on here line 13 19821 12:43:22,320 --> 12:43:26,520 I can just use functionality that comes 19822 12:43:24,560 --> 12:43:28,360 with this class so I'm going to delete 19823 12:43:26,520 --> 12:43:31,400 that line Al together I'm going to 19824 12:43:28,360 --> 12:43:35,480 capitalize the Hat on this new line 13 19825 12:43:31,400 --> 12:43:38,116 and just say hat. sort quote unquote 19826 12:43:35,480 --> 12:43:41,000 Harry so what have I done I've not 19827 12:43:38,116 --> 12:43:44,480 bothered in intiating an object of type 19828 12:43:41,000 --> 12:43:46,360 hat I am just accessing a class method 19829 12:43:44,480 --> 12:43:48,640 inside of the Hat class that you know 19830 12:43:46,360 --> 12:43:50,400 what is just going to work this is how 19831 12:43:48,640 --> 12:43:53,000 class methods work you use the name of 19832 12:43:50,400 --> 12:43:55,520 the class capital letter in all do 19833 12:43:53,000 --> 12:43:57,916 method name passing in any arguments you 19834 12:43:55,520 --> 12:44:00,560 want python is going to automatically 19835 12:43:57,916 --> 12:44:03,480 pass in some variable via which you can 19836 12:44:00,560 --> 12:44:05,000 refer to that class in that function 19837 12:44:03,480 --> 12:44:06,720 that you've implemented inside of that 19838 12:44:05,000 --> 12:44:08,720 class so that I can do something like 19839 12:44:06,720 --> 12:44:10,800 this it's not that I want a variable 19840 12:44:08,720 --> 12:44:12,880 called houses locally in this function I 19841 12:44:10,800 --> 12:44:16,040 want the variable called houses that's 19842 12:44:12,880 --> 12:44:18,520 associated with this current class so I 19843 12:44:16,040 --> 12:44:21,720 can still access this same list that I 19844 12:44:18,520 --> 12:44:23,480 defined on line six and now if I go back 19845 12:44:21,720 --> 12:44:26,520 down here to my terminal and run python 19846 12:44:23,480 --> 12:44:28,680 of haty enter Harry is still in 19847 12:44:26,520 --> 12:44:31,520 Hufflepuff once more Harry is still in 19848 12:44:28,680 --> 12:44:33,360 Hufflepuff once more Harry is back in 19849 12:44:31,520 --> 12:44:36,720 Gryffindor at least 19850 12:44:33,360 --> 12:44:39,436 randomly questions now on these class 19851 12:44:36,720 --> 12:44:43,000 variables or these class methods which 19852 12:44:39,436 --> 12:44:45,360 are in contrast with instance variables 19853 12:44:43,000 --> 12:44:47,436 and instance methods and the one thing 19854 12:44:45,360 --> 12:44:49,000 at least that's a little strange here is 19855 12:44:47,436 --> 12:44:51,720 that even though there's a decorator 19856 12:44:49,000 --> 12:44:54,956 called at class method there is not one 19857 12:44:51,720 --> 12:44:57,400 called at instance method a method is 19858 12:44:54,956 --> 12:44:59,756 just automatically a so-called instant 19859 12:44:57,400 --> 12:45:02,200 method when you define it without any 19860 12:44:59,756 --> 12:45:05,080 decorator can you have a class inside 19861 12:45:02,200 --> 12:45:07,480 another class you can you can Define one 19862 12:45:05,080 --> 12:45:09,240 class inside of another generally 19863 12:45:07,480 --> 12:45:11,240 speaking this isn't done but there are 19864 12:45:09,240 --> 12:45:13,720 cases where it can be helpful especially 19865 12:45:11,240 --> 12:45:16,800 for larger more sophisticated programs 19866 12:45:13,720 --> 12:45:19,400 so yes it is possible good other 19867 12:45:16,800 --> 12:45:22,200 questions the question was about the 19868 12:45:19,400 --> 12:45:26,800 self do houses when you when we remove 19869 12:45:22,200 --> 12:45:30,956 it we uh and we pass data the variable 19870 12:45:26,800 --> 12:45:33,400 is created itself why we remove the S so 19871 12:45:30,956 --> 12:45:35,160 in the previous examples both of the Hat 19872 12:45:33,400 --> 12:45:38,916 demonstration and also all of the 19873 12:45:35,160 --> 12:45:40,840 student demonstrations we were uh create 19874 12:45:38,916 --> 12:45:42,680 creating a student object by calling 19875 12:45:40,840 --> 12:45:44,756 student capital S open parenthesis 19876 12:45:42,680 --> 12:45:46,680 closed parenthesis with eventually name 19877 12:45:44,756 --> 12:45:49,080 and a house passed in and then we were 19878 12:45:46,680 --> 12:45:52,480 using the d uh the Double underscore 19879 12:45:49,080 --> 12:45:55,640 init method to initialize the self. name 19880 12:45:52,480 --> 12:45:58,560 and the self. house instance variables 19881 12:45:55,640 --> 12:46:00,880 therein to those respective values in 19882 12:45:58,560 --> 12:46:03,276 this latest version of the Sorting Hat I 19883 12:46:00,880 --> 12:46:05,880 haven't bothered with self anywhere only 19884 12:46:03,276 --> 12:46:08,040 because conceptually I don't need or 19885 12:46:05,880 --> 12:46:10,360 want there to be multiple hats in the 19886 12:46:08,040 --> 12:46:13,360 world I'm just using the class is kind 19887 12:46:10,360 --> 12:46:15,680 of a container to bundle up this list of 19888 12:46:13,360 --> 12:46:17,320 houses this sorting functionality maybe 19889 12:46:15,680 --> 12:46:20,116 eventually I'll add more functionality 19890 12:46:17,320 --> 12:46:21,880 to it but that's it and so sometimes you 19891 12:46:20,116 --> 12:46:23,640 can use objectoriented programming in 19892 12:46:21,880 --> 12:46:25,800 this somewhat different way when you 19893 12:46:23,640 --> 12:46:28,240 want there to be functionality but it's 19894 12:46:25,800 --> 12:46:31,400 not specific to any one specific hat 19895 12:46:28,240 --> 12:46:33,720 it's specific to the Sorting Hat 19896 12:46:31,400 --> 12:46:36,916 itself how about one other question now 19897 12:46:33,720 --> 12:46:38,880 on these class variables or methods just 19898 12:46:36,916 --> 12:46:40,480 another way of using objectoriented 19899 12:46:38,880 --> 12:46:42,116 programming but to solve somewhat 19900 12:46:40,480 --> 12:46:45,400 different problem well what's the 19901 12:46:42,116 --> 12:46:48,680 difference between the class head and I 19902 12:46:45,400 --> 12:46:50,360 know like a function of hat a good 19903 12:46:48,680 --> 12:46:52,800 question so why are we using a class at 19904 12:46:50,360 --> 12:46:55,436 all and not just having a file called 19905 12:46:52,800 --> 12:46:57,720 hat. py with a variable called houses 19906 12:46:55,436 --> 12:46:59,680 and a function called sort like why are 19907 12:46:57,720 --> 12:47:01,360 we adding this complexity in this 19908 12:46:59,680 --> 12:47:04,240 particular case we don't necessarily 19909 12:47:01,360 --> 12:47:06,880 need to I could absolutely go in here I 19910 12:47:04,240 --> 12:47:09,160 could get rid of the class I could uh 19911 12:47:06,880 --> 12:47:11,276 undo this indentation I could could get 19912 12:47:09,160 --> 12:47:14,360 rid of this decorator and I could get 19913 12:47:11,276 --> 12:47:16,116 rid of hat Dot and I could just do this 19914 12:47:14,360 --> 12:47:18,360 and additionally let's see let's get rid 19915 12:47:16,116 --> 12:47:21,916 of class here let's get rid of class 19916 12:47:18,360 --> 12:47:23,520 Here and Now run python of haty enter 19917 12:47:21,916 --> 12:47:25,160 and it still works put Harry in the 19918 12:47:23,520 --> 12:47:27,680 wrong house but that's what we have what 19919 12:47:25,160 --> 12:47:29,436 happens randomly that's fine too what 19920 12:47:27,680 --> 12:47:31,200 we're introducing today by way of 19921 12:47:29,436 --> 12:47:33,436 object-oriented programming is just a 19922 12:47:31,200 --> 12:47:35,360 different way of modeling the world it's 19923 12:47:33,436 --> 12:47:37,360 not really compelling with an example 19924 12:47:35,360 --> 12:47:39,480 like this frankly that's relatively 19925 12:47:37,360 --> 12:47:41,200 simple it's not very complex there's not 19926 12:47:39,480 --> 12:47:43,116 much functionality honestly the version 19927 12:47:41,200 --> 12:47:45,116 that we just typed up these 10 lines 19928 12:47:43,116 --> 12:47:47,596 this is fine this solves this problem 19929 12:47:45,116 --> 12:47:49,200 but as our code gets longer as we start 19930 12:47:47,596 --> 12:47:50,400 collaborating with other people as the 19931 12:47:49,200 --> 12:47:52,160 problems we're trying to solve with code 19932 12:47:50,400 --> 12:47:55,240 get more sophisticated you're going to 19933 12:47:52,160 --> 12:47:56,640 find that your code gets messy quickly 19934 12:47:55,240 --> 12:47:58,480 and you're going to find that you have a 19935 12:47:56,640 --> 12:48:01,000 huge number of functions for instance in 19936 12:47:58,480 --> 12:48:03,276 one file and some of them are related to 19937 12:48:01,000 --> 12:48:04,640 each other but some of them are not well 19938 12:48:03,276 --> 12:48:06,360 at that point wouldn't it be nice to 19939 12:48:04,640 --> 12:48:08,080 just organize them a little differently 19940 12:48:06,360 --> 12:48:09,840 and in the World of Harry Potter let's 19941 12:48:08,080 --> 12:48:11,720 have a class for student let's have a 19942 12:48:09,840 --> 12:48:13,596 class for Professor let's have a class 19943 12:48:11,720 --> 12:48:15,436 for the Sorting Hat let's have a class 19944 12:48:13,596 --> 12:48:17,320 for something else and so once your 19945 12:48:15,436 --> 12:48:19,436 world gets much more complicated than 19946 12:48:17,320 --> 12:48:20,800 some of the demonstrations we do here in 19947 12:48:19,436 --> 12:48:23,200 class when we want to focus on 19948 12:48:20,800 --> 12:48:24,800 individual ideas object-oriented 19949 12:48:23,200 --> 12:48:27,436 programming is just a way of 19950 12:48:24,800 --> 12:48:29,640 encapsulating related data that is 19951 12:48:27,436 --> 12:48:32,480 variables related functionality that is 19952 12:48:29,640 --> 12:48:34,720 methods inside of things that have names 19953 12:48:32,480 --> 12:48:36,756 these things are called classes so it's 19954 12:48:34,720 --> 12:48:38,400 just another way to solve problems and 19955 12:48:36,756 --> 12:48:40,160 when we focused on libraries a couple of 19956 12:48:38,400 --> 12:48:42,000 weeks back back that too was another 19957 12:48:40,160 --> 12:48:44,360 solution to the same problem you could 19958 12:48:42,000 --> 12:48:46,116 Define your own modules or packages put 19959 12:48:44,360 --> 12:48:48,800 some of your data Endor functionality in 19960 12:48:46,116 --> 12:48:50,956 there and that's fine too and sometimes 19961 12:48:48,800 --> 12:48:53,040 which one you should use overlaps if 19962 12:48:50,956 --> 12:48:55,200 you're familiar with vend diagrams the 19963 12:48:53,040 --> 12:48:57,080 overlapping region might mean that you 19964 12:48:55,200 --> 12:48:58,720 could use a class you could use a module 19965 12:48:57,080 --> 12:49:01,840 or a package you could just use a single 19966 12:48:58,720 --> 12:49:03,320 local file over time you'll develop an 19967 12:49:01,840 --> 12:49:06,276 instinct and maybe even a personal 19968 12:49:03,320 --> 12:49:09,400 preference for which tool to 19969 12:49:06,276 --> 12:49:11,276 use all right let me propose now that we 19970 12:49:09,400 --> 12:49:13,756 apply this same idea of a class method 19971 12:49:11,276 --> 12:49:17,596 to clean up one other thing as well let 19972 12:49:13,756 --> 12:49:19,520 me close hat dopy and reopen student. py 19973 12:49:17,596 --> 12:49:22,276 as we left it earlier and let me go 19974 12:49:19,520 --> 12:49:24,560 ahead and simplify it just a little bit 19975 12:49:22,276 --> 12:49:26,680 uh I'm going to go ahead and get rid of 19976 12:49:24,560 --> 12:49:27,840 the properties not because there's 19977 12:49:26,680 --> 12:49:29,276 anything wrong with them but just 19978 12:49:27,840 --> 12:49:31,520 because I want us to focus on some of 19979 12:49:29,276 --> 12:49:33,240 the key ideas when we began with this 19980 12:49:31,520 --> 12:49:35,160 program so I'm going to go ahead and 19981 12:49:33,240 --> 12:49:37,560 keep main as well I'm not going to 19982 12:49:35,160 --> 12:49:39,756 adversar try to change Harry's uh 19983 12:49:37,560 --> 12:49:41,680 address there I'm going to instead go 19984 12:49:39,756 --> 12:49:43,916 ahead though and just print the student 19985 12:49:41,680 --> 12:49:46,596 but this is the thing I want to focus on 19986 12:49:43,916 --> 12:49:48,720 here this in our previous student 19987 12:49:46,596 --> 12:49:51,360 examples was kind of a missed 19988 12:49:48,720 --> 12:49:53,276 opportunity to clean up my code well 19989 12:49:51,360 --> 12:49:54,956 what do I mean by that well up here at 19990 12:49:53,276 --> 12:49:56,360 the top of this file even though I've 19991 12:49:54,956 --> 12:49:57,596 simplified it by getting rid of the 19992 12:49:56,360 --> 12:49:58,880 properties and all of that error 19993 12:49:57,596 --> 12:50:00,880 checking because I want to focus on the 19994 12:49:58,880 --> 12:50:02,360 essence of this class now just the 19995 12:50:00,880 --> 12:50:05,720 students's name and the house and the 19996 12:50:02,360 --> 12:50:08,116 printing thereof this is by nature of 19997 12:50:05,720 --> 12:50:11,800 classes and object-oriented programming 19998 12:50:08,116 --> 12:50:14,200 theoretic Al all of my student specific 19999 12:50:11,800 --> 12:50:16,040 functionality that is to say if I have 20000 12:50:14,200 --> 12:50:18,756 functionality and data related to a 20001 12:50:16,040 --> 12:50:20,800 student you the programmer my colleague 20002 12:50:18,756 --> 12:50:22,720 would assume that it's all bundled up 20003 12:50:20,800 --> 12:50:25,116 encapsulated so to speak inside of the 20004 12:50:22,720 --> 12:50:27,436 student class and yet if you scroll down 20005 12:50:25,116 --> 12:50:29,400 further what is this like there's a 20006 12:50:27,436 --> 12:50:31,480 function called get student that just 20007 12:50:29,400 --> 12:50:33,240 exists elsewhere in this file that 20008 12:50:31,480 --> 12:50:35,116 prompts the user for a name prompts the 20009 12:50:33,240 --> 12:50:37,200 user for a house creates the student 20010 12:50:35,116 --> 12:50:40,080 object and then returns it like that's 20011 12:50:37,200 --> 12:50:42,640 not wrong like it works and we saw many 20012 12:50:40,080 --> 12:50:45,000 many times it kept working but this is a 20013 12:50:42,640 --> 12:50:47,520 little weird right because what if this 20014 12:50:45,000 --> 12:50:49,436 is a function that helps you get a 20015 12:50:47,520 --> 12:50:51,480 student helps you get the name of a 20016 12:50:49,436 --> 12:50:53,360 student and the house of a student why 20017 12:50:51,480 --> 12:50:55,240 isn't that functionality in the class 20018 12:50:53,360 --> 12:50:56,756 itself after all as my code gets more 20019 12:50:55,240 --> 12:50:58,276 and more complicated and does more 20020 12:50:56,756 --> 12:51:00,040 things I'm going to be looking at the 20021 12:50:58,276 --> 12:51:01,360 student class for all student related 20022 12:51:00,040 --> 12:51:03,320 functionality I'm not going to be 20023 12:51:01,360 --> 12:51:05,200 scrolling down expecting that oh maybe 20024 12:51:03,320 --> 12:51:07,680 there's some other student functionality 20025 12:51:05,200 --> 12:51:09,840 just kind of randomly later in this file 20026 12:51:07,680 --> 12:51:13,276 so it's not wrong but this is again 20027 12:51:09,840 --> 12:51:15,756 evidence of maybe bad design not so much 20028 12:51:13,276 --> 12:51:17,360 with this small program but this is an 20029 12:51:15,756 --> 12:51:18,916 example again of code smell like 20030 12:51:17,360 --> 12:51:20,116 something smells a little off here like 20031 12:51:18,916 --> 12:51:22,916 this is probably going to get us in 20032 12:51:20,116 --> 12:51:24,756 trouble by separating related 20033 12:51:22,916 --> 12:51:27,840 functionality so again it's a design 20034 12:51:24,756 --> 12:51:30,240 principle not a correctness concern but 20035 12:51:27,840 --> 12:51:32,720 class methods allow us to address this 20036 12:51:30,240 --> 12:51:35,080 too let me go ahead and do this I'm 20037 12:51:32,720 --> 12:51:37,916 going to delete get student altogether 20038 12:51:35,080 --> 12:51:40,400 leaving only main as my other function 20039 12:51:37,916 --> 12:51:42,956 here and inside of my student class I'm 20040 12:51:40,400 --> 12:51:46,040 going to do this I'm going to define a 20041 12:51:42,956 --> 12:51:48,116 function even more simply called get and 20042 12:51:46,040 --> 12:51:49,880 by nature of how class methods work it's 20043 12:51:48,116 --> 12:51:51,916 going to take in the name of the class 20044 12:51:49,880 --> 12:51:53,840 itself or reference there too as an 20045 12:51:51,916 --> 12:51:55,756 argument and I'm going to move the 20046 12:51:53,840 --> 12:51:57,640 functionality from get student into the 20047 12:51:55,756 --> 12:52:01,240 student class and I'm going to do this 20048 12:51:57,640 --> 12:52:04,756 name equals input quote unquote name uh 20049 12:52:01,240 --> 12:52:06,756 house equals input quote unquote house 20050 12:52:04,756 --> 12:52:11,640 and then what this function is going to 20051 12:52:06,756 --> 12:52:14,436 do is return a new student object by 20052 12:52:11,640 --> 12:52:16,840 calling class which again is just an 20053 12:52:14,436 --> 12:52:20,756 automatically passed in reference to the 20054 12:52:16,840 --> 12:52:23,080 class itself passing in name and house 20055 12:52:20,756 --> 12:52:26,000 and I will admit this syntax seems a 20056 12:52:23,080 --> 12:52:27,360 little strange that now I'm calling CLS 20057 12:52:26,000 --> 12:52:29,436 and I'm passing in these arguments but 20058 12:52:27,360 --> 12:52:30,956 let me do one final fix here let me go 20059 12:52:29,436 --> 12:52:34,240 to the top of this function and more 20060 12:52:30,956 --> 12:52:36,000 explicitly say this is a class method 20061 12:52:34,240 --> 12:52:38,560 this solves a potential Chicken and the 20062 12:52:36,000 --> 12:52:39,720 Egg problem so to speak whereby one 20063 12:52:38,560 --> 12:52:42,436 needs to come before the other 20064 12:52:39,720 --> 12:52:45,040 potentially so what am I doing here 20065 12:52:42,436 --> 12:52:48,276 inside of my student class I now have a 20066 12:52:45,040 --> 12:52:50,560 function called get it is I shall claim 20067 12:52:48,276 --> 12:52:53,276 a class method what does that mean it 20068 12:52:50,560 --> 12:52:56,436 just means I can call this method 20069 12:52:53,276 --> 12:52:58,756 without instantiating a student object 20070 12:52:56,436 --> 12:53:00,480 first there in lies the potential 20071 12:52:58,756 --> 12:53:02,200 Chicken and the Egg problem and if 20072 12:53:00,480 --> 12:53:04,436 unfamiliar that's an expression meaning 20073 12:53:02,200 --> 12:53:06,436 well did the world have chickens first 20074 12:53:04,436 --> 12:53:09,000 that laid eggs or was there an egg that 20075 12:53:06,436 --> 12:53:10,520 then Bor uh yielded the chicken but how 20076 12:53:09,000 --> 12:53:12,040 did the egg get there it's this sort of 20077 12:53:10,520 --> 12:53:14,680 weird circular problem and that's what 20078 12:53:12,040 --> 12:53:17,880 we're facing here it would be weird if 20079 12:53:14,680 --> 12:53:20,880 you had to create a student object in 20080 12:53:17,880 --> 12:53:23,200 order to call get in order to get 20081 12:53:20,880 --> 12:53:27,000 another student object like that sounds 20082 12:53:23,200 --> 12:53:29,480 messy let's just get a student via a 20083 12:53:27,000 --> 12:53:31,720 class method that by definition does not 20084 12:53:29,480 --> 12:53:33,680 require you to create a student object 20085 12:53:31,720 --> 12:53:36,956 first just like the Hat in its final 20086 12:53:33,680 --> 12:53:39,400 form we use the Hat class to just say 20087 12:53:36,956 --> 12:53:41,116 hat Capital H do sort we didn't need to 20088 12:53:39,400 --> 12:53:43,680 create a hat first we just used the 20089 12:53:41,116 --> 12:53:46,276 class itself so what am I going to do 20090 12:53:43,680 --> 12:53:48,596 here now let me go down to Main and 20091 12:53:46,276 --> 12:53:52,200 instead of saying get student notice 20092 12:53:48,596 --> 12:53:55,040 what I can now do student. get and 20093 12:53:52,200 --> 12:53:57,840 everything else can stay the same all 20094 12:53:55,040 --> 12:53:59,840 I've done now is I've migrated all of my 20095 12:53:57,840 --> 12:54:02,080 logic from get student which was this 20096 12:53:59,840 --> 12:54:04,916 own Standalone function but clearly 20097 12:54:02,080 --> 12:54:08,720 related to students by name I've moved 20098 12:54:04,916 --> 12:54:11,276 the same code really to inside of the 20099 12:54:08,720 --> 12:54:12,916 student class in a more simply named 20100 12:54:11,276 --> 12:54:14,640 function called get but I could still 20101 12:54:12,916 --> 12:54:16,400 call it get student if I want it just 20102 12:54:14,640 --> 12:54:18,200 seems a little redundant to call it get 20103 12:54:16,400 --> 12:54:20,560 student in a student class so I'm 20104 12:54:18,200 --> 12:54:23,320 simplifying so I have a method called 20105 12:54:20,560 --> 12:54:25,436 get but I'm calling it a class method to 20106 12:54:23,320 --> 12:54:28,200 avoid that chicken in the egg problem I 20107 12:54:25,436 --> 12:54:30,916 want to be able to call get without 20108 12:54:28,200 --> 12:54:34,080 having a student object in my universe 20109 12:54:30,916 --> 12:54:36,640 already and the syntax for that is at 20110 12:54:34,080 --> 12:54:38,480 class method the convention is to give 20111 12:54:36,640 --> 12:54:40,916 this method at least one argument by by 20112 12:54:38,480 --> 12:54:42,040 convention called CLS for class which is 20113 12:54:40,916 --> 12:54:44,680 just going to be a reference to the 20114 12:54:42,040 --> 12:54:46,400 class itself lines 11 and 12 are 20115 12:54:44,680 --> 12:54:49,000 identical to what they've always been 20116 12:54:46,400 --> 12:54:51,000 and get student the only new syntax here 20117 12:54:49,000 --> 12:54:53,520 is this but this again is one of the 20118 12:54:51,000 --> 12:54:55,360 features of object-oriented programming 20119 12:54:53,520 --> 12:54:58,596 you can now 20120 12:54:55,360 --> 12:55:01,640 instantiate a student object by just 20121 12:54:58,596 --> 12:55:03,956 using CLS that's passed in I technically 20122 12:55:01,640 --> 12:55:05,800 could use student capital S but it turns 20123 12:55:03,956 --> 12:55:07,680 out I'm doing what's more conventional 20124 12:55:05,800 --> 12:55:09,200 because this will both solve and avoid 20125 12:55:07,680 --> 12:55:11,756 problems down the line with more 20126 12:55:09,200 --> 12:55:14,276 complicated code this line here on line 20127 12:55:11,756 --> 12:55:15,720 13 just means create an object of the 20128 12:55:14,276 --> 12:55:17,800 current class what class is that well 20129 12:55:15,720 --> 12:55:19,756 whatever CLS is well that by definition 20130 12:55:17,800 --> 12:55:22,116 of how it all works is going to be 20131 12:55:19,756 --> 12:55:26,276 student and I want you to initialize it 20132 12:55:22,116 --> 12:55:29,116 as always with name and house so now 20133 12:55:26,276 --> 12:55:31,480 scrolling down my code is this and this 20134 12:55:29,116 --> 12:55:33,596 is just nice to read you did perhaps 20135 12:55:31,480 --> 12:55:35,240 have to acquire a taste for this and I 20136 12:55:33,596 --> 12:55:37,956 sound a little odd saying this is nice 20137 12:55:35,240 --> 12:55:39,800 to read but indeed student. just tells 20138 12:55:37,956 --> 12:55:41,640 me what's going on I'm going to get a 20139 12:55:39,800 --> 12:55:43,560 student I don't need a separate function 20140 12:55:41,640 --> 12:55:46,436 written by me called get student in the 20141 12:55:43,560 --> 12:55:48,436 file itself the get functionality is 20142 12:55:46,436 --> 12:55:50,800 built into the class all my student 20143 12:55:48,436 --> 12:55:52,400 related code now is together so let me 20144 12:55:50,800 --> 12:55:54,436 go down to my terminal window and run 20145 12:55:52,400 --> 12:55:56,800 python of student. enter let's type in 20146 12:55:54,436 --> 12:55:59,480 Harry let's type in Gryffindor and we're 20147 12:55:56,800 --> 12:56:02,436 back to where we began but but but 20148 12:55:59,480 --> 12:56:04,480 everything related to students now is in 20149 12:56:02,436 --> 12:56:07,400 this here class the only other thing in 20150 12:56:04,480 --> 12:56:09,596 the file is Main and this conditional 20151 12:56:07,400 --> 12:56:11,480 that we always use to avoid accidentally 20152 12:56:09,596 --> 12:56:14,436 executing main when we're making a 20153 12:56:11,480 --> 12:56:17,680 module or a package or the like so again 20154 12:56:14,436 --> 12:56:19,400 a solution to a problem not a big one in 20155 12:56:17,680 --> 12:56:20,800 the case of a relatively small program 20156 12:56:19,400 --> 12:56:22,400 but one that you will eventually 20157 12:56:20,800 --> 12:56:25,320 encounter as your programs get longer 20158 12:56:22,400 --> 12:56:26,240 and longer with more and more entities 20159 12:56:25,320 --> 12:56:30,360 to 20160 12:56:26,240 --> 12:56:32,880 represent questions now on this use of a 20161 12:56:30,360 --> 12:56:34,880 class method does the does the class 20162 12:56:32,880 --> 12:56:37,160 have to be defined before the main 20163 12:56:34,880 --> 12:56:39,160 function in terms of the order of the of 20164 12:56:37,160 --> 12:56:40,756 the program really good question so when 20165 12:56:39,160 --> 12:56:42,400 in doubt let's try this so let's try to 20166 12:56:40,756 --> 12:56:44,756 change the order let's move main to the 20167 12:56:42,400 --> 12:56:47,480 top which I've often encouraged so let's 20168 12:56:44,756 --> 12:56:50,200 go ahead and above the class do this and 20169 12:56:47,480 --> 12:56:52,520 notice now that technically line two is 20170 12:56:50,200 --> 12:56:54,916 mentioning student which does not exist 20171 12:56:52,520 --> 12:56:56,720 until line six and Below let me go ahead 20172 12:56:54,916 --> 12:57:00,840 and clear my terminal and run python of 20173 12:56:56,720 --> 12:57:03,480 studenty so far so good Harry Gryffindor 20174 12:57:00,840 --> 12:57:05,840 okay uh indeed Harry's from Gryffindor 20175 12:57:03,480 --> 12:57:07,720 the reason Michael it does not matter in 20176 12:57:05,840 --> 12:57:10,560 this case is because we're not actually 20177 12:57:07,720 --> 12:57:12,360 call main until the very end and just as 20178 12:57:10,560 --> 12:57:13,800 in the past that means that python has a 20179 12:57:12,360 --> 12:57:16,276 chance to read everything top to bottom 20180 12:57:13,800 --> 12:57:19,000 left to right so everything exists I 20181 12:57:16,276 --> 12:57:21,320 would say generally classes are defined 20182 12:57:19,000 --> 12:57:23,800 at the top of the file however it would 20183 12:57:21,320 --> 12:57:26,200 be even maybe cleaner to move the 20184 12:57:23,800 --> 12:57:28,436 classes definition to its own file and 20185 12:57:26,200 --> 12:57:30,520 then import it so essentially to make 20186 12:57:28,436 --> 12:57:32,320 reusable code by putting it into your 20187 12:57:30,520 --> 12:57:34,480 own module or package so that not just 20188 12:57:32,320 --> 12:57:36,756 this program but many others can use 20189 12:57:34,480 --> 12:57:39,840 that definition of student as well other 20190 12:57:36,756 --> 12:57:42,000 questions now on classes class methods 20191 12:57:39,840 --> 12:57:46,756 or the like I wanted to ask is there a 20192 12:57:42,000 --> 12:57:49,916 way to um like declare all the all the 20193 12:57:46,756 --> 12:57:52,840 possible all the possible attributes of 20194 12:57:49,916 --> 12:57:55,480 the class because it looks so 20195 12:57:52,840 --> 12:57:57,480 inconsistent um well so my takeaway 20196 12:57:55,480 --> 12:57:58,956 there is this is Python's approach to 20197 12:57:57,480 --> 12:58:00,680 these principles different languages 20198 12:57:58,956 --> 12:58:02,800 like Java just take a different approach 20199 12:58:00,680 --> 12:58:04,916 but have very similar features the 20200 12:58:02,800 --> 12:58:06,680 syntax just tends to vary and this is 20201 12:58:04,916 --> 12:58:09,080 how the python Community chose to 20202 12:58:06,680 --> 12:58:11,080 implement this idea the right mental 20203 12:58:09,080 --> 12:58:15,116 model ultimately is that these instance 20204 12:58:11,080 --> 12:58:18,680 variables instant methods belong to or 20205 12:58:15,116 --> 12:58:21,916 operate on specific objects a specific 20206 12:58:18,680 --> 12:58:25,040 student a specific hat class variables 20207 12:58:21,916 --> 12:58:28,320 and class methods operate on the entire 20208 12:58:25,040 --> 12:58:29,640 class itself or in turn all objects of 20209 12:58:28,320 --> 12:58:31,756 that class which we've not seen them a 20210 12:58:29,640 --> 12:58:33,880 demonstration of but it's sort of a 20211 12:58:31,756 --> 12:58:35,756 higher level concept so it turns out 20212 12:58:33,880 --> 12:58:37,840 besides these class methods which are 20213 12:58:35,756 --> 12:58:39,680 distinct from those instance methods 20214 12:58:37,840 --> 12:58:41,520 which to be fair do not have their own 20215 12:58:39,680 --> 12:58:43,240 decorator they just are by default 20216 12:58:41,520 --> 12:58:44,956 instance method there's yet other types 20217 12:58:43,240 --> 12:58:46,680 of methods you can have in classes in 20218 12:58:44,956 --> 12:58:48,596 Python they tend to be called Static 20219 12:58:46,680 --> 12:58:50,800 methods and they too come with another 20220 12:58:48,596 --> 12:58:52,840 decorator called at static method which 20221 12:58:50,800 --> 12:58:54,480 is a rabbit hole we won't go down but 20222 12:58:52,840 --> 12:58:56,040 realize that there is yet other 20223 12:58:54,480 --> 12:58:58,000 functionality that you can leverage 20224 12:58:56,040 --> 12:58:59,640 within object-oriented programming but 20225 12:58:58,000 --> 12:59:02,400 what we thought we'd do is focus really 20226 12:58:59,640 --> 12:59:04,360 on some final core features that you see 20227 12:59:02,400 --> 12:59:06,160 not just in Python but other languages 20228 12:59:04,360 --> 12:59:08,200 as well and perhaps one of the most 20229 12:59:06,160 --> 12:59:10,200 compelling features of objectoriented 20230 12:59:08,200 --> 12:59:11,916 programming that we haven't yet used 20231 12:59:10,200 --> 12:59:14,756 explicitly though it turns out we've 20232 12:59:11,916 --> 12:59:17,520 seen implicitly over the past weeks is 20233 12:59:14,756 --> 12:59:19,436 this notion of inheritance it turns out 20234 12:59:17,520 --> 12:59:22,040 via object-oriented programming there's 20235 12:59:19,436 --> 12:59:24,800 actually an opportunity to design your 20236 12:59:22,040 --> 12:59:27,520 classes in a hierarchical fashion 20237 12:59:24,800 --> 12:59:31,040 whereby you can have one class inherit 20238 12:59:27,520 --> 12:59:33,880 from or borrow attributes that is 20239 12:59:31,040 --> 12:59:36,680 methods or variables from another class 20240 12:59:33,880 --> 12:59:38,480 if they all have those in common so what 20241 12:59:36,680 --> 12:59:41,800 do I mean by this here well let me 20242 12:59:38,480 --> 12:59:44,160 propose that we Implement uh over in vs 20243 12:59:41,800 --> 12:59:46,720 code here a brand new file called 20244 12:59:44,160 --> 12:59:50,160 wizard. let me go ahead and run code of 20245 12:59:46,720 --> 12:59:53,436 wizard. py and then let's start as 20246 12:59:50,160 --> 12:59:55,320 before defining a class called student 20247 12:59:53,436 --> 12:59:57,916 and let's go ahead and first Define the 20248 12:59:55,320 --> 12:59:59,160 underscore uncore init method which of 20249 12:59:57,916 --> 13:00:01,040 course is minimally going to take an 20250 12:59:59,160 --> 13:00:02,680 argument traditionally called self and 20251 13:00:01,040 --> 13:00:05,240 in this case let's also have it take as 20252 13:00:02,680 --> 13:00:06,916 before a name and a house and then in 20253 13:00:05,240 --> 13:00:10,160 this init method let's go ahead and 20254 13:00:06,916 --> 13:00:14,240 assign the instance variables self. name 20255 13:00:10,160 --> 13:00:15,520 equals name and self. house equals house 20256 13:00:14,240 --> 13:00:17,480 let's assume that there's some other 20257 13:00:15,520 --> 13:00:19,276 functionality in this class as well dot 20258 13:00:17,480 --> 13:00:21,240 dot dot but let's move on now to 20259 13:00:19,276 --> 13:00:23,800 implementing the notion of a a professor 20260 13:00:21,240 --> 13:00:26,800 in The Wizarding World as well so for 20261 13:00:23,800 --> 13:00:29,400 this class let's call it 20262 13:00:26,800 --> 13:00:30,840 professor and a professor let's say is 20263 13:00:29,400 --> 13:00:32,756 also going to have its own 20264 13:00:30,840 --> 13:00:34,720 initialization method so underscore 20265 13:00:32,756 --> 13:00:36,840 underscore in it it's going to take self 20266 13:00:34,720 --> 13:00:38,880 as always as the first argument uh a 20267 13:00:36,840 --> 13:00:41,276 professor also has a name so we'll pass 20268 13:00:38,880 --> 13:00:43,080 that in second two and even though some 20269 13:00:41,276 --> 13:00:44,480 professors are heads of houses let's 20270 13:00:43,080 --> 13:00:46,000 assume that a professor is really 20271 13:00:44,480 --> 13:00:48,360 identified by their name and their 20272 13:00:46,000 --> 13:00:50,320 subject area the class that they teach 20273 13:00:48,360 --> 13:00:52,560 so we'll call this third argument 20274 13:00:50,320 --> 13:00:55,436 subject now as before let's go ahead and 20275 13:00:52,560 --> 13:00:59,360 assign self. name equals name and let's 20276 13:00:55,436 --> 13:01:00,756 assign self. sub equals subject here and 20277 13:00:59,360 --> 13:01:02,720 as before let's assume that there's some 20278 13:01:00,756 --> 13:01:04,800 more functionality associated with 20279 13:01:02,720 --> 13:01:07,560 professors as well well what do you 20280 13:01:04,800 --> 13:01:09,400 notice already here in my definitions of 20281 13:01:07,560 --> 13:01:11,596 St students and 20282 13:01:09,400 --> 13:01:14,080 professors typically we're a bit 20283 13:01:11,596 --> 13:01:16,916 reluctant to allow for any redundancy in 20284 13:01:14,080 --> 13:01:19,040 our code and here I feel like my init 20285 13:01:16,916 --> 13:01:21,080 method is taking a name for students my 20286 13:01:19,040 --> 13:01:22,560 init method is also taking a name for a 20287 13:01:21,080 --> 13:01:25,000 professor and I have these identical 20288 13:01:22,560 --> 13:01:26,400 lines of code like self. name equals 20289 13:01:25,000 --> 13:01:28,276 name and this is only going to get 20290 13:01:26,400 --> 13:01:30,756 exacerbated if I now go and add some 20291 13:01:28,276 --> 13:01:33,720 error checking so for instance How about 20292 13:01:30,756 --> 13:01:35,400 if uh if not name we should probably be 20293 13:01:33,720 --> 13:01:37,640 in the habit of raising something like a 20294 13:01:35,400 --> 13:01:40,560 value error in an explanatory message 20295 13:01:37,640 --> 13:01:42,276 like missing name and you know what if a 20296 13:01:40,560 --> 13:01:44,080 professor is missing their name I should 20297 13:01:42,276 --> 13:01:46,000 probably copy paste that code down here 20298 13:01:44,080 --> 13:01:47,640 and that's where Red Flag should be 20299 13:01:46,000 --> 13:01:50,560 going off whereby as soon as you start 20300 13:01:47,640 --> 13:01:52,400 copy pasting code there's probably a 20301 13:01:50,560 --> 13:01:54,560 better way so that we can write the code 20302 13:01:52,400 --> 13:01:56,720 once and perhaps reuse it in some way 20303 13:01:54,560 --> 13:01:59,276 and here too object-oriented programming 20304 13:01:56,720 --> 13:02:00,956 offers a solution it turns out that 20305 13:01:59,276 --> 13:02:04,000 object-oriented programming in Python 20306 13:02:00,956 --> 13:02:06,840 also supports inheritance whereby you 20307 13:02:04,000 --> 13:02:08,680 can Define multiple classes that somehow 20308 13:02:06,840 --> 13:02:10,796 relate to one another they don't need to 20309 13:02:08,680 --> 13:02:12,480 exist sort of in parallel in this way 20310 13:02:10,796 --> 13:02:14,200 there could actually be some hierarchy 20311 13:02:12,480 --> 13:02:16,040 between them so for instance in The 20312 13:02:14,200 --> 13:02:18,080 Wizarding World we could argue that both 20313 13:02:16,040 --> 13:02:20,360 a student and a professor are at the end 20314 13:02:18,080 --> 13:02:22,520 of the day Wizards so maybe what we 20315 13:02:20,360 --> 13:02:24,756 should really Define is a third class 20316 13:02:22,520 --> 13:02:27,840 for instance called wizard that has any 20317 13:02:24,756 --> 13:02:29,400 of the common attributes for students 20318 13:02:27,840 --> 13:02:31,040 and professors alike and for now we've 20319 13:02:29,400 --> 13:02:33,520 kept it relatively simple the only thing 20320 13:02:31,040 --> 13:02:35,560 they have in common is a name and a name 20321 13:02:33,520 --> 13:02:37,840 in student and Professor respectively so 20322 13:02:35,560 --> 13:02:40,200 why don't we minimally factor that out 20323 13:02:37,840 --> 13:02:41,680 first all right so let me go ahead here 20324 13:02:40,200 --> 13:02:43,436 and just to keep things organized at the 20325 13:02:41,680 --> 13:02:45,956 top of my file let's define a third 20326 13:02:43,436 --> 13:02:48,240 class called Wizard and a wizard will 20327 13:02:45,956 --> 13:02:51,320 have its own initialization method so 20328 13:02:48,240 --> 13:02:53,756 decore uncore init underscore uncore and 20329 13:02:51,320 --> 13:02:56,200 self as always and a wizard let's say 20330 13:02:53,756 --> 13:02:59,596 for now is only going to be initialized 20331 13:02:56,200 --> 13:03:00,840 with their name in this way and now I'm 20332 13:02:59,596 --> 13:03:02,756 going to go ahead and do some of that 20333 13:03:00,840 --> 13:03:05,680 error checking so if not name we'll 20334 13:03:02,756 --> 13:03:07,796 raise a value error in the Wizard class 20335 13:03:05,680 --> 13:03:10,436 otherwise we'll go ahead and do self. 20336 13:03:07,796 --> 13:03:12,680 name equals name and heck dot dot dot 20337 13:03:10,436 --> 13:03:14,596 maybe some other functionality as well 20338 13:03:12,680 --> 13:03:16,360 but not a subject which is specific to 20339 13:03:14,596 --> 13:03:18,880 professors and not a house which I've 20340 13:03:16,360 --> 13:03:21,360 claimed is specific to students now I 20341 13:03:18,880 --> 13:03:23,436 think we can begin to maybe remove some 20342 13:03:21,360 --> 13:03:26,756 of the redundancies in our other classes 20343 13:03:23,436 --> 13:03:28,720 here so for instance down with student 20344 13:03:26,756 --> 13:03:30,916 why don't I go ahead and remove this 20345 13:03:28,720 --> 13:03:33,480 error checking here and remove this 20346 13:03:30,916 --> 13:03:35,360 error this assignment of self. name 20347 13:03:33,480 --> 13:03:37,320 equals name because I'm already doing 20348 13:03:35,360 --> 13:03:38,640 that in Wizard and similarly down here 20349 13:03:37,320 --> 13:03:40,480 in Prof Professor why don't I do the 20350 13:03:38,640 --> 13:03:42,436 same let's get rid of the error checking 20351 13:03:40,480 --> 13:03:43,956 let's get rid of self. name equals name 20352 13:03:42,436 --> 13:03:46,640 because I'm again I'm doing that already 20353 13:03:43,956 --> 13:03:48,200 up there for Wizard as well but at the 20354 13:03:46,640 --> 13:03:50,596 moment even though they're all in the 20355 13:03:48,200 --> 13:03:53,040 same file I haven't told python that a 20356 13:03:50,596 --> 13:03:54,956 student is a wizard and a professor is a 20357 13:03:53,040 --> 13:03:56,956 wizard so I really need to link these 20358 13:03:54,956 --> 13:04:00,040 two together and the way you can 20359 13:03:56,956 --> 13:04:01,880 prescribe inheritance whereby one class 20360 13:04:00,040 --> 13:04:04,080 should inherit from another or 20361 13:04:01,880 --> 13:04:06,640 conversely one class should descend for 20362 13:04:04,080 --> 13:04:08,796 another from another we can do this I 20363 13:04:06,640 --> 13:04:11,400 can say class student but before the 20364 13:04:08,796 --> 13:04:14,796 colon I can go in and say in parenthesis 20365 13:04:11,400 --> 13:04:17,720 a student inherits from or is a subass 20366 13:04:14,796 --> 13:04:20,240 of wizard which conversely is the super 20367 13:04:17,720 --> 13:04:22,480 class of the student class so this just 20368 13:04:20,240 --> 13:04:24,116 means that when I Define a student class 20369 13:04:22,480 --> 13:04:27,000 go ahead and inherit all of the 20370 13:04:24,116 --> 13:04:28,560 characteristics of a wizard as well and 20371 13:04:27,000 --> 13:04:31,480 I'm going to do the same thing for Prof 20372 13:04:28,560 --> 13:04:33,160 for Professor so parenthesis wizard 20373 13:04:31,480 --> 13:04:34,756 after the class name professor and 20374 13:04:33,160 --> 13:04:36,080 that's going to give me access to some 20375 13:04:34,756 --> 13:04:38,560 of that same 20376 13:04:36,080 --> 13:04:40,720 functionality but because my student 20377 13:04:38,560 --> 13:04:43,040 class and my professor class still have 20378 13:04:40,720 --> 13:04:44,200 their same init methods those are the 20379 13:04:43,040 --> 13:04:46,200 methods that are going to get called 20380 13:04:44,200 --> 13:04:48,560 whenever I create a student in code or I 20381 13:04:46,200 --> 13:04:50,596 create a professor in code I need to 20382 13:04:48,560 --> 13:04:53,040 somehow explicitly say that I also want 20383 13:04:50,596 --> 13:04:55,720 to use the functionality in the Wizard 20384 13:04:53,040 --> 13:04:57,956 classes init method and the way to do 20385 13:04:55,720 --> 13:05:00,200 this in Python is is as follows let me 20386 13:04:57,956 --> 13:05:02,680 go into my init method for student and 20387 13:05:00,200 --> 13:05:05,240 let me call Super with no arguments 20388 13:05:02,680 --> 13:05:07,240 which is a reference to the super class 20389 13:05:05,240 --> 13:05:08,956 of this class so if this class is 20390 13:05:07,240 --> 13:05:12,040 student the super class that is the 20391 13:05:08,956 --> 13:05:14,320 parent class is Wizard so super open 20392 13:05:12,040 --> 13:05:17,596 paren closed paren will have the effect 20393 13:05:14,320 --> 13:05:19,040 of accessing the super class and then 20394 13:05:17,596 --> 13:05:21,436 I'm going to go ahead and explicitly 20395 13:05:19,040 --> 13:05:25,480 call its init method and I'm going to 20396 13:05:21,436 --> 13:05:28,116 pass to the Wizards init method the name 20397 13:05:25,480 --> 13:05:29,480 that the students init method was passed 20398 13:05:28,116 --> 13:05:31,596 and I'm going to go ahead and do the 20399 13:05:29,480 --> 13:05:33,880 same down here in Wizard this is one 20400 13:05:31,596 --> 13:05:35,680 line of copy paste but I think I'm okay 20401 13:05:33,880 --> 13:05:37,240 with it here because it's still allowing 20402 13:05:35,680 --> 13:05:38,956 me to do all of the name assignment and 20403 13:05:37,240 --> 13:05:41,916 the error checking up in the Wizard 20404 13:05:38,956 --> 13:05:44,640 class instead I think we're okay now by 20405 13:05:41,916 --> 13:05:46,680 just calling super. init for both 20406 13:05:44,640 --> 13:05:49,560 student and Professor alike now 20407 13:05:46,680 --> 13:05:51,000 admittedly this syntax is definitely out 20408 13:05:49,560 --> 13:05:52,956 there the fact that we're calling super 20409 13:05:51,000 --> 13:05:54,596 and parentheses and dots and underscore 20410 13:05:52,956 --> 13:05:56,720 underscore on the left and the right of 20411 13:05:54,596 --> 13:05:58,840 in it here but it's just a combination 20412 13:05:56,720 --> 13:06:00,520 of these two ideas super open 20413 13:05:58,840 --> 13:06:02,596 parenthesis closed parenthesis is a way 20414 13:06:00,520 --> 13:06:05,400 of programmatically accessing a current 20415 13:06:02,596 --> 13:06:07,116 classes parent class or super class and 20416 13:06:05,400 --> 13:06:09,756 underscore uncore init of course is just 20417 13:06:07,116 --> 13:06:12,116 referring to now that class's own 20418 13:06:09,756 --> 13:06:13,436 initialization method now per the dot 20419 13:06:12,116 --> 13:06:15,916 dot dots there could be a lot more going 20420 13:06:13,436 --> 13:06:18,796 on in these classes but what's nice now 20421 13:06:15,916 --> 13:06:20,880 is that wizard as a class is taking care 20422 13:06:18,796 --> 13:06:22,596 of all of the assignment of a Wizard's 20423 13:06:20,880 --> 13:06:24,360 name whether that wizard is a student or 20424 13:06:22,596 --> 13:06:26,160 a professor and it's even doing some 20425 13:06:24,360 --> 13:06:29,680 error cheing to make sure that the name 20426 13:06:26,160 --> 13:06:32,080 was actually passed in meanwhile student 20427 13:06:29,680 --> 13:06:33,956 is inheriting all of that functionality 20428 13:06:32,080 --> 13:06:35,756 and using it by calling the super 20429 13:06:33,956 --> 13:06:37,520 class's own init method but it's 20430 13:06:35,756 --> 13:06:39,160 additionally taking the house that's 20431 13:06:37,520 --> 13:06:41,520 presumably passed into the student 20432 13:06:39,160 --> 13:06:43,840 Constructor function and assigning it to 20433 13:06:41,520 --> 13:06:45,916 its own instance variable self. house 20434 13:06:43,840 --> 13:06:48,116 and similarly Professor are we storing 20435 13:06:45,916 --> 13:06:50,240 in self- thought subject the subject 20436 13:06:48,116 --> 13:06:52,840 that was passed into there that one as 20437 13:06:50,240 --> 13:06:54,916 well now how might we use these classes 20438 13:06:52,840 --> 13:06:56,640 well we'll continue to wave our hands 20439 13:06:54,916 --> 13:06:58,240 with a little bit of detail here but if 20440 13:06:56,640 --> 13:07:00,596 at the bottom of this file or any other 20441 13:06:58,240 --> 13:07:02,400 file that Imports this one I could now 20442 13:07:00,596 --> 13:07:04,400 write code like this I could create a 20443 13:07:02,400 --> 13:07:06,080 student variable and assign it the 20444 13:07:04,400 --> 13:07:07,796 return value of the student Constructor 20445 13:07:06,080 --> 13:07:10,720 call and maybe that student is named 20446 13:07:07,796 --> 13:07:13,436 Harry and that student's house for 20447 13:07:10,720 --> 13:07:15,276 instance might be Gryffindor and 20448 13:07:13,436 --> 13:07:17,680 meanwhile I might do something like this 20449 13:07:15,276 --> 13:07:20,116 professor equals professor over here and 20450 13:07:17,680 --> 13:07:21,880 notice the lowercase s on the left 20451 13:07:20,116 --> 13:07:23,756 capital S on the right same for 20452 13:07:21,880 --> 13:07:25,840 Professor on the left lowercase and 20453 13:07:23,756 --> 13:07:28,520 uppercase on the right respectively 20454 13:07:25,840 --> 13:07:32,320 Professor quote unquote seus and how 20455 13:07:28,520 --> 13:07:34,796 about defense against the dark arts will 20456 13:07:32,320 --> 13:07:36,956 be his subject and meanwhile if we want 20457 13:07:34,796 --> 13:07:38,040 more generically just a wizard who at 20458 13:07:36,956 --> 13:07:40,116 the moment 20459 13:07:38,040 --> 13:07:41,756 is neither student nor Professor 20460 13:07:40,116 --> 13:07:44,956 teaching classes actively we could even 20461 13:07:41,756 --> 13:07:46,796 do that we could do wizard equals wizard 20462 13:07:44,956 --> 13:07:48,040 in capital W on the right hand side of 20463 13:07:46,796 --> 13:07:50,436 the equal sign because it's the name of 20464 13:07:48,040 --> 13:07:54,840 the class and someone like Albus passing 20465 13:07:50,436 --> 13:07:57,240 in only albus's name not a house not a 20466 13:07:54,840 --> 13:07:59,880 subject because in this case he's known 20467 13:07:57,240 --> 13:08:02,116 only as a wizard meanwhile with each of 20468 13:07:59,880 --> 13:08:03,560 these calls this line of code here will 20469 13:08:02,116 --> 13:08:05,796 ensure that the init method for the 20470 13:08:03,560 --> 13:08:08,040 wizard class is called this line of code 20471 13:08:05,796 --> 13:08:09,956 here will ensure that the init method of 20472 13:08:08,040 --> 13:08:11,680 the student class and in turn the init 20473 13:08:09,956 --> 13:08:13,720 method of the super class wizard is 20474 13:08:11,680 --> 13:08:16,480 called and then lastly on this final 20475 13:08:13,720 --> 13:08:18,276 line of code will this syntax ensure 20476 13:08:16,480 --> 13:08:20,276 that the init method of the professor 20477 13:08:18,276 --> 13:08:23,320 class is called which in turn calls the 20478 13:08:20,276 --> 13:08:26,000 init method of the super class as well 20479 13:08:23,320 --> 13:08:28,680 any questions now on this idea of 20480 13:08:26,000 --> 13:08:29,756 inheritance which is a key feature of a 20481 13:08:28,680 --> 13:08:32,480 lot of 20482 13:08:29,756 --> 13:08:36,240 objectoriented programming languages um 20483 13:08:32,480 --> 13:08:37,840 so is there any situation where because 20484 13:08:36,240 --> 13:08:39,720 uh from what I've seen so far A lot of 20485 13:08:37,840 --> 13:08:41,480 times there's like a lot of nesting if 20486 13:08:39,720 --> 13:08:43,916 you do subar does it go one up is there 20487 13:08:41,480 --> 13:08:47,320 any situation where you know it's nested 20488 13:08:43,916 --> 13:08:49,000 in another class as well um above wizard 20489 13:08:47,320 --> 13:08:51,400 let's say a really good question if you 20490 13:08:49,000 --> 13:08:53,840 were to have a super super class so your 20491 13:08:51,400 --> 13:08:56,320 hierarchy is even taller than the two 20492 13:08:53,840 --> 13:08:58,480 levels of uh hierarchy that we currently 20493 13:08:56,320 --> 13:09:00,320 have absolutely but what's nice about 20494 13:08:58,480 --> 13:09:02,360 object-oriented Pro what's nice about 20495 13:09:00,320 --> 13:09:04,360 inheritance as the name implies is just 20496 13:09:02,360 --> 13:09:06,756 as you might have inherited certain 20497 13:09:04,360 --> 13:09:08,040 traits as a human from your grandfather 20498 13:09:06,756 --> 13:09:10,000 and Grand mother or your 20499 13:09:08,040 --> 13:09:12,436 great-grandfather or great-grandmother 20500 13:09:10,000 --> 13:09:14,200 some of those properties can actually uh 20501 13:09:12,436 --> 13:09:17,560 trickle down to you so to speak in the 20502 13:09:14,200 --> 13:09:20,680 context of code as well so when you 20503 13:09:17,560 --> 13:09:23,680 descend from another class that is when 20504 13:09:20,680 --> 13:09:25,840 you subclass a a super class or a super 20505 13:09:23,680 --> 13:09:27,480 super class you actually do inherit all 20506 13:09:25,840 --> 13:09:29,840 of the functionality not just from one 20507 13:09:27,480 --> 13:09:31,480 level above you but from two or three so 20508 13:09:29,840 --> 13:09:33,080 you can indeed access some of that 20509 13:09:31,480 --> 13:09:35,116 functionality as well and you can even 20510 13:09:33,080 --> 13:09:36,436 override it if you want some of these 20511 13:09:35,116 --> 13:09:39,560 classes to behave a little bit 20512 13:09:36,436 --> 13:09:42,040 differently than others other questions 20513 13:09:39,560 --> 13:09:43,720 on inheritance so it's kind of similar 20514 13:09:42,040 --> 13:09:46,880 to the last one but can you have like 20515 13:09:43,720 --> 13:09:48,880 two parents on the same level a really 20516 13:09:46,880 --> 13:09:51,956 good question so there are ways to 20517 13:09:48,880 --> 13:09:53,400 implement uh um descendants from 20518 13:09:51,956 --> 13:09:55,116 multiple parents and there's different 20519 13:09:53,400 --> 13:09:57,240 ways to do this not just in Python but 20520 13:09:55,116 --> 13:09:59,276 other languages we've kept things simple 20521 13:09:57,240 --> 13:10:01,720 here though by having a single uh 20522 13:09:59,276 --> 13:10:04,080 inheritance path a good question how 20523 13:10:01,720 --> 13:10:09,240 about one more question on inheritance 20524 13:10:04,080 --> 13:10:09,240 can we have multiple arguments in super 20525 13:10:09,436 --> 13:10:14,720 doubleit yes but in this case I'm only 20526 13:10:11,880 --> 13:10:17,680 passing in name on line 18 and I'm only 20527 13:10:14,720 --> 13:10:19,596 passing in name on line 10 why because 20528 13:10:17,680 --> 13:10:21,840 on line two when I Define the init 20529 13:10:19,596 --> 13:10:24,360 method for the wizard class I only 20530 13:10:21,840 --> 13:10:25,756 expect a single argument but I could 20531 13:10:24,360 --> 13:10:27,040 absolutely have under common 20532 13:10:25,756 --> 13:10:29,080 functionality like I could add in a 20533 13:10:27,040 --> 13:10:30,720 petronis if both students and professors 20534 13:10:29,080 --> 13:10:33,276 have patronises that can come out of 20535 13:10:30,720 --> 13:10:35,520 their wands I could have two arguments 20536 13:10:33,276 --> 13:10:37,000 instead we've been using this feature of 20537 13:10:35,520 --> 13:10:39,080 object-oriented programming now for 20538 13:10:37,000 --> 13:10:40,916 quite some time in the form of 20539 13:10:39,080 --> 13:10:42,956 exceptions indeed if you look at the 20540 13:10:40,916 --> 13:10:44,880 official documentation for exceptions in 20541 13:10:42,956 --> 13:10:46,680 Python you'll see that there's not even 20542 13:10:44,880 --> 13:10:48,680 the ones we've seen in class like value 20543 13:10:46,680 --> 13:10:51,116 error and others there's any number of 20544 13:10:48,680 --> 13:10:53,040 others as well but they are all 20545 13:10:51,116 --> 13:10:55,400 themselves hierarchical in nature this 20546 13:10:53,040 --> 13:10:57,320 is just a subset of the available 20547 13:10:55,400 --> 13:10:59,080 exceptions that come built into Python 20548 13:10:57,320 --> 13:11:01,276 and you can actually as a programmer 20549 13:10:59,080 --> 13:11:04,000 create your own exceptions as well but 20550 13:11:01,276 --> 13:11:06,480 as this chart here uh captures 20551 13:11:04,000 --> 13:11:09,240 hierarchically all exceptions we've seen 20552 13:11:06,480 --> 13:11:12,200 thus far actually descend from or 20553 13:11:09,240 --> 13:11:13,720 inherit from Super classes already so 20554 13:11:12,200 --> 13:11:15,400 for instance at the bottom of this list 20555 13:11:13,720 --> 13:11:17,596 here is value error which we've seen 20556 13:11:15,400 --> 13:11:19,796 quite a bit and if you follow the line 20557 13:11:17,596 --> 13:11:22,200 straight up on this asky rendition of 20558 13:11:19,796 --> 13:11:24,400 this chart you'll see that value error 20559 13:11:22,200 --> 13:11:26,200 has a parent class or super class called 20560 13:11:24,400 --> 13:11:28,276 exception and the exception class 20561 13:11:26,200 --> 13:11:30,436 meanwhile has a parent class called base 20562 13:11:28,276 --> 13:11:32,320 exception why did the authors of python 20563 13:11:30,436 --> 13:11:35,840 do this well it turns out that whether 20564 13:11:32,320 --> 13:11:37,756 you have a uh value error or a key error 20565 13:11:35,840 --> 13:11:40,240 or an assertion error or any number of 20566 13:11:37,756 --> 13:11:43,276 others there's a lot of functionality 20567 13:11:40,240 --> 13:11:46,080 common to all of those types of errors 20568 13:11:43,276 --> 13:11:48,596 that you want uh all that you want a 20569 13:11:46,080 --> 13:11:50,276 programmer to be able to use and so it 20570 13:11:48,596 --> 13:11:52,400 turns out that the authors of python 20571 13:11:50,276 --> 13:11:55,400 decided you know what let's not have a 20572 13:11:52,400 --> 13:11:57,240 dozen or more different classes that all 20573 13:11:55,400 --> 13:11:58,880 just have copy pasted similar 20574 13:11:57,240 --> 13:12:00,720 functionality let's create this 20575 13:11:58,880 --> 13:12:02,200 hierarchy so that even though the 20576 13:12:00,720 --> 13:12:04,480 exceptions toward the bottom of this 20577 13:12:02,200 --> 13:12:06,880 list are very precise they at least 20578 13:12:04,480 --> 13:12:09,240 inherit that is borrow some very common 20579 13:12:06,880 --> 13:12:11,240 fun fun ality up above so it turns out 20580 13:12:09,240 --> 13:12:13,560 that when you use the try and the accept 20581 13:12:11,240 --> 13:12:15,596 keyword in Python generally speaking 20582 13:12:13,560 --> 13:12:17,596 we've tried to catch very specific 20583 13:12:15,596 --> 13:12:19,916 exceptions like value error but 20584 13:12:17,596 --> 13:12:22,480 technically you could capture the parent 20585 13:12:19,916 --> 13:12:24,320 or even the grandparent exception for a 20586 13:12:22,480 --> 13:12:25,880 given exception especially if you're not 20587 13:12:24,320 --> 13:12:28,320 necessarily sure which one is going to 20588 13:12:25,880 --> 13:12:30,116 get raised or better yet there could be 20589 13:12:28,320 --> 13:12:32,080 many exceptions that get raised but you 20590 13:12:30,116 --> 13:12:33,796 want to handle them all the same and you 20591 13:12:32,080 --> 13:12:36,000 don't want to necessarily enumerate them 20592 13:12:33,796 --> 13:12:37,436 in parenthesis separated by commas you 20593 13:12:36,000 --> 13:12:39,916 want to say you want to handle all 20594 13:12:37,436 --> 13:12:42,080 exceptions of a certain super class in 20595 13:12:39,916 --> 13:12:43,720 much the same way so this has been 20596 13:12:42,080 --> 13:12:46,116 latent this whole time anytime we've 20597 13:12:43,720 --> 13:12:48,360 seen or used or caught or now raised 20598 13:12:46,116 --> 13:12:49,796 exceptions and built into python is this 20599 13:12:48,360 --> 13:12:51,880 hierarchy and if you were to invent your 20600 13:12:49,796 --> 13:12:53,320 own exception generally you wouldn't 20601 13:12:51,880 --> 13:12:55,796 want to start from scratch you would 20602 13:12:53,320 --> 13:12:57,880 want to descend from that is subclass 20603 13:12:55,796 --> 13:12:59,840 one of these existing exceptions and add 20604 13:12:57,880 --> 13:13:02,796 your own twist on it your own 20605 13:12:59,840 --> 13:13:04,480 functionality as well well there's one 20606 13:13:02,796 --> 13:13:06,240 final feature of object-oriented 20607 13:13:04,480 --> 13:13:08,596 programming that we'd like to share with 20608 13:13:06,240 --> 13:13:10,240 you today in that it will perhaps be 20609 13:13:08,596 --> 13:13:12,160 quite the eye opener is what you can 20610 13:13:10,240 --> 13:13:15,080 really do now that you have classes at 20611 13:13:12,160 --> 13:13:16,276 your disposal and this too surprise has 20612 13:13:15,080 --> 13:13:18,596 been a feature you and I have been 20613 13:13:16,276 --> 13:13:20,160 taking for granted for weeks now this 20614 13:13:18,596 --> 13:13:21,880 has just worked but it's been 20615 13:13:20,160 --> 13:13:24,240 implemented in a way that you can now 20616 13:13:21,880 --> 13:13:26,200 leverage yourself it turns out that 20617 13:13:24,240 --> 13:13:28,480 Python and some other languages too 20618 13:13:26,200 --> 13:13:30,756 support this notion of operator 20619 13:13:28,480 --> 13:13:34,000 overloading whereby you can take very 20620 13:13:30,756 --> 13:13:36,840 common symbols like plus or minus or 20621 13:13:34,000 --> 13:13:38,880 other such syntax on the on the keyboard 20622 13:13:36,840 --> 13:13:41,436 and you can Implement your own 20623 13:13:38,880 --> 13:13:44,596 interpretation thereof plus does not 20624 13:13:41,436 --> 13:13:46,400 have to equal addition and minus does 20625 13:13:44,596 --> 13:13:48,080 not have to equal subtraction and in 20626 13:13:46,400 --> 13:13:50,756 fact you and I have already seen another 20627 13:13:48,080 --> 13:13:54,320 context in which plus means something 20628 13:13:50,756 --> 13:13:57,880 else plus has not always in Python meant 20629 13:13:54,320 --> 13:14:00,480 addition per se what else has python 20630 13:13:57,880 --> 13:14:03,000 used Plus for concatenation for 20631 13:14:00,480 --> 13:14:05,436 concatenation for joining two strings 20632 13:14:03,000 --> 13:14:07,796 for adding to a list can you use plus as 20633 13:14:05,436 --> 13:14:10,116 well so plus has actually been funny 20634 13:14:07,796 --> 13:14:12,796 enough overloaded by the authors of 20635 13:14:10,116 --> 13:14:14,880 python for us and so we can use the same 20636 13:14:12,796 --> 13:14:16,436 symbol in much the same way as addition 20637 13:14:14,880 --> 13:14:18,796 but with different data types to solve 20638 13:14:16,436 --> 13:14:20,796 slightly different problems well let me 20639 13:14:18,796 --> 13:14:22,480 propose that we go back over to VSS code 20640 13:14:20,796 --> 13:14:25,596 here and let me go ahead and create a 20641 13:14:22,480 --> 13:14:28,276 new Final file called vault. py so code 20642 13:14:25,596 --> 13:14:31,436 of vault. py and let me propose that we 20643 13:14:28,276 --> 13:14:33,796 implement the idea of a vault at grots 20644 13:14:31,436 --> 13:14:35,796 keeping on theme wherein there's a bank 20645 13:14:33,796 --> 13:14:38,240 in the World of Harry Potter and within 20646 13:14:35,796 --> 13:14:40,756 this Bank uh family and individuals have 20647 13:14:38,240 --> 13:14:42,360 vaults containing all sorts of money in 20648 13:14:40,756 --> 13:14:44,000 The Wizarding World and the type of 20649 13:14:42,360 --> 13:14:46,200 money that exists in the World of Harry 20650 13:14:44,000 --> 13:14:48,240 Potter are coins called gallions and 20651 13:14:46,200 --> 13:14:50,596 sickles and canuts and those are in 20652 13:14:48,240 --> 13:14:52,116 descending order of value and so inside 20653 13:14:50,596 --> 13:14:54,480 of a vault might be a whole bunch of 20654 13:14:52,116 --> 13:14:56,916 coins gold silver and bronze essentially 20655 13:14:54,480 --> 13:14:59,240 each in those denominations tucked away 20656 13:14:56,916 --> 13:15:01,680 so how can I go about implementing first 20657 13:14:59,240 --> 13:15:03,880 of all the idea of a vault so that I can 20658 13:15:01,680 --> 13:15:06,680 store for instance for Harry Potter how 20659 13:15:03,880 --> 13:15:09,240 much uh coinage is in his family's Vault 20660 13:15:06,680 --> 13:15:11,400 or for Juan resley the same let me go 20661 13:15:09,240 --> 13:15:13,520 ahead in Vault up high and first create 20662 13:15:11,400 --> 13:15:15,756 a class called Vault essentially meant 20663 13:15:13,520 --> 13:15:17,880 to represent a bank vault perfect 20664 13:15:15,756 --> 13:15:19,840 another real world or fantasy world 20665 13:15:17,880 --> 13:15:22,400 entity that I want to represent with 20666 13:15:19,840 --> 13:15:23,796 code I could use a tupple or a list or a 20667 13:15:22,400 --> 13:15:26,116 dictionary but again I'm going to get a 20668 13:15:23,796 --> 13:15:28,276 lot more functionality with classes and 20669 13:15:26,116 --> 13:15:30,680 we'll see one final flourish with 20670 13:15:28,276 --> 13:15:32,320 operators inside of this Vault class 20671 13:15:30,680 --> 13:15:34,916 let's go ahead and do this let me Define 20672 13:15:32,320 --> 13:15:37,480 my init method taking its first argument 20673 13:15:34,916 --> 13:15:39,560 of self and let me Define uh three 20674 13:15:37,480 --> 13:15:42,160 arguments to this when you create a 20675 13:15:39,560 --> 13:15:43,720 vault in my code here I want to be able 20676 13:15:42,160 --> 13:15:45,480 to initialize it with some number of 20677 13:15:43,720 --> 13:15:47,160 gallions some number of sickles and some 20678 13:15:45,480 --> 13:15:49,400 number of conuts I want the use the 20679 13:15:47,160 --> 13:15:51,000 programmer to be able to pass in one or 20680 13:15:49,400 --> 13:15:52,276 more of those values ideally but they 20681 13:15:51,000 --> 13:15:54,596 can be optional so I'll give them 20682 13:15:52,276 --> 13:15:56,560 defaults so let's go ahead and Define a 20683 13:15:54,596 --> 13:15:58,796 parameter called gallions whose default 20684 13:15:56,560 --> 13:16:00,720 value will be zero sickles whose default 20685 13:15:58,796 --> 13:16:03,320 value will also be zero and canuts whose 20686 13:16:00,720 --> 13:16:05,880 default value will be zero as well so 20687 13:16:03,320 --> 13:16:07,560 the programmer can pass in one or two or 20688 13:16:05,880 --> 13:16:10,116 three or heck even none of those and 20689 13:16:07,560 --> 13:16:12,520 they'll all have some implied defaults 20690 13:16:10,116 --> 13:16:14,560 how do I want to remember those values 20691 13:16:12,520 --> 13:16:18,480 that are passed in well let me do this 20692 13:16:14,560 --> 13:16:22,040 self. gallion equals gallion and self. 20693 13:16:18,480 --> 13:16:25,400 sickles equals sickles and self. canuts 20694 13:16:22,040 --> 13:16:27,080 equals canuts and so I could add some 20695 13:16:25,400 --> 13:16:28,956 error checking especially if you don't 20696 13:16:27,080 --> 13:16:30,680 pass in a number I could turn these into 20697 13:16:28,956 --> 13:16:32,200 properties to do even more validation 20698 13:16:30,680 --> 13:16:34,240 but let's keep it simple and as always 20699 13:16:32,200 --> 13:16:35,756 Focus only on the new ideas so I'm just 20700 13:16:34,240 --> 13:16:37,000 going to trust that these values were 20701 13:16:35,756 --> 13:16:39,840 passed in and I'm going to immediately 20702 13:16:37,000 --> 13:16:41,956 assign them to these instance variables 20703 13:16:39,840 --> 13:16:45,160 what now do I want to do well let's come 20704 13:16:41,956 --> 13:16:47,480 up with a way of printing out what is in 20705 13:16:45,160 --> 13:16:49,720 someone's Vault ultimately but first 20706 13:16:47,480 --> 13:16:52,400 let's do this let's create a a vault for 20707 13:16:49,720 --> 13:16:54,400 The Potters by creating via assignment a 20708 13:16:52,400 --> 13:16:57,276 new Vault and let's say that the Potters 20709 13:16:54,400 --> 13:16:59,080 have 100 gallions 50 sickles and 24 20710 13:16:57,276 --> 13:17:00,720 canuts all right and that's in that 20711 13:16:59,080 --> 13:17:02,720 Vault and let's print out for instance 20712 13:17:00,720 --> 13:17:04,520 Potter all right let's run this code and 20713 13:17:02,720 --> 13:17:07,596 see how it works now let me go ahead and 20714 13:17:04,520 --> 13:17:10,200 run python a vault. pi enter 20715 13:17:07,596 --> 13:17:12,916 okay seems to work no syntax errors or 20716 13:17:10,200 --> 13:17:15,880 anything else but this is not very 20717 13:17:12,916 --> 13:17:18,560 enlightening how do I fix this thinking 20718 13:17:15,880 --> 13:17:21,436 back to what we've done before you have 20719 13:17:18,560 --> 13:17:23,116 to use the underscore underscore s 20720 13:17:21,436 --> 13:17:25,360 exactly I need to use one of those 20721 13:17:23,116 --> 13:17:27,840 special methods that comes with classes 20722 13:17:25,360 --> 13:17:29,916 and Define for myself how I want a vault 20723 13:17:27,840 --> 13:17:32,160 to be printed as a string so let me go 20724 13:17:29,916 --> 13:17:34,560 ahead and do that let me Define the stir 20725 13:17:32,160 --> 13:17:36,400 method taking in self as its sole 20726 13:17:34,560 --> 13:17:38,956 argument here and let's just return a 20727 13:17:36,400 --> 13:17:40,276 very simple string that just reveals 20728 13:17:38,956 --> 13:17:43,520 what's in the vault so I'm going to 20729 13:17:40,276 --> 13:17:46,360 return a formatted F string uh inside of 20730 13:17:43,520 --> 13:17:48,916 which is self. gallan and then the word 20731 13:17:46,360 --> 13:17:50,880 uh gallion so I know which those are uh 20732 13:17:48,916 --> 13:17:53,200 then let's do self. sickles and let's 20733 13:17:50,880 --> 13:17:55,276 output the word sickles and then lastly 20734 13:17:53,200 --> 13:17:58,080 let's output self. canuts and then 20735 13:17:55,276 --> 13:18:01,040 canuts here so I know in this string 20736 13:17:58,080 --> 13:18:03,560 just how many of each of those uh coins 20737 13:18:01,040 --> 13:18:05,680 I have in this particular family's Vault 20738 13:18:03,560 --> 13:18:08,116 all right let me go ahead and run python 20739 13:18:05,680 --> 13:18:10,840 of vault. changing nothing else except 20740 13:18:08,116 --> 13:18:13,000 the stir method and now we see indeed 20741 13:18:10,840 --> 13:18:15,560 that Harry has 100 gallions 50 sickles 20742 13:18:13,000 --> 13:18:17,360 and 25 canuts all right well let's do 20743 13:18:15,560 --> 13:18:20,000 one thing more here below that let's go 20744 13:18:17,360 --> 13:18:21,880 ahead and Define a Weasley variable and 20745 13:18:20,000 --> 13:18:23,680 Ron never seemed to have quite as much 20746 13:18:21,880 --> 13:18:25,640 uh money in the vault as did Harry so 20747 13:18:23,680 --> 13:18:28,000 let's say that the Weasley Vault will 20748 13:18:25,640 --> 13:18:30,040 have 25 50 and 100 so I'll just reverse 20749 13:18:28,000 --> 13:18:32,796 the order of those denominations uh 20750 13:18:30,040 --> 13:18:36,116 rather than Harry's 100 5025 and now let 20751 13:18:32,796 --> 13:18:38,116 me go ahead and print Weasley like this 20752 13:18:36,116 --> 13:18:40,720 and let's go ahead and clear my terminal 20753 13:18:38,116 --> 13:18:43,040 window run python of vault. this time 20754 13:18:40,720 --> 13:18:45,400 that stir method will be invoked twice 20755 13:18:43,040 --> 13:18:47,240 once for each of those Vault objects and 20756 13:18:45,400 --> 13:18:49,756 we'll see indeed that the first one for 20757 13:18:47,240 --> 13:18:53,680 Harry's got 50 and 25 respectively 20758 13:18:49,756 --> 13:18:55,436 versus Ron's 25 50 and 100 respectively 20759 13:18:53,680 --> 13:18:58,000 but now let's do something interesting 20760 13:18:55,436 --> 13:18:59,916 suppose that you wanted to combine the 20761 13:18:58,000 --> 13:19:02,360 contents of two vaults be it Harry's and 20762 13:18:59,916 --> 13:19:05,276 Ron's or any other two people how would 20763 13:19:02,360 --> 13:19:07,480 you go about doing this in code well if 20764 13:19:05,276 --> 13:19:09,796 I wanted to combine the vaults for 20765 13:19:07,480 --> 13:19:14,160 someone I could do this well I could do 20766 13:19:09,796 --> 13:19:17,436 gallion equals let's do potter. gallion 20767 13:19:14,160 --> 13:19:19,276 uh plus Weasley do gallion that gives me 20768 13:19:17,436 --> 13:19:22,360 a variable called gallion that has the 20769 13:19:19,276 --> 13:19:25,520 sum of Harry and Ron's gallion let's 20770 13:19:22,360 --> 13:19:27,480 next do sickles equals potter. sickles 20771 13:19:25,520 --> 13:19:30,360 plus Weasley do 20772 13:19:27,480 --> 13:19:34,360 sickles and then lastly let's do canuts 20773 13:19:30,360 --> 13:19:36,116 equals potter. canuts plus Weasley do 20774 13:19:34,360 --> 13:19:37,796 canuts I've got three variables what can 20775 13:19:36,116 --> 13:19:40,680 I now do with these values well let's 20776 13:19:37,796 --> 13:19:42,640 create a third a new Vault uh total will 20777 13:19:40,680 --> 13:19:45,320 be the name of this variable equals a 20778 13:19:42,640 --> 13:19:46,840 new Vault capital V notice and now let's 20779 13:19:45,320 --> 13:19:50,400 pass in those three new variables 20780 13:19:46,840 --> 13:19:52,680 gallions sickles and canuts and that's 20781 13:19:50,400 --> 13:19:54,400 it and let's print out this total Vault 20782 13:19:52,680 --> 13:19:56,916 so we should now see three vaults one 20783 13:19:54,400 --> 13:19:58,640 for Harry for Ron and the combination 20784 13:19:56,916 --> 13:20:01,000 the addition of the two let me go ahead 20785 13:19:58,640 --> 13:20:05,116 and rerun python of vaulty and there we 20786 13:20:01,000 --> 13:20:08,320 have it uh what was 10050 25 and 25 50 20787 13:20:05,116 --> 13:20:12,240 and 100 combined through addition now is 20788 13:20:08,320 --> 13:20:13,880 125 100 125 so pretty straightforward 20789 13:20:12,240 --> 13:20:15,756 using techniques from weeks ago where 20790 13:20:13,880 --> 13:20:18,436 we're just declaring a few new variables 20791 13:20:15,756 --> 13:20:20,560 and doing some addition but wouldn't it 20792 13:20:18,436 --> 13:20:22,796 be cool if I could do something like 20793 13:20:20,560 --> 13:20:25,320 this wouldn't it be cool if I could just 20794 13:20:22,796 --> 13:20:27,596 somehow not manually create my own Vault 20795 13:20:25,320 --> 13:20:29,880 and do all of this annoying math up here 20796 13:20:27,596 --> 13:20:32,596 what if I could just do Potter plus 20797 13:20:29,880 --> 13:20:35,240 Weasley and get rid of all of this logic 20798 13:20:32,596 --> 13:20:39,040 here like wouldn't it be nice if I 20799 13:20:35,240 --> 13:20:41,680 overload the operator no we know as plus 20800 13:20:39,040 --> 13:20:44,956 just like stir does just like list does 20801 13:20:41,680 --> 13:20:47,756 to allow me to add two vaults together 20802 13:20:44,956 --> 13:20:50,360 on the left and the right well it turns 20803 13:20:47,756 --> 13:20:53,240 out in Python and through operator 20804 13:20:50,360 --> 13:20:55,320 overla there is a way to do just this if 20805 13:20:53,240 --> 13:20:57,720 you consult the documentation there are 20806 13:20:55,320 --> 13:21:00,160 there's this and so many other special 20807 13:20:57,720 --> 13:21:02,880 methods that come with classes the third 20808 13:21:00,160 --> 13:21:05,560 one we see here is this one here 20809 13:21:02,880 --> 13:21:07,276 underscore uncore add underscore 20810 13:21:05,560 --> 13:21:08,596 underscore and you see that it very 20811 13:21:07,276 --> 13:21:10,756 generically is described in the 20812 13:21:08,596 --> 13:21:12,880 documentation as working for any object 20813 13:21:10,756 --> 13:21:14,680 be it a vault or a stir or a list or 20814 13:21:12,880 --> 13:21:16,436 something else by convention it's going 20815 13:21:14,680 --> 13:21:17,596 to take a first argument called self and 20816 13:21:16,436 --> 13:21:20,840 then it's going to take some other 20817 13:21:17,596 --> 13:21:22,640 argument by convention called Other Self 20818 13:21:20,840 --> 13:21:24,596 in effect is going to be referring to 20819 13:21:22,640 --> 13:21:26,720 whatever object is on the left of a plus 20820 13:21:24,596 --> 13:21:28,520 sign other is going to be referring to 20821 13:21:26,720 --> 13:21:30,840 whatever is on the right hand side of a 20822 13:21:28,520 --> 13:21:33,520 plus sign thereby giving us a way of 20823 13:21:30,840 --> 13:21:35,720 describing in code the operand on the 20824 13:21:33,520 --> 13:21:39,240 left and the operand on the right of the 20825 13:21:35,720 --> 13:21:41,160 operator Plus in between that is to say 20826 13:21:39,240 --> 13:21:44,276 if I go back to vs code here what I'm 20827 13:21:41,160 --> 13:21:46,756 trying to do is Implement support for 20828 13:21:44,276 --> 13:21:49,560 this well let me try without writing any 20829 13:21:46,756 --> 13:21:52,880 other code just yet python a vault up 20830 13:21:49,560 --> 13:21:56,680 high enter type error unsupported 20831 13:21:52,880 --> 13:21:59,080 operand types for Vault and Vault that 20832 13:21:56,680 --> 13:22:01,240 is to say python at this moment does not 20833 13:21:59,080 --> 13:22:02,880 know what it means to add two vaults 20834 13:22:01,240 --> 13:22:04,560 together right you and I might have an 20835 13:22:02,880 --> 13:22:06,956 instinct probably want to combine the 20836 13:22:04,560 --> 13:22:08,956 gallions and the sickles and the canuts 20837 13:22:06,956 --> 13:22:10,360 respectively python doesn't know that it 20838 13:22:08,956 --> 13:22:12,520 just knows that you have a new class 20839 13:22:10,360 --> 13:22:15,080 called Vault but let's teach python to 20840 13:22:12,520 --> 13:22:16,596 do this let me clear my terminal window 20841 13:22:15,080 --> 13:22:18,916 let me scroll back up to the class 20842 13:22:16,596 --> 13:22:21,520 itself where at the moment I only have 20843 13:22:18,916 --> 13:22:23,720 two special methods in it and stir but 20844 13:22:21,520 --> 13:22:25,240 let's add this third all right let me go 20845 13:22:23,720 --> 13:22:28,200 into the class here and Define 20846 13:22:25,240 --> 13:22:30,840 underscore uncore addcore underscore and 20847 13:22:28,200 --> 13:22:32,916 then specify its first parameter as self 20848 13:22:30,840 --> 13:22:34,560 as before and then a second parameter 20849 13:22:32,916 --> 13:22:36,640 for this particular method called by 20850 13:22:34,560 --> 13:22:38,000 convention other now as always I could 20851 13:22:36,640 --> 13:22:39,276 name those parameters anything I want 20852 13:22:38,000 --> 13:22:41,720 but I'm going to stick with convention 20853 13:22:39,276 --> 13:22:43,640 Here and Now inside of this method am I 20854 13:22:41,720 --> 13:22:45,840 going to have to now add together the 20855 13:22:43,640 --> 13:22:47,400 contents of two vaults well what two 20856 13:22:45,840 --> 13:22:49,360 vaults well if we scroll down to our 20857 13:22:47,400 --> 13:22:51,040 goal at hand the goal of course is to 20858 13:22:49,360 --> 13:22:53,560 add this Vault plus this other Vault 20859 13:22:51,040 --> 13:22:55,436 Potter plus Weasley respectively well it 20860 13:22:53,560 --> 13:22:57,720 turns out in Python that when you do 20861 13:22:55,436 --> 13:22:59,596 overload an operator like Plus what's 20862 13:22:57,720 --> 13:23:01,596 going to happen automatically as soon as 20863 13:22:59,596 --> 13:23:03,560 python sees that is it's going to call 20864 13:23:01,596 --> 13:23:05,520 that underscore underscore ad underscore 20865 13:23:03,560 --> 13:23:07,640 underscore method and it's going to pass 20866 13:23:05,520 --> 13:23:10,000 into it to our arguments whatever the 20867 13:23:07,640 --> 13:23:12,160 operand is on the left Potter in this 20868 13:23:10,000 --> 13:23:14,400 case and whatever the operand is on the 20869 13:23:12,160 --> 13:23:16,080 right Weasley in this case and those 20870 13:23:14,400 --> 13:23:18,880 values are going to get passed in as 20871 13:23:16,080 --> 13:23:20,320 self and other respectively what that 20872 13:23:18,880 --> 13:23:22,080 means is that we can access their 20873 13:23:20,320 --> 13:23:23,916 contents up here in our implementation 20874 13:23:22,080 --> 13:23:26,400 of AD as follows let me go ahead and 20875 13:23:23,916 --> 13:23:28,276 Define a local variable called gallion 20876 13:23:26,400 --> 13:23:31,640 and set that equal to for instance the 20877 13:23:28,276 --> 13:23:33,680 sum of self. gallions whatever's in uh 20878 13:23:31,640 --> 13:23:35,520 Potter's vault in this case plus 20879 13:23:33,680 --> 13:23:38,040 whatever is in Weasley's vault in this 20880 13:23:35,520 --> 13:23:41,276 case which would be other do gallion let 20881 13:23:38,040 --> 13:23:43,840 me do the same for sickles self. sickles 20882 13:23:41,276 --> 13:23:47,360 plus other do sickles and let me lastly 20883 13:23:43,840 --> 13:23:49,956 do that for canuts so self. canuts plus 20884 13:23:47,360 --> 13:23:51,916 other. canuts but at the end of the day 20885 13:23:49,956 --> 13:23:53,916 I'm going to need to return a brand new 20886 13:23:51,916 --> 13:23:56,200 bigger Vault that contains all of those 20887 13:23:53,916 --> 13:23:58,520 contents together and if we ultimately 20888 13:23:56,200 --> 13:24:01,080 want to assign that bigger Vault to a 20889 13:23:58,520 --> 13:24:03,116 variable like total here on the left we 20890 13:24:01,080 --> 13:24:04,880 better indeed return a value from this 20891 13:24:03,116 --> 13:24:06,956 ad method so I'm going to go ahead and 20892 13:24:04,880 --> 13:24:09,240 give myself a brand new vault as by 20893 13:24:06,956 --> 13:24:11,560 returning Capital vault which of course 20894 13:24:09,240 --> 13:24:13,400 is going to call My Vault function into 20895 13:24:11,560 --> 13:24:15,320 which I can now pass some of those 20896 13:24:13,400 --> 13:24:16,796 initialization arguments well how many 20897 13:24:15,320 --> 13:24:19,000 gallion sickles and canuts do I want 20898 13:24:16,796 --> 13:24:21,520 this brand new Vault to contain well I 20899 13:24:19,000 --> 13:24:24,320 want it to contain this many gallions 20900 13:24:21,520 --> 13:24:25,916 this many sickles and this many canuts 20901 13:24:24,320 --> 13:24:28,240 so ultimately what we're doing in this 20902 13:24:25,916 --> 13:24:30,680 implementation of ad is adding together 20903 13:24:28,240 --> 13:24:32,240 those gallion sickles and canuts passing 20904 13:24:30,680 --> 13:24:34,640 them to the Vault function so that we 20905 13:24:32,240 --> 13:24:37,796 get a brand new bigger Vault and return 20906 13:24:34,640 --> 13:24:40,160 that all together so now I've defined 20907 13:24:37,796 --> 13:24:43,840 this new special method called add that 20908 13:24:40,160 --> 13:24:46,160 should now just make Plus work for two 20909 13:24:43,840 --> 13:24:48,040 vaults all right let's see let me run 20910 13:24:46,160 --> 13:24:51,040 down to my terminal window python a 20911 13:24:48,040 --> 13:24:53,680 vault up high and hit enter and voila 20912 13:24:51,040 --> 13:24:56,160 now we've implemented an overloaded 20913 13:24:53,680 --> 13:24:57,796 operator plus to do what you and I as 20914 13:24:56,160 --> 13:25:00,040 humans would hope would be the case when 20915 13:24:57,796 --> 13:25:02,116 you add two vaults together but I've now 20916 13:25:00,040 --> 13:25:05,640 written the code more specifically to 20917 13:25:02,116 --> 13:25:08,040 teach python what it means concretely to 20918 13:25:05,640 --> 13:25:09,956 add two vaults together and it's with 20919 13:25:08,040 --> 13:25:11,796 very similar code in effect underneath 20920 13:25:09,956 --> 13:25:13,880 the hood that python is doing this for 20921 13:25:11,796 --> 13:25:16,276 two strings to concatenate them together 20922 13:25:13,880 --> 13:25:19,880 to joining to lists into a new list with 20923 13:25:16,276 --> 13:25:22,596 lists and so many other classes as well 20924 13:25:19,880 --> 13:25:25,400 any questions now on operator 20925 13:25:22,596 --> 13:25:27,916 overloading or this example here how 20926 13:25:25,400 --> 13:25:33,000 would you go about creating a function 20927 13:25:27,916 --> 13:25:35,436 for adding a student and a vault for two 20928 13:25:33,000 --> 13:25:36,796 two separate classes how would that be 20929 13:25:35,436 --> 13:25:38,240 possible 20930 13:25:36,796 --> 13:25:40,240 let me see what happens here I don't 20931 13:25:38,240 --> 13:25:41,756 know off hand let's do this let's create 20932 13:25:40,240 --> 13:25:44,956 a stir and see what happens if I add 20933 13:25:41,756 --> 13:25:46,596 Potter plus a stir stir object yeah okay 20934 13:25:44,956 --> 13:25:48,880 so it would work I'm just figuring this 20935 13:25:46,596 --> 13:25:50,160 out as I go here Eric so just to re be 20936 13:25:48,880 --> 13:25:51,880 clear what I did was I just changed 20937 13:25:50,160 --> 13:25:55,080 Weasley to stir just to see what would 20938 13:25:51,880 --> 13:25:57,916 happen when I add a vault plus a stir 20939 13:25:55,080 --> 13:26:00,956 and it will work theoretically why 20940 13:25:57,916 --> 13:26:04,640 because so long as the type of value on 20941 13:26:00,956 --> 13:26:07,480 the left has an add method implemented 20942 13:26:04,640 --> 13:26:09,480 other can be any type that you want you 20943 13:26:07,480 --> 13:26:11,200 just have to decide and code what it's 20944 13:26:09,480 --> 13:26:13,200 going to mean conceptually to add a 20945 13:26:11,200 --> 13:26:15,320 vault plus a string which in this case 20946 13:26:13,200 --> 13:26:16,880 probably doesn't make any sense at all 20947 13:26:15,320 --> 13:26:18,956 but it's possible it's going to be the 20948 13:26:16,880 --> 13:26:20,436 operand on the left and I'm inferring 20949 13:26:18,956 --> 13:26:22,320 that I did not know the answer a moment 20950 13:26:20,436 --> 13:26:25,116 ago I'm inferring that because what I 20951 13:26:22,320 --> 13:26:27,956 got was an attribute error here on line 20952 13:26:25,116 --> 13:26:30,596 11 because python did not like this 20953 13:26:27,956 --> 13:26:32,680 other gallion didn't work but I could 20954 13:26:30,596 --> 13:26:34,276 make it work by figuring something out 20955 13:26:32,680 --> 13:26:36,720 really good question didn't know that 20956 13:26:34,276 --> 13:26:39,680 one myself other questions on 20957 13:26:36,720 --> 13:26:42,520 operator overloading can you define new 20958 13:26:39,680 --> 13:26:45,756 operators in Python I don't think so 20959 13:26:42,520 --> 13:26:48,320 there is a very long but precise list of 20960 13:26:45,756 --> 13:26:50,840 operators that you can overload I do not 20961 13:26:48,320 --> 13:26:53,436 believe you can assign arbitrary 20962 13:26:50,840 --> 13:26:55,160 characters to be operators in Python uh 20963 13:26:53,436 --> 13:26:56,436 let me defer to Carter in the chat to 20964 13:26:55,160 --> 13:26:58,360 revoke okay I'm seeing two of my 20965 13:26:56,436 --> 13:26:59,720 colleagues are saying no not possible so 20966 13:26:58,360 --> 13:27:01,560 I'm going to go with my first instinct 20967 13:26:59,720 --> 13:27:03,756 no otherwise that'd be kind of cool you 20968 13:27:01,560 --> 13:27:05,640 could make Emoji do whatever you want to 20969 13:27:03,756 --> 13:27:06,880 how about one final question on operator 20970 13:27:05,640 --> 13:27:09,560 overloading 20971 13:27:06,880 --> 13:27:11,916 is that the only operation you can do uh 20972 13:27:09,560 --> 13:27:14,560 is a far as like can you do a 20973 13:27:11,916 --> 13:27:17,040 subtraction as well you can you can do 20974 13:27:14,560 --> 13:27:19,880 so many others let me um if Carter you 20975 13:27:17,040 --> 13:27:21,720 don't mind pulling up this URL here so 20976 13:27:19,880 --> 13:27:24,200 this link here special method names in 20977 13:27:21,720 --> 13:27:25,520 today's slides you'll see a long list of 20978 13:27:24,200 --> 13:27:27,480 all of The Operators that you can 20979 13:27:25,520 --> 13:27:29,840 overload you can do less than equals 20980 13:27:27,480 --> 13:27:31,720 than plus equals minus equals pretty 20981 13:27:29,840 --> 13:27:33,360 much any symbol you've seen me type on 20982 13:27:31,720 --> 13:27:35,116 the screen can be overloaded in the 20983 13:27:33,360 --> 13:27:38,116 context of 20984 13:27:35,116 --> 13:27:40,116 classes so even though today we focused 20985 13:27:38,116 --> 13:27:41,200 entirely on object-oriented programming 20986 13:27:40,116 --> 13:27:43,000 this is a technique that we've been 20987 13:27:41,200 --> 13:27:44,916 using really since the first week of the 20988 13:27:43,000 --> 13:27:47,480 class because indeed those ins those 20989 13:27:44,916 --> 13:27:49,200 stirs those floats those lists those 20990 13:27:47,480 --> 13:27:50,756 dictionaries and so much more were 20991 13:27:49,200 --> 13:27:53,480 already underneath the hood this whole 20992 13:27:50,756 --> 13:27:55,040 time classes and objects thereof but you 20993 13:27:53,480 --> 13:27:56,956 now as a programmer have the ability to 20994 13:27:55,040 --> 13:27:58,680 create your own classes with your own 20995 13:27:56,956 --> 13:28:00,640 instance or class variables with your 20996 13:27:58,680 --> 13:28:03,116 own instance or class methods with your 20997 13:28:00,640 --> 13:28:05,276 own properties and even with your own 20998 13:28:03,116 --> 13:28:07,480 custom behavior for operators so 20999 13:28:05,276 --> 13:28:10,320 ultimately you can absolutely continue 21000 13:28:07,480 --> 13:28:12,200 using those simple tles or lists or 21001 13:28:10,320 --> 13:28:14,276 those dictionaries or other structures 21002 13:28:12,200 --> 13:28:15,796 as well but object-oriented programming 21003 13:28:14,276 --> 13:28:17,520 and with it classes and now these 21004 13:28:15,796 --> 13:28:19,680 objects is just another tool in your 21005 13:28:17,520 --> 13:28:21,796 toolkit and dare say as your code gets 21006 13:28:19,680 --> 13:28:23,596 more sophisticated and your problems get 21007 13:28:21,796 --> 13:28:25,680 bigger you'll find that being able to 21008 13:28:23,596 --> 13:28:28,200 model these real world or even fantasy 21009 13:28:25,680 --> 13:28:30,200 world entities with classes and related 21010 13:28:28,200 --> 13:28:32,000 data and functionality will ultimately 21011 13:28:30,200 --> 13:28:34,880 just allow you to Define code that's not 21012 13:28:32,000 --> 13:28:39,596 just correct but ever well designed as 21013 13:28:34,880 --> 13:28:39,596 well this was cs50 21014 13:28:47,370 --> 13:28:57,220 [Music] 21015 13:28:59,240 --> 13:29:06,109 [Music] 21016 13:29:08,360 --> 13:29:13,520 all right this is cs50's Introduction to 21017 13:29:11,400 --> 13:29:15,560 programming with python my name is David 21018 13:29:13,520 --> 13:29:17,720 me and over these past many weeks have 21019 13:29:15,560 --> 13:29:20,080 we focused on functions and variables 21020 13:29:17,720 --> 13:29:22,596 early on then conditionals and loops and 21021 13:29:20,080 --> 13:29:24,640 exceptions a bit of libraries unit tests 21022 13:29:22,596 --> 13:29:26,796 file AO regular Expressions 21023 13:29:24,640 --> 13:29:28,880 object-oriented programming and really 21024 13:29:26,796 --> 13:29:31,320 Etc and indeed that's where we focus 21025 13:29:28,880 --> 13:29:32,756 today is on all the more that you can do 21026 13:29:31,320 --> 13:29:34,480 with python and programming more 21027 13:29:32,756 --> 13:29:36,720 generally Beyond some of those 21028 13:29:34,480 --> 13:29:37,840 fundamental concepts as well in fact if 21029 13:29:36,720 --> 13:29:39,796 you start to flip through the 21030 13:29:37,840 --> 13:29:41,436 documentation for python in all of its 21031 13:29:39,796 --> 13:29:43,680 form all of which is as always 21032 13:29:41,436 --> 13:29:45,520 accessible at docs. python.org you'll 21033 13:29:43,680 --> 13:29:48,520 see additional documentation on Python's 21034 13:29:45,520 --> 13:29:50,480 own tutorial in library uh its reference 21035 13:29:48,520 --> 13:29:52,596 it's how to and among all of those 21036 13:29:50,480 --> 13:29:54,480 various documents as well as others more 21037 13:29:52,596 --> 13:29:56,596 online you'll see that there's some 21038 13:29:54,480 --> 13:29:58,640 tidbits that we didn't quite touch on 21039 13:29:56,596 --> 13:30:00,360 and indeed even though we themed these 21040 13:29:58,640 --> 13:30:02,680 past several weeks of around fairly 21041 13:30:00,360 --> 13:30:04,840 broad topics that are rather essential 21042 13:30:02,680 --> 13:30:07,080 for doing typical types of problems in 21043 13:30:04,840 --> 13:30:08,796 Python it turns there's quite a number 21044 13:30:07,080 --> 13:30:10,400 of other features as well that we didn't 21045 13:30:08,796 --> 13:30:12,200 necessarily touch on that didn't 21046 13:30:10,400 --> 13:30:14,560 necessarily fit within any of those 21047 13:30:12,200 --> 13:30:16,240 overarching Concepts or might have been 21048 13:30:14,560 --> 13:30:18,116 a little too much too soon if we did 21049 13:30:16,240 --> 13:30:20,640 them too early on in the course and so 21050 13:30:18,116 --> 13:30:22,240 in today our final lecture will be Focus 21051 13:30:20,640 --> 13:30:23,796 really on all the more that you can do 21052 13:30:22,240 --> 13:30:25,796 with python and hopefully wet your 21053 13:30:23,796 --> 13:30:28,520 appetite for teaching yourself all the 21054 13:30:25,796 --> 13:30:30,200 more too for instance among Python's 21055 13:30:28,520 --> 13:30:31,720 various data types there's this other 21056 13:30:30,200 --> 13:30:34,400 one that we haven't had occasion to yet 21057 13:30:31,720 --> 13:30:36,276 use namely a set in mathematics a set is 21058 13:30:34,400 --> 13:30:38,160 typically a collection of values wherein 21059 13:30:36,276 --> 13:30:40,000 there are no duplicates so it's not 21060 13:30:38,160 --> 13:30:42,436 quite a list it's a bit more special 21061 13:30:40,000 --> 13:30:44,720 than that in that somehow any duplicates 21062 13:30:42,436 --> 13:30:46,880 are eliminated for you well it turns out 21063 13:30:44,720 --> 13:30:49,116 within python this is an actual data 21064 13:30:46,880 --> 13:30:51,916 type that you yourself can use in your 21065 13:30:49,116 --> 13:30:53,640 code and via the documentation here 21066 13:30:51,916 --> 13:30:55,480 might you be able to glean that it's a 21067 13:30:53,640 --> 13:30:57,596 useful problem if you want to somehow 21068 13:30:55,480 --> 13:30:59,680 automatically filter out duplicates so 21069 13:30:57,596 --> 13:31:02,080 let me go ahead and go over to VSS code 21070 13:30:59,680 --> 13:31:04,116 here and let me go ahead and show you a 21071 13:31:02,080 --> 13:31:06,320 file that I created a bit of in advance 21072 13:31:04,116 --> 13:31:09,400 whereby we have a file here called 21073 13:31:06,320 --> 13:31:12,080 houses. and in houses. I already went 21074 13:31:09,400 --> 13:31:14,400 ahead and whipped up a big uh list of 21075 13:31:12,080 --> 13:31:16,436 students inside of which is a number of 21076 13:31:14,400 --> 13:31:19,200 dictionaries Each of which represents a 21077 13:31:16,436 --> 13:31:20,840 student's name and house respectively 21078 13:31:19,200 --> 13:31:22,880 now this is a pretty sizable dictionary 21079 13:31:20,840 --> 13:31:24,880 and so it lends itself to iteration over 21080 13:31:22,880 --> 13:31:26,956 the same and suppose that the goal here 21081 13:31:24,880 --> 13:31:29,520 was quite simply to figure out well what 21082 13:31:26,956 --> 13:31:31,480 are the unique houses at Hogwarts in the 21083 13:31:29,520 --> 13:31:32,880 World of Harry Potter it would be nice 21084 13:31:31,480 --> 13:31:34,720 perhaps to not have to know these kinds 21085 13:31:32,880 --> 13:31:36,560 of details or look them up online here 21086 13:31:34,720 --> 13:31:38,560 we have a set of stud students albeit 21087 13:31:36,560 --> 13:31:40,200 not exhaustive with all of the houses 21088 13:31:38,560 --> 13:31:42,596 but among these students here what are 21089 13:31:40,200 --> 13:31:44,000 the unique houses in which they live 21090 13:31:42,596 --> 13:31:45,796 well I could certainly as a human just 21091 13:31:44,000 --> 13:31:47,956 eyeball this and tell you that it's well 21092 13:31:45,796 --> 13:31:49,080 Gryffindor Slither and Ravenclaw but how 21093 13:31:47,956 --> 13:31:50,720 could we go about doing it 21094 13:31:49,080 --> 13:31:52,840 programmatically for these students as 21095 13:31:50,720 --> 13:31:55,796 well well let's take one approach first 21096 13:31:52,840 --> 13:31:57,880 here let me go into houses. and let me 21097 13:31:55,796 --> 13:32:00,916 propose that we first how about create 21098 13:31:57,880 --> 13:32:03,596 an empty list called houses in which I'm 21099 13:32:00,916 --> 13:32:06,436 going to accumulate each of the houses 21100 13:32:03,596 --> 13:32:09,240 uniquely so every time I iterate through 21101 13:32:06,436 --> 13:32:11,520 this uh list of dictionaries I'm only 21102 13:32:09,240 --> 13:32:13,200 going to add a house to this list if I 21103 13:32:11,520 --> 13:32:15,160 haven't seen it before so how do I 21104 13:32:13,200 --> 13:32:17,560 express that well let me iterate over 21105 13:32:15,160 --> 13:32:19,596 all of the students with for student in 21106 13:32:17,560 --> 13:32:22,080 students as we've done in the past and 21107 13:32:19,596 --> 13:32:25,040 let me ask a question now so if the 21108 13:32:22,080 --> 13:32:27,640 current student's house and notice that 21109 13:32:25,040 --> 13:32:29,520 I'm indexing into the current student 21110 13:32:27,640 --> 13:32:33,000 because I know they are a dictionary or 21111 13:32:29,520 --> 13:32:37,276 dict object and if that student's house 21112 13:32:33,000 --> 13:32:40,756 is not in my houses list then indented 21113 13:32:37,276 --> 13:32:42,840 am I going to say houses. append because 21114 13:32:40,756 --> 13:32:46,200 again houses is a list and I'm going to 21115 13:32:42,840 --> 13:32:47,840 append that particular house to the list 21116 13:32:46,200 --> 13:32:49,400 then at the very bottom here let me go 21117 13:32:47,840 --> 13:32:51,240 ahead and do something somewhat 21118 13:32:49,400 --> 13:32:54,240 interesting here and say for each of the 21119 13:32:51,240 --> 13:32:56,480 houses that I've accumulated in I could 21120 13:32:54,240 --> 13:32:57,956 just say houses but if I just say houses 21121 13:32:56,480 --> 13:32:59,520 what was the point of accumulating them 21122 13:32:57,956 --> 13:33:01,200 all all at once I could just do this 21123 13:32:59,520 --> 13:33:03,720 whole thing in a loop let's at least go 21124 13:33:01,200 --> 13:33:05,756 about and sort those houses with sorted 21125 13:33:03,720 --> 13:33:07,520 which is going to sort the strings Al 21126 13:33:05,756 --> 13:33:09,796 alphabetically and let's go ahead there 21127 13:33:07,520 --> 13:33:11,240 in and print each of the houses let me 21128 13:33:09,796 --> 13:33:13,880 go ahead now in my terminal window and 21129 13:33:11,240 --> 13:33:15,680 run python of houses. and hit enter and 21130 13:33:13,880 --> 13:33:18,520 there we have it Gryffindor Ravenclaw 21131 13:33:15,680 --> 13:33:20,680 Slytherin in alphabetical order even 21132 13:33:18,520 --> 13:33:22,680 though in the list of dictionaries up 21133 13:33:20,680 --> 13:33:24,840 here technically the order in which we 21134 13:33:22,680 --> 13:33:27,880 saw these with was Gryffindor Gryffindor 21135 13:33:24,840 --> 13:33:29,756 Gryffindor slitherin Ravenclaw so indeed 21136 13:33:27,880 --> 13:33:32,080 my code seems to have sorted them 21137 13:33:29,756 --> 13:33:34,720 properly so this is perfectly fine and 21138 13:33:32,080 --> 13:33:36,640 it's one way of solving this problem but 21139 13:33:34,720 --> 13:33:39,200 it turns out we could would use more 21140 13:33:36,640 --> 13:33:41,000 that's built into the language python to 21141 13:33:39,200 --> 13:33:43,040 solve this problem ourself here I'm 21142 13:33:41,000 --> 13:33:45,276 rather Reinventing a wheel really the 21143 13:33:43,040 --> 13:33:47,160 notion of a set wherein duplicates are 21144 13:33:45,276 --> 13:33:49,080 eliminated for me so let me go ahead and 21145 13:33:47,160 --> 13:33:51,480 clear my terminal window and perhaps 21146 13:33:49,080 --> 13:33:53,240 change the type of object I'm using here 21147 13:33:51,480 --> 13:33:54,796 instead of a list which could also be 21148 13:33:53,240 --> 13:33:57,000 written like this to create an empty 21149 13:33:54,796 --> 13:34:00,116 list let me go ahead and create an empty 21150 13:33:57,000 --> 13:34:01,840 set whereby I call a function called set 21151 13:34:00,116 --> 13:34:03,520 that's going to return to me some object 21152 13:34:01,840 --> 13:34:05,880 in Python that represents this notion of 21153 13:34:03,520 --> 13:34:08,116 a set wherein duplicates are automatic 21154 13:34:05,880 --> 13:34:10,276 eliminated and now I can tighten up my 21155 13:34:08,116 --> 13:34:12,400 code because I don't have to use this if 21156 13:34:10,276 --> 13:34:14,596 condition myself I think I can just do 21157 13:34:12,400 --> 13:34:17,640 something like this inside of my Loop 21158 13:34:14,596 --> 13:34:20,276 let me do houses. add so it's not a pend 21159 13:34:17,640 --> 13:34:23,480 for a set it's a pen for a list but it's 21160 13:34:20,276 --> 13:34:25,040 add to a set per the documentation then 21161 13:34:23,480 --> 13:34:27,480 let me go ahead and add this current 21162 13:34:25,040 --> 13:34:29,680 student's house and now I think the rest 21163 13:34:27,480 --> 13:34:31,720 of my code can be the same I'm just now 21164 13:34:29,680 --> 13:34:33,956 trusting per the documentation for set 21165 13:34:31,720 --> 13:34:36,320 in Python that it's going to filter out 21166 13:34:33,956 --> 13:34:38,640 duplicates for me and I can just blind 21167 13:34:36,320 --> 13:34:40,880 add add add add all of these houses to 21168 13:34:38,640 --> 13:34:44,560 the set and any duplicates already there 21169 13:34:40,880 --> 13:34:46,400 will be gone python of houses. and enter 21170 13:34:44,560 --> 13:34:48,796 and voila we're back in business with 21171 13:34:46,400 --> 13:34:50,040 just those three there as well let me 21172 13:34:48,796 --> 13:34:52,720 pause here to see if there's any 21173 13:34:50,040 --> 13:34:54,596 questions now on this use of set which 21174 13:34:52,720 --> 13:34:56,240 is just another data type that's 21175 13:34:54,596 --> 13:34:58,320 available to you another class in the 21176 13:34:56,240 --> 13:35:00,956 world of python that you can reach for 21177 13:34:58,320 --> 13:35:03,596 when solving some problem like this how 21178 13:35:00,956 --> 13:35:06,436 can we locate an item in a set for 21179 13:35:03,596 --> 13:35:08,796 example find Griffin door in the oh how 21180 13:35:06,436 --> 13:35:11,000 do you find an item in a set you can use 21181 13:35:08,796 --> 13:35:14,640 very similar syntax as we've done for a 21182 13:35:11,000 --> 13:35:19,040 list before you can use syntax like if 21183 13:35:14,640 --> 13:35:20,880 Gryffindor in houses then and you can 21184 13:35:19,040 --> 13:35:23,640 answer a question along those lines so 21185 13:35:20,880 --> 13:35:26,240 you can use in and not in and similar 21186 13:35:23,640 --> 13:35:28,796 functions as well other questions on set 21187 13:35:26,240 --> 13:35:30,640 okay what happens if you have a similar 21188 13:35:28,796 --> 13:35:33,560 house name let's say instead of 21189 13:35:30,640 --> 13:35:36,480 slithering it is maybe an O instead of 21190 13:35:33,560 --> 13:35:39,796 an I will the fall Loop look throughout 21191 13:35:36,480 --> 13:35:43,360 each of those um letters in the house 21192 13:35:39,796 --> 13:35:45,520 name uh it would compare the string so 21193 13:35:43,360 --> 13:35:47,040 if Slytherin appears more than once but 21194 13:35:45,520 --> 13:35:49,080 is slightly misspelled or misc 21195 13:35:47,040 --> 13:35:52,276 capitalized if I heard you right those 21196 13:35:49,080 --> 13:35:54,360 would appear to be distinct string so 21197 13:35:52,276 --> 13:35:56,400 you would get both versions of Slytherin 21198 13:35:54,360 --> 13:35:58,520 in the result however we've seen in the 21199 13:35:56,400 --> 13:36:00,560 past how we can clean up users data if 21200 13:35:58,520 --> 13:36:02,240 indeed it might be messy we could force 21201 13:36:00,560 --> 13:36:04,720 everything to uppercase or everything to 21202 13:36:02,240 --> 13:36:07,276 lowercase or we could use capitalize the 21203 13:36:04,720 --> 13:36:08,640 function built into stirs or title case 21204 13:36:07,276 --> 13:36:10,720 that would handle some of the cleanup 21205 13:36:08,640 --> 13:36:12,840 for us in this case because the data is 21206 13:36:10,720 --> 13:36:14,840 not coming from humans using the input 21207 13:36:12,840 --> 13:36:16,916 function I wrote the code in advance 21208 13:36:14,840 --> 13:36:18,596 it's safer to assume that I got the 21209 13:36:16,916 --> 13:36:21,240 houses right but that's absolutely a 21210 13:36:18,596 --> 13:36:22,956 risk if it's coming from users allow me 21211 13:36:21,240 --> 13:36:24,276 to turn our attention back to some of 21212 13:36:22,956 --> 13:36:26,000 the other features here that we can 21213 13:36:24,276 --> 13:36:28,080 leverage in Python if we dig further 21214 13:36:26,000 --> 13:36:30,400 into the documentation and read up more 21215 13:36:28,080 --> 13:36:33,040 on its features well in some language 21216 13:36:30,400 --> 13:36:35,040 there's this notion of global variables 21217 13:36:33,040 --> 13:36:37,276 whereby you can define a variable that's 21218 13:36:35,040 --> 13:36:40,320 either local to a function as we've seen 21219 13:36:37,276 --> 13:36:42,680 many times or if you put a variable 21220 13:36:40,320 --> 13:36:44,560 outside of all of your functions perhaps 21221 13:36:42,680 --> 13:36:46,560 near the top of your file that would 21222 13:36:44,560 --> 13:36:48,720 generally be considered a global 21223 13:36:46,560 --> 13:36:50,400 variable or in the world of python it 21224 13:36:48,720 --> 13:36:51,956 might be specific to the module but for 21225 13:36:50,400 --> 13:36:54,160 all intents and purposes it's going to 21226 13:36:51,956 --> 13:36:56,400 behave for a given program as though it 21227 13:36:54,160 --> 13:36:58,040 is global however it turns out that if 21228 13:36:56,400 --> 13:37:00,116 you do this when solving some problem 21229 13:36:58,040 --> 13:37:01,880 down the line whereby you have multiple 21230 13:37:00,116 --> 13:37:03,796 functions and you do have one or more 21231 13:37:01,880 --> 13:37:06,640 variables that are outside of those 21232 13:37:03,796 --> 13:37:09,720 functions you might not be able to 21233 13:37:06,640 --> 13:37:11,796 change those variables as easily as you 21234 13:37:09,720 --> 13:37:13,796 might think so indeed let me go back to 21235 13:37:11,796 --> 13:37:15,720 vs code here and in just a moment I'm 21236 13:37:13,796 --> 13:37:17,400 going to go ahead and create a new file 21237 13:37:15,720 --> 13:37:19,560 how about called 21238 13:37:17,400 --> 13:37:21,160 bank.pay let's go ahead and implement 21239 13:37:19,560 --> 13:37:24,276 the notion of a bank wherein we can 21240 13:37:21,160 --> 13:37:26,480 store things like uh money in various 21241 13:37:24,276 --> 13:37:28,000 forms and let me go ahead and do this 21242 13:37:26,480 --> 13:37:29,916 let me go ahead and Implement a very 21243 13:37:28,000 --> 13:37:31,880 simple bank that simply keeps track of 21244 13:37:29,916 --> 13:37:33,680 my total balance the number of dollars 21245 13:37:31,880 --> 13:37:34,916 or cents or whatever I might be storing 21246 13:37:33,680 --> 13:37:36,720 in this bank and I'm going to give 21247 13:37:34,916 --> 13:37:39,200 myself a very iable called balance at 21248 13:37:36,720 --> 13:37:41,360 the top which is an integer a set to 21249 13:37:39,200 --> 13:37:43,320 zero now let me go ahead and Define a 21250 13:37:41,360 --> 13:37:44,956 main function as we often do and inside 21251 13:37:43,320 --> 13:37:47,200 of my main function let me go ahead and 21252 13:37:44,956 --> 13:37:49,240 print out quote unquote balance and then 21253 13:37:47,200 --> 13:37:51,480 print out the value of balance itself 21254 13:37:49,240 --> 13:37:53,880 passing to print as we've often done 21255 13:37:51,480 --> 13:37:56,756 more than one argument so that they get 21256 13:37:53,880 --> 13:37:58,400 uh separated by a single white space And 21257 13:37:56,756 --> 13:37:59,880 now since I have a main function really 21258 13:37:58,400 --> 13:38:01,916 setting the stage for doing more 21259 13:37:59,880 --> 13:38:04,320 interesting things soon let me go ahead 21260 13:38:01,916 --> 13:38:06,480 and do our usual if the name of this 21261 13:38:04,320 --> 13:38:09,756 file equals equals underscore uncore 21262 13:38:06,480 --> 13:38:12,040 main then go ahead and call Main so this 21263 13:38:09,756 --> 13:38:13,680 is a terribly short program but it's 21264 13:38:12,040 --> 13:38:15,560 perhaps representative of how you might 21265 13:38:13,680 --> 13:38:17,276 solve some future problem in Python 21266 13:38:15,560 --> 13:38:19,116 whereby you have a main function that's 21267 13:38:17,276 --> 13:38:21,040 going to eventually do some interesting 21268 13:38:19,116 --> 13:38:22,880 stuff and at the top of your file you 21269 13:38:21,040 --> 13:38:24,276 have one or more variables that are just 21270 13:38:22,880 --> 13:38:26,240 useful to keep there because then you 21271 13:38:24,276 --> 13:38:28,720 know where they are and perhaps not just 21272 13:38:26,240 --> 13:38:31,116 main but other functions can access them 21273 13:38:28,720 --> 13:38:34,400 as well so let's see when I run this 21274 13:38:31,116 --> 13:38:36,596 program python of bank.pay I would hope 21275 13:38:34,400 --> 13:38:38,240 based on my own in thus far then I'm 21276 13:38:36,596 --> 13:38:40,360 going to see that my current balance is 21277 13:38:38,240 --> 13:38:43,840 zero that is to say even though the 21278 13:38:40,360 --> 13:38:45,880 balance variable is defined on line one 21279 13:38:43,840 --> 13:38:48,840 hopefully I can still print it on line 21280 13:38:45,880 --> 13:38:51,200 five inside of main even though balance 21281 13:38:48,840 --> 13:38:54,040 was not defined in my main function here 21282 13:38:51,200 --> 13:38:56,480 we go hitting enter and voila balance 21283 13:38:54,040 --> 13:38:58,640 zero so it does seem to work even if you 21284 13:38:56,480 --> 13:39:00,880 declare a variable in Python outside of 21285 13:38:58,640 --> 13:39:03,160 your functions it appears that you can 21286 13:39:00,880 --> 13:39:05,956 access it you can read the value of that 21287 13:39:03,160 --> 13:39:07,916 variable even inside of a function like 21288 13:39:05,956 --> 13:39:09,560 Maine well let's get a little more 21289 13:39:07,916 --> 13:39:11,276 adventurous now because this program 21290 13:39:09,560 --> 13:39:12,840 really isn't solving anyone's problems 21291 13:39:11,276 --> 13:39:15,040 let's go ahead and Implement more of a 21292 13:39:12,840 --> 13:39:17,116 bank like the ability to deposit money 21293 13:39:15,040 --> 13:39:18,520 into the bank and to withdraw money from 21294 13:39:17,116 --> 13:39:20,360 the bank thereby giving me some more 21295 13:39:18,520 --> 13:39:22,276 functions that might very well need to 21296 13:39:20,360 --> 13:39:24,360 access that same variable Let Me Clear 21297 13:39:22,276 --> 13:39:26,796 My terminal window here and let me go 21298 13:39:24,360 --> 13:39:30,520 ahead and pretend for the moment that I 21299 13:39:26,796 --> 13:39:32,520 have the ability to deposit say $100 or 21300 13:39:30,520 --> 13:39:34,480 100 coins whatever the unit of currency 21301 13:39:32,520 --> 13:39:37,560 is here and then maybe I want to 21302 13:39:34,480 --> 13:39:39,796 withdraw straight away 50 of those same 21303 13:39:37,560 --> 13:39:41,720 dollars or coins and now let me go ahead 21304 13:39:39,796 --> 13:39:43,916 and just print out at the bottom of main 21305 13:39:41,720 --> 13:39:47,520 what my new balance should be so that in 21306 13:39:43,916 --> 13:39:50,520 an Ideal World once I've deposited 100 21307 13:39:47,520 --> 13:39:52,520 then withdrawn 50 after starting at zero 21308 13:39:50,520 --> 13:39:55,956 I'd like to think that my new balance on 21309 13:39:52,520 --> 13:39:57,400 line 8 should indeed be 50 all right but 21310 13:39:55,956 --> 13:39:58,840 I haven't implemented these functions 21311 13:39:57,400 --> 13:40:00,680 yet so let's do that as we've done in 21312 13:39:58,840 --> 13:40:02,756 the past down here I'm going to go ahead 21313 13:40:00,680 --> 13:40:04,400 and Define another function deposit I'm 21314 13:40:02,756 --> 13:40:06,956 going to say that it takes an argument 21315 13:40:04,400 --> 13:40:08,796 called n for number of coins or dollars 21316 13:40:06,956 --> 13:40:10,200 or the like and I'm just going to do 21317 13:40:08,796 --> 13:40:13,080 this I'm going to go ahead and say 21318 13:40:10,200 --> 13:40:14,796 balance plus equals n thereby changing 21319 13:40:13,080 --> 13:40:17,680 the value of N I could do it more 21320 13:40:14,796 --> 13:40:19,116 verbosely balance equals balance plus n 21321 13:40:17,680 --> 13:40:21,480 but I'm going to use the shorter hand 21322 13:40:19,116 --> 13:40:23,680 notation here instead and now let's 21323 13:40:21,480 --> 13:40:25,640 Implement withdraw so Define a function 21324 13:40:23,680 --> 13:40:28,320 called withdraw it to is going to take a 21325 13:40:25,640 --> 13:40:30,160 variable uh an argument n for number of 21326 13:40:28,320 --> 13:40:32,796 dollars or coins and now I'm going to go 21327 13:40:30,160 --> 13:40:35,956 ahead and subtract from balance using 21328 13:40:32,796 --> 13:40:37,840 minus equals uh n as well and I'm still 21329 13:40:35,956 --> 13:40:40,436 going to call Main if the name of this 21330 13:40:37,840 --> 13:40:42,720 file is main so what have I done I've 21331 13:40:40,436 --> 13:40:45,276 just added not just one but three 21332 13:40:42,720 --> 13:40:49,040 functions total all of which apparently 21333 13:40:45,276 --> 13:40:51,480 need to access balance by uh printing it 21334 13:40:49,040 --> 13:40:53,436 incrementing it or decrementing it as 21335 13:40:51,480 --> 13:40:55,240 we've seen here all right let me go 21336 13:40:53,436 --> 13:40:56,680 ahead and focus on these three functions 21337 13:40:55,240 --> 13:40:58,880 here let me go back to my terminal 21338 13:40:56,680 --> 13:41:02,240 window and run python of bank.pay and 21339 13:40:58,880 --> 13:41:04,956 hit enter and wow seems like we've 21340 13:41:02,240 --> 13:41:08,520 introduced some number of problems here 21341 13:41:04,956 --> 13:41:10,956 and what are these problems well Unbound 21342 13:41:08,520 --> 13:41:13,520 local error is perhaps the first time 21343 13:41:10,956 --> 13:41:16,796 we've seen this one here local variable 21344 13:41:13,520 --> 13:41:18,720 balance rep referenced before assignment 21345 13:41:16,796 --> 13:41:20,956 and that's a bit misleading definitely 21346 13:41:18,720 --> 13:41:24,080 confusing right because I absolutely 21347 13:41:20,956 --> 13:41:25,956 assigned balance of value on the top of 21348 13:41:24,080 --> 13:41:27,840 my code and indeed if I scroll back up 21349 13:41:25,956 --> 13:41:29,520 nothing has changed or been lost up 21350 13:41:27,840 --> 13:41:32,240 there it's definitely been assigned a 21351 13:41:29,520 --> 13:41:34,080 value and now on line uh 12 it would 21352 13:41:32,240 --> 13:41:36,400 seem that when deposit is called I'm 21353 13:41:34,080 --> 13:41:40,040 just trying to access that variable 21354 13:41:36,400 --> 13:41:43,520 again so intuitively what might explain 21355 13:41:40,040 --> 13:41:45,360 this error message Unbound local error 21356 13:41:43,520 --> 13:41:47,596 what is python telling us there that 21357 13:41:45,360 --> 13:41:50,200 python can or can't do when it comes to 21358 13:41:47,596 --> 13:41:53,560 these so-called Global variables that 21359 13:41:50,200 --> 13:41:56,320 are at the top of my file uh so if you 21360 13:41:53,560 --> 13:42:00,200 want to change this V variable you 21361 13:41:56,320 --> 13:42:03,480 should uh write in inside the function 21362 13:42:00,200 --> 13:42:06,200 Main and the global variable 21363 13:42:03,480 --> 13:42:08,160 unchangeable yeah so 21364 13:42:06,200 --> 13:42:10,596 if you want to change the value it might 21365 13:42:08,160 --> 13:42:12,840 need to be local to the function if you 21366 13:42:10,596 --> 13:42:15,080 are trying to change a global variable 21367 13:42:12,840 --> 13:42:17,160 though in a function it clearly does not 21368 13:42:15,080 --> 13:42:19,000 work so it's okay to read a global 21369 13:42:17,160 --> 13:42:20,840 variable read meaning access it and 21370 13:42:19,000 --> 13:42:22,956 print it and so forth but apparently you 21371 13:42:20,840 --> 13:42:24,956 can't write to a global variable in the 21372 13:42:22,956 --> 13:42:27,000 same way from within one of these 21373 13:42:24,956 --> 13:42:28,520 functions all right well maybe the fix 21374 13:42:27,000 --> 13:42:30,560 is to do this let me clear my terminal 21375 13:42:28,520 --> 13:42:32,240 window in that error and maybe I could 21376 13:42:30,560 --> 13:42:33,756 just do this let's get rid of the global 21377 13:42:32,240 --> 13:42:35,680 variable and let's go ahead and put it 21378 13:42:33,756 --> 13:42:38,840 for instance inside of 21379 13:42:35,680 --> 13:42:42,276 main might this now work well let me try 21380 13:42:38,840 --> 13:42:44,956 this now python of bank.pay 21381 13:42:42,276 --> 13:42:47,796 enter that alone did not solve it I 21382 13:42:44,956 --> 13:42:50,756 still have an Unbound local error this 21383 13:42:47,796 --> 13:42:54,436 time though it's for a different reason 21384 13:42:50,756 --> 13:42:57,240 it turns out now that balance on line 21385 13:42:54,436 --> 13:42:59,116 two is by definition a local variable a 21386 13:42:57,240 --> 13:43:00,840 local variable is one that exists in the 21387 13:42:59,116 --> 13:43:03,116 context of a function at least in this 21388 13:43:00,840 --> 13:43:04,640 case a global variable is the opposite 21389 13:43:03,116 --> 13:43:07,320 one that does not for instance at the 21390 13:43:04,640 --> 13:43:09,240 top of my file so here is another 21391 13:43:07,320 --> 13:43:11,956 distinction in Python if you declare a 21392 13:43:09,240 --> 13:43:13,916 variable in a function like main just as 21393 13:43:11,956 --> 13:43:16,480 I've done on line two with balance it is 21394 13:43:13,916 --> 13:43:19,360 indeed local to that function deposit 21395 13:43:16,480 --> 13:43:21,520 and withdraw do not have access to that 21396 13:43:19,360 --> 13:43:23,360 same variable why because it's local to 21397 13:43:21,520 --> 13:43:25,200 Main and so you would think now we're 21398 13:43:23,360 --> 13:43:27,400 kind of stuck in this vicious cycle well 21399 13:43:25,200 --> 13:43:30,320 maybe the solution then is to move uh 21400 13:43:27,400 --> 13:43:32,040 balance globally so all three functions 21401 13:43:30,320 --> 13:43:34,360 can access it but clearly where we began 21402 13:43:32,040 --> 13:43:36,560 as oena noted we can't therefore change 21403 13:43:34,360 --> 13:43:39,000 it so what turns out the solution to 21404 13:43:36,560 --> 13:43:41,520 this problem in Python is ironically 21405 13:43:39,000 --> 13:43:42,720 exactly this keyword here it's a little 21406 13:43:41,520 --> 13:43:44,480 different as you might have seen if you 21407 13:43:42,720 --> 13:43:46,240 programed before in other languages but 21408 13:43:44,480 --> 13:43:48,680 there's indeed a keyword in Python 21409 13:43:46,240 --> 13:43:50,880 called Global that allows you to tell a 21410 13:43:48,680 --> 13:43:53,116 function that hey this is not a variable 21411 13:43:50,880 --> 13:43:55,400 that's local to you I mean it to be a 21412 13:43:53,116 --> 13:43:57,116 global variable that I want you to edit 21413 13:43:55,400 --> 13:43:58,796 so if I go back to VSS code here 21414 13:43:57,116 --> 13:44:00,796 clearing my terminal window to get rid 21415 13:43:58,796 --> 13:44:02,756 of that error let me go ahead and undo 21416 13:44:00,796 --> 13:44:05,116 the change I just made and put balance 21417 13:44:02,756 --> 13:44:07,040 back at the top of my file but this time 21418 13:44:05,116 --> 13:44:10,640 time what I'm going to do is I'm going 21419 13:44:07,040 --> 13:44:13,436 to inform my two functions that need to 21420 13:44:10,640 --> 13:44:16,880 change the value of balance that it is 21421 13:44:13,436 --> 13:44:19,756 indeed Global by typing Global balance 21422 13:44:16,880 --> 13:44:22,200 again here as well as here Global 21423 13:44:19,756 --> 13:44:24,400 balance I still leave the same lines of 21424 13:44:22,200 --> 13:44:26,560 code now on lines 13 and 18 that 21425 13:44:24,400 --> 13:44:29,200 increment and decrement balance but this 21426 13:44:26,560 --> 13:44:31,596 now use of keyword Global is a little 21427 13:44:29,200 --> 13:44:33,240 bit of a clue to python that oh okay 21428 13:44:31,596 --> 13:44:35,160 it's not a local variable this is not a 21429 13:44:33,240 --> 13:44:38,200 bug that you've introduced you mean for 21430 13:44:35,160 --> 13:44:39,756 to edit this variable up above so now 21431 13:44:38,200 --> 13:44:42,520 let me go ahead in my terminal window 21432 13:44:39,756 --> 13:44:45,880 and run python of bank.pay I'm hoping to 21433 13:44:42,520 --> 13:44:49,200 see that my balance is 0 + 100 minus 50 21434 13:44:45,880 --> 13:44:51,480 is 50 and indeed it now is it starts off 21435 13:44:49,200 --> 13:44:55,240 at zero per my first print statement on 21436 13:44:51,480 --> 13:44:57,640 line five but it ends up at 50 total at 21437 13:44:55,240 --> 13:44:59,276 below that on line eight let me pause 21438 13:44:57,640 --> 13:45:02,240 here to see if now there's any questions 21439 13:44:59,276 --> 13:45:05,560 on these Global or local variables what 21440 13:45:02,240 --> 13:45:08,680 happens when you declare a variable 21441 13:45:05,560 --> 13:45:10,840 globally and as in the same variable 21442 13:45:08,680 --> 13:45:11,916 globally and in a function a good 21443 13:45:10,840 --> 13:45:14,240 question you're always thinking about 21444 13:45:11,916 --> 13:45:16,360 the so-called Corner cases so if you 21445 13:45:14,240 --> 13:45:18,000 declare a variable both globally like at 21446 13:45:16,360 --> 13:45:20,640 the top of your file and then an 21447 13:45:18,000 --> 13:45:23,840 identically named variable inside of a 21448 13:45:20,640 --> 13:45:26,116 function same name the ladder Will 21449 13:45:23,840 --> 13:45:28,796 Shadow so to speak the former that is 21450 13:45:26,116 --> 13:45:31,116 you'll be able to use the ladder that is 21451 13:45:28,796 --> 13:45:32,956 the local variable but it will have no 21452 13:45:31,116 --> 13:45:35,320 effect on the global variable 21453 13:45:32,956 --> 13:45:38,160 temporarily python will only know that 21454 13:45:35,320 --> 13:45:40,400 the local variable exists so in general 21455 13:45:38,160 --> 13:45:42,116 the rule of thumb is just don't do that 21456 13:45:40,400 --> 13:45:43,916 not only might it create bugs in your 21457 13:45:42,116 --> 13:45:46,276 code because you don't quite change what 21458 13:45:43,916 --> 13:45:49,040 you intend to change it's also perhaps 21459 13:45:46,276 --> 13:45:51,640 uh nonobvious to other readers as well 21460 13:45:49,040 --> 13:45:53,756 other questions on globals or locals 21461 13:45:51,640 --> 13:45:55,956 okay what if we decide to add balance as 21462 13:45:53,756 --> 13:45:57,756 an argument inside the main function 21463 13:45:55,956 --> 13:46:00,040 yeah another good Instinct but in this 21464 13:45:57,756 --> 13:46:02,796 case that also is not going to solve the 21465 13:46:00,040 --> 13:46:04,596 problem because if you pass in a 21466 13:46:02,796 --> 13:46:06,560 variable like balance to each of the 21467 13:46:04,596 --> 13:46:08,436 function functions and then change it 21468 13:46:06,560 --> 13:46:10,480 within that function it's only going to 21469 13:46:08,436 --> 13:46:12,240 be changing in effect a local copy 21470 13:46:10,480 --> 13:46:14,840 thereof it's not going to be changing 21471 13:46:12,240 --> 13:46:16,560 what's outside of those functions so I 21472 13:46:14,840 --> 13:46:18,596 think we actually need a better way 21473 13:46:16,560 --> 13:46:20,796 altogether and in fact allow me to 21474 13:46:18,596 --> 13:46:23,276 transition to perhaps a modification of 21475 13:46:20,796 --> 13:46:24,880 this same program recall that we looked 21476 13:46:23,276 --> 13:46:27,480 most recently at this notion of 21477 13:46:24,880 --> 13:46:29,756 objectoriented programming whereby you 21478 13:46:27,480 --> 13:46:32,720 can model real world entities for 21479 13:46:29,756 --> 13:46:35,360 instance a bank and you can model and 21480 13:46:32,720 --> 13:46:37,436 encapsulate information about that real 21481 13:46:35,360 --> 13:46:39,640 world entity for instance like someone's 21482 13:46:37,436 --> 13:46:41,400 account balance so let me propose that 21483 13:46:39,640 --> 13:46:43,436 we actually do this let me start from 21484 13:46:41,400 --> 13:46:45,756 scratch with bank.pay get rid of the 21485 13:46:43,436 --> 13:46:48,240 global variable Al together and actually 21486 13:46:45,756 --> 13:46:50,320 use some objectoriented code let me 21487 13:46:48,240 --> 13:46:52,796 define a class called account to 21488 13:46:50,320 --> 13:46:55,240 represent someone's bank account and 21489 13:46:52,796 --> 13:46:58,480 then let me go ahead and initialize with 21490 13:46:55,240 --> 13:47:00,320 my init method which again takes by 21491 13:46:58,480 --> 13:47:02,796 convention at least one argument called 21492 13:47:00,320 --> 13:47:05,560 self let me go ahead and initialize 21493 13:47:02,796 --> 13:47:07,796 every person's bank account to some 21494 13:47:05,560 --> 13:47:09,756 value like zero now how can I do that 21495 13:47:07,796 --> 13:47:12,720 well I'm going to go ahead and do self. 21496 13:47:09,756 --> 13:47:15,000 balance equals 0 thereby giving me an 21497 13:47:12,720 --> 13:47:17,160 instance variable called balance 21498 13:47:15,000 --> 13:47:19,000 initialized for this account to zero but 21499 13:47:17,160 --> 13:47:20,520 I'm going to proactively remember how we 21500 13:47:19,000 --> 13:47:22,680 also introduced this notion of 21501 13:47:20,520 --> 13:47:24,720 properties which might otherwise collide 21502 13:47:22,680 --> 13:47:26,436 with the names of my instance variables 21503 13:47:24,720 --> 13:47:28,360 so just by convention I'm going to do 21504 13:47:26,436 --> 13:47:30,480 this I'm going to rename this instance 21505 13:47:28,360 --> 13:47:32,436 variable proactively to underscore 21506 13:47:30,480 --> 13:47:34,200 balance to effectively indicate that 21507 13:47:32,436 --> 13:47:36,240 it's private even though that's not 21508 13:47:34,200 --> 13:47:38,360 enforced by python it's just a visual 21509 13:47:36,240 --> 13:47:41,000 clue to myself that this is something 21510 13:47:38,360 --> 13:47:43,276 that really I should not or other code 21511 13:47:41,000 --> 13:47:45,320 should not touch just functions in this 21512 13:47:43,276 --> 13:47:47,040 class now let me go ahead and do this 21513 13:47:45,320 --> 13:47:49,276 let me go ahead and Define an actual 21514 13:47:47,040 --> 13:47:51,276 function called balance that really is 21515 13:47:49,276 --> 13:47:54,720 going to be a property whose purpose in 21516 13:47:51,276 --> 13:47:56,436 life is just to return self. balance and 21517 13:47:54,720 --> 13:47:59,680 I'm going to go explicitly and say this 21518 13:47:56,436 --> 13:48:01,276 is indeed a property of this class now 21519 13:47:59,680 --> 13:48:03,640 let me go ahead and reimplement those 21520 13:48:01,276 --> 13:48:05,956 other two functions deposit and withdraw 21521 13:48:03,640 --> 13:48:09,116 but in the confines of this class so I'm 21522 13:48:05,956 --> 13:48:10,956 going to say Define uh deposit it's 21523 13:48:09,116 --> 13:48:13,400 going to take in an argument self as 21524 13:48:10,956 --> 13:48:15,756 always but an additional One n a number 21525 13:48:13,400 --> 13:48:17,276 of dollars or coins to deposit and how 21526 13:48:15,756 --> 13:48:21,640 do I now manipulate this well I'm going 21527 13:48:17,276 --> 13:48:23,640 to do self doore balance plus equals n 21528 13:48:21,640 --> 13:48:27,160 and now down here I'm going to do def 21529 13:48:23,640 --> 13:48:29,596 withdraw self n just like for deposit 21530 13:48:27,160 --> 13:48:32,880 but here I'm going to do self. balance 21531 13:48:29,596 --> 13:48:34,640 minus equals n and now if I go down 21532 13:48:32,880 --> 13:48:36,480 below this class I'm going to go ahead 21533 13:48:34,640 --> 13:48:38,560 and and Define myself a main function 21534 13:48:36,480 --> 13:48:41,040 just so I can try this now out I'm going 21535 13:48:38,560 --> 13:48:43,796 to go ahead and create an account object 21536 13:48:41,040 --> 13:48:45,400 by calling the account Constructor that 21537 13:48:43,796 --> 13:48:47,040 is the name of the class with two 21538 13:48:45,400 --> 13:48:49,000 parentheses if I'm not passing in any 21539 13:48:47,040 --> 13:48:50,916 arguments to in it I'm going to go ahead 21540 13:48:49,000 --> 13:48:52,840 now and print out as before the balance 21541 13:48:50,916 --> 13:48:55,596 of my account but to do that I'm going 21542 13:48:52,840 --> 13:48:57,680 to access the property of that account 21543 13:48:55,596 --> 13:49:00,400 like this and I'm going to go ahead now 21544 13:48:57,680 --> 13:49:03,116 and say deposit another $100 or coins 21545 13:49:00,400 --> 13:49:05,240 with deposit 100 and I'm going to go 21546 13:49:03,116 --> 13:49:07,680 ahead like before and also now 21547 13:49:05,240 --> 13:49:09,756 immediately withdraw for whatever reason 21548 13:49:07,680 --> 13:49:12,680 50 of the same and now I'm going to 21549 13:49:09,756 --> 13:49:14,880 print One Last Time balance followed by 21550 13:49:12,680 --> 13:49:16,480 account. balance again accessing that 21551 13:49:14,880 --> 13:49:18,240 property and for this whole thing to 21552 13:49:16,480 --> 13:49:21,560 work of course I need one of these if 21553 13:49:18,240 --> 13:49:24,040 name equals equals uncore main then go 21554 13:49:21,560 --> 13:49:25,756 ahead and call Main now before I run 21555 13:49:24,040 --> 13:49:27,596 this you'll see that it rather escalated 21556 13:49:25,756 --> 13:49:29,720 quickly I had a very simple goal at hand 21557 13:49:27,596 --> 13:49:32,160 to implement the notion of a bank and I 21558 13:49:29,720 --> 13:49:34,880 was able to implement that perfectly 21559 13:49:32,160 --> 13:49:36,956 fine ultimately by declaring balance to 21560 13:49:34,880 --> 13:49:39,200 be Global but then to tell each of my 21561 13:49:36,956 --> 13:49:41,116 functions that it is indeed Global but 21562 13:49:39,200 --> 13:49:43,040 that's not really the best form of 21563 13:49:41,116 --> 13:49:44,796 encapsulation we have at our disposal 21564 13:49:43,040 --> 13:49:46,200 now right per our focus on 21565 13:49:44,796 --> 13:49:47,756 object-oriented programming if we're 21566 13:49:46,200 --> 13:49:50,200 trying to implement some real world 21567 13:49:47,756 --> 13:49:51,880 entity like an account at a bank that's 21568 13:49:50,200 --> 13:49:53,560 what classes allow us to do and it 21569 13:49:51,880 --> 13:49:55,680 allows us to solve that same problem 21570 13:49:53,560 --> 13:49:57,080 perhaps a little more cleanly certainly 21571 13:49:55,680 --> 13:49:59,916 if we're going to accumulate more and 21572 13:49:57,080 --> 13:50:01,680 more functions or methods over time so 21573 13:49:59,916 --> 13:50:04,796 if I didn't make any mistakes here if I 21574 13:50:01,680 --> 13:50:07,756 run python of bank.pay and hit enter now 21575 13:50:04,796 --> 13:50:09,796 you'll see that it just works just fine 21576 13:50:07,756 --> 13:50:11,880 because in the world of classes in 21577 13:50:09,796 --> 13:50:14,240 Python these so-called instance 21578 13:50:11,880 --> 13:50:17,360 variables are by definition accessible 21579 13:50:14,240 --> 13:50:20,000 to all of the methods in that class 21580 13:50:17,360 --> 13:50:23,640 because we're accessing them all by way 21581 13:50:20,000 --> 13:50:25,520 of that special parameter self so which 21582 13:50:23,640 --> 13:50:27,796 way to do it for a reasonably small 21583 13:50:25,520 --> 13:50:30,160 script wherein you are simply trying to 21584 13:50:27,796 --> 13:50:32,520 implement uh a script that has some 21585 13:50:30,160 --> 13:50:33,916 Global uh information like an account 21586 13:50:32,520 --> 13:50:35,680 balance that you then need to manipulate 21587 13:50:33,916 --> 13:50:37,756 elsewhere the the global keyword is a 21588 13:50:35,680 --> 13:50:40,320 solution to that problem but generally 21589 13:50:37,756 --> 13:50:42,160 speaking in many languages python to 21590 13:50:40,320 --> 13:50:44,720 some extent among them using Global 21591 13:50:42,160 --> 13:50:47,000 variables tends to be frowned upon only 21592 13:50:44,720 --> 13:50:49,276 because things can get messy quickly and 21593 13:50:47,000 --> 13:50:51,756 it be can become less obvious quickly 21594 13:50:49,276 --> 13:50:53,360 exactly where your information is stored 21595 13:50:51,756 --> 13:50:55,596 if some of it's up here some of it's in 21596 13:50:53,360 --> 13:50:58,116 your function so generally the rule of 21597 13:50:55,596 --> 13:51:00,480 thumb is to use Global variables 21598 13:50:58,116 --> 13:51:02,480 sparingly though technically speaking in 21599 13:51:00,480 --> 13:51:04,840 Python these Global variables are 21600 13:51:02,480 --> 13:51:06,596 technically local to our module if we 21601 13:51:04,840 --> 13:51:09,200 were indeed implementing a library and 21602 13:51:06,596 --> 13:51:11,080 not just a program so in short try to 21603 13:51:09,200 --> 13:51:13,360 use Global variables sparingly but when 21604 13:51:11,080 --> 13:51:17,080 you do there is a solution to these same 21605 13:51:13,360 --> 13:51:19,956 problems questions now on globals or our 21606 13:51:17,080 --> 13:51:22,756 reimplementation of the same idea but 21607 13:51:19,956 --> 13:51:25,560 using full-fledged objectoriented 21608 13:51:22,756 --> 13:51:29,040 programming uh I just uh would like to 21609 13:51:25,560 --> 13:51:30,680 ask uh what this property does what this 21610 13:51:29,040 --> 13:51:32,640 property does so if I go back to VSS 21611 13:51:30,680 --> 13:51:34,680 code here you'll see that this was a 21612 13:51:32,640 --> 13:51:36,720 Technique we looked at in our lecture on 21613 13:51:34,680 --> 13:51:40,116 object-oriented programming whereby a 21614 13:51:36,720 --> 13:51:42,240 property is a instance variable that's 21615 13:51:40,116 --> 13:51:45,480 somehow protected it allows me to 21616 13:51:42,240 --> 13:51:47,480 control how it can be read and written 21617 13:51:45,480 --> 13:51:49,916 so in this case I only have what's 21618 13:51:47,480 --> 13:51:51,360 called generally a Setter and sorry in 21619 13:51:49,916 --> 13:51:53,040 this case I only have what's generally 21620 13:51:51,360 --> 13:51:54,720 called a getter and there's no mention 21621 13:51:53,040 --> 13:51:57,080 of the word getter here this is just 21622 13:51:54,720 --> 13:51:59,756 what app property means that function 21623 13:51:57,080 --> 13:52:02,200 balance will allow me recall to use 21624 13:51:59,756 --> 13:52:03,840 syntax like this where I can pretend as 21625 13:52:02,200 --> 13:52:06,596 though balance is indeed with no 21626 13:52:03,840 --> 13:52:09,520 underscore an instance variable but I 21627 13:52:06,596 --> 13:52:11,640 can now prevent code like mine in main 21628 13:52:09,520 --> 13:52:13,880 from trying to change balance because I 21629 13:52:11,640 --> 13:52:15,480 do not have a Setter I would not be able 21630 13:52:13,880 --> 13:52:17,116 to do something like account balance 21631 13:52:15,480 --> 13:52:19,436 equals a th000 to just give myself 21632 13:52:17,116 --> 13:52:21,756 $1,000 doll or coins because I have not 21633 13:52:19,436 --> 13:52:23,796 defined a Setter so again per our focus 21634 13:52:21,756 --> 13:52:25,640 on object-oriented programming these 21635 13:52:23,796 --> 13:52:28,080 properties just allow me some finer 21636 13:52:25,640 --> 13:52:30,756 grain control some languages allow you 21637 13:52:28,080 --> 13:52:32,880 to Define variables that are so to speak 21638 13:52:30,756 --> 13:52:35,360 constant that is once you have set a 21639 13:52:32,880 --> 13:52:37,040 value to them you cannot not change the 21640 13:52:35,360 --> 13:52:38,520 value of that variable and that tends to 21641 13:52:37,040 --> 13:52:41,080 be a good thing because it allows you to 21642 13:52:38,520 --> 13:52:42,560 program defensively just in case you 21643 13:52:41,080 --> 13:52:44,520 accidentally or someone else 21644 13:52:42,560 --> 13:52:46,640 accidentally tries to modify the value 21645 13:52:44,520 --> 13:52:49,640 of that variable if you have declared it 21646 13:52:46,640 --> 13:52:52,160 in some language as a constant it cannot 21647 13:52:49,640 --> 13:52:54,480 be changed or usually cannot be changed 21648 13:52:52,160 --> 13:52:56,400 without great effort unfortunately in 21649 13:52:54,480 --> 13:52:58,520 Python we're again on the sort of honor 21650 13:52:56,400 --> 13:52:59,680 System here where we have conventions to 21651 13:52:58,520 --> 13:53:01,436 indicate that something should be 21652 13:52:59,680 --> 13:53:03,000 treated as though it's constant but 21653 13:53:01,436 --> 13:53:04,640 that's not actually enforced by the 21654 13:53:03,000 --> 13:53:06,160 language so for instance let me let me 21655 13:53:04,640 --> 13:53:08,000 go back here to vs code and let me 21656 13:53:06,160 --> 13:53:10,040 create a new file for instance called 21657 13:53:08,000 --> 13:53:11,916 meow. pie and let's see if we can't 21658 13:53:10,040 --> 13:53:15,560 implement the notion of a cat meowing on 21659 13:53:11,916 --> 13:53:17,880 the screen so I'll do code of meow. py 21660 13:53:15,560 --> 13:53:19,596 and in meow. pie let me go ahead for 21661 13:53:17,880 --> 13:53:21,320 instance and Implement a very simple 21662 13:53:19,596 --> 13:53:24,680 program that just has a cap meowing 21663 13:53:21,320 --> 13:53:27,080 three times so how about this for I in 21664 13:53:24,680 --> 13:53:29,756 the range of three go ahead and print 21665 13:53:27,080 --> 13:53:31,480 out quote unquote meow all right well 21666 13:53:29,756 --> 13:53:33,160 we've seen in the past how we can clean 21667 13:53:31,480 --> 13:53:35,160 this up a little bit for instance if I'm 21668 13:53:33,160 --> 13:53:36,916 not actually using I I might as well 21669 13:53:35,160 --> 13:53:39,000 pythonic just change the name of that 21670 13:53:36,916 --> 13:53:41,400 variable to underscore even though that 21671 13:53:39,000 --> 13:53:43,796 has no functional effect here but here 21672 13:53:41,400 --> 13:53:46,276 we have this three sort of randomly 21673 13:53:43,796 --> 13:53:48,596 hardcoded that is typed explicitly into 21674 13:53:46,276 --> 13:53:50,916 my code and it's totally not a big deal 21675 13:53:48,596 --> 13:53:52,436 when your code is only two lines but 21676 13:53:50,916 --> 13:53:54,400 imagine that this is a much bigger 21677 13:53:52,436 --> 13:53:56,000 program with dozens or even hundreds of 21678 13:53:54,400 --> 13:53:58,640 lines and imagine that one of those 21679 13:53:56,000 --> 13:53:59,956 lines just is a three in there somewhere 21680 13:53:58,640 --> 13:54:01,436 like you're never going to find that 21681 13:53:59,956 --> 13:54:03,160 three very easily and it's going to be 21682 13:54:01,436 --> 13:54:04,520 very easily overlooked by you or 21683 13:54:03,160 --> 13:54:08,160 colleagues or others that you've 21684 13:54:04,520 --> 13:54:10,116 hardcoded some magic value like a three 21685 13:54:08,160 --> 13:54:11,796 right there in your code so it tends to 21686 13:54:10,116 --> 13:54:13,956 be best practice not just in Python but 21687 13:54:11,796 --> 13:54:15,880 other languages as well anytime you have 21688 13:54:13,956 --> 13:54:18,080 what is essentially a constant like a 21689 13:54:15,880 --> 13:54:20,080 number three that shouldn't ever change 21690 13:54:18,080 --> 13:54:22,240 is to at least let it Bubble Up surface 21691 13:54:20,080 --> 13:54:24,480 it to the top of your code so that it's 21692 13:54:22,240 --> 13:54:27,000 just obvious what your code's constant 21693 13:54:24,480 --> 13:54:28,720 values are and so by that I mean this at 21694 13:54:27,000 --> 13:54:30,956 the top of this file it would probably 21695 13:54:28,720 --> 13:54:33,040 be a little clear to colleagues and 21696 13:54:30,956 --> 13:54:35,200 frankly me tomorrow after I've forgotten 21697 13:54:33,040 --> 13:54:37,880 what I did today to Define a variable 21698 13:54:35,200 --> 13:54:40,480 like meow and set it equal to three and 21699 13:54:37,880 --> 13:54:42,756 then instead of hardcoding three here or 21700 13:54:40,480 --> 13:54:44,596 even lower in a much bigger program let 21701 13:54:42,756 --> 13:54:47,276 me just go ahead and pass in that 21702 13:54:44,596 --> 13:54:48,680 variable's value to my Loop so that now 21703 13:54:47,276 --> 13:54:50,360 it's just kind of obvious to me that 21704 13:54:48,680 --> 13:54:52,840 meow is apparently the number of times 21705 13:54:50,360 --> 13:54:54,560 to meow and if I ever want to change it 21706 13:54:52,840 --> 13:54:56,360 the only code I have to change is at the 21707 13:54:54,560 --> 13:54:57,840 very top of my file I don't need to go 21708 13:54:56,360 --> 13:54:59,680 fishing around or figure out what's 21709 13:54:57,840 --> 13:55:01,480 going to break what do I need to change 21710 13:54:59,680 --> 13:55:03,756 I just know that I can change these 21711 13:55:01,480 --> 13:55:06,160 constants up at the top the problem 21712 13:55:03,756 --> 13:55:08,560 though with Pip Pyon is that python 21713 13:55:06,160 --> 13:55:10,436 doesn't actually make variables constant 21714 13:55:08,560 --> 13:55:12,436 it's indeed a convention in Python and 21715 13:55:10,436 --> 13:55:14,160 some other languages to at least 21716 13:55:12,436 --> 13:55:16,240 capitalize your variables when you want 21717 13:55:14,160 --> 13:55:19,160 to indicate to the world that you should 21718 13:55:16,240 --> 13:55:21,000 not touch this it is constant but there 21719 13:55:19,160 --> 13:55:22,560 is literally nothing in my code 21720 13:55:21,000 --> 13:55:25,160 preventing me from saying you know what 21721 13:55:22,560 --> 13:55:27,400 today I feel like four meows instead 21722 13:55:25,160 --> 13:55:29,000 like that would work in other languages 21723 13:55:27,400 --> 13:55:31,080 though there's typically a keyword or 21724 13:55:29,000 --> 13:55:34,000 some other mechanism syntactically that 21725 13:55:31,080 --> 13:55:36,160 would allow you to prevent line three 21726 13:55:34,000 --> 13:55:38,040 current Cy from executing so that when 21727 13:55:36,160 --> 13:55:40,000 you tried to run your code you would 21728 13:55:38,040 --> 13:55:42,200 actually get an error message explicitly 21729 13:55:40,000 --> 13:55:44,240 saying you cannot do that so python 21730 13:55:42,200 --> 13:55:45,880 again is a bit more on the honor System 21731 13:55:44,240 --> 13:55:47,916 when it comes to these conventions 21732 13:55:45,880 --> 13:55:50,436 instead now it turns out there's other 21733 13:55:47,916 --> 13:55:52,640 types of constants quote unquote that 21734 13:55:50,436 --> 13:55:54,116 python uh typically manifest and in fact 21735 13:55:52,640 --> 13:55:55,480 let me go ahead and change this around a 21736 13:55:54,116 --> 13:55:58,400 little bit let me delete this version of 21737 13:55:55,480 --> 13:56:00,200 meow and let me introduce again a class 21738 13:55:58,400 --> 13:56:02,200 from our discussion of object-oriented 21739 13:56:00,200 --> 13:56:04,880 programming like a class representing a 21740 13:56:02,200 --> 13:56:07,200 cat another real world entity 21741 13:56:04,880 --> 13:56:09,560 recall that within classes you can have 21742 13:56:07,200 --> 13:56:11,360 not just instance variables but class 21743 13:56:09,560 --> 13:56:14,040 variables that is variables inside of 21744 13:56:11,360 --> 13:56:15,680 the class that aren't inside of self per 21745 13:56:14,040 --> 13:56:18,116 se but they're accessible to all of the 21746 13:56:15,680 --> 13:56:20,480 methods inside of that class here too 21747 13:56:18,116 --> 13:56:23,436 there's a convention but not enforced by 21748 13:56:20,480 --> 13:56:25,360 python of having class constants whereby 21749 13:56:23,436 --> 13:56:27,520 inside of the class you might want to 21750 13:56:25,360 --> 13:56:30,320 have a variable that should should 21751 13:56:27,520 --> 13:56:31,720 should not be changed but you just want 21752 13:56:30,320 --> 13:56:33,720 to indicate that visually by 21753 13:56:31,720 --> 13:56:35,956 capitalizing its name so for instance if 21754 13:56:33,720 --> 13:56:38,480 the def number of meows for a cat is 21755 13:56:35,956 --> 13:56:40,756 meant to be three I can literally inside 21756 13:56:38,480 --> 13:56:43,276 of my class but outside of any of my 21757 13:56:40,756 --> 13:56:45,680 defined methods just create a class 21758 13:56:43,276 --> 13:56:47,320 variable all capitalized with that same 21759 13:56:45,680 --> 13:56:50,436 value and then if I want to create a 21760 13:56:47,320 --> 13:56:52,796 method like uh meow for instance which 21761 13:56:50,436 --> 13:56:54,756 as an instance method might take in self 21762 13:56:52,796 --> 13:56:57,160 as we know and then I might have my Loop 21763 13:56:54,756 --> 13:56:58,756 here for underscore in the range of and 21764 13:56:57,160 --> 13:57:01,956 now I need to access this the convention 21765 13:56:58,756 --> 13:57:03,720 would be to say cat. meow to make clear 21766 13:57:01,956 --> 13:57:06,756 that I want the meow variable that's 21767 13:57:03,720 --> 13:57:08,320 associated with the class called cat 21768 13:57:06,756 --> 13:57:10,640 then I'm going to go ahead and print out 21769 13:57:08,320 --> 13:57:12,840 one of these meows and now at the bottom 21770 13:57:10,640 --> 13:57:14,360 of my code outside of the class let me 21771 13:57:12,840 --> 13:57:16,436 go ahead and do something like this let 21772 13:57:14,360 --> 13:57:18,880 me instantiate a cat using the cat 21773 13:57:16,436 --> 13:57:21,116 Constructor notice this is important per 21774 13:57:18,880 --> 13:57:23,000 our discussion of oop the class is 21775 13:57:21,116 --> 13:57:25,400 capitalized by convention but the 21776 13:57:23,000 --> 13:57:27,956 variable over here is is lowercase and I 21777 13:57:25,400 --> 13:57:29,436 could call it just C or anything else 21778 13:57:27,956 --> 13:57:31,360 but I kind of like the symmetry of 21779 13:57:29,436 --> 13:57:33,640 calling it little cat here and big cat 21780 13:57:31,360 --> 13:57:36,160 so to speak over here and now if I want 21781 13:57:33,640 --> 13:57:38,276 this particular cat to meow that default 21782 13:57:36,160 --> 13:57:41,840 number of three times I can just do cat. 21783 13:57:38,276 --> 13:57:45,240 meow like this and that method meow is 21784 13:57:41,840 --> 13:57:47,640 going to per line five access that class 21785 13:57:45,240 --> 13:57:49,480 constant but again it's constant only in 21786 13:57:47,640 --> 13:57:52,276 the fact only in the sense that you 21787 13:57:49,480 --> 13:57:54,116 should not touch that not that it's 21788 13:57:52,276 --> 13:57:56,320 actually going to be enforced by the 21789 13:57:54,116 --> 13:57:59,240 language all right let me go ahead then 21790 13:57:56,320 --> 13:58:02,320 and run this with python of meow STP and 21791 13:57:59,240 --> 13:58:04,640 there it is three of our meows meow meow 21792 13:58:02,320 --> 13:58:06,756 it turns out that python is 21793 13:58:04,640 --> 13:58:09,080 uh dynamically typed language that is to 21794 13:58:06,756 --> 13:58:10,956 say it's not strongly typed whereby when 21795 13:58:09,080 --> 13:58:12,916 you want an INT you have to tell the 21796 13:58:10,956 --> 13:58:14,360 program that you are using an INT you 21797 13:58:12,916 --> 13:58:17,200 don't have to tell the program that you 21798 13:58:14,360 --> 13:58:19,596 are using a stir or a float or a set or 21799 13:58:17,200 --> 13:58:21,436 anything else generally speaking to date 21800 13:58:19,596 --> 13:58:23,320 you and I when we're creating variables 21801 13:58:21,436 --> 13:58:25,276 we just give a variable a name we 21802 13:58:23,320 --> 13:58:27,436 frequently assign it using an the equal 21803 13:58:25,276 --> 13:58:29,400 sign some other value and honestly 21804 13:58:27,436 --> 13:58:32,200 python just kind of dynamically figures 21805 13:58:29,400 --> 13:58:34,160 out what type of variable it is if it's 21806 13:58:32,200 --> 13:58:36,320 uh quote unquote hello world the 21807 13:58:34,160 --> 13:58:38,840 variable is going to be a stir if it's 21808 13:58:36,320 --> 13:58:41,360 50 the integer the variable is going to 21809 13:58:38,840 --> 13:58:44,360 be an INT now in other languages 21810 13:58:41,360 --> 13:58:46,240 including C and C++ and Java and others 21811 13:58:44,360 --> 13:58:49,276 it's sometimes necessary for the 21812 13:58:46,240 --> 13:58:52,116 programmer to specify what types of 21813 13:58:49,276 --> 13:58:54,000 variables you want something to be the 21814 13:58:52,116 --> 13:58:56,756 upside of that is that it helps you 21815 13:58:54,000 --> 13:58:58,796 detect bugs more readily because if you 21816 13:58:56,756 --> 13:59:01,320 intend for a variable to store a string 21817 13:58:58,796 --> 13:59:03,436 or an integer but you accidentally store 21818 13:59:01,320 --> 13:59:06,080 an integer or a string the opposite or 21819 13:59:03,436 --> 13:59:08,240 something else Al together your uh 21820 13:59:06,080 --> 13:59:09,916 language can detect that kind of mistake 21821 13:59:08,240 --> 13:59:11,880 for you when you go for instance to run 21822 13:59:09,916 --> 13:59:13,640 the program it can say no you've made a 21823 13:59:11,880 --> 13:59:17,160 mistake and you can fix that before your 21824 13:59:13,640 --> 13:59:19,116 actual users detect as much in Python 2 21825 13:59:17,160 --> 13:59:21,240 here it's again more of a friendly 21826 13:59:19,116 --> 13:59:24,000 environment where you can provide hints 21827 13:59:21,240 --> 13:59:26,080 to python itself as to what type a 21828 13:59:24,000 --> 13:59:28,680 variable should be but the language 21829 13:59:26,080 --> 13:59:31,360 itself does not strongly enforce these 21830 13:59:28,680 --> 13:59:33,400 rather you can use a tool that will tell 21831 13:59:31,360 --> 13:59:35,400 you whether or not you're using a 21832 13:59:33,400 --> 13:59:37,436 variable directly but it's typically a 21833 13:59:35,400 --> 13:59:39,520 tool you would run as the programmer 21834 13:59:37,436 --> 13:59:41,200 before you actually release your code to 21835 13:59:39,520 --> 13:59:43,000 the world or if you have some kind of 21836 13:59:41,200 --> 13:59:45,640 automated process you can run this kind 21837 13:59:43,000 --> 13:59:47,756 of tool just like you could reformat or 21838 13:59:45,640 --> 13:59:49,720 lint your code with some other program 21839 13:59:47,756 --> 13:59:52,000 before you actually release it to the 21840 13:59:49,720 --> 13:59:53,436 world so how might we go about using 21841 13:59:52,000 --> 13:59:55,040 these so-called type penss well they're 21842 13:59:53,436 --> 13:59:57,200 documented in the usual place in 21843 13:59:55,040 --> 13:59:58,756 Python's own documentation and it turns 21844 13:59:57,200 --> 14:00:01,000 out there's a program that's pretty 21845 13:59:58,756 --> 14:00:04,040 popular for checking whether or not your 21846 14:00:01,000 --> 14:00:05,956 code is adhering to your own typ pins 21847 14:00:04,040 --> 14:00:07,400 and that program here is called mypie 21848 14:00:05,956 --> 14:00:09,116 and it's just one of several but this 21849 14:00:07,400 --> 14:00:11,320 one's particularly popular and can be 21850 14:00:09,116 --> 14:00:13,840 easily installed in the usual way with 21851 14:00:11,320 --> 14:00:15,916 Pip install mypie and its own 21852 14:00:13,840 --> 14:00:18,116 documentation is at this URL here but 21853 14:00:15,916 --> 14:00:20,080 we'll use it quite simply to check 21854 14:00:18,116 --> 14:00:22,560 whether or not our variables are indeed 21855 14:00:20,080 --> 14:00:24,400 using the right types so how can we go 21856 14:00:22,560 --> 14:00:26,520 about doing this all right let me go 21857 14:00:24,400 --> 14:00:29,320 back here to vs code clear my terminal 21858 14:00:26,520 --> 14:00:30,956 window and in fact erase meow. Pie as it 21859 14:00:29,320 --> 14:00:32,756 currently was and let's Implement a 21860 14:00:30,956 --> 14:00:34,916 different version of meow that quite 21861 14:00:32,756 --> 14:00:36,680 simply has a function called meow that 21862 14:00:34,916 --> 14:00:37,720 does the actual meowing on the screen 21863 14:00:36,680 --> 14:00:39,160 and then I'm just going to go ahead and 21864 14:00:37,720 --> 14:00:40,640 call that function down toward the 21865 14:00:39,160 --> 14:00:42,320 bottom I'm not going to bother with a 21866 14:00:40,640 --> 14:00:44,320 main function just for Simplicity so 21867 14:00:42,320 --> 14:00:46,560 that we can focus as always only on 21868 14:00:44,320 --> 14:00:49,040 what's new so here we are defining a 21869 14:00:46,560 --> 14:00:51,956 function called meow it's going to take 21870 14:00:49,040 --> 14:00:54,596 a number of times T meow for instance n 21871 14:00:51,956 --> 14:00:56,596 for number and inside of this function 21872 14:00:54,596 --> 14:00:59,720 I'm going to do my usual for underscore 21873 14:00:56,596 --> 14:01:01,916 in the range of n Go ahead and print 21874 14:00:59,720 --> 14:01:04,240 quote unquote meow So based on our 21875 14:01:01,916 --> 14:01:06,360 earlier code I think this is correct not 21876 14:01:04,240 --> 14:01:07,680 bothered defining the variable as I I'm 21877 14:01:06,360 --> 14:01:09,640 instead using the underscore because I'm 21878 14:01:07,680 --> 14:01:11,240 not using it anywhere but I think I now 21879 14:01:09,640 --> 14:01:13,680 have a working function whose purpose in 21880 14:01:11,240 --> 14:01:16,040 life is to meow zero or one or two or 21881 14:01:13,680 --> 14:01:18,116 three or more times well let's use this 21882 14:01:16,040 --> 14:01:19,436 function again not bothering with main 21883 14:01:18,116 --> 14:01:21,240 I'm just going to keep my function at 21884 14:01:19,436 --> 14:01:23,240 the very top because there's only one 21885 14:01:21,240 --> 14:01:25,436 and I'm going to write my code uh here 21886 14:01:23,240 --> 14:01:28,040 on line six so I'm going to give myself 21887 14:01:25,436 --> 14:01:29,160 I'm going to ask the user for a number 21888 14:01:28,040 --> 14:01:31,560 and I'm going to go ahead and prompt 21889 14:01:29,160 --> 14:01:33,596 them in the usual way for that number of 21890 14:01:31,560 --> 14:01:37,200 times to meow and now I'm going to go 21891 14:01:33,596 --> 14:01:39,240 ahead and call meow on that number now 21892 14:01:37,200 --> 14:01:41,480 some of you might see what I've already 21893 14:01:39,240 --> 14:01:43,240 done wrong but perhaps I myself don't so 21894 14:01:41,480 --> 14:01:46,240 let me go into my terminal window and 21895 14:01:43,240 --> 14:01:48,320 run python of meow. py the goal being to 21896 14:01:46,240 --> 14:01:50,320 prompt me this seems to be working I'm 21897 14:01:48,320 --> 14:01:52,956 going to type in three and I would 21898 14:01:50,320 --> 14:01:56,880 expect now the meow function to print 21899 14:01:52,956 --> 14:01:58,680 out meow three times enter but no 21900 14:01:56,880 --> 14:02:02,040 there's some kind of type error here 21901 14:01:58,680 --> 14:02:04,596 stir object cannot be interpreted as an 21902 14:02:02,040 --> 14:02:08,840 integer why might that 21903 14:02:04,596 --> 14:02:11,880 be why might that be because the input 21904 14:02:08,840 --> 14:02:14,436 function returns a string instead of an 21905 14:02:11,880 --> 14:02:17,160 in exactly the input function returns a 21906 14:02:14,436 --> 14:02:19,116 string or a stir not an INT so in the 21907 14:02:17,160 --> 14:02:20,916 past of course our solution to this 21908 14:02:19,116 --> 14:02:22,756 problem has just been to convert the 21909 14:02:20,916 --> 14:02:24,480 string to an INT by using the int 21910 14:02:22,756 --> 14:02:26,320 function but now let me start 21911 14:02:24,480 --> 14:02:29,000 programming more defensively so that 21912 14:02:26,320 --> 14:02:31,320 honestly I don't even find myself in 21913 14:02:29,000 --> 14:02:33,480 this situation at all let me go ahead 21914 14:02:31,320 --> 14:02:36,436 and do this let me add what's called a 21915 14:02:33,480 --> 14:02:39,480 type hint to my function that explicitly 21916 14:02:36,436 --> 14:02:41,360 specifies for meow what type of variable 21917 14:02:39,480 --> 14:02:43,116 should be passed in I'm going to go 21918 14:02:41,360 --> 14:02:45,436 ahead now and change the very first line 21919 14:02:43,116 --> 14:02:49,596 of my code and my function to specify 21920 14:02:45,436 --> 14:02:51,520 that n colon should be an INT and this 21921 14:02:49,596 --> 14:02:54,360 is a type hint the fact that I've added 21922 14:02:51,520 --> 14:02:56,360 a Col in a space and the word int is not 21923 14:02:54,360 --> 14:02:59,320 creating another int or anything like 21924 14:02:56,360 --> 14:03:02,116 that it's just a hint an annotation so 21925 14:02:59,320 --> 14:03:06,796 to speak to python that this variable on 21926 14:03:02,116 --> 14:03:09,276 the left called n should be an INT now 21927 14:03:06,796 --> 14:03:10,796 unfortunately python itself doesn't care 21928 14:03:09,276 --> 14:03:13,040 because again these type hints are not 21929 14:03:10,796 --> 14:03:14,560 enforced by the language and that's by 21930 14:03:13,040 --> 14:03:16,400 Design the language itself in the 21931 14:03:14,560 --> 14:03:18,596 community prefers that python be 21932 14:03:16,400 --> 14:03:20,916 dynamically typed not so strongly typed 21933 14:03:18,596 --> 14:03:23,276 as to require these things to be true 21934 14:03:20,916 --> 14:03:26,320 but if I run meow. py type in three 21935 14:03:23,276 --> 14:03:29,480 again the same error is there but let me 21936 14:03:26,320 --> 14:03:31,680 go about trying this mypie program an 21937 14:03:29,480 --> 14:03:34,160 example of a program that understands 21938 14:03:31,680 --> 14:03:36,956 typ hints and if I run it proac actively 21939 14:03:34,160 --> 14:03:40,240 myself can find bugs like this in my 21940 14:03:36,956 --> 14:03:42,000 code before I or worse a user actually 21941 14:03:40,240 --> 14:03:44,160 runs and encounters something cryptic 21942 14:03:42,000 --> 14:03:46,756 like this type error here let me clear 21943 14:03:44,160 --> 14:03:50,360 my terminal window and this time run my 21944 14:03:46,756 --> 14:03:53,160 Pi space meow. so I'm going to run my 21945 14:03:50,360 --> 14:03:56,276 piie on my program but I'm not running 21946 14:03:53,160 --> 14:03:59,200 python itself when I hit enter we'll see 21947 14:03:56,276 --> 14:04:01,640 this all right we see now that my pie 21948 14:03:59,200 --> 14:04:04,116 found apparently an error on line seven 21949 14:04:01,640 --> 14:04:07,320 error argument one to meow has 21950 14:04:04,116 --> 14:04:09,360 incompatible typ stir expected int so 21951 14:04:07,320 --> 14:04:11,840 it's still an error message but mypie is 21952 14:04:09,360 --> 14:04:13,956 not a program that my users would use 21953 14:04:11,840 --> 14:04:15,956 this is a program that you and I as 21954 14:04:13,956 --> 14:04:18,080 programmers would use and because we 21955 14:04:15,956 --> 14:04:20,000 have run this code now before we for 21956 14:04:18,080 --> 14:04:22,360 instance released this program to the 21957 14:04:20,000 --> 14:04:25,796 world I can now see even before the code 21958 14:04:22,360 --> 14:04:28,480 is called or run oh I seem to be M using 21959 14:04:25,796 --> 14:04:31,040 my argument to meow wrong I had better 21960 14:04:28,480 --> 14:04:33,796 fix this somehow well I can actually go 21961 14:04:31,040 --> 14:04:35,880 about in uh hint adding typ hints even 21962 14:04:33,796 --> 14:04:38,596 into my own variables here so as to 21963 14:04:35,880 --> 14:04:40,360 catch this another way too if I know on 21964 14:04:38,596 --> 14:04:42,160 line six that I'm creating already a 21965 14:04:40,360 --> 14:04:44,400 variable called number and I know 21966 14:04:42,160 --> 14:04:47,756 already that I'm assigning it equal to 21967 14:04:44,400 --> 14:04:50,160 the return value of input I could give 21968 14:04:47,756 --> 14:04:52,200 my pi and tools like it another hint and 21969 14:04:50,160 --> 14:04:54,916 say you know what this variable called 21970 14:04:52,200 --> 14:04:56,640 number should also be an INT that is to 21971 14:04:54,916 --> 14:05:00,040 say if I now start getting into the 21972 14:04:56,640 --> 14:05:02,680 habit of annotating all of my variables 21973 14:05:00,040 --> 14:05:04,916 and arguments to functions maybe my Pi 21974 14:05:02,680 --> 14:05:06,756 can actually help me find things quite 21975 14:05:04,916 --> 14:05:08,756 quickly as well before I get to the 21976 14:05:06,756 --> 14:05:11,080 point of running python itself let's go 21977 14:05:08,756 --> 14:05:13,840 ahead and try this again my piie of 21978 14:05:11,080 --> 14:05:15,956 meow. Pi and hit enter and this time 21979 14:05:13,840 --> 14:05:18,596 notice that my Pi actually found the 21980 14:05:15,956 --> 14:05:20,880 mistake a little more quickly notice 21981 14:05:18,596 --> 14:05:23,480 this time it found on line six that 21982 14:05:20,880 --> 14:05:25,956 error incompatible types and assignment 21983 14:05:23,480 --> 14:05:28,276 expression has Type stir variable has 21984 14:05:25,956 --> 14:05:31,360 Type int so before I even got to the 21985 14:05:28,276 --> 14:05:34,320 point of calling meow line six via this 21986 14:05:31,360 --> 14:05:36,240 typeint when used and analyzed by mypie 21987 14:05:34,320 --> 14:05:38,240 has helped me find oh wait a minute I 21988 14:05:36,240 --> 14:05:40,956 shouldn't be assigning the return value 21989 14:05:38,240 --> 14:05:42,956 of input to my variable called number in 21990 14:05:40,956 --> 14:05:44,680 the first place why mypie has just 21991 14:05:42,956 --> 14:05:47,360 pointed out to me that one returns a 21992 14:05:44,680 --> 14:05:49,320 stir I'm expecting an INT let me fix 21993 14:05:47,360 --> 14:05:50,840 this now instead all right so let me 21994 14:05:49,320 --> 14:05:52,240 clear my terminal window and now let me 21995 14:05:50,840 --> 14:05:53,596 do what most of you were probably 21996 14:05:52,240 --> 14:05:55,400 thinking I should have done in the first 21997 14:05:53,596 --> 14:05:57,720 place after all of these weeks but now 21998 14:05:55,400 --> 14:06:00,160 let me go ahead and convert the return 21999 14:05:57,720 --> 14:06:02,480 value of input to an integer for today's 22000 14:06:00,160 --> 14:06:04,040 purposes I'm not going to try to catch 22001 14:06:02,480 --> 14:06:05,640 any exceptions or the we're just going 22002 14:06:04,040 --> 14:06:08,640 to assume that the user types this in 22003 14:06:05,640 --> 14:06:11,560 properly and now let me go ahead and run 22004 14:06:08,640 --> 14:06:14,720 my piie of meow. pie having not only 22005 14:06:11,560 --> 14:06:17,200 added two typeint to my argument to my 22006 14:06:14,720 --> 14:06:19,400 function to my variable down here on 22007 14:06:17,200 --> 14:06:21,360 line six and I've also now fixed the 22008 14:06:19,400 --> 14:06:24,320 problem itself let me go ahead and run 22009 14:06:21,360 --> 14:06:27,560 my piie and success no issues found in 22010 14:06:24,320 --> 14:06:28,956 one source file now it's more reasonable 22011 14:06:27,560 --> 14:06:31,080 for me to go and run something like 22012 14:06:28,956 --> 14:06:33,680 python of meow and just trust that when 22013 14:06:31,080 --> 14:06:36,320 I type in three at least I'm not not 22014 14:06:33,680 --> 14:06:38,240 going to get a type error that is I 22015 14:06:36,320 --> 14:06:40,640 didn't mess up as a programmer with 22016 14:06:38,240 --> 14:06:41,880 respect to the types of my variables why 22017 14:06:40,640 --> 14:06:43,880 because when I wrote the coder in the 22018 14:06:41,880 --> 14:06:46,560 first place I provided these annotations 22019 14:06:43,880 --> 14:06:48,916 these hints that inform tools like my 22020 14:06:46,560 --> 14:06:52,080 piie that my intention had better line 22021 14:06:48,916 --> 14:06:53,720 up with what the actual code does let me 22022 14:06:52,080 --> 14:06:57,400 pause here and see if there's now any 22023 14:06:53,720 --> 14:06:59,756 questions on tight pins or my pie is it 22024 14:06:57,400 --> 14:07:02,040 common or how common is it for those to 22025 14:06:59,756 --> 14:07:04,480 be used or is it just that it's more 22026 14:07:02,040 --> 14:07:07,400 used in more complex code 22027 14:07:04,480 --> 14:07:10,880 um where it's more difficult to ensure 22028 14:07:07,400 --> 14:07:12,400 that you're actually uh using the 22029 14:07:10,880 --> 14:07:14,276 correct type in the way that you're 22030 14:07:12,400 --> 14:07:15,956 using the variables it's a good question 22031 14:07:14,276 --> 14:07:18,480 and it's rather a matter of opinion 22032 14:07:15,956 --> 14:07:20,560 python was designed to be a little more 22033 14:07:18,480 --> 14:07:22,840 versatile and flexible when it comes to 22034 14:07:20,560 --> 14:07:24,436 some of these details partly for uh 22035 14:07:22,840 --> 14:07:25,756 writeability to make it easier and 22036 14:07:24,436 --> 14:07:27,520 faster to write code partly for 22037 14:07:25,756 --> 14:07:28,840 performance so that the program like 22038 14:07:27,520 --> 14:07:30,116 python doesn't have to bother checking 22039 14:07:28,840 --> 14:07:32,480 these kinds of details we can just get 22040 14:07:30,116 --> 14:07:35,956 right into the code the reality though 22041 14:07:32,480 --> 14:07:37,560 is that uh strong type checks do tend to 22042 14:07:35,956 --> 14:07:39,756 be a good thing for the correctness of 22043 14:07:37,560 --> 14:07:42,400 your code why because programs like 22044 14:07:39,756 --> 14:07:44,796 mypie can find before your code is even 22045 14:07:42,400 --> 14:07:46,640 run if there's already known to be an 22046 14:07:44,796 --> 14:07:50,640 error and it tends to be good for 22047 14:07:46,640 --> 14:07:52,436 defensive programming um so the the 22048 14:07:50,640 --> 14:07:54,956 situation essentially is that within the 22049 14:07:52,436 --> 14:07:57,480 python ecosystem you can uh annotate 22050 14:07:54,956 --> 14:08:00,200 your types in this way you can use tools 22051 14:07:57,480 --> 14:08:02,240 to use those typin but to date python 22052 14:08:00,200 --> 14:08:05,320 itself does not enforce or expect to 22053 14:08:02,240 --> 14:08:07,320 enforce these conventions in larger code 22054 14:08:05,320 --> 14:08:09,840 bases in professional code bases 22055 14:08:07,320 --> 14:08:11,756 Commercial Code bases probably depending 22056 14:08:09,840 --> 14:08:13,116 on the product uh project manager or 22057 14:08:11,756 --> 14:08:14,756 depending on the engineering team they 22058 14:08:13,116 --> 14:08:17,080 may very well want themselves to be 22059 14:08:14,756 --> 14:08:19,596 using typ pins why if it just decreases 22060 14:08:17,080 --> 14:08:22,640 the probability of bugs in fact let me 22061 14:08:19,596 --> 14:08:26,040 propose now that I imagine a situation 22062 14:08:22,640 --> 14:08:28,480 where instead of expecting that meow 22063 14:08:26,040 --> 14:08:31,360 prints meow meow meow some number of 22064 14:08:28,480 --> 14:08:33,040 times suppose that I accidentally uh 22065 14:08:31,360 --> 14:08:35,080 assume that the meow function just 22066 14:08:33,040 --> 14:08:37,040 returns returns meow some number of 22067 14:08:35,080 --> 14:08:38,840 times we saw for instance when focusing 22068 14:08:37,040 --> 14:08:40,720 on unit tests that it tends to be a good 22069 14:08:38,840 --> 14:08:43,160 thing to have functions that return 22070 14:08:40,720 --> 14:08:44,796 values be it an INT or a string rather 22071 14:08:43,160 --> 14:08:46,640 than just having some side effect like 22072 14:08:44,796 --> 14:08:48,436 printing things out themselves so 22073 14:08:46,640 --> 14:08:50,596 perhaps I'm still in that mindset and 22074 14:08:48,436 --> 14:08:53,436 I've just assumed mistakenly for the 22075 14:08:50,596 --> 14:08:55,880 moment that meow returns a value like 22076 14:08:53,436 --> 14:08:58,000 meow or meow meow or meow meow meow a 22077 14:08:55,880 --> 14:08:59,596 big string of some number of meows 22078 14:08:58,000 --> 14:09:01,480 rather than just printing it itself as 22079 14:08:59,596 --> 14:09:03,880 it clearly does at the moment on line 22080 14:09:01,480 --> 14:09:06,040 three and therefore suppos that I 22081 14:09:03,880 --> 14:09:08,040 accidentally did something like this 22082 14:09:06,040 --> 14:09:11,160 rather than just getting the number and 22083 14:09:08,040 --> 14:09:14,436 passing it to meow suppose I did this uh 22084 14:09:11,160 --> 14:09:16,880 suppose I declared a number of a new 22085 14:09:14,436 --> 14:09:19,956 variable called meows the type of which 22086 14:09:16,880 --> 14:09:22,596 I think should be stir and suppose again 22087 14:09:19,956 --> 14:09:25,640 I assume accidentally that meow returns 22088 14:09:22,596 --> 14:09:27,560 to me a string of those meows so that I 22089 14:09:25,640 --> 14:09:28,840 myself can then print them later this 22090 14:09:27,560 --> 14:09:31,720 would be a little more conducive 22091 14:09:28,840 --> 14:09:33,320 arguably to testing my meow function why 22092 14:09:31,720 --> 14:09:35,916 because I could expect that it's return 22093 14:09:33,320 --> 14:09:38,160 rning meow or meow meow or meow meow 22094 14:09:35,916 --> 14:09:41,080 meow separated by new lines returning a 22095 14:09:38,160 --> 14:09:43,240 stir that I could then assert equals 22096 14:09:41,080 --> 14:09:44,596 what I expect it to be in something like 22097 14:09:43,240 --> 14:09:46,640 a unit test I'm not going to bother 22098 14:09:44,596 --> 14:09:48,320 writing any unit tests now but let's 22099 14:09:46,640 --> 14:09:51,640 just suppose that's the mindset I'm now 22100 14:09:48,320 --> 14:09:53,796 in and so on line seven I'm assuming 22101 14:09:51,640 --> 14:09:56,520 that I want to assign the return value 22102 14:09:53,796 --> 14:09:58,956 of meow to a new variable called meow's 22103 14:09:56,520 --> 14:10:01,040 which I've annotated with this type hint 22104 14:09:58,956 --> 14:10:03,040 as being a stir just so we can see 22105 14:10:01,040 --> 14:10:05,720 another variable this one's not an INT 22106 14:10:03,040 --> 14:10:09,240 but to stir instead well let me go ahead 22107 14:10:05,720 --> 14:10:12,240 and run this code now python of meow. 22108 14:10:09,240 --> 14:10:15,916 enter typing in three and you'll see a 22109 14:10:12,240 --> 14:10:18,640 curious bug meow meow meow none well why 22110 14:10:15,916 --> 14:10:21,200 is that well it turns out at the moment 22111 14:10:18,640 --> 14:10:23,080 my meow function only has a side effect 22112 14:10:21,200 --> 14:10:25,240 it just prints out meow some number of 22113 14:10:23,080 --> 14:10:26,720 times it doesn't explicitly return a 22114 14:10:25,240 --> 14:10:29,160 value as it would if there were 22115 14:10:26,720 --> 14:10:31,200 literally the return keyword there by 22116 14:10:29,160 --> 14:10:33,480 default then when a function in Python 22117 14:10:31,200 --> 14:10:36,560 does not explicitly return a value it's 22118 14:10:33,480 --> 14:10:38,640 implicit return value is effect none and 22119 14:10:36,560 --> 14:10:41,360 so what we're seeing here is this on 22120 14:10:38,640 --> 14:10:44,796 line 8 because I'm 22121 14:10:41,360 --> 14:10:49,400 assigning the return value of meow which 22122 14:10:44,796 --> 14:10:52,720 is none to my meow's variable line three 22123 14:10:49,400 --> 14:10:55,116 is what's still printing meow meow meow 22124 14:10:52,720 --> 14:10:57,680 and line eight is what's now incorrectly 22125 14:10:55,116 --> 14:10:59,916 printing none because I accidentally 22126 14:10:57,680 --> 14:11:01,756 thought that meow returns a value but it 22127 14:10:59,916 --> 14:11:03,840 doesn't so its return value is 22128 14:11:01,756 --> 14:11:07,200 effectively none so I'm printing very 22129 14:11:03,840 --> 14:11:08,916 weirdly the word none at the bottom so 22130 14:11:07,200 --> 14:11:10,796 how could I go about catching this kind 22131 14:11:08,916 --> 14:11:13,000 of mistake too like I might make this 22132 14:11:10,796 --> 14:11:15,240 mistake but maybe with less frequency if 22133 14:11:13,000 --> 14:11:18,116 I'm in the habit of annotating my code 22134 14:11:15,240 --> 14:11:20,480 with this new feature called co uh typ 22135 14:11:18,116 --> 14:11:21,956 Pence what you can do here is this let 22136 14:11:20,480 --> 14:11:24,596 me clear my terminal window to get rid 22137 14:11:21,956 --> 14:11:26,596 of that artifact and up here let me 22138 14:11:24,596 --> 14:11:29,956 additionally specify with some funny 22139 14:11:26,596 --> 14:11:33,360 looking syntax that my meow function 22140 14:11:29,956 --> 14:11:35,360 actually by Design returns none so you 22141 14:11:33,360 --> 14:11:38,596 literally use this arrow notation in 22142 14:11:35,360 --> 14:11:41,840 Python when hinting what the return 22143 14:11:38,596 --> 14:11:45,520 value of a function is you would do this 22144 14:11:41,840 --> 14:11:47,520 after the parentheses a space a hyphen a 22145 14:11:45,520 --> 14:11:49,080 greater than symbol like an arrow and 22146 14:11:47,520 --> 14:11:51,436 then another space and then the type of 22147 14:11:49,080 --> 14:11:54,956 the return value for now it's indeed 22148 14:11:51,436 --> 14:11:57,276 going to excuse me return none but now 22149 14:11:54,956 --> 14:11:59,916 at least I can catch it like this if I 22150 14:11:57,276 --> 14:12:01,436 now run not python but my P on my code 22151 14:11:59,916 --> 14:12:03,596 which would be a habit I'm now getting 22152 14:12:01,436 --> 14:12:05,480 into if using typ hints check that I'm 22153 14:12:03,596 --> 14:12:07,880 using all of my types correctly before I 22154 14:12:05,480 --> 14:12:11,276 even run my program we'll see that now 22155 14:12:07,880 --> 14:12:13,720 my Pie has found on line seven that meow 22156 14:12:11,276 --> 14:12:15,956 quote unquote does not return a value 22157 14:12:13,720 --> 14:12:18,520 and my Pi knows that because I have 22158 14:12:15,956 --> 14:12:21,956 proactively annotated my meow function 22159 14:12:18,520 --> 14:12:24,276 as having none as its return value so 22160 14:12:21,956 --> 14:12:26,520 now my piie can detect that I should now 22161 14:12:24,276 --> 14:12:29,320 realize oh wait a minute I'm being uh 22162 14:12:26,520 --> 14:12:31,116 foolish here ma meow clearly does not 22163 14:12:29,320 --> 14:12:33,840 return a value I should not be treating 22164 14:12:31,116 --> 14:12:36,720 it like it does on line seven let me go 22165 14:12:33,840 --> 14:12:38,360 about actually fixing this now so how do 22166 14:12:36,720 --> 14:12:39,796 I go about fixing this well let's 22167 14:12:38,360 --> 14:12:41,320 practice what we preached in our focus 22168 14:12:39,796 --> 14:12:43,480 on unit tests having a function like 22169 14:12:41,320 --> 14:12:45,680 meow not have side effects like printing 22170 14:12:43,480 --> 14:12:47,756 itself but let's have it return the 22171 14:12:45,680 --> 14:12:50,320 actual string and I can actually do this 22172 14:12:47,756 --> 14:12:52,480 kind of cleanly let me uh clear my error 22173 14:12:50,320 --> 14:12:54,796 message in my terminal window here let 22174 14:12:52,480 --> 14:12:57,240 me get rid of the loop here let me say 22175 14:12:54,796 --> 14:13:00,000 this time that okay fine meow is going 22176 14:12:57,240 --> 14:13:02,720 to return a value an actual stir or 22177 14:13:00,000 --> 14:13:04,360 string so I've changed none to stir and 22178 14:13:02,720 --> 14:13:06,040 now I can implement this in any number 22179 14:13:04,360 --> 14:13:07,596 of ways maybe even using a loop but 22180 14:13:06,040 --> 14:13:09,756 recall that we have this syntax in 22181 14:13:07,596 --> 14:13:12,596 Python which will I think solve this 22182 14:13:09,756 --> 14:13:16,480 problem for us if I want to return a 22183 14:13:12,596 --> 14:13:19,796 string of n meows what I can actually do 22184 14:13:16,480 --> 14:13:23,880 recall is this return quote unquote meow 22185 14:13:19,796 --> 14:13:25,916 back sln times that number n so it's 22186 14:13:23,880 --> 14:13:27,560 kind of a clever oneliner avoids the 22187 14:13:25,916 --> 14:13:30,276 need for a for Loop or something more 22188 14:13:27,560 --> 14:13:33,276 involved than that to just say multiply 22189 14:13:30,276 --> 14:13:36,116 meow back sln against itself three times 22190 14:13:33,276 --> 14:13:38,796 ENT or end times in this case in general 22191 14:13:36,116 --> 14:13:41,720 so that I get back a big string of zero 22192 14:13:38,796 --> 14:13:44,360 meows One Two Three or many more meows 22193 14:13:41,720 --> 14:13:46,796 instead I think now my code on line six 22194 14:13:44,360 --> 14:13:48,720 is actually correct now I've changed 22195 14:13:46,796 --> 14:13:50,956 meow to behave the way I was pretending 22196 14:13:48,720 --> 14:13:54,560 to assume it always worked so I'm 22197 14:13:50,956 --> 14:13:57,116 storing in meow's plural a variable 22198 14:13:54,560 --> 14:14:00,200 that's of type stir because now meow 22199 14:13:57,116 --> 14:14:04,680 does have a return value of type stir 22200 14:14:00,200 --> 14:14:06,116 itself per this typ hint as well all 22201 14:14:04,680 --> 14:14:09,360 right let me go ahead now and print 22202 14:14:06,116 --> 14:14:11,240 meows but because each of my meows comes 22203 14:14:09,360 --> 14:14:12,956 with a a trailing new line the back 22204 14:14:11,240 --> 14:14:14,880 slash n I'm going to proactively fix 22205 14:14:12,956 --> 14:14:16,560 what would be a minor aesthetic bug and 22206 14:14:14,880 --> 14:14:18,680 I'm just going to avoid outputting an 22207 14:14:16,560 --> 14:14:21,916 extra new line at the end of those uh 22208 14:14:18,680 --> 14:14:25,240 three so if I run python of meow. py now 22209 14:14:21,916 --> 14:14:30,680 type in three there's my meow meow meow 22210 14:14:25,240 --> 14:14:34,480 and now no mention of none questions now 22211 14:14:30,680 --> 14:14:37,640 on typ hints and these annot and mypie 22212 14:14:34,480 --> 14:14:39,240 and using them to defensively write code 22213 14:14:37,640 --> 14:14:42,200 that just decreases hopefully the 22214 14:14:39,240 --> 14:14:45,956 probability of your own bugs in the 22215 14:14:42,200 --> 14:14:49,916 return there is a in return there is a 22216 14:14:45,956 --> 14:14:53,276 double quotes that have meow 22217 14:14:49,916 --> 14:14:55,200 sln why the program don't take it as a 22218 14:14:53,276 --> 14:14:59,680 strange why does the program not take it 22219 14:14:55,200 --> 14:15:01,596 as a a a strange see so so recall that 22220 14:14:59,680 --> 14:15:03,796 um early on in the class we looked at 22221 14:15:01,596 --> 14:15:05,240 plus as a concatenation operator that 22222 14:15:03,796 --> 14:15:08,320 allows you to join a string on the left 22223 14:15:05,240 --> 14:15:11,756 and the right multiplication is also an 22224 14:15:08,320 --> 14:15:13,640 overloaded operator for Strings whereby 22225 14:15:11,756 --> 14:15:16,080 if you have a string on the left and an 22226 14:15:13,640 --> 14:15:18,436 INT on the right it will multiply the 22227 14:15:16,080 --> 14:15:22,480 string so to speak by concatenating or 22228 14:15:18,436 --> 14:15:24,000 joining that many meows all together so 22229 14:15:22,480 --> 14:15:26,080 this is a feature of object-oriented 22230 14:15:24,000 --> 14:15:29,560 programming an OB an operator 22231 14:15:26,080 --> 14:15:33,160 overloading as we saw it uh in the past 22232 14:15:29,560 --> 14:15:36,276 other questions on typ Pence or mypod 22233 14:15:33,160 --> 14:15:39,116 can we not type cast this data type of 22234 14:15:36,276 --> 14:15:40,436 the you know of this variable number no 22235 14:15:39,116 --> 14:15:42,240 you still and let me correct the 22236 14:15:40,436 --> 14:15:44,160 terminology it wouldn't be called type 22237 14:15:42,240 --> 14:15:45,956 casting in this context uh because it's 22238 14:15:44,160 --> 14:15:47,640 not like C or C++ where there's an 22239 14:15:45,956 --> 14:15:50,360 equivalence between these types you're 22240 14:15:47,640 --> 14:15:53,560 technically converting on line five a 22241 14:15:50,360 --> 14:15:55,240 stir to an INT you do still have to do 22242 14:15:53,560 --> 14:15:57,116 this because my piie for instance would 22243 14:15:55,240 --> 14:15:59,320 yell at you if you were trying to assign 22244 14:15:57,116 --> 14:16:02,276 a stir on the right to an INT on the 22245 14:15:59,320 --> 14:16:04,200 left you must still use the int function 22246 14:16:02,276 --> 14:16:07,116 int it's self is still a function it's 22247 14:16:04,200 --> 14:16:09,640 not a type hint but the word int is 22248 14:16:07,116 --> 14:16:12,116 being used in another way now in these 22249 14:16:09,640 --> 14:16:14,680 type hints so this int is still a 22250 14:16:12,116 --> 14:16:16,640 function call as it always has been this 22251 14:16:14,680 --> 14:16:18,560 syntax on the left is another use of the 22252 14:16:16,640 --> 14:16:20,680 keyword int but in the form of these 22253 14:16:18,560 --> 14:16:22,200 type hint so you still have to do the 22254 14:16:20,680 --> 14:16:24,720 conversion 22255 14:16:22,200 --> 14:16:27,160 yourself all right let me propose that 22256 14:16:24,720 --> 14:16:28,880 we transition to another feature of 22257 14:16:27,160 --> 14:16:30,680 python that's worth knowing especially 22258 14:16:28,880 --> 14:16:32,596 since it's one that you'll see in the 22259 14:16:30,680 --> 14:16:34,360 wild when you see code or libraries that 22260 14:16:32,596 --> 14:16:36,320 other folks have written namely 22261 14:16:34,360 --> 14:16:38,320 something known as a dock string or 22262 14:16:36,320 --> 14:16:40,436 document strings it turns out in the 22263 14:16:38,320 --> 14:16:42,796 world of python there is a standardized 22264 14:16:40,436 --> 14:16:46,360 way per another pep python enhancement 22265 14:16:42,796 --> 14:16:48,880 proposal this one 257 that essentially 22266 14:16:46,360 --> 14:16:51,040 standardizes how you should document 22267 14:16:48,880 --> 14:16:53,360 your functions among other aspects of 22268 14:16:51,040 --> 14:16:57,160 your code and so for instance let me go 22269 14:16:53,360 --> 14:16:59,436 back to my uh meow. py file here and let 22270 14:16:57,160 --> 14:17:01,160 me propose that we now start documenting 22271 14:16:59,436 --> 14:17:03,480 this code too so that I know what the 22272 14:17:01,160 --> 14:17:05,840 meow function does and in fact the 22273 14:17:03,480 --> 14:17:08,840 standard way of doing this using dock 22274 14:17:05,840 --> 14:17:11,240 string notation would be as follows to 22275 14:17:08,840 --> 14:17:12,840 comment this function not above it as 22276 14:17:11,240 --> 14:17:15,116 you might be in the habit of doing with 22277 14:17:12,840 --> 14:17:17,160 code in general but actually inside of 22278 14:17:15,116 --> 14:17:19,240 it but instead of commenting it like 22279 14:17:17,160 --> 14:17:22,756 this with the usual hash comment sign 22280 14:17:19,240 --> 14:17:25,200 like meow n times it turns out that when 22281 14:17:22,756 --> 14:17:27,640 you're formally docking when you're 22282 14:17:25,200 --> 14:17:30,480 formally documenting a function like 22283 14:17:27,640 --> 14:17:33,160 meow in this case you don't use regular 22284 14:17:30,480 --> 14:17:36,520 inline comment so to speak you use this 22285 14:17:33,160 --> 14:17:39,276 syntax instead you use triple quotation 22286 14:17:36,520 --> 14:17:42,400 marks either double or single then you 22287 14:17:39,276 --> 14:17:44,480 write out your comment meow and times 22288 14:17:42,400 --> 14:17:46,480 and then you write the same again at the 22289 14:17:44,480 --> 14:17:48,480 end so either three double quotes at the 22290 14:17:46,480 --> 14:17:50,640 start and the end or three single quotes 22291 14:17:48,480 --> 14:17:52,720 at the start and the end and python has 22292 14:17:50,640 --> 14:17:55,596 built into it certain tools and certain 22293 14:17:52,720 --> 14:17:57,840 assumptions that if it detects that 22294 14:17:55,596 --> 14:17:59,916 there is a comment using this dock 22295 14:17:57,840 --> 14:18:02,080 string format triple quotes on the left 22296 14:17:59,916 --> 14:18:03,640 and the right it will assume that that's 22297 14:18:02,080 --> 14:18:05,436 indeed the doc mentation for that 22298 14:18:03,640 --> 14:18:07,680 function and it turns out in the pyth 22299 14:18:05,436 --> 14:18:10,000 python ecosystem there's a lot of tools 22300 14:18:07,680 --> 14:18:12,916 that you can then use to analyze your 22301 14:18:10,000 --> 14:18:15,000 code automatically extract all of these 22302 14:18:12,916 --> 14:18:17,956 document strings for you and even 22303 14:18:15,000 --> 14:18:20,520 generate web pages or PDFs of 22304 14:18:17,956 --> 14:18:22,796 documentation for your own function so 22305 14:18:20,520 --> 14:18:24,796 there's these conventions via which if 22306 14:18:22,796 --> 14:18:26,596 you adhere to them you can start 22307 14:18:24,796 --> 14:18:28,880 documenting your code as for other 22308 14:18:26,596 --> 14:18:31,080 people by generating automatically the 22309 14:18:28,880 --> 14:18:32,720 documentation from your own code without 22310 14:18:31,080 --> 14:18:35,480 writing something up from scratch man 22311 14:18:32,720 --> 14:18:37,680 manually now it turns out if your 22312 14:18:35,480 --> 14:18:39,320 function uh does take arguments and 22313 14:18:37,680 --> 14:18:41,080 perhaps does a bit more there are 22314 14:18:39,320 --> 14:18:43,276 multiple conventions for how you can 22315 14:18:41,080 --> 14:18:44,796 document for the human programmers that 22316 14:18:43,276 --> 14:18:46,796 might be using your function whether 22317 14:18:44,796 --> 14:18:48,880 it's you or a colleague or someone else 22318 14:18:46,796 --> 14:18:50,796 on the internet to actually use these 22319 14:18:48,880 --> 14:18:53,160 doc strings to standardize the 22320 14:18:50,796 --> 14:18:55,560 information they're in so you might see 22321 14:18:53,160 --> 14:18:58,680 this instead using these same triple 22322 14:18:55,560 --> 14:19:00,756 quotes above and below now you might see 22323 14:18:58,680 --> 14:19:03,360 your one sentence uh one sentence 22324 14:19:00,756 --> 14:19:06,520 explanation of the function meow 22325 14:19:03,360 --> 14:19:08,640 meow and times uh sometimes depending on 22326 14:19:06,520 --> 14:19:10,276 the style in use it might actually still 22327 14:19:08,640 --> 14:19:12,040 be on the first line but with a blank 22328 14:19:10,276 --> 14:19:14,640 line below it but I'll keep everything 22329 14:19:12,040 --> 14:19:17,000 uniformly indented and this is a 22330 14:19:14,640 --> 14:19:18,916 convention used by some popular python 22331 14:19:17,000 --> 14:19:22,480 documentation tools as well you would 22332 14:19:18,916 --> 14:19:24,596 say syntax like this Pam n colon and 22333 14:19:22,480 --> 14:19:29,240 then a description of what n is number 22334 14:19:24,596 --> 14:19:31,200 of times to meow then colon Type n colon 22335 14:19:29,240 --> 14:19:35,000 int which just indicates that the type 22336 14:19:31,200 --> 14:19:37,080 of n is an integer then if this function 22337 14:19:35,000 --> 14:19:39,756 could actually raise an exception you 22338 14:19:37,080 --> 14:19:42,320 can document that too and actually it's 22339 14:19:39,756 --> 14:19:44,756 not really well it's arguably my mistake 22340 14:19:42,320 --> 14:19:47,116 here if n comes in as an argument and is 22341 14:19:44,756 --> 14:19:49,276 not in fact an INT maybe it's a float or 22342 14:19:47,116 --> 14:19:51,520 a string or something else the 22343 14:19:49,276 --> 14:19:53,160 multiplication sign here is not going to 22344 14:19:51,520 --> 14:19:55,040 work it's not going to multiply the 22345 14:19:53,160 --> 14:19:57,040 string it's going to trigger what I know 22346 14:19:55,040 --> 14:19:58,320 from experience to be a type error so 22347 14:19:57,040 --> 14:20:00,560 I'm going to go ahead and proactively 22348 14:19:58,320 --> 14:20:02,880 say in my own documentation that this 22349 14:20:00,560 --> 14:20:05,560 function technically if you use it wrong 22350 14:20:02,880 --> 14:20:07,640 could raise a type error even though I'm 22351 14:20:05,560 --> 14:20:10,040 hinting up here with this annotation 22352 14:20:07,640 --> 14:20:11,560 that you should pass in an INT again 22353 14:20:10,040 --> 14:20:13,840 python doesn't enforce that so if you 22354 14:20:11,560 --> 14:20:16,640 pass in a float this might in fact raise 22355 14:20:13,840 --> 14:20:20,160 this function a type error and so that 22356 14:20:16,640 --> 14:20:22,680 might happen if n is not an INT and then 22357 14:20:20,160 --> 14:20:25,200 lastly I might say for clarity sake for 22358 14:20:22,680 --> 14:20:29,080 other programmers this function returns 22359 14:20:25,200 --> 14:20:31,916 a string of n meow one per line and the 22360 14:20:29,080 --> 14:20:33,276 return type of that value R type is 22361 14:20:31,916 --> 14:20:36,116 going to be 22362 14:20:33,276 --> 14:20:38,640 now all of this syntax here as I've used 22363 14:20:36,116 --> 14:20:40,436 it is not python per se this is a 22364 14:20:38,640 --> 14:20:41,956 convention known as restructured text 22365 14:20:40,436 --> 14:20:44,200 which is a form of markdown like 22366 14:20:41,956 --> 14:20:47,040 language that's used for documentation 22367 14:20:44,200 --> 14:20:49,080 for websites for blogs and even more but 22368 14:20:47,040 --> 14:20:51,116 it's one of the popular conventions 22369 14:20:49,080 --> 14:20:53,756 within the world of python to document 22370 14:20:51,116 --> 14:20:55,756 your own functions so this does not have 22371 14:20:53,756 --> 14:20:59,400 anything to do fundamentally with type 22372 14:20:55,756 --> 14:21:02,000 hints type hints are a feature of python 22373 14:20:59,400 --> 14:21:04,956 what I'm doing here is just adhering to 22374 14:21:02,000 --> 14:21:08,116 a third party convention of putting in 22375 14:21:04,956 --> 14:21:10,680 between a Python doc string from the 22376 14:21:08,116 --> 14:21:13,116 start to the end a certain standard 22377 14:21:10,680 --> 14:21:15,240 format so that these third-party tools 22378 14:21:13,116 --> 14:21:17,596 can analyze my code for me top to bottom 22379 14:21:15,240 --> 14:21:19,880 left to right and ideally generate 22380 14:21:17,596 --> 14:21:22,956 documentation for me it can generate a 22381 14:21:19,880 --> 14:21:24,916 PDF a web page or something else so that 22382 14:21:22,956 --> 14:21:27,200 I or my colleagues don't need to not 22383 14:21:24,916 --> 14:21:29,436 just only write code but also manually 22384 14:21:27,200 --> 14:21:31,596 create documentation for our code we can 22385 14:21:29,436 --> 14:21:35,160 keep everything together and use tools 22386 14:21:31,596 --> 14:21:38,756 to generate the same for us any 22387 14:21:35,160 --> 14:21:40,480 questions now on these dock strings 22388 14:21:38,756 --> 14:21:42,916 which again are a Convention of 22389 14:21:40,480 --> 14:21:46,200 documenting your own code often 22390 14:21:42,916 --> 14:21:48,596 following some standard syntax yeah so 22391 14:21:46,200 --> 14:21:51,116 when you say like you would document it 22392 14:21:48,596 --> 14:21:52,956 and put it in a PDF is the purpose of 22393 14:21:51,116 --> 14:21:55,000 doing this to kind of like publish it 22394 14:21:52,956 --> 14:21:57,880 and share your function so other users 22395 14:21:55,000 --> 14:21:59,360 can use it absolutely in the past when 22396 14:21:57,880 --> 14:22:01,756 we have installed some thirdparty 22397 14:21:59,360 --> 14:22:04,160 libraries for instance cow a few weeks 22398 14:22:01,756 --> 14:22:05,640 back call that I showed you what 22399 14:22:04,160 --> 14:22:07,640 functions it had but if you read the 22400 14:22:05,640 --> 14:22:10,200 documentation you might actually see 22401 14:22:07,640 --> 14:22:11,680 that uh it was documented for us by the 22402 14:22:10,200 --> 14:22:13,200 author of that program now I don't 22403 14:22:11,680 --> 14:22:15,116 believe they were using this particular 22404 14:22:13,200 --> 14:22:17,160 syntax but it was definitely useful for 22405 14:22:15,116 --> 14:22:19,160 you and me to be able to read some web 22406 14:22:17,160 --> 14:22:21,560 page or PDF telling us how to use the 22407 14:22:19,160 --> 14:22:23,040 library rather than wasting time reading 22408 14:22:21,560 --> 14:22:25,240 through someone else's code and trying 22409 14:22:23,040 --> 14:22:27,320 to infer what functions exist and how to 22410 14:22:25,240 --> 14:22:29,480 use them it just tends to be much more 22411 14:22:27,320 --> 14:22:31,436 developer friendly to have proper 22412 14:22:29,480 --> 14:22:34,560 documentation for our own code or 22413 14:22:31,436 --> 14:22:37,320 libraries as as well other questions 22414 14:22:34,560 --> 14:22:38,956 yeah um when with Doc strings when you 22415 14:22:37,320 --> 14:22:41,080 when it's used to generate like a PDF or 22416 14:22:38,956 --> 14:22:43,200 whatever does it does it include uh any 22417 14:22:41,080 --> 14:22:45,880 of the code so if you're referencing in 22418 14:22:43,200 --> 14:22:48,116 the in your in your comment uh if you're 22419 14:22:45,880 --> 14:22:49,880 referencing the code in the comment 22420 14:22:48,116 --> 14:22:53,080 itself might not make sense without 22421 14:22:49,880 --> 14:22:55,640 seeing the code does it does do these in 22422 14:22:53,080 --> 14:22:57,400 include it short answer you can do that 22423 14:22:55,640 --> 14:23:00,720 not in the convention I'm using here but 22424 14:22:57,400 --> 14:23:03,880 there's actually a clever way to write 22425 14:23:00,720 --> 14:23:06,360 in your doc strings sample inputs to 22426 14:23:03,880 --> 14:23:07,956 your functions and Sample outputs for 22427 14:23:06,360 --> 14:23:10,116 your functions and if you use a 22428 14:23:07,956 --> 14:23:12,520 different tool that we've not discussed 22429 14:23:10,116 --> 14:23:14,840 that tool will run your code using those 22430 14:23:12,520 --> 14:23:16,956 sample inputs it will check that your 22431 14:23:14,840 --> 14:23:18,640 outputs match your sample outputs and if 22432 14:23:16,956 --> 14:23:20,840 not the program will yell at you saying 22433 14:23:18,640 --> 14:23:22,956 you've got a bug somewhere so this is 22434 14:23:20,840 --> 14:23:25,320 just another way where you can use doc 22435 14:23:22,956 --> 14:23:28,480 strings to not only document but even 22436 14:23:25,320 --> 14:23:30,160 catch errors in your code this has been 22437 14:23:28,480 --> 14:23:31,640 a lot and there's a bit more to go why 22438 14:23:30,160 --> 14:23:33,360 don't we go ahead here and take a five 22439 14:23:31,640 --> 14:23:35,360 minute break and we resume we'll take a 22440 14:23:33,360 --> 14:23:38,040 look at yet another feature of python 22441 14:23:35,360 --> 14:23:40,040 yet another library to write code faster 22442 14:23:38,040 --> 14:23:42,400 all right suppose we want to modify this 22443 14:23:40,040 --> 14:23:44,040 meow program to actually take its input 22444 14:23:42,400 --> 14:23:45,640 not from the input function and the 22445 14:23:44,040 --> 14:23:47,040 blinking prompt but from the command 22446 14:23:45,640 --> 14:23:48,480 line recall in our discussion of 22447 14:23:47,040 --> 14:23:51,276 libraries that you could use something 22448 14:23:48,480 --> 14:23:53,040 like cy. RGV to get at commandline 22449 14:23:51,276 --> 14:23:54,400 arguments that a human has provided when 22450 14:23:53,040 --> 14:23:56,640 you're running your program so why don't 22451 14:23:54,400 --> 14:23:58,916 we whip up a version of meow that uses 22452 14:23:56,640 --> 14:24:00,320 commandline arguments instead of again 22453 14:23:58,916 --> 14:24:02,080 input so I'm going to go ahead and 22454 14:24:00,320 --> 14:24:04,320 delete what we've done here thus far and 22455 14:24:02,080 --> 14:24:06,756 let me propose that we import CIS as 22456 14:24:04,320 --> 14:24:10,480 we've done in the past and let's do this 22457 14:24:06,756 --> 14:24:12,240 how about if the user does not type any 22458 14:24:10,480 --> 14:24:14,040 command line arguments then my program 22459 14:24:12,240 --> 14:24:17,000 will just meow once just so that it does 22460 14:24:14,040 --> 14:24:19,436 something visually interesting otherwise 22461 14:24:17,000 --> 14:24:22,360 let's also give the user an option to 22462 14:24:19,436 --> 14:24:24,640 specify how many times I want the cat to 22463 14:24:22,360 --> 14:24:27,436 meow so let's start simple let's first 22464 14:24:24,640 --> 14:24:31,880 of all go ahead and do this if the 22465 14:24:27,436 --> 14:24:33,840 length of cy. argv equals equals 1 that 22466 14:24:31,880 --> 14:24:37,240 is the user only typed the name of the 22467 14:24:33,840 --> 14:24:39,040 program and nothing else after the uh in 22468 14:24:37,240 --> 14:24:42,200 their command then let's go ahead and 22469 14:24:39,040 --> 14:24:44,796 just print out one meow like this uh 22470 14:24:42,200 --> 14:24:46,840 else for now let's go ahead and print 22471 14:24:44,796 --> 14:24:49,160 out something like this else go ahead 22472 14:24:46,840 --> 14:24:52,200 and print out let's say usage for the 22473 14:24:49,160 --> 14:24:53,880 program which will be usage of meow. py 22474 14:24:52,200 --> 14:24:56,000 just so that the user knows that the 22475 14:24:53,880 --> 14:24:57,796 program itself is called meow. py all 22476 14:24:56,000 --> 14:25:00,400 right now let me go down to my terminal 22477 14:24:57,796 --> 14:25:02,640 window and start to type python of meow. 22478 14:25:00,400 --> 14:25:05,956 and at this point notice that the length 22479 14:25:02,640 --> 14:25:07,916 of cy. argv should indeed be one why 22480 14:25:05,956 --> 14:25:10,756 well python the name doesn't end up in 22481 14:25:07,916 --> 14:25:12,916 cy. arv at all ever but meow. Pi the 22482 14:25:10,756 --> 14:25:16,160 name of the file does and it's going to 22483 14:25:12,916 --> 14:25:17,680 go in cy. argv 0 but that's only one 22484 14:25:16,160 --> 14:25:19,520 element so the length of this thing is 22485 14:25:17,680 --> 14:25:20,916 one there's nothing more to the right so 22486 14:25:19,520 --> 14:25:24,160 when I hit enter now we should see 22487 14:25:20,916 --> 14:25:26,796 indeed one meow if I don't cooperate 22488 14:25:24,160 --> 14:25:28,956 suppose I do something like meow's three 22489 14:25:26,796 --> 14:25:31,000 enter then I'm going to see a reminder 22490 14:25:28,956 --> 14:25:32,596 that this is how you use the program and 22491 14:25:31,000 --> 14:25:35,080 this is a common convention to literally 22492 14:25:32,596 --> 14:25:36,640 print out the word usage a colon then 22493 14:25:35,080 --> 14:25:38,720 the name of the program and maybe some 22494 14:25:36,640 --> 14:25:40,720 explanation of how to use it so I'm 22495 14:25:38,720 --> 14:25:42,596 keeping it very simple but let's be a 22496 14:25:40,720 --> 14:25:45,276 little fancier what if I really wanted 22497 14:25:42,596 --> 14:25:47,640 the user to type in maybe not three but 22498 14:25:45,276 --> 14:25:50,276 something more sophisticated and in fact 22499 14:25:47,640 --> 14:25:53,040 when uh controlling programs from the 22500 14:25:50,276 --> 14:25:55,480 command line it's very common to provide 22501 14:25:53,040 --> 14:25:58,480 what are often called switches or Flags 22502 14:25:55,480 --> 14:26:01,160 whereby you pass in something like 22503 14:25:58,480 --> 14:26:03,680 dashn which semantically means this 22504 14:26:01,160 --> 14:26:05,480 number of times then off in a space and 22505 14:26:03,680 --> 14:26:07,320 then something like the number three 22506 14:26:05,480 --> 14:26:09,200 this still allows me to do other things 22507 14:26:07,320 --> 14:26:11,080 at the command line if I want but the 22508 14:26:09,200 --> 14:26:12,840 fact that I've standardized on how I'm 22509 14:26:11,080 --> 14:26:15,916 providing command line arguments to this 22510 14:26:12,840 --> 14:26:18,956 program with dashn three is just a more 22511 14:26:15,916 --> 14:26:20,756 reliable way now of my program knowing 22512 14:26:18,956 --> 14:26:23,840 what does the three mean it's a little 22513 14:26:20,756 --> 14:26:25,680 less obvious if I just do meow. ppace 3 22514 14:26:23,840 --> 14:26:28,160 well what does the three mean at least 22515 14:26:25,680 --> 14:26:29,720 with syntax like dn3 especially if 22516 14:26:28,160 --> 14:26:32,276 you've read the documentation for this 22517 14:26:29,720 --> 14:26:34,640 program ultimately oh dashn means number 22518 14:26:32,276 --> 14:26:36,360 of times got it it's a way of passing in 22519 14:26:34,640 --> 14:26:38,520 two additional arguments but that have 22520 14:26:36,360 --> 14:26:42,840 some relationship between them so how do 22521 14:26:38,520 --> 14:26:44,640 I modify my program to understand- N3 22522 14:26:42,840 --> 14:26:49,720 well if I'm using CIS like this I could 22523 14:26:44,640 --> 14:26:52,360 do this L if the length of cy. argv 22524 14:26:49,720 --> 14:26:57,160 equals this time three because notice 22525 14:26:52,360 --> 14:26:59,796 there's one two three things at my 22526 14:26:57,160 --> 14:27:02,360 prompt so cy. arv 0 1 and two three 22527 14:26:59,796 --> 14:27:06,956 things total separated by spaces if 22528 14:27:02,360 --> 14:27:12,080 equals 3 and let's be safe and cy. arv 22529 14:27:06,956 --> 14:27:14,720 bracket 1 equals equals DN then let's go 22530 14:27:12,080 --> 14:27:18,720 ahead and do this let's go ahead and 22531 14:27:14,720 --> 14:27:22,680 convert uh cy. arv of 22532 14:27:18,720 --> 14:27:25,116 two to an integer and assign it to a 22533 14:27:22,680 --> 14:27:27,276 variable for instance called n and then 22534 14:27:25,116 --> 14:27:30,116 let's go ahead and do this for uh 22535 14:27:27,276 --> 14:27:32,400 underscore in the range of n let's go 22536 14:27:30,116 --> 14:27:33,680 ahead and print out some of these meaps 22537 14:27:32,400 --> 14:27:35,560 now there's still an opportunity maybe 22538 14:27:33,680 --> 14:27:36,640 to consolidate my print lines with meow 22539 14:27:35,560 --> 14:27:38,520 but for now I'm going to keep these 22540 14:27:36,640 --> 14:27:41,000 ideas separate so I'm going to handle 22541 14:27:38,520 --> 14:27:42,756 the default case with no arguments up 22542 14:27:41,000 --> 14:27:44,880 here as before and now more 22543 14:27:42,756 --> 14:27:46,756 interestingly I'm going to do this to be 22544 14:27:44,880 --> 14:27:48,756 clear I'm going to check if the user 22545 14:27:46,756 --> 14:27:52,080 gave me three command line arguments the 22546 14:27:48,756 --> 14:27:54,680 name of the program- n and a number if 22547 14:27:52,080 --> 14:27:59,640 indeed the second thing they gave me in 22548 14:27:54,680 --> 14:28:01,320 cy. arv of1 equals equals uh dasn then 22549 14:27:59,640 --> 14:28:04,880 I'm going to assume that the next thing 22550 14:28:01,320 --> 14:28:07,040 CIS V of two is going to be an integer 22551 14:28:04,880 --> 14:28:09,436 and I'll convert it to such and store it 22552 14:28:07,040 --> 14:28:11,520 in this variable n and now just using a 22553 14:28:09,436 --> 14:28:13,596 loop I'm going to print out meow that 22554 14:28:11,520 --> 14:28:15,640 many times all right so it's kind of a 22555 14:28:13,596 --> 14:28:17,596 combination of our earlier focus on 22556 14:28:15,640 --> 14:28:19,520 Loops our earlier focus on command line 22557 14:28:17,596 --> 14:28:21,640 arguments just creating a program that 22558 14:28:19,520 --> 14:28:23,680 allow me to claim is representative of 22559 14:28:21,640 --> 14:28:25,080 how a lot of command line programs work 22560 14:28:23,680 --> 14:28:27,480 even though we've typically not used 22561 14:28:25,080 --> 14:28:29,436 many like this but it's very common to 22562 14:28:27,480 --> 14:28:31,200 configure a program one you're about to 22563 14:28:29,436 --> 14:28:32,480 run it at the command line with 22564 14:28:31,200 --> 14:28:34,436 something like these command line 22565 14:28:32,480 --> 14:28:36,436 arguments like dashn or Dash something 22566 14:28:34,436 --> 14:28:40,240 else now I'm going to go ahead and hit 22567 14:28:36,436 --> 14:28:43,840 enter and I think I should see indeed 22568 14:28:40,240 --> 14:28:47,040 three meows by contrast if I do two at 22569 14:28:43,840 --> 14:28:49,880 the end I should see two meows if I do 22570 14:28:47,040 --> 14:28:52,160 one I should see one meow and frankly if 22571 14:28:49,880 --> 14:28:54,520 I just omit this all together I should 22572 14:28:52,160 --> 14:28:58,596 see one meow as well because that was my 22573 14:28:54,520 --> 14:29:01,360 default case earlier and now let me 22574 14:28:58,596 --> 14:29:02,796 allow us to uh assume that this program 22575 14:29:01,360 --> 14:29:04,596 eventually gets more more complicated 22576 14:29:02,796 --> 14:29:07,000 right let's imagine a world where I 22577 14:29:04,596 --> 14:29:10,596 don't want to support just dasn maybe I 22578 14:29:07,000 --> 14:29:12,596 want to support- a and-b and- c and d d 22579 14:29:10,596 --> 14:29:13,840 and a whole lot of others or heck at 22580 14:29:12,596 --> 14:29:16,360 that point I should maybe give them 22581 14:29:13,840 --> 14:29:19,200 words so maybe it's Das Dash number it's 22582 14:29:16,360 --> 14:29:21,436 indeed a convention uh in Computing 22583 14:29:19,200 --> 14:29:23,916 typically to use single dashes with a 22584 14:29:21,436 --> 14:29:25,756 single letter like n but use double 22585 14:29:23,916 --> 14:29:27,680 dashes if you're actually using a whole 22586 14:29:25,756 --> 14:29:30,480 word like number so the command line 22587 14:29:27,680 --> 14:29:32,840 argument might be dhn or maybe it's Das 22588 14:29:30,480 --> 14:29:34,880 Das number but you can imagine just how 22589 14:29:32,840 --> 14:29:38,400 complicated the code gets if now you 22590 14:29:34,880 --> 14:29:39,796 want to support dn- A- B- C and so forth 22591 14:29:38,400 --> 14:29:41,276 you're going to have to be checking all 22592 14:29:39,796 --> 14:29:42,680 over the place and what if they come in 22593 14:29:41,276 --> 14:29:45,400 a different order you're going to have 22594 14:29:42,680 --> 14:29:47,000 to check is dashn first or is it second 22595 14:29:45,400 --> 14:29:49,560 or is it third or is it fourth I mean 22596 14:29:47,000 --> 14:29:51,756 this just becomes very painful very 22597 14:29:49,560 --> 14:29:53,400 quickly just to do something relatively 22598 14:29:51,756 --> 14:29:55,756 simple like allow the user to pass 22599 14:29:53,400 --> 14:29:58,480 command line arguments into your program 22600 14:29:55,756 --> 14:30:01,200 well this is why as always there exist 22601 14:29:58,480 --> 14:30:03,160 libraries and another library that comes 22602 14:30:01,200 --> 14:30:04,840 with python that's probably worth 22603 14:30:03,160 --> 14:30:07,160 knowing something about is this one here 22604 14:30:04,840 --> 14:30:09,720 called ARG parse in fact with a lot of 22605 14:30:07,160 --> 14:30:12,720 the tools I myself or cs50's team writes 22606 14:30:09,720 --> 14:30:14,796 in Python we very frequently use arars 22607 14:30:12,720 --> 14:30:16,680 whenever they are more complicated than 22608 14:30:14,796 --> 14:30:18,840 a lot of our class demos and a little 22609 14:30:16,680 --> 14:30:20,436 more similar to this one where we want 22610 14:30:18,840 --> 14:30:22,916 to allow the user to pass in 22611 14:30:20,436 --> 14:30:25,400 configuration options at the command 22612 14:30:22,916 --> 14:30:28,916 line and by supporting things like dashn 22613 14:30:25,400 --> 14:30:31,720 or- a or- b or- c arars is a library 22614 14:30:28,916 --> 14:30:33,916 that per its documentation just handles 22615 14:30:31,720 --> 14:30:36,240 all all of this parsing so to speak this 22616 14:30:33,916 --> 14:30:38,116 analysis of command line Arguments for 22617 14:30:36,240 --> 14:30:39,640 you automatically so you can focus on 22618 14:30:38,116 --> 14:30:41,916 writing the interesting parts of your 22619 14:30:39,640 --> 14:30:44,276 program not the command line arguments 22620 14:30:41,916 --> 14:30:46,480 part so how might we use this well let 22621 14:30:44,276 --> 14:30:48,360 me go back to vs code here let me clear 22622 14:30:46,480 --> 14:30:51,000 my terminal window and let me propose 22623 14:30:48,360 --> 14:30:52,560 that I rewrite this using not CIS but 22624 14:30:51,000 --> 14:30:54,040 actually using ARG parse and I'm going 22625 14:30:52,560 --> 14:30:55,956 to start a little simple and then build 22626 14:30:54,040 --> 14:30:59,480 back up so let me throw all of this away 22627 14:30:55,956 --> 14:31:02,040 for now and instead import ARG parse uh 22628 14:30:59,480 --> 14:31:04,160 ARG parse stands for argument parser to 22629 14:31:02,040 --> 14:31:06,240 parse something means to read it uh kind 22630 14:31:04,160 --> 14:31:08,436 of pick it apart to analyze it so this 22631 14:31:06,240 --> 14:31:10,200 is indeed going to do just that for me 22632 14:31:08,436 --> 14:31:11,720 now let me go ahead and do this and for 22633 14:31:10,200 --> 14:31:13,400 this Library it's helpful to know a 22634 14:31:11,720 --> 14:31:15,200 little object-oriented programming like 22635 14:31:13,400 --> 14:31:17,040 we all now do I'm going to create a 22636 14:31:15,200 --> 14:31:18,680 variable called parser I could call it 22637 14:31:17,040 --> 14:31:21,080 anything I want I'm going to set it 22638 14:31:18,680 --> 14:31:25,436 equal to the return value of ARG parse 22639 14:31:21,080 --> 14:31:28,080 dot ARG you parser with a capital A and 22640 14:31:25,436 --> 14:31:30,596 a capital P A Constructor for a class 22641 14:31:28,080 --> 14:31:32,720 called argument parser that comes with 22642 14:31:30,596 --> 14:31:35,480 python itself within in this Library 22643 14:31:32,720 --> 14:31:37,840 here now I'm going to configure this 22644 14:31:35,480 --> 14:31:39,680 argument parser to know about the 22645 14:31:37,840 --> 14:31:41,880 specific command line arguments that I 22646 14:31:39,680 --> 14:31:44,796 myself want to support in my program so 22647 14:31:41,880 --> 14:31:47,436 I'm going to do this parser do addore 22648 14:31:44,796 --> 14:31:49,680 argument so that's apparently a method 22649 14:31:47,436 --> 14:31:53,160 in the parser object I'm going to add an 22650 14:31:49,680 --> 14:31:54,680 argument of- N Easy enough now I'm going 22651 14:31:53,160 --> 14:31:56,276 to go ahead and actually parse the 22652 14:31:54,680 --> 14:31:57,840 command line arguments I'm going to do 22653 14:31:56,276 --> 14:32:02,040 args or I could call the variable 22654 14:31:57,840 --> 14:32:04,360 anything I want parser dop parse ARS and 22655 14:32:02,040 --> 14:32:07,436 by default parse ARS is going to 22656 14:32:04,360 --> 14:32:09,796 automatically look at cis.org V for me I 22657 14:32:07,436 --> 14:32:12,436 don't need to import CIS myself I can 22658 14:32:09,796 --> 14:32:15,080 leave the argument parser uh its code to 22659 14:32:12,436 --> 14:32:17,040 import CIS look at cy. argv and figure 22660 14:32:15,080 --> 14:32:20,116 out where dashn or anything else 22661 14:32:17,040 --> 14:32:22,720 actually is and what's nice now because 22662 14:32:20,116 --> 14:32:25,116 this line of code here results in the 22663 14:32:22,720 --> 14:32:27,840 parser having parsed all of the command 22664 14:32:25,116 --> 14:32:30,400 line arguments I now have this object in 22665 14:32:27,840 --> 14:32:32,360 this variable called args inside of 22666 14:32:30,400 --> 14:32:34,320 which are all of the values of those 22667 14:32:32,360 --> 14:32:36,320 command line arguments no matter what 22668 14:32:34,320 --> 14:32:37,796 order they appeared in not such a big 22669 14:32:36,320 --> 14:32:39,840 deal when I've only got one because it's 22670 14:32:37,796 --> 14:32:42,640 only going to go in one place at the end 22671 14:32:39,840 --> 14:32:44,040 but if I've got- n- A- B- C you could 22672 14:32:42,640 --> 14:32:45,520 imagine them being in all different 22673 14:32:44,040 --> 14:32:47,596 orders they definitely don't have to be 22674 14:32:45,520 --> 14:32:49,360 alphabetical the user should be able to 22675 14:32:47,596 --> 14:32:51,640 type them in any order they want that's 22676 14:32:49,360 --> 14:32:53,880 better for usability ARG parser is going 22677 14:32:51,640 --> 14:32:55,520 to figure all of that out for me and all 22678 14:32:53,880 --> 14:32:59,200 I have to do now is this if I want to 22679 14:32:55,520 --> 14:33:01,596 iterate over that many uh numbers of 22680 14:32:59,200 --> 14:33:05,840 arguments and that many Ms rather I can 22681 14:33:01,596 --> 14:33:09,240 do this 4core in the range of the int 22682 14:33:05,840 --> 14:33:11,240 conversion of args do n so dot is the 22683 14:33:09,240 --> 14:33:14,040 syntax we kept using to access things 22684 14:33:11,240 --> 14:33:16,240 like properties inside of an object and 22685 14:33:14,040 --> 14:33:17,840 that's what args is it's an object 22686 14:33:16,240 --> 14:33:19,840 returned by the parse ARS function form 22687 14:33:17,840 --> 14:33:23,116 me I'm going to go ahead now and print 22688 14:33:19,840 --> 14:33:25,400 out quote unquote meow this many times 22689 14:33:23,116 --> 14:33:27,956 so it's not super simple like these are 22690 14:33:25,400 --> 14:33:30,400 three new lines of code I need to write 22691 14:33:27,956 --> 14:33:32,276 and rather understand but it's already a 22692 14:33:30,400 --> 14:33:34,596 little simpler and more compact and my 22693 14:33:32,276 --> 14:33:36,720 if and my L if and my ores and my ANS 22694 14:33:34,596 --> 14:33:39,000 and all of that Boolean logic it's 22695 14:33:36,720 --> 14:33:40,436 handling a lot of this for me so if I 22696 14:33:39,000 --> 14:33:43,916 didn't make any mistakes let me run 22697 14:33:40,436 --> 14:33:47,040 python now of meow. enter and I did make 22698 14:33:43,916 --> 14:33:49,796 a mistake here I did make a mistake 22699 14:33:47,040 --> 14:33:51,400 what's what's wrong here now what's 22700 14:33:49,796 --> 14:33:53,400 wrong well I definitely didn't run it 22701 14:33:51,400 --> 14:33:57,116 the way I intend so 22702 14:33:53,400 --> 14:33:59,640 dhn3 enter so it does work but if I 22703 14:33:57,116 --> 14:34:01,796 don't cooperate this actually seems to 22704 14:33:59,640 --> 14:34:04,000 be a worse version if I don't pass in 22705 14:34:01,796 --> 14:34:06,560 dhn and a number it just errors with a 22706 14:34:04,000 --> 14:34:08,160 type error int must be a string none is 22707 14:34:06,560 --> 14:34:10,240 what came back so there's clearly an 22708 14:34:08,160 --> 14:34:12,680 error here but the library is more 22709 14:34:10,240 --> 14:34:15,040 flexible I can actually provide some 22710 14:34:12,680 --> 14:34:17,320 documentation on how to use this thing 22711 14:34:15,040 --> 14:34:19,436 so how do I know how to use this well 22712 14:34:17,320 --> 14:34:21,520 typically it's conventional in Python 22713 14:34:19,436 --> 14:34:24,400 and in a lot of programming environments 22714 14:34:21,520 --> 14:34:29,000 to run a program with a special argument 22715 14:34:24,400 --> 14:34:30,840 DH or Das dashel and almost always I 22716 14:34:29,000 --> 14:34:32,756 will claim you'll then see some kind of 22717 14:34:30,840 --> 14:34:35,116 usage information indeed that's what I'm 22718 14:34:32,756 --> 14:34:38,116 looking at now I just ran python of 22719 14:34:35,116 --> 14:34:40,596 meow. space- I'll do it again let me 22720 14:34:38,116 --> 14:34:43,436 clear my screen and this time do d-el in 22721 14:34:40,596 --> 14:34:45,796 English enter and I see the same thing 22722 14:34:43,436 --> 14:34:48,640 it's not very useful at the moment it 22723 14:34:45,796 --> 14:34:50,200 just shows me what the usage is up here 22724 14:34:48,640 --> 14:34:52,480 and this is kind of interesting this is 22725 14:34:50,200 --> 14:34:53,840 a standard syntax Inu Computing and 22726 14:34:52,480 --> 14:34:55,796 we've kind of seen it in Python's 22727 14:34:53,840 --> 14:34:57,240 documentation before this just means 22728 14:34:55,796 --> 14:35:00,640 that the program's name is of course 22729 14:34:57,240 --> 14:35:03,320 meow. pie square brackets as almost 22730 14:35:00,640 --> 14:35:06,276 always in documentation means it's 22731 14:35:03,320 --> 14:35:09,596 optional so I don't have to type-h but I 22732 14:35:06,276 --> 14:35:12,240 can I don't have to type-n and another 22733 14:35:09,596 --> 14:35:14,360 value but I can and then down here is 22734 14:35:12,240 --> 14:35:16,360 some explanation of these options and 22735 14:35:14,360 --> 14:35:19,160 more verbally showing me that I can also 22736 14:35:16,360 --> 14:35:20,880 do Dash dasel and not just Dash but this 22737 14:35:19,160 --> 14:35:22,040 is so generic this has nothing to do 22738 14:35:20,880 --> 14:35:23,956 with my program this is not going to 22739 14:35:22,040 --> 14:35:25,880 help my users when I actually release 22740 14:35:23,956 --> 14:35:27,640 this software for the world so let me go 22741 14:35:25,880 --> 14:35:29,640 ahead and improve it let me add a 22742 14:35:27,640 --> 14:35:32,480 description to my argument parser that 22743 14:35:29,640 --> 14:35:34,320 the humans will see meow like a cat 22744 14:35:32,480 --> 14:35:35,840 quote unquote is going to be the value 22745 14:35:34,320 --> 14:35:38,756 of this named parameter called 22746 14:35:35,840 --> 14:35:41,796 description and let me also add a help 22747 14:35:38,756 --> 14:35:44,200 parameter to my dashn argument that just 22748 14:35:41,796 --> 14:35:46,840 explains what dashn means number of 22749 14:35:44,200 --> 14:35:48,680 times to meow quote unquote I'm not 22750 14:35:46,840 --> 14:35:50,360 going to change anything else but I am 22751 14:35:48,680 --> 14:35:52,956 going to go back to my terminal window 22752 14:35:50,360 --> 14:35:56,840 and run python of meow uh I'm going to 22753 14:35:52,956 --> 14:35:59,916 run python of meow. py-h or equivalently 22754 14:35:56,840 --> 14:36:02,276 d-el and now notice that this is a 22755 14:35:59,916 --> 14:36:04,276 little more user friendly if I scroll up 22756 14:36:02,276 --> 14:36:05,916 we still see the same usage but there's 22757 14:36:04,276 --> 14:36:07,640 a quick sentence in English of 22758 14:36:05,916 --> 14:36:10,560 explanation that this program meows like 22759 14:36:07,640 --> 14:36:13,200 a cat and if I look at the options now 22760 14:36:10,560 --> 14:36:16,520 oh that's what N means it's the number 22761 14:36:13,200 --> 14:36:18,480 of times to meow and this capital n a 22762 14:36:16,520 --> 14:36:20,360 middle variable if you will is just 22763 14:36:18,480 --> 14:36:24,040 indicating to me that I need to type a 22764 14:36:20,360 --> 14:36:27,360 number by convention after the lowercase 22765 14:36:24,040 --> 14:36:29,480 dasn so it would be nice though all that 22766 14:36:27,360 --> 14:36:31,320 said if my program still didn't just 22767 14:36:29,480 --> 14:36:33,560 break when I run it without any command 22768 14:36:31,320 --> 14:36:35,640 line arguments right ideally my program 22769 14:36:33,560 --> 14:36:38,720 would handle this just like my manual 22770 14:36:35,640 --> 14:36:40,916 version did when I used cy. Arvy myself 22771 14:36:38,720 --> 14:36:42,916 so we just need to add a little more uh 22772 14:36:40,916 --> 14:36:45,436 functionality to this library and if I 22773 14:36:42,916 --> 14:36:47,840 read the documentation I'll see that add 22774 14:36:45,436 --> 14:36:50,276 argument takes yet another named 22775 14:36:47,840 --> 14:36:53,000 argument if you want you can specify a 22776 14:36:50,276 --> 14:36:55,000 default value for dashn for instance one 22777 14:36:53,000 --> 14:36:57,240 and I'll do that there and you can 22778 14:36:55,000 --> 14:36:59,080 further specify that it's got to be an 22779 14:36:57,240 --> 14:37:02,000 INT and what this will additionally 22780 14:36:59,080 --> 14:37:04,276 allow me to do is if I tell AR parser to 22781 14:37:02,000 --> 14:37:06,200 make sure that the value of dasn is an 22782 14:37:04,276 --> 14:37:08,680 INT I don't need to do the conversion 22783 14:37:06,200 --> 14:37:10,840 manually I can just trust down on line 22784 14:37:08,680 --> 14:37:13,916 seven that when I access the property 22785 14:37:10,840 --> 14:37:16,000 called n inside of my args object it's 22786 14:37:13,916 --> 14:37:18,560 going to be automatically an INT for me 22787 14:37:16,000 --> 14:37:20,680 and again this is the value of a library 22788 14:37:18,560 --> 14:37:22,560 let it do all of the work for you so you 22789 14:37:20,680 --> 14:37:24,400 can get back to focusing on the 22790 14:37:22,560 --> 14:37:26,276 interesting project at hand whatever 22791 14:37:24,400 --> 14:37:27,680 problem it is you're trying to solve 22792 14:37:26,276 --> 14:37:30,040 like in this case granted not that 22793 14:37:27,680 --> 14:37:33,040 interesting but meowing like a cat let 22794 14:37:30,040 --> 14:37:36,436 me go ahead now and run python of meow. 22795 14:37:33,040 --> 14:37:39,276 and hit enter this time no arguments and 22796 14:37:36,436 --> 14:37:42,840 now it meows why because I specified 22797 14:37:39,276 --> 14:37:44,116 that if I don't as a user specify dashn 22798 14:37:42,840 --> 14:37:46,080 it's going to have a default value of 22799 14:37:44,116 --> 14:37:48,680 one apparently and I don't have to 22800 14:37:46,080 --> 14:37:50,596 convert that value from a stir to an INT 22801 14:37:48,680 --> 14:37:52,720 because I told AR parser please just 22802 14:37:50,596 --> 14:37:57,116 make this an INT for 22803 14:37:52,720 --> 14:37:59,560 me any questions now on AR pars were 22804 14:37:57,116 --> 14:38:01,880 really this principle of just 22805 14:37:59,560 --> 14:38:03,680 Outsourcing the commodity stuff the 22806 14:38:01,880 --> 14:38:05,680 stuff that everyone's program eventually 22807 14:38:03,680 --> 14:38:08,320 needs to do so that you can focus on the 22808 14:38:05,680 --> 14:38:11,320 juicy part yourself what does ARS that 22809 14:38:08,320 --> 14:38:14,160 end contain what does args do n contain 22810 14:38:11,320 --> 14:38:18,520 it contains the integer that the human 22811 14:38:14,160 --> 14:38:21,436 typed after a space after 22812 14:38:18,520 --> 14:38:24,756 dashn good question other 22813 14:38:21,436 --> 14:38:27,840 questions yeah did uh uh the the when 22814 14:38:24,756 --> 14:38:30,240 you specify the type um for the 22815 14:38:27,840 --> 14:38:32,680 argument uh what happens if does that 22816 14:38:30,240 --> 14:38:34,680 basically handle the ex C if if the user 22817 14:38:32,680 --> 14:38:36,200 inputs a string in this case a really 22818 14:38:34,680 --> 14:38:38,080 good question suppose that the human 22819 14:38:36,200 --> 14:38:39,756 does not type a number and therefore not 22820 14:38:38,080 --> 14:38:44,480 an INT well let's see what happen so 22821 14:38:39,756 --> 14:38:47,596 python of meow. dasn dog where dog is 22822 14:38:44,480 --> 14:38:49,796 obviously not a number enter and voila 22823 14:38:47,596 --> 14:38:51,756 we see an automatically generated error 22824 14:38:49,796 --> 14:38:53,720 message little cryptic admittedly but 22825 14:38:51,756 --> 14:38:56,680 I'm seeing a reminder of what the usage 22826 14:38:53,720 --> 14:38:58,596 is and a minor explanation of what is 22827 14:38:56,680 --> 14:39:00,360 invalid about this and again this is 22828 14:38:58,596 --> 14:39:02,320 what allows you this is what allows me 22829 14:39:00,360 --> 14:39:04,200 to like focus on writing actual code we 22830 14:39:02,320 --> 14:39:06,640 care about and just letting the library 22831 14:39:04,200 --> 14:39:08,796 automate some of this stuff for us all 22832 14:39:06,640 --> 14:39:10,276 right well allow me to propose now that 22833 14:39:08,796 --> 14:39:12,560 we take a look at one other feature of 22834 14:39:10,276 --> 14:39:14,400 python that we've seen before but it 22835 14:39:12,560 --> 14:39:16,680 turns out we can use it even more 22836 14:39:14,400 --> 14:39:18,320 powerfully as our programs become more 22837 14:39:16,680 --> 14:39:20,080 sophisticated and the problems we're 22838 14:39:18,320 --> 14:39:22,796 trying to solve themselves become more 22839 14:39:20,080 --> 14:39:26,116 involved let me go ahead and re uh turn 22840 14:39:22,796 --> 14:39:27,956 to vs code closing out meow. and 22841 14:39:26,116 --> 14:39:31,520 creating a new file for instance called 22842 14:39:27,956 --> 14:39:33,080 unpack. so code of unpack. py and let me 22843 14:39:31,520 --> 14:39:34,360 just remind us like what we mean by 22844 14:39:33,080 --> 14:39:36,240 unpacking because this is actually a 22845 14:39:34,360 --> 14:39:38,200 feature of python that we've seen before 22846 14:39:36,240 --> 14:39:39,640 for instance suppose that I write a 22847 14:39:38,200 --> 14:39:42,480 program that prompts the user for their 22848 14:39:39,640 --> 14:39:44,200 name like David Space men wouldn't it be 22849 14:39:42,480 --> 14:39:46,956 nice if we could C of sort of split the 22850 14:39:44,200 --> 14:39:48,400 user's name into two separate variables 22851 14:39:46,956 --> 14:39:49,560 and when we've done this in the past 22852 14:39:48,400 --> 14:39:51,916 we've done it in a few different ways 22853 14:39:49,560 --> 14:39:54,520 but one of them involved unpacking a 22854 14:39:51,916 --> 14:39:56,796 single value uh that comes back from 22855 14:39:54,520 --> 14:39:58,520 that like a list or uh some other data 22856 14:39:56,796 --> 14:40:00,756 structure and putting it immediately 22857 14:39:58,520 --> 14:40:03,640 into two variables so let's do this here 22858 14:40:00,756 --> 14:40:06,680 let me go ahead and call uh the input 22859 14:40:03,640 --> 14:40:08,956 function asking someone what's your name 22860 14:40:06,680 --> 14:40:11,400 question mark then let me go ahead and 22861 14:40:08,956 --> 14:40:12,956 just split a little naively on a single 22862 14:40:11,400 --> 14:40:14,916 space so I'm assuming that the only 22863 14:40:12,956 --> 14:40:17,480 users at the moment are people like me 22864 14:40:14,916 --> 14:40:19,480 David Space men no middle names no 22865 14:40:17,480 --> 14:40:21,116 multiple names it's just one and two 22866 14:40:19,480 --> 14:40:23,040 which itself could be buggy for other 22867 14:40:21,116 --> 14:40:25,436 users but for now I'm keeping it simple 22868 14:40:23,040 --> 14:40:27,000 just to remind us that I can now unpack 22869 14:40:25,436 --> 14:40:30,276 that return value with something like 22870 14:40:27,000 --> 14:40:32,240 first underscore last equals the return 22871 14:40:30,276 --> 14:40:33,720 value of input and now I can go ahead 22872 14:40:32,240 --> 14:40:36,276 and do something like this like printing 22873 14:40:33,720 --> 14:40:38,080 out with an F string hello comma and 22874 14:40:36,276 --> 14:40:40,080 then in curly braces first if I just 22875 14:40:38,080 --> 14:40:43,000 want to greet myself or any other user 22876 14:40:40,080 --> 14:40:44,680 as hello David without the last name and 22877 14:40:43,000 --> 14:40:46,596 frankly if I'm not using the last name 22878 14:40:44,680 --> 14:40:48,880 recall that a python convention is just 22879 14:40:46,596 --> 14:40:50,680 to name it underscore to make clear that 22880 14:40:48,880 --> 14:40:52,000 you know you're not using that value but 22881 14:40:50,680 --> 14:40:55,160 it does need to be there because you're 22882 14:40:52,000 --> 14:40:57,320 unpacking two values at once so if I run 22883 14:40:55,160 --> 14:40:59,360 this it won't be all that unfamiliar I'm 22884 14:40:57,320 --> 14:41:00,916 just going to run now python of unpack. 22885 14:40:59,360 --> 14:41:03,240 I'll type in David maen which has a 22886 14:41:00,916 --> 14:41:05,956 single space and there we have it hello 22887 14:41:03,240 --> 14:41:09,200 comma David well it turns out that 22888 14:41:05,956 --> 14:41:10,840 there's other ways to unpack values and 22889 14:41:09,200 --> 14:41:12,680 there's other features that python 22890 14:41:10,840 --> 14:41:15,596 offers especially when it comes to 22891 14:41:12,680 --> 14:41:17,680 defining and using functions and this is 22892 14:41:15,596 --> 14:41:19,160 slightly more intermediate functionality 22893 14:41:17,680 --> 14:41:21,040 if you will that's useful because you 22894 14:41:19,160 --> 14:41:22,956 can start to write even more elegant and 22895 14:41:21,040 --> 14:41:25,360 Powerful code once you get comfortable 22896 14:41:22,956 --> 14:41:27,116 with syntax like this so let me go ahead 22897 14:41:25,360 --> 14:41:30,640 and propose that we not just play with 22898 14:41:27,116 --> 14:41:32,796 Hello uh uh hello names anymore but 22899 14:41:30,640 --> 14:41:34,956 instead do something maybe involving 22900 14:41:32,796 --> 14:41:37,000 some coinage again so maybe not dollars 22901 14:41:34,956 --> 14:41:39,080 and cents but maybe again as in the past 22902 14:41:37,000 --> 14:41:40,796 some gallions and sickles and canuts 22903 14:41:39,080 --> 14:41:42,360 with among which there's a mathematical 22904 14:41:40,796 --> 14:41:44,840 relationship as to how many of those in 22905 14:41:42,360 --> 14:41:46,200 the Wizarding World equal each other and 22906 14:41:44,840 --> 14:41:48,756 let me go ahead and do this let me 22907 14:41:46,200 --> 14:41:51,000 Define a simple function called total 22908 14:41:48,756 --> 14:41:53,200 that just tells me the total value of 22909 14:41:51,000 --> 14:41:55,756 someone's vault in grots The Wizarding 22910 14:41:53,200 --> 14:41:57,560 Bank based on how many gallan sickles 22911 14:41:55,756 --> 14:41:59,360 and canuts that they have which again 22912 14:41:57,560 --> 14:42:01,560 are currencies from The Wizarding World 22913 14:41:59,360 --> 14:42:02,756 as opposed to our actual human world so 22914 14:42:01,560 --> 14:42:05,160 this total function might take a 22915 14:42:02,756 --> 14:42:07,480 variable like gallions and sickles and 22916 14:42:05,160 --> 14:42:08,880 canuts like this and then it's going to 22917 14:42:07,480 --> 14:42:11,480 return the formula which I admittedly 22918 14:42:08,880 --> 14:42:13,916 had a look up myself and it turns out 22919 14:42:11,480 --> 14:42:16,560 that the formula for converting gallions 22920 14:42:13,916 --> 14:42:21,480 and sickles to Kuts would be this 22921 14:42:16,560 --> 14:42:23,956 gallions times 17 plus sickles then 22922 14:42:21,480 --> 14:42:26,680 times all of that by 29 and then add in 22923 14:42:23,956 --> 14:42:28,756 the individual canuts not sure in what 22924 14:42:26,680 --> 14:42:30,520 detail this came up in the uh books or 22925 14:42:28,756 --> 14:42:32,560 movies but here we have it the official 22926 14:42:30,520 --> 14:42:34,956 formula all right now let's go ahead and 22927 14:42:32,560 --> 14:42:36,840 do this let me go ahead and call the 22928 14:42:34,956 --> 14:42:39,240 total function with just some sample 22929 14:42:36,840 --> 14:42:42,116 inputs suppose that someone like Harry 22930 14:42:39,240 --> 14:42:43,956 has 100 gallions 50 sickles and 25 22931 14:42:42,116 --> 14:42:45,520 canuts let me go ahead and print that 22932 14:42:43,956 --> 14:42:47,840 out on the screen all right well if 22933 14:42:45,520 --> 14:42:49,956 total returns an integer which I think 22934 14:42:47,840 --> 14:42:52,840 this arithmetic expression will do let 22935 14:42:49,956 --> 14:42:55,560 me go ahead and store uh rather pass the 22936 14:42:52,840 --> 14:42:57,360 return value of total to print and then 22937 14:42:55,560 --> 14:42:58,956 just for clarity let me write canuts at 22938 14:42:57,360 --> 14:43:01,640 the end so I know that the unit of 22939 14:42:58,956 --> 14:43:03,116 measure here is indeed canuts in total 22940 14:43:01,640 --> 14:43:04,520 all right now let me go ahead in my 22941 14:43:03,116 --> 14:43:07,880 terminal window and run python of 22942 14:43:04,520 --> 14:43:10,520 unpack. and hit enter and it turns out 22943 14:43:07,880 --> 14:43:13,916 mathematically that if I got my math 22944 14:43:10,520 --> 14:43:18,520 correct 100 gallions plus 50 sickles 22945 14:43:13,916 --> 14:43:21,640 plus uh 25 canuts equals in total 22946 14:43:18,520 --> 14:43:23,520 50775 canuts just avoiding having to use 22947 14:43:21,640 --> 14:43:25,040 our own human currency here but I'm not 22948 14:43:23,520 --> 14:43:28,040 doing anything along the lines of 22949 14:43:25,040 --> 14:43:30,116 unpacking at least just yet let me 22950 14:43:28,040 --> 14:43:32,240 propose now that I do this just for the 22951 14:43:30,116 --> 14:43:34,796 sake of discussion let me propose that I 22952 14:43:32,240 --> 14:43:36,880 leave the total function as is but let 22953 14:43:34,796 --> 14:43:39,680 me go ahead and just store all of my 22954 14:43:36,880 --> 14:43:43,796 coins in a list so coins in order from 22955 14:43:39,680 --> 14:43:45,720 left to right 100 50 25 it just because 22956 14:43:43,796 --> 14:43:48,720 for whatever purposes in this story I 22957 14:43:45,720 --> 14:43:51,276 have all of my coinage in a a list in 22958 14:43:48,720 --> 14:43:53,840 this order kind of a a purse or wallet 22959 14:43:51,276 --> 14:43:55,240 of sorts well how can I pass this in 22960 14:43:53,840 --> 14:43:56,916 well I'm not going to hardcode the same 22961 14:43:55,240 --> 14:43:58,720 values twice just for the sake of 22962 14:43:56,916 --> 14:44:01,360 discussion how could I pass in the 22963 14:43:58,720 --> 14:44:03,596 individual elements of a list to my 22964 14:44:01,360 --> 14:44:06,200 total function well of course I could 22965 14:44:03,596 --> 14:44:08,276 treat this list as I always do uh using 22966 14:44:06,200 --> 14:44:11,560 numeric indices by doing coins bracket 22967 14:44:08,276 --> 14:44:13,596 zero coins bracket one coins bracket two 22968 14:44:11,560 --> 14:44:15,276 so this is old school stuff with lists 22969 14:44:13,596 --> 14:44:17,680 if I've got a list called coins and 22970 14:44:15,276 --> 14:44:20,000 there's three elements the indices or 22971 14:44:17,680 --> 14:44:22,360 indexes of those elements are zero 1 and 22972 14:44:20,000 --> 14:44:25,640 two respectively from left to right so 22973 14:44:22,360 --> 14:44:28,560 all I'm doing here now is passing in the 22974 14:44:25,640 --> 14:44:30,480 first element from that list as gallions 22975 14:44:28,560 --> 14:44:32,756 the second element of that list as 22976 14:44:30,480 --> 14:44:35,880 sickles and the third element of this 22977 14:44:32,756 --> 14:44:37,916 list as my canuts and that lines up with 22978 14:44:35,880 --> 14:44:40,040 of course the signature of this function 22979 14:44:37,916 --> 14:44:42,400 which as total expects that I've passed 22980 14:44:40,040 --> 14:44:44,200 in those three things in that order left 22981 14:44:42,400 --> 14:44:45,520 to right all right let me go ahead and 22982 14:44:44,200 --> 14:44:47,840 run just to make sure I haven't broken 22983 14:44:45,520 --> 14:44:50,880 anything unpack. piy and hit enter and 22984 14:44:47,840 --> 14:44:53,080 the math still checks out but this is 22985 14:44:50,880 --> 14:44:55,596 getting a little verbose a little 22986 14:44:53,080 --> 14:44:58,040 verbose and wouldn't it be nice if I 22987 14:44:55,596 --> 14:45:00,160 could just pass the list of coins to 22988 14:44:58,040 --> 14:45:03,560 this total function wouldn't it be nice 22989 14:45:00,160 --> 14:45:06,640 if I could just say something like this 22990 14:45:03,560 --> 14:45:11,320 coins but let me pause and ask the group 22991 14:45:06,640 --> 14:45:14,040 why would this not actually work as 22992 14:45:11,320 --> 14:45:16,956 is it technically is passing in all 22993 14:45:14,040 --> 14:45:19,520 three but why would I get some kind of 22994 14:45:16,956 --> 14:45:23,200 error when I run this Eric uh because 22995 14:45:19,520 --> 14:45:25,200 you are passing a list to gallion yeah 22996 14:45:23,200 --> 14:45:26,880 I'm passing a list to gallion and 22997 14:45:25,200 --> 14:45:28,596 nothing for sickles and canuts and 22998 14:45:26,880 --> 14:45:30,400 notice those don't have default values 22999 14:45:28,596 --> 14:45:32,400 there's no equal signs on that first 23000 14:45:30,400 --> 14:45:34,276 line of code code which means Python's 23001 14:45:32,400 --> 14:45:36,480 not going to know what value should be 23002 14:45:34,276 --> 14:45:38,520 assumed there so it just seems like it's 23003 14:45:36,480 --> 14:45:41,080 not going to work plus it's the wrong 23004 14:45:38,520 --> 14:45:43,680 type as Eric notes it's a list and it's 23005 14:45:41,080 --> 14:45:45,480 not an integer as it was before so let's 23006 14:45:43,680 --> 14:45:48,796 actually run this incorrect version 23007 14:45:45,480 --> 14:45:50,200 python of unpacked High enter type error 23008 14:45:48,796 --> 14:45:51,756 and that is probably what you might 23009 14:45:50,200 --> 14:45:54,436 expect like I'm messing up with the 23010 14:45:51,756 --> 14:45:56,116 types here and I I'm required to pass in 23011 14:45:54,436 --> 14:45:58,400 two positional arguments sickles and 23012 14:45:56,116 --> 14:46:00,360 canuts that were not even passed so I've 23013 14:45:58,400 --> 14:46:02,436 definitely aired here but it certainly 23014 14:46:00,360 --> 14:46:04,680 seems fortunate if the only solution to 23015 14:46:02,436 --> 14:46:06,400 this is to do what I previously did 23016 14:46:04,680 --> 14:46:08,200 which is index into the first element 23017 14:46:06,400 --> 14:46:09,880 index into the second element index into 23018 14:46:08,200 --> 14:46:11,636 the third like you can imagine with 23019 14:46:09,880 --> 14:46:13,436 bigger fancier functions that take even 23020 14:46:11,636 --> 14:46:16,000 more arguments this is going to get very 23021 14:46:13,436 --> 14:46:18,276 verbose and honestly very vulnerable 23022 14:46:16,000 --> 14:46:21,276 potentially to just mistakes typos on my 23023 14:46:18,276 --> 14:46:24,200 part but here too is where you can do 23024 14:46:21,276 --> 14:46:27,000 what's known again as unpacking a value 23025 14:46:24,200 --> 14:46:29,436 in Python right now a list is kind of 23026 14:46:27,000 --> 14:46:32,040 packed with multiple values my current 23027 14:46:29,436 --> 14:46:33,840 list has these three values one 100 50 23028 14:46:32,040 --> 14:46:35,720 and 255 respectively but they're all 23029 14:46:33,840 --> 14:46:38,720 packed up in this one list wouldn't it 23030 14:46:35,720 --> 14:46:41,000 be nice if I could unpack that list just 23031 14:46:38,720 --> 14:46:44,480 like I previously unpacked the return 23032 14:46:41,000 --> 14:46:47,116 value of the stir classes split function 23033 14:46:44,480 --> 14:46:49,756 into multiple things too and indeed I 23034 14:46:47,116 --> 14:46:54,400 can do just that python actually allows 23035 14:46:49,756 --> 14:46:56,560 me to pass in not coins but Star Coins 23036 14:46:54,400 --> 14:46:58,596 so if you use a single asterisk at the 23037 14:46:56,560 --> 14:47:01,756 beginning of your variable that will 23038 14:46:58,596 --> 14:47:04,720 unpack it and it will take one sequence 23039 14:47:01,756 --> 14:47:07,400 in this case coins of size three and 23040 14:47:04,720 --> 14:47:09,916 explode it if you will unpack it into 23041 14:47:07,400 --> 14:47:12,200 three individual arguments no commas are 23042 14:47:09,916 --> 14:47:15,756 needed python just handles this for you 23043 14:47:12,200 --> 14:47:19,360 but the effect of passing in Star Coins 23044 14:47:15,756 --> 14:47:21,160 is to pass in the individual members of 23045 14:47:19,360 --> 14:47:23,720 that list which in this case are going 23046 14:47:21,160 --> 14:47:25,240 to be 100 50 and 25 respectively which 23047 14:47:23,720 --> 14:47:27,596 is perfect because now it's going to 23048 14:47:25,240 --> 14:47:31,116 line up with gallions sickles canuts 23049 14:47:27,596 --> 14:47:33,520 respectively so now when I run python of 23050 14:47:31,116 --> 14:47:35,200 unpack. py we're back in business and 23051 14:47:33,520 --> 14:47:37,320 the math checks out but I've kind of 23052 14:47:35,200 --> 14:47:38,796 cleaned up my code by just introducing 23053 14:47:37,320 --> 14:47:40,040 this new symbol which we've used of 23054 14:47:38,796 --> 14:47:42,796 course in other context for 23055 14:47:40,040 --> 14:47:46,116 multiplication and the like but now it's 23056 14:47:42,796 --> 14:47:49,240 also used for unpacking in this way 23057 14:47:46,116 --> 14:47:52,116 questions on what we've just done it's a 23058 14:47:49,240 --> 14:47:54,080 single operator but it's already quite 23059 14:47:52,116 --> 14:47:56,560 powerful because it allows us to take a 23060 14:47:54,080 --> 14:47:57,320 data structure and unpack it and pass it 23061 14:47:56,560 --> 14:48:01,596 in 23062 14:47:57,320 --> 14:48:06,840 individually does that work for um uh 23063 14:48:01,596 --> 14:48:08,636 tles sets dicks dictionaries as well 23064 14:48:06,840 --> 14:48:12,916 tupples 23065 14:48:08,636 --> 14:48:15,116 yes sets I don't know R Shin I don't 23066 14:48:12,916 --> 14:48:18,400 know if order is 23067 14:48:15,116 --> 14:48:20,080 preserved no oh is that no it does not 23068 14:48:18,400 --> 14:48:22,080 or you know you're 23069 14:48:20,080 --> 14:48:24,000 checking order is not preserved so it 23070 14:48:22,080 --> 14:48:26,680 wouldn't work with 23071 14:48:24,000 --> 14:48:29,276 set does not work with set does not work 23072 14:48:26,680 --> 14:48:30,880 with set sorry I'm verbally Googling 23073 14:48:29,276 --> 14:48:33,916 here just to save us some keystrokes so 23074 14:48:30,880 --> 14:48:35,436 it would work for um enumerations that 23075 14:48:33,916 --> 14:48:36,680 where order is indeed preserved and 23076 14:48:35,436 --> 14:48:37,880 we'll see another example in a moment 23077 14:48:36,680 --> 14:48:39,320 where it actually can be used in a 23078 14:48:37,880 --> 14:48:41,756 different way for dictionaries which 23079 14:48:39,320 --> 14:48:45,360 nowadays do preserve order other 23080 14:48:41,756 --> 14:48:48,160 questions on unpacking in this way yes 23081 14:48:45,360 --> 14:48:52,000 hi hello uh can you use unpacking to get 23082 14:48:48,160 --> 14:48:56,320 the value uh for example 10 + 50 + 23083 14:48:52,000 --> 14:48:58,796 25 uh instead of a for Loop and then 23084 14:48:56,320 --> 14:49:00,720 result plus short answer no if you want 23085 14:48:58,796 --> 14:49:02,560 the individual values you should be just 23086 14:49:00,720 --> 14:49:05,880 indexing in this case into those 23087 14:49:02,560 --> 14:49:08,320 specific locations um this is returning 23088 14:49:05,880 --> 14:49:10,360 multiple values the equivalent of a 23089 14:49:08,320 --> 14:49:11,956 comma separated list so you would use 23090 14:49:10,360 --> 14:49:14,436 the earlier approach if you cared about 23091 14:49:11,956 --> 14:49:17,720 the individual locations how about one 23092 14:49:14,436 --> 14:49:19,916 other question on unpacking what if uh 23093 14:49:17,720 --> 14:49:24,000 we have declared we we declar some 23094 14:49:19,916 --> 14:49:27,796 default values and if you use this Aster 23095 14:49:24,000 --> 14:49:30,240 coins will it over right or will it uh 23096 14:49:27,796 --> 14:49:32,276 skip it good question if I heard you 23097 14:49:30,240 --> 14:49:34,596 right what if for instance the list has 23098 14:49:32,276 --> 14:49:37,000 four values like this here and you're 23099 14:49:34,596 --> 14:49:39,956 still unpacking it when it's only three 23100 14:49:37,000 --> 14:49:43,320 that's expected well let's try it python 23101 14:49:39,956 --> 14:49:44,916 of unpack. piy enter another type error 23102 14:49:43,320 --> 14:49:46,560 this time it takes three positional 23103 14:49:44,916 --> 14:49:49,080 arguments but four were given so the 23104 14:49:46,560 --> 14:49:51,000 onus is on us as the programmer not to 23105 14:49:49,080 --> 14:49:53,636 do that in this case so potentially 23106 14:49:51,000 --> 14:49:56,116 fragile but avoidable if I'm controlling 23107 14:49:53,636 --> 14:49:57,436 the contents of this list in fact let me 23108 14:49:56,116 --> 14:49:59,956 propose now that we take a look at 23109 14:49:57,436 --> 14:50:02,520 another variant of this whereby we use 23110 14:49:59,956 --> 14:50:04,320 not just position IAL uh arguments 23111 14:50:02,520 --> 14:50:05,956 whereby we trust that the first is 23112 14:50:04,320 --> 14:50:07,680 gallions the second is sickles the third 23113 14:50:05,956 --> 14:50:09,116 is canuts suppose that we actually 23114 14:50:07,680 --> 14:50:11,080 passed in the names as we're allowed to 23115 14:50:09,116 --> 14:50:12,596 do in Python and then technically we 23116 14:50:11,080 --> 14:50:14,560 could pass them in in any order and 23117 14:50:12,596 --> 14:50:16,756 python would figure it out using named 23118 14:50:14,560 --> 14:50:18,200 parameters instead well how might I do 23119 14:50:16,756 --> 14:50:19,916 this well it's going to be a bit of a 23120 14:50:18,200 --> 14:50:23,040 regression at first so let me get rid of 23121 14:50:19,916 --> 14:50:25,000 this list here let me change this now to 23122 14:50:23,040 --> 14:50:28,000 just manually pass in the values I care 23123 14:50:25,000 --> 14:50:31,276 about gallions I want to still equal 100 23124 14:50:28,000 --> 14:50:34,916 sickles I want to equal 50 and nuts I 23125 14:50:31,276 --> 14:50:36,680 want to equal 25 so this is old school 23126 14:50:34,916 --> 14:50:38,796 parameter pressing it's no longer 23127 14:50:36,680 --> 14:50:41,520 positional I'm explicitly specifying the 23128 14:50:38,796 --> 14:50:43,240 names of these arguments but that's just 23129 14:50:41,520 --> 14:50:45,160 going to work because that's exactly 23130 14:50:43,240 --> 14:50:47,400 what the names of these parameters are 23131 14:50:45,160 --> 14:50:49,276 in my total function as before let's 23132 14:50:47,400 --> 14:50:52,276 make sure I nonetheless did not break 23133 14:50:49,276 --> 14:50:54,756 anything let's run python of uh of 23134 14:50:52,276 --> 14:50:55,796 unpack. piy enter and there we have it 23135 14:50:54,756 --> 14:51:00,200 still 23136 14:50:55,796 --> 14:51:05,080 50775 canuts well once you start giving 23137 14:51:00,200 --> 14:51:07,520 things names and values names and values 23138 14:51:05,080 --> 14:51:10,480 that probably should bring to mind one 23139 14:51:07,520 --> 14:51:12,680 of our most versatile data structures in 23140 14:51:10,480 --> 14:51:14,436 Python and even other languages that of 23141 14:51:12,680 --> 14:51:17,080 a dictionary remember that a dictionary 23142 14:51:14,436 --> 14:51:19,436 is just a collection of key value pairs 23143 14:51:17,080 --> 14:51:21,160 names and their respective values so 23144 14:51:19,436 --> 14:51:23,360 this kind of opens up an opportunity 23145 14:51:21,160 --> 14:51:26,240 what if I did this what if I actually 23146 14:51:23,360 --> 14:51:28,360 had for some reason in my program on a 23147 14:51:26,240 --> 14:51:30,160 variable as before called coins but 23148 14:51:28,360 --> 14:51:32,436 instead of making it a list of three 23149 14:51:30,160 --> 14:51:34,520 values like before what if it's a proper 23150 14:51:32,436 --> 14:51:37,956 dictionary so what if it's gallions 23151 14:51:34,520 --> 14:51:40,560 quote unquote colon 100 for 100 of those 23152 14:51:37,956 --> 14:51:43,560 sickles quote unquote and 50 of those 23153 14:51:40,560 --> 14:51:47,360 and Kuts quote unquote 25 of those each 23154 14:51:43,560 --> 14:51:50,000 of those separated by uh colons and let 23155 14:51:47,360 --> 14:51:52,116 me fix my square brackets to this time 23156 14:51:50,000 --> 14:51:54,680 be curly braces which recall is the 23157 14:51:52,116 --> 14:51:57,480 symbol we use for dictionaries or dict 23158 14:51:54,680 --> 14:51:59,796 objects in Python so now I have a 23159 14:51:57,480 --> 14:52:02,360 dictionary called coins not a list it's 23160 14:51:59,796 --> 14:52:04,880 a collection of keys and values three 23161 14:52:02,360 --> 14:52:08,756 keys gallions sickles canuts and three 23162 14:52:04,880 --> 14:52:12,400 values 100 50 25 respectively if I were 23163 14:52:08,756 --> 14:52:14,796 to now pass these individual values into 23164 14:52:12,400 --> 14:52:17,040 my total function I could do it as 23165 14:52:14,796 --> 14:52:19,040 always with my dictionary so I'm doing 23166 14:52:17,040 --> 14:52:21,480 it old school now coins is the name of 23167 14:52:19,040 --> 14:52:23,840 my dictionary I index into it not with 23168 14:52:21,480 --> 14:52:27,436 numbers like with lists but with words 23169 14:52:23,840 --> 14:52:29,680 so gallions strings like this uh coins 23170 14:52:27,436 --> 14:52:31,796 quote unquote sickles in square brackets 23171 14:52:29,680 --> 14:52:33,840 there and then lastly coins square 23172 14:52:31,796 --> 14:52:35,680 brackets quote unquote canuts so it's 23173 14:52:33,840 --> 14:52:37,360 getting it's verbose again like this is 23174 14:52:35,680 --> 14:52:39,560 not maybe the best road to go down but 23175 14:52:37,360 --> 14:52:41,956 we'll backpedal in a moment this is just 23176 14:52:39,560 --> 14:52:44,436 how if you happen to have all of your 23177 14:52:41,956 --> 14:52:46,956 coins stored in a dictionary you could 23178 14:52:44,436 --> 14:52:48,880 pass the gallion sickles and canuts into 23179 14:52:46,956 --> 14:52:50,840 your function respectively let's make 23180 14:52:48,880 --> 14:52:53,480 sure I didn't break anything let's rerun 23181 14:52:50,840 --> 14:52:55,796 python of unpack. py and we're still 23182 14:52:53,480 --> 14:52:57,756 good now how could we get to a situation 23183 14:52:55,796 --> 14:53:00,116 like this well as always imagine this 23184 14:52:57,756 --> 14:53:02,240 program is a little longer than this one 23185 14:53:00,116 --> 14:53:04,116 here and somehow you're using a 23186 14:53:02,240 --> 14:53:06,436 dictionary maybe just to keep track of 23187 14:53:04,116 --> 14:53:08,796 someone's purse or wallet like how many 23188 14:53:06,436 --> 14:53:10,360 coins of each type that they have and as 23189 14:53:08,796 --> 14:53:12,116 such it's perfectly reasonable to use a 23190 14:53:10,360 --> 14:53:14,360 dictionary but then you want to print 23191 14:53:12,116 --> 14:53:17,080 out the total and darn it if that total 23192 14:53:14,360 --> 14:53:19,480 function does not expect a dictionary so 23193 14:53:17,080 --> 14:53:21,840 you cannot just do something nice and 23194 14:53:19,480 --> 14:53:23,756 simple like pass in coins for reasons we 23195 14:53:21,840 --> 14:53:25,756 saw earlier that would be a type error 23196 14:53:23,756 --> 14:53:27,956 total expects three arguments three 23197 14:53:25,756 --> 14:53:29,680 integers you can't just pass in a 23198 14:53:27,956 --> 14:53:31,480 dictionary but if that's the data 23199 14:53:29,680 --> 14:53:34,040 structure you're using to store the 23200 14:53:31,480 --> 14:53:36,320 person's purse or wallet well it's kind 23201 14:53:34,040 --> 14:53:38,756 of unfortunate that we have this clash 23202 14:53:36,320 --> 14:53:41,360 between these data types well here's 23203 14:53:38,756 --> 14:53:43,116 what we can do we can't pass in coins 23204 14:53:41,360 --> 14:53:45,080 because watch if I try doing that and 23205 14:53:43,116 --> 14:53:48,116 run python of unpack. we're getting 23206 14:53:45,080 --> 14:53:50,000 another type error missing two required 23207 14:53:48,116 --> 14:53:53,880 positional arguments sickles and canuts 23208 14:53:50,000 --> 14:53:56,796 I have to pass in three things but 23209 14:53:53,880 --> 14:53:59,160 wonderfully python allows you to unpack 23210 14:53:56,796 --> 14:54:01,636 dictionaries as well for a dictionary 23211 14:53:59,160 --> 14:54:05,000 you don't use a single as risk you use 23212 14:54:01,636 --> 14:54:09,200 two and what this syntax has the effect 23213 14:54:05,000 --> 14:54:11,796 of doing is passing in three values with 23214 14:54:09,200 --> 14:54:16,040 names it has the effect of passing in 23215 14:54:11,796 --> 14:54:20,680 gallion equals 100 comma sickles equals 23216 14:54:16,040 --> 14:54:23,560 50 comma canuts equals 25 and so it has 23217 14:54:20,680 --> 14:54:25,520 the similar effect to the list unpacking 23218 14:54:23,560 --> 14:54:29,116 but that just passed in the values 100 23219 14:54:25,520 --> 14:54:31,720 50 25 separated by commas in effect when 23220 14:54:29,116 --> 14:54:34,560 unpacking a dictionary it passes in the 23221 14:54:31,720 --> 14:54:37,636 keys and the values separated 23222 14:54:34,560 --> 14:54:40,520 conceptually with equal signs just like 23223 14:54:37,636 --> 14:54:43,276 our function expects so if I now run 23224 14:54:40,520 --> 14:54:45,240 python of unpack. again we're still good 23225 14:54:43,276 --> 14:54:46,796 but we've tightened our code up again 23226 14:54:45,240 --> 14:54:49,200 and now I'm giving myself yet another 23227 14:54:46,796 --> 14:54:53,116 option I can either store a Wizard's 23228 14:54:49,200 --> 14:54:55,200 purse or or uh wallets in their uh in a 23229 14:54:53,116 --> 14:54:57,320 list as we did earlier or I can store it 23230 14:54:55,200 --> 14:55:00,320 a little more vers uh with even more 23231 14:54:57,320 --> 14:55:02,916 specificity using a dictionary instead 23232 14:55:00,320 --> 14:55:06,080 and so do be clear let me rewind star 23233 14:55:02,916 --> 14:55:09,160 star coins is the same thing if I rewind 23234 14:55:06,080 --> 14:55:11,436 a little bit to our first example of 23235 14:55:09,160 --> 14:55:13,796 named arguments is equivalent to what 23236 14:55:11,436 --> 14:55:16,840 I've highlighted here when you unpack a 23237 14:55:13,796 --> 14:55:19,756 dictionary it passes in all of the keys 23238 14:55:16,840 --> 14:55:22,160 and all of the values much like this 23239 14:55:19,756 --> 14:55:24,880 syntax here but let me tighten it up and 23240 14:55:22,160 --> 14:55:27,080 go to where we left off questions now on 23241 14:55:24,880 --> 14:55:29,596 unpacking can we have a in this 23242 14:55:27,080 --> 14:55:31,200 dictionary uh can we have instead of 23243 14:55:29,596 --> 14:55:34,116 having a con 23244 14:55:31,200 --> 14:55:37,040 name value pair can we have a variable 23245 14:55:34,116 --> 14:55:39,240 number of you know name value pairs 23246 14:55:37,040 --> 14:55:41,956 short answer yes you can have more than 23247 14:55:39,240 --> 14:55:44,320 three key value pairs as I have here but 23248 14:55:41,956 --> 14:55:46,796 it's not going to work unpacking it if 23249 14:55:44,320 --> 14:55:49,160 the total function is expecting only 23250 14:55:46,796 --> 14:55:50,840 three so if I were to add something here 23251 14:55:49,160 --> 14:55:53,680 like let me introduce pennies to The 23252 14:55:50,840 --> 14:55:56,480 Wizarding World and suppose I have one 23253 14:55:53,680 --> 14:56:00,320 penny for instance and now I run this 23254 14:55:56,480 --> 14:56:02,520 same code python of uh unpack. piy where 23255 14:56:00,320 --> 14:56:05,040 back to a type error again whereby I got 23256 14:56:02,520 --> 14:56:07,080 an unexpected keyword argument pennies 23257 14:56:05,040 --> 14:56:09,116 because that is not expected by the 23258 14:56:07,080 --> 14:56:11,360 total function we will see in just a 23259 14:56:09,116 --> 14:56:14,116 moment wonderfully a solution though to 23260 14:56:11,360 --> 14:56:16,000 that but for now it does not work other 23261 14:56:14,116 --> 14:56:19,240 questions on unpacking with dictionaries 23262 14:56:16,000 --> 14:56:21,596 or lists in list in list values we gave 23263 14:56:19,240 --> 14:56:24,596 the same number of arguments and we 23264 14:56:21,596 --> 14:56:26,720 declared a default value in the function 23265 14:56:24,596 --> 14:56:29,360 now if you use this as trick will it 23266 14:56:26,720 --> 14:56:31,720 overwrite that value or will it skip it 23267 14:56:29,360 --> 14:56:34,560 skip that default value a good question 23268 14:56:31,720 --> 14:56:38,320 if you if we did have default values up 23269 14:56:34,560 --> 14:56:41,040 here for instance equals 0 equals 0 23270 14:56:38,320 --> 14:56:42,436 equals zero the upside of that recall 23271 14:56:41,040 --> 14:56:44,436 from our discussion of arguments to 23272 14:56:42,436 --> 14:56:46,240 functions a while back is that now you 23273 14:56:44,436 --> 14:56:49,276 don't have to pass in all of those 23274 14:56:46,240 --> 14:56:51,276 values they will default to those zeros 23275 14:56:49,276 --> 14:56:53,360 therefore you could pass in fewer than 23276 14:56:51,276 --> 14:56:55,080 three values either using a list or a 23277 14:56:53,360 --> 14:56:57,436 dictionary that's unpacked in this 23278 14:56:55,080 --> 14:56:59,436 scenario I deliberately did not do that 23279 14:56:57,436 --> 14:57:01,320 because I wanted us to encounter this 23280 14:56:59,436 --> 14:57:04,320 specific error in this case but you 23281 14:57:01,320 --> 14:57:06,480 could absolutely go back and add those 23282 14:57:04,320 --> 14:57:08,756 defaults so it turns out that this 23283 14:57:06,480 --> 14:57:10,360 single asterisk or this double asterisk 23284 14:57:08,756 --> 14:57:12,560 is not only used in the context of 23285 14:57:10,360 --> 14:57:15,040 unpacking that same syntax is actually 23286 14:57:12,560 --> 14:57:17,796 used as a visual indicator in Python 23287 14:57:15,040 --> 14:57:21,040 when a function itself might very well 23288 14:57:17,796 --> 14:57:23,276 take a variable number of arguments that 23289 14:57:21,040 --> 14:57:25,080 is to say a function can be vartic which 23290 14:57:23,276 --> 14:57:27,916 means that it doesn't necessarily have 23291 14:57:25,080 --> 14:57:29,520 to take say three arguments specifically 23292 14:57:27,916 --> 14:57:32,480 even if they do or don't have default 23293 14:57:29,520 --> 14:57:35,276 values it can take maybe zero or one or 23294 14:57:32,480 --> 14:57:37,000 two or three and it turns out the Syntax 23295 14:57:35,276 --> 14:57:39,560 for implementing the same idea is quite 23296 14:57:37,000 --> 14:57:41,636 similar in spirit in fact let me go back 23297 14:57:39,560 --> 14:57:43,436 to vs code here and let me propose that 23298 14:57:41,636 --> 14:57:45,080 we start over with this code and get rid 23299 14:57:43,436 --> 14:57:46,596 of our notion of gallions and sickles 23300 14:57:45,080 --> 14:57:48,000 and canuts and do something just a 23301 14:57:46,596 --> 14:57:51,520 little more generic just so that we've 23302 14:57:48,000 --> 14:57:53,720 seen the Syntax for this suppose that I 23303 14:57:51,520 --> 14:57:56,080 Define a function as follows Define a 23304 14:57:53,720 --> 14:57:58,040 function let's call it f and that 23305 14:57:56,080 --> 14:58:00,520 function is not going to take a specific 23306 14:57:58,040 --> 14:58:02,000 number of arguments but a variable and 23307 14:58:00,520 --> 14:58:05,160 so I'm going to go ahead and use this 23308 14:58:02,000 --> 14:58:07,200 syntax here star args which indicates 23309 14:58:05,160 --> 14:58:09,116 that this function is indeed very adic 23310 14:58:07,200 --> 14:58:11,480 it takes some variable number of 23311 14:58:09,116 --> 14:58:13,200 positional arguments positional in the 23312 14:58:11,480 --> 14:58:15,200 sense that they go typically from left 23313 14:58:13,200 --> 14:58:17,400 to right but I don't know how many just 23314 14:58:15,200 --> 14:58:18,840 yet I want to support suppose that I 23315 14:58:17,400 --> 14:58:21,240 additionally want to support some number 23316 14:58:18,840 --> 14:58:23,956 of keyword arguments that is named 23317 14:58:21,240 --> 14:58:26,276 parameters that can be called optionally 23318 14:58:23,956 --> 14:58:28,040 and individually by their own name well 23319 14:58:26,276 --> 14:58:30,956 the convention syntactically here would 23320 14:58:28,040 --> 14:58:33,596 be to use two stars and then K W ARS I 23321 14:58:30,956 --> 14:58:35,240 could call args or KW args anything else 23322 14:58:33,596 --> 14:58:37,000 that I want but a convention you'll 23323 14:58:35,240 --> 14:58:38,360 frequently see in Python's own 23324 14:58:37,000 --> 14:58:40,400 documentation is that when you have 23325 14:58:38,360 --> 14:58:42,560 placeholders like this for some number 23326 14:58:40,400 --> 14:58:44,956 of arguments and some number of keyword 23327 14:58:42,560 --> 14:58:48,116 arguments um the world tends to use args 23328 14:58:44,956 --> 14:58:49,916 and key uh KW args well inside of this 23329 14:58:48,116 --> 14:58:51,916 function let's do something super simple 23330 14:58:49,916 --> 14:58:54,680 just for now let me go ahead and print 23331 14:58:51,916 --> 14:58:56,436 out literally quote unquote positional 23332 14:58:54,680 --> 14:58:58,240 just to indicate to myself while 23333 14:58:56,436 --> 14:59:00,360 wrapping my mind around what's going on 23334 14:58:58,240 --> 14:59:02,400 here what the positional argument arents 23335 14:59:00,360 --> 14:59:04,000 are and let me quite simply print out 23336 14:59:02,400 --> 14:59:05,796 those args this is not something you 23337 14:59:04,000 --> 14:59:07,360 would typically do you don't typically 23338 14:59:05,796 --> 14:59:08,756 just take in these arguments and print 23339 14:59:07,360 --> 14:59:10,560 them no matter how many there are I'm 23340 14:59:08,756 --> 14:59:13,436 just doing this diagnostically for now 23341 14:59:10,560 --> 14:59:15,080 to show you how the syntax works now let 23342 14:59:13,436 --> 14:59:16,756 me go ahead at the bottom of my file and 23343 14:59:15,080 --> 14:59:18,636 I won't bother with a main function this 23344 14:59:16,756 --> 14:59:20,636 time so we can focus only on this 23345 14:59:18,636 --> 14:59:22,796 function f let me go ahead and just call 23346 14:59:20,636 --> 14:59:24,276 F with three arguments I'll use the same 23347 14:59:22,796 --> 14:59:26,080 arguments as before but I'm didn't 23348 14:59:24,276 --> 14:59:28,040 bother giving them names just yet like 23349 14:59:26,080 --> 14:59:31,436 gallions and sickles and canuts and the 23350 14:59:28,040 --> 14:59:33,360 like so what do I have a program that no 23351 14:59:31,436 --> 14:59:35,680 matter what calls this function f but it 23352 14:59:33,360 --> 14:59:37,400 first defines F at the top of the file 23353 14:59:35,680 --> 14:59:40,040 is taking some number of positional 23354 14:59:37,400 --> 14:59:42,240 arguments some number of named arguments 23355 14:59:40,040 --> 14:59:44,360 and for the moment I'm just printing out 23356 14:59:42,240 --> 14:59:46,480 the positional ones let me go ahead and 23357 14:59:44,360 --> 14:59:49,360 in my terminal window run python of 23358 14:59:46,480 --> 14:59:51,840 unpack. piy and hit enter and you'll see 23359 14:59:49,360 --> 14:59:57,000 that the positional arguments passed in 23360 14:59:51,840 --> 14:59:58,956 are apparently this a sequence 50 25 but 23361 14:59:57,000 --> 15:00:00,560 notice this if I clear my terminal 23362 14:59:58,956 --> 15:00:03,596 window there and pass something else 23363 15:00:00,560 --> 15:00:05,796 like five a fourth argument previously 23364 15:00:03,596 --> 15:00:08,400 if I try to change the number of 23365 15:00:05,796 --> 15:00:10,276 arguments I'm passing in to my total 23366 15:00:08,400 --> 15:00:12,276 function which was only defined as 23367 15:00:10,276 --> 15:00:14,400 taking three I would have gotten a type 23368 15:00:12,276 --> 15:00:17,040 error some visual indication that no you 23369 15:00:14,400 --> 15:00:18,596 can't pass in more or fewer arguments 23370 15:00:17,040 --> 15:00:21,040 than is actually in the function's 23371 15:00:18,596 --> 15:00:25,040 definition but now watch if I run python 23372 15:00:21,040 --> 15:00:28,000 of unpack. Pi this time passing in 15 25 23373 15:00:25,040 --> 15:00:30,520 and five a fourth argument all four of 23374 15:00:28,000 --> 15:00:32,880 those went through just fine I can get 23375 15:00:30,520 --> 15:00:35,360 rid of all of those but one for instance 23376 15:00:32,880 --> 15:00:37,160 now rerun my program after clearing my 23377 15:00:35,360 --> 15:00:39,000 screen and now I'll see just one 23378 15:00:37,160 --> 15:00:40,916 argument here and even though there's a 23379 15:00:39,000 --> 15:00:42,916 comma and nothing after it this is 23380 15:00:40,916 --> 15:00:45,360 actually the syntax when seeing a a 23381 15:00:42,916 --> 15:00:46,916 tupple in effect whereby The Comma just 23382 15:00:45,360 --> 15:00:49,680 indicates this is indeed a list but 23383 15:00:46,916 --> 15:00:51,480 there's only one element therein well 23384 15:00:49,680 --> 15:00:54,080 let's get a little more curious too let 23385 15:00:51,480 --> 15:00:56,116 me go ahead and Rewind here to where we 23386 15:00:54,080 --> 15:00:57,720 started with just those three values and 23387 15:00:56,116 --> 15:01:00,000 this time let me go ahead and print out 23388 15:00:57,720 --> 15:01:03,276 my named argument so to speak which is 23389 15:01:00,000 --> 15:01:05,840 args but KW args again the positional 23390 15:01:03,276 --> 15:01:08,880 args in this syntax come first the named 23391 15:01:05,840 --> 15:01:11,400 arguments KW ARS come second uh that's 23392 15:01:08,880 --> 15:01:13,200 uh what python prescribes so now let me 23393 15:01:11,400 --> 15:01:14,796 go ahead and not pass in just these 23394 15:01:13,200 --> 15:01:17,360 numbers let me go ahead and pass in 23395 15:01:14,796 --> 15:01:19,276 actually named arguments so let me do 23396 15:01:17,360 --> 15:01:21,916 something now more specifically like 23397 15:01:19,276 --> 15:01:24,680 gallions equals 100 and sickles equals 23398 15:01:21,916 --> 15:01:26,560 50 and canuts equals 25 I'm not going to 23399 15:01:24,680 --> 15:01:28,596 bother doing any math with total I just 23400 15:01:26,560 --> 15:01:30,560 want to poke around right now at this 23401 15:01:28,596 --> 15:01:32,916 functionality of having a variable 23402 15:01:30,560 --> 15:01:35,840 number of arguments and what's neat now 23403 15:01:32,916 --> 15:01:40,596 is if I run python of unpack. and hit 23404 15:01:35,840 --> 15:01:43,636 enter no problem what KW args is is 23405 15:01:40,596 --> 15:01:45,720 automatically a dictionary that contains 23406 15:01:43,636 --> 15:01:48,116 all of the named arguments that were 23407 15:01:45,720 --> 15:01:50,160 passed to my function which is to say 23408 15:01:48,116 --> 15:01:53,160 when designing your own functions if you 23409 15:01:50,160 --> 15:01:55,000 want to support more than one argument 23410 15:01:53,160 --> 15:01:56,796 maybe more than two or three or four 23411 15:01:55,000 --> 15:01:59,436 maybe a variable number of arguments 23412 15:01:56,796 --> 15:02:01,276 indeed you can support both a variable 23413 15:01:59,436 --> 15:02:04,200 number of positional arguments that are 23414 15:02:01,276 --> 15:02:06,200 just value comma value comma value or 23415 15:02:04,200 --> 15:02:08,000 any number of named arguments where you 23416 15:02:06,200 --> 15:02:10,796 actually put the name of the parameter 23417 15:02:08,000 --> 15:02:14,040 equals the value and then maybe a comma 23418 15:02:10,796 --> 15:02:17,720 and some more of the same so now it 23419 15:02:14,040 --> 15:02:20,276 turns out we have seen this before uh in 23420 15:02:17,720 --> 15:02:22,756 some of the functions we've used to date 23421 15:02:20,276 --> 15:02:25,596 we didn't necessarily see it called args 23422 15:02:22,756 --> 15:02:27,596 or necessarily see it called KW ARS but 23423 15:02:25,596 --> 15:02:30,276 we have seen at least one example of 23424 15:02:27,596 --> 15:02:32,080 this in the wild recall our old friend 23425 15:02:30,276 --> 15:02:33,840 print which we've been using now for 23426 15:02:32,080 --> 15:02:36,400 weeks and when we first looked at the 23427 15:02:33,840 --> 15:02:38,720 documentation for print way back when it 23428 15:02:36,400 --> 15:02:41,480 looked a little something like this the 23429 15:02:38,720 --> 15:02:43,276 first argument to print was objects and 23430 15:02:41,480 --> 15:02:45,000 I waved my hand at the time at the 23431 15:02:43,276 --> 15:02:47,276 asteris that was at the start of that 23432 15:02:45,000 --> 15:02:49,116 variable name but then we had sep for 23433 15:02:47,276 --> 15:02:51,240 separator the default value of which was 23434 15:02:49,116 --> 15:02:52,916 a space we had n the default value of 23435 15:02:51,240 --> 15:02:54,880 which was a new line and then some other 23436 15:02:52,916 --> 15:02:57,636 named arguments that we waved our hands 23437 15:02:54,880 --> 15:03:00,240 at then and I'll again do now but what 23438 15:02:57,636 --> 15:03:02,596 you can now perhaps infer from our 23439 15:03:00,240 --> 15:03:04,680 emphasis on these asterisks today the 23440 15:03:02,596 --> 15:03:06,756 single stars or the double stars is that 23441 15:03:04,680 --> 15:03:09,796 you know what this is the convention in 23442 15:03:06,756 --> 15:03:13,480 Python's documentation to indicate that 23443 15:03:09,796 --> 15:03:16,040 print takes a variable number of 23444 15:03:13,480 --> 15:03:17,520 arguments so if we were to look at the 23445 15:03:16,040 --> 15:03:19,360 actual implementation of the print 23446 15:03:17,520 --> 15:03:21,040 function implemented by Python's own 23447 15:03:19,360 --> 15:03:23,756 authors it might very well look 23448 15:03:21,040 --> 15:03:25,840 something like this deaf print and then 23449 15:03:23,756 --> 15:03:27,520 the first argument would be star objects 23450 15:03:25,840 --> 15:03:29,796 thereby indicating that print takes a 23451 15:03:27,520 --> 15:03:31,436 variable number of arguments the next 23452 15:03:29,796 --> 15:03:33,560 one of which might be sep equals quote 23453 15:03:31,436 --> 15:03:35,756 unquote either using double quotes or as 23454 15:03:33,560 --> 15:03:37,400 in the documentation single quotes too 23455 15:03:35,756 --> 15:03:39,200 the next one of which might be end the 23456 15:03:37,400 --> 15:03:40,756 default value of which is a new line and 23457 15:03:39,200 --> 15:03:42,436 then some of those other named arguments 23458 15:03:40,756 --> 15:03:44,796 that we've not looked at as well and 23459 15:03:42,436 --> 15:03:46,756 then maybe inside of the print function 23460 15:03:44,796 --> 15:03:49,116 implemented by the authors of python 23461 15:03:46,756 --> 15:03:51,720 maybe there's a for Loop like for object 23462 15:03:49,116 --> 15:03:54,320 in objects that allows them to iterate 23463 15:03:51,720 --> 15:03:56,880 over each of those variable number of 23464 15:03:54,320 --> 15:03:59,200 objects and print each of them and this 23465 15:03:56,880 --> 15:04:01,276 is why in programs past you and I have 23466 15:03:59,200 --> 15:04:02,880 been able to do just print open 23467 15:04:01,276 --> 15:04:04,840 parenthesis close parenthesis with 23468 15:04:02,880 --> 15:04:06,436 nothing inside or you and I have been 23469 15:04:04,840 --> 15:04:08,480 able to print out something like Hello 23470 15:04:06,436 --> 15:04:10,400 World a single string inside of those 23471 15:04:08,480 --> 15:04:12,796 parentheses or you and I have been able 23472 15:04:10,400 --> 15:04:14,880 to do a single string hello and then 23473 15:04:12,796 --> 15:04:17,200 another string quote unquote World 23474 15:04:14,880 --> 15:04:19,720 thereby passing in two arguments or even 23475 15:04:17,200 --> 15:04:22,560 more so we've long had this ability to 23476 15:04:19,720 --> 15:04:24,360 use vartic AR uh functions whereby you 23477 15:04:22,560 --> 15:04:27,480 can pass in a variable number of 23478 15:04:24,360 --> 15:04:30,360 arguments what you now have via this 23479 15:04:27,480 --> 15:04:32,320 args and KW ARG syntax but again they do 23480 15:04:30,360 --> 15:04:35,360 not need to be called that is the 23481 15:04:32,320 --> 15:04:38,040 ability using that star or two stars to 23482 15:04:35,360 --> 15:04:41,000 implement those kinds of functions 23483 15:04:38,040 --> 15:04:42,756 yourself my own F function a moment ago 23484 15:04:41,000 --> 15:04:44,796 did not do anything all that interesting 23485 15:04:42,756 --> 15:04:47,040 but it hints at how you could if in the 23486 15:04:44,796 --> 15:04:49,520 future you have a use case for taking 23487 15:04:47,040 --> 15:04:52,160 zero or one or more of either type of 23488 15:04:49,520 --> 15:04:55,276 argument any questions 23489 15:04:52,160 --> 15:04:57,840 now on these types of 23490 15:04:55,276 --> 15:05:00,560 arguments what will happen if you print 23491 15:04:57,840 --> 15:05:03,436 quarks and the argument is 23492 15:05:00,560 --> 15:05:04,880 like a list ah so what would happen if 23493 15:05:03,436 --> 15:05:06,720 you print the argument like it's a list 23494 15:05:04,880 --> 15:05:10,080 so I think we saw that if I roll back in 23495 15:05:06,720 --> 15:05:11,756 my history here to when I had that F 23496 15:05:10,080 --> 15:05:13,240 function which I called f just to be 23497 15:05:11,756 --> 15:05:15,756 very generic just so we could play 23498 15:05:13,240 --> 15:05:20,680 around with the syntax this is what I 23499 15:05:15,756 --> 15:05:23,000 had here so this is a um I passed in 100 23500 15:05:20,680 --> 15:05:25,880 comma 50 comma 25 that gets 23501 15:05:23,000 --> 15:05:27,436 automatically stored in args and when I 23502 15:05:25,880 --> 15:05:29,756 run it you can actually see that 23503 15:05:27,436 --> 15:05:32,276 sequence of values by running python of 23504 15:05:29,756 --> 15:05:34,520 unpack up high there is that sequence 23505 15:05:32,276 --> 15:05:36,080 all in the form of one single variable 23506 15:05:34,520 --> 15:05:37,916 I'm printing it just for Diagnostic 23507 15:05:36,080 --> 15:05:40,000 purposes this is not really a useful or 23508 15:05:37,916 --> 15:05:43,756 pretty program but it hints at how we 23509 15:05:40,000 --> 15:05:44,680 can access that whole sequence of values 23510 15:05:43,756 --> 15:05:48,320 other 23511 15:05:44,680 --> 15:05:51,636 questions on this approach here can we 23512 15:05:48,320 --> 15:05:53,796 pass kws from one function to another 23513 15:05:51,636 --> 15:05:55,240 function absolutely you can pass either 23514 15:05:53,796 --> 15:05:57,596 of those to another function which you 23515 15:05:55,240 --> 15:05:59,636 might want to do if you want to wrap 23516 15:05:57,596 --> 15:06:01,956 another function provide some additional 23517 15:05:59,636 --> 15:06:04,436 functionality but still pass in all of 23518 15:06:01,956 --> 15:06:06,240 the supported arguments to the 23519 15:06:04,436 --> 15:06:10,040 underlying function as 23520 15:06:06,240 --> 15:06:12,360 well all right how about this next it 23521 15:06:10,040 --> 15:06:15,240 turns out that a few other tools we can 23522 15:06:12,360 --> 15:06:16,956 add to your toolkit relate to the types 23523 15:06:15,240 --> 15:06:19,160 of programming models that python 23524 15:06:16,956 --> 15:06:21,160 supports we started out quite some time 23525 15:06:19,160 --> 15:06:23,160 ago focusing really on procedural 23526 15:06:21,160 --> 15:06:24,720 programming in Python whereby we wrote 23527 15:06:23,160 --> 15:06:26,916 code top to bottom left to right 23528 15:06:24,720 --> 15:06:29,880 defining some functions or if you will 23529 15:06:26,916 --> 15:06:31,520 procedures along the way defining Vari 23530 15:06:29,880 --> 15:06:34,000 and having side effects and assigning 23531 15:06:31,520 --> 15:06:35,796 values as needed but we then eventually 23532 15:06:34,000 --> 15:06:38,160 introduced or really revealed that 23533 15:06:35,796 --> 15:06:40,200 python is also very much object oriented 23534 15:06:38,160 --> 15:06:41,880 and a lot of those variables a lot of 23535 15:06:40,200 --> 15:06:44,596 those types that we were using all that 23536 15:06:41,880 --> 15:06:46,956 time were in fact objects objects that 23537 15:06:44,596 --> 15:06:48,840 were uh came from certain classes and 23538 15:06:46,956 --> 15:06:50,436 those classes were templates of sorts 23539 15:06:48,840 --> 15:06:52,636 blueprints via which you could 23540 15:06:50,436 --> 15:06:54,796 encapsulate both data and functionality 23541 15:06:52,636 --> 15:06:56,880 therein well we also saw along the way 23542 15:06:54,796 --> 15:06:58,560 some hints of a third Paradigm of 23543 15:06:56,880 --> 15:07:00,040 programming that python also to some 23544 15:06:58,560 --> 15:07:02,360 extent it support 23545 15:07:00,040 --> 15:07:04,796 which is known as functional programming 23546 15:07:02,360 --> 15:07:06,720 whereby functions are ever more powerful 23547 15:07:04,796 --> 15:07:08,916 in that they tend not to have side 23548 15:07:06,720 --> 15:07:11,200 effects no printing or changing of State 23549 15:07:08,916 --> 15:07:13,320 globally but rather they're completely 23550 15:07:11,200 --> 15:07:16,200 self-contained and might take as inputs 23551 15:07:13,320 --> 15:07:18,160 and return values and that's generally a 23552 15:07:16,200 --> 15:07:20,560 paradigm we saw when we started sorting 23553 15:07:18,160 --> 15:07:22,720 things particularly with functions like 23554 15:07:20,560 --> 15:07:24,680 our sort function or Lambda function 23555 15:07:22,720 --> 15:07:27,360 when we passed in the function we wanted 23556 15:07:24,680 --> 15:07:29,520 to use to sort a list way back when well 23557 15:07:27,360 --> 15:07:31,840 it turns out python has other fun 23558 15:07:29,520 --> 15:07:33,680 functionality that is reminiscent of 23559 15:07:31,840 --> 15:07:35,840 functional programming and indeed is a 23560 15:07:33,680 --> 15:07:38,080 powerful way to solve problems a little 23561 15:07:35,840 --> 15:07:40,200 more differently still let me propose 23562 15:07:38,080 --> 15:07:42,956 this let me propose that I whip up a new 23563 15:07:40,200 --> 15:07:45,200 program here in vs code by closing our 23564 15:07:42,956 --> 15:07:47,400 unpack. and this time creating another 23565 15:07:45,200 --> 15:07:48,956 program called yell suppose the goal at 23566 15:07:47,400 --> 15:07:50,880 hand is to implement some program that 23567 15:07:48,956 --> 15:07:53,040 allows the user to pass in input and 23568 15:07:50,880 --> 15:07:55,276 then it yells the response by forcing 23569 15:07:53,040 --> 15:07:57,000 everything to uppercase my apologies to 23570 15:07:55,276 --> 15:07:59,000 those with with headphones there I'll 23571 15:07:57,000 --> 15:08:02,160 I'll modulate so let me go ahead and run 23572 15:07:59,000 --> 15:08:04,436 code of yell. pi and within yell. Pi 23573 15:08:02,160 --> 15:08:06,520 let's go ahead and Implement a program 23574 15:08:04,436 --> 15:08:08,796 that really does just that let's go 23575 15:08:06,520 --> 15:08:10,320 ahead and Define a main function up here 23576 15:08:08,796 --> 15:08:12,116 and let's assume for the moment that 23577 15:08:10,320 --> 15:08:14,240 this yell function already exists and 23578 15:08:12,116 --> 15:08:17,240 yell something like this is cs-50 23579 15:08:14,240 --> 15:08:19,200 properly capitalized not in all caps now 23580 15:08:17,240 --> 15:08:21,720 let's go ahead and implement this yell 23581 15:08:19,200 --> 15:08:25,560 function with deaf yell it's going to 23582 15:08:21,720 --> 15:08:27,636 take for now a single uh word or phrase 23583 15:08:25,560 --> 15:08:29,400 uh and let's go ahead and I'll call it 23584 15:08:27,636 --> 15:08:33,116 phrase here and I'm going to go ahead 23585 15:08:29,400 --> 15:08:34,680 and just print out the phrase. uper so 23586 15:08:33,116 --> 15:08:36,520 phrase. upper is going to force the 23587 15:08:34,680 --> 15:08:38,240 whole thing to uppercase and as usual 23588 15:08:36,520 --> 15:08:41,240 down here if the name of this file 23589 15:08:38,240 --> 15:08:43,596 equals equals quote unquote uh main then 23590 15:08:41,240 --> 15:08:45,240 let's go ahead as always and call Main 23591 15:08:43,596 --> 15:08:46,916 so let's just run this but for the most 23592 15:08:45,240 --> 15:08:49,916 part it should be fairly straightforward 23593 15:08:46,916 --> 15:08:53,040 when I run python of yell. py this is 23594 15:08:49,916 --> 15:08:55,040 cs50 is yelled on the screen all right 23595 15:08:53,040 --> 15:08:58,916 that's nice but it's not great that yell 23596 15:08:55,040 --> 15:09:01,276 only expects a single uh expects a 23597 15:08:58,916 --> 15:09:03,720 single phrase wouldn't it be nice like 23598 15:09:01,276 --> 15:09:06,116 print if I could pass in one phrase or 23599 15:09:03,720 --> 15:09:08,436 two or three or really multiple words 23600 15:09:06,116 --> 15:09:10,436 more generally but as individual words 23601 15:09:08,436 --> 15:09:12,756 themselves so let me retool this a 23602 15:09:10,436 --> 15:09:14,956 little bit and change yel to take in not 23603 15:09:12,756 --> 15:09:17,520 a phrase but how about something like a 23604 15:09:14,956 --> 15:09:21,480 list of words so that ultimately I can 23605 15:09:17,520 --> 15:09:24,480 call Yell like this uh quote unquote 23606 15:09:21,480 --> 15:09:26,916 this inside of a list quote unquote this 23607 15:09:24,480 --> 15:09:28,680 inside of a list and quote unquote cs50 23608 15:09:26,916 --> 15:09:30,520 inside of a list I'm not going to bother 23609 15:09:28,680 --> 15:09:32,000 with typ pen answer annotations for now 23610 15:09:30,520 --> 15:09:35,276 but I'll just assume that yel has been 23611 15:09:32,000 --> 15:09:37,276 defined now is taking a list of words as 23612 15:09:35,276 --> 15:09:39,320 defined here but now I want to force 23613 15:09:37,276 --> 15:09:41,080 them all to lowercase so I don't quite 23614 15:09:39,320 --> 15:09:44,000 want to do something as simple as this 23615 15:09:41,080 --> 15:09:47,080 like for word in words I could for 23616 15:09:44,000 --> 15:09:49,796 instance print that given word and maybe 23617 15:09:47,080 --> 15:09:53,040 end the line with nothing right now but 23618 15:09:49,796 --> 15:09:54,796 I think if I do this python of yell. no 23619 15:09:53,040 --> 15:09:57,596 that's that's not right I haven't forced 23620 15:09:54,796 --> 15:09:59,480 anything to uppercase so let's fix this 23621 15:09:57,596 --> 15:10:01,796 well let's go ahead and do the following 23622 15:09:59,480 --> 15:10:04,360 let me go ahead and accumulate the 23623 15:10:01,796 --> 15:10:06,160 uppercase words as follows let me create 23624 15:10:04,360 --> 15:10:07,880 a variable called uppercase and 23625 15:10:06,160 --> 15:10:10,436 initialize it to an empty list using 23626 15:10:07,880 --> 15:10:12,636 square brackets or or more verbose list 23627 15:10:10,436 --> 15:10:14,840 syntax and now let me go ahead and 23628 15:10:12,636 --> 15:10:18,040 iterate over each of those words in 23629 15:10:14,840 --> 15:10:22,116 Words and for each of them let's go into 23630 15:10:18,040 --> 15:10:25,360 our uppercase list append to it the 23631 15:10:22,116 --> 15:10:27,796 current words uppercase version so this 23632 15:10:25,360 --> 15:10:30,116 is a way of creating a new list called 23633 15:10:27,796 --> 15:10:32,436 uppercase that is just appending 23634 15:10:30,116 --> 15:10:34,160 appending appending to that list each of 23635 15:10:32,436 --> 15:10:37,000 the current words in the loop but 23636 15:10:34,160 --> 15:10:39,160 uppercased instead and now just let me 23637 15:10:37,000 --> 15:10:41,000 go ahead and print out the uppercase 23638 15:10:39,160 --> 15:10:44,000 list this isn't quite right let's see 23639 15:10:41,000 --> 15:10:46,720 what happens here python of 23640 15:10:44,000 --> 15:10:49,000 yelpy okay it's not quite right because 23641 15:10:46,720 --> 15:10:51,040 I don't think I want those quotes or 23642 15:10:49,000 --> 15:10:54,116 those square brackets what am I seeing 23643 15:10:51,040 --> 15:10:55,720 I'm actually printing a list but but but 23644 15:10:54,116 --> 15:10:57,840 here's where some of our unpacking 23645 15:10:55,720 --> 15:10:59,480 syntax now can be useful I don't have to 23646 15:10:57,840 --> 15:11:02,116 change my approach to this problem I can 23647 15:10:59,480 --> 15:11:04,796 just unpack uppercase by adding a single 23648 15:11:02,116 --> 15:11:07,596 star and now let me go ahead and rerun 23649 15:11:04,796 --> 15:11:09,400 python of yelpy and now it's actually 23650 15:11:07,596 --> 15:11:11,160 just English there's no remnants of 23651 15:11:09,400 --> 15:11:13,720 python syntax like the quotes and the 23652 15:11:11,160 --> 15:11:17,480 commas and the square brackets I've now 23653 15:11:13,720 --> 15:11:19,720 unpacked this is cs50 as three separate 23654 15:11:17,480 --> 15:11:21,636 arguments to print so already now this 23655 15:11:19,720 --> 15:11:24,436 unpacking technique would seem to be 23656 15:11:21,636 --> 15:11:27,080 useful well it's a little unfortunate 23657 15:11:24,436 --> 15:11:29,956 that I now need to call Yell though with 23658 15:11:27,080 --> 15:11:31,956 a list of values in this way this is 23659 15:11:29,956 --> 15:11:33,520 just not the norm or at least it's not 23660 15:11:31,956 --> 15:11:35,560 nearly as user friendly as something 23661 15:11:33,520 --> 15:11:37,480 like the print function where I can pass 23662 15:11:35,560 --> 15:11:39,240 in zero or one or two or three or any 23663 15:11:37,480 --> 15:11:41,916 number of arguments why are you making 23664 15:11:39,240 --> 15:11:44,000 me for your yell function pass in only a 23665 15:11:41,916 --> 15:11:45,276 list well we can do better let's adopt 23666 15:11:44,000 --> 15:11:46,796 some of the new conventions we've 23667 15:11:45,276 --> 15:11:48,916 learned and let's go ahead and get rid 23668 15:11:46,796 --> 15:11:51,436 of the list by removing the square 23669 15:11:48,916 --> 15:11:53,240 brackets and let's just pass yel three 23670 15:11:51,436 --> 15:11:55,116 arguments now I don't want to do 23671 15:11:53,240 --> 15:11:58,796 something like change the definition of 23672 15:11:55,116 --> 15:12:00,160 words to take in like word one word two 23673 15:11:58,796 --> 15:12:01,596 like that's not going to scale and it's 23674 15:12:00,160 --> 15:12:04,200 not going to handle different number of 23675 15:12:01,596 --> 15:12:07,160 words but we have a technique now we can 23676 15:12:04,200 --> 15:12:09,160 say star args which will allow the yell 23677 15:12:07,160 --> 15:12:11,360 function to accept any number of 23678 15:12:09,160 --> 15:12:13,200 arguments and just for specificity let's 23679 15:12:11,360 --> 15:12:14,756 not call it generically arcs let's name 23680 15:12:13,200 --> 15:12:17,320 it something a little more 23681 15:12:14,756 --> 15:12:19,040 self-explanatory like star words this 23682 15:12:17,320 --> 15:12:22,436 just means I have a variable number of 23683 15:12:19,040 --> 15:12:24,116 words being passed in now I think I've 23684 15:12:22,436 --> 15:12:26,880 made a marginal Improvement let me run 23685 15:12:24,116 --> 15:12:29,680 this again python of yell. py this is 23686 15:12:26,880 --> 15:12:32,116 cs50 is in all caps but is just a little 23687 15:12:29,680 --> 15:12:34,880 better right because now I can treat yel 23688 15:12:32,116 --> 15:12:37,116 just like I've long treated print pass 23689 15:12:34,880 --> 15:12:39,116 in as many things as you want and print 23690 15:12:37,116 --> 15:12:40,916 will deal with it now my yell function 23691 15:12:39,116 --> 15:12:43,480 is just as powerful it would seem and 23692 15:12:40,916 --> 15:12:45,956 better still it also forces everything 23693 15:12:43,480 --> 15:12:47,520 to uppercase well it turns out python 23694 15:12:45,956 --> 15:12:49,880 comes with this function called map 23695 15:12:47,520 --> 15:12:53,680 whose purpose in life is to allow you to 23696 15:12:49,880 --> 15:12:56,756 map that is apply some function to every 23697 15:12:53,680 --> 15:12:58,720 element of some sequence like a list so 23698 15:12:56,756 --> 15:13:02,956 for instance if we want to force to 23699 15:12:58,720 --> 15:13:05,636 Upper case each of the words this is 23700 15:13:02,956 --> 15:13:07,916 cs50 in the list of words that's been 23701 15:13:05,636 --> 15:13:10,880 passed in well we essentially want to 23702 15:13:07,916 --> 15:13:13,040 map the uppercase function to each of 23703 15:13:10,880 --> 15:13:15,436 those values so using map in Python can 23704 15:13:13,040 --> 15:13:17,840 I do just that let me go back here to vs 23705 15:13:15,436 --> 15:13:20,560 code and let me propose now that I 23706 15:13:17,840 --> 15:13:22,840 reimplement this as follows I get rid of 23707 15:13:20,560 --> 15:13:26,320 all three of these lines here getting 23708 15:13:22,840 --> 15:13:28,000 rid of uh that Loop in particular let me 23709 15:13:26,320 --> 15:13:31,360 still declare a variable called 23710 15:13:28,000 --> 15:13:33,520 uppercase but let me set it equal to the 23711 15:13:31,360 --> 15:13:36,720 return value of this new function called 23712 15:13:33,520 --> 15:13:39,796 map map takes two arguments here in this 23713 15:13:36,720 --> 15:13:43,520 case the name of a function that I want 23714 15:13:39,796 --> 15:13:45,596 to map onto a sequence of values well 23715 15:13:43,520 --> 15:13:47,956 what function do I want to apply to 23716 15:13:45,596 --> 15:13:49,756 every word that's been passed in well it 23717 15:13:47,956 --> 15:13:51,596 turns out thanks to my knowledge now of 23718 15:13:49,756 --> 15:13:54,320 object-oriented programming I know that 23719 15:13:51,596 --> 15:13:56,880 in the stir class there is a function 23720 15:13:54,320 --> 15:14:00,080 called upper we've usually called it by 23721 15:13:56,880 --> 15:14:02,756 using the name of a string variable Dot 23722 15:14:00,080 --> 15:14:05,040 Upper open paren close paren but if you 23723 15:14:02,756 --> 15:14:07,080 read the documentation for the stir 23724 15:14:05,040 --> 15:14:09,880 class you'll see that the function is 23725 15:14:07,080 --> 15:14:12,160 described indeed as stir. uper I'm not 23726 15:14:09,880 --> 15:14:14,596 using parentheses open and close at the 23727 15:14:12,160 --> 15:14:17,480 end of stir. uper because I don't want 23728 15:14:14,596 --> 15:14:20,956 to call it now I want to pass this 23729 15:14:17,480 --> 15:14:23,160 function to the map function so that map 23730 15:14:20,956 --> 15:14:26,000 can somehow add those parentheses so to 23731 15:14:23,160 --> 15:14:29,000 speak and call it on every one of these 23732 15:14:26,000 --> 15:14:30,880 words and this is what map does quite 23733 15:14:29,000 --> 15:14:32,596 powerfully and is an instance indeed of 23734 15:14:30,880 --> 15:14:35,200 functional programming whereby I'm 23735 15:14:32,596 --> 15:14:37,200 passing to this map function another 23736 15:14:35,200 --> 15:14:40,116 function not calling it I'm just passing 23737 15:14:37,200 --> 15:14:42,880 it in by a reference of sorts and what 23738 15:14:40,116 --> 15:14:45,680 map is going to do for me is iterate 23739 15:14:42,880 --> 15:14:48,000 over each of those words call stir. 23740 15:14:45,680 --> 15:14:51,596 Upper on each of those words and return 23741 15:14:48,000 --> 15:14:54,720 to me a brand new list containing all of 23742 15:14:51,596 --> 15:14:56,520 those results together in one list it 23743 15:14:54,720 --> 15:14:59,240 completely obviates the need for me to 23744 15:14:56,520 --> 15:15:00,720 do this more manually using that list 23745 15:14:59,240 --> 15:15:02,520 I'm still going to print the whole thing 23746 15:15:00,720 --> 15:15:04,916 using star uppercase so that if I get 23747 15:15:02,520 --> 15:15:07,480 back a three a list of three uppercase 23748 15:15:04,916 --> 15:15:09,756 words I'm going to unpack them and print 23749 15:15:07,480 --> 15:15:15,000 them all out so let's run this again 23750 15:15:09,756 --> 15:15:17,276 python of yelpy enter and voila it's 23751 15:15:15,000 --> 15:15:20,596 still working but the code now is even 23752 15:15:17,276 --> 15:15:22,160 more tight uh even tighter than before 23753 15:15:20,596 --> 15:15:23,916 so it turns out there's another way we 23754 15:15:22,160 --> 15:15:26,160 can solve this problem in a way that's 23755 15:15:23,916 --> 15:15:27,956 even more pythonic or at least quite 23756 15:15:26,160 --> 15:15:31,200 common and that's using a feature known 23757 15:15:27,956 --> 15:15:33,240 as a list comprehension and it's a a big 23758 15:15:31,200 --> 15:15:35,680 phrase if you will but it refers to the 23759 15:15:33,240 --> 15:15:37,680 ability in Python for you to very easily 23760 15:15:35,680 --> 15:15:39,720 construct a list on the fly without 23761 15:15:37,680 --> 15:15:42,116 using a loop without calling a pendant a 23762 15:15:39,720 --> 15:15:45,240 pend but to do everything in one dare 23763 15:15:42,116 --> 15:15:48,116 say elegant oneliner so how can I go 23764 15:15:45,240 --> 15:15:50,636 about using this notion of a uh of a 23765 15:15:48,116 --> 15:15:53,720 list comprehension well let me go ahead 23766 15:15:50,636 --> 15:15:55,636 and do this in yelpy in vscode here let 23767 15:15:53,720 --> 15:15:57,880 me go ahead and change my Approach as 23768 15:15:55,636 --> 15:15:59,880 follows instead of using map which is 23769 15:15:57,880 --> 15:16:01,520 perfectly fine and correct in this way 23770 15:15:59,880 --> 15:16:04,680 let me just show you this other way as 23771 15:16:01,520 --> 15:16:06,520 well a list comprehension is the 23772 15:16:04,680 --> 15:16:08,720 opportunity to create a list like this 23773 15:16:06,520 --> 15:16:10,560 using square brackets like this but 23774 15:16:08,720 --> 15:16:13,276 inside of those square brackets to write 23775 15:16:10,560 --> 15:16:15,596 a python expression that in effect is 23776 15:16:13,276 --> 15:16:18,796 going to dynamically generate a brand 23777 15:16:15,596 --> 15:16:21,116 new list for you using some logic you've 23778 15:16:18,796 --> 15:16:23,360 written and the approach I might take 23779 15:16:21,116 --> 15:16:27,880 here is this if I want to store in this 23780 15:16:23,360 --> 15:16:32,436 list the uppercase version of every word 23781 15:16:27,880 --> 15:16:36,116 in that word list I can do this word. 23782 15:16:32,436 --> 15:16:39,360 uper for word 23783 15:16:36,116 --> 15:16:41,360 inword now this is a mouthful but I dare 23784 15:16:39,360 --> 15:16:43,240 say python programmers love this 23785 15:16:41,360 --> 15:16:46,636 capability of being able to Define on 23786 15:16:43,240 --> 15:16:48,520 the fly a list inside of which is any 23787 15:16:46,636 --> 15:16:50,200 number of values that you would 23788 15:16:48,520 --> 15:16:52,116 ordinarily at least as we've done it 23789 15:16:50,200 --> 15:16:53,916 construct with a loop and again calling 23790 15:16:52,116 --> 15:16:56,116 a pend and a pend in a pend but that 23791 15:16:53,916 --> 15:16:58,956 usually takes two three four or more 23792 15:16:56,116 --> 15:17:01,200 lines this list comprehension that that 23793 15:16:58,956 --> 15:17:03,636 I've highlighted here is now an 23794 15:17:01,200 --> 15:17:06,560 alternative way to create the exact same 23795 15:17:03,636 --> 15:17:09,040 thing a list inside of which are a whole 23796 15:17:06,560 --> 15:17:12,480 bunch of uppercased words which words 23797 15:17:09,040 --> 15:17:16,436 for each word in the words list that was 23798 15:17:12,480 --> 15:17:20,360 passed into yell is what ends up in this 23799 15:17:16,436 --> 15:17:21,720 list questions on this syntax here it 23800 15:17:20,360 --> 15:17:23,796 definitely takes a little bit of getting 23801 15:17:21,720 --> 15:17:25,756 used to because you've got like this 23802 15:17:23,796 --> 15:17:28,160 value on the left this function call 23803 15:17:25,756 --> 15:17:29,360 here you've got this Loop inside of the 23804 15:17:28,160 --> 15:17:31,560 square bracket 23805 15:17:29,360 --> 15:17:33,400 but if you become accustomed to reading 23806 15:17:31,560 --> 15:17:35,360 the code in this way from left to right 23807 15:17:33,400 --> 15:17:38,116 this means give me the uppercase version 23808 15:17:35,360 --> 15:17:40,880 of the word for each word in my words 23809 15:17:38,116 --> 15:17:43,596 list questions here on list 23810 15:17:40,880 --> 15:17:48,320 comprehensions uh can you do conditional 23811 15:17:43,596 --> 15:17:51,000 so also like if else or uh combine if L 23812 15:17:48,320 --> 15:17:52,040 if else indeed you can and let me come 23813 15:17:51,000 --> 15:17:53,636 back to that where we'll see an 23814 15:17:52,040 --> 15:17:55,520 opportunity to do things conditionally 23815 15:17:53,636 --> 15:17:58,200 but for now I'm just upper casing every 23816 15:17:55,520 --> 15:18:01,160 word in the list a good question other 23817 15:17:58,200 --> 15:18:04,116 questions yeah um is is this is this 23818 15:18:01,160 --> 15:18:06,756 functional programming or u i mean this 23819 15:18:04,116 --> 15:18:08,796 particular thing where you saying words 23820 15:18:06,756 --> 15:18:10,756 do upper for word in word not 23821 15:18:08,796 --> 15:18:14,956 necessarily this is more of a feature of 23822 15:18:10,756 --> 15:18:16,720 python I would say yeah map was uh one 23823 15:18:14,956 --> 15:18:18,840 uh very specific incarnation of thereof 23824 15:18:16,720 --> 15:18:20,916 our use of Lambda and passing it in as a 23825 15:18:18,840 --> 15:18:22,680 key attribute to the sort fun sorted 23826 15:18:20,916 --> 15:18:25,636 function a while back was an example and 23827 15:18:22,680 --> 15:18:27,520 we're about to see uh one other so we 23828 15:18:25,636 --> 15:18:29,796 can even use these list comprehensions 23829 15:18:27,520 --> 15:18:31,680 to filter values in or out of our 23830 15:18:29,796 --> 15:18:33,520 resulting list so in fact in vs code 23831 15:18:31,680 --> 15:18:35,520 here let me close yel up high and close 23832 15:18:33,520 --> 15:18:37,320 my terminal window and let me create a 23833 15:18:35,520 --> 15:18:39,796 new program here whose purpose in life 23834 15:18:37,320 --> 15:18:42,756 maybe is to take a same list of students 23835 15:18:39,796 --> 15:18:45,320 as before with a shorter version thereof 23836 15:18:42,756 --> 15:18:47,116 and just filter out all of the students 23837 15:18:45,320 --> 15:18:50,040 in Gryffindor so let me go ahead and 23838 15:18:47,116 --> 15:18:51,400 create a file called gryffindors dopy 23839 15:18:50,040 --> 15:18:54,000 I'm going to go ahead and copy paste 23840 15:18:51,400 --> 15:18:56,560 from before really my list of students 23841 15:18:54,000 --> 15:18:58,796 at least hermion Harry Ron and Draco 23842 15:18:56,560 --> 15:19:01,916 from the start here just so that I can 23843 15:18:58,796 --> 15:19:03,636 focus on uh one student who happens not 23844 15:19:01,916 --> 15:19:05,596 to be from Slytherin and what I'm going 23845 15:19:03,636 --> 15:19:07,720 to do here now if I want to filter out 23846 15:19:05,596 --> 15:19:09,720 only the Gryffindor students let me go 23847 15:19:07,720 --> 15:19:11,756 ahead and do this let me create another 23848 15:19:09,720 --> 15:19:14,596 variable called gryffindors which is 23849 15:19:11,756 --> 15:19:16,200 going to equal the following list and 23850 15:19:14,596 --> 15:19:18,000 this is going to be a bit of a longer 23851 15:19:16,200 --> 15:19:20,480 line so I'm going to proactively move my 23852 15:19:18,000 --> 15:19:22,360 square brackets onto two separate lines 23853 15:19:20,480 --> 15:19:24,880 and I'm going to create now a list 23854 15:19:22,360 --> 15:19:27,040 comprehension I want to do this I want 23855 15:19:24,880 --> 15:19:30,916 this new list called gryffindors to 23856 15:19:27,040 --> 15:19:35,320 contain every students's name for each 23857 15:19:30,916 --> 15:19:39,160 student in the students list but but but 23858 15:19:35,320 --> 15:19:41,756 if the students house equals equals 23859 15:19:39,160 --> 15:19:43,916 quote unquote Gryffindor so this is 23860 15:19:41,756 --> 15:19:46,276 nearly identical in spirit to what I 23861 15:19:43,916 --> 15:19:47,880 just did earlier to create a list 23862 15:19:46,276 --> 15:19:50,160 comprehension out of each of the words 23863 15:19:47,880 --> 15:19:52,040 passed to my yell function but here I'm 23864 15:19:50,160 --> 15:19:53,796 doing so conditionally and so I'm 23865 15:19:52,040 --> 15:19:56,080 borrowing inspiration from our focus on 23866 15:19:53,796 --> 15:19:59,360 Loops borrowing some inspiration from 23867 15:19:56,080 --> 15:20:01,436 our focus on uh conditionals combining 23868 15:19:59,360 --> 15:20:03,240 that into this same square bracket 23869 15:20:01,436 --> 15:20:06,480 notation so that what gryffindors 23870 15:20:03,240 --> 15:20:09,436 ultimately is is zero or more students 23871 15:20:06,480 --> 15:20:11,840 names and the names that are included 23872 15:20:09,436 --> 15:20:15,000 are the result of iterating over each of 23873 15:20:11,840 --> 15:20:18,116 those students and only including in the 23874 15:20:15,000 --> 15:20:20,116 final result these students whose house 23875 15:20:18,116 --> 15:20:21,636 happens to be Gryffindor so when I go 23876 15:20:20,116 --> 15:20:23,720 ahead and run this with python of 23877 15:20:21,636 --> 15:20:26,080 gryffindors dopy and hit enter you'll 23878 15:20:23,720 --> 15:20:27,596 see huh nothing actually happened here 23879 15:20:26,080 --> 15:20:29,360 well that's because I didn't finish the 23880 15:20:27,596 --> 15:20:32,080 program let me go and actually finish 23881 15:20:29,360 --> 15:20:35,000 the program with this how about for each 23882 15:20:32,080 --> 15:20:37,080 Gryffindor in Gryffindor plural and 23883 15:20:35,000 --> 15:20:38,560 better yet so that it's sensible that I 23884 15:20:37,080 --> 15:20:40,400 did all of this work in advance let me 23885 15:20:38,560 --> 15:20:43,000 go ahead and sort all of those names 23886 15:20:40,400 --> 15:20:46,040 with our familiar sorted function let's 23887 15:20:43,000 --> 15:20:48,956 go ahead now and print out each of these 23888 15:20:46,040 --> 15:20:50,160 gryffindors so now notice if familiar 23889 15:20:48,956 --> 15:20:51,636 with the books and the movies you'll 23890 15:20:50,160 --> 15:20:53,320 know that only three of these four 23891 15:20:51,636 --> 15:20:55,916 students are actually in Gryffindor and 23892 15:20:53,320 --> 15:20:59,000 if I run python of Gryffindor dopy there 23893 15:20:55,916 --> 15:21:02,040 we see Harry Hermione and Ron but now in 23894 15:20:59,000 --> 15:21:03,956 sorted order as well so that's just one 23895 15:21:02,040 --> 15:21:05,680 way we can solve this same problem using 23896 15:21:03,956 --> 15:21:07,956 not just a list comprehension but a list 23897 15:21:05,680 --> 15:21:10,160 comprehension that has this conditional 23898 15:21:07,956 --> 15:21:12,040 therein but there's yet other ways to 23899 15:21:10,160 --> 15:21:13,840 solve this same problem too and we come 23900 15:21:12,040 --> 15:21:16,276 back to some functional features of 23901 15:21:13,840 --> 15:21:18,160 python in addition to functions like Map 23902 15:21:16,276 --> 15:21:19,916 There's also this one called filter that 23903 15:21:18,160 --> 15:21:22,040 can be used to achieve the same effect 23904 15:21:19,916 --> 15:21:24,436 but with a more functional approach if 23905 15:21:22,040 --> 15:21:27,436 you will let me go back to vs code here 23906 15:21:24,436 --> 15:21:29,756 and with the same example let me do this 23907 15:21:27,436 --> 15:21:32,160 let me leave the original list up above 23908 15:21:29,756 --> 15:21:33,956 as before including Draco who's not in 23909 15:21:32,160 --> 15:21:36,560 fact from Gryffindor and let me 23910 15:21:33,956 --> 15:21:39,276 temporarily Define a function called is 23911 15:21:36,560 --> 15:21:41,916 Gryffindor that takes in as uh value 23912 15:21:39,276 --> 15:21:44,796 something uh like a student s and then 23913 15:21:41,916 --> 15:21:48,080 let's do this let's go ahead and say if 23914 15:21:44,796 --> 15:21:51,596 s quote unquote house equals equals 23915 15:21:48,080 --> 15:21:56,520 Gryffindor then go ahead and return 23916 15:21:51,596 --> 15:21:58,080 true otherwise go ahead and return false 23917 15:21:56,520 --> 15:21:59,560 now we've seen before conditionals like 23918 15:21:58,080 --> 15:22:01,636 this that are a bit unnecessarily 23919 15:21:59,560 --> 15:22:03,560 verbose I don't need to have a 23920 15:22:01,636 --> 15:22:05,796 conditional if I'm already asking a 23921 15:22:03,560 --> 15:22:07,320 Boolean question up here so I can 23922 15:22:05,796 --> 15:22:09,636 actually tighten this up as we've done 23923 15:22:07,320 --> 15:22:12,160 in the past and just return does the 23924 15:22:09,636 --> 15:22:13,880 student's house equal equal Gryffindor 23925 15:22:12,160 --> 15:22:15,360 either it does and it's true or it 23926 15:22:13,880 --> 15:22:17,360 doesn't and it's false I don't need to 23927 15:22:15,360 --> 15:22:20,520 explicitly return true or false I can 23928 15:22:17,360 --> 15:22:22,400 just return the value of that Boolean 23929 15:22:20,520 --> 15:22:24,276 let's go ahead now and do this I'm going 23930 15:22:22,400 --> 15:22:26,276 to create as before a variable called 23931 15:22:24,276 --> 15:22:28,880 gryffindors a list for all of my 23932 15:22:26,276 --> 15:22:32,080 Gryffindor students that equals to this 23933 15:22:28,880 --> 15:22:34,160 time the result of calling filter filter 23934 15:22:32,080 --> 15:22:37,400 takes at least two arguments here one of 23935 15:22:34,160 --> 15:22:40,276 which is the name of a function to call 23936 15:22:37,400 --> 15:22:42,400 is Gryffindor and I'm going to apply 23937 15:22:40,276 --> 15:22:45,520 that function to each of the elements of 23938 15:22:42,400 --> 15:22:48,080 this sequence here so similar in spirit 23939 15:22:45,520 --> 15:22:49,956 to map I'm passing in a function that's 23940 15:22:48,080 --> 15:22:52,720 going to be applied to each of the 23941 15:22:49,956 --> 15:22:54,436 elements in the sequence but map returns 23942 15:22:52,720 --> 15:22:56,116 one value for each element in the 23943 15:22:54,436 --> 15:22:58,680 sequence that's how we forced all of the 23944 15:22:56,116 --> 15:23:02,360 words to uppercase but if I want to 23945 15:22:58,680 --> 15:23:04,720 conditionally include a student in my 23946 15:23:02,360 --> 15:23:07,360 resulting gryffindor's list I can use 23947 15:23:04,720 --> 15:23:09,360 filter instead filter expects its first 23948 15:23:07,360 --> 15:23:11,400 function to be not something like stir. 23949 15:23:09,360 --> 15:23:14,520 upper but a function that returns true 23950 15:23:11,400 --> 15:23:17,160 or false tell me whether or not I should 23951 15:23:14,520 --> 15:23:19,596 include or not include the current 23952 15:23:17,160 --> 15:23:21,200 student from the final list and the 23953 15:23:19,596 --> 15:23:22,840 question being asked is do they live in 23954 15:23:21,200 --> 15:23:25,520 Gryffindor we're checking the 23955 15:23:22,840 --> 15:23:27,880 dictionary's house key for that answer 23956 15:23:25,520 --> 15:23:30,520 and so ultimately I think we'll be left 23957 15:23:27,880 --> 15:23:33,680 with something quite similar for 23958 15:23:30,520 --> 15:23:36,480 Gryffindor in the sorted ver let's do 23959 15:23:33,680 --> 15:23:38,000 for Gryffindor in gryffindors let's go 23960 15:23:36,480 --> 15:23:40,480 ahead then and print out the current 23961 15:23:38,000 --> 15:23:42,636 students Gryffindor name it's not going 23962 15:23:40,480 --> 15:23:44,520 to be sorted just yet but when I run 23963 15:23:42,636 --> 15:23:46,520 this version here python of Gryffindor 23964 15:23:44,520 --> 15:23:48,160 stpy and hit enter we're back in 23965 15:23:46,520 --> 15:23:51,276 business it's unsorted but we have 23966 15:23:48,160 --> 15:23:53,116 Hermione Harry and Ron but not Draco and 23967 15:23:51,276 --> 15:23:54,880 if you recall from a few weeks back if 23968 15:23:53,116 --> 15:23:57,320 we want to sort even a list of 23969 15:23:54,880 --> 15:23:58,880 dictionaries we can still do that too I 23970 15:23:57,320 --> 15:24:01,880 can call sort 23971 15:23:58,880 --> 15:24:04,680 on Gryffindor plural and I can pass in a 23972 15:24:01,880 --> 15:24:06,796 key and that key can have a Anonymous 23973 15:24:04,680 --> 15:24:09,400 function AKA a Lambda function that 23974 15:24:06,796 --> 15:24:12,080 takes in a student as input call it s 23975 15:24:09,400 --> 15:24:14,680 and then Returns the value s quote 23976 15:24:12,080 --> 15:24:17,756 unquote name if my goal is to sort by 23977 15:24:14,680 --> 15:24:19,560 indeed uh students own names if I go 23978 15:24:17,756 --> 15:24:22,000 ahead now and run python of griffindor 23979 15:24:19,560 --> 15:24:24,916 dopy I see the same list of students but 23980 15:24:22,000 --> 15:24:26,436 this time it's sorted so here we've seen 23981 15:24:24,916 --> 15:24:28,080 two approaches to this particular 23982 15:24:26,436 --> 15:24:30,240 problem of Gryffindor students whereby 23983 15:24:28,080 --> 15:24:32,240 we can either use something like a list 23984 15:24:30,240 --> 15:24:34,436 comprehension and inside of that list 23985 15:24:32,240 --> 15:24:38,040 comprehension do a bit of filtration 23986 15:24:34,436 --> 15:24:39,880 including an if conditional as I did or 23987 15:24:38,040 --> 15:24:41,880 we can take a more functional approach 23988 15:24:39,880 --> 15:24:44,796 by just using this filter function 23989 15:24:41,880 --> 15:24:47,480 passing into it the function that I want 23990 15:24:44,796 --> 15:24:50,360 to make these decisions for me and then 23991 15:24:47,480 --> 15:24:52,436 include only those for whom true is 23992 15:24:50,360 --> 15:24:55,756 returned any questions on either of 23993 15:24:52,436 --> 15:24:57,956 these two approaches uh yeah I just had 23994 15:24:55,756 --> 15:24:59,400 a question that if we write the code 23995 15:24:57,956 --> 15:25:01,160 like the previous version where 23996 15:24:59,400 --> 15:25:04,000 everything is stuffed into one light 23997 15:25:01,160 --> 15:25:07,240 what the if we check for the style of 23998 15:25:04,000 --> 15:25:09,480 the code then won't it have a don't it 23999 15:25:07,240 --> 15:25:12,276 have a problem with it because it's less 24000 15:25:09,480 --> 15:25:13,916 readable so would a formatter like black 24001 15:25:12,276 --> 15:25:16,320 have a problem with the style of some of 24002 15:25:13,916 --> 15:25:18,436 this code the previous one where the 24003 15:25:16,320 --> 15:25:21,080 everything was stupped into one line oh 24004 15:25:18,436 --> 15:25:22,520 a good question would something like 24005 15:25:21,080 --> 15:25:24,480 black have a problem with this code well 24006 15:25:22,520 --> 15:25:26,000 let me rewind to that version which was 24007 15:25:24,480 --> 15:25:28,880 using the somewhat 24008 15:25:26,000 --> 15:25:31,636 longer uh list comprehension 24009 15:25:28,880 --> 15:25:34,360 which looked like if we go far enough 24010 15:25:31,636 --> 15:25:36,720 back give me a few more undos which 24011 15:25:34,360 --> 15:25:39,520 looked like this ultimately let me go 24012 15:25:36,720 --> 15:25:41,080 ahead and run black on gryffindors dopy 24013 15:25:39,520 --> 15:25:43,480 and you'll see that I actually it 24014 15:25:41,080 --> 15:25:45,756 reformatted ever so slightly but I 24015 15:25:43,480 --> 15:25:48,040 proactively fixed this myself had I done 24016 15:25:45,756 --> 15:25:49,916 this and done it on just one line but I 24017 15:25:48,040 --> 15:25:51,520 knew that black might not like that it 24018 15:25:49,916 --> 15:25:53,560 would have fixed it for me so I just 24019 15:25:51,520 --> 15:25:55,880 proactively fixed it before writing the 24020 15:25:53,560 --> 15:25:58,956 code myself how about time for one other 24021 15:25:55,880 --> 15:26:00,560 question on gryffindors high in this 24022 15:25:58,956 --> 15:26:05,240 approach of using a list comprehension 24023 15:26:00,560 --> 15:26:07,680 or filter yeah when when using filter 24024 15:26:05,240 --> 15:26:11,796 instead of calling the function is 24025 15:26:07,680 --> 15:26:14,680 Ginder can you use it ER right there 24026 15:26:11,796 --> 15:26:17,160 inside filter can you use the function 24027 15:26:14,680 --> 15:26:18,636 is Gryffindor so you don't want to call 24028 15:26:17,160 --> 15:26:20,880 it like this because you don't want to 24029 15:26:18,636 --> 15:26:23,200 call it then you want filter to call the 24030 15:26:20,880 --> 15:26:26,720 function for you if that's what you mean 24031 15:26:23,200 --> 15:26:28,796 so I pass it in only by its name 24032 15:26:26,720 --> 15:26:33,480 instead no I me 24033 15:26:28,796 --> 15:26:37,636 if you can write the return as house 24034 15:26:33,480 --> 15:26:40,000 equals equals the inside F yes indeed in 24035 15:26:37,636 --> 15:26:41,680 fact so recall that we indeed used these 24036 15:26:40,000 --> 15:26:43,560 Lambda functions way back when when we 24037 15:26:41,680 --> 15:26:46,596 wanted to pass in a quick and dirty 24038 15:26:43,560 --> 15:26:48,200 function anonymously to allow sorted to 24039 15:26:46,596 --> 15:26:50,720 filter by a different key of a 24040 15:26:48,200 --> 15:26:52,680 dictionary we can do that here I can 24041 15:26:50,720 --> 15:26:55,200 actually take the essence of this is 24042 15:26:52,680 --> 15:26:56,916 griffindor function I can change the 24043 15:26:55,200 --> 15:26:59,840 name of this function in my filter call 24044 15:26:56,916 --> 15:27:03,116 to be another Lambda function passing in 24045 15:26:59,840 --> 15:27:05,596 an argument like s and returning exactly 24046 15:27:03,116 --> 15:27:08,560 that I can now delete my is Gryffindor 24047 15:27:05,596 --> 15:27:10,880 function all together and now when I run 24048 15:27:08,560 --> 15:27:13,116 python of gryffindors dopy I still get 24049 15:27:10,880 --> 15:27:15,436 the same answer and I've not bothered 24050 15:27:13,116 --> 15:27:19,116 defining a function only to then use it 24051 15:27:15,436 --> 15:27:21,200 in one and only one place well let me 24052 15:27:19,116 --> 15:27:23,520 propose too that we equip you with one 24053 15:27:21,200 --> 15:27:26,240 other tool for your toolkit namely 24054 15:27:23,520 --> 15:27:28,276 dictionary comprehensions as well and 24055 15:27:26,240 --> 15:27:30,116 admittedly the syntax is starting to get 24056 15:27:28,276 --> 15:27:31,680 even weirder but as you get more 24057 15:27:30,116 --> 15:27:33,320 comfortable with all of these Primitives 24058 15:27:31,680 --> 15:27:35,400 and others these are just tools that you 24059 15:27:33,320 --> 15:27:37,360 can optionally but perhaps powerfully 24060 15:27:35,400 --> 15:27:39,880 use to solve future problems down the 24061 15:27:37,360 --> 15:27:42,160 road and with a dictionary comprehension 24062 15:27:39,880 --> 15:27:44,520 we have the ability to create on the fly 24063 15:27:42,160 --> 15:27:46,080 a dictionary with keys and some values 24064 15:27:44,520 --> 15:27:47,756 without having to do it sort of old 24065 15:27:46,080 --> 15:27:49,596 school by com creating an empty 24066 15:27:47,756 --> 15:27:51,720 dictionary and creating a for Loop and 24067 15:27:49,596 --> 15:27:53,436 iterating over that Loop and inserting 24068 15:27:51,720 --> 15:27:55,756 more and more keys and values into the 24069 15:27:53,436 --> 15:27:58,240 dictionary we can rather do it all at 24070 15:27:55,756 --> 15:28:01,080 once so in fact let me go back to vs Cod 24071 15:27:58,240 --> 15:28:04,400 here and let me propose now that I do 24072 15:28:01,080 --> 15:28:07,080 this let me go ahead and initially do it 24073 15:28:04,400 --> 15:28:08,680 the oldfashioned way here as follows let 24074 15:28:07,080 --> 15:28:10,360 me go ahead and simplify and get rid of 24075 15:28:08,680 --> 15:28:13,360 the houses Al together so that we can 24076 15:28:10,360 --> 15:28:15,480 focus for now just on a list of students 24077 15:28:13,360 --> 15:28:17,360 names I'm going to go ahead and run 24078 15:28:15,480 --> 15:28:19,796 students uh I'm going to go ahead and 24079 15:28:17,360 --> 15:28:22,320 write students equals quote unquote 24080 15:28:19,796 --> 15:28:23,636 hermion quote unquote Harry and we'll 24081 15:28:22,320 --> 15:28:25,560 keep it even shorter this time quote 24082 15:28:23,636 --> 15:28:27,680 unquote Ron only those three students in 24083 15:28:25,560 --> 15:28:29,480 Gryffindor I'm going to now proactively 24084 15:28:27,680 --> 15:28:31,240 as we've done in the past give myself an 24085 15:28:29,480 --> 15:28:33,520 empty list so that I have something to 24086 15:28:31,240 --> 15:28:35,160 accumulate some answers to this problem 24087 15:28:33,520 --> 15:28:37,720 in and now I'm going to do something 24088 15:28:35,160 --> 15:28:39,880 like this for student in students so I 24089 15:28:37,720 --> 15:28:41,956 can iterate over each of them let's go 24090 15:28:39,880 --> 15:28:46,000 ahead and with the gryffindors list 24091 15:28:41,956 --> 15:28:47,956 append to it the name of the students so 24092 15:28:46,000 --> 15:28:49,320 quote unquote name and then student 24093 15:28:47,956 --> 15:28:51,636 which is indeed their name from that 24094 15:28:49,320 --> 15:28:53,480 list and now let's go ahead and just put 24095 15:28:51,636 --> 15:28:54,880 these students all in Gryffindor I know 24096 15:28:53,480 --> 15:28:56,840 these three students are in Gryffindor 24097 15:28:54,880 --> 15:28:59,116 so suppose that the problem at hand is 24098 15:28:56,840 --> 15:29:01,560 that I want to build up a list of 24099 15:28:59,116 --> 15:29:03,240 dictionaries that only contains the 24100 15:29:01,560 --> 15:29:05,000 Gryffindor students so it's sort of a 24101 15:29:03,240 --> 15:29:06,796 step back from the previous version 24102 15:29:05,000 --> 15:29:08,796 where I already had the names and the 24103 15:29:06,796 --> 15:29:10,796 houses for now just assume that the 24104 15:29:08,796 --> 15:29:12,320 problem is I have all of their names but 24105 15:29:10,796 --> 15:29:14,160 I don't yet have the student 24106 15:29:12,320 --> 15:29:16,360 dictionaries themselves so I'm 24107 15:29:14,160 --> 15:29:19,000 rebuilding that same structure that I 24108 15:29:16,360 --> 15:29:20,400 previously took for granted now let's go 24109 15:29:19,000 --> 15:29:21,680 ahead and just for the sake of 24110 15:29:20,400 --> 15:29:23,520 discussion just print out these 24111 15:29:21,680 --> 15:29:25,840 gryffindors so we can see what we've 24112 15:29:23,520 --> 15:29:28,200 built if I run python of gryffindors 24113 15:29:25,840 --> 15:29:30,636 dopy in my prompt I see a bit of a 24114 15:29:28,200 --> 15:29:32,796 cryptic syntax but again look for our 24115 15:29:30,636 --> 15:29:34,560 little hints I've got a square bracket 24116 15:29:32,796 --> 15:29:36,560 at the end and a square bracket at the 24117 15:29:34,560 --> 15:29:38,956 beginning and that indicates as always 24118 15:29:36,560 --> 15:29:41,436 this is a list I then have a whole bunch 24119 15:29:38,956 --> 15:29:43,480 of curly braces with a whole bunch of 24120 15:29:41,436 --> 15:29:45,520 quoted keys they happen to be single 24121 15:29:43,480 --> 15:29:48,480 quotes by convention when using print on 24122 15:29:45,520 --> 15:29:50,160 a dictionary but that's just a visual 24123 15:29:48,480 --> 15:29:52,636 indicator that that is my key and the 24124 15:29:50,160 --> 15:29:54,596 first value thereof is Hermione second 24125 15:29:52,636 --> 15:29:56,880 key is a house this value thereof is 24126 15:29:54,596 --> 15:29:59,436 Gryffindor then there's a comma which 24127 15:29:56,880 --> 15:30:01,240 separates one dict object from the next 24128 15:29:59,436 --> 15:30:02,956 and if we look past Harry and Gryffindor 24129 15:30:01,240 --> 15:30:05,400 there's a third a second comma which 24130 15:30:02,956 --> 15:30:07,360 separates Harry and Gryffindor from Ron 24131 15:30:05,400 --> 15:30:10,240 and Gryffindor as well so in short here 24132 15:30:07,360 --> 15:30:12,200 is some code whereby I fairly manually 24133 15:30:10,240 --> 15:30:15,000 built up with a for Loop and an 24134 15:30:12,200 --> 15:30:17,680 otherwise initially empty list the same 24135 15:30:15,000 --> 15:30:20,560 data structure as before minus Draco 24136 15:30:17,680 --> 15:30:22,276 just for Gryffindor students but here's 24137 15:30:20,560 --> 15:30:23,680 where again with dictionary 24138 15:30:22,276 --> 15:30:25,916 comprehensions or really list 24139 15:30:23,680 --> 15:30:27,956 comprehensions first can we do this a 24140 15:30:25,916 --> 15:30:30,796 little more succinctly Let Me Clear My 24141 15:30:27,956 --> 15:30:33,596 terminal window let's get rid of this 24142 15:30:30,796 --> 15:30:35,596 initially empty list and this for Loop 24143 15:30:33,596 --> 15:30:37,720 that appends appends appends to it and 24144 15:30:35,596 --> 15:30:41,320 let's just do this a gryffindors 24145 15:30:37,720 --> 15:30:44,160 variable will equal the following list 24146 15:30:41,320 --> 15:30:46,200 comprehension inside of that list I want 24147 15:30:44,160 --> 15:30:49,400 a dictionary structured with someone's 24148 15:30:46,200 --> 15:30:52,520 name and their name someone's house and 24149 15:30:49,400 --> 15:30:55,636 only for now Gryffindor and that's it 24150 15:30:52,520 --> 15:30:59,840 but I want one of these objects 24151 15:30:55,636 --> 15:31:03,796 here in these curly braces for each 24152 15:30:59,840 --> 15:31:06,320 student in students so here too inside 24153 15:31:03,796 --> 15:31:10,080 of my list comprehension with my square 24154 15:31:06,320 --> 15:31:12,116 brackets I want an object as indic I 24155 15:31:10,080 --> 15:31:14,160 want a dictionary as indicated by the 24156 15:31:12,116 --> 15:31:17,116 curly braces I want each of those 24157 15:31:14,160 --> 15:31:19,436 dictionaries to have two keys name and 24158 15:31:17,116 --> 15:31:22,200 house respectively the values thereof 24159 15:31:19,436 --> 15:31:25,200 are the student's name from earlier here 24160 15:31:22,200 --> 15:31:27,276 and Gryffindor only which students do I 24161 15:31:25,200 --> 15:31:29,916 want to create those objects from 24162 15:31:27,276 --> 15:31:31,636 well for student in students so again on 24163 15:31:29,916 --> 15:31:33,520 the left I have what I want in the final 24164 15:31:31,636 --> 15:31:35,276 list and on the right I have a loop and 24165 15:31:33,520 --> 15:31:37,436 this time no conditional I want all of 24166 15:31:35,276 --> 15:31:40,160 these students in Gryffindor as their 24167 15:31:37,436 --> 15:31:42,436 house now let's print this again uh 24168 15:31:40,160 --> 15:31:45,080 python of gryffindors dopy and hit enter 24169 15:31:42,436 --> 15:31:47,560 and now we have the exact same output so 24170 15:31:45,080 --> 15:31:49,840 instead of three lines it's just one 24171 15:31:47,560 --> 15:31:51,756 it's a little more uh cryptic to read at 24172 15:31:49,840 --> 15:31:53,480 first glance but once familiar with list 24173 15:31:51,756 --> 15:31:55,796 comprehensions and this sort of syntax 24174 15:31:53,480 --> 15:31:57,840 is just another way of solving that same 24175 15:31:55,796 --> 15:31:59,840 problem what if I want to change this 24176 15:31:57,840 --> 15:32:02,436 and simplify what if I don't want a list 24177 15:31:59,840 --> 15:32:04,596 of dictionaries which I now have again 24178 15:32:02,436 --> 15:32:07,320 per the square brackets I have a list of 24179 15:32:04,596 --> 15:32:10,480 three objects here what if I just 24180 15:32:07,320 --> 15:32:13,360 want one bigger dictionary inside of 24181 15:32:10,480 --> 15:32:16,560 which is a key like Hermione colon 24182 15:32:13,360 --> 15:32:18,560 Gryffindor Harry colen Gryffindor Ron 24183 15:32:16,560 --> 15:32:20,400 colen Gryffindor I don't need a list I 24184 15:32:18,560 --> 15:32:23,596 don't need separate objects per student 24185 15:32:20,400 --> 15:32:25,596 I just want instead one big dictionary 24186 15:32:23,596 --> 15:32:27,040 where the keys are the students names 24187 15:32:25,596 --> 15:32:28,916 and the values of their house and I'm 24188 15:32:27,040 --> 15:32:32,240 assuming for now no one's going to have 24189 15:32:28,916 --> 15:32:34,756 the same first name in this world well I 24190 15:32:32,240 --> 15:32:37,080 can do this let me get rid of this here 24191 15:32:34,756 --> 15:32:39,360 and not create a list comprehension but 24192 15:32:37,080 --> 15:32:41,320 again this thing known as a dictionary 24193 15:32:39,360 --> 15:32:43,276 comprehension and the visual indicator 24194 15:32:41,320 --> 15:32:44,956 or difference here is that instead of 24195 15:32:43,276 --> 15:32:47,436 being square brackets on the very 24196 15:32:44,956 --> 15:32:49,880 outside this time it's going to be curly 24197 15:32:47,436 --> 15:32:52,880 braces instead so inside of these curly 24198 15:32:49,880 --> 15:32:55,240 braces what do I want every key to be I 24199 15:32:52,880 --> 15:32:57,200 want every key to be the student's name 24200 15:32:55,240 --> 15:32:59,360 I want every value for now to be 24201 15:32:57,200 --> 15:33:02,840 Gryffindor and I want to do this for 24202 15:32:59,360 --> 15:33:04,520 each student in students and now things 24203 15:33:02,840 --> 15:33:06,636 are getting really interesting and this 24204 15:33:04,520 --> 15:33:09,080 is another manifestation of python in 24205 15:33:06,636 --> 15:33:11,480 some views being very readable from left 24206 15:33:09,080 --> 15:33:14,116 to right absolutely takes practice and 24207 15:33:11,480 --> 15:33:16,000 comfort but this is creating a variable 24208 15:33:14,116 --> 15:33:18,956 called Gryffindor which is going to be a 24209 15:33:16,000 --> 15:33:21,040 dictionary per these curly braces every 24210 15:33:18,956 --> 15:33:22,596 key is going to be the name of some 24211 15:33:21,040 --> 15:33:24,956 student every value is going to be 24212 15:33:22,596 --> 15:33:27,596 Gryffindor what names of what students 24213 15:33:24,956 --> 15:33:30,480 well this dictionary comprehension will 24214 15:33:27,596 --> 15:33:33,520 be be constructed from the list of 24215 15:33:30,480 --> 15:33:35,080 students one at a time so when I print 24216 15:33:33,520 --> 15:33:36,560 this now the syntax will look a little 24217 15:33:35,080 --> 15:33:38,916 different cuz it's not a list of 24218 15:33:36,560 --> 15:33:41,000 dictionary objects it's just one bigger 24219 15:33:38,916 --> 15:33:43,320 dictionary object itself but now 24220 15:33:41,000 --> 15:33:44,880 printing gryffindors gives me Hermione 24221 15:33:43,320 --> 15:33:48,520 col and Gryffindor Harry colen 24222 15:33:44,880 --> 15:33:51,520 Gryffindor and Ron colen Gryffindor as 24223 15:33:48,520 --> 15:33:55,970 well any questions now on what we've 24224 15:33:51,520 --> 15:33:58,636 called dictionary comprehensions as well 24225 15:33:55,970 --> 15:34:01,636 [Music] 24226 15:33:58,636 --> 15:34:01,636 any questions on 24227 15:34:01,756 --> 15:34:07,000 here no well let's introduce one other 24228 15:34:04,480 --> 15:34:09,756 function from Python's toolkit followed 24229 15:34:07,000 --> 15:34:12,200 by one final feature and flourish and 24230 15:34:09,756 --> 15:34:15,276 then you're off on your way well let's 24231 15:34:12,200 --> 15:34:17,916 go ahead and think back to this recall 24232 15:34:15,276 --> 15:34:19,436 some time ago that we had just a simple 24233 15:34:17,916 --> 15:34:22,480 list of students as we have here 24234 15:34:19,436 --> 15:34:24,880 Hermione Harry and Ron and for instance 24235 15:34:22,480 --> 15:34:27,360 way back when we wanted to print out for 24236 15:34:24,880 --> 15:34:28,200 instance their ranking from 1 to 2 to 24237 15:34:27,360 --> 15:34:29,796 three 24238 15:34:28,200 --> 15:34:32,320 unfortunately when you do something like 24239 15:34:29,796 --> 15:34:34,000 this for student in students you can 24240 15:34:32,320 --> 15:34:35,916 print out the student's name quite 24241 15:34:34,000 --> 15:34:38,360 easily of course if I do python of 24242 15:34:35,916 --> 15:34:40,636 gryffindors dopy I get Hermione Harry 24243 15:34:38,360 --> 15:34:43,116 Ron in that same order but I don't see 24244 15:34:40,636 --> 15:34:45,956 any numerical rank I see no number one 24245 15:34:43,116 --> 15:34:48,596 two or three so I could maybe do this 24246 15:34:45,956 --> 15:34:50,436 with maybe uh a different type of for 24247 15:34:48,596 --> 15:34:53,796 Loop instead of this why don't I try 24248 15:34:50,436 --> 15:34:57,636 this so maybe I could do for I in the 24249 15:34:53,796 --> 15:34:58,916 range of the length of the student list 24250 15:34:57,636 --> 15:35:01,680 and we've done something like this 24251 15:34:58,916 --> 15:35:03,596 before and then I could print out I and 24252 15:35:01,680 --> 15:35:06,680 I could print out the student's name by 24253 15:35:03,596 --> 15:35:08,116 indexing into that list at location I 24254 15:35:06,680 --> 15:35:11,240 well what does this look like if I run 24255 15:35:08,116 --> 15:35:13,040 python of gryffindors dopy it's close uh 24256 15:35:11,240 --> 15:35:14,480 but you know these aren't programmers 24257 15:35:13,040 --> 15:35:16,520 they don't necessarily think of 24258 15:35:14,480 --> 15:35:18,956 themselves as zero index termy probably 24259 15:35:16,520 --> 15:35:20,400 wants to be first not zero so how can we 24260 15:35:18,956 --> 15:35:22,796 fix this well just a little bit of 24261 15:35:20,400 --> 15:35:25,160 arithmetic I could print out i+ one of 24262 15:35:22,796 --> 15:35:26,596 course and then the student's name so if 24263 15:35:25,160 --> 15:35:29,680 I clear my terminal window and run 24264 15:35:26,596 --> 15:35:32,200 python of griffindor high once more now 24265 15:35:29,680 --> 15:35:34,240 we have this enumeration 1 two three of 24266 15:35:32,200 --> 15:35:36,040 each of these students but it turns out 24267 15:35:34,240 --> 15:35:37,756 that python actually has had all this 24268 15:35:36,040 --> 15:35:40,276 time another built-in function that you 24269 15:35:37,756 --> 15:35:42,756 might Now find useful that is namely 24270 15:35:40,276 --> 15:35:44,520 enumerate and enumerate allows you to 24271 15:35:42,756 --> 15:35:47,720 solve this kind of problem much more 24272 15:35:44,520 --> 15:35:51,040 simply by iterating over some sequence 24273 15:35:47,720 --> 15:35:55,000 but finding out not each value one at a 24274 15:35:51,040 --> 15:35:57,116 time but both the value one at a time 24275 15:35:55,000 --> 15:35:59,720 and the index thereof it gives you back 24276 15:35:57,116 --> 15:36:02,116 two answers at once so if I go back to 24277 15:35:59,720 --> 15:36:04,636 VSS code here now and take this approach 24278 15:36:02,116 --> 15:36:07,240 I don't need to do this this complicated 24279 15:36:04,636 --> 15:36:09,720 range and length and then I all over the 24280 15:36:07,240 --> 15:36:14,160 place I can more succinctly do this I 24281 15:36:09,720 --> 15:36:16,756 can say for I comma student in the 24282 15:36:14,160 --> 15:36:18,480 enumerate return value passing in 24283 15:36:16,756 --> 15:36:21,160 students so this gives me back an 24284 15:36:18,480 --> 15:36:24,000 enumeration if you will and now I can go 24285 15:36:21,160 --> 15:36:25,560 about printing I + one as before and I 24286 15:36:24,000 --> 15:36:27,680 can print out the student so I don't 24287 15:36:25,560 --> 15:36:29,720 need to index into the list with bracket 24288 15:36:27,680 --> 15:36:31,276 I notation I don't need to call range I 24289 15:36:29,720 --> 15:36:33,276 don't need to call length again 24290 15:36:31,276 --> 15:36:35,200 enumerate takes a sequence of values 24291 15:36:33,276 --> 15:36:37,560 like these students and it allows me to 24292 15:36:35,200 --> 15:36:41,000 get back the current index 24293 15:36:37,560 --> 15:36:43,560 012 and the current value Hermione Harry 24294 15:36:41,000 --> 15:36:44,916 Ron respectively so now just tighten 24295 15:36:43,560 --> 15:36:46,840 things up further and indeed that's been 24296 15:36:44,916 --> 15:36:48,796 our theme here can we solve the same 24297 15:36:46,840 --> 15:36:51,080 problems as we've been solving for weeks 24298 15:36:48,796 --> 15:36:52,240 but tighten things up using just more of 24299 15:36:51,080 --> 15:36:54,956 this tool 24300 15:36:52,240 --> 15:36:56,840 kit allow us to equip you with one final 24301 15:36:54,956 --> 15:36:59,480 tool for your toolkit namely this 24302 15:36:56,840 --> 15:37:01,116 ability to to generate values in Python 24303 15:36:59,480 --> 15:37:02,520 from functions this is not a problem 24304 15:37:01,116 --> 15:37:04,160 that we've necessarily encountered 24305 15:37:02,520 --> 15:37:05,756 before but it turns out if you're 24306 15:37:04,160 --> 15:37:07,796 writing a function that reads or 24307 15:37:05,756 --> 15:37:09,400 generates lots of data your function 24308 15:37:07,796 --> 15:37:11,880 your program your computer might very 24309 15:37:09,400 --> 15:37:14,596 well run out of memory and your program 24310 15:37:11,880 --> 15:37:16,560 might not be able to run any further but 24311 15:37:14,596 --> 15:37:18,000 it turns out there's a solution to this 24312 15:37:16,560 --> 15:37:19,720 problem that's something you might have 24313 15:37:18,000 --> 15:37:21,596 in your back pocket particularly if 24314 15:37:19,720 --> 15:37:23,480 after this course you start crunching 24315 15:37:21,596 --> 15:37:25,360 quite a few numbers and analyzing all 24316 15:37:23,480 --> 15:37:27,080 the more data in fact let's go back to 24317 15:37:25,360 --> 15:37:28,956 vs code here and let's go ahead and 24318 15:37:27,080 --> 15:37:31,160 create a program that's perhaps timely 24319 15:37:28,956 --> 15:37:32,596 at this time of day particularly 24320 15:37:31,160 --> 15:37:34,360 depending on your time zone you might be 24321 15:37:32,596 --> 15:37:36,480 feeling all the more sleepy but here in 24322 15:37:34,360 --> 15:37:38,520 the US it's quite common to be lulled to 24323 15:37:36,480 --> 15:37:40,520 sleep when you're struggling otherwise 24324 15:37:38,520 --> 15:37:42,276 by counting sheep in your head and 24325 15:37:40,520 --> 15:37:43,880 typically as depicted in cartoons you 24326 15:37:42,276 --> 15:37:45,720 might see in your mind's eye one sheep 24327 15:37:43,880 --> 15:37:47,400 jumping over a fence and then two and 24328 15:37:45,720 --> 15:37:49,040 then three sheep and then four and then 24329 15:37:47,400 --> 15:37:50,680 eventually you presumably get so bored 24330 15:37:49,040 --> 15:37:52,840 counting these sheep you actually do 24331 15:37:50,680 --> 15:37:55,796 fall asleep so in vs code here let's 24332 15:37:52,840 --> 15:37:58,160 create a program called sleep.i that 24333 15:37:55,796 --> 15:38:00,360 allows me to print out out some number 24334 15:37:58,160 --> 15:38:02,956 of sheep as though I'm counting them in 24335 15:38:00,360 --> 15:38:04,840 my mind's eye and Via this program let's 24336 15:38:02,956 --> 15:38:07,040 do this let's prompt the user for a 24337 15:38:04,840 --> 15:38:09,000 variable n setting it equal to the 24338 15:38:07,040 --> 15:38:11,596 integer conversion of the return value 24339 15:38:09,000 --> 15:38:13,000 of input asking the user what's n for 24340 15:38:11,596 --> 15:38:14,840 how many sheep do they want to try 24341 15:38:13,000 --> 15:38:16,520 counting and then let's do a familiar 24342 15:38:14,840 --> 15:38:18,240 for Loop here and we'll start counting 24343 15:38:16,520 --> 15:38:20,000 from zero as always so we'll first have 24344 15:38:18,240 --> 15:38:22,680 zero sheep then one sheep then two sheep 24345 15:38:20,000 --> 15:38:25,040 and so on for I in the range of that 24346 15:38:22,680 --> 15:38:27,080 value n Go ahead and print out and I'll 24347 15:38:25,040 --> 15:38:29,480 paste here an emoji representing a sheep 24348 15:38:27,080 --> 15:38:31,276 time I so the first iteration I'll see 24349 15:38:29,480 --> 15:38:33,680 Zero sheep the second iteration I'll see 24350 15:38:31,276 --> 15:38:36,956 one and then two and then however many 24351 15:38:33,680 --> 15:38:38,400 uh specified by n ultimately minus one 24352 15:38:36,956 --> 15:38:40,680 all right let's go down into my terminal 24353 15:38:38,400 --> 15:38:42,956 window here and run python of sleep. and 24354 15:38:40,680 --> 15:38:45,480 I should see indeed after typing in say 24355 15:38:42,956 --> 15:38:47,436 three for my value of n zero sheep then 24356 15:38:45,480 --> 15:38:48,956 one sheep then two sheep and so forth 24357 15:38:47,436 --> 15:38:50,680 and if I make my terminal window even 24358 15:38:48,956 --> 15:38:52,956 bigger here we can of course do many 24359 15:38:50,680 --> 15:38:54,560 more than this typing in for instance 10 24360 15:38:52,956 --> 15:38:56,796 and you'll see that we get more and more 24361 15:38:54,560 --> 15:38:58,720 sheep as time passes presumably becoming 24362 15:38:56,796 --> 15:39:02,080 all the more tedious to Envision in my 24363 15:38:58,720 --> 15:39:03,276 mind's eye so let's now go ahead and uh 24364 15:39:02,080 --> 15:39:05,080 practice what we've been preaching when 24365 15:39:03,276 --> 15:39:07,680 it comes to the design of this program 24366 15:39:05,080 --> 15:39:10,116 and see if and when we actually run into 24367 15:39:07,680 --> 15:39:11,916 a problem let me go ahead here now and 24368 15:39:10,116 --> 15:39:14,560 put all of this in a main function by 24369 15:39:11,916 --> 15:39:16,200 defining main up here as always let me 24370 15:39:14,560 --> 15:39:17,680 go ahead and indent all of this code 24371 15:39:16,200 --> 15:39:19,436 here and then let me just do this 24372 15:39:17,680 --> 15:39:21,436 conditionally as always if the name of 24373 15:39:19,436 --> 15:39:24,116 this file equals equals quote unquote 24374 15:39:21,436 --> 15:39:25,720 main let's go ahead and call Main let's 24375 15:39:24,116 --> 15:39:27,560 make sure I didn't break anything just 24376 15:39:25,720 --> 15:39:29,680 yet even though functionally this should 24377 15:39:27,560 --> 15:39:32,240 be nearly the same and if I type in 24378 15:39:29,680 --> 15:39:34,840 three I still have zero then one then 24379 15:39:32,240 --> 15:39:36,636 two sheep on the screen but we've been 24380 15:39:34,840 --> 15:39:38,720 in the habit of course of creating 24381 15:39:36,636 --> 15:39:40,756 helper functions for ourselves that is 24382 15:39:38,720 --> 15:39:42,320 factoring our code in a way that allows 24383 15:39:40,756 --> 15:39:44,596 us to abstract away certain 24384 15:39:42,320 --> 15:39:46,956 functionality like uh generating some 24385 15:39:44,596 --> 15:39:48,596 number of sheep into separate functions 24386 15:39:46,956 --> 15:39:50,160 so that one they're indeed abstracted 24387 15:39:48,596 --> 15:39:51,400 and we no longer have to think about how 24388 15:39:50,160 --> 15:39:53,956 they're implemented and we can even 24389 15:39:51,400 --> 15:39:55,680 reuse them in projects as in libraries 24390 15:39:53,956 --> 15:39:58,040 but we've also been in the habit too of 24391 15:39:55,680 --> 15:40:00,000 now testing those functions as with unit 24392 15:39:58,040 --> 15:40:01,880 tests so I probably shouldn't keep all 24393 15:40:00,000 --> 15:40:04,000 of my logic anyway in Main and let's 24394 15:40:01,880 --> 15:40:07,000 Factor some of this out wouldn't it be 24395 15:40:04,000 --> 15:40:10,796 nice if I could for instance just call a 24396 15:40:07,000 --> 15:40:12,520 sheep function uh as by uh taking this 24397 15:40:10,796 --> 15:40:14,436 line of code here and instead of just 24398 15:40:12,520 --> 15:40:16,160 printing it here let's print out the 24399 15:40:14,436 --> 15:40:19,040 return value of a new function called 24400 15:40:16,160 --> 15:40:21,756 Sheep that tells the function how many 24401 15:40:19,040 --> 15:40:23,116 sheep to print I in this case let's go 24402 15:40:21,756 --> 15:40:25,240 down as always and create another 24403 15:40:23,116 --> 15:40:27,000 function here called Sheep the Sheep 24404 15:40:25,240 --> 15:40:28,680 function now will take a parameter n 24405 15:40:27,000 --> 15:40:31,116 that's specifies how many sheep do you 24406 15:40:28,680 --> 15:40:32,840 want to return and so that we can test 24407 15:40:31,116 --> 15:40:34,880 this as with a unit test though we won't 24408 15:40:32,840 --> 15:40:37,276 do that here let me go ahead and not 24409 15:40:34,880 --> 15:40:39,916 print the number of sheep as via a side 24410 15:40:37,276 --> 15:40:42,276 effect but let me go ahead and return 24411 15:40:39,916 --> 15:40:44,680 one of those sheep times n so that the 24412 15:40:42,276 --> 15:40:47,436 user gets back a whole string of sheep 24413 15:40:44,680 --> 15:40:48,956 that's the appropriate number to print 24414 15:40:47,436 --> 15:40:50,840 so here too functionally I don't think 24415 15:40:48,956 --> 15:40:53,360 we've changed anything too fundamentally 24416 15:40:50,840 --> 15:40:55,276 python of sleep. typing three still 24417 15:40:53,360 --> 15:40:58,796 gives us zero then one and then two 24418 15:40:55,276 --> 15:41:01,200 sheep but now we at least have a 24419 15:40:58,796 --> 15:41:03,756 framework for focusing on the 24420 15:41:01,200 --> 15:41:06,680 implementation of this sheep function 24421 15:41:03,756 --> 15:41:09,320 but it's a little inelegant now that 24422 15:41:06,680 --> 15:41:11,400 it's still up to the main function to do 24423 15:41:09,320 --> 15:41:12,956 this iteration we've seen in the past 24424 15:41:11,400 --> 15:41:15,240 way back in week zero wouldn't it be 24425 15:41:12,956 --> 15:41:17,080 nice to define a function that actually 24426 15:41:15,240 --> 15:41:19,360 handles the process of returning the 24427 15:41:17,080 --> 15:41:22,636 entire string that we want rather than 24428 15:41:19,360 --> 15:41:24,360 just one row of sheep at a time well I 24429 15:41:22,636 --> 15:41:26,756 think we can do this why don't I go 24430 15:41:24,360 --> 15:41:29,756 ahead and change sheep as follows let me 24431 15:41:26,756 --> 15:41:32,000 go ahead here and uh first create a 24432 15:41:29,756 --> 15:41:35,916 flock of sheep that's initially empty 24433 15:41:32,000 --> 15:41:38,720 using an empty list then for I in uh the 24434 15:41:35,916 --> 15:41:41,436 range of n let's go ahead and append 24435 15:41:38,720 --> 15:41:44,160 that flock for instance one sheep times 24436 15:41:41,436 --> 15:41:46,276 I so that I keep adding to this list 24437 15:41:44,160 --> 15:41:47,756 zero sheep then one sheep then two sheep 24438 15:41:46,276 --> 15:41:49,560 then three and so forth and then 24439 15:41:47,756 --> 15:41:51,636 ultimately I'm going to return the whole 24440 15:41:49,560 --> 15:41:53,636 flock of sheep at once so this is going 24441 15:41:51,636 --> 15:41:56,436 to return the equivalent of all of those 24442 15:41:53,636 --> 15:41:58,796 strings of sheep so that eh Maine can 24443 15:41:56,436 --> 15:42:00,756 handle the print thereof so back up here 24444 15:41:58,796 --> 15:42:03,116 in Maine let's do this how about for 24445 15:42:00,756 --> 15:42:06,000 each sheep I'll call it s since sheep is 24446 15:42:03,116 --> 15:42:09,400 both singular and plural for s in sheep 24447 15:42:06,000 --> 15:42:11,436 of n which again returns to me a list of 24448 15:42:09,400 --> 15:42:14,080 all of the sheep the whole flock let's 24449 15:42:11,436 --> 15:42:16,956 just print out each sheep S one at a 24450 15:42:14,080 --> 15:42:18,480 time all right so so far so good here I 24451 15:42:16,956 --> 15:42:21,720 think let me go ahead and run python of 24452 15:42:18,480 --> 15:42:24,796 sleep. Pi and hit enter what's N3 and 24453 15:42:21,720 --> 15:42:28,880 that still seems to work just fine but 24454 15:42:24,796 --> 15:42:30,840 let me get a little uh creative here and 24455 15:42:28,880 --> 15:42:33,000 see not just three sheep on my screen 24456 15:42:30,840 --> 15:42:35,116 but maybe 10 rows of sheep and that too 24457 15:42:33,000 --> 15:42:37,400 seems to work fine let me get a little 24458 15:42:35,116 --> 15:42:39,360 more adventurous and type in maybe a 100 24459 15:42:37,400 --> 15:42:41,200 sheep and it's starting to look ugly to 24460 15:42:39,360 --> 15:42:43,360 be fair but they're all printing out 24461 15:42:41,200 --> 15:42:45,840 pretty fast let me go ahead and try 24462 15:42:43,360 --> 15:42:48,116 again with maybe 1,000 sheep on the 24463 15:42:45,840 --> 15:42:50,276 screen and they flew by pretty fast it's 24464 15:42:48,116 --> 15:42:52,796 still pretty messy but they're all there 24465 15:42:50,276 --> 15:42:56,080 we could count them all up how about not 24466 15:42:52,796 --> 15:42:57,840 just a th000 but 10,000 sheep well that 24467 15:42:56,080 --> 15:42:59,276 too seems okay it's it's taking like 10 24468 15:42:57,840 --> 15:43:01,276 times as long and that's why you see 24469 15:42:59,276 --> 15:43:04,400 this flickering on the screen all of the 24470 15:43:01,276 --> 15:43:06,520 sheep are still printing but but but 24471 15:43:04,400 --> 15:43:08,796 it's a lot of data being printed if I 24472 15:43:06,520 --> 15:43:13,160 hang in there a little 24473 15:43:08,796 --> 15:43:15,436 longer hopefully we'll see all 10,000 24474 15:43:13,160 --> 15:43:17,720 sheep coming to 24475 15:43:15,436 --> 15:43:19,400 pass this is here in the video where 24476 15:43:17,720 --> 15:43:22,756 will we will speed up 24477 15:43:19,400 --> 15:43:25,840 time all a real online oh my God this is 24478 15:43:22,756 --> 15:43:28,636 a lot of sheep there we go okay and now 24479 15:43:25,840 --> 15:43:30,596 all of my sheep have been printed so it 24480 15:43:28,636 --> 15:43:32,636 seems to be working just fine well let 24481 15:43:30,596 --> 15:43:35,080 me just be even more adventurous and 24482 15:43:32,636 --> 15:43:37,840 okay let me try my luck let me try like 24483 15:43:35,080 --> 15:43:40,080 uh how about 1 million sheep this time 24484 15:43:37,840 --> 15:43:42,080 and hit 24485 15:43:40,080 --> 15:43:46,116 enter 24486 15:43:42,080 --> 15:43:50,040 huh something's no longer 24487 15:43:46,116 --> 15:43:51,956 working while we wait for a spoiler here 24488 15:43:50,040 --> 15:43:55,520 does anyone have any intuition for why 24489 15:43:51,956 --> 15:43:58,840 my program suddenly stopped printing 24490 15:43:55,520 --> 15:44:01,796 sheep what is going going wrong in this 24491 15:43:58,840 --> 15:44:03,880 version wherein I'm generating this 24492 15:44:01,796 --> 15:44:07,360 really big flock of sheep we might have 24493 15:44:03,880 --> 15:44:08,956 run out of memory or computation power 24494 15:44:07,360 --> 15:44:11,956 yeah so maybe we're actually pushing the 24495 15:44:08,956 --> 15:44:14,160 limits of my Mac my PCS my cloud serers 24496 15:44:11,956 --> 15:44:17,116 memory or CPU the brains of the 24497 15:44:14,160 --> 15:44:20,360 computer's capabilities because it's 24498 15:44:17,116 --> 15:44:22,956 just trying to generate massive massive 24499 15:44:20,360 --> 15:44:24,720 massive lists of sheep 1 million of 24500 15:44:22,956 --> 15:44:26,680 those rows of sheep Each of which has a 24501 15:44:24,720 --> 15:44:29,400 huge number of sheep and it seems that 24502 15:44:26,680 --> 15:44:31,240 my computer here is honestly just really 24503 15:44:29,400 --> 15:44:33,116 struggling and this is really 24504 15:44:31,240 --> 15:44:34,720 unfortunate now because it would seem 24505 15:44:33,116 --> 15:44:37,680 that even though this program clearly 24506 15:44:34,720 --> 15:44:40,320 works pretty well for a th sheep 10,000 24507 15:44:37,680 --> 15:44:42,720 sheep once you cross some threshold it 24508 15:44:40,320 --> 15:44:45,080 just stops working alt together or it 24509 15:44:42,720 --> 15:44:47,520 just takes way too long for the program 24510 15:44:45,080 --> 15:44:50,560 to be useful anymore but this seems a 24511 15:44:47,520 --> 15:44:52,160 little silly right because theoretically 24512 15:44:50,560 --> 15:44:53,956 I should absolutely be able to print all 24513 15:44:52,160 --> 15:44:57,200 of these same sheep if I just printed 24514 15:44:53,956 --> 15:44:59,560 one right away then print two right away 24515 15:44:57,200 --> 15:45:01,520 then print three then four then five it 24516 15:44:59,560 --> 15:45:04,680 seems that the essence of this problem 24517 15:45:01,520 --> 15:45:07,080 if I go back to my code is that per my 24518 15:45:04,680 --> 15:45:09,040 best practices that I'm trying to 24519 15:45:07,080 --> 15:45:10,596 practice what I'm preaching it seems 24520 15:45:09,040 --> 15:45:13,080 that the fundamental problem is that 24521 15:45:10,596 --> 15:45:15,276 I've modularized my code by creating 24522 15:45:13,080 --> 15:45:17,040 this helper function called Sheep whose 24523 15:45:15,276 --> 15:45:19,480 purpose in life is to do all of the 24524 15:45:17,040 --> 15:45:20,636 generation of sheep and then return all 24525 15:45:19,480 --> 15:45:23,360 of them at 24526 15:45:20,636 --> 15:45:25,320 once wouldn't it be better and I can 24527 15:45:23,360 --> 15:45:27,240 actually hear my fan turning on now even 24528 15:45:25,320 --> 15:45:29,240 just trying to generate these sheep 24529 15:45:27,240 --> 15:45:32,360 wouldn't it be better then to just print 24530 15:45:29,240 --> 15:45:34,520 the Sheep one 2 3 four at a time well we 24531 15:45:32,360 --> 15:45:36,636 could do that but that's really a a step 24532 15:45:34,520 --> 15:45:38,080 backwards that rather contradicts all of 24533 15:45:36,636 --> 15:45:39,956 the Lessons Learned of the past few 24534 15:45:38,080 --> 15:45:41,680 weeks where generally not putting 24535 15:45:39,956 --> 15:45:43,680 everything in main is a good thing 24536 15:45:41,680 --> 15:45:45,276 generally having an additional function 24537 15:45:43,680 --> 15:45:47,200 that you can then test separately with 24538 15:45:45,276 --> 15:45:49,040 unit test is a good thing do we really 24539 15:45:47,200 --> 15:45:51,636 need to give up all of those best 24540 15:45:49,040 --> 15:45:54,240 practices just to print out some sheep 24541 15:45:51,636 --> 15:45:56,680 and and here fall asleep well it turns 24542 15:45:54,240 --> 15:45:58,596 out there's a solution to this problem 24543 15:45:56,680 --> 15:46:00,956 and namely in the form of these 24544 15:45:58,596 --> 15:46:03,276 generators in Python you can define a 24545 15:46:00,956 --> 15:46:06,756 function as a generator whereby it can 24546 15:46:03,276 --> 15:46:09,276 still generate a massive amount of data 24547 15:46:06,756 --> 15:46:11,720 for your users but you can have it 24548 15:46:09,276 --> 15:46:13,756 return just a little bit of that data at 24549 15:46:11,720 --> 15:46:16,276 a time and you yourself can implement 24550 15:46:13,756 --> 15:46:18,320 the code in almost the same way but you 24551 15:46:16,276 --> 15:46:20,436 don't have to worry about too much 24552 15:46:18,320 --> 15:46:22,040 getting returned all at once these two 24553 15:46:20,436 --> 15:46:24,160 like all features of python are 24554 15:46:22,040 --> 15:46:25,880 documented in the official documentation 24555 15:46:24,160 --> 15:46:28,880 therein but what you'll find ultimately 24556 15:46:25,880 --> 15:46:31,956 that it all boils down down to this 24557 15:46:28,880 --> 15:46:34,560 keyword here yield up until now when 24558 15:46:31,956 --> 15:46:37,596 we've been making functions we have been 24559 15:46:34,560 --> 15:46:40,160 defining functions that return values if 24560 15:46:37,596 --> 15:46:41,956 at all using the keyword return and 24561 15:46:40,160 --> 15:46:43,436 indeed if we go back to our code here 24562 15:46:41,956 --> 15:46:45,276 that's exactly what I've been waiting 24563 15:46:43,436 --> 15:46:47,636 for I've been waiting to return the 24564 15:46:45,276 --> 15:46:50,116 whole flock at once unfortunately if you 24565 15:46:47,636 --> 15:46:52,720 wait too long and here we have it my 24566 15:46:50,116 --> 15:46:55,200 program was quote unquote killed that is 24567 15:46:52,720 --> 15:46:57,840 to say my computer got so fed up with 24568 15:46:55,200 --> 15:46:59,560 how much memory and CPU it was trying to 24569 15:46:57,840 --> 15:47:01,840 use it just said nope you're not going 24570 15:46:59,560 --> 15:47:03,916 to run at all and that's unfortunate now 24571 15:47:01,840 --> 15:47:06,320 my program no longer works for large 24572 15:47:03,916 --> 15:47:08,116 numbers of sleeps sheeps which is not 24573 15:47:06,320 --> 15:47:10,756 good if I'm really having trouble 24574 15:47:08,116 --> 15:47:13,880 falling asleep some night so how can I 24575 15:47:10,756 --> 15:47:16,240 use yield to solve this problem instead 24576 15:47:13,880 --> 15:47:19,240 well let me do this instead of building 24577 15:47:16,240 --> 15:47:21,796 up this massive list of sheep in this 24578 15:47:19,240 --> 15:47:24,680 big list called flock let's just do this 24579 15:47:21,796 --> 15:47:27,080 instead let me go ahead and simplify 24580 15:47:24,680 --> 15:47:30,916 this whole function as follows where by 24581 15:47:27,080 --> 15:47:33,680 I iterate for I in the range of N and 24582 15:47:30,916 --> 15:47:35,916 then on each iteration in the past I 24583 15:47:33,680 --> 15:47:38,040 might have been inclined to use return 24584 15:47:35,916 --> 15:47:40,756 and return something like one sheep 24585 15:47:38,040 --> 15:47:43,000 times I but this won't work here right 24586 15:47:40,756 --> 15:47:45,756 because if you want a million sheep and 24587 15:47:43,000 --> 15:47:47,916 you start a for Loop saying for I in the 24588 15:47:45,756 --> 15:47:50,000 range of a million you're going to 24589 15:47:47,916 --> 15:47:51,240 return accidentally zero sheep right 24590 15:47:50,000 --> 15:47:53,276 away and then this function is 24591 15:47:51,240 --> 15:47:55,360 essentially useless you shouldn't return 24592 15:47:53,276 --> 15:47:56,916 a value in the middle of a loop like 24593 15:47:55,360 --> 15:47:58,560 this because you're not going to get to 24594 15:47:56,916 --> 15:48:00,000 any of these subsequent iterations of 24595 15:47:58,560 --> 15:48:03,756 the loop it's going to iterate once and 24596 15:48:00,000 --> 15:48:06,360 boom you return but thanks to this other 24597 15:48:03,756 --> 15:48:10,040 keyword in Python called yield you can 24598 15:48:06,360 --> 15:48:12,956 tell python to effectively return just 24599 15:48:10,040 --> 15:48:14,840 one value at a time from this Loop so if 24600 15:48:12,956 --> 15:48:18,680 I go back to this version of my code 24601 15:48:14,840 --> 15:48:22,080 here and I say not return but yield this 24602 15:48:18,680 --> 15:48:25,360 is like saying return one value at a 24603 15:48:22,080 --> 15:48:27,680 time return one value at a time return 24604 15:48:25,360 --> 15:48:30,040 one value at a time the four Loop will 24605 15:48:27,680 --> 15:48:32,080 keep working and I will keep counting 24606 15:48:30,040 --> 15:48:35,680 from zero to one to two all the way up 24607 15:48:32,080 --> 15:48:37,040 toward 1 million but each time the 24608 15:48:35,680 --> 15:48:38,720 function is just going to hand you back 24609 15:48:37,040 --> 15:48:41,116 a little piece of data it's going to 24610 15:48:38,720 --> 15:48:43,520 generate so to speak just a little bit 24611 15:48:41,116 --> 15:48:45,480 of that data not all of the data at once 24612 15:48:43,520 --> 15:48:47,480 and that's good because my computer has 24613 15:48:45,480 --> 15:48:49,636 a decent amount of ram certainly enough 24614 15:48:47,480 --> 15:48:51,756 to fit one row of sheep it just doesn't 24615 15:48:49,636 --> 15:48:55,400 have enough memory to fit apparently 1 24616 15:48:51,756 --> 15:48:57,160 million rows of so many sheep so now if 24617 15:48:55,400 --> 15:48:59,320 I go to my terminal window 24618 15:48:57,160 --> 15:49:02,320 and run python of sleep. Pi and hit 24619 15:48:59,320 --> 15:49:04,480 enter what's in three would still work 24620 15:49:02,320 --> 15:49:06,040 zero then one and then two let me go 24621 15:49:04,480 --> 15:49:09,360 ahead and increase the size of this here 24622 15:49:06,040 --> 15:49:12,680 and run python of sleep.i let's try 1 24623 15:49:09,360 --> 15:49:15,680 million as before and hit enter and now 24624 15:49:12,680 --> 15:49:17,080 I immediately see results I don't think 24625 15:49:15,680 --> 15:49:18,880 we'll wait for all of these sheep to be 24626 15:49:17,080 --> 15:49:21,880 printed because then we will literally 24627 15:49:18,880 --> 15:49:23,720 all be asleep but what you'll notice 24628 15:49:21,880 --> 15:49:25,916 happening now is the program is not 24629 15:49:23,720 --> 15:49:27,320 hanging so to speak it's not waiting and 24630 15:49:25,916 --> 15:49:29,276 waiting and thinking thinking and trying 24631 15:49:27,320 --> 15:49:31,636 to generate the entire flock at once 24632 15:49:29,276 --> 15:49:33,636 it's just generating one row of sheep at 24633 15:49:31,636 --> 15:49:35,240 a time and it's flickering on the screen 24634 15:49:33,636 --> 15:49:36,796 because there's so many of them and 24635 15:49:35,240 --> 15:49:38,636 that's all thanks to yield it's 24636 15:49:36,796 --> 15:49:43,520 generating a little bit of data at a 24637 15:49:38,636 --> 15:49:48,320 time not all at once any questions now 24638 15:49:43,520 --> 15:49:48,320 on this feature called 24639 15:49:49,200 --> 15:49:53,916 generators any questions at all to add 24640 15:49:52,080 --> 15:49:55,400 one more piece of terminology to the mix 24641 15:49:53,916 --> 15:49:58,480 just so you've heard it this same 24642 15:49:55,400 --> 15:50:00,116 feature of uh this same feature here is 24643 15:49:58,480 --> 15:50:02,956 returning what we'll technically Now 24644 15:50:00,116 --> 15:50:04,720 call an iterator yield is returning an 24645 15:50:02,956 --> 15:50:07,796 iterator that allows your own code your 24646 15:50:04,720 --> 15:50:11,916 own for Loop in Maine to iterate over 24647 15:50:07,796 --> 15:50:16,720 these generated values one at a time how 24648 15:50:11,916 --> 15:50:19,596 how does uh this yield uh actually works 24649 15:50:16,720 --> 15:50:23,756 under under the hood I I mean is it is 24650 15:50:19,596 --> 15:50:26,116 it using multi trading you can think of 24651 15:50:23,756 --> 15:50:29,560 the implementation as being asynchronous 24652 15:50:26,116 --> 15:50:31,956 in this sense whereby the function is uh 24653 15:50:29,560 --> 15:50:34,116 returning a value immediately and then 24654 15:50:31,956 --> 15:50:36,080 subsequently giving you back another one 24655 15:50:34,116 --> 15:50:37,596 as well underneath the hood what's 24656 15:50:36,080 --> 15:50:40,160 really happening is the generator is 24657 15:50:37,596 --> 15:50:42,240 just retaining state for you it does not 24658 15:50:40,160 --> 15:50:44,240 going to run the entire loop from top to 24659 15:50:42,240 --> 15:50:46,116 bottom and then return a value it's 24660 15:50:44,240 --> 15:50:49,436 going to do one iteration and yield a 24661 15:50:46,116 --> 15:50:51,560 result and the python for you is going 24662 15:50:49,436 --> 15:50:54,116 to suspend the function if you will but 24663 15:50:51,560 --> 15:50:56,000 remember on what iteration it was so the 24664 15:50:54,116 --> 15:50:57,480 next time you iterate over it as it's 24665 15:50:56,000 --> 15:50:59,796 going to happen again and again in this 24666 15:50:57,480 --> 15:51:02,480 for Loop in main you get back another 24667 15:50:59,796 --> 15:51:04,320 value again and again so yield returns 24668 15:51:02,480 --> 15:51:06,360 indeed this thing called an iterator and 24669 15:51:04,320 --> 15:51:08,796 that iterator can be stepped over as in 24670 15:51:06,360 --> 15:51:10,956 a loop one element at a time but the 24671 15:51:08,796 --> 15:51:12,956 language python handles all of that for 24672 15:51:10,956 --> 15:51:16,240 you so that you don't need to do all of 24673 15:51:12,956 --> 15:51:18,240 the underlying uh Plumbing yourself how 24674 15:51:16,240 --> 15:51:20,796 about time for one other question on 24675 15:51:18,240 --> 15:51:24,360 these generators and iterators as our 24676 15:51:20,796 --> 15:51:26,680 sheep continue to fly by so in every 24677 15:51:24,360 --> 15:51:29,720 iteration the program will return to the 24678 15:51:26,680 --> 15:51:32,240 memory to the system so the program will 24679 15:51:29,720 --> 15:51:34,560 not crash correct on each iteration it's 24680 15:51:32,240 --> 15:51:36,276 only returning the one string of sheep 24681 15:51:34,560 --> 15:51:38,720 that's appropriate for the current value 24682 15:51:36,276 --> 15:51:41,400 of I it is not trying to return all 24683 15:51:38,720 --> 15:51:43,636 million rows of the same and therefore 24684 15:51:41,400 --> 15:51:47,116 it uses really one millionth the amount 24685 15:51:43,636 --> 15:51:49,200 of memory although that's a bit of an 24686 15:51:47,116 --> 15:51:51,320 oversimplification all right as these 24687 15:51:49,200 --> 15:51:53,796 sheep continue to fly across the screen 24688 15:51:51,320 --> 15:51:55,400 let me now uh go ahead and interrupt 24689 15:51:53,796 --> 15:51:57,320 this as you might have had to in the 24690 15:51:55,400 --> 15:51:58,636 past with infinite Loop in your own code 24691 15:51:57,320 --> 15:52:01,160 even though this isn't infinite it's 24692 15:51:58,636 --> 15:52:03,080 just really long contrl c will interrupt 24693 15:52:01,160 --> 15:52:06,796 with your keyboard that program giving 24694 15:52:03,080 --> 15:52:09,596 me back control of my computer well here 24695 15:52:06,796 --> 15:52:11,956 we are at the end of cs50's introduction 24696 15:52:09,596 --> 15:52:14,276 to programming with python and if today 24697 15:52:11,956 --> 15:52:17,080 in particular of all days felt like a 24698 15:52:14,276 --> 15:52:18,720 real escalation real quickly realize 24699 15:52:17,080 --> 15:52:20,956 that these are really these are just 24700 15:52:18,720 --> 15:52:23,080 additional perhaps optional Tools in 24701 15:52:20,956 --> 15:52:25,240 your toolkit that you can add to all of 24702 15:52:23,080 --> 15:52:26,840 the past Lessons Learned so that as you 24703 15:52:25,240 --> 15:52:28,596 exit from this course and Tackle other 24704 15:52:26,840 --> 15:52:30,160 courses or projects of your own you have 24705 15:52:28,596 --> 15:52:31,756 all the more of a mental model and all 24706 15:52:30,160 --> 15:52:33,916 the more of a toolbox with which to 24707 15:52:31,756 --> 15:52:36,680 solve those same problems if we think 24708 15:52:33,916 --> 15:52:38,680 back now just a few weeks ago it was 24709 15:52:36,680 --> 15:52:39,916 probably in our focus on functions and 24710 15:52:38,680 --> 15:52:41,636 variables that you first started 24711 15:52:39,916 --> 15:52:43,436 struggling but now in retrospect if you 24712 15:52:41,636 --> 15:52:45,200 look back at those problems and those 24713 15:52:43,436 --> 15:52:46,840 same problem sets odds are those same 24714 15:52:45,200 --> 15:52:48,956 problems would come all too easily to 24715 15:52:46,840 --> 15:52:50,360 you now conditionals was the next step 24716 15:52:48,956 --> 15:52:52,680 in the class wherein we gave you the 24717 15:52:50,360 --> 15:52:54,276 ability to ask questions and get answers 24718 15:52:52,680 --> 15:52:56,200 and therefore do things conditionally in 24719 15:52:54,276 --> 15:52:57,596 your code we came full circle today and 24720 15:52:56,200 --> 15:52:59,636 you can can see that you can now use 24721 15:52:57,596 --> 15:53:01,040 those same kinds of conditionals now to 24722 15:52:59,636 --> 15:53:02,596 do fancier things with list 24723 15:53:01,040 --> 15:53:04,560 comprehensions and D dictionary 24724 15:53:02,596 --> 15:53:06,040 comprehensions and the like Loops of 24725 15:53:04,560 --> 15:53:08,000 course have been omnipresent now for 24726 15:53:06,040 --> 15:53:09,636 weeks including today as we built up 24727 15:53:08,000 --> 15:53:11,436 those same structures and of course 24728 15:53:09,636 --> 15:53:13,596 something can go wrong and exceptions 24729 15:53:11,436 --> 15:53:16,360 and exception handling was our mechanism 24730 15:53:13,596 --> 15:53:18,400 for not only catching errors in code but 24731 15:53:16,360 --> 15:53:19,840 also raising your own exception so that 24732 15:53:18,400 --> 15:53:21,636 if you're laying the foundation to write 24733 15:53:19,840 --> 15:53:24,240 code for other people as in the form of 24734 15:53:21,636 --> 15:53:25,520 libraries you can do that too libraries 24735 15:53:24,240 --> 15:53:27,400 of course are things you can not only 24736 15:53:25,520 --> 15:53:29,680 use but now write on your own be it a 24737 15:53:27,400 --> 15:53:30,956 small module or whole package of code 24738 15:53:29,680 --> 15:53:33,080 that you want to share with others 24739 15:53:30,956 --> 15:53:35,480 around the world and even better can you 24740 15:53:33,080 --> 15:53:37,436 write tests for your own code for your 24741 15:53:35,480 --> 15:53:38,916 libraries for others code as well so 24742 15:53:37,436 --> 15:53:40,560 that ultimately you can be all the more 24743 15:53:38,916 --> 15:53:42,360 confident that not only your code is 24744 15:53:40,560 --> 15:53:44,756 correct today but if you make a change 24745 15:53:42,360 --> 15:53:46,320 to your code tomorrow you haven't broken 24746 15:53:44,756 --> 15:53:49,436 anything at least according to your 24747 15:53:46,320 --> 15:53:50,840 tests if they continue to pass file IO 24748 15:53:49,436 --> 15:53:52,636 though meanwhile was a way of now 24749 15:53:50,840 --> 15:53:54,320 storing data not just in the computer's 24750 15:53:52,636 --> 15:53:56,436 memory like all of these sheep but 24751 15:53:54,320 --> 15:53:59,080 actually storing things persistently 24752 15:53:56,436 --> 15:54:00,756 longer term to dis being in a CSV or 24753 15:53:59,080 --> 15:54:02,796 something more like a binary file like 24754 15:54:00,756 --> 15:54:05,240 an image with regular Expressions you 24755 15:54:02,796 --> 15:54:07,520 then had the ability to express patterns 24756 15:54:05,240 --> 15:54:09,320 and actually validate data or extract 24757 15:54:07,520 --> 15:54:11,520 data from information all the more of a 24758 15:54:09,320 --> 15:54:13,360 useful technique nowadays when so much 24759 15:54:11,520 --> 15:54:15,320 of the world is trying to analyze and 24760 15:54:13,360 --> 15:54:18,276 process data at scale some of which 24761 15:54:15,320 --> 15:54:20,116 might uh in fact be uh quite messy uh 24762 15:54:18,276 --> 15:54:22,200 from the get-go and then of course most 24763 15:54:20,116 --> 15:54:24,160 recently object-oriented programming an 24764 15:54:22,200 --> 15:54:25,840 opportunity to solve the same kinds of 24765 15:54:24,160 --> 15:54:28,200 problems but with a slightly different 24766 15:54:25,840 --> 15:54:30,796 perspective a way to encapsulate and to 24767 15:54:28,200 --> 15:54:33,680 represent real world entities this time 24768 15:54:30,796 --> 15:54:35,596 in code and today of course Etc with so 24769 15:54:33,680 --> 15:54:37,276 many other tools that you can add that 24770 15:54:35,596 --> 15:54:39,720 didn't necessarily fall under any of 24771 15:54:37,276 --> 15:54:42,276 those earlier umbrellas but are useful 24772 15:54:39,720 --> 15:54:44,160 functions and data types and techniques 24773 15:54:42,276 --> 15:54:46,520 just to have again in your back pocket 24774 15:54:44,160 --> 15:54:48,956 as yet other mechanisms for solving 24775 15:54:46,520 --> 15:54:50,480 problems as well not just putting 24776 15:54:48,956 --> 15:54:52,276 everyone to sleep but I thought another 24777 15:54:50,480 --> 15:54:55,200 way to end might be a little more 24778 15:54:52,276 --> 15:54:56,880 vocally to try writing one final program 24779 15:54:55,200 --> 15:54:59,040 together this one using a Library we've 24780 15:54:56,880 --> 15:55:01,360 seen in the past as well as one other 24781 15:54:59,040 --> 15:55:03,756 I've taken the liberty of installing a 24782 15:55:01,360 --> 15:55:05,596 text to speech library on my computer 24783 15:55:03,756 --> 15:55:08,276 here and I'm going to go ahead perhaps 24784 15:55:05,596 --> 15:55:11,320 and open a new file here called uh uh 24785 15:55:08,276 --> 15:55:13,560 say dopy in vs code and I'm going to go 24786 15:55:11,320 --> 15:55:16,840 ahead here and first import our own 24787 15:55:13,560 --> 15:55:19,796 friend import cow and I'm going to 24788 15:55:16,840 --> 15:55:23,680 import this new library here import Pi 24789 15:55:19,796 --> 15:55:26,000 TT sx3 the python text to speech library 24790 15:55:23,680 --> 15:55:27,680 and now perit documentation which I read 24791 15:55:26,000 --> 15:55:30,200 in Advance I'm going to go ahead and 24792 15:55:27,680 --> 15:55:34,080 create a variable for myself here engine 24793 15:55:30,200 --> 15:55:36,880 equals pyttsx3 init to initialize that 24794 15:55:34,080 --> 15:55:39,240 library for text to speech I'm going to 24795 15:55:36,880 --> 15:55:41,040 then ask the user well what do I want to 24796 15:55:39,240 --> 15:55:43,160 hear spoken and I might do something 24797 15:55:41,040 --> 15:55:45,560 like this a variable called this equals 24798 15:55:43,160 --> 15:55:47,080 the return value of input what's this 24799 15:55:45,560 --> 15:55:49,360 shall be my simple question and I'm 24800 15:55:47,080 --> 15:55:52,560 going to keep it this time as a string 24801 15:55:49,360 --> 15:55:54,956 we've seen how to use C we can do c.ca 24802 15:55:52,560 --> 15:55:58,116 of this turns out this new library can 24803 15:55:54,956 --> 15:56:00,040 allow me to use its own to say this as 24804 15:55:58,116 --> 15:56:02,956 well but then ultimately I'm going to 24805 15:56:00,040 --> 15:56:04,480 have to run the engine. run and wait 24806 15:56:02,956 --> 15:56:07,040 just in case it's a long phrase or 24807 15:56:04,480 --> 15:56:09,360 sentence to be said but that's it in 24808 15:56:07,040 --> 15:56:11,276 just eight lines of code not only am I 24809 15:56:09,360 --> 15:56:14,116 apparently going to have a cow appear on 24810 15:56:11,276 --> 15:56:17,080 the screen to close us out now but also 24811 15:56:14,116 --> 15:56:19,080 some synthesized text ultimately then we 24812 15:56:17,080 --> 15:56:20,560 hope with this course that you not only 24813 15:56:19,080 --> 15:56:21,796 learned python that you've not only 24814 15:56:20,560 --> 15:56:23,160 learned programming but you've really 24815 15:56:21,796 --> 15:56:25,080 learned how to solve problems and 24816 15:56:23,160 --> 15:56:27,400 ultimately how to teach yourself new 24817 15:56:25,080 --> 15:56:29,636 languages a funny enough I myself only 24818 15:56:27,400 --> 15:56:30,796 learned python just a few years ago and 24819 15:56:29,636 --> 15:56:32,756 even though I certainly went through 24820 15:56:30,796 --> 15:56:35,680 some formal documentation and resources 24821 15:56:32,756 --> 15:56:37,480 online I mostly learned what I know now 24822 15:56:35,680 --> 15:56:39,560 and even what I had to learn again for 24823 15:56:37,480 --> 15:56:41,720 today by just asking lots of questions 24824 15:56:39,560 --> 15:56:44,000 be it of Google or friends who are more 24825 15:56:41,720 --> 15:56:45,320 versed in this language than I and so 24826 15:56:44,000 --> 15:56:47,520 having that instinct having that 24827 15:56:45,320 --> 15:56:49,080 vocabulary very which to ask questions 24828 15:56:47,520 --> 15:56:51,320 of others to search for answers to 24829 15:56:49,080 --> 15:56:52,840 questions you absolutely now have enough 24830 15:56:51,320 --> 15:56:54,756 of a foundation in Python and 24831 15:56:52,840 --> 15:56:56,436 programming to go off and stand on your 24832 15:56:54,756 --> 15:56:58,116 own so you can certainly and you're 24833 15:56:56,436 --> 15:57:00,040 welcome and encouraged to go on and take 24834 15:56:58,116 --> 15:57:02,276 other courses in Python and programming 24835 15:57:00,040 --> 15:57:04,480 specifically but better still as quickly 24836 15:57:02,276 --> 15:57:06,436 as you can is to find some project 24837 15:57:04,480 --> 15:57:08,360 that's personally of interest that uses 24838 15:57:06,436 --> 15:57:09,956 python or some other language because at 24839 15:57:08,360 --> 15:57:12,320 least from my own experience I tend to 24840 15:57:09,956 --> 15:57:14,320 learn best and I hope you might too by 24841 15:57:12,320 --> 15:57:16,040 actually applying these skills not to 24842 15:57:14,320 --> 15:57:18,956 problems in the classroom but really 24843 15:57:16,040 --> 15:57:21,240 truly to problems in the real world 24844 15:57:18,956 --> 15:57:23,436 allow me with all that said to look at 24845 15:57:21,240 --> 15:57:27,080 my full screen terminal window here run 24846 15:57:23,436 --> 15:57:29,040 python of s.p crossing my fingers one 24847 15:57:27,080 --> 15:57:31,720 final time in hopes that I've not made 24848 15:57:29,040 --> 15:57:34,636 any mistakes or bugs and here we go 24849 15:57:31,720 --> 15:57:38,436 python of sey prompting me what's this 24850 15:57:34,636 --> 15:57:42,796 how about we end on this note 24851 15:57:38,436 --> 15:57:42,796 here this was cs50 1855881

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.