mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-28 18:26:54 +00:00
feat(curriculum): add Caesar cipher workshop (#60198)
Co-authored-by: Ilenia <26656284+ilenia-magoni@users.noreply.github.com> Co-authored-by: Zaira <33151350+zairahira@users.noreply.github.com> Co-authored-by: Kolade Chris <65571316+Ksound22@users.noreply.github.com>
This commit is contained in:
@@ -3742,7 +3742,9 @@
|
||||
},
|
||||
"workshop-caesar-cipher": {
|
||||
"title": "Build a Caesar Cipher",
|
||||
"intro": ["Learn about Build a Caesar Cipher in these lectures."]
|
||||
"intro": [
|
||||
"In this workshop, you'll build a Caesar cipher using basic Python concepts such as strings, conditionals, functions, and more."
|
||||
]
|
||||
},
|
||||
"lab-rpg-character": {
|
||||
"title": "Build an RPG character",
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
title: Introduction to the Build a Caesar Cipher
|
||||
block: workshop-caesar-cipher
|
||||
superBlock: full-stack-developer
|
||||
---
|
||||
|
||||
## Introduction to the Build a Caesar Cipher
|
||||
|
||||
In this workshop, you'll build a Caesar cipher using basic Python concepts such as strings, conditionals, functions, and more.
|
||||
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"name": "Build a Caesar Cipher",
|
||||
"isUpcomingChange": true,
|
||||
"usesMultifileEditor": true,
|
||||
"hasEditableBoundaries": true,
|
||||
"dashedName": "workshop-caesar-cipher",
|
||||
"superBlock": "full-stack-developer",
|
||||
"challengeOrder": [
|
||||
{
|
||||
"id": "680a3d4c065557260de2ff33",
|
||||
"title": "Step 1"
|
||||
},
|
||||
{
|
||||
"id": "680a41ef5bfdc059cfd9d4b5",
|
||||
"title": "Step 2"
|
||||
},
|
||||
{
|
||||
"id": "680a431692a5f863f726c438",
|
||||
"title": "Step 3"
|
||||
},
|
||||
{
|
||||
"id": "680a549f60f5a3fedfc0edd9",
|
||||
"title": "Step 4"
|
||||
},
|
||||
{
|
||||
"id": "680a5e7f3d47715196b12ca0",
|
||||
"title": "Step 5"
|
||||
},
|
||||
{
|
||||
"id": "680a7e200400089967b8b1f4",
|
||||
"title": "Step 6"
|
||||
},
|
||||
{
|
||||
"id": "680a82806c4c6bc3567f2708",
|
||||
"title": "Step 7"
|
||||
},
|
||||
{
|
||||
"id": "680a836235461fce1ff53b3f",
|
||||
"title": "Step 8"
|
||||
},
|
||||
{
|
||||
"id": "6810869355fa2468f9ebaf9c",
|
||||
"title": "Step 9"
|
||||
},
|
||||
{
|
||||
"id": "6810891bd6de8a87a833df42",
|
||||
"title": "Step 10"
|
||||
},
|
||||
{
|
||||
"id": "6818b80519e6c6c47a8bb6e8",
|
||||
"title": "Step 11"
|
||||
},
|
||||
{
|
||||
"id": "6818e9c7c8dc5694e8f64fc3",
|
||||
"title": "Step 12"
|
||||
},
|
||||
{
|
||||
"id": "6818eb3f98c0bca5af7c8d03",
|
||||
"title": "Step 13"
|
||||
},
|
||||
{
|
||||
"id": "6818ed1adc249bb91d373729",
|
||||
"title": "Step 14"
|
||||
},
|
||||
{
|
||||
"id": "6818fcb250f34e62cab32c39",
|
||||
"title": "Step 15"
|
||||
},
|
||||
{
|
||||
"id": "6819bc0637b80256a33adccc",
|
||||
"title": "Step 16"
|
||||
},
|
||||
{
|
||||
"id": "6819be9055828d65c813eec5",
|
||||
"title": "Step 17"
|
||||
},
|
||||
{
|
||||
"id": "6819c5c9faf2548e556163d5",
|
||||
"title": "Step 18"
|
||||
},
|
||||
{
|
||||
"id": "6819c7beb4a8289c2b4f24d5",
|
||||
"title": "Step 19"
|
||||
},
|
||||
{
|
||||
"id": "6819ca464db219ab86f37dc4",
|
||||
"title": "Step 20"
|
||||
},
|
||||
{
|
||||
"id": "6819cf38880d8cc9b9f6af7a",
|
||||
"title": "Step 21"
|
||||
},
|
||||
{
|
||||
"id": "681a1d60e037127e7c8e0230",
|
||||
"title": "Step 22"
|
||||
},
|
||||
{
|
||||
"id": "681a2a6cf95e82ca30866364",
|
||||
"title": "Step 23"
|
||||
},
|
||||
{
|
||||
"id": "681a2e35c406ade2f0a5f9b2",
|
||||
"title": "Step 24"
|
||||
},
|
||||
{
|
||||
"id": "681a44f4c3235f7d8f428545",
|
||||
"title": "Step 25"
|
||||
}
|
||||
],
|
||||
"blockLayout": "challenge-grid",
|
||||
"blockType": "workshop",
|
||||
"helpCategory": "Python"
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
---
|
||||
id: 680a3d4c065557260de2ff33
|
||||
title: Step 1
|
||||
challengeType: 20
|
||||
dashedName: step-1
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
As you may recall from the lectures, in Python, you declare a variable by writing the variable name on the left side of the assignment operator (`=`) and the value to assign on the right side:
|
||||
|
||||
```py
|
||||
variable_name = value
|
||||
```
|
||||
|
||||
Create a variable called `shift` and assign the value `5` to your new variable.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should declare a variable called `shift`. Pay attention to place the variable name at the beginning of the line.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).has_variable("shift")`)) })
|
||||
```
|
||||
|
||||
You should assign the value `5` to your `shift` variable.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_variable("shift").is_equivalent("shift = 5")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
---
|
||||
id: 680a41ef5bfdc059cfd9d4b5
|
||||
title: Step 2
|
||||
challengeType: 20
|
||||
dashedName: step-2
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In previous lectures, you learned about different data types you can store in a variable. You just assigned an integer value. Now you need to assign a string, which is a sequences of characters enclosed by either single or double quotes:
|
||||
|
||||
```py
|
||||
string_1 = 'I am a string'
|
||||
string_2 = "I am also a string"
|
||||
```
|
||||
|
||||
Declare another variable called `alphabet` and assign the string `abcdefghijklmnopqrstuvwxyz` to this variable.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should declare a variable called `alphabet`. Pay attention to place the variable name at the beginning of the line.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).has_variable("alphabet")`)) })
|
||||
```
|
||||
|
||||
You should assign the string `abcdefghijklmnopqrstuvwxyz` to your `alphabet` variable. Remember to use either single or double quotes to enclose the string.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`
|
||||
_Node(_code).find_variable("alphabet").is_equivalent("alphabet = 'abcdefghijklmnopqrstuvwxyz'")
|
||||
`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
shift = 5
|
||||
```
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
---
|
||||
id: 680a431692a5f863f726c438
|
||||
title: Step 3
|
||||
challengeType: 20
|
||||
dashedName: step-3
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In this workshop, you are going to build a *Caesar cipher*. This is one of the simplest techniques to encrypt text, which consists of substituting each letter of the plain text with the letter found at a fixed number of positions down the alphabet. For example, with a shift of 5, `a` would be replaced by `f`, `b` by `g` and so on.
|
||||
|
||||
To implement this cipher, you'll need to create a new version of your alphabet that starts at the position indicated by the shift. As you learned in a previous lecture, you can extract part of a string using string slicing:
|
||||
|
||||
```py
|
||||
fcc = 'freeCodeCamp'
|
||||
print(fcc[8:]) # Camp
|
||||
```
|
||||
|
||||
Create a variable named `shifted_alphabet` and use the slicing syntax to assign it the portion of `alphabet` that starts at the index of `shift`. Then, call the built-in `print()` function to print `shifted_alphabet` on the terminal and look at the result.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should declare a new variable named `shifted_alphabet`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).has_variable("shifted_alphabet")`)) })
|
||||
|
||||
```
|
||||
|
||||
You should assign `alphabet[shift:]` to `shifted_alphabet`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_variable("shifted_alphabet").is_equivalent("shifted_alphabet = alphabet[shift:]")`)) })
|
||||
```
|
||||
|
||||
You should call the `print()` function passing in `shifted_alphabet` as an argument.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).has_call("print(shifted_alphabet)")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
shift = 5
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
---
|
||||
id: 680a549f60f5a3fedfc0edd9
|
||||
title: Step 4
|
||||
challengeType: 20
|
||||
dashedName: step-4
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
As you can see from the output, the shifted alphabet starts at the letter `f` because `shift` has the value `5`. But now the first five letters of the alphabet – `a`, `b`, `c`, `d` and `e` – are missing from the shifted alphabet, so you'll need to add them at the end of the shifted alphabet.
|
||||
|
||||
The `+` operator is used to combine two or more strings together in a process called concatenation like this:
|
||||
|
||||
```py
|
||||
greeting = 'Hello' + ' ' + 'World'
|
||||
print(greeting) # Hello World
|
||||
|
||||
```
|
||||
|
||||
Use the slicing syntax to extract the missing first portion of `alphabet` and concatenate it to `alphabet[shift:]`.
|
||||
|
||||
As a reminder, `sentence[start:stop]` returns the characters of `sentence` from position `start` (included) to `stop` (excluded).
|
||||
|
||||
# --hints--
|
||||
|
||||
You should concatenate the missing first portion of `alphabet` to `alphabet[shift:]` using the slicing syntax. Use `shift` to specify where to stop the slicing.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
_shifted_alpha = _Node(_code).find_variable("shifted_alphabet")
|
||||
_first = _shifted_alpha.is_equivalent("shifted_alphabet = alphabet[shift:] + alphabet[:shift]")
|
||||
_second =_shifted_alpha.is_equivalent("shifted_alphabet = alphabet[shift:] + alphabet[0:shift]")
|
||||
assert _first or _second
|
||||
`) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
shift = 5
|
||||
shifted_alphabet = alphabet[shift:]
|
||||
print(shifted_alphabet)
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
---
|
||||
id: 680a5e7f3d47715196b12ca0
|
||||
title: Step 5
|
||||
challengeType: 20
|
||||
dashedName: step-5
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now that you have your entire shifted alphabet, remove the `print(shifted_alphabet)` call.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should remove `print(shifted_alphabet)` from your code.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`not _Node(_code).has_call("print(shifted_alphabet)")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
shift = 5
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
print(shifted_alphabet)
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
---
|
||||
id: 680a7e200400089967b8b1f4
|
||||
title: Step 6
|
||||
challengeType: 20
|
||||
dashedName: step-6
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The `str.maketrans()` method takes two strings of equal length and returns a translation table that maps each character of the first string with the corresponding character of the second string. Each character in the translation table is stored as a Unicode ordinal, a number that uniquely identifies the character.
|
||||
|
||||
```py
|
||||
lower_chars = 'abc'
|
||||
upper_chars = 'ABC'
|
||||
|
||||
table = str.maketrans(lower_chars, upper_chars)
|
||||
print(table) # {97: 65, 98: 66, 99: 67}
|
||||
```
|
||||
|
||||
You'll learn more about the type of structure returned by `str.maketrans()` later on in the curriculum. For now, create a translation table that maps the characters in `alphabet` to the characters in `shifted_alphabet` and assign it to a variable named `translation_table`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should declare a variable named `translation_table`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).has_variable("translation_table")`)) })
|
||||
```
|
||||
|
||||
You should call `str.maketrans()` passing in `alphabet` and `shifted_alphabet` as the arguments, and assign the result to `translation_table`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_variable("translation_table").is_equivalent("translation_table = str.maketrans(alphabet, shifted_alphabet)")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
shift = 5
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
---
|
||||
id: 680a82806c4c6bc3567f2708
|
||||
title: Step 7
|
||||
challengeType: 20
|
||||
dashedName: step-7
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Declare a new variable named `text` and assign it the string `hello world`. This will be the message to encrypt.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should declare a variable named `text`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).has_variable("text")`)) })
|
||||
```
|
||||
|
||||
You should assign the string `hello world` to `text`. Remember to enclose the string in either single or double quotes and pay attention to the letter case.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_variable("text").is_equivalent("text = 'hello world'")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
shift = 5
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
translation_table = str.maketrans(alphabet, shifted_alphabet)
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
---
|
||||
id: 680a836235461fce1ff53b3f
|
||||
title: Step 8
|
||||
challengeType: 20
|
||||
dashedName: step-8
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The `translate()` method takes as argument the translation table generated by `str.maketrans()`. It is called on a string and returns a copy of the original string where the characters have been replaced based on the translation table:
|
||||
|
||||
```py
|
||||
t = str.maketrans('lk', 'br')
|
||||
sentence = 'The tent gave in to the leaks.'
|
||||
|
||||
print(sentence.translate(t))
|
||||
# Output: The tent gave in to the bears.
|
||||
```
|
||||
|
||||
Call the `translate()` method on `text` passing in the `translation_table` as the argument and assign the result to a variable named `encrypted_text`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a variable named `encrypted_text`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).has_variable("encrypted_text")`)) })
|
||||
```
|
||||
|
||||
You should assign `text.translate(translation_table)` to `encrypted_text`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_variable("encrypted_text").is_equivalent("encrypted_text = text.translate(translation_table)")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
shift = 5
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
translation_table = str.maketrans(alphabet, shifted_alphabet)
|
||||
text = 'hello world'
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
---
|
||||
id: 6810869355fa2468f9ebaf9c
|
||||
title: Step 9
|
||||
challengeType: 20
|
||||
dashedName: step-9
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now print `encrypted_text` to see the output in the terminal.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should print `encrypted_text`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).has_call("print(encrypted_text)")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
shift = 5
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
translation_table = str.maketrans(alphabet, shifted_alphabet)
|
||||
text = 'hello world'
|
||||
encrypted_text = text.translate(translation_table)
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
---
|
||||
id: 6810891bd6de8a87a833df42
|
||||
title: Step 10
|
||||
challengeType: 20
|
||||
dashedName: step-10
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
As you can see from the output, the message has been encrypted. The next step will be making your code reusable in case you wanted to encrypt different messages.
|
||||
|
||||
For that, you'll need to create a function. As a reminder, here's how to create a function named `spam` that prints `Spam!` on the terminal:
|
||||
|
||||
```py
|
||||
def spam():
|
||||
print('Spam!')
|
||||
```
|
||||
|
||||
Create a function named `caesar`. Put all your existing code within the function body. Pay attention to keep the same indentation level for all of the lines within the function body.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a function named `caesar`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).has_function("caesar")`)) })
|
||||
```
|
||||
|
||||
You should move all the code you wrote so far within the `caesar` function body. Make sure you keep the same indentation level for all of the lines within the function body...
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_function("caesar").find_body().is_equivalent("alphabet = 'abcdefghijklmnopqrstuvwxyz'\\nshift = 5\\nshifted_alphabet = alphabet[shift:] + alphabet[:shift]\\ntranslation_table = str.maketrans(alphabet, shifted_alphabet)\\ntext = 'hello world'\\nencrypted_text = text.translate(translation_table)\\nprint(encrypted_text)")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
shift = 5
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
translation_table = str.maketrans(alphabet, shifted_alphabet)
|
||||
text = 'hello world'
|
||||
encrypted_text = text.translate(translation_table)
|
||||
print(encrypted_text)
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
---
|
||||
id: 6818b80519e6c6c47a8bb6e8
|
||||
title: Step 11
|
||||
challengeType: 20
|
||||
dashedName: step-11
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
As you learned in a previous lecture, functions can have parameters, which are variables that can be referenced within the function. Here's a `sum` function with two parameters, `num1` and `num2`.
|
||||
|
||||
```py
|
||||
def sum(num1, num2):
|
||||
print(num1 + num2)
|
||||
```
|
||||
|
||||
The message to encrypt and the shift are still hardcoded in your function. Give your function two parameters named `text` and `shift`, and delete the declarations of both the `text` and `shift` variables from the `caesar` function body.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `caesar` function should have two parameters, `text` and `shift`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_function("caesar").has_args("text, shift")`)) })
|
||||
```
|
||||
|
||||
You should not have a `text` variable declared within the `caesar` function body.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`not _Node(_code).find_function("caesar").find_body().has_variable("text")`)) })
|
||||
```
|
||||
|
||||
You should not have a `shift` variable declared within the `caesar` function body.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`not _Node(_code).find_function("caesar").find_body().has_variable("shift")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
def caesar():
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
shift = 5
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
translation_table = str.maketrans(alphabet, shifted_alphabet)
|
||||
text = 'hello world'
|
||||
encrypted_text = text.translate(translation_table)
|
||||
print(encrypted_text)
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
---
|
||||
id: 6818e9c7c8dc5694e8f64fc3
|
||||
title: Step 12
|
||||
challengeType: 20
|
||||
dashedName: step-12
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now, test the `caesar` function by calling it with the string `freeCodeCamp` and the number `3` as the arguments. Assign the function call to a variable named `encrypted_text`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a variable named `encrypted_text` in the global scope.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).has_variable("encrypted_text")`)) })
|
||||
```
|
||||
|
||||
You should assign `caesar('freeCodeCamp', 3)` to the `encrypted_text` variable.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_variable("encrypted_text").is_equivalent("encrypted_text = caesar('freeCodeCamp', 3)")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def caesar(text, shift):
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
translation_table = str.maketrans(alphabet, shifted_alphabet)
|
||||
encrypted_text = text.translate(translation_table)
|
||||
print(encrypted_text)
|
||||
--fcc-editable-region--
|
||||
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
---
|
||||
id: 6818eb3f98c0bca5af7c8d03
|
||||
title: Step 13
|
||||
challengeType: 20
|
||||
dashedName: step-13
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now your code is reusable. However, the `caesar` function prints a message on the terminal and gives back `None` by default. To prove it, print `encrypted_text` at the end of your code.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should print `encrypted_text` outside of the function body.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).has_call("print(encrypted_text)")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def caesar(text, shift):
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
translation_table = str.maketrans(alphabet, shifted_alphabet)
|
||||
encrypted_text = text.translate(translation_table)
|
||||
print(encrypted_text)
|
||||
|
||||
--fcc-editable-region--
|
||||
encrypted_text = caesar('freeCodeCamp', 3)
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
---
|
||||
id: 6818ed1adc249bb91d373729
|
||||
title: Step 14
|
||||
challengeType: 20
|
||||
dashedName: step-14
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
In previous lectures, you learned that the `return` statement is used to return a value from a function, so that you can use it elsewhere in your code:
|
||||
|
||||
```py
|
||||
def spam():
|
||||
return 'Spam!'
|
||||
```
|
||||
|
||||
Remove the `print(encrypted_text)` call from your function. Then, delete the declaration of the `encrypted_text` variable and return directly `text.translate(translation_table)` from your function.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should not have `print(encrypted_text)` within the `caesar` function.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`not _Node(_code).find_function("caesar").has_call("print(encrypted_text)")`)) })
|
||||
```
|
||||
|
||||
You should not have an `encrypted_text` variable within the `caesar` function.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`not _Node(_code).find_function("caesar").has_variable("encrypted_text")`)) })
|
||||
```
|
||||
|
||||
Your `caesar` function should return `text.translate(translation_table)`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_function("caesar").has_return("text.translate(translation_table)")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
def caesar(text, shift):
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
translation_table = str.maketrans(alphabet, shifted_alphabet)
|
||||
encrypted_text = text.translate(translation_table)
|
||||
print(encrypted_text)
|
||||
--fcc-editable-region--
|
||||
|
||||
encrypted_text = caesar('freeCodeCamp', 3)
|
||||
print(encrypted_text)
|
||||
|
||||
```
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
---
|
||||
id: 6818fcb250f34e62cab32c39
|
||||
title: Step 15
|
||||
challengeType: 20
|
||||
dashedName: step-15
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You might have noticed that, although the message is encrypted, the uppercase characters have been left untouched. This happens because the translation table does not include uppercase letters.
|
||||
|
||||
To fix it, you'll need to modify the strings passed to your `str.maketrans()` call using the `upper()` method:
|
||||
|
||||
```py
|
||||
greet = "Hello"
|
||||
print(greet.upper()) # HELLO
|
||||
```
|
||||
|
||||
Update your `str.maketrans()` call by concatenating to each argument the uppercase version of the argument itself.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should modify the arguments of your `str.maketrans()` call by concatenating to each argument the uppercase version of the argument itself.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`caesar('This Is A TEST', 5) == 'Ymnx Nx F YJXY'`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def caesar(text, shift):
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
--fcc-editable-region--
|
||||
translation_table = str.maketrans(alphabet, shifted_alphabet)
|
||||
--fcc-editable-region--
|
||||
return text.translate(translation_table)
|
||||
|
||||
|
||||
encrypted_text = caesar('freeCodeCamp', 3)
|
||||
print(encrypted_text)
|
||||
```
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
---
|
||||
id: 6819bc0637b80256a33adccc
|
||||
title: Step 16
|
||||
challengeType: 20
|
||||
dashedName: step-16
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now that you've implemented the basic functionalities of the cipher, it's time to add some validation. For that, you'll need an `if` statement. Here's a reminder of the syntax for an `if` statement:
|
||||
|
||||
```py
|
||||
if condition:
|
||||
# code to run when condition is true
|
||||
```
|
||||
|
||||
At the beginning of your function body, create an `if` statement. For now, use `True` as the condition, and within the `if` statement body return the string `Shift must be an integer value.`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have an `if` statement inside your `caesar` function.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_function("caesar").find_ifs()[0]`)) })
|
||||
```
|
||||
|
||||
Your `if` statement should use `True` as its condition.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_function("caesar").find_ifs()[0].find_conditions()[0].is_equivalent("True")`)) })
|
||||
```
|
||||
|
||||
You should return the string `Shift must be an integer value.` from your `if` statement.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_function("caesar").find_ifs()[0].find_bodies()[0].has_return("'Shift must be an integer value.'")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
def caesar(text, shift):
|
||||
|
||||
--fcc-editable-region--
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
translation_table = str.maketrans(alphabet + alphabet.upper(), shifted_alphabet + shifted_alphabet.upper())
|
||||
return text.translate(translation_table)
|
||||
|
||||
|
||||
encrypted_text = caesar('freeCodeCamp', 3)
|
||||
print(encrypted_text)
|
||||
```
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
---
|
||||
id: 6819be9055828d65c813eec5
|
||||
title: Step 17
|
||||
challengeType: 20
|
||||
dashedName: step-17
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The `isinstance()` function returns `True` if its first argument is an instance of the second argument, and `False` otherwise:
|
||||
|
||||
```py
|
||||
print(isinstance('Hello World', str)) # True
|
||||
print(isinstance(42, int)) # True
|
||||
```
|
||||
|
||||
Replace the current condition of your `if` statement with an `isinstance()` call. Pass in `shift` as the first argument, and `int` as the second argument.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `if` statement should use `isinstance(shift, int)` as its condition.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_function("caesar").find_ifs()[0].find_conditions()[0].is_equivalent("isinstance(shift, int)")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
def caesar(text, shift):
|
||||
if True:
|
||||
return 'Shift must be an integer value.'
|
||||
--fcc-editable-region--
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
translation_table = str.maketrans(alphabet + alphabet.upper(), shifted_alphabet + shifted_alphabet.upper())
|
||||
return text.translate(translation_table)
|
||||
|
||||
|
||||
encrypted_text = caesar('freeCodeCamp', 3)
|
||||
print(encrypted_text)
|
||||
```
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
---
|
||||
id: 6819c5c9faf2548e556163d5
|
||||
title: Step 18
|
||||
challengeType: 20
|
||||
dashedName: step-18
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
As you recall from the lectures, the `not` operator is a unary logical operator that negates an expression:
|
||||
|
||||
```py
|
||||
print(not True) # False
|
||||
print(not False) # True
|
||||
```
|
||||
|
||||
Use the `not` operator to fix the condition of the `if` statement so that your function returns `Shift must be an integer value.` when `shift` is *not* an integer.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use the `not` operator to negate `isinstance(shift, int)` in your `if` statement.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_function("caesar").find_ifs()[0].find_conditions()[0].is_equivalent("not isinstance(shift, int)")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
def caesar(text, shift):
|
||||
if isinstance(shift, int):
|
||||
return 'Shift must be an integer value.'
|
||||
--fcc-editable-region--
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
translation_table = str.maketrans(alphabet + alphabet.upper(), shifted_alphabet + shifted_alphabet.upper())
|
||||
return text.translate(translation_table)
|
||||
|
||||
|
||||
encrypted_text = caesar('freeCodeCamp', 3)
|
||||
print(encrypted_text)
|
||||
```
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
---
|
||||
id: 6819c7beb4a8289c2b4f24d5
|
||||
title: Step 19
|
||||
challengeType: 20
|
||||
dashedName: step-19
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
A negative or null shift should not be accepted by your function. Therefore, after your first `if` statement, create another `if` statement that checks if `shift` is less than `1` and returns the string `Shift must be a positive integer.`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a second `if` statement that checks if `shift` is less than `1`.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
_cond = _Node(_code).find_function("caesar").find_ifs()[1].find_conditions()[0]
|
||||
_options = ["shift < 1", "1 > shift", "shift <= 0", "0 => shift"]
|
||||
assert any(_cond.is_equivalent(option) for option in _options)
|
||||
`) })
|
||||
```
|
||||
|
||||
Your second `if` statement should return `Shift must be a positive integer.`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_function("caesar").find_ifs()[1].find_bodies()[0].has_return("'Shift must be a positive integer.'")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
def caesar(text, shift):
|
||||
if not isinstance(shift, int):
|
||||
return 'Shift must be an integer value.'
|
||||
|
||||
--fcc-editable-region--
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
translation_table = str.maketrans(alphabet + alphabet.upper(), shifted_alphabet + shifted_alphabet.upper())
|
||||
return text.translate(translation_table)
|
||||
|
||||
|
||||
encrypted_text = caesar('freeCodeCamp', 3)
|
||||
print(encrypted_text)
|
||||
```
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
---
|
||||
id: 6819ca464db219ab86f37dc4
|
||||
title: Step 20
|
||||
challengeType: 20
|
||||
dashedName: step-20
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
As you've already verified, the shift passed to encrypt the text should be positive. It cannot exceed `25` (the last index of `alphabet`) though.
|
||||
|
||||
Add a second condition to the `if` statement that verifies that `shift` is greater than `25`. Remember that the logical OR operation in Python is implemented through the `or` operator.
|
||||
|
||||
Also, update the returned message to `Shift must be an integer between 1 and 25.`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use the `or` operator to add a second condition after `shift < 1` checking if `shift` is greater than `25`. You should not modify the existing condition.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
_cond = _Node(_code).find_function("caesar").find_ifs()[1].find_conditions()[0]
|
||||
_options = ["shift > 25", "25 < shift", "shift >= 26", "26 =< shift"]
|
||||
assert any(_cond.is_equivalent(f"shift < 1 or {option}") for option in _options)
|
||||
`) })
|
||||
```
|
||||
|
||||
Your second `if` statement should return `Shift must be an integer between 1 and 25.`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_function("caesar").find_ifs()[1].find_bodies()[0].has_return("'Shift must be an integer between 1 and 25.'")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def caesar(text, shift):
|
||||
if not isinstance(shift, int):
|
||||
return 'Shift must be an integer value.'
|
||||
--fcc-editable-region--
|
||||
if shift < 1:
|
||||
return 'Shift must be a positive integer.'
|
||||
--fcc-editable-region--
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
translation_table = str.maketrans(alphabet + alphabet.upper(), shifted_alphabet + shifted_alphabet.upper())
|
||||
return text.translate(translation_table)
|
||||
|
||||
|
||||
encrypted_text = caesar('freeCodeCamp', 3)
|
||||
print(encrypted_text)
|
||||
```
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
---
|
||||
id: 6819cf38880d8cc9b9f6af7a
|
||||
title: Step 21
|
||||
challengeType: 20
|
||||
dashedName: step-21
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Python allows you to specify a default value for the parameters in a function, creating a function that can be called with fewer or no arguments. Here's how to create a function with a `name` parameter that has a default value:
|
||||
|
||||
```py
|
||||
def greet(name='Polly'):
|
||||
return 'Hello ' + name
|
||||
|
||||
print(greet()) # Hello Polly
|
||||
```
|
||||
|
||||
Add a third parameter named `encrypt` to your function and give it a default value of `True`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should add a third parameter named `encrypt` with a default value of `True` to your function. Do not modify the existing parameters.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_function("caesar").has_args("text, shift, encrypt=True")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
--fcc-editable-region--
|
||||
def caesar(text, shift):
|
||||
--fcc-editable-region--
|
||||
if not isinstance(shift, int):
|
||||
return 'Shift must be an integer value.'
|
||||
|
||||
if shift < 1 or shift > 25:
|
||||
return 'Shift must be an integer between 1 and 25.'
|
||||
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
translation_table = str.maketrans(alphabet + alphabet.upper(), shifted_alphabet + shifted_alphabet.upper())
|
||||
return text.translate(translation_table)
|
||||
|
||||
|
||||
encrypted_text = caesar('freeCodeCamp', 3)
|
||||
print(encrypted_text)
|
||||
```
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
---
|
||||
id: 681a1d60e037127e7c8e0230
|
||||
title: Step 22
|
||||
challengeType: 20
|
||||
dashedName: step-22
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You are going to use the parameter added in the previous step to determine if the function should encrypt the text passed to it (default behavior, `encrypt=True`), or if it should decrypt an encrypted message.
|
||||
|
||||
Create an `if` statement that checks if `encrypt` is not truthy. Within the new `if` statement, set `shift` to `- shift`. This is necessary to enable the shift to take place in the opposite direction with respect to the encryption process.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should set `shift` to `- shift` when `encrypt` is not truthy.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`caesar('Ymnx Nx F Yjxy', 5, False) == 'This Is A Test'`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def caesar(text, shift, encrypt=True):
|
||||
|
||||
if not isinstance(shift, int):
|
||||
return 'Shift must be an integer value.'
|
||||
|
||||
if shift < 1 or shift > 25:
|
||||
return 'Shift must be an integer between 1 and 25.'
|
||||
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
translation_table = str.maketrans(alphabet + alphabet.upper(), shifted_alphabet + shifted_alphabet.upper())
|
||||
encrypted_text = text.translate(translation_table)
|
||||
return encrypted_text
|
||||
|
||||
|
||||
encrypted_text = caesar('freeCodeCamp', 3)
|
||||
print(encrypted_text)
|
||||
```
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
---
|
||||
id: 681a2a6cf95e82ca30866364
|
||||
title: Step 23
|
||||
challengeType: 20
|
||||
dashedName: step-23
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Declare two functions named `encrypt` and `decrypt`, both with `text` and `shift` parameters.
|
||||
|
||||
You'll use `encrypt` for the encryption process, and `decrypt` for the decryption, labeling the two actions with a descriptive name.
|
||||
|
||||
Return a `caesar` call passing in `text` and `shift` from both your new functions, but make sure to pass in also `False` as the third argument for the `decrypt` function.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should have a function named `encrypt` with two parameters, `text` and `shift`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_function("encrypt").has_args("text, shift")`)) })
|
||||
```
|
||||
|
||||
Your `encrypt` function should return `caesar(text, shift)`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_function("encrypt").has_return("caesar(text, shift)")`)) })
|
||||
```
|
||||
|
||||
You should have a function named `decrypt` with two parameters, `text` and `shift`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_function("decrypt").has_args("text, shift")`)) })
|
||||
```
|
||||
|
||||
Your `decrypt` function should return `caesar(text, shift, False)`.
|
||||
|
||||
```js
|
||||
({ test: () => runPython(`
|
||||
_n = _Node(_code).find_function("decrypt")
|
||||
assert _n.has_return("caesar(text, shift, encrypt=False)") or _n.has_return("caesar(text, shift, False)")
|
||||
`) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def caesar(text, shift, encrypt=True):
|
||||
|
||||
if not isinstance(shift, int):
|
||||
return 'Shift must be an integer value.'
|
||||
|
||||
if shift < 1 or shift > 25:
|
||||
return 'Shift must be an integer between 1 and 25.'
|
||||
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
|
||||
if not encrypt:
|
||||
shift = - shift
|
||||
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
translation_table = str.maketrans(alphabet + alphabet.upper(), shifted_alphabet + shifted_alphabet.upper())
|
||||
encrypted_text = text.translate(translation_table)
|
||||
return encrypted_text
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
encrypted_text = caesar('freeCodeCamp', 3)
|
||||
print(encrypted_text)
|
||||
```
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
---
|
||||
id: 681a2e35c406ade2f0a5f9b2
|
||||
title: Step 24
|
||||
challengeType: 20
|
||||
dashedName: step-24
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
It's time to test the `encrypt` function. Using the same arguments, replace your `caesar` call with a call to `encrypt`. You'll see the same output on the terminal.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `encrypted_text` variable should have the value of `encrypt('freeCodeCamp', 3)`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_variable("encrypted_text").is_equivalent("encrypted_text = encrypt('freeCodeCamp', 3)")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def caesar(text, shift, encrypt=True):
|
||||
|
||||
if not isinstance(shift, int):
|
||||
return 'Shift must be an integer value.'
|
||||
|
||||
if shift < 1 or shift > 25:
|
||||
return 'Shift must be an integer between 1 and 25.'
|
||||
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
|
||||
if not encrypt:
|
||||
shift = - shift
|
||||
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
translation_table = str.maketrans(alphabet + alphabet.upper(), shifted_alphabet + shifted_alphabet.upper())
|
||||
encrypted_text = text.translate(translation_table)
|
||||
return encrypted_text
|
||||
|
||||
def encrypt(text, shift):
|
||||
return caesar(text, shift)
|
||||
|
||||
def decrypt(text, shift):
|
||||
return caesar(text, shift, encrypt=False)
|
||||
--fcc-editable-region--
|
||||
encrypted_text = caesar('freeCodeCamp', 3)
|
||||
print(encrypted_text)
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
---
|
||||
id: 681a44f4c3235f7d8f428545
|
||||
title: Step 25
|
||||
challengeType: 20
|
||||
dashedName: step-25
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now you're going to test the `decrypt` function. Replace the value assigned to `encrypted_text` with the following string, which represents a message to decrypt: `Pbhentr vf sbhaq va hayvxryl cynprf.`.
|
||||
|
||||
Then, declare a variable named `decrypted_text` and assign it a call to `decrypt` with `encrypted_text` as it first argument and a shift of `13` as the second argument.
|
||||
|
||||
Finally, print the `decrypted_text` on the terminal. With that, the Caesar cipher is complete.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should assign `Pbhentr vf sbhaq va hayvxryl cynprf.` to `encrypted_text`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_variable("encrypted_text").is_equivalent("encrypted_text = 'Pbhentr vf sbhaq va hayvxryl cynprf.'")`)) })
|
||||
```
|
||||
|
||||
You should have a variable named `decrypted_text`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).has_variable("decrypted_text")`)) })
|
||||
```
|
||||
|
||||
You should assign `decrypt(encrypted_text, 13)` to `decrypted_text`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).find_variable("decrypted_text").is_equivalent("decrypted_text = decrypt(encrypted_text, 13)")`)) })
|
||||
```
|
||||
|
||||
You should print `decrypted_text`.
|
||||
|
||||
```js
|
||||
({ test: () => assert(runPython(`_Node(_code).has_call("print(decrypted_text)")`)) })
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```py
|
||||
def caesar(text, shift, encrypt=True):
|
||||
|
||||
if not isinstance(shift, int):
|
||||
return 'Shift must be an integer value.'
|
||||
|
||||
if shift < 1 or shift > 25:
|
||||
return 'Shift must be an integer between 1 and 25.'
|
||||
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
|
||||
if not encrypt:
|
||||
shift = - shift
|
||||
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
translation_table = str.maketrans(alphabet + alphabet.upper(), shifted_alphabet + shifted_alphabet.upper())
|
||||
encrypted_text = text.translate(translation_table)
|
||||
return encrypted_text
|
||||
|
||||
def encrypt(text, shift):
|
||||
return caesar(text, shift)
|
||||
|
||||
def decrypt(text, shift):
|
||||
return caesar(text, shift, encrypt=False)
|
||||
--fcc-editable-region--
|
||||
encrypted_text = encrypt('freeCodeCamp', 3)
|
||||
print(encrypted_text)
|
||||
--fcc-editable-region--
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```py
|
||||
def caesar(text, shift, encrypt=True):
|
||||
|
||||
if not isinstance(shift, int):
|
||||
return 'Shift must be an integer value.'
|
||||
|
||||
if shift < 1 or shift > 25:
|
||||
return 'Shift must be an integer between 1 and 25.'
|
||||
|
||||
alphabet = 'abcdefghijklmnopqrstuvwxyz'
|
||||
|
||||
if not encrypt:
|
||||
shift = - shift
|
||||
|
||||
shifted_alphabet = alphabet[shift:] + alphabet[:shift]
|
||||
translation_table = str.maketrans(alphabet + alphabet.upper(), shifted_alphabet + shifted_alphabet.upper())
|
||||
encrypted_text = text.translate(translation_table)
|
||||
return encrypted_text
|
||||
|
||||
def encrypt(text, shift):
|
||||
return caesar(text, shift)
|
||||
|
||||
def decrypt(text, shift):
|
||||
return caesar(text, shift, encrypt=False)
|
||||
|
||||
encrypted_text = 'Pbhentr vf sbhaq va hayvxryl cynprf.'
|
||||
decrypted_text = decrypt(encrypted_text, 13)
|
||||
print(decrypted_text)
|
||||
```
|
||||
Reference in New Issue
Block a user