CS50 x 2024 Notes Python - 02

⑴

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 go into a folder called filter, in which I have this same bridge that we've seen in the past across the river there. 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 end, 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, PIL, let me go ahead and import something called Image, capital I, and ImageFilter, capital I, capital F.

So I'm going to do before = Image.open ( " bridge.bmp " ).

Then let me go ahead and create another variable called after and set that equal to before.filter, and then, in parentheses, ImageFilter, spelled as before, dot BoxBlur and then we'll give it a value of 10. How much do I want to blur it, for instance ?

​After that, I'm going to literally call after.save, and let's save it as a file called out.bmp. And that's it. I propose that this is now you can now write code in Python to blur an image, much like you might have for problem set 4.

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.bmp. Let me go ahead and open a file called edges.py. And maybe, in edges.py, we can use this same library. So from the Python Image Library, import Image and import ImageFilter. Let me go ahead and create another variable called before set it equal to Image.open ( " bridge.bmp " ), just like before. Let me create another variable called after, set that equal to before.filter ( ImageFilter. FIND_EDGES ), 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 4, 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 to do all of this in C, that was 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 like 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 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_recognition if you want to add support to your code space, or to your programming and 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 and ls in there, and you'll see four files - - the detect.py and recognize.py, which are going to detect faces and then recognize specific faces, respectively, and then two files I brought from a popular TV show, for instance.

So if I open office.jpg, here is one of the early cast photos from the hit TV series The Office.

And here is a photograph of someone 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, it 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, like eyes, nose, generally in a similar orientation even though we all have different faces, ultimately. But there's a pattern to the shapes that you're seeing on the screen. Well, it turns out this face_recognition library has been trained, perhaps via artificial intelligence over time, to recognize faces, but any bumber 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 of detect.py, which I wrote in advance, which uses that library.

And what that program is going to do - - it's going to think, 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. But suppose that we're 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 Jim's, from Pam's, from everyone else in the show, just base on this one piece 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 recognized.jpg, which should show me this 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 ecosyston of libraries. And this 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 among the goals of CS50, too, is not to teach you C, not 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 indeed, all of the ideas we have explored and will now explore more today, you'll see recurring for languages in the years to come. So how does Python itself work ? Well, let's do a quick review as we did when we transitioned from Scratch to C, 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 0, 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 this here, with printf, with the parentheses, the quotation marks, the backslash n, the semicolon.

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 0.

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.h, 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, will take off so that you can stand on your own, even with cs50 behind you. But the syntax for using a library in Python is a little different. You don't include a .h file. You just import, instead, the name of the library. All right. 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 don't just have to say, give me the whole libray. For efficiency purposes, you can say, let me import the get_string function from the cs50. So you have finer-grained control in 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 Python, or rather, in C, this code looks a little something like this. Bcak in week 1, we declared a variable of type string, even though later we revealed that to be char *. I gave this a variable name of answer for parity with Scratch. Then we use cs50's own get_string function and asked, for instance, the same question as in the white oval here. And then, using this placeholder syntax, there format codes, which was printf-specific, we could plug in that answer to this premade string where the %s is. And we saw %i and %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 in 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 get_string. I'm 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 if you who have perhaps programmed before, what does the plus represent in this context ? It's indeed joining the two strings together. So this is indeed 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 grammer to line up. So I still have " hello " 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 fact that we don't have a semicolon, 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 us 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 that I've done here is my first argument is, quote, unquote, " hello," with a comma but no space.

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.

You 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 of f string, for short.

And this looks weird to me still. But if you prefix a string in Python with an f, literally, you can then use curly braces inside of that string in Python. And Python will not print out literally a curly brace and a closed cruly 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 therein, is going to do the exact same thing of creating a string that says " hello, David ". So it's going to plug in the value for you. So you can think of this as %s but without that second step of having to keep track of what you want to plug back in for %s. Instead of %s, you literally put in curly braces, what do you want to put right there ? You format 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 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 and, from the cs50 library, import the function called get_string. Then let me go ahead and create a variable called answer. Let me set that equal to the return value of get_string with, as an argument, quote unquote, " What's your name ? " And then no semicolon at the end of that line, but on the next line, frankly here, I can pick any one of those potential solutions. So let me start with the first. So " hello, " + 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 D-A-V-I-D and voila, that there then works.

Or I can tweak this a little bit. I can 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 going to be ever-so-slightly bugy, sort of grammatically or visually, if you will. What did I do wrong here ?

Yeah, so 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 that placeholder syntax. So let's just pass in one bigger string as our argument, do " hello, " and then, in curly braces, answer like this. Well, let me go down to my terminal window and clear it. Let me run python of hello.py and enter, type in D-A-V-I-D, and voila. OK, I made a mistake. What did I do wrong here, minor thought it seems to be ?

So the stupid little f that you have to put before the string of 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 of hello.py. What's your name ? David. And how it looks the way I might intend. But it turns out in Python, you don't actually need to use get_string. In C, recall that 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 what 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 ? Why ? What if they give you a really long string that you didn't allocate space for ? Because you're not going to know as the programmer in advance how long of a string the human is going to type in. So you might undercut it and therefore have too much memory, or too 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 C, get_string 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, in 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 trasition 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 of hello.py, type in my name, David, and voila. I have that now working as well.

相关推荐
樱桃木1 小时前
回测可信度审查:样本外测试的五种常见自欺
python
zyseo81 小时前
谷歌SEO 网站迁移 301 映射脚本:旧站 URL 自动匹配新站结构
开发语言·python
伞伞悦读1 小时前
【第59期】转置不是摆好看:Python 矩阵乘法、逆矩阵与线性方程组
python
Dmz丶1 小时前
前端转 AI 100 天 Day 29:Nginx 反代 + HTTPS——让服务“能上公网“
python
清水白石0081 小时前
React Native与Flutter长期维护成本对比
开发语言·数据库
麦序子1 小时前
用 Python + python-docx 批量生成带表格样式的装修报价单 Word 文档(含合计公式)
开发语言·python·自然语言处理·word·python3.11
1-1=01 小时前
Python PyCharm
开发语言·python·pycharm
梦影_1 小时前
Langchain简单快速上手教程(九)—— 核心组件之少样本提示
人工智能·python·自然语言处理·中间件·langchain
牛肉胡辣汤1 小时前
Blender + Three.js 开发讲解:从 .blend 到能转的产品页
开发语言·javascript·blender