Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -316,111 +316,112 @@ STRICT REQUIREMENTS:
|
|
316 |
return f"Error: {str(e)}", None, None
|
317 |
|
318 |
def extract_and_run_sympy_code(response_text):
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
335 |
-
|
336 |
|
337 |
-
|
338 |
-
|
339 |
-
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
347 |
-
|
348 |
-
|
349 |
-
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
from contextlib import redirect_stdout
|
354 |
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
|
363 |
-
|
364 |
-
|
365 |
-
|
366 |
-
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
# Execute the code and capture output
|
381 |
-
with redirect_stdout(output_buffer):
|
382 |
-
exec(sympy_code, sympy_globals, local_vars)
|
383 |
-
|
384 |
-
# Get the printed output
|
385 |
-
printed_output = output_buffer.getvalue().strip()
|
386 |
-
|
387 |
-
# Initialize result string
|
388 |
-
result = []
|
389 |
-
|
390 |
-
# Add numerical and symbolic calculation results
|
391 |
-
for name, value in local_vars.items():
|
392 |
-
# Skip private variables and functions
|
393 |
-
if name.startswith('__') or callable(value) or isinstance(value, type):
|
394 |
-
continue
|
395 |
-
|
396 |
-
# Skip module references
|
397 |
-
if hasattr(value, '__module__'):
|
398 |
-
continue
|
399 |
-
|
400 |
-
# Format the output
|
401 |
-
try:
|
402 |
-
# If it's a sympy expression or numerical result
|
403 |
-
if isinstance(value, (sympy.Basic, int, float)) or hasattr(value, 'free_symbols'):
|
404 |
-
result.append(f"{name} = {value}")
|
405 |
-
# If it's a list or tuple of sympy expressions
|
406 |
-
elif isinstance(value, (list, tuple)) and all(isinstance(x, (sympy.Basic, int, float)) for x in value):
|
407 |
-
result.append(f"{name} = {value}")
|
408 |
-
except:
|
409 |
-
continue
|
410 |
-
|
411 |
-
# Add printed output if it exists and isn't just whitespace
|
412 |
-
if printed_output and not printed_output.isspace():
|
413 |
-
result.insert(0, printed_output)
|
414 |
-
|
415 |
-
# If we have no results, provide a message
|
416 |
-
if not result:
|
417 |
-
return "No calculation results produced."
|
418 |
-
|
419 |
-
return "\n".join(result)
|
420 |
-
|
421 |
-
except Exception as e:
|
422 |
-
return f"Error executing SymPy code: {str(e)}"
|
423 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
424 |
def check_and_resolve_discrepancy(initial_response, sympy_output):
|
425 |
"""
|
426 |
Compare the SymPy output with the initial response and resolve any discrepancies
|
|
|
316 |
return f"Error: {str(e)}", None, None
|
317 |
|
318 |
def extract_and_run_sympy_code(response_text):
|
319 |
+
"""
|
320 |
+
Extract SymPy code from the response and execute it.
|
321 |
+
Returns only the essential calculation results as a string.
|
322 |
+
"""
|
323 |
+
try:
|
324 |
+
# Find the SymPy code block
|
325 |
+
sympy_start = response_text.find('```python')
|
326 |
+
if sympy_start == -1:
|
327 |
+
return "No SymPy code found in the response."
|
328 |
+
|
329 |
+
# Extract the code (excluding the ```python and ``` markers)
|
330 |
+
code_start = response_text.find('\n', sympy_start) + 1
|
331 |
+
code_end = response_text.find('```', code_start)
|
332 |
+
if code_end == -1:
|
333 |
+
return "Malformed SymPy code block."
|
334 |
+
|
335 |
+
sympy_code = response_text[code_start:code_end].strip()
|
336 |
|
337 |
+
if "print" not in sympy_code and any(x in sympy_code for x in ['diff', 'integrate', 'solve']):
|
338 |
+
lines = sympy_code.split('\n')
|
339 |
+
modified_lines = []
|
340 |
+
for line in lines:
|
341 |
+
modified_lines.append(line)
|
342 |
+
# If line assigns a value and looks like it creates an expression
|
343 |
+
if ('=' in line and '#' not in line and 'import' not in line
|
344 |
+
and any(x in line for x in ['diff', 'integrate', 'solve', 'sqrt', 'log'])):
|
345 |
+
var_name = line.split('=')[0].strip()
|
346 |
+
modified_lines.append(f"print('{var_name} = ', {var_name})")
|
347 |
+
sympy_code = '\n'.join(modified_lines)
|
348 |
+
|
349 |
+
# Import necessary modules
|
350 |
+
import io
|
351 |
+
import sympy
|
352 |
+
from contextlib import redirect_stdout
|
|
|
353 |
|
354 |
+
# Create a string buffer to capture print output
|
355 |
+
output_buffer = io.StringIO()
|
356 |
+
|
357 |
+
# Create globals dict with minimal SymPy elements
|
358 |
+
sympy_globals = {
|
359 |
+
"Symbol": sympy.Symbol,
|
360 |
+
"symbols": sympy.symbols,
|
361 |
+
"solve": sympy.solve,
|
362 |
+
"integrate": sympy.integrate,
|
363 |
+
"diff": sympy.diff,
|
364 |
+
"limit": sympy.limit,
|
365 |
+
"sqrt": sympy.sqrt,
|
366 |
+
"exp": sympy.exp,
|
367 |
+
"simplify": sympy.simplify,
|
368 |
+
"expand": sympy.expand,
|
369 |
+
"log": sympy.log,
|
370 |
+
"print": print, # Allow print statements
|
371 |
+
"pi": sympy.pi,
|
372 |
+
"N": sympy.N,
|
373 |
+
"evalf": lambda x: x.evalf()
|
374 |
+
}
|
375 |
+
|
376 |
+
# Create locals dict to capture new variables
|
377 |
+
local_vars = {}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
378 |
|
379 |
+
# Execute the code and capture output
|
380 |
+
with redirect_stdout(output_buffer):
|
381 |
+
exec(sympy_code, sympy_globals, local_vars)
|
382 |
+
|
383 |
+
# Get the printed output
|
384 |
+
printed_output = output_buffer.getvalue().strip()
|
385 |
+
|
386 |
+
# Initialize result string
|
387 |
+
result = []
|
388 |
+
|
389 |
+
# Add numerical and symbolic calculation results
|
390 |
+
for name, value in local_vars.items():
|
391 |
+
# Skip private variables and functions
|
392 |
+
if name.startswith('__') or callable(value) or isinstance(value, type):
|
393 |
+
continue
|
394 |
+
|
395 |
+
# Skip module references
|
396 |
+
if hasattr(value, '__module__'):
|
397 |
+
continue
|
398 |
+
|
399 |
+
try:
|
400 |
+
# If it's a sympy expression or numerical result
|
401 |
+
if isinstance(value, (sympy.Basic, int, float)) or hasattr(value, 'free_symbols'):
|
402 |
+
result.append(f"{name} = {value}")
|
403 |
+
# If it's a list of solutions from solve()
|
404 |
+
elif isinstance(value, list):
|
405 |
+
result.append(f"{name} = {value}")
|
406 |
+
# If it's a list or tuple of sympy expressions
|
407 |
+
elif isinstance(value, (list, tuple)) and all(isinstance(x, (sympy.Basic, int, float)) for x in value):
|
408 |
+
result.append(f"{name} = {value}")
|
409 |
+
except:
|
410 |
+
continue
|
411 |
+
|
412 |
+
# Add printed output if it exists and isn't just whitespace
|
413 |
+
if printed_output and not printed_output.isspace():
|
414 |
+
result.insert(0, printed_output)
|
415 |
+
|
416 |
+
# If we have no results, provide a message
|
417 |
+
if not result:
|
418 |
+
return "No calculation results produced."
|
419 |
+
|
420 |
+
return "\n".join(result)
|
421 |
+
|
422 |
+
except Exception as e:
|
423 |
+
return f"Error executing SymPy code: {str(e)}"
|
424 |
+
|
425 |
def check_and_resolve_discrepancy(initial_response, sympy_output):
|
426 |
"""
|
427 |
Compare the SymPy output with the initial response and resolve any discrepancies
|