64일차

Suhyeon Lee·2024년 12월 31일

CodeKata

SQL

프로그래머스: 연도별 평균 미세먼지 농도 조회하기

  • 작성한 쿼리
SELECT
  YEAR(ym) AS `YEAR`
  , ROUND(AVG(pm_val1), 2) AS "PM10"
  , ROUND(AVG(pm_val2), 2) AS "PM2.5"
FROM
  air_pollution
WHERE
  location1 = '경기도'
  AND location2 = '수원'
GROUP BY
  YEAR(ym)
ORDER BY
  YEAR(ym)
;

프로그래머스: 한 해에 잡은 물고기 수 구하기

  • 작성한 쿼리
-- 1
SELECT
  COUNT(*) AS fish_count
FROM
  fish_info
WHERE
  YEAR(time) = 2021
;

-- 2
SELECT
  COUNT(*) AS fish_count
FROM
  fish_info
WHERE
  DATE_FORMAT(time, '%Y') = '2021'

프로그래머스: 분기별 분화된 대장균의 개체 수 구하기

  • 작성한 쿼리
SELECT
  CONCAT(QUARTER(differentiation_date), 'Q') AS QUARTER
  , COUNT(id) AS ECOLI_COUNT
FROM
  ECOLI_DATA
GROUP BY
  QUARTER
ORDER BY
  QUARTER
;

참고할 만한 다른 풀이

-- 1
SELECT
    CONCAT(CEIL(MONTH(DIFFERENTIATION_DATE) / 3), 'Q') QUARTER
    , COUNT(ID) ECOLI_COUNT
FROM
    ECOLI_DATA
GROUP BY
    QUARTER
ORDER BY
    QUARTER

-- 2
SELECT 
(CASE 
    WHEN MONTH(DIFFERENTIATION_DATE) BETWEEN 1 AND 3 THEN '1Q'
    WHEN MONTH(DIFFERENTIATION_DATE) BETWEEN 4 AND 6 THEN '2Q'
    WHEN MONTH(DIFFERENTIATION_DATE) BETWEEN 7 AND 9 THEN '3Q'
    ELSE '4Q'
 END) QUARTER, 
COUNT(*) ECOLI_COUNT
FROM ECOLI_DATA
GROUP BY QUARTER
ORDER BY QUARTER ASC

Python

73. 공원 산책

  • 작성한 코드
def solution(park, routes):
    answer = []
    
    x, y = 0, 0
    w, h = len(park[0]), len(park)
    direction = {'E':(0, 1), 'W':(0, -1), 'S':(1, 0), 'N':(-1, 0)}
    
    for i in range(h):
        for j in range(w):
            if park[i][j] == 'S':
                x, y = i, j
                break
    
    for r in routes:
        d, n = r.split(' ')
        x_now, y_now = x, y
        
        for i in range(int(n)):
            x_move = x + direction[d][0]
            y_move = y + direction[d][1]
            
            if 0 <= x_move <= h-1 and 0 <= y_move <= w-1 and (park[x_move][y_move] != 'X'):
                x, y = x_move, y_move
            else:
                x, y = x_now, y_now
                break
    answer = [x, y]
    return answer

참고할 만한 다른 풀이

  1. 클래스 활용
class Dog:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.g = {"N": (-1, 0), "W": (0, -1), "E": (0, 1), "S": (1, 0)}

    def move(self, park, direction, distance):
        i, j = self.g[direction]
        x, y = self.x + (i * distance), self.y + (j * distance)
        if x < 0 or y < 0 or x >= len(park) or y >= len(park[0]):
            return park
        elif "X" in park[x][min(self.y, y) : max(self.y, y) + 1] or "X" in [
            row[y] for row in park[min(self.x, x) : max(self.x, x)]
        ]:
            return park
        park[self.x][self.y] = "O"
        park[x][y] = "S"
        self.x = x
        self.y = y
        return park

    @classmethod
    def detect_start_dogs_location(self, park):
        for i, row in enumerate(park):
            for j, item in enumerate(row):
                if item == "S":
                    return i, j


def solution(park, routes):
    park = [list(row) for row in park]
    x, y = Dog.detect_start_dogs_location(park)

    dog = Dog(x, y)

    for route in routes:
        direction, distance = route.split()
        park = dog.move(park, direction, int(distance))

    return [dog.x, dog.y]
dx = {'N':-1, 'S':1, 'E':0, 'W': 0}
dy = {'N': 0, 'S':0, 'E':1, 'W':-1}

def solution(park, routes):
    answer = []
    x, y = -1, -1
    N, M = len(park), len(park[0])
    for i in range(N):
        for j in range(M):
            if park[i][j] == 'S':
                x, y = i, j

    for route in routes:
        dir_, dist = route.split(' ')

        isFalse = False
        for i in range(1, int(dist) + 1):
            nx, ny = x + dx[dir_] * i, y + dy[dir_] * i
            if nx < 0 or ny < 0 or nx > N-1 or ny > M-1:
                isFalse = True
                break
            if park[nx][ny] == 'X':
                isFalse = True
                break

        if isFalse:
            continue
        nx, ny = x + dx[dir_] * int(dist), y + dy[dir_] * int(dist)
        x, y = nx, ny

    answer = [x, y]

    return answer
def solution(park, routes):
    W = len(park[0])
    park = [['X']*(W+2)] + [[*'X'+i+'X'] for i in park] + [['X']*(W+2)]

    x,y = 1,0
    while park[x][y]!='S':
        y += 1
        if y>W:
            x,y = x+1,0

    delta = {k:v for k,v in zip('NEWS',[(-1,0),(0,1),(0,-1),(1,0)])}
    for i in routes:
        v,d = i.split()
        for k in range(1,int(d)+1):
            X,Y = x+k*delta[v][0], y+k*delta[v][1]
            if park[X][Y]=='X':
                break
        else:
            x,y = X,Y
    return [x-1,y-1]
  • 바운더리를 장애물로 각인을 시켜버리는 아이디어
def solution(park, routes):

    # 공원의 높이와 너비 계산
    H = len(park)
    W = len(park[0])

    # 시작점 "S"의 인덱스 추출
    for i, element in enumerate(park):
        arr = list(element)
        if "S" in arr:
            start = [i, list(arr).index("S")]

    pos = start

    for route in routes:

        # 명령어 입력 처리
        op, n = route.split(' ')
        n = int(n)

        obstacle = 0  #장애물을 마주칠시 1로 바뀌는 변수(스위치)


        # 북쪽으로 이동하는 경우
        if op == 'N':
            if pos[0] - n < 0:
                print("Out of range: N")
                continue
            else:
                for i in range(1, n+1):
                    if "X" == park[pos[0] - i][pos[1]]:
                        obstacle = 1
                        print("Obstacle encountered: N")
                        continue

            if obstacle == 1:
                continue
            else:
                pos[0] -= n
                print("Operation Complete: N")

        # 남쪽으로 이동하는 경우
        elif op == 'S':
            if pos[0] + n > H-1:
                print("Out of range: S")
                continue
            else:
                for i in range(1, n+1):
                    if "X" == park[pos[0] + i][pos[1]]:
                        obstacle = 1
                        print("Obstacle encountered: S")
                        continue

            if obstacle == 1:
                continue
            else:                
                pos[0] += n
                print("Operation Complete: S")

        # 서쪽으로 이동하는 경우
        elif op == 'W':
            if pos[1] - n < 0:
                print("Out of range: W")
                continue
            else:
                for i in range(1, n+1):
                    if "X" == park[pos[0]][pos[1] - i]:
                        obstacle = 1
                        print("Obstacle encountered: W")
                        continue

            if obstacle == 1:
                continue
            else:
                pos[1] -= n
                print("Operation Complete: W")

        # 동쪽으로 이동하는 경우
        elif op == 'E':
            if pos[1] + n > W-1:
                print("Out of range: E")
                continue
            else:
                for i in range(1, n+1):
                    if "X" == park[pos[0]][pos[1] + i]:
                        obstacle = 1
                        print("Obstacle encountered: E")
                        continue
            if obstacle == 1:
                continue
            else:
                pos[1] += n
                print("Operation Complete: W")


    answer = [pos[0], pos[1]]
    return answer

GIS

공간 정보 데이터 이해하기

최종 프로젝트 관련

브레인스토밍

  1. 국내에서 정책적으로 지원하는 분야/육성 분야 : 콘솔, 인디게임
    → 전략적 움직임?
  2. 국내 게임사들의 장르, 플랫폼 다변화, 해외 진출
  3. 확률형 아이템 규제의 여파로 새로운 비즈니스 모델에 대한 논의
  4. 블록체인 게임?
    ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
  5. 게임회사에서 데이터 사이언티스트는 뭘 하는가?
  6. 서브컬쳐 게임 - 넓은 의미의 수집형 게임
    트렌드와는 묶을 수 있지만 데이터 수집이 어려움
    매출도 확인이 어렵고
  7. 결국 라이브 게임 서비스를 하나 정해서 그 게임 데이터를 하는 방법 밖에는 없을 것 같음
  8. 스팀 게임 데이터로 장르, 특징 들로 분류, 할인 정보
  • 게임 산업과 개인 방송
  1. 개인방송 플렛폼의 상위 스트리머들이 어떤 게임을 했는지 순위를 매겨 보고, 이후 스팀이나 구글 플레이에서 얼마나 사용자, 매출의 변동
  2. 특정 게임만 하는 유튜버의 조회수 추이를 보며 게임의 화제성을 본다.
  3. 종합 게임 유튜버들의 조회수
  4. 1년 간 출시되었던 게임 장르를 분석해서 유행과 방향 예측
  5. 어떤 게임이 시청자를 가장 많이 끌어올렸는지
  6. 구독 서비스에 대한 분석
  7. 스트리머에게 광고를 줬을 때와 소문 듣고 했을 때의 차이
  • 특정 게임에 대한 분석
  1. 특정 게임의 통계 사이트를 만들어본다.
  2. 훅속작이 출시 예정인 게임을 전작과 비교해서분석
  3. 밸런스나 경제 시스템
  4. 사전 예약과 게임의 성공
  • 서브컬쳐
  1. 여러 게임들의 과금 효율성을 비교 분석
  2. 파워 인플레에 대한 고찰
  3. 컨트롤 게임보다 분재게임에 사람들이 빠지는 이유

스팀 동시동접사수 파악하기

장르 유형 게임 수명분석

국가별 게임 플레이 방식 비교하여 특정 이벤트 제시

스팀 도전과제를 활용한 게임 or 유저 분석
스팀 내에 도전과제가 게임의 플레이 시간, 유저 만족도에 영향을 미치는가?
도전과제를 분류해서 타게임에서 성취한 도전과제에 따라 새로운 게임을 추천해주는 모델 구현?

게임 수명 분석 -> 스팀 게임의 접속률을 기반으로 분석 (출시가 오래됐지만 여전히 접속률이 있는 게임들의 특징)
게임 산업과 개인 방송의 관계 -> 게임 서비스와 유튜버의 영상콘텐츠의 화제성을 분석해봄
게임 하나 선정 후 내 외부 데이터 분석

<소현 튜터님 말씀 정리>
게임 수명 분석 -> 스팀 게임의 접속률을 기반으로 분석 (출시가 오래됐지만 여전히 접속률이 있는 게임들의 특징)
게임 산업과 개인 방송의 관계 -> 게임 서비스와 유튜버의 영상콘텐츠의 화제성을 분석해봄
☞ 둘 다 할 수 있으면 합쳐서? 엮어서? 하나의 프로젝트로 해보는 걸 추천(기획 자체는 나쁘지 않아요)
☞ 데이터셋 선정이 가장 중요
1. 어떤 데이터를 수집할 수 있는지 리스트업 한 뒤 소현 튜터님과 이야기하기
e.g.
스팀 API를 통해 얻을 수 있는 정보 → 동접자수, 접속률, …
유튜브 API를 통해 얻을 수 있는 정보 → 언급된 게임명, 조회수 등
☞ 수집된 데이터를 보면서 어떤 걸 할 수 있는지 코멘트를 해 주실 수 있다고 하셨음
2. 가져올 수 있는 데이터 컬럼의 수가 몇 개인지가 중요함
→ 동접자 수 달랑 하나만 있는 걸로는 분석을 더 이상 진행할 수 없기 때문
3. 언제부터 언제까지의 데이터를 가져올 수 있는지가 중요
2024년 데이터만 있고 그 전의 데이터가 없다면 연간 분석 불가능하니까
★핵심★
날짜 데이터, 컬럼 많으면 분석할 게 많아서 좋음
어떤 걸 적용하더라도 도전할 수 있을 법한 데이터셋이 나와야 함!
프로젝트 중간에 데이터 수집 고민하지 않도록(비효율적임)
7일 전까지 특강 들으며 데이터 수집을 좀 더 고민할 것
(API 통신, 크롤링 특강 듣고 데이터를 직접 수집할 것)
kaggle 데이터보다는 live한 데이터를 우선적으로 생각할 것
(향후 면접관/인사담당자 고려)
있을 법한 인사이트 도출하기

회고

  • 2025년이 오다니… 2024년에 정말 많은 일들이 있었지만 잘 극복하고 새로운 한 해를 맞이하게 되어 다행이다!
profile
2 B R 0 2 B

0개의 댓글