背景說明

上次和ChatGPT學習重構類別的過程中得到了函數預設值的啟發後,這次在寫視覺化音樂分析工具的過程中繼續來和ChatGPT請教,一樣也是挺有收穫的(chatGPT在取名上真的是超級適合)

原始寫法

def plot_chroma(y, sr, shift_time=0.0, intervals=10):
    chroma = librosa.feature.chroma_stft(y=y, sr=sr)
    chroma_t = librosa.times_like(chroma, sr)
    frame_len = len(chroma_t)
    # 取出10個frame的index和chroma_t
    frame_index = np.linspace(0, frame_len-1, intervals, dtype=int)
    frame_time = np.round(chroma_t[frame_index] + shift_time, 2)
    
    fig, ax = plt.subplots(figsize=(10, 4))
    sns.heatmap(chroma, ax=ax)
    ax.set_title("Chroma")
    ax.set_xlabel("Time(frame)")
    ax.invert_yaxis()
    ax.set_yticklabels(
        ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"],
        rotation=0
    )
    ax.set_xticks(
        frame_index,
        frame_time,
        rotation=0
    )

    return fig, ax

這個函數方式希望去繪製一張Chroma圖,然後再額外調整圖片的座標軸顯示文字
然而為了要對齊所有橫軸的位置frame_index和要顯示對應的時間frame_time,因此要在ax.set_xticks()做處理,不過Code因此變得有點難看,於是就想到可以詢問ChatGPT如何調整

詠唱咒語(Prompt):

  • 以一個資深程式設計師的角度,協助我重構以下程式:
  • 你改了什麼變數名稱?為什麼?

ChatGPT優化

def plot_chroma(y, sr, shift_time=0.0, intervals=10, return_data=False):
    chroma = librosa.feature.chroma_stft(y=y, sr=sr)
    chroma_t = librosa.times_like(chroma, sr)
    frame_len = chroma.shape[1]
    # 取出 intervals 個 frame 的 index 和 chroma_t
    frame_index = np.linspace(0, frame_len-1, intervals, dtype=int)
    frame_time = np.round(chroma_t[frame_index] + shift_time, 2)

    # 畫出 chroma 的熱度圖
    fig, ax = plt.subplots(figsize=(10, 4))
    sns.heatmap(chroma, ax=ax)
    ax.set_title("Chroma")
    ax.set_xlabel("Time (frame)")
    ax.invert_yaxis()
    ax.set_yticklabels(
        ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"],
        rotation=0
    )
    ax.set_xticks(frame_index)
    ax.set_xticklabels(frame_time, rotation=0)

    if return_data:
        return fig, ax, chroma, frame_index, frame_time
    else:
        plt.show()
  • 使用chroma.shape[1]替代len(chroma_t):避免掉一次額外的計算
  • ax.set_xticks拆成
    • ax.set_xticks用來設定index
    • ax.set_xticklabels用來設定值和選擇
  • 修改變數名稱,增加可讀性
    • chroma_t -> chroma_times
    • frame_len -> num_frames
    • frame_len, frame_time -> selected_frames, selected_frame_times