2024.01.11 TIL - 알고리즘, 트러블슈팅

Innes·2024년 1월 11일
0

TIL(Today I Learned)

목록 보기
36/147
post-thumbnail

📘 오늘의 공부

  • 알고리즘 Code Kata
  • 팀프로젝트 - 카드 정렬
  • 트러블슈팅

📝 알고리즘

  • 문제 1. 약수의 합

    문제 설명
    정수 n을 입력받아 n의 약수를 모두 더한 값을 리턴하는 함수, solution을 완성해주세요.
    제한 사항
    n은 0 이상 3000이하인 정수입니다.

  • 풀이 : for문으로 약수구해서 더하기

function solution(n) {
    let answer = 0;
    for(let i = 1; i <= n; i++) {
        if (n % i === 0) {
            answer += i;
        } 
    } return answer;
}
  • 풀이 이유 : 약수를 어떻게 구하나 고민했는데, for문으로 n번째 숫자까지 돌면서 나눠서 나머지 0 인 값을 구하면 약수! -> 이걸 answer에 계속 더해가면 됨

  • 다른 아이디어 : 약수는 본인 n을 제외하고 n/2보다 클 수 없다! -> n/2까지만 비교해서 약수 구할 수 있음 (절반만 돌면 돼서 더 효율적)


  • 문제 2. 나머지가 1이 되는 수 찾기

    문제 설명
    자연수 n이 매개변수로 주어집니다. n을 x로 나눈 나머지가 1이 되도록 하는 가장 작은 자연수 x를 return 하도록 solution 함수를 완성해주세요. 답이 항상 존재함은 증명될 수 있습니다.
    제한사항
    3 ≤ n ≤ 1,000,000

  • 풀이

function solution(n) {
    for(let x = 0; x <= n; x++)
    if (n % x === 1) {
        return x;
    }
}
  • 풀이 이유 : 바로 직전 문제에서 return을 for문의 if문 안에 넣어놨더니 첫번째 true 값까지만 실행하고 반환해서 for문을 계속 돌리려고 오류를 찾았었다. 그런데 이번에 바로 조건에 부합하는 '가장 작은 자연수'를 구하는 문제가!? -> if문 안에 return 바로 넣으면 조건 부합하는 첫번째값 반환하고 끝나는 것 활용!



🏹 트러블 슈팅

  • 오류 : bootstrap 에서 가져온 floating label 인데, 여기서 '원하는 정렬 선택'부분을 없애고 싶은데 잘 안됨
  • bootstrap에서 가져온 코드
      <div class="form-floating">
        <select class="form-select" id="floatingSelect" aria-label="Floating label select example">
          <option selected>기본</option>
          <option class="sortBtn-count" value="1">추천순</option>
          <option class="sortBtn-average" value="2">평점순</option>
        </select>
        <label for="floatingSelect">원하는 정렬 선택</label>
      </div>
  • 실패했던 시도들

    • aria-label="Floating label select example 지워봄
    • 원하는 정렬 선택 없애봄
    • css로 label 태그 display: none; 해봄
    • 셀렉터 자체의 높이 줄여봄
  • 해결 : 부모 요소의 class="form-floating"를 지워주니 해결!
    -> div안에 select와 labe은 따로 있음, label에 floating관련 속성이 태그 안에 있음, 아 floating 관련 이슈일 수도 있겠구나 -> div (부모요소)의 class를 지워보기


  • 오류 : click event listener 오류

  • 오류메시지 : TypeError: document.getElementsByClassName(…).addEventListener is not a function

  • 해결

document.getElementsByClassName("sortBtn-average")[0].addEventListener('click', () => {
      console.log('print!');
    })
// [0] 추가하니까 됨! 
  • 이유 : 적용하고자 하는 class가 1개이면 [0] 해야된대(왜??..)

참고 : https://jae1590.tistory.com/184


<sort 에러>
TypeError: Cannot read properties of undefined (reading 'sort')

<찾은 답>
If using webpack-stats-plugin you must add the stats key like so:

    new StatsWriterPlugin({
      filename: 'stats.json',
      stats: {
        all: true,
      },
    })

(참고 : https://github.com/webpack/analyse/issues/18)


<오류>

  1. 맨처음에 코드 수정하다가 잘못해서 ctrlZ하다가 pull받기 이전까지 돌려버림
  2. 그거 모르고 내 브랜치에 push 해버림
  3. git pull origin DEV도 안되고,
    DEV로 들어가서 다른폴더에 파일 복사후 붙여넣기 등 이것저것 해보다가 다 안돼서
  4. DEV를 git clone 해버림
  5. 폴더가 하나 더 생겨서 기존 폴더로 파일들 옮긴후, git push origin 내브랜치 해서 겨우 복구!!!

오류 : 포스터 이미지, 카드 크기가 다른 것들이 종종 있어서 모두 같게 맞추고 싶었는데 실패
(목표 : 카드 크기, 이미지 크기 일괄 같게 만든 후 반응형에서도 오류 없게 만들기)

  • 시도 : 클래스 card와 card img의 height에 별의 별 짓을 다 해봄.
    ex) min-height, max-height, height: px; height: em;, height: rem;, height: 100% 등등
/* 시도 예시 */
.card {
  height: auto;
}

.card-img-top {
  padding: 10px;
  border-radius: 15px;
  height: 100%;
}
  • 해결 : 상위 요소에 크기가 확실히 지정되어 있는 경우, 하위 요소에 %로 크기를 지정할 경우 상위요소 크기의 %라는 뜻이다. 해당 카드들은 부트스트랩에서 가져온 카드들이었기 때문에 부트스트랩이 카드 크기를 지정해놓았다는 사실 -> 하위 요소에 %로 주어 크기를 일괄 적용 성공!
.card {
  height: 100%;
  /* 부트스트랩에서 지정한 카드 크기의 100%로 만들어줘 */
}

.card-img-top {
  padding: 10px;
  border-radius: 15px;
  height: 100%;
  /* 상위클래스(card)의 크기의 80%로 맞춰줘 */
}




🔗 팀프로젝트 - 카드 정렬 코드작성

1. sort(추첨순, 별점순) 정렬 로직

  • 로직 먼저 생각해보기
    1) 변수 지정 - vote_count(추천순), vote_average(별점순) 정보 data에서 가져오기
    2) 버튼에 click event 주기
    3) click 이벤트 함수에 sort 정렬 넣기 -> 방법 알아보기
    (평점, 별점 가져와서 정렬하면, 그 다음은?)
    각각에 해당하는 id값 가진 카드를 정렬하는걸로? 근데 카드는 배열이 아닌데...

2. 로직 구현해보기

  • 아이디어 1. vote_count, vote_average 값을 forEach로 빼서 각각 정렬 후, 카드 렌더링
    -> forEach로 뺀 값을 배열로 만들어서 sort() 하는게 맞나? 비효율적인듯..?
    // 추첨순 점수
    const sort1 = data.forEach((a) => {
      console.log(a.vote_count);
    });

    // 별점순 점수
    const sort2 = data.forEach((b) => {
      console.log(b.vote_average);
    });

    // sort 버튼 클릭이벤트 부여
    const sort3 = document.getElementsByClassName('sortBtn-count')
      .addEventListener('click', sort1.sort((next, prev) => prev > next ? -1 : 0));
    console.log(sort3);

    // 카드 렌더링
    data.forEach((movie) => {
      const card = createMovieCard(movie);
      $movieCardList.appendChild(card);
    });

  • 아이디어 2. forEach 하지 말고, 원 객체에서 value값을 sorting 하기 (객체에서 정렬하기)
    추천순으로 내림차순 정렬
    const sort_count = data.sort((a,b) => b.vote_count - a.vote_count);
    console.log(sort_count);

    평점순으로 내림차순 정렬
    const sort_average = data.sort((a,b) => b.vote_average - a.vote_average);
    console.log(sort_average);

    추천순 버튼에 클릭이벤트 - 기존 카드는 지우고, 새로운 정렬 카드로 붙이기
    document
    .querySelector('.sortBtn-count').addEventListener('click', () => {
      data.sort((a,b) => b.vote_count - a.vote_count);

        while ($movieCardList.firstChild) {
            $movieCardList.removeChild($movieCardList.firstChild);
        };

        data.forEach((movie) => {
            const card = createMovieCard(movie);
            $movieCardList.appendChild(card);
        });
    });

  • 아이디어 3 : 평점순 버튼에 클릭이벤트 - 기존 카드는 지우고, 새로운 정렬 카드로 붙이기
    document
    .querySelector('.sortBtn-average').addEventListener('click', () => {
      sort_average = data.sort((a,b) => b.vote_average - a.vote_average);

        while ($movieCardList.firstChild) {
            $movieCardList.removeChild($movieCardList.firstChild);
        };

        data.forEach((movie) => {
            const card = createMovieCard(movie);
            $movieCardList.appendChild(card);
        });
    });
  • 오류 원인 : api에서 정보 가져와서 정렬하는 코드가 카드붙이기 코드 스코프 밖에 있어서 정렬 안된 카드가 붙는것!


  • 완성 코드

// 추천순 버튼에 클릭 이벤트 - 기존 카드는 지우고, 새로운 정렬 카드로 붙이기

document
    .querySelector('.sortBtn-count')
    .addEventListener('click', () => {
      console.log('test');
        data.sort((a, b) => b.vote_count - a.vote_count);

  while ($movieCardList.firstChild) {
    $movieCardList.removeChild($movieCardList.firstChild);
  }

  data.forEach((movie) => {
    const card = createMovieCard(movie);
    $movieCardList.appendChild(card);
  });
});

// 평점순 버튼에 클릭 이벤트 - 기존 카드는 지우고, 새로운 정렬 카드로 붙이기
document.querySelector('.sortBtn-average').addEventListener('click', () => {
  data.sort((a, b) => b.vote_average - a.vote_average);

  while ($movieCardList.firstChild) {
    $movieCardList.removeChild($movieCardList.firstChild);
  }

  data.forEach((movie) => {
    const card = createMovieCard(movie);
    $movieCardList.appendChild(card);
  });
});



🐣 오늘의 느낀점

  • 시간이 지나면 지날수록 TIL을 안쓰게 된다는 튜터님들의 말씀을 처음에는 이해를 잘 못했는데 이제 점점 알 것 같다.ㅠㅠ 매 순간이 트러블슈팅이고 지금 당장 내 코드 구현하는것도 너무 바쁜데 이걸 기록까지 하려니 어려운 것 같다.ㅠㅠ 그래도 이렇게 매일의 과업으로 제출할 수 있게 도와주는 캠프에 참여하길 너무 잘했고, 반강제적으로 이렇게 매일 TIL을 작성하다보면 습관이 될 것 같다! 오늘도 수고했다 꾸준히 포기말고 화이팅!
profile
꾸준히 성장하는 우상향 개발자

0개의 댓글