W01: From function inputs to executable contracts
On this page
- Prerequisites and observable goals
- The central question: what exactly is being replaced?
- A complete chain: value, average rate, derivative, line
- Why the limit is not merely “set the change to zero”
- From an algebraic identity to a code specification
- Assignment is a transition, not an equation to solve
- Independent practice
- Complete solutions: W01
- Retention and readiness
Prerequisites and observable goals#
M01–M08 and C01: substitution, factoring, limits, derivatives, and program state.
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 does not instruct us to multiply an object by . It names the output obtained by applying the function to an input. A useful mental model is an expression with an input slot. If , the letter is replaceable; the rule, including its parentheses and signs, is not. Therefore
By contrast, 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 and focus on input . The point’s height is
For the nearby input, substitute the whole expression before simplifying:
The output change is the new output minus the entire old output:
The input change is . For ,
This cancellation removes a nonzero factor multiplying the entire numerator and denominator. It does not delete from a sum. Dividing by , for example, would instead give .
The original quotient is undefined at zero. Its simplified formula has a continuous extension there, and the limit is
The derivative is the slope at input 2. The function value is the height at input 2. Neither is automatically the intercept of a line. Starting with a point and slope gives
Substitute the point to check: . Substitute zero to find the intercept: . The tempting line 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 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 , factoring gives only for . The function on all real inputs is not the identical function: its domain includes 3. They agree on the original domain. The limit of at 3 is 6, but 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 , expand before memorizing:
Thus the average rate is for , while the derivative is . The tangent intercept at input is , 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, 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,
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.
For at , derive , 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.
A developer replaces by 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.
For with real constants and , derive the average rate and its difference from . Explain what changes when is negative and why the units of the rate are output units per input unit.
Start with position 1 m, velocity 2 m/s, acceleration m/s, and step 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.
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 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 . Substitution gives
Subtracting gives . For , divide by to obtain . Its limit is , so the tangent satisfies , or . At the line gives , as required; its vertical-axis intercept is , not the point height. Differentiating by the established rules gives and independently confirms . The rule checks the result, but the requested first-principles derivation explains the transition.
Back to W01.01W01.02Show solution
Equality of formulas must specify the domain
The first incorrect claim is agreement on all real inputs. The domain of is ; the domain of is . For , factor and cancel the nonzero factor. Nearby outputs tend to 6, so . That does not make 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.02W01.03Show solution
The finite interval includes a curvature contribution
Expansion and subtraction leave . Division by the nonzero interval yields . Its limit is , and the signed difference is . Negative 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.03W01.04Show solution
A different state dependency defines a different method
Using old values, m and m/s. Velocity-first uses the same new velocity but obtains position m. For constant acceleration, the exact position is 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.04W01.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.
"""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.05Retention and readiness#
Without notes, explain the differences among , , , and . 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.