Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,8 +1,18 @@
|
|
1 |
import gradio as gr
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
import sqlite3
|
3 |
import bcrypt
|
4 |
|
5 |
-
#
|
6 |
def init_db():
|
7 |
conn = sqlite3.connect("users.db")
|
8 |
cursor = conn.cursor()
|
@@ -12,12 +22,12 @@ def init_db():
|
|
12 |
username TEXT UNIQUE,
|
13 |
password TEXT
|
14 |
)
|
15 |
-
""")
|
16 |
conn.commit()
|
17 |
conn.close()
|
18 |
-
|
19 |
init_db()
|
20 |
|
|
|
21 |
def register(username, password):
|
22 |
conn = sqlite3.connect("users.db")
|
23 |
cursor = conn.cursor()
|
@@ -25,9 +35,9 @@ def register(username, password):
|
|
25 |
try:
|
26 |
cursor.execute("INSERT INTO users (username, password) VALUES (?, ?)", (username, hashed_pw))
|
27 |
conn.commit()
|
28 |
-
return "✅ Registration Successful!
|
29 |
except sqlite3.IntegrityError:
|
30 |
-
return "⚠️ Username already exists.
|
31 |
finally:
|
32 |
conn.close()
|
33 |
|
@@ -38,644 +48,97 @@ def login(username, password):
|
|
38 |
result = cursor.fetchone()
|
39 |
conn.close()
|
40 |
if result and bcrypt.checkpw(password.encode(), result[0]):
|
41 |
-
return "✅ Login Successful!
|
42 |
else:
|
43 |
-
return "❌ Incorrect username or password.
|
44 |
-
|
45 |
-
with gr.Blocks() as auth_app:
|
46 |
-
gr.Markdown("# 🔐 Circular Economy Marketplace Login")
|
47 |
-
with gr.Tab("Register"):
|
48 |
-
reg_username = gr.Textbox(label="Username")
|
49 |
-
reg_password = gr.Textbox(label="Password", type="password")
|
50 |
-
reg_btn = gr.Button("Register")
|
51 |
-
reg_output = gr.Textbox()
|
52 |
-
reg_btn.click(register, inputs=[reg_username, reg_password], outputs=reg_output)
|
53 |
-
|
54 |
-
with gr.Tab("Login"):
|
55 |
-
log_username = gr.Textbox(label="Username")
|
56 |
-
log_password = gr.Textbox(label="Password", type="password")
|
57 |
-
log_btn = gr.Button("Login")
|
58 |
-
log_output = gr.Textbox()
|
59 |
-
log_btn.click(login, inputs=[log_username, log_password], outputs=log_output)
|
60 |
-
|
61 |
-
auth_app.launch()
|
62 |
-
import pandas as pd
|
63 |
-
import numpy as np
|
64 |
-
|
65 |
-
# Load dataset
|
66 |
-
df = pd.read_csv("/content/ecommerce_product_dataset.csv")
|
67 |
-
|
68 |
-
# Inspect dataset
|
69 |
-
print(df.head())
|
70 |
-
|
71 |
-
# Handle missing values for numeric columns only
|
72 |
-
numeric_cols = df.select_dtypes(include=np.number).columns
|
73 |
-
df[numeric_cols] = df[numeric_cols].fillna(df[numeric_cols].median())
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
# Convert categorical variables
|
78 |
-
df = pd.get_dummies(df, columns=['Category','ProductName','DateAdded'])
|
79 |
-
from sklearn.model_selection import train_test_split
|
80 |
-
|
81 |
-
X = df.drop(columns=['StockQuantity']) # Features
|
82 |
-
y = df['Discount'] # Target variable
|
83 |
-
|
84 |
-
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
85 |
-
from sklearn.ensemble import RandomForestRegressor
|
86 |
-
from sklearn.metrics import mean_absolute_error, mean_squared_error
|
87 |
-
|
88 |
-
# Initialize model
|
89 |
-
rf_model = RandomForestRegressor(n_estimators=100, random_state=42)
|
90 |
-
|
91 |
-
# Train model
|
92 |
-
rf_model.fit(X_train, y_train)
|
93 |
-
|
94 |
-
# Make predictions
|
95 |
-
y_pred = rf_model.predict(X_test)
|
96 |
-
|
97 |
-
# Evaluate performance
|
98 |
-
mae = mean_absolute_error(y_test, y_pred)
|
99 |
-
# Calculate MSE and then take the square root to get RMSE
|
100 |
-
mse = mean_squared_error(y_test, y_pred) # Remove squared=False
|
101 |
-
rmse = np.sqrt(mse) # Calculate RMSE manually
|
102 |
-
|
103 |
-
print(f"Mean Absolute Error: {mae}")
|
104 |
-
print(f"Root Mean Squared Error: {rmse}")
|
105 |
-
import tensorflow as tf
|
106 |
-
from tensorflow import keras
|
107 |
-
|
108 |
-
# Build a simple Neural Network
|
109 |
-
model = keras.Sequential([
|
110 |
-
keras.layers.Dense(64, activation='relu', input_shape=(X_train.shape[1],)),
|
111 |
-
keras.layers.Dense(32, activation='relu'),
|
112 |
-
keras.layers.Dense(1) # Output layer
|
113 |
-
])
|
114 |
-
|
115 |
-
# Compile the model
|
116 |
-
model.compile(optimizer='adam', loss='mse', metrics=['mae'])
|
117 |
-
|
118 |
-
# Train the model
|
119 |
-
model.fit(X_train, y_train, epochs=50, batch_size=16, validation_data=(X_test, y_test))
|
120 |
-
|
121 |
-
# Make predictions
|
122 |
-
y_pred_nn = model.predict(X_test)
|
123 |
-
|
124 |
-
# Evaluate performance
|
125 |
-
mse_nn = mean_squared_error(y_test, y_pred_nn)
|
126 |
-
print(f"Neural Network RMSE: {np.sqrt(mse_nn)}")
|
127 |
-
import joblib
|
128 |
-
|
129 |
-
# Save model
|
130 |
-
joblib.dump(rf_model, "product_lifecycle_model.pkl")
|
131 |
-
|
132 |
-
# Load model (when needed)
|
133 |
-
model = joblib.load("product_lifecycle_model.pkl")
|
134 |
-
from sklearn.preprocessing import OneHotEncoder
|
135 |
-
from sklearn.compose import ColumnTransformer
|
136 |
-
from sklearn.pipeline import Pipeline
|
137 |
-
import joblib
|
138 |
-
|
139 |
-
categorical_features = ['Category']
|
140 |
-
numeric_features = ['Price', 'Rating', 'NumReviews', 'StockQuantity', 'Discount']
|
141 |
-
|
142 |
-
preprocessor = ColumnTransformer([
|
143 |
-
('cat', OneHotEncoder(handle_unknown='ignore'), categorical_features),
|
144 |
-
('num', 'passthrough', numeric_features)
|
145 |
-
])
|
146 |
-
|
147 |
-
joblib.dump(preprocessor, "preprocessor.pkl")
|
148 |
-
import pandas as pd
|
149 |
-
import joblib
|
150 |
-
from sklearn.preprocessing import OneHotEncoder
|
151 |
-
from sklearn.compose import ColumnTransformer
|
152 |
-
from sklearn.pipeline import Pipeline
|
153 |
-
from sklearn.ensemble import RandomForestRegressor
|
154 |
-
|
155 |
-
# Load dataset (ensure this matches your actual dataset)
|
156 |
-
df = pd.read_csv("/content/ecommerce_product_dataset.csv")
|
157 |
-
|
158 |
-
# Define features and target variable
|
159 |
-
X = df[["Category", "ProductName", "Price", "Rating", "NumReviews", "StockQuantity", "Discount"]]
|
160 |
-
y = df["Sales"] # Target variable (adjust based on your dataset)
|
161 |
|
162 |
-
#
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
preprocessor =
|
167 |
-
('cat', OneHotEncoder(handle_unknown='ignore'), categorical_features),
|
168 |
-
('num', 'passthrough', numeric_features)
|
169 |
-
])
|
170 |
-
|
171 |
-
# Fit the preprocessor on training data
|
172 |
-
X_transformed = preprocessor.fit_transform(X)
|
173 |
-
|
174 |
-
# Train the model
|
175 |
-
model = RandomForestRegressor(n_estimators=100, random_state=42)
|
176 |
-
model.fit(X_transformed, y)
|
177 |
-
|
178 |
-
# Save the fitted preprocessor & model
|
179 |
-
joblib.dump(preprocessor, "preprocessor.pkl")
|
180 |
-
joblib.dump(model, "product_lifecycle_model.pkl")
|
181 |
-
print("✅ Model and preprocessor saved successfully!")
|
182 |
-
import gradio as gr
|
183 |
-
import joblib
|
184 |
-
import pandas as pd
|
185 |
-
|
186 |
-
# Load trained model and fitted preprocessor
|
187 |
-
model = joblib.load("product_lifecycle_model.pkl")
|
188 |
-
preprocessor = joblib.load("preprocessor.pkl") # ✅ Now pre-fitted
|
189 |
-
|
190 |
-
def preprocess_input(Category, ProductName, Price, Rating, NumReviews, StockQuantity, Discount):
|
191 |
-
# Create DataFrame from user input
|
192 |
-
input_df = pd.DataFrame([[Category, ProductName, Price, Rating, NumReviews, StockQuantity, Discount]],
|
193 |
-
columns=["Category", "ProductName", "Price", "Rating", "NumReviews", "StockQuantity", "Discount"])
|
194 |
-
|
195 |
-
# Apply the saved preprocessor (which is already fitted)
|
196 |
-
input_processed = preprocessor.transform(input_df)
|
197 |
-
|
198 |
-
return input_processed
|
199 |
-
|
200 |
-
def predict_lifecycle(Category, ProductName, Price, Rating, NumReviews, StockQuantity, Discount):
|
201 |
-
try:
|
202 |
-
input_data = preprocess_input(Category, ProductName, Price, Rating, NumReviews, StockQuantity, Discount)
|
203 |
-
prediction = model.predict(input_data)[0]
|
204 |
-
return f"Predicted Product Lifecycle: {round(prediction, 2)} years"
|
205 |
-
except Exception as e:
|
206 |
-
return f"Error: {str(e)}"
|
207 |
-
|
208 |
-
# Create Gradio interface
|
209 |
-
iface = gr.Interface(
|
210 |
-
fn=predict_lifecycle,
|
211 |
-
inputs=[
|
212 |
-
gr.Dropdown(["Plastic", "Metal", "Wood", "Composite", "Electronics"], label="Category"),
|
213 |
-
gr.Textbox(label="Product Name"),
|
214 |
-
gr.Number(label="Price"),
|
215 |
-
gr.Number(label="Rating"),
|
216 |
-
gr.Number(label="NumReviews"),
|
217 |
-
gr.Number(label="StockQuantity"),
|
218 |
-
gr.Number(label="Discount")
|
219 |
-
],
|
220 |
-
outputs=gr.Textbox(label="Prediction"),
|
221 |
-
title="🔄 Product Lifecycle Prediction App",
|
222 |
-
description="Enter product details below to predict its lifecycle duration (in years)."
|
223 |
-
)
|
224 |
-
|
225 |
-
# Launch Gradio app
|
226 |
-
iface.launch()
|
227 |
-
import gradio as gr
|
228 |
-
import joblib
|
229 |
-
import pandas as pd
|
230 |
-
|
231 |
-
# Load trained model and fitted preprocessor
|
232 |
-
model = joblib.load("product_lifecycle_model.pkl")
|
233 |
-
preprocessor = joblib.load("preprocessor.pkl") # ✅ Now pre-fitted
|
234 |
-
|
235 |
-
def preprocess_input(Category, ProductName, Price, Rating, NumReviews, StockQuantity, Discount):
|
236 |
-
# Create DataFrame from user input
|
237 |
-
input_df = pd.DataFrame([[Category, ProductName, Price, Rating, NumReviews, StockQuantity, Discount]],
|
238 |
-
columns=["Category", "ProductName", "Price", "Rating", "NumReviews", "StockQuantity", "Discount"])
|
239 |
-
|
240 |
-
# Apply the saved preprocessor (which is already fitted)
|
241 |
-
input_processed = preprocessor.transform(input_df)
|
242 |
-
|
243 |
-
return input_processed
|
244 |
-
|
245 |
-
def predict_lifecycle(Category, ProductName, Price, Rating, NumReviews, StockQuantity, Discount):
|
246 |
-
try:
|
247 |
-
input_data = preprocess_input(Category, ProductName, Price, Rating, NumReviews, StockQuantity, Discount)
|
248 |
-
prediction = model.predict(input_data)[0]
|
249 |
-
return f"Predicted Product Lifecycle: {round(prediction, 2)} years"
|
250 |
-
except Exception as e:
|
251 |
-
return f"Error: {str(e)}"
|
252 |
-
|
253 |
-
# Create Gradio interface
|
254 |
-
iface = gr.Interface(
|
255 |
-
fn=predict_lifecycle,
|
256 |
-
inputs=[
|
257 |
-
gr.Dropdown(["Plastic", "Metal", "Wood", "Composite", "Electronics"], label="Category"),
|
258 |
-
gr.Textbox(label="Product Name"),
|
259 |
-
gr.Number(label="Price"),
|
260 |
-
gr.Number(label="Rating"),
|
261 |
-
gr.Number(label="NumReviews"),
|
262 |
-
gr.Number(label="StockQuantity"),
|
263 |
-
gr.Number(label="Discount")
|
264 |
-
],
|
265 |
-
outputs=gr.Textbox(label="Prediction"),
|
266 |
-
title="🔄 Product Lifecycle Prediction App",
|
267 |
-
description="Enter product details below to predict its lifecycle duration (in years)."
|
268 |
-
)
|
269 |
-
|
270 |
-
# Launch Gradio app
|
271 |
-
iface.launch()
|
272 |
-
import gradio as gr
|
273 |
-
import joblib
|
274 |
-
import pandas as pd
|
275 |
-
|
276 |
-
# Load trained model and fitted preprocessor
|
277 |
-
model = joblib.load("product_lifecycle_model.pkl")
|
278 |
-
preprocessor = joblib.load("preprocessor.pkl") # ✅ Now pre-fitted
|
279 |
-
|
280 |
-
def preprocess_input(Category, ProductName, Price, Rating, NumReviews, StockQuantity, Discount):
|
281 |
-
# Create DataFrame from user input
|
282 |
-
input_df = pd.DataFrame([[Category, ProductName, Price, Rating, NumReviews, StockQuantity, Discount]],
|
283 |
-
columns=["Category", "ProductName", "Price", "Rating", "NumReviews", "StockQuantity", "Discount"])
|
284 |
-
|
285 |
-
# Apply the saved preprocessor (which is already fitted)
|
286 |
-
input_processed = preprocessor.transform(input_df)
|
287 |
-
|
288 |
-
return input_processed
|
289 |
-
|
290 |
-
def predict_lifecycle(Category, ProductName, Price, Rating, NumReviews, StockQuantity, Discount):
|
291 |
-
try:
|
292 |
-
input_data = preprocess_input(Category, ProductName, Price, Rating, NumReviews, StockQuantity, Discount)
|
293 |
-
prediction = model.predict(input_data)[0]
|
294 |
-
return f"Predicted Product Lifecycle: {round(prediction, 2)} years"
|
295 |
-
except Exception as e:
|
296 |
-
return f"Error: {str(e)}"
|
297 |
-
|
298 |
-
# Create Gradio interface
|
299 |
-
iface = gr.Interface(
|
300 |
-
fn=predict_lifecycle,
|
301 |
-
inputs=[
|
302 |
-
gr.Dropdown(["Plastic", "Metal", "Wood", "Composite", "Electronics"], label="Category"),
|
303 |
-
gr.Textbox(label="Product Name"),
|
304 |
-
gr.Number(label="Price"),
|
305 |
-
gr.Number(label="Rating"),
|
306 |
-
gr.Number(label="NumReviews"),
|
307 |
-
gr.Number(label="StockQuantity"),
|
308 |
-
gr.Number(label="Discount")
|
309 |
-
],
|
310 |
-
outputs=gr.Textbox(label="Prediction"),
|
311 |
-
title="🔄 Product Lifecycle Prediction App",
|
312 |
-
description="Enter product details below to predict its lifecycle duration (in years)."
|
313 |
-
)
|
314 |
-
|
315 |
-
# Launch Gradio app
|
316 |
-
iface.launch()
|
317 |
-
import pandas as pd
|
318 |
-
import numpy as np
|
319 |
-
from sklearn.model_selection import train_test_split
|
320 |
-
from sklearn.preprocessing import LabelEncoder, StandardScaler
|
321 |
-
import joblib
|
322 |
-
|
323 |
-
# Load dataset
|
324 |
-
df = pd.read_csv("/content/dynamic_pricing_data.csv")
|
325 |
-
|
326 |
-
# Encode categorical variables
|
327 |
-
label_encoders = {}
|
328 |
-
for col in ["Product Name", "Category", "Demand", "Season"]:
|
329 |
-
le = LabelEncoder()
|
330 |
-
df[col] = le.fit_transform(df[col])
|
331 |
-
label_encoders[col] = le
|
332 |
-
|
333 |
-
# Save label encoders
|
334 |
-
joblib.dump(label_encoders, "label_encoders.pkl")
|
335 |
-
|
336 |
-
# Scale numerical features
|
337 |
-
scaler = StandardScaler()
|
338 |
-
num_cols = ["Base Price", "Competitor Price", "Stock", "Reviews", "Rating", "Discount"]
|
339 |
-
df[num_cols] = scaler.fit_transform(df[num_cols])
|
340 |
-
|
341 |
-
# Save scaler
|
342 |
-
joblib.dump(scaler, "scaler.pkl")
|
343 |
-
|
344 |
-
# Split data
|
345 |
-
X = df.drop(columns=["Final Price"])
|
346 |
-
y = df["Final Price"]
|
347 |
-
|
348 |
-
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
349 |
-
import joblib
|
350 |
-
import pandas as pd
|
351 |
-
import numpy as np
|
352 |
-
from sklearn.model_selection import train_test_split
|
353 |
-
from sklearn.preprocessing import LabelEncoder, StandardScaler
|
354 |
-
|
355 |
-
|
356 |
-
# Load dataset
|
357 |
-
df = pd.read_csv("/content/dynamic_pricing_data.csv")
|
358 |
-
|
359 |
-
# Encode categorical variables
|
360 |
-
label_encoders = {}
|
361 |
-
for col in ["Product Name", "Category", "Demand", "Season"]:
|
362 |
-
le = LabelEncoder()
|
363 |
-
df[col] = le.fit_transform(df[col])
|
364 |
-
label_encoders[col] = le
|
365 |
-
|
366 |
-
# Save label encoders
|
367 |
-
joblib.dump(label_encoders, "label_encoders.pkl")
|
368 |
-
|
369 |
-
# Scale numerical features
|
370 |
-
scaler = StandardScaler()
|
371 |
-
num_cols = ["Base Price", "Competitor Price", "Stock", "Reviews", "Rating", "Discount"]
|
372 |
-
df[num_cols] = scaler.fit_transform(df[num_cols])
|
373 |
-
|
374 |
-
# Save scaler
|
375 |
-
joblib.dump(scaler, "scaler.pkl")
|
376 |
-
|
377 |
-
# Split data
|
378 |
-
X = df.drop(columns=["Final Price"])
|
379 |
-
y = df["Final Price"]
|
380 |
-
|
381 |
-
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
382 |
-
|
383 |
-
# Train model (Assuming you're using RandomForestRegressor)
|
384 |
-
from sklearn.ensemble import RandomForestRegressor
|
385 |
-
model = RandomForestRegressor(n_estimators=100, random_state=42)
|
386 |
-
model.fit(X_train, y_train)
|
387 |
-
|
388 |
-
# Save the trained model to 'dynamic_pricing_model.pkl'
|
389 |
-
joblib.dump(model, "dynamic_pricing_model.pkl")
|
390 |
-
|
391 |
-
# Now you can load the model, scaler, and label encoders
|
392 |
-
model = joblib.load("dynamic_pricing_model.pkl")
|
393 |
-
scaler = joblib.load("scaler.pkl")
|
394 |
-
label_encoders = joblib.load("label_encoders.pkl")
|
395 |
-
print(model, scaler, label_encoders)
|
396 |
-
import joblib
|
397 |
-
import pandas as pd
|
398 |
-
import numpy as np
|
399 |
-
from sklearn.model_selection import train_test_split
|
400 |
-
from sklearn.preprocessing import LabelEncoder, StandardScaler
|
401 |
-
|
402 |
-
|
403 |
-
# Load dataset
|
404 |
-
df = pd.read_csv("/content/dynamic_pricing_data.csv")
|
405 |
-
|
406 |
-
# Encode categorical variables
|
407 |
-
label_encoders = {}
|
408 |
-
for col in ["Product Name", "Category", "Demand", "Season"]:
|
409 |
-
le = LabelEncoder()
|
410 |
-
df[col] = le.fit_transform(df[col])
|
411 |
-
label_encoders[col] = le
|
412 |
-
|
413 |
-
# Save label encoders
|
414 |
-
joblib.dump(label_encoders, "label_encoders.pkl")
|
415 |
-
|
416 |
-
# Scale numerical features
|
417 |
-
scaler = StandardScaler()
|
418 |
-
num_cols = ["Base Price", "Competitor Price", "Stock", "Reviews", "Rating", "Discount"]
|
419 |
-
df[num_cols] = scaler.fit_transform(df[num_cols])
|
420 |
-
|
421 |
-
# Save scaler
|
422 |
-
joblib.dump(scaler, "scaler.pkl")
|
423 |
-
|
424 |
-
# Split data
|
425 |
-
X = df.drop(columns=["Final Price"])
|
426 |
-
y = df["Final Price"]
|
427 |
-
|
428 |
-
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
429 |
-
|
430 |
-
# Train model (Assuming you're using RandomForestRegressor)
|
431 |
-
from sklearn.ensemble import RandomForestRegressor
|
432 |
-
model = RandomForestRegressor(n_estimators=100, random_state=42)
|
433 |
-
model.fit(X_train, y_train)
|
434 |
-
|
435 |
-
# Save the trained model to 'dynamic_pricing_model.pkl'
|
436 |
-
joblib.dump(model, "dynamic_pricing_model.pkl")
|
437 |
-
|
438 |
-
# Now you can load the model, scaler, and label encoders
|
439 |
-
model = joblib.load("dynamic_pricing_model.pkl")
|
440 |
-
scaler = joblib.load("scaler.pkl")
|
441 |
-
label_encoders = joblib.load("label_encoders.pkl")
|
442 |
-
print(model, scaler, label_encoders)
|
443 |
-
import joblib
|
444 |
-
model = joblib.load("dynamic_pricing_model.pkl")
|
445 |
scaler = joblib.load("scaler.pkl")
|
446 |
label_encoders = joblib.load("label_encoders.pkl")
|
447 |
-
print(model, scaler, label_encoders)
|
448 |
-
from sklearn.ensemble import RandomForestRegressor
|
449 |
-
from sklearn.metrics import mean_absolute_error, r2_score
|
450 |
-
|
451 |
-
# Train model
|
452 |
-
model = RandomForestRegressor(n_estimators=100, random_state=42)
|
453 |
-
model.fit(X_train, y_train)
|
454 |
|
455 |
-
|
456 |
-
|
|
|
|
|
|
|
457 |
|
458 |
-
|
459 |
-
|
460 |
-
print(f"MAE: {mean_absolute_error(y_test, y_pred)}")
|
461 |
-
print(f"R² Score: {r2_score(y_test, y_pred)}")
|
462 |
-
import gradio as gr
|
463 |
-
import numpy as np
|
464 |
-
|
465 |
-
# Load trained model, scaler, and label encoders
|
466 |
-
model = joblib.load("dynamic_pricing_model.pkl")
|
467 |
-
scaler = joblib.load("scaler.pkl")
|
468 |
-
label_encoders = joblib.load("label_encoders.pkl")
|
469 |
-
|
470 |
-
def predict_price(product_name, category, base_price, competitor_price, demand, stock, reviews, rating, season, discount):
|
471 |
-
# Encode categorical features
|
472 |
category = label_encoders["Category"].transform([category])[0]
|
473 |
demand = label_encoders["Demand"].transform([demand])[0]
|
474 |
season = label_encoders["Season"].transform([season])[0]
|
475 |
product_name = label_encoders["Product Name"].transform([product_name])[0]
|
476 |
-
|
477 |
-
# Scale numerical features
|
478 |
features = np.array([base_price, competitor_price, stock, reviews, rating, discount]).reshape(1, -1)
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
final_features = np.concatenate((features.flatten(), [category, demand, season, product_name])).reshape(1, -1)
|
483 |
-
|
484 |
-
# Predict
|
485 |
-
predicted_price = model.predict(final_features)[0]
|
486 |
-
return f"Optimal Price: ₹{round(predicted_price, 2)}"
|
487 |
|
488 |
-
# Create Gradio UI
|
489 |
-
iface = gr.Interface(
|
490 |
-
fn=predict_price,
|
491 |
-
inputs=[
|
492 |
-
gr.Dropdown(["iPhone 13", "Nike Shoes", "Samsung TV", "Adidas Jacket", "Dell Laptop", "Sony Headphones", "Apple Watch",
|
493 |
-
"LG Refrigerator", "HP Printer", "Bose Speaker"], label="Product Name"),
|
494 |
-
gr.Dropdown(["Electronics", "Fashion", "Home Appliances"], label="Category"),
|
495 |
-
gr.Number(label="Base Price"),
|
496 |
-
gr.Number(label="Competitor Price"),
|
497 |
-
gr.Dropdown(["Low", "Medium", "High"], label="Demand"),
|
498 |
-
gr.Number(label="Stock"),
|
499 |
-
gr.Number(label="Reviews"),
|
500 |
-
gr.Number(label="Rating"),
|
501 |
-
gr.Dropdown(["Holiday", "Summer", "Winter", "Off-season"], label="Season"),
|
502 |
-
gr.Number(label="Discount (%)"),
|
503 |
-
],
|
504 |
-
outputs=gr.Textbox(label="Predicted Price"),
|
505 |
-
title="🛒 Dynamic Pricing Model",
|
506 |
-
description="Enter product details to get an AI-predicted price recommendation.",
|
507 |
-
)
|
508 |
-
|
509 |
-
iface.launch()
|
510 |
-
import pandas as pd
|
511 |
-
from sklearn.preprocessing import OneHotEncoder
|
512 |
-
from sklearn.compose import ColumnTransformer
|
513 |
-
from sklearn.neighbors import NearestNeighbors
|
514 |
-
|
515 |
-
# Load the synthetic dataset
|
516 |
-
df = pd.read_csv('/content/synthetic_product_data.csv') # Update this path with the correct one
|
517 |
-
|
518 |
-
# Example of preprocessing categorical data
|
519 |
-
categorical_features = ['product_condition', 'category']
|
520 |
-
numeric_features = ['price']
|
521 |
-
|
522 |
-
# Create column transformer to preprocess data
|
523 |
-
preprocessor = ColumnTransformer(
|
524 |
-
transformers=[
|
525 |
-
('cat', OneHotEncoder(), categorical_features),
|
526 |
-
('num', 'passthrough', numeric_features)
|
527 |
-
])
|
528 |
-
|
529 |
-
# Apply preprocessing to transform the dataset
|
530 |
-
product_features = preprocessor.fit_transform(df[['product_condition', 'price', 'category']])
|
531 |
-
|
532 |
-
# Fit NearestNeighbors model
|
533 |
-
knn = NearestNeighbors(n_neighbors=5)
|
534 |
-
knn.fit(product_features)
|
535 |
-
|
536 |
-
# Function to recommend similar products
|
537 |
-
def recommend_products(product_id):
|
538 |
-
product = product_features[product_id].reshape(1, -1)
|
539 |
-
_, indices = knn.kneighbors(product)
|
540 |
-
return df.iloc[indices[0]]
|
541 |
-
|
542 |
-
# Example: Recommend products for product with id 3
|
543 |
-
recommended_products = recommend_products(3)
|
544 |
-
print(recommended_products)
|
545 |
-
import pandas as pd
|
546 |
-
import gradio as gr
|
547 |
-
from sklearn.preprocessing import OneHotEncoder
|
548 |
-
from sklearn.compose import ColumnTransformer
|
549 |
-
from sklearn.neighbors import NearestNeighbors
|
550 |
-
import random
|
551 |
-
|
552 |
-
# Load the synthetic dataset
|
553 |
-
df = pd.read_csv('/content/synthetic_product_data.csv') # Update this path with the correct one
|
554 |
-
|
555 |
-
# Example of preprocessing categorical data
|
556 |
-
categorical_features = ['product_condition', 'category']
|
557 |
-
numeric_features = ['price']
|
558 |
-
|
559 |
-
# Create column transformer to preprocess data
|
560 |
-
preprocessor = ColumnTransformer(
|
561 |
-
transformers=[
|
562 |
-
('cat', OneHotEncoder(), categorical_features),
|
563 |
-
('num', 'passthrough', numeric_features)
|
564 |
-
])
|
565 |
-
|
566 |
-
# Apply preprocessing to transform the dataset
|
567 |
-
product_features = preprocessor.fit_transform(df[['product_condition', 'price', 'category']])
|
568 |
-
|
569 |
-
# Fit NearestNeighbors model
|
570 |
-
knn = NearestNeighbors(n_neighbors=5)
|
571 |
-
knn.fit(product_features)
|
572 |
-
|
573 |
-
# Function to recommend similar products from the selected category
|
574 |
def recommend_products(category):
|
575 |
-
|
576 |
-
|
577 |
-
|
578 |
-
if filtered_df.empty:
|
579 |
-
return "No products found in this category."
|
580 |
-
|
581 |
-
# Randomly select a product from the filtered category
|
582 |
-
random_product = random.choice(filtered_df.index)
|
583 |
-
|
584 |
-
# Get the feature vector of the selected product
|
585 |
-
product = product_features[random_product].reshape(1, -1)
|
586 |
-
|
587 |
-
# Find similar products
|
588 |
-
_, indices = knn.kneighbors(product)
|
589 |
-
|
590 |
-
# Get the recommended products (only from the selected category)
|
591 |
-
recommended = df.iloc[indices[0]]
|
592 |
-
recommended = recommended[recommended['category'] == category] # Ensure all recommendations are from the selected category
|
593 |
-
|
594 |
-
return recommended[['product_id', 'product_condition', 'price', 'category']]
|
595 |
-
|
596 |
-
# Create Gradio interface
|
597 |
-
def gradio_interface(category):
|
598 |
-
recommended_products = recommend_products(category)
|
599 |
-
return recommended_products
|
600 |
-
|
601 |
-
# Set up Gradio inputs and outputs
|
602 |
-
category_input = gr.Dropdown(choices=df['category'].unique().tolist(), label="Select Product Category")
|
603 |
-
output = gr.Dataframe()
|
604 |
-
|
605 |
-
# Launch Gradio interface
|
606 |
-
gr.Interface(fn=gradio_interface,
|
607 |
-
inputs=category_input,
|
608 |
-
outputs=output,
|
609 |
-
live=True,
|
610 |
-
title="Product Recommendation System",
|
611 |
-
description="Select a product category to get similar products from the same category").launch()
|
612 |
-
import gradio as gr
|
613 |
-
import pandas as pd
|
614 |
-
import plotly.express as px
|
615 |
-
import numpy as np
|
616 |
-
import time
|
617 |
-
|
618 |
-
# Load dataset (Assuming a CSV file with relevant data)
|
619 |
-
data_file = "marketplace_data.csv"
|
620 |
-
|
621 |
-
def load_data():
|
622 |
-
return pd.read_csv(data_file)
|
623 |
-
|
624 |
-
def update_live_data():
|
625 |
-
"""Simulate real-time updates by adding new interactions."""
|
626 |
-
df = load_data()
|
627 |
-
new_entry = {
|
628 |
-
"Category": np.random.choice(["Electronics", "Plastic", "Metal", "Wood", "Composite"]),
|
629 |
-
"LifecycleYears": round(np.random.uniform(1, 20), 2),
|
630 |
-
"Price": round(np.random.uniform(10, 500), 2),
|
631 |
-
"NumReviews": np.random.randint(0, 1000)
|
632 |
-
}
|
633 |
-
df = df.append(new_entry, ignore_index=True)
|
634 |
-
df.to_csv(data_file, index=False)
|
635 |
|
636 |
def generate_dashboard():
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
x='Category', y='LifecycleYears', title='Average Product Lifecycle by Category')
|
643 |
-
|
644 |
-
# Dynamic Pricing Trends
|
645 |
-
price_trend_fig = px.line(df.groupby('Category')['Price'].mean().reset_index(),
|
646 |
-
x='Category', y='Price', title='Average Price Trends by Category')
|
647 |
-
|
648 |
-
# User Engagement Trends
|
649 |
-
engagement_fig = px.bar(df.groupby('Category')['NumReviews'].sum().reset_index(),
|
650 |
-
x='Category', y='NumReviews', title='Total User Reviews per Category')
|
651 |
-
|
652 |
-
# Sustainability & Recycling Insights
|
653 |
-
df['Sustainability Score'] = np.random.uniform(0, 100, len(df))
|
654 |
-
sustainability_fig = px.scatter(df, x='Price', y='Sustainability Score', color='Category',
|
655 |
-
title='Sustainability Score vs. Product Price')
|
656 |
-
|
657 |
return lifecycle_fig, price_trend_fig, engagement_fig, sustainability_fig
|
658 |
|
659 |
-
|
660 |
-
fn=generate_dashboard,
|
661 |
-
inputs=[],
|
662 |
-
outputs=[gr.Plot(label="Product Lifecycle Analytics"),
|
663 |
-
gr.Plot(label="Dynamic Pricing Insights"),
|
664 |
-
gr.Plot(label="User Engagement Trends"),
|
665 |
-
gr.Plot(label="Sustainability & Recycling Insights")],
|
666 |
-
live=True, # Enables real-time updates
|
667 |
-
title="♻️ Circular Economy Analytics Dashboard",
|
668 |
-
description="Interactive insights on product lifecycle, pricing, engagement, and sustainability trends."
|
669 |
-
)
|
670 |
-
|
671 |
-
# Simulate real-time data updates
|
672 |
-
def live_update():
|
673 |
while True:
|
674 |
-
|
675 |
-
|
676 |
-
|
677 |
-
|
678 |
-
|
679 |
-
|
680 |
-
|
681 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import gradio as gr
|
2 |
+
import joblib
|
3 |
+
import pandas as pd
|
4 |
+
from sklearn.preprocessing import OneHotEncoder, LabelEncoder, StandardScaler
|
5 |
+
from sklearn.compose import ColumnTransformer
|
6 |
+
from sklearn.ensemble import RandomForestRegressor
|
7 |
+
from sklearn.neighbors import NearestNeighbors
|
8 |
+
import numpy as np
|
9 |
+
import time
|
10 |
+
import threading
|
11 |
+
import plotly.express as px
|
12 |
import sqlite3
|
13 |
import bcrypt
|
14 |
|
15 |
+
# Initialize database
|
16 |
def init_db():
|
17 |
conn = sqlite3.connect("users.db")
|
18 |
cursor = conn.cursor()
|
|
|
22 |
username TEXT UNIQUE,
|
23 |
password TEXT
|
24 |
)
|
25 |
+
""")
|
26 |
conn.commit()
|
27 |
conn.close()
|
|
|
28 |
init_db()
|
29 |
|
30 |
+
# Authentication functions
|
31 |
def register(username, password):
|
32 |
conn = sqlite3.connect("users.db")
|
33 |
cursor = conn.cursor()
|
|
|
35 |
try:
|
36 |
cursor.execute("INSERT INTO users (username, password) VALUES (?, ?)", (username, hashed_pw))
|
37 |
conn.commit()
|
38 |
+
return "✅ Registration Successful!"
|
39 |
except sqlite3.IntegrityError:
|
40 |
+
return "⚠️ Username already exists."
|
41 |
finally:
|
42 |
conn.close()
|
43 |
|
|
|
48 |
result = cursor.fetchone()
|
49 |
conn.close()
|
50 |
if result and bcrypt.checkpw(password.encode(), result[0]):
|
51 |
+
return "✅ Login Successful!"
|
52 |
else:
|
53 |
+
return "❌ Incorrect username or password."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
|
55 |
+
# Load pre-trained models
|
56 |
+
product_model = joblib.load("product_lifecycle_model.pkl")
|
57 |
+
dynamic_pricing_model = joblib.load("dynamic_pricing_model.pkl")
|
58 |
+
recommendation_knn = joblib.load("recommendation_model.pkl")
|
59 |
+
preprocessor = joblib.load("preprocessor.pkl")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
scaler = joblib.load("scaler.pkl")
|
61 |
label_encoders = joblib.load("label_encoders.pkl")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
|
63 |
+
def predict_lifecycle(*inputs):
|
64 |
+
input_df = pd.DataFrame([inputs], columns=["Category", "ProductName", "Price", "Rating", "NumReviews", "StockQuantity", "Discount"])
|
65 |
+
processed_input = preprocessor.transform(input_df)
|
66 |
+
prediction = product_model.predict(processed_input)[0]
|
67 |
+
return f"Predicted Product Lifecycle: {round(prediction, 2)} years"
|
68 |
|
69 |
+
def predict_price(*inputs):
|
70 |
+
category, product_name, base_price, competitor_price, demand, stock, reviews, rating, season, discount = inputs
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
category = label_encoders["Category"].transform([category])[0]
|
72 |
demand = label_encoders["Demand"].transform([demand])[0]
|
73 |
season = label_encoders["Season"].transform([season])[0]
|
74 |
product_name = label_encoders["Product Name"].transform([product_name])[0]
|
|
|
|
|
75 |
features = np.array([base_price, competitor_price, stock, reviews, rating, discount]).reshape(1, -1)
|
76 |
+
scaled_features = scaler.transform(features)
|
77 |
+
final_features = np.concatenate((scaled_features.flatten(), [category, demand, season, product_name])).reshape(1, -1)
|
78 |
+
return f"Optimal Price: ₹{round(dynamic_pricing_model.predict(final_features)[0], 2)}"
|
|
|
|
|
|
|
|
|
|
|
79 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
def recommend_products(category):
|
81 |
+
recommended = recommendation_knn.kneighbors(category, return_distance=False)
|
82 |
+
return recommended.tolist()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
83 |
|
84 |
def generate_dashboard():
|
85 |
+
df = pd.read_csv("marketplace_data.csv")
|
86 |
+
lifecycle_fig = px.bar(df.groupby('Category')['LifecycleYears'].mean().reset_index(), x='Category', y='LifecycleYears', title='Product Lifecycle')
|
87 |
+
price_trend_fig = px.line(df.groupby('Category')['Price'].mean().reset_index(), x='Category', y='Price', title='Price Trends')
|
88 |
+
engagement_fig = px.bar(df.groupby('Category')['NumReviews'].sum().reset_index(), x='Category', y='NumReviews', title='User Reviews')
|
89 |
+
sustainability_fig = px.scatter(df, x='Price', y='Sustainability Score', color='Category', title='Sustainability Insights')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
return lifecycle_fig, price_trend_fig, engagement_fig, sustainability_fig
|
91 |
|
92 |
+
def update_live_data():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
while True:
|
94 |
+
df = pd.read_csv("marketplace_data.csv")
|
95 |
+
new_entry = {"Category": np.random.choice(["Electronics", "Plastic", "Metal", "Wood", "Composite"]),
|
96 |
+
"LifecycleYears": round(np.random.uniform(1, 20), 2),
|
97 |
+
"Price": round(np.random.uniform(10, 500), 2),
|
98 |
+
"NumReviews": np.random.randint(0, 1000)}
|
99 |
+
df = df.append(new_entry, ignore_index=True)
|
100 |
+
df.to_csv("marketplace_data.csv", index=False)
|
101 |
+
time.sleep(5)
|
102 |
+
|
103 |
+
t = threading.Thread(target=update_live_data, daemon=True)
|
104 |
+
t.start()
|
105 |
+
|
106 |
+
# Gradio UI
|
107 |
+
with gr.Blocks() as app:
|
108 |
+
gr.Markdown("# 🔄 Circular Economy Marketplace")
|
109 |
+
with gr.Tab("Login / Register"):
|
110 |
+
with gr.Row():
|
111 |
+
with gr.Column():
|
112 |
+
gr.Markdown("### Register")
|
113 |
+
reg_username = gr.Textbox(label="Username")
|
114 |
+
reg_password = gr.Textbox(label="Password", type="password")
|
115 |
+
reg_button = gr.Button("Register")
|
116 |
+
reg_output = gr.Textbox()
|
117 |
+
reg_button.click(register, inputs=[reg_username, reg_password], outputs=reg_output)
|
118 |
+
with gr.Column():
|
119 |
+
gr.Markdown("### Login")
|
120 |
+
log_username = gr.Textbox(label="Username")
|
121 |
+
log_password = gr.Textbox(label="Password", type="password")
|
122 |
+
log_button = gr.Button("Login")
|
123 |
+
log_output = gr.Textbox()
|
124 |
+
log_button.click(login, inputs=[log_username, log_password], outputs=log_output)
|
125 |
+
|
126 |
+
with gr.Tab("Product Lifecycle Prediction"):
|
127 |
+
lifecycle_inputs = [gr.Textbox(label=field) for field in ["Category", "ProductName", "Price", "Rating", "NumReviews", "StockQuantity", "Discount"]]
|
128 |
+
lifecycle_output = gr.Textbox()
|
129 |
+
gr.Interface(fn=predict_lifecycle, inputs=lifecycle_inputs, outputs=lifecycle_output)
|
130 |
+
|
131 |
+
with gr.Tab("Dynamic Pricing"):
|
132 |
+
price_inputs = [gr.Textbox(label=field) for field in ["Product Name", "Category", "Base Price", "Competitor Price", "Demand", "Stock", "Reviews", "Rating", "Season", "Discount"]]
|
133 |
+
price_output = gr.Textbox()
|
134 |
+
gr.Interface(fn=predict_price, inputs=price_inputs, outputs=price_output)
|
135 |
+
|
136 |
+
with gr.Tab("Recommendations"):
|
137 |
+
category_input = gr.Textbox(label="Category")
|
138 |
+
recommendations_output = gr.Textbox()
|
139 |
+
gr.Interface(fn=recommend_products, inputs=category_input, outputs=recommendations_output)
|
140 |
+
|
141 |
+
with gr.Tab("Analytics Dashboard"):
|
142 |
+
gr.Interface(fn=generate_dashboard, inputs=[], outputs=[gr.Plot(), gr.Plot(), gr.Plot(), gr.Plot()])
|
143 |
+
|
144 |
+
app.launch(share=True)
|