Trace argument mapping and scope

A variable’s scope determines where its name is accessible in the code. In Listing 1, the Python function calculate takes 2 input parameters, a and b, and returns a floating-point value. The main function initializes variables a, b, and c, calls calculate, and prints the result.

The comments mark 3 breakpoints (BREAKPOINT 1, BREAKPOINT 2, and BREAKPOINT 3) where the variable values are inspected before the next statement executes.

Listing 1: Functions calculate and main with positional arguments, local variables, and 3 breakpoint comments.
def calculate(a: float, b: float) -> float:
    c: float = 0.0
    result: float = 0.0

    # BREAKPOINT 2
    if c < b + a:
        c = a * 2
        result = -1.0

    # BREAKPOINT 3
    result = a + b + c
    return result


def main() -> None:
    a: float = 2.0
    b: float = 3.0
    c: float = 4.0

    c = calculate(b, a)

    # BREAKPOINT 1
    print(c)


if __name__ == "__main__":
    main()

Complete the following tasks:

  1. Map the 2 arguments in calculate(b, a) to the parameters of calculate. Give each caller value and the corresponding local parameter value.
  2. Complete Table 1. Record the active function and the values visible in that function at each breakpoint. Write not in scope when a listed name is not defined in the active function.
  3. Calculate the value returned by calculate.
  4. Explain why a and b in main remain unchanged while c in main changes.
Table 1: Trace of the active function and its visible values at each breakpoint.
Breakpoint Active function a b c result
BREAKPOINT 2
BREAKPOINT 3
BREAKPOINT 1