CS50 2021 - Lecture 6 - Python

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
thank you all for coming on an off day uh this is cs50 and before we do a proper beginning today um just wanted to call it a member of cs50's team who's been with us for the past several years works in media services on campus and is just one of a whole team of artists that help make cs50 and other classes here on campus possible and particularly on our audio team here from the ess group at harvard we have a team that helps modulate the audio raising and lowering things playing the tunes as we come in making sure that everything coming out of these laptops sounds great and particularly as the number of people ebbs and flows in a class they too kind of hang on those every words to make sure that everything ultimately sounds great and sadly one of our longest team members is leaving us and leaving harvard moving on to bigger and better things and just on behalf of cs50's whole team just wanted to thank luke for spending so much time with us over the past several years i know you're not expecting this luke but if you're comfortable coming up on stage we have a cs50 hoodie for you is a small token of thanks and given that luke has pretty much sat in these lectures like three times over over the years at least we also have an honorary i took cs50 shirt for him as well thanks thanks so much now in just a moment what you see on the screen is going to be distilled into just this but give us a moment just to reset here before we dive in during breaks and such if you have questions all right this is cs50 and this is already week six and this is the week in which you learn yet another language but the goal is not just to teach you another language for language's sake as we transition today and in the coming weeks from c where we spent the past several weeks now to python the goal ultimately is to teach you all how to teach yourselves new languages so that by the end of this course it's not in your mind the the fact that you learned how to program and see or learned some weeks back how to program in scratch but really how you learned how to program fundamentally in a paradigm known as procedural programming as well as with some taste today and in the weeks to come of other aspects of programming languages like object oriented programming and more so recall though back in week zero hello world looked a little something like this and the world was quite simple all you had to do was drag and drop these puzzle pieces but there were still functions and conditionals and loops and variables and all of those kinds of primitives we then transitioned of course to a much more arcane language that looked a little something like this and even now some weeks later you might still be struggling with some of the syntax or getting annoying bugs when you try to compile your code and it just doesn't work but there too the past few weeks we've been focusing on functions and loops and variables conditionals and really all of those same ideas and so what we begin to do today is to one simplify the language we're using transitioning from c now to python this now being the equivalent program in python and look at its relative simplicity but also transitioning to look at how you can implement these same kinds of features just using a different language so we're going to see a lot of code today and you won't have nearly as much practice with python as you did with c but that's because so many of the ideas are still going to be with us and really it's going to be a process of figuring out all right i want to do a loop i know how to do it in c how do i do this in python how do i do the same with conditionals how do i declare variables and the like and moving forward not just in cs50 but in life in general if you continue programming and learn some other language after the class if in five ten years there's a new more popular language that you pick up it's just gonna be a matter of googling and looking at websites like stack overflow and the like to look at just basic building blocks of programming languages because you already speak after these past six plus weeks you already speak programming itself fundamentally all right so let's do a few quick comparisons left and right of what something might have looked like in scratch and what it then looked like in c but now as of today what it's going to look like in python then we'll turn our attention to the command line ultimately in order to implement some actual programs so in scratch we had functions like this say hello world a verb or an action in c it looked a little something like this and a bit of a cryptic mess the first week you had the print f you had the double quotes you had the semicolon the parentheses so there's a lot more syntax just to do the same thing we're not going to get rid of all of that syntax now but as of today in python that same statement is going to look a little something like this and just to perhaps call out the obvious what is different or now simpler in python versus c even in this simple example here yeah good so it's now print instead of printf and there's also no semicolon and there's one other subtlety over here yeah so no new line and that doesn't mean it's not going to be printed it just turns out that one of the differences we'll see is that with print you get the new line for free it automatically gets outputted by default being sort of a common case but you can override it we'll see ultimately too how about in scratch we had multiple functions like this that not only said something on the screen but also asked a question there by being another function that returned a value called answer in c we saw code that looked a little something like this whereby that first line actually whoops sorry whereby that first line declares a variable called answer sets it equal to the return value of getstring one of the functions from the cs50 library and then the same double quotes and parentheses and semicolon then we had this format code in c that allowed us with percent s to actually print out that same value in python this 2 is going to look a little bit simpler instead we're going to have answer equals get string quote unquote what's your name and then print with a plus sign and a little bit of new syntax but let's see if we can't just infer from this example what it is that's going on well first missing on the left is what to the left of the equal sign there's no what this time feel free to just call it out so there's no type there's no type like the word string which even though that was a type in cs50 every other variable in c did we use int or string or float or bull or something else in python there's still going to be data types today onward but you the programmer don't have to bother telling the computer what types you're using the computer is going to be smart enough the language really is going to be smart enough to just figure it out from context meanwhile on the right hand side get string is going to be a function we'll use today and this week which comes from a python version of the cs50 library but we'll also start to take off those training wheels so that you'll see how to do things without any cs50 library moving forward using a different function instead as before no semicolon but the rest of the syntax is pretty much the same here this starts of course to get a little bit different though we're using print instead of printf but now even though this looks a little cryptic perhaps if you've never programmed before cs50 what might that plus be doing just based on inference here what do you think yeah so adding answer to the string hello and adding so to speak not mathematically but in the form of joining them together much like we saw the join block in scratch or concatenation was the term of art there this plus sign appends if you will whatever's in answer to whatever is quoted here and i deliberately left a space there so that grammatically it looks nice after the comma as well now there's another way to do this and it too is going to look cryptic at first glance but it just gets easier and more convenient over time you can also change this second line to be this instead so what's going on here this is actually a relatively new feature of python in the past couple of years where now what you're seeing is yes a string between these same double quotes but this is what python would call a format string or f string and it literally starts with the letter f which admittedly looks i think a little weird but that just indicates that python should ensue assume that anything inside of curly braces inside of the string should be interpolated so to speak which is a fancy term saying substitute the value of any variables therein and it can do some other things as well so answer is a variable declared of course on this first line this f string then says to python print out hello comma space and then the value of answer if by contrast you avoi if you omitted the curly braces just take a guess what would happen what would the symptom of that bug be if you accidentally forgot the curly braces but maybe still had the f there yeah i would literally print hello comma answer because it's going to take you literally so the curly braces just kind of allow you to plug things in and again it looks a little more cryptic but it's just going to save us time over time and if any of you programmed in java in high school for instance you saw plus in that context too for concatenation this just kind of makes your code a little tighter a little more succinct so it's a convenient feature now in python all right this was an example in scratch of a variable setting a variable like counter equal to zero in c it looked like this where you specify the type the name and then the value with a semicolon in python it's going to look like this and i'll state the obvious here you don't need to mention the type just like before with string and you don't need a semicolon so it's a little simpler if you want a variable just write it and set it equal to some value but the single equal sign still behaves the same as in c suppose we wanted to increment counter by one in scratch we use this puzzle piece here in c we could do this actually in a few different ways there was this way if counter already exists you just say counter equals counter plus one there was the slightly less verbose way where you could whoops sorry let me do the first sentence first in python that same thing as you might guess is actually going to be almost the same you just throw away the semicolon and the mathematics are ultimately the same copying from right to left via the assignment operator now recall and see that we had this shorthand notation which did the same thing in python you can similarly do the same thing just no need for the semicolon the only step backwards we're taking if you were a big fan of counter plus plus that doesn't exist in python nor minus minus you just can't do it you have to do the plus equals one or plus minus or minus equals one to achieve that same result all right how about in python two here in scratch recall was a conditional asking a silly question like is x less than y and if so just say as much in c that looked a little something like this printf and if with the parentheses the curly braces the semicolon and all of that in python this is going to get a little more pleasant to type two it's going to be just this and if someone wants to call it some of the obvious changes here what has been simplified now in python for a conditional it would seem yeah what's missing or chain so no curly braces and sorry and we're using the colon instead so i got rid of the curly braces in python but i'm using a colon instead and even though this is a single line of code so long as you indent subsequent lines along with the printf that's going to imply that everything uh if the if condition is true should be executed below it until you start to unindent and start uh writing a different line of code altogether so indentation in python is important so this is among the reasons we've emphasized uh axes like style just how well styled your code is and honestly we've seen certainly in office hours and you've seen in your own code sort of a tendency sometimes to be a little relaxed when it comes to indentation right if you're one of those folks who likes to indent everything on the left hand side of the window yeah it might compile and run but it's not particularly readable by you or anyone else python actually addresses this by just requiring indentation when logically needed so python is going to force you to start indenting properly now if that's been perhaps a tendency otherwise what else is missing well we have no semicolon here of course it's print instead of printf but otherwise those seem to be the primary differences what about something larger in scratch if an if else block like this you can perhaps guess what it's going to look like and see it looks like this curly braces semicolons and so forth in python it's going to now look like this almost the same but indentation's important the colons are important and there's one other difference that's now again visible here but we didn't call it out a second ago what else is different in python versus c for these conditionals yeah perfect we don't have any parentheses around the condition the boolean expression itself and why not well it's just simpler to type it's less to type you can still use parentheses and in fact you might want to or need to if you want to like uh combine thoughts and do this and that or this or that but by default you no longer need or should have those parentheses just say what you mean lastly with conditionals we had something like this an if else if else statement in c it looked a little something like this in python it's going to get really tighter now it's just if and this is the curiosity l if x greater than y so it's not else if it's literally one key word l if and the colons remain now on each of the three lines but the indentation is important and if we did want to do multiple things we could just indent below each of these conditionals as well all right let me pause this first to see if there's any questions on these syntactic differences yeah uh in between between what and what ah good question is python uh sensitive to spaces and where they go sometimes no sometimes yes is the short answer stylistically though you should be practicing what we're preaching here whereby you do have spaces to the left and right of binary operators that they're called something like less than or greater than is a binary operator because there's two upper and to the left and to the right of them and in fact in python more so than the world of c there's actually formal style conventions not only within cs50 have we had style a style guide on the course's website for instance that just dictates how you should write your code so that it looks like everyone else is in the python community they take this one step further and there's an actual standard whereby you don't have to adhere to it but generally speaking in the real world someone would reprimand you would reject your code if you're trying to contribute it to another project if you don't hear to these standards so while you could be laxed with some of this white space do make things readable and that's python's theme for the code to be as readable as possible all right so let's take a look at a couple of other constructs before transitioning to some actual code this of course in scratch was a loop meowing forever and c the closest we could get was doing something while true because true never changes so it's sort of a simple way of just saying do this forever in python it's pretty much the same thing but a couple small differences here the parentheses are gone the colon is there the indentation is there no semicolon and there's one other subtle difference what do you see true is capitalized just because both true and false are boolean values in python but you got to start capitalizing them just because all right how about a loop like this where you repeat something a finite number of times like meowing three times in c we could do this a few different ways there's this very mechanical way where you initialize a variable like i to zero you then use a while loop and check if i is less than three the total number of times you want to meow then you print what you want to print you increment i using this syntax or the longer more verbose syntax with plus equals or whatnot and then you do it again and again and again in python you can do it functionally the same way same idea slightly different syntax you just don't bother saying what type of variable you want python will infer from the fact that there's a zero right there you don't need the parentheses you do need the colon you do need the indentation you can't do the i plus plus but you can do this other technique as we could have done in c as well how else might we do this though too well it turns out in c we could do something like this which again sort of cryptic in at first glance became perhaps more familiar where you have an initialization a conditional and then an update that you do after each iteration in python there isn't really an analog there is no analog in python where you have the parentheses and the multiple semicolons in the same line instead there is a for loop but it's meant to read a little more like english 4i in 0 1 and 2. so we'll see in a bit these square brackets represent an array now to be called a list in python so lists in python are more like link lists than they are in the they are arrays more on that soon so this just means for i in the following list of three values and on each iteration of this loop python automatically for you it first sets i to zero then it sets i to one then it sets i to two so that you effectively do things three times but this doesn't necessarily scale as i've drawn it on the board suppose you took this at face value as the way you iterate some number of times in python using a for loop at what point does this approach perhaps get bad or bad design let me give folks just a moment to think yeah i'm back sure if you don't know how many times you want to loop or iterate you can't really create a hard-coded list like that of zero one two other thoughts yeah if you're iterating a large number of times this list is going to get longer and longer and you're just kind of stupidly going to be typing out like comma 3 comma 4 comma 5 comma dot comma 99 comma 100 i mean your code would start to look atrocious eventually so there is a better way in python there is a function or technically a type called range that essentially magically gives you back a range of values from zero on up to but not through a value so the effect of this line of code for i in the following range essentially hands you back a list of three values thereby letting you do something three times and if you want to do something 99 times instead you of course just change the three to a 99 question a really good question can you start counting at a higher number so not zero which is the implied default but something larger than that yes so it turns out the range function takes multiple arguments not just one but maybe two or even three that allows you to customize this behavior so you can customize where it begins you can customize the increment by default it's one but if you want to do every two values for like evens or odds you could do that as well and a few other things and before long we'll take a look at some python documentation that will become your authoritative source for answers like that like what can this function do other questions on this thus far seeing none so what else might we uh compare and contrast here well in the world of c recall that we had a whole bunch of built-in data types like these here um bull and char and double and float and so forth string which happened to come from the cs50 library but uh the the language c itself certainly understood the idea of strings because the backslash zero the support for percent s and printf that's all native built into c not a cs50 simplification all we did and revealed as of a couple of weeks ago is that string this data type is just a synonym for a type def for char star which is part of the language natively in python now this list actually gets a little shorter at least for these common primitive data types still going to have bulls we're going to have floats and ins and we're going to have strings but we're going to call them stirs and this is not a cs50 thing from the library stir str is in fact a data type in python that's going to do a lot more than strings did for us automatically in c ins and floats meanwhile don't need the corresponding longs and doubles because in fact among the problems python solves for us too ants can get as big as you want integer overflow is no longer going to be an issue per week one the language solves that for us floating point in precision unfortunately is still a problem that remains but there are libraries code that other people have written as we briefly discussed in weeks past that allow you to do scientific or financial computing using libraries that build on top of these data types as well so there's other data types too in python which we'll see actually gives us a whole bunch of more power and capability things called ranges like we just saw lists like i called out verbally with the square brackets things called tuples for things like x comma y or latitude comma longitude uh dictionaries or dicks which allow you to store keys and values much like our hash tables from last time and then sets in the mathematical sense where they filter out duplicates for you and you can just put a whole bunch of numbers a whole bunch of words or whatnot and the language would via this data type will filter out duplicates for you now there's going to be a few functions we give you this week and beyond training wheels that we're then going to very quickly take off just because as we'll see today they just simplify the process of getting user input correctly without accidentally writing buggy code just when you're trying to get hello world or something similar to work and we'll give you functions not like as long as this list in c but a subset of these get float get int and get string that'll automate the process of getting user input in a way that's more resilient against potential bugs but we'll see what those bugs might be and the way we're going to do this is similar in spirit to c instead of doing include cs50.h like we did in c you're going to now start saying import cs50 python supports similar to c libraries but there aren't header files anymore you just use the name of the library in python and if you want to import cs50s functions you just say import cs50 or if you want to be more precise and not just import the whole thing which could be slow if you've got a really big library with a lot of functionality in it you can be more precise and say from cs50 import get flow from cs50 import get int from cs50 import getstring or you can just separate them by commas and import three and only three things from a particular library like ours but starting today and onward we're going to start making much more heavy use of libraries code that other people wrote so that we're no longer reinventing the wheel we're not making our own linked lists our own trees our own dictionaries we're going to start standing on the shoulders of others so that you can get real work done so to speak faster by building your software on top of others code as well all right so that's it for the syntactic tour of the language and the sort of core feature soon we'll transition to application thereof but let me pause here to see if there's any questions on syntax or primitives or otherwise or otherwise oh yes and back oh sorry say again why doesn't python have what kind of operators sorry someone coughed when you said something operators the oh the increment operator i'd have to check the history honestly python has tended to be a fairly minimalist language and if you can do something one way the community arguably has tended to not give you multiple ways to do the same thing syntactically there's probably a better answer and i'll see if i can dig in and post something online to follow up on that all right so before we transition to now writing some actual code let me go ahead and consider exactly how we're going to write code in the world of c recall that it's generally been a two-step process we create a file called like hello.c and then step one make hello step two dot slash hello or if you think back to week two when we sort of peeled back the layer of what hello of what make was doing you could more verbosely type out the name of the actual compiler clang in our case command line arguments like dash o hello to specify what name you want to create and then you can specify the file name and then you can specify what libraries you want to link in so that was a very verbose approach but it was always a two-step approach and so even as you've been doing recent problem sets odds are you've realized that anytime you want to make a change to your code or make a change to your code and try and test your code again you're constantly doing those two steps moving forward in python it's going to become simpler and it's going to be just this the file name is going to change but that might go without saying it's going to be something like hello.pi py instead of hello.c and that's just a convention using a different file extension but there's no compilation step per se you jump right to the execution of your code and so python it turns out is the name not only of the language we're going to start using it's also the name of a program on a mac a pc assuming it's been pre-installed that interprets the language for you this is to say that python is generally described as being interpreted not compiled and by that i mean you get to skip from the programmer's perspective that compilation step there is no manual step in the world of python typically of writing your code and then compiling it to zeros and ones and then running the zeros and ones instead these kind of two steps get collapsed into the illusion of one whereby you instead are able to just run the code and let the computer figure out how to actually convert it to something the computer understands and the way we do that is via this whole process input and output but now when you have source code it's going to be passed into an interpreter not a compiler and the best analog of this is just to perhaps point out that in the human world if you speak or don't speak multiple human languages it can be a pretty slow process from going from one language to another for instance here are step-by-step instructions for finding someone in a phone book unfortunately in spanish unfortunately if you don't speak or read spanish you could figure this out you could run this algorithm but you're going to have to do some googling or you're going to have to open a literal dictionary from spanish to english and convert this and the catch with translating any language human or computer or otherwise is that you're going to pay a price typically some time and so converting this in spanish to this in english is just going to take you longer than if this were already in your native language and that's going to be one of the subtleties with the world of python yes it's a feature that you can just run the code without having to bother compiling it manually first but we might pay a price and things might be a little slower now there's ways to chip away at that but we'll see an example there of in fact let me transition now to just a couple of examples that demonstrate how python is not only easier for many people to use perhaps yourselves too because it throws away a lot of the annoying syntax it shortens the number of lines you have to write and also it comes with so many darn libraries you can just do so much more without having to write the code yourself so as an example of this let me switch over here to this image from problem set four which is the weeks bridge down by the charles river here in cambridge and this is the original photo pretty clear and it's even higher res if we looked at the original version of the photo but there have been no filters a la instagram applied to this photo recall for problem set four you had to implement a few filters and among them might have been blur and blur was probably among the more challenging of the ones because you had to iterate over all of the pixels you had to take into account what's above what's below to the left to the right i mean there was a lot of math and arithmetic and if you ultimately got it it was probably a great sense of satisfaction but that was probably several hours later in a language like python where there might be libraries that have been written by others on whose shoulders you can stand we could perhaps do something like this let me go ahead and run a program or write a program called blur.pi here and in blur.pi in vs code let me just do this let me import from a library not the cs50 library but the pillow library so to speak a keyword called image and another one called image filter then let me go ahead and say let me open the current version of this image which is called bridge.bmp so the before version of the image will be the result of calling image.open quote unquotebridge.bmp and then let me create an after version so you'll see before and after after equals the before version dot filter of image filter and there is if i read the documentation i'll see that there's something called a box blur that allows you to blur in box format like one pixel above below left and right so i'll do one pixel there and then after that's done let me go ahead and save the file as something like out.bmp that's it assuming this library works as described i am opening the file in python using line three and this is somewhat new syntax in the world of python we're gonna start making use of the dot operator more because in the world of python you have what's called object oriented programming or oop as a term of art and what this means is that you still have functions you still have variables but sometimes those functions are embedded inside of the variables or more specifically inside of the data types themselves think back to c when you wanted to convert something to uppercase there was a two upper function that takes as input an argument that's a char and you can pass in any chart you want and it will uppercase it for you and give you back a value well you know what if that's such a common paradigm where upper casing charge is a useful thing what the world of python does is it embeds into the string data type or char if you will the ability just to uppercase any char by treating the char or the string as though it's a struct in c recall that structs encapsulate multiple types of values in object oriented programming in a language like python you can encapsulate not just values but also functionality functions can now be inside of structs but we're not going to call them structs anymore we're going to call them objects but that's just a different vernacular so what am i doing here inside of the image library there's a function called open and it takes an argument the name of the file to open once i have a variable called before that is a struct or technically an object inside of which is now because it was returned from this function a function called filter that takes an argument the argument here happens to be image dot box blur one which itself is a function but it just returns the filter to use and then after dot save does what you might think it just saves the file so instead of using f open and if right you just say dot save and that does all of that messy work for you so it's just what four lines of code total let me go ahead and go down to my terminal window let me go ahead and show you with ls that at the moment sorry let me not bother showing that because i have other examples to come i'm going to go ahead and do python of blur dot pi nope sorry wrong place i did need to make a command there we go okay let me go ahead and type ls inside of my filter directory which is among the sample code online today there's only one file called bridge.b damn i'm trying to get these things ready at the same time let me rewind let me move this code into place all right i've gone ahead and moved this file blur.pi into a folder called filter inside of which there's another file called bridge.bmp which we can confer with ls let me now go ahead and run python which is my interpreter and also the name of the language and run python on this file so much like running the spanish algorithm through google translate or something like that as input to get back the english output this is going to translate the python language to something this computer or this cloud-based environment understands and then run the corresponding code top to bottom left to right i'm going to go ahead and enter no error message is generally a good thing if i type ls you'll now see out.bmp let me go ahead and open that and you know what just to make clear what's really happening let me blur it even further let's make a box that's not just one pixel around but 10. so let's make that change and let me just go ahead and rerun it with python of blur.pi i still have out.bmp let me go ahead and open out.bmp and show you first the before which looks like this that's the original and now crossing my fingers four lines of code later the result of blurring it as well so the library is doing all of the same kind of leg work that you all did for the assignment but it's encapsulated it all into a single library that you can then use instead those of you who might have been feeling more comfortable might have done a little something like this let me go ahead and open up one other file called edges.pi and in edges.i am again going to import from the pillow library the image keyword and the image filter then i'm going to go ahead and create a before image that's a result of calling image.open of the same thing bridge.bmp then i'm going to go ahead and run a filter on that called image whoops image filter dot find edges which is like a constant if you will defined inside of this library for us and then i'm going to do after dot save quote unquote dot bmp using the same file name i'm now going to run python of edges.pi after sorry user error we'll see what syntax error means soon let me go ahead and run the code now edges.pi let me now open that new file out.pmp and before we had this and now especially if what will look familiar if we did the more comfortable version of pset four we now get this after just four lines of code so again suggesting the power of using a language that's better optimized for the tool at hand and at the risk of really making folks sad let's go ahead and re-implement if we could problem set five real quickly here let me go ahead and open um another version of this code wherein i have a c version just from problem set five when you implemented a spell checker loading a hundred thousand plus words into memory and then you took kept track of just how much time and memory it took and that probably took a while implementing all of those functions in dictionary.c let me instead now go into a new file called dictionary.pi and let me stipulate for the sake of discussion that we already wrote in advance speller dot pi which corresponds to speller.c you didn't write either of those recall for problem set five we gave you speller.c assume that we're going to give you speller.pie so the onus on us right now is only to implement speller dictionary dot pi all right so i'm going to go ahead and define a few functions and we're going to see now the syntax for defining functions in python i want to go ahead and define a first a hash table which was the very first thing you defined in dictionary.c i'm going to go ahead then and say words gets this give me a dictionary otherwise known as a hash table all right let me define a function called check which was the first function you might have implemented check is going to take a word and you'll see in python the syntax is a little different you don't specify the return type you use the word def instead to define you still specify the name of the function and the any arguments there too but you will omit any mention of types but you do use a colon and indent so how do i check if a word is in my dictionary or in my hash table well in python i can just say if word in words go ahead and return true else go ahead and return false done with the check function all right now i want to do like load that was the heavy lift where you had to load the big file into memory so let me define a function called load it takes a string the name of a file to load so i'll call that dictionary just like in c but no data type let me go ahead and open a file by using an open function in python by opening that dictionary in read mode so this is a little similar to f open a function in c you might recall then let me iterate over every line in the file in python this is pretty pleasant for line in file colon indent how now do i get at the current word and then strip off the new line because in this file of words 140 000 words there's word backslash n word backslash n all right well let me go ahead and get a word from the current line but strip off from the right end of the string the new line which the r strip function in python does for me then let me go ahead and add to my dictionary or hash table that word done let me go ahead and close the file for good measure and then let me go ahead and return true because all was well that's it for the load function in python how about the size function this did not take any arguments it just returns the size of the hash table or dictionary in python i can do that by returning the length of the dictionary in question and then lastly gone from the world of python is malloc and free memory is managed for you so no matter what i do there's nothing to unload the computer will do that for me so i give you in these functions problems at five in python so i'm sorry we made you write it in c first but the implication now is that what are you getting for free in a language like python well encapsulated in this one line of code is much of what you wrote for problem set five implementing your array for all of your letters of the alphabet or more all of the linked lists that you implemented to create chains to store all of those words all of that is happening it's just someone else in the world wrote that code for you and you can now use it by way of a a dictionary and actually i can change this a little bit because add is technically not the right function to use here i'm actually treating the dictionary as something simpler a set so i'm going to make one tweak set recall was another data type in python but set just allows it to handle duplicates and it allows me to just throw things into it by literally using a function as simple as add and i'm going to make one other tweak here because when i'm checking a word it's possible it might be given to me in uppercase or capitalized it's not going to necessarily come in in the same lower case format that my dictionary did i can force every word to lower case by using word dot lower and i don't have to do it character for character i can do the whole darn string at once by just saying word dot lower all right let me go ahead and open up a terminal window here and let me go into first my c version on the left and actually i'm going to go ahead and split my terminal window into two and on the right i'm going to go into a version that i essentially just wrote but it's also available online if you want to play along afterward i'm going to go ahead and make speller in c on the left and note that it takes a moment to compile then i'm going to be ready to run speller of dictionaries let's do like the sherlock holmes text which is pretty big and then over here let me get ready to run python of speller on texts homes.txt2 so the syntax is a little different at the command prompt i just on the left have to compile the code with make and then run it with dot slash speller on the right i don't need to compile it but i do need to use the interpreter so even though the lines are wrapping a little bit here let me go ahead and run it on the right and i'm going to count how long it takes verbally for demonstration sake one mississippi two mississippi three mississippi okay so it's like three seconds give or take now running it in python keeping in mind i spent way fewer hours implementing a spell checker in python than you might have in problem set five but what's the trade-off going to be and what kinds of design decisions do we all now need to be making consciously here we go on the right in python one mississippi two mississippi three mississippi four mississippi five mississippi six mississippi seven mississippi eight mississippi nine mississippi ten mississippi eleven mississippi all right so ten or eleven seconds so which one is better let's like go to the group here which of these programs is the better one how might you answer that question based on demonstration alone what do you think okay so python to summarize is better for the programmer because it was way faster to write but c is maybe better for the computer because it's much faster to run i think that's a reasonable formulation other opinions at c yeah i'm dealing with something like a massive data set or something huge that that time is going to really build up on it might be worth it to put in the upfront effort and just go to get ac so the process continually runs faster absolutely a really good answer and let me summarize is it depends on the workload if you will if you were to you if you have a very large data set you might want to optimize your code to be as fast and performant as it can be especially if you're running that code again and again maybe you're a company like google people are searching a huge database all the time you really want to squeeze every bit of performance as you can out of the computer you might want to have someone smart take a language like c and write it at a very low level it's going to be painful they're going to have bugs they're going to have to deal with memory management and like but if and when it works correctly it's going to be much faster it would seem by contrast if you have a data set that's big and 140 000 words is not small but you don't want to spend like five hours 10 hours a week of your time building a spell checker or dictionary you can instead leverage a different language with different libraries and build on top of it in order to prioritize the human time instead other thoughts that perfect segue to exactly the next point we wanted to make which was is there something in between and indeed there is i'm oversimplifying what this language is actually doing it's not as stark a difference as saying like hey python is four times slower than c like that's not the right takeaway there are absolutely ways that engineers can optimize languages as they have already done for python and in fact i've configured my settings in such a way that i've kind of dramatized just how big the difference is it is going to be slower python typically than the equivalent c program but it doesn't have to be as big of a gap as it is here because indeed among the features you can turn on in python is to save some intermediate results technically speaking yes python is interpreting dictionary.pi and these other files translating them from one language to another but that doesn't mean it has to do that every darn time you run the program as you propose you can save or cache c-a-c-h-e the results of that process so that the second time in the third time are actually notably faster and in fact python itself the interpreter the most popular version thereof itself is actually implemented in c so you can make sure that your interpreter is as fast as possible and what then is maybe the high level takeaway yes if you are going to try to squeeze every bit of performance out of your code and maybe code is constrained you maybe you have very small devices maybe it's like a watch nowadays or maybe it's a sensor that's installed in some small format in an appliance or in infrastructure where you don't have much battery life and you don't have much size you might want to minimize just how much work is being done and so the faster the code runs and uh the better it's going to be if it's implemented something low level so c is still very commonly used for certain types of applications but again if you just want to solve real world problems and get real work done and your time is just as if not more valuable than the device you're running it on long term you know what python is among the most popular languages as well and frankly if i were implementing a spell checker moving forward i'm probably starting with python and i'm not going to waste time implementing all of that low-level stuff because the whole point of using newer modern languages is to use abstractions that other people have created for you and by abstraction i mean something like the dictionary function that just gives you a dictionary or hash table or the equivalent version that i used which in this case was a set all right any questions then on python thus far no all right let's oh yeah in the middle really good question or observation could you just compile python code yes absolutely this idea of compiling code or interpreting code is not native to the language itself it tends to be native to the conventions that we humans use so you could actually write an interpreter for c that would read it top to bottom left to right converting it to on the fly something that computer under the computer understands but historically that's not been the case c is generally a compiled language but it doesn't have to be what python nowadays is actually doing is what you described earlier it technically is sort of unbeknownst to us compiling the code technically not into zeros and ones technically into something called bytecode which is this intermediate step that just doesn't take as much time as it would to recompile the whole thing and this is an area of research for a computer scientist working in programming languages to improve these kinds of paradigms why well honestly for you and i the programmer it's just much easier to one run the code and not worry about the stupid second step of compiling it all the time why it's literally half as many steps for me the human and that's a nice thing to optimize for and ultimately two you might want all of the fancy features that come with these other languages so you should really just be fine-tuning how you can enable these features as opposed to shying away from them here and in fact the only time i personally ever use c is from like september to october of every year during cs50 almost every other month do i reach for python or another language called javascript to actually get real work done which is not to impugn c it's just that those other languages tend to be better fits for the amount of time i have to allocate and the types of problems that i want to solve all right let's go ahead and take a five minute break here and when we come back we'll start writing some programs from scratch all right so let's go ahead and start writing some code from the beginning here whereby we start small with some simple examples and then we'll build our way up to more sophisticated examples in python but what we'll do along the way is first look side by side at what the c code looked like way back in week one or two or three and so forth and then write the corresponding python code at right and then we'll transition just to focusing on python itself what i've done in advance today is i've downloaded some of the code from the course's website my source 6 directory which contains all of the pre-written c code from weeks past but it'll also have copies of the python code we'll write here together and look at so first here is hello dot c back from week zero this was version zero of it i'm gonna go ahead and do this i'm gonna go ahead and split my uh code window up here i'm gonna go ahead and create a new file called hello.pi and this isn't something you'll typically have to do laying your code out side by side but i've just clicked the little icon in vs code that looks like two columns that splits my code editor into two places so that we can in fact see things for now side by side with my terminal window down below all right now i'm going to go ahead and write the corresponding python program on the right which recall was just print quote unquote hello world and that's it now down in my terminal window i'm going to go ahead and run python of hello.pi enter and voila we've got hello.pi working so again i'm not going to play any further with the c code it's there just to jog your memory left and right so let's now look at a second version of hello world from that first week whereby if i go and get hello1.c i'm going to drag that over to the right whoops i'm going to go ahead and drag that over to the left here and now on the right let's modify hello.pi to look a little more like the second version in c all right i want to get a answer from the user as a return value but i also want to get some input from them so from cs50 i'm going to import the function called getstring for now we're going to get rid of that eventually but for now it's a helpful training wheel and then down here i'm going to say answer equals get string quote unquote what's your name question mark space but no semicolon no data type and then i'm going to go ahead and print just like the first example on the slide hello comma space plus answer and now let me go ahead and run this python flow.pie all right it's asking me what's my name david hello comma david but it's worth calling attention to the fact that i've also simplified further it's not just that the individual functions are simpler what is also now glaringly omitted from my python code at right both in this version and the previous version what did i not bother implementing yeah so i didn't even need to implement main we'll revisit the main function because having a main function actually does solve problems sometimes but it's no longer required and see you have to have that to kick start the entire process of actually running your code and in fact if you were missing main as you might have experienced if you accidentally compiled helpers.c instead of the file that contained main you would have seen a compiler error in python it's not necessary python you can just jump right in start programming and boom you're good to go especially if it's a small program like this you don't need the added overhead or complexity of a main function so that's one other difference here all right there were a few other ways we could say hello world recall that i could use a format string so i could put this whole thing in quotes i could use this f prefix and then let me go ahead and run python if hello.pi again you can perhaps see where we're going with this let me type my name david and here we go okay that's the mistake that someone identified earlier you need the curly braces otherwise no variables are interpolated that is substituted with their actual values so if i go back in and add those curly braces to the f string now let me run python of hello.pi type in my name and there we go we're back in business which one's better i mean it depends but generally speaking making shorter more concise code tends to be a good thing so stylistically the f string is probably a reasonable instinct to have all right well what more can we do besides this well let me go ahead here and let's get rid of the training wheel altogether actually so same c code at left let me get rid of the cs50 library which we will ultimately in a couple of weeks anyway i can't use getstring but i can use a function that comes with python called input and in fact this is actually a one for one substitution pretty much there's really no downside to using input instead of get string we implement getstring just for consistency with what you saw in c python of hello.pi what's your name david still actually works the same so gone are the cs50 specific training wheels we're going to bring them back shortly just to deal with integers or floats or other values too because it's going to make our lives a little simpler with error checking all right any questions before we now pivot to revisiting other examples from week one but now in python all right let me go ahead and open up now let's say uh calculator0.c which was one of the first examples we did involving math and operators like that as well as functions like get int let me go ahead and create a new file now called uh calculator dot pi at right so that i have my c code at left still and my python code it right all right let me go dive into a translation of this code into python i am going to use get int from the cs50 library so let me import that i'm going to go ahead now and get an int from the user so in x equals get int and i'll ask them for an x value just like we did weeks ago no need to specify a semicolon though or a int for the x it will just figure it out y is going to get another int by a y colon and then down here i'm going to go ahead and say print of x plus y so this is already a bit new recall the c version required that i use this format string as well as printf itself python's just a little more user friendly if all you want to do is print out a value like x plus y just print it don't fuss with any percent signs or format codes it's not printf it's indeed just print now all right let me go ahead and run python of calculator.pi enter just do a quick sample one plus two indeed equals three as an aside suppose i had taken a different approach to importing the whole cs50 library functionally it's the same you're not going to notice any performance impact here it's a small library but notice what does not work now whereas it did work in c python of calculator.pi enter we see our first traceback deliberately here so a traceback is just a term of art that says here is a trace back through all of the functions that just got executed in the world of c you might call this a stack trace stack being the operator operative word recall that when we talked about the stack and the heap the stack like a stack of trays was all of the functions that might get called one after the other we had main we had swap then swap one away and then main finished recall so here's a traceback of all the functions or code that got executed there's not really any functions other than my file itself otherwise there'd be more detail but even though it's a little cryptic we can perhaps infer from the output here name error so something related to the name of something name getint is not defined and this of course happens on line 3 over there all right so why is that well python essentially allows us to name space our functions that come from libraries there was a problem in c if you were using the cs50 library and thus had access to get in get string and so forth you could not use another library that had the same function names they would collide and the compiler would not know how to link them together correctly in python and other languages like javascript and in java you have a support for effectively what would be called namespaces you can isolate variables and function names to like their own namespace like their own container in memory and what this means is if you import all of cs50 you have to say that the get in you want is inside the cs50 library so just like with the image blurring and the image edges before where i had to specify image dot in image filter dot similarly here am i specifying with a dot operator albeit a little differently that i want cs50.getint in both places and now if i rerun python of calculator.pi one and two now we're back in business which one is better generally speaking it depends on just how many functions you're using from the library if you're using a whole bunch of functions just import the whole thing if you're only using maybe one or two import them line by line all right so let's go ahead and make a little tweak here let's get rid of this library and take this training wheel off too as quickly as we introduced it though for the problem set six you'll be able to use all of these same functions suppose i get rid of this and i just use the input function just like i did by replacing getstring earlier let me go ahead now and run this version of the code python of calculator.pi okay how about one plus two equals three huh all right obviously wrong incorrect can anyone explain what just happened based on instincts what just happened here yeah sure yeah exactly python is interpreting both or treating both x and y as strings which is actually what the input function returns by default and so plus is now being interpreted as concatenation as we defined it earlier so x plus y isn't x plus y mathematically but in terms of string joining just like in scratch so that's why we're getting 12 or really 1 2 which isn't itself a number it 2 is another string so we somehow need to convert things and we didn't have this ability quite as easily in c we did have like the a to i function ascii to integer which did allow you to do this the analog in python is actually just to do a cast a typecast using int so just like in c you can use the keyword and but use it a little differently notice that i'm not doing parenthesis int close parenthesis before the value i'm using int as a function so indeed function in python int is a function float is a function that you can pass values into to do this kind of conversion so now if i run python of calculator.pi one and two now we're back in business and getting the answer of three but there's kind of a catch here there's always going to be a trade-off like that sounds amazing that it just works in this way we can throw away the cs50 library already but what if the user accidentally types or maliciously types in like a cat instead of a number damn well there's one of these tracebacks like now my program has crashed this is similar in spirit to the kinds of seg faults that you might have had in c but they're not seg faults per se it doesn't necessarily relate to memory this time it relates to actual runtime values not being as expected so this time it's not a name error it's a value error invalid literal for int with base 10 quote unquote cat so again it's written for sort of a programmer more than um sort of a typical person because it's pretty arcane the language here but let's try to interpret it invalid literal a literal is just something someone typed uh for int which is the function name with base 10. it's just defaulting to decimal numbers cat is apparently not a decimal number doesn't look like it therefore can't be treated like it therefore there's a value error so what can we do unfortunately you would have to somehow catch this error and the only way to do that in python really is by way of another feature that c did not have namely what are called exceptions an exception is exactly what just happened name error value error there are things that can go wrong when your python code is running that aren't necessarily going to be detected until you run your code so in python and in javascript and in java and other more modern languages there's this ability to actually try to do something except if something goes wrong and in fact i'm going to introduce a bit of syntax here even though we won't have to use this much just yet instead of just blindly converting x to an int let me go ahead and try to do that and if there's an exception go ahead and say something like print uh that is not an int and then i'm gonna do something like exit right there and let me go ahead and do this here let me try to get y except if there's an exception then let me go ahead and say again that is not an int exclamation point and then i'm going to exit from there too otherwise i'll go ahead and print x plus y if i run python i've calculated up pi now whoops [Music] that oh forgot my close quote sorry all right so close quote python of calculator dot pi uh one and two still work but if i try to type in something wrong like cat now it actually detects the error so what is the cs50 library in python doing it's actually doing that try and accept for you because suffice it to say otherwise your programs for something simple like a calculator start to get longer and longer so we factored that kind of logic out to the cs50 getint function and get float function but underneath the hood they're essentially doing this try accept but they're being a little more precise they're detecting a specific error and they are doing it in a loop so that these functions will get executed again and again in fact the best way to do this is to say accept if there's a value error then print that error message out to the user and again let's not get too into the weeds here with this feature we've already put it into the cs50 library but that's why for instance we bootstrap things by just using these functions out of the box all right let's do something more with our calculator here how about this in the world of c we had another version of this code which actually did some division by way of which actually did division of numbers not just the addition here in so let me go ahead and close the c version and let's focus only on python now doing some of these same lines of codes but i'm going to go ahead and just assume that the user is going to cooperate and use proper input so from cs50 import getint that'll deal with any errors for me x gets getint asks the user for an intex y equals getint ask the user for an int y and then let's go ahead and do this let's declare a variable called z set it equal to x divided by y then let's go ahead and print z still no need for a format string i can just print out the variable's value let me go ahead and run python if calculator.pi let me do 1 10 and i get 0.1 what did i get in c though if you think back does it what would we have happened in c yeah we would have gotten zero in c but y in c when you divide one inch by another and those ends are like one and ten respectively it will give you what it will give you an integer back and unfortunately 0.1 the integer part of it is indeed zero so this was an example of truncation so truncation was an issue in c but it would seem as though this is no longer a problem in python insofar as the division operator actually handles that for us as an aside if you want the old behavior because it actually is sometimes useful for rounding or flooring values you can actually use two slashes and now you get the c behavior so that now one divided by ten is zero so you don't give up that capability but at least it does a more sensible default most people especially new programmers when dividing one value by another would want to get point one not zero for reasons that indeed we had to explain weeks ago but what about another problem we had with the world of floats before whereby there was imprecision let me go ahead and somewhat cryptically print out the value of z as follows i'm going to format it using an f string and i'm going to go ahead and format not just z because this is essentially the same thing notice this if i do python of calculator dot pi 1 and 10 i get by default just one significant digit but if i use this syntax in python which you won't have to use often i can actually do and see like i did before 50 significant digits after the decimal point so now let me rerun python of calculator.pi 1 and 10 and let's see if floating point and precision is still with us unfortunately it is and you can see as much here the f string the format string is just showing us now 50 digits instead of the default one so we've not solved all problems but we have solved at least some all right before we pivot away from a mirror calculator any questions now on syntax or concepts or the like yeah how do you what oh how do you comment really good question if you're using double slash for division with flooring or truncation like i described how do you do a comment in python this is a comment and the convention is actually to use a complete sentence like with a capital t here you don't need a period unless there's multiple sentences and technically it should be above the line of code by convention so you would use a hash symbol instead good question haven't seen those yet all right let's go ahead and make something else here how about let me go ahead and open up for instance an example called points1.c which we saw a few weeks back and let me go ahead on the other side and create a file called points.pi this was a program recall that asked the user how many points they lost on the first assignment and then it went ahead and just printed out whether they lost fewer points than me because i lost two if you recall the photo more points than me or the same points as me let me go ahead and zoom out so we can see a bit more of this and let me now on the top right here go about implementing this in python so i want to first prompt the user for some number of points so from cs50 let's import get in so it handles the error checking let's then do points equals getint and ask the user how many points did you lose question mark then let's go ahead and say if points less than 2 which was my value print you lost fewer points than me otherwise if it's else if points greater than 2 go ahead and print you lost more points than me else let's go ahead and handle the final scenario which is you lost the same number of points as me before i run this does anyone want to point out a mistake i've already made yeah yeah so else if in c is actually now l if in python it's a single word so let me change this to l if and now cross my fingers python of points.pi suppose you lost three points on some assignment you lost more points than my two if you only lost one point you lost fewer points than me so the logic is the same but notice the code is much tighter in 10 total lines we did in what was 24 lines because we've thrown away a lot of the syntax the curly braces are no longer necessary the parentheses are gone the semicolons so this is why it just tends to be more pleasant pretty quickly using a language like this all right let's do one other example here in c recall that we were able to determine the parity of some number if something is even or odd well in python let me go ahead and create a file called parity.pi and let's look for a moment at the c version at left here was the code in c that we used to determine the parity of a number and really the key takeaway from all these lines was just the remainder operator and that one is still with us so this is a simple demonstration just to make that point if in python i want to determine whether a number is even or odd well let's go ahead and from cs50 import getint then let's go ahead and get a number like n from the user using getint and ask them for n and then let's go ahead and say if n percent sign two equals zero then let's go ahead and print quote unquote even else let's go ahead and print out odd but before i run this anyone want to instinctively even though we've not talked about this point out a mistake here what did i do wrong yeah so double equals again so even though some of the stuff is changing some of the same ideas are the same so this two should be a double equal sign because i'm comparing for equality here and why is this the right math well if you divide a number by 2 it's either going to have 0 or 1 as a remainder and that's going to determine if it's even or odd for us so let's run python of parity dot pi type in a number like 50 and hopefully we get indeed even so again same idea but now we're down to eight lines of code instead of the 20. well let's now do something a little more interactive and a little representative of tools that actually ask the user questions in c recall that we had this agreement program agree dot c and then let's go ahead and implement a corresponding version in python in a file called a degree dot pi and let's look at the c version first on the left we used get char here and then we use the double vertical bars to check if c is equal to capital y or lower case y and then we did the same thing for n for no and so let's go over here and let's do from cs50 import get okay get char is not a thing and this here is another difference with python there is no data type for individual characters you have strings stirs and honestly those are fine because if you have a stir that's just one character for all intents and purposes it is just a single character so it's just a simplification you don't have to think as much you don't have to worry about double quotes single quotes in fact in python you can use double quotes or single quotes so long as you're consistent so long as you're consistent the single quotes do not mean something different like they do in c so i'm going to go ahead and use get string here although strictly speaking i could just use the input function as we saw before i'm going to get a string from the user that asks them this uh getstring quote unquote do you agree like a little checkbox or interactive prompt where you have to say yes or no you want to agree to the following terms or whatnot and then let's translate the conditionals to python now too so if s equals equals quote unquote y or s equals equals lowercase y let's go ahead and print out agreed just like in c l if s equals equals n or s equals equals little n let's go ahead then and print out not agreed and you can already see perhaps one of the differences here too is python a little more english-like in that you just literally use the english word or instead of the two vertical bars but it's ultimately doing the same thing can we simplify this code a bit though this would be a little annoying if we wanted to add support not just for big y and little y but yes or big yes or little yes or big y lower case e capital s right there's a lot of permutations of y e s or just y that we ideally should tolerate otherwise the user has gonna have to type exactly what we want which isn't very user friendly any intuition for how we could logically even if you don't know how to do it in code make this better yeah nice yeah we saw an example of a list before just 0 1 2. why don't we take that same idea and ask a similar question if s is in the following list of values y or little y or heck let me add to the list now yes or maybe all capital yes and it's going to get a little annoying admittedly but this is still better than the alternative with all the ors i could do things like this and so forth there's a whole bunch more permutations but let's leave this alone and let me just go into here and change this to if s is in the following list of n or little n or no and i won't do is let's just not worry about the weird capitalizations there for now let's go ahead and run this python of agree.pie do i agree why okay how about yes all right how about big yes okay that does not seem to work notice it did not say agreed and it did not say not agreed it didn't detect it so how can i do this well you know what i could do what i don't really need the uppercase and lowercase let me tighten this list up a little bit and why don't i just force s to be lowercase s dot lower recall whether it's one character or more is a function built into stirs now strings in python that forces the whole thing to lower case so now watch what i can do python of agree.pi little y that works big y that works big yes that works big y little e big s that also works so we've now handled in one fell swoop a whole bunch more logic and you know what we can tighten this up a bit here's an opportunity in python for slightly better design what have i done in here that's a little redundant does anyone see an opportunity to eliminate a redundancy doing something more than times than you need is a stretcher no yep we could move the s dot lower above notice that i'm using s dot lower twice but it's going to give me the same answer both times so i could do a couple of things here i could first of all get rid of this lower and get rid of this lower and then above this maybe i could do something like this s equal i can't just do this because that throws the value away it does the math but it doesn't convert the string itself it's going to return a value so i have to say s equals s dot lower i could do that or honestly i can chain these things together and this is not something we saw in c if get string returns a string and strings have functions like lower in them you can chain these functions together like this and do dot this dot that dot this other thing and eventually you want to stop because it's going to become crazy long but this is reasonable still fits on the screen it's pretty tight it does in one place what i was doing in two so i think that's okay let me go ahead and do python of agree.pi one last time let's try it one last time and it's still working as intended if also if i tried those other inputs as well yeah question um [Music] let me summarize could we could we handle uppercase and lowercase together in some form i'm actually doing that already i just have to pick a lane i have to either be all lowercase in my logic or all uppercase and not worry about what the human type's in because no matter what the human types in i'm forcing their input to lowercase and then i am using a lowercase list of values if i want to flip that fine i just have to be self-consistent but i'm handling that already yeah a really good loaded question are strings no longer an array of characters conceptually yes underneath the hood no they're a little more sophisticated than that because with strings you have a few changes not only do they have functions built into them because strings are now what we call objects in what's called object programming and we're going to keep seeing examples of this dot operator they're also immutable so to speak i-m-m-u-t-a-b-l-e immutable means they cannot be changed which means unlike c you can't go into a string and change its individual characters you can make a copy of the string that makes a change but you can't change the original string itself this is both a little annoying maybe sometimes but it's also pretty protective because you can't do screw ups like i did weeks ago when i was trying to copy s and call it t and then one affected the other python underneath the hood is handling all of the memory management and the pointers and all of that there are no pointers in pythons if that wasn't clear all of that pain if you will all of that power is now handled by the language itself not by us the programmers all right so let's introduce maybe some loops like we've been uh in the habit of doing let me open up meow.c which was an example in c just meowing a bunch of times textually let me create a file called meow.pi here on the right and notice on the left this was correct code in c but it was kind of poorly designed why because it was a missed opportunity for a loop why say something three times when you can say it just once so in python let me do it the poorly designed way first let me print out meow and like i generally should not let me copy paste it three times run python of meow.pie and it works okay but not good practice so let me go ahead and improve this a little bit and there's a few ways to do this if i wanted to do this three times i could instead do something like this for i in range of three recall that that was the better version rather than arbitrarily enumerate numbers yourself let me go ahead and print out quote unquote meow now if i run python of meow still seems to work so it's a little tighter in my god like programs can't really get much shorter than this we're down to two lines of code no main function no gratuitous syntax let's now improve the design further like we did in c by introducing a function called meow that actually does the meowing so this was our first abstraction recall both in scratch and in c let me focus now entirely on the python version here let me go ahead and first uh define a function [Music] let me first go ahead and do this for i in range of three let's assume for the moment that there's a meow function that i'm just going to call let's now go ahead and define using the def keyword which we saw briefly with the speller demonstration a function called meow that takes no arguments and all it does for now is print meow let me now go ahead and run python of meow.pie enter one of those tracebacks so this is another name error and again name meow is not defined what's your instinct here even though we've not tripped over this yet in python where does your mind go here yeah perfect as smart as as smarter as python seems to be it also it still makes certain assumptions and if it hasn't seen a keyword yet it just doesn't exist so if you want it to exist we have to be a little clever here i could just put it flip it around like this but this honestly isn't particularly good design why because now if you the reader of your code whether you wrote it or someone else you kind of have to go fishing now like where does this program begin and even though yes it's obviously that it begins on line four logically like if the file were longer you're going to be annoyed in phishing visually for the right lines of code so let's reintroduce main and indeed this would be a common paradigm when you want to start having abstractions and your own functions just put your own code in main so that one you can leave it up top and two you can solve the problem we just encountered so let me define a function called main that has that same loop meowing three times but now watch what happens let me go into my terminal and run python of meow.pi enter nothing all right investigate this what could explain this symptom i have not told you the answer yet so all you have is your instinct assuming you've never touched python before what might explain this symptom where nothing is meowing yeah yeah i didn't run the main function so in c this is functionality you get for free you have to have a main function but heck so long as you make it it will be called for you in python this is just a convention to create a main function borrowing a very common name for it but if you want to call that main function you have to do it so this looks a little weird admittedly that you have to call your own main function now and it has to be at the bottom of the file because only once the interpreter gets to the bottom of the file have all of your functions been defined higher up but this solves both problems it keeps your code that's the main part of your code at the very top of the file so it's just obvious to you and a tf or any reader in the future where the programs logically starts but it also ensures that maine is not called until everything else made included has been defined so this is another perfect example of we're learning a new language for the first time you're not going to have heard all the answers before just apply some logic as to like all right what could explain this symptom start to infer how the language does or doesn't work if i now go and run this python of meow.pie now we're back in business and just so you have seen it there is a quote-unquote better way of doing this that solves different problems that we are not going to encounter certainly in these initial days typically you would see in online tutorials or books something that looks like this where you actually have a weird conditional with multiple underscores that's functionally the same thing but it solves problems with libraries if we ourselves were implementing a library or something similar in spirit but we're going to keep things simpler and just write main at the bottom because we're not going to encounter that problem just yet all right let's make one change to this just to show how it's done in c the last version of meow also took command line argume sorry also took arguments to the function meow so suppose that i want to factor this out and i want to just call meow as a better abstraction where i just say meow this number of times and i figure out how many times by just like putting in number three or using getint or something like that to figure out how many times to say meow well now i have to define inside my meow function in input let's call it n and then use that as by doing this for i in range of n let me go ahead and print out meow that many times so again the only thing that's different in c is we don't bother specifying return types for any of these functions and we don't bother specifying the type of our arguments or our variables so same ideas simpler in some sense we're just throwing away keystrokes all right let me run this one final time python of meow.pi and we still have the same program all right let me pause here any questions and i know this is going fast but hopefully the c code is still somewhat familiar good question is there any difference between global and local variables short answer yes and we would run into that same problem if we declare a variable in one function another function is not going to have access to it we can solve that by putting variables globally but we don't have all of the features we had in c like there's no such thing as a constant in python the mentality in the python community is if you don't want some value to change don't touch it like just don't screw up so there's trade-offs here too some languages are stronger or more defensive than that but that too is part of the mindset with this particular language yeah oh sorry where's say a ladder that is an amazing segue let's come to that in just a moment because we're going to recreate also that mario example where we had like the um question marks for the coins and the vertical bars so let's come back to that in a second and your question correct strings are immutable anytime you seem to be modifying it as with the lower function you're getting back a copy so it's taking a little more memory somewhere but you don't have to deal with it python's doing that for you say it again you don't need what you don't free anything so if you weren't a big fan over the past couple of weeks of malloc or free or memory or addresses or all of those low-level implementation details python is the language for you because all of that is handled for you automatically java does the same javascript does the same yeah how do you define a global variable if there's no main function in python global variables by definition always need to be outside of main as well so that's not a problem if i wanted to have a function that's outside of and therefore global to all of these like global actually don't use the word global that's a special word in python uh variable equals uh foo f-o-o just as an arbitrary string value that a computer scientist would typically use um that is now global there are some caveats though as to how you access that but let's come back to that another time but that problem is solvable too all right so let's go ahead and do this to come back to the question about the print command let me go ahead and create a file now called mario dot pi won't bother showing the c code anymore we'll focus just on the new language here but recall that in python in mario we wanted to first do something like this this was a random screen from the side scroller version one of super mario brothers and we just want to print like three hashes to represent those three blocks well in python we could do something like this print oh sorry for i in the range of three go ahead and print out quote-unquote hash and i think this is pretty straightforward python of mario dot pi we get our three hashes you could imagine parameterizing this now though and getting actual user inputs so let's do that let me go up here and let me go and say from cs50 import getint and then let's get the input from the user so it actually is a value n like all right get int uh the height of the column of bricks that you want to do and then let's go ahead and print out n hashes instead of three so let me run this let's print out like five hashes okay one two three four five that seems to work too and it's gonna work for any positive value but it's not gonna work for how about negative one that just doesn't do anything but that seems okay but also recall that it's not going to work if the user types in something weird like oh sorry it is going to work if the user types in something weird like cat why we're using cs50s get in function which is handling all of those headaches for us but what if the user indeed types a negative number were tolerating that so that was the bug i wanted to highlight it would be nice to re-prompt them and re-prompt them and in c what was the programming construct we used when we wanted to ask the user a question and then if they didn't cooperate prompt them again prompt them again what was that yeah yeah do while loop right that was useful because it's almost the same as a while loop but instead of checking a condition and then doing something you do something and then check a condition which makes sense with user input because what are you even going to check if the user hasn't done anything yet you need that inverted logic unfortunately in python there is no do while loop there is a for loop there is a while loop and frankly those are enough to recreate this idea and the way to do this in python the pythonic way which is another term of art in the community is to say this deliberately induce an infinite loop while true with capital t for true and then do what you got to do like get an int from a user asking them for the height of this thing and then if that is what you want like a number greater than zero go ahead and break out of the loop so this is how in python you could recreate the idea of a do while loop you deliberately induce an infinite loop so something's going to happen at least once then if you get the answer you want you break out of it effectively achieving the same logic so this is the pythonic way of doing a do while loop let me go ahead and run python of mario.pi type in three this time and now i get back just the three hashes as well what if though i wanted to get rid of uh how about ultimately that cs50 library function and also encapsulate this in a function well let's go ahead and tweak this a little bit let me go ahead and remove this temporarily give myself a main function so i don't make the same mistake as i did initially earlier and let me give myself a function called get height that takes no arguments and inside of that function is going to be that same code but i don't want to break in this case i want to return n so recall that if you return from a function you're done you're going to exit from right that point so this would be fine you can just say return n inside of the loop or if you would prefer to break out you could do something like this instead break and then down here you could return down here you could return n as well and let me make one point here before we go back up to main this is a little different from c and this one's subtle what have i done here that in c would have been a bug but is apparently not i claim in python it's super subtle this one yeah he so similar it's not quite that we're using it for so it's okay not to declare a variable with like the data type we've addressed that before but on line nine we're assigning and a value it seems and then we return n on line 12 but notice the indentation in the world of c if we had declared a variable inside of a loop on line 9 it would have been scoped to that loop which means as soon as you get out of that loop like further down in the program n would not exist it would be local to the curly braces they're in here logically curly braces are gone but the indentation makes clear that n is still inside of this loop between lines 8 through 11 but n is actually still in scope in python the moment you create a variable in python for better or for worse it is available everywhere within that function even outside of the loop in which you defined it so this logic is actually okay in python in c recall to solve this same problem we would have had to do something a little hackish like this like define n up here on line 8 so that it exists now on line 10 and so that it exists on line 13 that is no longer an issue or need in python once you create a variable even if it's nested nested nested inside of some loops or conditionals it still exists within the function itself all right any questions then on on this before we now run this and then get rid of the cs50 library again okay so let me go ahead and get the height from the user let's go ahead and create a variable in main called height let's call this get height function and then let's use that height value instead of something hard coded there and let me see if this all works now python of morrow.pi hopefully i haven't messed up but i did but this is an easy fix now yeah i gotta call main so again i deleted that earlier but let me bring it back so i'm actually calling main let me rerun uh python of mario.pi there we go height three now it seems to be working so let's do one last thing with mario just to tie together that idea now of exceptions from before again exceptions are a feature of python whereby you can try to do something and if there's a problem you can handle it in any way you see fit previously i handled it by just yelling at the user that that's not an int but let's actually use this to re-implement cs50's own getint function let me throw away cs50's get in function and now let me go ahead and replace uh getint with input but it's not sufficient to just use input what do i have to add to this line of code on line eight if i want to get back an int yeah i have to cast it to an end by calling the int function around that value or i could do it on a separate line just to be clear i could also do n equals int of n that would work too but it's sort of an unnecessary extra line this is not sufficient because that does not change the value it creates the value but then it throws it away we need to assign it so the conventional way to do this would probably be in one line just to keep things nice and tight so that works fine now if i run python of mario.pi i can still type in three and all is well i can still type in negative one because that is an int that i am handling what i'm not yet handling is weird input like cat or some string that is not a base 10 number so here again is my traceback and notice that here let me scroll up a little bit here we can actually see more detail in the traceback notice that just like in c or just like in the debugger in vs code you can see a few things you can see mention of module that just means your file main which is my main function and get height so notice it's kind of backwards it's top to bottom instead of bottom up as we drew it on the board the other day and as we envisioned stacks of trays in the cafeteria but this is your stack of functions that have been called from top to bottom get height is the most recent main is the very first value error is the problem so let's try to do let's try to do this literally except if there's an error so what do i want to do i'm going to go in here and i'm going to say try to do the following whoops try to do the following except if there's a value error value error then go ahead and say something like well like before print that's not an integer exclamation point but the difference this time is because i'm in a loop the user is going to have a chance to recover from this issue so if i run mario.pi 3 still works as before if i run my dot pi and type in cat i detect it now and because i'm still in that loop and because the program hasn't crashed because i've caught so to speak the value error using this line of code here that's the way in python to detect these kinds of errors that would otherwise end up being on the user's own screen if i type in cat dog that doesn't work if i type in though two i get my two hashes because that's indeed an int any questions on this and we're not going to spend too much time on exceptions but just wanted to show you what's involved with getting rid of those training wheels yeah okay so let's do this that actually comes to the earlier question about printing the hashes on the same line or maybe something like this where we have little bricks in the sky or little question marks let's recreate this idea because the problem with print as was noted earlier is you're automatically printing out new lines but what if we don't want that well let's change this program entirely let me throw away all the functions let's just go to a simpler world where we're just doing this so let me start fresh and marrow it up hi i'm not going to bother with exceptions or functions let's just do a very simple program to create this idea four i in range of four this time because there are four of these things in the sky let's go ahead and just print out a question mark to represent each of those bricks odds are you know this is not going to end well because these are unfortunately as you've predicted on separate lines so it turns out that the print function actually takes in multiple arguments not just the thing you want to print but also some additional arguments that allow you to specify what the default line ending should be but what's interesting about this is that if you want to change the line ending to be something like quote unquote that is nothing instead of backslash n this is not sufficient because in python you can have two types of arguments or parameters some arguments are positional which is the fancy way of saying it's a comma separated list of arguments and that's what we did all the time in c something comma something comma something we did it in printf all the time and then other functions that took multiple arguments in python you have not only positional arguments where you just separate them by commas to give one or two or three or more arguments there are also named arguments which looks weird but is helpful for reasons like this if you read the documentation you will see that there is a named argument that python accepts called end and if you set that equal to something that will be used as the end of every line instead of the default which the documentation will also say is quote unquote backslash n so this line here has no effect on my logic at the moment but if i change it to just quote unquote essentially overriding the default new line character and now run mario again now i get all four on the same line there's a bit of a bug though my prompt is not meant to be on the same line so i can fix that by just printing nothing but really it's not nothing because you get the new line for free so let me run python of mario.pi again and now we have what i intended in the first place which was a little something that looked like this and this is just one example of an argument that has a name but this is a common paradigm in python 2 to not just separate things by commas but to be very specific because the print function might take 5 10 even 20 different arguments and my god if you had a enumerate like 10 or 20 commas you're going to screw up you're going to get things in the wrong order named arguments allow you to be resilient against that so you only specify arguments by name and it doesn't matter what order they are in are any questions then on on this and the overriding of new line and to be clear you can do something like very weird but logically expected like this by just changing the line ending too but the right way to solve the mario problem would be just override it to be nothing like this all right how about this for cool and this is why a lot of people like python suppose you don't really like loops you don't really like three line programs because that was kind of three times longer than it needs to be what if you just printed out a question mark four times python whoops python of mario.pi that also works so it turns out that just like the plus operator in python can join things together the multiply operator is not arithmetic in this case it actually means take this and do the concatenate it four times over so that's a way of just distilling into one line what would have otherwise taken multiple lines in c fewer but still multiple lines in python but is really now rather succinct in python by doing that instead let's do one last mario example which looked a little something like this if this is another part of the mario interface uh this is like a grid of like three by three bricks for instance so two dimensions now just not just vertical not horizontal but now both let's print out something like that using hashes well how about how do i do this so how about for i in range of three then i could do for j in range of three just because j comes after i and that's reasonable for counting i could now print out a hash symbol uh well let's see what this does python of mario.pi okay that's just one crazy long column what's what do i need to fix and wear here to make this look like this so three by three bricks instead of one long column any instincts okay so after printing three we want to skip a line so maybe like print out a blank line here okay let's try that i like that instinct right print three new line print three new line let's go ahead and run python of mario.pi okay it's more visible what i'm doing but still wrong what can i what's the remaining fix though yeah i'm getting an extra new line here which i don't want while i'm on this row so let me do end equals quote unquote and now together your solutions might take us the whole way there mario uh python of mario.i voila now we've got it in two dimensions and even this we can tighten up like we could just use the little trick we learned so we could just say print a hash times three times and we can get rid of one of those loops all together all it's doing is autumn oops all it's doing is automating that process but no i don't want to do that what do i how do i fix this here oh i don't think i want this anymore right because that's giving me an extra new line so now this program is really tightened up same thing two lines of code but we're now implementing this same two-dimensional structure here all right any questions here on these yeah say that once more oh um oh yes good question i see what you're saying so in a previous version let me rewind in time when we had this i did not put spaces the convention in python is not to do that why it just starts to add too much space and this is a little inconsistent because earlier when we talked about like pluses or spaces around the less than or equal signs i did say added here it's actually clear and recommended to keep them tighter together otherwise it just becomes harder to read where the gaps are good observation all right let's do how about um another five minute break let's do that and then we're going to dive into some more sophisticated problems and then ultimately build with some audio and visual examples as well see you in five all right so almost all of the examples we just did were recreations of what we did in week one and recall that week one was like our most syntax heavy week it was when we were first learning how to program in c but after week one we began to focus a bit more on ideas like arrays and other higher level constructs and we'll do that again here condensing some of those first early weeks into a fewer set of examples in python and will culminate by actually taking python out for a spin and doing things that would be way harder to do and way more time consuming to do in c um even more so than the speller example but how do you go about figuring out like what functions exist if you didn't hear it in class you don't see it online but you want to see it officially you can go to the python documentation docs.python.org here and i will disclaim that honestly the python documentation is not terribly user friendly google will often be your friend so googling something you're interested in to find your way to the appropriate page on python.org or stackoverflow.com is another popular website as always though the line should be googling things like how do i convert a string to lowercase like that's reasonable to google or how to convert to uppercase or how implement function in python but googling of course things like how to implement problem set 6 in cs50 of course crosses the line but moving forward and really with programming in general like google and stack overflow are your friends but the line is between the reasonable and the unreasonable so let me officially use the python documentation search just to search for something like the lowercase function like i know i can lowercase things in python i don't quite remember how so let me just search for the word lower you're going to get often an overwhelming number of results because python is a pretty big language with lots of functionality and you're going to want to look for familiar patterns for whatever reason string dot lower which is probably more popular or more commonly used than these other ones is third on the list but it's purple because i clicked it a moment ago when looking for it so stir dot lower is probably what i want because i am interested at the moment in lower casing strings when i click on that this is an example of what python's documentation tends to look like it's in this general format here's my stir dot lower function this returns a copy of the string with all the case characters converted to lower case and the lower casing algorithm dot dot dot so that doesn't give me much it doesn't give me sample code but it does say what the function does and if we keep looking you'll see mention of l strip which is left strip i used its analog r strip before right strip which allows you to remove that is stripped from the end of a string something like white space like a new line or even something else and if you scroll through string this web page here and we're halfway down the page already if you see my scroll bar tiny on the right there's a huge amount of functionality built into string objects here and this is just testament to just how rich the language itself is but it's also reason to uh to reassure that the goal when playing around with some new language and learning it is not to learn it exhaustively just like in english or in a human language there's always going to be vocab words you don't know ways of presenting the same information in some language that's going to be the case with python and what we'll do today and this week in problem set six is really get your footing with this language but you won't know all of python just like you won't know all of c and honestly you won't know all of any of these languages on your own unless you're perhaps using them full time professionally and even then there's more libraries than one might even retain themselves so let's actually now pivot to a few other ideas that we'll implement in python in a moment let me switch back over to vs code here and let me whip up say a recreation of our scores example from week two where we average like three scores together and that was an opportunity in week two to play with arrays to realize how constrained arrays are they can't grow or shrink you have to decide in advance but let's see what's different here in python so let me do scores.pi and let me give myself an array in python called scores sorry let me give myself a variable in python called scores set it equal to a list of three scores which are the same ones we've used before 72 73 33 in this context meant to be scores not ascii values and then let's just do the average of these so average will be another variable and it turns out i can do well how did i sum these before i probably had a for loop to add one then i knew how long there were turns out in python you can just say sum of scores divided by the length of scores that's going to give me my average so sum is a function that takes a list in this case as input and it just does the sum for you with a for loop or whatever underneath the hood lang gives you the length of the list how many things are in it so i can dynamically figure that out now let me go ahead and print out using print the word average and then in curly braces the actual average close quote all right so let's run this code python of scores.pi and there's my average in this case 59.33333 and so forth based on the math well let's actually now change this a little bit and make it a little more interesting and actually get input from the user rather than hard coding this let me go back up here and use from cs50 import get in because i don't want to deal with all the exceptions and the loops like i just want to use someone else's function here let me give myself an empty list called scores and this is not something we were able to do in c right because in c if you tried to make an empty array well that's pretty stupid because you can't add things to it it's a fixed size so it wouldn't even let you do that but i can just create an empty list in python because lists unlike arrays are really linked list they'll grow and shrink but you and i are not dealing with all the pointers underneath the hood python's doing that for us so now let's go ahead and get a whole bunch of scores from the user how about three of them in total so four i in range of three let's go ahead and grab a score from the user using getint asking them for score and then let's go ahead and append to the scores uh list that particular score so it turns out that a list and i could read the python documentation to confirm as much lists have a function built into them and functions built into objects are generally known as methods if you've heard that term before same idea but whereas a function kind of stands on its own a method is a function built into an object like a list here that's going to achieve the same result strictly speaking i don't need the variable just and i can see i could tighten this up and do something like this as well but i don't know i kind of like it this way it's more clear to me at least that what i'm doing here getting the score and then appending it to the list now the rest of the code can stay the same python of scores.pie score will be 72 73 33 and i get back the math but now the program's a little more dynamic which is nice but there's other syntax i could use here just so you've seen it python does have some neat syntactic tricks whereby if you don't want to do scores.append you can actually say scores plus equals this score so you can actually concatenate lists together in python 2. just as we used plus to join two strings together you can use plus to join two lists together the catch is you need to put the one score i'm adding here in a list of its own which is kind of silly but it's necessary so that this thing and this thing are both lists to do this more verbosely which most programmers wouldn't do but just for clarity this is the same thing as saying scores plus this score so now maybe it's a little more clear that scores and bracket score plural sorry singular are both lists themselves being concatenated or joined together so two different ways not sure one is better than the other this way is pretty common but dot append is also quite reasonable as well all right how about another example from week two this one was called uh upper case so let me do this in uppercase.pi though this time and let me import from cs50 getstring again and let me go ahead and say before will be my first variable let me get a string from the user asking them for a before string and then let me go ahead and say after just to demonstrate some changes uppercasing to this string let me change my line ending to be that using our new trick and this is where things get cool in python relatively speaking if i want to iterate over all of the characters in a string and print them out in uppercase one way to do that would be this for c in the before string go ahead and print out c dot uppercase sorry c dot upper but don't end the line yet because i want to keep these all on the same line until i'm all done so what am i doing python of uppercase.pi let me type in hello in all lowercase i've just uppercased the whole string how i first get string calling it before i then just print out some fluffy text that says after colon and i get rid of the line ending just so i can kind of line these up notice i hit the spacebar a couple times just so letters line up to be pretty for c and b4 this is new this is powerful in c i'm sorry in python whereby you don't have to do like in i equals zero and i less than this you could just say for c in the string in question for c and before and then here is just uppercasing that specific character and making sure we don't put a new line too soon but this is actually more work than i need to do based on what we've seen thus far like from our agreement example can i tighten this up further can i collapse lines five and six maybe even seven altogether if i the goal of this program is just to uppercase the before string how might i do this yeah in back stir dot upper yeah so i could do something like this after gets before dot upper so it's not stir literally dot upper stir just represents the string in question so it would be before.upper but right idea otherwise and so let me go ahead and just tweak my print statement a little bit let me just go ahead and print out the after variable here after creating it so this line is the same i'm getting a string called before i'm creating another variable called after and as you propose i'm calling upper on the whole string not one character at a time why because it's allowed and again in python there aren't technically characters individually there's only strings anyway so i might as well do them all at once so if i rerun the code now python of uppercase.pi now i'll type in hello in all lowercase and oh so close i think i can get rid of this override because i'm printing the whole thing out at once not character by character so now if i type in hello before now i have an even tighter version of the program here alright any questions then on lists or on strings and what this kind of function upper represents with its docks all right so couple other building blocks before we start oh where was that to the right the right right yes thank you yes do i have to create this variable upper no i don't i could actually tighten this up and if you really want to see something neat inside of the curly braces you don't have to just put the names of variables you can put a small amount of logic so long as it doesn't start to look stupid and kind of overwhelmingly complex such that it's sort of bad design at that point i can tighten this up like this and now run python of uppercase.pi writing hello again and that too worked but i would be careful about this you want to resist the temptation of having like a long line of code that's inside the curly braces because it's just going to be harder to read but absolutely you could indeed do that too all right how about uh command line arguments which was one thing we introduced in week two also so that we could actually have the ability to take input from the user whoops so we could actually take input from the user at the command line so as to take literally command line arguments these are a little different but it follows the same paradigm there's no main by default and there's no def main int argc char or we called it string arg v by default there's none of this so if you want access to the argument vector r v you import it and it turns out there's another module in python or library in python called sys and you can import from the system this thing called argv so same idea different place now i'm going to go ahead and do this let's write a program that just requires that the user types in to a word after the program's name or none at all so if the length of arg v equals two let's go ahead and print out how about hello comma argv bracket one close quote else if they don't type two words total at the prompt let's just say the default like we did weeks ago hello world so the only thing that's new here is we're importing rgb from sys and we're using this fancy f string format which kind of to your point too it's it's putting more complex logic in the curly braces but that's okay this in this case it's a list called argv and we're getting bracket one from it let's do python of argv dot pi enter hello world what if i do argv dot pi david at the command line now i get hello david so there's one curiosity here python is not included in argv whereas in c dot slash whatever was the first thing if the analog in python is that the name of your python program is the first thing in bracket zero which is why david is in bracket one the word python does not appear in the rv list just to be clear but otherwise the idea of these arguments is exactly the same as before and in fact what you can do which is kind of cool is because argv is a list you can do things like this for arg in argv go ahead and print out each argument so instead of using a for loop and i and all of this if i do python of argv enter it just writes the program's name if i do python of argv foo it puts rgv dot pi and foo if i do sorry if i do foo and bar those words all print out if i do fubar bads those print out too and foo and bar baz are like a mathematicians x and y and z for computer scientists when you just need uh some placeholder words so this is just nice it reads a little more like english and a for loop is just much more concise allows you to iterate very quickly when you want something like that suppose i only wanted the real words that the human typed after the program's name like suppose i want to ignore rgv.pi i mean i could do something hackish like this if arg equals dot pi i could just ignore you know let's invert the logic i could do this for instance so if the arg does not equal the program name then go ahead and print out the word so i get fubar and baz only or this is what's kind of neat about python 2. let me undo that and let me just take a slice of the array of the list instead so it turns out if rb is a list i can actually say you know what go into that list start at element one instead of zero and then go all the way to the end and we have not seen the syntax in c but this is a way of slicing a list in python so now watch what happens if i run python of rv dot pi enter i get only a subset of the list starting at position one going all the way to the end and you can even do kind of the opposite if for whatever reason you want to ignore the last element you can say colon we could say colon negative one and use a negative number which we've not seen before which slices off the end of the list as well so there's some syntactic tricks that tend to be powerful in python two even if at first glance you might not need them for typical things all right let's do one other example with exit and then we'll start actually applying some algorithms to make things interesting so in one last program here let's do exit.pi just to do one more mechanic before we introduce some algorithms and let's do this let's import from sys import rgv let's now do this let's make sure the user gives me one command line argument so if the length of argv does not equal 2 in total then let's go ahead and print out something like missing command line argument just to explain what the problem is and then let's do this we can exit but i'm going to use a better version of exit here let me import two functions from sys turns out the better way to do this is with sys.exit because i can then exit specifically too with us exit code otherwise down here i'm going to go ahead and print out something like uh hello comma rv bracket one same as before and then i'm going to exit with zero so again this was a subtle thing we introduced in week two where you can actually have your programs exit with some number where zero signifies success and anything else signifies error this is just the same idea in python so if i for instance just run the program like this oops i screwed up i meant to say exit here and exit here let me do that again if i run this like this i'm missing a command line argument so let me rerun it with like my name at the prompt so i have exactly two command line arguments the file name and my name hello comma david and if i do david malen it's not going to work either because now rgb does not equal two but the difference here is that we're exiting with one so that special programs can detect an error or zero in the event of success and now there's one other way to do this too suppose that you're importing a lot of functions and you don't really want to make a mess of things and just have all of these function names available without it being clear where they came from let's just import all of cis and let's just change our syntax kind of like i proposed for cs50 where we just prepend to all of these library functions cis just to be super explicit where they came from and if there's another uh exit or um rv value that we want to import from a library this is one way to avoid collision so if i do it one last time here missing command line argument but david still actually works all right only to demonstrate how we can implement that same idea let's now do something more powerful like a search algorithm like binary search i'm going to go ahead and open up a file called numbers.pi and let's just do some searching or linear search rather on a list of numbers let's go ahead and do this how about import cis as before let me give myself a list of numbers like four six eight two seven five zero so just a bunch of integers and then let's do this if you recall from week three we searched for the number zero at the end of the lockers on stage so let's just ask that question in python no need for a loop or anything like that if zero is in the numbers go ahead and print out found and then let's just exit successfully with zero else if we get down here let's just say print not found and then we'll sys then we'll sys exit with one so this is where python starts to get powerful again here's your list here is your loop that's doing all of the checking for you underneath the hood python is going to use linear search you don't have to implement it yourself no while loop no for loop you just ask a question if zero is in numbers then do the following so that's one feature we now get with python and get to throw away a lot of that code we can do it with strings too let me open a file called names.pi instead and do something that was even more involved in c because we needed stir comp and the for loop and so forth let me import cis for this file let's give myself a bunch of names like we did in c and those were bill and charlie and fred and george and ginny and two more percy and lastly ron and recall at the time we looked for ron and so we had to iterate through the whole thing doing stir comp and i plus plus and all of that now just ask the question if ron is uh in names then let's go ahead and whoops let me hide that i hit the command too soon let me go ahead and say print found as before cis exit 1 just to indicate success and then down here if we get to this point we can say not found and then we'll just sys exit one instead so again this just does linear search for us by default uh python of names.pie we found ron because indeed he's there and at the end of the list but we don't need to deal with all of the mechanics of it all right let's take things one step further in week three we also implemented the idea of a phone book that actually associated keys with values but remember the phone book in c was kind of a hack right because we first had two arrays one with names one with numbers then we introduced structs and so we gave you a person structure and then we had array of we had an array of persons you can do this in python using objects and things called classes but we can also just use a general purpose dictionary because just like in pset five you can associate keys with values using a hash table using a try well similarly can python just do this for us from cs50 let's import get string and now let's give myself a dictionary of people d-i-c-t open paren closed print gives you a dictionary or you can simplify the syntax actually and a dictionary again is just keys and values words and definitions you can also just use curly braces instead that gives me an empty dictionary but if i know what i want to put in it by default let's put carter in there with a number of plus 1 617 495 1000 just like last time and put myself david with plus one nine four nine uh four six eight two seven five oh and it came to my attention tragically after class that day that we had a bug in our little easter egg if today you would like to call me or text me at that number we have fixed the code that underlies that little easter egg spoiler ahead all right so this now gives me a variable called people that's associating keys with values there is some new syntax here in python not just the curly braces but the colons and the quotes on the left and the right this is a way in python of associating keys with values words with definitions anything with anything else and it's going to be a super common paradigm including in week 7 when we look at css and html and web programming keys and values are like this omnipresent idea in computer science and programming because it's just a really useful way of associating one thing with another so at this point in the story we have a dictionary a hash table if you will of people associating names with phone numbers just like a real world phone book let's write a program that gets a string from the user and asks them whose number they would like to look up then let's go ahead and say if that name is in the people dictionary go ahead and print out that person's number by going into the people dictionary and going to that specific name within there using an f string for the whole thing so this is similar to in spirit to before linear search and dictionary lookups will just happen automatically for you in python by just asking the question if name and people and this line's just going to print out whoever is in the people dictionary at that name so i'm using square brackets because here's the interesting thing in python just like you can index into an array or a list in python using numbers 0 1 2 you can very conveniently index into a dictionary in python using square brackets as well and just to make clear what's going on here let me go and create a temporary variable person equals people bracket name and then let's just sorry let's say number equals people bracket name and let's just print out the number in question in c and previously in python anything with square brackets like this would have been go to a location in a list or an array using a number but that can actually be a string like a word the human is typed and this is what's amazing about dictionaries it's not like a big line of a big linear thing it's this table that you can look up in one column the name and get back in the other column the number so let's go ahead and run python of phonebook.pi found not that oh wait [Music] that's not what's supposed to happen at all i think i'm in the wrong place what's going on print found i am confused okay let's run this again pythonphonebook.pi what the okay stand by uh-huh what the heck what am i not understanding here okay wrong shin carter do you see what i'm doing wrong what the say again oh what yeah uh i found okay we're gonna do this one sec whoa okay um all this is coming out of the video um so thanks all right i will try to figure out what was going wrong the best i can tell it was running the wrong program i don't quite understand why so we will diagnose this later i just put the file into a temporary directory for now to run it so let me go ahead and just run this python of phonebook.pi type in for instance my name and there's my corresponding number i have no idea what was just happening but i will get to the bottom of it and update you if we can put our finger on it so this was just an example now of implementing a phone book let's now consider what we can do that's a little more powerful in these examples like a phone book that actually keeps this information around thus far these simple phone book examples throw the information away but using csv files comma separated values maybe we could actually keep around the names and numbers so that like on your phone you can actually keep your contacts around long term so i'm going to go ahead now and do a slightly different example and let me just hide this detail so it's not confusing whoops i'm going to change my prompt temporarily so let me go ahead now and refine this example as follows i'm going to go into phonebook.pi and i'm going to import a whole library called csv and this is a powerful one because python comes with a library that just handles csv files for you a csv file is just a file with comma separated values and in fact to demonstrate this let me check on one thing here just to make this a little more real to demonstrate this let's go ahead and do this let me import the csv library from cs50 let me import getstring let me then open a file using the open function open a file called phonebook.csv in append format in contrast with read format and write format write just blows it away if it exists append adds to the bottom of it so i keep this phone book around just like you might keep adding contacts to your phone now let me go ahead and get a couple values from the user let me say getstring and ask the user for a name then let me get getstring again and ask the user for their number and now let me go ahead and do this and this is new and this is python specific and you would only know this by following a tutorial or reading the documentation let me give myself a variable called writer and ask the csv library for a writer to that file then let me go ahead and use that writer variable use a function or method inside of it called right row to write out a list containing that person's name and number notice the square brackets inside the parentheses because i'm just printing a list to that particular row in the file and then i'm just going to close the file so what is the effect of all of this well let me go ahead and run this version of phonebook.pi and i'm prompted for a name let's do carter's first plus one six one seven four uh four nine five one thousand and then let's go ahead and ls notice in my current directory there's two files now phonebook.pi which i wrote and apparently phonebook.csv csv just stands for comma separated values and it's like a very simple way of storing data in a spreadsheet if you will where the comma represents the separation between your columns there's only two columns here name and number but because i'm writing to this file in append mode let me run it one more time python of phonebook.pi and let me go ahead and do david and nine four nine four six eight two seven five oh enter and notice what happened in the csv file it automatically updated because i'm now persisting this data to the file in question so if i wanted to now read this file in i could actually go ahead and do linear search on the data using a read function to actually read from the csv but for now we'll just leave it a little simply as right and let me make one refinement here it turns out that if you're in the habit of read opening a file you don't have to even close it explicitly you can instead do this you can instead say with the opening of a file called phonebook.csv in append mode calling the thing file go ahead and do all of these lines here so the with keyword is a new thing in python and it's used in a few different ways but one of the ways it's used is to tighten up code here and i'm going to move my variables to the outside because they don't need to be inside of the with statement where the file is open this just has the effect of ensuring that you the programmer don't screw up and accidentally don't close your file in fact you might recall from c valgrind might have complained at you if you had a file that uh you didn't close a file you might have had a memory leak as a result the with keyword takes care of all of that for you as well how about let's do do you want to do this how about let's do one other thing let's do this let me go ahead and propose that on your phone or laptop here or online go to this url here where you'll find a google form and just to show that these csvs are actually kind of omnipresent and if you've ever like used a google form or manage a student group or something where you've collected data via google forms you can actually export all of that data via csv files so go ahead to this url here and those of you watching on demand later will find that the form is no longer working since we're only doing this live but that will lead to a google form that's going to let everyone input their answer to a question like what house do you want to end up into sort of an approximation of the sorting hat in harry potter and via this form will we then have the ability to export we'll see a csv file so let's give you a moment to do that in just a moment i'll share my version of the screen which is going to let me actually open the file the form itself and in just a moment i'll switch over my internet here is being slow come on come on okay stand by i will switch over in a moment once i have access sorry give me one second all right and in a moment oh my god so many steps today let's go to the same url okay so this is now my version of the form here where we have 200 plus responses to a simple question of the form what house do you belong in gryffindor hufflepuff ravenclaw or slytherin if i go over to responses i'll see all of the responses in the gui form here so graphical user interface and we could flip through this and it looks like uh interestingly 40 of harvard students want to be in gryffindor um 22 in slytherin and everyone else in between the others but you might have noticed if ever using a google form this google spreadsheet's link so i'm going to go ahead and click that and that's going to automatically open in this case google spreadsheets but you can see do the same thing with office 365 as well and now you see the raw data as a spreadsheet but in google spreadsheets if i go to file and then i go to download notice i can download this as an excel file a pdf and also a csv comma separated values so let me go ahead and do that that gives me a file in my downloads folder on my computer i'm going to now go back to my code editor here and what i'm going to go ahead and do is upload this file from my downloads folder to vs code so that we can actually see it within here and now you can see this open file and i'm going to shorten its name just so it's a little easier to read i'm going to rename this using the mv command to just hogwarts.csv and then we can see in the file that there's two columns timestamp column house where you have a whole bunch of timestamps when people filled out the form with someone very early in class and then everyone else just a moment ago and the second value after each comma is the name of the house well let me go ahead here and implement a program in a file called hogwarts.pi that processes this data so in hogwarts.pi let's just we're at a program that now reads a csv in this case not a phone book but everyone's sorting hat information and i'm going to go ahead and import csv and suppose i want to answer a reasonable question ignoring the fact that google's gui or graphical user interface can do this for me i just want to count up who's going to be in which house so let me give myself a dictionary called houses that's initially empty with curly braces and let me pre-create a few keys let me say griff indoor is going to be initialized to zero uh hufflepuff will be initialized to zero as well uh ravenclaw will be initialized to zero and finally slytherin will be initialized to zero so here's another example of a dictionary or a hash table just being a very general purpose piece of data you can have keys and values the keys in this case are the houses the values are initially zero but i'm going to use this instead of like four separate variables to keep track of everyone's answer to this form so i'm going to do this with opening hogwarts. csv in read mode not append i don't want to change it i just want to read it as file as my variable name let's go ahead and create a reader this time that is using the reader function in the csv library by opening that file i'm going to go ahead and ignore the first line of the file because recall that the first line is just timestamp and house i want to get the real data so this next function is just a little trick for ignoring the first file the first line of the file then let's do this for every other row in the reader that is line by line get the current person's house which is in row bracket one this is what the csv reader library is doing for us it's handling all of the reading of this file it figures out where the comma is and for every row in the file it hands you back a list of size two in bracket zero is the time stamp in bracket one is the house name so in my code i can say house equals row bracket one i don't care about the time stamp for this program and then let's go into my dictionary called houses plural index into it at the house location by its name and increment that zero to one and now at the end of this block of code that has the effect of iterating over every line of the file updating my dictionary in four different places based on whether someone typed gryffindor or slytherin or anything else and notice that i'm using the name of the house to index into my dictionary to essentially go up to this little cheat sheet and change the zero to a one the one to a two the two to a three instead of having like four separate variables which would just be much more annoying to maintain down at the bottom let's just print out the results for each house in those houses iterating over the keys they're in by default in python let's go ahead and print out an f string that says the current house has the current uh count and count will be the result of indexing into houses for that given house and let me close my quote so let's run this to summarize the data hogwarts.pi 140 of you answered gryffindor 54 hufflepuff 72 ravenclaw and 80 of you slytherin and that's just my now way of code and this is oh my god so much easier than c to actually analyze data in this way and one of the reasons that python's so popular for data science and analytics more generally is that it's actually really easy to manipulate data and run analytics like this and let me clean this up slightly it's a little annoying that i just have to know and trust that the house name is in bracket bracket one and timestamp is in bracket zero let's clean this up there's something called a dictionary reader in the csv uh library that i can use instead capital d capital r this means i can throw away this next thing because what a dictionary reader does is it still returns to me every row from the file one after the other but it doesn't just give me a list of size two representing each row it gives me a dictionary and it uses as the keys in that dictionary timestamp and house for every row in the file which is just to say it makes my code a little more readable because instead of doing this little trickery bracket one i can say quote unquote bracket house with a capital h because it's capitalized in the google form itself so the code now is just minorly different but it's way more resilient especially if i'm using google spreadsheets and i'm moving the columns around or doing something like that where the numbers might get messed up now i can run this on hogwarts.pi again and i get the same answers but i now don't have to worry about where those individual columns are all right any questions on those capabilities there that's a teaser of sorts for what some of the manipulation we'll do in pset six all right so some final examples and flair to intrigue with what you can do with python i'm gonna actually switch over to a terminal window on my own mac so that i can actually use audio a little more effectively so here's just a terminal window on mac os i before class have pre-installed some additional python libraries that won't really work in vs code in the cloud because they require audio that the browser won't necessarily support but i'm going to go ahead and write an example here that involves writing a speech-based program that actually does something with speech and i'm going to go ahead and import a library that again i pre-installed called python text to speech and i'm going to go ahead and per its documentation give myself a speech engine by using that library's init function for initialize i'm then going to use this engine's save function to do something fun like hello world and then i'm going to go ahead and tell this engine to run and wait while it says those words all right i'm going to save this file i'm not using vs code at the moment i'm using another popular program that we used in cs50 back in my day called vim which is a command line program that's just in this black and white window let me go ahead now and run python of speech.pi and hello world all right so it's a little computerized but it is speech that has been synthesized from this example let's change it a little bit to be more interesting let's do something like this let's ask the user for their name like what's your name question mark and then let's use a little f-string and say not hello world but hello to that person's name let me save my file run python of speech dot pi enter david hello david all right so we pronounce my name okay might struggle with different names depending on the phonetics but that one seemed to be okay let's do something else with python using similarly just a few lines of code uh let me go into today's examples and i'm going to go into a folder called detect oops a folder called faces dot pi sorry faces and in this flow folder that i've written in advance or a few files detect dot pi recognize.pi and two full of photos office.jpg and tobii.jpg if you're familiar with the show here for instance is the cast photo from the office here so here's a photo as input suppose i want to do something very facebook style where i want to analyze all of the faces or find detect all of the faces in there well let me go ahead and show you a program i wrote in advance that's not terribly long much of it is actually comments but let's see what i'm doing i'm importing the pillow library again to get access to images i'm importing a library called face recognition which i downloaded and installed in advance but it does what it says according to its documentation you go into that library and you call a function called load image file to load something like office.jpg and then you can use a line of code like this call a function called face locations passing the images input and you get back a list of all of the faces in the image and then down here a for loop that iterates over all of those face locations and inside of this loop i just do a bit of trickery i figure out the top right bottom and left corners of those locations and then using these lines of code here i'm using that image library to just draw a box essentially and the code looks cryptic honestly i would have to look this up to write it again but per the documentation this just draws a nice little box around the image so let me go ahead and zoom out here and run this now on office.jpg all right it's analyzing analyzing and you can see in the sidebar here here's the original and here is every face that my what 10 lines of python code found within that file what's a face presumably the library is looking for something maybe without a mask that has two eyes a nose and a mouth in some kind of arrangement some kind of pattern so it would seem pretty reliable at least on these fairly easy to read faces here what if we want to look for someone specific for instance someone that's always getting picked on well we could do something like this recognize.pi which is taking two files as input that image and the image of one person in particular and if you're trying to find toby in a crowd here i conflated the program sorry this is the version that draws a box around the given face here we have toby as identified why because that program recognize dot pi has a few more lines of code but long story short it additionally loads as input tobii.jpg in order to recognize that specific face and that specific face is a completely different photo but it looks similar enough to the person that it all worked out okay let's do one other that's a little sensitive to microphones let me go into how about my listen folder here which is available online too and let's just run python of listen0.pi i'm going to type in like david oh sorry no i'm going to hello world oh no that's the wrong version okay i look like an idiot okay hello there we go hello to you too and if i say goodbye i'm talking to my laptop like an idiot okay now it's detecting what i'm saying here so this first version of the program is just using some relatively simple if elif elif and it's just asking for input forcing it to lower case and that was my mistake with the first example and then i'm just checking is hello in the user's words is how are you in the user's words didn't see that but it's there is goodbye in the user's words now let's do a cooler version using a library just by looking at the effect python of listen1.pi hello world huh let's do version two of this that uses a uh audio a speech to text library hello world how are you my name is david no is that supposed to happen wait uh oh yes hello world how are you okay that's a bug okay let me just do it right wait let's pretend that never happened hello world okay so now it's artificial intelligence now let's do something a little more interesting the third version of this program that actually analyzes the words that are said hello world my name is david how are you okay so that time it not only analyzed what i said but it plucked my name out of it let's do two final examples this one will generate a qr code let me go ahead and write a program called qr.pi that very simply does this let me import a library called os let me import a library called qr code let me grab an image here that's qrcode.make and let me give you like the url of like a lecture video on youtube or something like that with this id let me just type this so i don't get it wrong okay so if i now use this url here of a video on youtube making sure i haven't made any typos i'm now going to go ahead and do two lines of code in python i'm going to first save that as a file called qr.png which is a two-dimensional barcode a qr code and indeed i'm going to use this format and i'm going to use the os dot system library to open qr.png automatically and if you'd like to take out your phone at this point you can see the result of my barcode that's just been dynamically generated hopefully from afar that will scan and i think that's an appropriate line to end on so that's it for cs50 we will see you next time you
Info
Channel: CS50
Views: 82,070
Rating: undefined out of 5
Keywords: cs50, harvard, computer, science, david, j., malan
Id: SjKEV8sDIAA
Channel Id: undefined
Length: 175min 0sec (10500 seconds)
Published: Wed Oct 13 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.