Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -10,7 +10,7 @@ import sys
|
|
10 |
import subprocess
|
11 |
import json
|
12 |
from pygments import highlight
|
13 |
-
from pygments.lexers import PythonLexer
|
14 |
from pygments.formatters import HtmlFormatter
|
15 |
import base64
|
16 |
from transformers import pipeline
|
@@ -1003,6 +1003,7 @@ def generate_manim_video(python_code, format_type, quality_preset, animation_spe
|
|
1003 |
except Exception as e:
|
1004 |
logger.error(f"Failed to clean temp dir: {str(e)}")
|
1005 |
|
|
|
1006 |
def detect_input_calls(code):
|
1007 |
"""Detect input() calls in Python code to prepare for handling"""
|
1008 |
input_calls = []
|
@@ -1015,21 +1016,149 @@ def detect_input_calls(code):
|
|
1015 |
input_calls.append({"line": i+1, "prompt": prompt})
|
1016 |
return input_calls
|
1017 |
|
1018 |
-
def
|
1019 |
-
|
|
|
1020 |
result = {
|
1021 |
"stdout": "",
|
1022 |
"stderr": "",
|
1023 |
"exception": None,
|
1024 |
"plots": [],
|
1025 |
"dataframes": [],
|
1026 |
-
"execution_time": 0
|
|
|
|
|
|
|
1027 |
}
|
1028 |
|
1029 |
-
#
|
1030 |
-
|
1031 |
-
#
|
1032 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1033 |
# Input values provided by the user
|
1034 |
__INPUT_VALUES = {}
|
1035 |
__INPUT_INDEX = 0
|
@@ -1046,73 +1175,62 @@ def input(prompt=''):
|
|
1046 |
print("\\n[WARNING] No more predefined inputs available, using empty string")
|
1047 |
return ""
|
1048 |
""".format(inputs)
|
1049 |
-
|
1050 |
-
code = modified_code + code
|
1051 |
-
|
1052 |
-
# Create a tempdir for script execution
|
1053 |
-
with tempfile.TemporaryDirectory() as temp_dir:
|
1054 |
-
# Path for saving plots
|
1055 |
-
plot_dir = os.path.join(temp_dir, 'plots')
|
1056 |
-
os.makedirs(plot_dir, exist_ok=True)
|
1057 |
-
|
1058 |
-
# Files for capturing stdout and stderr
|
1059 |
-
stdout_file = os.path.join(temp_dir, 'stdout.txt')
|
1060 |
-
stderr_file = os.path.join(temp_dir, 'stderr.txt')
|
1061 |
-
|
1062 |
-
# Add plot saving code
|
1063 |
-
if 'matplotlib' in code or 'plt' in code:
|
1064 |
-
if 'import matplotlib.pyplot as plt' not in code and 'from matplotlib import pyplot as plt' not in code:
|
1065 |
-
code = "import matplotlib.pyplot as plt\n" + code
|
1066 |
-
|
1067 |
-
# Add code to save plots
|
1068 |
-
save_plots_code = """
|
1069 |
-
# Save all figures
|
1070 |
-
import matplotlib.pyplot as plt
|
1071 |
-
import os
|
1072 |
-
__figures = plt.get_fignums()
|
1073 |
-
for __i, __num in enumerate(__figures):
|
1074 |
-
__fig = plt.figure(__num)
|
1075 |
-
__fig.savefig(os.path.join('{}', f'plot_{{__i}}.png'))
|
1076 |
-
""".format(plot_dir.replace('\\', '\\\\'))
|
1077 |
|
1078 |
-
|
|
|
|
|
|
|
1079 |
|
1080 |
-
# Add
|
1081 |
-
|
1082 |
-
|
1083 |
-
code = "import pandas as pd\n" + code
|
1084 |
-
|
1085 |
-
# Add code to save dataframe info
|
1086 |
-
dataframes_code = """
|
1087 |
-
# Capture DataFrames
|
1088 |
-
import pandas as pd
|
1089 |
-
import json
|
1090 |
-
import io
|
1091 |
import os
|
1092 |
-
|
1093 |
-
|
1094 |
-
|
1095 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1096 |
try:
|
1097 |
-
|
1098 |
-
|
1099 |
-
"
|
1100 |
-
"
|
1101 |
-
"
|
1102 |
-
|
1103 |
-
}
|
1104 |
-
|
1105 |
-
json.dump(__df_info, __f)
|
1106 |
except:
|
1107 |
pass
|
1108 |
-
|
1109 |
-
|
1110 |
-
|
|
|
|
|
|
|
|
|
|
|
1111 |
|
1112 |
-
#
|
1113 |
-
|
1114 |
-
|
1115 |
-
f.write(code)
|
1116 |
|
1117 |
# Execute with timeout
|
1118 |
start_time = time.time()
|
@@ -1120,19 +1238,37 @@ for __var_name, __var_val in __globals_dict.items():
|
|
1120 |
# Run the script with stdout and stderr redirection
|
1121 |
with open(stdout_file, 'w') as stdout_f, open(stderr_file, 'w') as stderr_f:
|
1122 |
process = subprocess.Popen(
|
1123 |
-
[sys.executable,
|
1124 |
stdout=stdout_f,
|
1125 |
stderr=stderr_f,
|
1126 |
cwd=temp_dir
|
1127 |
)
|
1128 |
|
1129 |
-
|
1130 |
-
|
1131 |
-
|
1132 |
-
process.
|
1133 |
-
|
1134 |
-
|
1135 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1136 |
|
1137 |
# Read the output
|
1138 |
with open(stdout_file, 'r') as f:
|
@@ -1154,6 +1290,15 @@ for __var_name, __var_val in __globals_dict.items():
|
|
1154 |
with open(os.path.join(temp_dir, df_file), 'r') as f:
|
1155 |
result["dataframes"].append(json.load(f))
|
1156 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1157 |
# Calculate execution time
|
1158 |
result["execution_time"] = time.time() - start_time
|
1159 |
|
@@ -1163,8 +1308,8 @@ for __var_name, __var_val in __globals_dict.items():
|
|
1163 |
|
1164 |
return result
|
1165 |
|
1166 |
-
def
|
1167 |
-
"""Display the results from the Python script execution"""
|
1168 |
if not result:
|
1169 |
st.error("No results to display.")
|
1170 |
return
|
@@ -1180,24 +1325,415 @@ def display_python_script_results(result):
|
|
1180 |
st.error("Errors:")
|
1181 |
st.code(result["stderr"], language="bash")
|
1182 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1183 |
# Display plots if any
|
1184 |
if result["plots"]:
|
1185 |
st.markdown("### Plots")
|
1186 |
cols = st.columns(min(3, len(result["plots"])))
|
1187 |
for i, plot_data in enumerate(result["plots"]):
|
1188 |
cols[i % len(cols)].image(plot_data, use_column_width=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1189 |
|
1190 |
# Display dataframes if any
|
1191 |
if result["dataframes"]:
|
1192 |
st.markdown("### DataFrames")
|
1193 |
for df_info in result["dataframes"]:
|
1194 |
-
with st.expander(f"{df_info
|
1195 |
st.markdown(df_info["preview_html"], unsafe_allow_html=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1196 |
|
1197 |
# Display standard output
|
1198 |
if result["stdout"]:
|
1199 |
st.markdown("### Standard Output")
|
1200 |
st.code(result["stdout"], language="bash")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1201 |
|
1202 |
def parse_animation_steps(python_code):
|
1203 |
"""Parse Manim code to extract animation steps for timeline editor"""
|
@@ -1703,6 +2239,39 @@ def main():
|
|
1703 |
st.session_state.custom_model = "gpt-4o" # Default model
|
1704 |
st.session_state.first_load_complete = False # Prevent refreshes on first load
|
1705 |
st.session_state.pending_tab_switch = None # Track pending tab switches
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1706 |
|
1707 |
# Page configuration with improved layout
|
1708 |
st.set_page_config(
|
@@ -1873,8 +2442,8 @@ def main():
|
|
1873 |
st.error("Failed to install required packages. Please try again.")
|
1874 |
st.stop()
|
1875 |
|
1876 |
-
# Create main tabs
|
1877 |
-
tab_names = ["✨ Editor", "🤖 AI Assistant", "🎨 Assets", "🎞️ Timeline", "🎓 Educational Export", "🐍 Python Runner"]
|
1878 |
tabs = st.tabs(tab_names)
|
1879 |
|
1880 |
# Sidebar for rendering settings and custom libraries
|
@@ -1947,6 +2516,34 @@ def main():
|
|
1947 |
if st.session_state.custom_library_result:
|
1948 |
with st.expander("Installation Results"):
|
1949 |
st.code(st.session_state.custom_library_result)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1950 |
|
1951 |
# EDITOR TAB
|
1952 |
with tabs[0]:
|
@@ -2421,8 +3018,8 @@ class MyScene(Scene):
|
|
2421 |
if "Scene" not in completed_code:
|
2422 |
completed_code = f"""from manim import *
|
2423 |
|
2424 |
-
|
2425 |
-
|
2426 |
{completed_code}"""
|
2427 |
|
2428 |
# Store the generated code
|
@@ -2788,6 +3385,60 @@ class YourScene(Scene):
|
|
2788 |
st.markdown("### 🐍 Python Script Runner")
|
2789 |
st.markdown("Execute Python scripts and visualize the results directly.")
|
2790 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2791 |
# Predefined example scripts
|
2792 |
example_scripts = {
|
2793 |
"Select an example...": "",
|
@@ -2912,58 +3563,22 @@ plt.title('Distribution of A by Category')
|
|
2912 |
|
2913 |
if run_btn:
|
2914 |
with st.spinner("Executing Python script..."):
|
2915 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2916 |
st.session_state.python_result = result
|
2917 |
|
2918 |
# Display results
|
2919 |
if st.session_state.python_result:
|
2920 |
-
|
2921 |
-
|
2922 |
-
# Option to insert plots into Manim animation
|
2923 |
-
if st.session_state.python_result["plots"]:
|
2924 |
-
with st.expander("Add Plots to Manim Animation"):
|
2925 |
-
st.markdown("Select a plot to include in your Manim animation:")
|
2926 |
-
|
2927 |
-
plot_cols = st.columns(min(3, len(st.session_state.python_result["plots"])))
|
2928 |
-
|
2929 |
-
for i, plot_data in enumerate(st.session_state.python_result["plots"]):
|
2930 |
-
# Create a unique temporary file for each plot
|
2931 |
-
with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmp:
|
2932 |
-
tmp.write(plot_data)
|
2933 |
-
plot_path = tmp.name
|
2934 |
-
|
2935 |
-
# Display the plot with selection button
|
2936 |
-
with plot_cols[i % len(plot_cols)]:
|
2937 |
-
st.image(plot_data, use_column_width=True)
|
2938 |
-
if st.button(f"Use Plot {i+1}", key=f"use_plot_{i}"):
|
2939 |
-
# Create code to include this plot in Manim
|
2940 |
-
plot_code = f"""
|
2941 |
-
# Import the plot image
|
2942 |
-
plot_image = ImageMobject(r"{plot_path}")
|
2943 |
-
plot_image.scale(2) # Adjust size as needed
|
2944 |
-
self.play(FadeIn(plot_image))
|
2945 |
-
self.wait(1)
|
2946 |
-
"""
|
2947 |
-
# Insert into editor code
|
2948 |
-
if st.session_state.code:
|
2949 |
-
st.session_state.code += "\n" + plot_code
|
2950 |
-
st.session_state.temp_code = st.session_state.code
|
2951 |
-
st.success(f"Plot {i+1} added to your animation code!")
|
2952 |
-
# Set pending tab switch to editor tab
|
2953 |
-
st.session_state.pending_tab_switch = 0
|
2954 |
-
st.rerun()
|
2955 |
-
else:
|
2956 |
-
basic_scene = f"""from manim import *
|
2957 |
-
class PlotScene(Scene):
|
2958 |
-
def construct(self):
|
2959 |
-
{plot_code}
|
2960 |
-
"""
|
2961 |
-
st.session_state.code = basic_scene
|
2962 |
-
st.session_state.temp_code = basic_scene
|
2963 |
-
st.success(f"Created new scene with Plot {i+1}!")
|
2964 |
-
# Set pending tab switch to editor tab
|
2965 |
-
st.session_state.pending_tab_switch = 0
|
2966 |
-
st.rerun()
|
2967 |
|
2968 |
# Provide option to save the script
|
2969 |
if st.button("📄 Save This Script", key="save_script_btn"):
|
@@ -3011,6 +3626,1218 @@ class PlotScene(Scene):
|
|
3011 |
- Perfect for educational content combining data and animations
|
3012 |
""")
|
3013 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3014 |
# Help section
|
3015 |
with st.sidebar.expander("ℹ️ Help & Info"):
|
3016 |
st.markdown("""
|
|
|
10 |
import subprocess
|
11 |
import json
|
12 |
from pygments import highlight
|
13 |
+
from pygments.lexers import PythonLexer, CppLexer
|
14 |
from pygments.formatters import HtmlFormatter
|
15 |
import base64
|
16 |
from transformers import pipeline
|
|
|
1003 |
except Exception as e:
|
1004 |
logger.error(f"Failed to clean temp dir: {str(e)}")
|
1005 |
|
1006 |
+
# ENHANCED PYTHON RUNNER FUNCTIONS
|
1007 |
def detect_input_calls(code):
|
1008 |
"""Detect input() calls in Python code to prepare for handling"""
|
1009 |
input_calls = []
|
|
|
1016 |
input_calls.append({"line": i+1, "prompt": prompt})
|
1017 |
return input_calls
|
1018 |
|
1019 |
+
def run_python_script_enhanced(code, inputs=None, timeout=60, enable_debug=False, enable_profile=False,
|
1020 |
+
additional_libs=None, project_files=None, realtime_viz=False):
|
1021 |
+
"""Enhanced version of run_python_script with debugging, profiling, etc."""
|
1022 |
result = {
|
1023 |
"stdout": "",
|
1024 |
"stderr": "",
|
1025 |
"exception": None,
|
1026 |
"plots": [],
|
1027 |
"dataframes": [],
|
1028 |
+
"execution_time": 0,
|
1029 |
+
"profile_data": None,
|
1030 |
+
"debug_steps": [],
|
1031 |
+
"realtime_data": []
|
1032 |
}
|
1033 |
|
1034 |
+
# Create a tempdir for script execution
|
1035 |
+
with tempfile.TemporaryDirectory() as temp_dir:
|
1036 |
+
# Path for saving plots
|
1037 |
+
plot_dir = os.path.join(temp_dir, 'plots')
|
1038 |
+
os.makedirs(plot_dir, exist_ok=True)
|
1039 |
+
|
1040 |
+
# Handle multi-file project if provided
|
1041 |
+
if project_files:
|
1042 |
+
for filename, file_content in project_files.items():
|
1043 |
+
with open(os.path.join(temp_dir, filename), 'w', encoding='utf-8') as f:
|
1044 |
+
f.write(file_content)
|
1045 |
+
|
1046 |
+
# Set the main script path
|
1047 |
+
main_script = os.path.join(temp_dir, "main.py")
|
1048 |
+
else:
|
1049 |
+
# Write the single code file
|
1050 |
+
main_script = os.path.join(temp_dir, "script.py")
|
1051 |
+
with open(main_script, 'w', encoding='utf-8') as f:
|
1052 |
+
f.write(code)
|
1053 |
+
|
1054 |
+
# Add library imports if specified
|
1055 |
+
if additional_libs:
|
1056 |
+
lib_imports = "\n".join([f"import {lib}" for lib in additional_libs if lib != "numpy" and lib != "matplotlib"])
|
1057 |
+
if lib_imports:
|
1058 |
+
with open(main_script, 'r+', encoding='utf-8') as f:
|
1059 |
+
content = f.read()
|
1060 |
+
f.seek(0, 0)
|
1061 |
+
f.write(lib_imports + "\n\n" + content)
|
1062 |
+
|
1063 |
+
# Add debugging setup if enabled
|
1064 |
+
if enable_debug:
|
1065 |
+
debug_setup = """
|
1066 |
+
import pdb
|
1067 |
+
import sys
|
1068 |
+
import traceback
|
1069 |
+
|
1070 |
+
class StringIODebugger:
|
1071 |
+
def __init__(self):
|
1072 |
+
self.steps = []
|
1073 |
+
|
1074 |
+
def add_step(self, frame, event, arg):
|
1075 |
+
if event == 'line':
|
1076 |
+
self.steps.append({
|
1077 |
+
'file': frame.f_code.co_filename,
|
1078 |
+
'line': frame.f_lineno,
|
1079 |
+
'function': frame.f_code.co_name,
|
1080 |
+
'locals': {k: str(v) for k, v in frame.f_locals.items() if not k.startswith('__')}
|
1081 |
+
})
|
1082 |
+
return self
|
1083 |
+
|
1084 |
+
debug_steps = []
|
1085 |
+
def trace_calls(frame, event, arg):
|
1086 |
+
if event != 'call':
|
1087 |
+
return
|
1088 |
+
co = frame.f_code
|
1089 |
+
func_name = co.co_name
|
1090 |
+
if func_name == 'write':
|
1091 |
+
return
|
1092 |
+
line_no = frame.f_lineno
|
1093 |
+
filename = co.co_filename
|
1094 |
+
if 'debugger' in filename or func_name.startswith('__'):
|
1095 |
+
return
|
1096 |
+
debug_steps.append(f"Calling {func_name} in {filename} at line {line_no}")
|
1097 |
+
return trace_calls
|
1098 |
+
|
1099 |
+
sys.settrace(trace_calls)
|
1100 |
+
"""
|
1101 |
+
with open(main_script, 'r+', encoding='utf-8') as f:
|
1102 |
+
content = f.read()
|
1103 |
+
f.seek(0, 0)
|
1104 |
+
f.write(debug_setup + "\n" + content)
|
1105 |
+
|
1106 |
+
# Add profiling if enabled
|
1107 |
+
if enable_profile:
|
1108 |
+
profile_setup = """
|
1109 |
+
import cProfile
|
1110 |
+
import pstats
|
1111 |
+
import io
|
1112 |
+
|
1113 |
+
# Set up profiler
|
1114 |
+
profiler = cProfile.Profile()
|
1115 |
+
profiler.enable()
|
1116 |
+
"""
|
1117 |
+
profile_teardown = """
|
1118 |
+
# Finish profiling
|
1119 |
+
profiler.disable()
|
1120 |
+
s = io.StringIO()
|
1121 |
+
ps = pstats.Stats(profiler, stream=s).sort_stats('cumulative')
|
1122 |
+
ps.print_stats()
|
1123 |
+
with open('profile_results.txt', 'w') as f:
|
1124 |
+
f.write(s.getvalue())
|
1125 |
+
"""
|
1126 |
+
with open(main_script, 'r+', encoding='utf-8') as f:
|
1127 |
+
content = f.read()
|
1128 |
+
f.seek(0, 0)
|
1129 |
+
f.write(profile_setup + "\n" + content + "\n" + profile_teardown)
|
1130 |
+
|
1131 |
+
# Add real-time visualization if enabled
|
1132 |
+
if realtime_viz:
|
1133 |
+
realtime_viz_setup = """
|
1134 |
+
# Setup for real-time visualization
|
1135 |
+
import threading
|
1136 |
+
import json
|
1137 |
+
import time
|
1138 |
+
|
1139 |
+
class RealTimeData:
|
1140 |
+
def __init__(self):
|
1141 |
+
self.data = []
|
1142 |
+
|
1143 |
+
def add_data(self, label, value):
|
1144 |
+
self.data.append({'label': label, 'value': value, 'time': time.time()})
|
1145 |
+
# Write to file for real-time monitoring
|
1146 |
+
with open('realtime_data.json', 'w') as f:
|
1147 |
+
json.dump(self.data, f)
|
1148 |
+
|
1149 |
+
rt_data = RealTimeData()
|
1150 |
+
|
1151 |
+
# Example usage: rt_data.add_data("iteration", i)
|
1152 |
+
"""
|
1153 |
+
with open(main_script, 'r+', encoding='utf-8') as f:
|
1154 |
+
content = f.read()
|
1155 |
+
f.seek(0, 0)
|
1156 |
+
f.write(realtime_viz_setup + "\n" + content)
|
1157 |
+
|
1158 |
+
# Add input handling code
|
1159 |
+
if inputs and len(inputs) > 0:
|
1160 |
+
# Modify the code to use predefined inputs instead of waiting for user input
|
1161 |
+
input_handling = """
|
1162 |
# Input values provided by the user
|
1163 |
__INPUT_VALUES = {}
|
1164 |
__INPUT_INDEX = 0
|
|
|
1175 |
print("\\n[WARNING] No more predefined inputs available, using empty string")
|
1176 |
return ""
|
1177 |
""".format(inputs)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1178 |
|
1179 |
+
with open(main_script, 'r+', encoding='utf-8') as f:
|
1180 |
+
content = f.read()
|
1181 |
+
f.seek(0, 0)
|
1182 |
+
f.write(input_handling + "\n" + content)
|
1183 |
|
1184 |
+
# Add matplotlib and pandas handling
|
1185 |
+
data_handling = """
|
1186 |
+
# Add plot saving code if matplotlib is used
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1187 |
import os
|
1188 |
+
|
1189 |
+
# For matplotlib plots
|
1190 |
+
if 'matplotlib' in globals() or 'matplotlib.pyplot' in globals() or 'plt' in globals():
|
1191 |
+
import matplotlib
|
1192 |
+
matplotlib.use('Agg') # Use non-interactive backend
|
1193 |
+
import matplotlib.pyplot as plt
|
1194 |
+
|
1195 |
+
# Hook to save all figures
|
1196 |
+
original_show = plt.show
|
1197 |
+
def custom_show(*args, **kwargs):
|
1198 |
+
for i, fig in enumerate(map(plt.figure, plt.get_fignums())):
|
1199 |
+
fig.savefig(os.path.join('{}', f'plot_{{i}}.png'))
|
1200 |
+
return original_show(*args, **kwargs)
|
1201 |
+
plt.show = custom_show
|
1202 |
+
|
1203 |
+
# For pandas DataFrames
|
1204 |
+
if 'pandas' in globals() or 'pd' in globals():
|
1205 |
+
import pandas as pd
|
1206 |
+
import json
|
1207 |
+
|
1208 |
+
# Save DataFrames
|
1209 |
+
original_df_repr_html = pd.DataFrame._repr_html_
|
1210 |
+
def custom_df_repr_html(self):
|
1211 |
try:
|
1212 |
+
df_info = {{
|
1213 |
+
"name": str(id(self)),
|
1214 |
+
"shape": self.shape,
|
1215 |
+
"columns": list(map(str, self.columns)),
|
1216 |
+
"preview_html": self.head().to_html()
|
1217 |
+
}}
|
1218 |
+
with open(f'df_{{id(self)}}.json', 'w') as f:
|
1219 |
+
json.dump(df_info, f)
|
|
|
1220 |
except:
|
1221 |
pass
|
1222 |
+
return original_df_repr_html(self)
|
1223 |
+
pd.DataFrame._repr_html_ = custom_df_repr_html
|
1224 |
+
""".format(plot_dir.replace('\\', '\\\\'))
|
1225 |
+
|
1226 |
+
with open(main_script, 'r+', encoding='utf-8') as f:
|
1227 |
+
content = f.read()
|
1228 |
+
f.seek(0, 0)
|
1229 |
+
f.write(data_handling + "\n" + content)
|
1230 |
|
1231 |
+
# Files for capturing stdout and stderr
|
1232 |
+
stdout_file = os.path.join(temp_dir, 'stdout.txt')
|
1233 |
+
stderr_file = os.path.join(temp_dir, 'stderr.txt')
|
|
|
1234 |
|
1235 |
# Execute with timeout
|
1236 |
start_time = time.time()
|
|
|
1238 |
# Run the script with stdout and stderr redirection
|
1239 |
with open(stdout_file, 'w') as stdout_f, open(stderr_file, 'w') as stderr_f:
|
1240 |
process = subprocess.Popen(
|
1241 |
+
[sys.executable, main_script],
|
1242 |
stdout=stdout_f,
|
1243 |
stderr=stderr_f,
|
1244 |
cwd=temp_dir
|
1245 |
)
|
1246 |
|
1247 |
+
# Real-time monitoring for real-time visualization
|
1248 |
+
if realtime_viz:
|
1249 |
+
realtime_data_file = os.path.join(temp_dir, 'realtime_data.json')
|
1250 |
+
while process.poll() is None:
|
1251 |
+
if os.path.exists(realtime_data_file):
|
1252 |
+
try:
|
1253 |
+
with open(realtime_data_file, 'r') as f:
|
1254 |
+
result["realtime_data"] = json.load(f)
|
1255 |
+
except:
|
1256 |
+
pass
|
1257 |
+
time.sleep(0.1)
|
1258 |
+
|
1259 |
+
# Check for timeout
|
1260 |
+
if time.time() - start_time > timeout:
|
1261 |
+
process.kill()
|
1262 |
+
result["stderr"] += f"\nScript execution timed out after {timeout} seconds."
|
1263 |
+
result["exception"] = "TimeoutError"
|
1264 |
+
break
|
1265 |
+
else:
|
1266 |
+
try:
|
1267 |
+
process.wait(timeout=timeout)
|
1268 |
+
except subprocess.TimeoutExpired:
|
1269 |
+
process.kill()
|
1270 |
+
result["stderr"] += f"\nScript execution timed out after {timeout} seconds."
|
1271 |
+
result["exception"] = "TimeoutError"
|
1272 |
|
1273 |
# Read the output
|
1274 |
with open(stdout_file, 'r') as f:
|
|
|
1290 |
with open(os.path.join(temp_dir, df_file), 'r') as f:
|
1291 |
result["dataframes"].append(json.load(f))
|
1292 |
|
1293 |
+
# Collect profiling data if enabled
|
1294 |
+
if enable_profile and os.path.exists(os.path.join(temp_dir, 'profile_results.txt')):
|
1295 |
+
with open(os.path.join(temp_dir, 'profile_results.txt'), 'r') as f:
|
1296 |
+
result["profile_data"] = f.read()
|
1297 |
+
|
1298 |
+
# Collect debug data if enabled
|
1299 |
+
if enable_debug and 'debug_steps' in globals():
|
1300 |
+
result["debug_steps"] = debug_steps
|
1301 |
+
|
1302 |
# Calculate execution time
|
1303 |
result["execution_time"] = time.time() - start_time
|
1304 |
|
|
|
1308 |
|
1309 |
return result
|
1310 |
|
1311 |
+
def display_python_script_results_enhanced(result):
|
1312 |
+
"""Display the enhanced results from the Python script execution"""
|
1313 |
if not result:
|
1314 |
st.error("No results to display.")
|
1315 |
return
|
|
|
1325 |
st.error("Errors:")
|
1326 |
st.code(result["stderr"], language="bash")
|
1327 |
|
1328 |
+
# Display profiling data if available
|
1329 |
+
if result.get("profile_data"):
|
1330 |
+
with st.expander("Profiling Results"):
|
1331 |
+
st.code(result["profile_data"], language="bash")
|
1332 |
+
|
1333 |
+
# Display debugging steps if available
|
1334 |
+
if result.get("debug_steps"):
|
1335 |
+
with st.expander("Debugging Steps"):
|
1336 |
+
for i, step in enumerate(result["debug_steps"]):
|
1337 |
+
st.markdown(f"**Step {i+1}**: {step}")
|
1338 |
+
|
1339 |
# Display plots if any
|
1340 |
if result["plots"]:
|
1341 |
st.markdown("### Plots")
|
1342 |
cols = st.columns(min(3, len(result["plots"])))
|
1343 |
for i, plot_data in enumerate(result["plots"]):
|
1344 |
cols[i % len(cols)].image(plot_data, use_column_width=True)
|
1345 |
+
|
1346 |
+
# Add button to use this plot in Manim
|
1347 |
+
if cols[i % len(cols)].button(f"Use in Manim", key=f"use_plot_{i}"):
|
1348 |
+
# Create a temporary file
|
1349 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix=".png") as tmp:
|
1350 |
+
tmp.write(plot_data)
|
1351 |
+
plot_path = tmp.name
|
1352 |
+
|
1353 |
+
# Generate Manim code
|
1354 |
+
plot_code = f"""
|
1355 |
+
# Import the plot image
|
1356 |
+
plot_image = ImageMobject(r"{plot_path}")
|
1357 |
+
plot_image.scale(2) # Adjust size as needed
|
1358 |
+
self.play(FadeIn(plot_image))
|
1359 |
+
self.wait(1)
|
1360 |
+
"""
|
1361 |
+
if st.session_state.code:
|
1362 |
+
st.session_state.code += "\n" + plot_code
|
1363 |
+
else:
|
1364 |
+
st.session_state.code = f"""from manim import *
|
1365 |
+
class PlotScene(Scene):
|
1366 |
+
def construct(self):
|
1367 |
+
{plot_code}
|
1368 |
+
"""
|
1369 |
+
st.session_state.temp_code = st.session_state.code
|
1370 |
+
st.success(f"Added plot to your Manim code!")
|
1371 |
+
# Set pending tab switch to editor tab
|
1372 |
+
st.session_state.pending_tab_switch = 0
|
1373 |
+
st.rerun()
|
1374 |
|
1375 |
# Display dataframes if any
|
1376 |
if result["dataframes"]:
|
1377 |
st.markdown("### DataFrames")
|
1378 |
for df_info in result["dataframes"]:
|
1379 |
+
with st.expander(f"{df_info.get('name', 'DataFrame')} - {df_info['shape'][0]} rows × {df_info['shape'][1]} columns"):
|
1380 |
st.markdown(df_info["preview_html"], unsafe_allow_html=True)
|
1381 |
+
|
1382 |
+
# Add button to visualize this dataframe in Manim
|
1383 |
+
if st.button(f"Visualize in Manim", key=f"viz_df_{df_info.get('name', 'df')}"):
|
1384 |
+
# Generate Manim code for dataframe visualization
|
1385 |
+
df_viz_code = f"""
|
1386 |
+
# Create a simple table visualization
|
1387 |
+
columns = {df_info['columns']}
|
1388 |
+
table = Table(
|
1389 |
+
col_labels=[Text(col, font_size=24) for col in columns]
|
1390 |
+
)
|
1391 |
+
|
1392 |
+
# Add data rows (showing first 5 rows)
|
1393 |
+
for i in range(min(5, {df_info['shape'][0]})):
|
1394 |
+
# This is a placeholder - in a real implementation, you'd extract actual data
|
1395 |
+
table.add_row(*[Text(f"Row {{i}}, Col {{j}}", font_size=20) for j in range(len(columns))])
|
1396 |
+
|
1397 |
+
self.play(Create(table))
|
1398 |
+
self.wait(1)
|
1399 |
+
"""
|
1400 |
+
if st.session_state.code:
|
1401 |
+
st.session_state.code += "\n" + df_viz_code
|
1402 |
+
else:
|
1403 |
+
st.session_state.code = f"""from manim import *
|
1404 |
+
class DataFrameScene(Scene):
|
1405 |
+
def construct(self):
|
1406 |
+
{df_viz_code}
|
1407 |
+
"""
|
1408 |
+
st.session_state.temp_code = st.session_state.code
|
1409 |
+
st.success(f"Added DataFrame visualization to your Manim code!")
|
1410 |
+
# Set pending tab switch to editor tab
|
1411 |
+
st.session_state.pending_tab_switch = 0
|
1412 |
+
st.rerun()
|
1413 |
|
1414 |
# Display standard output
|
1415 |
if result["stdout"]:
|
1416 |
st.markdown("### Standard Output")
|
1417 |
st.code(result["stdout"], language="bash")
|
1418 |
+
|
1419 |
+
# Display real-time data if available
|
1420 |
+
if result.get("realtime_data"):
|
1421 |
+
st.markdown("### Real-time Data")
|
1422 |
+
|
1423 |
+
# Convert to DataFrame for easier visualization
|
1424 |
+
import pandas as pd
|
1425 |
+
rt_df = pd.DataFrame(result["realtime_data"])
|
1426 |
+
|
1427 |
+
# Create a plotly chart
|
1428 |
+
import plotly.express as px
|
1429 |
+
if not rt_df.empty and "time" in rt_df.columns and "value" in rt_df.columns:
|
1430 |
+
fig = px.line(rt_df, x="time", y="value", color="label" if "label" in rt_df.columns else None,
|
1431 |
+
title="Real-time Data Visualization")
|
1432 |
+
st.plotly_chart(fig, use_container_width=True)
|
1433 |
+
|
1434 |
+
# Add button to create Manim animation from this data
|
1435 |
+
if st.button("Create Manim Animation from Data", key="create_manim_from_rt"):
|
1436 |
+
# Extract data points
|
1437 |
+
data_points = []
|
1438 |
+
for _, row in rt_df.iterrows():
|
1439 |
+
if "value" in row:
|
1440 |
+
data_points.append(float(row["value"]))
|
1441 |
+
|
1442 |
+
# Generate Manim code
|
1443 |
+
rt_viz_code = f"""
|
1444 |
+
# Visualize real-time data
|
1445 |
+
data = {data_points}
|
1446 |
+
axes = Axes(
|
1447 |
+
x_range=[0, {len(data_points)}, 1],
|
1448 |
+
y_range=[{min(data_points) if data_points else 0}, {max(data_points) if data_points else 10}, {(max(data_points)-min(data_points))/10 if data_points and max(data_points) > min(data_points) else 1}],
|
1449 |
+
axis_config={{"color": BLUE}}
|
1450 |
+
)
|
1451 |
+
points = [axes.coords_to_point(i, v) for i, v in enumerate(data)]
|
1452 |
+
graph = VMobject(color=RED)
|
1453 |
+
graph.set_points_as_corners(points)
|
1454 |
+
|
1455 |
+
self.play(Create(axes))
|
1456 |
+
self.play(Create(graph), run_time=2)
|
1457 |
+
self.wait(1)
|
1458 |
+
"""
|
1459 |
+
if st.session_state.code:
|
1460 |
+
st.session_state.code += "\n" + rt_viz_code
|
1461 |
+
else:
|
1462 |
+
st.session_state.code = f"""from manim import *
|
1463 |
+
class DataVisualizationScene(Scene):
|
1464 |
+
def construct(self):
|
1465 |
+
{rt_viz_code}
|
1466 |
+
"""
|
1467 |
+
st.session_state.temp_code = st.session_state.code
|
1468 |
+
st.success(f"Added real-time data visualization to your Manim code!")
|
1469 |
+
# Set pending tab switch to editor tab
|
1470 |
+
st.session_state.pending_tab_switch = 0
|
1471 |
+
st.rerun()
|
1472 |
+
|
1473 |
+
# C/C++ RUNNER FUNCTIONS
|
1474 |
+
def compile_cpp_code_enhanced(code, settings, project_files=None, enable_debug=False, breakpoints=None, watch_vars=None):
|
1475 |
+
"""Enhanced function to compile C++ code with advanced options."""
|
1476 |
+
try:
|
1477 |
+
# Create a temporary directory for compilation
|
1478 |
+
temp_dir = tempfile.mkdtemp(prefix="cpp_runner_")
|
1479 |
+
|
1480 |
+
# Write the project files
|
1481 |
+
if project_files:
|
1482 |
+
for filename, content in project_files.items():
|
1483 |
+
file_path = os.path.join(temp_dir, filename)
|
1484 |
+
with open(file_path, "w") as f:
|
1485 |
+
f.write(content)
|
1486 |
+
# Set main file for single file mode
|
1487 |
+
cpp_file = os.path.join(temp_dir, "main.cpp")
|
1488 |
+
else:
|
1489 |
+
# Write the single code file
|
1490 |
+
cpp_file = os.path.join(temp_dir, "main.cpp")
|
1491 |
+
with open(cpp_file, "w") as f:
|
1492 |
+
f.write(code)
|
1493 |
+
|
1494 |
+
# Output executable path
|
1495 |
+
exe_file = os.path.join(temp_dir, "program.exe" if platform.system() == "Windows" else "program")
|
1496 |
+
|
1497 |
+
# Build the compilation command
|
1498 |
+
compiler = settings.get("compiler", "g++")
|
1499 |
+
std_version = settings.get("std", "c++17")
|
1500 |
+
optimization = settings.get("optimization", "-O2")
|
1501 |
+
|
1502 |
+
compile_cmd = [
|
1503 |
+
compiler,
|
1504 |
+
"-std=" + std_version,
|
1505 |
+
optimization
|
1506 |
+
]
|
1507 |
+
|
1508 |
+
# Add debug flag if debugging is enabled
|
1509 |
+
if enable_debug:
|
1510 |
+
compile_cmd.append("-g")
|
1511 |
+
|
1512 |
+
# Add preprocessor definitions
|
1513 |
+
for definition in settings.get("definitions", []):
|
1514 |
+
if "=" in definition:
|
1515 |
+
name, value = definition.split("=", 1)
|
1516 |
+
compile_cmd.append(f"-D{name}={value}")
|
1517 |
+
else:
|
1518 |
+
compile_cmd.append(f"-D{definition}")
|
1519 |
+
|
1520 |
+
# Add include paths
|
1521 |
+
for path in settings.get("include_paths", []):
|
1522 |
+
compile_cmd.append(f"-I{path}")
|
1523 |
+
|
1524 |
+
# Add library paths
|
1525 |
+
for path in settings.get("library_paths", []):
|
1526 |
+
compile_cmd.append(f"-L{path}")
|
1527 |
+
|
1528 |
+
# Add files to compile
|
1529 |
+
if project_files:
|
1530 |
+
source_files = [os.path.join(temp_dir, f) for f in project_files.keys() if f.endswith((".cpp", ".c", ".cc"))]
|
1531 |
+
compile_cmd.extend(source_files)
|
1532 |
+
else:
|
1533 |
+
compile_cmd.append(cpp_file)
|
1534 |
+
|
1535 |
+
# Output file
|
1536 |
+
compile_cmd.extend(["-o", exe_file])
|
1537 |
+
|
1538 |
+
# Add libraries
|
1539 |
+
for lib in settings.get("libraries", []):
|
1540 |
+
if lib == "Eigen":
|
1541 |
+
# Eigen is header-only, nothing to link
|
1542 |
+
pass
|
1543 |
+
elif lib == "OpenCV":
|
1544 |
+
# Add OpenCV libraries
|
1545 |
+
try:
|
1546 |
+
# Get OpenCV libraries using pkg-config
|
1547 |
+
pkg_config = subprocess.run(
|
1548 |
+
["pkg-config", "--libs", "opencv4"],
|
1549 |
+
capture_output=True,
|
1550 |
+
text=True,
|
1551 |
+
check=False
|
1552 |
+
)
|
1553 |
+
if pkg_config.returncode == 0:
|
1554 |
+
compile_cmd.extend(pkg_config.stdout.strip().split())
|
1555 |
+
else:
|
1556 |
+
# Try opencv instead of opencv4
|
1557 |
+
pkg_config = subprocess.run(
|
1558 |
+
["pkg-config", "--libs", "opencv"],
|
1559 |
+
capture_output=True,
|
1560 |
+
text=True,
|
1561 |
+
check=False
|
1562 |
+
)
|
1563 |
+
if pkg_config.returncode == 0:
|
1564 |
+
compile_cmd.extend(pkg_config.stdout.strip().split())
|
1565 |
+
else:
|
1566 |
+
# Fallback to common OpenCV libraries
|
1567 |
+
compile_cmd.extend(["-lopencv_core", "-lopencv_imgproc", "-lopencv_highgui"])
|
1568 |
+
except:
|
1569 |
+
# Fallback to common OpenCV libraries
|
1570 |
+
compile_cmd.extend(["-lopencv_core", "-lopencv_imgproc", "-lopencv_highgui"])
|
1571 |
+
elif lib == "Boost":
|
1572 |
+
# Add common Boost libraries
|
1573 |
+
compile_cmd.extend(["-lboost_system", "-lboost_filesystem"])
|
1574 |
+
elif lib == "FFTW":
|
1575 |
+
compile_cmd.append("-lfftw3")
|
1576 |
+
elif lib == "SDL2":
|
1577 |
+
compile_cmd.append("-lSDL2")
|
1578 |
+
elif lib == "SFML":
|
1579 |
+
compile_cmd.extend(["-lsfml-graphics", "-lsfml-window", "-lsfml-system"])
|
1580 |
+
elif lib == "OpenGL":
|
1581 |
+
compile_cmd.extend(["-lGL", "-lGLU", "-lglut"])
|
1582 |
+
|
1583 |
+
# Add additional libraries
|
1584 |
+
for lib in settings.get("additional_libs", []):
|
1585 |
+
compile_cmd.append(f"-l{lib}")
|
1586 |
+
|
1587 |
+
# Add advanced flags
|
1588 |
+
if settings.get("advanced_flags"):
|
1589 |
+
compile_cmd.extend(settings["advanced_flags"].split())
|
1590 |
+
|
1591 |
+
# Run the compilation process
|
1592 |
+
logger.info(f"Compiling with command: {' '.join(compile_cmd)}")
|
1593 |
+
result = subprocess.run(
|
1594 |
+
compile_cmd,
|
1595 |
+
capture_output=True,
|
1596 |
+
text=True,
|
1597 |
+
check=False,
|
1598 |
+
cwd=temp_dir
|
1599 |
+
)
|
1600 |
+
|
1601 |
+
if result.returncode != 0:
|
1602 |
+
return None, result.stderr, temp_dir
|
1603 |
+
|
1604 |
+
return exe_file, None, temp_dir
|
1605 |
+
except Exception as e:
|
1606 |
+
return None, str(e), None
|
1607 |
+
|
1608 |
+
def run_cpp_executable_enhanced(exe_path, temp_dir, inputs=None, timeout=30, enable_debug=False, breakpoints=None, watch_vars=None):
|
1609 |
+
"""Enhanced function to run C++ executable with debugging support."""
|
1610 |
+
result = {
|
1611 |
+
"stdout": "",
|
1612 |
+
"stderr": "",
|
1613 |
+
"execution_time": 0,
|
1614 |
+
"images": [],
|
1615 |
+
"exception": None,
|
1616 |
+
"debug_output": None,
|
1617 |
+
"memory_usage": None
|
1618 |
+
}
|
1619 |
+
|
1620 |
+
try:
|
1621 |
+
# Prepare input data if provided
|
1622 |
+
input_data = "\n".join(inputs) if inputs else None
|
1623 |
+
|
1624 |
+
# Start timing
|
1625 |
+
start_time = time.time()
|
1626 |
+
|
1627 |
+
if enable_debug and breakpoints:
|
1628 |
+
# Run with GDB for debugging
|
1629 |
+
gdb_commands = ["set pagination off"]
|
1630 |
+
|
1631 |
+
# Add breakpoints
|
1632 |
+
for bp in breakpoints:
|
1633 |
+
gdb_commands.append(f"break {bp}")
|
1634 |
+
|
1635 |
+
# Add watchpoints for variables
|
1636 |
+
if watch_vars:
|
1637 |
+
for var in watch_vars:
|
1638 |
+
gdb_commands.append(f"watch {var}")
|
1639 |
+
|
1640 |
+
# Run the program
|
1641 |
+
gdb_commands.append("run")
|
1642 |
+
|
1643 |
+
# Continue to end
|
1644 |
+
gdb_commands.append("continue")
|
1645 |
+
|
1646 |
+
# Quit GDB
|
1647 |
+
gdb_commands.append("quit")
|
1648 |
+
|
1649 |
+
# Create GDB command file
|
1650 |
+
gdb_cmd_file = os.path.join(temp_dir, "gdb_commands.txt")
|
1651 |
+
with open(gdb_cmd_file, "w") as f:
|
1652 |
+
f.write("\n".join(gdb_commands))
|
1653 |
+
|
1654 |
+
# Run with GDB
|
1655 |
+
process = subprocess.run(
|
1656 |
+
["gdb", "-x", gdb_cmd_file, "-batch", exe_path],
|
1657 |
+
input=input_data,
|
1658 |
+
text=True,
|
1659 |
+
capture_output=True,
|
1660 |
+
timeout=timeout,
|
1661 |
+
cwd=temp_dir
|
1662 |
+
)
|
1663 |
+
|
1664 |
+
# Capture outputs
|
1665 |
+
result["stdout"] = process.stdout
|
1666 |
+
result["stderr"] = process.stderr
|
1667 |
+
result["debug_output"] = process.stdout
|
1668 |
+
else:
|
1669 |
+
# Run normally
|
1670 |
+
process = subprocess.run(
|
1671 |
+
[exe_path],
|
1672 |
+
input=input_data,
|
1673 |
+
text=True,
|
1674 |
+
capture_output=True,
|
1675 |
+
timeout=timeout,
|
1676 |
+
cwd=temp_dir
|
1677 |
+
)
|
1678 |
+
|
1679 |
+
# Capture outputs
|
1680 |
+
result["stdout"] = process.stdout
|
1681 |
+
result["stderr"] = process.stderr
|
1682 |
+
|
1683 |
+
# Calculate execution time
|
1684 |
+
result["execution_time"] = time.time() - start_time
|
1685 |
+
|
1686 |
+
# Look for generated images in the executable directory
|
1687 |
+
for ext in [".png", ".jpg", ".jpeg", ".bmp", ".ppm"]:
|
1688 |
+
image_files = [f for f in os.listdir(temp_dir) if f.endswith(ext)]
|
1689 |
+
for img_file in image_files:
|
1690 |
+
try:
|
1691 |
+
img_path = os.path.join(temp_dir, img_file)
|
1692 |
+
|
1693 |
+
# For PPM files, convert to PNG for easier display
|
1694 |
+
if img_file.endswith(".ppm"):
|
1695 |
+
# Create output path
|
1696 |
+
png_path = os.path.join(temp_dir, img_file.replace(".ppm", ".png"))
|
1697 |
+
|
1698 |
+
# Convert using PIL
|
1699 |
+
from PIL import Image
|
1700 |
+
Image.open(img_path).save(png_path)
|
1701 |
+
img_path = png_path
|
1702 |
+
img_file = img_file.replace(".ppm", ".png")
|
1703 |
+
|
1704 |
+
with open(img_path, "rb") as f:
|
1705 |
+
result["images"].append({
|
1706 |
+
"name": img_file,
|
1707 |
+
"data": f.read()
|
1708 |
+
})
|
1709 |
+
except Exception as e:
|
1710 |
+
logger.error(f"Error processing image {img_file}: {str(e)}")
|
1711 |
+
|
1712 |
+
# Estimate memory usage
|
1713 |
+
try:
|
1714 |
+
if platform.system() != "Windows":
|
1715 |
+
# Use ps command to get memory usage
|
1716 |
+
ps_output = subprocess.run(
|
1717 |
+
["ps", "-p", str(process.pid), "-o", "rss="],
|
1718 |
+
capture_output=True,
|
1719 |
+
text=True,
|
1720 |
+
check=False
|
1721 |
+
)
|
1722 |
+
if ps_output.returncode == 0:
|
1723 |
+
mem_kb = int(ps_output.stdout.strip())
|
1724 |
+
result["memory_usage"] = mem_kb / 1024 # Convert to MB
|
1725 |
+
except:
|
1726 |
+
pass
|
1727 |
+
|
1728 |
+
return result
|
1729 |
+
except subprocess.TimeoutExpired:
|
1730 |
+
result["stderr"] += f"\nProgram execution timed out after {timeout} seconds."
|
1731 |
+
result["exception"] = "TimeoutError"
|
1732 |
+
return result
|
1733 |
+
except Exception as e:
|
1734 |
+
result["stderr"] += f"\nError executing program: {str(e)}"
|
1735 |
+
result["exception"] = str(e)
|
1736 |
+
return result
|
1737 |
|
1738 |
def parse_animation_steps(python_code):
|
1739 |
"""Parse Manim code to extract animation steps for timeline editor"""
|
|
|
2239 |
st.session_state.custom_model = "gpt-4o" # Default model
|
2240 |
st.session_state.first_load_complete = False # Prevent refreshes on first load
|
2241 |
st.session_state.pending_tab_switch = None # Track pending tab switches
|
2242 |
+
# C++ runner state
|
2243 |
+
st.session_state.cpp_code = """#include <iostream>
|
2244 |
+
#include <vector>
|
2245 |
+
#include <algorithm>
|
2246 |
+
|
2247 |
+
int main() {
|
2248 |
+
std::cout << "Hello, Manim Animation Studio!" << std::endl;
|
2249 |
+
|
2250 |
+
// Create a vector of numbers
|
2251 |
+
std::vector<int> numbers = {5, 2, 8, 1, 9, 3, 7, 4, 6};
|
2252 |
+
|
2253 |
+
// Sort the vector
|
2254 |
+
std::sort(numbers.begin(), numbers.end());
|
2255 |
+
|
2256 |
+
// Print the sorted numbers
|
2257 |
+
std::cout << "Sorted numbers: ";
|
2258 |
+
for (int num : numbers) {
|
2259 |
+
std::cout << num << " ";
|
2260 |
+
}
|
2261 |
+
std::cout << std::endl;
|
2262 |
+
|
2263 |
+
return 0;
|
2264 |
+
}"""
|
2265 |
+
st.session_state.cpp_result = None
|
2266 |
+
st.session_state.cpp_project_files = {"main.cpp": st.session_state.cpp_code}
|
2267 |
+
st.session_state.cpp_settings = {
|
2268 |
+
"compiler": "g++",
|
2269 |
+
"std": "c++17",
|
2270 |
+
"optimization": "-O2",
|
2271 |
+
"include_paths": [],
|
2272 |
+
"library_paths": [],
|
2273 |
+
"libraries": []
|
2274 |
+
}
|
2275 |
|
2276 |
# Page configuration with improved layout
|
2277 |
st.set_page_config(
|
|
|
2442 |
st.error("Failed to install required packages. Please try again.")
|
2443 |
st.stop()
|
2444 |
|
2445 |
+
# Create main tabs
|
2446 |
+
tab_names = ["✨ Editor", "🤖 AI Assistant", "🎨 Assets", "🎞️ Timeline", "🎓 Educational Export", "🐍 Python Runner", "🔧 C/C++ Runner"]
|
2447 |
tabs = st.tabs(tab_names)
|
2448 |
|
2449 |
# Sidebar for rendering settings and custom libraries
|
|
|
2516 |
if st.session_state.custom_library_result:
|
2517 |
with st.expander("Installation Results"):
|
2518 |
st.code(st.session_state.custom_library_result)
|
2519 |
+
|
2520 |
+
# C/C++ Library Options
|
2521 |
+
with st.sidebar.expander("C/C++ Library Options"):
|
2522 |
+
st.markdown("### Advanced C/C++ Settings")
|
2523 |
+
|
2524 |
+
cpp_libs = st.multiselect(
|
2525 |
+
"Include Libraries",
|
2526 |
+
options=["Eigen", "Boost", "OpenCV", "FFTW", "Matplotlib-cpp"],
|
2527 |
+
default=st.session_state.cpp_settings.get("libraries", [])
|
2528 |
+
)
|
2529 |
+
|
2530 |
+
st.session_state.cpp_settings["libraries"] = cpp_libs
|
2531 |
+
|
2532 |
+
custom_include = st.text_input("Custom Include Path:")
|
2533 |
+
custom_lib = st.text_input("Custom Library Path:")
|
2534 |
+
|
2535 |
+
if custom_include and custom_include not in st.session_state.cpp_settings.get("include_paths", []):
|
2536 |
+
if "include_paths" not in st.session_state.cpp_settings:
|
2537 |
+
st.session_state.cpp_settings["include_paths"] = []
|
2538 |
+
st.session_state.cpp_settings["include_paths"].append(custom_include)
|
2539 |
+
|
2540 |
+
if custom_lib and custom_lib not in st.session_state.cpp_settings.get("library_paths", []):
|
2541 |
+
if "library_paths" not in st.session_state.cpp_settings:
|
2542 |
+
st.session_state.cpp_settings["library_paths"] = []
|
2543 |
+
st.session_state.cpp_settings["library_paths"].append(custom_lib)
|
2544 |
+
|
2545 |
+
if st.button("Update Library Settings"):
|
2546 |
+
st.success("Library settings updated!")
|
2547 |
|
2548 |
# EDITOR TAB
|
2549 |
with tabs[0]:
|
|
|
3018 |
if "Scene" not in completed_code:
|
3019 |
completed_code = f"""from manim import *
|
3020 |
|
3021 |
+
class MyScene(Scene):
|
3022 |
+
def construct(self):
|
3023 |
{completed_code}"""
|
3024 |
|
3025 |
# Store the generated code
|
|
|
3385 |
st.markdown("### 🐍 Python Script Runner")
|
3386 |
st.markdown("Execute Python scripts and visualize the results directly.")
|
3387 |
|
3388 |
+
# New UI elements for advanced features
|
3389 |
+
with st.expander("🔧 Advanced Python Features"):
|
3390 |
+
py_feature_col1, py_feature_col2 = st.columns(2)
|
3391 |
+
|
3392 |
+
with py_feature_col1:
|
3393 |
+
enable_debugging = st.checkbox("Enable Debugging", value=False, key="py_debug_enable")
|
3394 |
+
enable_profiling = st.checkbox("Enable Profiling", value=False, key="py_profile_enable")
|
3395 |
+
|
3396 |
+
with py_feature_col2:
|
3397 |
+
py_libs = st.multiselect(
|
3398 |
+
"Additional Libraries",
|
3399 |
+
options=["numpy", "scipy", "pandas", "matplotlib", "seaborn", "plotly", "scikit-learn", "tensorflow", "pytorch", "sympy"],
|
3400 |
+
default=["numpy", "matplotlib"],
|
3401 |
+
key="py_additional_libs"
|
3402 |
+
)
|
3403 |
+
|
3404 |
+
# Multi-file project support
|
3405 |
+
with st.expander("📁 Multi-file Project"):
|
3406 |
+
st.markdown("Add multiple Python files to your project")
|
3407 |
+
|
3408 |
+
# File manager
|
3409 |
+
if "py_project_files" not in st.session_state:
|
3410 |
+
st.session_state.py_project_files = {"main.py": st.session_state.python_script}
|
3411 |
+
|
3412 |
+
# File selector
|
3413 |
+
current_file = st.selectbox(
|
3414 |
+
"Select File",
|
3415 |
+
options=list(st.session_state.py_project_files.keys()),
|
3416 |
+
key="py_current_file"
|
3417 |
+
)
|
3418 |
+
|
3419 |
+
# New file creation
|
3420 |
+
new_file_col1, new_file_col2 = st.columns([3, 1])
|
3421 |
+
with new_file_col1:
|
3422 |
+
new_filename = st.text_input("New File Name", value="", key="py_new_filename")
|
3423 |
+
with new_file_col2:
|
3424 |
+
if st.button("Add File", key="py_add_file_btn"):
|
3425 |
+
if new_filename and new_filename not in st.session_state.py_project_files:
|
3426 |
+
if not new_filename.endswith(".py"):
|
3427 |
+
new_filename += ".py"
|
3428 |
+
st.session_state.py_project_files[new_filename] = "# New Python file\n\n"
|
3429 |
+
st.session_state.py_current_file = new_filename
|
3430 |
+
st.experimental_rerun()
|
3431 |
+
|
3432 |
+
# Update the current file content in session state
|
3433 |
+
if current_file in st.session_state.py_project_files:
|
3434 |
+
st.session_state.py_project_files[current_file] = st.session_state.python_script
|
3435 |
+
# Update main script if we're editing the main file
|
3436 |
+
if current_file == "main.py":
|
3437 |
+
st.session_state.python_script = st.session_state.python_script
|
3438 |
+
|
3439 |
+
# Real-time visualization toggle
|
3440 |
+
real_time_viz = st.checkbox("Enable Real-time Visualization", value=False, key="py_realtime_viz")
|
3441 |
+
|
3442 |
# Predefined example scripts
|
3443 |
example_scripts = {
|
3444 |
"Select an example...": "",
|
|
|
3563 |
|
3564 |
if run_btn:
|
3565 |
with st.spinner("Executing Python script..."):
|
3566 |
+
# Use the enhanced function
|
3567 |
+
result = run_python_script_enhanced(
|
3568 |
+
python_code,
|
3569 |
+
inputs=user_inputs,
|
3570 |
+
timeout=timeout_seconds,
|
3571 |
+
enable_debug=enable_debugging,
|
3572 |
+
enable_profile=enable_profiling,
|
3573 |
+
additional_libs=py_libs,
|
3574 |
+
project_files=st.session_state.py_project_files if "py_project_files" in st.session_state else None,
|
3575 |
+
realtime_viz=real_time_viz
|
3576 |
+
)
|
3577 |
st.session_state.python_result = result
|
3578 |
|
3579 |
# Display results
|
3580 |
if st.session_state.python_result:
|
3581 |
+
display_python_script_results_enhanced(st.session_state.python_result)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3582 |
|
3583 |
# Provide option to save the script
|
3584 |
if st.button("📄 Save This Script", key="save_script_btn"):
|
|
|
3626 |
- Perfect for educational content combining data and animations
|
3627 |
""")
|
3628 |
|
3629 |
+
# C/C++ RUNNER TAB
|
3630 |
+
with tabs[6]: # Assuming this is the 7th tab (index 6)
|
3631 |
+
st.markdown("### 🔧 C/C++ Runner")
|
3632 |
+
st.markdown("Write, compile, and run C/C++ code with advanced features.")
|
3633 |
+
|
3634 |
+
# Create a tabbed interface for different C++ features
|
3635 |
+
cpp_tabs = st.tabs(["Code Editor", "Project Files", "Libraries", "Build Settings", "Debugger"])
|
3636 |
+
|
3637 |
+
with cpp_tabs[0]: # Code Editor tab
|
3638 |
+
# Compiler options
|
3639 |
+
cpp_col1, cpp_col2, cpp_col3 = st.columns(3)
|
3640 |
+
|
3641 |
+
with cpp_col1:
|
3642 |
+
compiler = st.selectbox(
|
3643 |
+
"Compiler",
|
3644 |
+
options=["g++", "clang++", "gcc", "msvc"],
|
3645 |
+
index=["g++", "clang++", "gcc", "msvc"].index(st.session_state.cpp_settings["compiler"]),
|
3646 |
+
key="cpp_compiler"
|
3647 |
+
)
|
3648 |
+
st.session_state.cpp_settings["compiler"] = compiler
|
3649 |
+
|
3650 |
+
with cpp_col2:
|
3651 |
+
std_version = st.selectbox(
|
3652 |
+
"Standard",
|
3653 |
+
options=["c++11", "c++14", "c++17", "c++20"],
|
3654 |
+
index=["c++11", "c++14", "c++17", "c++20"].index(st.session_state.cpp_settings["std"]),
|
3655 |
+
key="cpp_std"
|
3656 |
+
)
|
3657 |
+
st.session_state.cpp_settings["std"] = std_version
|
3658 |
+
|
3659 |
+
with cpp_col3:
|
3660 |
+
optimization = st.selectbox(
|
3661 |
+
"Optimization",
|
3662 |
+
options=["-O0", "-O1", "-O2", "-O3"],
|
3663 |
+
index=["-O0", "-O1", "-O2", "-O3"].index(st.session_state.cpp_settings["optimization"]),
|
3664 |
+
key="cpp_opt"
|
3665 |
+
)
|
3666 |
+
st.session_state.cpp_settings["optimization"] = optimization
|
3667 |
+
|
3668 |
+
# Example code templates
|
3669 |
+
cpp_examples = {
|
3670 |
+
"Select an example...": "",
|
3671 |
+
"Hello World": """#include <iostream>
|
3672 |
+
|
3673 |
+
int main() {
|
3674 |
+
std::cout << "Hello, World!" << std::endl;
|
3675 |
+
return 0;
|
3676 |
+
}""",
|
3677 |
+
"Calculate Prime Numbers": """#include <iostream>
|
3678 |
+
#include <vector>
|
3679 |
+
#include <chrono>
|
3680 |
+
|
3681 |
+
bool isPrime(int n) {
|
3682 |
+
if (n <= 1) return false;
|
3683 |
+
if (n <= 3) return true;
|
3684 |
+
if (n % 2 == 0 || n % 3 == 0) return false;
|
3685 |
+
|
3686 |
+
for (int i = 5; i * i <= n; i += 6) {
|
3687 |
+
if (n % i == 0 || n % (i + 2) == 0)
|
3688 |
+
return false;
|
3689 |
+
}
|
3690 |
+
return true;
|
3691 |
+
}
|
3692 |
+
|
3693 |
+
int main() {
|
3694 |
+
int limit = 10000;
|
3695 |
+
std::vector<int> primes;
|
3696 |
+
|
3697 |
+
auto start = std::chrono::high_resolution_clock::now();
|
3698 |
+
|
3699 |
+
for (int i = 2; i <= limit; i++) {
|
3700 |
+
if (isPrime(i)) {
|
3701 |
+
primes.push_back(i);
|
3702 |
+
}
|
3703 |
+
}
|
3704 |
+
|
3705 |
+
auto end = std::chrono::high_resolution_clock::now();
|
3706 |
+
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
|
3707 |
+
|
3708 |
+
std::cout << "Found " << primes.size() << " prime numbers up to " << limit << std::endl;
|
3709 |
+
std::cout << "First 10 primes: ";
|
3710 |
+
for (int i = 0; i < std::min(10, (int)primes.size()); i++) {
|
3711 |
+
std::cout << primes[i] << " ";
|
3712 |
+
}
|
3713 |
+
std::cout << std::endl;
|
3714 |
+
std::cout << "Computation time: " << duration.count() << " ms" << std::endl;
|
3715 |
+
|
3716 |
+
return 0;
|
3717 |
+
}""",
|
3718 |
+
"Image Generation (PPM)": """#include <iostream>
|
3719 |
+
#include <fstream>
|
3720 |
+
#include <cmath>
|
3721 |
+
|
3722 |
+
// Generate a simple gradient image in PPM format
|
3723 |
+
int main() {
|
3724 |
+
const int width = 800;
|
3725 |
+
const int height = 600;
|
3726 |
+
|
3727 |
+
// Create a PPM file (P3 format - ASCII)
|
3728 |
+
std::ofstream image("output.ppm");
|
3729 |
+
image << "P3\\n" << width << " " << height << "\\n255\\n";
|
3730 |
+
|
3731 |
+
for (int y = 0; y < height; y++) {
|
3732 |
+
for (int x = 0; x < width; x++) {
|
3733 |
+
// Create a gradient based on position
|
3734 |
+
int r = static_cast<int>(255.0 * x / width);
|
3735 |
+
int g = static_cast<int>(255.0 * y / height);
|
3736 |
+
int b = static_cast<int>(255.0 * (x + y) / (width + height));
|
3737 |
+
|
3738 |
+
// Write RGB values
|
3739 |
+
image << r << " " << g << " " << b << "\\n";
|
3740 |
+
}
|
3741 |
+
}
|
3742 |
+
|
3743 |
+
image.close();
|
3744 |
+
std::cout << "Generated gradient image: output.ppm" << std::endl;
|
3745 |
+
return 0;
|
3746 |
+
}""",
|
3747 |
+
"Data Processing with Vectors": """#include <iostream>
|
3748 |
+
#include <vector>
|
3749 |
+
#include <algorithm>
|
3750 |
+
#include <numeric>
|
3751 |
+
#include <random>
|
3752 |
+
#include <iomanip>
|
3753 |
+
|
3754 |
+
int main() {
|
3755 |
+
const int data_size = 1000;
|
3756 |
+
|
3757 |
+
// Generate random data
|
3758 |
+
std::vector<double> data(data_size);
|
3759 |
+
|
3760 |
+
std::random_device rd;
|
3761 |
+
std::mt19937 gen(rd());
|
3762 |
+
std::normal_distribution<double> dist(100.0, 15.0);
|
3763 |
+
|
3764 |
+
std::cout << "Generating " << data_size << " random values..." << std::endl;
|
3765 |
+
for (auto& value : data) {
|
3766 |
+
value = dist(gen);
|
3767 |
+
}
|
3768 |
+
|
3769 |
+
// Calculate statistics
|
3770 |
+
double sum = std::accumulate(data.begin(), data.end(), 0.0);
|
3771 |
+
double mean = sum / data.size();
|
3772 |
+
|
3773 |
+
std::vector<double> deviations(data_size);
|
3774 |
+
std::transform(data.begin(), data.end(), deviations.begin(),
|
3775 |
+
[mean](double x) { return x - mean; });
|
3776 |
+
|
3777 |
+
double sq_sum = std::inner_product(deviations.begin(), deviations.end(),
|
3778 |
+
deviations.begin(), 0.0);
|
3779 |
+
double stddev = std::sqrt(sq_sum / data.size());
|
3780 |
+
|
3781 |
+
// Sort data
|
3782 |
+
std::sort(data.begin(), data.end());
|
3783 |
+
double median = data.size() % 2 == 0 ?
|
3784 |
+
(data[data.size()/2 - 1] + data[data.size()/2]) / 2 :
|
3785 |
+
data[data.size()/2];
|
3786 |
+
|
3787 |
+
// Output results
|
3788 |
+
std::cout << std::fixed << std::setprecision(2);
|
3789 |
+
std::cout << "Data analysis results:" << std::endl;
|
3790 |
+
std::cout << "Mean: " << mean << std::endl;
|
3791 |
+
std::cout << "Median: " << median << std::endl;
|
3792 |
+
std::cout << "StdDev: " << stddev << std::endl;
|
3793 |
+
std::cout << "Min: " << data.front() << std::endl;
|
3794 |
+
std::cout << "Max: " << data.back() << std::endl;
|
3795 |
+
|
3796 |
+
return 0;
|
3797 |
+
}""",
|
3798 |
+
"Interactive User Input": """#include <iostream>
|
3799 |
+
#include <string>
|
3800 |
+
#include <vector>
|
3801 |
+
|
3802 |
+
int main() {
|
3803 |
+
std::string name;
|
3804 |
+
int age;
|
3805 |
+
|
3806 |
+
// Get user input
|
3807 |
+
std::cout << "Enter your name: ";
|
3808 |
+
std::getline(std::cin, name);
|
3809 |
+
|
3810 |
+
std::cout << "Enter your age: ";
|
3811 |
+
std::cin >> age;
|
3812 |
+
std::cin.ignore(); // Clear the newline from the buffer
|
3813 |
+
|
3814 |
+
std::cout << "Hello, " << name << "! ";
|
3815 |
+
std::cout << "In 10 years, you will be " << age + 10 << " years old." << std::endl;
|
3816 |
+
|
3817 |
+
// Get multiple numbers
|
3818 |
+
int num_count;
|
3819 |
+
std::cout << "How many numbers would you like to enter? ";
|
3820 |
+
std::cin >> num_count;
|
3821 |
+
|
3822 |
+
std::vector<double> numbers;
|
3823 |
+
double total = 0.0;
|
3824 |
+
|
3825 |
+
for (int i = 0; i < num_count; i++) {
|
3826 |
+
double num;
|
3827 |
+
std::cout << "Enter number " << (i+1) << ": ";
|
3828 |
+
std::cin >> num;
|
3829 |
+
numbers.push_back(num);
|
3830 |
+
total += num;
|
3831 |
+
}
|
3832 |
+
|
3833 |
+
if (!numbers.empty()) {
|
3834 |
+
double average = total / numbers.size();
|
3835 |
+
std::cout << "The average of your numbers is: " << average << std::endl;
|
3836 |
+
}
|
3837 |
+
|
3838 |
+
return 0;
|
3839 |
+
}""",
|
3840 |
+
"Eigen Matrix Operations": """#include <iostream>
|
3841 |
+
#include <Eigen/Dense>
|
3842 |
+
|
3843 |
+
using Eigen::MatrixXd;
|
3844 |
+
using Eigen::VectorXd;
|
3845 |
+
|
3846 |
+
int main() {
|
3847 |
+
// Create a 3x3 matrix
|
3848 |
+
MatrixXd A(3, 3);
|
3849 |
+
A << 1, 2, 3,
|
3850 |
+
4, 5, 6,
|
3851 |
+
7, 8, 9;
|
3852 |
+
|
3853 |
+
// Create a 3D vector
|
3854 |
+
VectorXd b(3);
|
3855 |
+
b << 1, 2, 3;
|
3856 |
+
|
3857 |
+
// Perform operations
|
3858 |
+
std::cout << "Matrix A:\\n" << A << std::endl;
|
3859 |
+
std::cout << "Vector b:\\n" << b << std::endl;
|
3860 |
+
std::cout << "A * b:\\n" << A * b << std::endl;
|
3861 |
+
std::cout << "A transpose:\\n" << A.transpose() << std::endl;
|
3862 |
+
|
3863 |
+
// Solve a linear system Ax = b
|
3864 |
+
VectorXd x = A.colPivHouseholderQr().solve(b);
|
3865 |
+
std::cout << "Solution to Ax = b:\\n" << x << std::endl;
|
3866 |
+
|
3867 |
+
// Compute eigenvalues and eigenvectors
|
3868 |
+
Eigen::EigenSolver<MatrixXd> solver(A);
|
3869 |
+
std::cout << "Eigenvalues:\\n" << solver.eigenvalues() << std::endl;
|
3870 |
+
std::cout << "Eigenvectors:\\n" << solver.eigenvectors() << std::endl;
|
3871 |
+
|
3872 |
+
return 0;
|
3873 |
+
}""",
|
3874 |
+
"OpenCV Image Processing": """#include <iostream>
|
3875 |
+
#include <opencv2/opencv.hpp>
|
3876 |
+
|
3877 |
+
int main() {
|
3878 |
+
// Load an image (this will create a blank image if no file is found)
|
3879 |
+
cv::Mat image = cv::Mat::zeros(500, 500, CV_8UC3);
|
3880 |
+
|
3881 |
+
// Draw a circle
|
3882 |
+
cv::circle(image, cv::Point(250, 250), 100, cv::Scalar(0, 0, 255), 5);
|
3883 |
+
|
3884 |
+
// Draw a rectangle
|
3885 |
+
cv::rectangle(image, cv::Point(150, 150), cv::Point(350, 350), cv::Scalar(0, 255, 0), 3);
|
3886 |
+
|
3887 |
+
// Add text
|
3888 |
+
cv::putText(image, "OpenCV Example", cv::Point(100, 50), cv::FONT_HERSHEY_SIMPLEX, 1, cv::Scalar(255, 255, 255), 2);
|
3889 |
+
|
3890 |
+
// Save the image
|
3891 |
+
cv::imwrite("opencv_output.png", image);
|
3892 |
+
|
3893 |
+
std::cout << "Image created and saved as 'opencv_output.png'" << std::endl;
|
3894 |
+
|
3895 |
+
return 0;
|
3896 |
+
}"""
|
3897 |
+
}
|
3898 |
+
|
3899 |
+
# Example selection
|
3900 |
+
selected_cpp_example = st.selectbox("Example code:", options=list(cpp_examples.keys()))
|
3901 |
+
|
3902 |
+
# Set initial code from example or session state
|
3903 |
+
if selected_cpp_example != "Select an example..." and cpp_examples[selected_cpp_example] != "":
|
3904 |
+
initial_code = cpp_examples[selected_cpp_example]
|
3905 |
+
else:
|
3906 |
+
if "cpp_current_file" in st.session_state and st.session_state.cpp_current_file in st.session_state.cpp_project_files:
|
3907 |
+
initial_code = st.session_state.cpp_project_files[st.session_state.cpp_current_file]
|
3908 |
+
else:
|
3909 |
+
initial_code = st.session_state.cpp_code
|
3910 |
+
|
3911 |
+
# Code editor for C++
|
3912 |
+
if ACE_EDITOR_AVAILABLE:
|
3913 |
+
cpp_code = st_ace(
|
3914 |
+
value=initial_code,
|
3915 |
+
language="c_cpp",
|
3916 |
+
theme="monokai",
|
3917 |
+
min_lines=15,
|
3918 |
+
key=f"cpp_editor_{st.session_state.editor_key}"
|
3919 |
+
)
|
3920 |
+
else:
|
3921 |
+
cpp_code = st.text_area(
|
3922 |
+
"C/C++ Code",
|
3923 |
+
value=initial_code,
|
3924 |
+
height=400,
|
3925 |
+
key=f"cpp_textarea_{st.session_state.editor_key}"
|
3926 |
+
)
|
3927 |
+
|
3928 |
+
# Save the code to session state
|
3929 |
+
st.session_state.cpp_code = cpp_code
|
3930 |
+
|
3931 |
+
# Update project files
|
3932 |
+
if "cpp_current_file" in st.session_state and st.session_state.cpp_current_file in st.session_state.cpp_project_files:
|
3933 |
+
st.session_state.cpp_project_files[st.session_state.cpp_current_file] = cpp_code
|
3934 |
+
|
3935 |
+
# Check for standard input in the code
|
3936 |
+
has_cin = "std::cin" in cpp_code or "cin" in cpp_code
|
3937 |
+
|
3938 |
+
# Input values section if needed
|
3939 |
+
cpp_inputs = []
|
3940 |
+
if has_cin:
|
3941 |
+
with st.expander("Input Values"):
|
3942 |
+
st.info("This program uses standard input. Please provide input values below:")
|
3943 |
+
|
3944 |
+
num_inputs = st.number_input("Number of input lines:", min_value=1, max_value=10, value=1)
|
3945 |
+
for i in range(int(num_inputs)):
|
3946 |
+
cpp_input = st.text_input(f"Input line {i+1}:", key=f"cpp_input_{i}")
|
3947 |
+
cpp_inputs.append(cpp_input)
|
3948 |
+
|
3949 |
+
with cpp_tabs[1]: # Project Files tab
|
3950 |
+
st.markdown("### Project Files")
|
3951 |
+
st.markdown("Manage multiple source files for your C/C++ project")
|
3952 |
+
|
3953 |
+
# File selector
|
3954 |
+
cpp_current_file = st.selectbox(
|
3955 |
+
"Current File",
|
3956 |
+
options=list(st.session_state.cpp_project_files.keys()),
|
3957 |
+
index=list(st.session_state.cpp_project_files.keys()).index(st.session_state.cpp_current_file) if "cpp_current_file" in st.session_state else 0,
|
3958 |
+
key="cpp_file_selector"
|
3959 |
+
)
|
3960 |
+
|
3961 |
+
# Update the current file in session state
|
3962 |
+
st.session_state.cpp_current_file = cpp_current_file
|
3963 |
+
|
3964 |
+
# Create new file form
|
3965 |
+
new_file_col1, new_file_col2 = st.columns([3, 1])
|
3966 |
+
with new_file_col1:
|
3967 |
+
new_cpp_filename = st.text_input("New File Name", placeholder="e.g., utils.h, helper.cpp", key="new_cpp_file")
|
3968 |
+
with new_file_col2:
|
3969 |
+
if st.button("Add File", key="add_cpp_file"):
|
3970 |
+
if new_cpp_filename and new_cpp_filename not in st.session_state.cpp_project_files:
|
3971 |
+
# Add file extension if missing
|
3972 |
+
if not new_cpp_filename.endswith((".cpp", ".h", ".hpp", ".c", ".cc")):
|
3973 |
+
new_cpp_filename += ".cpp"
|
3974 |
+
|
3975 |
+
# Create a template based on file type
|
3976 |
+
if new_cpp_filename.endswith((".h", ".hpp")):
|
3977 |
+
template = f"""#ifndef {new_cpp_filename.split('.')[0].upper()}_H
|
3978 |
+
#define {new_cpp_filename.split('.')[0].upper()}_H
|
3979 |
+
|
3980 |
+
// Your header content here
|
3981 |
+
|
3982 |
+
#endif // {new_cpp_filename.split('.')[0].upper()}_H
|
3983 |
+
"""
|
3984 |
+
else:
|
3985 |
+
template = f"""#include <iostream>
|
3986 |
+
|
3987 |
+
// Your implementation here
|
3988 |
+
|
3989 |
+
"""
|
3990 |
+
|
3991 |
+
st.session_state.cpp_project_files[new_cpp_filename] = template
|
3992 |
+
st.session_state.cpp_current_file = new_cpp_filename
|
3993 |
+
st.experimental_rerun()
|
3994 |
+
|
3995 |
+
# File actions
|
3996 |
+
file_action_col1, file_action_col2 = st.columns(2)
|
3997 |
+
with file_action_col1:
|
3998 |
+
if st.button("Delete Current File", key="delete_cpp_file"):
|
3999 |
+
if cpp_current_file != "main.cpp" and cpp_current_file in st.session_state.cpp_project_files:
|
4000 |
+
del st.session_state.cpp_project_files[cpp_current_file]
|
4001 |
+
st.session_state.cpp_current_file = "main.cpp"
|
4002 |
+
st.experimental_rerun()
|
4003 |
+
else:
|
4004 |
+
st.error("Cannot delete main.cpp")
|
4005 |
+
|
4006 |
+
with file_action_col2:
|
4007 |
+
if st.button("Download Project Files", key="download_cpp_project"):
|
4008 |
+
# Create a zip file with all project files
|
4009 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix=".zip") as tmp:
|
4010 |
+
with zipfile.ZipFile(tmp.name, 'w') as zipf:
|
4011 |
+
for filename, content in st.session_state.cpp_project_files.items():
|
4012 |
+
# Add file to zip
|
4013 |
+
zipf.writestr(filename, content)
|
4014 |
+
|
4015 |
+
# Download the zip file
|
4016 |
+
with open(tmp.name, "rb") as f:
|
4017 |
+
zip_data = f.read()
|
4018 |
+
|
4019 |
+
st.download_button(
|
4020 |
+
label="Download ZIP",
|
4021 |
+
data=zip_data,
|
4022 |
+
file_name="cpp_project.zip",
|
4023 |
+
mime="application/zip"
|
4024 |
+
)
|
4025 |
+
|
4026 |
+
# Project structure visualization
|
4027 |
+
st.markdown("### Project Structure")
|
4028 |
+
|
4029 |
+
# Group files by type
|
4030 |
+
headers = []
|
4031 |
+
sources = []
|
4032 |
+
others = []
|
4033 |
+
|
4034 |
+
for filename in st.session_state.cpp_project_files:
|
4035 |
+
if filename.endswith((".h", ".hpp")):
|
4036 |
+
headers.append(filename)
|
4037 |
+
elif filename.endswith((".cpp", ".c", ".cc")):
|
4038 |
+
sources.append(filename)
|
4039 |
+
else:
|
4040 |
+
others.append(filename)
|
4041 |
+
|
4042 |
+
# Display structure
|
4043 |
+
st.markdown("#### Header Files")
|
4044 |
+
if headers:
|
4045 |
+
for header in sorted(headers):
|
4046 |
+
st.markdown(f"- `{header}`")
|
4047 |
+
else:
|
4048 |
+
st.markdown("No header files")
|
4049 |
+
|
4050 |
+
st.markdown("#### Source Files")
|
4051 |
+
if sources:
|
4052 |
+
for source in sorted(sources):
|
4053 |
+
st.markdown(f"- `{source}`")
|
4054 |
+
else:
|
4055 |
+
st.markdown("No source files")
|
4056 |
+
|
4057 |
+
if others:
|
4058 |
+
st.markdown("#### Other Files")
|
4059 |
+
for other in sorted(others):
|
4060 |
+
st.markdown(f"- `{other}`")
|
4061 |
+
|
4062 |
+
with cpp_tabs[2]: # Libraries tab
|
4063 |
+
st.markdown("### Library Manager")
|
4064 |
+
st.markdown("Configure libraries and dependencies for your C/C++ project")
|
4065 |
+
|
4066 |
+
# Common library selection
|
4067 |
+
common_libs = st.multiselect(
|
4068 |
+
"Common Libraries",
|
4069 |
+
options=["Eigen", "Boost", "OpenCV", "FFTW", "SDL2", "SFML", "OpenGL", "stb_image", "nlohmann_json", "fmt"],
|
4070 |
+
default=st.session_state.cpp_settings.get("libraries", []),
|
4071 |
+
key="cpp_common_libs"
|
4072 |
+
)
|
4073 |
+
|
4074 |
+
# Update libraries in settings
|
4075 |
+
st.session_state.cpp_settings["libraries"] = common_libs
|
4076 |
+
|
4077 |
+
# Include paths
|
4078 |
+
st.markdown("#### Include Paths")
|
4079 |
+
include_paths = st.text_area(
|
4080 |
+
"Include Directories (one per line)",
|
4081 |
+
value="\n".join(st.session_state.cpp_settings.get("include_paths", [])),
|
4082 |
+
height=100,
|
4083 |
+
key="cpp_include_paths"
|
4084 |
+
)
|
4085 |
+
|
4086 |
+
# Update include paths in settings
|
4087 |
+
st.session_state.cpp_settings["include_paths"] = [path for path in include_paths.split("\n") if path.strip()]
|
4088 |
+
|
4089 |
+
# Library paths
|
4090 |
+
st.markdown("#### Library Paths")
|
4091 |
+
library_paths = st.text_area(
|
4092 |
+
"Library Directories (one per line)",
|
4093 |
+
value="\n".join(st.session_state.cpp_settings.get("library_paths", [])),
|
4094 |
+
height=100,
|
4095 |
+
key="cpp_library_paths"
|
4096 |
+
)
|
4097 |
+
|
4098 |
+
# Update library paths in settings
|
4099 |
+
st.session_state.cpp_settings["library_paths"] = [path for path in library_paths.split("\n") if path.strip()]
|
4100 |
+
|
4101 |
+
# Additional libraries
|
4102 |
+
st.markdown("#### Additional Libraries")
|
4103 |
+
additional_libs = st.text_area(
|
4104 |
+
"Additional Libraries (one per line, without -l prefix)",
|
4105 |
+
value="\n".join(st.session_state.cpp_settings.get("additional_libs", [])),
|
4106 |
+
height=100,
|
4107 |
+
key="cpp_additional_libs"
|
4108 |
+
)
|
4109 |
+
|
4110 |
+
# Update additional libraries in settings
|
4111 |
+
st.session_state.cpp_settings["additional_libs"] = [lib for lib in additional_libs.split("\n") if lib.strip()]
|
4112 |
+
|
4113 |
+
# Library detection
|
4114 |
+
if st.button("Detect Installed Libraries", key="detect_libs"):
|
4115 |
+
with st.spinner("Detecting libraries..."):
|
4116 |
+
# This is a placeholder - in a real implementation, you'd scan the system
|
4117 |
+
detected_libs = []
|
4118 |
+
|
4119 |
+
# Check for Eigen
|
4120 |
+
try:
|
4121 |
+
result = subprocess.run(
|
4122 |
+
["find", "/usr/include", "-name", "Eigen"],
|
4123 |
+
capture_output=True,
|
4124 |
+
text=True,
|
4125 |
+
timeout=5
|
4126 |
+
)
|
4127 |
+
if "Eigen" in result.stdout:
|
4128 |
+
detected_libs.append("Eigen")
|
4129 |
+
except:
|
4130 |
+
pass
|
4131 |
+
|
4132 |
+
# Check for Boost
|
4133 |
+
try:
|
4134 |
+
result = subprocess.run(
|
4135 |
+
["find", "/usr/include", "-name", "boost"],
|
4136 |
+
capture_output=True,
|
4137 |
+
text=True,
|
4138 |
+
timeout=5
|
4139 |
+
)
|
4140 |
+
if "boost" in result.stdout:
|
4141 |
+
detected_libs.append("Boost")
|
4142 |
+
except:
|
4143 |
+
pass
|
4144 |
+
|
4145 |
+
# Check for OpenCV
|
4146 |
+
try:
|
4147 |
+
result = subprocess.run(
|
4148 |
+
["pkg-config", "--exists", "opencv4"],
|
4149 |
+
capture_output=True,
|
4150 |
+
timeout=5
|
4151 |
+
)
|
4152 |
+
if result.returncode == 0:
|
4153 |
+
detected_libs.append("OpenCV")
|
4154 |
+
except:
|
4155 |
+
pass
|
4156 |
+
|
4157 |
+
# Display detected libraries
|
4158 |
+
if detected_libs:
|
4159 |
+
st.success(f"Detected libraries: {', '.join(detected_libs)}")
|
4160 |
+
# Add to selected libraries if not already present
|
4161 |
+
for lib in detected_libs:
|
4162 |
+
if lib not in st.session_state.cpp_settings["libraries"]:
|
4163 |
+
st.session_state.cpp_settings["libraries"].append(lib)
|
4164 |
+
else:
|
4165 |
+
st.warning("No common libraries detected")
|
4166 |
+
|
4167 |
+
with cpp_tabs[3]: # Build Settings tab
|
4168 |
+
st.markdown("### Build Configuration")
|
4169 |
+
|
4170 |
+
# Build type
|
4171 |
+
build_type = st.radio(
|
4172 |
+
"Build Type",
|
4173 |
+
options=["Debug", "Release", "RelWithDebInfo"],
|
4174 |
+
index=1, # Default to Release
|
4175 |
+
key="cpp_build_type"
|
4176 |
+
)
|
4177 |
+
|
4178 |
+
# Update build type in settings
|
4179 |
+
st.session_state.cpp_settings["build_type"] = build_type
|
4180 |
+
|
4181 |
+
# Advanced compiler flags
|
4182 |
+
st.markdown("#### Advanced Compiler Flags")
|
4183 |
+
advanced_flags = st.text_area(
|
4184 |
+
"Additional Compiler Flags",
|
4185 |
+
value=st.session_state.cpp_settings.get("advanced_flags", ""),
|
4186 |
+
height=100,
|
4187 |
+
key="cpp_advanced_flags"
|
4188 |
+
)
|
4189 |
+
|
4190 |
+
# Update advanced flags in settings
|
4191 |
+
st.session_state.cpp_settings["advanced_flags"] = advanced_flags
|
4192 |
+
|
4193 |
+
# Preprocessor definitions
|
4194 |
+
st.markdown("#### Preprocessor Definitions")
|
4195 |
+
definitions = st.text_area(
|
4196 |
+
"Preprocessor Definitions (one per line)",
|
4197 |
+
value="\n".join(st.session_state.cpp_settings.get("definitions", [])),
|
4198 |
+
height=100,
|
4199 |
+
placeholder="Example:\nDEBUG\nVERSION=1.0\nUSE_FEATURE_X",
|
4200 |
+
key="cpp_definitions"
|
4201 |
+
)
|
4202 |
+
|
4203 |
+
# Update definitions in settings
|
4204 |
+
st.session_state.cpp_settings["definitions"] = [d for d in definitions.split("\n") if d.strip()]
|
4205 |
+
|
4206 |
+
# Generate CMakeLists.txt
|
4207 |
+
if st.button("Generate CMakeLists.txt", key="gen_cmake"):
|
4208 |
+
# Create CMakeLists.txt content
|
4209 |
+
cmake_content = f"""cmake_minimum_required(VERSION 3.10)
|
4210 |
+
project(ManimCppProject)
|
4211 |
+
|
4212 |
+
set(CMAKE_CXX_STANDARD {st.session_state.cpp_settings["std"].replace("c++", "")})
|
4213 |
+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
4214 |
+
set(CMAKE_CXX_EXTENSIONS OFF)
|
4215 |
+
|
4216 |
+
# Build type
|
4217 |
+
set(CMAKE_BUILD_TYPE {build_type})
|
4218 |
+
|
4219 |
+
# Preprocessor definitions
|
4220 |
+
"""
|
4221 |
+
|
4222 |
+
# Add definitions
|
4223 |
+
for definition in st.session_state.cpp_settings.get("definitions", []):
|
4224 |
+
if "=" in definition:
|
4225 |
+
name, value = definition.split("=", 1)
|
4226 |
+
cmake_content += f'add_definitions(-D{name}="{value}")\n'
|
4227 |
+
else:
|
4228 |
+
cmake_content += f"add_definitions(-D{definition})\n"
|
4229 |
+
|
4230 |
+
# Add include paths
|
4231 |
+
if st.session_state.cpp_settings.get("include_paths", []):
|
4232 |
+
cmake_content += "\n# Include directories\n"
|
4233 |
+
for path in st.session_state.cpp_settings["include_paths"]:
|
4234 |
+
cmake_content += f"include_directories({path})\n"
|
4235 |
+
|
4236 |
+
# Add library paths
|
4237 |
+
if st.session_state.cpp_settings.get("library_paths", []):
|
4238 |
+
cmake_content += "\n# Library directories\n"
|
4239 |
+
for path in st.session_state.cpp_settings["library_paths"]:
|
4240 |
+
cmake_content += f"link_directories({path})\n"
|
4241 |
+
|
4242 |
+
# Add common libraries
|
4243 |
+
if "Eigen" in st.session_state.cpp_settings.get("libraries", []):
|
4244 |
+
cmake_content += "\n# Eigen\n"
|
4245 |
+
cmake_content += "find_package(Eigen3 REQUIRED)\n"
|
4246 |
+
cmake_content += "include_directories(${EIGEN3_INCLUDE_DIR})\n"
|
4247 |
+
|
4248 |
+
if "OpenCV" in st.session_state.cpp_settings.get("libraries", []):
|
4249 |
+
cmake_content += "\n# OpenCV\n"
|
4250 |
+
cmake_content += "find_package(OpenCV REQUIRED)\n"
|
4251 |
+
cmake_content += "include_directories(${OpenCV_INCLUDE_DIRS})\n"
|
4252 |
+
|
4253 |
+
if "Boost" in st.session_state.cpp_settings.get("libraries", []):
|
4254 |
+
cmake_content += "\n# Boost\n"
|
4255 |
+
cmake_content += "find_package(Boost REQUIRED)\n"
|
4256 |
+
cmake_content += "include_directories(${Boost_INCLUDE_DIRS})\n"
|
4257 |
+
|
4258 |
+
# Add source files
|
4259 |
+
cmake_content += "\n# Source files\n"
|
4260 |
+
source_files = [f for f in st.session_state.cpp_project_files.keys() if f.endswith((".cpp", ".c", ".cc"))]
|
4261 |
+
cmake_content += "add_executable(main\n"
|
4262 |
+
for src in source_files:
|
4263 |
+
cmake_content += f" {src}\n"
|
4264 |
+
cmake_content += ")\n"
|
4265 |
+
|
4266 |
+
# Add libraries to link
|
4267 |
+
cmake_content += "\n# Link libraries\n"
|
4268 |
+
cmake_content += "target_link_libraries(main\n"
|
4269 |
+
|
4270 |
+
if "OpenCV" in st.session_state.cpp_settings.get("libraries", []):
|
4271 |
+
cmake_content += " ${OpenCV_LIBS}\n"
|
4272 |
+
|
4273 |
+
if "Boost" in st.session_state.cpp_settings.get("libraries", []):
|
4274 |
+
cmake_content += " ${Boost_LIBRARIES}\n"
|
4275 |
+
|
4276 |
+
# Additional libraries
|
4277 |
+
for lib in st.session_state.cpp_settings.get("additional_libs", []):
|
4278 |
+
cmake_content += f" {lib}\n"
|
4279 |
+
|
4280 |
+
cmake_content += ")\n"
|
4281 |
+
|
4282 |
+
# Save CMakeLists.txt to project files
|
4283 |
+
st.session_state.cpp_project_files["CMakeLists.txt"] = cmake_content
|
4284 |
+
|
4285 |
+
# Show the generated file
|
4286 |
+
st.success("CMakeLists.txt generated!")
|
4287 |
+
st.code(cmake_content, language="cmake")
|
4288 |
+
|
4289 |
+
with cpp_tabs[4]: # Debugger tab
|
4290 |
+
st.markdown("### C++ Debugger")
|
4291 |
+
st.markdown("Debug your C++ code with breakpoints and variable inspection")
|
4292 |
+
|
4293 |
+
# Enable debugging
|
4294 |
+
enable_cpp_debug = st.checkbox("Enable Debugging", value=False, key="cpp_debug_enable")
|
4295 |
+
|
4296 |
+
if enable_cpp_debug:
|
4297 |
+
# Breakpoints
|
4298 |
+
st.markdown("#### Breakpoints")
|
4299 |
+
st.markdown("Enter line numbers for breakpoints (one per line)")
|
4300 |
+
|
4301 |
+
breakpoints = st.text_area(
|
4302 |
+
"Breakpoints",
|
4303 |
+
placeholder="Example:\n10\n15\n20",
|
4304 |
+
height=100,
|
4305 |
+
key="cpp_breakpoints"
|
4306 |
+
)
|
4307 |
+
|
4308 |
+
breakpoint_lines = []
|
4309 |
+
for line in breakpoints.split("\n"):
|
4310 |
+
try:
|
4311 |
+
line_num = int(line.strip())
|
4312 |
+
if line_num > 0:
|
4313 |
+
breakpoint_lines.append(line_num)
|
4314 |
+
except:
|
4315 |
+
pass
|
4316 |
+
|
4317 |
+
# Watch variables
|
4318 |
+
st.markdown("#### Watch Variables")
|
4319 |
+
st.markdown("Enter variable names to watch (one per line)")
|
4320 |
+
|
4321 |
+
watch_vars = st.text_area(
|
4322 |
+
"Watch Variables",
|
4323 |
+
placeholder="Example:\ni\nsum\nresult",
|
4324 |
+
height=100,
|
4325 |
+
key="cpp_watch_vars"
|
4326 |
+
)
|
4327 |
+
|
4328 |
+
watch_variables = [var.strip() for var in watch_vars.split("\n") if var.strip()]
|
4329 |
+
|
4330 |
+
# Compilation and execution options
|
4331 |
+
st.markdown("### Run Configuration")
|
4332 |
+
|
4333 |
+
run_options_col1, run_options_col2 = st.columns(2)
|
4334 |
+
|
4335 |
+
with run_options_col1:
|
4336 |
+
cpp_timeout = st.slider("Execution Timeout (seconds)", 1, 60, 10)
|
4337 |
+
|
4338 |
+
with run_options_col2:
|
4339 |
+
compile_btn = st.button("🛠️ Compile and Run", use_container_width=True)
|
4340 |
+
|
4341 |
+
# Compile and run the C++ code
|
4342 |
+
if compile_btn:
|
4343 |
+
with st.spinner("Compiling C++ code..."):
|
4344 |
+
cpp_code_to_compile = st.session_state.cpp_code
|
4345 |
+
if "cpp_project_files" in st.session_state and st.session_state.cpp_project_files:
|
4346 |
+
# Use project files
|
4347 |
+
executable_path, compile_error, temp_dir = compile_cpp_code_enhanced(
|
4348 |
+
cpp_code_to_compile,
|
4349 |
+
st.session_state.cpp_settings,
|
4350 |
+
project_files=st.session_state.cpp_project_files,
|
4351 |
+
enable_debug=enable_cpp_debug if "enable_cpp_debug" in locals() else False,
|
4352 |
+
breakpoints=breakpoint_lines if "breakpoint_lines" in locals() else None,
|
4353 |
+
watch_vars=watch_variables if "watch_variables" in locals() else None
|
4354 |
+
)
|
4355 |
+
else:
|
4356 |
+
# Use single file
|
4357 |
+
executable_path, compile_error, temp_dir = compile_cpp_code_enhanced(
|
4358 |
+
cpp_code_to_compile,
|
4359 |
+
st.session_state.cpp_settings,
|
4360 |
+
enable_debug=enable_cpp_debug if "enable_cpp_debug" in locals() else False,
|
4361 |
+
breakpoints=breakpoint_lines if "breakpoint_lines" in locals() else None,
|
4362 |
+
watch_vars=watch_variables if "watch_variables" in locals() else None
|
4363 |
+
)
|
4364 |
+
|
4365 |
+
if compile_error:
|
4366 |
+
st.error("Compilation Error:")
|
4367 |
+
st.code(compile_error, language="bash")
|
4368 |
+
else:
|
4369 |
+
st.success("Compilation successful!")
|
4370 |
+
|
4371 |
+
with st.spinner("Running program..."):
|
4372 |
+
result = run_cpp_executable_enhanced(
|
4373 |
+
executable_path,
|
4374 |
+
temp_dir,
|
4375 |
+
inputs=cpp_inputs if "cpp_inputs" in locals() else None,
|
4376 |
+
timeout=cpp_timeout,
|
4377 |
+
enable_debug=enable_cpp_debug if "enable_cpp_debug" in locals() else False,
|
4378 |
+
breakpoints=breakpoint_lines if "breakpoint_lines" in locals() else None,
|
4379 |
+
watch_vars=watch_variables if "watch_variables" in locals() else None
|
4380 |
+
)
|
4381 |
+
|
4382 |
+
st.session_state.cpp_result = result
|
4383 |
+
|
4384 |
+
# Display results
|
4385 |
+
if "cpp_result" in st.session_state and st.session_state.cpp_result:
|
4386 |
+
result = st.session_state.cpp_result
|
4387 |
+
|
4388 |
+
st.markdown("### Results")
|
4389 |
+
|
4390 |
+
# Execution information
|
4391 |
+
info_cols = st.columns(3)
|
4392 |
+
with info_cols[0]:
|
4393 |
+
st.info(f"Execution Time: {result['execution_time']:.3f} seconds")
|
4394 |
+
|
4395 |
+
with info_cols[1]:
|
4396 |
+
if result.get("memory_usage"):
|
4397 |
+
st.info(f"Memory Usage: {result['memory_usage']:.2f} MB")
|
4398 |
+
|
4399 |
+
with info_cols[2]:
|
4400 |
+
if result["exception"]:
|
4401 |
+
st.error(f"Exception: {result['exception']}")
|
4402 |
+
|
4403 |
+
# Show debug output if available
|
4404 |
+
if result.get("debug_output"):
|
4405 |
+
with st.expander("Debug Output", expanded=True):
|
4406 |
+
st.code(result["debug_output"], language="bash")
|
4407 |
+
|
4408 |
+
# Result tabs
|
4409 |
+
result_tabs = st.tabs(["Output", "Images", "Manim Integration"])
|
4410 |
+
|
4411 |
+
with result_tabs[0]: # Output tab
|
4412 |
+
# Show stdout if any
|
4413 |
+
if result["stdout"]:
|
4414 |
+
st.markdown("#### Standard Output")
|
4415 |
+
st.code(result["stdout"], language="bash")
|
4416 |
+
|
4417 |
+
# Show stderr if any
|
4418 |
+
if result["stderr"]:
|
4419 |
+
st.markdown("#### Standard Error")
|
4420 |
+
st.code(result["stderr"], language="bash")
|
4421 |
+
|
4422 |
+
with result_tabs[1]: # Images tab
|
4423 |
+
# Show images if any
|
4424 |
+
if result["images"]:
|
4425 |
+
st.markdown("#### Generated Images")
|
4426 |
+
img_cols = st.columns(min(3, len(result["images"])))
|
4427 |
+
|
4428 |
+
for i, img in enumerate(result["images"]):
|
4429 |
+
with img_cols[i % len(img_cols)]:
|
4430 |
+
st.image(img["data"], caption=img["name"])
|
4431 |
+
else:
|
4432 |
+
st.info("No images were generated by the program.")
|
4433 |
+
|
4434 |
+
with result_tabs[2]: # Manim Integration tab
|
4435 |
+
st.markdown("#### Integrate C++ Results with Manim")
|
4436 |
+
|
4437 |
+
# Create options for integration
|
4438 |
+
integration_type = st.radio(
|
4439 |
+
"Integration Type",
|
4440 |
+
options=["Data Visualization", "Image Import", "Animation Sequence"],
|
4441 |
+
key="cpp_integration_type"
|
4442 |
+
)
|
4443 |
+
|
4444 |
+
if integration_type == "Data Visualization":
|
4445 |
+
# Extract numerical data from stdout if possible
|
4446 |
+
lines = result["stdout"].strip().split("\n")
|
4447 |
+
data_options = []
|
4448 |
+
|
4449 |
+
for i, line in enumerate(lines):
|
4450 |
+
# Check if line contains numbers
|
4451 |
+
numbers = []
|
4452 |
+
try:
|
4453 |
+
# Try to extract numbers from the line
|
4454 |
+
numbers = [float(x) for x in line.split() if x.replace(".", "").isdigit()]
|
4455 |
+
if numbers:
|
4456 |
+
data_options.append(f"Line {i+1}: {line[:30]}{'...' if len(line) > 30 else ''}")
|
4457 |
+
except:
|
4458 |
+
pass
|
4459 |
+
|
4460 |
+
if data_options:
|
4461 |
+
selected_data_line = st.selectbox(
|
4462 |
+
"Select Data to Visualize",
|
4463 |
+
options=["Select a line..."] + data_options,
|
4464 |
+
key="cpp_data_line"
|
4465 |
+
)
|
4466 |
+
|
4467 |
+
if selected_data_line != "Select a line...":
|
4468 |
+
line_idx = int(selected_data_line.split(":")[0].replace("Line ", "")) - 1
|
4469 |
+
line = lines[line_idx]
|
4470 |
+
|
4471 |
+
# Extract numbers
|
4472 |
+
try:
|
4473 |
+
numbers = [float(x) for x in line.split() if x.replace(".", "").isdigit()]
|
4474 |
+
|
4475 |
+
# Preview the data
|
4476 |
+
st.markdown(f"**Extracted Data:** {numbers}")
|
4477 |
+
|
4478 |
+
# Create visualization code
|
4479 |
+
if st.button("Create Manim Visualization", key="cpp_create_viz"):
|
4480 |
+
viz_code = f"""
|
4481 |
+
# Visualize data from C++ output
|
4482 |
+
values = {numbers}
|
4483 |
+
axes = Axes(
|
4484 |
+
x_range=[0, {len(numbers)}, 1],
|
4485 |
+
y_range=[{min(numbers) if numbers else 0}, {max(numbers) if numbers else 10}, {(max(numbers)-min(numbers))/10 if numbers and max(numbers) > min(numbers) else 1}],
|
4486 |
+
axis_config={{"color": BLUE}}
|
4487 |
+
)
|
4488 |
+
points = [axes.coords_to_point(i, v) for i, v in enumerate(values)]
|
4489 |
+
dots = VGroup(*[Dot(point, color=RED) for point in points])
|
4490 |
+
graph = VMobject(color=YELLOW)
|
4491 |
+
graph.set_points_as_corners(points)
|
4492 |
+
|
4493 |
+
self.play(Create(axes))
|
4494 |
+
self.play(Create(dots), run_time=2)
|
4495 |
+
self.play(Create(graph), run_time=2)
|
4496 |
+
self.wait(1)
|
4497 |
+
"""
|
4498 |
+
if st.session_state.code:
|
4499 |
+
st.session_state.code += "\n" + viz_code
|
4500 |
+
else:
|
4501 |
+
st.session_state.code = f"""from manim import *
|
4502 |
+
class CppDataVisualizationScene(Scene):
|
4503 |
+
def construct(self):
|
4504 |
+
{viz_code}
|
4505 |
+
"""
|
4506 |
+
st.session_state.temp_code = st.session_state.code
|
4507 |
+
st.success("Added C++ data visualization to your Manim code!")
|
4508 |
+
# Set pending tab switch to editor tab
|
4509 |
+
st.session_state.pending_tab_switch = 0
|
4510 |
+
st.rerun()
|
4511 |
+
except Exception as e:
|
4512 |
+
st.error(f"Error extracting numbers: {str(e)}")
|
4513 |
+
else:
|
4514 |
+
st.warning("No numeric data detected in the output.")
|
4515 |
+
|
4516 |
+
elif integration_type == "Image Import":
|
4517 |
+
# Handle image import
|
4518 |
+
if result["images"]:
|
4519 |
+
st.markdown("#### Select Images to Import")
|
4520 |
+
|
4521 |
+
for i, img in enumerate(result["images"]):
|
4522 |
+
st.markdown(f"**{img['name']}**")
|
4523 |
+
st.image(img["data"], width=300)
|
4524 |
+
|
4525 |
+
if st.button(f"Use in Manim", key=f"use_cpp_img_{i}"):
|
4526 |
+
# Save image to a temporary file
|
4527 |
+
with tempfile.NamedTemporaryFile(delete=False, suffix=f"_{img['name']}") as tmp:
|
4528 |
+
tmp.write(img["data"])
|
4529 |
+
img_path = tmp.name
|
4530 |
+
|
4531 |
+
# Generate Manim code
|
4532 |
+
image_code = f"""
|
4533 |
+
# Load and display image generated from C++
|
4534 |
+
cpp_image = ImageMobject(r"{img_path}")
|
4535 |
+
cpp_image.scale(2) # Adjust size as needed
|
4536 |
+
self.play(FadeIn(cpp_image))
|
4537 |
+
self.wait(1)
|
4538 |
+
"""
|
4539 |
+
if st.session_state.code:
|
4540 |
+
st.session_state.code += "\n" + image_code
|
4541 |
+
else:
|
4542 |
+
st.session_state.code = f"""from manim import *
|
4543 |
+
class CppImageScene(Scene):
|
4544 |
+
def construct(self):
|
4545 |
+
{image_code}
|
4546 |
+
"""
|
4547 |
+
st.session_state.temp_code = st.session_state.code
|
4548 |
+
st.success(f"Added C++ generated image to your Manim code!")
|
4549 |
+
st.session_state.pending_tab_switch = 0 # Switch to editor tab
|
4550 |
+
st.rerun()
|
4551 |
+
else:
|
4552 |
+
st.warning("No images were generated by the C++ program.")
|
4553 |
+
|
4554 |
+
elif integration_type == "Animation Sequence":
|
4555 |
+
st.markdown("#### Create Animation Sequence")
|
4556 |
+
st.info("This will create a Manim animation that visualizes the execution of your C++ program.")
|
4557 |
+
|
4558 |
+
# Animation type options
|
4559 |
+
animation_style = st.selectbox(
|
4560 |
+
"Animation Style",
|
4561 |
+
options=["Algorithm Visualization", "Data Flow", "Memory Model"],
|
4562 |
+
key="cpp_anim_style"
|
4563 |
+
)
|
4564 |
+
|
4565 |
+
if st.button("Generate Animation Sequence", key="cpp_gen_anim_seq"):
|
4566 |
+
# Create different animations based on selected style
|
4567 |
+
if animation_style == "Algorithm Visualization":
|
4568 |
+
# Example code for algorithm visualization
|
4569 |
+
algo_code = f"""
|
4570 |
+
# C++ Algorithm Visualization
|
4571 |
+
title = Text("C++ Algorithm Visualization")
|
4572 |
+
self.play(Write(title))
|
4573 |
+
self.play(title.animate.to_edge(UP))
|
4574 |
+
self.wait(0.5)
|
4575 |
+
|
4576 |
+
# Create an array representation
|
4577 |
+
values = [5, 2, 8, 1, 9, 3, 7, 4, 6] # Example values
|
4578 |
+
squares = VGroup(*[Square(side_length=0.7, fill_opacity=0.8, fill_color=BLUE) for _ in values])
|
4579 |
+
squares.arrange(RIGHT, buff=0.1)
|
4580 |
+
labels = VGroup(*[Text(str(v), font_size=24) for v in values])
|
4581 |
+
for label, square in zip(labels, squares):
|
4582 |
+
label.move_to(square.get_center())
|
4583 |
+
|
4584 |
+
array = VGroup(squares, labels)
|
4585 |
+
array_label = Text("Array", font_size=20).next_to(array, UP)
|
4586 |
+
self.play(FadeIn(array), Write(array_label))
|
4587 |
+
self.wait(1)
|
4588 |
+
|
4589 |
+
# Simulate sorting algorithm
|
4590 |
+
for i in range(len(values)-1):
|
4591 |
+
# Highlight current element
|
4592 |
+
self.play(squares[i].animate.set_fill(RED))
|
4593 |
+
|
4594 |
+
for j in range(i+1, len(values)):
|
4595 |
+
# Highlight comparison element
|
4596 |
+
self.play(squares[j].animate.set_fill(YELLOW))
|
4597 |
+
|
4598 |
+
# Simulate comparison
|
4599 |
+
if values[i] > values[j]:
|
4600 |
+
# Swap animation
|
4601 |
+
self.play(
|
4602 |
+
labels[i].animate.move_to(squares[j].get_center()),
|
4603 |
+
labels[j].animate.move_to(squares[i].get_center())
|
4604 |
+
)
|
4605 |
+
|
4606 |
+
# Update values and labels
|
4607 |
+
labels[i], labels[j] = labels[j], labels[i]
|
4608 |
+
values[i], values[j] = values[j], values[i]
|
4609 |
+
|
4610 |
+
# Reset comparison element
|
4611 |
+
self.play(squares[j].animate.set_fill(BLUE))
|
4612 |
+
|
4613 |
+
# Mark current element as processed
|
4614 |
+
self.play(squares[i].animate.set_fill(GREEN))
|
4615 |
+
|
4616 |
+
# Mark the last element as processed
|
4617 |
+
self.play(squares[-1].animate.set_fill(GREEN))
|
4618 |
+
|
4619 |
+
# Show sorted array
|
4620 |
+
sorted_label = Text("Sorted Array", font_size=20).next_to(array, DOWN)
|
4621 |
+
self.play(Write(sorted_label))
|
4622 |
+
self.wait(2)
|
4623 |
+
"""
|
4624 |
+
if st.session_state.code:
|
4625 |
+
st.session_state.code += "\n" + algo_code
|
4626 |
+
else:
|
4627 |
+
st.session_state.code = f"""from manim import *
|
4628 |
+
class CppAlgorithmScene(Scene):
|
4629 |
+
def construct(self):
|
4630 |
+
{algo_code}
|
4631 |
+
"""
|
4632 |
+
st.session_state.temp_code = st.session_state.code
|
4633 |
+
st.success("Added C++ algorithm visualization to your Manim code!")
|
4634 |
+
st.session_state.pending_tab_switch = 0 # Switch to editor tab
|
4635 |
+
st.rerun()
|
4636 |
+
|
4637 |
+
elif animation_style == "Data Flow":
|
4638 |
+
# Example code for data flow visualization
|
4639 |
+
data_flow_code = f"""
|
4640 |
+
# C++ Data Flow Visualization
|
4641 |
+
title = Text("C++ Data Flow")
|
4642 |
+
self.play(Write(title))
|
4643 |
+
self.play(title.animate.to_edge(UP))
|
4644 |
+
self.wait(0.5)
|
4645 |
+
|
4646 |
+
# Create nodes for data flow
|
4647 |
+
input_node = Circle(radius=0.5, fill_opacity=0.8, fill_color=BLUE)
|
4648 |
+
process_node = Square(side_length=1, fill_opacity=0.8, fill_color=GREEN)
|
4649 |
+
output_node = Circle(radius=0.5, fill_opacity=0.8, fill_color=RED)
|
4650 |
+
|
4651 |
+
# Position nodes
|
4652 |
+
input_node.move_to(LEFT*4)
|
4653 |
+
process_node.move_to(ORIGIN)
|
4654 |
+
output_node.move_to(RIGHT*4)
|
4655 |
+
|
4656 |
+
# Add labels
|
4657 |
+
input_label = Text("Input", font_size=20).next_to(input_node, DOWN)
|
4658 |
+
process_label = Text("Process", font_size=20).next_to(process_node, DOWN)
|
4659 |
+
output_label = Text("Output", font_size=20).next_to(output_node, DOWN)
|
4660 |
+
|
4661 |
+
# Create arrows
|
4662 |
+
arrow1 = Arrow(input_node.get_right(), process_node.get_left(), buff=0.2)
|
4663 |
+
arrow2 = Arrow(process_node.get_right(), output_node.get_left(), buff=0.2)
|
4664 |
+
|
4665 |
+
# Display nodes and arrows
|
4666 |
+
self.play(FadeIn(input_node), Write(input_label))
|
4667 |
+
self.wait(0.5)
|
4668 |
+
self.play(FadeIn(process_node), Write(process_label))
|
4669 |
+
self.wait(0.5)
|
4670 |
+
self.play(FadeIn(output_node), Write(output_label))
|
4671 |
+
self.wait(0.5)
|
4672 |
+
self.play(Create(arrow1), Create(arrow2))
|
4673 |
+
self.wait(1)
|
4674 |
+
|
4675 |
+
# Simulate data flow
|
4676 |
+
data = Text("Data", font_size=16).move_to(input_node.get_center())
|
4677 |
+
self.play(FadeIn(data))
|
4678 |
+
self.wait(0.5)
|
4679 |
+
|
4680 |
+
# Move data along the flow
|
4681 |
+
self.play(data.animate.move_to(arrow1.get_center()))
|
4682 |
+
self.wait(0.5)
|
4683 |
+
self.play(data.animate.move_to(process_node.get_center()))
|
4684 |
+
self.wait(0.5)
|
4685 |
+
transformed_data = Text("Processed", font_size=16, color=YELLOW)
|
4686 |
+
transformed_data.move_to(process_node.get_center())
|
4687 |
+
self.play(Transform(data, transformed_data))
|
4688 |
+
self.wait(0.5)
|
4689 |
+
self.play(data.animate.move_to(arrow2.get_center()))
|
4690 |
+
self.wait(0.5)
|
4691 |
+
self.play(data.animate.move_to(output_node.get_center()))
|
4692 |
+
self.wait(1)
|
4693 |
+
|
4694 |
+
result_text = Text("Final Result", font_size=24).to_edge(DOWN)
|
4695 |
+
self.play(Write(result_text))
|
4696 |
+
self.wait(2)
|
4697 |
+
"""
|
4698 |
+
if st.session_state.code:
|
4699 |
+
st.session_state.code += "\n" + data_flow_code
|
4700 |
+
else:
|
4701 |
+
st.session_state.code = f"""from manim import *
|
4702 |
+
class CppDataFlowScene(Scene):
|
4703 |
+
def construct(self):
|
4704 |
+
{data_flow_code}
|
4705 |
+
"""
|
4706 |
+
st.session_state.temp_code = st.session_state.code
|
4707 |
+
st.success("Added C++ data flow visualization to your Manim code!")
|
4708 |
+
st.session_state.pending_tab_switch = 0 # Switch to editor tab
|
4709 |
+
st.rerun()
|
4710 |
+
|
4711 |
+
elif animation_style == "Memory Model":
|
4712 |
+
# Example code for memory model visualization
|
4713 |
+
memory_code = f"""
|
4714 |
+
# C++ Memory Model Visualization
|
4715 |
+
title = Text("C++ Memory Model")
|
4716 |
+
self.play(Write(title))
|
4717 |
+
self.play(title.animate.to_edge(UP))
|
4718 |
+
self.wait(0.5)
|
4719 |
+
|
4720 |
+
# Create memory blocks
|
4721 |
+
stack_rect = Rectangle(height=3, width=4, fill_opacity=0.2, fill_color=BLUE)
|
4722 |
+
stack_rect.move_to(LEFT*3.5)
|
4723 |
+
stack_label = Text("Stack", font_size=20).next_to(stack_rect, UP)
|
4724 |
+
|
4725 |
+
heap_rect = Rectangle(height=3, width=4, fill_opacity=0.2, fill_color=RED)
|
4726 |
+
heap_rect.move_to(RIGHT*3.5)
|
4727 |
+
heap_label = Text("Heap", font_size=20).next_to(heap_rect, UP)
|
4728 |
+
|
4729 |
+
# Display memory areas
|
4730 |
+
self.play(
|
4731 |
+
Create(stack_rect), Write(stack_label),
|
4732 |
+
Create(heap_rect), Write(heap_label)
|
4733 |
+
)
|
4734 |
+
self.wait(1)
|
4735 |
+
|
4736 |
+
# Create variables on the stack
|
4737 |
+
int_var = Rectangle(height=0.5, width=1.5, fill_opacity=0.8, fill_color=BLUE_C)
|
4738 |
+
int_var.move_to(stack_rect.get_center() + UP*1)
|
4739 |
+
int_label = Text("int x = 5", font_size=16).next_to(int_var, RIGHT)
|
4740 |
+
|
4741 |
+
pointer_var = Rectangle(height=0.5, width=1.5, fill_opacity=0.8, fill_color=BLUE_D)
|
4742 |
+
pointer_var.move_to(stack_rect.get_center())
|
4743 |
+
pointer_label = Text("int* ptr", font_size=16).next_to(pointer_var, RIGHT)
|
4744 |
+
|
4745 |
+
# Display stack variables
|
4746 |
+
self.play(FadeIn(int_var), Write(int_label))
|
4747 |
+
self.wait(0.5)
|
4748 |
+
self.play(FadeIn(pointer_var), Write(pointer_label))
|
4749 |
+
self.wait(1)
|
4750 |
+
|
4751 |
+
# Create heap allocation
|
4752 |
+
heap_alloc = Rectangle(height=0.8, width=2, fill_opacity=0.8, fill_color=RED_C)
|
4753 |
+
heap_alloc.move_to(heap_rect.get_center() + UP*0.5)
|
4754 |
+
heap_label = Text("new int[4]", font_size=16).next_to(heap_alloc, LEFT)
|
4755 |
+
|
4756 |
+
# Display heap allocation
|
4757 |
+
self.play(FadeIn(heap_alloc), Write(heap_label))
|
4758 |
+
self.wait(1)
|
4759 |
+
|
4760 |
+
# Create arrow from pointer to heap
|
4761 |
+
arrow = Arrow(pointer_var.get_right(), heap_alloc.get_left(), buff=0.2, color=YELLOW)
|
4762 |
+
self.play(Create(arrow))
|
4763 |
+
self.wait(0.5)
|
4764 |
+
|
4765 |
+
# Simulate pointer assignment
|
4766 |
+
assign_text = Text("ptr = new int[4]", font_size=24).to_edge(DOWN)
|
4767 |
+
self.play(Write(assign_text))
|
4768 |
+
self.wait(1)
|
4769 |
+
|
4770 |
+
# Simulate memory deallocation
|
4771 |
+
delete_text = Text("delete[] ptr", font_size=24).to_edge(DOWN)
|
4772 |
+
self.play(Transform(assign_text, delete_text))
|
4773 |
+
self.play(FadeOut(arrow), FadeOut(heap_alloc), FadeOut(heap_label))
|
4774 |
+
self.wait(1)
|
4775 |
+
|
4776 |
+
# Simulate end of scope
|
4777 |
+
end_scope = Text("End of scope", font_size=24).to_edge(DOWN)
|
4778 |
+
self.play(Transform(assign_text, end_scope))
|
4779 |
+
self.play(FadeOut(int_var), FadeOut(int_label), FadeOut(pointer_var), FadeOut(pointer_label))
|
4780 |
+
self.wait(2)
|
4781 |
+
"""
|
4782 |
+
if st.session_state.code:
|
4783 |
+
st.session_state.code += "\n" + memory_code
|
4784 |
+
else:
|
4785 |
+
st.session_state.code = f"""from manim import *
|
4786 |
+
class CppMemoryModelScene(Scene):
|
4787 |
+
def construct(self):
|
4788 |
+
{memory_code}
|
4789 |
+
"""
|
4790 |
+
st.session_state.temp_code = st.session_state.code
|
4791 |
+
st.success("Added C++ memory model visualization to your Manim code!")
|
4792 |
+
st.session_state.pending_tab_switch = 0 # Switch to editor tab
|
4793 |
+
st.rerun()
|
4794 |
+
|
4795 |
+
# C++ Information and tips
|
4796 |
+
with st.expander("C/C++ Runner Information"):
|
4797 |
+
st.markdown("""
|
4798 |
+
### C/C++ Runner Tips
|
4799 |
+
|
4800 |
+
**Compilation Options:**
|
4801 |
+
- Choose the appropriate compiler based on your platform
|
4802 |
+
- Select the C++ standard version for your code
|
4803 |
+
- Optimization levels affect performance and debugging
|
4804 |
+
|
4805 |
+
**Library Support:**
|
4806 |
+
- Common libraries like Eigen, OpenCV, and Boost are supported
|
4807 |
+
- Add custom include paths and library paths as needed
|
4808 |
+
- Use the library detection feature to find installed libraries
|
4809 |
+
|
4810 |
+
**Input/Output:**
|
4811 |
+
- Standard input/output (cin/cout) is fully supported
|
4812 |
+
- File I/O works within the execution directory
|
4813 |
+
- For interactive programs, provide input values in advance
|
4814 |
+
|
4815 |
+
**Debugging:**
|
4816 |
+
- Set breakpoints at specific line numbers
|
4817 |
+
- Watch variables to track their values
|
4818 |
+
- Debug with GDB for detailed analysis
|
4819 |
+
|
4820 |
+
**Project Management:**
|
4821 |
+
- Create multi-file projects with headers and source files
|
4822 |
+
- Generate CMakeLists.txt for complex projects
|
4823 |
+
- Download project files as a ZIP archive
|
4824 |
+
|
4825 |
+
**Images and Visualization:**
|
4826 |
+
- Generate images in PPM, PNG, JPG formats
|
4827 |
+
- Use OpenCV for more advanced image processing
|
4828 |
+
- All generated images can be used in Manim animations
|
4829 |
+
|
4830 |
+
**Manim Integration:**
|
4831 |
+
- Create algorithm visualizations from C++ code
|
4832 |
+
- Import C++ generated images into Manim scenes
|
4833 |
+
- Visualize data structures and memory models
|
4834 |
+
|
4835 |
+
**Performance:**
|
4836 |
+
- Use release mode for best performance
|
4837 |
+
- Profile your code to identify bottlenecks
|
4838 |
+
- C++ is ideal for computationally intensive tasks
|
4839 |
+
""")
|
4840 |
+
|
4841 |
# Help section
|
4842 |
with st.sidebar.expander("ℹ️ Help & Info"):
|
4843 |
st.markdown("""
|