spagestic commited on
Commit
4c5b4cf
·
1 Parent(s): 6560704

feat: add Gradio interfaces for trigonometric functions and remove old trigonometry interface

Browse files
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.trigonometry_interface import (
3
- trig_interface, inverse_trig_interface, trig_identities_interface
4
- )
5
 
6
- geometry_interfaces_list = [trig_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")
 
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
- )