From b7453553bcaa251a1cb88e0090413437cd755e15 Mon Sep 17 00:00:00 2001 From: Head <40166539+HTMLhead@users.noreply.github.com> Date: Wed, 10 Oct 2018 15:12:47 +0900 Subject: [PATCH 1/3] =?UTF-8?q?lec3=20-=20Step2.=EB=8B=A4=EC=96=91?= =?UTF-8?q?=ED=95=9C=20=EC=B6=9C=EB=A0=A5=20=EC=A7=80=EC=9B=90=20(#48)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Lecture3 - step1. 기본기능 구현 (#40) * 스켈레톤 코드 작성 * 수많은 에러가 담긴 todo객체의 add함수 추가(id의 값을 제대로 가지지 못함, todo객체의 getStatusNum수정 필요 * 랜덤한 id값을 못가져오는 것을 수정. checkOverlap함수를 통해서 id의 값이 같지않도록 구현 * todo.add함수기능 완벽하게 구현 * todo.update함수 완성 * id를 입력받아 할일을 제거해주는 todo.remove함수 완성, 오류가많은 todo.printTask함수 완성 * todo.printTask함수 완성, tag를 확인하는 함수 제거(printTask를 통해 각 할일들의 태그가 무엇인지 확인이 가능하므로) * todo.printTagRelate 함수 완성, todo.add함수에서 버그를 발견함 * 새로운 객체 안 배열에 저장하도록 만들어 문제 해결 * remove함수를 호출했을때, saveData.task배열에서 지워지는것 뿐 아니라 saveData.idArrays배열에서도 id를 지워지게 수정 * 테스트코드를 주석처리함 들여쓰기를 다시 맞춤 * saveData객체를 없애고 그 내용을 todo객체 안으로 집어 넣음, todo.idArrays의 값은 todo.add를 호출할때마다 추가되도록 수정. * if(saveData.idArrays.indexOf(ranNum) !== -1)-> if(this.idArrays.includes(ranNum))으로 변경 * 기나긴 삼항연산자 statusNum[obj.status]++로 해결 * todo.update함수에서 바뀐 상태의 상태를 반영하지 않는 버그를 찾아내서 수정 * 함수마다 간단한 주석을 달아줌 * 주석추가 * 피드백을 위한 주석 추가 * 같은 숫자를 반복하는 것을 todo.task로부터 찾아와 sync가 완벽하게 맞도록 수정 * 쓸데없는 todo.idArrays에 쓰이는 배열과 메서드 제거 * 변수명 변경 * add나revmoe, update함수를 입력할때마다 각각 인자를 다르게 받아 다르게 출력하는 함수를 만듬 * 해야할 일들 주석으로 정리 * 만들어야 할 함수들 미리 작성 * time obj를 saveTimeObj로 이름을 변경하고 saveTimeObj에 doing일때의 시간과 done일때의 시간을 인자로 입력받아 경과된 시간을 반환해주는 getTakeTime 함수 구현 * 업데이트할 객체를 인자로 받아 id값과업데이트 될때의 시간 값을 saveTImeObj의 객체에 저장해주는 함수 구현 * todo.add함수에서 새 객체를 만들때 걸린시간 이라는 항목을 추가함 * timeobj객체를 todo안으로 집어넣어 활용하기로 결정, 수정 * doingTimeArray와 takenTimeArray가 굳이 필요할것 같이 않아서 제거, 대신 task배열내의 객체에 timeData추가. 이를 이용해 updateDoingTime메서드 완성 * updateTakeTime메서드 구현. id가 같은 task.timeData값에 걸린 시간을 계산해서 저장해줌 * showTag메서드와 그 메서드를 위한 printByTag메서드 구현. printByTag는 tag과 status를 인자로 받아 같은인자와 tag를 출력, showTag메서드는 그 값을 세번 불러서 서로다른 3가지의 status값을 모두 출력. * show메서드 구현 만약 status가 done상태일때만 시간을 출력해주도록 함 * printByTag메서드의 버그 수정(상태가done인 항목을 입력해도 걸린 시간이 나오지 않았음), show메서드의 버그 수정(상태가done이면 doing항목을 출력하라고 입력했을때 done항목도 같이 출력되었었음) * 테스트 케이스 추가 * showAll메서드 구현, bind메서드를 이용함 * 같은태그를가짐과동시에 같은상태인것의 개수를 세는 함수 getSameTagAndStatusNum함수를 만듦 * show함수를 좀더 보기좋게 수정 * showTags를 위한 getSameTagArrays와 printSameTag함수를 만듬. 태그의 모든값이 담긴 배열을 만들고, 배열의 값을 통해 같은 값을 출력하는 함수를 만듬 * 태그가 같은 할 일의 개수를 계산해주는 함수 getSameTagNum을 만듬 * 함수의 쓰임새에 따라 정렬하여 보기편하게 수정 * 테스트 케이스들을 모두 주석처리하고 id의 경우의 수를 100가지로 늘림 * 사소한 버그 수정 --- todo.js | 239 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 todo.js diff --git a/todo.js b/todo.js new file mode 100644 index 0000000..7ab76b8 --- /dev/null +++ b/todo.js @@ -0,0 +1,239 @@ +const todo = { + task: [], + + add: function (objToAdd) { + const notAddedLength = this.task.length + const newTodo = { + id: this.getRanNum(), + name: objToAdd.name, + status: 'todo', + tag: objToAdd.tag, + timeData: 0, + } + this.task.push(newTodo) + let statusNum = this.getStatusNum(this.task) + this.printChangeThing(newTodo, notAddedLength) + this.printStatusNum(statusNum) + },//해야할일과 id값을 추가해주는 함수 + + getRanNum: function () { + const ranNum = Math.floor(Math.random() * 100) + const idArrays = this.task.map(obj => obj.id) + if (idArrays.includes(ranNum)) { + return this.getRanNum() + } + return ranNum; + },//중복되지 않는 랜덤한 숫자를뽑아내는 함수 + + getStatusNum: function (accumulatedTask) { + const statusNum = { + todo: 0, + doing: 0, + done: 0 + } + accumulatedTask.forEach(obj => { + statusNum[obj.status]++ + }) + return statusNum + },//상태를 초기화 시켜주는 함수 + + printStatusNum: function (statusNum) { + console.log(`현재상태 todo : ${statusNum.todo}, doing: ${statusNum.doing}, done : ${statusNum.done}`) + },//상태를 출력해주는 함수 + + printChangeThing: function (objToPrint, beforeTaskLength, beforeTaskStatus) { + if (this.task.length > beforeTaskLength) { + console.log(`ID : ${objToPrint.id}, ${objToPrint.name} 항목이 추가되었습니다.`); + } else if (this.task.length < beforeTaskLength) { + console.log(`ID : ${objToPrint.id}, ${objToPrint.name} 삭제 완료`) + } else { + console.log(`ID: ${objToPrint.id}, ${objToPrint.name} 항목이 ${beforeTaskStatus} => ${objToPrint.status} 상태로 업데이트 되었습니다.`) + } + },//할일이 추가되거나 제거되거나 업데이트 될 때 적합한 내용을 출력해 주는 함수 + + update: function (objToUpdate) { + let beforeTaskStatus = [] + if (objToUpdate.nextstatus === 'doing') { + this.updateDoingTime(objToUpdate) + } else if (objToUpdate.nextstatus === 'done') { + this.updateTakeTime(objToUpdate) + } + this.task = this.task.map(taskObj => { + if (objToUpdate.id === taskObj.id) { + beforeTaskStatus.push(taskObj.status) + taskObj.status = objToUpdate.nextstatus.toLowerCase(); + return taskObj + } + return taskObj + }) + const changedTask = this.task.filter(taskObj => { + if (objToUpdate.id === taskObj.id) { + return taskObj + } + }) + let statusNum = this.getStatusNum(this.task) + this.printChangeThing(changedTask[0], this.task.length, beforeTaskStatus[0]) + this.printStatusNum(statusNum) + },//상태 업데이트 함수//주어진 정보의 시간을 넣을 수 있도록 수정 요망 + + updateDoingTime: function (objToUpdate) { + this.task.forEach(taskObj => { + if (taskObj.id === objToUpdate.id) { + taskObj.timeData = Date.now(); + } + }) + },//업데이트할 객체를 인자로 받아 task내의 timeData값을 변경. + + updateTakeTime: function (objToUpdate) { + this.task.forEach(taskObj => { + if (taskObj.id === objToUpdate.id) { + taskObj.timeData = this.getTakeTime(taskObj.timeData, Date.now()) + } + }) + },//업데이트할 객체를 인자로 받아 task내의 timeData의 값을 걸린 시간으로 변경. + + getTakeTime: function (doingTime, currentTime) { + let takenTime = '' + let takenMsecTime = currentTime - doingTime + const msecPerMinute = 1000 * 60, msecPerHour = msecPerMinute * 60, msecPerDay = msecPerHour * 24 + const takenDays = Math.floor(takenMsecTime / msecPerDay) + takenMsecTime = takenMsecTime - takenDays * msecPerDay + const takenHours = Math.floor(takenMsecTime / msecPerHour) + takenMsecTime = takenMsecTime - takenHours * msecPerHour + const takenMinutes = Math.floor(takenMsecTime / msecPerMinute) + takenMsecTime = takenMsecTime - takenMinutes * msecPerMinute + takenTime += takenDays + '일, ' + takenHours + '시간, ' + takenMinutes + '분' + return takenTime; + },//걸린 시간을 계산해주는 함수 + + remove: function (objToRemove) { + const notRemovedLength = todo.task.length + let filteredTask = this.task.filter(taskObj => taskObj.id === objToRemove.id) + let removedTask = this.task.filter(taskObj => taskObj.id !== objToRemove.id) + this.task = removedTask + this.printChangeThing(filteredTask[0], notRemovedLength) + },//할 일과 id값을 제거해주는 함수 + + show: function (status) { + console.log(`[${status} 상태인 할 일들]`) + this.task.forEach(taskObj => { + if (status === 'done' && taskObj.status === 'done') { + console.log(`ID : ${taskObj.id}, ${taskObj.name}, [${taskObj.tag}], ${taskObj.timeData}`) + } else if (taskObj.status === status) { + console.log(`ID : ${taskObj.id}, ${taskObj.name}, [${taskObj.tag}]`) + } + }) + },//인자로 입력받은 상태의 정보들을 출력해주는 함수 + + showTag: function (tag) { + const todoNum = this.getSameTagAndStatusNum(tag, 'todo') + console.log(`[todo, 총 ${todoNum}개]`) + this.printByTag(tag, 'todo'); + const doingNum = this.getSameTagAndStatusNum(tag, 'doing') + console.log(`[doing, 총 ${doingNum}개]`) + this.printByTag(tag, 'doing'); + const doneNum = this.getSameTagAndStatusNum(tag, 'done') + console.log(`[done, 총 ${doneNum}개]`) + this.printByTag(tag, 'done'); + },//수정필요, 여기에 showTags기능까지 넣어볼 것.//함수는 한가지의 일만 하는게 맞는듯 + + printByTag: function (tag, status) { + this.task.forEach(taskObj => { + if (taskObj.tag === tag && taskObj.status === status) { + if (status === 'done') { + console.log(`ID : ${taskObj.id}, ${taskObj.name}, ${taskObj.timeData}`) + return; + } + console.log(`ID : ${taskObj.id}, ${taskObj.name}`) + } + }) + },//tag의 값과 상태의 값을 인자로 받아 출력해주는 함수 + + getSameTagAndStatusNum: function (tag, status) { + let sameTagAndStatusNum = 0 + this.task.forEach(taskObj => { + if (taskObj.tag === tag && taskObj.status === status) { + sameTagAndStatusNum++ + } + }) + return sameTagAndStatusNum + },//태그와 상태가 같은 것들의 개수를 세어주는 함수 + + showTags: function () { + const taggedTask = this.task.filter(obj => { + return obj.tag !== undefined + }) + const sameTagArrays = this.getTagArrays(taggedTask); + sameTagArrays.forEach(tag => { + const sameTagNum = this.getSameTagNum(tag, taggedTask) + this.printSameTag(tag, taggedTask) + }) + },//태그에 따라 모든 값을 출력해주는 함수 + + getTagArrays: function(taggedTask) { + const sameTagArrays = []; + taggedTask.forEach(taggedTaskObj => { + if(!sameTagArrays.includes(taggedTaskObj.tag)) { + sameTagArrays.push(taggedTaskObj.tag) + } + }) + return sameTagArrays + },//현재 task배열 내에있는 모든 tag값들을 중복 없이 따로 모아놓는 배열을 만드는 함수 + + printSameTag: function(tag, taggedTask) { + console.log(`${tag}, 총 ${sameTagNum}개`) + taggedTask.forEach(taggedTaskObj => { + if(tag === taggedTaskObj.tag) { + console.log(`ID : ${taggedTaskObj.id}, ${taggedTaskObj.name}, [${taggedTaskObj.status}]`) + } + }) + },//tag의 값에 따라서 출력해주는 함수 + + getSameTagNum: function(tag, taggedTask) { + sameTagNum = 0 + taggedTask.forEach(taggedTaskObj => { + if(tag === taggedTaskObj.tag) { + sameTagNum++ + } + }) + return sameTagNum + },//같은 태그의 개수를 세어주는 함수 + + showAll: function () { + const statusNum = this.getStatusNum(this.task) + console.log(`총 ${this.task.length}개의 리스트를 가져왔습니다. + 지금부터 2초뒤에 todo내역을 출력합니다........`) + setTimeout(function () { + console.log(`[todo, 총${statusNum.todo}개]`); + this.show('todo') + console.log(`지금부터 3초뒤에 doing내역을 출력합니다.......`) + setTimeout(function () { + debugger; + console.log(`[doing, 총${statusNum.doing}개]`) + this.show('doing') + console.log(`지금부터 2초뒤에 done내역을 출력합니다........`) + setTimeout(function () { + console.log(`[done, 총${statusNum.done}개]`) + this.show('done') + }.bind(todo), 2000) + }.bind(todo), 3000) + }.bind(todo), 2000) + },//입력된 정보들의 상태에 따라 시간차로 출력해주는 함수 +}//해야 할일 객체 +// 테스트 + +todo.add({ name: '자바스크립트', tag: 'programming'}); +todo.add({ name: 'C++', tag: 'programming' }); +todo.add({ name: '회식', tag: '회사' }); +todo.add({ name: '노래연습', tag: '자기개발' }); +todo.add({ name: '과장님업무', tag: '회사' }) + +// todo.update({ id: 3, nextstatus: 'doing' }) +// todo.update({ id: 3, nextstatus: 'done' }) +// todo.update({ id: 2, nextstatus: 'done' }) +todo.showTag('programming') +todo.showTags(); +todo.show('todo') +todo.showAll(); + + From 82e620d86d7ec4d5fabd60f10d6cd3e5c316cfd3 Mon Sep 17 00:00:00 2001 From: jisuyoun Date: Thu, 18 Oct 2018 16:45:56 +0900 Subject: [PATCH 2/3] delete. code --- todo.js | 239 -------------------------------------------------------- 1 file changed, 239 deletions(-) delete mode 100644 todo.js diff --git a/todo.js b/todo.js deleted file mode 100644 index 7ab76b8..0000000 --- a/todo.js +++ /dev/null @@ -1,239 +0,0 @@ -const todo = { - task: [], - - add: function (objToAdd) { - const notAddedLength = this.task.length - const newTodo = { - id: this.getRanNum(), - name: objToAdd.name, - status: 'todo', - tag: objToAdd.tag, - timeData: 0, - } - this.task.push(newTodo) - let statusNum = this.getStatusNum(this.task) - this.printChangeThing(newTodo, notAddedLength) - this.printStatusNum(statusNum) - },//해야할일과 id값을 추가해주는 함수 - - getRanNum: function () { - const ranNum = Math.floor(Math.random() * 100) - const idArrays = this.task.map(obj => obj.id) - if (idArrays.includes(ranNum)) { - return this.getRanNum() - } - return ranNum; - },//중복되지 않는 랜덤한 숫자를뽑아내는 함수 - - getStatusNum: function (accumulatedTask) { - const statusNum = { - todo: 0, - doing: 0, - done: 0 - } - accumulatedTask.forEach(obj => { - statusNum[obj.status]++ - }) - return statusNum - },//상태를 초기화 시켜주는 함수 - - printStatusNum: function (statusNum) { - console.log(`현재상태 todo : ${statusNum.todo}, doing: ${statusNum.doing}, done : ${statusNum.done}`) - },//상태를 출력해주는 함수 - - printChangeThing: function (objToPrint, beforeTaskLength, beforeTaskStatus) { - if (this.task.length > beforeTaskLength) { - console.log(`ID : ${objToPrint.id}, ${objToPrint.name} 항목이 추가되었습니다.`); - } else if (this.task.length < beforeTaskLength) { - console.log(`ID : ${objToPrint.id}, ${objToPrint.name} 삭제 완료`) - } else { - console.log(`ID: ${objToPrint.id}, ${objToPrint.name} 항목이 ${beforeTaskStatus} => ${objToPrint.status} 상태로 업데이트 되었습니다.`) - } - },//할일이 추가되거나 제거되거나 업데이트 될 때 적합한 내용을 출력해 주는 함수 - - update: function (objToUpdate) { - let beforeTaskStatus = [] - if (objToUpdate.nextstatus === 'doing') { - this.updateDoingTime(objToUpdate) - } else if (objToUpdate.nextstatus === 'done') { - this.updateTakeTime(objToUpdate) - } - this.task = this.task.map(taskObj => { - if (objToUpdate.id === taskObj.id) { - beforeTaskStatus.push(taskObj.status) - taskObj.status = objToUpdate.nextstatus.toLowerCase(); - return taskObj - } - return taskObj - }) - const changedTask = this.task.filter(taskObj => { - if (objToUpdate.id === taskObj.id) { - return taskObj - } - }) - let statusNum = this.getStatusNum(this.task) - this.printChangeThing(changedTask[0], this.task.length, beforeTaskStatus[0]) - this.printStatusNum(statusNum) - },//상태 업데이트 함수//주어진 정보의 시간을 넣을 수 있도록 수정 요망 - - updateDoingTime: function (objToUpdate) { - this.task.forEach(taskObj => { - if (taskObj.id === objToUpdate.id) { - taskObj.timeData = Date.now(); - } - }) - },//업데이트할 객체를 인자로 받아 task내의 timeData값을 변경. - - updateTakeTime: function (objToUpdate) { - this.task.forEach(taskObj => { - if (taskObj.id === objToUpdate.id) { - taskObj.timeData = this.getTakeTime(taskObj.timeData, Date.now()) - } - }) - },//업데이트할 객체를 인자로 받아 task내의 timeData의 값을 걸린 시간으로 변경. - - getTakeTime: function (doingTime, currentTime) { - let takenTime = '' - let takenMsecTime = currentTime - doingTime - const msecPerMinute = 1000 * 60, msecPerHour = msecPerMinute * 60, msecPerDay = msecPerHour * 24 - const takenDays = Math.floor(takenMsecTime / msecPerDay) - takenMsecTime = takenMsecTime - takenDays * msecPerDay - const takenHours = Math.floor(takenMsecTime / msecPerHour) - takenMsecTime = takenMsecTime - takenHours * msecPerHour - const takenMinutes = Math.floor(takenMsecTime / msecPerMinute) - takenMsecTime = takenMsecTime - takenMinutes * msecPerMinute - takenTime += takenDays + '일, ' + takenHours + '시간, ' + takenMinutes + '분' - return takenTime; - },//걸린 시간을 계산해주는 함수 - - remove: function (objToRemove) { - const notRemovedLength = todo.task.length - let filteredTask = this.task.filter(taskObj => taskObj.id === objToRemove.id) - let removedTask = this.task.filter(taskObj => taskObj.id !== objToRemove.id) - this.task = removedTask - this.printChangeThing(filteredTask[0], notRemovedLength) - },//할 일과 id값을 제거해주는 함수 - - show: function (status) { - console.log(`[${status} 상태인 할 일들]`) - this.task.forEach(taskObj => { - if (status === 'done' && taskObj.status === 'done') { - console.log(`ID : ${taskObj.id}, ${taskObj.name}, [${taskObj.tag}], ${taskObj.timeData}`) - } else if (taskObj.status === status) { - console.log(`ID : ${taskObj.id}, ${taskObj.name}, [${taskObj.tag}]`) - } - }) - },//인자로 입력받은 상태의 정보들을 출력해주는 함수 - - showTag: function (tag) { - const todoNum = this.getSameTagAndStatusNum(tag, 'todo') - console.log(`[todo, 총 ${todoNum}개]`) - this.printByTag(tag, 'todo'); - const doingNum = this.getSameTagAndStatusNum(tag, 'doing') - console.log(`[doing, 총 ${doingNum}개]`) - this.printByTag(tag, 'doing'); - const doneNum = this.getSameTagAndStatusNum(tag, 'done') - console.log(`[done, 총 ${doneNum}개]`) - this.printByTag(tag, 'done'); - },//수정필요, 여기에 showTags기능까지 넣어볼 것.//함수는 한가지의 일만 하는게 맞는듯 - - printByTag: function (tag, status) { - this.task.forEach(taskObj => { - if (taskObj.tag === tag && taskObj.status === status) { - if (status === 'done') { - console.log(`ID : ${taskObj.id}, ${taskObj.name}, ${taskObj.timeData}`) - return; - } - console.log(`ID : ${taskObj.id}, ${taskObj.name}`) - } - }) - },//tag의 값과 상태의 값을 인자로 받아 출력해주는 함수 - - getSameTagAndStatusNum: function (tag, status) { - let sameTagAndStatusNum = 0 - this.task.forEach(taskObj => { - if (taskObj.tag === tag && taskObj.status === status) { - sameTagAndStatusNum++ - } - }) - return sameTagAndStatusNum - },//태그와 상태가 같은 것들의 개수를 세어주는 함수 - - showTags: function () { - const taggedTask = this.task.filter(obj => { - return obj.tag !== undefined - }) - const sameTagArrays = this.getTagArrays(taggedTask); - sameTagArrays.forEach(tag => { - const sameTagNum = this.getSameTagNum(tag, taggedTask) - this.printSameTag(tag, taggedTask) - }) - },//태그에 따라 모든 값을 출력해주는 함수 - - getTagArrays: function(taggedTask) { - const sameTagArrays = []; - taggedTask.forEach(taggedTaskObj => { - if(!sameTagArrays.includes(taggedTaskObj.tag)) { - sameTagArrays.push(taggedTaskObj.tag) - } - }) - return sameTagArrays - },//현재 task배열 내에있는 모든 tag값들을 중복 없이 따로 모아놓는 배열을 만드는 함수 - - printSameTag: function(tag, taggedTask) { - console.log(`${tag}, 총 ${sameTagNum}개`) - taggedTask.forEach(taggedTaskObj => { - if(tag === taggedTaskObj.tag) { - console.log(`ID : ${taggedTaskObj.id}, ${taggedTaskObj.name}, [${taggedTaskObj.status}]`) - } - }) - },//tag의 값에 따라서 출력해주는 함수 - - getSameTagNum: function(tag, taggedTask) { - sameTagNum = 0 - taggedTask.forEach(taggedTaskObj => { - if(tag === taggedTaskObj.tag) { - sameTagNum++ - } - }) - return sameTagNum - },//같은 태그의 개수를 세어주는 함수 - - showAll: function () { - const statusNum = this.getStatusNum(this.task) - console.log(`총 ${this.task.length}개의 리스트를 가져왔습니다. - 지금부터 2초뒤에 todo내역을 출력합니다........`) - setTimeout(function () { - console.log(`[todo, 총${statusNum.todo}개]`); - this.show('todo') - console.log(`지금부터 3초뒤에 doing내역을 출력합니다.......`) - setTimeout(function () { - debugger; - console.log(`[doing, 총${statusNum.doing}개]`) - this.show('doing') - console.log(`지금부터 2초뒤에 done내역을 출력합니다........`) - setTimeout(function () { - console.log(`[done, 총${statusNum.done}개]`) - this.show('done') - }.bind(todo), 2000) - }.bind(todo), 3000) - }.bind(todo), 2000) - },//입력된 정보들의 상태에 따라 시간차로 출력해주는 함수 -}//해야 할일 객체 -// 테스트 - -todo.add({ name: '자바스크립트', tag: 'programming'}); -todo.add({ name: 'C++', tag: 'programming' }); -todo.add({ name: '회식', tag: '회사' }); -todo.add({ name: '노래연습', tag: '자기개발' }); -todo.add({ name: '과장님업무', tag: '회사' }) - -// todo.update({ id: 3, nextstatus: 'doing' }) -// todo.update({ id: 3, nextstatus: 'done' }) -// todo.update({ id: 2, nextstatus: 'done' }) -todo.showTag('programming') -todo.showTags(); -todo.show('todo') -todo.showAll(); - - From 1c1e0611468e29d5814feabd05a19b4abd3f71f8 Mon Sep 17 00:00:00 2001 From: Ruby Lee <48516485+ruby413@users.noreply.github.com> Date: Tue, 7 May 2019 16:46:02 +0900 Subject: [PATCH 3/3] Koon&Ruby step5-3 (#135) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * step5-3 redo, undo, class 변경 * 파일수정을 위한 삭제 * 1. class 의 컨스트럭터에 맞춰 수정했습니다. 2. 모듈 export 시 불필요한 object는 수정했습니다. 3. 소스 중 불필요한 부분을 수정했습니다. --- README.md | 2 - oop/errorMsg.js | 6 + oop/main.js | 291 +++++++++++++++++++++++++++++++++++++++++++++++ oop/todoPrint.js | 26 +++++ 4 files changed, 323 insertions(+), 2 deletions(-) delete mode 100644 README.md create mode 100644 oop/errorMsg.js create mode 100644 oop/main.js create mode 100644 oop/todoPrint.js diff --git a/README.md b/README.md deleted file mode 100644 index d86263b..0000000 --- a/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# todo -레벨2 diff --git a/oop/errorMsg.js b/oop/errorMsg.js new file mode 100644 index 0000000..782d421 --- /dev/null +++ b/oop/errorMsg.js @@ -0,0 +1,6 @@ +module.exports = { + 'syntaxError' : "문법적으로 유효하지 않은 입력값입니다.", + 'unknownIDError' : "ID 사용이 잘못되었습니다.", + 'unknownID_duplicatedError' : "ID혹은 Status가 잘못되었습니다.", + 'ELSE_ERROR' : "알 수 없는 오류가 발생했습니다." +} \ No newline at end of file diff --git a/oop/main.js b/oop/main.js new file mode 100644 index 0000000..b14c491 --- /dev/null +++ b/oop/main.js @@ -0,0 +1,291 @@ +const readline = require('readline'); +const errorMsg = require('./errorMsg.js'); +const todoPrint = require('./todoPrint.js'); + + +const Print = new todoPrint.ShowPrint(); + + +let r = readline.createInterface({ + input:process.stdin, + output:process.stdout +}); + + +const showAllTimer = (input) => { + setTimeout(()=>{todoCommonMethod.todoCount()}, input); + setTimeout(()=>{r.prompt()} , input+1000) +} + +const ErrorCheck = class { + syntaxError(input) { + let firstWord = input.match(/\w+/); + let seperator = input.match(/\$/g); + let zeroSeperator = (firstWord[0] ==="undo" || firstWord[0] === "redo"); + let oneSeperator = ((firstWord[0] === "delete" || firstWord[0] === "show") && (seperator.length===1)); + let twoSeperator = ((firstWord[0] === "add" || firstWord[0] === "update") && (seperator.length===2)); + if(zeroSeperator || oneSeperator || twoSeperator){ + return true; + }else if (seperator === null){ + return false; + }else { + return false; + } + + } + unknownIDError(ID) { + if(ID === NaN) { + return false; + } + return !(todoModel.todoList.filter(v => v["id"] === ID).length === 0) ? true : false; + } + duplicatedStatusError(ID, status) { + return !(todoModel.todoList.filter(v => v["id"] === ID)[0]["status"] === status) ? true : false; + } +} +const Error = new ErrorCheck(); + +const TodoCommonMethod = class { + todoCount() { + let todo = todoModel.todoList.filter(v => v.status === 'todo').length; + let doing = todoModel.todoList.filter(v => v.status === 'doing').length; + let done = todoModel.todoList.filter(v => v.status === 'done').length; + + Print.printShowAll(todo,doing,done); + } + + showElse(input) { + let temp = todoModel.todoList.filter(v => v.status === input).map((obj)=>{ return ` '${obj.name}, ${obj.id}번'`}) + Print.printShowElse(temp.length, temp); + } + + makingID(){ + return Math.floor(Math.random() * 10000); + } + + findDataIdObj(input){ + let target = todoModel.todoList.filter(v => v["id"] === input); + let targetName = target[0].name; + let targetIdx = todoModel.todoList.indexOf(target[0]); + return [targetIdx, targetName]; + } +} + +const todoCommonMethod = new TodoCommonMethod(); + + +const HistoryController = class { + constructor() { + this.undoHistory = []; + this.redoHistory = []; + this.HistoryForm = function (model, name, id, status, tag){ + this.model = model; + this.name = name; + this.id = id; + this.status = status; + this.tag = tag; + } + } + + historyLengthCheck(form){ + if(this.undoHistory.length < 3) { + this.undoHistory.push(form); + } else { + this.undoHistory.shift(); + this.undoHistory.push(form); + } + } + + makeAddHistory(model, name, id, status, tag ){ + let historyForm = new this.HistoryForm(model, name, id, status, tag); + this.historyLengthCheck(historyForm) + } + + makeElseHistory(model, idx) { + let todoListData = todoModel.todoList[idx] + let [name, tag, status, id] = [todoListData['name'], todoListData['tag'], todoListData['status'], todoListData['id']]; + let historyForm = new this.HistoryForm(model, name, id, status, tag ); + + this.historyLengthCheck(historyForm) + } + + undoModel(model) { + let target = this.undoHistory[this.undoHistory.length-1]; + let [name, tag, status, id] = [target['name'], target['tag'], target['status'], target['id']]; + + switch(model){ + case 'add' : + this.undoAdd(id); + break; + + case 'update' : + this.undoUpdate(id, status); + break; + + case 'delete' : + this.undoDelete(id, name, tag, status) + break; + } + } + + undoAdd(id) { + todoModel.delete(id) + this.undoHistory.pop(); + } + undoUpdate(id, status) { + todoModel.update(id, status) + this.undoHistory.pop(); + } + undoDelete(id, name, tag, status) { + let newTodoList = new todoModel.TodoForm(name, tag[0], status, id); + todoModel.todoList.push(newTodoList); + Print.printAdd(name,id); + showAllTimer(1000); + } + + dataInput(input) { + this.redoHistory.push(input); + } + makeUpdateHistory(status) { + if(this.undoHistory[0] === undefined){ + return; + } + this.undoHistory[this.undoHistory.length-1]['prev_status'] = status; + } + redoModel(model) { + let target = this.redoHistory[this.redoHistory.length-1]; + let [name, tag, status, id, prev_status] = [target['name'], target['tag'], target['status'], target['id'], target['prev_status']]; + + switch (model) { + case 'add' : + let newTodoList = new todoModel.TodoForm(name, tag[0], status, id); + todoModel.todoList.push(newTodoList); + Print.printAdd(name,id); + showAllTimer(1000); + this.undoHistory.pop(); + break; + case 'update' : + todoModel.update(id, prev_status); + this.undoHistory.pop(); + break; + case 'delete' : + todoModel.delete(id, name, tag, status); + this.undoHistory.pop(); + break; + } + } +} +const historyController = new HistoryController(); + + +const TodoModel = class{ + + constructor() { + this.todoList = [{ name: 'sfd', tag: [ 'sdf' ], status: 'todo', id: 2614 } ]; + this.TodoForm = function (name, tag, status, id) { + this.name = name; + this.tag = [tag]; + this.status = status; + this.id = id; + } + } + show(input) { + let status = input[0]; + status === 'all' ? todoCommonMethod.todoCount() : todoCommonMethod.showElse(status); + } + add(input) { + let [name, tag] = input; + let id = todoCommonMethod.makingID(); + let newTodoList = new this.TodoForm(name, tag, 'todo', id); + historyController.makeAddHistory("add", name, id, 'todo', tag ); + + this.todoList.push(newTodoList); + + Print.printAdd(name,id); + showAllTimer(1000); + } + delete(id) { + let [targetIdx, targetName] = todoCommonMethod.findDataIdObj(id) + historyController.makeElseHistory('delete', targetIdx); + this.todoList.splice(targetIdx,1); + + Print.printDelete(targetName); + showAllTimer(1000); + } + update(id, status) { + let [targetIdx, targetName] = todoCommonMethod.findDataIdObj(id) + historyController.makeElseHistory('update', targetIdx); + this.todoList[targetIdx].status = status; + historyController.makeUpdateHistory(status); + + setTimeout(()=>{Print.printUpdate(targetName, status)}, 1000); + showAllTimer(4000); + } + +} + + +const todoModel = new TodoModel(); + +const arr = "update$2614$doing" + +const todoMain = (answer) => { + if(!Error.syntaxError(answer)) { + Print.printError(errorMsg.syntaxError); + return true; + } + + let tempArr = answer.match(/\w+/g); + let action = tempArr.shift(0); + + if(action === "add") { + todoModel.add(tempArr); + + } else if(action === "delete") { + tempArr[0] = Number(tempArr[0]) + let ID = tempArr[0] + !Error.unknownIDError(ID) ? Print.printError(errorMsg.unknownIDError) : todoModel.delete(ID); + + } else if(action === "update") { + tempArr[0] = Number(tempArr[0]) + let ID = tempArr[0] + let status = tempArr[1] + !Error.unknownIDError(ID) || !Error.duplicatedStatusError(ID,status) ? Print.printError(errorMsg.unknownID_duplicatedError) : todoModel.update(ID, status) + + } else if(action === "show") { + todoModel.show(tempArr); + + } else if(action === 'undo') { + let data = historyController.undoHistory; + let dataLength = data.length-1; + historyController.undoModel(data[dataLength]['model']); + historyController.redoHistory.push(data[dataLength]); + data.pop(); + + } else if(action === 'redo') { + let data = historyController.redoHistory; + let dataLength = data.length-1; + historyController.redoModel(data[dataLength]['model']); + data.pop(); + + } else { + Print.printError(errorMsg.ELSE_ERROR); + } + + + console.log(todoModel.todoList); + console.log(historyController.undoHistory); + console.log(historyController.redoHistory); + +} + + + + r.setPrompt('명령하세요 : '); + r.prompt(); + r.on('line', (answer) => { + + todoMain(answer); + + }) + diff --git a/oop/todoPrint.js b/oop/todoPrint.js new file mode 100644 index 0000000..6011c0b --- /dev/null +++ b/oop/todoPrint.js @@ -0,0 +1,26 @@ +const ShowPrint = class { + printShowAll(todo, doing, done){ + console.log(`현재 상태 : todo: ${todo}개, doing: ${doing}개, done: ${done}개`) + } + printShowElse(temp_length, temp){ + console.log(`${this.value1}리스트 : 총 ${temp_length}건 : ${temp}`); + } + printAdd(name,id){ + console.log(`${name} 1개가 추가됐습니다. (id : ${id})`); + } + printUpdate(targetName, status){ + console.log(`${targetName} 가 ${status}상태로 변경되었습니다.`); + } + printDelete(targetName){ + console.log(`${targetName} 가 todo에서 삭제되었습니다.`) + } + printError(errorKey){ + console.log(errorKey) + } +} + + + +module.exports = { + ShowPrint +}