Functions

Mathematical functions are rules for turning given inputs into specific outputs. For example,

\[ f(x) = x^2 \]

maps the input 4 to the output 16 and the input 9 to the output 81. Python functions are similar: they take in inputs, do specified computation, and give back outputs. Programming tasks that need to be done repeatedly, but with different inputs, are best formulated as functions.

Avoid Copy + Paste

Functions make it possible to reuse the same piece of code many times. If you find yourself copying and pasting the same chunk of code repeatedly, consider writing a function instead. This will save you time and make it easy to globally update the behavior of the reused chunk of code if needed.

Defining Functions

Python functions are defined with a block of code that has three main parts:

  1. the signature,

  2. an optional docstring, and

  3. the body.

The following code defines a function named circle_area() for computing the area of a circle,

\[ A = \pi r^2, \]

given a radius \(r\) (using the first six digits of \(\pi\)).

def circle_area(radius):
    """Compute the area of the circle with the given radius: A = π r^2."""
    return 3.14159 * radius**2
def circle_area(radius):
    """Compute the area of the circle with the given radius: A = π r^2."""
    return 3.14159 * radius**2
def circle_area(radius):
    """Compute the area of the circle with the given radius: A = π r^2."""
    return 3.14159 * radius**2

Signature

The function signature defines the name of the function and its inputs.

  • The keyword def begins the definition of the function.

  • The word following def is the name of the function. Function names must follow the same rules as variable names: start with a letter and use only letters, numbers, and underscores.

  • Immediately after the function name, parentheses ( and ) enclose the function parameters, the inputs. Functions can have one or many inputs, or none at all. Parameters are temporary variables within the function body.

  • The colon : marks the end of the function signature.

The circle_area() function has a single parameter, radius.

Lines after the signature that are indented with four spaces form the rest of the function definition. Code that is unindented is no longer part of the function definition.

Docstring

If the first line after the signature is a triple-quoted string, it is called the docstring. The docstring gives human-readable instructions and context about the function, its inputs, and its outputs. Like comments, docstrings do not affect the actual execution of the function.

Because circle_area() is quite simple, a single-line description suffices as the docstring.

Write Quality Docstrings

Clear, readable docstrings are extremely important if you want anyone (including your future self) to be able to read or use your code. When you define a function, always write at least a short docstring describing what the function does.

Body

The function body is everything after the docstring until the indentation goes back to the same level as def. The body of the function can be several lines long and is where the action happens. Within the body, the function parameters are available as temporary variables.

The body usually ends with a return statement which indicates the function output or outputs. If a function does not have a return statement, Python treats it as if the body ended in the line return None. The constant None is a placeholder indicating “no value.”

The body of circle_area() consists of a single line, the return statement. In this case, the area \(\pi r^2\) is computed as a float, and this float is the function output.

More Examples

def cone_volume(baseradius, height):
    """Compute the volume of the cone of the given radius and height.

    Parameters
    ----------
    baseradius : float
        Radius of the circular base of the cone.
    height : float
        Height of the cone, the distance from the circular base to the point.

    Returns
    -------
    volume : float
        Volume of the specified cone.
    """
    return 3.14159 * baseradius**2 * height / 3

This block defines a function named cone_volume() with two parameters: baseradius and height.

def cone_volume(baseradius, height):
    """Compute the volume of the cone of the given radius and height.

    Parameters
    ----------
    baseradius : float
        Radius of the circular base of the cone.
    height : float
        Height of the cone, the distance from the circular base to the point.

    Returns
    -------
    volume : float
        Volume of the specified cone.
    """
    return 3.14159 * baseradius**2 * height / 3

The docstring is several lines long and includes sections describing the inputs and outputs and their expected data types (float).

def cone_volume(baseradius, height):
    """Compute the volume of the cone of the given radius and height.

    Parameters
    ----------
    baseradius : float
        Radius of the circular base of the cone.
    height : float
        Height of the cone, the distance from the circular base to the point.

    Returns
    -------
    volume : float
        Volume of the specified cone.
    """
    return 3.14159 * baseradius**2 * height / 3

The body is a single line consisting of the return statement.

def exclaim():
    """Print a very long word forward and backward."""
    print("supercalifragilisticexpialidocious!")
    print("suoicodilaipxecitsiligarfilacrepus?")

This block defines a function named exclaim(), which does not have any parameters.

def exclaim():
    """Print a very long word forward and backward."""
    print("supercalifragilisticexpialidocious!")
    print("suoicodilaipxecitsiligarfilacrepus?")

The docstring is a brief one-line description.

def exclaim():
    """Print a very long word forward and backward."""
    print("supercalifragilisticexpialidocious!")
    print("suoicodilaipxecitsiligarfilacrepus?")

The body is two lines long and does not contain a return statement, so the function always returns None.

Calling Functions

After a function has been defined, it can be used by writing the function name followed by parentheses ( and ) around a comma-separated list of arguments to match the function parameters. This is referred to as calling the function. The arguments are temporarily assigned to the parameters each time the function is used. The values in the return statement are then returned and can be stored as variables.

# Call circle_area(). The parameter `radius` is assigned to the argument value 1.
area1 = circle_area(1)
print(area1)

# Call circle_area(). The parameter `radius` is assigned to the argument value 10.
area10 = circle_area(10)
print(area10)
3.14159
314.159

If a function has no parameters, it is called with (), without any arguments.

# Call exclaim() twice.
a = exclaim()
b = exclaim()

# The return value of exclaim() is None.
print(a)
supercalifragilisticexpialidocious!
suoicodilaipxecitsiligarfilacrepus?
supercalifragilisticexpialidocious!
suoicodilaipxecitsiligarfilacrepus?
None

Problem 2

For \(0 < x \le 2\), the natural logarithm \(\ln(x)\) can be written as the infinite series

\[\begin{split} \begin{aligned} \ln(x) &= \sum_{n=1}^{\infty} \frac{(-1)^{n-1}}{n}(x - 1)^n \\ &= (x - 1) - \frac{1}{2}(x - 1)^2 + \frac{1}{3}(x - 1)^3 - \frac{1}{4}(x - 1)^4 + \cdots \end{aligned} \end{split}\]

This is called the Taylor series for \(\ln(x)\) centered around \(x = 1\). Although a computer cannot add up infinitely many numbers (it would take infinitely many computations), the sum can be approximated by adding together the first several terms.

Write a function named natural_log() that accepts a float representing \(x\) and returns an estimate for \(\ln(x)\) using the first 5 terms of the above series. That is, natural_log(x) should return the number

\[ % \sum_{n=1}^{5}\frac{(-1)^{n-1}}{n}(x - 1)^n = (x - 1) - \frac{1}{2}(x - 1)^2 + \frac{1}{3}(x - 1)^3 - \frac{1}{4}(x - 1)^4 + \frac{1}{5}(x - 1)^5, \]

which will be close to the true value of \(\ln(x)\) if \(x\) is near \(1\). Include a brief docstring describing the function.

Spelling Matters

The functions in this and the following problems must be named exactly as described, otherwise the autograder will not be able to find and test them.

Test Cases

To test your function, call it with a few different input values using the following code and compare the results to those listed below.

print(natural_log(0.8))
print(natural_log(1.0))
print(natural_log(1.2))
-0.22313066666666664
0.0
0.18233066666666664

Spot Checks Don’t Guarantee Correctness

This test is only a spot check! Matching given outputs does not guarantee that the function always returns the right result for every possible input. However, if the outputs do not match (or if calling the function raises an error), this indicates that something is wrong with the function definition or the arguments being used.

Scope

Parameters are temporary variables that are only available within the body of a function definition.

def identity(my_parameter):
    return my_parameter


# Don't treat a parameter like a variable outside of the function definition.
identity(5)
print(my_parameter)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[4], line 7
      3 
      4 
      5 # Don't treat a parameter like a variable outside of the function definition.
      6 identity(5)
----> 7 print(my_parameter)

NameError: name 'my_parameter' is not defined

Likewise, any variables defined within a function are not available outside of the function definition.

def find_meaning():
    purpose = 42


# Variables defined in a function body are not available elsewhere.
find_meaning()
print(purpose)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[5], line 7
      3 
      4 
      5 # Variables defined in a function body are not available elsewhere.
      6 find_meaning()
----> 7 print(purpose)

NameError: name 'purpose' is not defined

On the other hand, variables that are defined outside of all function definitions are called global variables and can be used within a function definition.

phi = 1.61803398875


def how_close_to_golden(a, b):
    """Compute how close a/b is to the golden ratio."""
    return (a / b) - phi  # phi can be used here.


print(how_close_to_golden(144, 89))
-5.646066011233408e-05

Quick Check

The following code has an error in it. What is the problem?

def portion(a, b):
    total = a + b
    return a / total


c = portion(3, 5)
print(c)
print(total)
Answer

The variable total is defined in the function body of portion(), so it is a local variable that is not available outside of the function definition. This results in a NameError on the final line because the program cannot find a variable named total.

Functions can call other functions in the body of their definition. Consider again cone_volume(), a function for computing the formula

\[ V = \frac{1}{3}\pi r^2 h. \]

Since circle_area() is a function used to compute \(\pi r^2\), the definition of cone_volume() can be modified to use circle_area() for that computation (the docstring is omitted below for brevity).

def cone_volume(baseradius, height):
    return 3.14159 * baseradius**2 * height / 3

This is the definition from earlier.

def cone_volume(baseradius, height):
    return circle_area(baseradius) * height / 3

This calls circle_area() with baseradius as the argument corresponding to the parameter radius.

With the call, if circle_area() is altered to use a better approximation for \(\pi\), the new approximation is automatically used in cone_volume().

Evaluation Order

Consider a function for calculating the area of a disc (a circle with a hole in it) that uses circle_area() twice in its definition. Click through the tabs to see how the program reads and executes the code.

def circle_area(radius):
    """Compute the area of the circle with the given radius: A = π r^2."""
    return 3.14159 * radius**2


def disc_area(inner_radius, outer_radius):
    """Compute the area of a disc, the region between two circles with the same
    center but different radii.

    Parameters
    ----------
    inner_radius : float
        Inner disc radius, the distance from the center to the start of the disc.
    outer_radius : float
        Outer disc radius, the distance from the center to the end of the disc.

    Returns
    -------
    area : float
        Area of the specified disc.
    """
    smaller_circle_area = circle_area(inner_radius)
    larger_circle_area = circle_area(outer_radius)
    return larger_circle_area - smaller_circle_area


print(disc_area(3, 5))

Python reads the function definitions.

def circle_area(radius):
    """Compute the area of the circle with the given radius: A = π r^2."""
    return 3.14159 * radius**2


def disc_area(inner_radius, outer_radius):
    """Compute the area of a disc, the region between two circles with the same
    center but different radii.

    Parameters
    ----------
    inner_radius : float
        Inner disc radius, the distance from the center to the start of the disc.
    outer_radius : float
        Outer disc radius, the distance from the center to the end of the disc.

    Returns
    -------
    area : float
        Area of the specified disc.
    """
    smaller_circle_area = circle_area(inner_radius)
    larger_circle_area = circle_area(outer_radius)
    return larger_circle_area - smaller_circle_area


print(disc_area(3, 5))

The next line is executed, starting with the call disc_area(3, 5).

def circle_area(radius):
    """Compute the area of the circle with the given radius: A = π r^2."""
    return 3.14159 * radius**2


def disc_area(inner_radius, outer_radius):
    """Compute the area of a disc, the region between two circles with the same
    center but different radii.

    Parameters
    ----------
    inner_radius : float
        Inner disc radius, the distance from the center to the start of the disc.
    outer_radius : float
        Outer disc radius, the distance from the center to the end of the disc.

    Returns
    -------
    area : float
        Area of the specified disc.
    """
    smaller_circle_area = circle_area(inner_radius)
    larger_circle_area = circle_area(outer_radius)
    return larger_circle_area - smaller_circle_area


print(disc_area(3, 5))

The call disc_area(3, 5) causes the program to jump back to the function definition for disc_area() and assign inner_radius = 3 and outer_radius = 5 for the duration of the function body.

def circle_area(radius):
    """Compute the area of the circle with the given radius: A = π r^2."""
    return 3.14159 * radius**2


def disc_area(inner_radius, outer_radius):
    """Compute the area of a disc, the region between two circles with the same
    center but different radii.

    Parameters
    ----------
    inner_radius : float
        Inner disc radius, the distance from the center to the start of the disc.
    outer_radius : float
        Outer disc radius, the distance from the center to the end of the disc.

    Returns
    -------
    area : float
        Area of the specified disc.
    """
    smaller_circle_area = circle_area(inner_radius)
    larger_circle_area = circle_area(outer_radius)
    return larger_circle_area - smaller_circle_area


print(disc_area(3, 5))

The first line of the function body is executed, starting with the call circle_area(inner_radius).

def circle_area(radius):
    """Compute the area of the circle with the given radius: A = π r^2."""
    return 3.14159 * radius**2


def disc_area(inner_radius, outer_radius):
    """Compute the area of a disc, the region between two circles with the same
    center but different radii.

    Parameters
    ----------
    inner_radius : float
        Inner disc radius, the distance from the center to the start of the disc.
    outer_radius : float
        Outer disc radius, the distance from the center to the end of the disc.

    Returns
    -------
    area : float
        Area of the specified disc.
    """
    smaller_circle_area = circle_area(inner_radius)
    larger_circle_area = circle_area(outer_radius)
    return larger_circle_area - smaller_circle_area


print(disc_area(3, 5))

The call circle_area(inner_radius) causes the program to jump back to the function definition for circle_area() and assign radius = inner_radius for the duration of the function body.

def circle_area(radius):
    """Compute the area of the circle with the given radius: A = π r^2."""
    return 3.14159 * radius**2


def disc_area(inner_radius, outer_radius):
    """Compute the area of a disc, the region between two circles with the same
    center but different radii.

    Parameters
    ----------
    inner_radius : float
        Inner disc radius, the distance from the center to the start of the disc.
    outer_radius : float
        Outer disc radius, the distance from the center to the end of the disc.

    Returns
    -------
    area : float
        Area of the specified disc.
    """
    smaller_circle_area = circle_area(inner_radius)
    larger_circle_area = circle_area(outer_radius)
    return larger_circle_area - smaller_circle_area


print(disc_area(3, 5))

The first line of the function body is executed, returning the value of 3.14159 * radius**2.

def circle_area(radius):
    """Compute the area of the circle with the given radius: A = π r^2."""
    return 3.14159 * radius**2


def disc_area(inner_radius, outer_radius):
    """Compute the area of a disc, the region between two circles with the same
    center but different radii.

    Parameters
    ----------
    inner_radius : float
        Inner disc radius, the distance from the center to the start of the disc.
    outer_radius : float
        Outer disc radius, the distance from the center to the end of the disc.

    Returns
    -------
    area : float
        Area of the specified disc.
    """
    smaller_circle_area = circle_area(inner_radius)
    larger_circle_area = circle_area(outer_radius)
    return larger_circle_area - smaller_circle_area


print(disc_area(3, 5))

The program returns to the line it was executing when circle_area(inner_radius) was called. The value returned by the call is stored as a variable.

def circle_area(radius):
    """Compute the area of the circle with the given radius: A = π r^2."""
    return 3.14159 * radius**2


def disc_area(inner_radius, outer_radius):
    """Compute the area of a disc, the region between two circles with the same
    center but different radii.

    Parameters
    ----------
    inner_radius : float
        Inner disc radius, the distance from the center to the start of the disc.
    outer_radius : float
        Outer disc radius, the distance from the center to the end of the disc.

    Returns
    -------
    area : float
        Area of the specified disc.
    """
    smaller_circle_area = circle_area(inner_radius)
    larger_circle_area = circle_area(outer_radius)
    return larger_circle_area - smaller_circle_area


print(disc_area(3, 5))

The next line of the function body is executed, starting with the call circle_area(outer_radius).

def circle_area(radius):
    """Compute the area of the circle with the given radius: A = π r^2."""
    return 3.14159 * radius**2


def disc_area(inner_radius, outer_radius):
    """Compute the area of a disc, the region between two circles with the same
    center but different radii.

    Parameters
    ----------
    inner_radius : float
        Inner disc radius, the distance from the center to the start of the disc.
    outer_radius : float
        Outer disc radius, the distance from the center to the end of the disc.

    Returns
    -------
    area : float
        Area of the specified disc.
    """
    smaller_circle_area = circle_area(inner_radius)
    larger_circle_area = circle_area(outer_radius)
    return larger_circle_area - smaller_circle_area


print(disc_area(3, 5))

The call circle_area(outer_radius) causes the program to jump back to the function definition for circle_area() and assign radius = outer_radius for the duration of the function body.

def circle_area(radius):
    """Compute the area of the circle with the given radius: A = π r^2."""
    return 3.14159 * radius**2


def disc_area(inner_radius, outer_radius):
    """Compute the area of a disc, the region between two circles with the same
    center but different radii.

    Parameters
    ----------
    inner_radius : float
        Inner disc radius, the distance from the center to the start of the disc.
    outer_radius : float
        Outer disc radius, the distance from the center to the end of the disc.

    Returns
    -------
    area : float
        Area of the specified disc.
    """
    smaller_circle_area = circle_area(inner_radius)
    larger_circle_area = circle_area(outer_radius)
    return larger_circle_area - smaller_circle_area


print(disc_area(3, 5))

The first line of the function body is executed, returning the value of 3.14159 * radius**2.

def circle_area(radius):
    """Compute the area of the circle with the given radius: A = π r^2."""
    return 3.14159 * radius**2


def disc_area(inner_radius, outer_radius):
    """Compute the area of a disc, the region between two circles with the same
    center but different radii.

    Parameters
    ----------
    inner_radius : float
        Inner disc radius, the distance from the center to the start of the disc.
    outer_radius : float
        Outer disc radius, the distance from the center to the end of the disc.

    Returns
    -------
    area : float
        Area of the specified disc.
    """
    smaller_circle_area = circle_area(inner_radius)
    larger_circle_area = circle_area(outer_radius)
    return larger_circle_area - smaller_circle_area


print(disc_area(3, 5))

The program returns to the line it was executing when circle_area(outer_radius) was called. The value returned by the call is stored as a variable.

def circle_area(radius):
    """Compute the area of the circle with the given radius: A = π r^2."""
    return 3.14159 * radius**2


def disc_area(inner_radius, outer_radius):
    """Compute the area of a disc, the region between two circles with the same
    center but different radii.

    Parameters
    ----------
    inner_radius : float
        Inner disc radius, the distance from the center to the start of the disc.
    outer_radius : float
        Outer disc radius, the distance from the center to the end of the disc.

    Returns
    -------
    area : float
        Area of the specified disc.
    """
    smaller_circle_area = circle_area(inner_radius)
    larger_circle_area = circle_area(outer_radius)
    return larger_circle_area - smaller_circle_area


print(disc_area(3, 5))

The next line of the function body is executed, returning the value of larger_circle_area - smaller_circle_area.

def circle_area(radius):
    """Compute the area of the circle with the given radius: A = π r^2."""
    return 3.14159 * radius**2


def disc_area(inner_radius, outer_radius):
    """Compute the area of a disc, the region between two circles with the same
    center but different radii.

    Parameters
    ----------
    inner_radius : float
        Inner disc radius, the distance from the center to the start of the disc.
    outer_radius : float
        Outer disc radius, the distance from the center to the end of the disc.

    Returns
    -------
    area : float
        Area of the specified disc.
    """
    smaller_circle_area = circle_area(inner_radius)
    larger_circle_area = circle_area(outer_radius)
    return larger_circle_area - smaller_circle_area


print(disc_area(3, 5))

The program returns to the line it was executing when disc_area(3, 5) was called. The value returned by the call is used as an argument for print(), which displays the result.

50.26544

In nested function calls like f(g(h(x))), the functions are evaluated from the inside out: first h, then g, then f.

# Written in one line.
result = f(g(h(x)))

# Written one step at a time.
y = h(x)
z = g(y)
result = f(z)

Problem 3

Euler’s constant \(e\) is the base of the exponential function \(e^x\). One way to define \(e\) is as the limit

\[ e = \lim_{n\to\infty}\left(1 + \frac{1}{n}\right)^{\!n}. \]

To estimate this limit, we can compute \((1 + \frac{1}{n})^n\) for a large (but finite) number \(n\). The following function implements this idea.

def exponential_constant(n):
    """Estimate Euler's constant e as (1 + 1/n)^n for the given n."""
    return (1 + (1 / n)) ** n

Like the function natural_log() from Problem 2, the function exponential_constant() only computes an approximation. To check how good the approximation is, we can use the fact that the exponential and natural logarithm are inverses: \(e^{\ln(x)} = x\), so then \(x - e^{\ln(x)} = 0\).

Write a function named explog_error() that accepts two arguments (in this order):

  1. A float representing \(x\), and

  2. An int or float representing \(n\).

Compute and return the difference \( x - e^{\ln(x)} \) where \(e\) is estimated with exponential_constant() and \(\ln(x)\) is estimated with natural_log().

Test Cases

print(explog_error(1.314, 2))
print(explog_error(1.314, 10))
print(explog_error(1.314, 50))
0.06599324187790923
0.016565007091014605
0.003372826007180585

Multiple Return Values

Functions can return more than one value by using commas in a return statement. The return values can be extracted individually by using commas to the left of the = operator.

def powers(x):
    """Raise `x` to the second, third, and fourth power."""
    return x**2, x**3, x**4


# Call the function and store all return values at once.
a2, a3, a4 = powers(3)
print(a2)
print(a3)
print(a4)
9
27
81

Many Unused Returns

A function can have multiple return statements, but this does not mean that it returns multiple values. Consider the following incorrect implementation of the powers() function from above.

1def powers_bad(x):
2    """Raise `x` to the second, third, and fourth power, purportedly."""
3    return x**2
4    return x**3
5    return x**4

When the return statement on line 3 is executed, the function exits and execution immediately resumes at the line of code that called the function. The other return statements in lines 4 and 5 are never reached. Hence, this function only returns one value: x**2.

Built-in Functions

Python provides several basic functions that are always available. We have already seen print(), which prints a string representation of the arguments to the screen. Here are a few other useful built-in functions.

Signature

Returns

Description

print(arg1, ...)

None

Print a string representation of each argument.

abs(x)

int or float

Return the absolute value of x, that is, \(|x|\)

round(x)

int

Round a number x to the nearest integer

round(x, n)

int or float

Round a number x to n decimal places

divmod(a, b)

int, int

Do integer division of \(a \div b\) with a remainder

Note that print() does not return anything, abs() and round() return a single number, and divmod() returns two numbers.

x = 3 * (2**6) - 2 * (3**5)
print(x)

# Compute the absolute value of x.
print(abs(x))
-294
294
# Round a number to the nearest integer.
pi = 3.14159265358979323486264338
print(round(pi))

# Round the same number to four and eight decimal places.
print(round(pi, 4))
print(round(pi, 8))
3
3.1416
3.14159265
# Print several values on the same line.
print(pi, abs(pi), round(pi))
3.141592653589793 3.141592653589793 3

Problem 4

Recall the creamery from Problem 1 that has the following menu items.

  • Box of French fries, $2.49

  • Guacamole bacon burger, $8.69

  • Single scoop of ice cream, $3.99

Write a function named creamery_bill() that accepts three int arguments (in this order):

  1. The number of boxes of French fries to order.

  2. The number of guacamole bacon burgers to order.

  3. The number of single scoop ice creams to order.

Calculate the total cost of the order with the given numbers of items, including the 7.45% tax and the $5.00 coupon. Return the result, rounded to the nearest cent (two decimal places).

Test Cases

print(creamery_bill(2, 2, 2))  # 2 of each
print(creamery_bill(1, 2, 3))  # 1 fries, 2 burgers, 3 ice creams
print(creamery_bill(0, 3, 5))  # 3 burgers, 5 ice creams
27.6
29.21
44.45

Additionally, creamery_bill(3, 2, 2) should nearly equal problem1_total (with perhaps a small difference due to rounding).

The built-in function divmod() performs integer division and returns both the quotient and the remainder.

# 131 divided by 7 is 18 with remainder 5
quotient, remainder = divmod(131, 7)
print(quotient)
print(remainder)
18
5

The following is a simplified definition for divmod().

def divmod(a, b):
    """Return the integer quotient and remainder for `a` divided by `b`."""
    return a // b, a % b

Problem 5

One inch equals 2.54 centimeters. Therefore,

\[ x~\text{centimeters} = x~\text{centimeters} \times \frac{1~\text{inch}}{2.54~\text{centimeters}} = \frac{x}{2.54}~\text{inches}. \]

There are 12 inches in a foot.

Write a function named cm2ftin() that accepts a single argument representing a length in centimeters. Convert the length to inches, round the total number of inches to the nearest whole inch, then return two values: the number of feet and the remaining inches.

Test Cases

# 2.54 centimeters = 0 feet, 1 inch
feet, inches = cm2ftin(2.54)
print(feet)
print(inches)
0
1
# 1000 centimeters = 10 meters = 32 feet, 9.7 inches
feet, inches = cm2ftin(1000)
print(feet)
print(inches)
32
10