오늘은 중간발표가 있던 날이었다. 저번에 좋은 피드백을 받았던지라 오히려 이번 발표가 좀 걱정되긴 했다. 아니나다를까, 우리는 핵심 챌린지 중 하나인 '툭' 기술을 아직 개발해보지 않은 점에 대해 지적을 받았다. 우리는 다른 부분을 어느정도 커버해놓고 툭을 해보려고 했는데, 툭부터 해봐야했다는 말씀이셨다. 물론 공감은 가지만, 우리는 몰입해서 플러터를 4일만에 공부하고(thx to 코딩사과형..) 3일만에 상당 부분을 구현한 것인데 이런 부분은 봐주지 않으셔서 아쉬웠다. 그래도 뭐 어쩌겠는가 ! 항상 좋은 평가를 받기란 어려운 일이고, 만약 최종발표 직전까지 칭찬일색이었다면 오히려 가장 중요한 당일이 상당히 부담되었을 것이다.
이후에 점심을 먹으면서도 중간중간 얘기를 나눈 후에, 오후 1시에 바로 회의를 시작했다. 5명 전원이 툭 기능 개발에 붙자는 의견도 있었지만, 나는 생각이 달랐다. 최종발표 당일 우리 조에 주어지는 7분이 매우 중요하다고 생각했는데, 실제로 운영진 분들이 프로젝트 피드백을 해주실 때마다 최종발표를 염두에 두시는 경우가 많았다. 최종발표에서 특히 중시하는 부분은 바로 '시연'인데, 우리가 만든 서비스가 얼마나 멋진지를 제대로 보여줄 수 있는 시간이기 때문이다. 7분 중에 4~5분을 시연에 투자한다고 했을 때, '툭' 기능은 그 중 많아야 1분정도 차지할 것이다. 그럼 나머지 3~4분은 어떡할 것인가? 물론 기술적인 챌린지를 잘 해내는 것도 중요하지만, 5명이 다 달라붙는다고 해서 더 나은 결과물이 나오지는 않을 것이다. 결국 '툭' 기술은 한 가지로 수렴하게 될테니까 말이다. 실제로 이번 중간발표 때 아쉬운 피드백을 받은 것도, 시연의 가장 첫 번째 부분인 '카드생성' 부분을 정말 프로토타입 그 자체로 놔뒀기 때문이지 않나 싶었다. 개인적으로 발표에서 가장 중요한 것은 '첫인상' 이라고 생각하는데, 오늘 우리 발표에서 시연을 시작한 후에 '첫인상'이 된 부분이 다소 아쉽게 시작하다보니 그 이후 부분도 모두 아쉽게 느껴진다는 생각이 들었다.
그래서 나 역시 툭 기술에 도전해보고 싶었지만, 다른 팀원분과 둘이서는 일단 전반적인 UI 수정보완과 프로젝트 로직 리팩토링을 나누어 진행하기로 했다.
그렇게 해서 내가 오늘 진행한 부분은 크게 2가지다. 삭제로직 개선, 그리고 전반적인 프로젝트 File Structure 재구성이다. 오늘은 중간 발표에 협력사 설명회까지 있어서 시간이 많지 않았지만, 알차게 시간을 보낸 것 같다.
명함첩의 삭제로직을 개선하는 작업을 했는데, 기존에는 딱 하나의 명함만 삭제가 가능한 상황이었고, 그마저도 실제로 삭제 후에 재렌더링 해주는 것이 아니라 새로운 페이지를 덮어쓰는 방식이었다. 초기 발표 때 시연했던 Figma에 맞추어 일단 시연만 가능하도록 한 상태였는데, 이를 각 명함별로 삭제가 가능하도록 하였다. 그리고 원래는 끝까지 슬라이드하면 알아서 바로 삭제되는 상태였는데, 중간까지 밀고 삭제버튼을 눌러야만 되도록 하였으며, 삭제 전에 재확인하는 Dialog를 띄워주도록 만들었다.
또한, 전반적인 File Structure를 재구성하였다. 프로젝트를 원활하고 정돈되게 진행하기 위해서는 File Structure를 잘 잡는 것이 중요하다. 그래야 나중에 수정할 때, 맞추어 수정할 수 있기 때문이다. 하지만 기존에는 아래와 같은 폴더구조를 갖고 있었다.
보다시피 pages안에 main 안에 핵심기능별로 또 폴더를 나누고... 다소 복잡했다. 뭔가 바꾸고싶다는 생각이 들었는데, 인터넷에서 검색을 하다보니 일반적으로 Flutter에서 사용하는 File Structure에 관한 글들이 눈에 띄었다.
읽어보니 Flutter 프로젝트에서 일반적으로 사용하는 프로젝트 구조가 있다는 것이다! 그리고 Flutter에서는 파일명을 지을 때, 소문자와 언더스코어로만 구성한다고 한다. Dart Coding Standard 라나.. 어쨌든 이를 팀원들과 공유해서 만장일치로 합의한 후에 아래와 같이 변경하였다.
여기서 tests는 아직 DB와 연동을 하지 않았기에 임시로 만든 샘플 데이터들을 저장한 폴더로, 최종 배포 단계에서는 삭제하면 될 것이다 :) 비록 오늘 다소 속상하고 아쉬운 날이었지만, 최종발표 날에 결과로 보여주면 될 것이다. 그리고 운영진 피드백에 하나하나 신경 쓸 필요 없다고 의장님도 직접 말씀하셨다. 다행히도 우리 조는 중심을 다 같이 잘 잡고 있기 때문에, 흔들리지 않고 우리의 길을 갈 것이다. 화이팅 👍
오늘 도전한 문제는 맥주 마시면서 걸어가기 라는 문제이다.
우와.... 실패하고 말았다. 문제는 이렇게 생겼다.
처음에 문제를 보고 쉽다고 생각하고, 다음과 같이 쉽게 코드를 써내려갔다.
# 백준 # 맥주마시면서걸어가기 # 5시20분시작
# 50미터마다 최소 한병 마셔야함.
from sys import stdin
input = stdin.readline
# 테스트 케이스 개수
t = int(input())
def dist(A,B):
return abs(A[0]-B[0]) + abs(A[1]-B[1])
def sol(start, stores):
end = stores[-1]
stores.sort(key = lambda x:(x[0],x[1]))
before = start
keep = 0
for now in stores:
keep += dist(now, before)
drunk, keep = divmod(keep, 50)
if not drunk:
before = now
continue
drunk = drunk + 1 if keep else drunk
if drunk > 20:
return "sad"
if now == end:
return "happy"
before = now
for _ in range(t):
n = int(input())
depart = list(map(int, input().split()))
stores = [list(map(int, input().split())) for _ in range(n+1)]
# arrives += [map(int, input().split())] # arrive
print(sol(depart, stores))
하지만, 생각해보니 편의점이 출발지에서 가까운 순서대로 주어진다는 보장이 없기에, 단순히 리스트를 1회 선형탐색하는 O(N)으로는 답을 구하기가 어렵다는 것을 파악했다. 이후에 DFS로 한번 구현해보려 했는데, 오늘은 협력사 발표 이슈가 있어서 일찍 마무리하다보니 시간이 부족했다. 프로젝트 후에 다시 풀어봐야지 . . . .