[내일배움캠프] 데이터 분석 17일차 파이썬, SQLD 등

양호걸·2025년 11월 11일

오늘의 학습

라이브 세션

파이썬

컴프리헨션, 예외 처리 -> 파이썬이라서 더 중요한 문법
파이써닉(pythonic) 깔끔하고 읽기 좋은 코드로 작성, 일단 시도하고 처리

컴프리헨션: 반복문을 한 줄로 줄이는 문법
for, if
주의사항: 식 자체가 너무 복잡해지면 사용하면 안 됨

리스트 컴프리헨션

# [ 표현식 for 변수 in 반복대상 if 조건문 ]
result = []
for i in range(1, 5):
    result.append()
 print(result) # [1, 2, 3, 4]
 print([i for i in range(1, 5)]) # [1, 2, 3, 4] 리스트 선언, append
result2 = []
for i in range(1, 6):
    result2.append(i**2)

[i**2 for i in range(1, 6)]
result3 = []
for i in range(1, 6):
    if i % 2 == 0:
        result3.append(i**2)

[i**2 for i in range(1, 6) if i % 2 == 0]

딕셔너리 컴프리헨션 -> 키, 값
{ 키표현식: 값표현식 for 변수 in 반복대상 if 조건 }

students = ['철수', '영희', '유선']
{ student: 0 for student in students }
 # {'철수': 0, '영희': 0, '유선': 0}
words = ["Python", "Data", "AI"]
lengths = {word: len(word) for word in words}

result = {w: len(w) for w in words if len(w) >= 3}
nums = [1, 2, 3, 4, 5]  # 1: 1^2, 2: 2^2
sq = {n: n**2 for n in nums}
# 키 값 -> for 생성 숫자값으로
# [1, 2, 3] 0: 1, 1: 2, 2: 3
names = ["ha", "yh", "jh"]
re = {i: name for i, name in enumerate(names)}
# enumerate -> 자동으로 인덱스, 값 -> 쌍으로 생성
names = ["ha", "yh", "jh"]
dic = {}
for i, name in enumerate(names): # (0, "ha"), (1, "yh"), (2, "jh")
    dic[i] = name

셋 컴프리헨션
#set(1, 2, 3, 3, 4, 5)
#중복을 허용하지 않는 자료형 -> 중복 제거

names = ["Ha", "yh", "YH", "ha", "jh"]  # 소문자, 대문자
unique = {name.lower() for name in names}  # 셋 컴프리헨션
print(unique) # {'yh', 'jh', 'ha'}
s = {1, 2, 3}

xxxx 튜플 컴프리헨션 xxxx

중첩 컴프리헨션

구구단
n 입력 -> n x 1 = n .... n x 9 = 9n

inp = int(input())
for i in range(1, 10):
    print(f"{inp} x {i} = {inp * i}")

전체 구구단 세트
2 x 1 = 2 ... 2 x 9 = 18 2 x i = 2 i -> 9번
3 x 1 = 1 ... 3 x 9 = 27 3 x i = 3
i
...
9 x 1 = 9 ... 9 x 9 = 81 9 x i = 9 * i
변수가 두 개

for i in range(2, 10):
    for j in range(1, 10):
        print(f"{i} x {j} = {i * j}")

2중 for문을 리스트 컴프리헨션으로 표현

li = [f"{i} x {j} = {i * j}" for i in range(2, 10) for j in range(1, 10)]

[....]
for l in li:
    print(l)

'''
i=2 : j=1 ~ j=9
i=3 : j=1 ~ j=9
i=4 : j=1 ~ j=9
'''

예외 처리
2 <= n <= 9

def gugudan(n):
    for i in range(1, 10):
        print(f"{n} x {i} = {n * i}")

2 ~ 9 아닌 값 처리 -> 예외 처리
문자 입력 -> 예외 처리
--> 우리가 원하는 목적대로만 동작하게 만들어주는 것

try:
문제가 생길 수 있는 코드
범위 확인
조건문 -> not (2 <= n <= 9)
다시 입력해주세요
except:
문제가 생겼을 때의 처리 코드
else: (선택)
예외가 발생하지 않았을 때 실행하는 코드
finally: (선택)
예외가 있건 없건 무조건 실행하는 코드

def gugudan(n):
    try:
         경우 따지기
         타입 확인
        if not isinstance(n, int):
            raise TypeError("정수를 입력해주세요.")
        
         범위 확인
        if not (2 <= n <= 9):
            raise ValueError("2-9까지 숫자를 입력해주세요.")

        for i in range(1, 10):
            print(f"{n} x {i} = {n * i}")
        
    except ValueError as ve:
        print(f"[범위 오류] {ve}")
    except TypeError as te:
        print(f"[타입 오류] {te}")
    
    finally:
        print("함수가 실행되었습니다.")

gugudan(2) # "함수가 실행되었습니다."
gugudan(5) # "함수가 실행되었습니다."
gugudan("5") # "함수가 실행되었습니다."

dic = {"a":1, "b":2}
dic["c"] # 프로그램 자체가 멈춤
dic.get("c") # 오류를 보여주고 계속 진행됨 None

SQLD 자격증 챌린지

15 SQLD 파트 요약
15-1 Part 1 요약
15-2 Part 2 요약

오늘의 solvesql

폐쇄할 따릉이 정류소 찾기 2

WITH usage_2018 AS (
  SELECT
    station_id,
    COUNT(*) AS usage_count_2018
  FROM (
        SELECT rent_station_id AS station_id, 
               rent_at AS used_at
        FROM rental_history
        WHERE rent_at >= '2018-10-01' AND rent_at < '2018-11-01'
        UNION ALL
        SELECT return_station_id AS station_id, 
               return_at AS used_at
        FROM rental_history
        WHERE return_at >= '2018-10-01' AND return_at < '2018-11-01'
  ) AS t
  GROUP BY station_id
),
usage_2019 AS (
  SELECT
    station_id,
    COUNT(*) AS usage_count_2019
  FROM (
        SELECT rent_station_id AS station_id, 
               rent_at AS used_at
        FROM rental_history
        WHERE rent_at >= '2019-10-01' AND rent_at < '2019-11-01'
        UNION ALL
        SELECT return_station_id AS station_id,
               return_at AS used_at
        FROM rental_history
        WHERE return_at >= '2019-10-01' AND return_at < '2019-11-01'
  ) AS t
  GROUP BY station_id
)
SELECT s.station_id,
       s.name,
       s.local,
       ROUND((u19.usage_count_2019 / u18.usage_count_2018) * 100, 2) AS usage_pct
FROM station s
     INNER JOIN usage_2018 u18 ON s.station_id = u18.station_id
     INNER JOIN usage_2019 u19 ON s.station_id = u19.station_id
WHERE u18.usage_count_2018 > 0
  AND u19.usage_count_2019 > 0
  AND (u19.usage_count_2019 / u18.usage_count_2018) <= 0.5
ORDER BY usage_pct;

그냥 어렵고 오래 걸린 문제.
2018년 10월 정류소별 이용 건수를 집계하는데 대여와 반납을 각각 카운트해서 합쳐야하기 때문에 중복을 제거하지 않기 위해 UNION ALL을 사용
2019년도 동일한 방법으로 구함.
정류소 테이블과 집계한 두 연도의 테이블을 조인한 뒤, 2019년의 사용량이 2018년 대비 50%이하인 정류소만 출력
UNION을 많이 안써봐서 그런지 아직 헷갈리고 언제 어떻게 써야할지 잘 모르겠는 느낌..
정류소와 2018년 조인 그리고 그걸 2019년과 또 조인 INNER JOIN도 두번 해야해서 쉽지 않았다.

피드백 or 느낀점

오전에 코드카타 10문제 풀었다. 아직은 낮은 레벨이라 금방금방 풀림. 덕분에 자존감 챙기고 하루시작ㅋ굳

라이브 세션 파이썬 - 갑자기 훅 어려워진 느낌.. 넘 헷갈린다.. 복습하면서 문제도 좀 풀고 해야겠다. SQL도 쉽진 않았지만 그래도 뭔가 하면서 실력향상은 쬐끔씩 되는 느낌이었는데 파이썬은 늘고 있는게 맞는건지 내가 알고 있긴 한건지 왜케 어려운건지.. 파이썬이 진짜 직관적이고 쉬운 언어는 맞는건지.. 모르겠다 어렵다ㅠㅠ 파이써닉한 인간이 되어야할텐데

SQLD는 여러 자료들이랑 기출문제 풀면서 계속 공부중.. 60점은 넘겠지..?

내일 학습 할 것은 무엇인지

SQLD 기출 반복
solvesql 문제 꾸준히 풀기
파이썬도 문제 꾸준히 풀기 시작하자

#내일배움캠프 #TIL #데이터분석 #실무형데이터분석가양성과정

0개의 댓글