diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/add-a-box-shadow-to-a-card-like-element.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/add-a-box-shadow-to-a-card-like-element.md
index 6f849f04f3..024c531e35 100644
--- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/add-a-box-shadow-to-a-card-like-element.md
+++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/add-a-box-shadow-to-a-card-like-element.md
@@ -11,13 +11,13 @@ dashedName: add-a-box-shadow-to-a-card-like-element
`box-shadow` 屬性用來給元素添加陰影,該屬性值是由逗號分隔的一個或多個陰影列表。
-`box-shadow` 屬性的陰影依次由下面這些值描述:
+`box-shadow` 屬性按順序採用以下值:
- offset-x
陰影的水平偏移量;
- offset-y
陰影的垂直偏移量;
- blur-radius
模糊半徑;
- spread-radius
陰影擴展半徑;
+ offset-x
(陰影的水平偏移量),
+ offset-y
(陰影的垂直偏移量),
+ blur-radius
+ spread-radius
color
diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/adjust-the-hue-of-a-color.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/adjust-the-hue-of-a-color.md
index 3fcb82f6ed..e1f1a30130 100644
--- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/adjust-the-hue-of-a-color.md
+++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/adjust-the-hue-of-a-color.md
@@ -9,7 +9,7 @@ dashedName: adjust-the-hue-of-a-color
# --description--
-顏色具有多種特性,包括色相、飽和度和亮度。 CSS3 引入了 `hsl()` 做爲顏色的描述方式。
+顏色具有多種特性,包括色相、飽和度和亮度。 CSS3 引入了`hsl()`函數,作爲直接說明這些特徵來挑選顏色的替代方法。
**色相** 是色彩的基本屬性,就是平常所說的顏色名稱,如紅色、黃色等。 以顏色光譜爲例,光譜左邊從紅色開始,移動到中間的綠色,一直到右邊的藍色,色相值就是沿着這條線的取值。 在 `hsl()` 裏面,色相用色環來代替光譜,色相值就是色環裏面的顏色對應的從 0 到 360 度的角度值。
@@ -27,19 +27,19 @@ dashedName: adjust-the-hue-of-a-color
# --hints--
-應使用 `hsl()` 屬性來設置顏色爲 `green`。
+應使用 `hsl()` 函數來設置顏色爲 `green`。
```js
assert(code.match(/\.green\s*?{\s*?background-color\s*:\s*?hsl/gi));
```
-應使用 `hsl()` 屬性來設置顏色爲 `cyan`。
+應使用 `hsl()` 函數來設置顏色爲 `cyan`。
```js
assert(code.match(/\.cyan\s*?{\s*?background-color\s*:\s*?hsl/gi));
```
-應使用 `hsl()` 屬性來設置顏色爲 `blue`。
+應使用 `hsl()` 函數來設置顏色爲 `blue`。
```js
assert(code.match(/\.blue\s*?{\s*?background-color\s*:\s*?hsl/gi));
diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/create-a-graphic-using-css.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/create-a-graphic-using-css.md
index b2a1da0c88..bf4b287001 100644
--- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/create-a-graphic-using-css.md
+++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/create-a-graphic-using-css.md
@@ -15,11 +15,11 @@ dashedName: create-a-graphic-using-css
爲了創建一個圓形的對象,`border-radius` 應該被設置成 50%。
-你應該還記得之前關卡的 `box-shadow` 屬性以及它的依次取值 `offset-x`、`offset-y`、`blur-radius`、`spread-radius` 和顏色值。 其中 `blur-radius` 和 `spread-radius` 是可選的。
+你應該還記得之前關卡的 `box-shadow` 屬性以及它的依次取值 `offset-x`、`offset-y`、`blur-radius`、`spread-radius` 和 `color` 值。 其中 `blur-radius` 和 `spread-radius` 是可選的。
# --instructions--
-把編輯器裏的正方形元素變成新月形狀。 首先,把 `background-color` 改爲 `transparent`,接着把 `border-radius` 屬性設置成 50%,以創建一個圓形。 最後,更改 `box-shadow` 屬性,使其 `offset-x` 爲 25px,`offset-y` 爲 10px,`blur-radius` 爲 0,`spread-radius` 爲 0,顏色爲 `blue`。
+把編輯器裏的正方形元素變成新月形狀。 首先,把 `background-color` 改爲 `transparent`,接着把 `border-radius` 屬性設置成 50%,以創建一個圓形。 最後,更改 `box-shadow` 屬性,使其 `offset-x` 爲 25px,`offset-y` 爲 10px,`blur-radius` 爲 0,`spread-radius` 爲 0,`color` 爲 `blue`。
# --hints--
@@ -35,7 +35,7 @@ assert(code.match(/background-color:\s*?transparent;/gi));
assert(code.match(/border-radius:\s*?50%;/gi));
```
-更改 `box-shadow` 屬性,使其 `offset-x` 爲 25px,`offset-y` 爲 10px,`blur-radius` 爲 0,`spread-radius` 爲 0,顏色爲 `blue`。
+更改 `box-shadow` 屬性,使其 `offset-x` 爲 25px,`offset-y` 爲 10px,`blur-radius` 爲 0,`spread-radius` 爲 0,`color` 爲 `blue`。
```js
assert(
diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/create-a-more-complex-shape-using-css-and-html.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/create-a-more-complex-shape-using-css-and-html.md
index e385fae5b3..4eb3da185b 100644
--- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/create-a-more-complex-shape-using-css-and-html.md
+++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/create-a-more-complex-shape-using-css-and-html.md
@@ -28,15 +28,15 @@ dashedName: create-a-more-complex-shape-using-css-and-html
# --instructions--
-把屏幕裏的元素變成心形。 在 `heart::after` 選擇器裏,把 `background-color` 改成 `pink`,把 `border-radius` 改成 50%。
+把屏幕裏的元素變成心形。 在 `.heart::after` 選擇器裏,把 `background-color` 改成 `pink`,把 `border-radius` 改成 50%。
接下來,用類選擇器選取 class 爲 `heart`(只是 `heart`)的元素,爲它添加 `transform` 屬性。 使用 `rotate()` 函數並設置角度爲 -45 度。
-最後,在 `heart::before` 選擇器裏面,設置 `content` 屬性值爲空字符串。
+最後,在 `,heart::before` 選擇器裏面,設置 `content` 屬性值爲空字符串。
# --hints--
-`heart::after` 選擇器的 `background-color` 屬性值應爲 `pink`。
+`.heart::after` 選擇器的 `background-color` 屬性值應爲 `pink`。
```js
const heartAfter = code.match(/\.heart::after\s*{[\s\S]+?[^\}]}/g)[0];
@@ -45,7 +45,7 @@ assert(
);
```
-`heart::after` 僞元素的 `border-radius` 屬性值應爲 50%。
+`.heart::after` 僞元素的 `border-radius` 屬性值應爲 50%。
```js
assert(code.match(/border-radius\s*?:\s*?50%/gi).length == 2);
@@ -57,7 +57,7 @@ class 爲 `heart` 的元素的 `transform` 屬性應使用 `rotate()` 函數並
assert(code.match(/transform\s*?:\s*?rotate\(\s*?-45deg\s*?\)/gi));
```
-`heart::before` 僞元素的 `content` 應爲空字符串。
+`.heart::before` 僞元素的 `content` 應爲空字符串。
```js
assert(code.match(/\.heart::before\s*?{\s*?content\s*?:\s*?("|')\1\s*?;/gi));
diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/use-a-bezier-curve-to-move-a-graphic.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/use-a-bezier-curve-to-move-a-graphic.md
index 4564c6f8dc..07424eec6c 100644
--- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/use-a-bezier-curve-to-move-a-graphic.md
+++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/use-a-bezier-curve-to-move-a-graphic.md
@@ -11,7 +11,7 @@ dashedName: use-a-bezier-curve-to-move-a-graphic
前面的關卡涉及了使用 `ease-out` 預定義值描述了動畫以高速開始低速結束。 右邊的動畫展示了 `ease-out` 效果(藍色的元素)和 `linear` 效果(紅色的元素)的區別。 同樣的,`ease-out` 預定義值也可以用貝塞爾曲線函數實現。
-通俗的講,將一條直線放在範圍只有 1 的座標軸中,並從中間拿 `p1` 和 `p2` 兩個點來拉扯(X 軸的取值區間是 \[0, 1],Y 軸任意),最後形成的曲線就是動畫的貝塞爾速度曲線。 下面是貝塞爾曲線模仿 ease-out 預定義值的例子:
+通俗的講,將一條直線放在範圍只有 1 的座標軸中,並從中間拿 `p1` 和 `p2` 兩個點來拉扯(X 軸的取值區間是 \[0, 1],Y 軸任意),最後形成的曲線就是動畫的貝塞爾速度曲線。 下面是一個使用值來模仿 `ease-out` 樣式的 Bezier 曲線示例:
```css
animation-timing-function: cubic-bezier(0, 0, 0.58, 1);
diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/use-a-css-linear-gradient-to-create-a-striped-element.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/use-a-css-linear-gradient-to-create-a-striped-element.md
index 48be9ab988..4d9cc19dd4 100644
--- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/use-a-css-linear-gradient-to-create-a-striped-element.md
+++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/applied-visual-design/use-a-css-linear-gradient-to-create-a-striped-element.md
@@ -47,7 +47,7 @@ assert(!code.match(/90deg/gi));
assert(code.match(/yellow\s+?0(px)?/gi));
```
-40px 處的一個漸變顏色應該是 `yellow`。
+40 像素處的第一個色標應該是 `yellow`。
```js
assert(code.match(/yellow\s+?40px/gi));
diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/change-a-variable-for-a-specific-area.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/change-a-variable-for-a-specific-area.md
index 2bfd6c5228..ee1831a378 100644
--- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/change-a-variable-for-a-specific-area.md
+++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/change-a-variable-for-a-specific-area.md
@@ -11,7 +11,7 @@ dashedName: change-a-variable-for-a-specific-area
當你在 `:root` 裏創建變量時,這些變量的作用域是整個頁面。
-如果在元素裏創建相同的變量,會重寫作用於整個頁面的變量的值。
+然後,你可以通過在一個特定的選擇器中再次設置這些變量來重寫這些變量。
# --instructions--
@@ -27,7 +27,7 @@ assert(
);
```
-`penguin` class 不應該包含 `background-color` 屬性。
+`penguin` 類不應包含 `background-color` 屬性。
```js
assert(
diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/create-a-custom-css-variable.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/create-a-custom-css-variable.md
index e7157a9f81..80df381574 100644
--- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/create-a-custom-css-variable.md
+++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/create-a-custom-css-variable.md
@@ -15,7 +15,7 @@ dashedName: create-a-custom-css-variable
--penguin-skin: gray;
```
-這樣就會創建一個 `--penguin-skin` 變量,它的值爲 `gray`。 現在,其他元素可通過該變量來使元素變成灰色。
+這樣就會創建一個 `--penguin-skin` 變量,它的值爲 `gray`。 現在你可以在你的 CSS 中的其他地方使用這個變量來改變其他屬性的值爲灰色。
# --instructions--
diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/inherit-styles-from-the-body-element.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/inherit-styles-from-the-body-element.md
index f1a8db0a5c..92bf5bab5a 100644
--- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/inherit-styles-from-the-body-element.md
+++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/inherit-styles-from-the-body-element.md
@@ -77,7 +77,7 @@ assert(
);
```
-`h1` 元素的字體顏色應繼承 `body` 元素所設置的綠色。
+`h1` 元素應該繼承 `body` 的 `green` 顏色屬性。
```js
assert($('h1').length > 0 && $('h1').css('color') === 'rgb(0, 128, 0)');
diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/use-a-media-query-to-change-a-variable.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/use-a-media-query-to-change-a-variable.md
index 3ec6d996c1..d66d48f7c9 100644
--- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/use-a-media-query-to-change-a-variable.md
+++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/use-a-media-query-to-change-a-variable.md
@@ -15,7 +15,7 @@ CSS 變量可以簡化媒體查詢的定義方式。
# --instructions--
-在 `media query`(媒體查詢)聲明的 `:root` 選擇器裏,重定義 `--penguin-size` 的值爲 `200px`。 同時,重新定義 `--penguin-skin` 的值爲 `black`, 然後通過縮放頁面來查看它們是否生效。
+在媒體查詢聲明的 `:root` 選擇器裏,重定義 `--penguin-size` 的值爲 `200px`。 同時,重新定義 `--penguin-skin` 的值爲 `black`, 然後通過縮放頁面來查看它們是否生效。
# --hints--
diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/use-abbreviated-hex-code.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/use-abbreviated-hex-code.md
index f4f0454fb6..ec1049f8fe 100644
--- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/use-abbreviated-hex-code.md
+++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/use-abbreviated-hex-code.md
@@ -29,7 +29,7 @@ dashedName: use-abbreviated-hex-code
assert($('.red-text').css('color') === 'rgb(255, 0, 0)');
```
-應使用紅色的 `hex code` 縮寫形式,不應使用 `#FF0000`。
+應使用紅色的縮寫十六進制代碼,而不是十六進制代碼 `#FF0000`。
```js
assert(code.match(/\.red-text\s*?{\s*?color\s*:\s*?#F00\s*?;?\s*?}/gi));
@@ -41,7 +41,7 @@ assert(code.match(/\.red-text\s*?{\s*?color\s*:\s*?#F00\s*?;?\s*?}/gi));
assert($('.green-text').css('color') === 'rgb(0, 255, 0)');
```
-應使用綠色的 `hex code` 縮寫形式,不應使用 `#00FF00`。
+應使用綠色的縮寫十六進制代碼,而不是十六進制代碼 `#00FF00`。
```js
assert(code.match(/\.green-text\s*?{\s*?color\s*:\s*?#0F0\s*?;?\s*?}/gi));
@@ -53,7 +53,7 @@ assert(code.match(/\.green-text\s*?{\s*?color\s*:\s*?#0F0\s*?;?\s*?}/gi));
assert($('.cyan-text').css('color') === 'rgb(0, 255, 255)');
```
-應使用藍綠色的 `hex code` 縮寫形式,不應使用 `#00FFFF`。
+應使用青色的簡寫十六進制代碼,而不是十六進制代碼 `#00FFFF`。
```js
assert(code.match(/\.cyan-text\s*?{\s*?color\s*:\s*?#0FF\s*?;?\s*?}/gi));
@@ -65,7 +65,7 @@ assert(code.match(/\.cyan-text\s*?{\s*?color\s*:\s*?#0FF\s*?;?\s*?}/gi));
assert($('.fuchsia-text').css('color') === 'rgb(255, 0, 255)');
```
-應使用紫紅色的 `hex code` 縮寫形式,不應使用 `#FF00FF`。
+應使用紫紅色的簡寫十六進制代碼,而不是十六進制代碼 `#FF00FF`。
```js
assert(code.match(/\.fuchsia-text\s*?{\s*?color\s*:\s*?#F0F\s*?;?\s*?}/gi));
diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/use-hex-code-for-specific-colors.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/use-hex-code-for-specific-colors.md
index cc5a1a8206..ebe2bb1610 100644
--- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/use-hex-code-for-specific-colors.md
+++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-css/use-hex-code-for-specific-colors.md
@@ -27,13 +27,13 @@ body {
# --hints--
-`body` 元素的背景顏色應爲黑色。
+`body` 元素的 `background-color` 應爲黑色。
```js
assert($('body').css('background-color') === 'rgb(0, 0, 0)');
```
-應使用 `hex code` 來替換 `black`。
+應該使用黑色的十六進制代碼,而不是 `black` 這個詞。
```js
assert(
diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-html-and-html5/check-radio-buttons-and-checkboxes-by-default.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-html-and-html5/check-radio-buttons-and-checkboxes-by-default.md
index 618ece4fab..4f8c4786e8 100644
--- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-html-and-html5/check-radio-buttons-and-checkboxes-by-default.md
+++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-html-and-html5/check-radio-buttons-and-checkboxes-by-default.md
@@ -11,7 +11,7 @@ dashedName: check-radio-buttons-and-checkboxes-by-default
用 `checked` 屬性把第一個複選框和單選按鈕都設置爲默認選中。
-在一個 input 元素裏面添加 `checked` 這個詞,即可實現。 例如:
+爲此,只需將單詞 `checked` 添加到 `input` 元素的內部。 例如:
```html
diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-html-and-html5/comment-out-html.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-html-and-html5/comment-out-html.md
index 8ad833626d..4c736b33f8 100644
--- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-html-and-html5/comment-out-html.md
+++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-html-and-html5/comment-out-html.md
@@ -43,7 +43,7 @@ assert($('p').length === 0);
assert(code.match(/[^fc]-->/g).length > 1);
```
-不要更改 `h1` 元素、`h2` 元素、`p` 元素的順序。
+不要更改 `h1`、`h2`、`p` 元素的順序。
```js
assert(
diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-html-and-html5/inform-with-the-paragraph-element.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-html-and-html5/inform-with-the-paragraph-element.md
index 46626220fa..5bf539ee7e 100644
--- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-html-and-html5/inform-with-the-paragraph-element.md
+++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/basic-html-and-html5/inform-with-the-paragraph-element.md
@@ -9,7 +9,7 @@ dashedName: inform-with-the-paragraph-element
# --description--
-`p` 元素是網站上段落文本使用的元素。 `p` 是“paragraph(段落)”的縮寫。
+`p` 元素是網站上段落文本的首選元素。 `p` 是“paragraph(段落)”的縮寫。
你可以像這樣創建一個段落:
diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/css-flexbox/align-elements-using-the-justify-content-property.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/css-flexbox/align-elements-using-the-justify-content-property.md
index 9523daa918..8ffd31a75d 100644
--- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/css-flexbox/align-elements-using-the-justify-content-property.md
+++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/css-flexbox/align-elements-using-the-justify-content-property.md
@@ -17,7 +17,7 @@ flex 子元素有時不能充滿整個 flex 容器, 所以我們經常需要
對於如何沿主軸線排放 flex 項目,有幾種選擇。 很常用的一種是 `justify-content: center;`:即 flex 子元素在 flex 容器中居中排列。 其他選擇包括:
-flex-start
:從 flex 容器的起始位置開始排列項目。 對行來說是把項目移至左邊, 對於列是把項目移至頂部。 如未設置 justify-content
的值,那麼這就是默認值。flex-end
:從 flex 容器的終止位置開始排列項目。 對行來說是把項目移至右邊, 對於列是把項目移至底部。space-between
:項目間保留一定間距地沿主軸居中排列。 第一個和最後一個項目被放置在容器邊沿。 例如,在行中第一個項目會緊貼着容器左邊,最後一個項目會緊貼着容器右邊,然後其他項目均勻排布。space-around
:與space-between
相似,但頭尾兩個項目不會緊貼容器邊緣,所有項目之間的空間均勻排布。space-evenly
:頭尾兩個項目不會緊貼容器邊緣,所有項目之間的空間均勻排布。
+flex-start
:從 flex 容器的起始位置開始排列項目。 對行來說是把項目移至左邊, 對於列是把項目移至頂部。 如未設置 justify-content
的值,那麼這就是默認值。flex-end
:從 flex 容器的終止位置開始排列項目。 對行來說是把項目移至右邊, 對於列是把項目移至底部。space-between
:項目間保留一定間距地沿主軸居中排列。 第一個和最後一個項目被放置在容器邊沿。 例如,在行中第一個項目會緊貼着容器左邊,最後一個項目會緊貼着容器右邊,然後其他項目均勻排布。space-around
:與space-between
相似,但頭尾兩個項目不會緊貼容器邊緣,所有項目之間的空間均勻排布。space-evenly
:在 flex 項目之間均勻分配空間,在 flex 容器的任一端都有一個完整的空間。
# --instructions--
diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/css-flexbox/use-the-flex-wrap-property-to-wrap-a-row-or-column.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/css-flexbox/use-the-flex-wrap-property-to-wrap-a-row-or-column.md
index 213cbe47ed..d66fe12ddc 100644
--- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/css-flexbox/use-the-flex-wrap-property-to-wrap-a-row-or-column.md
+++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/css-flexbox/use-the-flex-wrap-property-to-wrap-a-row-or-column.md
@@ -9,7 +9,7 @@ dashedName: use-the-flex-wrap-property-to-wrap-a-row-or-column
# --description--
-CSS flexbox 有一個把 flex 子元素拆分爲多行(或多列)的特性。 默認情況下,flex 容器會調整項目大小,把它們都塞到一起。 對於行來說,所有項目都會在一條直線上。
+CSS flexbox 具有將 flex 容器拆分爲多行(或列)的功能。 默認情況下,flex 容器會調整項目大小,把它們都塞到一起。 對於行來說,所有項目都會在一條直線上。
不過,使用 `flex-wrap` 屬性可以使項目換行展示。 這意味着多出來的子元素會被移到新的行或列。 換行發生的斷點由子元素和容器的大小決定。
diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/css-grid/place-items-in-grid-areas-using-the-grid-area-property.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/css-grid/place-items-in-grid-areas-using-the-grid-area-property.md
index af1df38e53..d366b7adcd 100644
--- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/css-grid/place-items-in-grid-areas-using-the-grid-area-property.md
+++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/css-grid/place-items-in-grid-areas-using-the-grid-area-property.md
@@ -17,7 +17,7 @@ dashedName: place-items-in-grid-areas-using-the-grid-area-property
}
```
-這樣,class 爲 `item1` 的網格項就被放到了 `header` 區域裏。 在這個示例中,網格項將佔用第一行整行,因爲這一整行都被命名爲標題區域。
+這樣,class 爲 `item1` 的網格項就被放到了 `header` 區域裏。 在這種情況下,該項目將使用整個頂行,因爲該整行被命名爲 `header` 區域。
# --instructions--
diff --git a/curriculum/challenges/chinese-traditional/01-responsive-web-design/css-grid/use-css-grid-units-to-change-the-size-of-columns-and-rows.md b/curriculum/challenges/chinese-traditional/01-responsive-web-design/css-grid/use-css-grid-units-to-change-the-size-of-columns-and-rows.md
index 5eb6ad0470..de2781f1ed 100644
--- a/curriculum/challenges/chinese-traditional/01-responsive-web-design/css-grid/use-css-grid-units-to-change-the-size-of-columns-and-rows.md
+++ b/curriculum/challenges/chinese-traditional/01-responsive-web-design/css-grid/use-css-grid-units-to-change-the-size-of-columns-and-rows.md
@@ -31,7 +31,7 @@ grid-template-columns: auto 50px 10% 2fr 1fr;
# --hints--
-class 爲 `container` 的元素應具有 `grid-template-columns` 屬性且屬性值應爲 `1fr 100px 2fr`。
+`container` 類應該有一個 `grid-template-columns` 屬性,該屬性具有以下寬度的三列:`1fr`、`100px` 和 `2fr`。
```js
assert(
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-algorithm-scripting/convert-celsius-to-fahrenheit.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-algorithm-scripting/convert-celsius-to-fahrenheit.md
index 2d320ffa6c..7d6aad7e37 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-algorithm-scripting/convert-celsius-to-fahrenheit.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-algorithm-scripting/convert-celsius-to-fahrenheit.md
@@ -8,9 +8,9 @@ dashedName: convert-celsius-to-fahrenheit
# --description--
-將攝氏度轉換爲華氏度的計算方式爲:攝氏度乘以 `9/5` 然後加上 `32`。
+從攝氏轉換爲華氏的公式是,攝氏溫度乘以 `9/5`,再加上 `32`。
-輸入參數 `celsius` 代表一個攝氏度的溫度。 使用已定義的變量 `fahrenheit`,並賦值爲相應的華氏度的溫度值。 根據上述轉換公式來進行轉換。
+輸入參數 `celsius` 代表一個攝氏度的溫度。 使用已定義的變量 `fahrenheit`,並賦值爲相應的華氏度的溫度值。 使用上面提到的公式來幫助將攝氏溫度轉換爲華氏溫度。
# --hints--
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-data-structures/check-if-an-object-has-a-property.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-data-structures/check-if-an-object-has-a-property.md
index 942ea6fef7..f0f51ba526 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-data-structures/check-if-an-object-has-a-property.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-data-structures/check-if-an-object-has-a-property.md
@@ -19,7 +19,7 @@ users.hasOwnProperty('Alan');
# --instructions--
-請完善這個函數,如果傳遞給它的對象包含四個名字 `Alan`、`Jeff`、`Sarah` 和 `Ryan`,函數返回 true,否則返回 false。
+請完善這個函數,如果傳遞給它的對象包含四個名字 `Alan`、`Jeff`、`Sarah` 和 `Ryan`,函數返回 `true`,否則返回 `false`。
# --hints--
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-data-structures/remove-items-using-splice.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-data-structures/remove-items-using-splice.md
index 8e0fd29240..c2e13a57f3 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-data-structures/remove-items-using-splice.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-data-structures/remove-items-using-splice.md
@@ -10,7 +10,7 @@ dashedName: remove-items-using-splice
在之前的挑戰中,我們已經學習瞭如何用 `shift()` 和 `pop()` 從數組的開頭或末尾移除元素。 但如果我們想刪除數組中間的一個元素, 或者想一次刪除多個元素,該如何操作呢? 這時候我們就需要使用 `splice()` 方法了, `splice()` 可以讓我們從數組中的任意位置**連續刪除任意數量的元素**。
-`splice()` 最多可以接受 3 個參數,但現在我們先關注前兩個。 `splice()` 接收的前兩個參數是整數,表示正在調用 的`splice()` 數組中的元素的索引或位置。 別忘了,數組的索引是*從 0 開始的*,所以我們要用 `0` 來表示數組中的第一個元素。 `splice()` 的第一個參數代表從數組中的哪個索引開始移除元素,而第二個參數表示要從數組中的這個位置開始刪除多少個元素。 例如:
+`splice()` 最多可以接受 3 個參數,但現在我們先關注前兩個。 `splice()` 的前兩個參數是整數,表示數組中調用 `splice()` 的項的索引或位置。 別忘了,數組的索引是*從 0 開始的*,所以我們要用 `0` 來表示數組中的第一個元素。 `splice()` 的第一個參數代表從數組中的哪個索引開始移除元素,而第二個參數表示要從數組中的這個位置開始刪除多少個元素。 例如:
```js
let array = ['today', 'was', 'not', 'so', 'great'];
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-inequality-operator.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-inequality-operator.md
index a5e888650e..c584133299 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-inequality-operator.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-inequality-operator.md
@@ -14,18 +14,16 @@ dashedName: comparison-with-the-inequality-operator
**例如**
```js
-1 != 2
-1 != "1"
-1 != '1'
-1 != true
-0 != false
+1 != 2 // true
+1 != "1" // false
+1 != '1' // false
+1 != true // false
+0 != false // false
```
-按順序,這些表達式會返回 `true`、`false`、`false`、`false` 和 `false`。
-
# --instructions--
-在 `if` 語句中添加不等運算符 `!=` 以便函數在 `val` 不等於 `99` 時返回字符串 `Not Equal`。
+在 `if` 語句中添加不等式運算符 `!=` 以便函數在 `val` 不等於 `99` 時返回字符串 `Not Equal`。
# --hints--
@@ -59,7 +57,7 @@ assert(testNotEqual('12') === 'Not Equal');
assert(testNotEqual('bob') === 'Not Equal');
```
-你應該使用 `!=` 運算符。
+你應該使用 `!=` 運算符
```js
assert(code.match(/(?!!==)!=/));
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-less-than-operator.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-less-than-operator.md
index 894ffb329d..3cfac46864 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-less-than-operator.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-less-than-operator.md
@@ -14,58 +14,56 @@ dashedName: comparison-with-the-less-than-operator
**例如:**
```js
-2 < 5
-'3' < 7
-5 < 5
-3 < 2
-'8' < 4
+2 < 5 // true
+'3' < 7 // true
+5 < 5 // false
+3 < 2 // false
+'8' < 4 // false
```
-按順序,這些表達式會返回 `true`、`true`、`false`、`false` 和 `false`。
-
# --instructions--
-添加小於運算符到指定行,使得函數的返回語句有意義。
+將小於運算符添加到指示的行,以便返回語句有意義。
# --hints--
-`testLessThan(0)` 應該返回字符串 `Under 25`。
+`testLessThan(0)` 應該返回字符串 `Under 25`
```js
assert(testLessThan(0) === 'Under 25');
```
-`testLessThan(24)` 應該返回字符串 `Under 25`。
+`testLessThan(24)` 應該返回字符串 `Under 25`
```js
assert(testLessThan(24) === 'Under 25');
```
-`testLessThan(25)` 應該返回字符串 `Under 55`。
+`testLessThan(25)` 應該返回字符串 `Under 55`
```js
assert(testLessThan(25) === 'Under 55');
```
-`testLessThan(54)` 應該返回字符串 `Under 55`。
+`testLessThan(54)` 應該返回字符串 `Under 55`
```js
assert(testLessThan(54) === 'Under 55');
```
-`testLessThan(55)` 應該返回字符串 `55 or Over`。
+`testLessThan(55)` 應該返回字符串 `55 or Over`
```js
assert(testLessThan(55) === '55 or Over');
```
-`testLessThan(99)` 應該返回字符串 `55 or Over`。
+`testLessThan(99)` 應該返回字符串 `55 or Over`
```js
assert(testLessThan(99) === '55 or Over');
```
-應該使用 `<` 運算符至少兩次。
+應該使用 `<` 運算符至少兩次
```js
assert(code.match(/val\s*<\s*('|")*\d+('|")*/g).length > 1);
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-less-than-or-equal-to-operator.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-less-than-or-equal-to-operator.md
index 02a099677b..da386b35ec 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-less-than-or-equal-to-operator.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-less-than-or-equal-to-operator.md
@@ -14,18 +14,16 @@ dashedName: comparison-with-the-less-than-or-equal-to-operator
**例如**
```js
-4 <= 5
-'7' <= 7
-5 <= 5
-3 <= 2
-'8' <= 4
+4 <= 5 // true
+'7' <= 7 // true
+5 <= 5 // true
+3 <= 2 // false
+'8' <= 4 // false
```
-按順序,這些表達式會返回 `true`、`true`、`true`、`false` 和 `false`。
-
# --instructions--
-添加小於等於運算符到指定行,使得函數的返回語句有意義。
+將小於或等於運算符添加到指示的行,以便返回語句有意義。
# --hints--
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-equality-operator.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-equality-operator.md
index a2c7cd312c..784409a7ed 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-equality-operator.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-equality-operator.md
@@ -16,17 +16,15 @@ dashedName: comparison-with-the-strict-equality-operator
**示例**
```js
-3 === 3
-3 === '3'
+3 === 3 // true
+3 === '3' // false
```
-這些條件將分別返回 `true` and `false`。
-
在第二個例子中,`3` 是一個 `Number` 類型,而 `'3'` 是一個 `String` 類型。
# --instructions--
-在 `if` 語句中使用嚴格相等運算符,這樣當 `val` 嚴格等於 `7` 時,函數將返回字符串 `Equal`。
+在 `if` 語句中使用嚴格相等運算符,這樣函數將在 `val` 嚴格等於 `7` 時返回字符串 `Equal`。
# --hints--
@@ -48,7 +46,7 @@ assert(testStrict(7) === 'Equal');
assert(testStrict('7') === 'Not Equal');
```
-你應該使用 `===` 運算符。
+應該使用 `===` 運算符
```js
assert(code.match(/(val\s*===\s*\d+)|(\d+\s*===\s*val)/g).length > 0);
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-inequality-operator.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-inequality-operator.md
index 89487b9757..2dff6ed7fe 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-inequality-operator.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-inequality-operator.md
@@ -14,13 +14,11 @@ dashedName: comparison-with-the-strict-inequality-operator
**示例**
```js
-3 !== 3
-3 !== '3'
-4 !== 3
+3 !== 3 // false
+3 !== '3' // true
+4 !== 3 // true
```
-按順序,這些表達式會返回 `false`、`true`、`true`。
-
# --instructions--
在 `if` 語句中,添加嚴格不相等運算符,這樣函數在當 `val` 不嚴格等於 `17` 的時候,會返回 `Not Equal`。
@@ -51,7 +49,7 @@ assert(testStrictNotEqual(12) === 'Not Equal');
assert(testStrictNotEqual('bob') === 'Not Equal');
```
-應該使用 `!==` 運算符。
+應該使用 `!==` 運算符
```js
assert(code.match(/(val\s*!==\s*\d+)|(\d+\s*!==\s*val)/g).length > 0);
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/counting-cards.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/counting-cards.md
index fe9c860c58..facfb5dedd 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/counting-cards.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/counting-cards.md
@@ -25,7 +25,7 @@ dashedName: counting-cards
# --hints--
-卡牌序列 2、3、4、5、6 應該返回 `5 Bet`
+卡片序列 2、3、4、5、6 應返回字符串 `5 Bet`
```js
assert(
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/declare-a-read-only-variable-with-the-const-keyword.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/declare-a-read-only-variable-with-the-const-keyword.md
index 96d4da3c80..a60941f01c 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/declare-a-read-only-variable-with-the-const-keyword.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/declare-a-read-only-variable-with-the-const-keyword.md
@@ -21,32 +21,28 @@ FAV_PET = "Dogs";
你應該始終使用 `const` 關鍵字命名不想重新分配的變量。 這有助於避免給一個常量進行額外的再次賦值。
-命名常量的常見做法是全部使用大寫字母,單詞之間用下劃線分隔。
-
-**注意:** 對於不可變值,開發人員通常使用大寫變量標識符,對可變值(對象和數組)使用小寫或駝峯式標識符。 你將在後面的挑戰中瞭解有關對象、數組以及不可變和可變值的更多信息。 同樣在後面的挑戰中,你將看到大寫、小寫或駝峯式變量標識符的示例。
+**注意:** 通常,開發者會用大寫字母作爲常量標識符,用小寫字母或者駝峯命名作爲變量(對象或數組)標識符。 你將在後面的挑戰中瞭解有關對象、數組以及不可變和可變值的更多信息。 同樣在後面的挑戰中,你將看到大寫、小寫或駝峯式變量標識符的示例。
# --instructions--
-更改代碼,以便使用 `let` 或 `const` 聲明所有變量。 當你希望變量改變時使用 `let`,而當你希望變量保持不變時使用 `const`。 此外,重命名用 `const` 聲明的變量以符合常見做法,這意味着常量應該全部大寫。
+更改代碼,以便使用 `let` 或 `const` 聲明所有變量。 當你想要改變變量時使用 `let`,當你想要變量保持不變時使用 `const`。 此外,重命名使用 `const` 聲明的變量以符合慣例。
# --hints--
-`var` 不應存在於你的代碼中。
+代碼中不應有 `var`。
```js
-(getUserInput) => assert(!getUserInput('index').match(/var/g));
+assert.notMatch(code, /var/g);
```
你應該將 `fCC` 更改爲全部大寫。
```js
-(getUserInput) => {
- assert(getUserInput('index').match(/(FCC)/));
- assert(!getUserInput('index').match(/fCC/));
-}
+assert.match(code, /(FCC)/);
+assert.notMatch(code, /(fCC)/);
```
-`FCC` 應該是一個用 `const` 聲明的常量變量。
+`FCC` 應該是一個用 `const` 聲明的常量。
```js
assert.equal(FCC, 'freeCodeCamp');
@@ -56,14 +52,13 @@ assert.match(code, /const\s+FCC/);
`fact` 應該用 `let` 聲明。
```js
-(getUserInput) => assert(getUserInput('index').match(/(let fact)/g));
+assert.match(code, /(let\s+fact)/g);
```
`console.log` 應該更改爲打印 `FCC` 和 `fact` 變量。
```js
-(getUserInput) =>
- assert(getUserInput('index').match(/console\.log\(\s*FCC\s*\,\s*fact\s*\)\s*;?/g));
+assert.match(code, /console\.log\(\s*FCC\s*\,\s*fact\s*\)\s*;?/g);
```
# --seed--
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/decrement-a-number-with-javascript.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/decrement-a-number-with-javascript.md
index 936ad97e8e..81e322ff7c 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/decrement-a-number-with-javascript.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/decrement-a-number-with-javascript.md
@@ -38,9 +38,13 @@ assert(myVar === 10);
應該修改 `myVar = myVar - 1;`。
```js
-assert(
- /let\s*myVar\s*=\s*11;\s*\/*.*\s*([-]{2}\s*myVar|myVar\s*[-]{2});/.test(code)
-);
+assert(!code.match(/myVar\s*=\s*myVar\s*[-]\s*1.*?;?/));
+```
+
+你不應將 `10` 分配給 `myVar`。
+
+```js
+assert(!code.match(/myVar\s*=\s*10.*?;?/));
```
應該對 `myVar` 使用 `--` 運算符。
@@ -49,7 +53,7 @@ assert(
assert(/[-]{2}\s*myVar|myVar\s*[-]{2}/.test(code));
```
-不應修改註釋上方的代碼。
+你不應該修改註釋上面的代碼。
```js
assert(/let myVar = 11;/.test(code));
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/local-scope-and-functions.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/local-scope-and-functions.md
index a3af68c767..628ae3dcb8 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/local-scope-and-functions.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/local-scope-and-functions.md
@@ -23,7 +23,7 @@ myTest();
console.log(loc);
```
-`myTest()` 函數調用將在控制檯中顯示字符串 `foo`。 `console.log(loc)` 行會產生一個錯誤,因爲 `loc` 沒有定義在函數之外。
+`myTest()` 函數調用將在控制檯中顯示字符串 `foo`。 `console.log(loc)` 行(在 `myTest` 函數之外)將拋出錯誤,因爲 `loc` 未在函數之外定義。
# --instructions--
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/record-collection.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/record-collection.md
index 2c700ef03f..81b1216dc3 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/record-collection.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/record-collection.md
@@ -31,13 +31,13 @@ assert(
);
```
-執行 `updateRecords(recordCollection, 5439, "tracks", "Take a Chance on Me")` 後,`tracks` 的最後一個元素應該爲字符串 `Take a Chance on Me`。
+在 `updateRecords(recordCollection, 5439, "tracks", "Take a Chance on Me")` 之後,`tracks` 應該有字符串 `Take a Chance on Me` 作爲最後一個也是唯一的元素。
```js
assert(
- updateRecords(_recordCollection, 5439, 'tracks', 'Take a Chance on Me')[5439][
- 'tracks'
- ].pop() === 'Take a Chance on Me'
+ updateRecords(_recordCollection, 5439, 'tracks', 'Take a Chance on Me') &&
+ _recordCollection[5439]['tracks'].length === 1 &&
+ _recordCollection[5439]['tracks'].pop() === 'Take a Chance on Me'
);
```
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/understanding-uninitialized-variables.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/understanding-uninitialized-variables.md
index 540036f5c2..3210dfa7c1 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/understanding-uninitialized-variables.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/understanding-uninitialized-variables.md
@@ -9,7 +9,7 @@ dashedName: understanding-uninitialized-variables
# --description--
-當 JavaScript 中的變量被聲明的時候,程序內部會給它一個初始值 `undefined`。 當你對一個值爲 `undefined` 的變量進行運算操作的時候,算出來的結果將會是 `NaN`,它的意思是 "Not a Number" 。 當你用一個值是 `undefined` 的變量來做字符串拼接操作的時候,它會轉換成字符串(string )`undefined`。
+當 JavaScript 中的變量被聲明的時候,程序內部會給它一個初始值 `undefined`。 當你對一個值爲 `undefined` 的變量進行運算操作的時候,算出來的結果將會是 `NaN`,它的意思是 "Not a Number" 。 如果你用 `undefined` 變量連接一個字符串,你將得到一個 `undefined` 的 字符串 。
# --instructions--
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md
index 47dff8295c..1f41c91343 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md
@@ -41,7 +41,7 @@ assert(firstLetterOfLastName === 'L');
應該使用方括號表示法。
```js
-assert(code.match(/firstLetterOfLastName\s*?=\s*?lastName\[.*?\]/));
+assert(code.match(/firstLetterOfLastName\s*=\s*lastName\s*\[\s*\d\s*\]/));
```
# --seed--
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md
index b48a3627a5..23babc5302 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md
@@ -39,7 +39,7 @@ assert(thirdLetterOfLastName === 'v');
應該使用方括號表示法。
```js
-assert(code.match(/thirdLetterOfLastName\s*?=\s*?lastName\[.*?\]/));
+assert(code.match(/thirdLetterOfLastName\s*=\s*lastName\s*\[\s*\d\s*\]/));
```
# --seed--
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/functional-programming/refactor-global-variables-out-of-functions.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/functional-programming/refactor-global-variables-out-of-functions.md
index 0f96ede20c..0ac50d3144 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/functional-programming/refactor-global-variables-out-of-functions.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/functional-programming/refactor-global-variables-out-of-functions.md
@@ -27,6 +27,7 @@ dashedName: refactor-global-variables-out-of-functions
`bookList` 應等於 `["The Hound of the Baskervilles", "On The Electrodynamics of Moving Bodies", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae"]`.
```js
+add(bookList, "Test");
assert(
JSON.stringify(bookList) ===
JSON.stringify([
@@ -38,11 +39,11 @@ assert(
);
```
-`newBookList` 應等於 `["The Hound of the Baskervilles", "On The Electrodynamics of Moving Bodies", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae", "A Brief History of Time"]`.
+`add(bookList, "A Brief History of Time")` 應該返回 `["The Hound of the Baskervilles", "On The Electrodynamics of Moving Bodies", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae", "A Brief History of Time"]`。
```js
assert(
- JSON.stringify(newBookList) ===
+ JSON.stringify(add(bookList, "A Brief History of Time")) ===
JSON.stringify([
'The Hound of the Baskervilles',
'On The Electrodynamics of Moving Bodies',
@@ -53,11 +54,11 @@ assert(
);
```
-`newerBookList` 應等於 `["The Hound of the Baskervilles", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae"]`.
+`remove(bookList, "On The Electrodynamics of Moving Bodies")` 應該返回 `["The Hound of the Baskervilles", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae"]`。
```js
assert(
- JSON.stringify(newerBookList) ===
+ JSON.stringify(remove(bookList, 'On The Electrodynamics of Moving Bodies')) ===
JSON.stringify([
'The Hound of the Baskervilles',
'Philosophiæ Naturalis Principia Mathematica',
@@ -66,11 +67,11 @@ assert(
);
```
-`newestBookList` 應等於 `["The Hound of the Baskervilles", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae", "A Brief History of Time"]`.
+`remove(add(bookList, "A Brief History of Time"), "On The Electrodynamics of Moving Bodies");` 應該返回 `["The Hound of the Baskervilles", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae", "A Brief History of Time"]`。
```js
assert(
- JSON.stringify(newestBookList) ===
+ JSON.stringify(remove(add(bookList, 'A Brief History of Time'), 'On The Electrodynamics of Moving Bodies')) ===
JSON.stringify([
'The Hound of the Baskervilles',
'Philosophiæ Naturalis Principia Mathematica',
@@ -108,12 +109,6 @@ function remove(bookName) {
// Change code above this line
}
}
-
-const newBookList = add(bookList, 'A Brief History of Time');
-const newerBookList = remove(bookList, 'On The Electrodynamics of Moving Bodies');
-const newestBookList = remove(add(bookList, 'A Brief History of Time'), 'On The Electrodynamics of Moving Bodies');
-
-console.log(bookList);
```
# --solutions--
@@ -134,8 +129,4 @@ function remove(bookList, bookName) {
}
return bookListCopy;
}
-
-const newBookList = add(bookList, 'A Brief History of Time');
-const newerBookList = remove(bookList, 'On The Electrodynamics of Moving Bodies');
-const newestBookList = remove(add(bookList, 'A Brief History of Time'), 'On The Electrodynamics of Moving Bodies');
```
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/arguments-optional.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/arguments-optional.md
index 931c039647..c1fe4ee756 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/arguments-optional.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/arguments-optional.md
@@ -60,6 +60,12 @@ assert.isUndefined(addTogether(2, '3'));
assert.isUndefined(addTogether(2)([3]));
```
+`addTogether("2", 3)` 應該返回 `undefined`。
+
+```js
+assert.isUndefined(addTogether('2', 3));
+```
+
# --seed--
## --seed-contents--
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/everything-be-true.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/everything-be-true.md
index b11a7b8784..59d7ae2bbe 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/everything-be-true.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/everything-be-true.md
@@ -18,120 +18,123 @@ JavaScript 中,如果一個值在 Boolean 的上下文中的執行結果爲 `t
# --hints--
-`truthCheck([{"user": "Tinky-Winky", "sex": "male"}, {"user": "Dipsy", "sex": "male"}, {"user": "Laa-Laa", "sex": "female"}, {"user": "Po", "sex": "female"}], "sex")` 應返回 `true`。
+`truthCheck([{name: "Quincy", role: "Founder", isBot: false}, {name: "Naomi", role: "", isBot: false}, {name: "Camperbot", role: "Bot", isBot: true}], "isBot")` 應該返回 `false`。
```js
-assert.strictEqual(
- truthCheck(
- [
- { user: 'Tinky-Winky', sex: 'male' },
- { user: 'Dipsy', sex: 'male' },
- { user: 'Laa-Laa', sex: 'female' },
- { user: 'Po', sex: 'female' }
- ],
- 'sex'
- ),
- true
-);
+assert.strictEqual(truthCheck(
+ [
+ { name: "Quincy", role: "Founder", isBot: false },
+ { name: "Naomi", role: "", isBot: false },
+ { name: "Camperbot", role: "Bot", isBot: true }
+ ],
+ "isBot"), false);
```
-`truthCheck([{"user": "Tinky-Winky", "sex": "male"}, {"user": "Dipsy"}, {"user": "Laa-Laa", "sex": "female"}, {"user": "Po", "sex": "female"}], "sex")` 應返回 `false`。
+`truthCheck([{name: "Quincy", role: "Founder", isBot: false}, {name: "Naomi", role: "", isBot: false}, {name: "Camperbot", role: "Bot", isBot: true}], "name")` 應該返回 `true`。
```js
-assert.strictEqual(
- truthCheck(
- [
- { user: 'Tinky-Winky', sex: 'male' },
- { user: 'Dipsy' },
- { user: 'Laa-Laa', sex: 'female' },
- { user: 'Po', sex: 'female' }
- ],
- 'sex'
- ),
- false
-);
+assert.strictEqual(truthCheck(
+ [
+ { name: "Quincy", role: "Founder", isBot: false },
+ { name: "Naomi", role: "", isBot: false },
+ { name: "Camperbot", role: "Bot", isBot: true }
+ ],
+ "name"), true);
```
-`truthCheck([{"user": "Tinky-Winky", "sex": "male", "age": 0}, {"user": "Dipsy", "sex": "male", "age": 3}, {"user": "Laa-Laa", "sex": "female", "age": 5}, {"user": "Po", "sex": "female", "age": 4}], "age")` 應返回 `false`。
+`truthCheck([{name: "Quincy", role: "Founder", isBot: false}, {name: "Naomi", role: "", isBot: false}, {name: "Camperbot", role: "Bot", isBot: true}], "role")` 應該返回 `false`。
```js
-assert.strictEqual(
- truthCheck(
- [
- { user: 'Tinky-Winky', sex: 'male', age: 2 },
- { user: 'Dipsy', sex: 'male', age: 0 },
- { user: 'Laa-Laa', sex: 'female', age: 5 },
- { user: 'Po', sex: 'female', age: 4 }
- ],
- 'age'
- ),
- false
-);
+assert.strictEqual(truthCheck(
+ [
+ { name: "Quincy", role: "Founder", isBot: false },
+ { name: "Naomi", role: "", isBot: false },
+ { name: "Camperbot", role: "Bot", isBot: true }
+ ],
+ "role"), false);
```
-`truthCheck([{"name": "Pete", "onBoat": true}, {"name": "Repeat", "onBoat": true}, {"name": "FastForward", "onBoat": null}], "onBoat")` 應返回 `false`。
+`truthCheck([{name: "Pikachu", number: 25, caught: 3}, {name: "Togepi", number: 175, caught: 1}], "number")` 應該返回 `true`。
```js
-assert.strictEqual(
- truthCheck(
- [
- { name: 'Pete', onBoat: true },
- { name: 'Repeat', onBoat: true },
- { name: 'FastForward', onBoat: null }
- ],
- 'onBoat'
- ),
- false
-);
+assert.strictEqual(truthCheck(
+ [
+ { name: "Pikachu", number: 25, caught: 3 },
+ { name: "Togepi", number: 175, caught: 1 },
+ ],
+ "number"), true);
```
-`truthCheck([{"name": "Pete", "onBoat": true}, {"name": "Repeat", "onBoat": true, "alias": "Repete"}, {"name": "FastForward", "onBoat": true}], "onBoat")` 應返回 `true`。
+`truthCheck([{name: "Pikachu", number: 25, caught: 3}, {name: "Togepi", number: 175, caught: 1}, {name: "MissingNo", number: NaN, caught: 0}], "caught")` 應該返回 `false`。
```js
-assert.strictEqual(
- truthCheck(
- [
- { name: 'Pete', onBoat: true },
- { name: 'Repeat', onBoat: true, alias: 'Repete' },
- { name: 'FastForward', onBoat: true }
- ],
- 'onBoat'
- ),
- true
-);
+assert.strictEqual(truthCheck(
+ [
+ { name: "Pikachu", number: 25, caught: 3 },
+ { name: "Togepi", number: 175, caught: 1 },
+ { name: "MissingNo", number: NaN, caught: 0 },
+ ],
+ "caught"), false);
```
-`truthCheck([{"single": "yes"}], "single")` 應返回 `true`。
+`truthCheck([{name: "Pikachu", number: 25, caught: 3}, {name: "Togepi", number: 175, caught: 1}, {name: "MissingNo", number: NaN, caught: 0}], "number")` 應該返回 `false`。
```js
-assert.strictEqual(truthCheck([{ single: 'yes' }], 'single'), true);
+assert.strictEqual(truthCheck(
+ [
+ { name: "Pikachu", number: 25, caught: 3 },
+ { name: "Togepi", number: 175, caught: 1 },
+ { name: "MissingNo", number: NaN, caught: 0 },
+ ],
+ "number"), false);
```
-`truthCheck([{"single": ""}, {"single": "double"}], "single")` 應返回 `false`。
+`truthCheck([{name: "Quincy", username: "QuincyLarson"}, {name: "Naomi", username: "nhcarrigan"}, {name: "Camperbot"}], "username")` 應該返回 `false`。
```js
-assert.strictEqual(
- truthCheck([{ single: '' }, { single: 'double' }], 'single'),
- false
-);
+assert.strictEqual(truthCheck(
+ [
+ { name: "Quincy", username: "QuincyLarson" },
+ { name: "Naomi", username: "nhcarrigan" },
+ { name: "Camperbot" }
+ ],
+ "username"), false);
```
-`truthCheck([{"single": "double"}, {"single": undefined}], "single")` 應返回 `false`。
+`truthCheck([{name: "freeCodeCamp", users: [{name: "Quincy"}, {name: "Naomi"}]}, {name: "Code Radio", users: [{name: "Camperbot"}]}, {name: "", users: []}], "users")` 應該返回 `true`。
```js
-assert.strictEqual(
- truthCheck([{ single: 'double' }, { single: undefined }], 'single'),
- false
-);
+assert.strictEqual(truthCheck(
+ [
+ { name: "freeCodeCamp", users: [{ name: "Quincy" }, { name: "Naomi" }] },
+ { name: "Code Radio", users: [{ name: "Camperbot" }] },
+ { name: "", users: [] },
+ ],
+ "users"), true);
```
-`truthCheck([{"single": "double"}, {"single": NaN}], "single")` 應返回 `false`。
+`truthCheck([{id: 1, data: {url: "https://freecodecamp.org", name: "freeCodeCamp"}}, {id: 2, data: {url: "https://coderadio.freecodecamp.org/", name: "CodeRadio"}}, {id: null, data: {}}], "data")` 應該返回 `true`。
```js
-assert.strictEqual(
- truthCheck([{ single: 'double' }, { single: NaN }], 'single'),
- false
-);
+assert.strictEqual(truthCheck(
+ [
+ { id: 1, data: { url: "https://www.freecodecamp.org", name: "freeCodeCamp" } },
+ { id: 2, data: { url: "https://coderadio.freecodecamp.org/", name: "CodeRadio" } },
+ { id: null, data: {} },
+ ],
+ "data"), true);
+```
+
+`truthCheck([{id: 1, data: {url: "https://freecodecamp.org", name: "freeCodeCamp"}}, {id: 2, data: {url: "https://coderadio.freecodecamp.org/", name: "CodeRadio"}}, {id: null, data: {}}], "id")` 應該返回 `false`。
+
+```js
+assert.strictEqual(truthCheck(
+ [
+ { id: 1, data: { url: "https://www.freecodecamp.org", name: "freeCodeCamp" } },
+ { id: 2, data: { url: "https://coderadio.freecodecamp.org/", name: "CodeRadio" } },
+ { id: null, data: {} },
+ ],
+ "id"), false);
```
# --seed--
@@ -143,7 +146,7 @@ function truthCheck(collection, pre) {
return pre;
}
-truthCheck([{"user": "Tinky-Winky", "sex": "male"}, {"user": "Dipsy", "sex": "male"}, {"user": "Laa-Laa", "sex": "female"}, {"user": "Po", "sex": "female"}], "sex");
+truthCheck([{name: "Quincy", role: "Founder", isBot: false}, {name: "Naomi", role: "", isBot: false}, {name: "Camperbot", role: "Bot", isBot: true}], "isBot");
```
# --solutions--
diff --git a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/sorted-union.md b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/sorted-union.md
index 5916f08f7d..9df408baa0 100644
--- a/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/sorted-union.md
+++ b/curriculum/challenges/chinese-traditional/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/sorted-union.md
@@ -45,6 +45,18 @@ assert.deepEqual(uniteUnique([1, 2, 3], [5, 2, 1, 4], [2, 1], [6, 7, 8]), [
]);
```
+`uniteUnique([1, 3, 2], [5, 4], [5, 6])` 應該返回 `[1, 3, 2, 5, 4, 6]`。
+
+```js
+assert.deepEqual(uniteUnique([1, 3, 2], [5, 4], [5, 6]), [1, 3, 2, 5, 4, 6]);
+```
+
+`uniteUnique([1, 3, 2, 3], [5, 2, 1, 4], [2, 1])` 應該返回 `[1, 3, 2, 5, 4]`。
+
+```js
+assert.deepEqual(uniteUnique([1, 3, 2, 3], [5, 2, 1, 4], [2, 1]), [1, 3, 2, 5, 4]);
+```
+
# --seed--
## --seed-contents--
@@ -62,7 +74,11 @@ uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]);
```js
function uniteUnique(arr) {
return [].slice.call(arguments).reduce(function(a, b) {
- return [].concat(a, b.filter(function(e) {return a.indexOf(e) === -1;}));
+ return [].concat(
+ a,
+ b.filter(function(e, currentIndex) {
+ return b.indexOf(e) === currentIndex && a.indexOf(e) === -1;
+ }));
}, []);
}
```
diff --git a/curriculum/challenges/chinese-traditional/03-front-end-development-libraries/bootstrap/call-out-optional-actions-with-btn-info.md b/curriculum/challenges/chinese-traditional/03-front-end-development-libraries/bootstrap/call-out-optional-actions-with-btn-info.md
index 94ff3458d7..cc587c5172 100644
--- a/curriculum/challenges/chinese-traditional/03-front-end-development-libraries/bootstrap/call-out-optional-actions-with-btn-info.md
+++ b/curriculum/challenges/chinese-traditional/03-front-end-development-libraries/bootstrap/call-out-optional-actions-with-btn-info.md
@@ -10,7 +10,7 @@ dashedName: call-out-optional-actions-with-btn-info
Bootstrap 有着豐富的預定義按鈕顏色。 淺藍色的 `btn-info` class 通常用在備選操作上。
-在 `Like` 按鈕下方創建包含文本 `Info` 的塊級 Bootstrap 按鈕,然後爲該按鈕添加 Bootstrap 的 `btn-info` 和 `btn-block` classes。
+在 `Like` 按鈕下方使用文本 `Info` 創建一個新的塊級 Bootstrap 按鈕,並向其中添加 Bootstrap 的 `btn-info` 類。
注意:這些按鈕仍然需要 `btn` 和 `btn-block` class。
diff --git a/curriculum/challenges/chinese-traditional/03-front-end-development-libraries/react/render-conditionally-from-props.md b/curriculum/challenges/chinese-traditional/03-front-end-development-libraries/react/render-conditionally-from-props.md
index 3e74ea1d38..b5356f2e79 100644
--- a/curriculum/challenges/chinese-traditional/03-front-end-development-libraries/react/render-conditionally-from-props.md
+++ b/curriculum/challenges/chinese-traditional/03-front-end-development-libraries/react/render-conditionally-from-props.md
@@ -8,7 +8,7 @@ dashedName: render-conditionally-from-props
# --description--
-到目前爲止,已經看到了如何使用 `if/else`、`&&`和三元運算符(`condition ? expressionIfTrue : expressionIfFalse`)對渲染什麼和何時渲染做出有條件的判定。 然而,還有一個重要的話題需要討論,將這些概念中的任何一個或所有概念與另一個強大的 React 功能 props 結合起來。 使用 props 有條件地渲染代碼在 React 開發人員中很常見——也就是說:他們使用給定 prop 的值來自動決定渲染什麼。
+到目前爲止,你已經瞭解瞭如何使用 `if/else`、`&&` 和三元運算符(`condition ? expressionIfTrue : expressionIfFalse`)來決定渲染什麼和何時渲染。 然而,還有一個重要的話題需要討論,它可以讓你將這些概念中的一個或所有與另一個強大的 React 特性結合起來:props。 使用 props 有條件地渲染代碼對於 React 開發人員來說非常常見——也就是說,他們使用給定 props 的值來自動決定要渲染什麼。
在這個挑戰中,將設置一個子組件來根據 props 做出渲染決定。 可以使用三元運算符,但是可以看到過去幾個挑戰中涵蓋的其他幾個概念在這種情況下可能同樣有用。
diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/arithmetic-formatter.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/arithmetic-formatter.md
index 885d37f579..3e41aa1b71 100644
--- a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/arithmetic-formatter.md
+++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/arithmetic-formatter.md
@@ -8,21 +8,78 @@ dashedName: arithmetic-formatter
# --description--
-創建一個函數,該函數接收屬一個字符串列表,每個字符串代表一個算數問題,並返回垂直並排排列的問題。
+你將[使用我們的 Replit 入門代碼來完成這個項目](https://replit.com/github/freeCodeCamp/boilerplate-arithmetic-formatter)。
-你可以[在 Replit 上查看整個項目的具體描述和初始代碼](https://replit.com/github/freeCodeCamp/boilerplate-arithmetic-formatter)。
+# --instructions--
-訪問此鏈接後,fork 這個項目。 當你根據 “README.md” 中的說明完成了項目,請在下方提交你的項目鏈接。
+小學生經常把算術題垂直排列,這樣更容易解決。 例如,“235 + 52” 變成:
-我們仍在開發 Python 課程的交互式教學部分。 目前,freeCodeCamp.org YouTube 頻道上的一些視頻會教授你這個項目需要的所有技能。
+```py
+ 235
++ 52
+-----
+```
-
- Python for Everybody 視頻課程 (14 小時)
-
-
- 學習 Python 視頻課程 (2 小時)
-
-
+創建一個函數,接收一個屬於算術問題的字符串列表,並返回垂直和並排排列的問題。 該函數應該接受可選的第二個參數。 當第二個參數設置爲 `True` 時,應顯示答案。
+
+## 示例
+
+函數調用:
+
+```py
+arithmetic_arranger(["32 + 698", "3801 - 2", "45 + 43", "123 + 49"])
+```
+
+輸出:
+
+```py
+ 32 3801 45 123
++ 698 - 2 + 43 + 49
+----- ------ ---- -----
+```
+
+函數調用:
+
+```py
+arithmetic_arranger(["32 + 8", "1 - 3801", "9999 + 9999", "523 - 49"], True)
+```
+
+輸出:
+
+```py
+ 32 1 9999 523
++ 8 - 3801 + 9999 - 49
+---- ------ ------ -----
+ 40 -3800 19998 474
+```
+
+## 規則
+
+如果提供的問題格式正確,該函數將返回正確的轉換,否則,它將 **返回** 一個 **字符串** 來描述對用戶有意義的錯誤。
+
+
+- 會返回錯誤的情況:
+ - 如果提供給函數的 **問題過多**。 限制爲 **五個**,更多的將返回: `Error: Too many problems.`
+ - 函數可以接受的運算符是 **加法** 和 **減法** 。 乘法和除法將返回錯誤。 本要點中未提及的其他運算符將不需要進行測試。 返回的錯誤將是: `Error: Operator must be '+' or '-'.`
+ - 每個數字(操作數)應該只包含數字。 否則,該函數將返回: `Error: Numbers must only contain digits.`
+ - 每個操作數(也就是運算符兩側的數字)的寬度最多爲四位。 否則,返回的錯誤字符串將爲: `Error: Numbers cannot be more than four digits.`
+- 如果用戶提供了正確格式的問題,返回的轉換將遵循以下規則:
+ - 運算符和兩個數中最長的一個之間應該有一個空格,運算符與第二個數在同一行,兩個數的順序與所提供的相同(第一個將是頂部的,而第二個將是底部。
+ - 數字應該右對齊。
+ - 每個問題之間應該有四個空格。
+ - 每個問題的底部都應該有破折號。 破折號應該單獨沿着每個問題的整個長度延伸。 (上面的例子展示了這應該是什麼樣子。)
+
+## 開發
+
+在 `arithmetic_arranger.py` 中編寫你的代碼。 對於開發,你可以使用 `main.py` 來測試你的 `arithmetic_arranger()` 函數。 單擊“運行”按鈕,`main.py` 將運行。
+
+## 測試
+
+這個項目的單元測試在 `test_module.py` 中。 爲了你的方便,我們在 `main.py` 中從 `test_module.py` 運行測試。 只要你點擊“運行”按鈕,測試就會自動運行。 或者,你可以通過在控制檯中輸入 `pytest` 來運行測試。
+
+## 提交
+
+複製項目的 URL 並在下面提交。
# --hints--
diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/budget-app.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/budget-app.md
index ed6cdf2f45..363f126488 100644
--- a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/budget-app.md
+++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/budget-app.md
@@ -8,22 +8,80 @@ dashedName: budget-app
# --description--
-創建一個 Category(類別) 類,該類可用於創建不同的預算類別。
+你將[使用我們的 Replit 入門代碼來完成這個項目](https://replit.com/github/freeCodeCamp/boilerplate-budget-app)。
-你可以[在 Replit 上查看整個項目的具體描述和初始代碼](https://replit.com/github/freeCodeCamp/boilerplate-budget-app)。
+# --instructions--
-訪問此鏈接後,fork 這個項目。 當你根據 “README.md” 中的說明完成了項目,請在下方提交你的項目鏈接。
+完成 `budget.py` 中的 `Category` 類。 它應該能夠根據不同的預算類別實例化對象,例如 *食物* 、 *服裝* 和 *娛樂* 。 創建對象時,它們以類別的名稱傳遞。 該類應該有一個名爲 `ledger` 的實例變量,它是一個列表。 該類還應包含以下方法:
-我們仍在開發 Python 課程的交互式教學部分。 目前,freeCodeCamp.org YouTube 頻道上的一些視頻將會教授你這個項目需要的所有技能。
+- 接受金額和描述的 `deposit` 方法。 如果沒有給出描述,它應該默認爲一個空字符串。 該方法應以 `{"amount": amount, "description": description}` 的形式將對象附加到賬本列表。
+- `withdraw` 方法類似於 `deposit` 方法,但傳入的金額應作爲負數存儲在分類帳中。 如果沒有足夠的資金,則不應向分類帳添加任何內容。 如果取款發生,此方法應返回 `True`,否則返回 `False`。
+- `get_balance` 方法,根據發生的存款和取款返回預算類別的當前餘額。
+- 一個 `transfer` 方法,它接受一個金額和另一個預算類別作爲參數。 該方法應添加帶有金額和描述“Transfer to [目標預算類別]”的提款。 然後,該方法應將存款添加到其他預算類別,其金額和描述爲“Transfer from [來源預算類別]”。 如果沒有足夠的資金,則不應向任一分類帳添加任何內容。 如果轉賬發生,此方法應返回 `True`,否則返回 `False`。
+- 接受金額作爲參數的 `check_funds` 方法。 如果金額大於預算類別的餘額,則返回 `False`,否則返回 `True`。 `withdraw` 方法和 `transfer` 方法都應該使用此方法。
-
+打印預算對象時,它應顯示:
+
+- 30 個字符的標題行,類別名稱居中在一行 `*` 字符中。
+- 分類帳中的項目列表。 每行應顯示描述和金額。 應顯示描述的前 23 個字符,然後是金額。 金額應右對齊,包含兩位小數,最多顯示 7 個字符。
+- 一行顯示類別總數。
+
+下面是一個輸出示例:
+
+```bash
+*************Food*************
+initial deposit 1000.00
+groceries -10.15
+restaurant and more foo -15.89
+Transfer to Clothing -50.00
+Total: 923.96
+```
+
+除了 `Category` 類之外,創建一個名爲 `create_spend_chart` 的函數(在類之外),它將類別列表作爲參數。 它應該返回一個作爲條形圖的字符串。
+
+該圖表應顯示在傳遞給函數的每個類別中花費的百分比。 花費的百分比應該只計算取款而不是存款。 圖表左側應該是標籤 0 - 100。 條形圖中的“條”應由“o”字符組成。 每個條形的高度應四捨五入到最接近的 10。 條形圖下面的水平線應該超過最後一個條形圖再多兩個空格。 每個類別名稱應垂直寫在欄下方。 頂部應該有一個標題,上面寫着“Percentage spent by category”。
+
+此功能將使用最多四個類別進行測試。
+
+仔細查看下面的示例輸出,並確保輸出的間距與示例完全匹配。
+
+```bash
+Percentage spent by category
+100|
+ 90|
+ 80|
+ 70|
+ 60| o
+ 50| o
+ 40| o
+ 30| o
+ 20| o o
+ 10| o o o
+ 0| o o o
+ ----------
+ F C A
+ o l u
+ o o t
+ d t o
+ h
+ i
+ n
+ g
+```
+
+此項目的單元測試在 `test_module.py` 中。
+
+## 開發
+
+在 `budget.py` 中編寫你的代碼。 對於開發,你可以使用 `main.py` 來測試你的 `Category` 類。 單擊“運行”按鈕,`main.py` 將運行。
+
+## 測試
+
+爲了你的方便,我們將測試從 `test_module.py` 導入到 `main.py`。 只要你點擊“運行”按鈕,測試就會自動運行。
+
+## 提交
+
+複製項目的 URL 並將其提交給 freeCodeCamp。
# --hints--
diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/polygon-area-calculator.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/polygon-area-calculator.md
index fcc51c27a5..0c767fcb6a 100644
--- a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/polygon-area-calculator.md
+++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/polygon-area-calculator.md
@@ -8,26 +8,94 @@ dashedName: polygon-area-calculator
# --description--
+你將通過使用我們的[Replit 入門代碼](https://replit.com/github/freeCodeCamp/boilerplate-polygon-area-calculator)來完成本項目。
+
+# --instructions--
+
在這個項目中,你將使用面向對象的編程來創建 Rectangle(矩形) 類和 Square(正方形) 類。 Square 類應該是 Rectangle 的子類,並繼承方法和屬性。
-你可以[在 Replit 上查看整個項目的具體描述和初始代碼](https://replit.com/github/freeCodeCamp/boilerplate-polygon-area-calculator)。
+## Rectangle 類
-到達此鏈接後,fork 這個項目。 當你根據 “README.md” 中的說明完成了項目,請在下方提交你的項目鏈接。
+創建 Rectangle 對象時,應使用 `width` 和 `height` 屬性對其進行初始化。 該類還應包含以下方法:
-Python 課程的交互式教學部分仍在開發當中。 目前,freeCodeCamp.org YouTube 頻道上的一些視頻將會教授你這個項目需要的所有技能。
+- `set_width`
+- `set_height`
+- `get_area`:返回面積(`width * height`)
+- `get_perimeter`:返回周長(`2 * width + 2 * height`)
+- `get_diagonal`:返回對角線 (`(width ** 2 + height ** 2) ** .5`)
+- `get_picture`:返回一個字符串,該字符串使用包含“\*”的行來表示形狀。 行數應等於高度,每行中“\*”的數量應等於寬度。 每行末尾應該有一個新行 (`\n`)。 如果寬度或高度大於 50,則應返回字符串:“Too big for picture.”。
+- `get_amount_inside`:以另一個形狀(正方形或矩形)作爲參數。 返回傳入的形狀可以裝進該形狀的次數(沒有旋轉)。 例如,一個寬爲 4,高爲 8 的矩形可以放入兩個邊長爲 4 的正方形。
-
+另外,如果一個 Rectangle 實例被表示爲一個字符串,它應該看起來像: `Rectangle(width=5, height=10)`
+
+## Square 類
+
+Square 類應該是 Rectangle 的子類。 創建 Square 對象時,傳入單邊長度。 `__init__` 方法應該在 Rectangle 類的 `width` 和 `height` 屬性中存儲邊長。
+
+Square 類應該能夠訪問 Rectangle 類方法,但還應該包含一個 `set_side` 方法。 如果 Square 的實例表示爲字符串,則它應該如下所示:`Square(side=9)`
+
+此外,Square 類的 `set_width` 和 `set_height` 方法應該設置寬度和高度。
+
+## 使用示例
+
+```py
+rect = shape_calculator.Rectangle(10, 5)
+print(rect.get_area())
+rect.set_height(3)
+print(rect.get_perimeter())
+print(rect)
+print(rect.get_picture())
+
+sq = shape_calculator.Square(9)
+print(sq.get_area())
+sq.set_side(4)
+print(sq.get_diagonal())
+print(sq)
+print(sq.get_picture())
+
+rect.set_height(8)
+rect.set_width(16)
+print(rect.get_amount_inside(sq))
+```
+
+該代碼應該返回:
+
+```bash
+50
+26
+Rectangle(width=10, height=3)
+**********
+**********
+**********
+
+81
+5.656854249492381
+Square(side=4)
+****
+****
+****
+****
+
+8
+```
+
+此項目的單元測試在 `test_module.py` 中。
+
+## 開發
+
+在 `shape_calculator.py` 中編寫你的代碼。 對於開發,你可以使用 `main.py` 來測試你的 `shape_calculator()` 函數。 單擊“運行”按鈕,`main.py` 將運行。
+
+## 測試
+
+爲了你的方便,我們將測試從 `test_module.py` 導入到 `main.py`。 只要你點擊“運行”按鈕,測試就會自動運行。
+
+## 提交
+
+複製項目的 URL 並將其提交給 freeCodeCamp。
# --hints--
-它應該創建一個 Rectangle 類和 Square 類並通過所有測試。
+應該創建一個 Rectangle 類和一個 Square 類,並通過所有測試。
```js
diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/probability-calculator.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/probability-calculator.md
index 67b9a46aa1..039d407898 100644
--- a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/probability-calculator.md
+++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/probability-calculator.md
@@ -8,24 +8,68 @@ dashedName: probability-calculator
# --description--
-寫一個程序來確定從帽子中隨機拿取特定球的大致概率。
+你將通過使用我們的[Replit 入門代碼](https://replit.com/github/freeCodeCamp/boilerplate-probability-calculator)來完成本項目。
-你可以在 [Replit](https://replit.com/github/freeCodeCamp/boilerplate-probability-calculator) 上查看整個項目的具體描述和初始代碼。 訪問此鏈接後,fork 這個項目。 當你根據 “README.md” 中的說明完成了項目,請在下方提交你的項目鏈接。
+# --instructions--
-我們仍在開發 Python 課程的交互式教學部分。 目前,freeCodeCamp.org YouTube 頻道上的一些視頻將會教授你這個項目需要的所有技能。
+假設有一頂帽子,裏面有 5 個藍球、4 個紅球和 2 個綠球。 隨機抽取的 4 個球中至少包含 1 個紅球和 2 個綠球的概率是多少? 雖然可以使用高等數學來計算概率,但更簡單的方法是編寫一個程序來執行大量實驗來估計近似概率。
-
+對於這個項目,你將編寫一個程序來確定從帽子中隨機抽取某些球的大致概率。
+
+首先,在`prob_calculator.py` 中創建一個`Hat` 類。 該類應該採用可變數量的參數來指定帽子中每種顏色的球數。 例如,可以通過以下任何一種方式創建類對象:
+
+```py
+hat1 = Hat(yellow=3, blue=2, green=6)
+hat2 = Hat(red=5, orange=4)
+hat3 = Hat(red=5, orange=4, black=1, blue=0, pink=2, striped=9)
+```
+
+一頂帽子總是至少有一個球。 創建時傳遞給 hat 對象的參數應轉換爲 `contents` 實例變量。 `contents` 應該是一個字符串列表,其中包含帽子中每個球的一個項目。 列表中的每一項都應該是一個顏色名稱,代表該顏色的單個球。 例如,如果你的帽子是 `{"red": 2, "blue": 1}`,`contents` 應該是 `["red", "red", "blue"]`。
+
+`Hat` 類應該有一個 `draw` 方法,該方法接受一個參數,該參數指示要從帽子中抽取的球數。 此方法應該從 `contents` 中隨機刪除球,並將這些球作爲字符串列表返回。 在抽取過程中球不應回到帽子中,類似於沒有放回的黑盒實驗。 如果要抽的球數量超過可用數量,則返回所有球。
+
+接下來,在 `prob_calculator.py`(不是在 `Hat` 類中)創建一個 `experiment` 函數。 此函數應接受以下參數:
+
+- `hat`:一個包含球的帽子對象,應該在函數內複製。
+- `expected_balls`:一個對象,指示嘗試從帽子中抽取的確切球組以進行實驗。 例如,要確定從帽子中抽取 2 個藍球和 1 個紅球的概率,將 `expected_balls` 設置爲 `{"blue":2, "red":1}`。
+- `num_balls_drawn`:每次實驗中從帽子中抽出的球數。
+- `num_experiments`:要執行的實驗數量。 (進行的實驗越多,近似概率就越準確。)
+
+`experiment` 函數應該返回一個概率。
+
+例如,假設你想確定當你從一個包含 6 個黑球、4 個紅球和 3 個綠球的帽子中抽出 5 個球時,至少得到 2 個紅球和 1 個綠球的概率。 爲此,我們進行 `N` 次實驗,記錄其中我們至少得到 2 個紅球和 1 個綠球的次數 `M`,並估計概率爲`M/N`。 每個實驗都包括從一頂裝有指定球的帽子開始,抽取一些球,然後檢查我們是否得到了我們想要得到的球。
+
+以下是基於上面的示例調用 `experiment` 函數的方法,其中包含 2000 個實驗:
+
+```py
+hat = Hat(black=6, red=4, green=3)
+probability = experiment(hat=hat,
+ expected_balls={"red":2,"green":1},
+ num_balls_drawn=5,
+ num_experiments=2000)
+```
+
+由於這是基於隨機抽取的,因此每次運行代碼時概率會略有不同。
+
+*提示:考慮使用已經在 `prob_calculator.py` 頂部導入的模塊。 不要在 `prob_calculator.py` 中初始化隨機種子。*
+
+## 開發
+
+在 `prob_calculator.py` 中編寫你的代碼。 對於開發,你可以使用 `main.py` 來測試你的代碼。 單擊“運行”按鈕,`main.py` 將運行。
+
+樣板文件包括 `copy` 和 `random` 模塊的 `import` 語句。 考慮在你的項目中使用它們。
+
+## 測試
+
+這個項目的單元測試在 `test_module.py` 中。 爲了你的方便,我們將測試從 `test_module.py` 導入到 `main.py`。 只要你點擊“運行”按鈕,測試就會自動運行。
+
+## 提交
+
+複製項目的 URL 並將其提交給 freeCodeCamp。
# --hints--
-它應該能正確地計算概率並通過所有測試。
+它應該能正確地計算概率,並通過所有測試。
```js
diff --git a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/time-calculator.md b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/time-calculator.md
index e8fd73aa26..d0357eae42 100644
--- a/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/time-calculator.md
+++ b/curriculum/challenges/chinese-traditional/07-scientific-computing-with-python/scientific-computing-with-python-projects/time-calculator.md
@@ -8,24 +8,61 @@ dashedName: time-calculator
# --description--
-編寫一個名爲 “add_time” 的函數,該函數可以將一段時間添加到一個開始時間中,並返回結果。
+你將通過使用我們的[Replit 入門代碼](https://replit.com/github/freeCodeCamp/boilerplate-time-calculator)來完成本項目。
-你可以 [在 Replit 上查看整個項目的具體描述和初始代碼](https://replit.com/github/freeCodeCamp/boilerplate-time-calculator)。 訪問此鏈接後,fork 這個項目。 當你根據 “README.md” 中的說明完成了項目,請在下方提交你的項目鏈接。
+# --instructions--
-我們仍在開發 Python 課程的交互式教學部分。 目前,freeCodeCamp.org YouTube 頻道上的一些視頻將會教授你這個項目需要的所有技能。
+編寫一個名爲 `add_time` 的函數,它接受兩個必需參數和一個可選參數:
-
+- 12 小時制的開始時間(以 AM 或 PM 結束)
+- 指示小時數和分鐘數的持續時間
+- (可選)一週的開始日期,不區分大小寫
+
+該函數應將持續時間添加到開始時間並返回結果。
+
+如果結果是第二天,它應該在時間之後顯示 `(next day)`。 如果結果將超過一天以後,它應該在時間後面顯示 `(n days later)`,其中 "n "是之後的天數。
+
+如果給函數提供了可選的開始日期的星期參數,則輸出應顯示結果的星期幾。 輸出中的星期幾應出現在時間之後和天數之前。
+
+以下是函數應處理的不同情況的一些示例。 請注意結果的間距和標點符號。
+
+```py
+add_time("3:00 PM", "3:10")
+# Returns: 6:10 PM
+
+add_time("11:30 AM", "2:32", "Monday")
+# Returns: 2:02 PM, Monday
+
+add_time("11:43 AM", "00:20")
+# Returns: 12:03 PM
+
+add_time("10:10 PM", "3:30")
+# Returns: 1:40 AM (next day)
+
+add_time("11:43 PM", "24:20", "tueSday")
+# Returns: 12:03 AM, Thursday (2 days later)
+
+add_time("6:30 PM", "205:12")
+# Returns: 7:42 AM (9 days later)
+```
+
+不要導入任何 Python 庫。 假設開始時間是有效時間。 持續時間中的分鐘將是小於 60 的整數,但小時可以是任何整數。
+
+## 開發
+
+在 `time_calculator.py` 中編寫你的代碼。 對於開發,你可以使用 `main.py` 來測試你的 `time_calculator()` 函數。 單擊“運行”按鈕,`main.py` 將運行。
+
+## 測試
+
+這個項目的單元測試在 `test_module.py` 中。 爲了你的方便,我們將測試從 `test_module.py` 導入到 `main.py`。 只要你點擊“運行”按鈕,測試就會自動運行。
+
+## 提交
+
+複製項目的 URL 並將其提交給 freeCodeCamp。
# --hints--
-它應該能正確地添加時間並通過所有測試。
+它應該能正確地添加時間,並通過所有測試。
```js
diff --git a/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/demographic-data-analyzer.md b/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/demographic-data-analyzer.md
index 4d0c9a677a..31f1f9f613 100644
--- a/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/demographic-data-analyzer.md
+++ b/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/demographic-data-analyzer.md
@@ -8,13 +8,58 @@ dashedName: demographic-data-analyzer
# --description--
-在這個挑戰中,你必須使用 Pandas 對人口統計進行分析。 你將獲得從 1994 年人口普查數據庫中提取的人口統計數據數據集。
+你將通過使用我們的[Replit 入門代碼](https://replit.com/github/freeCodeCamp/boilerplate-demographic-data-analyzer)來完成本項目。
-你可以[在 Replit 上查看整個項目的具體描述和初始代碼](https://replit.com/github/freeCodeCamp/boilerplate-demographic-data-analyzer)。
+我們仍在開發 Python 課程的交互式教學部分。 目前,你可以在 YouTube 上通過 freeCodeCamp.org 上傳的一些視頻學習這個項目相關的知識。
-點擊此鏈接,fork 這個項目。 一旦你根據 “README.md” 中的說明完成項目,請提交你的項目鏈接到下面。
+- [Python for Everybody 視頻課程](https://www.freecodecamp.org/news/python-for-everybody/)(14 小時)
+- [Learn Python 視頻課程](https://www.freecodecamp.org/news/learn-python-video-course/)(10 小時)
-我們仍在開發 Python 數據分析課程的交互式教學。 現在,你需要使用其他資源來學習如何通過這一挑戰。
+# --instructions--
+
+在這個挑戰中,你必須使用 Pandas 對人口統計進行分析。 你將獲得從 1994 年人口普查數據庫中提取的人口統計數據數據集。 以下是數據的示例:
+
+```markdown
+| | age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | salary |
+|---:|------:|:-----------------|---------:|:------------|----------------:|:-------------------|:------------------|:---------------|:-------|:-------|---------------:|---------------:|-----------------:|:-----------------|:---------|
+| 0 | 39 | State-gov | 77516 | Bachelors | 13 | Never-married | Adm-clerical | Not-in-family | White | Male | 2174 | 0 | 40 | United-States | <=50K |
+| 1 | 50 | Self-emp-not-inc | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
+| 2 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
+| 3 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
+| 4 | 28 | Private | 338409 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Wife | Black | Female | 0 | 0 | 40 | Cuba | <=50K |
+```
+
+你必須使用 Pandas 來回答以下問題:
+
+- 這個數據集中每個種族有多少人? 這應該是一個以種族名稱作爲索引標籤的 Pandas 系列。 (`race` 欄)
+- 男性的平均年齡是多少?
+- 擁有學士學位的人的百分比是多少?
+- 受過高等教育(`Bachelors`, `Masters`, or `Doctorate`)收入超過 50K 的人佔多大比例?
+- 沒有受過高等教育的人的收入超過 50K 的比例是多少?
+- 一個人每週最少工作多少小時?
+- 每週工作最少小時數的人中有多少人的工資超過 50K?
+- 哪個國家/地區的收入 >50K 的人口比例最高,該比例是多少?
+- 確定印度收入 >50K 的人最受歡迎的職業。
+
+使用文件 `demographic_data_analyzer` 中的啓動代碼。 更新代碼,以便將所有設置爲“None”的變量設置爲適當的計算或代碼。 將所有小數四捨五入到最接近的十分之一。
+
+單元測試是在 `test_module.py` 下爲你編寫的。
+
+## 開發
+
+對於開發,你可以使用 `main.py` 來測試你的函數。 單擊“運行”按鈕,`main.py` 將運行。
+
+## 測試
+
+爲了你的方便,我們將測試從 `test_module.py` 導入到 `main.py`。 只要你點擊“運行”按鈕,測試就會自動運行。
+
+## 提交
+
+複製項目的 URL 並將其提交給 freeCodeCamp。
+
+## 數據集源
+
+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.
# --hints--
diff --git a/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/mean-variance-standard-deviation-calculator.md b/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/mean-variance-standard-deviation-calculator.md
index bc9ef61584..9c1ccbc598 100644
--- a/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/mean-variance-standard-deviation-calculator.md
+++ b/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/mean-variance-standard-deviation-calculator.md
@@ -8,13 +8,60 @@ dashedName: mean-variance-standard-deviation-calculator
# --description--
-創建一個函數,這個函數可以使用 Numpy 輸出 3 x 3 矩陣的每一行、每一列和所有元素的均值,方差和標準差。
+你將通過使用我們的[Replit 入門代碼](https://replit.com/github/freeCodeCamp/boilerplate-mean-variance-standard-deviation-calculator)來完成本項目。
-你可以在 [Replit](https://replit.com/github/freeCodeCamp/boilerplate-mean-variance-standard-deviation-calculator) 上查看整個項目的具體描述和初始代碼。
+我們仍在開發 Python 課程的交互式教學部分。 目前,你可以在 YouTube 上通過 freeCodeCamp.org 上傳的一些視頻學習這個項目相關的知識。
-點擊此鏈接,fork 這個項目。 當你根據 “README.md” 中的說明完成了項目,請在下方提交你的項目鏈接。
+- [Python for Everybody 視頻課程](https://www.freecodecamp.org/news/python-for-everybody/)(14 小時)
+- [Learn Python 視頻課程](https://www.freecodecamp.org/news/learn-python-video-course/)(10 小時)
-我們仍在開發 Python 數據分析課程的交互式教學。 現在,您將需要使用其他資源來學習如何通過這一挑戰。
+# --instructions--
+
+在 `mean_var_std.py` 中創建一個名爲 `calculate()` 的函數,該函數使用 Numpy 輸出行、列、和 3 x 3 矩陣中的元素。
+
+函數的輸入應該是一個包含 9 個數字的列表。 該函數應將列表轉換爲 3 x 3 Numpy 數組,然後返回一個字典,其中包含沿兩個軸和展平矩陣的均值、方差、標準差、最大值、最小值和總和。
+
+返回的字典應遵循以下格式:
+
+```py
+{
+ 'mean': [axis1, axis2, flattened],
+ 'variance': [axis1, axis2, flattened],
+ 'standard deviation': [axis1, axis2, flattened],
+ 'max': [axis1, axis2, flattened],
+ 'min': [axis1, axis2, flattened],
+ 'sum': [axis1, axis2, flattened]
+}
+```
+
+如果將包含少於 9 個元素的列表傳遞給函數,它應該引發 `ValueError` 異常並顯示消息:“List must contain nine numbers.” 返回的字典中的值應該是列表而不是 Numpy 數組。
+
+例如,`calculate([0,1,2,3,4,5,6,7,8])` 應該返回:
+
+```py
+{
+ 'mean': [[3.0, 4.0, 5.0], [1.0, 4.0, 7.0], 4.0],
+ 'variance': [[6.0, 6.0, 6.0], [0.6666666666666666, 0.6666666666666666, 0.6666666666666666], 6.666666666666667],
+ 'standard deviation': [[2.449489742783178, 2.449489742783178, 2.449489742783178], [0.816496580927726, 0.816496580927726, 0.816496580927726], 2.581988897471611],
+ 'max': [[6, 7, 8], [2, 5, 8], 8],
+ 'min': [[0, 1, 2], [0, 3, 6], 0],
+ 'sum': [[9, 12, 15], [3, 12, 21], 36]
+}
+```
+
+此項目的單元測試在 `test_module.py` 中。
+
+## 開發
+
+對於開發,你可以使用 `main.py` 來測試你的 `calculate()` 函數。 單擊“運行”按鈕,`main.py` 將運行。
+
+## 測試
+
+爲了你的方便,我們將測試從 `test_module.py` 導入到 `main.py`。 只要你點擊“運行”按鈕,測試就會自動運行。
+
+## 提交
+
+複製項目的 URL 並將其提交給 freeCodeCamp。
# --hints--
diff --git a/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/medical-data-visualizer.md b/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/medical-data-visualizer.md
index b0d1029027..a3ddebd093 100644
--- a/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/medical-data-visualizer.md
+++ b/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/medical-data-visualizer.md
@@ -8,13 +8,70 @@ dashedName: medical-data-visualizer
# --description--
-在這個項目中,你將要使用 matplotlib,seaborn 和 pandas 來對健康檢查數據進行數據可視化和計算。
+你將通過使用我們的[Replit 入門代碼](https://replit.com/github/freeCodeCamp/boilerplate-medical-data-visualizer)來完成本項目。
-你可以[在 Replit 上查看整個項目的具體描述和初始代碼](https://replit.com/github/freeCodeCamp/boilerplate-medical-data-visualizer)。
+我們仍在開發 Python 課程的交互式教學部分。 目前,你可以在 YouTube 上通過 freeCodeCamp.org 上傳的一些視頻學習這個項目相關的知識。
-打開此鏈接後,fork 這個項目。 一旦你根據 “README.md” 中的說明完成項目,請提交你的項目到下面的鏈接。
+- [Python for Everybody 視頻課程](https://www.freecodecamp.org/news/python-for-everybody/)(14 小時)
+- [Learn Python 視頻課程](https://www.freecodecamp.org/news/learn-python-video-course/)(10 小時)
-我們仍在開發 Python 數據分析課程的交互式課程部分。 現在,你需要使用其他資源來學習如何通過這一挑戰。
+# --instructions--
+
+在本項目中,您將使用 matplotlib、seaborn 和 pandas 來對體檢數據進行可視化和計算。 數據集的數值是從體檢中收集的。
+
+## 數據說明
+
+數據集中的行代表患者,列代表身體測量、各種血液檢查的結果和生活方式等信息。 您將使用該數據集來探索心臟病、身體測量數據、血液標誌物和對生活方式的選擇之間的關係。
+
+文件名:medical_examination.csv
+
+| 項目 | 變量類型 | 變量名 | 變量值類型 |
+|:--------:|:----:|:-----------:|:---------------------:|
+| 年齡 | 客觀特徵 | age | int (days) |
+| 身高 | 客觀特徵 | height | int (cm) |
+| 體重 | 客觀特徵 | weight | float (kg) |
+| 性別 | 客觀特徵 | gender | 分類編碼 |
+| 收縮壓 | 檢測特徵 | ap_hi | int |
+| 舒張壓 | 檢測特徵 | ap_lo | int |
+| 膽固醇 | 檢測特徵 | cholesterol | 1:正常,2:高於正常,3:遠遠高於正常值 |
+| 血糖值 | 檢測特徵 | gluc | 1:正常,2:高於正常,3:遠遠高於正常值 |
+| 吸菸問題 | 主觀特徵 | smoke | binary |
+| 飲酒量 | 主觀特徵 | alco | binary |
+| 體育活動 | 主觀特徵 | active | binary |
+| 是否有心血管疾病 | 目標變量 | cardio | binary |
+
+## 任務
+
+創建一個類似於 `examples/Figure_1.png` 的圖表,其中我們顯示 `cholesterol`、`gluc`、`alco`、`active` 和 `smoke` 變量,用於不同面板中 heart=1 和 heart=0 的患者。
+
+在 `medical_data_visualizer.py` 中使用數據完成以下任務:
+
+- 給數據添加一列 `overweight`。 要確定一個人是否超重,首先通過將他們的體重(公斤)除以他們的身高(米)的平方來計算他們的 BMI。 如果該值 > 25,則此人超重。 使用值 0 表示不超重,使用值 1 表示超重。
+- 使用 0 表示好的和 1 表示壞,來規範化數據。 如果 `cholesterol` 或 `gluc` 的值爲 1,則將值設爲 0。 如果值大於 1,則將值設爲 1。
+- 將數據轉換爲長格式並使用 seaborn 的 `catplot()` 創建一個顯示分類特徵值計數的圖表。 數據集應按“Cardio”拆分,因此每個 `cardio` 值都有一個圖表。 該圖表應該看起來像 `examples/Figure_1.png`。
+- 清理數據。 過濾掉以下代表不正確數據的患者段:
+ - 舒張壓高於收縮壓(使用 `(df['ap_lo'] <= df['ap_hi'])` 保留正確的數據)
+ - 高度小於第 2.5 個百分位數(使用 `(df['height'] >= df['height'].quantile(0.025))` 保留正確的數據)
+ - 身高超過第 97.5 個百分位
+ - 體重小於第 2.5 個百分位
+ - 體重超過第 97.5 個百分位
+- 使用數據集創建相關矩陣。 使用 seaborn 的 `heatmap()` 繪製相關矩陣。 遮罩上三角。 該圖表應類似於 `examples/Figure_2.png`。
+
+每當變量設置爲 `None` 時,請確保將其設置爲正確的代碼。
+
+單元測試是在 `test_module.py` 下爲你編寫的。
+
+## 開發
+
+對於開發,你可以使用 `main.py` 來測試你的函數。 單擊“運行”按鈕,`main.py` 將運行。
+
+## 測試
+
+爲了你的方便,我們將測試從 `test_module.py` 導入到 `main.py`。 只要你點擊“運行”按鈕,測試就會自動運行。
+
+## 提交
+
+複製項目的 URL 並將其提交給 freeCodeCamp。
# --hints--
diff --git a/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/page-view-time-series-visualizer.md b/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/page-view-time-series-visualizer.md
index 414b111006..a8fb8b8b99 100644
--- a/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/page-view-time-series-visualizer.md
+++ b/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/page-view-time-series-visualizer.md
@@ -8,13 +8,40 @@ dashedName: page-view-time-series-visualizer
# --description--
-對於這個項目,你將使用線圖、條形圖和箱形圖對時間序列數據進行可視化。 你將要使用 Pandas、matplotlib 和 seaborn 來對數據集進行可視化,這個數據集包含從 2016-05-09 到 2019-12-03 每一天在 freeCodeCamp.org 論壇的頁面訪問量。 這個數據可視化將幫助你瞭解訪問的模式,並且顯示年增長和月增長情況。
+你將通過使用我們的[Replit 入門代碼](https://replit.com/github/freeCodeCamp/boilerplate-page-view-time-series-visualizer)來完成本項目。
-你可以 [在 Replit 上查看整個項目的具體描述和初始代碼](https://replit.com/github/freeCodeCamp/boilerplate-page-view-time-series-visualizer)。
+我們仍在開發 Python 課程的交互式教學部分。 目前,你可以在 freeCodeCamp.org 的 YouTube 頻道中通過視頻學習到這個項目相關的所有知識
-點擊此鏈接,fork 這個項目。 一旦你根據 “README.md” 中的說明完成項目,請提交你的項目到下面的鏈接。
+- [Python for Everybody 視頻課程](https://www.freecodecamp.org/news/python-for-everybody/)(14 小時)
+- [Learn Python 視頻課程](https://www.freecodecamp.org/news/learn-python-video-course/)(10 小時)
-我們仍在開發 Python 數據分析課程的交互式課程部分。 現在,你將需要使用其他資源來學習如何通過這一挑戰。
+# --instructions--
+
+對於這個項目,你將使用線圖、條形圖和箱形圖對時間序列數據進行可視化。 你將使用 Pandas、Matplotlib 和 Seaborn 可視化包含 2016 年 5 月 9 日至 2019 年 12 月 3 日期間 freeCodeCamp.org 論壇上每天的頁面瀏覽量的數據集。 這個數據可視化將幫助你瞭解訪問的模式,並且顯示年增長和月增長情況。
+
+使用數據完成以下任務:
+
+- 使用 Pandas 從 “fcc-forum-pageviews.csv” 導入數據。 將索引設置爲 “date” 列。
+- 通過過濾掉頁面瀏覽量位於數據集前 2.5% 或數據集後 2.5% 的日期來清理數據。
+- 創建一個 `draw_line_plot` 函數,該函數使用 Matplotlib 繪製類似於“examples/Figure_1.png”的折線圖。 標題應爲“Daily freeCodeCamp Forum Page Views 5/2016-12/2019”。 x 軸上的標籤應爲“Date”,y 軸上的標籤應爲“Page Views”。
+- 創建一個 `draw_bar_plot` 函數,用於繪製類似於“examples/Figure_2.png”的條形圖。 它應該顯示按年份分組的每個月的平均每日頁面瀏覽量。 圖例應顯示月份標籤並具有“Months”標題。 在圖表上,x 軸上的標籤應爲“Years”,y 軸上的標籤應爲“Average Page Views”。
+- 創建一個 `draw_box_plot` 函數,該函數使用 Seaborn 繪製兩個相鄰的箱形圖,類似於“examples/Figure_3.png”。 這些箱線圖應顯示值在給定年份或月份內的分佈情況以及隨時間推移的比較情況。 第一個圖表的標題應爲“Year-wise Box Plot (Trend)”,第二個圖表的標題應爲“Month-wise Box Plot (Seasonality)”。 確保底部的月份標籤從“Jan”開始,並且 x 和 x 軸標記正確。 樣板文件包括準備數據的命令。
+
+對於每個圖表,請確保使用數據框的副本。 單元測試是在 `test_module.py` 下爲你編寫的。
+
+樣板文件還包括保存和返回圖像的命令。
+
+## 開發
+
+對於開發,你可以使用 `main.py` 來測試你的函數。 單擊“運行”按鈕,`main.py` 將運行。
+
+## 測試
+
+爲了你的方便,我們將測試從 `test_module.py` 導入到 `main.py`。 只要你點擊“運行”按鈕,測試就會自動運行。
+
+## 提交
+
+複製項目的 URL 並將其提交給 freeCodeCamp。
# --hints--
diff --git a/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/sea-level-predictor.md b/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/sea-level-predictor.md
index b2836a4656..97e9f9d9b0 100644
--- a/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/sea-level-predictor.md
+++ b/curriculum/challenges/chinese-traditional/08-data-analysis-with-python/data-analysis-with-python-projects/sea-level-predictor.md
@@ -8,13 +8,44 @@ dashedName: sea-level-predictor
# --description--
-在本項目中,您將分析自 1880 年以來全球平均海平面變化的數據集。 您將使用這些數據來預測到 2050 年的海平面變化。
+你將通過使用我們的[Replit 入門代碼](https://replit.com/github/freeCodeCamp/boilerplate-sea-level-predictor)來完成本項目。
-你可以在 [Replit 上查看整個項目的具體描述和初始代碼](https://replit.com/github/freeCodeCamp/boilerplate-sea-level-predictor)。
+我們仍在開發 Python 課程的交互式教學部分。 目前,你可以在 YouTube 上通過 freeCodeCamp.org 上傳的一些視頻學習這個項目相關的知識。
-打開此鏈接後,fork 這個項目。 一旦你根據 “README.md” 中的說明完成項目,請提交你的項目到下面的鏈接。
+- [Python for Everybody 視頻課程](https://www.freecodecamp.org/news/python-for-everybody/)(14 小時)
+- [Learn Python 視頻課程](https://www.freecodecamp.org/news/learn-python-video-course/)(10 小時)
+
+# --instructions--
+
+你將分析自 1880 年以來全球平均海平面變化的數據集。 你將使用這些數據來預測到 2050 年的海平面變化。
+
+使用數據完成以下任務:
+
+- 使用 Pandas 從 `epa-sea-level.csv` 導入數據。
+- 使用 matplotlib 創建散點圖,使用“Year”列作爲 x 軸,將“CSIRO Adjusted Sea Level”列作爲 y 軸。
+- 使用 `scipy.stats` 中的 `linregress` 函數來獲得最佳擬合線的斜率和 y 截距。 在散點圖的頂部繪製最佳擬合線。 使線穿過 2050 年以預測 2050 年的海平面上升。
+- 僅使用數據集中從 2000 年到最近一年的數據繪製一條新的最佳擬合線。 如果上升速度繼續與 2000 年一樣,則使該線也經過 2050 年以預測 2050 年的海平面上升。
+- x 標籤應爲 “Year”,y 標籤應爲 “Sea Level (inches)”,標題應爲 “Rise in Sea Level”。
+
+單元測試是在 `test_module.py` 下爲你編寫的。
+
+樣板文件還包括保存和返回圖像的命令。
+
+## 開發
+
+對於開發,你可以使用 `main.py` 來測試你的函數。 單擊“運行”按鈕,`main.py` 將運行。
+
+## 測試
+
+爲了你的方便,我們將測試從 `test_module.py` 導入到 `main.py`。 只要你點擊“運行”按鈕,測試就會自動運行。
+
+## 提交
+
+複製項目的 URL 並將其提交給 freeCodeCamp。
+
+## 數據源
+[Global Average Absolute Sea Level Change](https://datahub.io/core/sea-level-rise), 1880-2014 from the US Environmental Protection Agency using data from CSIRO, 2015; NOAA, 2015.
-我們仍在開發 Python 數據分析課程的交互式課程部分。 現在,你需要使用其他資源來學習如何通過這一挑戰。
# --hints--
diff --git a/curriculum/challenges/chinese-traditional/09-information-security/information-security-projects/anonymous-message-board.md b/curriculum/challenges/chinese-traditional/09-information-security/information-security-projects/anonymous-message-board.md
index 4bcf54054c..3d8a7e3cd7 100644
--- a/curriculum/challenges/chinese-traditional/09-information-security/information-security-projects/anonymous-message-board.md
+++ b/curriculum/challenges/chinese-traditional/09-information-security/information-security-projects/anonymous-message-board.md
@@ -16,7 +16,7 @@ dashedName: anonymous-message-board
- 使用 [我們的 Replit 啓動項目](https://replit.com/github/freeCodeCamp/boilerplate-project-messageboard)來完成你的項目。
- 使用一個你喜歡的站點生成器來完成項目。 需要確定包含了我們 GitHub 倉庫的所有文件。
-完成本項目後,請將一個正常運行的 demo(項目演示)託管在可以公開訪問的平臺。 然後將 URL 提交到 `Solution Link` 中。 此外,還可以將項目的源碼提交到 `GitHub Link` 中。
+完成本項目後,請將一個正常運行的 demo(項目演示)託管在可以公開訪問的平臺。 然後將 URL 提交到 `Solution Link` 中。 此外,還可以提交一個指向項目源碼的 `GitHub Link`。
# --instructions--
@@ -116,49 +116,270 @@ async (getUserInput) => {
你可以向 `/api/replies/{board}` 發送一個 POST 請求,其中包括字段 `text`、`delete_password` & `thread_id`。 這將更新 `bumped_on` 日期到評論日期。 在主題的 `replies` 數組中,將保存一個對象,至少有 `_id`、`text`、`created_on`、`delete_password`、& `reported` 這些屬性。
```js
+async (getUserInput) => {
+ const url = getUserInput('url');
+ const body = await fetch(url + '/api/threads/fcc_test');
+ const thread = await body.json();
+ const date = new Date();
+ const text = `fcc_test_reply_${date}`;
+ const delete_password = 'delete_me';
+ const thread_id = thread[0]._id;
+ const replyCount = thread[0].replies.length;
+
+ const data = { text, delete_password, thread_id };
+ const res = await fetch(url + '/api/replies/fcc_test', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(data)
+ });
+ if (res.ok) {
+ const checkData = await fetch(`${url}/api/replies/fcc_test?thread_id=${thread_id}`);
+ const parsed = await checkData.json();
+ try {
+ assert.equal(parsed.replies.length, replyCount + 1);
+ assert.equal(parsed.replies[0].text, text);
+ assert.equal(parsed._id, thread_id);
+ assert.equal(parsed.bumped_on, parsed.replies[0].created_on);
+ } catch (err) {
+ throw new Error(err.responseText || err.message);
+ }
+ } else {
+ throw new Error(`${res.status} ${res.statusText}`);
+ }
+};
```
你可以向 `/api/threads/{board}` 發送一個 GET 請求。 返回的將是一個數組,包括論壇上最近的 10 個被回覆的主題,及每個主題最新的 3 個回帖。 `reported` 和 `delete_password` 字段將不會被髮送到客戶端。
```js
+async (getUserInput) => {
+ const url = getUserInput('url');
+ const res = await fetch(url + '/api/threads/fcc_test');
+ if (res.ok) {
+ const threads = await res.json();
+ try {
+ assert.equal(res.status, 200);
+ assert.isAtMost(threads.length, 10);
+ for (let i = 0; i < threads.length; i++) {
+ assert.containsAllKeys(threads[i], ["_id", "text", "created_on", "bumped_on", "replies"]);
+ assert.isAtMost(threads[i].replies.length, 3);
+ assert.notExists(threads[i].delete_password);
+ assert.notExists(threads[i].reported);
+ for (let j = 0; j < threads[i].replies.length; j++) {
+ assert.notExists(threads[i].replies[j].delete_password);
+ assert.notExists(threads[i].replies[j].reported);
+ }
+ }
+ } catch (err) {
+ throw new Error(err.responseText || err.message);
+ }
+ } else {
+ throw new Error(`${res.status} ${res.statusText}`);
+ }
+};
```
你可以向 `/api/replies/{board}?thread_id={thread_id}` 發送一個 GET 請求。 返回的將是帶有所有的回覆的整個主題,不包括與之前測試相同的客戶端字段。
```js
+async (getUserInput) => {
+ const url = getUserInput('url');
+ let res = await fetch(url + '/api/threads/fcc_test');
+ const threads = await res.json();
+ const thread_id = threads[0]._id;
+ res = await fetch(`${url}/api/replies/fcc_test?thread_id=${thread_id}`);
+ if (res.ok) {
+ const thread = await res.json();
+ try {
+ assert.equal(res.status, 200);
+ assert.isObject(thread);
+ assert.containsAllKeys(thread, ["_id", "text", "created_on", "bumped_on", "replies"]);
+ assert.isArray(thread.replies);
+ assert.notExists(thread.delete_password);
+ assert.notExists(thread.reported);
+ for (let i = 0; i < thread.replies.length; i++) {
+ assert.notExists(thread.replies[i].delete_password);
+ assert.notExists(thread.replies[i].reported);
+ }
+ } catch (err) {
+ throw new Error(err.responseText || err.message);
+ }
+ } else {
+ throw new Error(`${res.status} ${res.statusText}`);
+ }
+};
```
你可以向 `/api/threads/{board}` 發送一個 DELETE 請求,並傳遞 `thread_id` & `delete_password` 來刪除該線程。 返回的將是字符串 `incorrect password` 或 `success`。
```js
+async (getUserInput) => {
+ const url = getUserInput('url');
+ let res = await fetch(url + '/api/threads/fcc_test');
+ const threads = await res.json();
+ const thread_id = threads[0]._id;
+ let data = { thread_id, delete_password: "wrong_password" };
+ const res_invalid = await fetch(url + '/api/threads/fcc_test', {
+ method: 'DELETE',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(data)
+ });
+ data = { thread_id, delete_password: "delete_me" };
+ res = await fetch(url + '/api/threads/fcc_test', {
+ method: 'DELETE',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(data)
+ });
+ if (res.ok) {
+ const deleted = await res.text();
+ const not_deleted = await res_invalid.text();
+ try {
+ assert.equal(res.status, 200);
+ assert.equal(deleted, "success");
+ assert.equal(not_deleted, "incorrect password");
+ } catch (err) {
+ throw new Error(err.responseText || err.message);
+ }
+ } else {
+ throw new Error(`${res.status} ${res.statusText}`);
+ }
+};
```
你可以向 `/api/replies/{board}` 發送一個 DELETE 請求,並傳遞 `thread_id`、`reply_id`、& `delete_password`。 返回的將是字符串 `incorrect password` 或 `success`。 成功後,`reply_id` 的文本將更改爲 `[deleted]`。
```js
+async (getUserInput) => {
+ const url = getUserInput('url');
+ const thread_data = {
+ text: "fcc_test_thread",
+ delete_password: "delete_me",
+ };
+ await fetch(`${url}/api/threads/fcc_test`, {
+ method: "POST",
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(thread_data)
+ });
+ let res = await fetch(`${url}/api/threads/fcc_test`);
+ let threads = await res.json();
+ const thread_id = threads[0]._id;
+
+ const reply_data = { thread_id, text: "fcc_test_reply", delete_password: "delete_me" };
+ await fetch(`${url}/api/replies/fcc_test`, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(reply_data)
+ });
+ res = await fetch(`${url}/api/threads/fcc_test`);
+ threads = await res.json();
+ const reply_id = threads[0].replies[0]._id;
+
+ const data = { thread_id, reply_id, delete_password: "delete_me" };
+ res = await fetch(url + '/api/replies/fcc_test', {
+ method: 'DELETE',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(data)
+ });
+
+ if (res.ok) {
+ const deleted = await res.text();
+ try {
+ assert.equal(res.status, 200);
+ assert.equal(deleted, "success");
+ res = await fetch(`${url}/api/replies/fcc_test?thread_id=${thread_id}`);
+ const thread = await res.json();
+ assert.equal(thread._id, thread_id);
+ assert.equal(thread.replies[0]._id, reply_id);
+ assert.equal(thread.replies[0].text, "[deleted]");
+ } catch (err) {
+ throw new Error(err.responseText || err.message);
+ }
+ } else {
+ throw new Error(`${res.status} ${res.statusText}`);
+ }
+};
```
-你可以向 `/api/threads/{board}` 發送一個 PUT 請求,並傳遞 `thread_id`。 返回的將是字符串 `success`。 `thread_id` 回覆的 `reported` 值將改爲 `true`。
+你可以向 `/api/threads/{board}` 發送一個 PUT 請求,並傳遞 `thread_id`。 返回的將是字符串 `reported`。 `thread_id` 回覆的 `reported` 值將改爲 `true`。
```js
+async (getUserInput) => {
+ const url = getUserInput('url');
+ let res = await fetch(`${url}/api/threads/fcc_test`);
+ const threads = await res.json();
+ const report_id = threads[0]._id;
+ const data = { report_id };
+
+ res = await fetch(`${url}/api/threads/fcc_test`, {
+ method: 'PUT',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(data)
+ });
+
+ if (res.ok) {
+ const reported = await res.text();
+ try {
+ assert.equal(res.status, 200);
+ assert.equal(reported, "reported");
+ } catch (err) {
+ throw new Error(err.responseText || err.message);
+ }
+ } else {
+ throw new Error(`${res.status} ${res.statusText}`);
+ }
+};
```
-你可以通過向 `/api/replies/{board}` 發送 PUT 請求並傳遞 `thread_id` & `reply_id`。 返回的將是字符串 `success`。 `reply_id` 的 `reported` 值將被改變爲 `true`。
+你可以通過向 `/api/replies/{board}` 發送 PUT 請求並傳遞 `thread_id` & `reply_id`。 返回的將是字符串 `reported`。 `reply_id` 的 `reported` 值將被改變爲 `true`。
```js
+async (getUserInput) => {
+ const url = getUserInput('url');
+ let res = await fetch(`${url}/api/threads/fcc_test`);
+ const threads = await res.json();
+ const thread_id = threads[0]._id;
+ const reply_id = threads[0].replies[0]._id;
+ const data = { thread_id, reply_id };
+
+ res = await fetch(`${url}/api/replies/fcc_test`, {
+ method: 'PUT',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(data)
+ });
+
+ if (res.ok) {
+ const reported = await res.text();
+ try {
+ assert.equal(res.status, 200);
+ assert.equal(reported, "reported");
+ } catch (err) {
+ throw new Error(err.responseText || err.message);
+ }
+ } else {
+ throw new Error(`${res.status} ${res.statusText}`);
+ }
+};
```
所有 10 項功能測試都已完成並通過。
```js
-
+async (getUserInput) => {
+ const tests = await fetch(getUserInput('url') + '/_api/get-tests');
+ const parsed = await tests.json();
+ assert.isTrue(parsed.length >= 10);
+ parsed.forEach((test) => {
+ assert.equal(test.state, 'passed');
+ assert.isAtLeast(test.assertions.length, 1);
+ });
+};
```
# --solutions--
diff --git a/curriculum/challenges/chinese-traditional/09-information-security/information-security-projects/port-scanner.md b/curriculum/challenges/chinese-traditional/09-information-security/information-security-projects/port-scanner.md
index fc0bb64c55..3b1c42645f 100644
--- a/curriculum/challenges/chinese-traditional/09-information-security/information-security-projects/port-scanner.md
+++ b/curriculum/challenges/chinese-traditional/09-information-security/information-security-projects/port-scanner.md
@@ -9,22 +9,74 @@ dashedName: port-scanner
# --description--
+你將通過使用我們的 [Replit 入門代碼](https://replit.com/github/freeCodeCamp/boilerplate-port-scanner) 來完成本項目。
+
+我們仍在開發 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 小時)
+
+# --instructions--
+
使用 Python 創建一個端口掃描器。
-你可以訪問 [Replit 上的完整項目描述和啓動代碼](https://replit.com/github/freeCodeCamp/boilerplate-port-scanner)。
+在 `port_scanner.py` 文件中,創建一個名爲 `get_open_ports` 的函數,它接受一個 `target` 參數和一個 `port_range` 參數。 `target` 可以是 URL 或 IP 地址。 `port_range` 是兩個數字的列表,表示要檢查的端口範圍的第一個和最後一個數字。
-在打開鏈接之後 fork 該項目。 根據 “README.md” 中的指示完成整個項目,然後在下面提交你的項目鏈接。
+以下是如何調用該函數的示例:
-Python 課程的交互式教學部分仍在開發當中。 目前,freeCodeCamp YouTube 頻道上的一些視頻將會教授你這個項目要求的一些 Python 技能。
+```py
+get_open_ports("209.216.230.240", [440, 445])
+get_open_ports("www.stackoverflow.com", [79, 82])
+```
-
+該函數應返回給定範圍內的開放端口列表。
+
+`get_open_ports` 函數還應採用可選的第三個參數 `True` 來表示“詳細”模式。 如果將其設置爲 true,則該函數應返回描述性字符串而不是端口列表。
+
+以下是詳細模式下應返回的字符串格式(`{}` 中的文本表示應顯示的信息):
+
+```bash
+Open ports for {URL} ({IP address})
+PORT SERVICE
+{port} {service name}
+{port} {service name}
+```
+
+你可以使用 `common_ports.py` 中的字典爲每個端口獲取正確的服務名稱。
+
+例如,如果函數是這樣調用的:
+
+```py
+port_scanner.get_open_ports("scanme.nmap.org", [20, 80], True)
+```
+
+它應該返回以下內容:
+
+```bash
+Open ports for scanme.nmap.org (45.33.32.156)
+PORT SERVICE
+22 ssh
+80 http
+```
+
+確保包含正確的間距和換行符。
+
+如果傳入 `get_open_ports` 函數的 URL 無效,該函數應返回字符串:“Error: Invalid hostname”。
+
+如果傳入 `get_open_ports` 函數的 IP 地址無效,該函數應返回字符串:“Error: Invalid IP address”。
+
+## 開發
+
+在 `port_scanner.py` 中編寫你的代碼。 對於開發,你可以使用 `main.py` 來測試你的代碼。 單擊“運行”按鈕,`main.py` 將運行。
+
+## 測試
+
+這個項目的單元測試在 `test_module.py` 中。 爲了你的方便,我們將測試從 `test_module.py` 導入到 `main.py`。 只要你點擊“運行”按鈕,測試就會自動運行。
+
+## 提交
+
+複製項目的 URL 並將其提交給 freeCodeCamp。
# --hints--
diff --git a/curriculum/challenges/chinese-traditional/09-information-security/information-security-projects/sha-1-password-cracker.md b/curriculum/challenges/chinese-traditional/09-information-security/information-security-projects/sha-1-password-cracker.md
index 7a74cecb66..4ad5dbe6d3 100644
--- a/curriculum/challenges/chinese-traditional/09-information-security/information-security-projects/sha-1-password-cracker.md
+++ b/curriculum/challenges/chinese-traditional/09-information-security/information-security-projects/sha-1-password-cracker.md
@@ -9,22 +9,51 @@ dashedName: sha-1-password-cracker
# --description--
+你將通過使用我們的 [Replit 入門代碼](https://replit.com/github/freeCodeCamp/boilerplate-SHA-1-password-cracker) 來完成本項目。
+
+我們仍在開發 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 小時)
+
+# --instructions--
+
+密碼不應以純文本形式存儲。 它們應該存儲爲哈希值,以防萬一密碼列表被泄露。 然而,並不是所有的哈希都是一樣的。
+
在這個項目中,你將通過創建一個密碼破解器來找出使用 SHA-1 散列的密碼,從而瞭解到良好安全的重要性。
-你可以訪問 [Replit 上的完整項目描述和啓動代碼](https://replit.com/github/freeCodeCamp/boilerplate-SHA-1-password-cracker)。
+創建一個函數,該函數接受密碼的 SHA-1 哈希值,如果它是使用的前 10,000 個密碼之一,則返回該密碼。 如果 SHA-1 哈希不是數據庫中的密碼,則返回“密碼不在數據庫中”。
-進入該鏈接後,fork 該項目。 一旦你根據 “README.md” 中的說明完成了項目,請在下面提交你的項目鏈接。
+該函數應該對 `top-10000-passwords.txt` 中的每個密碼進行散列,並將其與傳遞給函數的散列進行比較。
-我們仍在開發 Python 課程的交互式教學部分。 目前,freeCodeCamp.org YouTube 頻道上的一些視頻可以教你這個項目所需的一些 Python 技能。
+該函數應採用名爲 `use_salts` 的可選第二個參數。 如果設置爲 true,則文件 `known-salts.txt` 中的每個 salt 字符串,都應該在散列之前,和將它與傳遞給函數的哈希值進行比較之前,添加到 `top-10000-passwords.txt` 中的每個密碼的之前和之後。
-
+以下是一些用於測試該功能的散列密碼:
+
+- `b305921a3723cd5d70a375cd21a61e60aabb84ec` 應該返回 “sammy123”
+- `c7ab388a5ebefbf4d550652f1eb4d833e5316e3e` 應該返回 “abacab”
+- `5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8` 應該返回 “password”
+
+以下是一些散列密碼,用於在 `use_salts` 設置爲 `True` 時測試該功能:
+
+- `53d8b3dc9d39f0184144674e310185e41a87ffd5` 應該返回 “superman”
+- `da5a4e8cf89539e66097acd2f8af128acae2f8ae` 應該返回 “q1w2e3r4t5”
+- `ea3f62d498e3b98557f9f9cd0d905028b3b019e1` 應該返回 “bubbles1”
+
+`hashlib` 庫已經爲你導入。 你應該在你的代碼中使用它。 [在此瞭解更多關於 “hashlib” 的信息](https://docs.python.org/3/library/hashlib.html)
+
+## 開發
+
+在 `password_cracker.py` 中編寫你的代碼。 對於開發,你可以使用 `main.py` 來測試你的代碼。 單擊“運行”按鈕,`main.py` 將運行。
+
+## 測試
+
+此項目的單元測試在 `test_module.py` 中。 爲了你的方便,我們將測試從 `test_module.py` 導入到 `main.py`。 只要你點擊“運行”按鈕,測試就會自動運行。
+
+## 提交
+
+複製項目的 URL 並將其提交給 freeCodeCamp。
# --hints--
diff --git a/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/add-a-box-shadow-to-a-card-like-element.md b/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/add-a-box-shadow-to-a-card-like-element.md
index 8bdf13cfcf..f93f70196f 100644
--- a/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/add-a-box-shadow-to-a-card-like-element.md
+++ b/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/add-a-box-shadow-to-a-card-like-element.md
@@ -11,13 +11,13 @@ dashedName: add-a-box-shadow-to-a-card-like-element
`box-shadow` 属性用来给元素添加阴影,该属性值是由逗号分隔的一个或多个阴影列表。
-`box-shadow` 属性的阴影依次由下面这些值描述:
+`box-shadow` 属性按顺序采用以下值:
- offset-x
阴影的水平偏移量;
- offset-y
阴影的垂直偏移量;
- blur-radius
模糊半径;
- spread-radius
阴影扩展半径;
+ offset-x
(阴影的水平偏移量),
+ offset-y
(阴影的垂直偏移量),
+ blur-radius
+ spread-radius
color
diff --git a/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/adjust-the-hue-of-a-color.md b/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/adjust-the-hue-of-a-color.md
index 4c96f6b2c6..d8a1e6fecb 100644
--- a/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/adjust-the-hue-of-a-color.md
+++ b/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/adjust-the-hue-of-a-color.md
@@ -9,7 +9,7 @@ dashedName: adjust-the-hue-of-a-color
# --description--
-颜色具有多种特性,包括色相、饱和度和亮度。 CSS3 引入了 `hsl()` 做为颜色的描述方式。
+颜色具有多种特性,包括色相、饱和度和亮度。 CSS3 引入了`hsl()`函数,作为直接说明这些特征来挑选颜色的替代方法。
**色相** 是色彩的基本属性,就是平常所说的颜色名称,如红色、黄色等。 以颜色光谱为例,光谱左边从红色开始,移动到中间的绿色,一直到右边的蓝色,色相值就是沿着这条线的取值。 在 `hsl()` 里面,色相用色环来代替光谱,色相值就是色环里面的颜色对应的从 0 到 360 度的角度值。
@@ -27,19 +27,19 @@ dashedName: adjust-the-hue-of-a-color
# --hints--
-应使用 `hsl()` 属性来设置颜色为 `green`。
+应使用 `hsl()` 函数来设置颜色为 `green`。
```js
assert(code.match(/\.green\s*?{\s*?background-color\s*:\s*?hsl/gi));
```
-应使用 `hsl()` 属性来设置颜色为 `cyan`。
+应使用 `hsl()` 函数来设置颜色为 `cyan`。
```js
assert(code.match(/\.cyan\s*?{\s*?background-color\s*:\s*?hsl/gi));
```
-应使用 `hsl()` 属性来设置颜色为 `blue`。
+应使用 `hsl()` 函数来设置颜色为 `blue`。
```js
assert(code.match(/\.blue\s*?{\s*?background-color\s*:\s*?hsl/gi));
diff --git a/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/create-a-graphic-using-css.md b/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/create-a-graphic-using-css.md
index 9f17344fc7..8d644a5de9 100644
--- a/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/create-a-graphic-using-css.md
+++ b/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/create-a-graphic-using-css.md
@@ -15,11 +15,11 @@ dashedName: create-a-graphic-using-css
为了创建一个圆形的对象,`border-radius` 应该被设置成 50%。
-你应该还记得之前关卡的 `box-shadow` 属性以及它的依次取值 `offset-x`、`offset-y`、`blur-radius`、`spread-radius` 和颜色值。 其中 `blur-radius` 和 `spread-radius` 是可选的。
+你应该还记得之前关卡的 `box-shadow` 属性以及它的依次取值 `offset-x`、`offset-y`、`blur-radius`、`spread-radius` 和 `color` 值。 其中 `blur-radius` 和 `spread-radius` 是可选的。
# --instructions--
-把编辑器里的正方形元素变成新月形状。 首先,把 `background-color` 改为 `transparent`,接着把 `border-radius` 属性设置成 50%,以创建一个圆形。 最后,更改 `box-shadow` 属性,使其 `offset-x` 为 25px,`offset-y` 为 10px,`blur-radius` 为 0,`spread-radius` 为 0,颜色为 `blue`。
+把编辑器里的正方形元素变成新月形状。 首先,把 `background-color` 改为 `transparent`,接着把 `border-radius` 属性设置成 50%,以创建一个圆形。 最后,更改 `box-shadow` 属性,使其 `offset-x` 为 25px,`offset-y` 为 10px,`blur-radius` 为 0,`spread-radius` 为 0,`color` 为 `blue`。
# --hints--
@@ -35,7 +35,7 @@ assert(code.match(/background-color:\s*?transparent;/gi));
assert(code.match(/border-radius:\s*?50%;/gi));
```
-更改 `box-shadow` 属性,使其 `offset-x` 为 25px,`offset-y` 为 10px,`blur-radius` 为 0,`spread-radius` 为 0,颜色为 `blue`。
+更改 `box-shadow` 属性,使其 `offset-x` 为 25px,`offset-y` 为 10px,`blur-radius` 为 0,`spread-radius` 为 0,`color` 为 `blue`。
```js
assert(
diff --git a/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/create-a-more-complex-shape-using-css-and-html.md b/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/create-a-more-complex-shape-using-css-and-html.md
index 556adcf012..78a93a761f 100644
--- a/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/create-a-more-complex-shape-using-css-and-html.md
+++ b/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/create-a-more-complex-shape-using-css-and-html.md
@@ -28,15 +28,15 @@ dashedName: create-a-more-complex-shape-using-css-and-html
# --instructions--
-把屏幕里的元素变成心形。 在 `heart::after` 选择器里,把 `background-color` 改成 `pink`,把 `border-radius` 改成 50%。
+把屏幕里的元素变成心形。 在 `.heart::after` 选择器里,把 `background-color` 改成 `pink`,把 `border-radius` 改成 50%。
接下来,用类选择器选取 class 为 `heart`(只是 `heart`)的元素,为它添加 `transform` 属性。 使用 `rotate()` 函数并设置角度为 -45 度。
-最后,在 `heart::before` 选择器里面,设置 `content` 属性值为空字符串。
+最后,在 `,heart::before` 选择器里面,设置 `content` 属性值为空字符串。
# --hints--
-`heart::after` 选择器的 `background-color` 属性值应为 `pink`。
+`.heart::after` 选择器的 `background-color` 属性值应为 `pink`。
```js
const heartAfter = code.match(/\.heart::after\s*{[\s\S]+?[^\}]}/g)[0];
@@ -45,7 +45,7 @@ assert(
);
```
-`heart::after` 伪元素的 `border-radius` 属性值应为 50%。
+`.heart::after` 伪元素的 `border-radius` 属性值应为 50%。
```js
assert(code.match(/border-radius\s*?:\s*?50%/gi).length == 2);
@@ -57,7 +57,7 @@ class 为 `heart` 的元素的 `transform` 属性应使用 `rotate()` 函数并
assert(code.match(/transform\s*?:\s*?rotate\(\s*?-45deg\s*?\)/gi));
```
-`heart::before` 伪元素的 `content` 应为空字符串。
+`.heart::before` 伪元素的 `content` 应为空字符串。
```js
assert(code.match(/\.heart::before\s*?{\s*?content\s*?:\s*?("|')\1\s*?;/gi));
diff --git a/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/use-a-bezier-curve-to-move-a-graphic.md b/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/use-a-bezier-curve-to-move-a-graphic.md
index 3691df1b87..8124e9052a 100644
--- a/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/use-a-bezier-curve-to-move-a-graphic.md
+++ b/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/use-a-bezier-curve-to-move-a-graphic.md
@@ -11,7 +11,7 @@ dashedName: use-a-bezier-curve-to-move-a-graphic
前面的关卡涉及了使用 `ease-out` 预定义值描述了动画以高速开始低速结束。 右边的动画展示了 `ease-out` 效果(蓝色的元素)和 `linear` 效果(红色的元素)的区别。 同样的,`ease-out` 预定义值也可以用贝塞尔曲线函数实现。
-通俗的讲,将一条直线放在范围只有 1 的坐标轴中,并从中间拿 `p1` 和 `p2` 两个点来拉扯(X 轴的取值区间是 \[0, 1],Y 轴任意),最后形成的曲线就是动画的贝塞尔速度曲线。 下面是贝塞尔曲线模仿 ease-out 预定义值的例子:
+通俗的讲,将一条直线放在范围只有 1 的坐标轴中,并从中间拿 `p1` 和 `p2` 两个点来拉扯(X 轴的取值区间是 \[0, 1],Y 轴任意),最后形成的曲线就是动画的贝塞尔速度曲线。 下面是一个使用值来模仿 `ease-out` 样式的 Bezier 曲线示例:
```css
animation-timing-function: cubic-bezier(0, 0, 0.58, 1);
diff --git a/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/use-a-css-linear-gradient-to-create-a-striped-element.md b/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/use-a-css-linear-gradient-to-create-a-striped-element.md
index 01a6a44bbf..c02e080722 100644
--- a/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/use-a-css-linear-gradient-to-create-a-striped-element.md
+++ b/curriculum/challenges/chinese/01-responsive-web-design/applied-visual-design/use-a-css-linear-gradient-to-create-a-striped-element.md
@@ -47,7 +47,7 @@ assert(!code.match(/90deg/gi));
assert(code.match(/yellow\s+?0(px)?/gi));
```
-40px 处的一个渐变颜色应该是 `yellow`。
+40 像素处的第一个色标应该是 `yellow`。
```js
assert(code.match(/yellow\s+?40px/gi));
diff --git a/curriculum/challenges/chinese/01-responsive-web-design/basic-css/change-a-variable-for-a-specific-area.md b/curriculum/challenges/chinese/01-responsive-web-design/basic-css/change-a-variable-for-a-specific-area.md
index b1ea9f6dc4..b2c68b0b17 100644
--- a/curriculum/challenges/chinese/01-responsive-web-design/basic-css/change-a-variable-for-a-specific-area.md
+++ b/curriculum/challenges/chinese/01-responsive-web-design/basic-css/change-a-variable-for-a-specific-area.md
@@ -11,7 +11,7 @@ dashedName: change-a-variable-for-a-specific-area
当你在 `:root` 里创建变量时,这些变量的作用域是整个页面。
-如果在元素里创建相同的变量,会重写作用于整个页面的变量的值。
+然后,你可以通过在一个特定的选择器中再次设置这些变量来重写这些变量。
# --instructions--
@@ -27,7 +27,7 @@ assert(
);
```
-`penguin` class 不应该包含 `background-color` 属性。
+`penguin` 类不应包含 `background-color` 属性。
```js
assert(
diff --git a/curriculum/challenges/chinese/01-responsive-web-design/basic-css/create-a-custom-css-variable.md b/curriculum/challenges/chinese/01-responsive-web-design/basic-css/create-a-custom-css-variable.md
index 768aa15c16..c067c3a8ec 100644
--- a/curriculum/challenges/chinese/01-responsive-web-design/basic-css/create-a-custom-css-variable.md
+++ b/curriculum/challenges/chinese/01-responsive-web-design/basic-css/create-a-custom-css-variable.md
@@ -15,7 +15,7 @@ dashedName: create-a-custom-css-variable
--penguin-skin: gray;
```
-这样就会创建一个 `--penguin-skin` 变量,它的值为 `gray`。 现在,其他元素可通过该变量来使元素变成灰色。
+这样就会创建一个 `--penguin-skin` 变量,它的值为 `gray`。 现在你可以在你的 CSS 中的其他地方使用这个变量来改变其他属性的值为灰色。
# --instructions--
diff --git a/curriculum/challenges/chinese/01-responsive-web-design/basic-css/inherit-styles-from-the-body-element.md b/curriculum/challenges/chinese/01-responsive-web-design/basic-css/inherit-styles-from-the-body-element.md
index fcc71dae95..df3e1b708e 100644
--- a/curriculum/challenges/chinese/01-responsive-web-design/basic-css/inherit-styles-from-the-body-element.md
+++ b/curriculum/challenges/chinese/01-responsive-web-design/basic-css/inherit-styles-from-the-body-element.md
@@ -77,7 +77,7 @@ assert(
);
```
-`h1` 元素的字体颜色应继承 `body` 元素所设置的绿色。
+`h1` 元素应该继承 `body` 的 `green` 颜色属性。
```js
assert($('h1').length > 0 && $('h1').css('color') === 'rgb(0, 128, 0)');
diff --git a/curriculum/challenges/chinese/01-responsive-web-design/basic-css/use-a-media-query-to-change-a-variable.md b/curriculum/challenges/chinese/01-responsive-web-design/basic-css/use-a-media-query-to-change-a-variable.md
index 4d4dbd47a2..68be67458f 100644
--- a/curriculum/challenges/chinese/01-responsive-web-design/basic-css/use-a-media-query-to-change-a-variable.md
+++ b/curriculum/challenges/chinese/01-responsive-web-design/basic-css/use-a-media-query-to-change-a-variable.md
@@ -15,7 +15,7 @@ CSS 变量可以简化媒体查询的定义方式。
# --instructions--
-在 `media query`(媒体查询)声明的 `:root` 选择器里,重定义 `--penguin-size` 的值为 `200px`。 同时,重新定义 `--penguin-skin` 的值为 `black`, 然后通过缩放页面来查看它们是否生效。
+在媒体查询声明的 `:root` 选择器里,重定义 `--penguin-size` 的值为 `200px`。 同时,重新定义 `--penguin-skin` 的值为 `black`, 然后通过缩放页面来查看它们是否生效。
# --hints--
diff --git a/curriculum/challenges/chinese/01-responsive-web-design/basic-css/use-abbreviated-hex-code.md b/curriculum/challenges/chinese/01-responsive-web-design/basic-css/use-abbreviated-hex-code.md
index e327d10b1a..40747d32b5 100644
--- a/curriculum/challenges/chinese/01-responsive-web-design/basic-css/use-abbreviated-hex-code.md
+++ b/curriculum/challenges/chinese/01-responsive-web-design/basic-css/use-abbreviated-hex-code.md
@@ -29,7 +29,7 @@ dashedName: use-abbreviated-hex-code
assert($('.red-text').css('color') === 'rgb(255, 0, 0)');
```
-应使用红色的 `hex code` 缩写形式,不应使用 `#FF0000`。
+应使用红色的缩写十六进制代码,而不是十六进制代码 `#FF0000`。
```js
assert(code.match(/\.red-text\s*?{\s*?color\s*:\s*?#F00\s*?;?\s*?}/gi));
@@ -41,7 +41,7 @@ assert(code.match(/\.red-text\s*?{\s*?color\s*:\s*?#F00\s*?;?\s*?}/gi));
assert($('.green-text').css('color') === 'rgb(0, 255, 0)');
```
-应使用绿色的 `hex code` 缩写形式,不应使用 `#00FF00`。
+应使用绿色的缩写十六进制代码,而不是十六进制代码 `#00FF00`。
```js
assert(code.match(/\.green-text\s*?{\s*?color\s*:\s*?#0F0\s*?;?\s*?}/gi));
@@ -53,7 +53,7 @@ assert(code.match(/\.green-text\s*?{\s*?color\s*:\s*?#0F0\s*?;?\s*?}/gi));
assert($('.cyan-text').css('color') === 'rgb(0, 255, 255)');
```
-应使用蓝绿色的 `hex code` 缩写形式,不应使用 `#00FFFF`。
+应使用青色的简写十六进制代码,而不是十六进制代码 `#00FFFF`。
```js
assert(code.match(/\.cyan-text\s*?{\s*?color\s*:\s*?#0FF\s*?;?\s*?}/gi));
@@ -65,7 +65,7 @@ assert(code.match(/\.cyan-text\s*?{\s*?color\s*:\s*?#0FF\s*?;?\s*?}/gi));
assert($('.fuchsia-text').css('color') === 'rgb(255, 0, 255)');
```
-应使用紫红色的 `hex code` 缩写形式,不应使用 `#FF00FF`。
+应使用紫红色的简写十六进制代码,而不是十六进制代码 `#FF00FF`。
```js
assert(code.match(/\.fuchsia-text\s*?{\s*?color\s*:\s*?#F0F\s*?;?\s*?}/gi));
diff --git a/curriculum/challenges/chinese/01-responsive-web-design/basic-css/use-hex-code-for-specific-colors.md b/curriculum/challenges/chinese/01-responsive-web-design/basic-css/use-hex-code-for-specific-colors.md
index e5e6a200b5..5cbef292a1 100644
--- a/curriculum/challenges/chinese/01-responsive-web-design/basic-css/use-hex-code-for-specific-colors.md
+++ b/curriculum/challenges/chinese/01-responsive-web-design/basic-css/use-hex-code-for-specific-colors.md
@@ -27,13 +27,13 @@ body {
# --hints--
-`body` 元素的背景颜色应为黑色。
+`body` 元素的 `background-color` 应为黑色。
```js
assert($('body').css('background-color') === 'rgb(0, 0, 0)');
```
-应使用 `hex code` 来替换 `black`。
+应该使用黑色的十六进制代码,而不是 `black` 这个词。
```js
assert(
diff --git a/curriculum/challenges/chinese/01-responsive-web-design/basic-html-and-html5/check-radio-buttons-and-checkboxes-by-default.md b/curriculum/challenges/chinese/01-responsive-web-design/basic-html-and-html5/check-radio-buttons-and-checkboxes-by-default.md
index b27e605ed1..2cb39e3ae9 100644
--- a/curriculum/challenges/chinese/01-responsive-web-design/basic-html-and-html5/check-radio-buttons-and-checkboxes-by-default.md
+++ b/curriculum/challenges/chinese/01-responsive-web-design/basic-html-and-html5/check-radio-buttons-and-checkboxes-by-default.md
@@ -11,7 +11,7 @@ dashedName: check-radio-buttons-and-checkboxes-by-default
用 `checked` 属性把第一个复选框和单选按钮都设置为默认选中。
-在一个 input 元素里面添加 `checked` 这个词,即可实现。 例如:
+为此,只需将单词 `checked` 添加到 `input` 元素的内部。 例如:
```html
diff --git a/curriculum/challenges/chinese/01-responsive-web-design/basic-html-and-html5/comment-out-html.md b/curriculum/challenges/chinese/01-responsive-web-design/basic-html-and-html5/comment-out-html.md
index 27be6ed910..7ff4dc4c03 100644
--- a/curriculum/challenges/chinese/01-responsive-web-design/basic-html-and-html5/comment-out-html.md
+++ b/curriculum/challenges/chinese/01-responsive-web-design/basic-html-and-html5/comment-out-html.md
@@ -43,7 +43,7 @@ assert($('p').length === 0);
assert(code.match(/[^fc]-->/g).length > 1);
```
-不要更改 `h1` 元素、`h2` 元素、`p` 元素的顺序。
+不要更改 `h1`、`h2`、`p` 元素的顺序。
```js
assert(
diff --git a/curriculum/challenges/chinese/01-responsive-web-design/basic-html-and-html5/inform-with-the-paragraph-element.md b/curriculum/challenges/chinese/01-responsive-web-design/basic-html-and-html5/inform-with-the-paragraph-element.md
index a407cf9430..9b50a0fd7d 100644
--- a/curriculum/challenges/chinese/01-responsive-web-design/basic-html-and-html5/inform-with-the-paragraph-element.md
+++ b/curriculum/challenges/chinese/01-responsive-web-design/basic-html-and-html5/inform-with-the-paragraph-element.md
@@ -9,7 +9,7 @@ dashedName: inform-with-the-paragraph-element
# --description--
-`p` 元素是网站上段落文本使用的元素。 `p` 是“paragraph(段落)”的缩写。
+`p` 元素是网站上段落文本的首选元素。 `p` 是“paragraph(段落)”的缩写。
你可以像这样创建一个段落:
diff --git a/curriculum/challenges/chinese/01-responsive-web-design/css-flexbox/align-elements-using-the-justify-content-property.md b/curriculum/challenges/chinese/01-responsive-web-design/css-flexbox/align-elements-using-the-justify-content-property.md
index f9e00874ea..60898ae264 100644
--- a/curriculum/challenges/chinese/01-responsive-web-design/css-flexbox/align-elements-using-the-justify-content-property.md
+++ b/curriculum/challenges/chinese/01-responsive-web-design/css-flexbox/align-elements-using-the-justify-content-property.md
@@ -17,7 +17,7 @@ flex 子元素有时不能充满整个 flex 容器, 所以我们经常需要
对于如何沿主轴线排放 flex 项目,有几种选择。 很常用的一种是 `justify-content: center;`:即 flex 子元素在 flex 容器中居中排列。 其他选择包括:
-flex-start
:从 flex 容器的起始位置开始排列项目。 对行来说是把项目移至左边, 对于列是把项目移至顶部。 如未设置 justify-content
的值,那么这就是默认值。flex-end
:从 flex 容器的终止位置开始排列项目。 对行来说是把项目移至右边, 对于列是把项目移至底部。space-between
:项目间保留一定间距地沿主轴居中排列。 第一个和最后一个项目被放置在容器边沿。 例如,在行中第一个项目会紧贴着容器左边,最后一个项目会紧贴着容器右边,然后其他项目均匀排布。space-around
:与space-between
相似,但头尾两个项目不会紧贴容器边缘,所有项目之间的空间均匀排布。space-evenly
:头尾两个项目不会紧贴容器边缘,所有项目之间的空间均匀排布。
+flex-start
:从 flex 容器的起始位置开始排列项目。 对行来说是把项目移至左边, 对于列是把项目移至顶部。 如未设置 justify-content
的值,那么这就是默认值。flex-end
:从 flex 容器的终止位置开始排列项目。 对行来说是把项目移至右边, 对于列是把项目移至底部。space-between
:项目间保留一定间距地沿主轴居中排列。 第一个和最后一个项目被放置在容器边沿。 例如,在行中第一个项目会紧贴着容器左边,最后一个项目会紧贴着容器右边,然后其他项目均匀排布。space-around
:与space-between
相似,但头尾两个项目不会紧贴容器边缘,所有项目之间的空间均匀排布。space-evenly
:在 flex 项目之间均匀分配空间,在 flex 容器的任一端都有一个完整的空间。
# --instructions--
diff --git a/curriculum/challenges/chinese/01-responsive-web-design/css-flexbox/use-the-flex-wrap-property-to-wrap-a-row-or-column.md b/curriculum/challenges/chinese/01-responsive-web-design/css-flexbox/use-the-flex-wrap-property-to-wrap-a-row-or-column.md
index 4728a0818f..23fdde2992 100644
--- a/curriculum/challenges/chinese/01-responsive-web-design/css-flexbox/use-the-flex-wrap-property-to-wrap-a-row-or-column.md
+++ b/curriculum/challenges/chinese/01-responsive-web-design/css-flexbox/use-the-flex-wrap-property-to-wrap-a-row-or-column.md
@@ -9,7 +9,7 @@ dashedName: use-the-flex-wrap-property-to-wrap-a-row-or-column
# --description--
-CSS flexbox 有一个把 flex 子元素拆分为多行(或多列)的特性。 默认情况下,flex 容器会调整项目大小,把它们都塞到一起。 对于行来说,所有项目都会在一条直线上。
+CSS flexbox 具有将 flex 容器拆分为多行(或列)的功能。 默认情况下,flex 容器会调整项目大小,把它们都塞到一起。 对于行来说,所有项目都会在一条直线上。
不过,使用 `flex-wrap` 属性可以使项目换行展示。 这意味着多出来的子元素会被移到新的行或列。 换行发生的断点由子元素和容器的大小决定。
diff --git a/curriculum/challenges/chinese/01-responsive-web-design/css-grid/place-items-in-grid-areas-using-the-grid-area-property.md b/curriculum/challenges/chinese/01-responsive-web-design/css-grid/place-items-in-grid-areas-using-the-grid-area-property.md
index a6a6d6be2a..40a65506ce 100644
--- a/curriculum/challenges/chinese/01-responsive-web-design/css-grid/place-items-in-grid-areas-using-the-grid-area-property.md
+++ b/curriculum/challenges/chinese/01-responsive-web-design/css-grid/place-items-in-grid-areas-using-the-grid-area-property.md
@@ -17,7 +17,7 @@ dashedName: place-items-in-grid-areas-using-the-grid-area-property
}
```
-这样,class 为 `item1` 的网格项就被放到了 `header` 区域里。 在这个示例中,网格项将占用第一行整行,因为这一整行都被命名为标题区域。
+这样,class 为 `item1` 的网格项就被放到了 `header` 区域里。 在这种情况下,该项目将使用整个顶行,因为该整行被命名为 `header` 区域。
# --instructions--
diff --git a/curriculum/challenges/chinese/01-responsive-web-design/css-grid/use-css-grid-units-to-change-the-size-of-columns-and-rows.md b/curriculum/challenges/chinese/01-responsive-web-design/css-grid/use-css-grid-units-to-change-the-size-of-columns-and-rows.md
index f7f9d3b637..d622c35f70 100644
--- a/curriculum/challenges/chinese/01-responsive-web-design/css-grid/use-css-grid-units-to-change-the-size-of-columns-and-rows.md
+++ b/curriculum/challenges/chinese/01-responsive-web-design/css-grid/use-css-grid-units-to-change-the-size-of-columns-and-rows.md
@@ -31,7 +31,7 @@ grid-template-columns: auto 50px 10% 2fr 1fr;
# --hints--
-class 为 `container` 的元素应具有 `grid-template-columns` 属性且属性值应为 `1fr 100px 2fr`。
+`container` 类应该有一个 `grid-template-columns` 属性,该属性具有以下宽度的三列:`1fr`、`100px` 和 `2fr`。
```js
assert(
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-algorithm-scripting/convert-celsius-to-fahrenheit.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-algorithm-scripting/convert-celsius-to-fahrenheit.md
index a7a2492c9b..160ec0143a 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-algorithm-scripting/convert-celsius-to-fahrenheit.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-algorithm-scripting/convert-celsius-to-fahrenheit.md
@@ -8,9 +8,9 @@ dashedName: convert-celsius-to-fahrenheit
# --description--
-将摄氏度转换为华氏度的计算方式为:摄氏度乘以 `9/5` 然后加上 `32`。
+从摄氏转换为华氏的公式是,摄氏温度乘以 `9/5`,再加上 `32`。
-输入参数 `celsius` 代表一个摄氏度的温度。 使用已定义的变量 `fahrenheit`,并赋值为相应的华氏度的温度值。 根据上述转换公式来进行转换。
+输入参数 `celsius` 代表一个摄氏度的温度。 使用已定义的变量 `fahrenheit`,并赋值为相应的华氏度的温度值。 使用上面提到的公式来帮助将摄氏温度转换为华氏温度。
# --hints--
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-data-structures/check-if-an-object-has-a-property.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-data-structures/check-if-an-object-has-a-property.md
index 00c42f33df..381ddf60cc 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-data-structures/check-if-an-object-has-a-property.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-data-structures/check-if-an-object-has-a-property.md
@@ -19,7 +19,7 @@ users.hasOwnProperty('Alan');
# --instructions--
-请完善这个函数,如果传递给它的对象包含四个名字 `Alan`、`Jeff`、`Sarah` 和 `Ryan`,函数返回 true,否则返回 false。
+请完善这个函数,如果传递给它的对象包含四个名字 `Alan`、`Jeff`、`Sarah` 和 `Ryan`,函数返回 `true`,否则返回 `false`。
# --hints--
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-data-structures/remove-items-using-splice.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-data-structures/remove-items-using-splice.md
index f09cad0542..cfe53f8d1c 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-data-structures/remove-items-using-splice.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-data-structures/remove-items-using-splice.md
@@ -10,7 +10,7 @@ dashedName: remove-items-using-splice
在之前的挑战中,我们已经学习了如何用 `shift()` 和 `pop()` 从数组的开头或末尾移除元素。 但如果我们想删除数组中间的一个元素, 或者想一次删除多个元素,该如何操作呢? 这时候我们就需要使用 `splice()` 方法了, `splice()` 可以让我们从数组中的任意位置**连续删除任意数量的元素**。
-`splice()` 最多可以接受 3 个参数,但现在我们先关注前两个。 `splice()` 接收的前两个参数是整数,表示正在调用 的`splice()` 数组中的元素的索引或位置。 别忘了,数组的索引是*从 0 开始的*,所以我们要用 `0` 来表示数组中的第一个元素。 `splice()` 的第一个参数代表从数组中的哪个索引开始移除元素,而第二个参数表示要从数组中的这个位置开始删除多少个元素。 例如:
+`splice()` 最多可以接受 3 个参数,但现在我们先关注前两个。 `splice()` 的前两个参数是整数,表示数组中调用 `splice()` 的项的索引或位置。 别忘了,数组的索引是*从 0 开始的*,所以我们要用 `0` 来表示数组中的第一个元素。 `splice()` 的第一个参数代表从数组中的哪个索引开始移除元素,而第二个参数表示要从数组中的这个位置开始删除多少个元素。 例如:
```js
let array = ['today', 'was', 'not', 'so', 'great'];
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-inequality-operator.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-inequality-operator.md
index 83ca2ad008..5593e46bcd 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-inequality-operator.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-inequality-operator.md
@@ -14,18 +14,16 @@ dashedName: comparison-with-the-inequality-operator
**例如**
```js
-1 != 2
-1 != "1"
-1 != '1'
-1 != true
-0 != false
+1 != 2 // true
+1 != "1" // false
+1 != '1' // false
+1 != true // false
+0 != false // false
```
-按顺序,这些表达式会返回 `true`、`false`、`false`、`false` 和 `false`。
-
# --instructions--
-在 `if` 语句中添加不等运算符 `!=` 以便函数在 `val` 不等于 `99` 时返回字符串 `Not Equal`。
+在 `if` 语句中添加不等式运算符 `!=` 以便函数在 `val` 不等于 `99` 时返回字符串 `Not Equal`。
# --hints--
@@ -59,7 +57,7 @@ assert(testNotEqual('12') === 'Not Equal');
assert(testNotEqual('bob') === 'Not Equal');
```
-你应该使用 `!=` 运算符。
+你应该使用 `!=` 运算符
```js
assert(code.match(/(?!!==)!=/));
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-less-than-operator.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-less-than-operator.md
index 3ae0d78c71..d1ace773e5 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-less-than-operator.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-less-than-operator.md
@@ -14,58 +14,56 @@ dashedName: comparison-with-the-less-than-operator
**例如:**
```js
-2 < 5
-'3' < 7
-5 < 5
-3 < 2
-'8' < 4
+2 < 5 // true
+'3' < 7 // true
+5 < 5 // false
+3 < 2 // false
+'8' < 4 // false
```
-按顺序,这些表达式会返回 `true`、`true`、`false`、`false` 和 `false`。
-
# --instructions--
-添加小于运算符到指定行,使得函数的返回语句有意义。
+将小于运算符添加到指示的行,以便返回语句有意义。
# --hints--
-`testLessThan(0)` 应该返回字符串 `Under 25`。
+`testLessThan(0)` 应该返回字符串 `Under 25`
```js
assert(testLessThan(0) === 'Under 25');
```
-`testLessThan(24)` 应该返回字符串 `Under 25`。
+`testLessThan(24)` 应该返回字符串 `Under 25`
```js
assert(testLessThan(24) === 'Under 25');
```
-`testLessThan(25)` 应该返回字符串 `Under 55`。
+`testLessThan(25)` 应该返回字符串 `Under 55`
```js
assert(testLessThan(25) === 'Under 55');
```
-`testLessThan(54)` 应该返回字符串 `Under 55`。
+`testLessThan(54)` 应该返回字符串 `Under 55`
```js
assert(testLessThan(54) === 'Under 55');
```
-`testLessThan(55)` 应该返回字符串 `55 or Over`。
+`testLessThan(55)` 应该返回字符串 `55 or Over`
```js
assert(testLessThan(55) === '55 or Over');
```
-`testLessThan(99)` 应该返回字符串 `55 or Over`。
+`testLessThan(99)` 应该返回字符串 `55 or Over`
```js
assert(testLessThan(99) === '55 or Over');
```
-应该使用 `<` 运算符至少两次。
+应该使用 `<` 运算符至少两次
```js
assert(code.match(/val\s*<\s*('|")*\d+('|")*/g).length > 1);
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-less-than-or-equal-to-operator.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-less-than-or-equal-to-operator.md
index f8c13e4626..68d7e58760 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-less-than-or-equal-to-operator.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-less-than-or-equal-to-operator.md
@@ -14,18 +14,16 @@ dashedName: comparison-with-the-less-than-or-equal-to-operator
**例如**
```js
-4 <= 5
-'7' <= 7
-5 <= 5
-3 <= 2
-'8' <= 4
+4 <= 5 // true
+'7' <= 7 // true
+5 <= 5 // true
+3 <= 2 // false
+'8' <= 4 // false
```
-按顺序,这些表达式会返回 `true`、`true`、`true`、`false` 和 `false`。
-
# --instructions--
-添加小于等于运算符到指定行,使得函数的返回语句有意义。
+将小于或等于运算符添加到指示的行,以便返回语句有意义。
# --hints--
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-equality-operator.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-equality-operator.md
index 46da9d9293..b4d509aece 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-equality-operator.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-equality-operator.md
@@ -16,17 +16,15 @@ dashedName: comparison-with-the-strict-equality-operator
**示例**
```js
-3 === 3
-3 === '3'
+3 === 3 // true
+3 === '3' // false
```
-这些条件将分别返回 `true` and `false`。
-
在第二个例子中,`3` 是一个 `Number` 类型,而 `'3'` 是一个 `String` 类型。
# --instructions--
-在 `if` 语句中使用严格相等运算符,这样当 `val` 严格等于 `7` 时,函数将返回字符串 `Equal`。
+在 `if` 语句中使用严格相等运算符,这样函数将在 `val` 严格等于 `7` 时返回字符串 `Equal`。
# --hints--
@@ -48,7 +46,7 @@ assert(testStrict(7) === 'Equal');
assert(testStrict('7') === 'Not Equal');
```
-你应该使用 `===` 运算符。
+应该使用 `===` 运算符
```js
assert(code.match(/(val\s*===\s*\d+)|(\d+\s*===\s*val)/g).length > 0);
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-inequality-operator.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-inequality-operator.md
index c18d6dc0c0..d5a3421f1e 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-inequality-operator.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/comparison-with-the-strict-inequality-operator.md
@@ -14,13 +14,11 @@ dashedName: comparison-with-the-strict-inequality-operator
**示例**
```js
-3 !== 3
-3 !== '3'
-4 !== 3
+3 !== 3 // false
+3 !== '3' // true
+4 !== 3 // true
```
-按顺序,这些表达式会返回 `false`、`true`、`true`。
-
# --instructions--
在 `if` 语句中,添加严格不相等运算符,这样函数在当 `val` 不严格等于 `17` 的时候,会返回 `Not Equal`。
@@ -51,7 +49,7 @@ assert(testStrictNotEqual(12) === 'Not Equal');
assert(testStrictNotEqual('bob') === 'Not Equal');
```
-应该使用 `!==` 运算符。
+应该使用 `!==` 运算符
```js
assert(code.match(/(val\s*!==\s*\d+)|(\d+\s*!==\s*val)/g).length > 0);
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/counting-cards.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/counting-cards.md
index 2b10dc4500..251ccf7b2b 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/counting-cards.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/counting-cards.md
@@ -25,7 +25,7 @@ dashedName: counting-cards
# --hints--
-卡牌序列 2、3、4、5、6 应该返回 `5 Bet`
+卡片序列 2、3、4、5、6 应返回字符串 `5 Bet`
```js
assert(
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/declare-a-read-only-variable-with-the-const-keyword.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/declare-a-read-only-variable-with-the-const-keyword.md
index ab5e98a380..77ad94805d 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/declare-a-read-only-variable-with-the-const-keyword.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/declare-a-read-only-variable-with-the-const-keyword.md
@@ -21,32 +21,28 @@ FAV_PET = "Dogs";
你应该始终使用 `const` 关键字命名不想重新分配的变量。 这有助于避免给一个常量进行额外的再次赋值。
-命名常量的常见做法是全部使用大写字母,单词之间用下划线分隔。
-
-**注意:** 对于不可变值,开发人员通常使用大写变量标识符,对可变值(对象和数组)使用小写或驼峰式标识符。 你将在后面的挑战中了解有关对象、数组以及不可变和可变值的更多信息。 同样在后面的挑战中,你将看到大写、小写或驼峰式变量标识符的示例。
+**注意:** 通常,开发者会用大写字母作为常量标识符,用小写字母或者驼峰命名作为变量(对象或数组)标识符。 你将在后面的挑战中了解有关对象、数组以及不可变和可变值的更多信息。 同样在后面的挑战中,你将看到大写、小写或驼峰式变量标识符的示例。
# --instructions--
-更改代码,以便使用 `let` 或 `const` 声明所有变量。 当你希望变量改变时使用 `let`,而当你希望变量保持不变时使用 `const`。 此外,重命名用 `const` 声明的变量以符合常见做法,这意味着常量应该全部大写。
+更改代码,以便使用 `let` 或 `const` 声明所有变量。 当你想要改变变量时使用 `let`,当你想要变量保持不变时使用 `const`。 此外,重命名使用 `const` 声明的变量以符合惯例。
# --hints--
-`var` 不应存在于你的代码中。
+代码中不应有 `var`。
```js
-(getUserInput) => assert(!getUserInput('index').match(/var/g));
+assert.notMatch(code, /var/g);
```
你应该将 `fCC` 更改为全部大写。
```js
-(getUserInput) => {
- assert(getUserInput('index').match(/(FCC)/));
- assert(!getUserInput('index').match(/fCC/));
-}
+assert.match(code, /(FCC)/);
+assert.notMatch(code, /(fCC)/);
```
-`FCC` 应该是一个用 `const` 声明的常量变量。
+`FCC` 应该是一个用 `const` 声明的常量。
```js
assert.equal(FCC, 'freeCodeCamp');
@@ -56,14 +52,13 @@ assert.match(code, /const\s+FCC/);
`fact` 应该用 `let` 声明。
```js
-(getUserInput) => assert(getUserInput('index').match(/(let fact)/g));
+assert.match(code, /(let\s+fact)/g);
```
`console.log` 应该更改为打印 `FCC` 和 `fact` 变量。
```js
-(getUserInput) =>
- assert(getUserInput('index').match(/console\.log\(\s*FCC\s*\,\s*fact\s*\)\s*;?/g));
+assert.match(code, /console\.log\(\s*FCC\s*\,\s*fact\s*\)\s*;?/g);
```
# --seed--
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/decrement-a-number-with-javascript.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/decrement-a-number-with-javascript.md
index 6bb66dfee2..a45765f10c 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/decrement-a-number-with-javascript.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/decrement-a-number-with-javascript.md
@@ -38,9 +38,13 @@ assert(myVar === 10);
应该修改 `myVar = myVar - 1;`。
```js
-assert(
- /let\s*myVar\s*=\s*11;\s*\/*.*\s*([-]{2}\s*myVar|myVar\s*[-]{2});/.test(code)
-);
+assert(!code.match(/myVar\s*=\s*myVar\s*[-]\s*1.*?;?/));
+```
+
+你不应将 `10` 分配给 `myVar`。
+
+```js
+assert(!code.match(/myVar\s*=\s*10.*?;?/));
```
应该对 `myVar` 使用 `--` 运算符。
@@ -49,7 +53,7 @@ assert(
assert(/[-]{2}\s*myVar|myVar\s*[-]{2}/.test(code));
```
-不应修改注释上方的代码。
+你不应该修改注释上面的代码。
```js
assert(/let myVar = 11;/.test(code));
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/local-scope-and-functions.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/local-scope-and-functions.md
index 2c950d2134..ef9bc82e3d 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/local-scope-and-functions.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/local-scope-and-functions.md
@@ -23,7 +23,7 @@ myTest();
console.log(loc);
```
-`myTest()` 函数调用将在控制台中显示字符串 `foo`。 `console.log(loc)` 行会产生一个错误,因为 `loc` 没有定义在函数之外。
+`myTest()` 函数调用将在控制台中显示字符串 `foo`。 `console.log(loc)` 行(在 `myTest` 函数之外)将抛出错误,因为 `loc` 未在函数之外定义。
# --instructions--
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/record-collection.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/record-collection.md
index 053a7cbc6d..cd4128de24 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/record-collection.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/record-collection.md
@@ -31,13 +31,13 @@ assert(
);
```
-执行 `updateRecords(recordCollection, 5439, "tracks", "Take a Chance on Me")` 后,`tracks` 的最后一个元素应该为字符串 `Take a Chance on Me`。
+在 `updateRecords(recordCollection, 5439, "tracks", "Take a Chance on Me")` 之后,`tracks` 应该有字符串 `Take a Chance on Me` 作为最后一个也是唯一的元素。
```js
assert(
- updateRecords(_recordCollection, 5439, 'tracks', 'Take a Chance on Me')[5439][
- 'tracks'
- ].pop() === 'Take a Chance on Me'
+ updateRecords(_recordCollection, 5439, 'tracks', 'Take a Chance on Me') &&
+ _recordCollection[5439]['tracks'].length === 1 &&
+ _recordCollection[5439]['tracks'].pop() === 'Take a Chance on Me'
);
```
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/understanding-uninitialized-variables.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/understanding-uninitialized-variables.md
index 5644f150a2..d48cd193ec 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/understanding-uninitialized-variables.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/understanding-uninitialized-variables.md
@@ -9,7 +9,7 @@ dashedName: understanding-uninitialized-variables
# --description--
-当 JavaScript 中的变量被声明的时候,程序内部会给它一个初始值 `undefined`。 当你对一个值为 `undefined` 的变量进行运算操作的时候,算出来的结果将会是 `NaN`,它的意思是 "Not a Number" 。 当你用一个值是 `undefined` 的变量来做字符串拼接操作的时候,它会转换成字符串(string )`undefined`。
+当 JavaScript 中的变量被声明的时候,程序内部会给它一个初始值 `undefined`。 当你对一个值为 `undefined` 的变量进行运算操作的时候,算出来的结果将会是 `NaN`,它的意思是 "Not a Number" 。 如果你用 `undefined` 变量连接一个字符串,你将得到一个 `undefined` 的 字符串 。
# --instructions--
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md
index 420d93de36..36a782192f 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md
@@ -41,7 +41,7 @@ assert(firstLetterOfLastName === 'L');
应该使用方括号表示法。
```js
-assert(code.match(/firstLetterOfLastName\s*?=\s*?lastName\[.*?\]/));
+assert(code.match(/firstLetterOfLastName\s*=\s*lastName\s*\[\s*\d\s*\]/));
```
# --seed--
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md
index f707560920..3685598220 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md
@@ -39,7 +39,7 @@ assert(thirdLetterOfLastName === 'v');
应该使用方括号表示法。
```js
-assert(code.match(/thirdLetterOfLastName\s*?=\s*?lastName\[.*?\]/));
+assert(code.match(/thirdLetterOfLastName\s*=\s*lastName\s*\[\s*\d\s*\]/));
```
# --seed--
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/functional-programming/refactor-global-variables-out-of-functions.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/functional-programming/refactor-global-variables-out-of-functions.md
index fb12266947..36d8046caa 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/functional-programming/refactor-global-variables-out-of-functions.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/functional-programming/refactor-global-variables-out-of-functions.md
@@ -27,6 +27,7 @@ dashedName: refactor-global-variables-out-of-functions
`bookList` 应等于 `["The Hound of the Baskervilles", "On The Electrodynamics of Moving Bodies", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae"]`.
```js
+add(bookList, "Test");
assert(
JSON.stringify(bookList) ===
JSON.stringify([
@@ -38,11 +39,11 @@ assert(
);
```
-`newBookList` 应等于 `["The Hound of the Baskervilles", "On The Electrodynamics of Moving Bodies", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae", "A Brief History of Time"]`.
+`add(bookList, "A Brief History of Time")` 应该返回 `["The Hound of the Baskervilles", "On The Electrodynamics of Moving Bodies", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae", "A Brief History of Time"]`。
```js
assert(
- JSON.stringify(newBookList) ===
+ JSON.stringify(add(bookList, "A Brief History of Time")) ===
JSON.stringify([
'The Hound of the Baskervilles',
'On The Electrodynamics of Moving Bodies',
@@ -53,11 +54,11 @@ assert(
);
```
-`newerBookList` 应等于 `["The Hound of the Baskervilles", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae"]`.
+`remove(bookList, "On The Electrodynamics of Moving Bodies")` 应该返回 `["The Hound of the Baskervilles", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae"]`。
```js
assert(
- JSON.stringify(newerBookList) ===
+ JSON.stringify(remove(bookList, 'On The Electrodynamics of Moving Bodies')) ===
JSON.stringify([
'The Hound of the Baskervilles',
'Philosophiæ Naturalis Principia Mathematica',
@@ -66,11 +67,11 @@ assert(
);
```
-`newestBookList` 应等于 `["The Hound of the Baskervilles", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae", "A Brief History of Time"]`.
+`remove(add(bookList, "A Brief History of Time"), "On The Electrodynamics of Moving Bodies");` 应该返回 `["The Hound of the Baskervilles", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae", "A Brief History of Time"]`。
```js
assert(
- JSON.stringify(newestBookList) ===
+ JSON.stringify(remove(add(bookList, 'A Brief History of Time'), 'On The Electrodynamics of Moving Bodies')) ===
JSON.stringify([
'The Hound of the Baskervilles',
'Philosophiæ Naturalis Principia Mathematica',
@@ -108,12 +109,6 @@ function remove(bookName) {
// Change code above this line
}
}
-
-const newBookList = add(bookList, 'A Brief History of Time');
-const newerBookList = remove(bookList, 'On The Electrodynamics of Moving Bodies');
-const newestBookList = remove(add(bookList, 'A Brief History of Time'), 'On The Electrodynamics of Moving Bodies');
-
-console.log(bookList);
```
# --solutions--
@@ -134,8 +129,4 @@ function remove(bookList, bookName) {
}
return bookListCopy;
}
-
-const newBookList = add(bookList, 'A Brief History of Time');
-const newerBookList = remove(bookList, 'On The Electrodynamics of Moving Bodies');
-const newestBookList = remove(add(bookList, 'A Brief History of Time'), 'On The Electrodynamics of Moving Bodies');
```
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/arguments-optional.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/arguments-optional.md
index 6a1b05331d..1ceacda495 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/arguments-optional.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/arguments-optional.md
@@ -60,6 +60,12 @@ assert.isUndefined(addTogether(2, '3'));
assert.isUndefined(addTogether(2)([3]));
```
+`addTogether("2", 3)` 应该返回 `undefined`。
+
+```js
+assert.isUndefined(addTogether('2', 3));
+```
+
# --seed--
## --seed-contents--
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/everything-be-true.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/everything-be-true.md
index 92df453bd5..71413b628f 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/everything-be-true.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/everything-be-true.md
@@ -18,120 +18,123 @@ JavaScript 中,如果一个值在 Boolean 的上下文中的执行结果为 `t
# --hints--
-`truthCheck([{"user": "Tinky-Winky", "sex": "male"}, {"user": "Dipsy", "sex": "male"}, {"user": "Laa-Laa", "sex": "female"}, {"user": "Po", "sex": "female"}], "sex")` 应返回 `true`。
+`truthCheck([{name: "Quincy", role: "Founder", isBot: false}, {name: "Naomi", role: "", isBot: false}, {name: "Camperbot", role: "Bot", isBot: true}], "isBot")` 应该返回 `false`。
```js
-assert.strictEqual(
- truthCheck(
- [
- { user: 'Tinky-Winky', sex: 'male' },
- { user: 'Dipsy', sex: 'male' },
- { user: 'Laa-Laa', sex: 'female' },
- { user: 'Po', sex: 'female' }
- ],
- 'sex'
- ),
- true
-);
+assert.strictEqual(truthCheck(
+ [
+ { name: "Quincy", role: "Founder", isBot: false },
+ { name: "Naomi", role: "", isBot: false },
+ { name: "Camperbot", role: "Bot", isBot: true }
+ ],
+ "isBot"), false);
```
-`truthCheck([{"user": "Tinky-Winky", "sex": "male"}, {"user": "Dipsy"}, {"user": "Laa-Laa", "sex": "female"}, {"user": "Po", "sex": "female"}], "sex")` 应返回 `false`。
+`truthCheck([{name: "Quincy", role: "Founder", isBot: false}, {name: "Naomi", role: "", isBot: false}, {name: "Camperbot", role: "Bot", isBot: true}], "name")` 应该返回 `true`。
```js
-assert.strictEqual(
- truthCheck(
- [
- { user: 'Tinky-Winky', sex: 'male' },
- { user: 'Dipsy' },
- { user: 'Laa-Laa', sex: 'female' },
- { user: 'Po', sex: 'female' }
- ],
- 'sex'
- ),
- false
-);
+assert.strictEqual(truthCheck(
+ [
+ { name: "Quincy", role: "Founder", isBot: false },
+ { name: "Naomi", role: "", isBot: false },
+ { name: "Camperbot", role: "Bot", isBot: true }
+ ],
+ "name"), true);
```
-`truthCheck([{"user": "Tinky-Winky", "sex": "male", "age": 0}, {"user": "Dipsy", "sex": "male", "age": 3}, {"user": "Laa-Laa", "sex": "female", "age": 5}, {"user": "Po", "sex": "female", "age": 4}], "age")` 应返回 `false`。
+`truthCheck([{name: "Quincy", role: "Founder", isBot: false}, {name: "Naomi", role: "", isBot: false}, {name: "Camperbot", role: "Bot", isBot: true}], "role")` 应该返回 `false`。
```js
-assert.strictEqual(
- truthCheck(
- [
- { user: 'Tinky-Winky', sex: 'male', age: 2 },
- { user: 'Dipsy', sex: 'male', age: 0 },
- { user: 'Laa-Laa', sex: 'female', age: 5 },
- { user: 'Po', sex: 'female', age: 4 }
- ],
- 'age'
- ),
- false
-);
+assert.strictEqual(truthCheck(
+ [
+ { name: "Quincy", role: "Founder", isBot: false },
+ { name: "Naomi", role: "", isBot: false },
+ { name: "Camperbot", role: "Bot", isBot: true }
+ ],
+ "role"), false);
```
-`truthCheck([{"name": "Pete", "onBoat": true}, {"name": "Repeat", "onBoat": true}, {"name": "FastForward", "onBoat": null}], "onBoat")` 应返回 `false`。
+`truthCheck([{name: "Pikachu", number: 25, caught: 3}, {name: "Togepi", number: 175, caught: 1}], "number")` 应该返回 `true`。
```js
-assert.strictEqual(
- truthCheck(
- [
- { name: 'Pete', onBoat: true },
- { name: 'Repeat', onBoat: true },
- { name: 'FastForward', onBoat: null }
- ],
- 'onBoat'
- ),
- false
-);
+assert.strictEqual(truthCheck(
+ [
+ { name: "Pikachu", number: 25, caught: 3 },
+ { name: "Togepi", number: 175, caught: 1 },
+ ],
+ "number"), true);
```
-`truthCheck([{"name": "Pete", "onBoat": true}, {"name": "Repeat", "onBoat": true, "alias": "Repete"}, {"name": "FastForward", "onBoat": true}], "onBoat")` 应返回 `true`。
+`truthCheck([{name: "Pikachu", number: 25, caught: 3}, {name: "Togepi", number: 175, caught: 1}, {name: "MissingNo", number: NaN, caught: 0}], "caught")` 应该返回 `false`。
```js
-assert.strictEqual(
- truthCheck(
- [
- { name: 'Pete', onBoat: true },
- { name: 'Repeat', onBoat: true, alias: 'Repete' },
- { name: 'FastForward', onBoat: true }
- ],
- 'onBoat'
- ),
- true
-);
+assert.strictEqual(truthCheck(
+ [
+ { name: "Pikachu", number: 25, caught: 3 },
+ { name: "Togepi", number: 175, caught: 1 },
+ { name: "MissingNo", number: NaN, caught: 0 },
+ ],
+ "caught"), false);
```
-`truthCheck([{"single": "yes"}], "single")` 应返回 `true`。
+`truthCheck([{name: "Pikachu", number: 25, caught: 3}, {name: "Togepi", number: 175, caught: 1}, {name: "MissingNo", number: NaN, caught: 0}], "number")` 应该返回 `false`。
```js
-assert.strictEqual(truthCheck([{ single: 'yes' }], 'single'), true);
+assert.strictEqual(truthCheck(
+ [
+ { name: "Pikachu", number: 25, caught: 3 },
+ { name: "Togepi", number: 175, caught: 1 },
+ { name: "MissingNo", number: NaN, caught: 0 },
+ ],
+ "number"), false);
```
-`truthCheck([{"single": ""}, {"single": "double"}], "single")` 应返回 `false`。
+`truthCheck([{name: "Quincy", username: "QuincyLarson"}, {name: "Naomi", username: "nhcarrigan"}, {name: "Camperbot"}], "username")` 应该返回 `false`。
```js
-assert.strictEqual(
- truthCheck([{ single: '' }, { single: 'double' }], 'single'),
- false
-);
+assert.strictEqual(truthCheck(
+ [
+ { name: "Quincy", username: "QuincyLarson" },
+ { name: "Naomi", username: "nhcarrigan" },
+ { name: "Camperbot" }
+ ],
+ "username"), false);
```
-`truthCheck([{"single": "double"}, {"single": undefined}], "single")` 应返回 `false`。
+`truthCheck([{name: "freeCodeCamp", users: [{name: "Quincy"}, {name: "Naomi"}]}, {name: "Code Radio", users: [{name: "Camperbot"}]}, {name: "", users: []}], "users")` 应该返回 `true`。
```js
-assert.strictEqual(
- truthCheck([{ single: 'double' }, { single: undefined }], 'single'),
- false
-);
+assert.strictEqual(truthCheck(
+ [
+ { name: "freeCodeCamp", users: [{ name: "Quincy" }, { name: "Naomi" }] },
+ { name: "Code Radio", users: [{ name: "Camperbot" }] },
+ { name: "", users: [] },
+ ],
+ "users"), true);
```
-`truthCheck([{"single": "double"}, {"single": NaN}], "single")` 应返回 `false`。
+`truthCheck([{id: 1, data: {url: "https://freecodecamp.org", name: "freeCodeCamp"}}, {id: 2, data: {url: "https://coderadio.freecodecamp.org/", name: "CodeRadio"}}, {id: null, data: {}}], "data")` 应该返回 `true`。
```js
-assert.strictEqual(
- truthCheck([{ single: 'double' }, { single: NaN }], 'single'),
- false
-);
+assert.strictEqual(truthCheck(
+ [
+ { id: 1, data: { url: "https://www.freecodecamp.org", name: "freeCodeCamp" } },
+ { id: 2, data: { url: "https://coderadio.freecodecamp.org/", name: "CodeRadio" } },
+ { id: null, data: {} },
+ ],
+ "data"), true);
+```
+
+`truthCheck([{id: 1, data: {url: "https://freecodecamp.org", name: "freeCodeCamp"}}, {id: 2, data: {url: "https://coderadio.freecodecamp.org/", name: "CodeRadio"}}, {id: null, data: {}}], "id")` 应该返回 `false`。
+
+```js
+assert.strictEqual(truthCheck(
+ [
+ { id: 1, data: { url: "https://www.freecodecamp.org", name: "freeCodeCamp" } },
+ { id: 2, data: { url: "https://coderadio.freecodecamp.org/", name: "CodeRadio" } },
+ { id: null, data: {} },
+ ],
+ "id"), false);
```
# --seed--
@@ -143,7 +146,7 @@ function truthCheck(collection, pre) {
return pre;
}
-truthCheck([{"user": "Tinky-Winky", "sex": "male"}, {"user": "Dipsy", "sex": "male"}, {"user": "Laa-Laa", "sex": "female"}, {"user": "Po", "sex": "female"}], "sex");
+truthCheck([{name: "Quincy", role: "Founder", isBot: false}, {name: "Naomi", role: "", isBot: false}, {name: "Camperbot", role: "Bot", isBot: true}], "isBot");
```
# --solutions--
diff --git a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/sorted-union.md b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/sorted-union.md
index d625992eea..922706eb45 100644
--- a/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/sorted-union.md
+++ b/curriculum/challenges/chinese/02-javascript-algorithms-and-data-structures/intermediate-algorithm-scripting/sorted-union.md
@@ -45,6 +45,18 @@ assert.deepEqual(uniteUnique([1, 2, 3], [5, 2, 1, 4], [2, 1], [6, 7, 8]), [
]);
```
+`uniteUnique([1, 3, 2], [5, 4], [5, 6])` 应该返回 `[1, 3, 2, 5, 4, 6]`。
+
+```js
+assert.deepEqual(uniteUnique([1, 3, 2], [5, 4], [5, 6]), [1, 3, 2, 5, 4, 6]);
+```
+
+`uniteUnique([1, 3, 2, 3], [5, 2, 1, 4], [2, 1])` 应该返回 `[1, 3, 2, 5, 4]`。
+
+```js
+assert.deepEqual(uniteUnique([1, 3, 2, 3], [5, 2, 1, 4], [2, 1]), [1, 3, 2, 5, 4]);
+```
+
# --seed--
## --seed-contents--
@@ -62,7 +74,11 @@ uniteUnique([1, 3, 2], [5, 2, 1, 4], [2, 1]);
```js
function uniteUnique(arr) {
return [].slice.call(arguments).reduce(function(a, b) {
- return [].concat(a, b.filter(function(e) {return a.indexOf(e) === -1;}));
+ return [].concat(
+ a,
+ b.filter(function(e, currentIndex) {
+ return b.indexOf(e) === currentIndex && a.indexOf(e) === -1;
+ }));
}, []);
}
```
diff --git a/curriculum/challenges/chinese/03-front-end-development-libraries/bootstrap/call-out-optional-actions-with-btn-info.md b/curriculum/challenges/chinese/03-front-end-development-libraries/bootstrap/call-out-optional-actions-with-btn-info.md
index cf5e9edbaf..58e5d09cdc 100644
--- a/curriculum/challenges/chinese/03-front-end-development-libraries/bootstrap/call-out-optional-actions-with-btn-info.md
+++ b/curriculum/challenges/chinese/03-front-end-development-libraries/bootstrap/call-out-optional-actions-with-btn-info.md
@@ -10,7 +10,7 @@ dashedName: call-out-optional-actions-with-btn-info
Bootstrap 有着丰富的预定义按钮颜色。 浅蓝色的 `btn-info` class 通常用在备选操作上。
-在 `Like` 按钮下方创建包含文本 `Info` 的块级 Bootstrap 按钮,然后为该按钮添加 Bootstrap 的 `btn-info` 和 `btn-block` classes。
+在 `Like` 按钮下方使用文本 `Info` 创建一个新的块级 Bootstrap 按钮,并向其中添加 Bootstrap 的 `btn-info` 类。
注意:这些按钮仍然需要 `btn` 和 `btn-block` class。
diff --git a/curriculum/challenges/chinese/03-front-end-development-libraries/react/render-conditionally-from-props.md b/curriculum/challenges/chinese/03-front-end-development-libraries/react/render-conditionally-from-props.md
index 99ad221e60..2d2c09fa76 100644
--- a/curriculum/challenges/chinese/03-front-end-development-libraries/react/render-conditionally-from-props.md
+++ b/curriculum/challenges/chinese/03-front-end-development-libraries/react/render-conditionally-from-props.md
@@ -8,7 +8,7 @@ dashedName: render-conditionally-from-props
# --description--
-到目前为止,已经看到了如何使用 `if/else`、`&&`和三元运算符(`condition ? expressionIfTrue : expressionIfFalse`)对渲染什么和何时渲染做出有条件的判定。 然而,还有一个重要的话题需要讨论,将这些概念中的任何一个或所有概念与另一个强大的 React 功能 props 结合起来。 使用 props 有条件地渲染代码在 React 开发人员中很常见——也就是说:他们使用给定 prop 的值来自动决定渲染什么。
+到目前为止,你已经了解了如何使用 `if/else`、`&&` 和三元运算符(`condition ? expressionIfTrue : expressionIfFalse`)来决定渲染什么和何时渲染。 然而,还有一个重要的话题需要讨论,它可以让你将这些概念中的一个或所有与另一个强大的 React 特性结合起来:props。 使用 props 有条件地渲染代码对于 React 开发人员来说非常常见——也就是说,他们使用给定 props 的值来自动决定要渲染什么。
在这个挑战中,将设置一个子组件来根据 props 做出渲染决定。 可以使用三元运算符,但是可以看到过去几个挑战中涵盖的其他几个概念在这种情况下可能同样有用。
diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/arithmetic-formatter.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/arithmetic-formatter.md
index ed25e8c3ea..d2e65d3348 100644
--- a/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/arithmetic-formatter.md
+++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/arithmetic-formatter.md
@@ -8,21 +8,78 @@ dashedName: arithmetic-formatter
# --description--
-创建一个函数,该函数接收属一个字符串列表,每个字符串代表一个算数问题,并返回垂直并排排列的问题。
+你将[使用我们的 Replit 入门代码来完成这个项目](https://replit.com/github/freeCodeCamp/boilerplate-arithmetic-formatter)。
-你可以[在 Replit 上查看整个项目的具体描述和初始代码](https://replit.com/github/freeCodeCamp/boilerplate-arithmetic-formatter)。
+# --instructions--
-访问此链接后,fork 这个项目。 当你根据 “README.md” 中的说明完成了项目,请在下方提交你的项目链接。
+小学生经常把算术题垂直排列,这样更容易解决。 例如,“235 + 52” 变成:
-我们仍在开发 Python 课程的交互式教学部分。 目前,freeCodeCamp.org YouTube 频道上的一些视频会教授你这个项目需要的所有技能。
+```py
+ 235
++ 52
+-----
+```
-
- Python for Everybody 视频课程 (14 小时)
-
-
- 学习 Python 视频课程 (2 小时)
-
-
+创建一个函数,接收一个属于算术问题的字符串列表,并返回垂直和并排排列的问题。 该函数应该接受可选的第二个参数。 当第二个参数设置为 `True` 时,应显示答案。
+
+## 示例
+
+函数调用:
+
+```py
+arithmetic_arranger(["32 + 698", "3801 - 2", "45 + 43", "123 + 49"])
+```
+
+输出:
+
+```py
+ 32 3801 45 123
++ 698 - 2 + 43 + 49
+----- ------ ---- -----
+```
+
+函数调用:
+
+```py
+arithmetic_arranger(["32 + 8", "1 - 3801", "9999 + 9999", "523 - 49"], True)
+```
+
+输出:
+
+```py
+ 32 1 9999 523
++ 8 - 3801 + 9999 - 49
+---- ------ ------ -----
+ 40 -3800 19998 474
+```
+
+## 规则
+
+如果提供的问题格式正确,该函数将返回正确的转换,否则,它将 **返回** 一个 **字符串** 来描述对用户有意义的错误。
+
+
+- 会返回错误的情况:
+ - 如果提供给函数的 **问题过多**。 限制为 **五个**,更多的将返回: `Error: Too many problems.`
+ - 函数可以接受的运算符是 **加法** 和 **减法** 。 乘法和除法将返回错误。 本要点中未提及的其他运算符将不需要进行测试。 返回的错误将是: `Error: Operator must be '+' or '-'.`
+ - 每个数字(操作数)应该只包含数字。 否则,该函数将返回: `Error: Numbers must only contain digits.`
+ - 每个操作数(也就是运算符两侧的数字)的宽度最多为四位。 否则,返回的错误字符串将为: `Error: Numbers cannot be more than four digits.`
+- 如果用户提供了正确格式的问题,返回的转换将遵循以下规则:
+ - 运算符和两个数中最长的一个之间应该有一个空格,运算符与第二个数在同一行,两个数的顺序与所提供的相同(第一个将是顶部的,而第二个将是底部。
+ - 数字应该右对齐。
+ - 每个问题之间应该有四个空格。
+ - 每个问题的底部都应该有破折号。 破折号应该单独沿着每个问题的整个长度延伸。 (上面的例子展示了这应该是什么样子。)
+
+## 开发
+
+在 `arithmetic_arranger.py` 中编写你的代码。 对于开发,你可以使用 `main.py` 来测试你的 `arithmetic_arranger()` 函数。 单击“运行”按钮,`main.py` 将运行。
+
+## 测试
+
+这个项目的单元测试在 `test_module.py` 中。 为了你的方便,我们在 `main.py` 中从 `test_module.py` 运行测试。 只要你点击“运行”按钮,测试就会自动运行。 或者,你可以通过在控制台中输入 `pytest` 来运行测试。
+
+## 提交
+
+复制项目的 URL 并在下面提交。
# --hints--
diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/budget-app.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/budget-app.md
index 04dc308c82..f997454a41 100644
--- a/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/budget-app.md
+++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/budget-app.md
@@ -8,22 +8,80 @@ dashedName: budget-app
# --description--
-创建一个 Category(类别) 类,该类可用于创建不同的预算类别。
+你将[使用我们的 Replit 入门代码来完成这个项目](https://replit.com/github/freeCodeCamp/boilerplate-budget-app)。
-你可以[在 Replit 上查看整个项目的具体描述和初始代码](https://replit.com/github/freeCodeCamp/boilerplate-budget-app)。
+# --instructions--
-访问此链接后,fork 这个项目。 当你根据 “README.md” 中的说明完成了项目,请在下方提交你的项目链接。
+完成 `budget.py` 中的 `Category` 类。 它应该能够根据不同的预算类别实例化对象,例如 *食物* 、 *服装* 和 *娱乐* 。 创建对象时,它们以类别的名称传递。 该类应该有一个名为 `ledger` 的实例变量,它是一个列表。 该类还应包含以下方法:
-我们仍在开发 Python 课程的交互式教学部分。 目前,freeCodeCamp.org YouTube 频道上的一些视频将会教授你这个项目需要的所有技能。
+- 接受金额和描述的 `deposit` 方法。 如果没有给出描述,它应该默认为一个空字符串。 该方法应以 `{"amount": amount, "description": description}` 的形式将对象附加到账本列表。
+- `withdraw` 方法类似于 `deposit` 方法,但传入的金额应作为负数存储在分类帐中。 如果没有足够的资金,则不应向分类帐添加任何内容。 如果取款发生,此方法应返回 `True`,否则返回 `False`。
+- `get_balance` 方法,根据发生的存款和取款返回预算类别的当前余额。
+- 一个 `transfer` 方法,它接受一个金额和另一个预算类别作为参数。 该方法应添加带有金额和描述“Transfer to [目标预算类别]”的提款。 然后,该方法应将存款添加到其他预算类别,其金额和描述为“Transfer from [来源预算类别]”。 如果没有足够的资金,则不应向任一分类帐添加任何内容。 如果转账发生,此方法应返回 `True`,否则返回 `False`。
+- 接受金额作为参数的 `check_funds` 方法。 如果金额大于预算类别的余额,则返回 `False`,否则返回 `True`。 `withdraw` 方法和 `transfer` 方法都应该使用此方法。
-
+打印预算对象时,它应显示:
+
+- 30 个字符的标题行,类别名称居中在一行 `*` 字符中。
+- 分类帐中的项目列表。 每行应显示描述和金额。 应显示描述的前 23 个字符,然后是金额。 金额应右对齐,包含两位小数,最多显示 7 个字符。
+- 一行显示类别总数。
+
+下面是一个输出示例:
+
+```bash
+*************Food*************
+initial deposit 1000.00
+groceries -10.15
+restaurant and more foo -15.89
+Transfer to Clothing -50.00
+Total: 923.96
+```
+
+除了 `Category` 类之外,创建一个名为 `create_spend_chart` 的函数(在类之外),它将类别列表作为参数。 它应该返回一个作为条形图的字符串。
+
+该图表应显示在传递给函数的每个类别中花费的百分比。 花费的百分比应该只计算取款而不是存款。 图表左侧应该是标签 0 - 100。 条形图中的“条”应由“o”字符组成。 每个条形的高度应四舍五入到最接近的 10。 条形图下面的水平线应该超过最后一个条形图再多两个空格。 每个类别名称应垂直写在栏下方。 顶部应该有一个标题,上面写着“Percentage spent by category”。
+
+此功能将使用最多四个类别进行测试。
+
+仔细查看下面的示例输出,并确保输出的间距与示例完全匹配。
+
+```bash
+Percentage spent by category
+100|
+ 90|
+ 80|
+ 70|
+ 60| o
+ 50| o
+ 40| o
+ 30| o
+ 20| o o
+ 10| o o o
+ 0| o o o
+ ----------
+ F C A
+ o l u
+ o o t
+ d t o
+ h
+ i
+ n
+ g
+```
+
+此项目的单元测试在 `test_module.py` 中。
+
+## 开发
+
+在 `budget.py` 中编写你的代码。 对于开发,你可以使用 `main.py` 来测试你的 `Category` 类。 单击“运行”按钮,`main.py` 将运行。
+
+## 测试
+
+为了你的方便,我们将测试从 `test_module.py` 导入到 `main.py`。 只要你点击“运行”按钮,测试就会自动运行。
+
+## 提交
+
+复制项目的 URL 并将其提交给 freeCodeCamp。
# --hints--
diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/polygon-area-calculator.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/polygon-area-calculator.md
index 2f38caf779..5a178af72e 100644
--- a/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/polygon-area-calculator.md
+++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/polygon-area-calculator.md
@@ -8,26 +8,94 @@ dashedName: polygon-area-calculator
# --description--
+你将通过使用我们的[Replit 入门代码](https://replit.com/github/freeCodeCamp/boilerplate-polygon-area-calculator)来完成本项目。
+
+# --instructions--
+
在这个项目中,你将使用面向对象的编程来创建 Rectangle(矩形) 类和 Square(正方形) 类。 Square 类应该是 Rectangle 的子类,并继承方法和属性。
-你可以[在 Replit 上查看整个项目的具体描述和初始代码](https://replit.com/github/freeCodeCamp/boilerplate-polygon-area-calculator)。
+## Rectangle 类
-到达此链接后,fork 这个项目。 当你根据 “README.md” 中的说明完成了项目,请在下方提交你的项目链接。
+创建 Rectangle 对象时,应使用 `width` 和 `height` 属性对其进行初始化。 该类还应包含以下方法:
-Python 课程的交互式教学部分仍在开发当中。 目前,freeCodeCamp.org YouTube 频道上的一些视频将会教授你这个项目需要的所有技能。
+- `set_width`
+- `set_height`
+- `get_area`:返回面积(`width * height`)
+- `get_perimeter`:返回周长(`2 * width + 2 * height`)
+- `get_diagonal`:返回对角线 (`(width ** 2 + height ** 2) ** .5`)
+- `get_picture`:返回一个字符串,该字符串使用包含“\*”的行来表示形状。 行数应等于高度,每行中“\*”的数量应等于宽度。 每行末尾应该有一个新行 (`\n`)。 如果宽度或高度大于 50,则应返回字符串:“Too big for picture.”。
+- `get_amount_inside`:以另一个形状(正方形或矩形)作为参数。 返回传入的形状可以装进该形状的次数(没有旋转)。 例如,一个宽为 4,高为 8 的矩形可以放入两个边长为 4 的正方形。
-
+另外,如果一个 Rectangle 实例被表示为一个字符串,它应该看起来像: `Rectangle(width=5, height=10)`
+
+## Square 类
+
+Square 类应该是 Rectangle 的子类。 创建 Square 对象时,传入单边长度。 `__init__` 方法应该在 Rectangle 类的 `width` 和 `height` 属性中存储边长。
+
+Square 类应该能够访问 Rectangle 类方法,但还应该包含一个 `set_side` 方法。 如果 Square 的实例表示为字符串,则它应该如下所示:`Square(side=9)`
+
+此外,Square 类的 `set_width` 和 `set_height` 方法应该设置宽度和高度。
+
+## 使用示例
+
+```py
+rect = shape_calculator.Rectangle(10, 5)
+print(rect.get_area())
+rect.set_height(3)
+print(rect.get_perimeter())
+print(rect)
+print(rect.get_picture())
+
+sq = shape_calculator.Square(9)
+print(sq.get_area())
+sq.set_side(4)
+print(sq.get_diagonal())
+print(sq)
+print(sq.get_picture())
+
+rect.set_height(8)
+rect.set_width(16)
+print(rect.get_amount_inside(sq))
+```
+
+该代码应该返回:
+
+```bash
+50
+26
+Rectangle(width=10, height=3)
+**********
+**********
+**********
+
+81
+5.656854249492381
+Square(side=4)
+****
+****
+****
+****
+
+8
+```
+
+此项目的单元测试在 `test_module.py` 中。
+
+## 开发
+
+在 `shape_calculator.py` 中编写你的代码。 对于开发,你可以使用 `main.py` 来测试你的 `shape_calculator()` 函数。 单击“运行”按钮,`main.py` 将运行。
+
+## 测试
+
+为了你的方便,我们将测试从 `test_module.py` 导入到 `main.py`。 只要你点击“运行”按钮,测试就会自动运行。
+
+## 提交
+
+复制项目的 URL 并将其提交给 freeCodeCamp。
# --hints--
-它应该创建一个 Rectangle 类和 Square 类并通过所有测试。
+应该创建一个 Rectangle 类和一个 Square 类,并通过所有测试。
```js
diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/probability-calculator.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/probability-calculator.md
index 9e1bd8d0ca..624826daab 100644
--- a/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/probability-calculator.md
+++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/probability-calculator.md
@@ -8,24 +8,68 @@ dashedName: probability-calculator
# --description--
-写一个程序来确定从帽子中随机拿取特定球的大致概率。
+你将通过使用我们的[Replit 入门代码](https://replit.com/github/freeCodeCamp/boilerplate-probability-calculator)来完成本项目。
-你可以在 [Replit](https://replit.com/github/freeCodeCamp/boilerplate-probability-calculator) 上查看整个项目的具体描述和初始代码。 访问此链接后,fork 这个项目。 当你根据 “README.md” 中的说明完成了项目,请在下方提交你的项目链接。
+# --instructions--
-我们仍在开发 Python 课程的交互式教学部分。 目前,freeCodeCamp.org YouTube 频道上的一些视频将会教授你这个项目需要的所有技能。
+假设有一顶帽子,里面有 5 个蓝球、4 个红球和 2 个绿球。 随机抽取的 4 个球中至少包含 1 个红球和 2 个绿球的概率是多少? 虽然可以使用高等数学来计算概率,但更简单的方法是编写一个程序来执行大量实验来估计近似概率。
-
+对于这个项目,你将编写一个程序来确定从帽子中随机抽取某些球的大致概率。
+
+首先,在`prob_calculator.py` 中创建一个`Hat` 类。 该类应该采用可变数量的参数来指定帽子中每种颜色的球数。 例如,可以通过以下任何一种方式创建类对象:
+
+```py
+hat1 = Hat(yellow=3, blue=2, green=6)
+hat2 = Hat(red=5, orange=4)
+hat3 = Hat(red=5, orange=4, black=1, blue=0, pink=2, striped=9)
+```
+
+一顶帽子总是至少有一个球。 创建时传递给 hat 对象的参数应转换为 `contents` 实例变量。 `contents` 应该是一个字符串列表,其中包含帽子中每个球的一个项目。 列表中的每一项都应该是一个颜色名称,代表该颜色的单个球。 例如,如果你的帽子是 `{"red": 2, "blue": 1}`,`contents` 应该是 `["red", "red", "blue"]`。
+
+`Hat` 类应该有一个 `draw` 方法,该方法接受一个参数,该参数指示要从帽子中抽取的球数。 此方法应该从 `contents` 中随机删除球,并将这些球作为字符串列表返回。 在抽取过程中球不应回到帽子中,类似于没有放回的黑盒实验。 如果要抽的球数量超过可用数量,则返回所有球。
+
+接下来,在 `prob_calculator.py`(不是在 `Hat` 类中)创建一个 `experiment` 函数。 此函数应接受以下参数:
+
+- `hat`:一个包含球的帽子对象,应该在函数内复制。
+- `expected_balls`:一个对象,指示尝试从帽子中抽取的确切球组以进行实验。 例如,要确定从帽子中抽取 2 个蓝球和 1 个红球的概率,将 `expected_balls` 设置为 `{"blue":2, "red":1}`。
+- `num_balls_drawn`:每次实验中从帽子中抽出的球数。
+- `num_experiments`:要执行的实验数量。 (进行的实验越多,近似概率就越准确。)
+
+`experiment` 函数应该返回一个概率。
+
+例如,假设你想确定当你从一个包含 6 个黑球、4 个红球和 3 个绿球的帽子中抽出 5 个球时,至少得到 2 个红球和 1 个绿球的概率。 为此,我们进行 `N` 次实验,记录其中我们至少得到 2 个红球和 1 个绿球的次数 `M`,并估计概率为`M/N`。 每个实验都包括从一顶装有指定球的帽子开始,抽取一些球,然后检查我们是否得到了我们想要得到的球。
+
+以下是基于上面的示例调用 `experiment` 函数的方法,其中包含 2000 个实验:
+
+```py
+hat = Hat(black=6, red=4, green=3)
+probability = experiment(hat=hat,
+ expected_balls={"red":2,"green":1},
+ num_balls_drawn=5,
+ num_experiments=2000)
+```
+
+由于这是基于随机抽取的,因此每次运行代码时概率会略有不同。
+
+*提示:考虑使用已经在 `prob_calculator.py` 顶部导入的模块。 不要在 `prob_calculator.py` 中初始化随机种子。*
+
+## 开发
+
+在 `prob_calculator.py` 中编写你的代码。 对于开发,你可以使用 `main.py` 来测试你的代码。 单击“运行”按钮,`main.py` 将运行。
+
+样板文件包括 `copy` 和 `random` 模块的 `import` 语句。 考虑在你的项目中使用它们。
+
+## 测试
+
+这个项目的单元测试在 `test_module.py` 中。 为了你的方便,我们将测试从 `test_module.py` 导入到 `main.py`。 只要你点击“运行”按钮,测试就会自动运行。
+
+## 提交
+
+复制项目的 URL 并将其提交给 freeCodeCamp。
# --hints--
-它应该能正确地计算概率并通过所有测试。
+它应该能正确地计算概率,并通过所有测试。
```js
diff --git a/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/time-calculator.md b/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/time-calculator.md
index b713263442..55dc881119 100644
--- a/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/time-calculator.md
+++ b/curriculum/challenges/chinese/07-scientific-computing-with-python/scientific-computing-with-python-projects/time-calculator.md
@@ -8,24 +8,61 @@ dashedName: time-calculator
# --description--
-编写一个名为 “add_time” 的函数,该函数可以将一段时间添加到一个开始时间中,并返回结果。
+你将通过使用我们的[Replit 入门代码](https://replit.com/github/freeCodeCamp/boilerplate-time-calculator)来完成本项目。
-你可以 [在 Replit 上查看整个项目的具体描述和初始代码](https://replit.com/github/freeCodeCamp/boilerplate-time-calculator)。 访问此链接后,fork 这个项目。 当你根据 “README.md” 中的说明完成了项目,请在下方提交你的项目链接。
+# --instructions--
-我们仍在开发 Python 课程的交互式教学部分。 目前,freeCodeCamp.org YouTube 频道上的一些视频将会教授你这个项目需要的所有技能。
+编写一个名为 `add_time` 的函数,它接受两个必需参数和一个可选参数:
-
+- 12 小时制的开始时间(以 AM 或 PM 结束)
+- 指示小时数和分钟数的持续时间
+- (可选)一周的开始日期,不区分大小写
+
+该函数应将持续时间添加到开始时间并返回结果。
+
+如果结果是第二天,它应该在时间之后显示 `(next day)`。 如果结果将超过一天以后,它应该在时间后面显示 `(n days later)`,其中 "n "是之后的天数。
+
+如果给函数提供了可选的开始日期的星期参数,则输出应显示结果的星期几。 输出中的星期几应出现在时间之后和天数之前。
+
+以下是函数应处理的不同情况的一些示例。 请注意结果的间距和标点符号。
+
+```py
+add_time("3:00 PM", "3:10")
+# Returns: 6:10 PM
+
+add_time("11:30 AM", "2:32", "Monday")
+# Returns: 2:02 PM, Monday
+
+add_time("11:43 AM", "00:20")
+# Returns: 12:03 PM
+
+add_time("10:10 PM", "3:30")
+# Returns: 1:40 AM (next day)
+
+add_time("11:43 PM", "24:20", "tueSday")
+# Returns: 12:03 AM, Thursday (2 days later)
+
+add_time("6:30 PM", "205:12")
+# Returns: 7:42 AM (9 days later)
+```
+
+不要导入任何 Python 库。 假设开始时间是有效时间。 持续时间中的分钟将是小于 60 的整数,但小时可以是任何整数。
+
+## 开发
+
+在 `time_calculator.py` 中编写你的代码。 对于开发,你可以使用 `main.py` 来测试你的 `time_calculator()` 函数。 单击“运行”按钮,`main.py` 将运行。
+
+## 测试
+
+这个项目的单元测试在 `test_module.py` 中。 为了你的方便,我们将测试从 `test_module.py` 导入到 `main.py`。 只要你点击“运行”按钮,测试就会自动运行。
+
+## 提交
+
+复制项目的 URL 并将其提交给 freeCodeCamp。
# --hints--
-它应该能正确地添加时间并通过所有测试。
+它应该能正确地添加时间,并通过所有测试。
```js
diff --git a/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/demographic-data-analyzer.md b/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/demographic-data-analyzer.md
index b689408a1a..8f765f565d 100644
--- a/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/demographic-data-analyzer.md
+++ b/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/demographic-data-analyzer.md
@@ -8,13 +8,58 @@ dashedName: demographic-data-analyzer
# --description--
-在这个挑战中,你必须使用 Pandas 对人口统计进行分析。 你将获得从 1994 年人口普查数据库中提取的人口统计数据数据集。
+你将通过使用我们的[Replit 入门代码](https://replit.com/github/freeCodeCamp/boilerplate-demographic-data-analyzer)来完成本项目。
-你可以[在 Replit 上查看整个项目的具体描述和初始代码](https://replit.com/github/freeCodeCamp/boilerplate-demographic-data-analyzer)。
+我们仍在开发 Python 课程的交互式教学部分。 目前,你可以在 YouTube 上通过 freeCodeCamp.org 上传的一些视频学习这个项目相关的知识。
-点击此链接,fork 这个项目。 一旦你根据 “README.md” 中的说明完成项目,请提交你的项目链接到下面。
+- [Python for Everybody 视频课程](https://www.freecodecamp.org/news/python-for-everybody/)(14 小时)
+- [Learn Python 视频课程](https://www.freecodecamp.org/news/learn-python-video-course/)(10 小时)
-我们仍在开发 Python 数据分析课程的交互式教学。 现在,你需要使用其他资源来学习如何通过这一挑战。
+# --instructions--
+
+在这个挑战中,你必须使用 Pandas 对人口统计进行分析。 你将获得从 1994 年人口普查数据库中提取的人口统计数据数据集。 以下是数据的示例:
+
+```markdown
+| | age | workclass | fnlwgt | education | education-num | marital-status | occupation | relationship | race | sex | capital-gain | capital-loss | hours-per-week | native-country | salary |
+|---:|------:|:-----------------|---------:|:------------|----------------:|:-------------------|:------------------|:---------------|:-------|:-------|---------------:|---------------:|-----------------:|:-----------------|:---------|
+| 0 | 39 | State-gov | 77516 | Bachelors | 13 | Never-married | Adm-clerical | Not-in-family | White | Male | 2174 | 0 | 40 | United-States | <=50K |
+| 1 | 50 | Self-emp-not-inc | 83311 | Bachelors | 13 | Married-civ-spouse | Exec-managerial | Husband | White | Male | 0 | 0 | 13 | United-States | <=50K |
+| 2 | 38 | Private | 215646 | HS-grad | 9 | Divorced | Handlers-cleaners | Not-in-family | White | Male | 0 | 0 | 40 | United-States | <=50K |
+| 3 | 53 | Private | 234721 | 11th | 7 | Married-civ-spouse | Handlers-cleaners | Husband | Black | Male | 0 | 0 | 40 | United-States | <=50K |
+| 4 | 28 | Private | 338409 | Bachelors | 13 | Married-civ-spouse | Prof-specialty | Wife | Black | Female | 0 | 0 | 40 | Cuba | <=50K |
+```
+
+你必须使用 Pandas 来回答以下问题:
+
+- 这个数据集中每个种族有多少人? 这应该是一个以种族名称作为索引标签的 Pandas 系列。 (`race` 栏)
+- 男性的平均年龄是多少?
+- 拥有学士学位的人的百分比是多少?
+- 受过高等教育(`Bachelors`, `Masters`, or `Doctorate`)收入超过 50K 的人占多大比例?
+- 没有受过高等教育的人的收入超过 50K 的比例是多少?
+- 一个人每周最少工作多少小时?
+- 每周工作最少小时数的人中有多少人的工资超过 50K?
+- 哪个国家/地区的收入 >50K 的人口比例最高,该比例是多少?
+- 确定印度收入 >50K 的人最受欢迎的职业。
+
+使用文件 `demographic_data_analyzer` 中的启动代码。 更新代码,以便将所有设置为“None”的变量设置为适当的计算或代码。 将所有小数四舍五入到最接近的十分之一。
+
+单元测试是在 `test_module.py` 下为你编写的。
+
+## 开发
+
+对于开发,你可以使用 `main.py` 来测试你的函数。 单击“运行”按钮,`main.py` 将运行。
+
+## 测试
+
+为了你的方便,我们将测试从 `test_module.py` 导入到 `main.py`。 只要你点击“运行”按钮,测试就会自动运行。
+
+## 提交
+
+复制项目的 URL 并将其提交给 freeCodeCamp。
+
+## 数据集源
+
+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.
# --hints--
diff --git a/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/mean-variance-standard-deviation-calculator.md b/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/mean-variance-standard-deviation-calculator.md
index 53b7b4fa5f..272dc6a86e 100644
--- a/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/mean-variance-standard-deviation-calculator.md
+++ b/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/mean-variance-standard-deviation-calculator.md
@@ -8,13 +8,60 @@ dashedName: mean-variance-standard-deviation-calculator
# --description--
-创建一个函数,这个函数可以使用 Numpy 输出 3 x 3 矩阵的每一行、每一列和所有元素的均值,方差和标准差。
+你将通过使用我们的[Replit 入门代码](https://replit.com/github/freeCodeCamp/boilerplate-mean-variance-standard-deviation-calculator)来完成本项目。
-你可以在 [Replit](https://replit.com/github/freeCodeCamp/boilerplate-mean-variance-standard-deviation-calculator) 上查看整个项目的具体描述和初始代码。
+我们仍在开发 Python 课程的交互式教学部分。 目前,你可以在 YouTube 上通过 freeCodeCamp.org 上传的一些视频学习这个项目相关的知识。
-点击此链接,fork 这个项目。 当你根据 “README.md” 中的说明完成了项目,请在下方提交你的项目链接。
+- [Python for Everybody 视频课程](https://www.freecodecamp.org/news/python-for-everybody/)(14 小时)
+- [Learn Python 视频课程](https://www.freecodecamp.org/news/learn-python-video-course/)(10 小时)
-我们仍在开发 Python 数据分析课程的交互式教学。 现在,您将需要使用其他资源来学习如何通过这一挑战。
+# --instructions--
+
+在 `mean_var_std.py` 中创建一个名为 `calculate()` 的函数,该函数使用 Numpy 输出行、列、和 3 x 3 矩阵中的元素。
+
+函数的输入应该是一个包含 9 个数字的列表。 该函数应将列表转换为 3 x 3 Numpy 数组,然后返回一个字典,其中包含沿两个轴和展平矩阵的均值、方差、标准差、最大值、最小值和总和。
+
+返回的字典应遵循以下格式:
+
+```py
+{
+ 'mean': [axis1, axis2, flattened],
+ 'variance': [axis1, axis2, flattened],
+ 'standard deviation': [axis1, axis2, flattened],
+ 'max': [axis1, axis2, flattened],
+ 'min': [axis1, axis2, flattened],
+ 'sum': [axis1, axis2, flattened]
+}
+```
+
+如果将包含少于 9 个元素的列表传递给函数,它应该引发 `ValueError` 异常并显示消息:“List must contain nine numbers.” 返回的字典中的值应该是列表而不是 Numpy 数组。
+
+例如,`calculate([0,1,2,3,4,5,6,7,8])` 应该返回:
+
+```py
+{
+ 'mean': [[3.0, 4.0, 5.0], [1.0, 4.0, 7.0], 4.0],
+ 'variance': [[6.0, 6.0, 6.0], [0.6666666666666666, 0.6666666666666666, 0.6666666666666666], 6.666666666666667],
+ 'standard deviation': [[2.449489742783178, 2.449489742783178, 2.449489742783178], [0.816496580927726, 0.816496580927726, 0.816496580927726], 2.581988897471611],
+ 'max': [[6, 7, 8], [2, 5, 8], 8],
+ 'min': [[0, 1, 2], [0, 3, 6], 0],
+ 'sum': [[9, 12, 15], [3, 12, 21], 36]
+}
+```
+
+此项目的单元测试在 `test_module.py` 中。
+
+## 开发
+
+对于开发,你可以使用 `main.py` 来测试你的 `calculate()` 函数。 单击“运行”按钮,`main.py` 将运行。
+
+## 测试
+
+为了你的方便,我们将测试从 `test_module.py` 导入到 `main.py`。 只要你点击“运行”按钮,测试就会自动运行。
+
+## 提交
+
+复制项目的 URL 并将其提交给 freeCodeCamp。
# --hints--
diff --git a/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/medical-data-visualizer.md b/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/medical-data-visualizer.md
index 5d2bcd36b2..2866a7074e 100644
--- a/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/medical-data-visualizer.md
+++ b/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/medical-data-visualizer.md
@@ -8,13 +8,70 @@ dashedName: medical-data-visualizer
# --description--
-在这个项目中,你将要使用 matplotlib,seaborn 和 pandas 来对健康检查数据进行数据可视化和计算。
+你将通过使用我们的[Replit 入门代码](https://replit.com/github/freeCodeCamp/boilerplate-medical-data-visualizer)来完成本项目。
-你可以[在 Replit 上查看整个项目的具体描述和初始代码](https://replit.com/github/freeCodeCamp/boilerplate-medical-data-visualizer)。
+我们仍在开发 Python 课程的交互式教学部分。 目前,你可以在 YouTube 上通过 freeCodeCamp.org 上传的一些视频学习这个项目相关的知识。
-打开此链接后,fork 这个项目。 一旦你根据 “README.md” 中的说明完成项目,请提交你的项目到下面的链接。
+- [Python for Everybody 视频课程](https://www.freecodecamp.org/news/python-for-everybody/)(14 小时)
+- [Learn Python 视频课程](https://www.freecodecamp.org/news/learn-python-video-course/)(10 小时)
-我们仍在开发 Python 数据分析课程的交互式课程部分。 现在,你需要使用其他资源来学习如何通过这一挑战。
+# --instructions--
+
+在本项目中,您将使用 matplotlib、seaborn 和 pandas 来对体检数据进行可视化和计算。 数据集的数值是从体检中收集的。
+
+## 数据说明
+
+数据集中的行代表患者,列代表身体测量、各种血液检查的结果和生活方式等信息。 您将使用该数据集来探索心脏病、身体测量数据、血液标志物和对生活方式的选择之间的关系。
+
+文件名:medical_examination.csv
+
+| 项目 | 变量类型 | 变量名 | 变量值类型 |
+|:--------:|:----:|:-----------:|:---------------------:|
+| 年龄 | 客观特征 | age | int (days) |
+| 身高 | 客观特征 | height | int (cm) |
+| 体重 | 客观特征 | weight | float (kg) |
+| 性别 | 客观特征 | gender | 分类编码 |
+| 收缩压 | 检测特征 | ap_hi | int |
+| 舒张压 | 检测特征 | ap_lo | int |
+| 胆固醇 | 检测特征 | cholesterol | 1:正常,2:高于正常,3:远远高于正常值 |
+| 血糖值 | 检测特征 | gluc | 1:正常,2:高于正常,3:远远高于正常值 |
+| 吸烟问题 | 主观特征 | smoke | binary |
+| 饮酒量 | 主观特征 | alco | binary |
+| 体育活动 | 主观特征 | active | binary |
+| 是否有心血管疾病 | 目标变量 | cardio | binary |
+
+## 任务
+
+创建一个类似于 `examples/Figure_1.png` 的图表,其中我们显示 `cholesterol`、`gluc`、`alco`、`active` 和 `smoke` 变量,用于不同面板中 heart=1 和 heart=0 的患者。
+
+在 `medical_data_visualizer.py` 中使用数据完成以下任务:
+
+- 给数据添加一列 `overweight`。 要确定一个人是否超重,首先通过将他们的体重(公斤)除以他们的身高(米)的平方来计算他们的 BMI。 如果该值 > 25,则此人超重。 使用值 0 表示不超重,使用值 1 表示超重。
+- 使用 0 表示好的和 1 表示坏,来规范化数据。 如果 `cholesterol` 或 `gluc` 的值为 1,则将值设为 0。 如果值大于 1,则将值设为 1。
+- 将数据转换为长格式并使用 seaborn 的 `catplot()` 创建一个显示分类特征值计数的图表。 数据集应按“Cardio”拆分,因此每个 `cardio` 值都有一个图表。 该图表应该看起来像 `examples/Figure_1.png`。
+- 清理数据。 过滤掉以下代表不正确数据的患者段:
+ - 舒张压高于收缩压(使用 `(df['ap_lo'] <= df['ap_hi'])` 保留正确的数据)
+ - 高度小于第 2.5 个百分位数(使用 `(df['height'] >= df['height'].quantile(0.025))` 保留正确的数据)
+ - 身高超过第 97.5 个百分位
+ - 体重小于第 2.5 个百分位
+ - 体重超过第 97.5 个百分位
+- 使用数据集创建相关矩阵。 使用 seaborn 的 `heatmap()` 绘制相关矩阵。 遮罩上三角。 该图表应类似于 `examples/Figure_2.png`。
+
+每当变量设置为 `None` 时,请确保将其设置为正确的代码。
+
+单元测试是在 `test_module.py` 下为你编写的。
+
+## 开发
+
+对于开发,你可以使用 `main.py` 来测试你的函数。 单击“运行”按钮,`main.py` 将运行。
+
+## 测试
+
+为了你的方便,我们将测试从 `test_module.py` 导入到 `main.py`。 只要你点击“运行”按钮,测试就会自动运行。
+
+## 提交
+
+复制项目的 URL 并将其提交给 freeCodeCamp。
# --hints--
diff --git a/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/page-view-time-series-visualizer.md b/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/page-view-time-series-visualizer.md
index aba7f8e37d..1cbc8be6c4 100644
--- a/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/page-view-time-series-visualizer.md
+++ b/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/page-view-time-series-visualizer.md
@@ -8,13 +8,40 @@ dashedName: page-view-time-series-visualizer
# --description--
-对于这个项目,你将使用线图、条形图和箱形图对时间序列数据进行可视化。 你将要使用 Pandas、matplotlib 和 seaborn 来对数据集进行可视化,这个数据集包含从 2016-05-09 到 2019-12-03 每一天在 freeCodeCamp.org 论坛的页面访问量。 这个数据可视化将帮助你了解访问的模式,并且显示年增长和月增长情况。
+你将通过使用我们的[Replit 入门代码](https://replit.com/github/freeCodeCamp/boilerplate-page-view-time-series-visualizer)来完成本项目。
-你可以 [在 Replit 上查看整个项目的具体描述和初始代码](https://replit.com/github/freeCodeCamp/boilerplate-page-view-time-series-visualizer)。
+我们仍在开发 Python 课程的交互式教学部分。 目前,你可以在 freeCodeCamp.org 的 YouTube 频道中通过视频学习到这个项目相关的所有知识
-点击此链接,fork 这个项目。 一旦你根据 “README.md” 中的说明完成项目,请提交你的项目到下面的链接。
+- [Python for Everybody 视频课程](https://www.freecodecamp.org/news/python-for-everybody/)(14 小时)
+- [Learn Python 视频课程](https://www.freecodecamp.org/news/learn-python-video-course/)(10 小时)
-我们仍在开发 Python 数据分析课程的交互式课程部分。 现在,你将需要使用其他资源来学习如何通过这一挑战。
+# --instructions--
+
+对于这个项目,你将使用线图、条形图和箱形图对时间序列数据进行可视化。 你将使用 Pandas、Matplotlib 和 Seaborn 可视化包含 2016 年 5 月 9 日至 2019 年 12 月 3 日期间 freeCodeCamp.org 论坛上每天的页面浏览量的数据集。 这个数据可视化将帮助你了解访问的模式,并且显示年增长和月增长情况。
+
+使用数据完成以下任务:
+
+- 使用 Pandas 从 “fcc-forum-pageviews.csv” 导入数据。 将索引设置为 “date” 列。
+- 通过过滤掉页面浏览量位于数据集前 2.5% 或数据集后 2.5% 的日期来清理数据。
+- 创建一个 `draw_line_plot` 函数,该函数使用 Matplotlib 绘制类似于“examples/Figure_1.png”的折线图。 标题应为“Daily freeCodeCamp Forum Page Views 5/2016-12/2019”。 x 轴上的标签应为“Date”,y 轴上的标签应为“Page Views”。
+- 创建一个 `draw_bar_plot` 函数,用于绘制类似于“examples/Figure_2.png”的条形图。 它应该显示按年份分组的每个月的平均每日页面浏览量。 图例应显示月份标签并具有“Months”标题。 在图表上,x 轴上的标签应为“Years”,y 轴上的标签应为“Average Page Views”。
+- 创建一个 `draw_box_plot` 函数,该函数使用 Seaborn 绘制两个相邻的箱形图,类似于“examples/Figure_3.png”。 这些箱线图应显示值在给定年份或月份内的分布情况以及随时间推移的比较情况。 第一个图表的标题应为“Year-wise Box Plot (Trend)”,第二个图表的标题应为“Month-wise Box Plot (Seasonality)”。 确保底部的月份标签从“Jan”开始,并且 x 和 x 轴标记正确。 样板文件包括准备数据的命令。
+
+对于每个图表,请确保使用数据框的副本。 单元测试是在 `test_module.py` 下为你编写的。
+
+样板文件还包括保存和返回图像的命令。
+
+## 开发
+
+对于开发,你可以使用 `main.py` 来测试你的函数。 单击“运行”按钮,`main.py` 将运行。
+
+## 测试
+
+为了你的方便,我们将测试从 `test_module.py` 导入到 `main.py`。 只要你点击“运行”按钮,测试就会自动运行。
+
+## 提交
+
+复制项目的 URL 并将其提交给 freeCodeCamp。
# --hints--
diff --git a/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/sea-level-predictor.md b/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/sea-level-predictor.md
index 2642541fbe..1f959901d8 100644
--- a/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/sea-level-predictor.md
+++ b/curriculum/challenges/chinese/08-data-analysis-with-python/data-analysis-with-python-projects/sea-level-predictor.md
@@ -8,13 +8,44 @@ dashedName: sea-level-predictor
# --description--
-在本项目中,您将分析自 1880 年以来全球平均海平面变化的数据集。 您将使用这些数据来预测到 2050 年的海平面变化。
+你将通过使用我们的[Replit 入门代码](https://replit.com/github/freeCodeCamp/boilerplate-sea-level-predictor)来完成本项目。
-你可以在 [Replit 上查看整个项目的具体描述和初始代码](https://replit.com/github/freeCodeCamp/boilerplate-sea-level-predictor)。
+我们仍在开发 Python 课程的交互式教学部分。 目前,你可以在 YouTube 上通过 freeCodeCamp.org 上传的一些视频学习这个项目相关的知识。
-打开此链接后,fork 这个项目。 一旦你根据 “README.md” 中的说明完成项目,请提交你的项目到下面的链接。
+- [Python for Everybody 视频课程](https://www.freecodecamp.org/news/python-for-everybody/)(14 小时)
+- [Learn Python 视频课程](https://www.freecodecamp.org/news/learn-python-video-course/)(10 小时)
+
+# --instructions--
+
+你将分析自 1880 年以来全球平均海平面变化的数据集。 你将使用这些数据来预测到 2050 年的海平面变化。
+
+使用数据完成以下任务:
+
+- 使用 Pandas 从 `epa-sea-level.csv` 导入数据。
+- 使用 matplotlib 创建散点图,使用“Year”列作为 x 轴,将“CSIRO Adjusted Sea Level”列作为 y 轴。
+- 使用 `scipy.stats` 中的 `linregress` 函数来获得最佳拟合线的斜率和 y 截距。 在散点图的顶部绘制最佳拟合线。 使线穿过 2050 年以预测 2050 年的海平面上升。
+- 仅使用数据集中从 2000 年到最近一年的数据绘制一条新的最佳拟合线。 如果上升速度继续与 2000 年一样,则使该线也经过 2050 年以预测 2050 年的海平面上升。
+- x 标签应为 “Year”,y 标签应为 “Sea Level (inches)”,标题应为 “Rise in Sea Level”。
+
+单元测试是在 `test_module.py` 下为你编写的。
+
+样板文件还包括保存和返回图像的命令。
+
+## 开发
+
+对于开发,你可以使用 `main.py` 来测试你的函数。 单击“运行”按钮,`main.py` 将运行。
+
+## 测试
+
+为了你的方便,我们将测试从 `test_module.py` 导入到 `main.py`。 只要你点击“运行”按钮,测试就会自动运行。
+
+## 提交
+
+复制项目的 URL 并将其提交给 freeCodeCamp。
+
+## 数据源
+[Global Average Absolute Sea Level Change](https://datahub.io/core/sea-level-rise), 1880-2014 from the US Environmental Protection Agency using data from CSIRO, 2015; NOAA, 2015.
-我们仍在开发 Python 数据分析课程的交互式课程部分。 现在,你需要使用其他资源来学习如何通过这一挑战。
# --hints--
diff --git a/curriculum/challenges/chinese/09-information-security/information-security-projects/anonymous-message-board.md b/curriculum/challenges/chinese/09-information-security/information-security-projects/anonymous-message-board.md
index 66e96b9796..89c14c053a 100644
--- a/curriculum/challenges/chinese/09-information-security/information-security-projects/anonymous-message-board.md
+++ b/curriculum/challenges/chinese/09-information-security/information-security-projects/anonymous-message-board.md
@@ -16,7 +16,7 @@ dashedName: anonymous-message-board
- 使用 [我们的 Replit 启动项目](https://replit.com/github/freeCodeCamp/boilerplate-project-messageboard)来完成你的项目。
- 使用一个你喜欢的站点生成器来完成项目。 需要确定包含了我们 GitHub 仓库的所有文件。
-完成本项目后,请将一个正常运行的 demo(项目演示)托管在可以公开访问的平台。 然后将 URL 提交到 `Solution Link` 中。 此外,还可以将项目的源码提交到 `GitHub Link` 中。
+完成本项目后,请将一个正常运行的 demo(项目演示)托管在可以公开访问的平台。 然后将 URL 提交到 `Solution Link` 中。 此外,还可以提交一个指向项目源码的 `GitHub Link`。
# --instructions--
@@ -116,49 +116,270 @@ async (getUserInput) => {
你可以向 `/api/replies/{board}` 发送一个 POST 请求,其中包括字段 `text`、`delete_password` & `thread_id`。 这将更新 `bumped_on` 日期到评论日期。 在主题的 `replies` 数组中,将保存一个对象,至少有 `_id`、`text`、`created_on`、`delete_password`、& `reported` 这些属性。
```js
+async (getUserInput) => {
+ const url = getUserInput('url');
+ const body = await fetch(url + '/api/threads/fcc_test');
+ const thread = await body.json();
+ const date = new Date();
+ const text = `fcc_test_reply_${date}`;
+ const delete_password = 'delete_me';
+ const thread_id = thread[0]._id;
+ const replyCount = thread[0].replies.length;
+
+ const data = { text, delete_password, thread_id };
+ const res = await fetch(url + '/api/replies/fcc_test', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(data)
+ });
+ if (res.ok) {
+ const checkData = await fetch(`${url}/api/replies/fcc_test?thread_id=${thread_id}`);
+ const parsed = await checkData.json();
+ try {
+ assert.equal(parsed.replies.length, replyCount + 1);
+ assert.equal(parsed.replies[0].text, text);
+ assert.equal(parsed._id, thread_id);
+ assert.equal(parsed.bumped_on, parsed.replies[0].created_on);
+ } catch (err) {
+ throw new Error(err.responseText || err.message);
+ }
+ } else {
+ throw new Error(`${res.status} ${res.statusText}`);
+ }
+};
```
你可以向 `/api/threads/{board}` 发送一个 GET 请求。 返回的将是一个数组,包括论坛上最近的 10 个被回复的主题,及每个主题最新的 3 个回帖。 `reported` 和 `delete_password` 字段将不会被发送到客户端。
```js
+async (getUserInput) => {
+ const url = getUserInput('url');
+ const res = await fetch(url + '/api/threads/fcc_test');
+ if (res.ok) {
+ const threads = await res.json();
+ try {
+ assert.equal(res.status, 200);
+ assert.isAtMost(threads.length, 10);
+ for (let i = 0; i < threads.length; i++) {
+ assert.containsAllKeys(threads[i], ["_id", "text", "created_on", "bumped_on", "replies"]);
+ assert.isAtMost(threads[i].replies.length, 3);
+ assert.notExists(threads[i].delete_password);
+ assert.notExists(threads[i].reported);
+ for (let j = 0; j < threads[i].replies.length; j++) {
+ assert.notExists(threads[i].replies[j].delete_password);
+ assert.notExists(threads[i].replies[j].reported);
+ }
+ }
+ } catch (err) {
+ throw new Error(err.responseText || err.message);
+ }
+ } else {
+ throw new Error(`${res.status} ${res.statusText}`);
+ }
+};
```
你可以向 `/api/replies/{board}?thread_id={thread_id}` 发送一个 GET 请求。 返回的将是带有所有的回复的整个主题,不包括与之前测试相同的客户端字段。
```js
+async (getUserInput) => {
+ const url = getUserInput('url');
+ let res = await fetch(url + '/api/threads/fcc_test');
+ const threads = await res.json();
+ const thread_id = threads[0]._id;
+ res = await fetch(`${url}/api/replies/fcc_test?thread_id=${thread_id}`);
+ if (res.ok) {
+ const thread = await res.json();
+ try {
+ assert.equal(res.status, 200);
+ assert.isObject(thread);
+ assert.containsAllKeys(thread, ["_id", "text", "created_on", "bumped_on", "replies"]);
+ assert.isArray(thread.replies);
+ assert.notExists(thread.delete_password);
+ assert.notExists(thread.reported);
+ for (let i = 0; i < thread.replies.length; i++) {
+ assert.notExists(thread.replies[i].delete_password);
+ assert.notExists(thread.replies[i].reported);
+ }
+ } catch (err) {
+ throw new Error(err.responseText || err.message);
+ }
+ } else {
+ throw new Error(`${res.status} ${res.statusText}`);
+ }
+};
```
你可以向 `/api/threads/{board}` 发送一个 DELETE 请求,并传递 `thread_id` & `delete_password` 来删除该线程。 返回的将是字符串 `incorrect password` 或 `success`。
```js
+async (getUserInput) => {
+ const url = getUserInput('url');
+ let res = await fetch(url + '/api/threads/fcc_test');
+ const threads = await res.json();
+ const thread_id = threads[0]._id;
+ let data = { thread_id, delete_password: "wrong_password" };
+ const res_invalid = await fetch(url + '/api/threads/fcc_test', {
+ method: 'DELETE',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(data)
+ });
+ data = { thread_id, delete_password: "delete_me" };
+ res = await fetch(url + '/api/threads/fcc_test', {
+ method: 'DELETE',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(data)
+ });
+ if (res.ok) {
+ const deleted = await res.text();
+ const not_deleted = await res_invalid.text();
+ try {
+ assert.equal(res.status, 200);
+ assert.equal(deleted, "success");
+ assert.equal(not_deleted, "incorrect password");
+ } catch (err) {
+ throw new Error(err.responseText || err.message);
+ }
+ } else {
+ throw new Error(`${res.status} ${res.statusText}`);
+ }
+};
```
你可以向 `/api/replies/{board}` 发送一个 DELETE 请求,并传递 `thread_id`、`reply_id`、& `delete_password`。 返回的将是字符串 `incorrect password` 或 `success`。 成功后,`reply_id` 的文本将更改为 `[deleted]`。
```js
+async (getUserInput) => {
+ const url = getUserInput('url');
+ const thread_data = {
+ text: "fcc_test_thread",
+ delete_password: "delete_me",
+ };
+ await fetch(`${url}/api/threads/fcc_test`, {
+ method: "POST",
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(thread_data)
+ });
+ let res = await fetch(`${url}/api/threads/fcc_test`);
+ let threads = await res.json();
+ const thread_id = threads[0]._id;
+
+ const reply_data = { thread_id, text: "fcc_test_reply", delete_password: "delete_me" };
+ await fetch(`${url}/api/replies/fcc_test`, {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(reply_data)
+ });
+ res = await fetch(`${url}/api/threads/fcc_test`);
+ threads = await res.json();
+ const reply_id = threads[0].replies[0]._id;
+
+ const data = { thread_id, reply_id, delete_password: "delete_me" };
+ res = await fetch(url + '/api/replies/fcc_test', {
+ method: 'DELETE',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(data)
+ });
+
+ if (res.ok) {
+ const deleted = await res.text();
+ try {
+ assert.equal(res.status, 200);
+ assert.equal(deleted, "success");
+ res = await fetch(`${url}/api/replies/fcc_test?thread_id=${thread_id}`);
+ const thread = await res.json();
+ assert.equal(thread._id, thread_id);
+ assert.equal(thread.replies[0]._id, reply_id);
+ assert.equal(thread.replies[0].text, "[deleted]");
+ } catch (err) {
+ throw new Error(err.responseText || err.message);
+ }
+ } else {
+ throw new Error(`${res.status} ${res.statusText}`);
+ }
+};
```
-你可以向 `/api/threads/{board}` 发送一个 PUT 请求,并传递 `thread_id`。 返回的将是字符串 `success`。 `thread_id` 回复的 `reported` 值将改为 `true`。
+你可以向 `/api/threads/{board}` 发送一个 PUT 请求,并传递 `thread_id`。 返回的将是字符串 `reported`。 `thread_id` 回复的 `reported` 值将改为 `true`。
```js
+async (getUserInput) => {
+ const url = getUserInput('url');
+ let res = await fetch(`${url}/api/threads/fcc_test`);
+ const threads = await res.json();
+ const report_id = threads[0]._id;
+ const data = { report_id };
+
+ res = await fetch(`${url}/api/threads/fcc_test`, {
+ method: 'PUT',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(data)
+ });
+
+ if (res.ok) {
+ const reported = await res.text();
+ try {
+ assert.equal(res.status, 200);
+ assert.equal(reported, "reported");
+ } catch (err) {
+ throw new Error(err.responseText || err.message);
+ }
+ } else {
+ throw new Error(`${res.status} ${res.statusText}`);
+ }
+};
```
-你可以通过向 `/api/replies/{board}` 发送 PUT 请求并传递 `thread_id` & `reply_id`。 返回的将是字符串 `success`。 `reply_id` 的 `reported` 值将被改变为 `true`。
+你可以通过向 `/api/replies/{board}` 发送 PUT 请求并传递 `thread_id` & `reply_id`。 返回的将是字符串 `reported`。 `reply_id` 的 `reported` 值将被改变为 `true`。
```js
+async (getUserInput) => {
+ const url = getUserInput('url');
+ let res = await fetch(`${url}/api/threads/fcc_test`);
+ const threads = await res.json();
+ const thread_id = threads[0]._id;
+ const reply_id = threads[0].replies[0]._id;
+ const data = { thread_id, reply_id };
+
+ res = await fetch(`${url}/api/replies/fcc_test`, {
+ method: 'PUT',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify(data)
+ });
+
+ if (res.ok) {
+ const reported = await res.text();
+ try {
+ assert.equal(res.status, 200);
+ assert.equal(reported, "reported");
+ } catch (err) {
+ throw new Error(err.responseText || err.message);
+ }
+ } else {
+ throw new Error(`${res.status} ${res.statusText}`);
+ }
+};
```
所有 10 项功能测试都已完成并通过。
```js
-
+async (getUserInput) => {
+ const tests = await fetch(getUserInput('url') + '/_api/get-tests');
+ const parsed = await tests.json();
+ assert.isTrue(parsed.length >= 10);
+ parsed.forEach((test) => {
+ assert.equal(test.state, 'passed');
+ assert.isAtLeast(test.assertions.length, 1);
+ });
+};
```
# --solutions--
diff --git a/curriculum/challenges/chinese/09-information-security/information-security-projects/port-scanner.md b/curriculum/challenges/chinese/09-information-security/information-security-projects/port-scanner.md
index f4b825d9d9..2b035409c8 100644
--- a/curriculum/challenges/chinese/09-information-security/information-security-projects/port-scanner.md
+++ b/curriculum/challenges/chinese/09-information-security/information-security-projects/port-scanner.md
@@ -9,22 +9,74 @@ dashedName: port-scanner
# --description--
+你将通过使用我们的 [Replit 入门代码](https://replit.com/github/freeCodeCamp/boilerplate-port-scanner) 来完成本项目。
+
+我们仍在开发 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 小时)
+
+# --instructions--
+
使用 Python 创建一个端口扫描器。
-你可以访问 [Replit 上的完整项目描述和启动代码](https://replit.com/github/freeCodeCamp/boilerplate-port-scanner)。
+在 `port_scanner.py` 文件中,创建一个名为 `get_open_ports` 的函数,它接受一个 `target` 参数和一个 `port_range` 参数。 `target` 可以是 URL 或 IP 地址。 `port_range` 是两个数字的列表,表示要检查的端口范围的第一个和最后一个数字。
-在打开链接之后 fork 该项目。 根据 “README.md” 中的指示完成整个项目,然后在下面提交你的项目链接。
+以下是如何调用该函数的示例:
-Python 课程的交互式教学部分仍在开发当中。 目前,freeCodeCamp YouTube 频道上的一些视频将会教授你这个项目要求的一些 Python 技能。
+```py
+get_open_ports("209.216.230.240", [440, 445])
+get_open_ports("www.stackoverflow.com", [79, 82])
+```
-
+该函数应返回给定范围内的开放端口列表。
+
+`get_open_ports` 函数还应采用可选的第三个参数 `True` 来表示“详细”模式。 如果将其设置为 true,则该函数应返回描述性字符串而不是端口列表。
+
+以下是详细模式下应返回的字符串格式(`{}` 中的文本表示应显示的信息):
+
+```bash
+Open ports for {URL} ({IP address})
+PORT SERVICE
+{port} {service name}
+{port} {service name}
+```
+
+你可以使用 `common_ports.py` 中的字典为每个端口获取正确的服务名称。
+
+例如,如果函数是这样调用的:
+
+```py
+port_scanner.get_open_ports("scanme.nmap.org", [20, 80], True)
+```
+
+它应该返回以下内容:
+
+```bash
+Open ports for scanme.nmap.org (45.33.32.156)
+PORT SERVICE
+22 ssh
+80 http
+```
+
+确保包含正确的间距和换行符。
+
+如果传入 `get_open_ports` 函数的 URL 无效,该函数应返回字符串:“Error: Invalid hostname”。
+
+如果传入 `get_open_ports` 函数的 IP 地址无效,该函数应返回字符串:“Error: Invalid IP address”。
+
+## 开发
+
+在 `port_scanner.py` 中编写你的代码。 对于开发,你可以使用 `main.py` 来测试你的代码。 单击“运行”按钮,`main.py` 将运行。
+
+## 测试
+
+这个项目的单元测试在 `test_module.py` 中。 为了你的方便,我们将测试从 `test_module.py` 导入到 `main.py`。 只要你点击“运行”按钮,测试就会自动运行。
+
+## 提交
+
+复制项目的 URL 并将其提交给 freeCodeCamp。
# --hints--
diff --git a/curriculum/challenges/chinese/09-information-security/information-security-projects/sha-1-password-cracker.md b/curriculum/challenges/chinese/09-information-security/information-security-projects/sha-1-password-cracker.md
index e78aa6ae76..f990c94651 100644
--- a/curriculum/challenges/chinese/09-information-security/information-security-projects/sha-1-password-cracker.md
+++ b/curriculum/challenges/chinese/09-information-security/information-security-projects/sha-1-password-cracker.md
@@ -9,22 +9,51 @@ dashedName: sha-1-password-cracker
# --description--
+你将通过使用我们的 [Replit 入门代码](https://replit.com/github/freeCodeCamp/boilerplate-SHA-1-password-cracker) 来完成本项目。
+
+我们仍在开发 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 小时)
+
+# --instructions--
+
+密码不应以纯文本形式存储。 它们应该存储为哈希值,以防万一密码列表被泄露。 然而,并不是所有的哈希都是一样的。
+
在这个项目中,你将通过创建一个密码破解器来找出使用 SHA-1 散列的密码,从而了解到良好安全的重要性。
-你可以访问 [Replit 上的完整项目描述和启动代码](https://replit.com/github/freeCodeCamp/boilerplate-SHA-1-password-cracker)。
+创建一个函数,该函数接受密码的 SHA-1 哈希值,如果它是使用的前 10,000 个密码之一,则返回该密码。 如果 SHA-1 哈希不是数据库中的密码,则返回“密码不在数据库中”。
-进入该链接后,fork 该项目。 一旦你根据 “README.md” 中的说明完成了项目,请在下面提交你的项目链接。
+该函数应该对 `top-10000-passwords.txt` 中的每个密码进行散列,并将其与传递给函数的散列进行比较。
-我们仍在开发 Python 课程的交互式教学部分。 目前,freeCodeCamp.org YouTube 频道上的一些视频可以教你这个项目所需的一些 Python 技能。
+该函数应采用名为 `use_salts` 的可选第二个参数。 如果设置为 true,则文件 `known-salts.txt` 中的每个 salt 字符串,都应该在散列之前,和将它与传递给函数的哈希值进行比较之前,添加到 `top-10000-passwords.txt` 中的每个密码的之前和之后。
-
+以下是一些用于测试该功能的散列密码:
+
+- `b305921a3723cd5d70a375cd21a61e60aabb84ec` 应该返回 “sammy123”
+- `c7ab388a5ebefbf4d550652f1eb4d833e5316e3e` 应该返回 “abacab”
+- `5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8` 应该返回 “password”
+
+以下是一些散列密码,用于在 `use_salts` 设置为 `True` 时测试该功能:
+
+- `53d8b3dc9d39f0184144674e310185e41a87ffd5` 应该返回 “superman”
+- `da5a4e8cf89539e66097acd2f8af128acae2f8ae` 应该返回 “q1w2e3r4t5”
+- `ea3f62d498e3b98557f9f9cd0d905028b3b019e1` 应该返回 “bubbles1”
+
+`hashlib` 库已经为你导入。 你应该在你的代码中使用它。 [在此了解更多关于 “hashlib” 的信息](https://docs.python.org/3/library/hashlib.html)
+
+## 开发
+
+在 `password_cracker.py` 中编写你的代码。 对于开发,你可以使用 `main.py` 来测试你的代码。 单击“运行”按钮,`main.py` 将运行。
+
+## 测试
+
+此项目的单元测试在 `test_module.py` 中。 为了你的方便,我们将测试从 `test_module.py` 导入到 `main.py`。 只要你点击“运行”按钮,测试就会自动运行。
+
+## 提交
+
+复制项目的 URL 并将其提交给 freeCodeCamp。
# --hints--
diff --git a/curriculum/challenges/espanol/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md b/curriculum/challenges/espanol/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md
index 251cb737e2..0da67d79d6 100644
--- a/curriculum/challenges/espanol/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md
+++ b/curriculum/challenges/espanol/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md
@@ -41,7 +41,7 @@ assert(firstLetterOfLastName === 'L');
Debes usar la notación de corchetes.
```js
-assert(code.match(/firstLetterOfLastName\s*?=\s*?lastName\[.*?\]/));
+assert(code.match(/firstLetterOfLastName\s*=\s*lastName\s*\[\s*\d\s*\]/));
```
# --seed--
diff --git a/curriculum/challenges/espanol/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md b/curriculum/challenges/espanol/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md
index 7e5ef9881d..ca9a4139dd 100644
--- a/curriculum/challenges/espanol/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md
+++ b/curriculum/challenges/espanol/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md
@@ -39,7 +39,7 @@ assert(thirdLetterOfLastName === 'v');
Debes usar la notación de corchetes.
```js
-assert(code.match(/thirdLetterOfLastName\s*?=\s*?lastName\[.*?\]/));
+assert(code.match(/thirdLetterOfLastName\s*=\s*lastName\s*\[\s*\d\s*\]/));
```
# --seed--
diff --git a/curriculum/challenges/italian/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md b/curriculum/challenges/italian/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md
index a4f84e0268..cf5e277164 100644
--- a/curriculum/challenges/italian/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md
+++ b/curriculum/challenges/italian/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md
@@ -41,7 +41,7 @@ assert(firstLetterOfLastName === 'L');
Dovresti usare la notazione a parentesi.
```js
-assert(code.match(/firstLetterOfLastName\s*?=\s*?lastName\[.*?\]/));
+assert(code.match(/firstLetterOfLastName\s*=\s*lastName\s*\[\s*\d\s*\]/));
```
# --seed--
diff --git a/curriculum/challenges/italian/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md b/curriculum/challenges/italian/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md
index 0e89b3f80f..656b831ba8 100644
--- a/curriculum/challenges/italian/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md
+++ b/curriculum/challenges/italian/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md
@@ -39,7 +39,7 @@ assert(thirdLetterOfLastName === 'v');
Dovresti usare la notazione a parentesi.
```js
-assert(code.match(/thirdLetterOfLastName\s*?=\s*?lastName\[.*?\]/));
+assert(code.match(/thirdLetterOfLastName\s*=\s*lastName\s*\[\s*\d\s*\]/));
```
# --seed--
diff --git a/curriculum/challenges/japanese/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md b/curriculum/challenges/japanese/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md
index d5f4e0c0a3..8b40125feb 100644
--- a/curriculum/challenges/japanese/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md
+++ b/curriculum/challenges/japanese/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-first-character-in-a-string.md
@@ -41,7 +41,7 @@ assert(firstLetterOfLastName === 'L');
ブラケット記法を使用してください。
```js
-assert(code.match(/firstLetterOfLastName\s*?=\s*?lastName\[.*?\]/));
+assert(code.match(/firstLetterOfLastName\s*=\s*lastName\s*\[\s*\d\s*\]/));
```
# --seed--
diff --git a/curriculum/challenges/japanese/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md b/curriculum/challenges/japanese/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md
index 0b339305c0..08735479c7 100644
--- a/curriculum/challenges/japanese/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md
+++ b/curriculum/challenges/japanese/02-javascript-algorithms-and-data-structures/basic-javascript/use-bracket-notation-to-find-the-nth-character-in-a-string.md
@@ -39,7 +39,7 @@ assert(thirdLetterOfLastName === 'v');
ブラケット記法を使用してください。
```js
-assert(code.match(/thirdLetterOfLastName\s*?=\s*?lastName\[.*?\]/));
+assert(code.match(/thirdLetterOfLastName\s*=\s*lastName\s*\[\s*\d\s*\]/));
```
# --seed--
diff --git a/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/add-a-box-shadow-to-a-card-like-element.md b/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/add-a-box-shadow-to-a-card-like-element.md
index a75d1bac0a..e4e2eff7c5 100644
--- a/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/add-a-box-shadow-to-a-card-like-element.md
+++ b/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/add-a-box-shadow-to-a-card-like-element.md
@@ -11,14 +11,14 @@ dashedName: add-a-box-shadow-to-a-card-like-element
A propriedade `box-shadow` aplica uma ou mais sombras a um elemento.
-A propriedade `box-shadow` recebe valores para
+A propriedade `box-shadow` recebe os seguintes valores em ordem:
- offset-x
(determina a distância que você quer "empurrar" a sombra na horizontal),
- offset-y
(determina a distância que você quer "empurrar" a sombra na vertical),
- blur-radius
(faz com que a sombra fique mais borrada),
- spread-radius
(faz com que a sombra se espalhe mais) e
- color
(cor), nessa ordem.
+ offset-x
(determina a distância que você quer "empurrar" a sombra na horizontal)
+ offset-y
(determina a distância que você quer "empurrar" a sombra na vertical)
+ blur-radius
+ spread-radius
+ color
Os valores `blur-radius` e `spread-radius` são opcionais.
diff --git a/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/adjust-the-hue-of-a-color.md b/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/adjust-the-hue-of-a-color.md
index 27623fc32b..951b17e2cf 100644
--- a/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/adjust-the-hue-of-a-color.md
+++ b/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/adjust-the-hue-of-a-color.md
@@ -9,7 +9,7 @@ dashedName: adjust-the-hue-of-a-color
# --description--
-As cores têm várias características, incluindo tonalidade, saturação e luminosidade. CSS3 introduziu a função `hsl()` como uma forma alternativa de escolher uma cor informando diretamente essas características.
+As cores têm várias características, incluindo tonalidade, saturação e luminosidade. O CSS3 introduziu a função `hsl()` como uma forma alternativa de escolher uma cor informando diretamente essas características.
**Tonalidade** é o que as pessoas geralmente chamam de 'cor'. Se você imaginar um espectro de cores começando com o vermelho à esquerda, passando pelo verde no meio e pelo azul à direita, a tonalidade é qualquer cor que esteja dentro deste espectro. No `hsl()`, a tonalidade é definida usando o conceito de círculo cromático em vez de um espectro, onde o ângulo da cor no círculo é um valor entre 0 e 360.
@@ -39,7 +39,7 @@ Você deve usar a função `hsl()` para declarar a cor `cyan` (ciano).
assert(code.match(/\.cyan\s*?{\s*?background-color\s*:\s*?hsl/gi));
```
-Você deve usar a função `hsl()` para declarar a cor `blue` (blue).
+Você deve usar a função `hsl()` para declarar a cor `blue` (azul).
```js
assert(code.match(/\.blue\s*?{\s*?background-color\s*:\s*?hsl/gi));
diff --git a/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/create-a-graphic-using-css.md b/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/create-a-graphic-using-css.md
index f0db8c30c3..39908e10f4 100644
--- a/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/create-a-graphic-using-css.md
+++ b/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/create-a-graphic-using-css.md
@@ -15,11 +15,11 @@ Você criará um objeto redondo e transparente com uma sombra nítida ligeiramen
Para criar um objeto redondo, a propriedade `border-radius` deve ter um valor de 50%.
-Você deve se lembrar de um desafio anterior que a propriedade `box-shadow` recebe valores para o eixo horizontal (`offset-x`), eixo vertical (`offset-y`), `blur-radius`, `spread-radius` e um valor de cor, nessa ordem. Os valores `blur-radius` e `spread-radius` são opcionais.
+Você deve se lembrar de um desafio anterior que a propriedade `box-shadow` recebe valores para o eixo horizontal (`offset-x`), eixo vertical (`offset-y`), `blur-radius`, `spread-radius` e um valor de `color`, nessa ordem. Os valores `blur-radius` e `spread-radius` são opcionais.
# --instructions--
-Manipule o elemento quadrado no editor para criar a forma da lua. Primeiro, altere a propriedade `background-color` para `transparent` e, em seguida, defina a propriedade `border-radius` para 50% para fazer a forma circular. Finalmente, altere a propriedade `box-shadow` e defina o `offset-x` para 25px, o `offset-y` para 10px, `blur-radius` para 0, `spread-radius` para 0 e cor para azul (`blue`).
+Manipule o elemento quadrado no editor para criar a forma da lua. Primeiro, altere a propriedade `background-color` para `transparent` e, em seguida, defina a propriedade `border-radius` para 50% para fazer a forma circular. Finalmente, altere a propriedade `box-shadow` e defina o `offset-x` para 25px, o `offset-y` para 10px, `blur-radius` para 0, `spread-radius` para 0 e `color` para azul (`blue`).
# --hints--
@@ -35,7 +35,7 @@ A propriedade `border-radius` deve ter o valor de `50%`.
assert(code.match(/border-radius:\s*?50%;/gi));
```
-A propriedade `box-shadow` deve receber 25px para o eixo horizontal (`offset-x`), 10px para o eixo vertical (`offset-y`), 0 para `blur-radius`, 0 para `spread-radius` e, finalmente, azul (`blue`) para a cor.
+A propriedade `box-shadow` deve receber 25px para o eixo horizontal (`offset-x`), 10px para o eixo vertical (`offset-y`), 0 para `blur-radius`, 0 para `spread-radius` e, finalmente, azul (`blue`) para `color`.
```js
assert(
diff --git a/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/create-a-more-complex-shape-using-css-and-html.md b/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/create-a-more-complex-shape-using-css-and-html.md
index b8a75f3804..e158adeafb 100644
--- a/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/create-a-more-complex-shape-using-css-and-html.md
+++ b/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/create-a-more-complex-shape-using-css-and-html.md
@@ -28,15 +28,15 @@ Para que os pseudo-elementos `::before` e `::after` funcionem corretamente, eles
# --instructions--
-Transforme o elemento em tela em um coração. No seletor `heart::after`, altere a propriedade `background-color` para `pink` e `border-radius` para 50%.
+Transforme o elemento em tela em um coração. No seletor `.heart::after`, altere a propriedade `background-color` para `pink` e `border-radius` para 50%.
Em seguida, adicione a propriedade `transform` no elemento com a classe `heart` (apenas `heart`). Use a função `rotate()` com o valor de -45 graus.
-Finalmente, no seletor `heart::before`, a propriedade `content` deve possuir um valor vazio.
+Finalmente, no seletor `.heart::before`, a propriedade `content` deve possuir um valor vazio.
# --hints--
-A propriedade `background-color` do seletor `heart::after` deve ter o valor `pink`.
+A propriedade `background-color` do seletor `.heart::after` deve ter o valor `pink`.
```js
const heartAfter = code.match(/\.heart::after\s*{[\s\S]+?[^\}]}/g)[0];
@@ -45,7 +45,7 @@ assert(
);
```
-A propriedade `border-radius` do seletor `heart::after` deve ter um valor de 50%.
+A propriedade `border-radius` do seletor `.heart::after` deve ter um valor de 50%.
```js
assert(code.match(/border-radius\s*?:\s*?50%/gi).length == 2);
@@ -57,7 +57,7 @@ A propriedade `transform` da classe `heart` deve usar a função `rotate()` com
assert(code.match(/transform\s*?:\s*?rotate\(\s*?-45deg\s*?\)/gi));
```
-A propriedade `content` do seletor `heart::before` deve ter um valor vazio.
+A propriedade `content` do seletor `.heart::before` deve ter um valor vazio.
```js
assert(code.match(/\.heart::before\s*?{\s*?content\s*?:\s*?("|')\1\s*?;/gi));
diff --git a/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/use-a-bezier-curve-to-move-a-graphic.md b/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/use-a-bezier-curve-to-move-a-graphic.md
index 4a3bc14aaa..d47c75b7ae 100644
--- a/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/use-a-bezier-curve-to-move-a-graphic.md
+++ b/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/use-a-bezier-curve-to-move-a-graphic.md
@@ -11,7 +11,7 @@ dashedName: use-a-bezier-curve-to-move-a-graphic
Em um desafio anterior, tratamos da palavra-chave `ease-out`, que descreve uma mudança de animação que começa acelerando e desacelera ao final da animação. À direita, a diferença entre a palavra-chave `ease-out` (para o elemento azul) e a palavra-chave `linear` (para o elemento vermelho) é demonstrada. Progressões de animação semelhantes à palavra-chave `ease-out` podem ser alcançadas usando a função de curva de Bézier cúbica.
-Em geral, alterar os pontos de ancoragem `p1` (ponto 1) e `p2` (ponto 2) leva à criação de diferentes curvas de Bézier, que controlam como a animação progride ao longo do tempo. Aqui está um exemplo de curva de Bézier usando valores para imitar o estilo ease-out:
+Em geral, alterar os pontos de ancoragem `p1` (ponto 1) e `p2` (ponto 2) leva à criação de diferentes curvas de Bézier, que controlam como a animação progride ao longo do tempo. Aqui está um exemplo de curva de Bézier usando valores para imitar o estilo `ease-out`:
```css
animation-timing-function: cubic-bezier(0, 0, 0.58, 1);
diff --git a/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/use-a-css-linear-gradient-to-create-a-striped-element.md b/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/use-a-css-linear-gradient-to-create-a-striped-element.md
index eb38a98026..5ccfc7ec63 100644
--- a/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/use-a-css-linear-gradient-to-create-a-striped-element.md
+++ b/curriculum/challenges/portuguese/01-responsive-web-design/applied-visual-design/use-a-css-linear-gradient-to-create-a-striped-element.md
@@ -47,7 +47,7 @@ A interrupção de cor em 0 pixels deve ser `yellow`.
assert(code.match(/yellow\s+?0(px)?/gi));
```
-A interrupção de cor em 40 pixels deve ser `yellow`.
+A primeira interrupção de cor em 40 pixels deve ser `yellow`.
```js
assert(code.match(/yellow\s+?40px/gi));
diff --git a/curriculum/challenges/portuguese/01-responsive-web-design/basic-css/change-a-variable-for-a-specific-area.md b/curriculum/challenges/portuguese/01-responsive-web-design/basic-css/change-a-variable-for-a-specific-area.md
index 9d9d12402e..b47ba11372 100644
--- a/curriculum/challenges/portuguese/01-responsive-web-design/basic-css/change-a-variable-for-a-specific-area.md
+++ b/curriculum/challenges/portuguese/01-responsive-web-design/basic-css/change-a-variable-for-a-specific-area.md
@@ -11,7 +11,7 @@ dashedName: change-a-variable-for-a-specific-area
Quando você cria suas variáveis em `:root`, elas ficam disponíveis para uso em toda a página.
-Mas nada impede que você redefina os valores dessas variáveis dentro de qualquer outro seletor CSS.
+Mas nada impede que você redefina os valores dessas variáveis dentro de qualquer outro seletor de CSS.
# --instructions--
@@ -27,7 +27,7 @@ assert(
);
```
-A classe `penguin` não deve conter a propriedade `background-color`
+A classe `penguin` não deve conter a propriedade `background-color`.
```js
assert(
diff --git a/curriculum/challenges/portuguese/01-responsive-web-design/basic-css/create-a-custom-css-variable.md b/curriculum/challenges/portuguese/01-responsive-web-design/basic-css/create-a-custom-css-variable.md
index 2abca63d83..ffcf11974a 100644
--- a/curriculum/challenges/portuguese/01-responsive-web-design/basic-css/create-a-custom-css-variable.md
+++ b/curriculum/challenges/portuguese/01-responsive-web-design/basic-css/create-a-custom-css-variable.md
@@ -15,7 +15,7 @@ Para criar uma variável no CSS, você precisa dar um nome, prefixar este nome c
--penguin-skin: gray;
```
-Isso vai criar uma variável chamada `--penguin-skin` e atribuir a ela o valor de `gray`. Agora você pode usar essa variável em outro lugar do seu CSS para alterar o valor de outros elementos para cinza (gray).
+Isso vai criar uma variável chamada `--penguin-skin` e atribuir a ela o valor de `gray`. Agora você pode usar essa variável em outro lugar do seu CSS para alterar o valor de outras propriedades para cinza (gray).
# --instructions--
diff --git a/curriculum/challenges/portuguese/01-responsive-web-design/basic-css/inherit-styles-from-the-body-element.md b/curriculum/challenges/portuguese/01-responsive-web-design/basic-css/inherit-styles-from-the-body-element.md
index 48a34ee28b..a182fbd7da 100644
--- a/curriculum/challenges/portuguese/01-responsive-web-design/basic-css/inherit-styles-from-the-body-element.md
+++ b/curriculum/challenges/portuguese/01-responsive-web-design/basic-css/inherit-styles-from-the-body-element.md
@@ -77,7 +77,7 @@ assert(
);
```
-O elemento `h1` deve herdar a cor verde do elemento `body`.
+O elemento `h1` deve herdar a cor `green` do elemento `body`.
```js
assert($('h1').length > 0 && $('h1').css('color') === 'rgb(0, 128, 0)');
diff --git a/curriculum/challenges/portuguese/01-responsive-web-design/basic-css/override-styles-in-subsequent-css.md b/curriculum/challenges/portuguese/01-responsive-web-design/basic-css/override-styles-in-subsequent-css.md
index 8af5661caf..8efac5ca27 100644
--- a/curriculum/challenges/portuguese/01-responsive-web-design/basic-css/override-styles-in-subsequent-css.md
+++ b/curriculum/challenges/portuguese/01-responsive-web-design/basic-css/override-styles-in-subsequent-css.md
@@ -27,7 +27,7 @@ class="class1 class2"
**Observação:** a ordem das classes dentro do atributo "class" não é importante.
-O importante é a ordem em que as classes (`class`) são declaradas dentro da tag `