Skip to content

Commit aa95c73

Browse files
Update app.py
1 parent 888602e commit aa95c73

File tree

1 file changed

+36
-25
lines changed

1 file changed

+36
-25
lines changed

backend/app.py

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def log_print(*args):
4343
print(*args, file=log_stream)
4444
sys.stdout.flush()
4545

46-
# ========== PDF REPORT ==========
46+
# === PDF REPORT GENERATOR ===
4747
def generate_pdf_report(summary, r2, mse, forecast_dict):
4848
c = canvas.Canvas(REPORT_PATH, pagesize=letter)
4949
width, height = letter
@@ -79,13 +79,13 @@ def generate_pdf_report(summary, r2, mse, forecast_dict):
7979
c.drawImage(FORECAST_PLOT_PATH, 1 * inch, 1 * inch, width=5.5 * inch, preserveAspectRatio=True)
8080
c.save()
8181

82-
# ========== FORECAST PLOT ==========
82+
# === PLOT FORECAST (READABLE X) ===
8383
def plot_forecast_with_axis(X, y, model, values_parsed, y_future, use_dates):
8484
x_min, x_max = min(X.min(), values_parsed.min()), max(X.max(), values_parsed.max())
8585
x_plot = np.linspace(x_min, x_max, 200).reshape(-1, 1)
8686
y_plot = model.predict(x_plot)
8787

88-
plt.figure()
88+
plt.figure(figsize=(10, 5))
8989
plt.scatter(X, y, label='Training Data', alpha=0.6)
9090
plt.plot(x_plot, y_plot, color='blue', label='Linear Regression')
9191
plt.scatter(values_parsed, y_future, color='red', label='Forecast', marker='x')
@@ -95,16 +95,15 @@ def plot_forecast_with_axis(X, y, model, values_parsed, y_future, use_dates):
9595
plt.title('Forecast with Linear Regression')
9696

9797
if use_dates:
98-
ticks = np.linspace(x_min, x_max, 6)
99-
labels = [datetime.fromordinal(int(t)).strftime('%Y-%m-%d') for t in ticks]
100-
plt.xticks(ticks, labels, rotation=45)
98+
ticks = np.linspace(x_min, x_max, 6, dtype=int)
99+
labels = [datetime.fromordinal(t).strftime('%Y-%m-%d') for t in ticks]
100+
plt.xticks(ticks, labels, rotation=45, ha='right')
101101

102102
plt.tight_layout()
103103
plt.savefig(FORECAST_PLOT_PATH)
104104
plt.close()
105105

106-
# ========== ROUTES ==========
107-
106+
# === ROUTES ===
108107
@app.route("/get-columns", methods=["POST"])
109108
def get_columns():
110109
file = request.files.get("file")
@@ -137,14 +136,16 @@ def upload_file():
137136

138137
df = df[[x_col, y_col]].dropna()
139138
df.columns = ['X', 'Y']
140-
log_print("Data Cleaned using Pandas:\n\n Printing Header:\n", df.head())
139+
log_print("Data Cleaned:\n\n", df.head())
141140

142-
# Plot original data
143-
plt.figure()
141+
# Save scatter plot
142+
plt.figure(figsize=(10, 5))
144143
plt.scatter(df['X'], df['Y'])
145144
plt.xlabel('X')
146145
plt.ylabel('Y')
147146
plt.title('Scatter Plot')
147+
plt.xticks(rotation=45, ha='right')
148+
plt.tight_layout()
148149
plt.savefig(PLOT_PATH)
149150
plt.close()
150151

@@ -162,7 +163,7 @@ def upload_file():
162163
y_pred = model.predict(X)
163164
r2 = r2_score(y, y_pred)
164165
mse = mean_squared_error(y, y_pred)
165-
log_print(f"\n\n Model Trained with Scikit-Learn: \n R² = {r2:.4f}, MSE = {mse:.4f}")
166+
log_print(f"\nModel Trained:\nR² = {r2:.4f}, MSE = {mse:.4f}")
166167

167168
try:
168169
openai.api_key = os.getenv("OPENAI_API_KEY")
@@ -176,9 +177,10 @@ def upload_file():
176177
)
177178
summary = response.choices[0].message.content
178179
cached_summary = summary
179-
except:
180+
except Exception as e:
180181
summary = "OpenAI summarization failed."
181182
cached_summary = summary
183+
log_print("OpenAI error:", str(e))
182184

183185
return jsonify({
184186
"summary": summary,
@@ -192,19 +194,29 @@ def upload_file():
192194
@app.route("/predict", methods=["POST"])
193195
def predict():
194196
future_x = request.form.get("future_x")
195-
if not future_x:
196-
return jsonify({"forecast": "No future values provided."}), 400
197-
198-
values = future_x.split(",")
199-
numeric_vals, date_vals = [], []
200-
for x in values:
201-
try:
202-
date_vals.append(datetime.strptime(x.strip(), "%Y-%m-%d").toordinal())
203-
except:
204-
numeric_vals.append(float(x.strip()))
205-
values_parsed = np.array(date_vals if date_vals else numeric_vals).reshape(-1, 1)
197+
x_col = request.form.get("x_column")
198+
y_col = request.form.get("y_column")
199+
200+
if not future_x or not x_col or not y_col:
201+
return jsonify({"forecast": "Missing input values or column selection."}), 400
202+
203+
try:
204+
values = future_x.split(",")
205+
numeric_vals, date_vals = [], []
206+
for x in values:
207+
try:
208+
date_vals.append(datetime.strptime(x.strip(), "%Y-%m-%d").toordinal())
209+
except:
210+
numeric_vals.append(float(x.strip()))
211+
values_parsed = np.array(date_vals if date_vals else numeric_vals).reshape(-1, 1)
212+
except Exception as e:
213+
return jsonify({"forecast": f"Invalid input: {str(e)}"}), 400
206214

207215
df = pd.read_csv(CSV_CACHE)
216+
if x_col not in df.columns or y_col not in df.columns:
217+
return jsonify({"forecast": "Selected columns not found."}), 400
218+
219+
df = df[[x_col, y_col]].dropna()
208220
df.columns = ['X', 'Y']
209221
df['X_date'] = pd.to_datetime(df['X'], errors='coerce')
210222
use_dates = df['X_date'].notna().sum() >= len(df) // 2
@@ -217,7 +229,6 @@ def predict():
217229

218230
model = LinearRegression()
219231
model.fit(X, y)
220-
221232
y_future = model.predict(values_parsed)
222233
result = {
223234
datetime.fromordinal(int(x)).strftime("%Y-%m-%d") if use_dates else float(x): round(p, 2)

0 commit comments

Comments
 (0)