[MUSIC PLAYING] SPEAKER 1: This is CS50 and this is the end of week seven. Today is perhaps where we really teaching you languages. We introduced in the past couple of weeks HTML and CSS, neither of which are programming languages. And indeed, even though we didn't look at nearly all of the tags that HTML comes with and nearly all of the properties that CSS comes with, that's kind of it for HTML and CSS. We'll just generally start assuming that you understand the general ideas of tags, and attributes, and pages being sent from client to server. Because today we start to look at another programming language, PHP. We're going to do this super fast. We're not going to teach you PHP per se, much like we didn't aspire to teach you C, per se, but rather programming. And indeed, one of the goals for this course is not to teach you C, or HTML, or CSS, or PHP, or any number of other buzz words or acronyms, but rather the computer science and how to program fundamentally. And indeed, today we start to take those training wheels off all the further by flying through a language called PHP, as follows. Here is what this language looks like. It turns out that there is no need for a main function in a program written in a language called PHP. So that already sounds a little simpler than C, with which we're familiar. It turns out that if you want to declare a variable, you do it almost identically to C. But there's clearly one difference here when I declare a string, or maybe two differences. What looks different? AUDIENCE: The dollar sign. SPEAKER 1: Yes, there's dollar sign, which we've never seen before. And what is missing? Yeah? AUDIENCE: [INAUDIBLE] SPEAKER 1: Yeah, there's no data type. So it turns out that PHP is what we call a loosely typed language, where C is strongly typed. Loosely typed just means that there are different data types, there are strings, and ints, and floats. But the computer figures that out. You the human programmer don't have to figure it out. So all you have to do to declare a variable is dollar sign, the name of your variable, and then, for instance, quote unquote, hello world. Well this is what a condition looks like in PHP. Any differences? No. So it turns out these are identical. And you might have fewer branches or more branches, but the syntax turns out exactly the same. Boolean expressions can be ordered together. Boolean expressions can be anded together. You still have switches. Even if you haven't used these, these do exist in C and they're functionally equivalent in PHP. And in fact, in PHP they're a little more powerful. In C, you can only compare certain data types like ints and chars, whereas in PHP you can actually compare full fledge strings without having to worry about pointers and the like. So here's a for loop. This is just pseudocode code, if you will. But structurally it's identical to C. Here's a while loop, pseudocode therefore-- identical to C. Here's a do while loop-- identical. And so there's kind of this pattern here whereby there's a few other syntactic features we're indeed going to see. In fact, here is a nice way in PHP whereby, if you want to iterate over an array, and you don't want to jump through the mental and syntactic hoops of having int i equals 0, i less than n, i plus plus-- which is just a lot of annoying syntax. You can say a little more fluidly for each numbers as number, where in this case dollar sign numbers, I'm assuming, is like an array called numbers. And then I'm assuming number, singular, is going to be a variable. And what PHP will do for me as I iterate over this loop is, on each iteration, it's going update the variable number to be the ith element in numbers, plural. So it just handles all of that for me. No square brackets, no dollar sign, no semi-colons. It's just a little simpler. Well, if you want an array, it turns out you can do something pretty similar to C. The syntax is a little different. But here's an array called dollar signed numbers. And I use, in PHP, square brackets, it turns out. And we're going to see these again in JavaScript-- yet another language. I just use square bracket notation to have a comma separated list of integers, in this case. But that gives me an array. But even more powerful in PHP, we also have what are generally called associative arrays. And a lot of languages have these as well. The thing about C arrays is that the indexes for an array, the thing that you use in square brackets via which you access elements, must be what? AUDIENCE: [INAUDIBLE] SPEAKER 1: They have to be numbers or integers, specifically from zero on up. Well, in PHP, and, it turns out, in other languages, you can start to have indexes that are not numeric. But they're actually words or phrases, so that rather than try to remember where something is, or stored in a variable i, you can actually use a word and say that-- you can say a word like this. So dollar sign quote is the name of a variable here. This is somewhat funky syntax that's associating two key value pairs for this variable. Specifically, this is giving me an array that is of length 2. But the indexes are not 0 and 1. The indexes are quote unquote symbol and quote unquote price. And the values of those indexes, respectively, is FB for Facebook and $79.53, when I last checked a price for this. What does that mean? Well, it means that instead of writing code like this, where I used to do something like dollar sign-- or rather, in C I wouldn't even have a dollar sign. I would do something like quotes and then I would do bracket i to get at some arbitrarily numerically indexed value. Starting today in PHP, if you want to get at some value, we sort of have more semantic expressiveness. Just a fancy way of saying we can just call things what they are. And if you want to get at something symbol, now you literally do quote unquote symbol in square brackets instead of a mere number. So it's a nice convenience. And that's sort of it for now. There's bunches of other features in PHP. And indeed, PHP comes with the proverbial kitchen sink. Dozens, hundreds of functions come with PHP-- so many more than came with C. And that's not intended to overwhelm but rather help you realize that we no longer have to write code that's sort of down here conceptually. Now we can just start taking advantage of much more advanced features that languages like PHP have. So we don't have to worry about moving things around in memory. We don't have to worry about malloc and all of these lower level, powerful details that you will wrestle with, if not struggle with, pset5, but you can begin to soon take for granted. In fact, let's write a super simple program in PHP, as follows. I'm going to go head into CS50 IDE here, and what I'm going to do is create a new file, that very simply is going to be called hello dot PHP. So instead of dot c, it's going to be called dot PHP. And then in this file, I can start typing. But it turns out that the one thing I have to know is that any PHP file in general, needs to start with some special syntax. Similar in spirit to HTML, but again, PHP is a programming language, not a markup language. So every file, and it's sort of stupid looking I'll admit. Open bracket, question mark, PHP. And that's just the language's way of saying, hey, computer here comes some code written in a language called PHP. And then at the very end of your file, you do kind of sort of the opposite. You don't write PHP again, you just do question mark, angle bracket. And then anything you put inside of these two tags, so to speak, will be, or should be, PHP code. So let's do something super simple. I'm going to go ahead and do print def, hello world, backslash n, save. And now at my prompt, I'm going to do, make hello-- no, I'm going to do, dot slash hello. No, dot slash, hm. So something's different. And indeed, this is a key difference between PHP and languages like C. C was a so-called compiled language. What did it mean for C to be compiled? What was the implication? Yeah. AUDIENCE: Wrote it into machine code so it could be run by the computer. SPEAKER 1: Exactly. We have to first convert it into so-called machine code, zeros and ones, before it will actually be executable and understood by the computer. By Intel inside. By the CPU inside of the computer. PHP, by contrast, is what's called an interpreted language, which means that you don't compile it into zeros and ones, machine code, you instead leave it as source code. And you instead pass it as input to a program, an interpreter that someone else wrote years ago that understands it line by line, character for character. So in other words, humans out there wrote a program that will look at your code line by line, and figure out what the computer should do, without converting it directly to zeros and ones. So if it sees a for loop, this so-called interpreter is going to be like, all right, I should do something again and again and again. What should I do? Let me look at the next line. Let me look at the next line. And it truly interprets it line by line. So to execute it, I don't use make. I don't use dot slash in this case. I instead do PHP, which is the name of a program, a.k.a. An interpreter, that's pre-installed in CS50 IDE, and now I need to pass a command line argument, which is quite simply the name of the file that I want to interpret. Or more casually, that I want to run. And if I hit Enter, there we have it. Hello world. Now it turns out that I used print def deliberately to bridge us from C to PHP. Most PHP programmers, as you'll see, don't even bother using print def. They just use a function called print, which C did not have. And so if I rerun it now, it actually behaves functionally the same. I can't use the percent s and percent i and so forth, but there are other ways in PHP of doing that. But this is only to say that syntactically, other than some weird things up top, and some weird characters down at the bottom, the concepts now of programming in this other language are going to be exactly the same. In fact, let's do one other example. So I'm going to go ahead and close this file. Let me create another one that I'll call conditions 1 dot PHP. So no zero, because what I did was I looked back a few weeks ago, we had a file called conditions 1 dot C. And what I did was converted it in my head, and in here on paper, and soon on the course's website, line by line into PHP. So in the C version, we did something like string s gets get string. So it's a little different to do that in PHP. Instead, I'm just going to do, or rather, I might have done int n gets get int, in this example earlier. So instead of that, I'm going to do n gets read line, I'd like an integer, please. So this is just my prompt. And so it turns out, and I would only know this from having read or seen the function before, read lines of function in PHP takes an argument that is a prompt for the human, and its purpose in life is to read a line of text that he or she types in. And then it stores that text into the variable n. And now I might want to do something like I did weeks ago, in like week one of the class. If n is greater than zero, then, I'm going to borrow that syntax we just saw, print def, you picked a positive number, backslash n. Else if n equals equals zero, I'm going to go ahead and say, print def, you picked zero backslash n. Else, the case here should of course be, print def, you picked a negative number. And we can certainly implement the logic of this thing in a bunch of different ways, but the point here is that syntactically, barely anything is new. It's just the dollar sign and a new function and read line. But fundamentally, what's new now is I'm interpreting this. I'm passing it as input to another program. So if I want to run this, if I didn't make any mistakes, I'm going to run PHP, of conditions 1 dot PHP, Enter, I'm going to type in the number 50, and let's assume for now it works. Because the logic is the same stuff as week one. All right, so that's pretty underwhelming, right? We could do this in any number of languages. Let's do something way more powerful. Let's finish problem set five. So I'm going to go ahead and do this. I'm going to create a file called dictionary dot PHP, and inclined as you might be to scramble down lots of notes, the notes will only help you if you're allowed to implement problems set five in PHP. But we'll see how quickly now we can implement that same problem set. So in dictionary dot PHP, I am going to assume that there is already a file in the world called speller. And indeed, I did this in advance, and we won't walk through this line by line, but if you're curious later and really want to wrap your mind around the differences between c and PHP, literally compare this file, speller, from today's source code that we'll post later today, against p set five speller dot c that we give you, and it's almost the same line by line. There's some more dollar signs. A couple functions are a little different. But it's a nice way of sort of seeing how you translate one language to another. And it's almost identical line for line. But I'm going to assume that that exists, and what I'm going to do here is try to blow your mind by reimplementing the entirety of problem set five way faster than you've been doing thus far. So for instance, I'm going to first declare a global variable called size, and set it equal to zero. Now that's not much savings. Odds are you implemented size pretty much the same, or hint hint, will tonight or tomorrow, just using a global variable called size, and setting it equal to zero. That's not a particularly amazing spoiler. So what were your data structures of choice, those of you who have dived in and read the spec, what data structures have most of you have been using? A hash table or try, maybe some variants thereof. So implementing a hash table at least, is kind of a lot of lines of code, right? And not all of them might be functional at this point in the week, but that's fine. Because in PHP, if I want a hash table, done. Right? So that variable that I've just declared is obviously called dollar sign table, per the introduction before. But I really just want, at the end of the day, an array. But not a numerically indexed array, because that's like week two stuff, when we talked about arrays. I want a hash table. But a hash table is really just a concrete way of saying, you want an associative array. You want to be able to associate keys with values. Keys with values. What is a dictionary, really? Well it's a whole bunch of keys. Words like apple, pear, and banana, and all of these English words that we hand you. And the values that you're effectively inserting into your dictionary are either true, or the absence, false. In other words you are inserting a whole bunch of key value pairs, apple, true, pear, true, banana, true. So that when you retrieve or look up that data in your hash table with your check function, you're either getting back an answer, yes, I found it in my complex hash table, or no, it's not there, so you return false. So to do that, all I need is the data structure like I proposed before. I just need to be able to associate words like, quote unquote, symbol, with a value like, true. So there's my hash table. Let's actually use it. So there's a few functions I need to implement. I'm going to go ahead and bite off a function called size. It takes no arguments. I don't have to bother with the word, void, in PHP. I'm simply going to return size. And as an aside, PHP has this minorly annoying detail, where if something's global, you have to tell the function in which you're using it, hey, this is a global variable. So, minor stupidity, but you have to do it nonetheless. So what about load? I'm going to implement a function called load that takes in the name of a dictionary, just like in problem set five. And before I proceed, notice that I haven't been typing quite the same things. What's obviously different in PHP about how you declare a function versus C? Yeah. AUDIENCE: [INAUDIBLE] SPEAKER 1: No return type. And indeed, that's the case, PHP insofar as it's loosely typed, is also a little sloppy in that sense. You don't specify as the programmer what this function returns. You would have to actually look at the code to figure that out. Or read the comments or the documentation. So pluses and minuses of these kinds of decisions. But I do have to say the key word, function. And when we learn JavaScript in a couple weeks we're going to see the same thing again, but it's the same idea. The name of the function, its argument or arguments or lack thereof, and now here is the implementation. So I'm going to cut some corners just to be dramatic for just a moment. But I'm going to go ahead and say this. This is how I can load a file into an array. There is a function in PHP called file. You hand it the name of a file. It hands you back an array, inside of which is every line from the file. From zero, one, on up to n minus 1 lines. That's it, right? There's no f read. There's no f get s. There's no percent s. There's no headaches. There's no feof. All of that stuff with which you've been wrestling perhaps, with p set four and five, goes away. So I just read those lines into the file, and then you know what? If I want to iterate over those words, I can do, for each lines as line. Remember that this was kind of a clever way of iterating over an array, index by index, and on each iteration calling the current line, dollar sign line. And right here I'm going to go and say table, bracket, line, gets true. In other words, this is how I insert into my hash table in PHP. I say dollar sign table, which is my associative array that was empty per the line of code up above. I then index into it not, using a number, but literally using the keyword that I care about. Maybe it's apple or pear or banana or whatever, but specifically I'm indexing into it like I proposed earlier. I take the name of my associative array, and then I use quote unquote in the square brackets with a string, instead of an actual number. And so that's it. The load function is done. Once that loop iterates, I've put everything into the hash table. Now small disclaimer, there's a couple things I do need to fix. And the version I'll post online will have all of the nuances, but it's mostly just going to be some error checking and some minor tweaks. But that's indeed the gist of it. If I now want to implement the function called check, which expects a word as its argument, how might I go about doing that? Well, I'm simply going to say, if inside of my table, at location word, if is set. So if there is-- actually, you know what? I'm going to do it in a bit of pseudocode. But the idea is the same. If that equals true, return true. All right. Else-- you can kind of see where this is going-- to return false. Done. Check is done. Pretty nice, right? And so what is this really getting at? And this too, I cut some corners. Look at the version online for all of the slight nuances. But that's the gist of it. Index into your associative array, a.k.a. Hash table, see if there's a value there, if it's set to true, and if so, return true. So we've whittled down all of the complexity. So kind of mind blowing, right? I won't bother finishing it with unload, because in fact-- oh, you know what? Yeah, let's finish it with unload. Unload in a hash table might look like function unload, return. OK so that's unload. Because there's nothing to unload, right? There's no malloc. I didn't explicitly ask the operating system for anything. I just started using variables. And so this too is a manifestation of features of higher level languages. So again, most of this term we've been dealing down here with C. Super low level. You can see the computer's memory. You can touch anything you want in your computer's RAM, for better or for worse. Up here, we're going to give up that power. But my god, look how much less code I wrote. In fact if I weren't talking and talking over my typing, we would have been done with this example five minutes ago. So what's the price being paid? Well let's take a look. Let's take a look. I'm going to go ahead and run CS50. Let me first go into today's examples where I have the texts directory as before. I'm going to run the solution that it comes with problem set five called speller, which is in CS50's account. And I'm going to run it on something big like the King James Bible, just so that we really put the staff solutions to the test. Now sometimes the internet's a little slower, a little faster, might take a while to scroll. But it took a total of .56 seconds to spell check the King James Bible using the staff solution. So pretty good. Yours might be much slower, and that's totally fine. But it is correct here. So that's the staff solution. If I go in and clean up the PHP version. And I'm going to do a little like baking show thing. We're going to take the code I wrote earlier, so it's perfectly correct. Because the code I wrote is not going to be perfectly correct just now. But if I run the PHP version, what do I have to give up today? Took me five minutes to implement p set five, I claim. What price have I paid? Yeah. AUDIENCE: Speed. SPEAKER 1: Speed. What do you mean? AUDIENCE: It's going to take longer. SPEAKER 1: All right. Let's see. It's going to take longer, not to write, but to run it. Yeah. So let's try this. So here I'm going to go ahead and do PHP of speller, and because the file's called speller. So I'm not running the dictionary, recall, I'm running the program called speller. I'm going to pass in the same file, King James the fifth. It's flying by. This could just be internet speed, so don't read too much into that. But it does feel longer for sure. 1.26 seconds. Now that's still pretty damn fast, right? And the only reason that felt like more like three, or four, or five seconds, that's just because the internet was being slow. The computer time spent was 1.26 seconds, versus I think 0.56. So more than twice as slow. Now that's still pretty darn fast, but it's a manifestation of, indeed, that exact price. Because we're interpreting in the code line by line, and that program PHP is reading my code top to bottom, left to right, it has to do more thinking. It has to kind of convert it inside of itself to the corresponding machine code on the fly, so to speak, even though the mechanics are a bit different. Instead of just feeding to the Intel CPU the raw zeros and ones that it understands natively. So absolutely, hands down, we have paid a price. And code written in a language like PHP tends to be slower. But my god. So now when I spell check my file, I spend an extra 0.7 or so seconds vs 20 hours to implement a faster spell checker, right? It's kind of a trade off. And if you're just starting p set five, might not be 20 hours. Might be far fewer than that. But it's a trade off, for real. And if you're running code on really big data sets, or on even older hardware, those kinds of differences can certainly add up. Any questions thus far? Yeah. AUDIENCE: [INAUDIBLE] SPEAKER 1: Sorry, can you say it once more? AUDIENCE: [INAUDIBLE] SPEAKER 1: You're giving up time. Well, so yeah. You are saving time by not having to compile it, if that's what you're asking. And indeed, in CS50, most of the programs, even though they might take a while to write, they're relatively short. Few dozen, few hundred lines of code, and so they compile pretty quickly. But when you start writing bigger programs, like if you're Microsoft or you're Google and writing really big programs in C, or C++, or similarly compiled languages, could take many seconds, or even minutes or longer to compile millions of lines of code. And there too, that difference is going to add up. And in fact, once we transition today, same day today, to web programming using PHP, you're going to find it just so much more pleasurable to write code when you don't have to do these stupid steps like change to your terminal window, type make hello, re run it, reload the window. Just so many stupid mechanical steps that just get in the way of doing the interesting, the fun work. And indeed we throw that away with PHP. And we can interact with it more rapidly. Yeah. AUDIENCE: [INAUDIBLE] SPEAKER 1: Sure. Can I clarify what it means to be interpreted? When you compile a language like C, it goes down as we said to machine code, zeros and ones. And Intel decided years ago that certain patterns of zeros and ones represent addition, or subtraction, or print, or other basic operations. In the world of an interpreted language like PHP, or JavaScript, or Python, or Ruby, or bunches of others, instead someone has written an interpreter-- in this case, it's also called PHP, identical to the name of the language-- that essentially has a big loop in it that iterates over all of the lines of the code that I feed it as input, like hello dot PHP, or dictionary dot PHP. And then you can think of their big loop as having a lot of conditions. And those conditions say, if the human has written the keyword for, start doing his or her code again and again. Or if the human has written the line of code, if, only execute their next line conditionally. So it's truly like interpreting it in a human sense, line by line, and that just takes time. It takes overhead. And so that's a price-- good question-- we pay. So let's do another demo that's a little more dramatic. There is, I'd say, a ballpark this at a 90% probability of failing horribly, but you will be amazed with 10% probability. So every year we try to do this, whereby we try to write a program that goes through problem set zero, for which you've submitted your phone numbers and a lot of other demographic information, and we programmatically send you a text message. And then everyone's phone starts beeping or vibrating, and it's just amazing, because well, look at what computers can do. This rarely works correctly it seems, in large part because I typically get blacklisted by Gmail or some other service for actually trying to do this on scale. But funny thing is too, since we don't have everyone here today, fun fact the last time we tried this two years ago, I think I wrote a program that sat in a loop iterating over all the students in the class, and each of them a text message, and it said something like, why aren't you in lecture? Love, CS50 bot. You have no idea how many apologetic and sort of painful emails I've received in response from the n minus 100 people who weren't here that day. And even funnier, more shameful story-- you know, let's put it out there. It's already on video a few years back. So you will soon see me write a for loop, whereby it's very easy to write a bug in that for loop, such that the first time through the loop, you send one text message. The second time through the loop I should have sent one more text message, and then one more text message, and one more. But it turns out if you make a typo when programming, sometimes you can write programs that send one text message, then two text messages, then three text messages to everyone who's already received a text message. And as you know, doing something, plus something, plus something, plus something, is big O of a lot of text messages, or n squared, or at $0.10 a text message, $20,000. Thankfully I hit Control-C before that happened, but I did owe at least one of your predecessors $20 for the 200 some odd text messages that, not only went to his phone, but also it was like an older flip phone so it like pushed out of his memory every other personal text message he had actually gotten. So we have one goal today, not to do that. Maybe turn on airplane mode. All right. So let's go into a program here callled-- that I will call text dot PHP. And in advance, I've got two files here. I made a file for just staff, that's got all of the staff's info, all the names from the course's website. And then for now I just put some fake numbers 555-1212. So these wouldn't actually go anywhere. But notice the inside of this CSV file, which we talked about briefly before in the context of file IO. What's a CSV file? Comma separated variables. And this is kind of like a very lightweight database, if you will. There's kind of sort of four columns in this file, and there jagged, but the commas essentially represent columns in the file. The first column is the TF or CA's name. Second column is their last name. Third column is their phone number. And fourth column apparently is-- fourth column is apparently what? OK, so it's their carrier. So Verizon, or Sprint, or what not. And if I misspoke earlier, CSV. Comma separated values is CSV here. So what can I do with this? Well this is just a big text file, and it's kind of long, right? Like this is going to be kind of annoying. And it turns out, though, that if I want to send a text message to, let's say Alex here. Let me go into my browser and exit the full screen mode just so I can toggle back and forth. It turns out, let's see, if I go in here, and log into Gmail, all right. Don't look at this part. Just I get to see. of course the livestream can still see what I'm doing. All right. So here is just Gmail with John Harvard's account. So if I want to send a text message to Alex, I can of course compose a message. And it turns out, and I've tested it with Alex before here, so you can append a certain domain name to people's phone numbers, because there exists in the world things called SMS to email gateways. Which is a fancy way of saying all of us who have mobile phones that have phone numbers, of course, there probably is for your carrier, a certain suffix like at Vtext.com for Verizon text message dot com, that you can append to your own personal phone number, and then you or friends, or your parents can text you at that particular address. And Verizon has a server, an email server, that upon receiving this email, looks at the numeric part and then uses whatever special industry magic they have to actually send it out over the airwaves to your particular cell phone. Now this is nice because I don't really know how to send a text message or to write code yet for my mobile phone, and you might do exactly that for a final project, but for now all I have is my laptop here. So I want to iterate over that CSV file, line, by line, by line, by line, grab each of the staff's phone numbers, and their carrier and programatically, concatenate, that is, connect the phone number with the appropriate domain name and then send an email. So that's a lot of steps. And good luck doing that in C. It is a nightmare of a situation to open a file, to read it line, by line, by line, as you are seeing, or may soon see with problem set five, if not problem set four, and then to dynamically concatenate two strings together, because in C, to take two strings and combine them, what do you minimally need to do most likely? You need to declare more memory, right? And ask, malloc, can I have more memory? So I can put half of this here, half of this here. It's just so many steps. And by that point you've lost interest in the stupid little demo where you make everyone's phone beep. Let's do this sort of PHP style, whereby we just start using more of that kitchen sink. And the ideas are fundamentally the same, but we don't have to worry too much about that lower level. So let's see how I might go about doing this. And just so that I don't repeat past mistakes, I've written some notes for myself here. And let's see if I can walk us through some of the fundamental steps, and then for time's sake we'll perhaps cut some corners in the end. I'm going to go ahead and do open bracket PHP to start this file. And I'm going to go ahead and do this. File handle, as you'll soon see, actually calls a function called f open. And remember this opens a file. And the quote, unquote, r means what, again? Just open it for read. Now in p set for, you did this. And handle could be anything, fu, bar, bas, any variable name. But generally a computer scientist would call an open file, giving you a file handle, something to hold onto so to speak. I'm just going to do some error checking. So if the handle is false, just like in C, I'm going to do something like, could not open file, backslash n. And then I'm just going to go ahead and exit. And it turns out, in PHP, I'm not inside a function. There's no main function here. So I don't return, per se. I exit. Which is essentially the same thing. And I'm exiting with one y probably. One just means an error of some sort. It's non-zero, so it's an error. All right, so if I'm down here now in my program I have opened the file. I'm going to go ahead and declare an array called addresses, and in C I would have to know the size of the array in advance, right? Or I would need to declare this is a pointer, and then use malloc. And then every time I read through another row in the file, I'm going to need to malloc more memory, malloc more memory. That's a pain in the neck. And thankfully, PHP, and Ruby, and Python, and JavaScript, they will grow your arrays for you automatically. No more malloc. No more memory management. The computer takes care of that. But the price you pay. It's a little slower. And for a program like this we're not going to notice. We're going to send 100 text messages. For instance not going to feel it. IT really only starts to matter your language of choice when your data or your programs get really, really sizable, as will be the case more so with our web based stuff. But for now let's forge ahead. While it turns out there's a function in C called f get CSV. File get CSV, that takes a file handle as its argument, and it proceeds then, row, by row, by row, to read in a row. So it just reads a line of text from the file. But what's nice about this function, it doesn't just hand me a line of text. It looks for those commas, and parses the line. And to parse the line means to split it on certain values in this context. In other words, dollar sign row is a variable that's going to give me a bunch of indexes. This is going to be the first column in my CSV. This is going to be the second column, this is going to be the third, and this is going to be the fourth. Because recall, and Excel the not cooperate the last time we did this, but if I download staff dot CSV. Whoops, not rename. If I download staff dot CSV, and try opening it, I've already registered-- oh I didn't update Excel since last time. You'll see that in staff dot CSV, I have four columns. So when I read in the first row for Abby here, dollar sign row 0 is Abby, dollar sign row one is Lyons, dollar sign row two is her number, and then her phone's carrier. So that's all. And that's nice, because I don't have to now figure out where all of those commas actually are. So I'm going to go ahead and do this, given that definition, I'm going to say that her name is in row bracket zero, as promised. And I'm going to grab-- and actually, you know what? I'm not going to worry about her name, in this case. I'm going to keep it simpler. I'm going to do her number is in row bracket two, I think. And her carrier was in where? Row three, one over. So nothing new there. It's just zero indexing into an array. And now, I'm going to do the following. If the carrier equals equals AT&T-- I'm just going to have a loop-- I want to create an email address that looks like this. It's going to be 617-555-1212 at, what is it, text.ATT.net, is what I want to do. So how do I do this? I'm going to do the following. Her address is going to be her number, and now, let me go ahead and do this. This is some funky syntax. I could do the percent s trick, but I can actually just do this. So this is a PHP thing, but let's consider what I'm doing. Dollars sign address on the left, just a variable. Give me a variable. I don't have to specify the type. PHP will figure it out. On the right hand side, what's the data type of that whole thing on the right hand side? Looks like a string, because there's double quotes on the far left and far right. Now there's some funky new syntax here. There's the curly braces, and the dollar sign number. But take a guess what is that syntax probably telling PHP to do for me? Yeah. Just insert the value there. So no percent s. We could use print f, or s print f or something like it, but PHP and a lot of higher level languages, you're going to see that you could do the same thing functionally, maybe six different ways. And so it starts to become a matter of design or style. So this is just a cryptic looking way of saying, give me an email address, but plug-in the number in between these curly braces. And the curly braces will not end up in the final address. Now we can skip over some of these lines for time's sake. So if a carrier equals equals verHorizon-- whoops, Verizon-- I want to do something very similar, where the address gets, quote, unquote, number at text.ATT.net. And then I can do the same kind of thing for the rest of the carriers. But I'll just do dot, dot, dot for now. And now let's suppose that I want to add array, push. I want to add to the array, called addresses. This address, this is how you add something to an array in PHP. You don't need to do malloc. You don't have to resize the array. You just say array, push. What do you want to push-- what array do you want to push something onto? Addresses. What you want to push onto addresses? Address. And in fact, if you really want to be clever, some syntactic sugar for this, so to speak, which just means how can you do this in the prettier way, would be to do this. That too has the effect of growing the addresses array by size one, and then plop that additional email address into it. Yeah. AUDIENCE: [INAUDIBLE] SPEAKER 1: A typo on the else if-- oh, carrier. That's OK. It also won't like my failure to implement part of this program later on. But thank you for catching. One more bug. Thank you. We want this to be Vtext.com. Yes. All right. So where does this leave us? We've written the code to open the file. We have a loop to iterate over the rows in the file. We have code that adds to my array, one at a time, the correctly formatted email address. So all that really remains is to send an email to each of these people. So I've gone ahead and readied myself as follows. What I'm going to do here is-- and let's go ahead and skip to some actual code, which looks like this. So here is the pre-baked version I wrote earlier. And notice I finished implementing Sprint. I finished implementing T-Mobile. I finished implementing Virgin Mobile. And I will apologize in advance. There's a few carriers that some students in the class have that I didn't bother enumerating in the if condition here. So not all the texts will go out. But let's see what else I need to do. I close the file, just like in p set four. And this is new syntax. And we'll see a little bit of this over time, especially with p set seven and eight. But this is syntax for creating a special type of structure. It turns out there's a library that comes with PHP, called PHP mailer. Its purpose in life is to programmatically send emails. It's code someone else wrote that makes it easier for us to send emails, so we don't have to keep going back and forth to Gmail, and pasting in people's email addresses. There's a whole bunch of lines here that honestly, I just kind of copied and pasted from the documentation. And in fact, if you're curious, I left all of the URLs of the documentation in the code that we'll post later. And notice that among the things I'm doing is, I'm telling this library, use Gmail's server, right? SMTP we talked briefly about when we were at Yale about being simple mail transfer protocol. It's the protocol that servers used to send email, and that's-- Gmail has one of those. A port, this is the TCP port number. It's fine if you haven't seen 587 before. Just know that from the documentation. Here's my username. I'm going to use the CF50 bot. And in a moment, I'm just going to type in the bot's actual password. And then down here, notice what remains. I set my from address to be bot at CS50.net. I think I won't regret sending a text message to 800 people that says, miss you, love CS50 bot, perhaps for those who couldn't make it today. And then in line 76, what do I do? This kind of looks like C. So for i equals 0, n equals-- now count is new. It turns out that if you want to get the number of things in an array, you don't have to remember it anymore. You can just ask a function called count, and it will tell you how many addresses are in that array. And then I'm going to add the address to the email. And I know this from using the documentation. There's an add address function. And now notice there is one piece of syntax. We've seen this before in C. Similar in spirit. You can think of dollar sign mail as a variable, which it is. But it's a struct inside of which are not only properties, variables if you will. But it turns out that in PHP, which is an object oriented programming language, like Java if you took APCS. Dollar sign mail, if you want to-- it also has functions inside of it, or methods. So this is to say that special PHP mailer library, if I've got a variable thereof, if I want to call a function that comes with that library, for today's purposes, just know you use the arrow notation. There's no dot notation. It's just the arrow. But that's not a pointer. It's just borrowed from C's syntax. So call add address inside of this library's object or variable. All right. This is the magical line. That's how I send an email. That is the equivalent of opening up Gmail, typing it out, and hitting send. But it's going to instead send an email to this address, with this body, from the CS50 bot. And now key line. This line was absent in like 2011 when I think I last tried this. That line there, of course, clears the addresses. So logically, if I don't clear the address after each iteration, the first email or text message goes to Alice, the second goes to Alice and Bob, the third goes to Alice and Bob and Charlie, hence the very expensive mistake I made that year. So let's see. Are there any questions before we send you all a text message with 10 percent probability? Any questions? All right. Let's me go in here and change the password to what should work, will likely get blacklisted by Gmail. So they might not all go out, since they probably don't like us sending 800 emails in a for loop all at once. Since that's not particularly human behavior. Oh, I'm going to change one other thing. Up at the top, I'm going to sent-- change the file to students dot CSV. And I won't open this, but this is an identical CSV file with not 100 staff, but 800 students, just from Harvard, because Yale has October recess this week. And it seems like kind of a jerk thing to do to text all of them as to why they're not in class on holiday. That's OK. Just Harvard students today inside of that file. And now let's go back to my terminal window. I'm kind of nervous. OK so now I'm going to go into the directory, and PHP text dot PHP. How about one brave volunteer? So I don't want this on me. OK, come on up. What's your name? MAYA: Maya. SPEAKER 1: Maya. Come on up, Maya. All right. Let's see if this works. I put my own email address in the file-- my own phone number in the file, so that hopefully I'll get one as well. Nice to meet you. MAYA: Likewise. SPEAKER 1: So all you have to do is hit Enter to send 800 text messages, if I didn't screw up. Nice. Could take a while, statistically, until we get to an email address-- a text message that's in the room right now. Let's linger and see. AUDIENCE: [WHISTLING] SPEAKER 1: Oh, yes. AUDIENCE: Oh, gotcha. SPEAKER 1: For loops are-- this is not slow because of PHP. This is slow because Gmail is throttling us and not letting us send more than like one email per second. Anything? This was a hard thing for me to test at home with just me and my one phone, so. Is that hopefully from the bot? Yes? No? Say yes. No? It's from a friend? Awkward. OK. Pretty sure it's working though. Uh oh. They black-- oh, wait a minute. Oh, you know what? One moment please. Only Maya and I-- Mia, was it? MAYA: Maya. SPEAKER 1: Maya, are going to know what I did wrong here. Oh, wait a minute. I think I just sent 100 text messages to 555-1212. Stand by. I can't win any year. OK. Maya? Fix that in post production. Dammit! Following from address. OK, stand by. Sorry. It's painful every year. OK, one moment. This is good. I am instead going to do this. Print address. OK, stand by. Print addresses, bracket i. Yeah, I like that. Dollar sign-- OK I'll explain what I'm doing in a moment, after I've run this. Every year. OK, here we go. I have just-- and I don't want to show everyone's phone number, but Maya can confirm with a nod of the head, that she sees everyone's phone number in the class that I'm going to copy into a program called Gmail. And if in Gmail, what do we want to say? Miss you. Love-- that's not from me. I haven't even hit send yet. So let's go ahead and do this, if I can zoom in. OK. So I'm using a program called Gmail now. If Maya, you'd like to click the Send button, we will simulate what that code should have done. Anything? [BEEPS] AUDIENCE: Yep. SPEAKER 1: Yes? Salvation? AUDIENCE: Yep. SPEAKER 1: Miss you. And I'm going to send out the rest. I sent out half because I didn't think Gmail would let those go through. So just remember, today is the day that you learned that I can use Gmail. That was horrifying. A big applause to Maya. Thank you. All right, so. what [BEEPS] We got a few beeps, yes? All right. Now I'm going to get 700 really unhappy emails back from classmates. So at least we'll see if that was worth it. So what went wrong? I'll figure out what went wrong after the fact, but just look how easy it was to do that in PHP. So what can we actually do now that we have this expressiveness of PHP. That was-- that was horrible. All right. So that was what should have gone out. This was me testing this morning on my phone, actual screenshot of my phone. But now let's consider why we're actually introducing all of this stuff in the first place. So the goal is not to write these programs that are written at the command line, right? So I wrote a simple hello program, I wrote a little program that does conditionals, and used a read line and so forth. And in theory, I just wrote a program that sent out 800 text messages, give or take 800. And that program was all still run at the command line. And that of course is not the web, right? The goal now is to start using what I claim is an easier to use language, daresay a more powerful language in terms of the features that come with it, to start writing code that generates web pages. So last time and last week, we talked about HTTP and HTML. And what's nice about HTML is that it's just pure text. And text is certainly something that you can print by literally calling the print f function, or the print function. And indeed, that's what PHP is now going to allow us to do. So among the examples we have in today's source code, in addition to some of the code that I put up there a moment ago, we have programs like this for instance. Froshims, or Freshman Intramural Sports, was actually one of the first extracurriculars I got involved with years ago. And my roommate and I, with some other kids on campus, used to run the froshims program. I'm getting my text messages now. Now so we, back in the day, so this was 1996 or so, there was an internet, but there was no process-- there was no website for froshims. And so if you wanted to sign up for soccer or volleyball or whatever, you would fill out this thing called a piece of paper, and you would walk across Harvard yard, and you would slide it into the mail slot of the proctor, who was in Wigglesworth, one of the dorms. And this were you registered. And he or she would then compose an email to you manually, much like I just did here with Maya, and then you would be confirmed as having been registered. So this was like low hanging fruit, so to speak. It was kind of stupid that we were using paper for this. I wanted us to be able to just go on a website, or have the freshmen go on a website, register for sports, and just automate a lot of this stuff by putting their names and emails and so forth into a database. And in fact, the very first version of the website, using super ugly HTML, might have looked something like this. It was actually, ironically, more embarrassing looking than this back then. But I used a programming language. Not PHP, but rather called Perl, which is an older language, but very similar in spirit. And I just completely taught it to myself. And it took me a while to figure it out, asking lots of questions of friends. But the ideas there were exactly the same. Because what PHP was really designed for is not the command line stuff we just played with, but for web programming. It's really tied in its feature set to the web, as follows. This is froshims. And if I wanted to register in this form, this is quite ugly, certainly, but let me go ahead and be a less comfortable student, and whatever sport for Matthews, click Register. What I want to be able to do is submit information from a form, not to Google's server like we did last time, completely cheating by using their backend, I want to implement my own backend code. Which means write PHP code that lives at a URL that form data can be submitted to. And then your code, written in PHP on a server, can then respond to that user input. Like his or her name, or comfort level, or dorm, and then do something with it. In this case, I just stupidly printed it out as text, which is not all that pretty. But you could certainly imagine, if you know HTML, and you'll soon know how to generate HTML with print f, and print, and similar functions, you can certainly generate a prettier web page that says, hey David, you are now registered. You're a less comfortable student from Matthews, right? You can just use a whole bunch of %ses, or the curly braces and dollar sign notation I used a moment ago, to generate text that's more user friendly than this. So let's take a look at this one file. Froshim zero dot PHP looks like this. When I reload CS50 IDE, froshim zero looks like this. This is froshim zero dot PHP. And what do you notice about this file? AUDIENCE: [INAUDIBLE] SPEAKER 1: Sorry, a little louder? AUDIENCE: [INAUDIBLE] It's all in HTML. And in fact, it is, because what's interesting about PHP is that it was designed to be, for better or for worse, intermingled with HTML code. And in fact, even though this file, froshim zero dot PHP, has a PHP comment at the top of it, it's all just HTML. But by contrast, if I open up, let's say, register zero dot PHP, which just has a big comment at the top. This too looks almost entirely like HTML, except for what? Line, what, 21 looks a little weird. But notice I'm entering PHP mode with open bracket question mark PHP. Then I've got some stuff. And then at the end of that line almost I have, question mark PHP. And this is what I mean by intermingled. You can write HTML that you just want the server to spit out. But if you want to do something dynamic partway through the page, like insert my name or dorm or comfort level, I can use a function like print r, which is print recursive, which just means print out this variable, formatting it however you want. It's really not for human purposes, it's just for debugging or diagnostic purposes. So that's how I did that. If I instead go froshims two dot PHP, notice that the action of this form is not registered zero dot PHP as the old-- the previous one actually was. But it's registered two dot PHP. So let's look at how this one behaves a little differently. If I go into version two. If here, if I register as David, less comfortable, from dorm of Mathews, register. So this time it said, you are registered, not really. Let's see what I did here. If I look at register two dot PHP, this has some more PHP code. It's a little cleaner, although it still wraps a little long on this line. Notice here. I print out my HTML tag, my head tag, my title tag, the head, the body. And then I start to say things like enter PHP mode. And so that tag, open bracket PHP-- question mark PHP says, hey, server, execute-- interpret the following stuff as PHP until you see the end tag. And even though you might not know any other PHP than you've seen thus far, you can kind of read it pretty intuitively. If name is empty, or comfort is empty, or dorm is empty, what do I do? What do I say to the user? You must provide your name, comfort, and dorm, and so forth. Else, I say you are registered, well not really. And I say not really because there's no database. I'm not doing anything with the data. I'm just throwing it away for demonstration purposes. Now I kind of skimped over line 22. There's more syntax there, but dollar sign underscore post is kind of interesting. And this is what's nice about PHP. In PHP, you have what are called a few super global variables. They are sort of even more important than global variables. And these, all capitalized as such, come with PHP. So if you have a server that has a web server installed, like Apache, and you install the language support for PHP, all of a sudden you can start using these super global variables in your code. And what's nice about PHP is that if you just write a file that ends in dot PHP, put it on a web server, and then you submit a form to it via that action tag and a form tag, that action attribute in the form tag, PHP and the web completely figures out how to grab all of those key value pairs out of the URL like question mark q equals cats, it will figure out how to q and cats. If you submit a photo, or a username, or a password to like Facebook, PHP will figure out for you where all of that data is. And it will just hand you an associative array called dollar sign underscore post, or dollar sign underscore get, depending on whether you're using get or post submissions. And it will just hand you a super global variable, so that if you want to get at the name that the user submitted via that web form, you literally just say the name of the super global variable, quote, unquote, name. And quote, unquote comfort, and quote, unquote dorm. And we're going to be able to do this and so much more with PHP. And even though this was a whirlwind glance at it, we'll dive in much more next week. We'll introduce a database so that you're actually going to start implementing your own e-trade based-- like website in just a week's time. So we'll see you next time, and hope you got the text messages. Bye. [MUSIC PLAYING] [DOOR OPENING] SPEAKER 2: Hey. SPEAKER 3: What's up? SPEAKER 2: What are you doing? SPEAKER 3: Working on a problem set. SPEAKER 2: Nice. High five. [HIGH FIVE] What are-- uh, what are you doing here? SPEAKER 3: Just hanging out. Just got back from the gym. I couldn't help but notice when we high-fived, that you have pretty rough hands. Do you go to the gym? SPEAKER 2: No. No. SPEAKER 3: Dude, you look pretty big. Which is bad, because everyone knows 8-ball is the big man on campus. High-five. SPEAKER 2: Uh, no. No, I think I'm good. I think I'm good.