DRY와 "한 가지 작업만"

Python으로 함수 작성하기

Shayne Miel

Software Architect @ Duo Security

반복하지 말기(DRY)

train = pd.read_csv('train.csv')
train_y = train['labels'].values
train_X = train[col for col in train.columns if col != 'labels'].values
train_pca = PCA(n_components=2).fit_transform(train_X)
plt.scatter(train_pca[:,0], train_pca[:,1])
val = pd.read_csv('validation.csv')
val_y = val['labels'].values
val_X = val[col for col in val.columns if col != 'labels'].values
val_pca = PCA(n_components=2).fit_transform(val_X)
plt.scatter(val_pca[:,0], val_pca[:,1])
test = pd.read_csv('test.csv')
test_y = test['labels'].values
test_X = test[col for col in test.columns if col != 'labels'].values
test_pca = PCA(n_components=2).fit_transform(train_X)
plt.scatter(test_pca[:,0], test_pca[:,1])
Python으로 함수 작성하기

반복의 문제점

train = pd.read_csv('train.csv')
train_y = train['labels'].values
train_X = train[col for col in train.columns if col != 'labels'].values
train_pca = PCA(n_components=2).fit_transform(train_X)
plt.scatter(train_pca[:,0], train_pca[:,1])
val = pd.read_csv('validation.csv')
val_y = val['labels'].values
val_X = val[col for col in val.columns if col != 'labels'].values
val_pca = PCA(n_components=2).fit_transform(val_X)
plt.scatter(val_pca[:,0], val_pca[:,1])
test = pd.read_csv('test.csv')
test_y = test['labels'].values
test_X = test[col for col in test.columns if col != 'labels'].values
test_pca = PCA(n_components=2).fit_transform(train_X)  ### 이런! ###
plt.scatter(test_pca[:,0], test_pca[:,1])
Python으로 함수 작성하기

또 다른 반복의 문제점

train = pd.read_csv('train.csv')
train_y = train['labels'].values  ### <- 여기, 그리고 여기 --v ### 
train_X = train[col for col in train.columns if col != 'labels'].values
train_pca = PCA(n_components=2).fit_transform(train_X)
plt.scatter(train_pca[:,0], train_pca[:,1])
val = pd.read_csv('validation.csv')
val_y = val['labels'].values  ### <- 여기, 그리고 여기 --v ### 
val_X = val[col for col in val.columns if col != 'labels'].values
val_pca = PCA(n_components=2).fit_transform(val_X)
plt.scatter(val_pca[:,0], val_pca[:,1])
test = pd.read_csv('test.csv')
test_y = test['labels'].values  ### <- 여기, 그리고 여기 --v ### 
test_X = test[col for col in test.columns if col != 'labels'].values
test_pca = PCA(n_components=2).fit_transform(test_X)
plt.scatter(test_pca[:,0], test_pca[:,1])
Python으로 함수 작성하기

함수로 반복 피하기

def load_and_plot(path):
  """데이터셋을 로드하고 첫 두 개의 주성분을 시각화합니다.

  Args:
    path (str): CSV 파일 경로.

  Returns:
    tuple of ndarray: (features, labels)
  """
  data = pd.read_csv(path)
  y = data['label'].values
  X = data[col for col in data.columns if col != 'label'].values
  pca = PCA(n_components=2).fit_transform(X)
  plt.scatter(pca[:,0], pca[:,1])
  return X, y
train_X, train_y = load_and_plot('train.csv')

val_X, val_y = load_and_plot('validation.csv')
test_X, test_y = load_and_plot('test.csv')
Python으로 함수 작성하기
def load_and_plot(path):
  """데이터셋을 로드하고 첫 두 개의 주성분을 시각화합니다.

  Args:
    path (str): CSV 파일 경로.

  Returns:
    tuple of ndarray: (features, labels)
  """
  data = pd.read_csv(path)
  y = data['label'].values
  X = data[col for col in data.columns if col != 'label'].values

  pca = PCA(n_components=2).fit_transform(X)
  plt.scatter(pca[:,0], pca[:,1])

  return X, y
Python으로 함수 작성하기
def load_and_plot(path):
  """데이터셋을 로드하고 첫 두 개의 주성분을 시각화합니다.

  Args:
    path (str): CSV 파일 경로.

  Returns:
    tuple of ndarray: (features, labels)
  """
  # load the data
  data = pd.read_csv(path)
  y = data['label'].values
  X = data[col for col in data.columns if col != 'label'].values

  pca = PCA(n_components=2).fit_transform(X)
  plt.scatter(pca[:,0], pca[:,1])

  return X, y
Python으로 함수 작성하기
def load_and_plot(path):
  """데이터셋을 로드하고 첫 두 개의 주성분을 시각화합니다.

  Args:
    path (str): CSV 파일 경로.

  Returns:
    tuple of ndarray: (features, labels)
  """
  # load the data
  data = pd.read_csv(path)
  y = data['label'].values
  X = data[col for col in data.columns if col != 'label'].values

  # 첫 두 개의 주성분을 시각화
  pca = PCA(n_components=2).fit_transform(X)
  plt.scatter(pca[:,0], pca[:,1])

  return X, y
Python으로 함수 작성하기
def load_and_plot(path):
  """데이터셋을 로드하고 첫 두 개의 주성분을 시각화합니다.

  Args:
    path (str): CSV 파일 경로.

  Returns:
    tuple of ndarray: (features, labels)
  """
  # load the data
  data = pd.read_csv(path)
  y = data['label'].values
  X = data[col for col in data.columns if col != 'label'].values

  # 첫 두 개의 주성분을 시각화
  pca = PCA(n_components=2).fit_transform(X)
  plt.scatter(pca[:,0], pca[:,1])

  # 로드한 데이터 반환
  return X, y
Python으로 함수 작성하기

한 가지 작업만 수행하기

def load_data(path):
  """데이터셋을 로드합니다.

  Args:
    path (str): CSV 파일 경로.

  Returns:
    tuple of ndarray: (features, labels)
  """
  data = pd.read_csv(path)
  y = data['labels'].values
  X = data[col for col in data.columns 
           if col != 'labels'].values
  return X, y
def plot_data(X):
  """행렬의 첫 두 개 주성분을 시각화합니다.

  Args:
    X (numpy.ndarray): 시각화할 데이터.
  """
  pca = PCA(n_components=2).fit_transform(X)
  plt.scatter(pca[:,0], pca[:,1])
Python으로 함수 작성하기

단일 작업의 장점

코드는 다음과 같이 바뀝니다:

  • 더 유연해짐
  • 더 이해하기 쉬움
  • 테스트가 더 간단함
  • 디버깅이 더 간단함
  • 변경이 더 쉬움
Python으로 함수 작성하기

코드 스멜과 리팩터링

"컴퓨터가 이해하는 코드는 아무나 쓸 수 있다. 좋은 프로그래머는 사람이 이해하는 코드를 쓴다." - Martin Fowler (1999)

Martin Fowler의 "Refactoring"

Python으로 함수 작성하기

연습해 봅시다!

Python으로 함수 작성하기

Preparing Video For Download...