euler314 commited on
Commit
e9acc95
·
verified ·
1 Parent(s): aef7e3e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +1958 -131
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 run_python_script(code, inputs=None, timeout=60):
1019
- """Execute a Python script and capture output, handling input calls"""
 
1020
  result = {
1021
  "stdout": "",
1022
  "stderr": "",
1023
  "exception": None,
1024
  "plots": [],
1025
  "dataframes": [],
1026
- "execution_time": 0
 
 
 
1027
  }
1028
 
1029
- # Replace input() calls with predefined values if provided
1030
- if inputs and len(inputs) > 0:
1031
- # Modify the code to use predefined inputs instead of waiting for user input
1032
- modified_code = """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
- code += "\n" + save_plots_code
 
 
 
1079
 
1080
- # Add dataframe display code if pandas is used
1081
- if 'pandas' in code or 'pd.' in code or 'DataFrame' in code:
1082
- if 'import pandas as pd' not in code and 'from pandas import' not in code:
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
- __globals_dict = globals()
1093
- __dataframes = []
1094
- for __var_name, __var_val in __globals_dict.items():
1095
- if isinstance(__var_val, pd.DataFrame) and not __var_name.startswith('__'):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1096
  try:
1097
- # Save basic info
1098
- __df_info = {
1099
- "name": __var_name,
1100
- "shape": __var_val.shape,
1101
- "columns": list(__var_val.columns),
1102
- "preview_html": __var_val.head().to_html()
1103
- }
1104
- with open(os.path.join('{}', f'df_{{__var_name}}.json'), 'w') as __f:
1105
- json.dump(__df_info, __f)
1106
  except:
1107
  pass
1108
- """.format(temp_dir.replace('\\', '\\\\'))
1109
-
1110
- code += "\n" + dataframes_code
 
 
 
 
 
1111
 
1112
- # Create the script file
1113
- script_path = os.path.join(temp_dir, 'script.py')
1114
- with open(script_path, 'w') as f:
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, script_path],
1124
  stdout=stdout_f,
1125
  stderr=stderr_f,
1126
  cwd=temp_dir
1127
  )
1128
 
1129
- try:
1130
- process.wait(timeout=timeout)
1131
- except subprocess.TimeoutExpired:
1132
- process.kill()
1133
- result["stderr"] += f"\nScript execution timed out after {timeout} seconds."
1134
- result["exception"] = "TimeoutError"
1135
- return result
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 display_python_script_results(result):
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['name']} - {df_info['shape'][0]} rows × {df_info['shape'][1]} columns"):
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 - LaTeX tab removed
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
- class MyScene(Scene):
2425
- def construct(self):
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
- result = run_python_script(python_code, inputs=user_inputs, timeout=timeout_seconds)
 
 
 
 
 
 
 
 
 
 
2916
  st.session_state.python_result = result
2917
 
2918
  # Display results
2919
  if st.session_state.python_result:
2920
- display_python_script_results(st.session_state.python_result)
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("""