diff --git a/client/src/pages/learn/upcoming-python/learn-regular-expressions-by-building-a-password-generator/index.md b/client/src/pages/learn/upcoming-python/learn-regular-expressions-by-building-a-password-generator/index.md new file mode 100644 index 00000000000..deb7f9ea4a4 --- /dev/null +++ b/client/src/pages/learn/upcoming-python/learn-regular-expressions-by-building-a-password-generator/index.md @@ -0,0 +1,10 @@ +--- +title: Introduction to the Learn Regular Expressions by Building a Password Generator +block: learn-regular-expressions-by-building-a-password-generator +superBlock: upcoming-python +isBeta: true +--- + +## Introduction to the Learn Regular Expressions by Building a Password Generator + +This is a test for the new project-based curriculum. diff --git a/curriculum/challenges/_meta/learn-regular-expressions-by-building-a-password-generator/meta.json b/curriculum/challenges/_meta/learn-regular-expressions-by-building-a-password-generator/meta.json new file mode 100644 index 00000000000..c06a6a2496c --- /dev/null +++ b/curriculum/challenges/_meta/learn-regular-expressions-by-building-a-password-generator/meta.json @@ -0,0 +1,304 @@ +{ + "name": "Learn Regular Expressions by Building a Password Generator", + "isUpcomingChange": false, + "usesMultifileEditor": true, + "hasEditableBoundaries": true, + "dashedName": "learn-regular-expressions-by-building-a-password-generator", + "order": 4, + "time": "5 hours", + "template": "", + "required": [], + "superBlock": "scientific-computing-with-python", + "isBeta": true, + "challengeOrder": [ + { + "id": "6564642ce403fe29cc23fee7", + "title": "Step 1" + }, + { + "id": "6564683821b2ee3174e7250e", + "title": "Step 2" + }, + { + "id": "656469e62377ab34a5bcb8d1", + "title": "Step 3" + }, + { + "id": "656485a8a3496d4a36b1496a", + "title": "Step 4" + }, + { + "id": "65646ab6bced52360f44670f", + "title": "Step 5" + }, + { + "id": "6564883669b5af4b69f794cc", + "title": "Step 6" + }, + { + "id": "656489e0a5d0954c1a64fc93", + "title": "Step 7" + }, + { + "id": "65646ffeaed2d238c562a014", + "title": "Step 8" + }, + { + "id": "656470d517833a39bb8b5608", + "title": "Step 9" + }, + { + "id": "656474314bf37d3c83a85143", + "title": "Step 10" + }, + { + "id": "656475bbf1c2573de1d2c69c", + "title": "Step 11" + }, + { + "id": "656477845006313fbfea0ad1", + "title": "Step 12" + }, + { + "id": "656479aa5f298441c190bf8f", + "title": "Step 13" + }, + { + "id": "65647c71a5d2bd431596f629", + "title": "Step 14" + }, + { + "id": "65648e4c5b316c4ec5e4fddc", + "title": "Step 15" + }, + { + "id": "65648eefbee2014f5815f4ba", + "title": "Step 16" + }, + { + "id": "65648f4b2281ba50051ae39c", + "title": "Step 17" + }, + { + "id": "6564a767a7241362f7d8d664", + "title": "Step 18" + }, + { + "id": "656490295d346850a4c4f2b5", + "title": "Step 19" + }, + { + "id": "65649122c7f77f519aaf0975", + "title": "Step 20" + }, + { + "id": "656491fa4e69005287eb5a9a", + "title": "Step 21" + }, + { + "id": "656ef54070c72161e6feb90f", + "title": "Step 22" + }, + { + "id": "656ef5bc5c0cd464be1df675", + "title": "Step 23" + }, + { + "id": "656ef783bba6976de014eaa8", + "title": "Step 24" + }, + { + "id": "656ef7f792734072dedd8319", + "title": "Step 25" + }, + { + "id": "656ef89b4b486b7a16077864", + "title": "Step 26" + }, + { + "id": "656494269ccce754411a2112", + "title": "Step 27" + }, + { + "id": "65649a631440b757f9f7b428", + "title": "Step 28" + }, + { + "id": "6564b8c9349bd76dc037967b", + "title": "Step 29" + }, + { + "id": "656eec2f40d18056cc58b229", + "title": "Step 30" + }, + { + "id": "6564c67db26c417561ab510d", + "title": "Step 31" + }, + { + "id": "656f04b20397d9a574cc7eb2", + "title": "Step 32" + }, + { + "id": "656f0bc259c1f6b57486ed68", + "title": "Step 33" + }, + { + "id": "656f0d6bc60b58b9777a36c9", + "title": "Step 34" + }, + { + "id": "656f10458134d4c4e283a2f1", + "title": "Step 35" + }, + { + "id": "6564cbb6311a40783b3f5de6", + "title": "Step 36" + }, + { + "id": "6564cf2e8642517abdf9d6e2", + "title": "Step 37" + }, + { + "id": "6564d096a55d707bd77ab67b", + "title": "Step 38" + }, + { + "id": "6564d27c8e4c197d367c3b1c", + "title": "Step 39" + }, + { + "id": "6564d2eeb36ebe7dd9bd1ee9", + "title": "Step 40" + }, + { + "id": "6564d500f1a48e7f2b732a37", + "title": "Step 41" + }, + { + "id": "6564d68c34027a8072a704f4", + "title": "Step 42" + }, + { + "id": "6564d75a923d21815caaa445", + "title": "Step 43" + }, + { + "id": "6564d97a5ef99783216a6229", + "title": "Step 44" + }, + { + "id": "6564daa2725b9b8420141b1c", + "title": "Step 45" + }, + { + "id": "6564db880cf9408535f17ff4", + "title": "Step 46" + }, + { + "id": "6564dd65c3c2fa873a83d213", + "title": "Step 47" + }, + { + "id": "6564de10a0887f882b0012d3", + "title": "Step 48" + }, + { + "id": "6564eebf0d2d6390b9377197", + "title": "Step 49" + }, + { + "id": "6564efa70114b591b74d5679", + "title": "Step 50" + }, + { + "id": "6564f0279e23ce924eedd1b2", + "title": "Step 51" + }, + { + "id": "6564f32b18480893cf7799fd", + "title": "Step 52" + }, + { + "id": "6564f583ca6fbf9556098dd6", + "title": "Step 53" + }, + { + "id": "6564f834dd717998092cfd47", + "title": "Step 54" + }, + { + "id": "6564fd78ffff909b1531d3c3", + "title": "Step 55" + }, + { + "id": "6565012a2564509d40a90048", + "title": "Step 56" + }, + { + "id": "6565bb128adfcd5ec362382d", + "title": "Step 57" + }, + { + "id": "6565c014db6e9b63c257771d", + "title": "Step 58" + }, + { + "id": "6565bd4265158360de8e2ae7", + "title": "Step 59" + }, + { + "id": "6565c084627071646f94c4b0", + "title": "Step 60" + }, + { + "id": "6577319039f4f7de9251b822", + "title": "Step 61" + }, + { + "id": "657732654845d8e2fb1217e6", + "title": "Step 62" + }, + { + "id": "6577333feab1e8e927014f03", + "title": "Step 63" + }, + { + "id": "657733bc97eb83efdb7e3988", + "title": "Step 64" + }, + { + "id": "6565c13fdb798865c161d8f8", + "title": "Step 65" + }, + { + "id": "657dadf4d8b93c1704f3a57c", + "title": "Step 66" + }, + { + "id": "6565c234de8cdf673c96bdf3", + "title": "Step 67" + }, + { + "id": "657db2114b4029241956f5d6", + "title": "Step 68" + }, + { + "id": "657db4cb77190e33a20e852a", + "title": "Step 69" + }, + { + "id": "6565c32f89ab8d68b42aff30", + "title": "Step 70" + }, + { + "id": "6565c3a146bd5469b62bc59e", + "title": "Step 71" + }, + { + "id": "6565c4767f49286aec825c6d", + "title": "Step 72" + } + ], + "helpCategory": "Python" +} \ No newline at end of file diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564642ce403fe29cc23fee7.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564642ce403fe29cc23fee7.md new file mode 100644 index 00000000000..6e659d54341 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564642ce403fe29cc23fee7.md @@ -0,0 +1,30 @@ +--- +id: 6564642ce403fe29cc23fee7 +title: Step 1 +challengeType: 20 +dashedName: step-1 +--- + +# --description-- + +A Python module is a file containing code designed to perform specific tasks. The Python standard library contains many modules that you can import and use in your code. You can achieve this by using the `import` statement followed by the name of the module. + +Start this project by importing the `string` module. + +# --hints-- + +You should import the `string` module. + +```js +({ test: () => assert.match(code, /^import\s+string/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564683821b2ee3174e7250e.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564683821b2ee3174e7250e.md new file mode 100644 index 00000000000..1e4c026690c --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564683821b2ee3174e7250e.md @@ -0,0 +1,53 @@ +--- +id: 6564683821b2ee3174e7250e +title: Step 2 +challengeType: 20 +dashedName: step-2 +--- + +# --description-- + +You can access the utilities defined inside the imported module through the dot notation. The dot notation works by appending a dot followed by the utility name to the module name. For example, here's how to access the `ascii_lowercase` constant: + +```py +import string + + +print(string.ascii_lowercase) +# Output: abcdefghijklmnopqrstuvwxyz +``` + +In this project, you are going to use different constants from the `string` module. + +Declare a new variable called `letters` and assign `string.ascii_letters` to this variable. + +# --hints-- + +You should declare a variable named `letters`. + +```js +({ test: () => assert(__userGlobals.has("letters")) }) +``` + +You should assign `string.ascii_letters` to your `letters` variable. + +```js +({ test: () => assert(__pyodide.runPython(` + import string + abc = __locals.get("letters") + abc == string.ascii_letters + `)) +}) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +import string + + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656469e62377ab34a5bcb8d1.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656469e62377ab34a5bcb8d1.md new file mode 100644 index 00000000000..7ac084afe92 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656469e62377ab34a5bcb8d1.md @@ -0,0 +1,58 @@ +--- +id: 656469e62377ab34a5bcb8d1 +title: Step 3 +challengeType: 20 +dashedName: step-3 +--- + +# --description-- + +Declare two new variables named `digits` and `symbols` and assign them `string.digits` and `string.punctuation`, respectively. + +# --hints-- + +You should declare a variable named `digits`. + +```js +({ test: () => assert(__userGlobals.has("digits")) }) +``` + +You should assign `string.digits` to your `digits` variable. + +```js +({ test: () => assert(__pyodide.runPython(` + import string + nums = __locals.get("digits") + nums == string.digits + `)) +}) +``` + +You should declare a variable named `symbols`. + +```js +({ test: () => assert(__userGlobals.has("symbols")) }) +``` + +You should assign `string.punctuation` to your `symbols` variable. + +```js +({ test: () => assert(__pyodide.runPython(` + import string + s = __locals.get("symbols") + s == string.punctuation + `)) +}) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +import string + +letters = string.ascii_letters +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65646ab6bced52360f44670f.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65646ab6bced52360f44670f.md new file mode 100644 index 00000000000..cc5caadf882 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65646ab6bced52360f44670f.md @@ -0,0 +1,48 @@ +--- +id: 65646ab6bced52360f44670f +title: Step 5 +challengeType: 20 +dashedName: step-5 +--- + +# --description-- + +Now declare a variable named `all_characters` and assign it the result of concatenating your existing variables. + +# --hints-- + +You should declare a variable named `all_characters`. + +```js +({ test: () => assert(__userGlobals.has("all_characters")) }) +``` + +You should concatenate `letters`, `digits`, and `symbols` and assign the result to your `all_characters` variable. + +```js +({ test: () => assert(__pyodide.runPython(` + import string + from itertools import permutations + chars = __locals.get("all_characters") + perms = permutations([string.ascii_letters, string.digits, string.punctuation]) + any("".join(perm) == chars for perm in perms) + `)) +}) +``` + +# --seed-- + +## --seed-contents-- + +```py +import string + + +# Define the possible characters for the password +letters = string.ascii_letters +digits = string.digits +symbols = string.punctuation +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65646ffeaed2d238c562a014.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65646ffeaed2d238c562a014.md new file mode 100644 index 00000000000..fafcf5b14df --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65646ffeaed2d238c562a014.md @@ -0,0 +1,41 @@ +--- +id: 65646ffeaed2d238c562a014 +title: Step 8 +challengeType: 20 +dashedName: step-8 +--- + +# --description-- + +It is a common convention to place `import` statements at the top of your code. And additionally, in case of multiple `import` statements, sort them in alphabetical order to improve readability. + +At the top of your code, import the `random` module. + +# --hints-- + +You should import the `random` module. + +```js +({ test: () => assert.match(code, /^import\s+random/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +import string +--fcc-editable-region-- + +# Define the possible characters for the password +letters = string.ascii_letters +digits = string.digits +symbols = string.punctuation + +# Combine all characters +all_characters = letters + digits + symbols + +print(all_characters) + +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656470d517833a39bb8b5608.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656470d517833a39bb8b5608.md new file mode 100644 index 00000000000..6a7b665fa07 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656470d517833a39bb8b5608.md @@ -0,0 +1,43 @@ +--- +id: 656470d517833a39bb8b5608 +title: Step 9 +challengeType: 20 +dashedName: step-9 +--- + +# --description-- + +The `random` module contains a pseudo-random number generator. Most of its functionalities depend on the `random()` function, which returns a floating point number in the range between `0.0` (inclusive) and `1.0` (exclusive). + +Call the `random()` function and print the result. + +# --hints-- + +You should print `random.random()`. + +```js +({ test: () => assert.match(code, /^print\s*\(\s*random\.random\s*\(\s*\)\s*\)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import random +import string + + +# Define the possible characters for the password +letters = string.ascii_letters +digits = string.digits +symbols = string.punctuation + +# Combine all characters +all_characters = letters + digits + symbols + +print(all_characters) +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656474314bf37d3c83a85143.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656474314bf37d3c83a85143.md new file mode 100644 index 00000000000..ef3bfb73797 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656474314bf37d3c83a85143.md @@ -0,0 +1,43 @@ +--- +id: 656474314bf37d3c83a85143 +title: Step 10 +challengeType: 20 +dashedName: step-10 +--- + +# --description-- + +The `choice()` function from the `random` module takes a sequence and returns a random item of the sequence. + +Modify your `print()` call to use the `choice()` function and pass `all_characters` as the argument. + +# --hints-- + +You should modify your existing `print()` call to print `random.choice(all_characters)`. + +```js +({ test: () => assert.match(code, /^print\s*\(\s*random\.choice\s*\(\s*all_characters\s*\)\s*\)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import random +import string + + +# Define the possible characters for the password +letters = string.ascii_letters +digits = string.digits +symbols = string.punctuation + +# Combine all characters +all_characters = letters + digits + symbols + +print(all_characters) +--fcc-editable-region-- +print(random.random()) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656475bbf1c2573de1d2c69c.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656475bbf1c2573de1d2c69c.md new file mode 100644 index 00000000000..bdf9f83fd86 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656475bbf1c2573de1d2c69c.md @@ -0,0 +1,56 @@ +--- +id: 656475bbf1c2573de1d2c69c +title: Step 11 +challengeType: 20 +dashedName: step-11 +--- + +# --description-- + +Every time the code runs, you should see a random character from the `all_characters` string. This is exactly what you want to achieve to create a random password. + +However, the algorithm on which `random` relies makes the generated pseudo-random numbers predictable. Therefore, although the `random` module is suitable for the most common applications, it cannot be used for cryptographic purposes, due to its deterministic nature. + +Instead of importing `random`, import the `secrets` module. Then change the `print()` call to use `secrets.choice(all_characters)`. + +# --hints-- + +You should import the `secrets` module instead of the `random` module. + +```js +({ + test: () => { + assert.match(code, /^import\s+secrets/m) + assert.isFalse( /^import\s+random/m.test(code)) + } +}) +``` + +You should modify your existing `print()` call to print `secrets.choice(all_characters)`. + +```js +({ test: () => assert.match(code, /^print\s*\(\s*secrets\.choice\s*\(\s*all_characters\s*\)\s*\)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +import random +import string + + +# Define the possible characters for the password +letters = string.ascii_letters +digits = string.digits +symbols = string.punctuation + +# Combine all characters +all_characters = letters + digits + symbols + +print(all_characters) +print(random.choice(all_characters)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656477845006313fbfea0ad1.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656477845006313fbfea0ad1.md new file mode 100644 index 00000000000..30c5f76c957 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656477845006313fbfea0ad1.md @@ -0,0 +1,42 @@ +--- +id: 656477845006313fbfea0ad1 +title: Step 12 +challengeType: 20 +dashedName: step-12 +--- + +# --description-- + +Although the effect might seem equal to `random.choice()`, `secrets` ensure you the most secure source of randomness that your operating system can provide. + +Now, delete your two `print()` calls. + +# --hints-- + +You should delete your two `print()` calls. + +```js +({ test: () => assert.isFalse( /print/.test(code)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import secrets +import string + + +# Define the possible characters for the password +letters = string.ascii_letters +digits = string.digits +symbols = string.punctuation + +# Combine all characters +all_characters = letters + digits + symbols +--fcc-editable-region-- +print(all_characters) +print(secrets.choice(all_characters)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656479aa5f298441c190bf8f.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656479aa5f298441c190bf8f.md new file mode 100644 index 00000000000..98227cdc3fd --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656479aa5f298441c190bf8f.md @@ -0,0 +1,43 @@ +--- +id: 656479aa5f298441c190bf8f +title: Step 13 +challengeType: 20 +dashedName: step-13 +--- + +# --description-- + + Declare a `generate_password` function and write all your code except the `import` lines inside the function body. + +# --hints-- + +You should declare a function named `generate_password`. + +```js +({ test: () => assert(__pyodide.runPython(` + import inspect + generate_psw = __locals.get("generate_password") + inspect.isfunction(generate_psw) + `)) +}) +``` + +# --seed-- + +## --seed-contents-- + +```py +import secrets +import string + +--fcc-editable-region-- +# Define the possible characters for the password +letters = string.ascii_letters +digits = string.digits +symbols = string.punctuation + +# Combine all characters +all_characters = letters + digits + symbols + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65647c71a5d2bd431596f629.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65647c71a5d2bd431596f629.md new file mode 100644 index 00000000000..e81fdd50c83 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65647c71a5d2bd431596f629.md @@ -0,0 +1,46 @@ +--- +id: 65647c71a5d2bd431596f629 +title: Step 14 +challengeType: 20 +dashedName: step-14 +--- + +# --description-- + +Your `generate_password` function needs a few parameters. Start by adding a `length` parameter. + +# --hints-- + +Your `generate_password` function should take a `length` parameter. + +```js +({ test: () => assert(__pyodide.runPython(` + import inspect + generate_psw = __locals.get("generate_password") + sig = str(inspect.signature(generate_psw)) + sig == "(length)" + `)) +}) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +import secrets +import string + + +def generate_password(): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656485a8a3496d4a36b1496a.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656485a8a3496d4a36b1496a.md new file mode 100644 index 00000000000..0a0410ac4a3 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656485a8a3496d4a36b1496a.md @@ -0,0 +1,36 @@ +--- +id: 656485a8a3496d4a36b1496a +title: Step 4 +challengeType: 20 +dashedName: step-4 +--- + +# --description-- + +These three variables constitute the possible characters to choose from when generating the password. + +Just before them, add a comment saying `Define the possible characters for the password`. + +# --hints-- + +You should add the comment just above your three variables. + +```js +({ test: () => assert.match(code, /^#\s*Define the possible characters for the password.*^letters/ms) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +import string + + + +letters = string.ascii_letters +digits = string.digits +symbols = string.punctuation +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564883669b5af4b69f794cc.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564883669b5af4b69f794cc.md new file mode 100644 index 00000000000..a04cc0a51bf --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564883669b5af4b69f794cc.md @@ -0,0 +1,39 @@ +--- +id: 6564883669b5af4b69f794cc +title: Step 6 +challengeType: 20 +dashedName: step-6 +--- + +# --description-- + +Your `all_characters` variable is a string formed by all lowercase and uppercase letters, all the 10 digits and several special characters. + +Just before it, add a comment saying `Combine all characters`. + +# --hints-- + +You should add the comment just above your `all_characters` variable. + +```js +({ test: () => assert.match(code, /^#\s*Combine all characters\s+^all_characters/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- +import string + + +# Define the possible characters for the password +letters = string.ascii_letters +digits = string.digits +symbols = string.punctuation + + +all_characters = letters + digits + symbols +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656489e0a5d0954c1a64fc93.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656489e0a5d0954c1a64fc93.md new file mode 100644 index 00000000000..6fd9516c5a1 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656489e0a5d0954c1a64fc93.md @@ -0,0 +1,37 @@ +--- +id: 656489e0a5d0954c1a64fc93 +title: Step 7 +challengeType: 20 +dashedName: step-7 +--- + +# --description-- + +Now print the `all_characters` variable to see what it looks like. + +# --hints-- + +You should print your `all_characters` variable. + +```js +({ test: () => assert.match(code, /^print\s*\(\s*all_characters\s*\)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import string + + +# Define the possible characters for the password +letters = string.ascii_letters +digits = string.digits +symbols = string.punctuation +--fcc-editable-region-- +# Combine all characters +all_characters = letters + digits + symbols + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65648e4c5b316c4ec5e4fddc.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65648e4c5b316c4ec5e4fddc.md new file mode 100644 index 00000000000..8677b8d5536 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65648e4c5b316c4ec5e4fddc.md @@ -0,0 +1,47 @@ +--- +id: 65648e4c5b316c4ec5e4fddc +title: Step 15 +challengeType: 20 +dashedName: step-15 +--- + +# --description-- + +At the bottom of your function, declare a `password` variable and assign an empty string to this variable. + +# --hints-- + +You should have a `password` variable inside your function with the value of an empty string. Pay attention to the indentation. + +```js +({ test: () => + { + const transformedCode = code.replace(/\r/g, ""); + const generate_pw = __helpers.python.getDef("\n"+transformedCode, "generate_password"); + const {function_body} = generate_pw; + assert(function_body.match(/password\s*=\s*("|')\1/)); + } +}) +``` + +# --seed-- + +## --seed-contents-- + +```py +import secrets +import string + + +def generate_password(length): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65648eefbee2014f5815f4ba.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65648eefbee2014f5815f4ba.md new file mode 100644 index 00000000000..2351611d9f1 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65648eefbee2014f5815f4ba.md @@ -0,0 +1,48 @@ +--- +id: 65648eefbee2014f5815f4ba +title: Step 16 +challengeType: 20 +dashedName: step-16 +--- + +# --description-- + +Below your new variable, add a comment saying `Generate password`. + +# --hints-- + +You should add the provided comment. + +```js +({ test: () => + { + const transformedCode = code.replace(/\r/g, ""); + const generate_pw = __helpers.python.getDef("\n"+transformedCode, "generate_password"); + const {function_body} = generate_pw; + assert(function_body.match(/#\s*Generate password/)); + } +}) +``` + +# --seed-- + +## --seed-contents-- + +```py +import secrets +import string + + +def generate_password(length): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols +--fcc-editable-region-- + password = '' + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65648f4b2281ba50051ae39c.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65648f4b2281ba50051ae39c.md new file mode 100644 index 00000000000..e2e180033f5 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65648f4b2281ba50051ae39c.md @@ -0,0 +1,62 @@ +--- +id: 65648f4b2281ba50051ae39c +title: Step 17 +challengeType: 20 +dashedName: step-17 +--- + +# --description-- + +Next, write a `for` loop with `i` as the loop variable. Use the `range()` function to iterate up to the value of the `length`. + +Inside the loop, use the addition assignment operator to add a random character from `all_characters` to the current value of `password`. Use the `choice()` function from the `secrets` module for that. + +# --hints-- + +You should write a `for` loop that iterates over `range(length)`. + +```js +({ test: () => + { + const transformedCode = code.replace(/\r/g, ""); + const generate_pw = __helpers.python.getDef("\n"+transformedCode, "generate_password"); + const {function_body} = generate_pw; + assert(function_body.match(/for\s+i\s+in\s+range\s*\(\s*length\s*\)\s*:/)); + } +}) +``` + +You should use the `+=` operator to add a random character from `all_characters` to the current value of `password`. + +```js +({ test: () => + { + const generate_pwd = __helpers.python.getDef(code, "generate_password"); + const {function_body} = generate_pwd; + assert(function_body.match(/^(\s*)for\s+i\s+in\s+range\s*\(\s*length\s*\)\s*:\s*^\1\1password\s*\+=\s*secrets\.choice\s*\(\s*all_characters\s*\)/m)); + } +}) +``` + +# --seed-- + +## --seed-contents-- + +```py +import secrets +import string + +def generate_password(length): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols +--fcc-editable-region-- + password = '' + # Generate password + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656490295d346850a4c4f2b5.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656490295d346850a4c4f2b5.md new file mode 100644 index 00000000000..a31789007a2 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656490295d346850a4c4f2b5.md @@ -0,0 +1,51 @@ +--- +id: 656490295d346850a4c4f2b5 +title: Step 19 +challengeType: 20 +dashedName: step-19 +--- + +# --description-- + +After the loop, add a `return` statement to your function so it returns the `password` variable. + +# --hints-- + +You should return `password` at the end of your function. + +```js +({ test: () => + { + const transformedCode = code.replace(/\r/g, ""); + const generate_pw = __helpers.python.getDef("\n"+transformedCode, "generate_password"); + const {function_body} = generate_pw; + assert(function_body.match(/^(\s*)for\s+\w\s+in\s+range\s*\(\s*length\s*\)\s*:.+^\1return\s+password/ms)); + } +}) +``` + +# --seed-- + +## --seed-contents-- + +```py +import secrets +import string + + +def generate_password(length): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols +--fcc-editable-region-- + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65649122c7f77f519aaf0975.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65649122c7f77f519aaf0975.md new file mode 100644 index 00000000000..37997047d64 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65649122c7f77f519aaf0975.md @@ -0,0 +1,59 @@ +--- +id: 65649122c7f77f519aaf0975 +title: Step 20 +challengeType: 20 +dashedName: step-20 +--- + +# --description-- + +Finally, call the `generate_password` function with `8` as the argument and assign the function call to a `new_password` variable. + +# --hints-- + +You should call `generate_password` passing `8` as the argument. + +```js +({ test: () => assert.match(code, /generate_password\s*\(\s*8\s*\)/) }) +``` + +You should assign `generate_password(8)` to a `new_password` variable. + +```js +({ + test: () => { + assert(__userGlobals.has("new_password")); + assert.match(code, /^new_password\s*=\s*generate_password\s*\(\s*8\s*\)/m); + } +}) +``` + +# --seed-- + +## --seed-contents-- + +```py +import secrets +import string + + +def generate_password(length): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + return password + +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656491fa4e69005287eb5a9a.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656491fa4e69005287eb5a9a.md new file mode 100644 index 00000000000..10643186b08 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656491fa4e69005287eb5a9a.md @@ -0,0 +1,49 @@ +--- +id: 656491fa4e69005287eb5a9a +title: Step 21 +challengeType: 20 +dashedName: step-21 +--- + +# --description-- + +Check the result by printing your new variable. + +# --hints-- + +You should print `new_password`. + +```js +({ test: () => assert.match(code, /^print\s*\(\s*new_password\s*\)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import secrets +import string + + +def generate_password(length): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + return password + +--fcc-editable-region-- +new_password = generate_password(8) + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656494269ccce754411a2112.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656494269ccce754411a2112.md new file mode 100644 index 00000000000..06daef69d1e --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656494269ccce754411a2112.md @@ -0,0 +1,56 @@ +--- +id: 656494269ccce754411a2112 +title: Step 27 +challengeType: 20 +dashedName: step-27 +--- + +# --description-- + +The `re` module allows you to use *regular expressions* in your code. You will learn more about regular expressions very soon. + +For now, add an `import` statement at the top of your code to import the `re` module. + +# --hints-- + +You should import the `re` module. + +```js +({ test: () => assert.match(code, /^import\s+re/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +--fcc-editable-region-- + +import secrets +import string +--fcc-editable-region-- + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, '') + ] + + return password + +# new_password = generate_password(8) +# print(new_password) +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65649a631440b757f9f7b428.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65649a631440b757f9f7b428.md new file mode 100644 index 00000000000..766eaf6b0ef --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/65649a631440b757f9f7b428.md @@ -0,0 +1,71 @@ +--- +id: 65649a631440b757f9f7b428 +title: Step 28 +challengeType: 20 +dashedName: step-28 +--- + +# --description-- + +A regular expression, or regex, is a pattern used to match a specific combination of characters inside a string. It is a valid alternative to `if`/`else` conditional statements when you need to match or find patterns inside a string for validation purposes, character replacement, and others. + +The `compile()` function from the `re` module compiles the string passed as the argument into a regular expression object that can be used by other `re` methods. + +Declare a new `pattern` variable and assign the value of `re.compile('i')` to this variable. + +# --hints-- + +You should declare a `pattern` variable. + +```js +({ test: () => assert(__userGlobals.has("pattern")) }) +``` + +You should assign `re.compile('i')` to your `pattern` variable. + +```js +({ test: () => assert(__pyodide.runPython(` + import re + p = __locals.get("pattern") + p == re.compile('i') + `)) +}) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, '') + ] + + return password + +# new_password = generate_password(8) +# print(new_password) +--fcc-editable-region-- + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564a767a7241362f7d8d664.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564a767a7241362f7d8d664.md new file mode 100644 index 00000000000..ae5e8ab15e1 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564a767a7241362f7d8d664.md @@ -0,0 +1,54 @@ +--- +id: 6564a767a7241362f7d8d664 +title: Step 18 +challengeType: 20 +dashedName: step-18 +--- + +# --description-- + +A standalone single underscore is used to represent a value you don't care or that won't be used in your code. +Your iteration variable is not actually used. + +Modify your `i` variable into a single underscore. + +# --hints-- + +You should modify your `i` variable into `_`. + +```js +({ test: () => + { + const transformedCode = code.replace(/\r/g, ""); + const generate_pw = __helpers.python.getDef("\n"+transformedCode, "generate_password"); + const {function_body} = generate_pw; + assert(function_body.match(/for\s+_\s+in\s+range\s*\(\s*length\s*\)\s*:/)); + } +}) +``` + +# --seed-- + +## --seed-contents-- + +```py +import secrets +import string + + +def generate_password(length): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols +--fcc-editable-region-- + password = '' + # Generate password + for i in range(length): + password += secrets.choice(all_characters) + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564b8c9349bd76dc037967b.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564b8c9349bd76dc037967b.md new file mode 100644 index 00000000000..df213fe08f1 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564b8c9349bd76dc037967b.md @@ -0,0 +1,71 @@ +--- +id: 6564b8c9349bd76dc037967b +title: Step 29 +challengeType: 20 +dashedName: step-29 +--- + +# --description-- + +The `search()` function from the `re` module analyzes the string passed as the argument looking for the first place where the regex pattern matches the string. + +Declare a variable called `quote` and assign the string `Not all those who wander are lost.` to this variable. Then, print the result of `pattern.search(quote)`. + +# --hints-- + +You should have a `quote` variable. + +```js +({ test: () => assert(__userGlobals.has("quote")) }) +``` + +You should assign the provided string to your new `quote` variable. + +```js +({ test: () => assert.equal(__userGlobals.get("quote"), "Not all those who wander are lost.") }) +``` + +You should print `pattern.search(quote)`. + +```js +({ test: () => assert.match(code, /^print\s*\(\s*pattern\.search\s*\(\s*quote\s*\)\s*\)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, '') + ] + + return password + +# new_password = generate_password(8) +# print(new_password) +--fcc-editable-region-- +pattern = re.compile('i') + +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564c67db26c417561ab510d.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564c67db26c417561ab510d.md new file mode 100644 index 00000000000..ea14a6de78f --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564c67db26c417561ab510d.md @@ -0,0 +1,67 @@ +--- +id: 6564c67db26c417561ab510d +title: Step 31 +challengeType: 20 +dashedName: step-31 +--- + +# --description-- + +As you can see from the output, now your regex matches the first `l` inside the string. + +In your pattern, you can add a quantifier after a character to specify how many times that character should be repeated. For example, the `+` quantifier means it should repeat one or more times. + +Add a `+` quantifier to your pattern. + +# --hints-- + +You should modify your `pattern` variable into `re.compile('l+')`. + +```js +({ test: () => assert(__pyodide.runPython(` + import re + p = __locals.get("pattern") + p == re.compile('l+') + `)) +}) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, '') + ] + + return password + +# new_password = generate_password(8) +# print(new_password) +--fcc-editable-region-- +pattern = re.compile('l') +quote = 'Not all those who wander are lost.' +print(pattern.search(quote)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564cbb6311a40783b3f5de6.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564cbb6311a40783b3f5de6.md new file mode 100644 index 00000000000..525deb93a9a --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564cbb6311a40783b3f5de6.md @@ -0,0 +1,60 @@ +--- +id: 6564cbb6311a40783b3f5de6 +title: Step 36 +challengeType: 20 +dashedName: step-36 +--- + +# --description-- + +Character classes also allow you to indicate a range of characters to match. You need to specify the starting and the ending characters separated by an hyphen, `-`. Characters follow the Unicode order. + +Modify your `pattern` variable to match any letter `t` preceded by a lowercase letter in the `quote` variable. Use the range of characters from `a` to `z` for that. + +# --hints-- + +You should modify your `pattern` variable to match any letter `t` in `quote` preceded by a lowercase letter using the `[a-z]` class. + +```js +({ test: () => assert.equal(__userGlobals.get("pattern"), "[a-z]t") }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, '[0123456789]') + ] + + return password + +# new_password = generate_password(8) +# print(new_password) +--fcc-editable-region-- +pattern = 'w[ha]' +quote = 'Not all those who wander are lost.' +print(re.findall(pattern, quote)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564cf2e8642517abdf9d6e2.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564cf2e8642517abdf9d6e2.md new file mode 100644 index 00000000000..241ee2936b0 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564cf2e8642517abdf9d6e2.md @@ -0,0 +1,58 @@ +--- +id: 6564cf2e8642517abdf9d6e2 +title: Step 37 +challengeType: 20 +dashedName: step-37 +--- + +# --description-- + +Now, modify the pattern in your constraint tuple to indicate the range of all digits using square brackets. + +# --hints-- + +You should have the `(nums, '[0-9]')` tuple in your `constraints` list. + +```js +({ test: () => assert.match(code, /constraints\s*=\s*\[\s*\(\s*nums\s*,\s*("|')\[0-9\]\1\s*\)\s*\]/) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) +--fcc-editable-region-- + constraints = [ + (nums, '[0123456789]') + ] +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) + +pattern = '[a-z]t' +quote = 'Not all those who wander are lost.' +#print(re.findall(pattern, quote)) + +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d096a55d707bd77ab67b.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d096a55d707bd77ab67b.md new file mode 100644 index 00000000000..7c060bca5cf --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d096a55d707bd77ab67b.md @@ -0,0 +1,60 @@ +--- +id: 6564d096a55d707bd77ab67b +title: Step 38 +challengeType: 20 +dashedName: step-38 +--- + +# --description-- + +The caret, `^`, placed at the beginning of the character class, matches all the characters except those specified in the class. + +Add a `^` as the first character inside your character class and see what happens. + +# --hints-- + +You should add a `^` as the first character inside your character class. + +```js +({ test: () => assert.equal(__userGlobals.get("pattern"), "[^a-z]t") }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, '[0-9]') + ] + + return password + +# new_password = generate_password(8) +# print(new_password) +--fcc-editable-region-- +pattern = '[a-z]t' +quote = 'Not all those who wander are lost.' +print(re.findall(pattern, quote)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d27c8e4c197d367c3b1c.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d27c8e4c197d367c3b1c.md new file mode 100644 index 00000000000..1d7f583c3e4 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d27c8e4c197d367c3b1c.md @@ -0,0 +1,58 @@ +--- +id: 6564d27c8e4c197d367c3b1c +title: Step 39 +challengeType: 20 +dashedName: step-39 +--- + +# --description-- + +Add a new tuple to the `constraints` list. Use `lowercase` as the first item and a regex pattern that matches a single lowercase letter as the second item. + +# --hints-- + +You should add a second tuple to the `constraints` list. Use the `lowercase` parameter as the first item and `[a-z]` as the second item. + +```js +({ test: () => assert.match(code, /constraints\s*=\s*\[\s*\(\s*nums\s*,\s*("|')\[0-9\]\1\s*\)\s*,\s*\(\s*lowercase\s*,\s*("|')\[a-z\]\2\s*\)\s*,?\s*\]/) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) +--fcc-editable-region-- + constraints = [ + (nums, '[0-9]') + ] +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) + +pattern = '[^a-z]t' +quote = 'Not all those who wander are lost.' +# print(re.findall(pattern, quote)) + +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d2eeb36ebe7dd9bd1ee9.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d2eeb36ebe7dd9bd1ee9.md new file mode 100644 index 00000000000..9bbbad8cfdf --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d2eeb36ebe7dd9bd1ee9.md @@ -0,0 +1,59 @@ +--- +id: 6564d2eeb36ebe7dd9bd1ee9 +title: Step 40 +challengeType: 20 +dashedName: step-40 +--- + +# --description-- + +Add a third tuple to the `constraints` list. Use the `uppercase` parameter as the first item and a regex pattern that matches a single uppercase letter as the second item. + +# --hints-- + +You should add a third tuple to the `constraints` list using `uppercase` as the first item and a character class that matches a single uppercase letter as the second item. + +```js +({ test: () => assert.match(code, /constraints\s*=\s*\[\s*\(\s*nums\s*,\s*("|')\[0-9\]\1\s*\)\s*,\s*\(\s*lowercase\s*,\s*("|')\[a-z\]\2\s*\)\s*,\s*\(\s*uppercase\s*,\s*("|')\[A-Z\]\3\s*\)\s*,?\s*\]/) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) +--fcc-editable-region-- + constraints = [ + (nums, '[0-9]'), + (lowercase, '[a-z]') + ] +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) + +pattern = '[^a-z]t' +quote = 'Not all those who wander are lost.' +# print(re.findall(pattern, quote)) + +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d500f1a48e7f2b732a37.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d500f1a48e7f2b732a37.md new file mode 100644 index 00000000000..4367db96fc0 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d500f1a48e7f2b732a37.md @@ -0,0 +1,60 @@ +--- +id: 6564d500f1a48e7f2b732a37 +title: Step 41 +challengeType: 20 +dashedName: step-41 +--- + +# --description-- + +Add one last tuple to your list. Use the `special_chars` parameter as the first item and an empty string as the second item. + +# --hints-- + +You should add a fourth tuple to the `constraints` list using `special_chars` as the first item and an empty string as the second item. + +```js +({ test: () => assert.match(code, /constraints\s*=\s*\[\s*\(\s*nums\s*,\s*("|')\[0-9\]\1\s*\)\s*,\s*\(\s*lowercase\s*,\s*("|')\[a-z\]\2\s*\)\s*,\s*\(\s*uppercase\s*,\s*("|')\[A-Z\]\3\s*\)\s*,\s*\(\s*special_chars\s*,\s*("|')\4\s*\)\s*,?\s*\]/) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) +--fcc-editable-region-- + constraints = [ + (nums, '[0-9]'), + (lowercase, '[a-z]'), + (uppercase, '[A-Z]') + ] +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) + +pattern = '[^a-z]t' +quote = 'Not all those who wander are lost.' +# print(re.findall(pattern, quote)) + +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d68c34027a8072a704f4.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d68c34027a8072a704f4.md new file mode 100644 index 00000000000..85af9f0e5c7 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d68c34027a8072a704f4.md @@ -0,0 +1,61 @@ +--- +id: 6564d68c34027a8072a704f4 +title: Step 42 +challengeType: 20 +dashedName: step-42 +--- + +# --description-- + +The dot character is a wildcard that matches any character in a string — except for a newline character by default. Modify `pattern` to match the entire string. Use a `.` followed by the `+` quantifier. + +# --hints-- + +You should modify your `pattern` variable to match the whole `quote` string. + +```js +({ test: () => assert.equal(__userGlobals.get("pattern"), ".+") }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, '[0-9]'), + (lowercase, '[a-z]'), + (uppercase, '[A-Z]'), + (special_chars, '') + ] + + return password + +# new_password = generate_password(8) +# print(new_password) +--fcc-editable-region-- +pattern = '[^a-z]t' +quote = 'Not all those who wander are lost.' +print(re.findall(pattern, quote)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d75a923d21815caaa445.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d75a923d21815caaa445.md new file mode 100644 index 00000000000..4ae0fdbe47f --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d75a923d21815caaa445.md @@ -0,0 +1,63 @@ +--- +id: 6564d75a923d21815caaa445 +title: Step 43 +challengeType: 20 +dashedName: step-43 +--- + +# --description-- + +If you need to match a character that has a special meaning in the pattern, such as `.` or `+`, you can escape it by prepending a backslash character, `\`. For example, this matches a literal plus sign: `\+`. + +Modify `pattern` so that it matches a single literal dot. + +# --hints-- + +You should modify your `pattern` variable into `\.`. + +```js +({ test: () => assert.match(code, /^pattern\s*=\s*("|')\\\.\1/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, '[0-9]'), + (lowercase, '[a-z]'), + (uppercase, '[A-Z]'), + (special_chars, '') + ] + + return password + +# new_password = generate_password(8) +# print(new_password) +--fcc-editable-region-- +pattern = '.+' +quote = 'Not all those who wander are lost.' +print(re.findall(pattern, quote)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d97a5ef99783216a6229.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d97a5ef99783216a6229.md new file mode 100644 index 00000000000..132d22a267f --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564d97a5ef99783216a6229.md @@ -0,0 +1,63 @@ +--- +id: 6564d97a5ef99783216a6229 +title: Step 44 +challengeType: 20 +dashedName: step-44 +--- + +# --description-- + +Python provides a particular type of string called *raw* string. Raw strings are prefixed with a `r`. The key distinction from regular strings lies in how they handle the backslash character: in raw strings, backslashes are treated as literal characters rather than escape characters. When writing regular expressions, using raw strings is a good practice, since they can usually contain a lot of `\` characters. + +Turn your `pattern` string into a raw string by prefixing it with a `r`. + +# --hints-- + +You should modify your `pattern` variable into `r'\.'`. + +```js +({ test: () => assert.match(code, /^pattern\s*=\s*r("|')\\\.\1/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, '[0-9]'), + (lowercase, '[a-z]'), + (uppercase, '[A-Z]'), + (special_chars, '') + ] + + return password + +# new_password = generate_password(8) +# print(new_password) +--fcc-editable-region-- +pattern = '\.' +quote = 'Not all those who wander are lost.' +print(re.findall(pattern, quote)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564daa2725b9b8420141b1c.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564daa2725b9b8420141b1c.md new file mode 100644 index 00000000000..39f6c2d6d8e --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564daa2725b9b8420141b1c.md @@ -0,0 +1,61 @@ +--- +id: 6564daa2725b9b8420141b1c +title: Step 45 +challengeType: 20 +dashedName: step-45 +--- + +# --description-- + +Now, turn the four patterns from the `constraints` list into raw strings. + +# --hints-- + +You should turn the four strings inside the `constraints` list into raw strings. + +```js +({ test: () => assert.match(code, /constraints\s*=\s*\[\s*\(\s*nums\s*,\s*r("|')\[0-9\]\1\s*\)\s*,\s*\(\s*lowercase\s*,\s*r("|')\[a-z\]\2\s*\)\s*,\s*\(\s*uppercase\s*,\s*r("|')\[A-Z\]\3\s*\)\s*,\s*\(\s*special_chars\s*,\s*r("|')\4\s*\)\s*,?\s*\]/) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) +--fcc-editable-region-- + constraints = [ + (nums, '[0-9]'), + (lowercase, '[a-z]'), + (uppercase, '[A-Z]'), + (special_chars, '') + ] +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) + +pattern = r'\.' +quote = 'Not all those who wander are lost.' +# print(re.findall(pattern, quote)) + +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564db880cf9408535f17ff4.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564db880cf9408535f17ff4.md new file mode 100644 index 00000000000..af15d2918e5 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564db880cf9408535f17ff4.md @@ -0,0 +1,61 @@ +--- +id: 6564db880cf9408535f17ff4 +title: Step 46 +challengeType: 20 +dashedName: step-46 +--- + +# --description-- + +The character class `\d` is a shorthand for `[0-9]`. Replace this character class with the shorthand inside your first constraint tuple. + +# --hints-- + +You should turn the `[0-9]` class into `\d`. + +```js +({ test: () => assert.match(code, /constraints\s*=\s*\[\s*\(\s*nums\s*,\s*r("|')\\d\1\s*\)\s*,\s*\(\s*lowercase\s*,\s*r("|')\[a-z\]\2\s*\)\s*,\s*\(\s*uppercase\s*,\s*r("|')\[A-Z\]\3\s*\)\s*,\s*\(\s*special_chars\s*,\s*r("|')\4\s*\)\s*,?\s*\]/) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) +--fcc-editable-region-- + constraints = [ + (nums, r'[0-9]'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), + (special_chars, r'') + ] +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) + +pattern = r'\.' +quote = 'Not all those who wander are lost.' +# print(re.findall(pattern, quote)) + +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564dd65c3c2fa873a83d213.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564dd65c3c2fa873a83d213.md new file mode 100644 index 00000000000..d798220a04a --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564dd65c3c2fa873a83d213.md @@ -0,0 +1,63 @@ +--- +id: 6564dd65c3c2fa873a83d213 +title: Step 47 +challengeType: 20 +dashedName: step-47 +--- + +# --description-- + +In a character class, you can combine multiple ranges by writing one range after another inside the square brackets (without any additional characters). For example: `[a-d3-6]` is the combination of `[a-d]` and `[3-6]`. + +Now, create your fourth pattern to match any non-alphanumeric character. Combine the `a-z`, `A-Z`, and `0-9` ranges into a single character class and add a `^` as the first character to negate the pattern. + +# --hints-- + +You should complete your fourth pattern to match any non-alphanumeric character. + +```js +({ test: () => assert.match(code, /constraints\s*=\s*\[\s*\(\s*nums\s*,\s*r("|')\\d\1\s*\)\s*,\s*\(\s*lowercase\s*,\s*r("|')\[a-z\]\2\s*\)\s*,\s*\(\s*uppercase\s*,\s*r("|')\[A-Z\]\3\s*\)\s*,\s*\(\s*special_chars\s*,\s*r("|')\[\^a-zA-Z0-9\]\4\s*\)\s*,?\s*\]/) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) +--fcc-editable-region-- + constraints = [ + (nums, r'\d'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), + (special_chars, r'') + ] +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) + +pattern = r'\.' +quote = 'Not all those who wander are lost.' +# print(re.findall(pattern, quote)) + +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564de10a0887f882b0012d3.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564de10a0887f882b0012d3.md new file mode 100644 index 00000000000..1a1fcb72764 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564de10a0887f882b0012d3.md @@ -0,0 +1,63 @@ +--- +id: 6564de10a0887f882b0012d3 +title: Step 48 +challengeType: 20 +dashedName: step-48 +--- + +# --description-- + +In the same way the `[0-9]` class is equivalent to `\d`, the `[^0-9]` class is equivalent to `\D`. Alphanumeric characters can be matched with `\w` and non-alphanumeric characters can be matched with `\W`. + +Replace the `[^a-zA-Z0-9]` character class with `\W`. + +# --hints-- + +You should replace the `[^a-zA-Z0-9]` character class with `\W`. + +```js +({ test: () => assert.match(code, /constraints\s*=\s*\[\s*\(\s*nums\s*,\s*r("|')\\d\1\s*\)\s*,\s*\(\s*lowercase\s*,\s*r("|')\[a-z\]\2\s*\)\s*,\s*\(\s*uppercase\s*,\s*r("|')\[A-Z\]\3\s*\)\s*,\s*\(\s*special_chars\s*,\s*r("|')\\W\4\s*\)\s*,?\s*\]/) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) +--fcc-editable-region-- + constraints = [ + (nums, r'\d'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), + (special_chars, r'[^a-zA-Z0-9]') + ] +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) + +pattern = r'\.' +quote = 'Not all those who wander are lost.' +# print(re.findall(pattern, quote)) + +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564eebf0d2d6390b9377197.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564eebf0d2d6390b9377197.md new file mode 100644 index 00000000000..af02fd4a4d4 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564eebf0d2d6390b9377197.md @@ -0,0 +1,61 @@ +--- +id: 6564eebf0d2d6390b9377197 +title: Step 49 +challengeType: 20 +dashedName: step-49 +--- + +# --description-- + +Now, turn `pattern` into the shorthand class for non-alphanumeric characters. + +# --hints-- + +Your `pattern` variable should be `\W`. + +```js +({ test: () => assert.match(code, /^pattern\s*=\s*r("|')\\W\1/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), + (special_chars, r'\W') + ] + + return password + +# new_password = generate_password(8) +# print(new_password) +--fcc-editable-region-- +pattern = r'\.' +quote = 'Not all those who wander are lost.' +print(re.findall(pattern, quote)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564efa70114b591b74d5679.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564efa70114b591b74d5679.md new file mode 100644 index 00000000000..93ba3536c1b --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564efa70114b591b74d5679.md @@ -0,0 +1,63 @@ +--- +id: 6564efa70114b591b74d5679 +title: Step 50 +challengeType: 20 +dashedName: step-50 +--- + +# --description-- + +The space characters and the final period are matched, as they are the only non-alphanumeric characters in the string. + +Now turn your `quote` string into a single underscore character. + +# --hints-- + +Your `quote` variable should be `_`. + +```js +({ test: () => assert.equal(__userGlobals.get("quote"), "_") }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), + (special_chars, r'\W') + ] + + return password + +# new_password = generate_password(8) +# print(new_password) +--fcc-editable-region-- +pattern = r'\W' +quote = 'Not all those who wander are lost.' +print(re.findall(pattern, quote)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564f0279e23ce924eedd1b2.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564f0279e23ce924eedd1b2.md new file mode 100644 index 00000000000..4140891792d --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564f0279e23ce924eedd1b2.md @@ -0,0 +1,69 @@ +--- +id: 6564f0279e23ce924eedd1b2 +title: Step 51 +challengeType: 20 +dashedName: step-51 +--- + +# --description-- + +Since the underscore character is a valid character for variable names, it is included in the `\w` character class (equivalent to `[a-zA-Z0-9_]`), which can be conveniently used to match variable names. + +Therefore, the `\W` character class is equivalent to `[^a-zA-Z0-9_]` with the underscore character that is not matched. For this reason you cannot use it to match all your special characters. + +Delete the last three lines in your code. + +# --hints-- + +You should delete the last three lines in your code. + +```js +({ test: () => { + assert.isFalse(/pattern\s*=\s*r("|')\\W\1/.test(code)); + assert.isFalse(/quote\s*=\s*("|')_\1/.test(code)); + assert.isFalse(/print\(re\.findall\(pattern, quote\)\)/.test(code)); +}}) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), + (special_chars, r'\W') + ] + + return password + +# new_password = generate_password(8) +# print(new_password) +--fcc-editable-region-- +pattern = r'\W' +quote = '_' +print(re.findall(pattern, quote)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564f32b18480893cf7799fd.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564f32b18480893cf7799fd.md new file mode 100644 index 00000000000..cbce569f3af --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564f32b18480893cf7799fd.md @@ -0,0 +1,58 @@ +--- +id: 6564f32b18480893cf7799fd +title: Step 52 +challengeType: 20 +dashedName: step-52 +--- + +# --description-- + +Now, combine your raw string with an f-string and interpolate your `symbols` variable inside the character class. Remember that you can interpolate a variable within an f-string using curly brackets `{ }`. + +# --hints-- + +The second item in your fourth constraint tuple should be the string `fr'[{symbols}]'`. + +```js +({ test: () => assert.match(code, /\(\s*special_chars\s*,\s*fr("|')\[\{\s*symbols\s*\}\]\1/) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), +--fcc-editable-region-- + (special_chars, r'\W') +--fcc-editable-region-- + ] + + return password + +# new_password = generate_password(8) +# print(new_password) +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564f583ca6fbf9556098dd6.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564f583ca6fbf9556098dd6.md new file mode 100644 index 00000000000..80f33eace1d --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564f583ca6fbf9556098dd6.md @@ -0,0 +1,57 @@ +--- +id: 6564f583ca6fbf9556098dd6 +title: Step 53 +challengeType: 20 +dashedName: step-53 +--- + +# --description-- + +Below the `constraints` list, add a comment saying `Check constraints`. + +# --hints-- + +You should add the provided comment. + +```js +({ test: () => assert.match(code, /#\s*Check\sconstraints/) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) +--fcc-editable-region-- + constraints = [ + (nums, r'\d'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), + (special_chars, fr'[{symbols}]') + ] + +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564f834dd717998092cfd47.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564f834dd717998092cfd47.md new file mode 100644 index 00000000000..9651ba05628 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564f834dd717998092cfd47.md @@ -0,0 +1,59 @@ +--- +id: 6564f834dd717998092cfd47 +title: Step 54 +challengeType: 20 +dashedName: step-54 +--- + +# --description-- + +After your new comment, write a `for` loop to iterate over the `constraints` list. Use `constraint` and `pattern` as the iterating variables. + +# --hints-- + +You should write a `for` loop to iterate over the `constraints` list with `constraint` and `pattern`. + +```js +assert.match(code, /for\s+constraint\s*,\s*pattern\s+in\s+constraints\s*:/) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), + (special_chars, fr'[{symbols}]') + ] +--fcc-editable-region-- + # Check constraints + +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564fd78ffff909b1531d3c3.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564fd78ffff909b1531d3c3.md new file mode 100644 index 00000000000..29e6ef008b3 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6564fd78ffff909b1531d3c3.md @@ -0,0 +1,59 @@ +--- +id: 6564fd78ffff909b1531d3c3 +title: Step 55 +challengeType: 20 +dashedName: step-55 +--- + +# --description-- + +Inside the `for` loop, call the `findall()` function passing `pattern` and `password` as the arguments. + +# --hints-- + +You should call `re.findall()` passing `pattern` and `password` as the arguments. + +```js +({ test: () => assert.match(code, /^(\s*)for.+:\s*^\1\s{4}re\.findall\s*\(\s*pattern\s*,\s*password\s*\)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), + (special_chars, fr'[{symbols}]') + ] +--fcc-editable-region-- + # Check constraints + for constraint, pattern in constraints: +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565012a2564509d40a90048.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565012a2564509d40a90048.md new file mode 100644 index 00000000000..f7c0e64b857 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565012a2564509d40a90048.md @@ -0,0 +1,62 @@ +--- +id: 6565012a2564509d40a90048 +title: Step 56 +challengeType: 20 +dashedName: step-56 +--- + +# --description-- + +You are interested in the number of elements in the list returned by the `findall()` function. + +Pass your existent `findall()` call to the `len()` function. + +# --hints-- + +You should call the `len()` function with `re.findall(pattern, password)` as the argument. + +```js +({ test: () => assert.match(code, /^(\s*)for.+:\s*^\1\s{4}len\s*\(\s*re\.findall\s*\(\s*pattern\s*,\s*password\s*\)\s*\)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), + (special_chars, fr'[{symbols}]') + ] +--fcc-editable-region-- + # Check constraints + for constraint, pattern in constraints: + re.findall(pattern, password) +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565bb128adfcd5ec362382d.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565bb128adfcd5ec362382d.md new file mode 100644 index 00000000000..35bffcc8291 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565bb128adfcd5ec362382d.md @@ -0,0 +1,60 @@ +--- +id: 6565bb128adfcd5ec362382d +title: Step 57 +challengeType: 20 +dashedName: step-57 +--- + +# --description-- + +Inside your `for` loop, compare `constraint` and the length of the list returned by `findall()`. Use the `<=` operator for that. + +# --hints-- + +You should compare `constraint` and the length of the list returned by `findall` using the `<=` operator inside your `for` loop. + +```js +({ test: () => assert.match(code, /^(\s*)for.+:\s*^\1\s{4}constraint\s*<=\s*len\s*\(\s*re\.findall\s*\(\s*pattern\s*,\s*password\s*\)\s*\)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), + (special_chars, fr'[{symbols}]') + ] +--fcc-editable-region-- + # Check constraints + for constraint, pattern in constraints: + len(re.findall(pattern, password)) +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565bd4265158360de8e2ae7.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565bd4265158360de8e2ae7.md new file mode 100644 index 00000000000..9799f90428b --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565bd4265158360de8e2ae7.md @@ -0,0 +1,67 @@ +--- +id: 6565bd4265158360de8e2ae7 +title: Step 59 +challengeType: 20 +dashedName: step-59 +--- + +# --description-- + +Turn the expression inside your `for` loop into an `if` statement. Use the expression you wrote in the previous step as the `if` condition. Inside the new conditional statement, increment the `count` value by `1`. + +# --hints-- + +You should turn `constraint <= len(re.findall(pattern, password))` into the `if` condition. + +```js +({ test: () => assert.match(code, /^(\s*)for.+:\s*^\1(\s{4})if\s+constraint\s* <=\s*len\s*\(\s*re\.findall\s*\(\s*pattern\s*,\s*password\s*\)\s*\)\s*:/m) }) +``` + +You should increment `count` by one inside your new `if` statement. + +```js +({ test: () => assert.match(code, /^(\s*)for.+:\s*^\1(\s{4})if\s+constraint\s* <=\s*len\s*\(\s*re\.findall\s*\(\s*pattern\s*,\s*password\s*\)\s*\)\s*:\s*^\1\2\2(count\s*\+=\s*1|count\s*=\s*count\s*\+\s*1)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), + (special_chars, fr'[{symbols}]') + ] +--fcc-editable-region-- + # Check constraints + count = 0 + for constraint, pattern in constraints: + constraint <= len(re.findall(pattern, password)) +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c014db6e9b63c257771d.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c014db6e9b63c257771d.md new file mode 100644 index 00000000000..f8763d36d4c --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c014db6e9b63c257771d.md @@ -0,0 +1,61 @@ +--- +id: 6565c014db6e9b63c257771d +title: Step 58 +challengeType: 20 +dashedName: step-58 +--- + +# --description-- + +Right before your `for` loop, declare a `count` variable and assign the value zero to this variable. + +# --hints-- + +You should declare a `count` variable and assign the value `0` to this variable. + +```js +({ test: () => assert.match(code, /count\s*=\s*0/) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), + (special_chars, fr'[{symbols}]') + ] +--fcc-editable-region-- + # Check constraints + + for constraint, pattern in constraints: + constraint <= len(re.findall(pattern, password)) +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c084627071646f94c4b0.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c084627071646f94c4b0.md new file mode 100644 index 00000000000..cc05d24a567 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c084627071646f94c4b0.md @@ -0,0 +1,68 @@ +--- +id: 6565c084627071646f94c4b0 +title: Step 60 +challengeType: 20 +dashedName: step-60 +--- + +# --description-- + +Finally, after the `for` loop, create an `if` statement to check if `count` is equal to `4` and break out of the `while` loop by using the `break` statement. + +# --hints-- + +You should create an `if` statement that checks if `count` is equal to `4` after the `for` loop. + +```js +({ test: () => assert.match(code, /^(\s*)for.+:\s*^\1(\s{4})if\s+constraint\s* <=\s*len\s*\(\s*re\.findall\s*\(\s*pattern\s*,\s*password\s*\)\s*\)\s*:\s*^\1\2\2count\s*\+=\s*1\s*^\1if\s+count\s*==\s*4\s*:/m) }) +``` + +You should use `break` inside your new `if` to break out of the `while` loop. + +```js +({ test: () => assert.match(code, /^(\s*)for.+:\s*^\1(\s{4})if\s+constraint\s* <=\s*len\s*\(\s*re\.findall\s*\(\s*pattern\s*,\s*password\s*\)\s*\)\s*:\s*^\1\2\2count\s*\+=\s*1\s*^\1if\s+count\s*==\s*4\s*:\s*^\1\2break/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), + (special_chars, fr'[{symbols}]') + ] +--fcc-editable-region-- + # Check constraints + count = 0 + for constraint, pattern in constraints: + if constraint <= len(re.findall(pattern, password)): + count += 1 +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c13fdb798865c161d8f8.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c13fdb798865c161d8f8.md new file mode 100644 index 00000000000..1ff7833aaf6 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c13fdb798865c161d8f8.md @@ -0,0 +1,71 @@ +--- +id: 6565c13fdb798865c161d8f8 +title: Step 65 +challengeType: 20 +dashedName: step-65 +--- + +# --description-- + +Now it's time to test your function. Uncomment the last two lines in your code and modify the function call passing 5 arguments. Use `8` for the length and `1` for the other four constraints. + +# --hints-- + +You should call `generate_password` with the provided arguments. + +```js +({ test: () => assert.match(code, /^new_password\s*=\s*generate_password\s*\(\s*8\s*,\s*1\s*,\s*1\s*,\s*1\s*,\s*1\s*\)/m) }) +``` + +You should print your `new_password` variable. + +```js +({ test: () => assert.match(code, /^print\s*\(\s*new_password\s*\)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), + (special_chars, fr'[{symbols}]') + ] + + # Check constraints + if all( + constraint <= len(re.findall(pattern, password)) + for constraint, pattern in constraints + ): + break + + return password + +--fcc-editable-region-- +# new_password = generate_password(8) +# print(new_password) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c234de8cdf673c96bdf3.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c234de8cdf673c96bdf3.md new file mode 100644 index 00000000000..37a0652b40b --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c234de8cdf673c96bdf3.md @@ -0,0 +1,67 @@ +--- +id: 6565c234de8cdf673c96bdf3 +title: Step 67 +challengeType: 20 +dashedName: step-67 +--- + +# --description-- + +As long as all the arguments in a function call are keyword arguments, the order of the arguments doesn't matter. + +To confirm this, try to change the order of `length=8` and `nums=1` in your function call. + +# --hints-- + +You should change the order of `length=8` and `nums=1` in your `generate_password()` call. + +```js +({ test: () => assert.match(code, /^new_password\s*=\s*generate_password\s*\(\s*nums\s*=\s*1\s*,\s*length\s*=\s*8\s*,\s*special_chars\s*=\s*1\s*,\s*uppercase\s*=\s*1\s*,\s*lowercase\s*=\s*1\s*\)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (special_chars, fr'[{symbols}]'), + (uppercase, r'[A-Z]'), + (lowercase, r'[a-z]') + ] + + # Check constraints + if all( + constraint <= len(re.findall(pattern, password)) + for constraint, pattern in constraints + ): + break + + return password + +--fcc-editable-region-- +new_password = generate_password(length=8, nums=1, special_chars=1, uppercase=1, lowercase=1) +print(new_password) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c32f89ab8d68b42aff30.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c32f89ab8d68b42aff30.md new file mode 100644 index 00000000000..b5336c8fb85 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c32f89ab8d68b42aff30.md @@ -0,0 +1,66 @@ +--- +id: 6565c32f89ab8d68b42aff30 +title: Step 70 +challengeType: 20 +dashedName: step-70 +--- + +# --description-- + +Now, remove all the arguments from your function call. + +# --hints-- + +You should call `generate_password` without arguments. + +```js +({ test: () => assert.match(code, /^new_password\s*=\s*generate_password\s*\(\s*\)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length=16, nums=1, special_chars=1, uppercase=1, lowercase=1): + + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (special_chars, fr'[{symbols}]'), + (uppercase, r'[A-Z]'), + (lowercase, r'[a-z]') + ] + + # Check constraints + if all( + constraint <= len(re.findall(pattern, password)) + for constraint, pattern in constraints + ): + break + + return password + +--fcc-editable-region-- +new_password = generate_password(length=8) +print(new_password) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c3a146bd5469b62bc59e.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c3a146bd5469b62bc59e.md new file mode 100644 index 00000000000..d5ffe314062 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c3a146bd5469b62bc59e.md @@ -0,0 +1,66 @@ +--- +id: 6565c3a146bd5469b62bc59e +title: Step 71 +challengeType: 20 +dashedName: step-71 +--- + +# --description-- + +Modify your `print()` call to take the string `Generated password:` as the first argument, before `new_password`. + +# --hints-- + +You should pass the `Generated password:` string and `new_password` to your `print()` call. + +```js +({ test: () => assert.match(code, /^print\s*\(\s*("|')Generated\spassword:\1\s*,\s*new_password\s*\)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length=16, nums=1, special_chars=1, uppercase=1, lowercase=1): + + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (special_chars, fr'[{symbols}]'), + (uppercase, r'[A-Z]'), + (lowercase, r'[a-z]') + ] + + # Check constraints + if all( + constraint <= len(re.findall(pattern, password)) + for constraint, pattern in constraints + ): + break + + return password + +--fcc-editable-region-- +new_password = generate_password() +print(new_password) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c4767f49286aec825c6d.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c4767f49286aec825c6d.md new file mode 100644 index 00000000000..a3a56df3890 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6565c4767f49286aec825c6d.md @@ -0,0 +1,116 @@ +--- +id: 6565c4767f49286aec825c6d +title: Step 72 +challengeType: 20 +dashedName: step-72 +--- + +# --description-- + +Finally, put the last two lines of your code inside an `if` statement that execute when `__name__ == '__main__'`. In this way, your code won't run when imported as a module. Otherwise, it will call `generate_password()` and print the generated password. + +With that, the password generator project is complete. + +# --hints-- + +You should have an `if` statement that checks if `__name__ == '__main__'` and put the last two lines of your code in it. + +```js +({ test: () => assert.match(code, /^if\s+__name__\s*==\s*("|')__main__\1\s*:\s*^(\s{4})new_password\s*=\s*generate_password\s*\(\s*\)\s*^\2print\s*\(\s*("|')Generated\spassword:\3\s*,\s*new_password\s*\)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length=16, nums=1, special_chars=1, uppercase=1, lowercase=1): + + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (special_chars, fr'[{symbols}]'), + (uppercase, r'[A-Z]'), + (lowercase, r'[a-z]') + ] + + # Check constraints + if all( + constraint <= len(re.findall(pattern, password)) + for constraint, pattern in constraints + ): + break + + return password + +--fcc-editable-region-- +new_password = generate_password() +print('Generated password:', new_password) +--fcc-editable-region-- +``` + +# --solutions-- + +```py +import re +import secrets +import string + + +def generate_password(length=16, nums=1, special_chars=1, uppercase=1, lowercase=1): + + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (special_chars, fr'[{symbols}]'), + (uppercase, r'[A-Z]'), + (lowercase, r'[a-z]') + ] + + # Check constraints + if all( + constraint <= len(re.findall(pattern, password)) + for constraint, pattern in constraints + ): + break + + return password + + +if __name__ == '__main__': + new_password = generate_password() + print('Generated password:', new_password) + +``` + diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656eec2f40d18056cc58b229.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656eec2f40d18056cc58b229.md new file mode 100644 index 00000000000..19ef5b075ed --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656eec2f40d18056cc58b229.md @@ -0,0 +1,65 @@ +--- +id: 656eec2f40d18056cc58b229 +title: Step 30 +challengeType: 20 +dashedName: step-30 +--- + +# --description-- + +The value `None` is returned since `i` is not found inside the parsed string. + +Now, modify your pattern into `l` and see the result. + +# --hints-- + +You should modify your `pattern` variable into `re.compile('l')`. + +```js +({ test: () => assert(__pyodide.runPython(` + import re + p = __locals.get("pattern") + p == re.compile('l') + `)) +}) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, '') + ] + + return password + +# new_password = generate_password(8) +# print(new_password) +--fcc-editable-region-- +pattern = re.compile('i') +quote = 'Not all those who wander are lost.' +print(pattern.search(quote)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656ef54070c72161e6feb90f.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656ef54070c72161e6feb90f.md new file mode 100644 index 00000000000..df879472d40 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656ef54070c72161e6feb90f.md @@ -0,0 +1,55 @@ +--- +id: 656ef54070c72161e6feb90f +title: Step 22 +challengeType: 20 +dashedName: step-22 +--- + +# --description-- + +It seems all fine, but it would be nice to have a way to check that the generated password complies to specific features. For example, a minimum number of special characters, digits, or uppercase/lowercase letters. You are going to take care of that very soon. + +For now, comment out the last two lines of your code. + +# --hints-- + +You should turn the last two lines of your code into comments. + +```js +({ test: () => { + assert.match(code, /#\s*new_password\s*=\s*generate_password\s*\(\s*8\s*\)/); + assert.match(code, /#\s*print\s*\(\s*new_password\s*\)/); +} }) +``` + + +# --seed-- + +## --seed-contents-- + +```py +import secrets +import string + + +def generate_password(length): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + return password + +--fcc-editable-region-- +new_password = generate_password(8) +print(new_password) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656ef5bc5c0cd464be1df675.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656ef5bc5c0cd464be1df675.md new file mode 100644 index 00000000000..5467293cf15 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656ef5bc5c0cd464be1df675.md @@ -0,0 +1,56 @@ +--- +id: 656ef5bc5c0cd464be1df675 +title: Step 23 +challengeType: 20 +dashedName: step-23 +--- + +# --description-- + +Next, you are going to give your function more parameters that will act as constraints for the generated password. + +Modify your function declaration by adding `nums`, `special_chars`, `uppercase`, and `lowercase` in this order after the existent `length` parameter. + +# --hints-- + +Your function should take `length`, `nums`, `special_chars`, `uppercase`, and `lowercase` as the parameters. The order matters. + +```js +({ test: () => assert(__pyodide.runPython(` + import inspect + foo = __locals.get("generate_password") + sig = str(inspect.signature(foo)) + sig == '(length, nums, special_chars, uppercase, lowercase)' + `)) +}) +``` + +# --seed-- + +## --seed-contents-- + +```py +import secrets +import string + +--fcc-editable-region-- +def generate_password(length): +--fcc-editable-region-- + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + return password + +# new_password = generate_password(8) +# print(new_password) +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656ef783bba6976de014eaa8.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656ef783bba6976de014eaa8.md new file mode 100644 index 00000000000..25a43f9abc3 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656ef783bba6976de014eaa8.md @@ -0,0 +1,47 @@ +--- +id: 656ef783bba6976de014eaa8 +title: Step 24 +challengeType: 20 +dashedName: step-24 +--- + +# --description-- + +Put your `password` variable declaration and the following `for` loop inside a `while` loop. Use `True` as the condition for your new loop. + +# --hints-- + +You should create a `while True` loop enclosing your existing `password` declaration and `for` loop. + +```js +({ test: () => assert.match(code, /^(\s*)while\s+True\s*:\s*^\1\1password\s*=\s*("|')\2\s*#\s*Generate\spassword\s*^\1\1for\s+_\s+in\s+range\s*\(\s*length\s*\s*\)\s*:\s*^\1\1\1password\s*\+=\s*secrets\.choice\s*\(\s*all_characters\s*\)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols +--fcc-editable-region-- + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656ef7f792734072dedd8319.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656ef7f792734072dedd8319.md new file mode 100644 index 00000000000..c86eb3203a1 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656ef7f792734072dedd8319.md @@ -0,0 +1,56 @@ +--- +id: 656ef7f792734072dedd8319 +title: Step 25 +challengeType: 20 +dashedName: step-25 +--- + +# --description-- + +After your `for` loop, create a `constraints` variable and assign an empty list to this variable. + +# --hints-- + +You should declare a `constraints` variable after your `for` loop and assign an empty list to this variable. + +```js +({ test: () => + { + const transformedCode = code.replace(/\r/g, ""); + const generate_pw = __helpers.python.getDef("\n"+transformedCode, "generate_password"); + const {function_body} = generate_pw; + assert(function_body.match(/^(\s*)for.*:.*^\1constraints\s*=\s*\[\s*\]/ms)); + } +}) +``` + +# --seed-- + +## --seed-contents-- + +```py +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols +--fcc-editable-region-- + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656ef89b4b486b7a16077864.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656ef89b4b486b7a16077864.md new file mode 100644 index 00000000000..28b451cbff4 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656ef89b4b486b7a16077864.md @@ -0,0 +1,65 @@ +--- +id: 656ef89b4b486b7a16077864 +title: Step 26 +challengeType: 20 +dashedName: step-26 +--- + +# --description-- + +A tuple is another built-in data structure in Python. Tuples are very much like lists, but they are defined with parentheses `()`, instead of square brackets. Also, tuples are immutable, unlike lists. + +```py +my_tuple = ('larch', 1, True) +``` + +Your `constraints` list is going to store tuples. The first item of each tuple will be a constraint parameter. + +Add a tuple to your list. Use `nums` as the first item and an empty string as the second item. + +# --hints-- + +You should add a tuple to the `constraints` list. + +```js +({ test: () => assert.match(code, /constraints\s*=\s*\[\s*\(.*\)\s*\]/) }) +``` + +You should add `(nums, '')` to the `constraints` list. + +```js +({ test: () => assert.match(code, /constraints\s*=\s*\[\s*\(\s*nums\s*,\s*("|')\1\s*\)\s*\]/) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) +--fcc-editable-region-- + constraints = [] + +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656f04b20397d9a574cc7eb2.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656f04b20397d9a574cc7eb2.md new file mode 100644 index 00000000000..da5f46bf97d --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656f04b20397d9a574cc7eb2.md @@ -0,0 +1,64 @@ +--- +id: 656f04b20397d9a574cc7eb2 +title: Step 32 +challengeType: 20 +dashedName: step-32 +--- + +# --description-- + +You can obtain the same result without using the `compile()` function. Modify your `pattern` variable into the literal string `l+`. Then, change the `print()` call to print `re.search(pattern, quote)`. + +# --hints-- + +You should modify your `pattern` variable into the literal string `l+`. + +```js +({ test: () => assert.equal(__userGlobals.get("pattern"), "l+") }) +``` + +You should print `re.search(pattern, quote)`. + +```js +({ test: () => assert.match(code, /^print\s*\(\s*re\.search\s*\(\s*pattern\s*,\s*quote\s*\)\s*\)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, '') + ] + + return password + +# new_password = generate_password(8) +# print(new_password) +--fcc-editable-region-- +pattern = re.compile('l+') +quote = 'Not all those who wander are lost.' +print(pattern.search(quote)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656f0bc259c1f6b57486ed68.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656f0bc259c1f6b57486ed68.md new file mode 100644 index 00000000000..cd324988a3d --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656f0bc259c1f6b57486ed68.md @@ -0,0 +1,60 @@ +--- +id: 656f0bc259c1f6b57486ed68 +title: Step 33 +challengeType: 20 +dashedName: step-33 +--- + +# --description-- + +To check that the generated password meets the required features, you are going to use the `findall()` function from the `re` module. It's similar to `search` but it returns a list with all the occurrences of the matched pattern. + +Replace the `search()` call with `findall()` and check the output. + +# --hints-- + +You should modify your existing `print()` call replacing `search()` with `findall()`. + +```js +({ test: () => assert.match(code, /^print\s*\(\s*re\.findall\s*\(\s*pattern\s*,\s*quote\s*\)\s*\)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, '') + ] + + return password + +# new_password = generate_password(8) +# print(new_password) +--fcc-editable-region-- +pattern = 'l+' +quote = 'Not all those who wander are lost.' +print(re.search(pattern, quote)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656f0d6bc60b58b9777a36c9.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656f0d6bc60b58b9777a36c9.md new file mode 100644 index 00000000000..6da7ea8c974 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656f0d6bc60b58b9777a36c9.md @@ -0,0 +1,64 @@ +--- +id: 656f0d6bc60b58b9777a36c9 +title: Step 34 +challengeType: 20 +dashedName: step-34 +--- + +# --description-- + +A character class is indicated by square brackets and matches one character among those specified between the brackets. For example, `ma[dnt]` matches either `mad`, `man`, or `mat`. + +Modify your pattern to match a `w` followed by either `h` or `a`. + +# --hints-- + +Your pattern should use a character class to match a `w` followed by either `h` or `a`. + +```js +({ test: () => assert(__pyodide.runPython(` + regex = __locals.get("pattern") + regex == "w[ha]" or regex == "w[ah]" + `)) +}) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, '') + ] + + return password + +# new_password = generate_password(8) +# print(new_password) +--fcc-editable-region-- +pattern = 'l+' +quote = 'Not all those who wander are lost.' +print(re.findall(pattern, quote)) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656f10458134d4c4e283a2f1.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656f10458134d4c4e283a2f1.md new file mode 100644 index 00000000000..0e18f1b1c72 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/656f10458134d4c4e283a2f1.md @@ -0,0 +1,58 @@ +--- +id: 656f10458134d4c4e283a2f1 +title: Step 35 +challengeType: 20 +dashedName: step-35 +--- + +# --description-- + +Now, turn the empty string in the constraint tuple into a regex pattern to match a single digit. Use a character class specifying each digit from `0` to `9`. + +# --hints-- + +You should have the `(nums, '[0123456789]')` tuple in your `constraints` list. + +```js +({ test: () => assert.match(code, /constraints\s*=\s*\[\s*\(\s*nums\s*,\s*("|')\[\d{10}\]\1\s*\)\s*\]/) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) +--fcc-editable-region-- + constraints = [ + (nums, '') + ] +--fcc-editable-region-- + return password + +# new_password = generate_password(8) +# print(new_password) + +pattern = 'w[ha]' +quote = 'Not all those who wander are lost.' +# print(re.findall(pattern, quote)) + +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6577319039f4f7de9251b822.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6577319039f4f7de9251b822.md new file mode 100644 index 00000000000..4b64573d26b --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6577319039f4f7de9251b822.md @@ -0,0 +1,80 @@ +--- +id: 6577319039f4f7de9251b822 +title: Step 61 +challengeType: 20 +dashedName: step-61 +--- + +# --description-- + +Instead of using a loop and a counter variable, you can achieve the same result with a different approach. + +Replace your existing `for` loop and two `if` statements with a single `if` statement. For the `if` condition, use a list created with the list comprehension syntax. + +The list stores the results of evaluating the expression `constraint <= len(re.findall(pattern, password))` for each `constraint`-`pattern` tuple in the `constraints` list. + +# --hints-- + +You should replace your existing `for` loop and two `if` statements with a single `if` statement. + +```js +({ test: () => { + assert.match(code, /^(\s{8})if\s+.+:\s*^\1\s{4}break/ms); + assert.isFalse(/if\s+count\s*==\s*4\s*:/.test(code)); +} }) +``` + +Your new `if` condition should be a list comprehension that is the result of evaluating the expression `constraint <= len(re.findall(pattern, password))` for each `constraint`-`pattern` tuple in the `constraints` list. + +```js +({ test: () => assert.match(code, /^(\s{8})if\s+\[\s*constraint\s*<=\s*len\s*\(\s*re\.findall\s*\(\s*pattern\s*,\s*password\s*\)\s*\)\s+for\s+constraint\s*,\s*pattern\s+in\s+constraints\s*\]\s*:\s*^\1\s{4}break/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), + (special_chars, fr'[{symbols}]') + ] + + # Check constraints + count = 0 +--fcc-editable-region-- + for constraint, pattern in constraints: + if constraint <= len(re.findall(pattern, password)): + count += 1 + + if count == 4: +--fcc-editable-region-- + break + + return password + +# new_password = generate_password(8) +# print(new_password) +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/657732654845d8e2fb1217e6.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/657732654845d8e2fb1217e6.md new file mode 100644 index 00000000000..d94550adf54 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/657732654845d8e2fb1217e6.md @@ -0,0 +1,68 @@ +--- +id: 657732654845d8e2fb1217e6 +title: Step 62 +challengeType: 20 +dashedName: step-62 +--- + +# --description-- + +`all()` is a built-in Python function that returns `True` if all the elements inside a given iterable evaluate to `True`. Otherwise, it returns `False`. + +You can combine the `all()` function with the list comphehension syntax to make your code more concise. + +Modify your `if` condition by passing the list comprehension you created in the previous step to the `all()` function. + +# --hints-- + +You should pass your list comprehension to the `all()` function. + +```js +({ test: () => assert.match(code, /^(\s*)if\s+all\s*\(\s*\[\s*constraint\s*<=\s*len\s*\(\s*re\.findall\s*\(\s*pattern\s*,\s*password\s*\)\s*\)\s*for\s+constraint\s*,\s*pattern\s+in\s+constraints\s*\]\s*\)\s*:\s*^\1\s{4}break/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), + (special_chars, fr'[{symbols}]') + ] + + # Check constraints + count = 0 +--fcc-editable-region-- + if [constraint <= len(re.findall(pattern, password)) + for constraint, pattern in constraints]: +--fcc-editable-region-- + break + + return password + +# new_password = generate_password(8) +# print(new_password) +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6577333feab1e8e927014f03.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6577333feab1e8e927014f03.md new file mode 100644 index 00000000000..4af481db69e --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/6577333feab1e8e927014f03.md @@ -0,0 +1,72 @@ +--- +id: 6577333feab1e8e927014f03 +title: Step 63 +challengeType: 20 +dashedName: step-63 +--- + +# --description-- + +Having `all([expression for i in iterable])`, means that a new list is created by evaluating `expression` for each `i` in `iterable`. After the `all()` function iterates over the newly created list, the list is deleted automatically, since it is no longer needed. + +Memory can be saved by using a generator expression. Generator expressions follow the syntax of list comprehensions but they use parentheses instead of square brackets. + +Change your list comprehension into a generator expression by removing the square brackets. + +# --hints-- + +You should turn your list comprehension into a generator expression by removing the square brackets. + +```js +({ test: () => assert.match(code, /^(\s*)if\s+all\s*\(\s*constraint\s*<=\s*len\s*\(\s*re\.findall\s*\(\s*pattern\s*,\s*password\s*\)\s*\)\s*for\s+constraint\s*,\s*pattern\s+in\s+constraints\s*\)\s*:\s*^\1\s{4}break/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), + (special_chars, fr'[{symbols}]') + ] + + # Check constraints + count = 0 +--fcc-editable-region-- + if all( + [ + constraint <= len(re.findall(pattern, password)) + for constraint, pattern in constraints + ] + ): +--fcc-editable-region-- + break + + return password + +# new_password = generate_password(8) +# print(new_password) +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/657733bc97eb83efdb7e3988.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/657733bc97eb83efdb7e3988.md new file mode 100644 index 00000000000..1a6ad451a06 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/657733bc97eb83efdb7e3988.md @@ -0,0 +1,65 @@ +--- +id: 657733bc97eb83efdb7e3988 +title: Step 64 +challengeType: 20 +dashedName: step-64 +--- + +# --description-- + +You don't need the `count` variable anymore. Delete this variable and its value. + +# --hints-- + +You should delete the `count = 0` line. + +```js +({ test: () => assert.isFalse( /count\s*=\s*0/.test(code)) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (lowercase, r'[a-z]'), + (uppercase, r'[A-Z]'), + (special_chars, fr'[{symbols}]') + ] +--fcc-editable-region-- + # Check constraints + count = 0 + if all( + constraint <= len(re.findall(pattern, password)) + for constraint, pattern in constraints + ): +--fcc-editable-region-- + break + + return password + +# new_password = generate_password(8) +# print(new_password) +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/657dadf4d8b93c1704f3a57c.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/657dadf4d8b93c1704f3a57c.md new file mode 100644 index 00000000000..1bfd5e5a824 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/657dadf4d8b93c1704f3a57c.md @@ -0,0 +1,77 @@ +--- +id: 657dadf4d8b93c1704f3a57c +title: Step 66 +challengeType: 20 +dashedName: step-66 +--- + +# --description-- + +It works, but there are still a couple of things you can improve. First of all, calling a function with 5 arguments can create confusion on which value will be assigned to which parameter. + +You can call a function using keyword arguments, that is writing the parameter name explicitly followed by the assignment operator and the value. For example: + +```py +def add(x, y): + return x + y + +spam(x=1, y=7) # 8 +``` + +Modify your function call to use keyword arguments. + +# --hints-- + +Your `new_password` variable should have the value of `generate_password(length=8, nums=1, special_chars=1, uppercase=1, lowercase=1)`. + +```js +({ test: () => assert.match(code, /^new_password\s*=\s*generate_password\s*\(\s*length\s*=\s*8\s*,\s*nums\s*=\s*1\s*,\s*special_chars\s*=\s*1\s*,\s*uppercase\s*=\s*1\s*,\s*lowercase\s*=\s*1\s*\)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length, nums, special_chars, uppercase, lowercase): + + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (special_chars, fr'[{symbols}]'), + (uppercase, r'[A-Z]'), + (lowercase, r'[a-z]') + ] + + # Check constraints + if all( + constraint <= len(re.findall(pattern, password)) + for constraint, pattern in constraints + ): + break + + return password + +--fcc-editable-region-- +new_password = generate_password(8, 1, 1, 1, 1) +print(new_password) +--fcc-editable-region-- +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/657db2114b4029241956f5d6.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/657db2114b4029241956f5d6.md new file mode 100644 index 00000000000..5f195d679d7 --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/657db2114b4029241956f5d6.md @@ -0,0 +1,72 @@ +--- +id: 657db2114b4029241956f5d6 +title: Step 68 +challengeType: 20 +dashedName: step-68 +--- + +# --description-- + +Modify your function declaration to take default arguments. Use `16` for the `length` and `1` for the other constraints. + +# --hints-- + +Your function should take default parameters. + +```js +({ test: () => assert(__pyodide.runPython(` + import inspect + foo = __locals.get("generate_password") + sig = str(inspect.signature(foo)) + sig == '(length=16, nums=1, special_chars=1, uppercase=1, lowercase=1)' + `)) +}) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + +--fcc-editable-region-- +def generate_password(length, nums, special_chars, uppercase, lowercase): +--fcc-editable-region-- + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (special_chars, fr'[{symbols}]'), + (uppercase, r'[A-Z]'), + (lowercase, r'[a-z]') + ] + + # Check constraints + if all( + constraint <= len(re.findall(pattern, password)) + for constraint, pattern in constraints + ): + break + + return password + + +new_password = generate_password(nums=1, length=8, special_chars=1, uppercase=1, lowercase=1) +print(new_password) + +``` diff --git a/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/657db4cb77190e33a20e852a.md b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/657db4cb77190e33a20e852a.md new file mode 100644 index 00000000000..c0ee80f692f --- /dev/null +++ b/curriculum/challenges/english/07-scientific-computing-with-python/learn-regular-expressions-by-building-a-password-generator/657db4cb77190e33a20e852a.md @@ -0,0 +1,67 @@ +--- +id: 657db4cb77190e33a20e852a +title: Step 69 +challengeType: 20 +dashedName: step-69 +--- + +# --description-- + +When you combine default arguments with keyword arguments, you are able to explicitly pass fewer arguments than those required by the function. The arguments that are not explicitly passed to the function call will take their default values. + +Modify your `generate_password()` call to take only `length=8`. + +# --hints-- + +You should pass only `length=8` to your `generate_password()` call. + +```js +({ test: () => assert.match(code, /^new_password\s*=\s*generate_password\s*\(\s*length\s*=\s*8\s*\)/m) }) +``` + +# --seed-- + +## --seed-contents-- + +```py +import re +import secrets +import string + + +def generate_password(length=16, nums=1, special_chars=1, uppercase=1, lowercase=1): + # Define the possible characters for the password + letters = string.ascii_letters + digits = string.digits + symbols = string.punctuation + + # Combine all characters + all_characters = letters + digits + symbols + + while True: + password = '' + # Generate password + for _ in range(length): + password += secrets.choice(all_characters) + + constraints = [ + (nums, r'\d'), + (special_chars, fr'[{symbols}]'), + (uppercase, r'[A-Z]'), + (lowercase, r'[a-z]') + ] + + # Check constraints + if all( + constraint <= len(re.findall(pattern, password)) + for constraint, pattern in constraints + ): + break + + return password + +--fcc-editable-region-- +new_password = generate_password(nums=1, length=8, special_chars=1, uppercase=1, lowercase=1) +print(new_password) +--fcc-editable-region-- +```