Foundations to FrontierPart III: Calculus IBezhig

W01: From function inputs to executable contracts

5 exercises, each with a complete solution. 1 code listing.

On this page
  1. Prerequisites and observable goals
  2. The central question: what exactly is being replaced?
  3. A complete chain: value, average rate, derivative, line
  4. Why the limit is not merely “set the change to zero”
  5. From an algebraic identity to a code specification
  6. Assignment is a transition, not an equation to solve
  7. Independent practice
  8. Complete solutions: W01
  9. Retention and readiness

Prerequisites and observable goals#

Before

M01–M08 and C01: substitution, factoring, limits, derivatives, and program state.

After

Translate one object between algebra, geometry, and code; separate a domain restriction from a limiting extension; verify a tangent line and a state update.

The central question: what exactly is being replaced?#

The notation f(x)f(x) does not instruct us to multiply an object ff by xx. It names the output obtained by applying the function to an input. A useful mental model is an expression with an input slot. If f(u)=u2−u−3f(u)=u^2-u-3, the letter uu is replaceable; the rule, including its parentheses and signs, is not. Therefore

f(x+h)=(x+h)2−(x+h)−3.f(x+h)=(x+h)^2-(x+h)-3.

By contrast, f(x)+h=x2−x−3+hf(x)+h=x^2-x-3+h changes an already computed output. These are two different operations: move the input, or move the output. A graph makes the distinction visible. Moving the input travels to another point of the curve; adding to the output shifts vertically at the same input.

A program has an analogous boundary. A function receiving two coordinates is not automatically receiving a velocity, a direction, or an already transformed position. Write the input representation and units before arithmetic. In a game, confusing world position with screen position is the same category of error as confusing an input with its output: the numbers may look plausible while representing different objects.

A complete chain: value, average rate, derivative, line#

Let f(x)=x2−x−3f(x)=x^2-x-3 and focus on input a=2a=2. The point’s height is

f(2)=22−2−3=4−2−3=−1.f(2)=2^2-2-3=4-2-3=-1.

For the nearby input, substitute the whole expression before simplifying:

f(2+h)=(2+h)2−(2+h)−3=4+4h+h2−2−h−3=−1+3h+h2.\begin{align*} f(2+h)&=(2+h)^2-(2+h)-3\\ &=4+4h+h^2-2-h-3=-1+3h+h^2. \end{align*}

The output change is the new output minus the entire old output:

f(2+h)−f(2)=(−1+3h+h2)−(−1)=3h+h2.f(2+h)-f(2)=(-1+3h+h^2)-(-1)=3h+h^2.

The input change is (2+h)−2=h(2+h)-2=h. For h≠0h\ne0,

f(2+h)−f(2)h=h(3+h)h=3+h.\frac{f(2+h)-f(2)}h=\frac{h(3+h)}h=3+h.

This cancellation removes a nonzero factor multiplying the entire numerator and denominator. It does not delete hh from a sum. Dividing 3+h3+h by hh, for example, would instead give 3/h+13/h+1.

The original quotient is undefined at zero. Its simplified formula has a continuous extension there, and the limit is

f′(2)=lim⁡h→0(3+h)=3.f'(2)=\lim_{h\to0}(3+h)=3.

The derivative is the slope at input 2. The function value −1-1 is the height at input 2. Neither is automatically the intercept of a line. Starting with a point and slope gives

y−f(2)=f′(2)(x−2),y+1=3(x−2),y=3x−7.y-f(2)=f'(2)(x-2),\qquad y+1=3(x-2),\qquad y=3x-7.

Substitute the point to check: 3(2)−7=−13(2)-7=-1. Substitute zero to find the intercept: −7-7. The tempting line y=3x−1y=3x-1 has the correct slope but the wrong point, since it gives 5 at input 2. One successful check of slope alone would miss the error.

Why the limit is not merely “set the change to zero”#

The quotient compares two distinct inputs. Its meaning requires a nonzero interval. The derivative describes how those comparisons behave as the interval shrinks. The simplified polynomial 3+h3+h makes the limiting behavior easy to evaluate, but it does not retroactively define the original quotient at zero. Keeping these domains separate is mathematical bookkeeping with a purpose: the same distinction arises when an implementation rejects an input that a mathematically equivalent formula would accept after simplification.

For r(x)=(x2−9)/(x−3)r(x)=(x^2-9)/(x-3), factoring gives r(x)=x+3r(x)=x+3 only for x≠3x\ne3. The function s(x)=x+3s(x)=x+3 on all real inputs is not the identical function: its domain includes 3. They agree on the original domain. The limit of rr at 3 is 6, but r(3)r(3) remains undefined unless we explicitly define a new function. An optimizer, database migration, or API rewrite likewise must say whether it preserves outputs on accepted inputs or changes the accepted inputs themselves.

From an algebraic identity to a code specification#

For q(x)=Ax2+Bx+Cq(x)=Ax^2+Bx+C, expand before memorizing:

q(x+h)−q(x)=A(x2+2xh+h2)+Bx+Bh+C−(Ax2+Bx+C)=2Axh+Ah2+Bh=h(2Ax+Ah+B).\begin{align*} q(x+h)-q(x) &=A(x^2+2xh+h^2)+Bx+Bh+C-(Ax^2+Bx+C)\\ &=2Axh+Ah^2+Bh=h(2Ax+Ah+B). \end{align*}

Thus the average rate is 2Ax+Ah+B2Ax+Ah+B for h≠0h\ne0, while the derivative is 2Ax+B2Ax+B. The tangent intercept at input aa is q(a)−a(2Aa+B)q(a)-a(2Aa+B), obtained by expanding point-slope form. This derivation supplies a specification and an independent implementation check.

The lab uses exact rational arithmetic so that roundoff does not obscure the substitution lesson. A Fraction represents a rational numerator and nonzero denominator; it is not a symbolic expression or an arbitrary real number. Rejecting floating-point inputs is a deliberate educational contract, not a rule that all quadratic libraries should follow. The exact formula avoids subtracting nearly equal approximate outputs, but real-world measurement inputs would still have uncertainty.

Assignment is a transition, not an equation to solve#

In mathematics, x=x+1x=x+1 has no real solution. In Python, x = x + 1 evaluates the right side using the old binding, then assigns a new value to the name on the left. When several state components must use the same old state, compute them before overwriting it. For a particle,

xnew=xold+voldΔt,vnew=vold+aΔtx_{\rm new}=x_{\rm old}+v_{\rm old}\Delta t,\qquad v_{\rm new}=v_{\rm old}+a\Delta t

is one explicit update rule. Updating velocity first and then using it for position defines a different numerical method. Neither should silently be called the same formula. W05 later connects this choice to stability and conservation.

Independent practice#

F foundation C standard course work T transfer S optional stretch L runnable lab or project. Attempt the complete set before opening its solutions.

W01.01CSolution

For g(x)=3x2+2x−4g(x)=3x^2+2x-4 at a=−1a=-1, derive g(a+h)g(a+h), the difference quotient, the derivative, and the tangent line without starting from differentiation rules. Check the required point and distinguish its height from the intercept.

W01.02TSolution

A developer replaces r(x)=(x2−9)/(x−3)r(x)=(x^2-9)/(x-3) by s(x)=x+3s(x)=x+3 and says the functions are identical on all real inputs. Identify the first incorrect claim, give both domains, calculate the limit at 3, and state two possible API contracts for handling input 3.

W01.03CSolution

For q(x)=Ax2+Bx+Cq(x)=Ax^2+Bx+C with real constants and h≠0h\ne0, derive the average rate and its difference from q′(x)q'(x). Explain what changes when hh is negative and why the units of the rate are output units per input unit.

W01.04TSolution

Start with position 1 m, velocity 2 m/s, acceleration −3-3 m/s2^2, and step .1.1 s. Compute one simultaneous-old-state update, then a velocity-first update. Explain why substituting the new velocity produces a different answer and does not establish that either method is an exact solution.

W01.05LSolution

Implement Quadratic in integration_code/starters/calculus_bridge.py. Accept only integers or exact fractions for coefficients and inputs; reject Boolean/float inputs and a zero average-rate interval. Implement value, average rate, and tangent slope/intercept. Test against the unsimplified quotient for several nonzero positive and negative rational intervals.

Optional small hints

For .01, write 3(−1+h)2+2(−1+h)−43(-1+h)^2+2(-1+h)-4 before distributing. For .02, simplifying a formula does not enlarge its original domain automatically. For .04, label every right-hand value “old” or “new.” For the lab, test both tangent conditions: slope and passage through the point.

Complete solutions: W01#

Compare the first step where your work differs. A corrected answer is not yet an independent success.

W01.01Show solution

Substitute, subtract, factor, limit, then locate the line

The given point height is g(−1)=3−2−4=−3g(-1)=3-2-4=-3. Substitution gives

g(−1+h)=3(1−2h+h2)−2+2h−4=−3−4h+3h2.\begin{align*} g(-1+h)&=3(1-2h+h^2)-2+2h-4\\ &=-3-4h+3h^2. \end{align*}

Subtracting g(−1)g(-1) gives (−3−4h+3h2)−(−3)=−4h+3h2(-3-4h+3h^2)-(-3)=-4h+3h^2. For h≠0h\ne0, divide h(−4+3h)h(-4+3h) by hh to obtain −4+3h-4+3h. Its limit is −4-4, so the tangent satisfies y+3=−4(x+1)y+3=-4(x+1), or y=−4x−7y=-4x-7. At x=−1x=-1 the line gives −3-3, as required; its vertical-axis intercept is −7-7, not the point height. Differentiating by the established rules gives g′(x)=6x+2g'(x)=6x+2 and independently confirms g′(−1)=−4g'(-1)=-4. The rule checks the result, but the requested first-principles derivation explains the transition.

Back to W01.01
W01.02Show solution

Equality of formulas must specify the domain

The first incorrect claim is agreement on all real inputs. The domain of rr is R∖{3}\R\setminus\{3\}; the domain of ss is R\R. For x≠3x\ne3, factor (x−3)(x+3)(x-3)(x+3) and cancel the nonzero factor. Nearby outputs tend to 6, so lim⁡x→3r(x)=6\lim_{x\to3}r(x)=6. That does not make r(3)r(3) defined. A compatibility-preserving API could continue rejecting 3 while using the simplified formula elsewhere. A deliberately extended API could define the missing output to be 6 and document the change. Both are coherent; pretending there is no contract change is not.

Back to W01.02
W01.03Show solution

The finite interval includes a curvature contribution

Expansion and subtraction leave h(2Ax+Ah+B)h(2Ax+Ah+B). Division by the nonzero interval yields 2Ax+Ah+B2Ax+Ah+B. Its limit is 2Ax+B2Ax+B, and the signed difference is AhAh. Negative hh uses an input to the left; both numerator and denominator retain their signs, so the same formula applies. It does not turn the quotient into an absolute rate. A change in an output measured in meters divided by an input change measured in seconds is measured in meters per second. The coefficients must carry units compatible with the polynomial; dimensional analysis does not permit adding unlike quantities merely because the symbols fit.

Back to W01.03
W01.04Show solution

A different state dependency defines a different method

Using old values, xnew=1+2(.1)=1.2x_{\rm new}=1+2(.1)=1.2 m and vnew=2−3(.1)=1.7v_{\rm new}=2-3(.1)=1.7 m/s. Velocity-first uses the same new velocity but obtains position 1+1.7(.1)=1.171+1.7(.1)=1.17 m. For constant acceleration, the exact position is 1+2(.1)+12(−3)(.1)2=1.1851+2(.1)+\tfrac12(-3)(.1)^2=1.185 m, lying between these two approximations. The exact velocity is 1.7 m/s. Agreement of velocity alone does not establish exactness of the whole state. Halving the step and studying error is a better test than declaring one answer plausible.

Back to W01.04
W01.05Show solution

Reference implementation and checks

The immutable coefficient object prevents a test from changing the polynomial halfway through a comparison. Each input passes the same exact-type check; Python’s Boolean subtype relationship is explicitly rejected. The average-rate formula is the derived identity, with the original nonzero-interval precondition retained. Tangent construction returns two scalars rather than confusing a function value with an intercept.

integration_code/solutions/calculus_bridge.pyPython
"""W01: exact quadratic rates. Inputs are int or Fraction, not binary floats."""
from dataclasses import dataclass
from fractions import Fraction


def rational(value):
    if type(value) not in (int,Fraction):
        raise TypeError("use an integer or Fraction for this exact lab")
    return Fraction(value)


@dataclass(frozen=True)
class Quadratic:
    a: Fraction
    b: Fraction
    c: Fraction

    def __post_init__(self):
        for key in ('a','b','c'):
            object.__setattr__(self,key,rational(getattr(self,key)))

    def value(self,x):
        x=rational(x)
        return self.a*x*x+self.b*x+self.c

    def average_rate(self,x,h):
        x,h=rational(x),rational(h)
        if h == 0:
            raise ValueError("average rate needs a nonzero interval")
        return (self.value(x+h)-self.value(x))/h

    def tangent(self,x):
        x=rational(x)
        slope=2*self.a*x+self.b
        intercept=self.value(x)-slope*x
        return slope,intercept


if __name__=='__main__':
    f=Quadratic(3,2,-4)
    print('point height:',f.value(-1))
    print('average rate:',f.average_rate(-1,Fraction(1,10)))
    print('tangent slope and intercept:',f.tangent(-1))

Run the integration test suite as described in the companion README. Generated tests compare the simplified rate to separately evaluated output differences, including negative fractions. They also verify the tangent passes through its base point. Shared arithmetic still has a shared implementation dependency on Python’s exact rational operations; this is a selected consistency check, not a proof for all possible programs. The algebra above supplies the general identity.

Back to W01.05

Retention and readiness#

Without notes, explain the differences among f(x+h)f(x+h), f(x)+hf(x)+h, f(a)f(a), and f′(a)f'(a). Reconstruct a tangent from a fresh point/slope pair and reject a wrong intercept by substitution. Advance when the object and the calculation can both be explained; repair a sign or state-order gap before increasing complexity.