파이썬 알고리즘 : 하샤드 수

2024년 2월 29일 알고리즘 문제풀이 문제 하샤드 수 난이도 Lv.1 코드 1 2 3 4 5 6 7 def solution(x): answer = True arr = list(map(int, str(x))) tmp = sum(arr) if x % tmp != 0: answer = False return answer 반복문보단 map 함수를 이용하려고 했다.

2024년 2월 29일 · 1 분 · 배준수

기능 VS 아키텍처

Today I Learned 날짜 2024년 2월 28일 수요일 내용 세일즈 팝업 이번 스프린트에서 가장 고민이 깊은 부분은 실시간성 데이터들이다. 상품을 보여주는 위젯에 “5분 전에 춘천 사는 김씨가 샀어!” 라던가, “재고가 5개 밖에 안남았어!” 라고 말해줘야 한다. 이 데이터가 내일 들어와도 “5분 전에 춘천 사는 김씨가 샀어!”라고 고정되어 있다던가, 아직도 5개가 남아있다면 효과가 떨어질 수 밖에 없다. 재고가 1개로 줄어들었다던가, 방금 구매한 고객에 대한 정보가 바뀌어있어야 한다. 기존에 알파리뷰에 있는 세일즈팝업이 이 데이터를 이용한다. 재고, 상품 상세정보 페이지 방문자 수, 판매량, 최근 구매 내역이나 리뷰 작성 내역등이 포함된 팝업이다. 이 위젯은 기존에 있던 다른 위젯들과는 구성이 조금 다른데, 렌더링이 우리 서버에서 발생하지 않는다는 것이다. 기존 위젯은 App proxy를 이용하여 다음과 같이 발생한다. ...

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

데이터의 소스를 찾아서

Today I Learned 날짜 2024년 2월 27일 화요일 내용 Underscore(_) 기존의 코드들을 살펴보다가 한 가지를 발견했다. def test(): 와 def _test(): 의 차이는 무엇인가? 어떤 함수들은 정의 앞에 밑줄이 그어져 있었다. 저번에 한번 봤을 떈 오타겠거니 넘어갔는데 그런 함수가 많다! 관련된 부분을 찾아봤다. 클린 아키텍처나 클린코드 등의 책을 읽으면 수 없이 많이 나오는 이야기지만, 정의된 함수를 다른 곳에서 알 수 있게 할 것인가 말 것인가는 중요한 고민이다. 이에 대한 정답은 아직 나도 공부중이라 답변은 힘들고.. javascript에는 public, private, protected 등 접근을 제어하는 설정들이 존재한다. 반면 이 개념이 python에는 없다. 대신 표시하기 위해 관습적으로 _나 __(2개)를 사용한다. 1개인 def _test(): 는 내부적으로 사용되는 것이라 는 뜻이고, 2개는 클래스 내부에서만 사용되는 메서드나 속성에 사용된다. 결론은 여기 말고 다른곳에서 쓰지말라는 뜻. ...

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

파이썬 알고리즘 : 프렌즈4블록

2024년 2월 27일 알고리즘 문제풀이 문제 프렌즈4블록 난이도 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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 def solution(m, n, board): answer = 0 # 시계방향으로 90도 회전하는 함수 # 따라서 n x m 인 배열이 된다. # 블록의 추락도 아래가 아닌 왼쪽으로 발생해야 한다. arr = [[] for _ in range(n)] for k in range(n): for i in range(m-1,-1,-1): arr[k].append(board[i][k]) # 점을 기준으로 오른쪽, 아래, 오른쪽 아래가 모두 동일한지 확인하는 함수 def check(a,b): result = False tmp = arr[a][b] if arr[a+1][b] == tmp and arr[a][b+1] == tmp and arr[a+1][b+1] == tmp: result = True return result # 점을 기준으로 오른쪽, 아래, 오른쪽 아래 4개를 지우는 함수. # 지워지는 블록이 다른 곳과 겹칠 경우를 대비하여, 실제 지워진 갯수를 계산하여 반환 def delete(a,b): result = 0 if arr[a][b] != '0': arr[a][b] = '0' result += 1 if arr[a+1][b] != '0': arr[a+1][b] = '0' result += 1 if arr[a][b+1] != '0': arr[a][b+1] = '0' result += 1 if arr[a+1][b+1] != '0': arr[a+1][b+1] = '0' result += 1 return result # 90도 회전하였기 때문에, 왼쪽으로 블록이 떨어지는 함수 구현 # 각 행마다, 비어있는 열을 발견할 경우 오른쪽을 탐색하여 떨어질 블록을 찾아 바꿔준다. # 한 칸씩 떨어뜨리면, 여러 블록을 떨어뜨리는 경우가 복잡해진다. def fall(): for i in range(n): for j in range(m): if arr[i][j] == '0': for k in range(j+1,m): if arr[i][k] != '0': arr[i][j] = arr[i][k] arr[i][k] = '0' break # '0'이 아니라는 조건을 추가하지 않으면 무한루프가 실행된다. while True: delete_list = [] for i in range(n-1): # 여기가 1,m 이면 테스트 5가 실패함 for j in range(m-1): if arr[i][j] != '0' and check(i,j): delete_list.append([i,j]) if not delete_list: break for a,b in delete_list: tmp = delete(a,b) answer += tmp fall() return answer 겁나 힘들게 풀었다… 기존에는 위와 같이 풀되, 90도로 회전하지 않았다. 이떄 발생하는 어려움은 블록을 부수고 떨어뜨리는 것을 구현하기 힘들었다. 위에서 아래로 떨어뜨릴 경우 같은 열이지만 다른 행인 원소들간의 비교가 이루어져야 한다. 위 각주에서도 말했지만 한 칸씩 옮길 경우 2개가 같이 떨어질 떄나, 여러 칸을 떨어뜨리는 경우의 수는 상당히 복잡하기 때문에 구현이 힘들었다. 추락을 같은 List 안에서 발생하도록 하면 훨씬 편해질 것이라고 생각해서 배열을 90도 회전하였다. ...

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

데이터베이스 구조 고민과 Shopify App proxy

Today I Learned 날짜 2024년 2월 26일 월요일 내용 기존 로직 파악 다음 스프린트 때 구현할 기능들에 대해 코드 초안을 작성하고 있다. 기존에 구현되어 있는 방식을 이해하지 못해 막혀있는 부분과 작성했지만 개선해야 할 부분을 회의를 통해 알게 되었다. 고객의 스토어에 표시할 위젯을 Shopify theme asset에 저장할 수 도 있다. 하지만 이 때 위젯을 가지고 있는 것은 shopify가 된다. 우리 서비스에서 제공하고, 수정 및 변경이 원활하기 위해선 우리가 가지고 있는 것이 바람직하다. 우리 서비스를 설치한 스토어는 테마를 수정하는 에디터에서 앱 블록을 추가할 수 있다. 앱 블록에는 스크립트가 작성되어 있는데, “어떤 위젯이 필요하니 app proxy를 이용해 알파리뷰 서버의 특정 endpoint로 요청하라”고 적혀있다. 우리 서버는 해당 요청을 받으면 이에 맞는 위젯 HTML에 알맞은 데이터를 추가하여 보내준다. 데이터까지 입력된 완성된 HTML을 보내주는 것이다. 앱 블록은 받은 것을 출력하면 된다. ...

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

파이썬 알고리즘 : 크레인 인형뽑기 게임

2024년 2월 26일 알고리즘 문제풀이 문제 크레인 인형뽑기 게임 난이도 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 def solution(board, moves): n = len(board) stk = [] answer = 0 # 열에서 가장 위에 있는 인형을 찾는 함수 # 찾으면 board에서 0으로 바꾸고 반환 def first_target(row): for i in range(n): if board[i][row]: result = board[i][row] board[i][row] = 0 break else: result = False return result # 인형이 있을 때, 이미 들어있는 인형과 동일하면 2개 제거, 아니면 추가 for x in moves: row = x-1 tmp = first_target(row) if tmp: if stk: if stk[-1] == tmp: stk.pop() answer += 2 continue stk.append(tmp) return answer

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

기술개발 초안 작성

Today I Learned 날짜 2024년 2월 23일 금요일 내용 내가 짤 코드 생각해보기 이전부터 항상 느끼던 갈증은 “내가 어떻게 코드를 작성할 것인가”를 미리 생각하지 못하는 것에서 발생했다. 직접 VS Code 에 입력할 때가 되어서야, ChatGPT에게 물어보고 나서야 내가 나아갈 방향을 안다는 것은 내가 개발자가 아닌 코드싸개에 불과하다는 걸 시사한다. 지난 1월 30일에 작성한 TIL에 있던 내용이다. 내가 뱉은 말을 지키기 위해, 실행에 옮겼다. 어제 개발자들끼리 회의도 있었기 때문에 충분히 가능하다고 생각했다. ...

2024년 2월 23일 · 2 분 · 배준수

파이썬 알고리즘 : 짝지어 제거하기

2024년 2월 23일 알고리즘 문제풀이 문제 짝지어 제거하기 난이도 Lv.2 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def solution(s): arr = list(s) stk = [] for i in range(len(s)): if not stk: stk.append(arr[i]) continue else: if stk[-1] == arr[i]: stk.pop() else: stk.append(arr[i]) if not stk: answer = 1 else: answer = 0 return answer

2024년 2월 23일 · 1 분 · 배준수

스프린트 전 개발팀 회의

Today I Learned 날짜 2024년 2월 22일 목요일 내용 3회의 다음 스프린트의 기획과 디자인이 어제 나왔다. 저번 스프린트에 대한 회고에서, 사전에 개발자들끼리 조율하지 않아 발생하는 문제들에 대해 팀 구성원 모두 인지하고 있었기 떄문에 약속한대로 프론트와 백 간의 주고 받는 데이터에 대해 이야기를 나누었다. 이 Try의 관찰자로서 어떻게 이야기를 주고 받을지에 대해 큰 틀을 짰다. 데이터 그 자체에 주목하며 각 페이지 별로 필요한 데이터를 확인한다. ex. 위젯의 생성 시간, 상품의 평점 등 ...

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

파이썬 알고리즘 : 정수 내림차순으로 배치하기

2024년 2월 22일 알고리즘 문제풀이 문제 정수 내림차순으로 배치하기 난이도 Lv.1 코드 1 2 3 4 5 6 7 def solution(n): arr = list(str(n)) map(int,arr) arr.sort(reverse=True) map(str,arr) answer = ''.join(arr) return int(answer)

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