Skip to content

Exercise 2: Code Debugging

Debug the code snippets below with Copilot/Continue or Browser-based AI.

CODE 1 (Reorganization of pkoffee/main.py)

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from scipy.optimize import curve_fit
from pathlib import Path
import seaborn as sns

def load_data(file_path):
    data = pd.read_csv(file_path)
    X = data["cups"].values()
    Y = data["productivity"].values()
    return data, X, Y

def setup_plot():
    fig = plt.figure(figsize=(10, 6))
    ax = plt.gca()
    ax.set_xlabel("Cups of Coffee")
    ax.set_ylabel("Productivity")
    ax.set_title("Productivity vs Coffee")
    ax.grid(True, alpha=0.3)
    return fig, ax

def plot_violin(data, ax):
    sns.violinplot(data=data, x="cups", y="prductivity", hue="cups", ax=ax, inner="quartile", cut=0, density_norm='width', palette="Greens", linewidth=0.8, legend=False)

def define_models(X, Y):
    x_min, x_max = float(np.min(X)), float(np.max(X))
    y_min, y_max = float(np.min(Y)), float(np.max(X))
    dy = max(1e-8, y_max - y_min)

    MODELS = [
        {"name": "quadratic", "p0": [y_min, 0.0, 0.01], "bounds": (-np.inf, np.inf), "f": lambda xx, a0, a1, a2: a0 + a1 * xx + a2 * xx ** 2},
        {"name": "saturating", "p0": [dy, max(1.0, 0.2 * (x_min + x_max)), y_min], "bounds": ([-np.inf, 0.0, -np.inf], [np.inf, np.inf, np.inf]), "f": lambda xx, Vmax, K, y0: y0 + Vmax * (xx / np.maximum(K + xx, 1e-9))},
        {"name": "logistic", "p0": [dy, 0.5, 0.5 * (x_min + x_max), y_min], "bounds": ([-np.inf, 0.0, -np.inf, -np.inf], [np.inf, np.inf, np.inf, np.inf]), "f": lambda xx, L, k, x0, y0: y0 + L / (1.0 + np.exp(-k * (xx - x0)))},
        {"name": "peak", "p0": [max(y_min, y_max), max(1.0, 0.5 * (x_min + x_max))], "bounds": ([-np.inf, 0.0], [np.inf, np.inf]), "f": lambda xx, a, b: a * xx * np.exp(-xx / np.maximum(b, 1e-9))},
        {"name": "peak2", "p0": [max(1e-6, y_max / max(1.0, x_max ** 2)), max(1.0, 0.5 * (x_min + x_max))], "bounds": ([-np.inf, 0.0], [np.inf, np.inf]), "f": lambda xx, a, b: a * (xx ** 2) * np.exp(-xx / np.maximum(b, 1e-9))},
    ]
    return MODELS

def fit_models(MODELS, X, Y):
    fits = []
    for m in MODELS:
        popt, _ = curve_fit(m["f"], X, Y, p0=m["p0"], bounds=m["bounds"], maxfev=20000)
        yhat = m["f"](X, *popt)
        ss_res = float(np.sum((Y - yhat) ** 2))
        ss_tot = float(np.sum((Y - np.mean(Y)) ** 2))
        r2 = 1.0 - ss_res / ss_tot if ss_tot > 0 else np.nan
        fits.append({"name": m["name"], "func": m["f"], "params": popt, "r2": r2})
    return fits

def sort_fits(fits):
    fits.sort(key=lambda d: (d["r2"] if np.isfinite(d["r2"]) else -np.inf), reverse=True)
    return fits

def plot_fits(fits, ax, X):
    x_smooth = np.linspace(np.min(X), np.max(X), 300)
    for idx, res in enumerate(fits):
        y_s = res["func"](x_smooth, *res["params"])
        label = f"{res['name']} (R²={res['r2']:.3f})"
        ax.plot(x_smooth, y_s, lw=2, label=label)

def save_plot(fig, out_path):
    plt.tight_layout()
    plt.savefig(out_path, dpi=150)
    plt.show()

def main():
    data, X, Y = load_data("coffees_productivity.csv")
    fig, ax = setup_plot()
    plot_violin(data, ax)
    MODELS = define_models(X, Y)
    fits = fit_models(MODELS, X, Y)
    fits = sort_fits(fits)
    plot_fits(fits, ax, X)
    ax.legend()
    ax.set_ylim(-0.2, 8)
    out_path = Path(__file__).with_name("fit_plot.png")
    save_plot(fig, out_path)

if __name__ == "__main__":
    main()

CODE 2

import os
import shutil

folder_name = input("Enter the folder name: ")
prefix = input("Enter the string to prepend to the filename: ")
text = toUpperCase(prefix)
if  not os.path.isdir(folder_name):
    print("Folder does not exist.")
    exit(1)
files = os.listdir(folder_name)
for file in files:
      new_filename = f"{text}_{file}"

shutil.move(os.path.join(folder_name, file),
os.path.joi(folder_name, new_file_name))

print("Files renamed successfully.")