diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..6d0ee45db --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.vscode +.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index e97a1d649..51ba8acb2 100644 --- a/README.md +++ b/README.md @@ -1,69 +1,176 @@ # ๐Ÿš‡ ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ๋ฏธ์…˜ -## ๐Ÿš€ ๊ธฐ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ +> ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ๋ฏธ์…˜์€ ์šฐ์•„ํ•œ ํ…Œํฌ์ฝ”์Šค ํ”„๋ฆฌ์ฝ”์Šค 3์ฃผ์ฐจ ๋ฏธ์…˜์ž…๋‹ˆ๋‹ค. + +์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ๋ฏธ์…˜์—์„œ๋Š” ์œ ์ €๊ฐ€ ์ง€ํ•˜์ฒ  ์—ญ๊ณผ ์—ญ์„ ํฌํ•จํ•˜๊ณ ์žˆ๋Š” ๋…ธ์„ ๊ณผ ๋…ธ์„ ์˜ ๊ตฌ๊ฐ„์„ ๊ด€๋ฆฌํ•˜๊ณ , ๊ทธ์— ๋”ฐ๋ผ ๋งŒ๋“ค์–ด์ง„ ์ „์ฒด ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„๋ฅผ ์ถœ๋ ฅํ•ด๋ณผ ์ˆ˜ ์žˆ๋Š” ํ™”๋ฉด์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. + +## โœ”๏ธ ์ฃผ์–ด์ง„ ์š”๊ตฌ์‚ฌํ•ญ + +- [๊ธฐ๋Šฅ์š”๊ตฌ์‚ฌํ•ญ](#๊ธฐ๋Šฅ-์š”๊ตฌ์‚ฌํ•ญ) +- [ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ](#ํ”„๋กœ๊ทธ๋ž˜๋ฐ-์š”๊ตฌ์‚ฌํ•ญ) +- [์ถ”๊ฐ€๋œ ์š”๊ตฌ์‚ฌํ•ญ](#์ถ”๊ฐ€๋œ-์š”๊ตฌ์‚ฌํ•ญ) +- [๋ฏธ์…˜ ์ €์žฅ์†Œ ๋ฐ ์ง„ํ–‰ ์š”๊ตฌ์‚ฌํ•ญ](#๋ฏธ์…˜-์ €์žฅ์†Œ-๋ฐ-์ง„ํ–‰-์š”๊ตฌ์‚ฌํ•ญ) + +## โœ”๏ธ ์ฃผ์–ด์ง„ ์ฐธ๊ณ ์‚ฌํ•ญ + +- [ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ๊ฒฐ๊ณผ](#ํ”„๋กœ๊ทธ๋žจ-์‹คํ–‰-๊ฒฐ๊ณผ) + +## โœ”๏ธ ํ”ผ๋“œ๋ฐฑ ์ •๋ฆฌ + +- [2์ฃผ์ฐจ ํ”ผ๋“œ๋ฐฑ ์ •๋ฆฌ](#2์ฃผ์ฐจ-ํ”ผ๋“œ๋ฐฑ-์ •๋ฆฌ) + +## โœ”๏ธ ํ™”๋ฉด์˜ ๊ตฌ์„ฑ + +![ํ™”๋ฉด ๊ตฌ์„ฑ - 1, 2](images/1.png) + +## โœ”๏ธ ๊ตฌํ˜„ํ•  ๊ธฐ๋Šฅ ๋ชฉ๋ก + +### 0. ์ „์ฒด ํ™”๋ฉด + +- ์ „์ฒด ์ง€ํ•˜์ฒ  ๊ด€๋ฆฌ + +### 1.์ง€ํ•˜์ฒ  ์—ญ ๊ด€๋ฆฌ ๊ด€๋ จ ๊ธฐ๋Šฅ + +- ์œ ์ €๋กœ๋ถ€ํ„ฐ ์ง€ํ•˜์ฒ  ์—ญ ์ด๋ฆ„์„ ์ž…๋ ฅ๋ฐ›์•„ ๋“ฑ๋กํ•˜๋Š” ๊ธฐ๋Šฅ + + - ๐Ÿšฆ**์˜ˆ์™ธ ์ƒํ™ฉ** + - ์œ ์ €๊ฐ€ ์ง€ํ•˜์ฒ  ์—ญ ์ด๋ฆ„์„ 1๊ธ€์ž๋งŒ ์ž…๋ ฅํ•˜๊ฑฐ๋‚˜ ์ž…๋ ฅํ•˜์ง€ ์•Š์•˜์„ ๋•Œ ex) `"์ž "`, `""` + - ์œ ์ €๊ฐ€ ์™„์„ฑ๋˜์ง€ ์•Š์€ ์—ญ ์ด๋ฆ„์„ ์ž…๋ ฅํ–ˆ์„ ๋•Œ ex) `"์ž ใ…์‹ค"`, `"์„œใ…“ใ„ฑ์ดŒ"` + - ์œ ์ €๊ฐ€ ์ค‘๋ณต๋œ ์ง€ํ•˜์ฒ  ์—ญ ์ด๋ฆ„์„ ์ž…๋ ฅํ–ˆ์„ ๋•Œ + - ์œ ์ €๊ฐ€ ๊ณต๋ฐฑ์œผ๋กœ ์‹œ์ž‘ํ•˜๊ฑฐ๋‚˜ ๋๋‚˜๋Š” ์—ญ ์ด๋ฆ„์„ ์ž…๋ ฅํ–ˆ์„ ๋•Œ + - ์œ ์ €๊ฐ€ ์—ฐ์†์ ์ธ ๊ณต๋ฐฑ์ด ๋“ค์–ด๊ฐ„ ์—ญ ์ด๋ฆ„์„ ์ž…๋ ฅํ–ˆ์„ ๋•Œ + - ์œ ์ €๊ฐ€ ํŠน์ˆ˜๋ฌธ์ž ๊ฐ€ ํฌํ•จ๋œ ์—ญ ์ด๋ฆ„์„ ์ž…๋ ฅํ–ˆ์„ ๋•Œ ex) `"์ž ์‹ค์—ญ;;"`, `"*์„์ดŒ*"` + +- ์ €์žฅ๋œ ์ง€ํ•˜์ฒ  ์—ญ ๋ชฉ๋ก์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ธฐ๋Šฅ +- ์ €์žฅ๋œ ์ง€ํ•˜์ฒ  ์—ญ์—์„œ ์—ญ์„ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ + - ๐Ÿšฆ**์˜ˆ์™ธ ์ƒํ™ฉ** + - ๋…ธ์„ ์— ๋“ฑ๋ก๋œ ์—ญ์€ ์‚ญ์ œํ•  ์ˆ˜ ์—†์Œ + +### 2.์ง€ํ•˜์ฒ  ๋…ธ์„  ๊ด€๋ฆฌ ๊ด€๋ จ ๊ธฐ๋Šฅ + +- ์œ ์ €๋กœ๋ถ€ํ„ฐ ๋…ธ์„  ์ด๋ฆ„์„ ์ž…๋ ฅ๋ฐ›์•„ ๋“ฑ๋กํ•˜๋Š” ๊ธฐ๋Šฅ + + - ๐Ÿšฆ**์˜ˆ์™ธ ์ƒํ™ฉ** + - ์œ ์ €๊ฐ€ ๋…ธ์„  ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์ง€ ์•Š์•˜์„ ๋•Œ ex) `""` + - ์œ ์ €๊ฐ€ ์™„์„ฑ๋˜์ง€ ์•Š์€ ๋…ธ์„  ์ด๋ฆ„์„ ์ž…๋ ฅํ–ˆ์„ ๋•Œ ex) `"๊ฒฝใ…‡์˜์ค‘์•™์„ "`, `"4ํ˜ธ์„ ใ„ด"` + - ์œ ์ €๊ฐ€ ์ค‘๋ณต๋œ ๋…ธ์„  ์ด๋ฆ„์„ ์ž…๋ ฅํ–ˆ์„ ๋•Œ + - ์œ ์ €๊ฐ€ ๊ณต๋ฐฑ์œผ๋กœ ์‹œ์ž‘ํ•˜๊ฑฐ๋‚˜ ๋๋‚˜๋Š” ๋…ธ์„  ์ด๋ฆ„์„ ์ž…๋ ฅํ–ˆ์„ ๋•Œ + - ์œ ์ €๊ฐ€ ์—ฐ์†์ ์ธ ๊ณต๋ฐฑ์ด ๋“ค์–ด๊ฐ„ ๋…ธ์„  ์ด๋ฆ„์„ ์ž…๋ ฅํ–ˆ์„ ๋•Œ + - ์œ ์ €๊ฐ€ ํŠน์ˆ˜๋ฌธ์ž๊ฐ€ ํฌํ•จ๋œ ๋…ธ์„  ์ด๋ฆ„์„ ์ž…๋ ฅํ–ˆ์„ ๋•Œ + - ์œ ์ €๊ฐ€ ์ƒํ–‰ ์ข…์ ์—ญ๊ณผ ํ•˜ํ–‰ ์ข…์ ์—ญ์„ ๊ฐ™๊ฒŒ ์ž…๋ ฅํ–ˆ์„ ๋•Œ + +- ์ €์žฅ๋œ ๋…ธ์„  ๋ชฉ๋ก์„ ๋ณด์—ฌ์ฃผ๋Š” ๊ธฐ๋Šฅ +- ์ €์žฅ๋œ ๋…ธ์„  ๋ชฉ๋ก์—์„œ ๋…ธ์„ ์„ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ + +### 3.์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„ ๊ด€๋ฆฌ ๊ด€๋ จ ๊ธฐ๋Šฅ + +- ๊ฐ ๋…ธ์„  ๋ณ„๋กœ ๋งŒ๋“ค์–ด์ง„ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ํ•ด๋‹น ๋…ธ์„  ๊ด€๋ฆฌ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๊ธฐ๋Šฅ +- ์—ญ์„ ์„ ํƒํ•˜๊ณ  ์œ ์ €์˜ ์ž…๋ ฅ์„ ๋ฐ›์•„ ๋…ธ์„ ์˜ ์ˆœ์„œ๋ฅผ ์ •ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ + + - ํ•˜๋‚˜์˜ ์—ญ์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋…ธ์„ ์— ์ถ”๊ฐ€๋  ์ˆ˜ ์žˆ์Œ + - ์—ญ๊ณผ ์—ญ ์‚ฌ์ด์— ์ƒˆ๋กœ์šด ์—ญ์ด ์ถ”๊ฐ€๋  ์ˆ˜ ์žˆ์Œ + - ๐Ÿšฆ**์˜ˆ์™ธ ์ƒํ™ฉ** + - ์œ ์ €๊ฐ€ ๋…ธ์„ ์˜ ์ˆœ์„œ๋ฅผ 0 ๋˜๋Š” ์Œ์ˆ˜๋กœ ์ž…๋ ฅํ–ˆ์„ ๋•Œ + - ์œ ์ €๊ฐ€ ๋…ธ์„ ์˜ ์ˆœ์„œ๋ฅผ ์†Œ์ˆ˜๋กœ ์ž…๋ ฅํ–ˆ์„ ๋•Œ ex) `1.2` + +- ์—ญ์„ ๋…ธ์„ ์—์„œ ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ + - ์ข…์ ์„ ์ œ๊ฑฐํ•  ๊ฒฝ์šฐ, ๊ทธ ๋‹ค์Œ ์—ญ์ด ์ข…์ ์ด ๋จ + - ๐Ÿšฆ**์˜ˆ์™ธ ์ƒํ™ฉ** + - ๋…ธ์„ ์— ํฌํ•จ๋œ ์—ญ์ด 2๊ฐœ ์ดํ•˜์ผ ๋•Œ ์—ญ์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์—†์Œ + +### 4.์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ์ถœ๋ ฅ ๊ด€๋ จ ๊ธฐ๋Šฅ + +- ๋…ธ์„  ๋ณ„ ์ €์žฅ๋œ ์—ญ๋“ค์„ ์ˆœ์„œ๋Œ€๋กœ ๋ชจ๋‘ ์ถœ๋ ฅํ•˜๋Š” ๊ธฐ๋Šฅ + +## โœ”๏ธ ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ๋ฏธ์…˜ ํšŒ๊ณ  (2020.12.09 ~ 2020.12.15) + +์ด๋ฒˆ ๋ฏธ์…˜๋„ ์ €๋ฒˆ ์ฃผ ์ž๋™์ฐจ ๊ฒฝ์ฃผ ๊ฒŒ์ž„ ๋ฏธ์…˜๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ **๊ธฐ๋Šฅ์— ๋”ฐ๋ผ ๋ชจ๋“ˆ์„ ๋ถ„๋ฆฌํ•˜๊ณ , ๋ถ„๋ฆฌํ•œ ๋ชจ๋“ˆ์„ ์ฐพ๊ธฐ ์‰ฝ๊ฒŒ ๊ตฌ์กฐํ™”**ํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ–ˆ๋‹ค. ์–ด๋–ป๊ฒŒ ๋ชจ๋“ˆ์„ ๋ถ„๋ฆฌํ•ด์•ผ 1๊ฐœ์˜ ๋ชจ๋“ˆ์—์„œ 1๊ฐœ์˜ ์—ญํ• ๋งŒ์„ ํ•˜๊ฒŒ ๋งŒ๋“ค์ง€ ๊ณ ๋ฏผํ–ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  **data์†์„ฑ์„ ํ™œ์šฉํ•ด ์œ ์ผํ•œ ๋ฐ์ดํ„ฐ ๊ฐ’๋“ค์„ ๊ด€๋ฆฌ**ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐ ์ง‘์ค‘ํ–ˆ๋‹ค. ์ฃผ์–ด์ง„ ์š”๊ตฌ์‚ฌํ•ญ์„ ์ˆ™์ง€ํ•˜๊ณ , ๋งค ์ฝ”๋“œ์— ์ ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋…ธ๋ ฅํ–ˆ๋‹ค. + +### ๋ชจ๋“ˆ ๋ถ„๋ฆฌ, ๊ตฌ์กฐํ™” + +1๊ฐœ์˜ ํ•จ์ˆ˜๊ฐ€ 1๊ฐœ์˜ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๊ตฌํ˜„ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ–ˆ๋‹ค. ์ƒ๊ฐ๋ณด๋‹ค ๋‹ค์–‘ํ•˜๊ณ  ๋งŽ์€ ๊ธฐ๋Šฅ์— ์กฐ๊ธˆ ํ—ค๋งจ ๊ฐ์ด ์—†์ง€ ์•Š์•„ ์žˆ์ง€๋งŒ, ์ฝ”๋“œ์˜ ๋ฐ˜๋ณต์„ ์ค„์ด๊ณ  ์žฌ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค์–ด ๋ชจ๋“ˆ์„ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐ ํž˜์ผ๋‹ค. ๋น„๋ก ์ด๋ฒˆ์— ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ์— ์™„๋ฒฝํžˆ ๋งŒ์กฑํ•˜์ง€๋Š” ์•Š์ง€๋งŒ, ์•ž์œผ๋กœ ๋” ๋งŽ์€ ์—ฐ์Šต์„ ํ†ตํ•ด ์Šค์Šค๋กœ ๋งŒ์กฑํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค์–ด๋‚˜๊ฐ€๊ณ  ์‹ถ๋‹ค. + +### ์ฝ๊ธฐ ์ข‹์€ ์ฝ”๋“œ๋ž€ ๋ฌด์—‡์ผ๊นŒ? + +์ด๋ฒˆ ์ฃผ ๋ฏธ์…˜์€ ์ƒ๊ฐ๋ณด๋‹ค ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ๋งŽ์ด ๋“ค์—ˆ๋‹ค. ์˜ˆ์™ธ ์ƒํ™ฉ๋„ ์ƒ๊ฐํ•˜์ง€ ๋ชปํ•œ ๊ณณ์—์„œ ํŠ€์–ด๋‚˜์™”๊ณ , ์ฝ”๋“œ๊ฐ€ ๊ธธ์–ด์ง€๋ฉด ์•ˆ๋œ๋‹ค๋Š” ์ƒ๊ฐ์— ๋ฌด์ž‘์ • ๋ชจ๋“ˆํ™” ํ•ด ๋–ผ๋‚ธ ์ ๋„ ์žˆ์—ˆ๋‹ค. ์ˆซ์ž ์•ผ๊ตฌ ๊ฒŒ์ž„, ์ž๋™์ฐจ ๊ฒฝ์ฃผ ๊ฒŒ์ž„์—์„œ๋Š” ๋ณด๋‹ค ์†์‰ฝ๊ฒŒ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ณ  ์ƒ๊ฐํ•˜๋Š”๋Œ€๋กœ ๋ฉ”์†Œ๋“œ ๋ถ„๋ฆฌ๋„ ์ž˜ ๋˜์—ˆ๋Š”๋ฐ, ์ด๋ฒˆ ๋ฏธ์…˜์—์„œ๋Š” ๋‚˜๋ฆ„๋Œ€๋กœ(?) ์ฒด๊ณ„์ ์œผ๋กœ ๊ฐ€๋‹ฅ์„ ์žก๊ณ  ๋“ค์–ด๊ฐ”๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์ง€๋งŒ ๋งˆ์Œ์ฒ˜๋Ÿผ ์ž˜ ๋งŒ๋“ค์–ด์ง€์ง€ ์•Š์€ ๊ฒƒ ๊ฐ™์•„ ์•„์‰ฌ์›€์ด ํฌ๋‹ค. ํ”„๋กœ์ ํŠธ๊ฐ€ ์ปค์ง์— ๋”ฐ๋ผ ์“ฐ์ด๋Š” ๋ณ€์ˆ˜ ๋ช…์ด๋‚˜ ํ•จ์ˆ˜ ๋ช…๋„ ํ—ท๊ฐˆ๋ฆฌ๊ธฐ ์‰ฌ์›Œ ๋” ๋ช…ํ™•ํ•˜๊ณ  ์™€๋‹ฟ์„ ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋„๋ก ๊ณ ๋ฏผ๊ณผ ์—ฐ์Šต์„ ๊ฑฐ๋“ญํ•ด์•ผ๊ฒ ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ณ  ๋‚˜์„œ, ๋ฆฌํŒฉํ† ๋งํ•˜๋ฉฐ ๋‚ด๊ฐ€ ๊ตฌํ˜„ํ•œ ์ฝ”๋“œ์˜ ๋ถ€์กฑํ•œ ์ ์— ๋Œ€ํ•ด ์—ฌ์‹คํžˆ ๊นจ๋‹ฌ์•˜๊ณ , ๋ณด๋‹ค ์ฝ๊ธฐ ์‰ฝ๊ณ  ๋ˆ„๊ตฌ๋‚˜ ์‰ฝ๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•  ๊ฒƒ์ด๋‹ค. + +--- + +## ๊ธฐ๋Šฅ ์š”๊ตฌ์‚ฌํ•ญ ### ์ง€ํ•˜์ฒ  ์—ญ ๊ด€๋ จ ๊ธฐ๋Šฅ + - ์ง€ํ•˜์ฒ  ์—ญ์„ ๋“ฑ๋กํ•˜๊ณ  ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋‹ค. (๋‹จ, ๋…ธ์„ ์— ๋“ฑ๋ก๋œ ์—ญ์€ ์‚ญ์ œํ•  ์ˆ˜ ์—†๋‹ค) - ์ค‘๋ณต๋œ ์ง€ํ•˜์ฒ  ์—ญ ์ด๋ฆ„์ด ๋“ฑ๋ก๋  ์ˆ˜ ์—†๋‹ค. - ์ง€ํ•˜์ฒ  ์—ญ์€ 2๊ธ€์ž ์ด์ƒ์ด์–ด์•ผ ํ•œ๋‹ค. - ์ง€ํ•˜์ฒ  ์—ญ์˜ ๋ชฉ๋ก์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค. ### ์ง€ํ•˜์ฒ  ๋…ธ์„  ๊ด€๋ จ ๊ธฐ๋Šฅ + - ์ง€ํ•˜์ฒ  ๋…ธ์„ ์„ ๋“ฑ๋กํ•˜๊ณ  ์‚ญ์ œํ•  ์ˆ˜ ์žˆ๋‹ค. - ์ค‘๋ณต๋œ ์ง€ํ•˜์ฒ  ๋…ธ์„  ์ด๋ฆ„์ด ๋“ฑ๋ก๋  ์ˆ˜ ์—†๋‹ค. - ๋…ธ์„  ๋“ฑ๋ก ์‹œ ์ƒํ–‰ ์ข…์ ์—ญ๊ณผ ํ•˜ํ–‰ ์ข…์ ์—ญ์„ ์ž…๋ ฅ๋ฐ›๋Š”๋‹ค. - ์ง€ํ•˜์ฒ  ๋…ธ์„ ์˜ ๋ชฉ๋ก์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค. ### ์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ + - ์ง€ํ•˜์ฒ  ๋…ธ์„ ์— ๊ตฌ๊ฐ„์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ธฐ๋Šฅ์€ ๋…ธ์„ ์— ์—ญ์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ธฐ๋Šฅ์ด๋ผ๊ณ ๋„ ํ•  ์ˆ˜ ์žˆ๋‹ค. - - ์—ญ๊ณผ ์—ญ์‚ฌ์ด๋ฅผ ๊ตฌ๊ฐ„์ด๋ผ ํ•˜๊ณ  ์ด ๊ตฌ๊ฐ„๋“ค์˜ ๋ชจ์Œ์ด ๋…ธ์„ ์ด๋‹ค. + - ์—ญ๊ณผ ์—ญ์‚ฌ์ด๋ฅผ ๊ตฌ๊ฐ„์ด๋ผ ํ•˜๊ณ  ์ด ๊ตฌ๊ฐ„๋“ค์˜ ๋ชจ์Œ์ด ๋…ธ์„ ์ด๋‹ค. - ํ•˜๋‚˜์˜ ์—ญ์€ ์—ฌ๋Ÿฌ๊ฐœ์˜ ๋…ธ์„ ์— ์ถ”๊ฐ€๋  ์ˆ˜ ์žˆ๋‹ค. - ์—ญ๊ณผ ์—ญ ์‚ฌ์ด์— ์ƒˆ๋กœ์šด ์—ญ์ด ์ถ”๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‹ค. - ๋…ธ์„ ์—์„œ ๊ฐˆ๋ž˜๊ธธ์€ ์ƒ๊ธธ ์ˆ˜ ์—†๋‹ค. - +![์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ](images/section1.png) ### ์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„ ์‚ญ์ œ ๊ธฐ๋Šฅ + - ๋…ธ์„ ์— ๋“ฑ๋ก๋œ ์—ญ์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค. - ์ข…์ ์„ ์ œ๊ฑฐํ•  ๊ฒฝ์šฐ ๋‹ค์Œ ์—ญ์ด ์ข…์ ์ด ๋œ๋‹ค. - ๋…ธ์„ ์— ํฌํ•จ๋œ ์—ญ์ด ๋‘๊ฐœ ์ดํ•˜์ผ ๋•Œ๋Š” ์—ญ์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์—†๋‹ค. - +![์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„ ์‚ญ์ œ ๊ธฐ๋Šฅ](images/section2.png) ### ์ง€ํ•˜์ฒ  ๋…ธ์„ ์— ๋“ฑ๋ก๋œ ์—ญ ์กฐํšŒ ๊ธฐ๋Šฅ + - ๋…ธ์„ ์˜ ์ƒํ–‰ ์ข…์ ๋ถ€ํ„ฐ ํ•˜ํ–‰ ์ข…์ ๊นŒ์ง€ ์—ฐ๊ฒฐ๋œ ์ˆœ์„œ๋Œ€๋กœ ์—ญ ๋ชฉ๋ก์„ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋‹ค. -
+
-## ๐Ÿ’ป ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ๊ฒฐ๊ณผ +## ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ๊ฒฐ๊ณผ ### ์—ญ๊ด€๋ฆฌ - + +![ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ๊ฒฐ๊ณผ - ์—ญ๊ด€๋ฆฌ](images/station_manager.gif) ### ๋…ธ์„ ๊ด€๋ฆฌ - + +![ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ๊ฒฐ๊ณผ - ๋…ธ์„ ๊ด€๋ฆฌ](images/line_manager.gif) ### ๊ตฌ๊ฐ„๊ด€๋ฆฌ - + +![ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ๊ฒฐ๊ณผ - ๊ตฌ๊ฐ„๊ด€๋ฆฌ](images/section_manager.gif) ### ๋…ธ์„ ๋„ ์ถœ๋ ฅ - +![ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ๊ฒฐ๊ณผ - ๋…ธ์„ ๋„ ์ถœ๋ ฅ](images/map_print_manager.gif) -## โœ… ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ +## ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์š”๊ตฌ์‚ฌํ•ญ ### ๋ฉ”๋‰ด ๋ฒ„ํŠผ + - ์—ญ ๊ด€๋ฆฌ button ํƒœ๊ทธ๋Š” `#station-manager-button` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - ๋…ธ์„  ๊ด€๋ฆฌ button ํƒœ๊ทธ๋Š” `#line-manager-button` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - ๊ตฌ๊ฐ„ ๊ด€๋ฆฌ button ํƒœ๊ทธ๋Š” `#section-manager-button` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ์ถœ๋ ฅ ๊ด€๋ฆฌ button ํƒœ๊ทธ๋Š” `#map-print-manager-button` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. ### ์ง€ํ•˜์ฒ  ์—ญ ๊ด€๋ จ ๊ธฐ๋Šฅ + - ์ง€ํ•˜์ฒ  ์—ญ์„ ์ž…๋ ฅํ•˜๋Š” input ํƒœ๊ทธ๋Š” `#station-name-input` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - ์ง€ํ•˜์ฒ  ์—ญ์„ ์ถ”๊ฐ€ํ•˜๋Š” button ํƒœ๊ทธ๋Š” `#station-add-button` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - ์ง€ํ•˜์ฒ  ์—ญ์„ ์‚ญ์ œํ•˜๋Š” button ํƒœ๊ทธ๋Š” `.station-delete-button` class๊ฐ’์„ ๊ฐ€์ง„๋‹ค. ### ์ง€ํ•˜์ฒ  ๋…ธ์„  ๊ด€๋ จ ๊ธฐ๋Šฅ + - ์ง€ํ•˜์ฒ  ๋…ธ์„ ์˜ ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜๋Š” input ํƒœ๊ทธ๋Š” `#line-name-input` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - ์ง€ํ•˜์ฒ  ๋…ธ์„ ์˜ ์ƒํ–‰ ์ข…์ ์„ ์„ ํƒํ•˜๋Š” select ํƒœ๊ทธ๋Š” `#line-start-station-selector` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - ์ง€ํ•˜์ฒ  ๋…ธ์„ ์˜ ํ•˜ํ–‰ ์ข…์ ์„ ์„ ํƒํ•˜๋Š” select ํƒœ๊ทธ๋Š” `#line-end-station-selector` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. @@ -71,6 +178,7 @@ - ์ง€ํ•˜์ฒ  ๋…ธ์„ ์„ ์‚ญ์ œํ•˜๋Š” button ํƒœ๊ทธ๋Š” `.line-delete-button` class๊ฐ’์„ ๊ฐ€์ง„๋‹ค. ### ์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ + - ์ง€ํ•˜์ฒ  ๋…ธ์„ ์„ ์„ ํƒํ•˜๋Š” button ํƒœ๊ทธ๋Š” `.section-line-menu-button` class๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - ์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„์„ ์„ค์ •ํ•  ์—ญ select ํƒœ๊ทธ๋Š” `#section-station-selector` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. - ์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„์˜ ์ˆœ์„œ๋ฅผ ์ž…๋ ฅํ•˜๋Š” input ํƒœ๊ทธ๋Š” `#section-order-input` id๊ฐ’์„ ๊ฐ€์ง„๋‹ค. @@ -78,6 +186,7 @@ - ์ง€ํ•˜์ฒ  ๊ตฌ๊ฐ„์„ ์ œ๊ฑฐํ•˜๋Š” button ํƒœ๊ทธ๋Š” `.section-delete-button` class๊ฐ’์„ ๊ฐ€์ง„๋‹ค. ### ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ์ถœ๋ ฅ ๊ธฐ๋Šฅ + - ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ์ถœ๋ ฅ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด `
` ํƒœ๊ทธ๋ฅผ ๋งŒ๋“ค๊ณ  ํ•ด๋‹น ํƒœ๊ทธ ๋‚ด๋ถ€์— ๋…ธ์„ ๋„๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ### ๊ธฐ์กด ์š”๊ตฌ์‚ฌํ•ญ @@ -101,14 +210,176 @@ - [https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Template_literals](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Template_literals) ### ์ถ”๊ฐ€๋œ ์š”๊ตฌ์‚ฌํ•ญ -- [data](https://developer.mozilla.org/ko/docs/Learn/HTML/Howto/%EB%8D%B0%EC%9D%B4%ED%84%B0_%EC%86%8D%EC%84%B1_%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0)์†์„ฑ์„ ํ™œ์šฉํ•˜์—ฌ html ํƒœ๊ทธ์— ์—ญ, ๋…ธ์„ , ๊ตฌ๊ฐ„์˜ ์œ ์ผํ•œ ๋ฐ์ดํ„ฐ ๊ฐ’๋“ค์„ ๊ด€๋ฆฌํ•œ๋‹ค. + +- [data](https://developer.mozilla.org/ko/docs/Learn/HTML/Howto/%EB%8D%B0%EC%9D%B4%ED%84%B0_%EC%86%8D%EC%84%B1_%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0)์†์„ฑ์„ ํ™œ์šฉํ•˜์—ฌ html ํƒœ๊ทธ์— ์—ญ, ๋…ธ์„ , ๊ตฌ๊ฐ„์˜ ์œ ์ผํ•œ ๋ฐ์ดํ„ฐ ๊ฐ’๋“ค์„ ๊ด€๋ฆฌํ•œ๋‹ค. - [localStorage](https://developer.mozilla.org/ko/docs/Web/API/Window/localStorage)๋ฅผ ์ด์šฉํ•˜์—ฌ, ์ƒˆ๋กœ๊ณ ์นจํ•˜๋”๋ผ๋„ ๊ฐ€์žฅ ์ตœ๊ทผ์— ์ž‘์—…ํ•œ ์ •๋ณด๋“ค์„ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.
-## ๐Ÿ“ ๋ฏธ์…˜ ์ €์žฅ์†Œ ๋ฐ ์ง„ํ–‰ ์š”๊ตฌ์‚ฌํ•ญ +## ๋ฏธ์…˜ ์ €์žฅ์†Œ ๋ฐ ์ง„ํ–‰ ์š”๊ตฌ์‚ฌํ•ญ - ๋ฏธ์…˜์€ [https://github.com/woowacourse/javascript-subway-map-precours](https://github.com/woowacourse/javascript-subway-map-precourse) ์ €์žฅ์†Œ๋ฅผ fork/cloneํ•ด ์‹œ์ž‘ํ•œ๋‹ค. - **๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์ „์— javascript-subway-precourse/docs/README.md ํŒŒ์ผ์— ๊ตฌํ˜„ํ•  ๊ธฐ๋Šฅ ๋ชฉ๋ก**์„ ์ •๋ฆฌํ•ด ์ถ”๊ฐ€ํ•œ๋‹ค. - **git์˜ commit ๋‹จ์œ„๋Š” ์•ž ๋‹จ๊ณ„์—์„œ README.md ํŒŒ์ผ์— ์ •๋ฆฌํ•œ ๊ธฐ๋Šฅ ๋ชฉ๋ก ๋‹จ์œ„๋กœ ์ถ”๊ฐ€**ํ•œ๋‹ค. - [ํ”„๋ฆฌ์ฝ”์Šค ๊ณผ์ œ ์ œ์ถœ](https://github.com/woowacourse/woowacourse-docs/tree/master/precourse) ๋ฌธ์„œ ์ ˆ์ฐจ๋ฅผ ๋”ฐ๋ผ ๋ฏธ์…˜์„ ์ œ์ถœํ•œ๋‹ค. + +--- + +## 2์ฃผ์ฐจ ํ”ผ๋“œ๋ฐฑ ์ •๋ฆฌ + +> ๐Ÿ”ซ: 1์ฃผ์ฐจ ํ”ผ๋“œ๋ฐฑ์—์„œ๋„ ๊ฐ•์กฐ๋œ ๋ถ€๋ถ„ + +### ๐Ÿ“Œ๊ธฐ๋Šฅ ๋ชฉ๋ก ๊ตฌํ˜„ + +- ๐Ÿ”ซ๊ธฐ๋Šฅ ๋ชฉ๋ก ๊ตฌํ˜„์„ ์žฌ๊ฒ€ํ† ํ•œ๋‹ค. + + - ๊ธฐ๋Šฅ ๋ชฉ๋ก์„ ๋„ˆ๋ฌด ์ƒ์„ธํžˆ ์ž‘์„ฑํ•˜์ง€ ์•Š๋Š”๋‹ค. (์–ธ์ œ๋“  ๋ณ€๊ฒฝ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ) + - ๊ตฌํ˜„ํ•ด์•ผ ํ•  ๊ธฐ๋Šฅ ๋ชฉ๋ก์„ ์ •๋ฆฌํ•˜๋Š” ๋ฐ ์ง‘์ค‘ํ•œ๋‹ค. + - **์˜ˆ์™ธ์ ์ธ ์ƒํ™ฉ๋„ ๊ธฐ๋Šฅ ๋ชฉ๋ก์— ์ •๋ฆฌํ•œ๋‹ค.** + - ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋ฉฐ ๊ณ„์†ํ•ด์„œ ์ถ”๊ฐ€ํ•ด ๋‚˜๊ฐ„๋‹ค. + - ๊ธฐ๋Šฅ ๋ชฉ๋ก ์ž‘์„ฑ ์˜ˆ์‹œ(์ž๋™์ฐจ ๊ฒฝ์ฃผ ๊ฒŒ์ž„) + + ```text + - ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ์ด๋ฆ„์„ ์‰ผํ‘œ ๊ธฐ์ค€์œผ๋กœ ๋ถ„๋ฆฌํ•ด์•ผ ํ•œ๋‹ค. + - ์‚ฌ์šฉ์ž ์ด๋ฆ„์ด 5์ž ์ดํ•˜์ธ์ง€ ๊ฒ€์ฆํ•ด์•ผ ํ•œ๋‹ค. + - ์ž๋™์ฐจ๋Š” 4์ด์ƒ์ธ ๊ฒฝ์šฐ ์ „์ง„ํ•œ๋‹ค. + - ์ž๋™์ฐจ๋Š” 4๋ฏธ๋งŒ์ธ ๊ฒฝ์šฐ ์ •์ง€ํ•œ๋‹ค. + - 0 ~ 9 ์‚ฌ์ด์˜ ์ž„์˜์˜ ๊ฐ’์„ ์ƒ์„ฑํ•œ๋‹ค. + - ์—ฌ๋Ÿฌ ๋Œ€์˜ ์ž๋™์ฐจ ์ค‘ ์ตœ๋Œ€ ์œ„์น˜ ๊ฐ’์„ ๊ตฌํ•œ๋‹ค. + - ์ตœ๋Œ€ ์œ„์น˜ ๊ฐ’์— ํ•ด๋‹นํ•˜๋Š” ์ž๋™์ฐจ ๋ชฉ๋ก์„ ๊ตฌํ•œ๋‹ค. + ``` + +### ๐Ÿ“ŒGit + +- git `commit message`์— `#๋ฒˆํ˜ธ`๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š๋Š”๋‹ค. + - `#๋ฒˆํ˜ธ`๋Š” `๋‹ค๋ฅธ ์ด์Šˆ` ๋˜๋Š” `Pull Request`๋ฅผ ์ฐธ์กฐํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. +- git์„ ํ†ตํ•ด ๊ด€๋ฆฌํ•  ์ž์›์— ๋Œ€ํ•ด์„œ๋„ ๊ณ ๋ คํ•œ๋‹ค. + - `.idea`, `.vscode`, `node_modules` ๋“ฑ๊ณผ ๊ฐ™์€ ๊ฒฝ์šฐ git์œผ๋กœ ๊ด€๋ฆฌํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. + - git์— ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•  ๋•Œ์—๋Š” git์„ ํ†ตํ•ด ๊ด€๋ฆฌํ•  ํ•„์š”๊ฐ€ ์žˆ๋Š” ์ง€ ์—ฌ๋ถ€๋ฅผ ๊ณ ๋ คํ•ด์•ผ ํ•œ๋‹ค. +- Pull Request๋ฅผ ๋ณด๋‚ด๊ธฐ ์ „, ๋ธŒ๋žœ์น˜๋ฅผ ํ™•์ธํ•œ๋‹ค. + - ์ƒˆ๋กœ ๋งŒ๋“  ๋ธŒ๋žœ์น˜์—์„œ ์ž‘์—…ํ•œ ํ›„, PR์„ ๋ณด๋‹Œ๋‹ค. + +### ๐Ÿ“Œ์ƒ์ˆ˜, ์ด๋ฆ„ ๋ฐ ์ฃผ์„ + +- ๊ฐ€๋Šฅํ•˜๋ฉด ํ•˜๋“œ์ฝ”๋”ฉ๋˜๋Š” ๊ฐ’๋“ค์„ `์ƒ์ˆ˜`๋กœ ํ™œ์šฉํ•œ๋‹ค. +- ์„œ๋น„์Šค, ๊ฒŒ์ž„ ๋“ฑ์—์„œ๋Š” ๋กœ์ง์ด ๋ณ€๊ฒฝ๋˜๊ฑฐ๋‚˜ ์š”๊ตฌ์‚ฌํ•ญ์ด ์ถ”๊ฐ€๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ํ•ด๋‹นํ•˜๋Š” ๊ฐ’๋“ค์„ ํ•˜๋“œ์ฝ”๋”ฉํ•˜๋‹ค๋ณด๋ฉด ์ˆ˜์ • ๊ณผ์ • ์ค‘์— ํœด๋จผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. +- ํ•˜๋“œ์ฝ”๋”ฉ ๋˜๋Š” ๊ฐ’๋“ค์˜ ์˜ˆ์‹œ(์ž๋™์ฐจ ๊ฒฝ์ฃผ ๊ฒŒ์ž„) + + ```text + - ์ด๋™/์ •์ง€ ๊ธฐ์ค€ : 4 + - Random ์ƒ์„ฑ ๊ธฐ์ค€ : 10 + - ์—ฌ๋Ÿฌ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋“ค + ``` + +- ๐Ÿ”ซ`์ด๋ฆ„`์„ ํ†ตํ•ด ์˜๋„๋ฅผ ๋“œ๋Ÿฌ๋‚ด๋ผ. + + - ๋ณ€์ˆ˜, ํ•จ์ˆ˜ ์ด๋ฆ„์„ ์ถ•์•ฝํ•˜์ง€ ๋ง์•„๋ผ. + - ์˜๋„๋ฅผ ๋“œ๋Ÿฌ๋‚ผ ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ด๋ฆ„์ด ๊ธธ์–ด์ ธ๋„ ๊ดœ์ฐฎ๋‹ค. + +- ๐Ÿ”ซ์ฃผ์„์€ ๊ผญ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋งŒ ๋‚จ๊ธด๋‹ค. + - ๊ฐ€๋Šฅํ•˜๋ฉด ๋ณ€์ˆ˜ ์ด๋ฆ„, ํ•จ์ˆ˜(๋ฉ”์†Œ๋“œ) ์ด๋ฆ„์„ ํ†ตํ•ด ์˜๋„๋ฅผ ๋“œ๋Ÿฌ๋‚ด๊ณ , ์˜๋„๋ฅผ ๋“œ๋Ÿฌ๋‚ด๊ธฐ ํž˜๋“  ๊ฒฝ์šฐ ์ฃผ์„์„ ๋‹จ๋‹ค. + +### ๐Ÿ“ŒCoding + +- Boolean์„ returnํ•˜๋Š” ๊ฒฝ์šฐ, ๊ฐ„๊ฒฐํžˆ ํ•œ๋‹ค. + + - ์ข‹์ง€ ์•Š์€ ์˜ˆ์‹œ + + ```javascript + const isValidCar = (car) => { + if (car.hasValidName()) { + return true; + } + return false; + }; + ``` + + - ์ข‹์€ ์˜ˆ์‹œ (๋ณด๋‹ค ๋ช…ํ™•ํ•˜๊ณ , ์ฝ”๋“œ๊ฐ€ ๊ฐ„๊ฒฐ) + + ```javascript + const isValidCar = () => { + return car.hasVAlidName(); + }; + ``` + +- javascript์—์„œ ์ œ๊ณตํ•˜๋Š” api๋ฅผ ์ ๊ทน์ ์œผ๋กœ ํ™œ์šฉํ•œ๋‹ค. + + - ๋ฉ”์†Œ๋“œ๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•˜๊ธฐ ์ „์—, javascript api์—์„œ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋Šฅ์ธ์ง€ ๊ฒ€์ƒ‰์„ ๋จผ์ € ํ•ด๋ณธ๋‹ค. + - ์ œ๊ณตํ•˜์ง€ ์•Š๋Š” ๊ธฐ๋Šฅ์ผ ๊ฒฝ์šฐ, ์ง์ ‘ ๊ตฌํ˜„ํ•œ๋‹ค. + - ์ž๋™์ฐจ ๊ฒฝ์ฃผ ๊ฒŒ์ž„์˜ ์šฐ์Šน์ž ์ถœ๋ ฅ ์˜ˆ์‹œ + + ```javascript + const winners = ["east", "west", "south"]; + winners + .map((winner) => { + return winner; + }) + .join(","); + // "east,west,south" + ``` + +- ๋ถˆํ•„์š”ํ•œ ๋ณ€์ˆ˜๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•œ๋‹ค. + + - ๋ณต์žก๋„์™€ ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•  ๊ฐ€๋Šฅ์„ฑ์„ ๋†’์ธ๋‹ค. + - ์ค‘๋ณต์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ด `๋ฉค๋ฒ„๋ณ€์ˆ˜์˜ ์ˆ˜`๋ฅผ ์ตœ์†Œํ™”ํ•œ๋‹ค. + - ์ž๋™์ฐจ ๊ฒฝ์ฃผ ๊ฒŒ์ž„ ์˜ˆ์‹œ + + - ์ข‹์ง€ ์•Š์€ ์˜ˆ์‹œ + + ```javascript + function RacingCarGame() { + this.cars; + this.maxDistance; + this.winners; + } + ``` + + - ์ข‹์€ ์˜ˆ์‹œ + + ```javascript + function RacingCarGame() { + this.cars; + + this.getWinners = () => {...} + this.getMaxDistance = () => {...} + } + ``` + +- ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง๊ณผ UI ๋กœ์ง์„ ๋ถ„๋ฆฌํ•ด๋ผ. + + - ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง๊ณผ UI ๋กœ์ง์„ ํ•œ ํ•จ์ˆ˜๊ฐ€ ๋‹ด๋‹นํ•˜์ง€ ์•Š๋„๋ก ํ•œ๋‹ค. + - ๋‹จ์ผ ์ฑ…์ž„์˜ ์›์น™์„ ์ง€์ผœ์•ผ ํ•œ๋‹ค. + - ์ž๋™์ฐจ ๊ฒฝ์ฃผ ๊ฒŒ์ž„ ์˜ˆ์‹œ + + - ์ข‹์ง€ ์•Š์€ ์˜ˆ์‹œ + + ```javascript + function Car() { + this.position = 0; + + // ์ž๋™์ฐจ ์ด๋™ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๋น„์ง€๋‹ˆ์Šค ๋กœ์ง + this.move = (randomNumber) => {...} ; + + // UI ๋กœ์ง + this.render = () => { + $element.innerHTML = template() + }; + } + ``` + +- ํ•จ์ˆ˜(๋ฉ”์†Œ๋“œ) ๋ผ์ธ์— ๋Œ€ํ•œ ๊ธฐ์ค€ + + - ๊ณต๋ฐฑ ๋ผ์ธ๋„ ํ•œ ๋ผ์ธ์— ํ•ด๋‹นํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฃผ์„์€ ๊ฐ€๋Šฅํ•˜๋ฉด ํ•จ์ˆ˜ ๋ฐ– ๋˜๋Š” ์ฝ”๋“œ ์šฐ์ธก์— ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•œ๋‹ค. + +- ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ์˜ˆ์™ธ ์ผ€์ด์Šค์— ๋Œ€ํ•ด ๊ณ ๋ฏผํ•œ๋‹ค. + + - ์ •์ƒ์ ์ธ ๊ฒฝ์šฐ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์˜ˆ์™ธ ์ƒํ™ฉ์„ ๋ชจ๋‘ ๊ณ ๋ คํ•ด ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•˜๋Š” ๊ฒƒ์ด ๋” ์–ด๋ ต๋‹ค. + - ์˜ˆ์™ธ ์ƒํ™ฉ์„ ์ž˜ ๊ณ ๋ คํ•ด ํ”„๋กœ๊ทธ๋ž˜๋ฐํ•˜๋Š” `์Šต๊ด€`์„ ๋“ค์—ฌ์•ผ ํ•œ๋‹ค. + - ๊ทธ๋ฆฌ๊ณ  ์ด๋Ÿฌํ•œ ์˜ˆ์™ธ ์ƒํ™ฉ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ์ž˜ ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. + - ์ž๋™์ฐจ ๊ฒฝ์ฃผ ๊ฒŒ์ž„์˜ ์˜ˆ์™ธ์ƒํ™ฉ ์˜ˆ์‹œ + + ```text + - ๋งŒ์•ฝ ์ง„ํ–‰ํ•  ๊ฒŒ์ž„์˜ ํšŸ์ˆ˜์— ์Œ์ˆ˜๋ฅผ ์ž…๋ ฅํ•œ๋‹ค๋ฉด? + - ๋งŒ์•ฝ ์ด๋ฆ„์— ๋นˆ ๊ฐ’์„ ๋„ฃ๋Š”๋‹ค๋ฉด? + - ๋งŒ์•ฝ ์‰ผํ‘œ๋ฅผ ์ด๋ฆ„์œผ๋กœ ๋„ฃ๋Š”๋‹ค๋ฉด? + ``` diff --git a/images/1.png b/images/1.png new file mode 100644 index 000000000..7acaf4667 Binary files /dev/null and b/images/1.png differ diff --git a/index.html b/index.html index fc99deac2..7ce6a0b1e 100644 --- a/index.html +++ b/index.html @@ -6,8 +6,15 @@
-

๐Ÿš‡ ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ๊ด€๋ฆฌ

+

๐Ÿš‡ ์ง€ํ•˜์ฒ  ๋…ธ์„ ๋„ ๊ด€๋ฆฌ

+ +
diff --git a/src/components/line-manage-container.js b/src/components/line-manage-container.js new file mode 100644 index 000000000..05bb02b30 --- /dev/null +++ b/src/components/line-manage-container.js @@ -0,0 +1,72 @@ +import SubwayLine from "../domain/subway-line.js"; +import inputNameValidator from "../utils/inputs/validator/name-validator.js"; +import clearInput from "../utils/inputs/clear-input.js"; +import { saveToLocalStorage } from "../index.js"; +import { showNewRow, makeSelectOptions } from "../utils/display/make-elements.js"; +import { getStationByName } from "../utils/global-utils.js"; +import { LINE_ALERT_MESSAGES } from "../global/messages.js"; +import { LINE_ARRAY_KEY, LINE_TAGS } from "../global/constant.js"; + +const SUBWAY_LINE_TBODY_ID = "lines"; +const VALIDATION_TYPE = "LINE"; + +function loadLines(state) { + for (const line of state.subwayLines) { + showNewRow(SUBWAY_LINE_TBODY_ID, line, [ + line.lineName, + line.stations[0].stationName, + line.stations[line.stations.length - 1].stationName + ]); + } +} + +function validateLineName(subwayLines, lineName, upLine, downLine, addLineInput) { + if (inputNameValidator(VALIDATION_TYPE, lineName)) { + saveLine(subwayLines, lineName, upLine, downLine); + saveToLocalStorage(LINE_ARRAY_KEY, JSON.stringify(subwayLines)); + clearInput(addLineInput); + } else { + clearInput(addLineInput); + } +} + +function saveLine(subwayLines, lineName, upLine, downLine) { + let lineId = 0; + if (subwayLines.length !== 0) { + lineId = subwayLines[subwayLines.length - 1].id + 1; + } + + const line = new SubwayLine( + lineName, + getStationByName(upLine.value), + getStationByName(downLine.value), + lineId + ); + + showNewRow(SUBWAY_LINE_TBODY_ID, line, [ + line.lineName, + line.stations[0].stationName, + line.stations[line.stations.length - 1].stationName + ]); + + subwayLines.push(line); +} + +export default function lineManageContainer(state) { + const addLineInput = document.getElementById(LINE_TAGS.LINE_NAME_INPUT_ID); + const addLineSubmit = document.getElementById(LINE_TAGS.ADD_LINE_ID); + const upLine = document.getElementById(LINE_TAGS.SELECT_UP_LINE_ID); + const downLine = document.getElementById(LINE_TAGS.SELECT_DOWN_LINE_ID); + makeSelectOptions(upLine, state.stationArray); + makeSelectOptions(downLine, state.stationArray); + loadLines(state); + + addLineSubmit.addEventListener("click", () => { + if (upLine.value !== downLine.value) { + const lineNameInputValue = addLineInput.value.trim(); + validateLineName(state.subwayLines, lineNameInputValue, upLine, downLine, addLineInput); + } else { + alert(LINE_ALERT_MESSAGES.ERROR_UPLINE_DOWNLINE_SAME); + } + }); +} diff --git a/src/components/map-print-manage-container.js b/src/components/map-print-manage-container.js new file mode 100644 index 000000000..f29fc0652 --- /dev/null +++ b/src/components/map-print-manage-container.js @@ -0,0 +1,39 @@ +import { state } from "../index.js"; + +function printAllLineAndStations(elementToAppend, subwayLines) { + for (const line of subwayLines) { + printLineName(elementToAppend, line.lineName); + printStation(elementToAppend, line.stations); + } +} + +function printLineName(elementToAppend, lineName) { + const h2 = document.createElement("h2"); + + h2.append(lineName); + elementToAppend.append(h2); +} + +function printStation(elementToAppend, stationArray) { + for (const station of stationArray) { + const stationsInLine = document.createElement("li"); + stationsInLine.append(station.stationName); + elementToAppend.append(stationsInLine); + } +} + +export default function mapPrintManageContainer() { + const parent = document.getElementById("manage-map-print"); + const div = document.createElement("div"); + + if (state.subwayLines.length) { + printAllLineAndStations(div, state.subwayLines); + } else { + const title = `

๋…ธ์„ ์ด ์—†์Šต๋‹ˆ๋‹ค.
๋…ธ์„ ์— ์•„๋ž˜์˜ ์—ญ๋“ค์„ ๋“ฑ๋กํ•ด ์ฃผ์„ธ์š”.

`; + const titleElement = new DOMParser().parseFromString(title, "text/html").firstElementChild; + div.append(titleElement); + printStation(div, state.stationArray); + } + + parent.append(div); +} diff --git a/src/components/section-manage-container.js b/src/components/section-manage-container.js new file mode 100644 index 000000000..5392b8d63 --- /dev/null +++ b/src/components/section-manage-container.js @@ -0,0 +1,184 @@ +import { state, saveToLocalStorage } from "../index.js"; +import { LINE_ARRAY_KEY, SECTION_TAGS } from "../global/constant.js"; +import { CONFIRM_MESSAGES } from "../global/messages.js"; +import { SECTION_HTML, makeSectionHtml } from "../global/innerHtml.js"; +import { getStationByName } from "../utils/global-utils.js"; +import { + makeNewElementWithInnerHtml, + makeNewTdWithElement +} from "../utils/display/make-elements.js"; +import sectionInputValidator, { + checkZero +} from "../utils/inputs/validator/section-input-validator.js"; + +import clearInput from "../utils/inputs/clear-input.js"; + +function removeAllChild(element) { + while (element.firstChild) { + element.removeChild(element.firstChild); + } +} + +function loadEditSectionLines() { + const parentDiv = document.getElementById(SECTION_TAGS.PARENT_SECTION_ID); + + for (const line of state.subwayLines) { + const lineManageButton = makeNewElementWithInnerHtml("button", line.lineName); + lineManageButton.classList.add(SECTION_TAGS.LINE_MENU_BUTTON_CLASS); + lineManageButton.dataset.id = `manage-${line.id}`; + + parentDiv.append(lineManageButton); + } +} + +function indexOfNewElement(sectionInput, stationsInLine) { + if (sectionInput < stationsInLine.length) { + return sectionInput; + } + return stationsInLine.length; +} + +function addSectionInput(input, option, line, tableBody) { + const sectionInputValue = checkZero(input.value); + + if (sectionInputValidator(sectionInputValue, option.value, line.stations)) { + const newStation = getStationByName(option.value); + const newIndex = indexOfNewElement(sectionInputValue, line.stations); + const tr = makeOneRow(newStation, newIndex, line, tableBody); + line.stations.splice(parseInt(sectionInputValue), 0, newStation); + + updateAddedIndex(newIndex, tableBody.children); + tableBody.insertBefore(tr, tableBody.children[newIndex]); + saveToLocalStorage(LINE_ARRAY_KEY, JSON.stringify(state.subwayLines)); + clearInput(input); + } else { + clearInput(input); + } +} + +function makeSelectOptions(stationArray) { + const selectWrapper = document.createElement("select"); + selectWrapper.id = SECTION_TAGS.STATION_SELECTOR_ID; + + for (const station of stationArray) { + const option = ``; + appendHtmlToParent(selectWrapper, option); + } + return selectWrapper; +} + +function makeSectionManager(stationArray, wrapper, parent) { + const selectWrapper = makeSelectOptions(stationArray); + + appendHtmlToParent(wrapper, SECTION_HTML.SECTION_TABLE_HTML); + wrapper.append(selectWrapper); + appendHtmlToParent(wrapper, SECTION_HTML.SECTION_INPUT_HTML); + parent.append(wrapper); +} + +export default function sectionManageContainer() { + loadEditSectionLines(); + const parentDiv = document.getElementById(SECTION_TAGS.PARENT_SECTION_ID); + const lineWrapperDiv = document.createElement("div"); + lineWrapperDiv.id = "manage-wrapper"; + + for (const line of state.subwayLines) { + const manage = document.querySelector(`[data-id="manage-${line.id}"]`); + manage.addEventListener("click", () => { + removeAllChild(lineWrapperDiv); + appendHtmlToParent(lineWrapperDiv, makeSectionHtml(line.lineName)); + makeSectionManager(state.stationArray, lineWrapperDiv, parentDiv); + + const table = document.getElementById("section-table"); + const tableBody = document.getElementById("section-tbody"); + + const selectedOption = document.getElementById(SECTION_TAGS.STATION_SELECTOR_ID); + const sectionInput = document.getElementById(SECTION_TAGS.ORDER_INPUT_ID); + const addSectionInputButton = document.getElementById(SECTION_TAGS.ADD_BUTTON_ID); + + addSectionInputButton.addEventListener("click", () => { + addSectionInput(sectionInput, selectedOption, line, tableBody); + }); + + showTableItems(line, tableBody); + table.append(tableBody); + lineWrapperDiv.append(table); + }); + } +} + +// TODO - utils๋กœ ๋นผ๊ธฐ + +function appendHtmlToParent(parent, html) { + const htmlDOM = new DOMParser().parseFromString(html, "text/html").body.childNodes; + + for (const node of htmlDOM) { + parent.append(node); + } +} + +function updateDeletedIndex(currentIndex, trDatas) { + for (let index = parseInt(currentIndex.innerHTML); index < trDatas.length; index++) { + trDatas[index].firstChild.innerHTML = parseInt(trDatas[index].firstChild.innerHTML) - 1; + } +} + +function updateAddedIndex(currentIndex, trDatas) { + for (let index = parseInt(currentIndex); index < trDatas.length; index++) { + trDatas[index].firstChild.innerHTML = parseInt(trDatas[index].firstChild.innerHTML) + 1; + } +} + +function deletedStationFromLine(currentStations, deleteButton) { + return currentStations.filter( + station => parseInt(deleteButton.dataset.id) !== parseInt(station.id) + ); +} + +function deleteStationFromLine(tr, line, tableBody) { + if (confirm(CONFIRM_MESSAGES.CONFIRM_DELETE)) { + line.stations = deletedStationFromLine(line.stations, tr.childNodes[2].firstChild); + tr.remove(); + + updateDeletedIndex(tr.childNodes[0], tableBody.children); + } + saveToLocalStorage(LINE_ARRAY_KEY, JSON.stringify(state.subwayLines)); +} + +function makeTdDeleteButton(station, tr, line, tableBody) { + const tdDeleteButton = makeNewElementWithInnerHtml("button", "๋…ธ์„ ์—์„œ ์‚ญ์ œ"); + tdDeleteButton.class = SECTION_TAGS.DELETE_BUTTON_CLASS; + tdDeleteButton.dataset.id = station.id; + + tdDeleteButton.addEventListener("click", () => { + deleteStationFromLine(tr, line, tableBody); + }); + + return tdDeleteButton; +} + +function makeTrWithDataset(station, index) { + const tr = document.createElement("tr"); + tr.dataset.stationId = station.id; + tr.dataset.trId = index; + + return tr; +} + +function makeOneRow(station, index, line, tableBody) { + const tr = makeTrWithDataset(station, index); + const tdIndex = makeNewElementWithInnerHtml("td", index); + const tdStationName = makeNewElementWithInnerHtml("td", station.stationName); + const tdDeleteButton = makeTdDeleteButton(station, tr, line, tableBody); + const tdDelete = makeNewTdWithElement(tdDeleteButton); + tr.append(...[tdIndex, tdStationName, tdDelete]); + + return tr; +} + +function showTableItems(line, tableBody) { + for (const [index, station] of Object.entries(line.stations)) { + const tr = makeOneRow(station, index, line, tableBody); + tableBody.append(tr); + } +} diff --git a/src/components/station-manage-container.js b/src/components/station-manage-container.js new file mode 100644 index 000000000..6a90aaabc --- /dev/null +++ b/src/components/station-manage-container.js @@ -0,0 +1,50 @@ +import Station from "../domain/station.js"; +import inputNameValidator from "../utils/inputs/validator/name-validator.js"; +import clearInput from "../utils/inputs/clear-input.js"; +import { saveToLocalStorage } from "../index.js"; +import { showNewRow } from "../utils/display/make-elements.js"; +import { STATION_ARRAY_KEY, STATION_TAGS } from "../global/constant.js"; + +const VALIDATION_TYPE = "STATION"; + +function loadStations(state) { + for (const station of state.stationArray) { + showNewRow(STATION_TAGS.STATION_TBODY_ID, station, [station.stationName]); + } +} + +function makeStationId(stationArray) { + let stationId = 0; + + if (stationArray.length !== 0) { + stationId = stationArray[stationArray.length - 1].id + 1; + } + + return stationId; +} + +function makeNewStation(stationArray, stationNameInputValue) { + const stationId = makeStationId(stationArray); + const station = new Station(stationNameInputValue, stationId); + + showNewRow(STATION_TAGS.STATION_TBODY_ID, station, [station.stationName]); + stationArray.push(station); + saveToLocalStorage(STATION_ARRAY_KEY, JSON.stringify(stationArray)); +} + +export default function stationManageContainer(state) { + const addStationButton = document.getElementById(STATION_TAGS.ADD_BUTTON_ID); + const stationNameInput = document.getElementById(STATION_TAGS.STATION_NAME_INPUT_ID); + + loadStations(state); + addStationButton.addEventListener("click", () => { + const stationNameInputValue = stationNameInput.value.trim(); + + if (inputNameValidator(VALIDATION_TYPE, stationNameInputValue)) { + makeNewStation(state.stationArray, stationNameInputValue); + clearInput(stationNameInput); + } else { + clearInput(stationNameInput); + } + }); +} diff --git a/src/components/total-subway-manage-container.js b/src/components/total-subway-manage-container.js new file mode 100644 index 000000000..27064a85b --- /dev/null +++ b/src/components/total-subway-manage-container.js @@ -0,0 +1,47 @@ +import stationManageContainer from "./station-manage-container.js"; +import lineManageContainer from "./line-manage-container.js"; +import sectionManageContainer from "./section-manage-container.js"; +import mapPrintManageContainer from "./map-print-manage-container.js"; + +import { state } from "../index.js"; +import { menuIDs } from "../global/innerHtml.js"; + +const menus = document.querySelectorAll("#menu > button"); + +function removeAllChild(element) { + while (element.firstChild) { + element.removeChild(element.firstChild); + } +} + +function createDOM(index) { + const html = menuIDs[index].html; + const createdDOM = new DOMParser().parseFromString(html, "text/html"); + + return createdDOM.body.firstChild; +} + +function contentToShow(content, index) { + content.appendChild(createDOM(index)); + + if (index === 0) { + new stationManageContainer(state); + } else if (index === 1) { + new lineManageContainer(state); + } else if (index === 2) { + new sectionManageContainer(); + } else if (index === 3) { + new mapPrintManageContainer(); + } +} + +export default function totalSubwayManageContainer() { + const content = document.getElementById("content"); + + for (const [index, child] of menus.entries()) { + child.addEventListener("click", () => { + removeAllChild(content); + contentToShow(content, index); + }); + } +} diff --git a/src/domain/station.js b/src/domain/station.js new file mode 100644 index 000000000..1118bcb02 --- /dev/null +++ b/src/domain/station.js @@ -0,0 +1,9 @@ +export default class Station { + constructor(stationName, id) { + this.stationName = stationName; + this.id = id; + this.type = "STATION"; + } +} + +export const allStationArray = []; diff --git a/src/domain/subway-line.js b/src/domain/subway-line.js new file mode 100644 index 000000000..201922c6c --- /dev/null +++ b/src/domain/subway-line.js @@ -0,0 +1,8 @@ +export default class SubwayLine { + constructor(lineName, upLine, DownLine, id) { + this.lineName = lineName; + this.stations = [upLine, DownLine]; + this.id = id; + this.type = "LINE"; + } +} diff --git a/src/global/constant.js b/src/global/constant.js new file mode 100644 index 000000000..8b7b61d2a --- /dev/null +++ b/src/global/constant.js @@ -0,0 +1,24 @@ +export const STATION_ARRAY_KEY = "stationArray"; +export const LINE_ARRAY_KEY = "linesArray"; + +export const STATION_TAGS = { + STATION_TBODY_ID: "stations", + ADD_BUTTON_ID: "station-add-button", + STATION_NAME_INPUT_ID: "station-name-input" +}; + +export const LINE_TAGS = { + LINE_NAME_INPUT_ID: "line-name-input", + SELECT_UP_LINE_ID: "line-start-station-selector", + SELECT_DOWN_LINE_ID: "line-end-station-selector", + ADD_LINE_ID: "line-add-button" +}; + +export const SECTION_TAGS = { + PARENT_SECTION_ID: "manage-sections", + LINE_MENU_BUTTON_CLASS: "section-line-menu-button", + STATION_SELECTOR_ID: "section-station-selector", + ORDER_INPUT_ID: "section-order-input", + ADD_BUTTON_ID: "section-add-button", + DELETE_BUTTON_CLASS: "section-delete-button" +}; diff --git a/src/global/innerHtml.js b/src/global/innerHtml.js new file mode 100644 index 000000000..b84e0b16c --- /dev/null +++ b/src/global/innerHtml.js @@ -0,0 +1,108 @@ +import { SECTION_TAGS } from "../global/constant.js"; + +export const menuIDs = { + 0: { + id: "manage-station", + html: ` +
+
+

์—ญ ์ด๋ฆ„

+ + +
+ +
+

๐Ÿš‰ ์ง€ํ•˜์ฒ  ์—ญ ๋ชฉ๋ก

+ + + + + + + + +
์—ญ ์ด๋ฆ„์„ค์ •
+
+
` + }, + 1: { + id: "manage-lines", + html: ` +
+
+

๋…ธ์„  ์ด๋ฆ„

+ +
+ ์ƒํ–‰ ์ข…์  +
+ ํ•˜ํ–‰ ์ข…์  + +
+ +
+ +
+

๐Ÿš‰ ์ง€ํ•˜์ฒ  ์—ญ ๋ชฉ๋ก

+ + + + + + + + + + +
๋…ธ์„  ์ด๋ฆ„์ƒํ–‰ ์ข…์ ์—ญํ•˜ํ–‰ ์ข…์ ์—ญ์„ค์ •
+
+
+ ` + }, + 2: { + id: "manage-sections", + html: ` +
+

๊ตฌ๊ฐ„์„ ์ˆ˜์ •ํ•  ๋…ธ์„ ์„ ์„ ํƒํ•ด ์ฃผ์„ธ์š”.

+
` + }, + 3: { + id: "manage-map-print", + html: ` +
+ ` + } +}; + +export const SECTION_HTML = { + SECTION_INPUT_HTML: ` + + + `, + SECTION_TABLE_HTML: ` + + + + + + + + + +
์ˆœ์„œ์ด๋ฆ„์„ค์ •
` +}; + +export function makeSectionHtml(lineName) { + return ` +
+

${lineName} ๊ด€๋ฆฌ

+
๊ตฌ๊ฐ„ ๋“ฑ๋ก
+
`; +} diff --git a/src/global/messages.js b/src/global/messages.js new file mode 100644 index 000000000..47ec22616 --- /dev/null +++ b/src/global/messages.js @@ -0,0 +1,26 @@ +export const STATION_ALERT_MESSAGES = { + ERROR_STATION_INPUT_DUPLICATED: "์ด๋ฏธ ์กด์žฌํ•˜๋Š” ์—ญ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.", + ERROR_STATION_INPUT_LENGTH_UNDER: "2๊ธ€์ž ์ด์ƒ์˜ ์—ญ ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค!", + ERROR_STATION_INPUT_SPECIAL_CHARACTER: "์—ญ ์ด๋ฆ„์—๋Š” ํŠน์ˆ˜๋ฌธ์ž๊ฐ€ ์ž…๋ ฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค!", + ERROR_STATION_INPUT_NOT_COMPLETE: "์—ญ ์ด๋ฆ„์„ ๋ฐ”๋ฅด๊ฒŒ ์ž‘์„ฑํ•ด ์ฃผ์„ธ์š”!", + ERROR_STATION_INPUT_MULTIPLE_SPACES: "1๊ฐœ ์ดํ•˜์˜ ๊ณต๋ฐฑ๋งŒ ์ž…๋ ฅ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค!" +}; + +export const LINE_ALERT_MESSAGES = { + ERROR_LINE_INPUT_DUPLICATED: "์ด๋ฏธ ์กด์žฌํ•˜๋Š” ๋…ธ์„  ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.", + ERROR_LINE_INPUT_LENGTH_UNDER: "1๊ธ€์ž ์ด์ƒ์˜ ๋…ธ์„  ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค!", + ERROR_LINE_INPUT_SPECIAL_CHARACTER: "๋…ธ์„  ์ด๋ฆ„์—๋Š” ํŠน์ˆ˜๋ฌธ์ž๊ฐ€ ์ž…๋ ฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค!", + ERROR_LINE_INPUT_NOT_COMPLETE: "๋…ธ์„  ์ด๋ฆ„์„ ๋ฐ”๋ฅด๊ฒŒ ์ž‘์„ฑํ•ด ์ฃผ์„ธ์š”!", + ERROR_LINE_INPUT_MULTIPLE_SPACES: "1๊ฐœ ์ดํ•˜์˜ ๊ณต๋ฐฑ๋งŒ ์ž…๋ ฅ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค!", + ERROR_CANNOT_DELETE_STATION_IN_LINE: "๋…ธ์„ ์— ์กด์žฌํ•˜๋Š” ์—ญ์€ ์‚ญ์ œํ•˜์‹ค ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.", + ERROR_UPLINE_DOWNLINE_SAME: "์ƒํ–‰ ์ข…์  ์—ญ๊ณผ ํ•˜ํ–‰ ์ข…์  ์—ญ์€ ์„œ๋กœ ๋‹ฌ๋ผ์•ผ ํ•ฉ๋‹ˆ๋‹ค." +}; + +export const SECTION_ALERT_MESSAGES = { + ERROR_SECTION_INPUT_DUPLICATED: "ํ•œ ๊ตฌ๊ฐ„์— ์ค‘๋ณต๋œ ์—ญ์€ ๋“ฑ๋กํ•˜์‹ค ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.", + ERROR_SECTION_INPUT_NUMBER: "์ˆœ์„œ์—๋Š” ์ •์ˆ˜ ํ˜•ํƒœ์˜ ์ˆซ์ž๋ฅผ ์ž…๋ ฅํ•ด ์ฃผ์…”์•ผ ํ•ฉ๋‹ˆ๋‹ค." +}; + +export const CONFIRM_MESSAGES = { + CONFIRM_DELETE: "์ •๋ง๋กœ ์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?" +}; diff --git a/src/index.js b/src/index.js index e69de29bb..55561038d 100644 --- a/src/index.js +++ b/src/index.js @@ -0,0 +1,25 @@ +import totalSubwayManageContainer from "./components/total-subway-manage-container.js"; +import { STATION_ARRAY_KEY, LINE_ARRAY_KEY } from "./global/constant.js"; + +export const state = { + stationArray: [], + subwayLines: [], +}; + +export function saveToLocalStorage(key, value) { + localStorage.setItem(key, value); +} + +function init() { + if (localStorage.getItem(STATION_ARRAY_KEY)) { + state.stationArray = JSON.parse(localStorage.getItem(STATION_ARRAY_KEY)); + } + + if (localStorage.getItem(LINE_ARRAY_KEY)) { + state.subwayLines = JSON.parse(localStorage.getItem(LINE_ARRAY_KEY)); + } + + totalSubwayManageContainer(); +} + +init(); diff --git a/src/utils/display/make-elements.js b/src/utils/display/make-elements.js new file mode 100644 index 000000000..d665f3d83 --- /dev/null +++ b/src/utils/display/make-elements.js @@ -0,0 +1,116 @@ +import { state, saveToLocalStorage } from "../../index.js"; +import { LINE_ARRAY_KEY, STATION_ARRAY_KEY } from "../../global/constant.js"; +import { + CONFIRM_MESSAGES, + LINE_ALERT_MESSAGES, +} from "../../global/messages.js"; + +function confirmDelete(array, station, tr) { + const confirmDelete = confirm(CONFIRM_MESSAGES.CONFIRM_DELETE); + + if (confirmDelete) { + deleteObject(array, station, tr); + } +} + +function deleteObject(object, stationToDelete, tr) { + const deleteStation = object.filter( + (station) => station.id !== stationToDelete.id + ); + tr.remove(); + if (stationToDelete.type === "LINE") { + state.subwayLines = deleteStation; + saveToLocalStorage(LINE_ARRAY_KEY, JSON.stringify(deleteStation)); + } else if (stationToDelete.type === "STATION") { + state.stationArray = deleteStation; + saveToLocalStorage(STATION_ARRAY_KEY, JSON.stringify(deleteStation)); + } +} + +function isContainedInLine(station) { + const isContained = state.subwayLines.filter((line) => { + let contain = false; + line.stations.filter((stations) => { + if (stations.stationName === station.stationName) { + contain = true; + } + }); + return contain; + }); + + return isContained.length; +} + +function alertContainedStationInLine(station, tr) { + if (isContainedInLine(station) === 0) { + confirmDelete(state.stationArray, station, tr); + } else { + return alert(LINE_ALERT_MESSAGES.ERROR_CANNOT_DELETE_STATION_IN_LINE); + } +} + +function makeTdDeleteButton(station, tr) { + const td = document.createElement("td"); + const deleteButtonHtml = ``; + const deleteButton = new DOMParser().parseFromString( + deleteButtonHtml, + "text/html" + ).childNodes[0].lastElementChild.firstElementChild; + + deleteButton.addEventListener("click", () => { + if (station.type === "LINE") { + confirmDelete(state.subwayLines, station, tr); + } else if (station.type === "STATION") { + alertContainedStationInLine(station, tr); + } + }); + td.appendChild(deleteButton); + + return td; +} + +function makeOneRowWithDeleteButton(object, [...args]) { + const tr = document.createElement("tr"); + const deleteButton = makeTdDeleteButton(object, tr); + + for (const arg of [...args]) { + tr.appendChild(makeNewTdWithElement(arg)); + tr.id = object.id; + } + tr.appendChild(deleteButton); + + return tr; +} + +export function showNewRow(parentID, rowToShow, [...args]) { + const oneRowWithDeleteButton = makeOneRowWithDeleteButton(rowToShow, [ + ...args, + ]); + const locationOfRow = document.getElementById(parentID); + + return locationOfRow.appendChild(oneRowWithDeleteButton); +} + +export function makeSelectOptions(selectBox, optionToMakeArray) { + for (const optionValue of optionToMakeArray) { + const option = document.createElement("option"); + + option.value = optionValue.stationName; + option.text = optionValue.stationName; + selectBox.appendChild(option); + } +} + +export function makeNewElementWithInnerHtml(elementType, innerHTML) { + const element = document.createElement(elementType); + element.innerHTML = innerHTML; + + return element; +} + +export function makeNewTdWithElement(element) { + const td = document.createElement("td"); + td.append(element); + + return td; +} diff --git a/src/utils/global-utils.js b/src/utils/global-utils.js new file mode 100644 index 000000000..3cb9cf860 --- /dev/null +++ b/src/utils/global-utils.js @@ -0,0 +1,7 @@ +import { state } from "../index.js"; + +export function getStationByName(name) { + return state.stationArray.filter( + (station) => station.stationName === name + )[0]; +} diff --git a/src/utils/inputs/clear-input.js b/src/utils/inputs/clear-input.js new file mode 100644 index 000000000..d383a93a5 --- /dev/null +++ b/src/utils/inputs/clear-input.js @@ -0,0 +1,3 @@ +export default function clearInput(elementToClear) { + elementToClear.value = ""; +} diff --git a/src/utils/inputs/validator/name-validator.js b/src/utils/inputs/validator/name-validator.js new file mode 100644 index 000000000..bb144a71b --- /dev/null +++ b/src/utils/inputs/validator/name-validator.js @@ -0,0 +1,72 @@ +import { STATION_ALERT_MESSAGES, LINE_ALERT_MESSAGES } from "../../../global/messages.js"; +import { state } from "../../../index.js"; + +const checkSpecialCharacter = /[\{\}\[\]\/?.,;:|\)*~`!^\-_+โ‚ฉ\<\>@\#$%&\\\=\(\'\"]/; +const checkInvalidKorean = /[|ใ„ฑ-ใ…Ž|ใ…-ใ…ฃ]/; +const checkMultipleSpaces = /\s{2,}/; +const STATION_INPUT_MINIMUM_LENGTH = 2; +const LINE_INPUT_MINIMUM_LENGTH = 1; + +function isDuplicatedName(array, name) { + let isDuplicated = false; + + for (const object of array) { + if (object.type === "STATION" && object.stationName === name) { + isDuplicated = true; + } + if (object.type === "LINE" && object.lineName === name) { + isDuplicated = true; + } + } + + return isDuplicated; +} + +function isValidStationName(value) { + let isValid = false; + + if (isDuplicatedName(state.stationArray, value)) { + alert(STATION_ALERT_MESSAGES.ERROR_STATION_INPUT_DUPLICATED); + } else if (value.length < STATION_INPUT_MINIMUM_LENGTH) { + alert(STATION_ALERT_MESSAGES.ERROR_STATION_INPUT_LENGTH_UNDER); + } else if (checkSpecialCharacter.test(value)) { + alert(STATION_ALERT_MESSAGES.ERROR_STATION_INPUT_SPECIAL_CHARACTER); + } else if (checkInvalidKorean.test(value)) { + alert(STATION_ALERT_MESSAGES.ERROR_STATION_INPUT_NOT_COMPLETE); + } else if (checkMultipleSpaces.test(value)) { + alert(STATION_ALERT_MESSAGES.ERROR_STATION_INPUT_MULTIPLE_SPACES); + } else { + isValid = true; + } + + return isValid; +} + +function isValidLineName(value) { + let isValid = false; + + if (isDuplicatedName(state.subwayLines, value)) { + alert(LINE_ALERT_MESSAGES.ERROR_LINE_INPUT_DUPLICATED); + } else if (value.length < LINE_INPUT_MINIMUM_LENGTH) { + alert(LINE_ALERT_MESSAGES.ERROR_LINE_INPUT_LENGTH_UNDER); + } else if (checkSpecialCharacter.test(value)) { + alert(LINE_ALERT_MESSAGES.ERROR_LINE_INPUT_SPECIAL_CHARACTER); + } else if (checkInvalidKorean.test(value)) { + alert(LINE_ALERT_MESSAGES.ERROR_LINE_INPUT_NOT_COMPLETE); + } else if (checkMultipleSpaces.test(value)) { + alert(LINE_ALERT_MESSAGES.ERROR_LINE_INPUT_MULTIPLE_SPACES); + } else { + isValid = true; + } + + return isValid; +} + +export default function inputNameValidator(type, value) { + if (type === "STATION") { + return isValidStationName(value); + } + if (type === "LINE") { + return isValidLineName(value); + } +} diff --git a/src/utils/inputs/validator/section-input-validator.js b/src/utils/inputs/validator/section-input-validator.js new file mode 100644 index 000000000..b6e4bade9 --- /dev/null +++ b/src/utils/inputs/validator/section-input-validator.js @@ -0,0 +1,40 @@ +import { SECTION_ALERT_MESSAGES } from "../../../global/messages.js"; + +const checkNumber = /^\d+$/; +const checkFirstDigitZero = /^0{1,}/; + +export function isDuplicatedStationInSection(selectedStation, stationsInLine) { + let isDuplicated = false; + + for (const station of stationsInLine) { + if (station.stationName === selectedStation) { + isDuplicated = true; + } + } + + return isDuplicated; +} + +export function checkZero(inputValue) { + let deleteZeroInValue = inputValue.trim().replace(checkFirstDigitZero, ""); + + if (deleteZeroInValue === "") { + deleteZeroInValue = "0"; + } + + return deleteZeroInValue; +} + +export default function sectionInputValidator(inputValue, selectedStation, stationsInLine) { + let isValid = false; + + if (!checkNumber.test(inputValue)) { + alert(SECTION_ALERT_MESSAGES.ERROR_SECTION_INPUT_NUMBER); + } else if (isDuplicatedStationInSection(selectedStation, stationsInLine)) { + alert(SECTION_ALERT_MESSAGES.ERROR_SECTION_INPUT_DUPLICATED); + } else { + isValid = true; + } + + return isValid; +}