You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Leo is signing up for a new social network website called ProgrammerBook. He wants to make sure that his password is strong.
187
188
189
+
Leo 正在注册一个名为 ProgrammerBook 的新兴社交网络网站,他希望确保自己的密码足够安全。
190
+
188
191
Leo starts with a modest definition of what it means for a password to be strong: it’s strong if it’s not the word ‘password’ and not the word ‘qwerty.’ (Those are terrible passwords, for sure, but in reality, we have to do way better than this definition to ensure that our password is strong!)
189
192
193
+
Leo 对 “强密码” 的定义颇为低调:他觉得只要密码不是 “password” 或 “qwerty”,就算是一个强密码了。(这两个密码无疑是极差的,然而实际上,若真想确保密码安全,我们还需做到比这更好的水平!)
194
+
190
195
A helpful function would be one that takes a proposed password and tells us whether it is strong or not.
191
196
197
+
这里我们需要一个实用的函数,它能够接收一个拟定的密码,并判断其强度是否达标。
198
+
192
199
Unlike our previous functions in this chapter, we’re not dealing with numbers here. The parameter, the password to check, is text. And the return value is supposed to indicate some yes/no result. We need new types!
The Python type for text is called a **string**. There are zillions of possible strings, because we can use a string to store whatever text we want. And the Python type for a yes/no result is called a **Boolean** or **bool**. A bool has only two values: True or False.
Alright! We’re ready to prompt Copilot. For functions that return bool (True/False) values, we usually name the function as `has_x`, or `is_x`, or using some other verb that implies a true/false result.
Look over that code for a moment. That `!=` operator is the ‘not equal’ operator, and each string that doesn’t count as a strong password is in single quotation marks. We’re going to use quotation marks every time we work with a string value. Again, we’ll talk more about how to read code in the next chapter, but for now we hope that the code makes a fuzzy sort of sense: it looks like it’s checking that the password isn’t `password` and isn’t `qwerty`, which matches our definition of a strong password.
Well, technically True is correct, but wow is ‘Leo’ a bad password. We should really have done better with our definition of a strong password. Let’s change our prompt to give a more reasonable definition of what it means for a password to be strong.
@@ -256,19 +293,40 @@ at least one number, and at least one special symbol.
256
293
257
294
Return True if the password is a strong password, False if not.
258
295
"""
259
-
returnany(char.isupper() for char in password) and \
260
-
any(char.isdigit() for char in password) and \
296
+
returnany(char.isupper() for char in password) and
297
+
any(char.isdigit() for char in password) and
298
+
any(not char.isalnum() for char in password)
299
+
```
300
+
301
+
```python
302
+
defis_strong_password(password):
303
+
"""
304
+
强密码应至少包含一个大写字母,
305
+
至少一个数字,以及至少一个特殊符号。
306
+
307
+
判断密码是否符合强密码标准,是则返回 True,否则返回 False。
308
+
"""
309
+
returnany(char.isupper() for char in password) and
310
+
any(char.isdigit() for char in password) and
261
311
any(not char.isalnum() for char in password)
262
312
```
263
313
264
314
That `for char in password` that shows up a few times here is a way for Python to consider each character of the password. It enables something called a loop, which is a key topic that we’ll study in Chapter 5.
265
315
316
+
这几处 `for char in password` 是 Python 用来遍历密码中每个字符的语法。它开启了循环这一功能,这是我们在第五章将要详细学习的核心概念。
317
+
266
318
It’s of course possible that you didn’t get the same code from Copilot as we did. But based on the code that we got, it looks like the first piece is looking for any uppercase character, the second piece is looking for any digit, and the third is looking for something that's not an `isalnum`.
Let's test this function to see how well we’re doing.
271
327
328
+
我们来测试这个函数,评估一下它的效果如何。
329
+
272
330
```
273
331
>>> is_strong_password('Leo')
274
332
False
@@ -282,14 +340,22 @@ True
282
340
283
341
Uh oh—we got the wrong answer for that third password. It looks pretty strong, but it's not, because it lacks a special symbol. Our function returned `True`, but that’s the wrong return value: it was supposed to return `False`.
The code that Copilot gave us is wrong. Maybe the code that you got worked fine, but we didn’t get so lucky and it’s important we know how to identify (like we just did) when the code is wrong and then fix it. It’s not important to know why it’s wrong right now, but if you are curious about why our prompt may have given us the wrong behavior, we didn’t specify what we meant by a special character and the code it gave us counts spaces as special characters.
At this point, with our wrong code, we have two options. One option is to hit `<Ctrl>+Enter` and look through the other suggestions that Copilot gives us. Maybe one of those suggestions will have something to do with special symbols that looks different from the one that didn't work?
In our original prompt, we talked about "special symbols". This, in retrospect, is pretty vague. We probably meant something more specific, like "punctuation". If we specifically talk about punctuation in our prompt, we get this interaction with Copilot:
Look at the bottom of that error message, `'string'` is not defined, eh? We’re running into an issue that’s similar to what we saw in Chapter 2 with modules. Copilot wants to use a module, called `string`, but it is a module that needs to be imported before we can use it. There are a lot of modules in Python, but the `string` module is pretty well known. As you work with Copilot more, you’ll learn which modules are commonly used so you know to import them. You could also do a quick internet search to ask, “is string a Python module” and the results would confirm that it is. What we need to do is import the module.
Note that this is different, somewhat, from what we encountered in Chapter 2\. In Chapter 2, we saw what happens when the code from Copilot imports modules we didn’t have installed, and we had to install the package containing those modules to fix the issue. In this case, the code from Copilot is using a module that already happens to be installed with Python, but it forgot to import it. So, we don’t need to install string; we just have to import it.
> There are a number of useful modules available in Python. We saw how powerful matplotlib is in Chapter 2. But in order for Python code to take advantage of modules, we have to import that module. You might ask why don’t we just have modules available to us without importing them, but that would massively increase the complexity of the code and what Python has to do to run code behind the scenes. Instead, the model is to include modules if you want to use them, and they aren’t included by default.
@@ -369,9 +463,10 @@ Return True if the password is a strong password, False if not.
369
463
any(char in string.punctuation for char in password)
370
464
```
371
465
372
-
373
466
Now we're in good shape:
374
467
468
+
目前我们的状况相当不错:
469
+
375
470
```
376
471
>>> is_strong_password('Leo')
377
472
False
@@ -385,8 +480,12 @@ True
385
480
386
481
That last one is `True`—-it's a strong password!—because it has the `$` punctuation added to it.
387
482
483
+
最后一个结果显示为 `True`——这个密码很安全!——这得益于它包含了 `$` 这个符号。
484
+
388
485
We hope that you're now convinced of the value of testing! Sometimes our students don’t test their code. They assume that the code they write is correct because it made sense to them. An interesting difference between novice and experienced programmers is that novices often assume their code is right, whereas experience programmers assume the code is wrong until thoroughly tested and proved otherwise. Beyond this, we find that our students sometimes fail to test well because it's disheartening to learn that the code is wrong. But it's better to know now, rather than later when others are using your code in a serious application. Finding errors through testing is actually a good thing.
Now that we have a function that tells us whether a password is strong or not, let’s write a function that obtains a strong password from the user. It will ask again and again for a password until the user types a strong one. This is the kind of code that websites use when they tell you, “Sorry, your password is too weak, try again.”
0 commit comments