{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "1e3007e1",
   "metadata": {},
   "source": [
    "# Lesson 05: Loops and Conditionals Challenge\n",
    "\n",
    "In this activity, you'll solve four problems that build on what you've learned about conditional statements and loops in Lesson 05. These problems will require you to **think creatively**, **combine concepts**, and **explore** different approaches to solving problems with loops and conditionals.\n",
    "\n",
    "## Instructions:\n",
    "- Each problem has a clear objective\n",
    "- You may need to research, experiment, or combine multiple concepts\n",
    "- Test your solutions in the code cells provided\n",
    "- There are multiple ways to solve each problem - be creative!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c0839fd4",
   "metadata": {},
   "source": [
    "---\n",
    "## Problem 1: The Password Validator\n",
    "\n",
    "**Objective:** Create a password validation system that checks if a password meets certain criteria.\n",
    "\n",
    "**Your Task:**\n",
    "Write a function called `validate_password(password)` that checks if a password is valid based on these rules:\n",
    "- At least 8 characters long\n",
    "- Contains at least one uppercase letter\n",
    "- Contains at least one lowercase letter\n",
    "- Contains at least one digit (0-9)\n",
    "\n",
    "The function should:\n",
    "- Return `True` if the password meets all criteria\n",
    "- Return `False` if it doesn't\n",
    "- Print specific messages explaining which criteria are not met\n",
    "\n",
    "**Test Cases:**\n",
    "- `validate_password(\"Pass123\")` → False (too short)\n",
    "- `validate_password(\"password123\")` → False (no uppercase)\n",
    "- `validate_password(\"PASSWORD123\")` → False (no lowercase)\n",
    "- `validate_password(\"Password\")` → False (no digit)\n",
    "- `validate_password(\"Password123\")` → True (all criteria met)\n",
    "\n",
    "**Hints:**\n",
    "- See the Python documentation page on [string methods](https://docs.python.org/3/library/stdtypes.html#string-methods)\n",
    "- Use string methods like `.isupper()`, `.islower()`, `.isdigit()`\n",
    "- You'll need to loop through the password characters\n",
    "- Use conditional statements to check each requirement"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "f0896a9f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Password must be at least 8 characters long\n",
      "Test 1: False\n",
      "\n",
      "Password must contain at least one uppercase letter\n",
      "Test 2: False\n",
      "\n",
      "Password must contain at least one lowercase letter\n",
      "Test 3: False\n",
      "\n",
      "Password must contain at least one digit\n",
      "Test 4: False\n",
      "\n",
      "Password is valid!\n",
      "Test 5: True\n",
      "\n",
      "Password must contain at least one uppercase letter\n",
      "Password must contain at least one digit\n",
      "Test 6: False\n"
     ]
    }
   ],
   "source": [
    "# Problem 1: Your solution here\n",
    "\n",
    "def validate_password(password):\n",
    "    \"\"\"\n",
    "    Validates a password based on specific criteria.\n",
    "    \n",
    "    Args:\n",
    "        password (str): The password to validate\n",
    "    \n",
    "    Returns:\n",
    "        bool: True if valid, False otherwise\n",
    "    \"\"\"\n",
    "    \n",
    "    # Initialize flags for each requirement\n",
    "    has_upper = False\n",
    "    has_lower = False\n",
    "    has_digit = False\n",
    "    \n",
    "    # Loop through each character to check requirements\n",
    "    for char in password:\n",
    "        if char.isupper():\n",
    "            has_upper = True\n",
    "\n",
    "        if char.islower():\n",
    "            has_lower = True\n",
    "\n",
    "        if char.isdigit():\n",
    "            has_digit = True\n",
    "    \n",
    "    # Check each requirement and print messages\n",
    "    is_valid = True\n",
    "\n",
    "    if len(password) < 8:\n",
    "        print(\"\\nPassword must be at least 8 characters long\")\n",
    "        is_valid = False\n",
    "    \n",
    "    if not has_upper:\n",
    "        print(\"\\nPassword must contain at least one uppercase letter\", end=\"\")\n",
    "        is_valid = False\n",
    "    \n",
    "    if not has_lower:\n",
    "        print(\"\\nPassword must contain at least one lowercase letter\", end=\"\")\n",
    "        is_valid = False\n",
    "    \n",
    "    if not has_digit:\n",
    "        print(\"\\nPassword must contain at least one digit\", end=\"\")\n",
    "        is_valid = False\n",
    "    \n",
    "    if is_valid:\n",
    "        print(\"\\nPassword is valid!\", end=\"\")\n",
    "    \n",
    "    return is_valid\n",
    "\n",
    "# Test cases\n",
    "print(\"Test 1:\", validate_password(\"Pass123\"))\n",
    "print(\"\\nTest 2:\", validate_password(\"password123\"))\n",
    "print(\"\\nTest 3:\", validate_password(\"PASSWORD123\"))\n",
    "print(\"\\nTest 4:\", validate_password(\"Password\"))\n",
    "print(\"\\nTest 5:\", validate_password(\"Password123\"))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7e5027de",
   "metadata": {},
   "source": [
    "---\n",
    "## Problem 2: The Number Pattern Printer\n",
    "\n",
    "**Objective:** Create patterns using nested loops.\n",
    "\n",
    "**Your Task:**\n",
    "Write a function called `print_pattern(n)` that prints the pattern below with n rows.\n",
    "\n",
    "The function should support three pattern types:\n",
    "\n",
    "**Pattern: \"triangle\"**\n",
    "```\n",
    "1\n",
    "1 2\n",
    "1 2 3\n",
    "1 2 3 4\n",
    "1 2 3 4 5\n",
    "```\n",
    "\n",
    "**Hints:**\n",
    "- Use nested loops (one for rows, one for columns)\n",
    "- Take a look at Python's `range()` function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "fa826b52",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Triangle with 3 rows:\n",
      "1 \n",
      "1 2 \n",
      "1 2 3 \n",
      "\n",
      "Triangle with 4 rows:\n",
      "1 \n",
      "1 2 \n",
      "1 2 3 \n",
      "1 2 3 4 \n",
      "\n",
      "Triangle with 5 rows:\n",
      "1 \n",
      "1 2 \n",
      "1 2 3 \n",
      "1 2 3 4 \n",
      "1 2 3 4 5 \n"
     ]
    }
   ],
   "source": [
    "# Problem 2: Your solution here\n",
    "\n",
    "def print_pattern(n):\n",
    "    \"\"\"\n",
    "    Prints number pattern with n rows.\n",
    "    \n",
    "    Args:\n",
    "        n (int): The size of the pattern\n",
    "    \"\"\"\n",
    "\n",
    "    # Outer loop for rows (1 to n)\n",
    "    for row in range(1, n + 1):\n",
    "\n",
    "        # Inner loop for columns (1 to current row number)\n",
    "        for col in range(1, row + 1):\n",
    "            print(col, end=\" \")\n",
    "\n",
    "        print()  # New line after each row\n",
    "\n",
    "# Test the pattern\n",
    "print(\"\\nTriangle with 3 rows:\")\n",
    "print_pattern(3)\n",
    "\n",
    "print(\"\\nTriangle with 4 rows:\")\n",
    "print_pattern(4)\n",
    "\n",
    "print(\"\\nTriangle with 5 rows:\")\n",
    "print_pattern(5)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "34e25af5",
   "metadata": {},
   "source": [
    "---\n",
    "## Problem 3: The Prime Number Finder\n",
    "\n",
    "**Objective:** Find all prime numbers in a given range using loops and conditionals.\n",
    "\n",
    "**Background:**\n",
    "A prime number is a number greater than 1 that has no positive divisors other than 1 and itself. For example, 2, 3, 5, 7, 11 are prime numbers.\n",
    "\n",
    "**Your Task:**\n",
    "Write a function called `find_primes(start, end)` that:\n",
    "- Finds all prime numbers between `start` and `end` (inclusive)\n",
    "- Returns a list of all prime numbers found\n",
    "- Prints the total count of primes found\n",
    "\n",
    "**Test Cases:**\n",
    "- `find_primes(1, 20)` → [2, 3, 5, 7, 11, 13, 17, 19]\n",
    "- `find_primes(10, 30)` → [11, 13, 17, 19, 23, 29]\n",
    "- `find_primes(50, 60)` → [53, 59]\n",
    "\n",
    "**Hints:**\n",
    "- A number is prime if it's not divisible by any number from 2 to (number - 1)\n",
    "- Use nested loops: outer loop for each number, inner loop to check divisibility\n",
    "- Use the modulo operator `%` to check divisibility\n",
    "- Consider using a `break` statement for efficiency"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "1f8e4c22",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Primes from 1 to 20:\n",
      "Found 8 prime numbers\n",
      "[2, 3, 5, 7, 11, 13, 17, 19]\n",
      "\n",
      "Primes from 10 to 30:\n",
      "Found 6 prime numbers\n",
      "[11, 13, 17, 19, 23, 29]\n",
      "\n",
      "Primes from 50 to 60:\n",
      "Found 2 prime numbers\n",
      "[53, 59]\n"
     ]
    }
   ],
   "source": [
    "# Problem 3: Your solution here\n",
    "\n",
    "def find_primes(start, end):\n",
    "    \"\"\"\n",
    "    Finds all prime numbers in a given range.\n",
    "    \n",
    "    Args:\n",
    "        start (int): Start of the range\n",
    "        end (int): End of the range (inclusive)\n",
    "    \n",
    "    Returns:\n",
    "        list: List of prime numbers in the range\n",
    "    \"\"\"\n",
    "\n",
    "    primes = []\n",
    "    \n",
    "    # Loop through each number in the range\n",
    "    for num in range(start, end + 1):\n",
    "\n",
    "        # Skip numbers less than 2 (not prime)\n",
    "        if num < 2:\n",
    "            continue\n",
    "        \n",
    "        # Assume the number is prime until proven otherwise\n",
    "        is_prime = True\n",
    "        \n",
    "        # Check if the number is divisible by any number from 2 to num-1\n",
    "        # Optimization: only need to check up to square root of num\n",
    "        for divisor in range(2, int(num ** 0.5) + 1):\n",
    "            if num % divisor == 0:\n",
    "\n",
    "                # Found a divisor, so not prime\n",
    "                is_prime = False\n",
    "\n",
    "                break # No need to check further\n",
    "        \n",
    "        # If still prime, add to list\n",
    "        if is_prime:\n",
    "            primes.append(num)\n",
    "    \n",
    "    # Print the count\n",
    "    print(f\"Found {len(primes)} prime numbers\")\n",
    "    \n",
    "    return primes\n",
    "\n",
    "# Test cases\n",
    "print(\"Primes from 1 to 20:\")\n",
    "result1 = find_primes(1, 20)\n",
    "print(result1)\n",
    "\n",
    "print(\"\\nPrimes from 10 to 30:\")\n",
    "result2 = find_primes(10, 30)\n",
    "print(result2)\n",
    "\n",
    "print(\"\\nPrimes from 50 to 60:\")\n",
    "result3 = find_primes(50, 60)\n",
    "print(result3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "947a421a",
   "metadata": {},
   "source": [
    "---\n",
    "## Problem 4: Fixing Buggy Loops and Conditionals\n",
    "\n",
    "**Objective:** Debug and fix code snippets that contain common loop and conditional errors.\n",
    "\n",
    "**Your Task:**\n",
    "Below are three code snippets that contain bugs. For each one:\n",
    "1. Identify the error\n",
    "2. Fix the code\n",
    "3. Test that it works correctly\n",
    "4. Add a comment explaining what was wrong\n",
    "\n",
    "Run each fixed snippet to verify it works!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "513ba425",
   "metadata": {},
   "source": [
    "### Bug 1: The Infinite Loop\n",
    "\n",
    "This code is supposed to print numbers from 1 to 5.\n",
    "\n",
    "**Expected Output:** \n",
    "```\n",
    "1\n",
    "2\n",
    "3\n",
    "4\n",
    "5\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "4656b1c9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n"
     ]
    }
   ],
   "source": [
    "# Bug 1: Fix the code below\n",
    "\n",
    "counter = 1\n",
    "\n",
    "while counter <= 5:\n",
    "    print(counter)\n",
    "    counter += 1  # This line was missing, causing an infinite loop!"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "37c5263e",
   "metadata": {},
   "source": [
    "### Bug 2: The Range Confusion\n",
    "\n",
    "This code should print even numbers from 2 to 10.\n",
    "\n",
    "**Expected Output:**\n",
    "```\n",
    "2\n",
    "4\n",
    "6\n",
    "8\n",
    "10\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "a80eac78",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "4\n",
      "6\n",
      "8\n",
      "10\n"
     ]
    }
   ],
   "source": [
    "# Bug 2: Fix the code below\n",
    "\n",
    "for i in range(2, 11, 2): # The third step argument was missing, and the end value should be 11 to include 10\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f385db24",
   "metadata": {},
   "source": [
    "### Bug 3: The Grade Classifier\n",
    "\n",
    "This code should classify grades scores according to:\n",
    "- A: 90-100\n",
    "- B: 80-89\n",
    "- C: 70-79\n",
    "- D: 60-69\n",
    "- F: below 60\n",
    "\n",
    "For `score = 85`:\n",
    "\n",
    "**Expected Output:** `Score: 85, Grade: B`\n",
    "\n",
    "**Current (Wrong) Output:** `Score: 85, Grade: F`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "dc024ddc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Score: 85, Grade: B\n"
     ]
    }
   ],
   "source": [
    "# Bug 3: Fix the code below\n",
    "\n",
    "score = 85\n",
    "\n",
    "if score >= 90:\n",
    "    grade = 'A'\n",
    "\n",
    "elif score >= 80:\n",
    "    grade = 'B'\n",
    "\n",
    "elif score >= 70:\n",
    "    grade = 'C'\n",
    "\n",
    "elif score >= 60:\n",
    "    grade = 'D'\n",
    "\n",
    "else:\n",
    "    grade = 'F'\n",
    "\n",
    "print(f\"Score: {score}, Grade: {grade}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0a952a4f",
   "metadata": {},
   "source": [
    "The three conditionals for B, C and D were incorrectly using `if` instead of `elif`, which would cause all conditions to be checked independently, leading to incorrect grade assignment.\n",
    "\n",
    "### Alternate solution: lookup table"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "114f9ecb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Score: 85, Grade: B\n"
     ]
    }
   ],
   "source": [
    "grades = {\n",
    "    10: 'A',\n",
    "    9: 'A',\n",
    "    8: 'B',\n",
    "    7: 'C',\n",
    "    6: 'D',\n",
    "}\n",
    "\n",
    "def lookup_grader(score, grades=grades):\n",
    "    \n",
    "    return grades.get(score // 10, 'F')\n",
    "\n",
    "print(f\"Score: {score}, Grade: {lookup_grader(score)}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2194a85b",
   "metadata": {},
   "source": [
    "---\n",
    "## __Reflection Questions__\n",
    "\n",
    "After completing the challenges, answer these questions:\n",
    "\n",
    "1. Which problem required the most nested loops? How did you keep track of the logic?\n",
    "2. How did you decide when to use a `for` loop vs a `while` loop?\n",
    "3. What was the most challenging aspect of combining loops and conditionals?\n",
    "4. Did you use `break` or `continue` statements? If so, where and why?\n",
    "5. What debugging strategies did you use when your loops weren't working as expected?\n",
    "\n",
    "**Write your answers in the markdown cell below:**"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "91b74fca",
   "metadata": {},
   "source": [
    "### Your Reflections:\n",
    "\n",
    "1. **Problem 3 (Prime Number Finder)** required the most nested loops, with an outer loop to iterate through each number in the range and an inner loop to check divisibility. I kept track of the logic by using clear variable names (`is_prime`, `divisor`) and adding comments to explain each step. The key was breaking down the problem: outer loop handles \"which number to check\" while inner loop handles \"is this number prime?\"\n",
    "\n",
    "2. I used **`for` loops** when I knew the exact number of iterations needed (like iterating through a range of numbers or characters in a string) and **`while` loops** when the condition was more dynamic (like in the bug fixing exercise where we needed to continue until a counter reached a value). For loops are cleaner when working with sequences, while while loops are better for conditional repetition.\n",
    "\n",
    "3. The most challenging aspect was **managing the flow of multiple conditions within loops**, especially in Problem 3 where I needed to determine if a number was prime. I had to think carefully about when to set flags (`is_prime = True/False`) and when to break out of loops early for efficiency. It required thinking through all possible paths the code could take.\n",
    "\n",
    "4. Yes, I used **`break`** in Problem 3 (Prime Number Finder) to exit the inner loop as soon as a divisor was found - there's no need to keep checking once we know a number isn't prime. I also used **`continue`** in the same problem to skip numbers less than 2, since they can't be prime. These statements made the code more efficient and easier to read.\n",
    "\n",
    "5. My debugging strategies included:\n",
    "   - **Adding print statements** to see what values variables held at different points\n",
    "   - **Testing with simple inputs** first (like small ranges or short passwords) before trying complex cases\n",
    "   - **Breaking down complex conditions** into smaller steps with intermediate variables\n",
    "   - **Reading error messages carefully** to understand what Python was trying to tell me\n",
    "   - **Running code incrementally** - testing each part before moving to the next"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "243af547",
   "metadata": {},
   "source": [
    "---\n",
    "## Congratulations!\n",
    "\n",
    "You've completed the Lesson 05 Loops and Conditionals Challenge! You've practiced:\n",
    "- Using conditional statements to validate data\n",
    "- Creating patterns with nested loops\n",
    "- Implementing algorithms with loops and conditionals\n",
    "- Building interactive programs with user input\n",
    "- Combining multiple programming concepts\n",
    "\n",
    "Keep practicing!"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
