Sparta/CODEKATA

[250827] 스파르타코딩 본캠프 17일차

junecho 2025. 8. 27. 14:10

💥  CODEKATA                                                                                                           

~ 73문제

 

오늘 배운 것

NULL  AS  컬럼명  : 열(컬럼)을 생성할 때 명시적으로 NULL 값을 할당하는 데 사용

SET  @변수명  : 변수 선언 및 값 할당

 

 

 

71)   오프라인/온라인 판매 데이터 통합하기

WITH ons AS (
    SELECT
        DATE_FORMAT(sales_date, "%Y-%m-%d") as sales_date, product_id, user_id, sales_amount
    FROM
        online_sale
    WHERE
        sales_date LIKE "2022-03-%"
),
offs AS (
    SELECT
        DATE_FORMAT(sales_date, "%Y-%m-%d") as sales_date, product_id, 
        NULL AS user_id, sales_amount
    FROM
        offline_sale
    WHERE
        sales_date LIKE "2022-03-%"
),
unioned AS (
    SELECT * FROM ons
    UNION ALL
    SELECT * FROM offs
)
SELECT
    sales_date, product_id, user_id, SUM(sales_amount) AS sales_amount
FROM 
    unioned
GROUP BY
    1,2,3
ORDER BY
    1,2,3

오…UNION 할 때 컬럼 갯수가 동일해야 하는데, offline 테이블에는 user_id 가 없어서 안되나 싶었는데 NULL  AS user_id 하고 만들면 됐다

WITH 1개 이상은 써보고 UNION도 처음 써봄!

 

 

 

 

73)  입양 시각 구하기 (2)

SELECT 
    HOUR(datetime) AS hour, count(1) as count
FROM 
    animal_outs
GROUP BY
    1
ORDER BY
    1

HOUR() 로 시간을 뽑았더니 존재하는 시간대만 나오고 문제에서의 0~23시 전체가 출력되지 않음.

검색해보니 SET 을 사용한다함

SET 문법을 처음 봐서 그냥 답코드 복사해옴

SET @변수명 = 값;
SELECT @변수명 AS 별칭
# 답코드
SET
    @hour = -1;
SELECT 
    @hour := @hour + 1 AS hour,
    (SELECT count(1)
    FROM animal_outs
    WHERE @hour = hour(datetime)) AS count
FROM 
    animal_outs
WHERE 
    @hour < 23

  1. @hour = -1 ❓❓ : @hour = 0 을 하게 되면 0시가 누락되고 1시부터 시작함
  2. := ❓❓ : 할당 연산자. = 는 비교 연산자로도 사용되지만 얘는 명확하게 값 대입만을 위한 할당 연산자

파이썬 코드로 나타내면 이거랑 똑같은 듯

hour = -1
result = []

for hour in range(-1,23):
    hour += 1
    result.append(hour)

print(result)

# 출력 >>> 
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]

 

 

 

 


 

개인과제 해설 답안

더보기
# 03 - 답코드
text1 = "a1b23c004"

def sum_of_digits(text):
    num_sum = 0
    for i in text:
        if i.isdigit():
            num_sum += int(i)
    return num_sum

print(sum_of_digits(text1))

########################################################################

# 04 - 답코드
scores = {"Alice": 85, "Bob": 52, "Chris": 60, "Dana": 59}

def grade_pass_fail(scores, threshold=60):
    result = {"pass": 0, "fail": 0}
    for k, v in scores.items():
        if v>= threshold:
            result['pass'] += 1
        else:
            result['fail'] += 1
    return result


print(grade_pass_fail(scores))

######################################################################## 

# 05 - 답코드 1번째
current = {"apple": 5, "banana": 2, "milk": 1}
arrival = {"banana": 3, "bread": 4, "milk": 2}

def merge_inventory(current, arrival):
    result = current.copy()
    for k, v in arrival.items():
        # result[k] = result.get(k, 0) + v 
        if k in result:
            result[k] += v
        else:
            result[k] = v

    return 0

print(merge_inventory(current, arrival))

# 05 - 답코드 2번째
current = {"apple": 5, "banana": 2, "milk": 1}
arrival = {"banana": 3, "bread": 4, "milk": 2}

def merge_inventory(current, arrival):
    result = {k: current.get(k,0) + arrival.get(k,0) for k in current.keys() | arrival.keys()}
    return result

print(merge_inventory(current, arrival))

######################################################################## 

# 06 - 답코드 1번째
nums1 = [2, 7, 11, 15]
target1 = 9

def two_sum(nums, target):
    for i in range(len(nums)):
        for j in range(i+1, len(nums)):
            if nums[i] + nums[j] == target:
                return (i, j)
    return (-1, -1)

print(two_sum(nums1, target1))

# 06 - 답코드 2번째
nums1 = [2, 7, 11, 15]
target1 = 9

def two_sum(nums, target):
    # 숫자 7을 i=1 에서 처음 보면 seen[7] = 1
    seen = {}
    for i, x in enumerate(nums):
        need = target - x
        if need in seen:
            return (seen[need], i)
        seen[x] = i
    return (-1, -1)

print(two_sum(nums1, target1))

######################################################################## 

# 07 - 답코드
data = [10, 20, 30, 40, 50]
k = 3

def moving_average(data, k):
    if k <= 0 or k > len(data):
        return []
    
    result = []
    window_sum = sum(data[:k])
    result.append(round(window_sum/k, 2))
    
    for i in range(k, len(data)):
        window_sum += data[i] - data[i-k]
        result.append(round(window_sum/k, 2))
    return result
    
print(moving_average(data, k))

######################################################################## 

# 08 답코드
nums = [1, 2, 3, 5, 7, 8, 9]

def compress_ranges(nums):
    if not nums:
        return ""
    
    # parts = 완성된 구간 리스트를 쌓아둘 리스트 (결과 리스트)
    # starts = 현재 연속 구간의 시작 값
    # prev = 방금까지 본 마지막 값
    parts = []
    starts = prev = nums[0]
    
    for x in nums[1:]:
        # 다음 원소 x가 직전 값 prev의 다음 연속이면 
        # 구간 확장
        if x == prev + 1:
            prev = x
        else:
            # 연속이 끊어졌다면
            # 지금까지의 구간 start ~ prev 를 문자열로 확정 -> parts에 넣음
            if starts == prev:
                parts.append(str(starts))
            else:
                parts.append(f"{starts}-{prev}")
            starts = prev = x
    if starts == prev:
                parts.append(str(starts))
    else:
        parts.append(f"{starts}-{prev}") 
    return ",".join(parts)

print(compress_ranges(nums))

 

 


 

아티클

더보기

오늘의 아티클 (주제)


주제 : 파이썬 초보자가 저지르는 10가지 실수


- **요약**
    - 나쁜 코딩 습관을 쉽게 고치는 방법을 일러줌
- **주요 포인트**
    - import * 사용 X ⇒ 사용하려는 특정 객체를 부르거나, 전체 모듈을 불러운 후 객체를 사용하기 전에 모듈명 명시
    - except 절에 예외를 꼭 지정하자
    - numpy 사용하자 ⇒ for 문 사용하는 것보다 더 빠르게 해결해줌
    - 파이썬으로 열었던 파일을 닫자 ⇒ with 구문 사용해서 예외 발생시에도 파일을 정상적으로 닫을 수 있게 해야함
    - PEP8 가이드라인을 지키자
    - 딕셔너리의 key와 value를 올바르게 사용하기
    - 컴프리헨션 적절하게 사용하기
    - range(len()) 대신 enumerate, 두가지 리스트를 함께 반복하는 경우는 zip 사용하기
    - 연산자 사용 x ⇒ f스트링 사용하기
    - 함수의 기본 인수로 리스트 같은 가변 객체 사용 X ⇒ 의도치 않은 문제 발생할 수 있으므로 None 사용하고, 함수 내부에서 선언하기
- **핵심 개념**
    - PEP8 ****: 파이썬 공식 코드 스타일 가이드
- **개인 인사이트**
    
    ---
    
    range와 len만 사용해서 읽다가 매우 뜨끔했다. 
    
    enumerate, zip 은 강의에서만 듣고 실제로 한 번도 사용해본 적이 없다. 쓰는 법을 연습해야겠다.
    
    또한 컴프리헨션도 익숙치 않아서 그냥 쭉 풀어쓰는데 또한 연습해야겠다.