💥 CODEKATA
~ 73문제
✅ 오늘 배운 것
NULL AS 컬럼명 : 열(컬럼)을 생성할 때 명시적으로 NULL 값을 할당하는 데 사용
SET @변수명 : 변수 선언 및 값 할당
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
⇒
- @hour = -1 ❓❓ : @hour = 0 을 하게 되면 0시가 누락되고 1시부터 시작함
- := ❓❓ : 할당 연산자. = 는 비교 연산자로도 사용되지만 얘는 명확하게 값 대입만을 위한 할당 연산자
파이썬 코드로 나타내면 이거랑 똑같은 듯
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))
아티클
더보기
오늘의 아티클 (주제)
- **요약**
- 나쁜 코딩 습관을 쉽게 고치는 방법을 일러줌
- **주요 포인트**
- import * 사용 X ⇒ 사용하려는 특정 객체를 부르거나, 전체 모듈을 불러운 후 객체를 사용하기 전에 모듈명 명시
- except 절에 예외를 꼭 지정하자
- numpy 사용하자 ⇒ for 문 사용하는 것보다 더 빠르게 해결해줌
- 파이썬으로 열었던 파일을 닫자 ⇒ with 구문 사용해서 예외 발생시에도 파일을 정상적으로 닫을 수 있게 해야함
- PEP8 가이드라인을 지키자
- 딕셔너리의 key와 value를 올바르게 사용하기
- 컴프리헨션 적절하게 사용하기
- range(len()) 대신 enumerate, 두가지 리스트를 함께 반복하는 경우는 zip 사용하기
- 연산자 사용 x ⇒ f스트링 사용하기
- 함수의 기본 인수로 리스트 같은 가변 객체 사용 X ⇒ 의도치 않은 문제 발생할 수 있으므로 None 사용하고, 함수 내부에서 선언하기
- **핵심 개념**
- PEP8 ****: 파이썬 공식 코드 스타일 가이드
- **개인 인사이트**
---
range와 len만 사용해서 읽다가 매우 뜨끔했다.
enumerate, zip 은 강의에서만 듣고 실제로 한 번도 사용해본 적이 없다. 쓰는 법을 연습해야겠다.
또한 컴프리헨션도 익숙치 않아서 그냥 쭉 풀어쓰는데 또한 연습해야겠다.
'Sparta > CODEKATA' 카테고리의 다른 글
| [250829] 스파르타코딩 본캠프 19일차 (2) - QCC (2) | 2025.08.29 |
|---|---|
| [250828] 스파르타코딩 본캠프 18일차 (2) (1) | 2025.08.28 |
| [250826] 스파르타코딩 본캠프 16일차 - 도전과제 (3) | 2025.08.26 |
| [250825] 스파르타코딩 본캠프 15일차 (2) - 필수과제 (2) | 2025.08.25 |
| [250824] 파이썬 코테 01 (3) | 2025.08.24 |