개발 공부를 시작한게 엊그제같은데 어느덧 한달이 훌쩍 지나가버렸다.
한달동안 HTML / CSS 그리고 javascript에 대하여 배웠는데 다른 사람들보다 알고있는게 많이 없다보니, 매일 아침 8시에 일어나 저녁 12시까지 학습하다 보면 일주일이 어느새 훌쩍 지나가버린다. 나에게 개발공부는 시간도둑 간장게장같은 존재라고 할까?
그래도 내가 만들고 직접 함수도 짜보고 연구도 해보고 새롭게 접근도 해보는 이러한 일련의 과정들이 지치기보다는 오히려 재밌게 느껴진다. 그래서 개발 공부를 시작한 부분이기도 하니까
그리고 일주일에 30문제를 풀어나가던 알고리즘 스터디도 이제 0단계를 모두 풀기 전까지 매일 10문제씩 풀어보기로 스터디원들과 이야기 했다. 목표는 5월까지 2단계 절반이상을 풀어보는 것인데, 0단계를 빠르게 치고나가 이제 본격적으로 알고리즘 문제를 풀어보기 위함이다.
5주차 학습에서는 기존 자바스크립트의 메소드에서 한단계 진화한 map, reduce, filter forEach 메소드가 새롭게 튀어나왔는데 프로그래머스 문제들을 풀면서 먼저 접했던 부분이라 크게 어렵지는 않았던것 같다.
문제들을 풀다보면 for문을 무지성적으로 사용하게 될 때가 있는데 보기에도 깔끔해 보이지 않고, 너무 for문에만 의존하기만 하면 성장이 없을것 같아서 최대한 메쏘드를 활용해서 풀면서 삽질 해보는식으로 진행하고 있다.
문제풀면서 알게된 것
string.includes = 문자열 존재여부 참거짓 반환 return my_string.split('').reverse().join(''); = 문자열 뒤집기 //sort = 배열 오름차순 정렬 = sort((a, b) => a - b) = 내림차순 정렬 for in = array.length //구조분해 function solution(dot) { const [num,num2] = dot; const check = num * num2 > 0; return num > 0 ? (check ? 1 : 4) : (check ? 3 : 2); } //삼항연산자 - ? 0 : 1 = 참이면 전자 거짓이면 후자 출력 return angle < 90 ? 1 : angle === 90 ? 2 : angle < 180 ? 3 : 4; //단항연산자 - 값을 숫자로 강제 변환 return +str2.includes(str1); = 1 or 0 //스프레드 구문 활용 //배열 합치기 const arr3 = [...arr1, ...arr2]; //**reduce** - 배열의 합 구할때 사용 arr.reduce((acc, el, i) => , 0) //**map** - 배열의 단순 반복작업에는 forEach, 반복 작업을 통한 새로운 배열 생성은 map //filter, find 의 차이점 //공간, 시간복잡도 줄이는법 찾아보기
등 아직 스프레드 시트 활용이 제대로 안된다거나 메소드 사용이 익숙치 않아서 한참을 삽질하다가 결국 for문을 사용하기도 하지만 처음 접했을때
이게 뭐지? 하던 삼항 연산자나 다른 메소드들 사용에 많이 익숙해졌다.
또, 다른 스터디 팀원들이 문제에 접근하는 방식을 보면 그저 감탄만 나올때가 많지만 그로인해 많은것을 배워가는것 같다. 잘못된 풀이를 바로잡고 더 클린하게 코드를 짜는것 이런것들이 쌓이다보면 풀이에 있는 간결한 코드를 나도 만들 수 있게 되겠지..!
혼자 고민해보고 풀지 못하는 문제들도 있고, 혹시 풀이에 더 나은 코드가 있다면 그 방법으로 다시 풀어보면서 고민하는 과정들이 오래걸려도 결국 내가 이겼을 때에는 포켓몬을 잡은 지우의 마음으로 메쏘드 넌 내꺼야를 외치면서 다음 문제로 넘어가는 재미가 있다.
아 그리고 정보처리기사 에 대해 며칠동안 고민해본 결과.. 아무래도 자격증을 취득하는것이 여러모로 나을거같아서 시험을 접수하게 되었는데...
3월 6일 시험... 기초 프로젝트와 곂치는 기간동안 시험 준비를 무난하게 할 수 있을지 일단 못먹어도 고! 접수 완료 해버렸다.
이미 여러번의 기사시험 경험이 있어서 그때처럼 준비하려고 생각중인데 합격률과 악명을 들어보면 그렇게 만만하지도 않은것 같다.
이제 오는 6주차 부터는 매일 강의 + 과제 + 코테 준비 + 정처기 준비 이걸 매일 싸이클을 돌려야 하니 아침 기상을 6시로 땡겨버릴까 생각이 들기도 한다. 거의 취업준비의 트라이애슬론 같은 기분..?
아무튼 앞으로 6주차 부터는 프론트엔드 교육과정의 첫 번째 통곡의 벽인 리액트 강의가 기다리고 있는 만큼 이제까지도 정신없이 공부만 하면서 지냈지만 앞으로는 더욱 험난한 가시밭길이 될거라 생각한다. 그래도 견디는 사람만이 승리하는 만큼 피할 수 없다면 즐길 생각이다
5주차 강의 첫번째 단위기간을 마치면서 오는 2월과 리액트 강의 또 오는 6주차도 화이팅이다!!
ps. 아 추가로 5주차 미션을 좀 더 수정해 봤는데 아무래도 중복되는 부분이 너무 많아서 마음에 들지가 않는다. HTML부터 해서 6주차에는 전체를 한번 뜯어고치는 방향으로 진행해 보아야겠다.
아래는 마음에 안드는 5주차 미션 결과물
const emailInput = document.querySelector('#email');
const passInput = document.querySelector('#pass');
const passCheckInput = document.querySelector('#passCheck')
const signForm = document.querySelector('.signup');
const toggle = document.querySelector('.fa-solid');
//이메일 유효성 검사
function validateEmail(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
//비밀번호 유효성 검사
function validatePass (password) {
const passwordRegex = /^(?=.*[A-Za-z])(?=.*\d).{8,}$/;
return passwordRegex.test(password);
}
//에러 메세지 함수
function errorMessage (input, message) {
//에러메세지 중복 삭제
const err = document.createElement('p');
err.classList.add('errorMessage');
err.style.color = '#FF5B56';
err.textContent = message;
input.style.borderColor = '#FF5B56';
if (input === emailInput) {
if (input.parentElement.querySelector('.errorMessage')) {
input.parentElement.querySelector('.errorMessage').remove();
}
input.parentElement.appendChild(err);
} else if (input === passInput || input === passCheckInput) {
if (input.parentElement.parentElement.querySelector('.errorMessage')) {
input.parentElement.parentElement.querySelector('.errorMessage').remove();
}
input.parentElement.parentElement.appendChild(err);
}
}
//이메일 에러메세지 출력
function emailErrorMessage (e) {
//에러메세지 - 값이 없을 경우
if (emailInput.value.trim() === '') {
errorMessage(emailInput, '이메일을 입력해주세요.');
}
//에러메세지 - 형식에 맞지 않을 경우
else if (!validateEmail(emailInput.value)) {
errorMessage(emailInput, '올바른 이메일 주소가 아닙니다.');
}
//에러메세지 - 중복값
else if (emailInput.value === 'test@codeit.com') {
errorMessage(emailInput, '이미 사용 중인 이메일입니다.');
}
//올바른 값으로 수정
else if (validateEmail(emailInput.value)) {
if (emailInput.parentElement.querySelector('.errorMessage')) {
emailInput.parentElement.querySelector('.errorMessage').remove();
emailInput.style.borderColor = '#CCD5E3';
}
}
}
//비밀번호 에러메세지 출력
function passErrorMessage (e) {
//에러메세지 - 값이 없을 경우
if (passInput.value.trim() === '') {
errorMessage(passInput, '비밀번호를 입력해주세요.');
}
//에러메세지 - 형식에 맞지 않을 경우
else if (!validatePass(passInput.value)) {
errorMessage(passInput, '비밀번호는 영문, 숫자 조합 8자 이상 입력해 주세요.');
}
//올바른 값으로 수정
else if (validatePass(passInput.value)) {
if (passInput.parentElement.parentElement.querySelector('.errorMessage')) {
passInput.parentElement.parentElement.querySelector('.errorMessage').remove();
passInput.style.borderColor = '#CCD5E3';
}
}
}
//비밀번호 확인 에러메세지
function passCheckErrorMessage (e) {
//에러메세지 - 값이 다를 경우
if (passInput.value !== passCheckInput.value) {
errorMessage(passCheckInput, '비밀번호가 일치하지 않습니다.');
} else {
if (passCheckInput.parentElement.parentElement.querySelector('.errorMessage')) {
passCheckInput.parentElement.parentElement.querySelector('.errorMessage').remove();
passCheckInput.style.borderColor = '#CCD5E3';
}
}
}
//로그인 시도
function submitForm (e) {
//현재페이지에서 테스트
e.preventDefault();
if (emailInput.value === 'test@codeit.com' && passInput.value === 'codeit101') {
window.location.href = "./folder";
} else {
errorMessage(emailInput, '이메일을 확인해주세요.');
errorMessage(passInput, '비밀번호를 확인해주세요.');
errorMessage(passCheckInput, '비밀번호를 확인해주세요.')
}
}
//눈 모양 클릭
function toggleIcon (e) {
if (toggle.previousElementSibling.type === 'password') {
toggle.previousElementSibling.type = 'text';
toggle.classList.remove('fa-eye-slash');
toggle.classList.add('fa-eye');
} else {
toggle.previousElementSibling.type = 'password';
toggle.classList.remove('fa-eye');
toggle.classList.add('fa-eye-slash');
}
}
emailInput.addEventListener('focusout', emailErrorMessage);
passInput.addEventListener('focusout', passErrorMessage);
signForm.addEventListener('submit', submitForm);
passCheckInput.addEventListener('focusout', passCheckErrorMessage);
toggle.addEventListener('click', toggleIcon);
// 잘 안된거
// signin up => css 통합
// toggle icon 관련 두 아이콘에 한번에 적용하고 싶어서 querySelectorAll로 선택하면 에러가 나옴
// 로그인, 회원가입 페이지에 공통적으로 사용하는 로직이 있다면, 반복하지 않고 공통된 로직을 모듈로 분리해 사용해 주세요.