Tips for Better Code¶

Stats 507, Fall 2021

James Henderson, PhD
September 23, 2021

Overview¶

  • Tip 1
  • Tip 2
  • Tip 3
  • Tip 4
  • Takeaways

Tip 1¶

  • Don't do more than you have to.
  • Example: Looping over pairs of n items.

  • Don't use $n^2$ comparisons when you only need $n \choose 2$.

Tip 1¶

  • Don't do more than you have to.
  • Example: Looping over pairs of n items.
  • Don't use $n^2$ comparisons when you only need $n \choose 2$.
In [ ]:
# worse
phi = (1 + np.sqrt(5)) / 2
psi = (1 - np.sqrt(5)) / 2
x = np.zeros((3, 3))
for i in range(3):
    for j in range(3):
        if i < j:
            x[i, j] = phi ** i - psi ** j
        elif i > j:
            x[i, j] = phi ** j - psi ** i

Tip 1¶

  • Don't do more than you have to.
  • Example: Looping over pairs of n items.
  • Don't use $n^{2}$ comparisons when you only need $n \choose 2$.
In [ ]:
# better
phi = (1 + np.sqrt(5)) / 2
psi = (1 - np.sqrt(5)) / 2
x = np.zeros((3, 3))
for i in range(3):
    for j in range(i + 1, 3):
        x[i, j] = x[j, i] = phi ** i - psi ** j

Tip 2¶

  • Iterate over indices only when necessary, else iterate over values.
  • Example: Finding the maximum.

Tip 2¶

  • Iterate over indices only when necessary, else iterate over values.
  • Example: Finding the maximum.
In [ ]:
# worse
n = 1000
x = list(np.random.uniform(size=n))
m = x[0]
for i in range(len(x)):
    if x[i] > m:
        m = x[i]

Tip 2¶

  • Iterate over indices only when necessary, else iterate over values.
  • Example: Finding the maximum.
In [ ]:
# better
m = x[0]
for v in x:
    if v > m:
        m = v

Tip 3¶

  • Limit use of intermediate variables in simple calculations.
  • Do use intermediate variables to add clarity to complex calculations.

  • Example: Computing z-scores.

Tip 3¶

  • Limit use of intermediate variables in simple calculations.
  • Do use intermediate variables to add clarity to complex calculations.
  • Example: Computing z-scores.
In [ ]:
# worse
x = np.random.uniform(size=n)
xbar = np.mean(x)
sd = np.std(x)
num = x - xbar
z = num / sd

Tip 3¶

  • Limit use of intermediate variables in simple calculations.
  • Do use intermediate variables to add clarity for complex calculations.
  • Example: Computing z-scores.
In [ ]:
# better
z = (x - np.mean(x)) / np.std(x)

Tip 4¶

  • Don't use two names when one will do.
  • Do pick meaningful, but concise variable names.

  • Example: Fibonacci function.

Tip 4¶

  • Don't use two names when one will do.
  • Do pick meaningful, but concise variable names.
  • Example: Fibonacci function.
In [ ]:
# worse
def fib_for(n, first_fib_number=0, second_fib_number=1):
    """
    Compute the Fibonacci number $F_n$, when $F_0 = a$ and $F_1 = b$.

    This function computes $F_n$ directly by iterating using a for loop.

    Parameters
    ----------
    n : int
        The desired Fibonacci number $F_n$. 
    first_fib_number, second_fib_number : int, optional.
        Values of $F_0$ and $F_n$ to initalize the sequence with. 

    Returns
    -------
    The Fibonacci number $F_n$ for the sequence beginning with the specified
    inputs. 

    """
    a = first_fib_number
    b = second_fib_number

    if n == 0:
        return(a)
    elif n == 1:
        return(b)
    else:
        for i in range(n - 1):
            a, b = b, a + b
        return(b)

Tip 4¶

  • Don't use two names when one will do.
  • Do pick meaningful, but concise variable names.
  • Example: Fibonacci function.
In [ ]:
# better
def fib_for(n, f0=0, f1=1):
    """
    Compute the Fibonacci number $F_n$, when $F_0 = a$ and $F_1 = b$.

    This function computes $F_n$ directly by iterating using a for loop.

    Parameters
    ----------
    n : int
        The desired Fibonacci number $F_n$. 
    f0, f1 : int, optional.
        Values to initalize the sequence $F_0$ = `f0`, $F_1$ = `f1`. 

    Returns
    -------
    The Fibonacci number $F_n$ for the sequence beginning with `f0` and `f1`. 

    """
    if n == 0:
        return(a)
    elif n == 1:
        return(b)
    else:
        for i in range(n - 1):
            a, b = b, a + b
        return(b)

Takeaways¶

  • Don't do more than you have to.
  • Iterate over indices only when necessary, otherwise iterate over values.
  • Limit use of intermediate variables in simple caclulations.
  • Do use intermediate variables to make complex calculations clearer.
  • Don't use two names when one will do.