Skip to content

Commit 2db8e26

Browse files
Adding the GPR Notebook for Hyperparameter tuning
1 parent cd5ef3b commit 2db8e26

File tree

8 files changed

+431
-258
lines changed

8 files changed

+431
-258
lines changed

GPR_Optimization.py

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# /// script
2+
# requires-python = ">=3.12"
3+
# dependencies = [
4+
# "marimo",
5+
# "matplotlib==3.10.3",
6+
# "numpy==2.2.6",
7+
# "scikit-learn==1.6.1",
8+
# "scipy==1.15.3",
9+
# ]
10+
# ///
11+
12+
import marimo
13+
14+
__generated_with = "0.13.7"
15+
app = marimo.App(width="medium")
16+
17+
18+
@app.cell
19+
def _():
20+
import numpy as np
21+
import matplotlib.pyplot as plt
22+
from sklearn.gaussian_process import GaussianProcessRegressor
23+
from sklearn.gaussian_process.kernels import Matern, WhiteKernel, ConstantKernel as C
24+
25+
def black_box_function(x):
26+
return - (np.sin(3*x) + 0.5 * x)
27+
return (
28+
C,
29+
GaussianProcessRegressor,
30+
Matern,
31+
WhiteKernel,
32+
black_box_function,
33+
np,
34+
plt,
35+
)
36+
37+
38+
@app.cell
39+
def _(black_box_function, np, plt):
40+
X = np.linspace(0, 5.5, 1000).reshape(-1, 1)
41+
y = black_box_function(X)
42+
plt.plot(X, y)
43+
plt.title("Black-box function")
44+
plt.xlabel("x")
45+
plt.ylabel("f(x)")
46+
plt.show()
47+
return X, y
48+
49+
50+
@app.cell
51+
def _(black_box_function, np):
52+
X_grid = np.linspace(0, 2, 100).reshape(-1, 1)
53+
y_grid = black_box_function(X_grid)
54+
x_best = X_grid[np.argmax(y_grid)]
55+
return
56+
57+
58+
@app.cell
59+
def _(black_box_function, np):
60+
# Initial sample points (simulate prior evaluations)
61+
X_sample = np.array([[1.0], [3.0], [5.5]])
62+
y_sample = black_box_function(X_sample)
63+
return X_sample, y_sample
64+
65+
66+
@app.cell
67+
def _(C, GaussianProcessRegressor, Matern, WhiteKernel, X_sample, y_sample):
68+
# Define the kernel
69+
kernel = C(1.0) * Matern(length_scale=1.0, nu=2.5) + WhiteKernel(noise_level=1e-5, noise_level_bounds=(1e-10, 1e1))
70+
71+
# Create and fit the Gaussian Process model
72+
gpr = GaussianProcessRegressor(kernel=kernel, alpha=0.0)
73+
gpr.fit(X_sample, y_sample)
74+
return (gpr,)
75+
76+
77+
@app.cell
78+
def _(X, X_sample, gpr, plt, y, y_sample):
79+
# Predict across the domain
80+
mu, std = gpr.predict(X, return_std=True)
81+
82+
# Plot the result
83+
plt.figure(figsize=(10, 5))
84+
plt.plot(X, y, 'k--', label="True function")
85+
plt.plot(X, mu, 'b-', label="GPR mean")
86+
plt.fill_between(X.ravel(), mu - std, mu + std, alpha=0.3, label="Uncertainty")
87+
plt.scatter(X_sample, y_sample, c='red', label="Samples")
88+
plt.legend()
89+
plt.title("Gaussian Process Fit")
90+
plt.xlabel("x")
91+
plt.ylabel("f(x)")
92+
plt.show()
93+
return
94+
95+
96+
@app.cell
97+
def _(np):
98+
from scipy.stats import norm
99+
100+
def expected_improvement(X, X_sample, y_sample, model, xi=0.01):
101+
mu, std = model.predict(X, return_std=True)
102+
mu_sample_opt = np.min(y_sample)
103+
104+
with np.errstate(divide='warn'):
105+
imp = mu_sample_opt - mu - xi # because we are minimizing
106+
Z = imp / std
107+
ei = imp * norm.cdf(Z) + std * norm.pdf(Z)
108+
ei[std == 0.0] = 0.0
109+
110+
return ei
111+
112+
return (expected_improvement,)
113+
114+
115+
@app.cell
116+
def _(X, X_sample, expected_improvement, gpr, np, plt, y_sample):
117+
ei = expected_improvement(X, X_sample, y_sample, gpr)
118+
119+
plt.figure(figsize=(10, 4))
120+
plt.plot(X, ei, label="Expected Improvement")
121+
plt.axvline(X[np.argmax(ei)], color='r', linestyle='--', label="Next sample point")
122+
plt.title("Acquisition Function (Expected Improvement)")
123+
plt.xlabel("x")
124+
plt.ylabel("EI(x)")
125+
plt.legend()
126+
plt.show()
127+
128+
return
129+
130+
131+
@app.cell
132+
def _(X, black_box_function, expected_improvement, gpr, np):
133+
def bayesian_optimization(n_iter=10):
134+
# Initial data
135+
X_sample = np.array([[1.0], [2.5], [4.0]])
136+
y_sample = black_box_function(X_sample)
137+
138+
for i in range(n_iter):
139+
gpr.fit(X_sample, y_sample)
140+
ei = expected_improvement(X, X_sample, y_sample, gpr)
141+
x_next = X[np.argmax(ei)].reshape(-1, 1)
142+
143+
# Evaluate the function at the new point
144+
y_next = black_box_function(x_next)
145+
146+
# Add the new sample to our dataset
147+
X_sample = np.vstack((X_sample, x_next))
148+
y_sample = np.append(y_sample, y_next)
149+
return X_sample, y_sample
150+
151+
return (bayesian_optimization,)
152+
153+
154+
@app.cell
155+
def _(bayesian_optimization):
156+
X_opt, y_opt = bayesian_optimization(n_iter=10)
157+
158+
return X_opt, y_opt
159+
160+
161+
@app.cell
162+
def _(X, X_opt, black_box_function, plt, y_opt):
163+
# Plot final sampled points
164+
plt.plot(X, black_box_function(X), 'k--', label="True function")
165+
plt.scatter(X_opt, y_opt, c='red', label="Sampled Points")
166+
plt.title("Bayesian Optimization with Gaussian Process")
167+
plt.xlabel("x")
168+
plt.ylabel("f(x)")
169+
plt.legend()
170+
plt.show()
171+
172+
return
173+
174+
175+
@app.cell
176+
def _():
177+
return
178+
179+
180+
if __name__ == "__main__":
181+
app.run()

public/GPR_Optimization.html

Lines changed: 82 additions & 0 deletions
Large diffs are not rendered by default.

public/index.html

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -85,22 +85,14 @@ <h2 class="notebook-title">polars vs pandas</h2>
8585
<h2 class="notebook-title">pyspark parametrize</h2>
8686
<a href="data_science_tools/pyspark_parametrize.html" class="notebook-link">View the notebook</a>
8787
</li>
88-
<li class="notebook-item">
89-
<h2 class="notebook-title">diffbot llm</h2>
90-
<a href="llm/diffbot_llm.html" class="notebook-link">View the notebook</a>
91-
</li>
92-
<li class="notebook-item">
93-
<h2 class="notebook-title">lchain deepseek</h2>
94-
<a href="llm/lchain_deepseek.html" class="notebook-link">View the notebook</a>
95-
</li>
96-
<li class="notebook-item">
97-
<h2 class="notebook-title">lchain ollama</h2>
98-
<a href="llm/lchain_ollama.html" class="notebook-link">View the notebook</a>
99-
</li>
10088
<li class="notebook-item">
10189
<h2 class="notebook-title">pydantic ai examples</h2>
10290
<a href="llm/pydantic_ai_examples.html" class="notebook-link">View the notebook</a>
10391
</li>
92+
<li class="notebook-item">
93+
<h2 class="notebook-title">temp</h2>
94+
<a href="temp/temp.html" class="notebook-link">View the notebook</a>
95+
</li>
10496
</ul>
10597
</body>
10698
</html>

public/llm/diffbot_llm.html

Lines changed: 0 additions & 82 deletions
This file was deleted.

public/llm/lchain_deepseek.html

Lines changed: 0 additions & 82 deletions
This file was deleted.

public/llm/lchain_ollama.html

Lines changed: 0 additions & 82 deletions
This file was deleted.

public/temp.html

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<link rel="icon" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.13.7/dist/favicon.ico" />
6+
<!-- Preload is necessary because we show these images when we disconnect from the server,
7+
but at that point we cannot load these images from the server -->
8+
<link rel="preload" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.13.7/dist/assets/gradient-yHQUC_QB.png" as="image" />
9+
<link rel="preload" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.13.7/dist/assets/noise-60BoTA8O.png" as="image" />
10+
<!-- Preload the fonts -->
11+
<link rel="preload" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.13.7/dist/assets/Lora-VariableFont_wght-B2ootaw-.ttf" as="font" crossorigin="anonymous" />
12+
<link rel="preload" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.13.7/dist/assets/PTSans-Regular-CxL0S8W7.ttf" as="font" crossorigin="anonymous" />
13+
<link rel="preload" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.13.7/dist/assets/PTSans-Bold-D9fedIX3.ttf" as="font" crossorigin="anonymous" />
14+
<link rel="preload" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.13.7/dist/assets/FiraMono-Regular-BTCkDNvf.ttf" as="font" crossorigin="anonymous" />
15+
<link rel="preload" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.13.7/dist/assets/FiraMono-Medium-DU3aDxX5.ttf" as="font" crossorigin="anonymous" />
16+
<link rel="preload" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.13.7/dist/assets/FiraMono-Bold-CLVRCuM9.ttf" as="font" crossorigin="anonymous" />
17+
18+
<meta name="viewport" content="width=device-width, initial-scale=1" />
19+
<meta name="theme-color" content="#000000" />
20+
<meta name="description" content="a marimo app" />
21+
<link rel="apple-touch-icon" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.13.7/dist/apple-touch-icon.png" />
22+
<link rel="manifest" crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.13.7/dist/manifest.json" />
23+
24+
<script data-marimo="true">
25+
function __resizeIframe(obj) {
26+
var scrollbarHeight = 20; // Max between windows, mac, and linux
27+
28+
function setHeight() {
29+
var element = obj.contentWindow.document.documentElement;
30+
// If there is no vertical scrollbar, we don't need to resize the iframe
31+
if (element.scrollHeight === element.clientHeight) {
32+
return;
33+
}
34+
35+
// Create a new height that includes the scrollbar height if it's visible
36+
var hasHorizontalScrollbar = element.scrollWidth > element.clientWidth;
37+
var newHeight = element.scrollHeight + (hasHorizontalScrollbar ? scrollbarHeight : 0);
38+
39+
// Only update the height if it's different from the current height
40+
if (obj.style.height !== `${newHeight}px`) {
41+
obj.style.height = `${newHeight}px`;
42+
}
43+
}
44+
45+
// Resize the iframe to the height of the content and bottom scrollbar height
46+
setHeight();
47+
48+
// Resize the iframe when the content changes
49+
const resizeObserver = new ResizeObserver((entries) => {
50+
setHeight();
51+
});
52+
resizeObserver.observe(obj.contentWindow.document.body);
53+
}
54+
</script>
55+
<marimo-filename hidden>temp.py</marimo-filename>
56+
<marimo-mode data-mode='read' hidden></marimo-mode>
57+
<marimo-version data-version='0.13.7' hidden></marimo-version>
58+
<marimo-user-config data-config='{"completion": {"activate_on_typing": true, "copilot": false}, "display": {"cell_output": "above", "code_editor_font_size": 14, "dataframes": "rich", "default_table_page_size": 10, "default_width": "medium", "theme": "light"}, "formatting": {"line_length": 79}, "keymap": {"overrides": {}, "preset": "default"}, "language_servers": {"pylsp": {"enable_flake8": false, "enable_mypy": true, "enable_pydocstyle": false, "enable_pyflakes": false, "enable_pylint": false, "enable_ruff": true, "enabled": true}}, "package_management": {"manager": "uv"}, "runtime": {"auto_instantiate": true, "auto_reload": "off", "on_cell_change": "autorun", "output_max_bytes": 8000000, "reactive_tests": true, "std_stream_max_bytes": 1000000, "watcher_on_save": "lazy"}, "save": {"autosave": "after_delay", "autosave_delay": 1000, "format_on_save": false}, "server": {"browser": "default", "follow_symlink": false}, "snippets": {"custom_paths": [], "include_default_snippets": true}}' data-overrides='{}' hidden></marimo-user-config>
59+
<marimo-app-config data-config='{"sql_output": "auto", "width": "medium"}' hidden></marimo-app-config>
60+
<marimo-server-token data-token='static' hidden></marimo-server-token>
61+
<title>temp</title>
62+
<script type="module" crossorigin crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.13.7/dist/assets/index-4h4O6nRv.js"></script>
63+
<link rel="stylesheet" crossorigin crossorigin="anonymous" href="https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.13.7/dist/assets/index-DredxwTT.css">
64+
65+
<script data-marimo="true">
66+
window.__MARIMO_STATIC__ = {};
67+
window.__MARIMO_STATIC__.version = "0.13.7";
68+
window.__MARIMO_STATIC__.notebookState = {"cellIds": ["Hbol", "MJUe", "vblA"], "cellNames": ["Xw==", "Xw==", "Xw=="], "cellCodes": ["", "aW1wb3J0JTIwbnVtcHklMjBhcyUyMG5wJTIwJTBBWCUyMCUzRCUyMG5wLmxpbnNwYWNlKDAlMkMxMCUyQzEwMCklMEFwcmludChYKQ==", ""], "cellConfigs": ["JTdCJTIyY29sdW1uJTIyJTNBJTIwbnVsbCUyQyUyMCUyMmRpc2FibGVkJTIyJTNBJTIwZmFsc2UlMkMlMjAlMjJoaWRlX2NvZGUlMjIlM0ElMjBmYWxzZSU3RA==", "JTdCJTIyY29sdW1uJTIyJTNBJTIwbnVsbCUyQyUyMCUyMmRpc2FibGVkJTIyJTNBJTIwZmFsc2UlMkMlMjAlMjJoaWRlX2NvZGUlMjIlM0ElMjBmYWxzZSU3RA==", "JTdCJTIyY29sdW1uJTIyJTNBJTIwbnVsbCUyQyUyMCUyMmRpc2FibGVkJTIyJTNBJTIwZmFsc2UlMkMlMjAlMjJoaWRlX2NvZGUlMjIlM0ElMjBmYWxzZSU3RA=="], "cellOutputs": {"Hbol": "JTdCJTIyY2hhbm5lbCUyMiUzQSUyMCUyMm91dHB1dCUyMiUyQyUyMCUyMm1pbWV0eXBlJTIyJTNBJTIwJTIydGV4dCUyRnBsYWluJTIyJTJDJTIwJTIyZGF0YSUyMiUzQSUyMCUyMiUyMiUyQyUyMCUyMnRpbWVzdGFtcCUyMiUzQSUyMDE3NDgyOTIyMTguNTk0NzUzJTdE", "MJUe": "JTdCJTIyY2hhbm5lbCUyMiUzQSUyMCUyMm91dHB1dCUyMiUyQyUyMCUyMm1pbWV0eXBlJTIyJTNBJTIwJTIydGV4dCUyRnBsYWluJTIyJTJDJTIwJTIyZGF0YSUyMiUzQSUyMCUyMiUyMiUyQyUyMCUyMnRpbWVzdGFtcCUyMiUzQSUyMDE3NDgyOTIyMTkuOTI2OTAzJTdE", "vblA": "JTdCJTIyY2hhbm5lbCUyMiUzQSUyMCUyMm91dHB1dCUyMiUyQyUyMCUyMm1pbWV0eXBlJTIyJTNBJTIwJTIydGV4dCUyRnBsYWluJTIyJTJDJTIwJTIyZGF0YSUyMiUzQSUyMCUyMiUyMiUyQyUyMCUyMnRpbWVzdGFtcCUyMiUzQSUyMDE3NDgyOTIyMTkuOTMwNTg0JTdE"}, "cellConsoleOutputs": {"MJUe": ["JTdCJTIyY2hhbm5lbCUyMiUzQSUyMCUyMnN0ZG91dCUyMiUyQyUyMCUyMm1pbWV0eXBlJTIyJTNBJTIwJTIydGV4dCUyRnBsYWluJTIyJTJDJTIwJTIyZGF0YSUyMiUzQSUyMCUyMiU1QiUyMDAuJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwJTIwMC4xMDEwMTAxJTIwJTIwJTIwMC4yMDIwMjAyJTIwJTIwJTIwMC4zMDMwMzAzJTIwJTIwJTIwMC40MDQwNDA0JTIwJTIwJTIwMC41MDUwNTA1MSU1Q24lMjAlMjAwLjYwNjA2MDYxJTIwJTIwMC43MDcwNzA3MSUyMCUyMDAuODA4MDgwODElMjAlMjAwLjkwOTA5MDkxJTIwJTIwMS4wMTAxMDEwMSUyMCUyMDEuMTExMTExMTElNUNuJTIwJTIwMS4yMTIxMjEyMSUyMCUyMDEuMzEzMTMxMzElMjAlMjAxLjQxNDE0MTQxJTIwJTIwMS41MTUxNTE1MiUyMCUyMDEuNjE2MTYxNjIlMjAlMjAxLjcxNzE3MTcyJTVDbiUyMCUyMDEuODE4MTgxODIlMjAlMjAxLjkxOTE5MTkyJTIwJTIwMi4wMjAyMDIwMiUyMCUyMDIuMTIxMjEyMTIlMjAlMjAyLjIyMjIyMjIyJTIwJTIwMi4zMjMyMzIzMiU1Q24lMjAlMjAyLjQyNDI0MjQyJTIwJTIwMi41MjUyNTI1MyUyMCUyMDIuNjI2MjYyNjMlMjAlMjAyLjcyNzI3MjczJTIwJTIwMi44MjgyODI4MyUyMCUyMDIuOTI5MjkyOTMlNUNuJTIwJTIwMy4wMzAzMDMwMyUyMCUyMDMuMTMxMzEzMTMlMjAlMjAzLjIzMjMyMzIzJTIwJTIwMy4zMzMzMzMzMyUyMCUyMDMuNDM0MzQzNDMlMjAlMjAzLjUzNTM1MzU0JTVDbiUyMCUyMDMuNjM2MzYzNjQlMjAlMjAzLjczNzM3Mzc0JTIwJTIwMy44MzgzODM4NCUyMCUyMDMuOTM5MzkzOTQlMjAlMjA0LjA0MDQwNDA0JTIwJTIwNC4xNDE0MTQxNCU1Q24lMjAlMjA0LjI0MjQyNDI0JTIwJTIwNC4zNDM0MzQzNCUyMCUyMDQuNDQ0NDQ0NDQlMjAlMjA0LjU0NTQ1NDU1JTIwJTIwNC42NDY0NjQ2NSUyMCUyMDQuNzQ3NDc0NzUlNUNuJTIwJTIwNC44NDg0ODQ4NSUyMCUyMDQuOTQ5NDk0OTUlMjAlMjA1LjA1MDUwNTA1JTIwJTIwNS4xNTE1MTUxNSUyMCUyMDUuMjUyNTI1MjUlMjAlMjA1LjM1MzUzNTM1JTVDbiUyMCUyMDUuNDU0NTQ1NDUlMjAlMjA1LjU1NTU1NTU2JTIwJTIwNS42NTY1NjU2NiUyMCUyMDUuNzU3NTc1NzYlMjAlMjA1Ljg1ODU4NTg2JTIwJTIwNS45NTk1OTU5NiU1Q24lMjAlMjA2LjA2MDYwNjA2JTIwJTIwNi4xNjE2MTYxNiUyMCUyMDYuMjYyNjI2MjYlMjAlMjA2LjM2MzYzNjM2JTIwJTIwNi40NjQ2NDY0NiUyMCUyMDYuNTY1NjU2NTclNUNuJTIwJTIwNi42NjY2NjY2NyUyMCUyMDYuNzY3Njc2NzclMjAlMjA2Ljg2ODY4Njg3JTIwJTIwNi45Njk2OTY5NyUyMCUyMDcuMDcwNzA3MDclMjAlMjA3LjE3MTcxNzE3JTVDbiUyMCUyMDcuMjcyNzI3MjclMjAlMjA3LjM3MzczNzM3JTIwJTIwNy40NzQ3NDc0NyUyMCUyMDcuNTc1NzU3NTglMjAlMjA3LjY3Njc2NzY4JTIwJTIwNy43Nzc3Nzc3OCU1Q24lMjAlMjA3Ljg3ODc4Nzg4JTIwJTIwNy45Nzk3OTc5OCUyMCUyMDguMDgwODA4MDglMjAlMjA4LjE4MTgxODE4JTIwJTIwOC4yODI4MjgyOCUyMCUyMDguMzgzODM4MzglNUNuJTIwJTIwOC40ODQ4NDg0OCUyMCUyMDguNTg1ODU4NTklMjAlMjA4LjY4Njg2ODY5JTIwJTIwOC43ODc4Nzg3OSUyMCUyMDguODg4ODg4ODklMjAlMjA4Ljk4OTg5ODk5JTVDbiUyMCUyMDkuMDkwOTA5MDklMjAlMjA5LjE5MTkxOTE5JTIwJTIwOS4yOTI5MjkyOSUyMCUyMDkuMzkzOTM5MzklMjAlMjA5LjQ5NDk0OTQ5JTIwJTIwOS41OTU5NTk2JTVDbiUyMCUyMDkuNjk2OTY5NyUyMCUyMCUyMDkuNzk3OTc5OCUyMCUyMCUyMDkuODk4OTg5OSUyMCUyMDEwLiUyMCUyMCUyMCUyMCUyMCUyMCUyMCUyMCU1RCU1Q24lMjIlMkMlMjAlMjJ0aW1lc3RhbXAlMjIlM0ElMjAxNzQ4MjkyMjE5LjkzMjkzMzglN0Q="]}};
69+
window.__MARIMO_STATIC__.assetUrl = "https://cdn.jsdelivr.net/npm/@marimo-team/frontend@0.13.7/dist";
70+
window.__MARIMO_STATIC__.files = {};
71+
</script>
72+
</head>
73+
<body>
74+
<div id="root"></div>
75+
76+
<marimo-code hidden="">
77+
import%20marimo%0A%0A__generated_with%20%3D%20%220.13.7%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20numpy%20as%20np%20%0A%20%20%20%20X%20%3D%20np.linspace(0%2C10%2C100)%0A%20%20%20%20print(X)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
78+
</marimo-code>
79+
80+
<marimo-code-hash hidden="">aedf1ff40fcab818e81332aa77d9fe138097f5fa660be8fe3efd77cd485e2686</marimo-code-hash>
81+
</body>
82+
</html>

0 commit comments

Comments
 (0)