# Clean Code Exercises

## Exercise 1: Name Refactor

**Task:** Refactor this function with better names and structure:

```javascript
function proc(u, p) {
  if (p.length < 8) return false;
  const h = crypto.hash(p);
  return u.pw === h;
}
```

**Validation:**
- [ ] All variables and the function have intent-revealing names
- [ ] A reader can understand the logic without guessing
- [ ] No abbreviations unless universally known (e.g., `id`)

**Hints:**
1. `proc` → what does it do? `validatePassword`, `checkCredentials`?
2. `u` → `user`; `p` → `password`; `h` → `hashedPassword`
3. Consider extracting the length check or the hash step

---

## Exercise 2: Extract Function

**Task:** This function does several things. Extract at least two smaller functions:

```javascript
function processOrder(order) {
  if (!order.items || order.items.length === 0) return { error: 'No items' };
  if (!order.shippingAddress) return { error: 'No address' };
  let total = 0;
  for (const item of order.items) total += item.price * item.quantity;
  const tax = total * 0.1;
  const finalTotal = total + tax;
  saveToDatabase({ ...order, total: finalTotal });
  sendConfirmationEmail(order.customerEmail);
  return { success: true, total: finalTotal };
}
```

**Validation:**
- [ ] At least 2 focused functions extracted
- [ ] Original function orchestrates, doesn't contain low-level logic
- [ ] Each extracted function has a clear name

**Hints:**
1. Extract validation into `validateOrder` or separate checks
2. Extract total calculation into `calculateOrderTotal`
3. Consider extracting `saveAndNotify` or keep save/email separate

---

## Exercise 3: Replace Magic Numbers

**Task:** Identify and replace magic numbers in this code:

```javascript
function getPriceTier(customer) {
  if (customer.orders < 5) return 'bronze';
  if (customer.orders < 20) return 'silver';
  return 'gold';
}
```

Add constants for the thresholds. Consider: what if the thresholds change?

**Validation:**
- [ ] Thresholds (5, 20) are named constants
- [ ] Tier names could also be constants if used elsewhere
- [ ] Logic is unchanged, readability improved

**Hints:**
1. `const BRONZE_MIN_ORDERS = 0`, `SILVER_MIN_ORDERS = 5`, `GOLD_MIN_ORDERS = 20`
2. Or `const TIER_THRESHOLDS = [5, 20]` for easier config
3. Document the business rule if non-obvious

---

## Exercise 4: Reduce Nesting

**Task:** Refactor this to use early returns:

```javascript
function findUser(id) {
  if (id) {
    const user = db.query('users', id);
    if (user) {
      if (user.isActive) {
        return user;
      } else {
        return null;
      }
    } else {
      return null;
    }
  } else {
    return null;
  }
}
```

**Validation:**
- [ ] No more than 2 levels of nesting
- [ ] Early returns handle invalid cases
- [ ] Happy path is clear at the end

**Hints:**
1. `if (!id) return null;` first
2. `if (!user) return null;` next
3. `if (!user.isActive) return null;` then return user

---

## Exercise 5: Self-Documenting Code

**Task:** Remove the comment and make the code speak for itself:

```javascript
// Check if the user has reached the free tier limit
if (users.filter(u => u.plan === 'free').length >= 10) {
  showUpgradePrompt();
}
```

**Validation:**
- [ ] Comment removed
- [ ] Intent clear from names and structure
- [ ] Consider extracting to a named boolean variable

**Hints:**
1. `const freeUserCount = users.filter(u => u.plan === 'free').length;`
2. `const FREE_TIER_LIMIT = 10;`
3. `const hasReachedFreeTierLimit = freeUserCount >= FREE_TIER_LIMIT;`
