개발일기 21.06.13 1주차 WIL

Nhahan·2021년 6월 13일
0

항해99 개발일기

목록 보기
20/31

1. 미니프로젝트

 flask로 진자를 이용해서 백의 정보를 프론트로 넘겨 표시해주는 기능이 매우 편했다. ajax와는 비교할 수 없는 편리함이었다. 진자를 이용하면 직관적으로 html에서 바로 원하는 위치에 정보를 표시할 수 있다보니 프론트에 대한 지식이 깊게 없어도 쉽게 진행할 수 있었다.

클라이언트사이드렌더링의 장점 / 단점

장점

1-1. 트래픽감소
필요한, 변경된 데이터만 받아서 그림
1-2. 사용자경험
새로고침이 발생하지 않아 사용자가 네이티브 앱과 비슷한 경험을 할 수 있다.

단점

2-1. 검색엔진
자바스크립트 위주로 돌아가는 프로젝트는 자바스크립트 엔진이 돌아가지 않으면 원하는 정보를 표시해주지 못함. 크롬에서 react로 만든 웹앱의 소스를 확인하면, 내용이 비어있다. 그렇기때문에 검색엔진 크롤러가 데이터들을 제대로 수집하지 못한다. 하지만 짱짱맨 구글의 검색엔진은 자바스크립트 엔진이 내장되어있다. 하지만 네이버, 다음 등의 검색엔진은 제대로 크롤링하지 못하기때문에 서버사이드렌더링을 따로 구현해야한다.

서버사이드렌더링의 장점 / 단점

장점

1-1.검색엔진최적화(SEO) 가능
서버사이드렌더링을 통해 얻을 수 있는 가장 큰 이점!
1-2.성능개선
첫 렌더링된 html을 클라이언트에게 전달해주기때문에 초기로딩속도를 많이 줄여줄 수 있다. 자바스크립트 파일을 불러오고 렌더링 작업이 완료되기 전에 사용자가 사이트 컨텐츠를 이용할 수 있게 된다.

단점

2-1. 프로젝트의 복잡도
React에서 서버사이드렌더링을 구현할 경우 Router와 Redux와 함께 사용하다보면 복잡해질 수 있다.
2-2. 성능의 악화 가능성
서버사이드 렌더링을 하게 될 때는, ReactDOMServer.renderToString 함수를 사용한다. 이 함수는 동기적으로 작동한다. 그래서, 렌더링하는동안은 이벤트루프가 막히게 된다. 하지만.. ! 라이브러리를 통하여 비동기식으로 작동하게끔 코드를 작성 할 수 있다.

대안

3-1. 메타태그만 넣어주기
서버쪽에서 라우트에 따라 필요한 메타태그만 넣어주는 것. 그러면, 크롤러에선 해당 페이지에 대한 기본 정보는 얻어 갈 수 있게 된다.
3-2. Prerender
이 서비스는 오직 검색엔진 최적화를 위해서만 사용

 팀원끼리 프로젝트를 계획할 때 불가능하다고 생각하는 기능은 애초에 빼고 시작했기 때문에 프로젝트를 완수함에 있어서 큰 어려움은 없었다. 이틀 째에 내가 하기로 한 기능을 모두 구현했고, 그 뒤로는 그 기능을 어떻게 발전시킬 수 있을까하는 고민으로 시간을 보냈는데 오히려 이 과정이 더 힘들었다. 단순 api를 이용하는게 아니라 셀레니움을 이용해서 더 정확하고 세밀한 정보를 긁어오려다가 수많은 실패와 좌절을 겪었다. 결국 포기했고 그냥 앞으로 도움이 될지 안될지 모르는 셀레니움의 기능만 많이 알게 되었다.

2. 자료구조와 알고리즘

 미니프로젝트가 끝나고 알고리즘 주가 시작되었다. 이번주까지 항해99에서 제공해준 자료구조/알고리즘 강의를 4주차까지 완료하는게 과제인데 일단 끝내긴 했으나 아직 정확히 무슨 말인지 잘 모르겠다.

 들으면 들을수록 과연 코딩이 이번에 처음인 내가 이 강의를 단기간에 이해할 수 있을까하는 의문이 들었다. 다행히 이런 문제를 풀고 머리 쓰는 것을 좋아해서 열심히 하긴 했지만, 결과물은 보다싶이 아래와 같다.

def get_melon_best_album(genre_array, plays_array):
    genre_list = []
    genre_counts = {}
    genre_rank = []
    genre_dicts = []
    for i in range(len(genre_array)):
        genre_dicts.append({genre_array[i]: (plays[i], i)})
    for x in genre_array:
        if x not in genre_list:
            genre_list.append(x)
    for g in range(len(genre_array)):
        for genre in genre_list:
            if genre_array[g] == genre:
                if genre not in genre_counts:
                    genre_counts[genre] = plays_array[g]
                elif genre_counts[genre] < plays_array[g]:
                    genre_counts[genre] = plays_array[g]
    genre_counts_list = list(genre_counts)
    genre_counts_points = [0] * len(genre_counts_list)
    for n in range(len(genre_array)):
        for nl in range(len(genre_counts_list)):
            if genre_array[n] == genre_counts_list[nl]:
                genre_counts_points[nl] += plays_array[n]
    genre_counts = {name: value for name, value in zip(genre_counts_list, genre_counts_points)}
    for delete in range(len(genre_counts)):
        genre_rank.append(max(genre_counts, key=genre_counts.get))
        del genre_counts[max(genre_counts, key=genre_counts.get)]
    answer = list()
    for rank in genre_rank:  # pop, classic
        temp_rank_dicts = []
        for genre_dict in genre_dicts:  # [{'classic': 500}, {'pop': 600}, {'classic': 150}, {'classic': 800}, {'pop': 2500}]
            if rank in genre_dict:  # pop, classic
                temp_rank_dicts.append(genre_dict)
        temp_rank = list()
        temp_rank_list = list()
        temp_rank_checker = list()
        for t in range(
                len(temp_rank_dicts)):  # [{'pop': (600, 1)}, {'pop': (2500, 4)}]     # [{'classic': (500, 0)}, {'classic': (150, 2)}, {'classic': (800, 3)}]
            if len(temp_rank_dicts) == 2:
                temp_rank.append(temp_rank_dicts[t][rank][1])
            else:
                temp_rank_list.append(temp_rank_dicts[t][rank][0])
                if t is len(temp_rank_dicts) - 1:
                    temp_rank_list.sort(reverse=True)
                    temp_rank_list = temp_rank_list[:2]
                    for m in range(len(temp_rank_dicts)):
                        if temp_rank_dicts[m][rank][0] == temp_rank_list[0] and temp_rank_dicts[m][rank][1] not in temp_rank_checker:
                            temp_rank_checker.append((temp_rank_dicts[m][rank][0]))
                            temp_rank.append(temp_rank_dicts[m][rank][1])
                    for m in range(len(temp_rank_dicts)):
                        if temp_rank_dicts[m][rank][0] == temp_rank_list[1] and temp_rank_dicts[m][rank][1] not in temp_rank_checker:
                            temp_rank_checker.append((temp_rank_dicts[m][rank][0]))
                            temp_rank.append(temp_rank_dicts[m][rank][1])
        temp_rank.sort(reverse=True)
        answer += temp_rank
    return answer

결과는 나오지만 굉장히 알아보기 힘든 죽음의 하드코딩...

 파이썬의 문법도 잘 모르는데 억지로억지로 해나가다보니 이런 코드도 작성하게 됐다. 머리에 쥐나는줄... 다 풀고 해설 영상을 보니 튜터님은 딕셔너리를 이용해 깔끔하게 해결하시는 걸 보니 약간 현타가 오기도 했다. 내가 이런 휴지통 코드를 썼다니ㅠㅠ

 딕셔너리를 잘 쓸 줄 모르다보니 딕셔너리의 내용을 여러 리스트 변수로 할당해 풀다보니 정말 정말 복잡해진 것이다.

 다음주(당장 내일!)부터 이제 본격적으로 문제풀이를 시작할텐데 상당히 기대된다. 1주차를 끝내면서 느끼지만 정말 코딩하는 게 재밌고 나의 적성과 잘 맞는다는 생각이 든다. 정말 흥미롭고 재밌다.


사전스터디 프로젝트 링크 0주차
미니프로젝트 링크 1주차

0개의 댓글