DRY และ "Do One Thing"

การเขียนฟังก์ชันใน 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)  ### yikes! ###
plt.scatter(test_pca[:,0], test_pca[:,1])
การเขียนฟังก์ชันใน Python

อีกปัญหาของการเขียนโค้ดซ้ำ

train = pd.read_csv('train.csv')
train_y = train['labels'].values  ### <- there and there --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  ### <- there and there --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  ### <- there and there --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):
  """Load a dataset and plot the first two principal components.

  Args:
    path (str): The location of a CSV file.

  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):
  """Load a dataset and plot the first two principal components.

  Args:
    path (str): The location of a CSV file.

  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):
  """Load a dataset and plot the first two principal components.

  Args:
    path (str): The location of a CSV file.

  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):
  """Load a dataset and plot the first two principal components.

  Args:
    path (str): The location of a CSV file.

  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

  # plot the first two principal components
  pca = PCA(n_components=2).fit_transform(X)
  plt.scatter(pca[:,0], pca[:,1])

  return X, y
การเขียนฟังก์ชันใน Python
def load_and_plot(path):
  """Load a dataset and plot the first two principal components.

  Args:
    path (str): The location of a CSV file.

  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

  # plot the first two principle components
  pca = PCA(n_components=2).fit_transform(X)
  plt.scatter(pca[:,0], pca[:,1])

  # return loaded data
  return X, y
การเขียนฟังก์ชันใน Python

Do One Thing

def load_data(path):
  """Load a dataset.

  Args:
    path (str): The location of a CSV file.

  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):
  """Plot the first two principal components of a matrix.

  Args:
    X (numpy.ndarray): The data to plot.
  """
  pca = PCA(n_components=2).fit_transform(X)
  plt.scatter(pca[:,0], pca[:,1])
การเขียนฟังก์ชันใน Python

ข้อดีของการทำสิ่งเดียว

โค้ดจะ:

  • ยืดหยุ่นมากขึ้น
  • เข้าใจได้ง่ายขึ้น
  • ทดสอบได้ง่ายขึ้น
  • ดีบักได้ง่ายขึ้น
  • แก้ไขได้สะดวกขึ้น
การเขียนฟังก์ชันใน Python

Code smell และการ Refactor

"คนโง่ก็เขียนโค้ดที่คอมพิวเตอร์เข้าใจได้ แต่โปรแกรมเมอร์ที่ดีเขียนโค้ดที่มนุษย์เข้าใจได้" - Martin Fowler (1999)

"Refactoring" โดย Martin Fowler

การเขียนฟังก์ชันใน Python

มาฝึกกันเถอะ!

การเขียนฟังก์ชันใน Python

Preparing Video For Download...