# One line. One collection.
# list and set comprehensions — transform, filter, deduplicate

# ─────────────────────────────────────────────
# List comprehensions — transform
# ─────────────────────────────────────────────

names = ["raven", "wolf", "ghost", "viper"]

upper  = [name.upper() for name in names]
title  = [name.capitalize() for name in names]
length = [len(name) for name in names]

print(upper)    # ['RAVEN', 'WOLF', 'GHOST', 'VIPER']
print(title)    # ['Raven', 'Wolf', 'Ghost', 'Viper']
print(length)   # [5, 4, 5, 5]

# numbers
squares = [n ** 2 for n in range(1, 6)]
print(squares)  # [1, 4, 9, 16, 25]

# ─────────────────────────────────────────────
# List comprehensions — filter
# ─────────────────────────────────────────────

scores = [85, 74, 91, 63, 98, 55]

passing = [s for s in scores if s >= 80]
failing = [s for s in scores if s < 80]

print(passing)  # [85, 91, 98]
print(failing)  # [74, 63, 55]

# ─────────────────────────────────────────────
# List comprehensions — transform and filter
# ─────────────────────────────────────────────

labels = [f"{s} — passed" for s in scores if s >= 80]
print(labels)
# ['85 — passed', '91 — passed', '98 — passed']

# from a string
letters = [ch for ch in "RedHorn" if ch.isupper()]
print(letters)  # ['R', 'H']

# from a list of strings
names = ["Raven Wolf", "Ghost Viper", "Bull Cruz"]
first_names = [name.split()[0] for name in names]
print(first_names)  # ['Raven', 'Ghost', 'Bull']

# ─────────────────────────────────────────────
# Set comprehensions — unique values
# ─────────────────────────────────────────────

# duplicates removed automatically
raw = ["raven", "wolf", "raven", "ghost", "wolf"]
unique = {name.capitalize() for name in raw}
print(unique)   # {'Ghost', 'Raven', 'Wolf'} — order varies

# filter into a set
scores = [85, 74, 91, 63, 85, 91, 98]
unique_passing = {s for s in scores if s >= 80}
print(unique_passing)   # {98, 91, 85}

# ─────────────────────────────────────────────
# List vs set comprehension — side by side
# ─────────────────────────────────────────────

data = [1, 2, 2, 3, 3, 3, 4]

as_list = [x * 2 for x in data]    # [2, 4, 4, 6, 6, 6, 8] — keeps duplicates
as_set  = {x * 2 for x in data}    # {2, 4, 6, 8}           — unique only

print(as_list)
print(as_set)

# ─────────────────────────────────────────────
# When NOT to use a comprehension
# ─────────────────────────────────────────────

names = ["Raven", "Wolf", "Ghost"]

# WRONG — building a list just to print
# [print(name) for name in names]

# CORRECT — use a regular loop for side effects
for name in names:
    print(name)

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

# [expr for x in iterable]           — list, all elements
# [expr for x in iterable if cond]   — list, filtered
# {expr for x in iterable}           — set, unique only
# {expr for x in iterable if cond}   — set, filtered + unique
#
# [] — ordered, allows duplicates
# {} — unordered, unique values only
# don't use comprehensions for side effects (print, append, etc.)
