sql

select 문의 기본 문법

  1. SQL문 작성 규칙

    (1) 대소문자 구별 하지 않음

    • 명령어 대문자, 나머지 소문자로 작성하길 권장함

    (2) 한줄 또는 여러줄로 작성 가능

    • 코드 수준에 따른 들여쓰기는 SQL문장의 가독성을 좋게함
  2. 전체 데이터 조회하기

    (1) employees 테이블의 모든 정보를 출력하세요.

    SELECT *
    FROM employees;

    * : 모든 열 조회
    FROM : ~ 테이블로부터 라는 의미

  3. 원하는 열만 조회하고 정렬하기
    (1) employees 테이블에서 employees_id, first_name과 last_name을 출력하세요.

    SELECT employees_id, first_name, last_name
    FROM employees;

    (2) employees 테이블에서 employee_id, first_name, last_name을 출력하고 employee_id를 기준으로 내림차순으로 정렬하세요.

    SELECT employee_id, first_name, last_name
    FROM employees
    ORDER BY employee_id DESC;

    • ORDER BY 명령문 default : 오름차순 정렬(ASC)
    • ORDER BY 열 이름, 열 이름 DESC, 열 이름 ASC 가능
  4. 중복된 출력 값 제거하기

    (1) employees 테이블에서 중복 값이 생기지 않도록 job_id를 출력하세요.

    SELECT DISTINCT job_id
    FROM employees;

    • DISTINCT 명령어 뒤에 열 이름을 계속 나열하면 순서대로 DISTINCT가 모두 적용됨
  5. SQL 문을 효율적으로 작성하기 위해 별칭 사용하기
    (1) employees 테이블에서 employees_id는 ‘사원번호’, first_name은 ‘이름’, last_name은 ‘성’으로 출력하세요.

    SELECT employees_id AS 사원번호, first_name AS 이름, last_name AS 성
    FROM employees;

  6. 데이터 값 연결하기
    (1) employees 테이블에서 employees_id를 출력하고 first_name과 last_name을 붙여서 출력하세요.

    SELECT employees_id, first_name||last_name
    FROM employess;

    (2) employees 테이블에서 employee_id를 출력하고, first_name과 last_name을 붙여서 출력하되 가운데 한 칸을 띄워주세요. 다음 열에는 email을 출력하되 @company.com 문구를 붙여서 출력하세요.

    SELECT employee_id, first_name||’ ‘||last_name, email||@company.com
    FROM employees;

  7. 산술 처리하기 : 데이터 값끼리 계산
    (1) employees 테이블에서 employee_id, salary, salary에 500을 더한 값, 100을 뺀 값, 10%를 추가해서 2로 나눈 값을 출력하세요.

    SELECT employee_id, salary, salary+500, salary-100, (salary1.1)/2
    FROM employees;
    (2) employees에서 employee_id를 ‘사원번호’, salary를 ‘급여’, salary+500을 ‘추가급여’, salary-100을 ‘인하급여’, (salary
    1.1)/2를 ‘조정급여’로 출력하세요.

    SELECT employee_id AS 사원번호,
                    salary AS 급여,
                    salary+500 AS 추가급여,
                    salary-100 AS 인하급여,
                    (salary*1.1)/2 AS 조정급여
    FROM employees;

자료출처: 모두의 SQL

cosine 유사도

코사인 유사도(cosine similarity)

  • 벡터의 내적 : 1부터 -1까지의 값을 가짐
  • 0 = cos90° = 두 벡터의 방향이 서로 독립(유사하지 않음)
  • 1 = cos0° = 두 벡터의 방향이 서로 완전히 같음
  • -1 = cos180° = 두 벡터의 방향이 서로 반대임

사용 분야

  • 유사도 측정 시 사용
  • 정보 검색 : 문서의 유사함을 측정하는 방법
  • 텍스트 마이닝 : 클러스터의 응집도를 측정하는 방법
  • 거리함수로 사용할 수 없음

위키백과 코사인 유사도

참고 블로그

sql과 database

SQL

  • 정형 데이터로 만들어진 관계형 데이터베이스를 조작하는 언어

데이터베이스

  • 데이터 = 기록 정보
  • 데이터를 모아둔 것

데이터의 형태

  1. 정형 데이터(structured data)
  • 틀이 잡혀있는 체계화된 데이터
  • 높은 안정성, 유연하지 못한 구조
  • 금융, 제조 등 대부분 기업의 업무용 데이터 베이스
  1. 비정형 데이터(unstructured data)
  • 클이 잡혀있지 않고 사전 정의가 없는 데이터
  • 다양하고 방대한 양의 데이터
  • 별도의 분석 처리 기술이 필요
  • 텍스트, 이미지, 음원 데이터, 빅데이터 등

관계형 데이터베이스

  • 컬럼과 로우를 갖는 2차원 테이블
  • 오라클, DB2, MysQL, MS SQL Server 등

계층형 데이터베이스

  • 로컬 pc의 폴더와 파일 형식
  • 기업용 데이터베이스에는 거의 사용되지 않음

XML 데이터베이스

  • W3W(World Wide Web Consortium)의 XML 표준 문서 구조를 계층형 트리 형태로 저장하거나 관리
  • XQuery라는 언어를 사용

자료출처: 모두의 SQL

python tuple unpacking

튜플 언패킹

  • 파이썬에서 iterable한 객체는 sequence unpacking operator *를 사용하여 언패킹 할 수 있습니다.
  • 변수를 할당하는 문장에서 왼쪽에 두 개 이상의 변수를 사용하고 한 변수 앞에 * 연산자가 붙으면, 오른쪽 값들 중 할당되고 남은 값들이 * 연산자가 붙은 변수에 할당됩니다.
1
2
x, *y = (1, 2, 3, 4)
x

1

1
y

[2, 3, 4]

1
2
*x, y = (1, 2, 3, 4)
x

[1, 2, 3]

1
y

4

python 최대공약수(GCD)

최대공약수 greatest common divisor(GCD)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def finding_gcd(a, b):
while(b != 0):
result = b
a, b = b, a % b
return result

def test_finding_gcd():
number1 = 21
number2 = 12
assert(finding_gcd(number1, number2) == 3)
print("테스트 통과!")

if __name__ == "__main__":
test_finding_gcd()

os와 shutil을 이용한 file_copy

os와 shutil(쉘 유틸리티) 모듈을 이용하여 파일 옮기기

  • 진행하려는 내용
  • naver_12와 naver_22의 내부에 있는 모든 파일을 naver_34폴더로 옮기려 합니다.
1
2
3
# 모듈 불러오기
import os
import shutil # 쉘 유틸리티
1
2
# 현재 작업경로 확인
os.getcwd()
1
2
# 작업경로 내부 파일 리스트
os.listdir(os.getcwd())
1
2
3
4
5
6
7
# 파일을 복사해올 소스 경로
base_dir = '/Users/daesuncho/Documents/Machine_Learning/project'
# 소스경로
src_dir = os.path.join(base_dir, 'naver_12')
src_dir1 = os.path.join(base_dir, 'naver_22')
# 도착경로
dst_dir = os.path.join(base_dir, 'naver_34')
1
2
3
4
# 내부 파일 숫자 확인
naver_12 = os.listdir(src_dir)
naver_22 = os.listdir(src_dir1)
len(naver_12), len(naver_22), print(len(naver_12)+len(naver_22))
1
2
3
4
5
6
7
8
9
10
# src_dir에 있는 모든 파일을 dst_dir폴더로 옮기기
for fname in naver_12:
src = os.path.join(src_dir, fname)
dst = os.path.join(dst_dir, fname)
shutil.copyfile(src, dst)
# src_dir에 있는 모든 파일을 dst_dir폴더로 옮기기
for fname in naver_22:
src1 = os.path.join(src_dir1, fname)
dst = os.path.join(dst_dir, fname)
shutil.copyfile(src1, dst)
1
2
3
# dst_dir 폴더 내부의 수량 확인하기
dstfolder = os.listdir(dst_dir)
len(dstfolder)
1
2
3
4
# 숫자가 1개 모자라는 이유 파악하기
# 특정이름의 파일 가져오기
path_dir = './naver_34/' # file path
file_list = os.listdir(path_dir) # 파일이름을 변수에 담고
1
2
3
for item in file_list:
if item.find('DS') is not -1:
print(item)

numpy_indexing & slicing

numpy indexing & slicing

  • 인덱싱

    • 파이썬 리스트와 동일한 개념으로 사용
    • , 를 사용하여 각 차원의 인덱스에 접근 가능
  • 1차원 벡터 인덱싱

    1
    import numpy as np
    1
    2
    3
    # 1차원 벡터 인덱싱
    x = np.arange(10)
    print(x)
    1
    2
    # 첫번째, 마지막, 4번째
    x[0], x[-1], x[3]
    1
    2
    3
    # 4번째 값을 100으로 변경
    x[3] = 100
    print(x)
  • 2차원 행렬 인덱싱

    1
    2
    x = np.arange(10).reshape(2, 5)
    print(x)
    1
    2
    # 0번째 행의 2번째 열의 값 가져오기
    x[0, 2]
  • 3차원 행렬 인덱싱

    1
    2
    3
    # 4행 3열의 행렬이 3개를 만듬
    x = np.arange(36).reshape(3, 4, 3)
    print(x)
    1
    2
    # 0번째 행렬을 가져옴
    x[0]
    1
    x[1, 2]
    1
    2
    # 인덱스를 하나 명시할 때마다 차원이 하나씩 줄어듬
    x[1, 2, 1]

슬라이싱

  • 리스트, 문자열 slicing과 동일한 개념으로 사용
  • , 를 사용하여 각 차원 별로 슬라이싱 가능
  • 슬라이싱으로 해도 차원이 바뀌지 않음
1
2
x = np.arange(10)
print(x)
1
x[1:7]
1
2
# 슬라이싱을 해도 차원이 바뀌지는 않음
x[:]
  • 2차원 행렬 슬라이싱
    1
    2
    x = np.arange(10).reshape(2, 5)
    print(x)
    1
    2
    3
    4
    # 6, 7, 8 가져오기
    # 모든 행 가져오기 x[:]
    # 컬럼부분 가져오기 x[:, 1:4]
    x[:, 1:4]
    1
    2
    # 모든 행의 앞의 2번째만 가져오기 
    x[:, :2]
    1
    2
    3
    4
    5
    # 인덱싱과 슬라이싱 혼합
    # 0번째를 가져오고 2번째에서 자름
    # 앞에 0을 사용하여 인덱스를 사용하여 차원이 하나 줄음
    # 크기가 2인 벡터
    x[0, :2]
    1
    2
    # 자원을 유지하면서 위와 동일한 값 가져오기
    x[:1, :2]
  • 3차원 텐서 슬라이싱
    1
    2
    3
    # 차원을 유지하면서 0, 1, 2, 3, 4, 5가져오기
    # x[:1]첫번째 행렬 가져오기
    x[:1, :2, :]
    1
    2
    3
    # 2차원 행렬에서 0, 1, 2, 3, 4, 5가져오기
    # x[:1]첫번째 행렬 가져오기
    x[0, :2, :]

numpy 모듈을 사용하여 ndarray 데이터 생성하기

numpy 모듈을 사용하여 ndarray 데이터 생성하기

  • numpy

    • 넘파이
    • 수치해석용 Python 라이브러리
    • CPython에서만 사용 가능
    • BLAS/LAPACK 기반
    • ndarray 다차원 행렬 자료 구조 제공
    • 내부 반복문 사용으로 빠른 행렬 연산 가능
    • 행렬 인덱싱(array indexing) 기능

      데이터 사이언스 스쿨

  • ndarray 클래스

    • 다차원 행렬 자료 구조를 지원
    • 벡터화 연산(vectorized operation) 지원
  • Python 리스트

    • 여러가지 타입의 원소
    • linked List 구현
    • 메모리 용량이 크고 속도가 느림
    • 벡터화 연산 불가
  • NumPy ndarray

    • 동일 타입의 원소
    • contiguous memory layout
    • 메모리 최적화, 계산 속도 향상
    • 벡터화 연산 가능
  • 행렬의 차원 및 크기는 ndim 속성과 shape 속성으로 알 수 있다.

1
2
# 필요 모듈 호출
import numpy as np
1
2
3
4
5
6
7
8
9
10
# 1차원 벡터
x = np.array([1, 2, 3, 4])
print(x)
# 2차원 행렬(2행 3열), 리스트안에 리스트로 만듬
y = np.array([[2, 3, 4], [1, 2, 5]])
print(y)
# 타입 확인
print(type(y))
# 차원 확인
print(x.ndim, y.ndim)

np.arange 함수로 생성하기

1
2
# 0 ~ 9까지 ndarray 생성
np.arange(10)
1
2
# 1 ~ 9까지 ndarray 생성
np.arange(1, 10)
1
2
# 1 ~ 9까지 2칸씩 띄어서 생성
np.arange(1, 10, 2)
1
2
# 5 ~ 100까지 5의 배수 생성
np.arange(5, 101, 5)

zeros, ones

1
2
# 4행 5열의 모든 원소가 1인 ndarray 생성, 튜플을 이용하여 생성
np.ones((4, 5))
1
2
3
# 3차원 tensor 생성
# 3행 4열의 행렬 2개, 대괄호가 3개 생김
np.ones((2, 3, 4))
1
2
3
# 4차원 생성
# 대괄호가 4개 생김
np.zeros((2, 3, 8, 8))
1
2
# 초기화된 ndarray 생성
np.empty((3, 4))
1
2
# 7로만 이루어진 tensor 생성
np.full((3, 4), 7)
1
2
3
# 5행 5열의 단위 행렬 2차원
# 대각선의 모든 값이 1, 나머지 0
np.eye(5)

np.linspace

1
2
3
# 시작, 끝, 전체 수가 3개가 되도록 나눔
# 원소간의 차이가 동일하게 만듬
np.linspace(1, 10, 3)
1
2
# 숫자 사이 간격이 동일하게
np.linspace(1, 10, 4)
1
2
3
# 4등분, 전체 갯수 5
# 그래프에서 x축에 균등하게 값을 줄 때 사용
np.linspace(1, 10, 5)

reshape

1
2
3
4
5
6
# 1 ~ 15까지 벡터 생성
x = np.arange(1, 16)
print(x)

# 1차원의 shape
x.shape
1
2
# 2차원의 행렬로 형태를 바꿈, 3행 5열로 변경
x.reshape(3, 5)
1
x. reshape(5, 3)
1
2
# 3차원으로 바꿈, 3행 1열이 5개
x.reshape(5, 3, 1)
1
2
3
# 숫자 20개 필요하나 x안에는 15개만 있으므로 대응이 불가능하여 오류 발생
# reshape 하려는 숫자가 원래 존재하는 숫자와 동일한지 확인 필요
x.reshape(5, 4)

random 서브 모듈 이용하여 ndarray 생성히기

  • 랜덤한 값을 생성
  • 보통 train 전 초반에 무작위 값을 생성
1
2
3
# rand 함수, 2행 3열의 랜덤한 값 생성
# 0과 1 사이의 값이 생성
np.random.rand(2, 3)
1
2
# 1차원 벡터
np.random.rand(10)
1
2
# 3차원 tensor, 4행 2열
np.random.rand(3, 4, 2)
1
2
3
4
# 정규분포, n: normal distribution(정규분포)
# 정규분포로 샘플링된 랜덤 ndarrya 생성
# 정규분포이므로 음수값도 생성
np.random.randn(3, 4)

randint 함수

  • 정수에서 샘플링할 때 사용
1
2
3
# 정수에서 샘플링할 때 사용
# 1 ~ 99, 3행 5열 2차원 행렬
np.random.randint(1, 100, size=(3, 5, 2))

seed 함수

  • 랜덤한 값을 동일하게 다시 생성하고자 할 때 사용
  • 고정된 랜덤 값
1
2
3
# 항상 호출 전 동일한 값을 갖고 싶을 때 사용
np.random.seed(100)
np.random.randn(3, 4)

choice

  • 주어진 1차원 ndarray로부터 랜덤으로 샘플링
  • 정수가 주어진 경우, np.arange(해당숫자)로 간주
1
2
3
# 정수 : 100
# size 샘플링을 3, 4로 가져옴
np.random.choice(100, size=(3, 4))
1
2
3
# 중복 허용
x = np.array([1, 2, 3, 1.5, 2.6, 4.9])
np.random.choice(x, size=(2, 2))
1
2
3
# 중복 x
x = np.array([1, 2, 3, 1.5, 2.6, 4.9])
np.random.choice(x, size=(2, 2), replace=False)
1
2
3
4
# 확률분포에 따른 ndarray 생성
# uniform : low에서 high 사이의 값을 가져옴
# normal 등
np.random.uniform(1.0, 3.0, size=(4, 5))
1
2
# 정규분포
np.random.normal(size=(3, 4))
1
2
3
4
# 정규분포 : 평균, 분포, 사이즈 
np.random.normal(size=(3, 4))
# 아래와 동일
np.random.randn(3, 4)

machine_learning CNN

C.N.N

  • Convolutional Neural Network
  • 이미지 공간의 정보를 유지한 상태로 학습이 가능한 모델

CNN의 주요 용어 정리

  • Convolution(합성곱)
    • 원본 이미지와 필터의 곱
  • 채널(Channel)
    • 이미지 픽셀 1개 = 하나의 실수(scalar)
    • 컬러사진: 3차원 * 높이 150 * 길이 250 = shape(150 * 250 * 3)
    • 흑백사진: 1차원 * 높이 150 * 길이 250 = shape(150 * 250 * 1)
  • 필터(Filter, kernel)
    • 1개의 filter = 1개의 feature map
    • convolution layer에 n개의 filter필터가 적용된다면 출력데이터는 n개의 채널을 갖습니다.
  • 커널(Kernel)
  • 스트라이드(Strid)
    • 필터가 순회하는 지정된 간격
  • 패딩(Padding)
    • Padding을 통해서 Convolution 레이어의 출력 데이터의 사이즈를 조절하는 기능이 외에, 외각을 “0”값으로 둘러싸는 특징으로 부터 인공 신경망이 이미지의 외각을 인식하는 학습 효과도 있습니다.
  • 피처 맵(Feature Map)
  • 액티베이션 맵(Activation Map)
  • 풀링(Pooling) 레이어
    • 일반적으로 Pooing 크기와 Stride를 같은 크기로 설정하여 모든 원소가 한 번씩 처리 되도록 설정합니다.
    • CNN에서는 주로 Max Pooling을 사용합니다.

2.1 Convolution 레이어 출력 데이터 크기 산정

  • 입력 데이터 높이: H
  • 입력 데이터 폭: W
  • 필터 높이: FH
  • 필터 폭: FW
  • Strid 크기: S
  • 패딩 사이즈: P
    \begin{align}
    OutputHeight & = OH = \frac{(H + 2P - FH)}{S} + 1 \
    OutputWeight & = OW = \frac{(W + 2P - FW)}{S} + 1
    \end{align}
  • 만약 Pooling 사이즈가 (3, 3)이라면 위 식의 결과는 자연수이고 3의 배수여야 합니다. 이 조건을 만족하도록 Filter의 크기, Stride의 간격, Pooling 크기 및 패딩 크기를 조절해야 합니다.

2.2 Pooling 레이어 출력 데이터 크기 산정

  • 일반적인 Pooling 사이즈는 정사각형입니다.

  • Pooling 사이즈를 Stride 같은 크기로 만들어서, 모든 요소가 한번씩 Pooling되도록 만듭니다.

  • 입력 데이터의 행 크기와 열 크기는 Pooling 사이즈의 배수(나누어 떨어지는 수)여야 합니다.

  • 결과적으로 Pooling 레이어의 출력 데이터의 크기는 행과 열의 크기를 Pooling 사이즈로 나눈 몫입니다.

  • Pooling 크기가 (2, 2) 라면 출력 데이터 크기는 입력 데이터의 행과 열 크기를 2로 나눈 몫입니다. pooling 크기가 (3, 3)이라면 입력데이터의 행과 크기를 3으로 나눈 몫이 됩니다.

  • CNN을 구성하면서 Filter, Stride, Padding을 조절하여 특징 추출(Feature Extraction) 부분의 입력과 출력 크기를 계산하고 맞추는 작업이 중요합니다.

자료 출처

케라스 CNN model 중간 저장

자료 출처

python function

함수

  • 반복되는 코드를 묶음으로 효율적인 코드를 작성하도록 해주는 기능
  • 기본 함수
  • 파라미터와 아규먼트
  • 리턴
  • args, *kwargs
  • docstring
  • scope
  • inner function
  • lambda function
  • Map, Filter, Reduce
  • Decorlator

1. 기본 함수

  • 함수의 선언과 호출
    1
    2
    3
    4
    5
    6
    7
    8
    # 함수선언
    def grade(point): # def : 예약어, 함수이름 : grade, 파라미터 : point
    if point >= 90:
    print("A")
    elif point >= 80:
    print("B")
    else:
    print("C")
    1
    2
    # 함수호출
    grade(88) # 함수이름(point로 넘겨줄 값을 입력)

2. 파라미터와 아규먼트

  • 파라미터: 함수를 선언할 때 호출하는 부분에서 보내주는 데이터를 받는 변수
  • 아규먼트: 함수를 호출할 때 함수에 보내주는 데이터
1
2
3
def plus(num1, num2): # 파라미터
print(num1 + num2)
plus(1, 2) # 아규먼트
1
2
3
def plus(num1, num2=10): # 디폴트 파라미터
print(num1 + num2)
plus(1, 2) # 아규먼트
1
2
3
def plus(num1, num2=10, num3=20): # 디폴트 파라미터
print(num1 + num2 - num3)
plus(1, 2) # 아규먼트
  • 키워드 아규먼트 : 특정 파라미터를 지정해서 넣고 싶을 때 사용
    1
    plus(3, num3=100) # 키워드 아규먼트

3. 리턴

  • 함수를 실행한 결과를 저장하고 싶을 때 사용합니다.
  • 함수에서 return 코드가 실행되면 무조건 함수가 종료됩니다.
  • return
    1
    2
    3
    4
    5
    def plus(num1, num2):
    print(num1 + num2)

    result = plus(1, 2)
    print(result)
    1
    2
    3
    4
    5
    6
    def plus(num1, num2):
    print(num1 + num2)
    return num1 + num2

    result = plus(1, 2)
    print(result)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    def grade(point): # def : 예약어, 함수이름 : grade, 파라미터 : point
    if point >= 90:
    return "A"
    elif point >= 80:
    return "B"
    else:
    return "C"

    grade(90)
    1
    2
    3
    4
    5
    6
    7
    def passornot(result):
    pass_ = ""
    if result == "A" or result == "B":
    return "PASS"
    else:
    return "FAIL"
    passornot("A")
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    def grade(point): # def : 예약어, 함수이름 : grade, 파라미터 : point
    if point >= 90:
    return "A"
    elif point >= 80:
    return "B"
    else:
    return "C"

    def passornot(result):
    pass_ = ""
    if result == "A" or result == "B":
    return "PASS"
    else:
    return "FAIL"
    1
    2
    # 함수 호출하기
    passornot(grade(98))
    1
    2
    3
    4
    5
    # 함수에서 return 코드가 실행되면 무조건 함수가 종료됩니다. 
    def echo(msg):
    if msg == 'quit':
    return
    print(msg)

4. args, *kwargs

  • 함수를 호출할 때 아규먼트와 키워드 아규먼트의 갯수를 특정지을 수 없을 때 사용
    1
    2
    3
    4
    5
    6
    7
    # 갯수에 상관없이 모든 아규먼트를 더해주는  함수
    def plus(*args):
    print(type(args), args)
    return sum(args)

    # 함수 호출
    plus(1, 2, 3, 4, 5)
    1
    2
    3
    4
    5
    6
    7
    8
    # 키워드가 있는 아규먼트
    def plus(*args, **kwargs):
    print(type(args), args)
    print(type(kwargs), kwargs)
    return sum(args) + sum(kwargs.values())

    # 함수 실행
    plus(1, 2, 3, 4, 5, num1=6, num2=7)
    1
    2
    3
    4
    5
    def func(num1, num2, num3):
    return num1 + num2 + num3

    data = [1, 2, 3]
    func(*data) # func(1, 2, 3)
    1
    2
    3
    4
    5
    def func(num1, num2=10, num3=20):
    return sum(num1) + num2 + num3

    data = [1, 2, 3]
    func(data) # func([1, 2, 3])
    1
    2
    3
    4
    5
    def func(num1, num2, num3):
    return num1 + num2 + num3

    data = [1, 2, 3]
    func(*data) # func(1, 2, 3)
    1
    2
    3
    4
    5
    6
    7
    def func(num1, num2, num3):
    return num1 + num2 + num3
    data = {
    "num2": 100,
    "num3": 200,
    }
    func(1, **data) # func(1, num2=100, num3=200)
  • 문장을 입력받아서 문법에 맞도록 결과를 출력하는 코드를 작성
  • 마지막 문자는 . 이 있을수도 있고 없을수도 있습니다.
  • 논리적인 문제해결 순서 -> 코드로 변경
  • str.upper(), str.lower(), offset index [], str.add(문자열 덧셈)
  • python IS the best Language
  • python IS the best Language.
  • Python is the best lagnuage.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # 1. 문자열 입력받기
    sentence = input('input sentence : ')

    # 2. 모두 소문자로 변경
    result = sentence.lower() # lower함수는 리턴이 있는 함수이므로 result에 저장

    # 3. 가장 앞글자를 대문자로 변경
    result = result[0].upper() + result[1:] # 가장 앞글자 + 나머지 글자

    # 4. 마지막 문자가 .인지 확인해서 .이 아니면 .을 추가
    if result[-1] != ".":
    result += "."

    result
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # 6자리의 로또번호를 생성하는 코드를 작성하세요. 
    # 6자리의 번호는 중복이 없어야 합니다.
    # 문자열, 숫자, 리스트
    # while, not in, in, list.append(), break, len(), list.sort()
    # 문제가 조금 복잡하면 간단한 기능부터 구현하고 업데이트를 하는 방법으로 해결
    # 랜덤한 숫자 6개 출력 -> 숫자가 중복되지 않는 코드를 추가

    lotto = []
    # 랜덤한 숫자 6개를 while문을 사용해서 작성
    while True:
    num = random.randint(1, 45)
    # 숫자를 추가할 때 lotto 리스트에 중복되는 숫자가 없으면 추가
    if num not in lotto:
    lotto.append(num)
    if len(lotto) >= 6:
    lotto.sort()

    break
    lotto

5. docstring

1
2
3
4
# 한줄로 작성
def echo(msg):
"echo print msg"
print(msg)
1
2
3
4
5
6
7
8
9
10
11
def echo(msg):
"""
echo func return its input agument
The operation is:
1. print msg parameter
2. return msg parameter
param : mag : str
return : str
"""
print(msg)
return msg
1
2
# docstring 확인 방법
echo?
1
echo??
1
help(echo)
1
print(echo.__doc__)

6. Scope 범위

  • 함수 안에서 선언되는 변수와 함수 밖에서 선언되는 변수의 범위가 다릅니다.
  • global(전역), local(지역)
  • 전역영역에 선언되어있으면 함수가 실행될 때 전역영역의 변수를 가져다 사용합니다.
  • 지역영역에 선언되어있으면 함수가 실행될 때 지역영역의 변수를 가져다 사용합니다.
  • 메모리를 덜 잡아먹기 때문에 로컬영역에서 선언할 수 있으면 로컬에서 선언하는 것이 좋습니다.
1
2
3
4
5
6
7
# global
gv = 10

def echo():
print(gv)

echo()
1
2
3
4
5
6
7
8
9
# local
gv = 10

def echo():
gv = 100
print(gv)

echo() # 100
gv # 10
1
2
3
4
5
6
7
8
9
gv = 10 

def echo():
global gv
gv=100
print(gv)

echo()
gv # 100

7. inner function

  • 함수가 지역영역에 선언, 함수 안에 함수가 선언
    1
    2
    3
    4
    5
    6
    def outer(a, b):

    def inner(c, d):
    return c + d

    return inner(a, b)
    1
    outer(1, 2) # 3
    1
    inner(2, 3) # 오류발생 : 전역영역에서 지역영역의 함수를 사용하려 했기 때문입니다. 지역영역에 선언된 함수이므로 지역영역에서만 사용할 수 있습니다.

inner함수 = 익명함수라고 부릅니다. 전역영역에서 가져다 사용할 수 없는 함수이기 때문입니다.

1
2
3
4
5
6
7
8
9
10
# 지역영역의 함수 사용하기
def outer(a, b):

def inner(c, d):
print(a, b)
return c + d

return inner # 리턴을 변경시켜주고

outer(1, 2)(3, 4) # inner(3, 4)

8. callback function

  • 함수를 아규먼트, 파라미터로 설정해서 사용하는 것을 의미합니다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def calc(func, a, b):
    # code
    a **= 2
    b **= 2
    return func(a, b)

    def plus(a, b):
    return a + b

    def minus(a, b):
    return a - b
    1
    2
    # 덧셈
    calc(plus, 1, 2)
    1
    2
    # 뺄셈
    calc(minus, 1, 2)

9. lambda function

  • 파라미터를 간단한 계산으로 리턴되는 함수 : 삼항연산
    1
    2
    3
    4
    5
    def plus(a, b): # 파라미터
    return a + b # 리턴

    # lambda 파라미터: 리턴
    plus2 = lambda a, b: a + b
    1
    plus2(2, 3)
    1
    calc(lambda a, b: a + b, 4, 5)

10. Map, Filter, Reduce

  • map: 순서가 있는 데이터 집합에서 모든 값에 함수를 적용시킨 결과를 출력
  • 아규먼트로 func(함수), *iterable을 받음
  • iterable 한 데이터에 함수를 각 요소마다 모두 적용시킨 결과 데이터를 만들고 싶을 때 사용합니다.
  • map(func, ls1, ls2) : ls(iterable한 데이터)가 여러개 올 수 있습니다.
1
2
3
4
5
6
ls = [1, 2, 3, 4]

def odd_even(num):
return 'odd' if num % 2 else 'even'

odd_even(3), odd_even(4)
1
list(map(odd_even, ls)) # 함수, 리스트를 넣음
1
2
3
4
5
6
7
8
9
10
# input 함수로 구분자는 " "으로 여러개의 숫자를 입력 받습니다. 
# str.split(" ")리스트로 만들고
# 만들어진 리스트의 값들을 int로 형변환
datas = input("insert numbers : ") # 10 20 30 40 50 40 30 20 10
result = datas.split(" ")
result
```
```python
result = list(map(int, result))
result

10-2. Filter

  • Filter : 리스트 데이터에서 특정 조건에 맞는 value만 남기는 함수
  • filter(func, ls) : ls(iterable한 데이터)가 1개밖에 못옵니다.
  • True, False로 만듭니다.
  • func is True인 것만 리턴합니다.
    1
    2
    3
    4
    ls = range(10)

    # 홀수만 출력
    list(filter(lambda data: True if data % 2 else False, ls))

10-3. Reduce

  • 리스트 데이터를 처음부터 순서대로 특정 함수를 실행하여 결과를 누적시켜 주는 함수
    1
    2
    3
    4
    5
    6
    from functools import reduce # import 해야 사용 가능합니다. 

    ls = [3, 1, 2, 4, 5]
    # ((((1+2)+3)+4)+5)
    # 파라미터가 반드시 2개여야 함
    reduce(lambda x, y: x + y, ls)

10. Decorlator

  • 함수에서 코드를 바꾸지 않고 기능을 추가하거나 수정하고 싶을 때 사용하는 문법
    1
    2
    3
    4
    5
    6
    7
    8
    9
    def a():
    code_1
    code_2
    code_3

    def b():
    code_1
    code_4
    code_3

데코레이터의 사용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def c(func): # 2. func으로 def a()이 들어옴 

def wrapper(*args, **kwargs): # inner func
code_1 # 4. 코드가 실행됨
result = func(*args, **kwargs) # 5. 코드가 실행됨
code_3 # 6. 코드가 실행됨
return result # 7. 반환함

return wrapper # 8. 반환함

@c # 1. def c라는 함수가 실행이 됨, code_1, code_3 기능이 적용됨, code_1, 3, 2가 실행됨
def a(): # def a라는 함수가 wrapper 함수로 변경됨
code_2 # 3. code_2 가 실행됨

@c # code_1, code_3 기능이 실행됨, 결과적으로 code_1, 3, 4가 실행됨
def b(): # b라는 함수가 wrapper 함수로 변경됨
code_4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# a
def plus(a, b):
print("start") # code_1
result = a + b # code_2
print("result : {}".format(result)) # code_3
return result

# b
def minus(a, b):
print("start") # code_1
result = a - b # code_4
print("result : {}".format(result)) # code_3
return result

# c : code_1, cod_3을 묶어주는 데코레이션 함수
def disp(func):
def wrapper(*args, **kwargs):
print("start") # code_1
result = func(*args, **kwargs) # code_2, code_4
print("result : {}".format(result)) # code_3
return result
return wrapper
1
2
3
4
5
@disp
def plus(a, b):
result = a + b # code_2
return result
plus(1, 2)
1
2
3
4
5
6
7
8
9
10
11
12
# 함수의 실행 시간을 출력하는 데코레이터 함수를 작성하세요. 
import time


def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time() # code 1
result = func(*args, **kwargs) # code 2, code 4
end_time = time.time() # code 3
print("running time : {}".format(end_time - start_time)) # code 3
return result
return wrapper
1
2
3
4
@timer
def test1(num1, num2):
data = range(num1, num2+1)
return sum(data)
1
2
3
4
5
6
@timer
def test2(num1, num2):
result = 0
for num in range(num1, num2+1):
result += num
return result
1
test1(1, 100000)
1
test2(1, 100000)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 패스워드를 입력받아야 함수가 실행되도록하는 데코레이터 작성
def check_password(func):
def wrapper(*args, **kwargs):
pw = 'dss12'
# datas = [
# {'id': 'test', 'pw': '1234'},
# {'id': 'test2', 'pw': '12345'}
# ]
# check password
input_pw = input('insert pw : ')
if input_pw == pw:
result = func(*args, **kwargs)
else:
result = 'not allow!'
return result
return wrapper
1
2
3
@check_password
def plus(a, b):
return a + b
1
plus(1, 2)
1
2
3
4
5
6
7
8
9
10
11
@check_password
def lotto_func():
lotto = []
while True:
number = random.randint(1, 45)
if number not in lotto:
lotto.append(number)
if len(lotto) >= 6:
lotto.sort()
break
return lotto
1
lotto_func()

join()

  • 리스트로 되어있는 데이터를 특정 문자열을 구분자로 사용해서 하나의 문장으로 만들어주는 함수
    1
    2
    ls = ['python', 'is', 'good']
    " ".join(ls)
    1
    2
    3
    4
    5
    6
    7
    8
    # pandas dataframe
    import pandas as pd

    df = pd.DataFrame([ # DataFrame : class
    {"name": "jin", "age": 20},
    {"name": "andy", "age": 21},
    ])
    df

id, pw 카운트 함수, 1. zip함수를 이용하는 방법

1
2
3
4
5
ls = ['a', 'b', 'c']
print(list(range(len(ls))))
print(list(zip(range(len(ls)), ls)))
for idx, data in list(zip(range(len(ls)), ls)):
print(idx, data)
1
2
3
4
user_datas = [
{'user': 'test', 'pw': '1234', 'count': 0},
{'user': 'python', 'pw': '5678', 'count': 0},
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# user_data를 입력받아서 아이디와 패스워드를 체크하는 데코레이터 함수를 코드로 작성하세요. 
# 로그인 될 때마다 count를 1씩 증가
def need_login(func):
def wrapper(*args, **kwargs): # inner function 만듬
# 아아디 패스워드 입력
user, pw = tuple(input("insert user pw : ").split(' ')) # user와 pw 나눈 후 tuple로 변환

# 존재하는 아이디와 패스워드 확인
for idx, user_data in zip(range(len(user_datas)), user_datas): # 카운트하기 위해 몇 번째 데이터인지 확인필요
if (user_data['user'] == user) and (user_data['pw'] == pw):
user_datas[idx]['count'] += 1 # 유저 데이터의 인덱스에서 카운트를 1씩 증가 시킴
# 함수 실행
return func(*args, **kwargs) # wrapper 함수 종료, 결과값 출력
return "wrong login data!"
return wrapper
1
2
3
4
5
@need_login
def plus(num1, num2):
return num1 + num2

plus(1, 2)
1
user_datas

2. enumerate함수를 이용하는 방법

1
list(enumerate(user_datas))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# user_data를 입력받아서 아이디와 패스워드를 체크하는 데코레이터 함수를 코드로 작성하세요. 
# 로그인 될 때마다 count를 1씩 증가
def need_login(func):
def wrapper(*args, **kwargs): # inner function 만듬
# 아아디 패스워드 입력
user, pw = tuple(input("insert user pw : ").split(' ')) # user와 pw 나눈 후 tuple로 변환

# 존재하는 아이디와 패스워드 확인
for idx, user_data in enumerate(user_datas): # 카운트하기 위해 몇 번째 데이터인지 확인필요
if (user_data['user'] == user) and (user_data['pw'] == pw):
user_datas[idx]['count'] += 1 # 유저 데이터의 인덱스에서 카운트를 1씩 증가 시킴
# 함수 실행
return func(*args, **kwargs) # wrapper 함수 종료, 결과값 출력
return "wrong login data!"
return wrapper
1
2
3
4
5
@need_login
def plus(num1, num2):
return num1 + num2

plus(1, 2)
1
user_datas