# Local vs global — where variables live
# scope — every variable has a home

# ─────────────────────────────────────────────
# Local variables
# ─────────────────────────────────────────────

def greet():
    message = "Hello, Bull."    # local variable
    print(message)

greet()
# print(message)    # NameError — message doesn't exist here

# local variable lives and dies with the function

# ─────────────────────────────────────────────
# Global variables
# ─────────────────────────────────────────────

name = "Bull"    # global variable

def greet():
    print(f"Hello, {name}.")    # can read it

greet()    # Hello, Bull.

# function can read global variables

# ─────────────────────────────────────────────
# Local shadows global
# ─────────────────────────────────────────────

name = "Bull"

def greet():
    name = "Horn"           # local — doesn't touch the global
    print(f"Hello, {name}.")

greet()         # Hello, Horn.
print(name)     # Bull — global unchanged

# same name inside and outside — two different variables

# ─────────────────────────────────────────────
# Why this matters
# ─────────────────────────────────────────────

def calculate_bmi(weight, height):
    bmi = weight / height ** 2    # local — only exists here
    return bmi

result = calculate_bmi(70, 1.75)
# print(bmi)       # NameError — bmi doesn't exist here
print(result)    # 22.857... — the returned value, not the local variable

# bmi is gone after the function ends
# return sent its value out before that happened

# ─────────────────────────────────────────────
# Quick reference
# ─────────────────────────────────────────────

# local  — defined inside a function, gone when it ends
# global — defined outside, readable everywhere
# same name inside and outside — two different variables, no conflict
# use return to get values out — don't rely on globals
