Today I Learned

[내일배움캠프 QA/QC 트랙 6기 본캠프] TIL #012

JiJi0406 2026. 5. 27. 20:50

 

 

그동안 배운 내용 한번 싹 복기할 겸 라이브 세션 녹화본을 2배속으로 돌려봤다.

영상을 멍하니 보기만 한다고 해서는 머리에 절~대로 안 들어옴 ㅎㅎ 튜터님이 세션 중에 질문 던지실 때마다 화면 일시정지 해놓고 직접 코딩해서 정답 맞히는 셀프 퀴즈쇼를 진행했다. 이렇게 하니까 확실히 머릿속에서 바로 안 튀어나오고 버벅거리는 구멍들이 어디인지 딱 드러나는 것 같다. 아는 것과 손으로 쓸 수 있는 건 엄연히 다르다는 걸 느끼며, 오늘 확인한 빵꾸 개념들을 TIL에 정리해보자.

 

 

[라이브 세션] : 허진성 튜터님  Python 실력 쑥쑥 심화 세션 3회차

 

 

오늘 라이브세션 내용은 CS 개념들이라, 모든 내용을 하나하나 다 외울 필요는 전혀 없음.

필요할 때마다 찾아보면 된다. 

 

1. 모듈, 패키지, 라이브러리

  • 모듈: 특정 기능을 수행하는 함수나 변수들을 모아놓은 파이썬 파일 하나 (작은 도구 상자)
  • 패키지: 관련 모듈들을 모아서 구조화해 놓은 디렉터리 (폴더)
  • 라이브러리: 수많은 패키지와 모듈을 모아둔 거대한 집합소 (도서관)
데이터 분석 필수 라이브러리: Pandas, Numpy, scikit-learn

 

 

 

2. datetime : 날짜/시간 다루기 모듈

%Y 네 자리 연도 2026
%m 숫자 월 05
%d 일(day) 27
%H 24시간 형식 시 14
%M 30
%S 00
%A 전체 요일명 Tuesday
 
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo

# 1. 현재 시각 구하기 및 타임존(KST) 설정
now_utc = datetime.now()
print("기본 서버 시각:", now_utc)

# 아시아/서울 타임존 타겟팅
now_kst = datetime.now(ZoneInfo("Asia/Seoul"))
print("한국 표준시(KST):", now_kst)

# 2. timedelta를 이용한 시간 연산 (배포 점검 시간 계산 등)
maintenance_start = datetime(2026, 5, 27, 23, 0)
maintenance_end = maintenance_start + timedelta(hours=3, minutes=30)
print("점검 종료 예정 시각:", maintenance_end)

# 3. 시간 차이 계산 및 초/분/시 단위 변환
time_diff = maintenance_end - maintenance_start
print("총 점검 소요 시간(초):", time_diff.total_seconds())
print("총 점검 소요 시간(분):", time_diff.total_seconds() / 60)

 

 

3. math : 수학 연산

기본적인 사칙연산 외에 올림, 내림, 제곱근 등 수학적 계산이 필요할 때 로드해서 쓴다. 

+ 부동 소수점(Floating Point)

컴퓨터는 0.1이나 0.2 같은 실수를 이진수로 저장할 때 완벽한 정밀도로 담지 못하고 근사치로 저장한다. 그래서 파이썬에서
0.1 + 0.2 == 0.3을 실행하면 False가 뜨는 참사가...
소수점 연산 결과값을 안전하게 비교하려면 math.isclose() 함수를 거쳐야 에러를 막을 수 있다.
import math

# 1. 기본 상수 및 정림 연산
print("원주율:", math.pi)
print("루트 25:", math.sqrt(25))        # 출력: 5.0 (항상 float 반환)
print("5의 3제곱:", math.pow(5, 3))     # 출력: 125.0

# 2. 올림, 내림, 버림 비교
print("올림 (4.1 ->):", math.ceil(4.1))   # 출력: 5
print("내림 (4.9 ->):", math.floor(4.9))  # 출력: 4
print("절사 (-4.9 ->):", math.trunc(-4.9)) # 출력: -4 (0에 가깝게 소수점 버림)

# 3. 부동 소수점 비교 버그 대처
print("0.1 + 0.2 == 0.3 결과:", 0.1 + 0.2 == 0.3)  # False 나옴
print("math.isclose 사용 결과:", math.isclose(0.1 + 0.2, 0.3))  # True 안전하게 판정

 

 

 

4. random : 난수 추출

무작위 데이터를 생성하거나 샘플을 추출할 때 사용하며, 데이터 분석에서 실험군을 무작위로 나눌 때도 자주 등장한다.

재현성이 중요할 때는 seed를 고정하면 매번 같은 결과가 나온다.

비밀번호/토큰 생성 등 보안이 필요한 경우엔 random 대신 secrets 모듈 사용

import random
import secrets
import string

# 1. 시드 고정으로 동일한 난수 재현하기
random.seed(777)
print("시드 고정 첫 번째 정수 리스트:", [random.randint(1, 10) for _ in range(3)])

# 2. 표본 추출 및 섞기 (가상 유저 대상 가중치 부여 포함)
testers = ["User_A", "User_B", "User_C", "User_D"]
print("무작위 1명 초이스:", random.choice(testers))
print("중복 없이 2명 추출:", random.sample(testers, 2))

# 가중치 부여 추출 (User_B가 뽑힐 확률을 5배 상향 조정)
print("가중치 적용 추출(5회):", random.choices(["User_A", "User_B", "User_C"], weights=[1, 5, 1], k=5))

# 리스트 제자리 순서 섞기 (원본 변형, 반환값은 None)
random.shuffle(testers)
print("무작위 셔플 결과 리스트:", testers)

# 3. 참고용 보안 난수 (임의의 임시 패스워드 생성)
char_pool = string.ascii_letters + string.digits
temp_password = "".join(secrets.choice(char_pool) for _ in range(8))
print("보안용 임시 토큰:", temp_password)

 

 

5. os — 파일/디렉터리 다루기

현재 작업 경로를 파악하거나 폴더 생성, 파일 목록 검색 등 운영체제(OS)의 기능을 파악하고 핸들링하는 필수 모듈이다. 경로를 합칠 때는 윈도우와 맥/리눅스의 슬래시 방향 차이로 생기는 에러를 막기 위해 무조건 os.path.join()을 쓰는 게 안전하다.

import os

# 1. 작업 디렉터리 확인 및 탐색
print("현재 파이썬 작업 경로:", os.getcwd())
print("현재 폴더 내 전체 아이템 리스트:", os.listdir("."))

# 2. 환경 독립적 안전한 경로 생성 및 검사
log_dir = "automation_logs"
file_name = "bug_report.txt"
full_path = os.path.join(log_dir, file_name)

print("결합된 상대 경로:", full_path)
print("절대 경로 변환:", os.path.abspath(full_path))
print("상위 폴더명 추출:", os.path.dirname(full_path))
print("실제 해당 파일이 존재하는가?:", os.path.exists(full_path))

# 3. 폴더 생성 및 하위 디렉터리 재귀 탐색
os.makedirs("automation_logs/daily", exist_ok=True)  # 폴더가 이미 있어도 에러 안 나게 방어
# os.walk를 쓰면 지정 폴더 하위 구조를 튜플 형태로 전부 긁어옴

 

 

[과제 및 지난 개념 리마인드 복습]

어제 제출했던 과제들도 다시 한 번 풀어봤는데, 풀다가 정리해두면 좋을 것 같은 내용이 생각나서 밑에 다시 정리해봤다.

 

 

1. 리스트 슬라이싱([start:end:step])과 range(start, end, step) 함수 : 범위 지정 비교

목적부터 다르다.

이미 있는 데이터에서 잘라오냐(슬라이싱) vs 새로운 숫자 시퀀스를 만들어내냐(range)

특징 리스트 슬라이싱 (list[start:end:step]) range 함수 (range(start, end, step))
목적 이미 존재하는 리스트에서 일부만 추출 규칙적인 정수 생성 (주로 for문 루프용)
결과물 타입 기존 데이터와 같은 타입 (리스트면 리스트) range 객체 (그 자체로는 숫자가 안 보임)
메모리 새로 추출한 리스트만큼 메모리 새로 먹음 아무리 큰 범위를 지정해도 메모리를 거의 안 먹음
생략 가능 여부 [:] 처럼 시작/끝 생략 가능 (전체 복사) start는 생략 가능(0부터 시작), 단 end는 필수

 

 

 

2. 딕셔너리 .items()와 중첩 구조 언패킹(Unpacking)

1) .items() 호출 시 타입 유지

딕셔너리 a에서 for b, c in a.items():를 돌리면, 변수 b와 c에는 딕셔너리에 저장되어 있던 원래 데이터의 타입이 그대로 유지되어 할당됨. 파이썬이 내부적으로 (Key, Value) 형태의 튜플을 알아서 분해(언패킹)해주기 때문

 

2) 중첩 구조의 언패킹 단계

만약 딕셔너리의 밸류가 [(d,e), (f,g)]와 같이 리스트 안에 튜플이 중첩된 구조라면, 겉에서부터 단계적으로 껍질을 까서 접근할 수 있음!!

# 예시 딕셔너리 구조
a = {
    "data": [("d", "e"), ("f", "g")]
}

for b, c in a.items():
    # 1단계: b = "data" (str), c = [("d", "e"), ("f", "g")] (list) -> 통째로 리스트 타입 유지됨!
    
    # 2단계: c[0]을 통해 첫 번째 튜플인 ("d", "e")에 접근 가능
    v, x = c[0]  
    # 언패킹 메커니즘에 의해 v = "e", x = "f"로 각각 자동 할당됨!

 

오키...?