chore(i18n,learn): processed translations (#48105)

This commit is contained in:
camperbot
2022-10-18 12:59:49 +05:30
committed by GitHub
parent e22f87a085
commit 41bbc30b94
6193 changed files with 34016 additions and 29293 deletions
@@ -91,7 +91,7 @@ const el = document.getElementById('name')
assert(!!el && el.required)
```
你的 `#name` 元素應該是 `#survey-form` 元素的子元素。
Your `#name` should be a descendant of `#survey-form`.
```js
const el = document.querySelector('#survey-form #name')
@@ -119,7 +119,7 @@ const el = document.getElementById('email')
assert(!!el && el.required)
```
你的 `#email` 元素應該是 `#survey-form` 元素的子元素。
Your `#email` should be a descendant of `#survey-form`
```js
const el = document.querySelector('#survey-form #email')
@@ -133,7 +133,7 @@ const el = document.getElementById('number')
assert(!!el && el.tagName === 'INPUT')
```
你的 `#number` 元素應該是 `#survey-form` 元素的子元素。
Your `#number` should be a descendant of `#survey-form`.
```js
const el = document.querySelector('#survey-form #number')
@@ -203,21 +203,21 @@ const el = document.getElementById('number-label')
assert(!!el && el.innerText.length > 0)
```
你的 `#name-label` 元素應該是 `#survey-form` 元素的子元素。
Your `#name-label` should be a descendant of `#survey-form`.
```js
const el = document.querySelector('#survey-form #name-label')
assert(!!el)
```
你的 `#email-label` 元素應該是 `#survey-form` 元素的子元素。
Your `#email-label` should be a descendant of `#survey-form`.
```js
const el = document.querySelector('#survey-form #email-label')
assert(!!el)
```
你的 `#number-label` 元素應該是 `#survey-form` 元素的子元素。
Your `#number-label` should be a descendant of `#survey-form`.
```js
const el = document.querySelector('#survey-form #number-label')
@@ -8,7 +8,7 @@ dashedName: falsy-bouncer
# --description--
從數組中移除所有假值(falsy values)。
Remove all falsy values from an array. Return a new array; do not mutate the original array.
JavaScript 中的假值有 `false`、`null`、`0`、`""`、`undefined`、`NaN`。
@@ -40,6 +40,14 @@ assert.deepEqual(bouncer([false, null, 0, NaN, undefined, '']), []);
assert.deepEqual(bouncer([null, NaN, 1, 2, undefined]), [1, 2]);
```
You should not mutate `arr`.
```js
const arr = ['a', false, 0, 'Naomi'];
bouncer(arr);
assert.deepEqual(arr, ['a', false, 0, 'Naomi'])
```
# --seed--
## --seed-contents--
@@ -37,12 +37,6 @@ assert(code.match(/quotient/g).length === 1);
# --seed--
## --after-user-code--
```js
(function(y){return 'quotient = '+y;})(quotient);
```
## --seed-contents--
```js
@@ -11,12 +11,12 @@ dashedName: escape-sequences-in-strings
引號不是字符串中唯一可以被轉義(<dfn>escaped</dfn>)的字符。 使用轉義字符有兩個原因:
1. 首先是可以讓你使用無法輸入的字符,例如退格。
1. To allow you to use characters you may not otherwise be able to type out, such as a newline.
2. 其次是可以讓你在一個字符串中表示多個引號,而不會出錯。
我們在之前的挑戰中學到了這個。
<table class='table table-striped'><thead><tr><th>代碼</th><th>輸出</th></tr></thead><tbody><tr><td><code>\'</code></td><td>單引號</td></tr><tr><td><code>\"</code></td><td>雙引號</td></tr><tr><td><code>\\</code></td><td>反斜槓</td></tr><tr><td><code>\n</code></td><td>換行符</td></tr><tr><td><code>\r</code></td><td>回車符</td></tr><tr><td><code>\t</code></td><td>製表符</td></tr><tr><td><code>\b</code></td><td>退格</td></tr><tr><td><code>\f</code></td><td>換頁符</td></tr></tbody></table>
<table class='table table-striped'><thead><tr><th>代碼</th><th>輸出</th></tr></thead><tbody><tr><td><code>\'</code></td><td>單引號</td></tr><tr><td><code>\"</code></td><td>雙引號</td></tr><tr><td><code>\\</code></td><td>反斜槓</td></tr><tr><td><code>\n</code></td><td>換行符</td></tr><tr><td><code>\t</code></td><td>tab</td></tr><tr><td><code>\r</code></td><td>carriage return</td></tr><tr><td><code>\b</code></td><td>退格</td></tr><tr><td><code>\f</code></td><td>換頁符</td></tr></tbody></table>
*請注意,必須對反斜槓本身進行轉義,它才能顯示爲反斜槓。*
@@ -78,14 +78,6 @@ assert(myStr === 'FirstLine\n\t\\SecondLine\nThirdLine');
# --seed--
## --after-user-code--
```js
(function(){
if (myStr !== undefined){
console.log('myStr:\n' + myStr);}})();
```
## --seed-contents--
```js
@@ -31,12 +31,6 @@ assert(/var\s+a\s*=\s*9(\s*;?\s*)$/.test(code));
# --seed--
## --after-user-code--
```js
if(typeof a !== 'undefined') {(function(a){return "a = " + a;})(a);} else { (function() {return 'a is undefined';})(); }
```
## --seed-contents--
```js
@@ -62,12 +62,6 @@ assert(code.match(/"/g).length === 4 && code.match(/'/g).length === 2);
# --seed--
## --after-user-code--
```js
(function() { return "myStr = " + myStr; })();
```
## --seed-contents--
```js
@@ -98,7 +98,7 @@ function nextInLine(arr, item) {
}
// Setup
const testArr = [1, 2, 3, 4, 5];
let testArr = [1, 2, 3, 4, 5];
// Display code
console.log("Before: " + JSON.stringify(testArr));
@@ -109,7 +109,7 @@ console.log("After: " + JSON.stringify(testArr));
# --solutions--
```js
const testArr = [1, 2, 3, 4, 5];
let testArr = [1, 2, 3, 4, 5];
function nextInLine(arr, item) {
arr.push(item);
@@ -71,6 +71,13 @@ assert(
);
```
Global variables should not be used to cache the array.
```js
countdown(1)
assert.deepStrictEqual(countdown(5), [5, 4, 3, 2, 1]);
```
# --seed--
## --seed-contents--
@@ -56,6 +56,13 @@ assert.deepStrictEqual(rangeOfNumbers(6, 9), [6, 7, 8, 9]);
assert.deepStrictEqual(rangeOfNumbers(4, 4), [4]);
```
Global variables should not be used to cache the array.
```js
rangeOfNumbers(1, 3)
assert.deepStrictEqual(rangeOfNumbers(6, 9), [6, 7, 8, 9]);
```
# --seed--
## --seed-contents--
@@ -12,24 +12,35 @@ ES6 提供了一個新的創建對象的語法,使用關鍵字 <dfn>class</dfn
值得注意的是,`class` 只是一個語法糖,它並不像 Java、Python 或者 Ruby 這一類的語言一樣,嚴格履行了面向對象的開發規範。
在 ES5 裏面,我們通常會定義一個構造函數 `constructor`,然後使用 `new` 關鍵字來實例化一個對象:
In ES5, an object can be created by defining a `constructor` function and using the `new` keyword to instantiate the object.
```js
var SpaceShuttle = function(targetPlanet){
this.targetPlanet = targetPlanet;
}
var zeus = new SpaceShuttle('Jupiter');
```
`class` 語法只是簡單地替換了構造函數 `constructor` 的寫法:
In ES6, a `class` declaration has a `constructor` method that is invoked with the `new` keyword. If the `constructor` method is not explicitly defined, then it is implicitly defined with no arguments.
```js
// Explicit constructor
class SpaceShuttle {
constructor(targetPlanet) {
this.targetPlanet = targetPlanet;
}
takeOff() {
console.log("To " + this.targetPlanet + "!");
}
}
// Implicit constructor
class Rocket {
launch() {
console.log("To the moon!");
}
}
const zeus = new SpaceShuttle('Jupiter');
// prints To Jupiter! in console
zeus.takeOff();
const atlas = new Rocket();
// prints To the moon! in console
atlas.launch();
```
應該注意 `class` 關鍵字聲明瞭一個新的函數,裏面添加了一個構造函數。 當用 `new` 創建一個新的對象時,構造函數會被調用。
@@ -53,7 +53,8 @@ assert(
`bicycle.setGear(48)` 應將 `gear` 的值改爲 48。
```js
assert(new bicycle.setGear(48).gear === 48);
bicycle.setGear(48);
assert(bicycle.gear === 48);
```
# --seed--
@@ -10,20 +10,20 @@ dashedName: add-elements-to-the-end-of-an-array-using-concat-instead-of-push
函數式編程就是創建和使用具有不變性的函數。
上一個挑戰介紹了 `concat` 方法,這是一種在不改變原始數組的前提下,將數組組合成新數組的方法。 將 `concat` 方法與 `push` 方法做比較。 `push` 將元素添加到調用它的數組的末尾,這樣會改變該數組。 舉個例子:
The last challenge introduced the `concat` method as a way to merge arrays into a new array without mutating the original arrays. 將 `concat` 方法與 `push` 方法做比較。 `push` adds items to the end of the same array it is called on, which mutates that array. 舉個例子:
```js
const arr = [1, 2, 3];
arr.push([4, 5, 6]);
arr.push(4, 5, 6);
```
`arr` 的值被修改爲 `[1, 2, 3, [4, 5, 6]]`,這不是函數編程方式。
`arr` would have a modified value of `[1, 2, 3, 4, 5, 6]`, which is not the functional programming way.
`concat` 方法可以將新項目添加到數組末尾,而不產生副作用。
`concat` offers a way to merge new items to the end of an array without any mutating side effects.
# --instructions--
修改 `nonMutatingPush` 函數,用 `concat` 替代 `push` 將 `newItem` 添加到 `original` 末尾。 該函數應返回一個數組。
Change the `nonMutatingPush` function so it uses `concat` to merge `newItem` to the end of `original` without mutating `original` or `newItem` arrays. 該函數應返回一個數組。
# --hints--
@@ -137,14 +137,6 @@ assert.strictEqual(
# --seed--
## --after-user-code--
```js
if(bob){
bob = new Person("Bob Ross");
}
```
## --seed-contents--
```js
@@ -42,6 +42,13 @@ assert.deepEqual(steamrollArray([1, {}, [3, [[4]]]]), [1, {}, 3, 4]);
assert(!code.match(/\.\s*flat\s*\(/) && !code.match(/\.\s*flatMap\s*\(/));
```
Global variables should not be used.
```js
steamrollArray([1, {}, [3, [[4]]]])
assert.deepEqual(steamrollArray([1, {}, [3, [[4]]]]), [1, {}, 3, 4])
```
# --seed--
## --seed-contents--
@@ -47,28 +47,48 @@ sumPrimes(10);
# --solutions--
```js
function eratosthenesArray(n) {
var primes = [];
if (n > 2) {
var half = n>>1;
var sieve = Array(half);
for (var i = 1, limit = Math.sqrt(n)>>1; i <= limit; i++) {
if (!sieve[i]) {
for (var step = 2*i+1, j = (step*step)>>1; j < half; j+=step) {
sieve[j] = true;
}
}
}
primes.push(2);
for (var p = 1; p < half; p++) {
if (!sieve[p]) primes.push(2*p+1);
class PrimeSeive {
constructor(num) {
const seive = Array(Math.floor((num - 1) / 2)).fill(true);
const upper = Math.floor((num - 1) / 2);
const sqrtUpper = Math.floor((Math.sqrt(num) - 1) / 2);
for (let i = 0; i <= sqrtUpper; i++) {
if (seive[i]) {
// Mark value in seive array
const prime = 2 * i + 3;
// Mark all multiples of this number as false (not prime)
const primeSqaredIndex = 2 * i ** 2 + 6 * i + 3;
for (let j = primeSqaredIndex; j < upper; j += prime) {
seive[j] = false;
}
}
}
return primes;
}
this._seive = seive;
}
isPrime(num) {
return num === 2
? true
: num % 2 === 0
? false
: this.isOddPrime(num);
}
isOddPrime(num) {
return this._seive[(num - 3) / 2];
}
};
function sumPrimes(num) {
return eratosthenesArray(num+1).reduce(function(a,b) {return a+b;}, 0);
const primeSeive = new PrimeSeive(num);
let sum = 2;
for (let i = 3; i <= num; i += 2) {
if (primeSeive.isOddPrime(i)) sum += i;
}
return sum;
}
sumPrimes(10);
@@ -79,23 +79,55 @@ assert(beagle.constructor === Dog);
`beagle.eat()` 應該記錄字符串 `nom nom nom`
```js
console.log = function (msg) {
throw msg;
};
assert.throws(() => beagle.eat(), 'nom nom nom');
capture();
beagle.eat();
uncapture();
assert(logOutput == 'nom nom nom');
```
`beagle.bark()` 應該將字符串 `Woof!` 打印到控制檯
```js
console.log = function (msg) {
throw msg;
};
assert.throws(() => beagle.bark(), 'Woof!');
capture();
beagle.bark();
uncapture();
assert(logOutput == 'Woof!');
```
# --seed--
## --before-user-code--
```js
var logOutput = "";
var originalConsole = console
function capture() {
var nativeLog = console.log;
console.log = function (message) {
logOutput = message;
if(nativeLog.apply) {
nativeLog.apply(originalConsole, arguments);
} else {
var nativeMsg = Array.prototype.slice.apply(arguments).join(' ');
nativeLog(nativeMsg);
}
};
}
function uncapture() {
console.log = originalConsole.log;
}
capture();
```
## --after-user-code--
```js
uncapture();
(function() { return logOutput || "console.log never called"; })();
```
## --seed-contents--
```js
@@ -8,7 +8,7 @@ dashedName: build-a-25--5-clock
# --description--
**目標:** 構建一個應用,功能和 <a href="https://codepen.io/freeCodeCamp/full/XpKrrW" target="_blank" rel="noopener noreferrer nofollow">https://codepen.io/freeCodeCamp/full/XpKrrW</a> 類似。
**Objective:** Build an app that is functionally similar to this: <a href="https://25--5-clock.freecodecamp.rocks" target="_blank" rel="noopener noreferrer nofollow">https://25--5-clock.freecodecamp.rocks</a>.
完成以下需求,並且通過所有測試。 可以使用你需要的任何庫或 API。 賦予它你自己的個人風格。
@@ -8,7 +8,7 @@ dashedName: build-a-drum-machine
# --description--
**目標:** 構建一個應用,功能和 <a href="https://codepen.io/freeCodeCamp/full/MJyNMd" target="_blank" rel="noopener noreferrer nofollow">https://codepen.io/freeCodeCamp/full/MJyNMd</a> 類似。
**Objective:** Build an app that is functionally similar to this: <a href="https://drum-machine.freecodecamp.rocks/" target="_blank" rel="noopener noreferrer nofollow">https://drum-machine.freecodecamp.rocks/</a>.
完成以下需求,並且通過所有測試。 可以使用你需要的任何庫或 API。 賦予它你自己的個人風格。
@@ -8,7 +8,7 @@ dashedName: build-a-javascript-calculator
# --description--
**目標:** 構建一個應用,功能和 <a href="https://codepen.io/freeCodeCamp/full/wgGVVX" target="_blank" rel="noopener noreferrer nofollow">https://codepen.io/freeCodeCamp/full/wgGVVX</a> 類似。
**Objective:** Build an app that is functionally similar to this: <a href="https://javascript-calculator.freecodecamp.rocks/" target="_blank" rel="noopener noreferrer nofollow">https://javascript-calculator.freecodecamp.rocks/</a>.
完成以下需求,並且通過所有測試。 可以使用你需要的任何庫或 API。 賦予它你自己的個人風格。
@@ -8,7 +8,7 @@ dashedName: build-a-markdown-previewer
# --description--
**目標:** 構建一個應用,功能和 <a href="https://codepen.io/freeCodeCamp/full/GrZVVO" target="_blank" rel="noopener noreferrer nofollow">https://codepen.io/freeCodeCamp/full/GrZVVO</a> 類似。
**Objective:** Build an app that is functionally similar to this: <a href="https://markdown-previewer.freecodecamp.rocks/" target="_blank" rel="noopener noreferrer nofollow">https://markdown-previewer.freecodecamp.rocks/</a>.
完成以下需求,並且通過所有測試。 可以使用你需要的任何庫或 API。 賦予它你自己的個人風格。
@@ -8,7 +8,7 @@ dashedName: build-a-random-quote-machine
# --description--
**目標:** 構建一個應用,功能和 <a href="https://codepen.io/freeCodeCamp/full/qRZeGZ" target="_blank" rel="noopener noreferrer nofollow">https://codepen.io/freeCodeCamp/full/qRZeGZ</a> 類似。
**Objective:** Build an app that is functionally similar to this: <a href="https://random-quote-machine.freecodecamp.rocks/" target="_blank" rel="noopener noreferrer nofollow">https://random-quote-machine.freecodecamp.rocks/</a>.
完成以下需求,並且通過所有測試。 可以使用你需要的任何庫或 API。 賦予它你自己的個人風格。
@@ -8,9 +8,9 @@ dashedName: visualize-data-with-a-bar-chart
# --description--
**目標:** 在 [CodePen.io](https://codepen.io) 上實現一個功能類似 <https://codepen.io/freeCodeCamp/full/GrZVaM> 的 App。
**Objective:** Build an app that is functionally similar to this: <a href="https://bar-chart.freecodecamp.rocks" target="_blank" rel="noopener noreferrer nofollow">https://bar-chart.freecodecamp.rocks</a>.
在滿足以下[需求](https://en.wikipedia.org/wiki/User_story)並能通過所有測試的前提下, 你可以根據自己的喜好來美化你的 app。
完成以下需求,並且通過所有測試。 使用你需要的任何庫或 API。 賦予它你自己的個人風格。
你可以使用 HTML、JavaScript、CSS、以及基於 svg 的 D3 可視化庫來完成這個挑戰。 該任務需要使用 D3 的座標軸屬性生成座標軸,這個屬性會自動生成沿軸的刻度。 通過 D3 測試需要這些刻度,因爲它們的位置被用來確定繪製元素的對齊方式。 你可以在這裏 <https://github.com/d3/d3/blob/master/API.md#axes-d3-axis> 獲取關於生成座標軸的信息。 每次測試查詢的元素都必須是非虛擬 DOM。 如果你使用了前端框架(例如 Vue),那麼對於動態的內容測試結果可能不準確。 我們希望最終能夠兼容這些框架,但 D3 項目目前還不支持它們。
@@ -42,7 +42,7 @@ dashedName: visualize-data-with-a-bar-chart
以下是完成此項目所需的數據: `https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/GDP-data.json`
你可以<a href='https://codepen.io/pen?template=MJjpwO' target='_blank' rel='nofollow'>使用 CodePen 模板</a>來創建你的項目,點擊 `Save` 即可創建你的項目。 或者你可以在任何你喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`.
你可以<a href='https://codepen.io/pen?template=MJjpwO' target="_blank" rel="noopener noreferrer nofollow">使用 CodePen 模版</a>創建你的新項目,點擊 `Save` 即可創建你的新項目。 或者你可以在任何你喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`.
當你完成了本項目,並且該項目所有測試運行通過,請提交項目的 URL。
@@ -8,9 +8,9 @@ dashedName: visualize-data-with-a-choropleth-map
# --description--
**目標:** 在 [CodePen.io](https://codepen.io) 上實現一個功能類似 <https://codepen.io/freeCodeCamp/full/EZKqza> 的 App。
**Objective:** Build an app that is functionally similar to this: <a href="https://choropleth-map.freecodecamp.rocks" target="_blank" rel="noopener noreferrer nofollow">https://choropleth-map.freecodecamp.rocks</a>.
在滿足以下[需求](https://en.wikipedia.org/wiki/User_story)並能通過所有測試的前提下, 你可以根據自己的喜好來美化你的 app。
完成以下需求,並且通過所有測試。 你可以使用你需要的任何庫或 API。 賦予它你自己的個人風格。
你可以使用 HTML、JavaScript、CSS、以及基於 svg 的 D3 可視化庫來完成這個挑戰。 每次測試查詢的元素都必須是非虛擬 DOM。 如果你使用了前端框架(例如 Vue),那麼對於動態的內容測試結果可能不準確。 我們希望最終能夠兼容這些框架,但 D3 項目目前還不支持它們。
@@ -41,7 +41,7 @@ dashedName: visualize-data-with-a-choropleth-map
- **US Education Data:** `https://cdn.freecodecamp.org/testable-projects-fcc/data/choropleth_map/for_user_education.json`
- **US County Data:** `https://cdn.freecodecamp.org/testable-projects-fcc/data/choropleth_map/counties.json`
你可以<a href='https://codepen.io/pen?template=MJjpwO' target='_blank' rel='nofollow'>使用 CodePen 模板</a>來創建你的項目,點擊 `Save` 即可創建你的項目。 或者你可以在任何你喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`.
你可以<a href='https://codepen.io/pen?template=MJjpwO' target="_blank" rel="noopener noreferrer nofollow">使用這份 CodePen 模版</a>來創建你的新項目,點擊 `Save` 即可創建屬於你自己的項目。 或者你可以在任何你喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`.
當你完成了本項目,並且該項目所有測試運行通過,請提交項目的 URL。
@@ -8,9 +8,9 @@ dashedName: visualize-data-with-a-heat-map
# --description--
**目標:** 在 [CodePen.io](https://codepen.io) 上實現一個功能類似 <https://codepen.io/freeCodeCamp/full/JEXgeY> 的 App。
**Objective:** Build an app that is functionally similar to this: <a href="https://heat-map.freecodecamp.rocks" target="_blank" rel="noopener noreferrer nofollow">https://heat-map.freecodecamp.rocks</a>.
在滿足以下[需求](https://en.wikipedia.org/wiki/User_story)並能通過所有測試的前提下, 你可以根據自己的喜好來美化你的 app。
完成以下需求,並且通過所有測試。 你可以使用你需要的任何庫或 API。 賦予它你自己的個人風格。
你可以使用 HTML、JavaScript、CSS、以及基於 svg 的 D3 可視化庫來完成這個挑戰。 每次測試查詢的元素都必須是非虛擬 DOM。 如果你使用了前端框架(例如 Vue),那麼對於動態的內容測試結果可能不準確。 我們希望最終能夠兼容這些框架,但 D3 項目目前還不支持它們。
@@ -50,7 +50,7 @@ dashedName: visualize-data-with-a-heat-map
以下是完成此項目所需的數據:`https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/global-temperature.json`
你可以<a href='https://codepen.io/pen?template=MJjpwO' target='_blank' rel='nofollow'>使用這個 CodePen 模板</a>來創建你的項目,點擊 `Save` 即可創建你的項目。 或者你可以在任何你喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`.
你可以<a href='https://codepen.io/pen?template=MJjpwO' target="_blank" rel="noopener noreferrer nofollow">使用 CodePen 模版</a>創建你的新項目,點擊 `Save` 即可創建你的新項目。 或者你可以在任何你喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`.
當你完成了本項目,並且該項目所有測試運行通過,請提交項目的 URL。
@@ -8,9 +8,9 @@ dashedName: visualize-data-with-a-scatterplot-graph
# --description--
**目標:** 在 [CodePen.io](https://codepen.io) 上實現一個功能類似 <https://codepen.io/freeCodeCamp/full/bgpXyK> 的 App。
**Objective:** Build an app that is functionally similar to this: <a href="https://scatterplot-graph.freecodecamp.rocks" target="_blank" rel="noopener noreferrer nofollow">https://scatterplot-graph.freecodecamp.rocks</a>.
在滿足以下[需求](https://en.wikipedia.org/wiki/User_story)並能通過所有測試的前提下, 你可以根據自己的喜好來美化你的 app。
完成以下需求,並且通過所有測試。 你可以使用你需要的任何庫或 API。 賦予它你自己的個人風格。
你可以使用 HTML、JavaScript、CSS、以及基於 svg 的 D3 可視化庫來完成這個挑戰。 該任務需要使用 D3 的座標軸屬性生成座標軸,這個屬性會自動生成沿軸的刻度。 這些刻度是通過 D3 測試所必需的,因爲它們的位置是用來確定圖表元素的對齊方式。 你可以在這裏 <https://github.com/d3/d3/blob/master/API.md#axes-d3-axis> 獲取關於生成座標軸的信息。 每次測試查詢的元素都必須是非虛擬 DOM。 如果你使用了前端框架(例如 Vue),因爲內容是動態渲染的,試結果可能不準確。 我們希望最終能夠兼容這些框架,但 D3 框架目前還不支持它們。
@@ -46,7 +46,7 @@ dashedName: visualize-data-with-a-scatterplot-graph
以下是完成此項目所需的數據:`https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/cyclist-data.json`
你可以<a href='https://codepen.io/pen?template=MJjpwO' target='_blank' rel='nofollow'>使用這個 CodePen 模板</a>來創建你的項目,點擊 `Save` 即可創建你的項目。 或者你可以在任何你喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`.
你可以<a href='https://codepen.io/pen?template=MJjpwO' target="_blank" rel="noopener noreferrer nofollow">使用 CodePen 模版</a>創建你的新項目,點擊 `Save` 即可創建你的新項目。 或者你可以在任何你喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`.
當你完成了本項目,並且項目通過所有測試,請提交項目的 URL。
@@ -8,9 +8,9 @@ dashedName: visualize-data-with-a-treemap-diagram
# --description--
**目標:** 在 [CodePen.io](https://codepen.io) 上實現一個功能類似 <https://codepen.io/freeCodeCamp/full/KaNGNR> 的 App。
**Objective:** Build an app that is functionally similar to this: <a href="https://treemap-diagram.freecodecamp.rocks" target="_blank" rel="noopener noreferrer nofollow">https://treemap-diagram.freecodecamp.rocks</a>.
在滿足以下[需求](https://en.wikipedia.org/wiki/User_story)並能通過所有測試的前提下, 你可以根據自己的喜好來美化你的 app。
完成以下需求,並且通過所有測試。 使用你需要的任何庫或 API。 賦予它你自己的個人風格。
你可以使用 HTML、JavaScript、CSS、以及基於 svg 的 D3 可視化庫來完成這個挑戰。 該任務需要使用 D3 的座標軸屬性生成座標軸,這個屬性會自動生成沿軸的刻度。 這些刻度是通過 D3 測試所必需的,因爲它們的位置是用來確定圖表元素的對齊方式。 你可以在這裏 <https://github.com/d3/d3/blob/master/API.md#axes-d3-axis> 獲取關於生成座標軸的信息。 每次測試查詢的元素都必須是非虛擬 DOM。 如果你使用了前端框架(例如 Vue),那麼對於動態的內容測試結果可能不準確。 我們希望最終能夠兼容這些框架,但 D3 項目目前還不支持它們。
@@ -42,7 +42,7 @@ dashedName: visualize-data-with-a-treemap-diagram
- **Movie Sales:** `https://cdn.freecodecamp.org/testable-projects-fcc/data/tree_map/movie-data.json`
- **Video Game Sales:** `https://cdn.freecodecamp.org/testable-projects-fcc/data/tree_map/video-game-sales-data.json`
你可以<a href='https://codepen.io/pen?template=MJjpwO' target='_blank' rel='nofollow'>使用 CodePen 模板</a>來創建你的項目,點擊 `Save` 即可創建你的項目。 或者你可以在任何你喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`.
你可以<a href='https://codepen.io/pen?template=MJjpwO' target="_blank" rel="noopener noreferrer nofollow">使用 CodePen 模版</a>創建你的新項目,點擊 `Save` 即可創建你的新項目。 或者你可以在任何你喜歡的環境中使用以下 CDN 鏈接來運行測試:`https://cdn.freecodecamp.org/testable-projects-fcc/v1/bundle.js`.
當你完成了本項目,並且該項目所有測試運行通過,請提交項目的 URL。
@@ -10,9 +10,9 @@ dashedName: create-a-model
**C** RUD 第一小節——CREATE
首先,我們需要一個 Schema, 每一個 Schema 都對應一個 MongoDB 的 collection, 並且在相應的 collection 裏定義 documents 的“樣子”。 Schema 用於組成模型(Model), 我們甚至可以通過嵌套 Schema 來創建複雜的模型。目前我們先從簡。 我們可以根據模型創建實例,模型實例化後的對象稱爲 documents。
First of all, we need a Schema. 每一個 Schema 都對應一個 MongoDB 的 collection, 並且在相應的 collection 裏定義 documents 的“樣子”。 Schemas are building blocks for Models. They can be nested to create complex models, but in this case, we'll keep things simple. 我們可以根據模型創建實例,模型實例化後的對象稱爲 documents。
Replit 是一個真實的服務器,在其中,通過 handler 函數和數據庫交互。 這些函數會在特定事件(比如有人調用了我們的服務器 API)發生時執行。 接下來的挑戰題目即是以此爲基礎。 `done()` 是一個回調函數,它的作用是在一個異步操作(比如對數據庫進行插入、查詢、更新或刪除)執行完成時,通知我們可以繼續執行後續的其它代碼。 這與 Node.js 中的處理方式十分類似,在 Node.js 中,我們會在(異步操作)成功時調用 `done(null, data)`,在失敗時調用 `done(err)`。
Replit is a real server, and in real servers, the interactions with the database happen in handler functions. 這些函數會在特定事件(比如有人調用了我們的服務器 API)發生時執行。 接下來的挑戰題目即是以此爲基礎。 `done()` 是一個回調函數,它的作用是在一個異步操作(比如對數據庫進行插入、查詢、更新或刪除)執行完成時,通知我們可以繼續執行後續的其它代碼。 這與 Node.js 中的處理方式十分類似,在 Node.js 中,我們會在(異步操作)成功時調用 `done(null, data)`,在失敗時調用 `done(err)`。
注意:與遠程服務器進行交互時,我們需要考慮到發生錯誤的可能!
@@ -38,7 +38,7 @@ age : number
favoriteFoods : array of strings (*)
```
採用 Mongoose 基礎 schema 類型。 你如果還想添加更多的鍵,就請使用 required 或 unique 等簡單的驗證器(validators),並設置默認值。 詳情請參考 [Mongoose 文檔](http://mongoosejs.com/docs/guide.html)。
採用 Mongoose 基礎 schema 類型。 你如果還想添加更多的鍵,就請使用 required 或 unique 等簡單的驗證器(validators),並設置默認值。 查看我們的 <a href="https://www.freecodecamp.org/news/introduction-to-mongoose-for-mongodb-d2a7aa593c57/" target="_blank" rel="noopener noreferrer nofollow">Mongoose 文章</a>。
請從 `personSchema` 創建一個名爲 `Person` 的 model。
@@ -8,9 +8,9 @@ dashedName: authentication-strategies
# --description--
策略是認證用戶的一種方式。 如果你讓用戶在註冊時填寫了用戶信息,那你就可以基於這些信息進行驗證。或者也可以引入第三方登錄,如 Google 或者 Github。 對於這個項目的驗證策略,我們會採用自己搭建的方式完成。 可以[點擊這裏](http://passportjs.org/)訪問 Passport 網站,查看數以百計的策略。
策略是認證用戶的一種方式。 如果你讓用戶在註冊時填寫了用戶信息,那你就可以基於這些信息進行驗證。或者也可以引入第三方登錄,如 Google 或者 Github。 在這個項目中,我們將使用 Passport 中間件。 Passport 提供了一套全面的策略,支持使用用戶名和密碼、GitHub、谷歌等進行認證。
引入 `passport-local@~1.0.0` 作爲依賴,然後將它添加到服務器,就像這樣:`const LocalStrategy = require('passport-local');`
`passport-local@~1.0.0` has already been added as a dependency, so add it to your server as follows: `const LocalStrategy = require('passport-local');`
然後,需要讓 passport **使用**一個實例化的 LocalStrategy 對象,這個對象的一些設置已完成。 請注意,接下來的所有代碼都應寫在連接數據庫的回調中,因爲它們的執行都依賴數據庫。
@@ -34,7 +34,7 @@ passport.use(new LocalStrategy(
在下一個挑戰中,我們會基於表單數據調用上面寫好的驗證策略。
完成上述要求後,請提交你的頁面鏈接。 如果你遇到任何問題,可以參考[這裏](https://gist.github.com/camperbot/53b495c02b92adeee0aa1bd3f3be8a4b)的答案。
完成上述要求後,請提交你的頁面鏈接。 如果你在運行時遇到錯誤,可以點擊此處查看<a href="https://gist.github.com/camperbot/53b495c02b92adeee0aa1bd3f3be8a4b" target="_blank" rel="noopener noreferrer nofollow">已執行項目的當前進度</a>。
# --hints--
@@ -10,7 +10,7 @@ dashedName: authentication-with-socket-io
目前,你還無法確定連接到服務器的用戶身份。 雖然 `req.user` 包含用戶信息,但這個只在用戶直接與服務器交互時產生。當用戶通過 web socket 與服務器連接時,由於不存在 `req` 對象,我們就無法獲取用戶數據。 解決這個問題的方法之一是通過讀取和解析請求中包含 passport session 的 cookie,然後反序列化,進而獲取用戶信息對象。 幸運的是,NPM 上有可以讓這個複雜的流程簡單化的庫。
添加 `passport.socketio@~3.7.0`、`connect-mongo@~3.2.0`、`cookie-parser@~1.4.5` 作爲依賴,把它們分別賦值給 `passportSocketIo`、`MongoStore`、`cookieParser`。 同時,我們需要從之前引入的 `express-session` 中開闢新的內存空間, 就像這樣:
`passport.socketio@~3.7.0`, `connect-mongo@~3.2.0`, and `cookie-parser@~1.4.5` have already been added as dependencies. Require them as `passportSocketIo`, `MongoStore`, and `cookieParser` respectively. Also, we need to initialize a new memory store, from `express-session` which we previously required. It should look like this:
```js
const MongoStore = require('connect-mongo')(session);
@@ -65,7 +65,7 @@ console.log('user ' + socket.request.user.name + ' connected');
它將在服務器控制檯記錄已連接的用戶!
完成以上要求後,請提交你的頁面鏈接。 如果你遇到了問題,可以參考[這裏](https://gist.github.com/camperbot/1414cc9433044e306dd7fd0caa1c6254)的答案。
完成以上要求後,請提交你的頁面鏈接。 If you're running into errors, you can check out the project up to this point <a href="https://gist.github.com/camperbot/1414cc9433044e306dd7fd0caa1c6254" target="_blank" rel="noopener noreferrer nofollow">https://gist.github.com/camperbot/1414cc9433044e306dd7fd0caa1c6254</a>.
# --hints--
@@ -26,7 +26,7 @@ module.exports = function (app, myDataBase) {
現在,我們來把 server.js 中與驗證相關的代碼分離到 auth.js 中,例如序列化,設置驗證策略等。 請正確添加依賴,並在 server.js 中調用 `auth(app, myDataBase)`。
完成上述要求後,請提交你的頁面鏈接。 如果你遇到了問題,可以參考[這裏](https://gist.github.com/camperbot/2d06ac5c7d850d8cf073d2c2c794cc92)的答案。
完成上述要求後,請提交你的頁面鏈接。 If you're running into errors, you can <a href="https://gist.github.com/camperbot/2d06ac5c7d850d8cf073d2c2c794cc92" target="_blank" rel="noopener noreferrer nofollow">check out an example of the completed project</a>.
# --hints--
@@ -38,7 +38,7 @@ socket.on('user count', function(data) {
現在你可以嘗試啓動你的 app 並登錄,你會看到在客戶端的控制檯打印出了 “1”,這就表示目前連接到服務器的用戶數爲 1。 你可以試着通過打開多個 app 來驗證數量是否會增加。
完成上述要求後,請提交你的頁面鏈接。 如果你遇到了問題,可以參考[這裏](https://gist.github.com/camperbot/28ef7f1078f56eb48c7b1aeea35ba1f5)的答案。
完成上述要求後,請提交你的頁面鏈接。 If you're running into errors, you can <a href="https://gist.github.com/camperbot/28ef7f1078f56eb48c7b1aeea35ba1f5" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
# --hints--
@@ -31,7 +31,7 @@ app
});
```
完成上述要求後,請提交你的頁面鏈接。 如果你遇到了問題,可以參考[這裏](https://gist.github.com/camperbot/ae49b8778cab87e93284a91343da0959)的答案。
完成上述要求後,請提交你的頁面鏈接。 If you're running into errors, you can <a href="https://gist.github.com/camperbot/ae49b8778cab87e93284a91343da0959" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
# --hints--
@@ -22,7 +22,7 @@ socket.on('disconnect', () => {
**注意:**和 `'disconnect'` 類似,所有 socket 可以發送到服務器的事件,我們都應該在有 “socket” 定義的連接監聽器裏處理。
完成上述要求後,請提交你的頁面鏈接。 如果你遇到了問題,可以參考[這裏](https://gist.github.com/camperbot/ab1007b76069884fb45b215d3c4496fa)的答案。
完成上述要求後,請提交你的頁面鏈接。 If you're running into errors, you can <a href="https://gist.github.com/camperbot/ab1007b76069884fb45b215d3c4496fa" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
# --hints--
@@ -10,7 +10,7 @@ dashedName: hashing-your-passwords
回過頭來看信息安全,你也許記得在數據庫中存儲明文密碼是*絕對*禁止的。 現在,我們需要引入 BCrypt 來解決這個問題。
添加 `bcrypt@~5.0.0` 作爲依賴,並在服務端使用它。 你需要在兩個步驟中使用哈希運算:註冊和保存新賬戶,以及登錄時檢查密碼是否正確。
`bcrypt@~5.0.0` has already been added as a dependency, so require it in your server. 你需要在兩個步驟中使用哈希運算:註冊和保存新賬戶,以及登錄時檢查密碼是否正確。
目前處理註冊的路由中,我們是這樣把密碼添加到數據庫的:`password: req.body.password`。 保存哈希值的一個簡單方式是在數據庫邏輯中添加 `const hash = bcrypt.hashSync(req.body.password, 12);`,然後把 `req.body.password` 替換爲 `password: hash`。
@@ -24,7 +24,7 @@ if (!bcrypt.compareSync(password, user.password)) {
當你需要存儲密碼時,這樣做可以有效地提升網站的安全性。
完成上述要求後,請提交你的頁面鏈接。 如果你遇到了問題,可以參考[這裏](https://gist.github.com/camperbot/dc16cca09daea4d4151a9c36a1fab564)的答案。
完成上述要求後,請提交你的頁面鏈接。 If you're running into errors, you can <a href="https://gist.github.com/camperbot/dc16cca09daea4d4151a9c36a1fab564" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
# --hints--
@@ -24,7 +24,7 @@ h2.center#welcome Welcome, #{username}!
a(href='/logout') Logout
```
完成上述要求後,請提交你的頁面鏈接。 如果你遇到了問題,可以參考[這裏](https://gist.github.com/camperbot/136b3ad611cc80b41cab6f74bb460f6a)的答案。
完成上述要求後,請提交你的頁面鏈接。 If you're running into errors, you can <a href="https://gist.github.com/camperbot/136b3ad611cc80b41cab6f74bb460f6a" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
# --hints--
@@ -18,7 +18,7 @@ dashedName: how-to-use-passport-strategies
這時,由於我們還沒有實現註冊功能,如果你在表單裏輸入了用戶名和密碼,路由將會重定向到主頁 `/`,在服務端將會打印 `'User {USERNAME} attempted to log in.'`。
完成上述要求後,請提交你的頁面鏈接。 如果你遇到了問題,可以參考[這裏](https://gist.github.com/camperbot/7ad011ac54612ad53188b500c5e99cb9)的答案。
完成上述要求後,請提交你的頁面鏈接。 If you're running into errors, you can <a href="https://gist.github.com/camperbot/7ad011ac54612ad53188b500c5e99cb9" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
# --hints--
@@ -10,7 +10,7 @@ dashedName: implement-the-serialization-of-a-passport-user
截至目前,我們還沒有配置完數據庫,因此還無法加載用戶數據。 實現這個的方式很多,但對於我們的項目,一旦服務器啓動,那麼只要有 app 實例在運行,數據庫就應一直處於連接狀態。 爲此,你需要在環境變量 `MONGO_URI` 中添加你的數據庫地址(比如:`mongodb+srv://:@cluster0-jvwxi.mongodb.net/?retryWrites=true&w=majority`)。 我們會在 `connection.js` 文件中調用它。
*你可以在 [MongoDB Atlas](https://www.mongodb.com/cloud/atlas) 創建一個免費的數據庫。*
*If you are having issues setting up a free database on MongoDB Atlas, check out <a href="https://www.freecodecamp.org/news/get-started-with-mongodb-atlas/" target="_blank" rel="noopener noreferrer nofollow">tutorial</a>.*
現在我們想要連接到數據庫,然後開始監聽請求。 這樣做的目的是在連接數據庫之前或者出現數據庫錯誤時,不接收任何請求。 要實現這一點,你需要在以下代碼中包含序列化和應用的路由:
@@ -40,7 +40,7 @@ myDB(async client => {
記得要取消 `deserializeUser` 中 `myDataBase` 的註釋,並把 `doc` 添加到 `done(null, null)`。
完成上述要求後,請提交你的頁面鏈接。 如果你遇到了問題,可以參考[這裏](https://gist.github.com/camperbot/175f2f585a2d8034044c7e8857d5add7)的答案。
完成上述要求後,請提交你的頁面鏈接。 If you're running into errors, you can <a href="https://gist.github.com/camperbot/175f2f585a2d8034044c7e8857d5add7" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
# --hints--
@@ -8,11 +8,13 @@ dashedName: implementation-of-social-authentication-ii
# --description--
設置 GitHub 驗證的最後一步是創建策略本身。 爲此,你需要在項目中添加 `passport-github@~1.1.0` 依賴,並在 `auth.js` 中請求它,作爲 `GithubStrategy`,像這樣:`const GitHubStrategy = require('passport-github').Strategy;`。 別忘了請求和配置 `dotenv`,使用你的環境變量。
設置 GitHub 驗證的最後一步是創建策略本身。 `passport-github@~1.1.0` has already been added as a dependency, so require it in your `auth.js` file as `GithubStrategy` like this: `const GitHubStrategy = require('passport-github').Strategy;`. 別忘了請求和配置 `dotenv`,使用你的環境變量。
爲了設置 GitHub 策略,我們需要在 Passport 中使用實例化的 `GitHubStrategy`,它可以接收兩個參數:一個對象(包括 `clientID`、`clientSecret` 和 `callbackURL`),以及一個回調函數。在這個回調函數中,我們要處理驗證成功時,判斷用戶是否已經在數據庫中存在的邏輯,以及在用戶數據庫對象中最初保存哪些字段。 這種處理方式適用於絕大部分第三方驗證策略,但有些策略會需要我們提供更多的信息,詳情請參考相關策略的 GitHub README。 例如,Google 的驗證策略會要求你提供一個 *scope*,用於標示用戶成功登錄後,你需要從返回的對象中獲取那些信息。以及,這也需要經過用戶同意,你纔可以獲取到。 你可以在[這裏](https://github.com/jaredhanson/passport-github/)瞭解當前我們使用的驗證策略的用法,不過我們也會在 freeCodeCamp 課程中進行詳細講解。
爲了設置 GitHub 策略,我們需要在 Passport 中使用實例化的 `GitHubStrategy`,它可以接收兩個參數:一個對象(包括 `clientID`、`clientSecret` 和 `callbackURL`),以及一個回調函數。在這個回調函數中,我們要處理驗證成功時,判斷用戶是否已經在數據庫中存在的邏輯,以及在用戶數據庫對象中最初保存哪些字段。 這種處理方式適用於絕大部分第三方驗證策略,但有些策略會需要我們提供更多的信息,詳情請參考相關策略的 GitHub README。 例如,Google 的驗證策略會要求你提供一個 *scope*,用於標示用戶成功登錄後,你需要從返回的對象中獲取那些信息。以及,這也需要經過用戶同意,你纔可以獲取到。
你的新策略應該這樣去實現:
The current strategy we are implementing authenticates users using a GitHub account and OAuth 2.0 tokens. The client ID and secret obtained when creating an application are supplied as options when creating the strategy. The strategy also requires a `verify` callback, which receives the access token and optional refresh token, as well as `profile` which contains the authenticated user's GitHub profile. The `verify` callback must call `cb` providing a user to complete authentication.
Here's how your new strategy should look at this point:
```js
passport.use(new GitHubStrategy({
@@ -27,13 +29,13 @@ passport.use(new GitHubStrategy({
));
```
目前,你的驗證部分不會成功。由於沒有數據庫的邏輯和回調函數,你的代碼目前還會報錯。但如果你試一試,就可以在控制檯裏看到輸出了你的 GitHub 個人信息。
Your authentication won't be successful yet, and it will actually throw an error without the database logic and callback, but it should log your GitHub profile to your console if you try it!
完成上述要求後,請提交你的頁面鏈接。 如果你遇到了問題,可以參考[這裏](https://gist.github.com/camperbot/ff3a1166684c1b184709ac0bee30dee6)的答案。
Submit your page when you think you've got it right. If you're running into errors, you can <a href="https://gist.github.com/camperbot/ff3a1166684c1b184709ac0bee30dee6" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
# --hints--
應正確添加依賴 passport-github。
passport-github dependency should be added.
```js
(getUserInput) =>
@@ -52,7 +54,7 @@ passport.use(new GitHubStrategy({
);
```
應正確請求依賴 passport-github。
passport-github should be required.
```js
(getUserInput) =>
@@ -70,7 +72,7 @@ passport.use(new GitHubStrategy({
);
```
到目前爲止,Github 策略應正確設置。
GitHub strategy should be setup correctly thus far.
```js
(getUserInput) =>
@@ -42,7 +42,7 @@ myDataBase.findOneAndUpdate(
你現在應該可以登錄你的應用了,試試吧。
完成上述要求後,你可以在下方提交你的頁面鏈接。 如果你遇到了問題,可以參考 [這裏](https://gist.github.com/camperbot/183e968f0e01d81dde015d45ba9d2745) 的答案。
完成上述要求後,你可以在下方提交你的頁面鏈接。 If you're running into errors, you can <a href="https://gist.github.com/camperbot/183e968f0e01d81dde015d45ba9d2745" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
# --hints--
@@ -18,7 +18,7 @@ dashedName: implementation-of-social-authentication
在 OAuth 驗證策略中,我們至少需要提供 *Client ID* 和 *Client Secret*,這樣第三方平臺就會獲悉驗證請求的來源,以及這個來源是否有效。 爲此,需要去我們使用的第三方驗證平臺(比如 GitHub)獲取這兩個字段的值。 注意,我們獲取到的這個值是唯一的,僅對我們的當前 app 有效——**因此,千萬不要分享給別人**,更不要上傳到公共倉庫或者直接寫在代碼裏。 通常,我們會把它們放在 `.env` 文件裏,並通過 `process.env.GITHUB_CLIENT_ID` 獲取。 對於這次挑戰,我們將會使用 GitHub 作爲驗證平臺。
首先,你需要進入賬戶設置裏的 “developer settings(開發者設置)”板塊,在 '[OAuth applications](https://github.com/settings/developers)' 獲取 *Client ID and Secret*。 點擊 “Register a new application(註冊一個新的應用)”,設置你的應用名稱,然後把你的 Replit 主頁地址(**不是項目代碼的 url**)粘貼到 Homepage URL。然後,回調 url 需要設置成上面 Homepage URL 裏你粘貼的地址,但後面要加上 `/auth/github/callback`。 這樣在用戶通過 Github 驗證後才能跳轉到我們指定的頁面。 在你的 `.env` 文件裏將返回的信息保存爲 `'GITHUB_CLIENT_ID'` 和 `'GITHUB_CLIENT_SECRET'`。
Obtaining your *Client ID and Secret* from GitHub is done in your account profile settings under 'developer settings', then <a href="https://github.com/settings/developers" target="_blank" rel="noopener noreferrer nofollow">'OAuth applications'</a>. 點擊 “Register a new application(註冊一個新的應用)”,設置你的應用名稱,然後把你的 Replit 主頁地址(**不是項目代碼的 url**)粘貼到 Homepage URL。然後,回調 url 需要設置成上面 Homepage URL 裏你粘貼的地址,但後面要加上 `/auth/github/callback`。 這樣在用戶通過 Github 驗證後才能跳轉到我們指定的頁面。 在你的 `.env` 文件裏將返回的信息保存爲 `'GITHUB_CLIENT_ID'` 和 `'GITHUB_CLIENT_SECRET'`。
在你的 `routes.js` 文件中,添加 `showSocialAuth: true` 到主頁路由,在 `showRegistration: true` 的後面。 然後,爲 `/auth/github` 和 `/auth/github/callback` 創建兩個接收 GET 請求的路由。 第一個只需要通過調用 passport 來驗證 `'github'`。 第二個應該調用 passport 來驗證 `'github'`,但需要在失敗時跳轉回主頁 `/`,成功時跳轉到用戶頁面 `/profile`(跳轉的邏輯與上一個項目中的邏輯一樣)。
@@ -31,7 +31,7 @@ app.route('/login')
});
```
完成上述要求後,請提交你的頁面鏈接。 如果你遇到了問題,可以參考[這裏](https://gist.github.com/camperbot/1f7f6f76adb178680246989612bea21e)的答案。
完成上述要求後,請提交你的頁面鏈接。 If you're running into errors, you can check out the project up to this point <a href="https://gist.github.com/camperbot/1f7f6f76adb178680246989612bea21e" target="_blank" rel="noopener noreferrer nofollow">https://gist.github.com/camperbot/1f7f6f76adb178680246989612bea21e</a>.
# --hints--
@@ -30,11 +30,11 @@ app.use((req, res, next) => {
});
```
完成上述要求後,請提交你的頁面鏈接。 如果你遇到了問題,可以參考[這裏](https://gist.github.com/camperbot/c3eeb8a3ebf855e021fd0c044095a23b)的答案。
完成上述要求後,請提交你的頁面鏈接。 If you're running into errors, you can <a href="https://gist.github.com/camperbot/c3eeb8a3ebf855e021fd0c044095a23b" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
# --hints--
`req.Logout` 應在 `/logout` 路由中調用。
`req.logout()` should be called in your `/logout` route.
```js
(getUserInput) =>
@@ -47,7 +47,7 @@ app.route('/register')
);
```
完成上述要求後,請提交你的頁面鏈接。 如果你遇到了問題,可以參考[這裏](https://gist.github.com/camperbot/b230a5b3bbc89b1fa0ce32a2aa7b083e)的答案。
完成上述要求後,請提交你的頁面鏈接。 If you're running into errors, you can <a href="https://gist.github.com/camperbot/b230a5b3bbc89b1fa0ce32a2aa7b083e" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
**注意:**接下來的挑戰可能會在運行 *picture-in-picture*(畫中畫)模式的瀏覽器中出現問題。 如果你使用的線上 IDE 提供在 IDE 內預覽 app 的功能,請考慮打開新的標籤頁預覽。
@@ -28,7 +28,7 @@ socket.emit('chat message', messageToSend);
至此,我們已經完成發送信息到所有客戶端的功能。
完成上述要求後,請提交你的頁面鏈接。 如果你遇到了問題,可以參考[這裏](https://gist.github.com/camperbot/d7af9864375207e254f73262976d2016)的答案。
完成上述要求後,請提交你的頁面鏈接。 If you're running into errors, you can <a href="https://gist.github.com/camperbot/d7af9864375207e254f73262976d2016" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
# --hints--
@@ -12,7 +12,7 @@ dashedName: serialization-of-a-user-object
我們需要用到序列化和反序列化的方法來進行配置。 passport 爲我們提供了 `passport.serializeUser( OURFUNCTION )` 和 `passport.deserializeUser( OURFUNCTION )` 兩個方法。
`serializeUser` 方法接收兩個參數,分別是表示用戶的對象和一個回調函數。 其中,回調函數的返回值應爲這個用戶的唯一標識符:最簡單的寫法就是讓它返回用戶的 `_id`。 它應當是唯一的,是由 MongoDB 產生的。 類似地,`deserializeUser` 也接收兩個參數,分別是在序列化時生成的標識符以及一個回調函數。在回調函數裏,我們需要根據根據傳入的標識符(比如 \_id)返回表示用戶的對象。 爲了在 MongoDB 中通過 query(查詢語句)獲取 `_id` 字段,首先我們需要創建 `const ObjectID = require('mongodb').ObjectID;`;然後調用它:`new ObjectID(THE_ID)`。 確保添加 `mongodb@~3.6.0` 作爲依賴項。 你可以在下面的例子中看到:
`serializeUser` 方法接收兩個參數,分別是表示用戶的對象和一個回調函數。 其中,回調函數的返回值應爲這個用戶的唯一標識符:最簡單的寫法就是讓它返回用戶的 `_id`。 它應當是唯一的,是由 MongoDB 產生的。 類似地,`deserializeUser` 也接收兩個參數,分別是在序列化時生成的標識符以及一個回調函數。在回調函數裏,我們需要根據根據傳入的標識符(比如 \_id)返回表示用戶的對象。 爲了在 MongoDB 中通過 query(查詢語句)獲取 `_id` 字段,首先我們需要創建 `const ObjectID = require('mongodb').ObjectID;`;然後調用它:`new ObjectID(THE_ID)`。 `mongodb@~3.6.0` has already been added as a dependency. 你可以在下面的例子中看到:
```js
passport.serializeUser((user, done) => {
@@ -28,7 +28,7 @@ passport.deserializeUser((id, done) => {
因此,在我們在下一步中配置 DB 前,`deserializeUser` 會拋出錯誤。所以,現在請先註釋掉上面的代碼,在 `deserializeUser` 中僅調用 `done(null, null)` 即可。
完成上述要求後,請提交你的頁面鏈接。 如果你遇到了問題,可以參考 [這裏](https://gist.github.com/camperbot/7068a0d09e61ec7424572b366751f048) 的答案。
完成上述要求後,請提交你的頁面鏈接。 If you're running into errors, you can <a href="https://gist.github.com/camperbot/7068a0d09e61ec7424572b366751f048" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
# --hints--
@@ -10,25 +10,25 @@ dashedName: set-up-a-template-engine
你可以採用下面的任意一種方式完成這些挑戰:
- 克隆[這個 GitHub 倉庫](https://github.com/freeCodeCamp/boilerplate-advancednode/),在本地完成這些挑戰。
- 使用[我們的 Replit 上的初始化項目](https://replit.com/github/freeCodeCamp/boilerplate-advancednode)來完成項目。
- Clone <a href="https://github.com/freeCodeCamp/boilerplate-advancednode/" target="_blank" rel="noopener noreferrer nofollow">this GitHub repo</a> and complete these challenges locally.
- Use <a href="https://replit.com/github/freeCodeCamp/boilerplate-advancednode" target="_blank" rel="noopener noreferrer nofollow">our Replit starter project</a> to complete these challenges.
- 使用一個你選擇的站點生成器來完成項目。 需要確定包含了我們 GitHub 倉庫的所有文件。
完成本項目後,請將一個正常運行的 demo(項目演示)託管在可以公開訪問的平臺。 然後在 `Solution Link` 框中提交你的項目 URL。
你可以在應用的模版引擎中使用靜態模板文件(如那些寫在 *Pug* 裏的)。 在運行時,模版引擎會用服務端的真實數據替換掉模版文件中的變量, 然後將模版轉譯成發送給客戶端的 HTML 靜態文件。 這樣可以輕鬆地構造 HTML 頁面,允許在頁面直接顯示變量內容而不需要從客戶端發送 API 請求。
在 `package.json` 文件中添加依賴 `pug@~3.0.0`。
`pug@~3.0.0` has already been installed, and is listed as a dependency in your `package.json` file.
Express 需要知道你正在使用哪個模板引擎。 我們將使用 `set` 方法來分配 `pug` 作爲 `view engine` 屬性的值: `app.set('view engine', 'pug')`。
在正確渲染 `views/pug` 目錄中的索引文件之後,加載頁面。
Your page will be blank until you correctly render the index file in the `views/pug` directory.
修改 `/` 路由中 `res.render()` 聲明的參數爲 `views/pug` 目錄的文件路徑。 這個路徑可以是相對路徑(相對於 views),也可以是絕對路徑,不需要文件擴展。
To render the `pug` template, you need to use `res.render()` in the `/` route. Pass the file path to the `views/pug` directory as the argument to the method. The path can be a relative path (relative to views), or an absolute path, and does not require a file extension.
如果一切順利,那麼你的應用主頁不會再顯示信息 “`Pug template is not defined.`”,而是會顯示一個信息表明你已經成功渲染 Pug 模版!
If all went as planned, your app home page will no longer be blank and will display a message indicating you've successfully rendered the Pug template!
完成以上要求後,請提交你的頁面鏈接。 如果你遇到問題,可以查看[這裏](https://gist.github.com/camperbot/3515cd676ea4dfceab4e322f59a37791)的答案。
完成以上要求後,請提交你的頁面鏈接。 If you're running into errors, you can <a href="https://gist.github.com/camperbot/3515cd676ea4dfceab4e322f59a37791" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
# --hints--
@@ -8,15 +8,13 @@ dashedName: set-up-passport
# --description--
現在我們來創建 *Passport*,最終我們需要用它來實現用戶註冊和登錄。 除了 Passport,我們還會用 Express-session 來處理 session(會話)。 在客戶端,我們可以用這個中間件把 session id 儲存到 cookie。同時,我們可以在服務器上通過這個 id 訪問 session 數據。 通過這種方式,我們無需把用戶的個人賬號信息存到 cookie,來完成用戶的驗證。只需要用這個 id 作爲 *key* 來訪問服務器上用戶的數據即可。
現在我們來創建 *Passport*,最終我們需要用它來實現用戶註冊和登錄。 除了 Passport,我們還會用 Express-session 來處理 session(會話)。 Express-session has a ton of advanced features you can use, but for now we're just going to use the basics! Using this middleware saves the session id as a cookie in the client and allows us to access the session data using that id on the server. This way we keep personal account information out of the cookie used by the client to verify to our server they are authenticated and just keep the *key* to access the data stored on the server.
爲了在你的項目中使用 Passport,首先你需要在 package.json 文件中添加依賴: `passport@~0.4.1`
`passport@~0.4.1` and `express-session@~1.17.1` are already installed, and are both listed as dependencies in your `package.json` file.
此外,還需要添加 Express-session 作爲依賴。 Express-session 有許多高級特性,但我們暫時只需要瞭解其基礎功能。 `express-session@~1.17.1`
You will need to set up the session settings now and initialize Passport. Be sure to first create the variables 'session' and 'passport' to require 'express-session' and 'passport' respectively.
現在,我們需要配置 session 並初始化 Passport。 請先創建變量 “session” 和 “passport” 來分別引入 “express-session” 和 “passport”。
爲了讓 express 應用可以使用 session,我們需要添加一些基礎選項。 請在 .env 文件中添加字段 “SESSION_SECRET”,並給它賦一個隨機值, 便於加密 cookie、計算哈希。
To set up your express app to use the session we'll define just a few basic options. Be sure to add 'SESSION_SECRET' to your .env file and give it a random value. This is used to compute the hash used to encrypt your cookie!
```js
app.use(session({
@@ -27,13 +25,13 @@ app.use(session({
}));
```
還有,我們需要讓 express **使用** “passport.initialize()” 和 “passport.session()”。 (例如,`app.use(passport.initialize());`)。
As well you can go ahead and tell your express app to **use** 'passport.initialize()' and 'passport.session()'. (For example, `app.use(passport.initialize());`)
完成上述要求後,請提交你的頁面鏈接。 如果你遇到了問題,可以參考[這裏](https://gist.github.com/camperbot/4068a7662a2f9f5d5011074397d6788c)的答案。
Submit your page when you think you've got it right. If you're running into errors, you can <a href="https://gist.github.com/camperbot/4068a7662a2f9f5d5011074397d6788c" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
# --hints--
應添加 Passort 和 express-session 作爲依賴。
Passport and Express-session should be dependencies.
```js
(getUserInput) =>
@@ -57,7 +55,7 @@ app.use(session({
);
```
依賴應正確引入。
Dependencies should be correctly required.
```js
(getUserInput) =>
@@ -80,7 +78,7 @@ app.use(session({
);
```
Express app 可以使用新的依賴。
Express app should use new dependencies.
```js
(getUserInput) =>
@@ -103,7 +101,7 @@ Express app 可以使用新的依賴。
);
```
應正確設置 session 和 session secret。
Session and session secret should be correctly set up.
```js
(getUserInput) =>
@@ -10,7 +10,7 @@ dashedName: set-up-the-environment
在接下來的挑戰中,我們將會用到 `chat.pug` 文件。 首先,在你的 `routes.js` 文件中爲 `/chat` 添加一個處理 GET 請求的路由,並給它傳入 `ensureAuthenticated`。在回調函數中,我們需要讓它渲染 `chat.pug` 文件,並在響應中包含 `{ user: req.user }` 信息。 現在,請修改 `/auth/github/callback` 路由,讓它可以像這樣設置 user_id:`req.session.user_id = req.user.id`,並在設置完成後重定向至 `/chat`。
添加 `socket.io@~2.3.0` 作爲依賴項,並且在你的服務器中和 `http` (內置在 Nodejs 中)一起導入/實例化。具體如下:
`socket.io@~2.3.0` has already been added as a dependency, so require/instantiate it in your server as follows with `http` (comes built-in with Nodejs):
```javascript
const http = require('http').createServer(app);
@@ -19,7 +19,7 @@ const io = require('socket.io')(http);
現在我們的 *express 應用*已經包含了 *http* 服務,接下來我們需要監聽 *http* 服務的事件。 爲此,我們需要把 `app.listen` 更新爲 `http.listen`。
需要處理的第一件事是監聽客戶端的新連接。 <dfn>on</dfn> 關鍵字就是監聽這個特定事件。 它需要 2 個參數:一個包含所發出事件標題的字符串,以及一個用於傳遞數據的函數。 在連接監聽器中,我們用 *socket* 來代表它所包含的數據。 socket 就是指已連接到服務器的客戶端。
需要處理的第一件事是監聽客戶端的新連接。 <dfn>on</dfn> 關鍵字就是監聽這個特定事件。 It requires 2 arguments: a string containing the title of the event that's emitted, and a function with which the data is passed through. 在連接監聽器中,我們用 *socket* 來代表它所包含的數據。 socket 就是指已連接到服務器的客戶端。
爲了可以監聽服務器的連接事件,我們在數據庫連接的部分加入如下代碼:
@@ -42,7 +42,7 @@ let socket = io();
**注意:**只有在連接到處於同一個 url/server 上的 socket 時,`io()`纔可以正常執行。 如果需要連接到外部的 socket,就需要這樣調用:`io.connect('URL');`。
完成上述要求後,請提交你的頁面鏈接。 如果你遇到了問題,可以參考[這裏](https://gist.github.com/camperbot/aae41cf59debc1a4755c9a00ee3859d1)的答案。
完成上述要求後,請提交你的頁面鏈接。 If you're running into errors, you can <a href="https://gist.github.com/camperbot/aae41cf59debc1a4755c9a00ee3859d1" target="_blank" rel="noopener noreferrer nofollow">check out the project completed up to this point</a>.
# --hints--
@@ -12,19 +12,43 @@ dashedName: use-a-template-engines-powers
在 Pug 文件中,你可以用變量名來調用變量,比如寫成 `#{variable_name}` 來實現行內調用,或像 `p=variable_name` 把元素與變量直接寫在一起,這表示 p 元素的內容等價於這個變量。
建議大家在 [Pug 的 README](https://github.com/pugjs/pug) 裏看看它的語法和用法,這樣你寫出的代碼會相對簡練。 另外要注意,Pug 使用縮進來表示嵌套的代碼塊。
Pug is all about using whitespace and tabs to show nested elements and cutting down on the amount of code needed to make a beautiful site. Read the Pug documentation for more information on usage and syntax.
在 pug 的 'index.pug' 文件中,我們使用了 *title* 和 *message* 兩個變量。
Here is an example:
爲了從服務器傳遞這些信息,你需要給 *res.render* 的第二個參數傳入一個對象,其中包含變量對應的值。 比如,如果你想傳遞對象 `{title: 'Hello', message: 'Please login'}` 到你的主頁,
```html
<!--Typing this using Pug-->
head
script(type='text/javascript').
if (foo) bar(1 + 5);
body
if youAreUsingPug
p You are amazing
else
p Get on it!
看起來應該像這樣:`res.render(process.cwd() + '/views/pug/index', {title: 'Hello', message: 'Please login'});`。現在刷新頁面,你應該看到那些值就像在 index.pug 文件中一樣被渲染在頁面上正確的位置。
<!--will lead to creating this code-->
<head>
<script type="text/javascript">
if (foo) bar(1 + 5);
</script>
</head>
<body>
<p>You are amazing</p>
</body>
```
完成上述要求後,請提交你的頁面鏈接。 如果你遇到了問題,可以參考 [這裏](https://gist.github.com/camperbot/4af125119ed36e6e6a8bb920db0c0871) 的答案。
Looking at our pug file `index.pug` included in your project, we used the variables `title` and `message`.
To pass those along from our server, you will need to add an object as a second argument to your `res.render` with the variables and their values. For example, pass this object along setting the variables for your index view: `{title: 'Hello', message: 'Please login'}`
It should look like: `res.render(process.cwd() + '/views/pug/index', {title: 'Hello', message: 'Please login'});` Now refresh your page and you should see those values rendered in your view in the correct spot as laid out in your `index.pug` file!
Submit your page when you think you've got it right. If you're running into errors, you can check out the <a href="https://gist.github.com/camperbot/4af125119ed36e6e6a8bb920db0c0871" target="_blank" rel="noopener noreferrer nofollow">project completed up to this point</a>.
# --hints--
Pug 應正確地展示變量。
Pug should correctly render variables.
```js
(getUserInput) =>
@@ -8,7 +8,7 @@ dashedName: assert-deep-equality-with--deepequal-and--notdeepequal
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a> or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
`deepEqual()` 斷言兩個對象是否深度相等。
@@ -8,15 +8,15 @@ dashedName: compare-the-properties-of-two-elements
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
# --instructions--
在 `tests/1_unit-tests.js` 中,在標有 `#8` 的 `Comparisons` 套件裏,將每個 `assert` 改成 `assert.isAbove` 或 `assert.isAtMost` 方法,讓測試通過(結果應該返回 `true`)。 不要改變傳入斷言的參數。
Within `tests/1_unit-tests.js` under the test labelled `#8` in the `Comparisons` suite, change each `assert` to either `assert.isAbove` or `assert.isAtMost` to make the test pass (should evaluate to `true`). Do not alter the arguments passed to the asserts.
# --hints--
不應有未通過的測試
All tests should pass.
```js
(getUserInput) =>
@@ -30,7 +30,7 @@ dashedName: compare-the-properties-of-two-elements
);
```
請爲第一個斷言選擇正確的方法 — `isAbove` 或 `isAtMost`。
You should choose the correct method for the first assertion - `isAbove` vs. `isAtMost`.
```js
(getUserInput) =>
@@ -48,7 +48,7 @@ dashedName: compare-the-properties-of-two-elements
);
```
請爲第二個斷言選擇正確的方法 — `isAbove` 或 `isAtMost`。
You should choose the correct method for the second assertion - `isAbove` vs. `isAtMost`.
```js
(getUserInput) =>
@@ -62,7 +62,7 @@ dashedName: compare-the-properties-of-two-elements
);
```
請爲第三個斷言選擇正確的方法 — `isAbove` 或 `isAtMost`。
You should choose the correct method for the third assertion - `isAbove` vs. `isAtMost`.
```js
(getUserInput) =>
@@ -80,7 +80,7 @@ dashedName: compare-the-properties-of-two-elements
);
```
請爲第四個斷言選擇正確的方法 — `isAbove` 或 `isAtMost`。
You should choose the correct method for the fourth assertion - `isAbove` vs. `isAtMost`.
```js
(getUserInput) =>
@@ -10,8 +10,8 @@ dashedName: learn-how-javascript-assertions-work
你可以採用下面的任意一種方式完成這些挑戰:
- 克隆[這個 GitHub 倉庫](https://github.com/freeCodeCamp/boilerplate-mochachai/)並在本地完成項目。
- 使用[我們的 Replit 上的初始化項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)來完成項目。
- Clone <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">this GitHub repo</a> and complete these challenges locally.
- Use <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">our Replit starter project</a> to complete these challenges.
- 使用一個你喜歡的站點生成器來完成項目。 需要確定包含了我們 GitHub 倉庫的所有文件。
完成本項目後,請將一個正常運行的 demo(項目演示)託管在可以公開訪問的平臺。 然後在 `Solution Link` 框中提交你的項目 URL。
@@ -8,7 +8,7 @@ dashedName: run-functional-tests-on-an-api-response-using-chai-http-iii---put-me
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
當你測試一個 `PUT` 請求時,你經常會隨同它一起發送數據。 你在 `PUT` 請求中包含的數據被稱爲請求的主體。
@@ -8,7 +8,7 @@ dashedName: run-functional-tests-on-an-api-response-using-chai-http-iv---put-met
# --description--
請注意,本項目在 [這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai) 的基礎上進行開發。你也可以從 [GitHub](https://github.com/freeCodeCamp/boilerplate-mochachai/) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
這個練習與上一個類似。
@@ -8,7 +8,7 @@ dashedName: run-functional-tests-on-api-endpoints-using-chai-http-ii
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
# --instructions--
@@ -8,7 +8,7 @@ dashedName: run-functional-tests-on-api-endpoints-using-chai-http
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
Mocha 允許你使用名爲 `chai-http` 的插件測試異步操作,例如調用 API 端點。
@@ -8,11 +8,11 @@ dashedName: run-functional-tests-using-a-headless-browser-ii
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
# --instructions--
在 `tests/2_functional-tests.js` 中,在 `'Submit the surname "Vespucci" in the HTML form'` 測試(`// #5`),自動執行以下操作:
Within `tests/2_functional-tests.js`, in the `'Submit the surname "Vespucci" in the HTML form'` test (`// #6`), automate the following:
1. 在表格中填寫姓氏 `Vespucci`。
2. 點擊提交按鈕
@@ -8,7 +8,7 @@ dashedName: run-functional-tests-using-a-headless-browser
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
在頁面上有一個輸入表單。 它將數據作爲 AJAX 請求發送到 `PUT /travellers` 端點。
@@ -7,7 +7,7 @@ dashedName: simulate-actions-using-a-headless-browser
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
在接下來的挑戰中,你將使用無頭瀏覽器模擬人類與頁面的交互。
@@ -8,7 +8,7 @@ dashedName: test-for-truthiness
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
`isTrue()` 僅當給出的值爲 Boolean 的 `true` 時可以通過測試;`isNotTrue()` 則會在給出除 `true` 以外的值時通過測試。
@@ -8,7 +8,7 @@ dashedName: test-if-a-string-contains-a-substring
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
`include()` 和 `notInclude()` 同樣可以用於字符串。 `include()` 用於斷言字符串中包含某個子字符串。
@@ -8,7 +8,7 @@ dashedName: test-if-a-value-falls-within-a-specific-range
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
```javascript
.approximately(actual, expected, delta, [message])
@@ -8,7 +8,7 @@ dashedName: test-if-a-value-is-a-string
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
`isString` 或 `isNotString` 斷言一個值是否爲字符串。
@@ -8,7 +8,7 @@ dashedName: test-if-a-value-is-of-a-specific-data-structure-type
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
`#typeOf` 斷言一個值的類型符合給定的類型,這個類型與 `Object.prototype.toString` 一致。
@@ -8,7 +8,7 @@ dashedName: test-if-a-variable-or-function-is-defined
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
# --instructions--
@@ -8,7 +8,7 @@ dashedName: test-if-an-array-contains-an-item
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
# --instructions--
@@ -8,7 +8,7 @@ dashedName: test-if-an-object-has-a-property
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
`property` 斷言一個對象含有給定屬性。
@@ -8,7 +8,7 @@ dashedName: test-if-an-object-is-an-instance-of-a-constructor
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
`#instanceOf` 斷言一個對象是一個構造器的實例。
@@ -8,7 +8,7 @@ dashedName: test-if-one-value-is-below-or-at-least-as-large-as-another
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
# --instructions--
@@ -8,11 +8,11 @@ dashedName: use-assert-isok-and-assert-isnotok
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
`isOk()` 用來測試值是否爲真值,`isNotOk()` 用來測試值是否爲假值。
可以在[過濾數組中的假值](https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/falsy-bouncer)這個挑戰中瞭解更多關於真值和假值的信息。
To learn more about truthy and falsy values, try our <a href="https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/basic-algorithm-scripting/falsy-bouncer" target="_blank" rel="noopener noreferrer nofollow">Falsy Bouncer</a> challenge.
# --instructions--
@@ -8,7 +8,7 @@ dashedName: use-regular-expressions-to-test-a-string
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
`match()` 斷言一個值匹配一個正則表達式(第二個參數)。
@@ -8,7 +8,7 @@ dashedName: use-the-double-equals-to-assert-equality
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
`equal()` 使用 `==` 比較對象。
@@ -8,7 +8,7 @@ dashedName: use-the-triple-equals-to-assert-strict-equality
# --description--
請注意,本項目在[這個 Replit 項目](https://replit.com/github/freeCodeCamp/boilerplate-mochachai)的基礎上進行開發。你也可以從 [GitHub](https://repl.it/github/freeCodeCamp/boilerplate-mochachai) 上克隆。
As a reminder, this project is being built upon the following starter project on <a href="https://replit.com/github/freeCodeCamp/boilerplate-mochachai" target="_blank" rel="noopener noreferrer nofollow">Replit</a>, or cloned from <a href="https://github.com/freeCodeCamp/boilerplate-mochachai/" target="_blank" rel="noopener noreferrer nofollow">GitHub</a>.
`strictEqual()` 使用 `===` 比較對象。
@@ -8,10 +8,10 @@ dashedName: american-british-translator
# --description--
構建一個 JavaScript 的全棧應用,在功能上與這個應用相似:<https://american-british-translator.freecodecamp.rocks/>。 可以採用下面的任意一種方式完成這個挑戰:
Build a full stack JavaScript app that is functionally similar to this: <a href="https://american-british-translator.freecodecamp.rocks/" target="_blank" rel="noopener noreferrer nofollow">https://american-british-translator.freecodecamp.rocks/</a>. 可以採用下面的任意一種方式完成這個挑戰:
- 克隆 [這個 GitHub 倉庫](https://github.com/freeCodeCamp/boilerplate-project-american-british-english-translator/) 並在本地完成項目。
- 使用[我們的 Replit 初始化項目](https://replit.com/github/freeCodeCamp/boilerplate-project-american-british-english-translator)來完成你的項目。
- Clone <a href="https://github.com/freeCodeCamp/boilerplate-project-american-british-english-translator/" target="_blank" rel="noopener noreferrer nofollow">this GitHub repo</a> and complete your project locally.
- Use <a href="https://replit.com/github/freeCodeCamp/boilerplate-project-american-british-english-translator" target="_blank" rel="noopener noreferrer nofollow">our Replit starter project</a> to complete your project.
- 使用您選擇的站點生成器來完成項目。 並確保包含了我們 GitHub 倉庫的所有文件。
當完成本項目,請確認有一個可以公開訪問的正常運行 demo 。 然後將 URL 提交到 `Solution Link` 中。 此外,還可以將項目的源碼提交到 `GitHub Link` 中。
@@ -8,10 +8,10 @@ dashedName: issue-tracker
# --description--
構建一個 JavaScript 的全棧應用,在功能上與這個應用相似: <https://issue-tracker.freecodecamp.rocks/>。 可以採用下面的任意一種方式完成這個挑戰:
Build a full stack JavaScript app that is functionally similar to this: <a href="https://issue-tracker.freecodecamp.rocks/" target="_blank" rel="noopener noreferrer nofollow">https://issue-tracker.freecodecamp.rocks/</a>. 可以採用下面的任意一種方式完成這個挑戰:
- 克隆 [GitHub 倉庫](https://github.com/freeCodeCamp/boilerplate-project-issuetracker/) 並在本地完成你的項目。
- 使用[我們的 Replit 初始化項目](https://replit.com/github/freeCodeCamp/boilerplate-project-issuetracker)來完成你的項目。
- Clone <a href="https://github.com/freeCodeCamp/boilerplate-project-issuetracker/" target="_blank" rel="noopener noreferrer nofollow">this GitHub repo</a> and complete your project locally.
- Use <a href="https://replit.com/github/freeCodeCamp/boilerplate-project-issuetracker" target="_blank" rel="noopener noreferrer nofollow">this Replit starter project</a> to complete your project.
- 使用一個你喜歡的站點生成器來完成項目。 需要確定包含了我們 GitHub 倉庫的所有文件。
完成本項目後,請將一個正常運行的 demo(項目演示)託管在可以公開訪問的平臺。 然後在 `Solution Link` 框中提交你的項目 URL。 此外,還可以將項目的源碼提交到 `GitHub Link` 中。
@@ -8,10 +8,10 @@ dashedName: metric-imperial-converter
# --description--
構建一個 JavaScript 的全棧應用,在功能上與這個應用相似:<https://metric-imperial-converter.freecodecamp.rocks/>。 可以採用下面的任意一種方式完成這個挑戰:
Build a full stack JavaScript app that is functionally similar to this: <a href="https://metric-imperial-converter.freecodecamp.rocks/" target="_blank" rel="noopener noreferrer nofollow">https://metric-imperial-converter.freecodecamp.rocks/</a>. 可以採用下面的任意一種方式完成這個挑戰:
- 克隆 [GitHub 倉庫](https://github.com/freeCodeCamp/boilerplate-project-metricimpconverter/) 並在本地完成你的項目。
- 使用[我們的 Replit 初始化項目](https://replit.com/github/freeCodeCamp/boilerplate-project-metricimpconverter)來完成你的項目。
- Clone <a href="https://github.com/freeCodeCamp/boilerplate-project-metricimpconverter/" target="_blank" rel="noopener noreferrer nofollow">this GitHub repo</a> and complete your project locally.
- Use <a href="https://replit.com/github/freeCodeCamp/boilerplate-project-metricimpconverter" target="_blank" rel="noopener noreferrer nofollow">our Replit starter project</a> to complete your project.
- 使用一個你喜歡的站點生成器來完成項目。 需要確定包含了我們 GitHub 倉庫的所有文件。
完成本項目後,請將一個正常運行的 demo(項目演示)託管在可以公開訪問的平臺。 然後在 `Solution Link` 框中提交你的項目 URL。 此外,還可以將項目的源碼提交到 `GitHub Link` 中。
@@ -8,10 +8,10 @@ dashedName: personal-library
# --description--
構建一個 JavaScript 的全棧應用,在功能上與這個應用相似:<https://personal-library.freecodecamp.rocks/>。 可以採用下面的任意一種方式完成這個挑戰:
Build a full stack JavaScript app that is functionally similar to this: <a href="https://personal-library.freecodecamp.rocks/" target="_blank" rel="noopener noreferrer nofollow">https://personal-library.freecodecamp.rocks/</a>. 可以採用下面的任意一種方式完成這個挑戰:
- 克隆 [這個 GitHub 倉庫](https://github.com/freeCodeCamp/boilerplate-project-library) 並在本地完成項目。
- 使用[我們的 Replit 初始化項目](https://replit.com/github/freeCodeCamp/boilerplate-project-library)來完成你的項目。
- Clone <a href="https://github.com/freeCodeCamp/boilerplate-project-library" target="_blank" rel="noopener noreferrer nofollow">this GitHub repo</a> and complete your project locally.
- Use <a href="https://replit.com/github/freeCodeCamp/boilerplate-project-library" target="_blank" rel="noopener noreferrer nofollow">our Replit starter project</a> to complete your project.
- 使用一個你喜歡的站點生成器來完成項目。 需要確定包含了我們 GitHub 倉庫的所有文件。
完成本項目後,請將一個正常運行的 demo(項目演示)託管在可以公開訪問的平臺。 然後在 `Solution Link` 框中提交你的項目 URL。 此外,還可以將項目的源碼提交到 `GitHub Link` 中。
@@ -8,10 +8,10 @@ dashedName: sudoku-solver
# --description--
構建一個 JavaScript 的全棧應用,在功能上與這個應用相似:<https://sudoku-solver.freecodecamp.rocks/>。 可以採用下面的任意一種方式完成這個挑戰:
Build a full stack JavaScript app that is functionally similar to this: <a href="https://sudoku-solver.freecodecamp.rocks/" target="_blank" rel="noopener noreferrer nofollow">https://sudoku-solver.freecodecamp.rocks/</a>. 可以採用下面的任意一種方式完成這個挑戰:
- 克隆 [GitHub 倉庫](https://github.com/freecodecamp/boilerplate-project-sudoku-solver) 並在本地完成你的項目。
- 使用[我們的 Replit 初始化項目](https://replit.com/github/freeCodeCamp/boilerplate-project-sudoku-solver)來完成你的項目。
- Clone <a href="https://github.com/freecodecamp/boilerplate-project-sudoku-solver" target="_blank" rel="noopener noreferrer nofollow">this GitHub repo</a> and complete your project locally.
- Use <a href="https://replit.com/github/freeCodeCamp/boilerplate-project-sudoku-solver" target="_blank" rel="noopener noreferrer nofollow">our Replit starter project</a> to complete your project.
- 使用一個你喜歡的站點生成器來完成項目。 需要確定包含了我們 GitHub 倉庫的所有文件。
完成本項目後,請將一個正常運行的 demo(項目演示)託管在可以公開訪問的平臺。 然後在 `Solution Link` 框中提交你的項目 URL。 此外,還可以將項目的源碼提交到 `GitHub Link` 中。
@@ -270,7 +270,7 @@ async (getUserInput) => {
};
```
如果提交給 `/api/check` 的對象缺失 `puzzle`、`coordinate` 或 `value`,返回的值將是 `{ error: Required field(s) missing }`
If the object submitted to `/api/check` is missing `puzzle`, `coordinate` or `value`, the returned value will be `{ error: 'Required field(s) missing' }`
```js
async (getUserInput) => {
@@ -324,7 +324,7 @@ async (getUserInput) => {
};
```
如果提交給 `/api/check` 的 `value` 不是一個介於 1 到 9 之間的數字,則返回的值將是 `{ error: 'Invalid value' }`
If the `value` submitted to `/api/check` is not a number between 1 and 9, the returned value will be `{ error: 'Invalid value' }`
```js
async (getUserInput) => {
@@ -353,9 +353,11 @@ async (getUserInput) => {
try {
const getTests = await $.get(getUserInput('url') + '/_api/get-tests');
assert.isArray(getTests);
const units = getTests.filter((el) => el.context.includes('UnitTests'));
assert.isAtLeast(units.length, 12, 'At least 12 tests passed');
units.forEach((test) => {
const unitTests = getTests.filter((test) => {
return !!test.context.match(/Unit\s*Tests/gi);
});
assert.isAtLeast(unitTests.length, 12, 'At least 12 tests passed');
unitTests.forEach((test) => {
assert.equal(test.state, 'passed', 'Test in Passed State');
assert.isAtLeast(
test.assertions.length,
@@ -369,18 +371,18 @@ async (getUserInput) => {
};
```
所有 14 項功能測試都已完成並通過。 請參閱 `/tests/2_functional-tests.js` 來了解你應該編寫的測試的功能。
所有 14 項功能測試都已完成並通過。 See `/tests/2_functional-tests.js` for the expected functionality you should write tests for.
```js
async (getUserInput) => {
try {
const getTests = await $.get(getUserInput('url') + '/_api/get-tests');
assert.isArray(getTests);
const funcs = getTests.filter((el) =>
el.context.includes('Functional Tests')
);
assert.isAtLeast(funcs.length, 14, 'At least 14 tests passed');
funcs.forEach((test) => {
const functTests = getTests.filter((test) => {
return !!test.context.match(/Functional\s*Tests/gi);
});
assert.isAtLeast(functTests.length, 14, 'At least 14 tests passed');
functTests.forEach((test) => {
assert.equal(test.state, 'passed', 'Test in Passed State');
assert.isAtLeast(
test.assertions.length,
@@ -14,7 +14,7 @@ dashedName: build-your-own-functions
更多資源
\- [練習](https://www.youtube.com/watch?v=ksvGhDsjtpw)
\- <a href="https://www.youtube.com/watch?v=ksvGhDsjtpw" target="_blank" rel="noopener noreferrer nofollow">Exercise</a>
# --question--
@@ -14,7 +14,7 @@ dashedName: comparing-and-sorting-tuples
更多資源:
\- [練習](https://www.youtube.com/watch?v=EhQxwzyT16E)
\- <a href="https://www.youtube.com/watch?v=EhQxwzyT16E" target="_blank" rel="noopener noreferrer nofollow">Exercise</a>
# --question--
@@ -14,19 +14,19 @@ dashedName: data-visualization-mailing-lists
更多資源:
\- [練習:Geodata](https://www.youtube.com/watch?v=KfhslNzopxo)
\- <a href="https://www.youtube.com/watch?v=KfhslNzopxo" target="_blank" rel="noopener noreferrer nofollow">練習:Geodata</a>
\- [練習:Gmane 模型](https://www.youtube.com/watch?v=wSpl1-7afAk)
\- <a href="https://www.youtube.com/watch?v=wSpl1-7afAk" target="_blank" rel="noopener noreferrer nofollow">練習:Gmane 模型</a>
\- [練習:Gmane Spider](https://www.youtube.com/watch?v=H3w4lOFBUOI)
\- <a href="https://www.youtube.com/watch?v=H3w4lOFBUOI" target="_blank" rel="noopener noreferrer nofollow">Exercise: Gmane Spider</a>
\- [練習:Gmane Viz](https://www.youtube.com/watch?v=LRqVPMEXByw)
\- <a href="https://www.youtube.com/watch?v=LRqVPMEXByw" target="_blank" rel="noopener noreferrer nofollow">Exercise: Gmane Viz</a>
\- [練習:Page Rank](https://www.youtube.com/watch?v=yFRAZBkBDBs)
\- <a href="https://www.youtube.com/watch?v=yFRAZBkBDBs" target="_blank" rel="noopener noreferrer nofollow">Exercise: Page Rank</a>
\- [練習:Page Spider](https://www.youtube.com/watch?v=sXedPQ_AnWA)
\- <a href="https://www.youtube.com/watch?v=sXedPQ_AnWA" target="_blank" rel="noopener noreferrer nofollow">Exercise: Page Spider</a>
\- [練習: Page Viz](https://www.youtube.com/watch?v=Fm0hpkxsZoo)
\- <a href="https://www.youtube.com/watch?v=Fm0hpkxsZoo" target="_blank" rel="noopener noreferrer nofollow">Exercise: Page Viz</a>
# --question--
@@ -14,7 +14,7 @@ dashedName: dictionaries-and-loops
更多資源:
\- [練習](https://www.youtube.com/watch?v=PrhZ9qwBDD8)
\- <a href="https://www.youtube.com/watch?v=PrhZ9qwBDD8" target="_blank" rel="noopener noreferrer nofollow">Exercise</a>
# --question--
@@ -14,7 +14,7 @@ dashedName: files-as-a-sequence
更多資源:
\- [練習](https://www.youtube.com/watch?v=il1j4wkte2E)
\- <a href="https://www.youtube.com/watch?v=il1j4wkte2E" target="_blank" rel="noopener noreferrer nofollow">Exercise</a>
# --question--
@@ -14,9 +14,9 @@ dashedName: intermediate-expressions
更多資源:
\- [練習 1](https://youtu.be/t_4DPwsaGDY)
\- <a href="https://youtu.be/t_4DPwsaGDY" target="_blank" rel="noopener noreferrer nofollow">Exercise 1</a>
\- [練習 2](https://youtu.be/wgkC8SxraAQ)
\- <a href="https://youtu.be/wgkC8SxraAQ" target="_blank" rel="noopener noreferrer nofollow">Exercise 2</a>
# --question--
@@ -14,7 +14,7 @@ dashedName: intermediate-strings
更多資料:
[練習](https://www.youtube.com/watch?v=1bSqHot-KwE)
\- <a href="https://www.youtube.com/watch?v=1bSqHot-KwE" target="_blank" rel="noopener noreferrer nofollow">Exercise</a>
# --question--
@@ -18,9 +18,9 @@ dashedName: introduction-why-program
更多資源:
\- [Windows 系統安裝 Python](https://youtu.be/F7mtLrYzZP8)
\- <a href="https://youtu.be/F7mtLrYzZP8" target="_blank" rel="noopener noreferrer nofollow">Install Python on Windows</a>
\- [MacOS 系統安裝 Python](https://youtu.be/wfLnZP-4sZw)
\- <a href="https://youtu.be/wfLnZP-4sZw" target="_blank" rel="noopener noreferrer nofollow">Install Python on MacOS</a>
# --question--
@@ -14,7 +14,7 @@ dashedName: iterations-more-patterns
更多資源:
\- [練習](https://www.youtube.com/watch?v=kjxXZQw0uPg)
\- <a href="https://www.youtube.com/watch?v=kjxXZQw0uPg" target="_blank" rel="noopener noreferrer nofollow">Exercise</a>
# --question--
@@ -14,9 +14,9 @@ dashedName: more-conditional-structures
更多資源:
\- [練習 1](https://www.youtube.com/watch?v=crLerB4ZxMI)
\- <a href="https://www.youtube.com/watch?v=crLerB4ZxMI" target="_blank" rel="noopener noreferrer nofollow">Exercise 1</a>
\- [練習 2](https://www.youtube.com/watch?v=KJN3-7HH6yk)
\- <a href="https://www.youtube.com/watch?v=KJN3-7HH6yk" target="_blank" rel="noopener noreferrer nofollow">Exercise 2</a>
# --question--
@@ -14,11 +14,11 @@ dashedName: networking-web-scraping-with-python
更多資料:
\- [練習:socket1](https://www.youtube.com/watch?v=dWLdI143W-g)
\- <a href="https://www.youtube.com/watch?v=dWLdI143W-g" target="_blank" rel="noopener noreferrer nofollow">Exercise: socket1</a>
\- [練習:urllib](https://www.youtube.com/watch?v=8yis2DvbBkI)
\- <a href="https://www.youtube.com/watch?v=8yis2DvbBkI" target="_blank" rel="noopener noreferrer nofollow">Exercise: urllib</a>
\- [練習:urllinks](https://www.youtube.com/watch?v=g9flPDG9nnY)
\- <a href="https://www.youtube.com/watch?v=g9flPDG9nnY" target="_blank" rel="noopener noreferrer nofollow">Exercise: urllinks</a>
# --question--
@@ -10,15 +10,21 @@ bilibiliIds:
dashedName: relational-databases-and-sqlite
---
# --description--
<a href="https://www.sqlite.org/download.html" target="_blank" rel="noopener noreferrer nofollow">Download SQLite</a>
<a href="https://sqlitebrowser.org/dl/" target="_blank" rel="noopener noreferrer nofollow">Download DB Browser for SQLite</a>
<a href="https://www.sqlite.org/famous.html" target="_blank" rel="noopener noreferrer nofollow">SQLite usage</a>
# --question--
## --text--
哪個不是數據庫中主要的數據結構?
哪一個不是數據庫中的主要數據結構?
## --answers--
指數
索引
---
@@ -26,11 +32,11 @@ dashedName: relational-databases-and-sqlite
---
一行
行
---
一列
列
## --video-solution--
@@ -14,15 +14,15 @@ dashedName: relational-databases-many-to-many-relationships
更多資料:
\- [練習:電子郵件](https://www.youtube.com/watch?v=uQ3Qv1z_Vao)
\- <a href="https://www.youtube.com/watch?v=uQ3Qv1z_Vao" target="_blank" rel="noopener noreferrer nofollow">Exercise: Email</a>
\- [練習:名冊](https://www.youtube.com/watch?v=qEkUEAz8j3o)
\- <a href="https://www.youtube.com/watch?v=qEkUEAz8j3o" target="_blank" rel="noopener noreferrer nofollow">Exercise: Roster</a>
\- [練習:曲目](https://www.youtube.com/watch?v=I-E7avcPeSE)
\- <a href="https://www.youtube.com/watch?v=I-E7avcPeSE" target="_blank" rel="noopener noreferrer nofollow">Exercise: Tracks</a>
\- [練習:推特好友](https://www.youtube.com/watch?v=RZRAoBFIH6A)
\- <a href="https://www.youtube.com/watch?v=RZRAoBFIH6A" target="_blank" rel="noopener noreferrer nofollow">Exercise: Twfriends</a>
\- [練習:推特爬蟲](https://www.youtube.com/watch?v=xBaJddvJL4A)
\- <a href="https://www.youtube.com/watch?v=xBaJddvJL4A" target="_blank" rel="noopener noreferrer nofollow">Exercise: Twspider</a>
# --question--
@@ -14,7 +14,7 @@ dashedName: strings-and-lists
更多資源:
\- [練習](https://www.youtube.com/watch?v=-9TfJF2dwHI)
\- <a href="https://www.youtube.com/watch?v=-9TfJF2dwHI" target="_blank" rel="noopener noreferrer nofollow">Exercise</a>
# --question--
@@ -14,13 +14,13 @@ dashedName: web-services-api-rate-limiting-and-security
更多資料:
\- [練習:GeoJSON](https://www.youtube.com/watch?v=TJGJN0T8tak)
\- <a href="https://www.youtube.com/watch?v=TJGJN0T8tak" target="_blank" rel="noopener noreferrer nofollow">Exercise: GeoJSON</a>
\- [練習:JSON](https://www.youtube.com/watch?v=vTmw5RtfGMY)
\- <a href="https://www.youtube.com/watch?v=vTmw5RtfGMY" target="_blank" rel="noopener noreferrer nofollow">Exercise: JSON</a>
\- [練習:Twitter](https://www.youtube.com/watch?v=2c7YwhvpCro)
\- <a href="https://www.youtube.com/watch?v=2c7YwhvpCro" target="_blank" rel="noopener noreferrer nofollow">Exercise: Twitter</a>
\- [練習:XML](https://www.youtube.com/watch?v=AopYOlDa-vY)
\- <a href="https://www.youtube.com/watch?v=AopYOlDa-vY" target="_blank" rel="noopener noreferrer nofollow">Exercise: XML</a>
# --question--
@@ -8,7 +8,7 @@ dashedName: arithmetic-formatter
# --description--
你將[使用我們的 Replit 入門代碼來完成這個項目](https://replit.com/github/freeCodeCamp/boilerplate-arithmetic-formatter)。
You will be <a href="https://replit.com/github/freeCodeCamp/boilerplate-arithmetic-formatter" target="_blank" rel="noopener noreferrer nofollow"> working on this project with our Replit starter code</a>.
# --instructions--
@@ -64,7 +64,7 @@ arithmetic_arranger(["32 + 8", "1 - 3801", "9999 + 9999", "523 - 49"], True)
- 每個數字(操作數)應該只包含數字。 否則,該函數將返回: `Error: Numbers must only contain digits.`
- 每個操作數(也就是運算符兩側的數字)的寬度最多爲四位。 否則,返回的錯誤字符串將爲: `Error: Numbers cannot be more than four digits.`
- 如果用戶提供了正確格式的問題,返回的轉換將遵循以下規則:
- 運算符和兩個數中最長的一個之間應該有一個空格,運算符與第二個數在同一行,兩個數的順序與所提供的相同(第一個將是頂部的,而第二個將是底部。
- There should be a single space between the operator and the longest of the two operands, the operator will be on the same line as the second operand, both operands will be in the same order as provided (the first will be the top one and the second will be the bottom).
- 數字應該右對齊。
- 每個問題之間應該有四個空格。
- 每個問題的底部都應該有破折號。 破折號應該單獨沿着每個問題的整個長度延伸。 (上面的例子展示了這應該是什麼樣子。)
@@ -8,7 +8,7 @@ dashedName: budget-app
# --description--
你將[使用我們的 Replit 入門代碼來完成這個項目](https://replit.com/github/freeCodeCamp/boilerplate-budget-app)。
You will be <a href="https://replit.com/github/freeCodeCamp/boilerplate-budget-app" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Replit starter code</a>.
# --instructions--
@@ -8,7 +8,7 @@ dashedName: polygon-area-calculator
# --description--
你將通過使用我們的[Replit 入門代碼](https://replit.com/github/freeCodeCamp/boilerplate-polygon-area-calculator)來完成本項目。
You will be <a href="https://replit.com/github/freeCodeCamp/boilerplate-polygon-area-calculator" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Replit starter code</a>.
# --instructions--
@@ -8,7 +8,7 @@ dashedName: probability-calculator
# --description--
你將通過使用我們的[Replit 入門代碼](https://replit.com/github/freeCodeCamp/boilerplate-probability-calculator)來完成本項目。
You will be <a href="https://replit.com/github/freeCodeCamp/boilerplate-probability-calculator" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Replit starter code</a>.
# --instructions--
@@ -37,7 +37,7 @@ hat3 = Hat(red=5, orange=4, black=1, blue=0, pink=2, striped=9)
`experiment` 函數應該返回一個概率。
例如,假設你想確定當你從一個包含 6 個黑球、4 個紅球和 3 個綠球的帽子中抽出 5 個球時,至少得到 2 個紅球和 1 個綠球的概率。 爲此,我們進行 `N` 次實驗,記錄其中我們至少得到 2 個紅球和 1 個綠球的次數 `M`,並估計概率爲`M/N`。 每個實驗都包括從一頂裝有指定球的帽子開始,抽取一些球,然後檢查我們是否得到了我們想要得到的球。
For example, if you want to determine the probability of getting at least two red balls and one green ball when you draw five balls from a hat containing six black, four red, and three green. To do this, you will perform `N` experiments, count how many times `M` you get at least two red balls and one green ball, and estimate the probability as `M/N`. Each experiment consists of starting with a hat containing the specified balls, drawing several balls, and checking if you got the balls you were attempting to draw.
以下是基於上面的示例調用 `experiment` 函數的方法,其中包含 2000 個實驗:
@@ -8,7 +8,7 @@ dashedName: time-calculator
# --description--
你將通過使用我們的[Replit 入門代碼](https://replit.com/github/freeCodeCamp/boilerplate-time-calculator)來完成本項目。
You will be <a href="https://replit.com/github/freeCodeCamp/boilerplate-time-calculator" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Replit starter code</a>.
# --instructions--
@@ -11,16 +11,17 @@ dashedName: introduction-to-data-analysis
---
# --description--
數據分析是指通過清理、轉換、處理原始數據,從而洞察數據價值的行爲。
以下有更多的資料:
更多資源:
\- [幻燈片](https://docs.google.com/presentation/d/1cUIt8b2ySz-85_ykfeuuWsurccwTAuFPn782pZBzFsU/edit?usp=sharing)
\- <a href="https://chinese.freecodecamp.org/news/what-is-data-analysis/" rel="noopener noreferrer nofollow">專欄文章</a>
# --question--
## --text--
以下哪一項 **不是** 數據分析的一部分?
以下哪一項**不屬於**數據分析範疇?
## --answers--
@@ -28,7 +29,7 @@ dashedName: introduction-to-data-analysis
---
爲分析選擇所需的結論。
分析數據並得出結論。
---
@@ -8,12 +8,13 @@ dashedName: demographic-data-analyzer
# --description--
你將通過使用我們的[Replit 入門代碼](https://replit.com/github/freeCodeCamp/boilerplate-demographic-data-analyzer)來完成本項目。
You will be <a href="https://replit.com/github/freeCodeCamp/boilerplate-demographic-data-analyzer" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Replit starter code</a>.
我們仍在開發 Python 課程的交互式教學部分。 目前,你可以在 YouTube 上通過 freeCodeCamp.org 上傳的一些視頻學習這個項目相關的知識。
- [Python for Everybody 視頻課程](https://www.freecodecamp.org/news/python-for-everybody/)(14 小時)
- [Learn Python 視頻課程](https://www.freecodecamp.org/news/learn-python-video-course/)(10 小時)
- <a href="https://www.freecodecamp.org/news/python-for-everybody/" target="_blank" rel="noopener noreferrer nofollow">Python for Everybody Video Course</a> (14 hours)
- <a href="https://www.freecodecamp.org/news/how-to-analyze-data-with-python-pandas/" target="_blank" rel="noopener noreferrer nofollow">How to Analyze Data with Python Pandas</a> (10 hours)
# --instructions--
@@ -59,7 +60,7 @@ dashedName: demographic-data-analyzer
## 數據集源
Dua, D. and Graff, C. (2019). [UCI Machine Learning Repository](http://archive.ics.uci.edu/ml). Irvine, CA: University of California, School of Information and Computer Science.
Dua, D. and Graff, C. (2019). <a href="http://archive.ics.uci.edu/ml" target="_blank" rel="noopener noreferrer nofollow">UCI Machine Learning Repository</a>. Irvine, CA: University of California, School of Information and Computer Science.
# --hints--
@@ -8,12 +8,13 @@ dashedName: mean-variance-standard-deviation-calculator
# --description--
你將通過使用我們的[Replit 入門代碼](https://replit.com/github/freeCodeCamp/boilerplate-mean-variance-standard-deviation-calculator)來完成本項目。
You will be <a href="https://replit.com/github/freeCodeCamp/boilerplate-mean-variance-standard-deviation-calculator" target="_blank" rel="noopener noreferrer nofollow">working on this project with our Replit starter code</a>.
我們仍在開發 Python 課程的交互式教學部分。 目前,你可以在 YouTube 上通過 freeCodeCamp.org 上傳的一些視頻學習這個項目相關的知識。
- [Python for Everybody 視頻課程](https://www.freecodecamp.org/news/python-for-everybody/)(14 小時)
- [Learn Python 視頻課程](https://www.freecodecamp.org/news/learn-python-video-course/)(10 小時)
- <a href="https://www.freecodecamp.org/news/python-for-everybody/" target="_blank" rel="noopener noreferrer nofollow">Python for Everybody Video Course</a>(14 hours)
- <a href="https://www.freecodecamp.org/news/how-to-analyze-data-with-python-pandas/" target="_blank" rel="noopener noreferrer nofollow">How to Analyze Data with Python Pandas</a> (10 hours)
# --instructions--

Some files were not shown because too many files have changed in this diff Show More