Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions Step4_1_mission.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# Step 4-1 Mission

---

> ### 첫 번째 Pseudo Code 설계

* show 함수의 인자 값에 따라 어떻게 처리할 것인지?

1. switch 문을 이용해서 'all', 'todo', 'doing', 'done' 을 개별적으로 처리

* todos 배열에 담아있는 객체에 어떻게 접근할지 생각하자

1. for ..of 문을 이용하여 todos 배열의 값을 접근 하자 ( 배열 안의 데이터는 객체임 )

* 객체의 'name' 을 어떻게 리턴하지?
1. 객체의 'status' 에 접근하는 코드를 설계하자
2. 객체의 'status' 에 접근을 하면 함수의 인자값과 비교한다. ('all', 'todo', 'doing', 'done')

```javascript
// pseudo 코드
function show(type) {
switch (type)
case 'all' : break;
case 'todo' : break;
case 'doing' : break;
case 'done' : break;

for (obj of todos) {
// 배열에 값에 접근..
if ('todo') // todo 의 count 증가
else if ('doing') // doing 의 count 증가
else if ('done') // done 의 count 증가
}
}
```



---

> ### 두 번째 Pseudo Code 설계 - 중복되는 코드 제거

* 첫 번째 구현에서 if 문으로 인한 중복되는 코드가 많음. 리팩토링 하자

1. if 문으로 'todo', 'doing', 'done' 의 count 증가 방식을 변경

-> status 객체를 만들어서 count 를 증가한다.

```javascript
// 변경 전 pseudo 코드
if ('todo') // todo 의 count 증가
else if ('doing') // doing 의 count 증가
else if ('done') // done 의 count 증가

// 변경 후 pseudo 코드
const status = { 'todo': 0, 'doing': 0, 'done': 0 };
status[obj['status']]++; // 'status' 속성의 값을 가져와 count 을 증가시키는 방식
```

* 코드의 중복을 제거함으로써 가독성이 좋아졌다. 당연히 결과도 잘 나온다.

---

> ### 최종 Pseudo Code

* Pseudo Code 로 표현

```javascript
function show(type) {
var status = {'todo': 0, 'doing': 0, 'done': 0};
var list = [];

for (object fo todos) {
if (object['status'] == type)
list.push(object['name']);
status[object['status']]++;
}

print('현재 상태 출력');
}
```





130 changes: 130 additions & 0 deletions Step4_2_control_command.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
const processData = require('./process_data');

// 비동기로 처리..show all..
const showCompletionStatus = () => {
setTimeout( () => { processQuery['show'](['all']); }, 1000 );
}

const checkStatusCommand = (currentStatus) => {
return ['all', 'todo', 'doing', 'done'].some( (status) => { return currentStatus === status } );
}

const checkparamArrLength = (paramArr, checkLength) => { return paramArr.length === checkLength; }

const checkIdForm = (id) => { return isNaN(id) ? false : true; }

const processQuery = {
'show': (paramArr) => {
if (!checkparamArrLength(paramArr, 1)) {
console.log(`올바른 명령어가 아닙니다.`);
return false;
}

if (!checkStatusCommand(paramArr[0])) {
console.log(`${paramArr[0]} 는 존재하지 않는 상태입니다.`);
return false;
}

let strTodoList = "";
const viewType = paramArr[0];
const statusList = processData.getStatusListByTodoList();
if (viewType === 'all') {
strTodoList = `현재 상태 : todo: ${statusList['todo'].length}개,`
+ `doing: ${statusList['doing'].length}개,`
+ `done: ${statusList['done'].length}개`;
} else {
strTodoList = `${viewType} 리스트 : 총 ${statusList[viewType].length}건:`
+ `${statusList[viewType]}`;
}

console.log(strTodoList);
return true;
},

'add': (paramArr) => {
if (!checkparamArrLength(paramArr, 2)) {
console.log(`올바른 명령어가 아닙니다.`);
return false;
}

if(paramArr[1].match(/(?<=\[\")[a-z]*(?=\"\])/i) === null) {
console.log(`tag 입력 형식이 잘못되었습니다.`);
return false;
}

const id = processData.getRandomID();
const inputName = paramArr[0];
const inputTag = paramArr[1].split('["').join('').split('"]').join('');
const inputData = {'name': inputName, 'tags': [inputTag], 'status': 'todo', 'id': id};
console.log(`${inputName} 1개가 추가되었습니다.(id : ${id})`);
processData.saveTodoList(inputData, 'add');
// 비동기로 1초 뒤에 show all
showCompletionStatus();
return true;
},

'delete': (paramArr) => {
if (!checkparamArrLength(paramArr, 1)) {
console.log(`올바른 명령어가 아닙니다.`);
return false;
}

if (!checkIdForm(paramArr[0])) {
console.log(`id 형식의 입력이 잘못되었습니다. ( ${paramArr[0]} )`);
return false;
}

const id = parseInt(paramArr[0]);
const idList = processData.getIdListByTodoList();
for(let index = 0; index < idList.length; index++) {
if (id === idList[index]) {
const [name, status] = processData.getNameAndStatusById(id);
console.log(`${name} ${status} 가 목록에서 삭제됐습니다.`);
processData.saveTodoList(index, 'delete');
// 비동기로 1초 뒤에 show all
showCompletionStatus();
return true;
}
}

console.log(`id ${id} 은(는) 존재하지 않습니다.`);
},

'update': (paramArr) => {
if (!checkparamArrLength(paramArr, 2)) {
console.log(`올바른 명령어가 아닙니다.`);
return false;
}

if (!checkIdForm(paramArr[0])) {
console.log(`id 형식의 입력이 잘못되었습니다. ( ${paramArr[0]} )`);
return false;
}

if (!checkStatusCommand(paramArr[1])) {
console.log(`${paramArr[1]} 는 존재하지 않는 상태입니다.`);
return false;
}

const id = parseInt(paramArr[0]);
const currentStatus = paramArr[1];
const idList = processData.getIdListByTodoList();
for (let index = 0; index < idList.length; index++) {
if (id === idList[index]) {
const [name] = processData.getNameAndStatusById(id);
processData.saveTodoList([index, currentStatus], 'update');
// 비동기로 3초 뒤에 결과 메시지 출력
setTimeout( () => {
console.log(`${name}가 ${currentStatus} (으)로 상태가 변경됐습니다.`);
// 비동기로 1초 뒤에 show all
showCompletionStatus();
} , 3000 );
return true;
}
}

console.log(`id ${id} 은(는) 존재하지 않습니다.`);
},
}

module.exports = processQuery;
69 changes: 69 additions & 0 deletions Step4_2_process_data.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
const fs = require('fs');
const todoList = JSON.parse(fs.readFileSync('todo.json'));

const saveTodoList = (input, command) => {
if (command === 'add') {
const objectData = input;
todoList.push(objectData);
} else if (command === 'delete') {
const index = input;
todoList.splice(index, 1);
} else if (command === 'update') {
const index = input[0];
const status = input[1];
todoList[index]['status'] = status;
}
// write..
fs.writeFileSync('todo.json', JSON.stringify(todoList));
}

const getStatusListByTodoList = () => {
const statusList = {'todo': [], 'doing': [], 'done': []};
todoList.forEach( (object) => {
const inputData = `'${object['name']},${object['id']}'`;
statusList[object['status']].push(inputData);
} );
return statusList;
}

const getNameAndStatusById = (id) => {
for (const object of todoList) {
if (object['id'] === id) {
return [object['name'], object['status']];
}
}
console.log(`id ${id} 은(는) 존재하지 않습니다.`);
}

const getIdListByTodoList = () => {
return todoList.map( (value) => { return value['id']; } );
}

// 1 ~ 9999 까지
const getRandomID = () => {
const limitLength = 10000;
const IdList = getIdListByTodoList();
if (IdList.length >= limitLength) {
console.log('꽉 차있습니다. 비워주세요');
return;
}
while (true) {
const randomID = Math.floor(Math.random() * 10000) + 1;
let isExistsRandomID = false;
for (const value of IdList) {
if (value === randomID) {
isExistsRandomID = true;
break;
}
}
if (!isExistsRandomID) return randomID;
}
}

module.exports = {
saveTodoList,
getStatusListByTodoList,
getNameAndStatusById,
getIdListByTodoList,
getRandomID,
};
30 changes: 30 additions & 0 deletions Step4_2_simulator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const controlCommand = require('./control_command');
const readLine = require('readline');

const rl = readLine.createInterface( {
input:process.stdin,
output:process.stdout,
} );

( () => {

rl.setPrompt('명령하세요 : ');
rl.prompt();
rl.on( 'line', (query) => {
if (query === 'exit') rl.close();
const splitQuery = query.replace(/\s/gi, "").split('$');
const executionCommand = splitQuery[0];
const nonCommand = splitQuery.splice(1);
const isComplete = controlCommand[executionCommand](nonCommand);

if (isComplete) {
let millisecond = 1000;
if (executionCommand === 'update') millisecond = 4010;
else if (executionCommand === 'show') millisecond = 0;
setTimeout( () => { rl.prompt(); }, millisecond );
} else {
rl.prompt();
}
} ).on( 'close', () => { process.exit(); } );

} )();
1 change: 1 addition & 0 deletions Step4_2_todo.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"name":"Algorithm 공부하기","tags":["programming","c++"],"status":"done","id":378},{"name":"페어 프로그래밍 하기","tags":["team"],"status":"done","id":7152},{"name":"git프로그램만들기","tags":["CS mission"],"status":"doing","id":3882},{"name":"주말에 DP 공부하기","tags":["hard.."],"status":"doing","id":1599},{"name":"코드리뷰받기","tags":["code\",\"javascript"],"status":"todo","id":2826},{"name":"축구하기","tags":["favorite"],"status":"doing","id":7998},{"name":"시험공부하기","tags":["hard"],"status":"todo","id":1480}]
Loading