# Practical guidance # bad if sqrt(square(a) + square(b)) > 1: x = x + sqrt(square(a) + square(b)) # good h = sqrt(square(a) + square(b)) if h > 1: x = x + h # bad x = (-b + sqrt(square(b) - 4 * a * c)) / (2 * a) # good disc_term = sqrt(square(b) - 4 * a * c) x = (-b + disc_term) / (2 * a) # ugly def find_quadratic_root(a, b, c, plus=True): """Applies the quadratic formula to the polynomial ax^2 + bx + c.""" if plus: return (-b + sqrt(square(b) - 4 * a * c)) / (2 * a) else: return (-b - sqrt(square(b) - 4 * a * c)) / (2 * a) # good def find_quadratic_root(a, b, c, plus=True): """Applies the quadratic formula to the polynomial ax^2 + bx + c.""" disc_term = sqrt(square(b) - 4 * a * c) if not plus: disc_term *= -1 return (-b + disc_term) / (2 * a) # Local assignment def percent_difference(x, y): difference = abs(x-y) return 100 * difference / x diff = percent_difference(40, 50) if False: # change to True to see effect difference # not in local frame # The nonlocal statement def make_withdraw(balance): def withdraw(amount): nonlocal balance if amount > balance: return 'Insufficient funds' balance = balance - amount return balance return withdraw withdraw = make_withdraw(100) withdraw(25) withdraw(25) withdraw(60) withdraw(15) # Error without nonlocal if False: # change to True to see effect def make_withdraw(balance): def withdraw(amount): if amount > balance: return 'Insufficient funds' balance = balance - amount return balance return withdraw withdraw = make_withdraw(100) withdraw(25) # Local state using mutable data type def make_withdraw_list(balance): b = [balance] def withdraw(amount): if amount > b[0]: return 'Insufficient funds' b[0] = b[0] - amount return b[0] return withdraw withdraw = make_withdraw_list(100) withdraw(25) # Create two withdraw functions wd = make_withdraw(100) wd2 = make_withdraw(100) wd(25) wd2(15) # Multiple references to a withdraw function wd = make_withdraw(100) wd2 = wd wd(25) wd2(15) # Referential transparency wd = make_withdraw(100) wd(25) + wd(15) 75 + 85