CS50x 2024 - Lecture 6 - Python - Çift Dilli Altyazılar

Thanks for watching!
You Thanks for and All right.
This is CS50,
and is finally week six,
and this is that week we promised wherein we finally transitioned from C,
this level,
older language via which we explored memory and how really computers work underneath the hood to what's now called Python,
which is more higher level language whereby We're still going to be able to solve the same types of problems,
but it's going to suddenly start to get much,
much easier because what Python offers as do higher level languages more
generally are what we might describe as abstractions
over the very low level ideas that you've been implementing in sections and problem sets and so much more.
But recall from week zero, where we began, was our simplest of programs that just printed hello world.
Things escalated quickly thereafter in week one where suddenly we had all of this new syntax,
but the idea was still the same of just printing out hello world.
Well, as of today, a lot of that distraction, a lot of the visual distraction goes away entirely such that what used to be this in sea will
now be.
quite simply this in Python.
And a bit of a head fake in that we're going to see some other fancier features of Python.
But you'll find that Python's popularity in large part derives from just how relatively readable it is.
And also is what ultimately see just how exciting and filled the ecosystem among Python programmers is.
That is to say, there's a lot more libraries.
There's a lot more problems that people have solved in Python
that you can now incorporate into your own programs in order to stand on their shoulders and get real work done faster.
But recall, though, from C that we had a few steps, by which to actually compile that kind of code.
So we got into the habit of make to make our program called Hello, and then we've been in the habit of running it.
With dot slash hello the effect of which of course is to like feed all of the zeros and ones that compose the hello program
Into the computer's memory and in turn the CPU
We revealed that what make is really doing is something a little more specific
Namely running clang the seed language compiler specifically with some automatic command line argument And so as to output the name that you want,
link in the library that you want, and so forth.
But with Python wonderfully, we're going to get rid of those steps, too, and quite simply run it as follows.
Henceforth, our programs will no longer be in
files, ending in .c, suffice it to say, our files starting today are going to start ending with .py, which is an indication.
to the computer, Mac OS, Windows, Linux, or anything else, that this is a Python program.
But C...
Wherein we've been in the habit of compiling our code and running it,
compiling our code and running it anytime you make a change with Python those two steps sort of get reduced into one such that anytime you make a change and want to rerun your code,
you don't explicitly compile it anymore.
You instead just run a program called Python,
similar in spirit to clang,
but whereas clang is a compiler,
Python will see is not only the name of the language,
but the name of a program and the type of that program is that of interpreter.
An interpreter is a program that reads your code top to bottom.
Does what it says without having this intermediate step of first
Having to compile it in zeros and ones so with that said let me do
This let me flip over here to vs code and within vs code let me
Write my first python program and as always i can create a new file with the code
Command within vs code i'm going to create this file called hello.py for instance.
And quite, quite simply, I'm going to go ahead and simply do print, quote, unquote, hello world.
And if I go down to my terminal window,
instead of compiling this,
I'm instead going to interpret this program by running Python In name of the file, I want Python to interpret, hitting enter.
And while Now you see hello world.
But let me go ahead and compare this at left.
Let also go ahead and bring back briefly a file called hello
.c And I'm going to do this as we did in the very first day of C where I included standard io.h.
I did int main void.
I did inside of their printf quote unquote hello comma world.
quote, semicolon.
And me go ahead and VS code.
And you drag your file over to the right or the left, you actually split screen things, if of help.
And what I've done here is, and let me hide my terminal window, I've now compared these two files left and right.
So here's hello.c from, say, week one.
Here's hello.py from week six now.
And the obvious,
the differences are perhaps obvious but there's still some there's a subtlety at least one subtlety beyond
getting rid of lots of syntax what did I apparently omit from my python version
even though it didn't appear to behave in any buggy way yeah sorry The library.
So I didn't actually have to include any kind of library, like standard I.O.
library, print apparently in Python, just works.
So I don't need to use main anymore.
So this main function to be clear,
we was required in C, because that's what told the compiler what the main part of your program is.
And you can't just start writing code otherwise.
What else do you see?
So, there's no more semicolon, wonderfully enough, at the end of this line, even though
there was here, and things are getting a little more subtle now.
So the new line,
so recall that in printf,
if you wanted to move the cursor to the next line when you're done printing, you had to do it yourself.
So it seems as though Python,
because when I interpreted this program I to go, the cursor did move to the next line on its own.
They sort of reverse the default behavior.
So those are just some of the salient differences here.
One, you don't have to explicitly include standard libraries, so to speak, like standard I.O.
You don't need to define a main function anymore.
You just start writing your code.
You don't need these parentheses, these curly braces.
printf is now closed.
seem and you don't need the backslash n.
Now there is one thing that's also a little looser,
even though I didn't do it here, even though in C, it was required to use double quotes.
Anytime you want to use a string, a.k.a.
char star,
in Python, as with a lot of languages nowadays, you can actually get away with just using single quotes, so long as you are consistent.
Generally speaking, some like this because you don't have to hold shift and therefore you just hit one key instead of two.
So there's an argument in terms of efficiency.
However, if you want to use an apostrophe in your string, then you have to escape it.
And so in general stylistically, I'll use double quotes in this way.
But with things are getting a little...
little looser now with Python whereby that's not actually a requirement.
But what's especially exciting with Python and really a lot of
higher level languages is just how much real work you can get done relatively quickly.
So you've just spent quite a bit of time, dare say, implementing your spell checker and implementing your own dictionary of sorts.
Well, let me pose that maybe we should have asked you to do that in Python instead of C.
Well, let me go ahead and do this.
Let me close these two tabs and reopen my terminal window.
Let me go into a directory called speller that I downloaded in advance from for class.
And if I type LS in here,
you'll notice that it's very similar to what you spent time on with problem set five, but the file extensions are different.
There's a dictionary dot pi instead of dictionary dot c.
There's a speller dot pi instead of a speller dot c,
and there's the exact same directories, dictionaries and texts that we gave you for problem set five.
So let me just stipulate that I spent time implementing speller dot c in python.
pie, but I didn't go about really implementing dictionary.py yet.
And so why don't we go ahead and actually implement dictionary.py together by doing this?
Let me clear my terminal, do code dictionary.py.
And let me propose that we implement, ultimately, four functions.
And what are those functions going to be?
Well, they're going to be the check function, the load function, the size function, and the unload function.
But recall that in problem set five, you implemented your own hash table.
And so while there isn't a hash table data type in Python, I'm going to go ahead and do this.
I'm going to create a variable, a variable, in dictionary.py called words.
I'm to and do I'm going I'm to make it a set in the mathematical sense.
A set is a collection of things that won't contain duplicates.
Any duplicates will be filtered out.
So going to now, after that, creating that one global variable, I'm going to create a function called check, just as you did.
And check takes as input a word.
And if I want to check if a word is in that set of words, I can simply do word.lower in words.
And that's it.
Let me now define another function called load,
which recall took an argument, which was the name of the dictionary you want to load into memory.
Inside of my load function, I'm now going to do this.
I'm going to say with open dictionary as a variable called file.
And in there,
I'm going to go ahead and update the set of words to be the updated version of whatever's in this file
as a result of reading it and then splitting its lines,
whereby this file has a big, long column of words, each of which is separated by a new line.
Split line is going to split all of those into one big collection.
And then I'm just going to go ahead and load I'm now going to go ahead and define a size function just as you did.
But in Python,
I'm going to go ahead and just go ahead and return the length of that set of words where length or LEN is a function itself in Python.
And I'm going to do one last function.
It turns out that in Python, even though for this program, I'm going to go and implement a function called unload.
There's not actually anything to unload in Python because Python will manage your memory for you.
malloc is gone.
Free is gone.
Pointers are gone.
It handles all of that seemingly magically for now for you.
So here then is I claim what you could have done with problem set five if implementing it in Python instead.
Let me go ahead and open my terminal window,
let me increase its size,
let run python of speller.py, which is the name of the actual program, not the dictionary per se that I implemented.
Let's run it on a file called home.text, because was a particularly big file.
And I hit Enter now, we'll see hopefully the same output that you saw in C flying across the screen.
And if I Eventually we should see that same summary at the bottom as to how many words seem to be misspelled,
how many words were in the dictionary, and ultimately how fast this whole process was.
Now the total amount of time required was 1.93 seconds, which was actually longer than it seemed to take.
That's because we're doing this in the cloud and it was taking some amount of time to send it.
and of the text in my screen.
But code was only taking 1.93 seconds total on the actual server.
And hopefully, these same kinds of numbers line up with your own.
The difference being what I did not have to implement for this spell checker is your own hash table,
is your own dictionary, literally, beyond what I've done using Python here with some of these.
built-in features.
So why you see?
Why not always use Python, assuming that you prefer the idea of being able to whip up within seconds?
The entirety of problem set five?
How much you choose now?
between languages.
And I apologize if you're harboring resentment that this wasn't a week earlier.
Why Python or YC?
Any instincts?
Any thoughts?
Just a reason.
Yeah, we're Yeah, really good conjecture.
So you always thought that Python was slower than C and takes up more space than C odds are that's in fact correct.
So even though ultimately this 1.93 seconds is still pretty darn fast.
Odds are it's a little slower than the C version would have been.
It's possible too that my version in Python actually does take up a Yeah.
underneath the hood.
Why?
Well, because Python itself is managing memory for you.
And it doesn't necessarily know a priori how much memory you're going to need.
You, the programmer might, and you, the programmer writing in C, allocated presumably exactly as much memory as you might have
needed last week with problem set five, but Python's got to maybe do that.
do its best to effort for you and try to manage memory for you.
And there's going to be some overhead.
The fact that I have so many fewer lines of code,
the fact that these lines of code sort of solve problems that five for me means that Python or whoever invented Python,
they wrote lines of code to sort of give me this functionality.
And so if you think of Python, it's not on is a middleman of sorts, it's doing more work for me.
It's doing more of the heavy lift.
So it might take me a bit more time,
but my gosh, look how much time it has saved in terms of writing this code more quickly.
And arguably,
this code is even more readable,
or at least will be after today, week six, once you have an eye for the syntax and features of Python.
on itself.
So beyond that, it turns out you can do other things pretty easily as well.
Let me go back into my terminal window.
Let me close this dictionary dot pi.
Let me go into a folder called filter in which I have this same bridge that we've seen in the past across the river there.
So here's a bridge.
This is the original version of this particular photograph.
Suppose I actually want to write a program that blurs this.
Well, you might recall from problem set 4,
you could write that same code in C by manipulating all of the red, the green, the blue pixels that are ultimately composing that file.
But let me go ahead and propose this instead.
Let me create a file called blur.py.
And in this file...
Let me go ahead and just go ahead and import a library.
So from the Python image library,
P-I-L, let go ahead and import something called image, capital I, and image filter, capital I, capital F.
So I'm going to do before equals image.open,
quote unquote,
bridge.Bmp,
then let me and
variable called after and set that equal to before dot filter and then in parentheses image filter spelled as before dot box blur and then we'll give it a of 10.
How much do I want to blur it?
For instance, after that, I'm going to literally call after dot save and let's save it as a file called out dot BMP.
And that's it,
I propose that this is how you can now write code in Python to blur in image much like you might have for problem set four.
Now let me go ahead in my terminal window and run Python of blur.py.
When I hit enter, those four lines of code will run.
It seems to have happened quite quickly.
Let me go ahead and open now,
out.BMP, and whereas the previous image looked like this a moment ago, let me go ahead and open out.BMP.
And hopefully you can indeed see that it blurred it for me using that same code.
And if we want things to escalate a little more quickly, let me go ahead and do this instead.
Let me close blur.pmp.
Let me go ahead and open a file called edges.py.
And maybe in edges.py, we can use the same library.
So from the Python image library, import image and import image filter.
Let me go ahead and create another variable call before.
Set it equal to image.open quote unquote bridge.pmp.
Just like before.
Let me create another variable called after.
Set that equal to before.
imagefilter.findedges, which comes with this library automatically, and lastly the same thing, save this as a file called out.bmp.
So if you struggled perhaps with this one previously whereby you wrote for the more comfortable version of problem set for edge detection,
so to speak,
well, you might have then created a file that given an input like this, the original bridge.bmp, this new version,
out.bmp with just four lines of code, now looks like this.
So again,
if this is a little frustrating that we had you do all of this in C,
that was sort of exactly the point to motivate that you now understand nonetheless what's going on underneath.
the hood, but with Python, you can express the solutions to problems all the more efficiently all the more readily.
And just one last one too,
it's very common nowadays in the world of photography and social media and the light to do face detection for better or for worse.
And it turns out that face detection, even if you want to integrate it into your own application, is something that lots of...
of other people have integrated into their applications as well.
So Python,
to my point earlier of having this very rich ecosystem of libraries that other people wrote,
you can literally run a command like pip install face underscore recognition if you want to add support to your code
space or to your programming environment more generally for the notion of
face recognition in fact this is going to automatically install from some server
elsewhere a library that someone else wrote called face recognition and with
this library you can do something like this let me go into a directory that I
came with in advance let me go ahead in LS in there and Detect.py and recognize.py,
which are going to detect faces and then recognize specific faces, respectively.
And two files I brought from a popular TV show, for instance.
So I open Office.jpg, here is one of the early cast photos from the TV series, The Office.
And here is a photograph of someone else.
one specific from the show, Toby.
Now, this is, of course, Toby's face.
But what is it that makes Toby's face a face?
More generally,
if I open up Office.jpg and I asked you,
the human,
to identify all of the faces in this picture, wouldn't be that hard with a marker to sort of circle all of the faces.
But how?
Why?
How do you, as humans, detect faces, might you think?
Features, yeah, like eyes, nose, generally in a similar orientation, even though we all have different faces ultimately.
But there's a pattern to the sort of, to the shapes that you're seeing on the screen.
Well, it out this.
has been trained, perhaps via artificial intelligence over time, to recognize faces, but any number of different faces, perhaps among these folks here.
So if I go back into my terminal window here...
Let me go ahead and run, say, Python detect.py, which I wrote in advance, which uses that library.
And what that program is going to do, it's to do some thinking.
It's just found some face.
And let me go ahead now and open a file.
It just created called detected.jpg, which I didn't have in my folder a moment ago.
But when I open this here file, you'll now see all of the faces based on this library's detection thereof.
looking for a very specific face among them, maybe Toby's.
Well, maybe if we write a program that
doesn't just take as input the Office.jpg,
but a second input,
Toby.jpg,
maybe this library and code more generally can distinguish Toby's face from gyms,
from pams, from everyone else in the show, just based on this one piece of code.
of training data, so to speak.
Well, let me instead run Python of recognize.py and hit enter.
It's going to do some thinking, some thinking, some thinking.
And it is going to output now a file called recognize.jpg, which should show me his face, ideally, specifically.
And so what has it done?
Well, with sort of a green marker, there is Toby among all of these faces.
That's maybe a dozen or so lines of code, but it's built on top of this ecosystem of libraries.
And is, again, just one of the reasons why Python is so popular.
Undoubtedly, some number of years from now, Python will be out, and something else will be back in.
But that's indeed a model.
is not to teach you C,
not to teach you Python,
not in a couple of weeks to teach you JavaScript and other languages too, but to teach you how to program.
And all of the ideas we have explored and will now explore more today, you'll see recurring for languages in the years to come.
Any questions before we now dive into how it is this code
is working and why I type the things that I did before we forge ahead.
Any questions along these lines?
Anything at all.
No?
All right.
So.
How does Python itself work?
Well, let's do a quick review as we did when we transitioned from scratch to see this time, though, from scratch say to Python.
So in Python, as with many languages, there are these things called functions, the actions and verbs that actually get things done.
So here on the left,
recall from week zero was the simplest of functions we played with first,
the say block, which just literally has the cat say something on the screen.
We've seen in C,
for instance,
the equivalent line of code is arguably with the parentheses,
the quotation marks, the backslash, and the semi colon in Python now, it's going to indeed be a little simpler than that.
But the idea is the same as it was back in week zero libraries.
So we've seen already in C, and now we've already seen in Python that these things exist too.
In the world of C, recall that besides the standard ones, like standard IO.
that header file,
we could very quickly introduce CS50.h,
which was like your entry point, the header file for the CS50 library, which gave you a bunch of functions as well.
Well, we're going to give you a similar library for at least the next week or
two training wheels for Python specifically that, again, we'll take off so that you can stand on your own even with CS50 behind you.
But the syntax, for using a library.
And is a little different.
You don't include a .h file, you just import instead the name of the library.
What does that actually mean?
Well, if there are specific functions in that library you want to use, in Python you can be more precise.
You just have to say give me the whole library for efficiency purposes.
as you can say, let me import the getString function from the CS50 library.
So you have finer-grained control and Python,
which can actually speed things up if you're not loading things unnecessarily into memory if all you want is, say, one feature therein.
So here,
for instance,
in Scratch,
was an example of how we might use not only a built-in function,
like the say block, or in C in the printf, but how we might similarly now do the same but achieve this in Python.
So how might we do this?
Well, in or rather in C, this code looks a little something like this, back in week one.
We declared a variable of type string.
that to be char star,
I gave this a variable name of answer for parity with scratch,
then we use CS50's own get string function and ask,
for instance,
the same question as in the white oval here,
and then using this placeholder syntax,
these format codes,
which was printf specific,
we could plug in that answer to this pre-made string where the percent S is and we saw percent I and percent F and a bunch of others as well.
So this is sort of how in C you approximate the idea of concatenating two things together,
joining two things just as we did here in scratch.
So on Python it turns out it's not only going to be a little easier but there's going to be
even more ways to do this and so even what might seem today like a lot of different syntax,
it really is just different ways stylistically to achieve the same goals.
And over time,
as you get more comfortable with this,
you, too, will develop your own style,
or if working for a company, or working with a team, you might collectively decide which conventions you want to use.
But here, for instance, is one way.
You could implement this.
Same idea in Scratch, but in Python instead.
So notice, I'm going to still use a variable called answer.
I'm going to use CS50's function called getString.
I'm still going to use quote unquote, what's your name?
But down here is where we see the most difference.
It's again not called printf in Python.
It's now called just print.
And what might you infer the plus operator is doing here?
It's not addition, obviously, in a mathematical sense.
But those of you who have perhaps programmed before, what the plus represent in this context?
It's indeed joining the two strings together.
So this is indeed, it concatenating the thing on the left with the thing on the right.
So you don't use the placeholder in this particular scenario.
You can instead a little more simply just use plus, but you want your grammar to line up.
So I still have H-E-L-O, comma space and then close quote because I want to form a full phrase.
Notice, too, there's also one other slightly more subtle difference on the first line besides the first line.
Let call in, what else is different?
I didn't declare the type of the variable.
So Python still has strings, as we'll see.
But you don't have to tell the interpreter what type of variable it is.
And this is going to save up some keystrokes.
And it's just going to be a little more user-friendly over time.
Meanwhile, you can do this also a little bit differently if you prefer.
You can instead trust that the print function in Python can actually do even more for you automatically.
The print function in Python.
can take multiple arguments separated by commas in the usual way.
And by default, Python is going to insert for you a single space between its first argument and its second argument.
So notice what I've done here is my first argument is quote unquote hello with the comma,
Then outside of the quotes,
I'm putting a comma because that just means here comes my second argument and then I put the same variable as before.
And I'm just going to let Python figure out that it should,
by default, per its documentation can join these two variables putting a single space in between them.
Can do this yet another way and this way looks a little weirder,
but this is actually probably the most common way nowadays in Python is to use what's called a format string or F string for short.
And this looks weird, to me still, it looks weird, but if you prefix a string in with an F, literally.
You can then use curly braces inside of that string in Python.
And Python,
when I'll print out literally a curly brace and a closed curly brace, it will instead interpolate whatever is inside of those curly braces.
That is to say,
if answer is a variable that has some value,
like David or something like that,
saying F before the first quotation mark,
and then using these curly braces there in is going to do the exact same thing of creating a string that says,
hello comma space David.
So it's going to plug in the value for you.
So you can kind of think of this as percent S,
but without that second step of having to like keep track of what you want to plug back in.
you literally put in curly braces, what do you want to put right there?
You the string yourself.
So given all of those ways, how might we actually go about implementing this or using this ourselves?
Well, let me propose that we do this here.
Let me propose that.
that I go back to VS code.
Let me go ahead and open up hello.py again.
And as before, instead of just printing out something like quote unquote hello world, let me actually print out something a little more interesting.
So let me go ahead.
the CS50 library import the function called getString.
Then, let me go ahead and create a variable called answer.
Let me set that equal to the return value of getString with, as an argument, quote unquote, what's your name?
Question And then, no semicolon at the end of that line.
But the next line, frankly, here can pick any one of those potential solutions.
So let me start with the first.
comma space quote plus answer.
And now, if I go down to my terminal window and run python of hello.py, I'm prompted for my name.
I can type in david and voila, that there then works.
Or I can tweak this a little bit.
I trust that Python will concatenate its first and second argument for me.
But this isn't quite right,
let me go ahead and rerun python of hello.py hit enter and type in David It's gonna be ever so slightly buggy sort of grammatically or visually if you will.
What did I do wrong here?
Yeah, so I had I left the space in there, even though I'm getting one for free from print.
So that's an easy solution here.
But let's do it one other way after running this to be sure.
D-A-V-I-D, and OK, now it looks like I intended.
Well, let's go ahead and use with that placeholder syntax.
So let's just pass in one bigger string as our argument.
Do hello, comma, and then in curly braces, answer like this.
Well, let me go down to my terminal window and clear it.
Let me run pipe.
and enter, type in D-A-V-I-D, and voila, OK, I made a mistake.
What did I do wrong here?
Minor, though it seems to be, yeah.
So the stupid little f that you have to put before the string to tell Python that this is a special string.
It's a format string or f string that it should additionally format for you.
So if I rerun this after adding that F, I can do Python if hello.py.
What's your name, David?
And now it looks the way I might intend,
but it turns out in You don't actually need to use getString in C,
recall we introduced that, because it's actually pretty annoying in C to get strings.
In particular, to get strings safely.
Recall those short examples we did with scanF, not too long ago.
And scanF kind of scans with the user types at the keyboard and loads it into memory.
But the fundamental danger with scanF when it comes to strings was what?
Why was it dangerous to use scanF to get strings from a user?
Yeah exactly what if they give you a really long string that you didn't
allocate space for because you're not going to know is the programmer in
advance how long of a string the human is going to type in so you might under you
might undercut it and therefore have too much memory being able to many characters being put into that memory,
thereby giving you some kind of buffer overflow, which might crash the computer or minimally your program.
So it turns out in Pussy, get was especially useful.
In Python, it's not really that useful.
All it does is use a function that does come with Python called input.
And fact, the input function in Python, for all intents and purposes, is the same as the get string function that we give to you.
But just to ease the transition from C to Python, we implemented a Python version of get string nonetheless.
But this is to say, if I go to VS code here, and I just change get string to input.
And in fact, I even get rid of the CS50 library at the top, this too should work fine.
If I rerun Python, if I load.py, type in my name David, and voila, I have that now working as well.
All right, questions about this use of get string or input?
or any of our syntax thus far.
All right, well, what variables?
We've used variables already,
and we already identified the fact that you don't have to specify the type of your variables proactively,
even though clearly Python supports strings thus far.
Well, in Python, here's how you might declare a variable that not necessarily is assigned like a string, but maybe an integer instead.
So in Scratch, here's how you could create a variable called counter, if you want to count things, and set it equal to 0.
In C, what we've done is this int counter equals 0 semicolon.
That's the exact same thing as in scratch.
But in Python, as you might imagine, we can chip away at this and type out the same idea a more easily.
One, we don't need to say int anymore.
Two, we don't need the semicolon anymore.
And so you just do what you intend.
If you want a variable, just write it out.
If you want to assign it a value, you use the equal sign.
If you want to specify that value, you put it on the right.
And just as in C, this is not the equality operator.
It's the assignment operator.
Recall that in Scratch, if wanted to increment a variable by one or any value, you could use this puzzle piece here.
Well, in C, you do syntax like this, which again is not equality.
It's saying add one to counter and then assign it back to the counter variable.
In Python, you can do exactly the same thing, minus the semicolon.
So you don't need to use the semicolon here.
But you might recall that in C, there some syntactic sugar for this idea, because it was pretty popular.
And you could shorten this in C as you can in Python to actually just this.
Plus equals one will add to the counter variable, whatever that is.
but it's not all steps forward.
You might be in the habit of using plus plus or minus minus.
Sorry, those are not available in Python.
Why?
It's the designers of Python decided that you don't need them, because this gets the job done anyway.
But there's a question down here in front unless it was about the same.
All right, so.
That's one feature we're taking away, but it's not such a big deal to do plus equal in this case.
Well, what about the actual types involved here beyond actually being able to define variables?
Well, recall that in the world of C, we had at least these data types, those that came with the
language in particular, and we played with quite a of these over time.
In Python, we're going to take a bunch of those away.
In Python,
you're only going to have access to a bool,
true or false,
a float, which is a real number with a decimal point typically, an int or an integer, and a string now known as stir.
So Python here sort of cuts some corners, feels like it's too long to write out strings.
So string in Python is called stir, S-T-R, but it's the exact same idea.
The notice,
though, that missing from this now, in particular, are double and long, which
recall actually used more bits in order to store information, will see that that might not necessarily be a bad thing.
In Python just simplifies the world and to do different types of variables,
but gets out of the business of you having to decide,
do you want a small int or a large int or something along those lines?
Well, let me go ahead and do this.
Let me switch back over to VS code here.
And why don't we actually try to play around with some calculations using these data types and more?
Let me go ahead and propose that we implement like we did way back in week.
One, a simple calculator.
So me do this, code of calculator dot c.
So I'm indeed going to do this in c first, just so that we have a similar example at hand.
So I'm going to include standard io dot h here at the top.
I'm going to go ahead and do int main void inside of main.
I'm going to go ahead and declare a variable called x and set that equal to get int.
And I'm going to prompt the user.
that value x.
But if I'm using GetInt, recall that actually is from the CS50 library.
So in C, I'm going to need CS50.h still for this example.
But back in week one, I then did something else.
I then said, give me another variable called y, set that equal to GetInt, and that equal to that, pass in that prompt there.
And then lastly, let's just do something super simple, like add two numbers together.
So in C, I'll use printf.
I'm going to go ahead and do percent.
n as a placeholder, and then I'm just going to plug in x plus y.
So all of that was in C.
So was a decent number of lines of code to accomplish that task, only three of which are really the logical part of my program.
Like these are the three that we're really interested in.
So let me instead now do this, code of calculator dot pi.
which is going to give me a new tab.
Let me just drag it over to the right so I can view these side by side.
And in calculator.py, let's do this.
From the CS50 library, import the getint function.
which is also available,
then let's go ahead and create a variable called x and set it equal to the return value of getInt passing in the same prompt.
No semicolon, no mention of int.
Let's then create a second variable y, set it equal to getInt, prompt the user for y as before, noInt explicitly, no semicolon.
And now let's just go ahead and print out x plus y.
So it turns out that the print function in Python is further flexible that you don't need these format strings.
in integer, just pass it in integer.
Even if that integer is the sum of two other integers, so it just sort of works as you might expect.
So let me go down into my terminal here.
Let me run Python of calculator dot pi.
And when I hit Enter, I'm prompted for x.
Let's do 1.
I'm prompted for y.
Let's do 2.
And voila, I should see.
3 as the result.
So no actual surprises there.
But let me go ahead and, you know what, let's take away this training wheel, right?
We don't want to keep introducing CS50 specific things.
So suppose we didn't give you getInt.
Well, it turns out that getInt is still doing a bit of help for you, even though getString was kind of a throwaway.
And we could replace getString with input.
So let's try the same idea.
Let's go ahead and prompt the user for input for both x and y Python, instead of getInt from CS50.
Let me go ahead and rerun Python of calculator.py and hit Enter.
So far so good.
Let me type in one.
Let me type in 2, and what answer should we see?
Hopefully still 3, but nope.
Now the answer is 12.
Or is it?
Why am I seeing 12 and not 3?
Yeah, so it's actually concatenating what seemed to be two strings.
So we actually read the documentation for the input function, it's behaving exactly as it's supposed to.
It is getting input from the user from their keyboard.
But anything you type at the keyboard is effectively a string.
Even if some of the symbols happen to look like, or actually be decimal numbers, they're still going to come to you as strings.
And so x is a string, a.k.a.
and.k.a.a And we've already seen that if you use plus in between two strings or stirs,
you're going to get concatenation, not addition.
So you're not seeing 12 as much as you're seeing one two.
not 12.
So how can we fix this?
Well, in C, we this technique where we could cast one thing to another by just putting, like, int in parentheses, for instance, in Python, things are a little higher level such that you can't quite
get away with just casting one thing to another because a string recall is not necessary, is not the same thing as a char.
A string has one,
a zero or more characters,
a char always has one, and in C, there a perfect mapping between and single numbers in decimal, like 65 per capital A.
But in Python,
we can do something somewhat similar, and not so much cast, but convert this input to an int, and convert this input to an int.
So just like in C, you can nest functions.
You can call one function and pass its output as the input to another function.
And this now will convert x and y to integers.
And so now, plus is going to behave as you would expect.
Let me rerun Python of calculator.py, type in 1, type in 2, and now we're back to seeing 3 as the result.
If this is a little unclear this nesting, let me do this one other way.
Instead of just passing inputs output into int, I could also more pedantically do this.
x should actually equal int of x, y should actually equal int of y.
This would be the exact same effect.
It's just like two extra lines where it's not really necessary.
But that would work fine.
If you don't like that approach, we could even do an inline.
We could actually convert x to an int and y to an int.
Why?
Well, int, int in the context of Python itself, is a function.
And it takes, as input here, a string or a stir and returns to you, the numeric, the integral equivalent.
So similar idea.
function, so all of the syntax that I've been tinkering with here is sort of fundamentally the same as it would be in C.
But this case, we're not casting, but converting more specifically.
Well, let me go back to these data types.
These are some of the data types that are available to us in Python.
Turns out there's a bunch of others as well that will start to dab.
with today.
You get a range of values,
a list of values,
which going to be like an array,
but better, tuples, which are kind of like x comma y, often combinations of their values that don't change.
Dict for dictionary, it turns out that in Python, you get dictionaries, you hash tables for free.
They're built into the language.
And we already saw that Python also gives you a data type known as a set,
which is just a collection of values that gives you, gets rid of any duplicates for you.
And as we saw briefly in speller,
and we'll play more with these ideas soon,
it's going to actually be pretty darn easy to get values or check for values in those there data types.
So that in C,
we were able to able to get input easily,
we had all of these functions in the CS50 library for Python, we're only going to give you these instead.
They're going to be the same name, so it's still get string, not get stir, because we wanted the functions to remain named the same.
But get float, get int, get string, all exist.
But again, get string is not all that useful.
But get int and get string.
yet float actually are.
Why?
Well, let me go back to VS code here.
And let me go back to the second version of this program, whereby I proactively converted each of these return values to integers.
So recall that this is the solution to the 1.2 problem.
run Python of calculator.py and input 1 and 2, I get back now 3 as expected.
But I'm not showing you is that there's still potentially a bug here.
Let me run Python of calculator.py and let me just not cooperate.
Instead of typing what looks like a number, let me actually type something that's clearly a string like cat.
We're going to see the first of our errors.
The first of our runtime errors.
And like in C, is going to look cryptic at first.
But this is generally known as a trace back.
Where it's going to trace back for you.
Everything your program just did.
Even though this one's relatively short.
And you'll see that calculator.py, line one.
I didn't even get very far before there's an error.
And then with all of these errors, carrot symbols here like this is a problem.
Why invalid literal for int function with base 10 quote unquote cat again just like in C it's very arcane it's hard to understand this the first time you
read it but what it's trying to tell me is that cat is not an integer and therefore the int function
cannot convert it to an integer for you.
We're going to leave this problem alone for now.
But this is why, again, get ints looking kind of good.
And get floats looking kind of good, because those functions from CS50's library will deal with these kinds of problems for you.
Now, just so you've seen it, there's another way to import functions from these things.
If you were to use, for instance, in a program, get floats.
get in and get string.
You don't need to do three separate lines like this.
You can actually separate them a little more cleanly with commas.
And in fact, if I go back to.
a version of this program here in VS Code, whereby I actually do use the GetInt function.
So let me actually get rid of all this and use GetInt as before.
Let me get rid of all this and use GetInt as before.
Previously, the way I did this was by saying from CS50 import GetInt.
If you know in advance what function you want to use.
But suppose for whatever reason, you already have your own function name GetInt and therefore it would collide with CS50's own.
You can avoid that issue.
that first statement we saw earlier, just the library itself.
Don't specify explicitly which functions you're going to use.
But thereafter,
and you could not do this in C,
you could specify CS50 dot get int,
CS50 dot get int,
in order to go into the library,
access its get int function,
and therefore it doesn't matter if you or any number of other people wrote an identically named function called getInt,
you're using here clearly CS50 zone.
So this is, again, just a more ways to achieve the same solution but with different syntax.
All right, any questions?
about any of this syntax or features thus far.
Now, all right, well, how about maybe another example here, whereby we revisit
conditionals, which were the way of implementing do this thing or this thing, sort proverbial forks in the road.
In Scratch recall, we might use building blocks like these to just check And if so, say so, in C, this looked like this.
And notice that we had parentheses around the x and the y.
We had curly braces.
Even though I did disclaim that for single lines of code, you can actually omit the curly braces.
But we always include them in CS50's code.
But you have the backslash n and the semicolon.
In a moment, you're about to see the pipe.
the Python equivalent this, which is almost the same.
It's just a little nicer.
This, then, is the Python equivalent thereof.
So what's different at a glance here?
Just to be clear, what's different?
So the conditional is not in parentheses.
You can use parentheses, especially if logically you need to group things.
But if you don't need them, don't use them as Python's mindset.
What else has changed here?
No curly braces, yes, so no curly braces around this.
And even though it's one line of code, you just don't use curly braces at all.
Why?
Because in Python, indentation is actually really, really important.
And we know from office hours and problem sets
occasionally that if you forgot to run style 50 or you didn't manually format your code beautifully,
C not actually going to care if everything is aligned on the left.
If you never once hit the tab character or the space bar, C, or specifically clang, isn't really going to care.
But you're teaching fellow, you're to care or your colleague in the real world, because your code's just a mess and hard to read.
Python though,
because you are not the only ones in the world that might be,
might have bad habits when it comes to style,
Python as a language decided, that's it, like everyone has to indent in order for their code to even work.
So the convention is Python is to use four spaces.
So one, two, three, four or hit tab and let it automatically convert to the same and use a colon instead of the curly braces.
For instance, to make clear what is associated with this particular...
Conditional we can omit though the backslash in for per before we can omit the semicolon
But this is essentially the python version thereof here in C in scratch if you want to do an if else
Like we did back in week zero in C
It's very similar to the if except you add the else clause and write out an additional print def like this in Python
We can tighten the same up.
If x less than y colon, that's exactly the same.
First line is the same.
All we're doing now is adding an else and the second print line here.
How about in scratch?
If had a three-way fork in the road, if, else, if, else, in C, it looked pretty much like that.
If, else, if, else, in Python, we can tighten this up.
And this is not a typo.
What jumps out at you is weird, but you got to just get you Yeah, LF.
And like years later, I still can't remember if it's LF or else if because other languages actually do EL, S-I-L.
So, and now I probably now biased all you to now question this, but LIF in Python.
ELIF is not a typo.
It's in the spirit of, let's just save ourselves some keystrokes.
So LIF is identical to ELTF, but it's a little tighter to type it this way.
All right.
So, if we now have this ability to express conditionals, what can we actually do with them?
Well, let me go over to this.
And let me propose that we revisit maybe another program from before, where we just compare two integers in particular.
So I'm in VS code, let me open up a file called say compare.py.
And in compare.py, we'll use the CS50 library just so we don't risk any errors, like if the human doesn't type an integer.
So we're going to go ahead and say from CS50 import getInt.
And in compare.py, let's get two variables, x equals getInt.
user for x.
So what's x question mark?
To be a bit more verbose, y equals get int, quote unquote, what's y question mark?
And then let's go ahead and just compare these two values.
So if x is less than y,
then go ahead and print out with print x is less than y,
close quote,
x is greater than y,
go ahead and print out x is greater than y, close quote, else, go ahead and print out, x is equal to y.
So the exact same program, but I've added to the mix getting a value of x and y.
Let me run python of compare dot pi, enter.
for x, two for y, x is less than y.
Let's run it once more,
x is two,
y is one,
x is greater than y,
and just for good measure let's run it a third time, x is one, y is one, x is equal to y.
So the code there say works exactly as you would expect, as you would hope.
But it turns out that in the world of Python,
We're actually going to get some other behavior that might actually have been what you expected weeks ago,
even though C did not behave this way.
In the world of Python and in the world of strings, AKA stirs, strings actually behave more like you would expect.
So by that I mean this.
Let me actually go back to this code.
And of using integers, let me go ahead and get rid of, I could do get string, but we said that that's not really necessary.
So let's just go ahead and change this to input.
And actually, you know, let's just start fresh.
Let's give myself a string called s and use the input function and ask the user for s.
Let's use another variable called t.
just because it comes after s and use the input function to get t, then let's compare s and t are the same.
Now, a couple of weeks ago, this backfired.
And if I tried to compare two strings for equality, it did not work.
But if I do if s equals equals t, print, quote unquote, same, else, let's go ahead and print different.
I dare say in Python, I think this is going to work as you would expect.
So of compare.py, let's type in cat and cat.
And indeed, those are the same.
Let run it again and type in cat and dog respectively.
And those are now different.
But in C, we always got different, different, different.
Even if I type the exact same word,
be cat or dog or hi or anything else, why in C were S and T always different a couple of weeks ago?
Yeah.
exactly in C string is the same thing as char star which is a memory address and
because we had called get string twice even if the human type the same things
that was two different chunks of memory at two different addresses so those two
char stars were just naturally always different even if the characters at those
addresses were the same python is meant to be higher level it's meant to be a
little more intuitive it's meant to be more accessible to folks who might not necessarily know lower level details.
So Python equals, equals, even for strings, just works the way that you might expect.
But in Python, we can do some other things to even more easily than we could in C.
Let me go back to VS code here.
Let me close compare dot pi.
Let's re implement a program from C called agree.
which allowed us to prompt the user for like a yes-no question.
Like, do you agree to these terms and conditions or something like that?
So let's do code of agree.pup.
and with a gree.py let me go ahead and actually let's go ahead and do this.
Let me also open up a file that I came with in advance and this is called a gree.c and
this is what we did some weeks ago when we wanted to check whether or the user had agreed to something or not.
So we use the CS50 library,
the standard IO library,
we a main function,
we used get char and then we used equals equals a lot and we used the two vertical bars which meant logical or is this thing true
or is this thing true and chiff agreed or not agreed.
So this works, and this is relatively simple.
It's like the right way to do it in C.
But notice it was a little verbose because we wanted to handle uppercase and lowercase, uppercase and lowercase.
So that did start to bloat the code, admittedly.
So let's try to do the same thing in Python and see what we can do.
the same or different, no pun intended.
So let me do this.
In a gree.py, why don't we try to get input from the user as before?
And I could use getString, but I'll go ahead and use input.
So S equals input, do you agree?
Question in double quotes.
And then let's go ahead and check.
If S equals equals capital Y,
and it's not vertical bar now,
it's actually more readable, more English-like, or S equals equals lowercase Y, then go ahead and print out agreed as before.
L if, say I did it there, L if S equals capital N, or S equals lowercase N, go ahead and print out So agreed.
So it's almost the same as the C version, except that I'm using literally OR instead of two vertical bars.
So let's run this.
So Python of agree.py, enter.
Do I agree?
Yes, for little y.
Let's do it again.
Python of agree.py, capital Y.
Yes, that works there.
And if I do it again with lowercase n, and if I do it with capital n, this program 2 seems to work.
But what if I do this?
Let me rerun Python of agree.py.
Let me type in.
Okay, it just ignores me.
Let me run it again.
Let type in no.
Just ignores me.
Let try it very emphatically.
Yes, in all caps, it just ignores me.
So there's some explosion of possibilities that ideally we should handle, right?
This is bad user interface design if I have the user has to type Y or N even if yes and no in English are perfectly reasonable and logical too.
So how could we handle that?
So in Python, we can use something like an array, technically called a list, to maybe check a bunch of things at once.
So let me do this.
Let me instead say not equality, but let me use the in keyword in Python and check if it's in a collection of possible values.
Let me say if s is in and here comes in square brackets just like in square brackets quote unquote y comma quote unquote yes.
Then we can go ahead and print out.
l if s is in this list of values, lowercase n or lowercase no, then we can print out, for instance, not agreed.
But is a bit of a step backwards, because now I'm only handling lowercase.
So let me go into the mix and maybe add capital Y.
Wait a Then maybe capital, yes.
Maybe yes, also.
I mean, weird, but we should probably.
And like, yes, I mean, there's like a lot of combinations.
So this is not going to end well, or it's just going to bloat my code unnecessarily.
And eventually, for longer words, I'm surely going to miss a capitalization.
So logically, whether it's in Python or C or any language, what might be a better design for this problem of handling why?
And yes, but who cares about the capitalization?
So don't use capitals.
You only support lowercase.
That's fine.
That's kind of a cop-out, right?
Because now, like the program's usability is worse.
Oh, so we could convert it to lowercase.
Yeah, although I did hear you say we could just check the first letter.
I bet that's going to get us into trouble.
And we probably don't want to allow any word starting with y,
any word starting with n,
just because illogically,
especially you want the lawyers happy, presumably you should probably get an explicit semantically correct word, like y or n or yes or no.
But yeah, we can actually.
converting this to something maybe smaller.
But how do we go about converting this?
In C,
that alone was going to be pretty darn annoying because we'd have to sort of use the two lower function
on each every character and compare it for equality.
Just feels like that's a bit of work.
But in Python, you're going to get more functionality for free.
might very well be a function like in C called 2 lower or 2 upper.
But the weird thing about C, perhaps in retrospect, is that those functions just kind of worked on the honor system.
2 lower and 2 upper just trusted that you would pass them an input,
an argument that is,
in fact,
a And in a lot of other higher level languages, they introduce this notion of object-oriented programming, which is commonly described as OOP.
And in the world of object-oriented programming,
your values can not only, your variables, for instance, and your data types can not only have values, they can also have functionality built in.
into them.
So if you have a data type like a string,
frankly, it just makes good sense that string should be upper caseable, lower caseable, capitalizable, and any number of other operations on strings.
So in the world of object oriented programming,
functions like too upper and too lower and is upper and is lower are not just in some random library that you can use.
they're built into the strings themselves.
And what this means is that in the world of strings in Python,
here, for instance, is the URL of the documentation for all of the functions, otherwise known as methods, that come with strings.
So you don't go check for a C-type library like we did in C,
you check the actual data type, the documentation, therefore, and you will see in Python's own documentation what functions, AKA methods, come with strings.
So a method is just a function, but it's a function that comes with some data type, like a string.
So let me propose that we do this.
In the world of object-oriented programming, we can come back to...
agree.py and we can actually improve the program by getting rid of this crazy long
list which I wasn't even done with and just canonicalize everything as lower case.
So just check for lower case y and lower case yes lower case n lower case no and that's it.
But to your suggestion let's force everything that the user types in two lowercase.
Not because we want to permanently change their input.
We can throw the value away thereafter.
But because we want to more easily logically compare it for membership in this list of values.
So one way to do this would be to literally do s equals s dot lower.
So here's the difference.
In the world of C, we would have done this too lower and pass in the value S.
But in the world of Python, and in general object-oriented programming, Java is another language that does this.
If S is a string, aka str, therefore is actually what's known in Python as an object.
An object cannot be used.
or attributes inside of them, but also functionality built in.
And like in C with a struct, if you want to go inside of something, you use the dot operator.
And inside of this string, I claim is a function, a.k.a.
method called lower.
Long story short,
the only takeaway,
if this is a bit abstract,
is that instead of doing lower,
and then in parentheses,
s, in the world of object-oriented programming, you kind of flip that and you do s dot name of the method.
And then open-print, close-print, if you don't need to pass in any arguments.
So this actually achieves the same.
So me go ahead and rerun agree.py.
Let me type in lowercase y.
That works.
Let me run it again.
Type in lowercase yes.
That works.
Let me run it again.
Type in capital y.
That works.
Let me type in capital yes.
All capital, all upper case yes.
That too works.
Let me try.
know, let me try know in lower case and all of these permutations now actually work, because I'm forcing it to lower case.
But even more interestingly in Python, if you're sort of becoming a languages person, then if you.
s that is being set the return value of input function.
And then you're immediately going about changing it to lower case.
You can also chain method calls together in something like Python by doing this.
We can get rid of this line altogether.
And then I can just do this dot lower.
And so whatever the return value of input is,
it's going to be a stir,
whatever the human types in, you can then immediately force it to lowercase and then assign the whole value to this variable called s.
You don't actually have to wait around and do it on a separate line altogether.
Questions, then, on any of this.
All right, let me do one other that's reminiscent of something we did in the past.
Let me go into VS Code here, clear my terminal.
Let's close both the C and the Python version of Agree.
And let's create a program called uppercase.py, whose purpose in life is to actually uppercase a whole string.
In the world of C, we had to do this character by character by character, and that's fine.
I'm going to go ahead and do it similarly here in Python, whereby I want to convert it character by character.
But unfortunately, before I can do that, I actually need some way of looping in Python, which we actually haven't seen yet.
So we need one more set of building blocks.
And in fact, if we were to consult the Python documentation, we'd see this and much more.
So in fact, here's a list of all of the functions that come with Python.
It's actually not that long of a list because so much of the functionality of Python is built into data types,
like strings, and integers, and floats, and more.
source of truth for Python documentation.
So as opposed to using like the CS50 manual for C,
which meant to be a simplified version of a publicly available documentation, will generally for Python point you to the official docs.
I will disclaim,
they're not really written for like introductory students and they'll generally leave some detail off and use arcane language,
but at this point in the term,
even if it might be a little frustrating at first,
it's good to see documentation in the real world,
because that's what you're going to have after the course, and so you'll get used to it through practice over time.
But with loops,
let's introduce one other feature that we can compare to scratch here,
for instance, in the scratch is how we might have repeated something for three times, like meowing on the screen.
In C, there a bunch of ways to do this.
And the clunkiest was maybe to do it with a while loop,
where we declare a variable called i,
set it equal to 0, and then iteratively increment i again and again, until it exceeds, until it equals 3, each time printing out meow.
In Python, we can do this.
In a few different ways as well, the nearest translation of C into Python is perhaps this.
It's almost the same.
And logically, it really is the same.
But you don't specify int, and you don't have a semicolon.
You don't have curly braces, but you do have a colon.
You use printf.
You use print, and you can't use i++, but you still can use i++ equals 1.
So logically, exactly the same idea is in C.
It's just a little tighter.
I mean, it's a little easier to read, even though it's very mechanical, if you will.
You're all of these.
You're defining this variable and changing it incrementally.
Well, recall that in C, we also use a for loop, which at first glance was probably more cryptic than a while loop.
but odds are by now, you're more comfortable or more in the habit of using loops.
Same exact idea.
In Python, though, So we might do it like this.
We've seen how in square brackets, you can have lists of values, like y, yes, and so forth.
Well, let's just do the same thing with numbers.
So if you want Python to do something three times,
give it a list of three values, like 0, 1, 2, and then print out Hello World that many times.
Now this is correct, but it's bad design, even if you've never seen Python before.
extrapolate mentally from this.
Why is this probably not the right way or the best way to do this looping?
Yeah, if you want to do it four times five times fifty times a hundred times
I mean surely there's a better way than enumerating all of these values and there is in fact in Python
There's a function called range that actually returns to you very efficiently a range of values and by default 0,
and then 1,
and then 2, and if you want more than that, you just change the argument to range to be how many values do you want.
So if you passed in range of 50,
you would get back 0 through 49, which effectively allows you to do something 50 times in total.
So this is perhaps the most Pythonic way, so to speak.
And this is actually a term of art.
Pythonic isn't necessarily the only way to do something, but it's the way to do something based on sort of consensus in the Python community.
So it's pretty common to do this.
But there's some curiosity here.
Notice I'm declaring a variable i, but I'm never actually using it.
In fact, I don't even increment it because that's sort of happening automatically.
Well, what's really happening here is automatically in Python on every iteration of this loop, Python is assigning I to the next value.
So initially, I is zero, then it goes through an iteration, then I is one, then I is two.
And then that's it if you only asked for three values.
But there's this other.
so you know whereby if you're the programmer and you know you don't actually care about the name of this variable,
you can actually change it to an underscore, which has no functional effect per se.
It just signals to the reader,
your colleague,
your teaching fellow that it's a variable and you need it in order to achieve a for loop,
but you don't care about the name of the variable cuz variable you're not going to use it explicitly anywhere.
So that might be an even more Pythonic way of doing things,
but if you're more comfortable seeing the eye and using the variable more explicitly, that's fine.
Underscore does not mean anything special.
It's just a valid character for a variable name.
So this is convention, nothing more technical than that.
What about a forever loop?
and scratch, like literally meow forever.
Well, over here, we can just use and see while true, printf meow again and again and again.
In Python, it's almost the same.
You still get rid of the curly braces.
You add the colon.
You rid of the semicolon, but there's a subtlety.
What else is different here?
Yeah, so true is uppercase.
Why?
Who Like world decided that in Python true is capitalized and false is capitalized in many other languages.
They're saying most they are not.
It's just a difference that you have to keep in mind or remember.
All right,
so now that we have looping constructs,
let me go back to my code here and recall that I propose that we re-implement a program like uppercase,
force an entire string to uppercase and in C we would have done this with like a for loop iterating from left to right.
But what's nice in Python frankly is that it's a lot easier to loop in Python
than it is in C because you can loop over anything that is iterable.
iterable in the sense that you can iterate over it from left to right.
So what do I mean by this?
Well, let me go ahead and in uppercase.py,
let's first prompt the user for a variable called before and set that equal to the return value of input,
giving them a prompt of before colon.
Then let's go ahead as we did weeks ago and print out just the word after,
just to make clear to the user what is actually going to be printed.
Then let me go ahead and specify the following.
loop for,
and previously you saw me use I,
but because I'm dealing with characters,
I'm actually going to do this instead, for c in before colon print out c dot up And that's it.
Now, this is a little flawed.
I will concede.
But let me run this.
Python of uppercase.py, let's type in something like cat, c, a, t, and all lowercase.
Enter.
All right, well, you after.
And I did get it right in the sense that it is capital C, capital A, capital T.
But it looks a little stupid.
And in order to fix this, we actually need to introduce something that's called named parameters.
So let me actually go ahead and propose that we can fix this problem.
by actually passing in another argument to the print function.
And this is a little different syntactically from C.
But I go back to BS code here, it turns out that there's two aesthetic problems here.
One, I did not want the new line automatically inserted after after.
Why?
Because just like in week one, I want them to line up nicely, or maybe in week two.
And I don't want a new line after CAT.
So even though it first.
So it might have seemed nice that Python just does the backslash end for you can backfire
if you don't actually want a new line every time.
So the syntax is going to look a little weird,
but in Python with the print function,
if you want to change the character that's automatically used at the end of every line, you can literally pass in a second argument.
called end and set it equal to something else.
So if you want to set it equal to something else, and that's something else is nothing, quote unquote, then that's fine.
You can actually...
specify n equals quote unquote down here to if you want to specify that the end at the end of every one of these characters should be nothing I can specify end equals quote unquote what
this implies is that by default and python the default value of this end parameter is actually always backslash n so if you want to override it and take that away you just literally change it
to quote unquote instead.
Now, if rerun this program, uppercase.py, type in cat and all lowercase, now you'll see two minor bugs here.
One was just stupid.
I had one too many spaces here.
But you'll notice that I didn't move the cursor to the next line after.
cat was printed in all uppercase and that we can fix by just printing nothing.
It out when you don't pass print an argument at all,
it automatically gives you just the line ending, nothing else, so I think this will move the cursor as expected.
So let me clear it now.
Run of uppercase.py and hit enter.
Type in cat in all lowercase.
Cross my fingers this time and now I have indeed capitalized this character by character by character just like we did in C,
but honestly,
this too not really necessary turns out I don't need to loop over a whole string because strings themselves come with methods
And if you were to visit the documentation for strings
You would see that indeed upper is a method that comes with every string and you don't need to call it on
a Individually I could instead get rid of all of this and just print out So,
instance, I can just print out before dot upper, and the upper function that comes with strings will automatically apply to every character they're in, and I think achieve
the same result.
So let me go ahead and try this again, Python of uppercase.py, type in CAT, enter, and indeed, it works exactly the same way.
Let me take this one step further.
Let me go ahead and combine a couple of ideas now here.
Let me go ahead and, for instance, let me get rid of this last print line.
Let me change my logic to be after equals the return.
And now I can use one of those f-strings and plug this in maybe here after.
And I can get rid of the new line ending.
I can specify this is an f-string.
So I'm just changing this around a little bit logically so that now I have a variable
called after that is the uppercase version of before.
And now if I do Python of uppercase.py type in CAT, That too now works.
And if I actually, let me add a space there.
If I run Python of uppercase.py type in CAT, that too now works.
And lastly here.
If you don't want to bother creating another variable like this, you can even put short bits of code inside of these format strings.
So I,
for instance,
could go in here into these curly braces and not just put a variable name,
you can actually put Python code inside of the curly braces inside of my string.
And so now if I run Python of uppercase.py type in cat, even that too, now works.
Now which one is is best.
This is kind of reasonable to put the bit of code inside of the string.
I would not start writing long lines of code inside of curly braces that start to wrap no less
because then it's just going to be a matter of bad style.
But this again is to say that there's a bunch of different ways to solve each of these problems.
And so up until now, we've generally seen not named parameters and is the first parameter we've ever seen that has a name.
up until now in C and up until a moment ago in Python, we've always been assuming that our parameters are positional.
What matters is the order in which you specify them, not necessarily something else.
Okay, that was a lot.
Any questions?
about any of this here.
No?
All right, feels like a lot.
Let's our 10-minute break here.
Fruit roll-ups are now served.
We'll be back in 10.
All right, we are back.
And recall that as we left off,
we had just introduced loops, and we'd seen a different bunch of different ways by which we could get, say, a cat to meow.
Let's actually translate that to some code and start to make sense of.
some of the programs with which we began like creating our own functions as we
did for the speller example at the very beginning and actually do this a little more methodically.
So let me go over to VS code here.
Let me go ahead and create a program called meow dot pie instead of meow dot
see is in the past and suffice it to say if you want to implement the idea of a cat
we can do better than just saying print meow print meow print meow this of course would work.
This is correct.
If the goal is to get the thing to meow three times but when I run pie meow.py,
it's going to work as expected, but this is just not good design, right?
We should minimally be using a loop.
So let me propose that we improve this per the building blocks we've seen,
and I could say something like 4i in range of three, go ahead and print out now quote unquote meow.
So this is better in the sense that it's still Prince meow meow,
but if I want to change this to like a dog and change them out to a wolf or something like that I can change it in one place and not three different places.
So just in general better design.
But what if now,
much like in scratch and in C,
I wanted to create my own meow function, which did not come with either of those languages as well.
Well as a teaser at the start of class,
we saw that you can define your own functions with this keyword DEF,
which is a little bit different from how C does it,
but let me go ahead and do this indeed in Python and define my own function meow.
So let me go ahead and do DEF,
space, meow, open paren, close paren, and then inside of that function, I'm just going to literally do for now.
print.
And now down here, notice, I can actually go ahead and just call meow.
And I can go ahead and call meow.
And can call meow.
And this is not the best design at the moment.
But Python does not constrain me to have to implement a main function, as we've seen thus far.
But I can define my own helper functions, if you will, like a helper function called meow.
So let me go ahead and just run this for demonstration sake and run python of meow.py.
that does seem to work,
but this is not good design,
and let me go ahead and actually do this for I in range of three,
now let me call the meow function, and this too should work.
If I do python of meow.py, there we have meow meow meow.
But I very deliberately did something clever here.
I defined meow at the top of my file,
but that's not the best practice because as in C,
when someone opens the file for the first time,
whether it's you,
a TF,
a TA,
a colleague,
you'd like to see the main part of the program at the top of my
because it's easier mentally to dive right in and know what this file is doing.
So let me go ahead and practice what I'm preaching and put the main part of my code,
even if there's no main function, per se, at the top of this file.
So now I have the loop at the top.
I'm calling meow online 2, and I'm defining meow on lines 5 and 6.
Well, instinctively, you can perhaps see where this is going.
If I run python of meow.py and hit enter, there's one of those trace backs that's tracing my error.
And here, my error is apparently online too in meow.py.
And you'll notice that, huh, the name now is not defined.
And so previously, we saw a different type of error, a value error.
Here, we're seeing a name error in the sense that Python does not recognize the name of this function.
And intuitively, why might that be?
Even if the error is a little cryptic, yeah.
Yeah, Python 2 is fancier as it seems to be then C.
It still takes things pretty literally top to bottom, left to right.
So if you define meow on line 5, you can't use it on line 2.
OK, so I could undo this, and I could flip the order.
But let me just stipulate that as soon as we have a bunch of functions,
it's probably naive to assume I can just keep putting my functions above, above, above, above.
And honestly,
that's going to move all of my main code,
so to speak, to the bottom of the file, which is sort of counterproductive or less obvious.
So it turns out in Python, even though I'm a main function, it's actually quite common to define one nonetheless.
So what I could do to solve this problem is this.
Let me go ahead and define a function called main that takes no arguments, in this case, let me indent that same code beneath it.
And now let me keep meow defined at the bottom of my So if we read this literally,
on line one, I'm defining a function called main, and it will do what is prescribed on lines two and three.
On line six, I'm defining a function called meow, and it will do what's prescribed on line seven.
So it's fairly straightforward, even though the keyword def is, of course, new today.
If I run, though, pythonofmow.py, you'd like to think I'll see three minutes.
But I see nothing.
I don't see an error, but I see nothing why intuitively.
What explains the lack of behavior?
I didn't call main.
So this is the thing,
even though it's not required in Python to have a main function,
but it is conventional in Python to have a main function, you have to call the function yourself.
It doesn't get magically called as it does in C.
So this might seem a little stupid and that's fine, but it is the convention in Python.
Generally, the very last line of your file might just be literally this.
Call main because this satisfies the constraint that main is defined on line one.
find on line 6, but we don't call anything until line 10.
So line 10 says, call main, so that means execute this code.
Line 3 says, call meow, which means execute this code.
So now it all works, because the last thing I'm doing is called main.
You can think of C as just kind of secretly having this line there for you.
the whole time.
But now that we have our own functions,
notice that we can enhance this implementation of meow to maybe be parameterized and take actually an argument itself.
So let me make a tweak here.
Just like in C and just like in scratch, I can actually let meow meow a specific number of times.
So let me do this.
Wouldn't it be nice instead of having my loop in main to instead just distill main into a single line of code and just pass in the number of times
you want the thing to meow.
What I could do in meow here is I have to give it a and I could call it anything I want.
I'm going to call it n for number which seems fine.
And then in the meow function I could do this for i in range.
of not three,
but in now,
I can tell range to give me a range that is a variable length based on what n is,
and then I indent the print below the loop now.
And this should now do what I expect, too.
Let me run Python of meow.py, enter, and there's three.
But if I change the three to a five and rerun this, Python of meow.py, now I'm getting five meows.
So we've just seen a third way how in Python now, we can implement the idea of meowing as its own abstracted function.
And I can assume now that meow exists.
I can now sort of treat it as out of sight, out of mind.
It's an abstraction, and frankly, into a library, import it from a file, like we've done with CS50, and sort of make it usable.
by other people as well.
So the takeaway here,
really, though, is that in Python, you can similarly, to C, define own functions,
but you should understand the slight differences as to what gets called automatically for you.
All right, other differences or similarities with C.
Well, recall that in C, truncation was an issue.
Truncation is whereby,
if you, for instance, divide an int, buy an int, and it's a fractional answer, everything after the decimal point gets truncated by default.
Because int divided by an int in C gives you an int.
fit the remainder in that integer, everything at the decimal gets cut off.
So what does this mean?
Well, let me actually go back to VS code here.
Let me go ahead and open, say, calculator.py again.
And let's change up what the calculator now does.
Let me do this.
Let me define a variable called x, set it equal to the input function.
prompting the user for X.
Let ask the user for Y.
Let me not repeat past mistakes and let me proactively convert both of these to ints and I'll do it in one pretty one-liner here so that I
definitely get X and Y and on the honor system I just won't type cat I won't type dog even though
this program is not really complete without error checking.
Now, let me go ahead and declare a third variable, z equals x divided by y.
And now, let's just go ahead and print out z.
I don't need a format code.
I don't need an f string.
If all you want to do is print a variable, print is very flexible.
You can just say print z in parentheses.
Let me run Python of calculator.py.
Hit Enter.
Let's type in 1 for x, 3, 4, y.
I left out a space there.
And oh, interesting.
What seems to have happened here?
Let me fix my spacing and rerun this again.
Python of calculator.py.
So 1, 3, what did not happen?
Yeah, so it didn't truncate.
So Python's a little smarter when it comes to converting one value to another.
So an integer divided by an integer,
if it ends up giving you this fractional component, not to worry now, you'll get back what is effectively a float in Python here.
Well, what else do we want to be mindful of in, say, Python?
recall that in C, we had this.
in precision whereby if you want to represent a number like one third and on a piece of paper,
it's like 0.3 with a line over it because the three infinitely repeats.
But saw a problem in in C last time when we actually played around with some value.
So for instance,
let me go back to VS code here and this is going to be the ugliest syntax I do think we see today.
But there was a way in C using percent F to show more than the default number of
digits after the decimal point to see more significant digits.
In Python, there's something similar.
It just looks very weird.
And the way you do it in Python is this.
You specify that you want an F string, a format string.
And I'm just going to start and finish my thought first.
F before for quote unquote.
If you want to print out Z, you could literally just do this.
And so this is just an F string, but you're interpolating Z.
So it doesn't do anything more than it did a moment ago when I literally just passed in Z.
But as soon as you have an F string, you can configure the variable to print out to a specific number of digits.
So if you actually want to print out Z to say 50 decimal points,
just to see a lot, you can use crazy syntax like this.
So it's just using the curly braces as I introduced before,
but you then use a dot after a
colon and then you specify the number of digits that you want and then F to make clear it's a float.
Honestly, I Google this all the time when I don't remember.
the syntax, but the point is the functionality exists.
All right, let me go down here.
and rerun Python of calculator.py.
And unfortunately, if I divide one by three, not all of my problems are solved, floating point precision is still a thing.
So be mindful of the fact that there are these limitations in the world of Python, floating point precision remains.
If you want to do even better than that though,
there exists a lot more libraries, third party libraries that can give you much greater precision for scientific purposes, financial purposes, or the like.
But what about another problem from C?
Enter your overflow.
Like if you just count too high,
recall that you might actually, the capacity of an integer and end up going back to zero or worse going negative altogether.
In Python, this problem does not exist.
In Python, when you have an integer, a.k.a.
int, even though we haven't needed to use the keyword int, it will grow and grow and grow.
And Python will reserve more and more memory for that integer to fit it.
So it is not a fixed number of bits.
So floating point in precision, still a problem.
Integer overflow, not a problem in the latest versions of Python.
So a difference worth knowing.
But what about other features of Python that we didn't have in C?
Well, let's actually revisit one of those tracebacks.
into earlier to see how we might actually solve it.
So let me go back to VS Code here.
And just for fun, let me go ahead and do this.
Let me clear my terminal, and let me change my calculator to actually have a getInt function.
We've seen how to define our own functions.
Let me not bother with the CS50 library.
Let me just invent my own getInt function as follows.
So def getInt,
and just like the CS50 function,
I'm going to have getInt take a prompt, a string to show the user, to ask them for an integer.
And now I'm going to go ahead and return the return value of input,
passing that same prompt to input, because input, just like getString, shows the user a string of text.
But I do want to convert this.
an int.
So this is just a one line or really of an implementation of GetEnd.
So this is kind of like what CS50 did in its Python library, but not quite.
Why?
Because there's a problem with it.
So let me do this.
Let me define a main function just by convention.
Let me use this implementation of GetEnd to ask the user for x.
Let me use this GetEnd function to prompt the user.
user for y and then let me do something simple like print out x plus y and then
very last thing I have to call main.
And this is a minor point, but I'm deliberately putting multiple blank lines between my functions.
This too is Pythonic.
It's matter of style.
Style 50 will help you with this.
It's just meant for larger files to really make your functions stand out and be a little more separated visually from others.
Alright, let me go ahead and run Python of calculator.py.
Enter.
Let me type in 1.
Let me type in 3.
And that actually works.
1 plus 3 is 4.
Let me do the more obvious.
1 plus 2 gives me 3.
So the calculator is in fact working.
Until such time as I,
the human don't cooperate and type in something like cat for x, then we get that same trace back as before.
But I'm seeing it now in this file.
And let me zoom in on my terminal just to make clear.
We don't need to see the old history.
let me let me type in cat enter and you'll see the same trace back and you'll see that okay
here's where now there's multiple functions involved so what's going on the first problems at line 12
in main but that's not actually the problem because main calls might get in function so on line six of
calculator.py this is really the issue so again it's tracing everything.
from top to bottom here.
And value error, invalid literal 4int with base 10 cat, which is to say, like before, cat is not an integer in base 10.
Or any other base, it just cannot be converted to an integer.
So how do you fix this?
Or really, how does the CS50 library fix this?
You won't have to write much code like this.
But it turns out that Python supports what are called exceptions.
And generally, an exception is a better way of handling certain types of errors.
Because in C, we call that the only way we could really handle errors is by having functions return special values.
Like could return null, which means it ran out of memory.
something went wrong,
some functions we wrote in C could return 1,
could return 2, could return negative 1, recall that we could write our own functions that return values to indicate something went wrong.
But the problem in C is that if you're stealing certain values,
be it null, or 1, or 2, or 3, your function can never return no or one or two or three as actual values.
Why?
Because other people are going to interpret them as errors.
So you kind of have to use up some of your possible return values in a language like C and treat them specially as errors.
In Python and other languages, Java and others, you don't have to do that.
You can instead have more out of band error handling known as exceptions, and what's happening here.
When I run calculator.py and I type in cat, what I'm seeing here is actually an exception.
It's something exceptional, but not in a good way.
Like, this exception means this was not supposed to happen.
The type of exception happens to be called a value.
you error.
And within the world of Python there's this whole taxonomy that is to say a whole list of possible exceptions,
value error is one of the most common.
We saw another one before name error when I said meow when Python didn't know what meow meant.
So this is just an example of an exception but what this means is that there is a way for me to try to handle this
myself.
So I'm actually going to go ahead and do this.
Instead of getInt simply blindly returning the integer conversion of whatever input the user gives me,
I'm going to instead literally try to do this instead.
So it's kind of an aptly named phrase.
It literally means that.
Please try to do this, except if something goes.
Except if there is a value error in which case I want Python to do something else, for instance, quote unquote, not an integer.
So what does this mean?
It's a little weird, the syntax, but in the get in function, Python will first try to do the following.
It will try to get an input from the user.
it will try to convert it to an integer, and it will try to return it.
But if one of those operations fails, namely the integer step in this case, then an exception could happen.
And you might get what's called a value error.
Why?
Because the documentation tells you that might happen.
Or in my case, I experienced the first hand, and now I want to catch this kind of exception in my own code.
So if there is a value error, I'm not going to see that crazy trace back anymore.
I'm instead going to see, quote unquote, not an integer.
But what the CS 50 library does for you technically is it lets you try again and again and again,
recall in the past,
if I tip in cat and dog and bird,
it's just going to keep asking me again and again until I actually give it an int.
So that kind of implies that we really need a loop inside of this function.
And the easiest way to do something forever is to loop while true, just like in C, but a capital T in Python.
And what I'm going to do now is implement a better version of get in here, because what's it going to do?
It is going to try it's going to do this forever.
It's going to try to get an input converted to an in and return it and just like break breaks you out of a loop,
return also breaks you out of a loop as well, right?
Because once you've returned, there's no more need for this function to execute.
So long story short,
you won't have to write much code like this yourself,
but this is essentially what the CS50 library is doing when it implements the Python version of GetInt.
So what happens now?
If I run Python of calculator.py and I type in cat, I get yelled at, but I'm prompted again, because of the loop.
I type in dog, I'm yelled at, but I'm prompted again.
I type in bird, yelled at, but I'm prompted again.
If type in one.
to now it proceeds because it tried and succeeded this time as opposed to trying and failing last time.
And technically, the CS50 library doesn't actually yell at you with not an integer.
So technically, if you want to handle the error, that is to say, catch the exception, you can actually just say, oh, pass.
And it will just silently try again and again.
So let me go ahead and run this.
Python of calculator.py works almost the same.
But now it works just like the C version.
It doesn't yell at you, but it does prompt you again and again and again.
But I'll do one and two, and that now is satisfied.
So that then is exceptions which you'll encounter, but you yourself much code along those lines.
Well, what else can we now do?
Well, let's revisit something like this from Mario.
Recall.
whereby we had this two-dimensional world with things in the way for Mario like this column of three bricks.
Let me actually play around now for a moment with some loops just to see how there's different ways that might actually resonate with
you just in terms of the simplicity of some of these things.
Let me go ahead and create a program called Mario.py and suppose that I want to print a column of
three bricks kind of doesn't get any easier than this in Python.
So for I in range three just go ahead and print out a single hash.
done like that then is what we took took us more lines of code in the past.
But if I run Mario dot pi, that there gets the job done.
I can change the I to an underscore, but it's not bad to remind myself that I is what's really doing my counting.
Well, what else could we do beyond this?
Well, recall that in the world of Mario.
We prompted the user actually for a specific height.
We just always hard code three.
So I could actually do something like this.
Let me actually open up from today's code that I came with in advance and pull up this C version of Mario.
So this was from some time ago in week one,
and this is how we a loop that ensures that we get a positive integer from the user by just
doing while and is not positive.
And then we use this for loop to actually print out that many hashes.
Now in Python, it's actually going to be pretty similar, except for the fact that in Python, there is no do while loop.
But recall that a do while loop was useful because it means you can get the user to try something and then maybe try again.
maybe try again, so it's really good for user input.
So let's actually do this.
Let me borrow the CS50's library, get int function, just so we don't have to re-implement that ourselves again and again.
Let me in Python do this the Pythonic way.
In Python, if you want to prompt the user to do something again and again and again, potentially, by convention, induce an infinite loop.
You just get yourself into an infinite loop.
But the goal is going to be try something,
try something, try something, and soon as you have what you want, break out of the loop instead.
So we're implementing the idea of a do-while loop ourselves.
So I'm going to do this, n for number equals getint.
And let's ask the user for a height.
Then let's just check if n is greater than 0, you know what?
Break.
We've got the value we need.
And if not, it's just going to implicitly keep looping again and again and again.
So in Python,
this is to say, super common to deliberately induce an infinite loop and break out of it when you have what you want.
All right, now I can just do the same kind of code as before.
For i in range, not of range sometimes, ri in range, not 3, but n.
Now I can go ahead and print out.
out a hash like this.
If I open my terminal window,
it's going to work almost the same,
but now Mario is going to prompt me for the height,
so I could type in 3,
or I could type in 4, or I could be uncooperative and type in 0, or negative 1, or even cat.
And because I'm using the CS50 library, cat is ignored.
Because I'm using my while loop and breaking out of it, only 1n is positive, I'm also ignoring the 0 and the negative 1.
So again, this would be a pi.
implementing this particular idea.
If I want to maybe enhance this a bit further,
let me propose that, for instance, we consider something like the two-dimensional version of the horizontal version of this instead.
So recall that some time ago, we printed out like four question marks in the sky that might have looked a little something like this.
Now the very mechanical way to do this would be as follows.
Let me close.
Let me clear my terminal and let me just delete my old Mario version here,
and let's just do this for I in range of four.
Let's go ahead and print out a question mark.
All right, I'm going to run python of mario.py enter and it's still a column instead of a row.
But what's the fix here perhaps?
What's the fix?
Yeah.
Yeah, we can use that named parameter and say end equals quote unquote to just press the default backslash and but let's give
ourselves one at the very end of the loop just to move the cursor correctly.
So now if we're on Python of Mario to pi now it looks like what it might have in the sky here.
But it turns out Python has some neat features too.
More syntactic sugar if you will for doing things a little more easy.
Turns out in Python, you could also do this.
You could just say print quote unquote question mark times 4.
And just like plus means concatenation,
star here means really multiply the string by itself that many times, so sort of automatically concatenate it with itself.
So if I run Python of Mario.py, this to work.
So again,
just some features of Python that make it a little more pleasant to
use so you don't always have to like slog through implementing a loop or something along those lines.
Well, what about something more two-dimensional like in the world of this brick here?
Well, in the context of this sort of grid of bricks, we might do something like this in VS Code.
Let me go back tomorrow.py.
And let me do a three by three grid for that block, like we did in week one.
So for I in range of three, I can nest loops just like in C, for in range of three.
I can then print out a hash here, and then let's leave this alone, even though it's not quite right yet.
Let's do python of Mario dot pi.
Okay, it's like nine bricks all in a column, which so your mind might wander to the end parameter again.
So yeah, let's fix this and equals quote unquote.
But at the end of that loop, let's just print out a new line.
So this logically is the same as it was in C.
But in this case, I'm now doing it in Python, just a little more easily without I plus plus without a.
conditional, I'm just relying on this 4i in syntax using range.
I tighten this up further.
Frankly, if I already have the outer loop, I could do something like this.
I could print out a single hash times 3.
And now if I run Python of mario.py, that works too.
So I can combine these ideas in interesting ways.
as well.
The goal is simply to siege you with some of these building blocks.
All right, how about code that was maybe a little more logical in nature?
Well, in Python, we indeed have some other features as well, namely like lists.
And lists are denoted by those square brackets, reminiscent of the world of arrays.
But in Python, what's really nice about lists is that their memory is automatically handled for you.
In array is about having values contiguously in memory.
In Python, a list is more like a linked list, like you can it will allocate memory for you and grow and shrink these things.
And do not have to know about pointers,
you do not have to know about nodes,
you do not have to implement linked lists yourself, you just get lists as the data type in Python itself.
Here, for instance, is some of the documentation for lists specifically.
And in particular, lists also, like strings or stirs, have methods, functions that come with them, that just make it easy to do certain things.
So, for instance, if I want to choose Maybe do something like taking averages of scores like we did some time ago.
We do that using a combination of lists and the function called LANG,
which I alluded to earlier, which will tell you the length of a list.
Now how might we do this?
Well, if read the documentation for LANG, it out there's other functions there too that might be helpful.
So let me go back to VS code here.
Let me close Mario.py.
called scores.py, reminiscent of something we did weeks ago, too.
Let me go ahead and just for demonstration,
say, give me myself a variable called scores that has my three test scores or whatnot from weeks ago.
So I'm using square brackets, not curly braces, as in C.
This is a linked list or a list in Python.
And I'm going to get the average of these values.
Well, I could do this average equals and it turns out in Python, you just get a lot of functionality for free and those functions sometimes take not single arguments, but lists as their arguments.
So for instance, I can use Python's built in some function and pass in those scores.
I can then divide that some by the length of the scores.
list as well.
So length of a list just tells you how many things are in it.
So this is like doing magically 72 plus 73 plus 33 all divided by 3 in total.
If I want to now do the math out,
I can print the result so I can print out using an F string and maybe like some prefix text here
Let's print out that average here.
So let me do Python of scores.py enter and there's the average Slightly imprecisely,
but at that point I'm not doing so well anyway,
so that's fine So at this point we've seen that we have sort of more
Functionality than see like in see how would we have computed?
I mean we literally created a variable.
We then had a loop.
We iterated over the array.
We added things together There was just so much more work It's nice when you have a language that comes with functions among them,
laying among them some, that just does more of this for you.
But suppose you actually want to get the scores from the user.
When C, we used an array, and then C, we get int.
We can do something a little similar here.
Let me propose that instead of hard coding those three values, let me do this.
From CS50, import get.
And now, let me give myself an empty list by just saying scores equals open bracket, close bracket.
And unlike C,
where you just can't do this,
you can't say give me an array, and I'll figure out the length later, unless you resort to pointers and memory management or the like.
And Python, you can absolutely give yourself an initially empty list.
Now, let's do this.
For i in range of three, let's prompt the human for three test scores.
So the first score will be the return value of get int, prompting the.
score.
And now if I want to add this score to that otherwise empty list,
here's where methods come into play functions that come with objects like lists.
I can do scores, plural, because that's the name of my variable from line three dot append.
And I can append that score.
So if we read the documentation for lists and Python,
you'll see that lists come with a function,
a method called append, which literally just tax a value on to the end, tax a value on to the end.
Like all of that annoying code,
we would have written in C to like iterate with pointer and pointer and pointer to the end of the list,
append it, malloc a new node, Python does all of that for us.
And so once you've done that,
now I can do some similar to before,
the average equals the sum of those scores divided by the length of that list of scores,
and I can again print out with an F string the average value in that variable like this.
So again you just have more building blocks at your disposal when it comes to something like this.
You can also do this just so you've seen other syntax.
It turns out that instead of doing scores.append, you could also do this.
You could concatenate scores with itself by adding two lists together like this.
This looks a lot like But on the left is my variable scores.
On the right here, I am taking whatever is in that list, and I'm adding the current score by adding it to its own list.
And this will update the value as we go.
But it does, in fact, change the value of score as opposed to appending to the initial list.
All right, how about some other building blocks here?
Let me propose this.
Let me close out scores.py.
Let me open up a file called phonebook.py to reminiscent of what we did weeks ago in C.
And me give myself a of names.
We bother with numbers just yet.
Let's just play with lists for another moment.
So here is a variable called names.
It names, it has a names in it.
Maybe Carter and David and John Harvard as in past weeks.
And now let me go ahead and ask the user.
user to input a name, because this is going to be like a phone book.
I want to ask the user for a and then look up that person's name in the phone book,
even though I'm not bothering by having any phone numbers just yet.
How could I search for a linear search someone's name?
Well, in Python, I could do this for name, rather, for n in names.
If the current name equals what the human typed in, then go ahead and print out found, then break out of this loop.
Otherwise, we'll print out not found at the bottom.
All right, so try this.
Python of phone book dot pi.
Let's search for maybe Carter.
That's easy.
He's at the beginning.
Well, he was found, but then I printed not found.
So that's not quite what I want.
How about David?
D-A-V-I-D?
Found, not found.
All right, not very correct.
How about this?
Let's search for Eli, not in the list.
OK, so at least someone not being in the list is working.
But logically, for Carter, for David, and even John, why are we seeing found and then not found?
Why is it not found, yeah.
Okay, I don't have to seem to have indented the print, but let me try this.
If I just go with the else here,
let me go up here and indent this and say else,
I'm not sure logically this is what we want,
because what I think this is gonna do if I search for maybe Carter, okay, that worked.
So it's partially fixed the problem, but let me try searching for maybe David.
Now we're sort of the opposite problem, not found, found, why?
Well, I don't think we want to immediately conclude that someone's not found just because they don't equal the current name in the list.
So it turns out we could fix this in a couple of different ways, but there's kind of a neat features of Python.
In Python, even for loops can have an else clause.
And this is weird, but the way this works is as follows.
In Python, if you break out of a loop, that's it for the for loop.
if though you get all the way through the list that you're looping over and you
never once call line eight you never break out of the loop Python is smart enough
to realize okay you just went through lines five through eight you never
actually logically called break here's an else clause to be associated with it
semantically this is weird we've only ever seen if and else associated with
each other but for loops and Python actually can have else as well Now,
if I do Python, a phone book dot pi, type in Carter, now we get only one answer.
If I do it again and type in David, now we get only one answer.
Do it again with John.
Now we get only one answer, do it with Eli, now we get only one answer.
So again,
you just get a few more tools in your toolkit when it comes to a language like Python that might very well make solving problems a little more.
Pleasant, but this is kind of stupid in Python.
This is correct But it's not well designed because I don't need to iterate over lists like this so pedantically like we've been doing for weeks and see
I can actually tighten this up and I can just do this
I can get rid of the loop and I can say if name in names then print out quote unquote found like that's it in
Python.
If you want Python to search a whole list of values for you, just let Python do the work.
And you can literally just say,
if the name that the human inputted is in names, which is this list here, Python will use linear search for you.
Search automatically from left to right, presumably, looking for the value.
And if it doesn't, find it, then and only then will this else clause execute instead.
So again, Python's just starting to save us some time because this too will find Carter, but it will not find, for instance, Eli.
All right, so we get that functionality for free.
But what more can we perhaps do here?
Well, it turns out.
That Python has yet other features we might want to explore,
namely dictionary,
shortened as dict,
and a dictionary in Python is just like it was in C,
and really in computer science in general, dictionary was an abstract data type, and it's a collection of key value pairs.
It looks a little something like this.
If in C,
if in Python,
if in any language,
you want to associate something with something like a name with a number,
you had to in problems that five implement the darn thing yourself by implementing an entire spell checker with an array and linked list to sort of store all of those words in your dictionary.
In Python, as we saw earlier, you can use a set, or can use more simply a dictionary that implements a dictionary.
for you, all of problem sets, fives, ideas, but Python does the heavy lifting for you.
Dict in Python is essentially a hash table, a collection of key value pairs.
So what does this mean for me in Python?
It means that I can do some pretty handy things pretty easily.
So for instance, let me go back here to the S code, and let me change my phone book altogether to be this.
Let me give myself a list of dictionaries.
So people is now going to be a global list, and I'm going to demarcate it here with open square bracket and closed square bracket.
And just to be nice in the entirety,
I'm going to have these people no longer just be Carter and David and John, as in the previous example.
But I want each of the elements of this list to be a key value pair, like a name and a number.
So how can I do this?
In Python, you can use this syntax.
And this is, I think, the...
last of the weird-looking syntax today.
You can define a dictionary.
That is something like this by using two curly braces like this and inside of your curly braces
You get to invent the name the keys and the values
So if you want one key to be the person's name you can do quote-unquote name and then quote-unquote
Carter If you want another key to be number you can do quote-unquote number and then quote-unquote something like last time
1 617 495 1000 for instance for Carter's number there And collectively everything here on line two represents a dictionary,
it's as though on a chalkboard I wrote down name Carter number plus one six one seven four nine five one thousand row by row by row in this table.
This is simply the code equivalent thereof.
If you want to be really nitpicky or tidy you could style your code to look like this which makes it a little more clear perhaps as to what's going on.
It's starting to add a lot of white space to the screen.
of key-value pairs, again, akin to a two-column table like this.
I'm going to undo the white space just to kind of tighten things up because I want to cram two other people in here,
so I'm going to go ahead and do another...
set of curly braces with quote unquote name and David quote unquote number and we'll have the same number so plus one six one seven four nine five one thousand and then lastly let's do another
set of curly braces for name of say John and John Harvard's number quote unquote number will be plus one plus one let's see nine four nine four six eight two seven five oh it was
always the
of and then by convention you typically end even this element with a comma but it's not strictly
necessary syntactically but stylistically that's often added for you.
So what is people?
People is now a list.
of dictionaries, a list of dictionaries.
So what does that mean?
It means I can now do code like this.
I can prompt the user with the input function for someone's name.
If the goal now is to look up that person's number, how can I look up that number?
Well, for each person in the list of people, let's go ahead and do this.
If equals whatever name the human typed in,
then get that person's number by going into that person and doing quote-unquote number and then go ahead and print out
something like this F string found that person's number and then since we found them let's just break out altogether.
And we get through that whole thing let's just at the very end print out So, what's weird here?
If focus on this code here, this syntax obviously is new.
The square brackets, though, just means, hey, Python, here comes a list, hey, Python, that's it for the list.
Inside of this list are three dictionaries.
The curly braces mean, hey, Python, here comes a dictionary, hey, Python, that's it for the dictionary.
Each of these dictionaries has two keys.
name and its value, number and its value.
So can kind of think of each of these lines as being like a C struct,
like with type def and struct, but I don't have to decide in advance what the keys and the values are going to be.
I can just on the fly create a dictionary like this.
Again, reminiscent of this kind of chalkboard design.
All right,
so what am I actually doing in code, a dictionary in Python lets you index into it's similar to an array with numbers in C.
So in C,
this is a little bit different in C,
you might have been in the habit of doing person.name,
but because it's a dictionary,
the syntax in Python is you actually use square brackets with strings as being inside the square brackets rather than numbers.
But all this is now doing is it's creating a variable on line 11, setting that number equal to that same person's number.
Why?
Because we're inside of this loop, I'm iterating over each person one at a time.
And that's what 4, that's what N does.
It assigns the person variable to this dictionary.
Then this dictionary.
Then this dictionary automatically for me.
No need for I and I++ and all of that.
So this is just saying if the current person's name equals the name we're looking for,
get a variable called number and assign it that person's number and then number.
So whereas last time we were just printing found and not found, now I'm going to print an actual number.
So if I run Python of phonebooked.py and I search for Carter, there then is his number.
If I run Python of phonebooked.py, type in John, there then is John's number.
And if I search for someone who's not there, I instead just get not found.
So what's interesting and compelling about dictionaries is they're kind of known as the Swiss army knives of data structures and programming,
because you can just use them in so many interesting clever ways.
Like if you ever want to associate something with something else,
like a dictionary is your friend and you no longer have to write dozens of lines of code as in piece at five,
you can write single lines of code to achieve the same idea.
So for instance,
if I to want to tighten this up, I actually don't need this loop altogether and even better version of this code would be this.
I don't need this variable technically,
even though this will look a little uglier,
notice that I'm only creating a variable called number because I want to set it equal to this person's number, but strictly speaking.
Speaking, anytime you've declared a and then used it the next line, you don't really need it.
So I could do this.
I could get rid of that line.
And instead of printing number in my curly braces, I could actually do person.
square brackets,
and you might be inclined to do this,
but this is going to confuse Python because you're mixing double quotes on the inside and the outside,
but you can use single quotes here, compellingly.
So you don't have to do it this way,
but this is just to show you syntactically,
you can put most anything you want in these curly braces, so long as you don't confuse Python by using the same syntax.
But let me do one other thing here, This is even more powerful.
Let me propose that if all you're storing is names and numbers, names and numbers, I can actually simplify this dictionary significantly.
Let me actually re-declare this people.
data structure to be not a list of dictionaries but how about just one big
dictionary because if I'm only associating names with numbers I don't
technically need to create special keys called name and number why don't I just
associate Carter with his number plus one six one seven four nine five one
thousand why don't I just associate quote-unquote David with his number plus one six one seven And then lastly,
let's just associate John with his number,
plus 1,949494682750,
and that,
too, But notice that I'm going to get rid of my list of people,
and instead just have one dictionary of people,
the downside of which is that you can only have one key, one value, one key, one value.
You can't have a name key and a number key and an email key
and an address key and any number of other pieces of data that might be compelling.
But if you've only got key value pairs like this,
we can tighten up this code significantly so that now down here, I can actually do this.
name I'm looking for is somewhere in that people dictionary then go ahead and get the person's number by going into the people dictionary,
indexing into it at that person's name, and then printing out found, for instance, that here.
number, making this an F string else you can go ahead and print out not found in this case here.
So again the difference is that the previous version created a list of dictionaries and I very manually methodically iterated over it
looking for the person but what's nice again about dictionaries is that Python
gives you a lot of support for just looking into them easily and Just like you can use it for lists,
you can use it for dictionaries as well.
And Python will look for that name among the keys in the dictionary.
And if it finds it, you use this syntax to get at that person's number.
OK, a lot all at once.
But are there any questions on this here syntax?
We'll then introduce a couple of final features with the final flourish.
Yes, in this case, I do not need to use break because I don't have any loop involved.
So break is only used as we've seen it in the context of looping over something when you want to terminate the loop early.
But here Python is doing the searching for you.
So Python's taking care of that automatically.
All right, just a couple of final features so that you have a couple of more building blocks.
Here is the documentation for dictionaries themselves in case you want to poke around as to what more you can do with them.
But it turns out that there are other libraries that come with Python,
not even third-party, and one of them is the sys library, whereby you have system-related functionality.
And here's its official documentation for instance.
But what this means is that certain functionality that was just immediately available in C is sometimes tucked away now into libraries in Python.
So for instance,
let me go back And let me just create a program called greet.py,
which is reminiscent of an old C program that just greets the user using command line arguments.
But in C, recall that we got access to command line arguments with main and in arg C and arg V.
But none of those have we seen at all today.
And fact, main itself is no longer required.
So if you want to do command line arguments in Python, we'll actually do this.
From the sys library, you can import something called argv.
So argv still exists.
It's just tucked away inside of this library, otherwise known as a module.
And I can then do this.
If the length of argv, for instance, does not equal to, well, then we're going to go ahead and do what we did rather.
Let's do this.
If the length of argv does equal to,
we're going to go ahead and do what we did a couple of weeks ago whereby I'm going to print out.
Hello, comma, and then argv bracket 1, for instance.
So whatever is in location 1 of that list.
Else, if the length of argv is not equal to
2, that is the human did not type two words at the prompt, let's go ahead and print out hello world by default.
So we did the exact same thing in C.
The only difference here is that this now is how you get access to argv.
So let me run this.
Python of greet.py and hit enter, hello world is all I get.
And actually, I got it.
out of habit, I included backslash n, but I don't need that in Python.
So me fix that.
Python of greet.py, hello world.
But if I do Python of greet.py, d-a-v-i-d, now notice that argv equals two.
If I instead do something like Carter, argv now equals two, but there is a difference.
Technically, I'm typing three words.
at the prompt, three words at the prompt.
But argv still only equals two because the command Python is ignored from argv.
It's only the name of your profile and the thing you type after it.
So that's then how we might print out arguments in Python using argv.
Well, what else might we do using some of these here features?
Well, it turns out that you can exit from programs using the same sys library.
So let me close greet.py.
Let me open up exit.py just for demonstration sake.
And do something like this.
Let's import sys.
And if the length of sys.org v.
So here's just another way of doing this.
And actually, I'll do it the same first.
From import argv if the length of argv.
does not equal to,
well let's actually yell at the user with something like missing command line argument and then what we can do is exit out of the program
entirely using sys.exit which is a function therein but notice that exit is a function
insists so you know what it's actually more convenient in this case let's
just import all of sys but because that has not given me direct access to argv,
let me if all is well let's just go ahead and print out
comma sys dot rv bracket one close quote and that will print out hello so and so
and when I'm ready to exit with a non-zero a non with a zero exit status I
can actually start to specify these things here so just like in C if you want
to exit from a program with one or two or anything else you can use sys.exit.
And if you want to exit with a zero, you can do this here instead.
So we have the same capabilities as in C, just a little bit differently.
Let me propose that, let's see, let me propose that How about this?
How about this?
If we want to go ahead and create something a little more Interactive, recall that there was that command a while back, Namely pip.
whereby I ran pip install face recognition.
That's one of the examples with which we began.
And allows me to install more functionality from a third party into my own code space or my programming environment more generally.
Well, we have a little fun with this, in fact.
Let me go back to BS code here.
And just like there's a command in Linux called cow say,
whereby you can get the cow to say something, you can also use this kind of thing in Python.
So if I do pip install cow say, this, if it's not installed called Cauce.
And what this means is that if I actually want to code up a program called like moo.py,
I can import the Cauce library and I can do something simple like cauce.cau because there's a function in this library called Cau and I can say
something like this is CS50 quote unquote.
How do I run this program?
I run Python of mood.py and underwhelming.
If I increase the size of my terminal window,
run of mood.py, we have that same adorable cow as before, but I now have programmatic capabilities with which to manipulate it.
And in fact, I could make this program a little more interesting.
I could do something like name,
equals quote or rather name equals input what's your name and combine some of today's ideas and now I
can say not this is CS 50 but something like quote unquote hello comma person's name and now if I
increase the size of my terminal rerun python of moo.py it's not going to actually moo or say this is
CS 50 it's
gonna to say something like hello David and so forth and suffice it to say through other functions
you can do not only counts but dragons and other fancy things too but even in Python too can
you generate not just ASCII art but actual art and actual images and the note I thought
we'd end on is doing one other live I'm going to go back into VS code here.
I'm to close mood.py.
I'm to do pip install qr code,
which is the name of a library that I might want to install to generate qr codes automatically and qr codes are these two dimensional bar codes.
If you want to generate these things yourself, you don't have to go to a website and type in a URL.
You can actually write this kind of code here.
might I do this?
Well, let me go into a new file called say qr.py.
And let me do this.
Let me go ahead and.
Import this library called QR code.
Let me go ahead and create a variable called image or anything else.
Let me set it equal to this library's QR code's function called make.
No relationship to C, it's just called make because you want to make a QR code.
Let me type in maybe the URL of a lecture video here on YouTube, so YouTube slash xvfzj05pg.
zero quote unquote,
and then I can go ahead and do image dot save because inside of this image variable,
which is a different data type that this library gave me doesn't come with Python per se.
I can save a file like qr dot png and I can save it in the ping format, the portable network graphic.
And so just to be clear what this should hopefully do for me is create a qr code containing that particular URL.
But not as text,
but rather as an actual image that I can send that can post online or in our case generate into my code space and then open.
And so with all that said, we've seen a bunch of new syntax today.
ideas underlying Python are exactly the same as they've been in C.
It's just that you don't have to do nearly as much heavy lifting yourself.
And here,
for instance,
in just three lines of code,
can you generate a massive QR code that people can scan as you can in a moment with your phones and actually link to something like a CS 50 class.
So let me Let go ahead and run Python of qr.py.
Seems to have run.
Let me run code of qr.png, which is the file I created.
I'll close my terminal window.
Allow you an opportunity to scan this here.
Barry CS50 lecture.
and someone's volume up there we go what a perfect ending all right that was CS50 we'll see you next time

Daha Fazla Özelliği Açın

Trancy uzantısını yükleyerek, AI altyazılar, AI kelime tanımları, AI dilbilgisi analizi, AI konuşma vb. dahil olmak üzere daha fazla özelliği açabilirsiniz.

feature cover

Büyük Video Platformlarıyla Uyumlu

Trancy, YouTube, Netflix, Udemy, Disney+, TED, edX, Kehan, Coursera gibi platformlar için çift dilli altyazı desteği sağlamakla kalmaz, aynı zamanda düzenli web sayfaları için AI kelime/cümle çevirisi, tam metin etkileşimli çeviri ve diğer özellikler sunar. Gerçek bir çok yönlü dil öğrenme asistanıdır.

Tüm Platform Tarayıcıları

Trancy, iOS Safari tarayıcı uzantısı dahil olmak üzere tüm platform tarayıcılarını destekler.

Çoklu Görüntüleme Modları

Tiyatro, okuma, karışık ve diğer görüntüleme modlarını destekleyerek kapsamlı bir çift dilli deneyim sunar.

Çoklu Uygulama Modları

Cümle dikte, sözlü değerlendirme, çoktan seçmeli, dikte ve diğer uygulama modlarını destekler.

AI Video Özeti

Videoları özetlemek ve hızlı bir şekilde temel içeriği kavramak için OpenAI kullanın.

AI Altyazılar

Sadece 3-5 dakikada doğru ve hızlı YouTube AI altyazıları oluşturun.

AI Kelime Tanımları

Altyazılardaki kelimelere dokunarak, AI destekli tanımlarıyla kelime anlamlarını öğrenin.

AI Dilbilgisi Analizi

Cümle dilbilgisini analiz ederek cümle anlamlarını hızlıca anlayın ve zor dilbilgisi konularını öğrenin.

Daha Fazla Web Özelliği

Çift dilli video altyazılarının yanı sıra, Trancy ayrıca web sayfaları için kelime çevirisi ve tam metin çevirisi sağlar.

Başlamak için hazır

Trancy'yi bugün deneyin ve benzersiz özelliklerini kendiniz deneyimleyin.

İndir