Spaces:
Runtime error
Runtime error
feat: add Gradio interfaces for trigonometric functions and remove old trigonometry interface
Browse files- maths/differential_equations/differential_equations_interface.py +0 -106
- maths/equations/equations_interface.py +0 -88
- maths/geometry/cos_degrees.py +9 -0
- maths/geometry/geometry_tab.py +4 -4
- maths/geometry/inverse_trig_functions.py +12 -0
- maths/geometry/sin_degrees.py +9 -0
- maths/geometry/solve_trig_equations.py +24 -0
- maths/geometry/tan_degrees.py +9 -0
- maths/geometry/trig_identities.py +20 -0
- maths/geometry/trigonometry_interface.py +0 -79
maths/differential_equations/differential_equations_interface.py
DELETED
@@ -1,106 +0,0 @@
|
|
1 |
-
"""
|
2 |
-
Gradio Interface for Differential Equations solvers.
|
3 |
-
|
4 |
-
SECURITY WARNING: These interfaces use eval() to parse user-provided Python lambda strings
|
5 |
-
for defining ODE functions. This is a potential security risk if arbitrary code is entered.
|
6 |
-
Use with caution and only with trusted inputs, especially if deploying this application
|
7 |
-
outside a controlled environment.
|
8 |
-
"""
|
9 |
-
import gradio as gr
|
10 |
-
import numpy as np
|
11 |
-
import matplotlib.pyplot as plt # For displaying plots if not returned directly by solver
|
12 |
-
from typing import Callable, Tuple, List, Dict, Any, Union
|
13 |
-
import ast # For safer string literal evaluation if needed for parameters
|
14 |
-
import math # To make math functions available in eval scope for ODEs
|
15 |
-
|
16 |
-
# Import the solver functions
|
17 |
-
from maths.differential_equations.solve_first_order_ode import solve_first_order_ode
|
18 |
-
from maths.differential_equations.solve_second_order_ode import solve_second_order_ode
|
19 |
-
from maths.differential_equations.ode_interface_utils import parse_float_list, parse_time_span, string_to_ode_func
|
20 |
-
|
21 |
-
# --- Helper Functions ---
|
22 |
-
|
23 |
-
# (Keep the helper functions here if needed, otherwise they can be removed as they are now in ode_interface_utils.py)
|
24 |
-
|
25 |
-
# --- Gradio Interface for First-Order ODEs ---
|
26 |
-
# first_order_ode_interface = gr.Interface(
|
27 |
-
# fn=lambda ode_str, t_span_str, y0_str, t_eval_count, method: solve_first_order_ode(
|
28 |
-
# string_to_ode_func(ode_str, ('t', 'y')),
|
29 |
-
# parse_time_span(t_span_str),
|
30 |
-
# parse_float_list(y0_str), # y0 can be a list for systems
|
31 |
-
# int(t_eval_count),
|
32 |
-
# method
|
33 |
-
# ),
|
34 |
-
# inputs=[
|
35 |
-
# gr.Textbox(label="ODE Function (lambda t, y: ...)",
|
36 |
-
# placeholder="e.g., lambda t, y: -y*t OR for system lambda t, y: [y[1], -0.1*y[1] - y[0]]",
|
37 |
-
# info="Define dy/dt or a system [dy1/dt, dy2/dt,...]. `y` is a list/array for systems."),
|
38 |
-
# gr.Textbox(label="Time Span (t_start, t_end)", placeholder="e.g., 0,10"),
|
39 |
-
# gr.Textbox(label="Initial Condition(s) y(t_start)", placeholder="e.g., 1 OR for system 1,0"),
|
40 |
-
# gr.Slider(minimum=10, maximum=1000, value=100, step=10, label="Evaluation Points Count"),
|
41 |
-
# gr.Radio(choices=['RK45', 'LSODA', 'BDF', 'RK23', 'DOP853'], value='RK45', label="Solver Method")
|
42 |
-
# ],
|
43 |
-
# outputs=[
|
44 |
-
# gr.Image(label="Solution Plot", type="filepath", show_label=True, visible=lambda res: res['success'] and res['plot_path'] is not None),
|
45 |
-
# gr.Textbox(label="Solver Message"),
|
46 |
-
# gr.Textbox(label="Success Status"),
|
47 |
-
# gr.JSON(label="Raw Data (t, y values)", visible=lambda res: res['success']) # For users to copy if needed
|
48 |
-
# ],
|
49 |
-
# title="First-Order ODE Solver",
|
50 |
-
# description="Solves dy/dt = f(t,y) or a system of first-order ODEs. " \
|
51 |
-
# "WARNING: Uses eval() for the ODE function string - potential security risk. " \
|
52 |
-
# "For systems, `y` in lambda is `[y1, y2, ...]`, return `[dy1/dt, dy2/dt, ...]`. " \
|
53 |
-
# "Example (Damped Oscillator): ODE: lambda t, y: [y[1], -0.5*y[1] - y[0]], y0: 1,0, Timespan: 0,20",
|
54 |
-
# flagging_mode="manual"
|
55 |
-
# )
|
56 |
-
|
57 |
-
# # --- Gradio Interface for Second-Order ODEs ---
|
58 |
-
# second_order_ode_interface = gr.Interface(
|
59 |
-
# fn=lambda ode_str, t_span_str, y0_val_str, dy0_dt_val_str, t_eval_count, method: solve_second_order_ode(
|
60 |
-
# string_to_ode_func(ode_str, ('t', 'y', 'dy_dt')), # Note: dy_dt is one variable name here
|
61 |
-
# parse_time_span(t_span_str),
|
62 |
-
# parse_float_list(y0_val_str, expected_len=1)[0], # y0 is a single float
|
63 |
-
# parse_float_list(dy0_dt_val_str, expected_len=1)[0], # dy0_dt is a single float
|
64 |
-
# int(t_eval_count),
|
65 |
-
# method
|
66 |
-
# ),
|
67 |
-
# inputs=[
|
68 |
-
# gr.Textbox(label="ODE Function (lambda t, y, dy_dt: ...)",
|
69 |
-
# placeholder="e.g., lambda t, y, dy_dt: -0.1*dy_dt - math.sin(y)",
|
70 |
-
# info="Define d²y/dt². `y` is current value, `dy_dt` is current first derivative."),
|
71 |
-
# gr.Textbox(label="Time Span (t_start, t_end)", placeholder="e.g., 0,20"),
|
72 |
-
# gr.Textbox(label="Initial y(t_start)", placeholder="e.g., 1.0"),
|
73 |
-
# gr.Textbox(label="Initial dy/dt(t_start)", placeholder="e.g., 0.0"),
|
74 |
-
# gr.Slider(minimum=10, maximum=1000, value=100, step=10, label="Evaluation Points Count"),
|
75 |
-
# gr.Radio(choices=['RK45', 'LSODA', 'BDF', 'RK23', 'DOP853'], value='RK45', label="Solver Method")
|
76 |
-
# ],
|
77 |
-
# outputs=[
|
78 |
-
# gr.Image(label="Solution Plot (y(t) and dy/dt(t))", type="filepath", show_label=True, visible=lambda res: res['success'] and res['plot_path'] is not None),
|
79 |
-
# gr.Textbox(label="Solver Message"),
|
80 |
-
# gr.Textbox(label="Success Status"),
|
81 |
-
# gr.JSON(label="Raw Data (t, y, dy_dt values)", visible=lambda res: res['success'])
|
82 |
-
# ],
|
83 |
-
# title="Second-Order ODE Solver",
|
84 |
-
# description="Solves d²y/dt² = f(t, y, dy/dt). " \
|
85 |
-
# "WARNING: Uses eval() for the ODE function string - potential security risk. " \
|
86 |
-
# "Example (Pendulum): ODE: lambda t, y, dy_dt: -9.81/1.0 * math.sin(y), y0: math.pi/4, dy0/dt: 0, Timespan: 0,10",
|
87 |
-
# flagging_mode="manual"
|
88 |
-
# )
|
89 |
-
|
90 |
-
# Example usage for testing (can be removed)
|
91 |
-
if __name__ == '__main__':
|
92 |
-
# Test first order
|
93 |
-
# result1 = solve_first_order_ode(lambda t,y: -y*t, (0,5), [1])
|
94 |
-
# print(result1['success'], result1['message'])
|
95 |
-
# if result1['plot_path']: import os; os.system(f"open {result1['plot_path']}")
|
96 |
-
|
97 |
-
|
98 |
-
# Test second order
|
99 |
-
# result2 = solve_second_order_ode(lambda t,y,dydt: -0.1*dydt - y, (0,20), 1, 0)
|
100 |
-
# print(result2['success'], result2['message'])
|
101 |
-
# if result2['plot_path']: import os; os.system(f"open {result2['plot_path']}")
|
102 |
-
|
103 |
-
# To run one of these interfaces for testing:
|
104 |
-
# first_order_ode_interface.launch()
|
105 |
-
# second_order_ode_interface.launch()
|
106 |
-
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
maths/equations/equations_interface.py
DELETED
@@ -1,88 +0,0 @@
|
|
1 |
-
# filepath: c:\Users\visha\Desktop\coding\counting\maths\equations\equations_interface.py
|
2 |
-
import gradio as gr
|
3 |
-
from maths.equations.solve_quadratic import solve_quadratic
|
4 |
-
|
5 |
-
# Quadratic Equation Solver Interface
|
6 |
-
def quadratic_solver_wrapper(a, b, c, return_format):
|
7 |
-
result = solve_quadratic(a, b, c, return_format=return_format)
|
8 |
-
if return_format == "dict":
|
9 |
-
if "error" in result:
|
10 |
-
return result["error"]
|
11 |
-
roots = result["roots"]
|
12 |
-
vertex = result["vertex"]
|
13 |
-
output = ""
|
14 |
-
sign_b = "+" if b >= 0 else ""
|
15 |
-
sign_c = "+" if c >= 0 else ""
|
16 |
-
output += f"Equation: {a}x² {sign_b} {b}x {sign_c} {c} = 0\n\n"
|
17 |
-
if roots[1] is None:
|
18 |
-
output += f"Root: {roots[0]}\n"
|
19 |
-
else:
|
20 |
-
output += f"Root 1: {roots[0]}\n"
|
21 |
-
output += f"Root 2: {roots[1]}\n"
|
22 |
-
if vertex:
|
23 |
-
output += f"\nVertex: ({vertex[0]}, {vertex[1]})"
|
24 |
-
return output
|
25 |
-
else:
|
26 |
-
return result
|
27 |
-
|
28 |
-
def plot_quadratic(a, b, c):
|
29 |
-
import numpy as np
|
30 |
-
import matplotlib.pyplot as plt
|
31 |
-
result = solve_quadratic(a, b, c, return_format="dict")
|
32 |
-
vertex_x = -b / (2*a) if a != 0 else 0
|
33 |
-
vertex_y = c - (b**2 / (4*a)) if a != 0 else 0
|
34 |
-
fig, ax = plt.subplots(figsize=(8, 6))
|
35 |
-
if a != 0:
|
36 |
-
if "roots" in result and result["roots"][0] is not None and result["roots"][1] is not None:
|
37 |
-
root1 = result["roots"][0].real if hasattr(result["roots"][0], "real") else float(result["roots"][0])
|
38 |
-
root2 = result["roots"][1].real if hasattr(result["roots"][1], "real") else float(result["roots"][1])
|
39 |
-
x_min = min(root1, root2, vertex_x) - 2
|
40 |
-
x_max = max(root1, root2, vertex_x) + 2
|
41 |
-
else:
|
42 |
-
x_min = vertex_x - 5
|
43 |
-
x_max = vertex_x + 5
|
44 |
-
x = np.linspace(x_min, x_max, 1000)
|
45 |
-
y = a * (x**2) + b * x + c
|
46 |
-
ax.plot(x, y, 'b-', label=f'f(x) = {a}x² + {b}x + {c}')
|
47 |
-
ax.plot(vertex_x, vertex_y, 'ro', label=f'Vertex: ({vertex_x:.2f}, {vertex_y:.2f})')
|
48 |
-
if "roots" in result:
|
49 |
-
roots = result["roots"]
|
50 |
-
if roots[0] is not None and (isinstance(roots[0], (int, float)) or (hasattr(roots[0], "imag") and roots[0].imag == 0)):
|
51 |
-
root1 = float(roots[0].real if hasattr(roots[0], "real") else roots[0])
|
52 |
-
ax.plot(root1, 0, 'go', label=f'Root 1: {root1:.2f}')
|
53 |
-
if roots[1] is not None and (isinstance(roots[1], (int, float)) or (hasattr(roots[1], "imag") and roots[1].imag == 0)):
|
54 |
-
root2 = float(roots[1].real if hasattr(roots[1], "real") else roots[1])
|
55 |
-
ax.plot(root2, 0, 'go', label=f'Root 2: {root2:.2f}')
|
56 |
-
ax.axhline(y=0, color='k', linestyle='-', alpha=0.3)
|
57 |
-
ax.axvline(x=0, color='k', linestyle='-', alpha=0.3)
|
58 |
-
ax.grid(True, alpha=0.3)
|
59 |
-
ax.set_xlabel('x')
|
60 |
-
ax.set_ylabel('f(x)')
|
61 |
-
ax.set_title(f'Graph of f(x) = {a}x² + {b}x + {c}')
|
62 |
-
ax.legend()
|
63 |
-
else:
|
64 |
-
if b != 0:
|
65 |
-
x = np.linspace(-5, 5, 100)
|
66 |
-
y = b * x + c
|
67 |
-
ax.plot(x, y, 'b-', label=f'f(x) = {b}x + {c} (Linear)')
|
68 |
-
root = -c/b
|
69 |
-
ax.plot(root, 0, 'go', label=f'Root: {root:.2f}')
|
70 |
-
ax.axhline(y=0, color='k', linestyle='-', alpha=0.3)
|
71 |
-
ax.axvline(x=0, color='k', linestyle='-', alpha=0.3)
|
72 |
-
ax.grid(True, alpha=0.3)
|
73 |
-
ax.set_xlabel('x')
|
74 |
-
ax.set_ylabel('f(x)')
|
75 |
-
ax.set_title(f'Graph of f(x) = {b}x + {c} (Linear)')
|
76 |
-
ax.legend()
|
77 |
-
else:
|
78 |
-
x = np.linspace(-5, 5, 100)
|
79 |
-
y = c * np.ones_like(x)
|
80 |
-
ax.plot(x, y, 'b-', label=f'f(x) = {c} (Constant)')
|
81 |
-
ax.axhline(y=0, color='k', linestyle='-', alpha=0.3)
|
82 |
-
ax.axvline(x=0, color='k', linestyle='-', alpha=0.3)
|
83 |
-
ax.grid(True, alpha=0.3)
|
84 |
-
ax.set_xlabel('x')
|
85 |
-
ax.set_ylabel('f(x)')
|
86 |
-
ax.set_title(f'Graph of f(x) = {c} (Constant)')
|
87 |
-
ax.legend()
|
88 |
-
return fig
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
maths/geometry/cos_degrees.py
CHANGED
@@ -1,5 +1,14 @@
|
|
1 |
import math
|
|
|
2 |
|
3 |
def cos_degrees(angle):
|
4 |
"""Calculate the cosine of an angle in degrees."""
|
5 |
return math.cos(math.radians(angle))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import math
|
2 |
+
import gradio as gr
|
3 |
|
4 |
def cos_degrees(angle):
|
5 |
"""Calculate the cosine of an angle in degrees."""
|
6 |
return math.cos(math.radians(angle))
|
7 |
+
|
8 |
+
cos_degrees_interface = gr.Interface(
|
9 |
+
fn=cos_degrees,
|
10 |
+
inputs=gr.Number(label="Angle (degrees)"),
|
11 |
+
outputs="number",
|
12 |
+
title="Cosine Calculator",
|
13 |
+
description="Calculate cosine of an angle in degrees."
|
14 |
+
)
|
maths/geometry/geometry_tab.py
CHANGED
@@ -1,9 +1,9 @@
|
|
1 |
import gradio as gr
|
2 |
-
from maths.geometry.
|
3 |
-
|
4 |
-
|
5 |
|
6 |
-
geometry_interfaces_list = [
|
7 |
geometry_tab_names = ["Trig Functions", "Inverse Trig", "Trig Identities"]
|
8 |
|
9 |
geometry_tab = gr.TabbedInterface(geometry_interfaces_list, geometry_tab_names, title="Geometry")
|
|
|
1 |
import gradio as gr
|
2 |
+
from maths.geometry.sin_degrees import sin_degrees_interface
|
3 |
+
from maths.geometry.inverse_trig_functions import inverse_trig_interface
|
4 |
+
from maths.geometry.trig_identities import trig_identities_interface
|
5 |
|
6 |
+
geometry_interfaces_list = [sin_degrees_interface, inverse_trig_interface, trig_identities_interface]
|
7 |
geometry_tab_names = ["Trig Functions", "Inverse Trig", "Trig Identities"]
|
8 |
|
9 |
geometry_tab = gr.TabbedInterface(geometry_interfaces_list, geometry_tab_names, title="Geometry")
|
maths/geometry/inverse_trig_functions.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
import math
|
|
|
2 |
|
3 |
def inverse_trig_functions(value: float, function_name: str) -> str:
|
4 |
"""
|
@@ -29,3 +30,14 @@ def inverse_trig_functions(value: float, function_name: str) -> str:
|
|
29 |
else:
|
30 |
return "Error: Invalid function name. Choose 'asin', 'acos', or 'atan'."
|
31 |
return f"{math.degrees(result_rad):.4f} degrees"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import math
|
2 |
+
import gradio as gr
|
3 |
|
4 |
def inverse_trig_functions(value: float, function_name: str) -> str:
|
5 |
"""
|
|
|
30 |
else:
|
31 |
return "Error: Invalid function name. Choose 'asin', 'acos', or 'atan'."
|
32 |
return f"{math.degrees(result_rad):.4f} degrees"
|
33 |
+
|
34 |
+
inverse_trig_interface = gr.Interface(
|
35 |
+
fn=inverse_trig_functions,
|
36 |
+
inputs=[
|
37 |
+
gr.Number(label="Value"),
|
38 |
+
gr.Radio(["asin", "acos", "atan"], label="Inverse Function")
|
39 |
+
],
|
40 |
+
outputs="text",
|
41 |
+
title="Inverse Trigonometry Calculator",
|
42 |
+
description="Calculate inverse trigonometric functions. Output in degrees."
|
43 |
+
)
|
maths/geometry/sin_degrees.py
CHANGED
@@ -1,5 +1,14 @@
|
|
1 |
import math
|
|
|
2 |
|
3 |
def sin_degrees(angle):
|
4 |
"""Calculate the sine of an angle in degrees."""
|
5 |
return math.sin(math.radians(angle))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import math
|
2 |
+
import gradio as gr
|
3 |
|
4 |
def sin_degrees(angle):
|
5 |
"""Calculate the sine of an angle in degrees."""
|
6 |
return math.sin(math.radians(angle))
|
7 |
+
|
8 |
+
sin_degrees_interface = gr.Interface(
|
9 |
+
fn=sin_degrees,
|
10 |
+
inputs=gr.Number(label="Angle (degrees)"),
|
11 |
+
outputs="number",
|
12 |
+
title="Sine Calculator",
|
13 |
+
description="Calculate sine of an angle in degrees."
|
14 |
+
)
|
maths/geometry/solve_trig_equations.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
import math
|
|
|
2 |
|
3 |
def solve_trig_equations(a: float, b: float, c: float, trig_func: str, interval_degrees: tuple[float, float] = (0, 360)) -> str:
|
4 |
"""
|
@@ -56,3 +57,26 @@ def solve_trig_equations(a: float, b: float, c: float, trig_func: str, interval_
|
|
56 |
if not unique_solutions:
|
57 |
return f"No solutions found for {a}*{func}(x) + {b} = {c} in the interval [{min_interval_deg}, {max_interval_deg}] degrees."
|
58 |
return f"Solutions for x in [{min_interval_deg}, {max_interval_deg}] degrees: {', '.join(unique_solutions)}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import math
|
2 |
+
import gradio as gr
|
3 |
|
4 |
def solve_trig_equations(a: float, b: float, c: float, trig_func: str, interval_degrees: tuple[float, float] = (0, 360)) -> str:
|
5 |
"""
|
|
|
57 |
if not unique_solutions:
|
58 |
return f"No solutions found for {a}*{func}(x) + {b} = {c} in the interval [{min_interval_deg}, {max_interval_deg}] degrees."
|
59 |
return f"Solutions for x in [{min_interval_deg}, {max_interval_deg}] degrees: {', '.join(unique_solutions)}"
|
60 |
+
|
61 |
+
def parse_interval(interval_str: str) -> tuple[float, float]:
|
62 |
+
try:
|
63 |
+
parts = [float(x.strip()) for x in interval_str.split(',')]
|
64 |
+
if len(parts) == 2 and parts[0] <= parts[1]:
|
65 |
+
return parts[0], parts[1]
|
66 |
+
raise ValueError("Interval must be two numbers, min,max.")
|
67 |
+
except Exception:
|
68 |
+
raise gr.Error("Invalid interval format. Use 'min,max' (e.g., '0,360').")
|
69 |
+
|
70 |
+
solve_trig_equations_interface = gr.Interface(
|
71 |
+
fn=lambda a, b, c, func, interval_str: solve_trig_equations(a, b, c, func, parse_interval(interval_str)),
|
72 |
+
inputs=[
|
73 |
+
gr.Number(label="a (coefficient of function)"),
|
74 |
+
gr.Number(label="b (constant added to function part)"),
|
75 |
+
gr.Number(label="c (constant on other side of equation)"),
|
76 |
+
gr.Radio(["sin", "cos", "tan"], label="Trigonometric Function"),
|
77 |
+
gr.Textbox(label="Interval for x (degrees, comma-separated, e.g., 0,360)", value="0,360")
|
78 |
+
],
|
79 |
+
outputs="text",
|
80 |
+
title="Trigonometric Equation Solver",
|
81 |
+
description="Solves equations like a * func(x) + b = c for x in a given interval (degrees)."
|
82 |
+
)
|
maths/geometry/tan_degrees.py
CHANGED
@@ -1,5 +1,14 @@
|
|
1 |
import math
|
|
|
2 |
|
3 |
def tan_degrees(angle):
|
4 |
"""Calculate the tangent of an angle in degrees."""
|
5 |
return math.tan(math.radians(angle))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import math
|
2 |
+
import gradio as gr
|
3 |
|
4 |
def tan_degrees(angle):
|
5 |
"""Calculate the tangent of an angle in degrees."""
|
6 |
return math.tan(math.radians(angle))
|
7 |
+
|
8 |
+
tan_degrees_interface = gr.Interface(
|
9 |
+
fn=tan_degrees,
|
10 |
+
inputs=gr.Number(label="Angle (degrees)"),
|
11 |
+
outputs="number",
|
12 |
+
title="Tangent Calculator",
|
13 |
+
description="Calculate tangent of an angle in degrees."
|
14 |
+
)
|
maths/geometry/trig_identities.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
import math
|
|
|
2 |
|
3 |
def trig_identities(angle_degrees: float, identity_name: str = "pythagorean1") -> str:
|
4 |
"""
|
@@ -51,3 +52,22 @@ def trig_identities(angle_degrees: float, identity_name: str = "pythagorean1") -
|
|
51 |
if not results:
|
52 |
return f"Unknown identity: {identity_name}. Available: pythagorean1, pythagorean2, pythagorean3, all."
|
53 |
return "\n".join(results)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
import math
|
2 |
+
import gradio as gr
|
3 |
|
4 |
def trig_identities(angle_degrees: float, identity_name: str = "pythagorean1") -> str:
|
5 |
"""
|
|
|
52 |
if not results:
|
53 |
return f"Unknown identity: {identity_name}. Available: pythagorean1, pythagorean2, pythagorean3, all."
|
54 |
return "\n".join(results)
|
55 |
+
|
56 |
+
trig_identities_interface = gr.Interface(
|
57 |
+
fn=trig_identities,
|
58 |
+
inputs=[
|
59 |
+
gr.Number(label="Angle (degrees)"),
|
60 |
+
gr.Radio(
|
61 |
+
choices=[
|
62 |
+
("sin²(x) + cos²(x) = 1", "pythagorean1"),
|
63 |
+
("1 + tan²(x) = sec²(x)", "pythagorean2"),
|
64 |
+
("1 + cot²(x) = csc²(x)", "pythagorean3"),
|
65 |
+
("All Pythagorean", "all")
|
66 |
+
],
|
67 |
+
label="Trigonometric Identity to Demonstrate"
|
68 |
+
)
|
69 |
+
],
|
70 |
+
outputs="text",
|
71 |
+
title="Trigonometric Identities Demonstrator",
|
72 |
+
description="Show common trigonometric identities for a given angle."
|
73 |
+
)
|
maths/geometry/trigonometry_interface.py
DELETED
@@ -1,79 +0,0 @@
|
|
1 |
-
import gradio as gr
|
2 |
-
from maths.geometry.sin_degrees import sin_degrees
|
3 |
-
from maths.geometry.cos_degrees import cos_degrees
|
4 |
-
from maths.geometry.tan_degrees import tan_degrees
|
5 |
-
from maths.geometry.inverse_trig_functions import inverse_trig_functions
|
6 |
-
from maths.geometry.solve_trig_equations import solve_trig_equations
|
7 |
-
from maths.geometry.trig_identities import trig_identities
|
8 |
-
|
9 |
-
# High School Math Tab
|
10 |
-
trig_interface = gr.Interface(
|
11 |
-
fn=lambda angle, function: {
|
12 |
-
"sin": sin_degrees(angle),
|
13 |
-
"cos": cos_degrees(angle),
|
14 |
-
"tan": tan_degrees(angle)
|
15 |
-
}[function],
|
16 |
-
inputs=[
|
17 |
-
gr.Number(label="Angle (degrees)"),
|
18 |
-
gr.Radio(["sin", "cos", "tan"], label="Trigonometric Function")
|
19 |
-
],
|
20 |
-
outputs="number",
|
21 |
-
title="Trigonometry Calculator",
|
22 |
-
description="Calculate trigonometric functions for angles in degrees"
|
23 |
-
)
|
24 |
-
|
25 |
-
inverse_trig_interface = gr.Interface(
|
26 |
-
fn=inverse_trig_functions,
|
27 |
-
inputs=[
|
28 |
-
gr.Number(label="Value"),
|
29 |
-
gr.Radio(["asin", "acos", "atan"], label="Inverse Function")
|
30 |
-
],
|
31 |
-
outputs="text",
|
32 |
-
title="Inverse Trigonometry Calculator",
|
33 |
-
description="Calculate inverse trigonometric functions. Output in degrees."
|
34 |
-
)
|
35 |
-
|
36 |
-
def parse_interval(interval_str: str) -> tuple[float, float]:
|
37 |
-
"""Helper to parse comma-separated interval string (e.g., "0,360") into a tuple."""
|
38 |
-
try:
|
39 |
-
parts = [float(x.strip()) for x in interval_str.split(',')]
|
40 |
-
if len(parts) == 2 and parts[0] <= parts[1]:
|
41 |
-
return parts[0], parts[1]
|
42 |
-
raise ValueError("Interval must be two numbers, min,max.")
|
43 |
-
except Exception:
|
44 |
-
# Return a default or raise specific error for Gradio
|
45 |
-
raise gr.Error("Invalid interval format. Use 'min,max' (e.g., '0,360').")
|
46 |
-
|
47 |
-
|
48 |
-
solve_trig_equations_interface = gr.Interface(
|
49 |
-
fn=lambda a, b, c, func, interval_str: solve_trig_equations(a,b,c,func, parse_interval(interval_str)),
|
50 |
-
inputs=[
|
51 |
-
gr.Number(label="a (coefficient of function)"),
|
52 |
-
gr.Number(label="b (constant added to function part)"),
|
53 |
-
gr.Number(label="c (constant on other side of equation)"),
|
54 |
-
gr.Radio(["sin", "cos", "tan"], label="Trigonometric Function"),
|
55 |
-
gr.Textbox(label="Interval for x (degrees, comma-separated, e.g., 0,360)", value="0,360")
|
56 |
-
],
|
57 |
-
outputs="text",
|
58 |
-
title="Trigonometric Equation Solver",
|
59 |
-
description="Solves equations like a * func(x) + b = c for x in a given interval (degrees)."
|
60 |
-
)
|
61 |
-
|
62 |
-
trig_identities_interface = gr.Interface(
|
63 |
-
fn=trig_identities,
|
64 |
-
inputs=[
|
65 |
-
gr.Number(label="Angle (degrees)"),
|
66 |
-
gr.Radio(
|
67 |
-
choices=[
|
68 |
-
("sin²(x) + cos²(x) = 1", "pythagorean1"),
|
69 |
-
("1 + tan²(x) = sec²(x)", "pythagorean2"),
|
70 |
-
("1 + cot²(x) = csc²(x)", "pythagorean3"),
|
71 |
-
("All Pythagorean", "all")
|
72 |
-
],
|
73 |
-
label="Trigonometric Identity to Demonstrate"
|
74 |
-
)
|
75 |
-
],
|
76 |
-
outputs="text",
|
77 |
-
title="Trigonometric Identities Demonstrator",
|
78 |
-
description="Show common trigonometric identities for a given angle."
|
79 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|