1보 전진을 위한 3보 후퇴

Today I Learned 날짜 2024년 3월 28일 목요일 내용 새로운 스프린트를 시작해야 하지만 이전 것에 발목잡혔다. 이메일 HTML 이메일의 내용이 조건에 따라 달라지도록 구현했다. 기능 자체는 작동이 되는데, 여러모로 디테일이 많이 부족했다. 두 선이 겹친듯 안겹친듯 출력된다 던가, 옆 마진이나 패딩이 다르다던가…. 한 번 할 때 신경써서 세세하게 할껄. 삭제 로직 어드민 내에서 앱을 삭제할 수 있는 기능을 추가했지만 이상하게 작동이 안됐다. 알고보니, 삭제 과정에서 이유를 저장하는 테이블에 데이터를 저장해야하는데, 테스트 서버에 마이그레이션을 까먹어서 저장을 못해 오류처리 되는 문제였다. 항상 병합 후 취해야 하는 조치가 있다면 꼭 기록해두자. ...

2024년 3월 28일 · 1 분 · 배준수

파이썬 알고리즘 : 서울에서 김서방 찾기

2024년 3월 28일 알고리즘 문제풀이 문제 서울에서 김서방 찾기 난이도 Lv.1 코드 1 2 3 4 def solution(seoul): answer = '' answer = str(seoul.index('Kim')) return f"김서방은 {answer}에 있다"

2024년 3월 28일 · 1 분 · 배준수

위젯 렌더링 대작전

Today I Learned 날짜 2024년 3월 27일 수요일 내용 열심히 진행했던 스프린트인 리스트 디자이너의 QA작업에 돌입했다. 데이터 갱신 타이밍 위젯에 표시되는 상품들의 실시간성 데이터들은 1시간 간격으로 cron을 이용해 업데이트 하도록 설계했다. 간과한 것은, 새롭게 위젯을 만들 때, 데이터가 생성되야 한다는 것이다. 이 로직이 없으면 새로 만들어진 위젯의 상품들은 다음 크론이 오기 전까지 데이터가 없게 되어 고객이 사용할 수 없다. 관련된 데이터를 업데이트 하는 함수들 crud에 만들어놨었다. 이를 가져와서 위젯을 생성하는 클래스 내에서 호출하도록 구현했다. 모양새가 정말 맘에 들지 않지만.. 현재는 기능을 완성하여 출시하는 것이 중요하다고 생각해서 기능 완성에 중점을 두었고, 여기에는 이상 없다. ...

2024년 3월 27일 · 3 분 · 배준수

씨에수에수왕

Today I Learned 날짜 2024년 3월 26일 화요일 내용 다 고쳤다고 생각했는데, 이젠 위젯 수정 과정에서 발생한 오류들이… 위젯 수정 후 렌더링 썸네일 렌더링과는 별개로, 처음 위젯을 생성할 때는 상품의 썸네일 이미지도 가져와서 설정하는 로직이 있다. 그런데, 이미 존재하는 위젯을 수정하는 과정에서 상품을 추가할 때는 썸네일을 가져오지 않았다. 추가해주었다. 레이아웃 수정 행,열의 값이나 레이아웃 형태를 변경하면 위젯이 고장나버리는 문제가 있었다. 디자인 옵션은 받은 값을 통채로 덮어씌워져서 개별 값이 문제가 될 리가 없었다. 로그를 확인해보니 currency가 문제가 있었다. 뜬금없이 애는 또 왜…. ...

2024년 3월 26일 · 4 분 · 배준수

파이썬 알고리즘 : 압축

2024년 3월 26일 알고리즘 문제풀이 문제 압축 난이도 Lv.2 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 def solution(msg): answer = [] alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' arr = dict() for i in range(len(alphabet)): arr[alphabet[i]] = i+1 # 다음 추가될 색인 번호는 마지막보다 1 큰 수 last_num = len(alphabet)+1 # idx까지 볼때 idx-1 까지만 포함되므로 1로 설정 idx = 1 n = len(msg) while idx <= n: # 이미 있다면 다음이 더 긴지 확인하기 위해 idx만 1 증가 if msg[:idx] in arr: idx += 1 continue else: # 사전에 없다면, 길이가 1 작을 때가 가장 긴 단어이므로(2단계) 그 번호를 출력 answer.append(arr[msg[:idx-1]]) # 없는 단어와 색인 번호를 추가 arr[msg[:idx]] = last_num # 다음 추가될 색인 번호 1 증가 last_num += 1 # 찾아낸 가장 긴 단어는 삭제 msg = msg[idx-1:] # 인덱스 오류를 방지하기 위해 매 반복마다 길이 체크 n = len(msg) # 인덱스 초기화 idx = 1 # 마지막 반복 때 사전에 있는 단어로 끝났다면 추가되지 않는 단어가 생기므로 추가 # KAKAO에서 마지막 O는 별도로 추가해야함 if msg: answer.append(arr[msg]) return answer 매 번 느끼는 거지만, 문제가 길 때(특히 카카오)는 차근차근 시키는대로 하는게 정답이다. ...

2024년 3월 26일 · 1 분 · 배준수

위젯 렌더링 고치기

Today I Learned 날짜 2024년 3월 25일 월요일 내용 상당히 바쁜 하루… 위젯 렌더링 위젯 프리뷰 기능에서 계속 오류가 발생했다. 고쳐도 고쳐도 문제가 계속 나온다! currency 문제 위젯 내에 가격을 표시할 때, 해당 스토어의 국가에 맞는 화폐단위도 출력해야한다. 미국이라면 USD, 한국이라면 KRW 이런식… 이 데이터를 결정하는 것은 서버쪽이 처리해야 했다. 따라서 프론트가 데이터를 보낼 때는 화폐 단위 정보는 없는 형태로 보낸다. 고정되어 저장된 설정의 위젯을 보여주는 것과 달리 프리뷰는 그때그떄 고객이 설정한 데이터의 형식을 보여줘야 한다. 따라서 고객의 디자인 설정값이 요청 본문에 담겨있고, 이를 렌더링한 위젯을 반환한다. 이때, 서버에서 관리하는 데이터베이스 내 위젯 객체와 클라이언트에서 보내는 요청을 검증하는 스키마는 currency를 제외하곤 동일하다. 이걸 몰라서 한참 해메고 있었다.. 자꾸 500 에러가 뜨는데 왜 안될까 못찾았는데.. 클라이언트에게 데이터를 받아 스키마 객체로 처리한다. 이 데이터를 그대로 위젯 데이터객체에 넣는다. 렌더링한다. 이 때, 스키마에는 currency가 없어 렌더링 과정에서 참조할 필드가 없으니 오류가 발생한다. 의 문제였다. ...

2024년 3월 25일 · 2 분 · 배준수

파이썬 알고리즘 : 대충 만든 자판

2024년 3월 25일 알고리즘 문제풀이 문제 대충 만든 자판 난이도 Lv.1 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 def solution(keymap, targets): answer = [] arr = dict() idx = 0 # 각 글자를 입력하기 위한 버튼 누르는 횟수의 최솟값을 저장하는 배열 arr을 만드는 과정 # 각 버튼의 0번 index 부터 하나씩 참조 while True: # 모든 키의 입력 범위를 넘어갔는지 확인하기 위한 플래그 flag = False # 모든 버튼 순회 for button in keymap: # 예를 들어, 버튼을 5번 누를 수 있는데 idx가 6이라면 그 버튼은 더이상 조사할 필요가 없으므로 넘어감 if idx >= len(button): continue # 어떤 버튼을 참조했음을 플래그에 표시. 이 과정이 없으면 keymap중 가장 긴 버튼의 길이를 구하느 과정이 따로 필요 flag = True # idx번 눌렀을 때 해당 버튼에서 입력되는 글자 letter = button[idx] # 지금 입력되는 글자가, 아직 입력된적 없는 글자라면 배열에 추가 if letter not in arr: arr[letter] = idx+1 # 이미 입력된적 있다면, idx를 작은 값으로 바꿔줌. 각 글자를 누르는 최소 방법만 알면 되기 때문 # 0번 인덱스는 1번 눌러야 하므로 idx+1을 저장 else: arr[letter] = min(arr[letter],idx+1) # 아무 버튼도 탐색하지 않았다면 무한루프 종료 if not flag: break idx += 1 for target in targets: cnt = 0 # 타겟을 하나씩 탐색하며 글자를 확인 for i in range(len(target)): # 만약 글자를 입력할 방법이 있다면 해당 키의 값을 추가 if target[i] in arr: cnt += arr[target[i]] # 글자를 입력할 방법이 없다면 -1로 지정하고 종료 else: cnt = -1 break answer.append(cnt) return answer

2024년 3월 25일 · 2 분 · 배준수

스프레드시트에 데이터 병합하는 크론 고치기

Today I Learned 날짜 2024년 3월 22일 금요일 내용 위젯 위젯 내용이 에러메시지에 담기는 문제에 대해 조언을 받았는데, 프론트 쪽의 문제일 수 도 있다고 한다. 응답을 받을 때 Text로 처리하는 함수를 사용하는 쪽으로.. 자세한 결과는 월요일에나 나오지 않을까 싶다. 고객 데이터 조회 예전에 진행했던 태스크에 문제가 생겼다. 고객들의 서비스 사용 정보를 구글 스프레드시트에 매일 갱신하는 함수가 제대로 작동하지 않았다. 리뷰 서비스나, AI 서비스를 사용하면 사용 개시 시간을 기록해야 하는데 사용한다고 기록했음에도 불구하고 구체적인 시간은 저장되지 않고 있었다. ...

2024년 3월 22일 · 2 분 · 배준수

에러메시지에 응답 담기

Today I Learned 날짜 2024년 3월 21일 목요일 내용 Angular 최근 작업한, 앱 내에 서비스 삭제 경로를 추가하는 건 나름(?) 큰 작업이었다. 그동안은 컴포넌트에 변수에 대한 조건을 추가하는 등의 사소한 작업이었는데, 새로운 하위 컴포넌트를 만들어야 했다. 모달 형태로. 기능 자체는 어제 TIL에 작성한 대로 완성했다. 다만, 기존에 작성되있는 방식에 맞추기 위해, 유지보수를 수월하게 하기 위해, 박살난 CSS 수준을 끌어올리기 위해 감사하게도 코드 리뷰를 받을 수 있었다. 이 TIL에 적어내면 참 좋겠으나 아직 내 것으로 받아들이지 못해 쓸 수 없다. 그래도 열심히 받아 적었으니 빨리 적용해보고 내가 몰랐던 부분에 대해 정리해야겠다. 최근 스프린트들이 프론트쪽에 작업이 몰리면서, 내가 프론트를 어느정도 할 수 있다면 팀의 일정에 도움이 많이 되겠다고 느꼈다. 마침 기가 막히게 성장할 환경이 갖추어졌으니 열심히 하기만 하면 될 듯! ...

2024년 3월 21일 · 2 분 · 배준수

앱 삭제 기능 만들기

Today I Learend 날짜 2024년 3월 20일 수요일 내용 앱 삭제하는 경로를 추가했다. 오늘은 백엔드 작업을 많이 했다. 프론트 기존에 우리 서비스에서 사용하는 체크박스 클래스로 바꿔주었다. 앱을 삭제하는 버튼은 고객이 이유를 선택해야만 활성화되도록 구현하기 위해 ngIf 를 사용했다. 1 2 <button *ngIf="uninstallReasons.length > 0" class="btn-enabled" mat-button (click)="onConfirm()">Delete App</button> <button *ngIf="uninstallReasons.length === 0" class="btn-disabled" mat-button disabled>Delete App</button> 각 사유들은 checkbox로 만들었고 체크되면 삭제 사유를 담는 배열에 추가시켰다. 1 2 3 <div class="checkbox-container" aria-label="Select a reason" [(ngModel)]="uninstallReasons"> <alpha-checkbox (change)="updateUninstallReasons($event, 10)">Technical issues</alpha-checkbox> </div> 처음 사유를 추가했을 때, 버튼이 활성화되었다. 하지만 체크를 비활성화하여 다시 사유를 선택하지 않게 되었을 때 버튼이 비활성화되지 않았다. 따라서 uninstallreason의 배열 상태를 추적하는 ChangeDetectorRef를 사용했다. ...

2024년 3월 20일 · 2 분 · 배준수