graph TD
A[Start: Beam analysis task] --> B{Is the structure well-approximated as 1D beam behavior?}
B -- No --> C[Use a 2D/3D numerical structural method]
B -- Yes --> D{Need closed-form or piecewise equations for review, reuse, or sensitivity?}
D -- Yes --> E[Use SOLVE_BEAM_SYMBOLIC]
D -- No --> F{Need only quick numeric spot checks?}
F -- Yes --> G[Use a simpler numeric check workflow]
F -- No --> E
E --> H{Do assumptions hold: linear elastic, small deflection, suitable boundary idealization?}
H -- Yes --> I[Proceed and interpret reactions + V(x), M(x)]
H -- No --> J[Treat as preliminary and escalate to higher-fidelity modeling]
Beam Symbolic
Overview
Introduction Symbolic beam analysis is the process of deriving exact algebraic expressions for support reactions, shear force, bending moment, rotation (slope), and deflection of a beam under specified loads and boundary conditions. Instead of producing only discrete numerical values at sampled points, symbolic analysis returns piecewise formulas that remain valid over intervals of the beam span. In practical terms, that means an engineer can inspect the full structural response as functions of position x, not just a table of numbers. For background, beam theory is commonly framed through Euler–Bernoulli assumptions, where plane sections remain plane and deflections are relatively small; a concise reference is Euler–Bernoulli beam theory.
In business and engineering workflows, this matters because many decisions depend on understanding where the worst-case response occurs and how it changes when geometry, stiffness, or loads are adjusted. In product design, infrastructure planning, and reliability analysis, teams often begin with conceptual models before moving to detailed finite element analysis. Symbolic models are especially effective in this early-to-mid stage because they preserve physical structure and can be re-parameterized quickly. A single expression for M(x) or v(x) supports rapid “what-if” exploration, design reviews, and hand-check validation against more complex tools.
Boardflare’s category function SOLVE_BEAM_SYMBOLIC wraps the symbeam package so spreadsheet users can define a one-dimensional beam model using support and load arrays, then retrieve closed-form piecewise results. The underlying library is symbeam, which in turn relies on symbolic algebra capabilities from SymPy. This integration allows users to stay in an Excel-first workflow while still leveraging symbolic mechanics methods that are typically available only in Python scripting environments.
Compared with purely numerical calculators, symbolic beam outputs provide three strategic advantages. First, they improve interpretability: equations explicitly show dependence on x, E, I, and load magnitudes. Second, they improve reuse: the same formulas can be evaluated at arbitrary points, embedded in reports, or differentiated/integrated for further checks. Third, they improve traceability: because equilibrium and compatibility are enforced analytically, the resulting expressions are auditable and easier to communicate across disciplines. This is particularly useful where engineering teams must justify assumptions to quality, safety, or procurement stakeholders.
At a conceptual level, beam analysis ties loading to structural response through a hierarchy of derivatives and integrals. Distributed load intensity q(x) drives shear V(x), which drives moment M(x), which drives curvature and deflection. Symbolic methods keep this chain explicit, so users can validate sign conventions, continuity across segments, and support reactions without hiding intermediate logic. When the input model is appropriate for Euler–Bernoulli behavior, symbolic outputs become a high-value bridge between textbook mechanics, spreadsheet-based scenario modeling, and production-grade computational analysis.
When to Use It Use symbolic beam analysis when the job-to-be-done is not just “get an answer,” but “understand the governing relationship.” In organizations that iterate quickly—consulting teams, equipment manufacturers, civil design groups, or R&D units—engineers frequently need to compare multiple concepts with varying spans, support layouts, and load conditions. SOLVE_BEAM_SYMBOLIC is well suited for this because it returns piecewise equations that can be reused across many downstream checks.
One common scenario is conceptual structural sizing. A design team may be evaluating whether a cantilevered bracket, machine rail, or secondary beam can meet deflection limits before committing to expensive CAD/FEA detail. By defining supports (e.g., fixed, pin, roller), point moments, and distributed loads symbolically, the team can derive M(x) and v(x) expressions and immediately inspect how changes in stiffness or load assumptions alter response. This is often faster and clearer than repeatedly exporting discrete outputs from black-box tools.
A second scenario is standards-driven checking where a reviewer needs transparent evidence. In many internal governance processes, analysts must show that reaction sums, bending maxima, and deflection trends follow directly from statics and constitutive relations. Symbolic outputs are naturally reviewable because they expose relationships explicitly. For example, if a support reaction appears as a symbolic expression in terms of load intensity and span, a reviewer can sanity-check proportionality and units quickly. In spreadsheet-heavy organizations, this can materially reduce review cycle time.
A third scenario is parametric studies and sensitivity analysis. Suppose a facilities team compares several retrofit options for a simply supported member carrying mixed loading from equipment and distributed service loads. The team might leave E and I symbolic while testing geometry alternatives, then substitute candidate material and section properties later. With SOLVE_BEAM_SYMBOLIC, the same solved expressions can be evaluated repeatedly for different assumptions, reducing model rewrites and transcription errors.
This category is also useful in education and internal upskilling. Engineering onboarding often requires connecting classical beam formulas to real design workflows. Symbolic outputs help junior engineers see how support conditions and load placement shape piecewise behavior, making it easier to build intuition for shear jumps, moment continuity, and deflection boundary conditions. The function can therefore serve both production calculations and training-oriented verification.
There are also clear cases where symbolic beam analysis is not the best first choice. If the structure is highly nonlinear, exhibits large deformations, includes complex 3D effects, or demands detailed stress concentrations, numerical finite element methods may be more appropriate. Similarly, if a user only needs a quick single-point check with fixed numeric inputs, a simpler closed-form calculator might be faster. The strongest fit for this category is one-dimensional beam behavior with a need for interpretable, reusable expressions across span segments.
How It Works At the theory level, the beam is modeled as a one-dimensional structural member along coordinate x \in [0, L]. External actions include point loads, point moments, and distributed loads. Supports impose boundary constraints and generate reactions. Under Euler–Bernoulli assumptions, the core governing equation is:
E I \frac{d^4 v(x)}{dx^4} = q(x)
where v(x) is transverse deflection, E is Young’s modulus, I is second moment of area, and q(x) is distributed load intensity (sign convention dependent). This relation connects stiffness and loading to deformation through fourth-order behavior.
From this equation, standard field relationships are obtained:
\frac{dV(x)}{dx} = -q(x), \qquad \frac{dM(x)}{dx} = V(x)
and, under common sign conventions,
M(x) = E I \frac{d^2 v(x)}{dx^2}, \qquad \theta(x)=\frac{dv(x)}{dx}
In practice, symbolic solvers integrate piecewise over load-defined segments and solve for integration constants using support and continuity conditions. The result is not a single global polynomial in most realistic cases, but a set of piecewise expressions each valid on a specific interval.
The implementation in this category uses symbeam, which offers beam objects, support definitions, and load insertion methods. Symbolic algebra and simplification are handled via SymPy, enabling exact expressions where possible. Boardflare’s SOLVE_BEAM_SYMBOLIC workflow follows a sequence:
- Parse and normalize inputs from Excel-style arguments.
- Initialize a beam of span
L(numeric or symbolic). - Set stiffness fields (
E,I) over the span. - Add support conditions at specified coordinates.
- Add point loads, moments, and distributed loads.
- Solve equilibrium and compatibility constraints.
- Return reactions plus piecewise V(x) and M(x) expressions.
Support handling is central because boundary conditions determine solvability and constants. A fixed support constrains translation and rotation, typically producing force and moment reactions. Pin and roller supports generally constrain translation while allowing rotation, leading to force reactions without moment restraint. Internal hinges alter continuity constraints and can change the form of piecewise solutions. By explicitly declaring support types in inputs, users map physical boundary behavior into symbolic equations.
Load handling is similarly structured. Point loads create shear discontinuities and slope changes in moment diagrams. Point moments create jumps in moment fields. Distributed loads contribute continuously over intervals, typically increasing polynomial order of local expressions. A symbolic solver accounts for these effects by segmenting the beam at support/load coordinates and enforcing continuity where physically required.
A useful way to understand output is as two linked layers:
- Reaction layer: discrete unknowns solved from global equilibrium and boundary conditions.
- Field layer: piecewise functions for internal actions and, in broader beam formulations, kinematic response.
Even when users initially focus on reactions, field equations are often where design decisions occur because peak demand and serviceability checks depend on shape over x, not only endpoint values.
Assumptions should be treated explicitly. Typical assumptions include linear elasticity, small deflections, prismatic behavior where modeled, and one-dimensional beam action. If real behavior violates these assumptions (e.g., material nonlinearity, shear deformation significance, torsion-coupled response, local buckling), symbolic Euler–Bernoulli results should be considered a screening model and validated with higher-fidelity methods.
From a computational standpoint, symbolic methods trade some runtime for interpretability. As support/load complexity increases, expressions can become large. Still, for common engineering configurations, symbolic outputs remain practical and often offer better auditability than opaque numerical-only pipelines. In cross-functional organizations, this transparency can be as valuable as raw computational speed.
Practical Example Consider a machinery platform beam where an engineering team needs rapid serviceability and load-path insight before final detailing. The member has span L=6\,\text{m}, with a pin at x=0 and a roller at x=6. The beam carries (a) a concentrated equipment load at x=2.5\,\text{m}, (b) a maintenance point moment near the right side from an attached cantilevered fixture, and (c) a uniform distributed dead load over the full span. The team wants equations for shear and moment so they can identify critical locations and communicate behavior in a design review.
Step 1 is model framing. The analyst encodes supports as a 2D array of coordinate/type pairs and loads as typed entries with magnitudes and locations. In Boardflare terms, this maps directly to the supports and loads inputs of SOLVE_BEAM_SYMBOLIC. At this stage, the team can use numeric stiffness values for direct deflection interpretation or keep E and I symbolic to preserve parametric flexibility.
Step 2 is stiffness definition. If section selection is undecided, the analyst sets young_modulus="E" and inertia="I" so results keep material/section dependencies explicit. This is valuable when procurement is evaluating alternative steel grades or section catalogs. If the section is already selected, actual values can be passed and deflection-related expressions will evaluate numerically.
Step 3 is solving and extraction. Running SOLVE_BEAM_SYMBOLIC returns two core artifacts:
- Reactions table: force/moment reactions at support points.
- Equations table: piecewise spans with corresponding V(x) and M(x) expressions.
Step 4 is engineering interpretation. The analyst inspects where shear changes sign and where moment extrema appear. Because expressions are piecewise, critical points are checked both at segment boundaries and at interior stationary points. For serviceability-oriented projects, this step feeds into slope/deflection interpretation in extended workflows.
Step 5 is scenario iteration. Suppose operations requests a heavier machine option and a shifted equipment location. Instead of rebuilding a model from scratch, the analyst modifies load entries and re-solves. If E and I were left symbolic, section alternatives can be compared quickly by substitution. This enables a short cycle from request to decision memo.
Step 6 is communication and governance. The team includes symbolic expressions in the review package, alongside selected evaluated points and envelope plots generated externally if needed. Reviewers can trace each term to an input load/support assumption, reducing ambiguity. In many organizations this traceability is crucial for sign-off quality.
A practical advantage over ad-hoc spreadsheets is consistency under mixed loading. Manual spreadsheets often treat point and distributed loads in separate formula blocks, which can introduce brittle logic around discontinuities. By using a symbolic engine, segmentation and continuity are handled systematically, reducing risk of hidden formula mistakes.
The same workflow also supports educational quality checks. Senior engineers can compare solver output against simplified hand-derived cases (e.g., pure UDL, single point load) to validate sign conventions and boundary conditions before introducing more complex load combinations. This creates a reliable pattern for both training and production.
For teams migrating from legacy spreadsheets, a recommended adoption pattern is incremental:
- Recreate one known benchmark case in SOLVE_BEAM_SYMBOLIC.
- Confirm reactions and diagram trends match approved references.
- Introduce symbolic parameters for uncertain design variables.
- Build a reusable template for recurring beam families.
This approach captures the benefits of symbolic mechanics without forcing a disruptive toolchain change.
How to Choose This category currently exposes one function, SOLVE_BEAM_SYMBOLIC, so the selection question is primarily about fit to problem type rather than choosing among multiple near-identical APIs. A useful decision framework is: choose this function when the structure is a 1D beam and the user needs explicit equations, not just point estimates.
The table below provides a practical decision guide.
| Need | Use SOLVE_BEAM_SYMBOLIC? | Why |
|---|---|---|
| Closed-form reactions and piecewise internal-force equations | Yes | Function is designed to output symbolic reactions plus V(x) and M(x) by span segment. |
| Excel-centric workflow with Python-backed symbolic engine | Yes | Input style is spreadsheet-friendly, while computation leverages symbeam/SymPy under the hood. |
| Rapid parametric studies with symbolic E and I | Yes | Symbolic stiffness inputs preserve variable dependence for later substitution. |
| Highly nonlinear, 3D, or large-deformation behavior | No (screening only) | Euler–Bernoulli symbolic model may be insufficient; use higher-fidelity numerical tools for final validation. |
| Need only one fixed numeric check at a single point | Maybe | Symbolic output still works, but a simpler numeric calculator could be faster if interpretability is not required. |
For operational use, the following decision tree helps teams determine whether SOLVE_BEAM_SYMBOLIC is the right first step.
Even in a single-function category, “how to choose” still includes how to configure. Effective use of SOLVE_BEAM_SYMBOLIC depends on four configuration choices:
- Boundary realism: Map supports to physical restraint behavior correctly (
fixed,pin,roller,hinge). - Load representation: Encode point, moment, and distributed loads with consistent sign and coordinates.
- Stiffness strategy: Keep
EandIsymbolic for sensitivity work, numeric for direct magnitude outputs. - Validation level: Decide whether the result is for concept screening, design iteration, or formal verification support.
Pros of this function include transparent equations, strong auditability, and straightforward scenario updates. Constraints include assumption sensitivity and potential expression complexity for heavily segmented models. As a result, an effective practice is to treat symbolic output as both a design engine and a validation layer: it can generate primary results and independently cross-check numerical tools.
In summary, the category choice is simple and deliberate: when the engineering task benefits from explicit beam-response equations in an Excel-accessible workflow, use SOLVE_BEAM_SYMBOLIC. When geometry/physics exceed one-dimensional linear-beam assumptions, retain it as a fast screening and communication tool, then transition to richer numerical analysis for final decisions.
SOLVE_BEAM_SYMBOLIC
Solves a one-dimensional beam model with symbolic or numeric inputs and returns closed-form expressions for reactions together with the piecewise shear-force and bending-moment equations over each span segment. The implementation uses symbeam to assemble supports, loads, and stiffness properties, then calls the symbolic solver.
The solver enforces static equilibrium and constitutive compatibility to produce piecewise fields. In symbolic form, these satisfy the standard beam differential relation E I \frac{d^4 v(x)}{dx^4} = q(x) together with support and continuity boundary conditions.
Excel Usage
=SOLVE_BEAM_SYMBOLIC(span, supports, loads, young_modulus, inertia)
span(str, required): Length of the beam (m or symbolic string).supports(list[list], required): 2D array of support definitions [[x, type]]. x: position. type: “fixed”, “pin”, “roller”, “hinge”.loads(list[list], required): 2D array of load definitions [[type, val, x1, x2]]. type: “point”, “moment”, “dist”. val: magnitude or expression. x1, x2: coordinates.young_modulus(str, optional, default: “E”): Young’s Modulus E (Pa or symbol). Default is ‘E’.inertia(str, optional, default: “I”): Second moment of area I (m4 or symbol). Default is ‘I’.
Returns (dict): Excel data type containing symbolic reactions and piecewise shear-force and bending-moment equations.
Example 1: Cantilever beam with no applied load
Inputs:
| span | supports | loads | young_modulus | inertia | |||
|---|---|---|---|---|---|---|---|
| 1 | 0 | fixed | point | 0 | 1 | 200000000000 | 0.00001 |
Excel formula:
=SOLVE_BEAM_SYMBOLIC(1, {0,"fixed"}, {"point",0,1}, 200000000000, 0.00001)
Expected output:
{"type":"Double","basicValue":2,"properties":{"Reactions":{"type":"Array","elements":[[{"type":"String","basicValue":"Point"},{"type":"String","basicValue":"Type"},{"type":"String","basicValue":"Expression"}],[{"type":"String","basicValue":"0"},{"type":"String","basicValue":"Force"},{"type":"String","basicValue":"0"}],[{"type":"String","basicValue":"0"},{"type":"String","basicValue":"Moment"},{"type":"String","basicValue":"0"}]]},"Equations":{"type":"Array","elements":[[{"type":"String","basicValue":"Span"},{"type":"String","basicValue":"Field"},{"type":"String","basicValue":"Expression"}],[{"type":"String","basicValue":"[0, 1.00000000000000]"},{"type":"String","basicValue":"V(x)"},{"type":"String","basicValue":"0"}],[{"type":"String","basicValue":"[0, 1.00000000000000]"},{"type":"String","basicValue":"M(x)"},{"type":"String","basicValue":"0"}]]}}}
Example 2: Cantilever beam with zero point load at free end
Inputs:
| span | supports | loads | young_modulus | inertia | |||
|---|---|---|---|---|---|---|---|
| 2 | 0 | fixed | point | 0 | 2 | 200000000000 | 0.00001 |
Excel formula:
=SOLVE_BEAM_SYMBOLIC(2, {0,"fixed"}, {"point",0,2}, 200000000000, 0.00001)
Expected output:
{"type":"Double","basicValue":2,"properties":{"Reactions":{"type":"Array","elements":[[{"type":"String","basicValue":"Point"},{"type":"String","basicValue":"Type"},{"type":"String","basicValue":"Expression"}],[{"type":"String","basicValue":"0"},{"type":"String","basicValue":"Force"},{"type":"String","basicValue":"0"}],[{"type":"String","basicValue":"0"},{"type":"String","basicValue":"Moment"},{"type":"String","basicValue":"0"}]]},"Equations":{"type":"Array","elements":[[{"type":"String","basicValue":"Span"},{"type":"String","basicValue":"Field"},{"type":"String","basicValue":"Expression"}],[{"type":"String","basicValue":"[0, 2.00000000000000]"},{"type":"String","basicValue":"V(x)"},{"type":"String","basicValue":"0"}],[{"type":"String","basicValue":"[0, 2.00000000000000]"},{"type":"String","basicValue":"M(x)"},{"type":"String","basicValue":"0"}]]}}}
Example 3: Cantilever beam with zero end moment
Inputs:
| span | supports | loads | young_modulus | inertia | |||
|---|---|---|---|---|---|---|---|
| 2 | 0 | fixed | moment | 0 | 2 | 200000000000 | 0.00001 |
Excel formula:
=SOLVE_BEAM_SYMBOLIC(2, {0,"fixed"}, {"moment",0,2}, 200000000000, 0.00001)
Expected output:
{"type":"Double","basicValue":2,"properties":{"Reactions":{"type":"Array","elements":[[{"type":"String","basicValue":"Point"},{"type":"String","basicValue":"Type"},{"type":"String","basicValue":"Expression"}],[{"type":"String","basicValue":"0"},{"type":"String","basicValue":"Force"},{"type":"String","basicValue":"0"}],[{"type":"String","basicValue":"0"},{"type":"String","basicValue":"Moment"},{"type":"String","basicValue":"0"}]]},"Equations":{"type":"Array","elements":[[{"type":"String","basicValue":"Span"},{"type":"String","basicValue":"Field"},{"type":"String","basicValue":"Expression"}],[{"type":"String","basicValue":"[0, 2.00000000000000]"},{"type":"String","basicValue":"V(x)"},{"type":"String","basicValue":"0"}],[{"type":"String","basicValue":"[0, 2.00000000000000]"},{"type":"String","basicValue":"M(x)"},{"type":"String","basicValue":"0"}]]}}}
Example 4: Cantilever beam with zero distributed load
Inputs:
| span | supports | loads | young_modulus | inertia | ||||
|---|---|---|---|---|---|---|---|---|
| 2 | 0 | fixed | dist | 0 | 0 | 2 | 200000000000 | 0.00001 |
Excel formula:
=SOLVE_BEAM_SYMBOLIC(2, {0,"fixed"}, {"dist",0,0,2}, 200000000000, 0.00001)
Expected output:
{"type":"Double","basicValue":2,"properties":{"Reactions":{"type":"Array","elements":[[{"type":"String","basicValue":"Point"},{"type":"String","basicValue":"Type"},{"type":"String","basicValue":"Expression"}],[{"type":"String","basicValue":"0"},{"type":"String","basicValue":"Force"},{"type":"String","basicValue":"0"}],[{"type":"String","basicValue":"0"},{"type":"String","basicValue":"Moment"},{"type":"String","basicValue":"0"}]]},"Equations":{"type":"Array","elements":[[{"type":"String","basicValue":"Span"},{"type":"String","basicValue":"Field"},{"type":"String","basicValue":"Expression"}],[{"type":"String","basicValue":"[0, 2.00000000000000]"},{"type":"String","basicValue":"V(x)"},{"type":"String","basicValue":"0"}],[{"type":"String","basicValue":"[0, 2.00000000000000]"},{"type":"String","basicValue":"M(x)"},{"type":"String","basicValue":"0"}]]}}}
Python Code
Show Code
from symbeam import beam
def solve_beam_symbolic(span, supports, loads, young_modulus='E', inertia='I'):
"""
Solve a statically determinate beam symbolically and return reactions plus internal-force equations.
See: https://github.com/amcc1996/symbeam
This example function is provided as-is without any representation of accuracy.
Args:
span (str): Length of the beam (m or symbolic string).
supports (list[list]): 2D array of support definitions [[x, type]].
x: position.
type: "fixed", "pin", "roller", "hinge".
loads (list[list]): 2D array of load definitions [[type, val, x1, x2]].
type: "point", "moment", "dist".
val: magnitude or expression.
x1, x2: coordinates.
young_modulus (str, optional): Young's Modulus E (Pa or symbol). Default is 'E'. Default is 'E'.
inertia (str, optional): Second moment of area I (m4 or symbol). Default is 'I'. Default is 'I'.
Returns:
dict: Excel data type containing symbolic reactions and piecewise shear-force and bending-moment equations.
"""
try:
def to2d(value):
if not isinstance(value, list):
return [[value]]
if value and not any(isinstance(row, list) for row in value):
return [value]
return value
def to_text(value):
return str(value)
def to_float_or_raw(value):
try:
return float(value)
except (TypeError, ValueError):
return value
span_value = to_float_or_raw(span)
b = beam(span_value)
supports = to2d(supports)
loads = to2d(loads)
if not isinstance(supports, list) or not all(isinstance(row, list) for row in supports):
return "Error: supports must be a 2D list"
if not isinstance(loads, list) or not all(isinstance(row, list) for row in loads):
return "Error: loads must be a 2D list"
b.set_young(0, span_value, to_float_or_raw(young_modulus))
b.set_inertia(0, span_value, to_float_or_raw(inertia))
for row in supports:
if len(row) < 2:
continue
pos = to_float_or_raw(row[0])
support_type = str(row[1]).lower()
b.add_support(pos, support_type)
for row in loads:
if len(row) < 3:
continue
load_type = str(row[0]).lower()
value = to_float_or_raw(row[1])
x_one = to_float_or_raw(row[2])
x_two = to_float_or_raw(row[3]) if len(row) > 3 else None
if load_type == "point":
b.add_point_load(x_one, value)
elif load_type == "moment":
b.add_point_moment(x_one, value)
elif load_type in ("dist", "udl", "distributed"):
if x_two is None:
return "Error: distributed load requires both x1 and x2"
b.add_distributed_load(x_one, x_two, value)
b.solve(output=False)
reactions = []
for point in b.points:
if point.has_reaction_force():
reactions.append([to_text(point.x_coord), "Force", to_text(point.reaction_force)])
if point.has_reaction_moment():
reactions.append([to_text(point.x_coord), "Moment", to_text(point.reaction_moment)])
equations = []
for segment in b.segments:
span_label = f"[{to_text(segment.x_start)}, {to_text(segment.x_end)}]"
equations.append([span_label, "V(x)", to_text(segment.shear_force)])
equations.append([span_label, "M(x)", to_text(segment.bending_moment)])
return {
"type": "Double",
"basicValue": float(len(reactions)),
"properties": {
"Reactions": {
"type": "Array",
"elements": [
[
{"type": "String", "basicValue": "Point"},
{"type": "String", "basicValue": "Type"},
{"type": "String", "basicValue": "Expression"}
]
] + [
[{"type": "String", "basicValue": cell} for cell in row] for row in reactions
]
},
"Equations": {
"type": "Array",
"elements": [
[
{"type": "String", "basicValue": "Span"},
{"type": "String", "basicValue": "Field"},
{"type": "String", "basicValue": "Expression"}
]
] + [
[{"type": "String", "basicValue": cell} for cell in row] for row in equations
]
}
}
}
except Exception as e:
return f"Error: {str(e)}"Online Calculator