Theme

JavaScript: Loops and Arrays πŸ”

Day 25 - Handling Repetition and Collections

Web Programming

Why Do We Need Loops? πŸ€”

The Repetition Challenge

❌ Without Loops

console.log("Student 1");
console.log("Student 2");
console.log("Student 3");
console.log("Student 4");
console.log("Student 5");
// ... 25 more lines? 😱

βœ… With Loops

for (let i = 1; i <= 30; i++) {
  console.log(`Student ${i}`);
}
Key Insight: Computers excel at repetitive tasks - they're fast and never get tired!

Today's Learning Objectives 🎯

While Loops ⏰

Keep going while a condition is true

let count = 0;

while (count < 5) {
  console.log(`Count is: ${count}`);
  count++; // Don't forget this!
}
⚠️ Watch Out for Infinite Loops!

Always ensure your loop condition will eventually become false!

Quick Challenge:

What happens if we forget count++? πŸ€”

For Loops 🎒

When you know how many times to repeat

// for (initialization; condition; update)
for (let i = 0; i < 5; i++) {
  console.log(`Iteration ${i}`);
}

Parts of a For Loop:

  1. Initialization: let i = 0
  2. Condition: i < 5
  3. Update: i++

Execution Order:

  1. Initialize once
  2. Check condition
  3. Execute body
  4. Update
  5. Go to step 2

Loop Control: Break & Continue πŸ›‘

break

Exits the loop completely

for (let i = 0; i < 10; i++) {
  if (i === 5) break;
  console.log(i);
}
// Output: 0, 1, 2, 3, 4

continue

Skips to next iteration

for (let i = 0; i < 5; i++) {
  if (i === 2) continue;
  console.log(i);
}
// Output: 0, 1, 3, 4

Quick Loop Practice πŸ’»

5-Minute Challenge: Create These Loops

  1. Count from 10 to 1 (countdown)
  2. Print only even numbers from 0 to 20
  3. Calculate the sum of numbers 1 to 100

Hint for #3:

let sum = 0;
for (let i = 1; i <= 100; i++) {
  // What goes here?
}

πŸ“š Historical Moment: Y2K πŸ•

When Loop Boundaries Mattered Most

The Y2K Panic of 1999

The Clinton administration called preparing for Y2K "the single largest technology management challenge in history."

Feared Consequences:

  • ⚑ Power grid failures
  • πŸ₯ Medical equipment crashes
  • 🏦 Banking system collapses
  • ✈️ Transportation shutdowns

The Core Problem:

Systems stored years as 2 digits (99 for 1999). When 2000 came, computers would read "00" - creating invalid loop conditions and date calculations!

Source: NPR - "Y2K seems like a joke now, but in 1999 people were really freaking out"

Y2K: Why It Matters to You πŸŽ“

The Power of Proper Loop Boundaries

The Y2K Bug in Code:

// Buggy Y2K-style code
let year = 99; // Meant to be 1999
year++; // Now it's 00 - is that 1900 or 2000?

// Loop that breaks with wrong boundaries
for (let year = 95; year <= 05; year++) {
  console.log(`Processing year: 19${year}`);
}
// What happens when year = 00? πŸ’₯

πŸ”΄ The acronym that emerged: TEOTWAWKI

"The End Of The World As We Know It"

πŸ’­ Reflection Question:

Why must programmers think carefully about loop boundaries and edge cases?

Think about: array indexing, date ranges, off-by-one errors...

Arrays: Collections of Data πŸ“¦

Store Multiple Values in One Variable

// Creating arrays
const students = ["Alice", "Bob", "Charlie", "Diana"];
const scores = [95, 87, 92, 88, 91];
const mixed = [42, "hello", true, null];

// Accessing elements (0-indexed!)
console.log(students[0]); // "Alice"
console.log(scores[2]); // 92
Remember: Arrays are zero-indexed! The first element is at index 0.

πŸ“š Historical Moment ⚑

JavaScript's Type Coercion: A User Request

The Surprising Origin of JavaScript Quirks

Myth: JavaScript's "weird" behavior was due to being created in 10 days.

Reality: The original prototype (Mocha) didn't have implicit type conversion. Users asked for it!

What This Means:

Features we complain about today were actually requested enhancements that Brendan Eich added to version 1.0 based on user feedback!

Source: Buttondown - "Was Javascript really made in 10 days?"

Type Coercion & Arrays πŸ”„

Why Understanding This Matters

Array Type Coercion Can Be Surprising:

// Arrays can contain mixed types
const data = [1, "2", 3, "4"];

// Type coercion in array operations
console.log([1, 2] + [3, 4]); // "1,23,4" 😲
console.log([10, 5, 40].sort()); // [10, 40, 5] 😲

// Why? Default sort converts to strings!
// "10" < "40" < "5" alphabetically

// The fix: provide a comparison function
console.log([10, 5, 40].sort((a, b) => a - b)); // [5, 10, 40] βœ…

⚠️ Key Takeaway

Understanding how JavaScript handles types in arrays prevents subtle bugs and helps you write more reliable code!

πŸ’­ Reflection Question:

Can you think of a situation where automatic type coercion in arrays might cause unexpected results in a real application?

Working with Arrays πŸ”§

const fruits = ["apple", "banana", "orange"];

// Length property
console.log(fruits.length); // 3

// Adding elements
fruits.push("grape"); // Add to end
fruits.unshift("mango"); // Add to beginning

// Removing elements
fruits.pop(); // Remove from end
fruits.shift(); // Remove from beginning

// Modifying elements
fruits[1] = "strawberry"; // Change element

Looping Through Arrays πŸ”„

The Perfect Partnership

const numbers = [10, 20, 30, 40, 50];

// Traditional for loop
for (let i = 0; i < numbers.length; i++) {
  console.log(numbers[i]);
}

// For...of loop (cleaner!)
for (const num of numbers) {
  console.log(num);
}
Pro Tip: Use for...of when you don't need the index!

Array Magic: Higher-Order Methods ✨

More Elegant Than Loops!

The Big Three:

  • πŸ“ map() - Transform each element
  • πŸ” filter() - Keep only what you want
  • πŸ“Š reduce() - Combine into single value

Key Concept: These methods take functions as arguments (callbacks)

πŸ“š Historical Moment: Y2K Resolution βœ…

Much Ado About Nothing?

What Actually Happened on January 1, 2000?

Despite the massive fears, there were very few Y2K problems when midnight struck.

Minor Issues:

  • 🏭 One nuclear facility in Japan had radiation equipment fail (backup systems worked)
  • πŸ“± Some minor glitches worldwide
  • βœ… No major disasters occurred

The Surprise:

Countries like Italy, Russia, and South Korea did little preparation - yet had no more problems than countries like the U.S. that spent millions!

Source: National Geographic - "Y2K bug"

The Y2K Legacy πŸ§ͺ

Testing Edge Cases Matters

Was Y2K Preparation Wasted?

Some say the massive testing prevented disasters. Others say the threat was overblown. The truth? We'll never know for certain.

What We DO Know:

// Testing edge cases in arrays
function processData(arr) {
  // Test: What if arr is empty?
  if (arr.length === 0) return [];

  // Test: What if arr has 1 item?
  if (arr.length === 1) return arr;

  // Test: What about negative numbers?
  // Test: What about non-numbers?
  return arr.filter(x =>
    typeof x === 'number' && x >= 0
  );
}

🎯 Programming Wisdom from Y2K:

  • βœ… Always test edge cases (empty arrays, single items, boundaries)
  • βœ… Don't assume "normal" inputs only
  • βœ… Better safe than sorry - defensive programming saves time!

πŸ’­ Reflection Question:

What edge cases should you test when working with loops and arrays?

Examples: Empty arrays? Single elements? Very large arrays? Mixed types?

The Map Method πŸ—ΊοΈ

Transform Every Element

// Double all numbers
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6, 8, 10]

// Make names uppercase
const names = ["alice", "bob", "charlie"];
const upperNames = names.map(name => name.toUpperCase());
console.log(upperNames); // ["ALICE", "BOB", "CHARLIE"]
Important: map() returns a NEW array - original is unchanged!

The Filter Method πŸ”

Keep Only What Passes the Test

// Keep only even numbers
const numbers = [1, 2, 3, 4, 5, 6, 7, 8];
const evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // [2, 4, 6, 8]

// Keep long words
const words = ["hi", "hello", "goodbye", "yes", "no"];
const longWords = words.filter(word => word.length > 3);
console.log(longWords); // ["hello", "goodbye"]

Filter returns elements where callback returns true

The Reduce Method πŸ“Š

Combine All Elements Into One Value

// Sum all numbers
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((total, num) => total + num, 0);
console.log(sum); // 15

// Find the maximum
const scores = [85, 92, 78, 96, 88];
const max = scores.reduce((max, score) => {
  return score > max ? score : max;
}, 0);
console.log(max); // 96
Pattern: reduce((accumulator, current) => ..., initialValue)

Visualizing Array Methods 🎨

The Sandwich Example πŸ₯ͺ

Start: [🍞, πŸ₯¬, πŸ…, πŸ§€, πŸ₯“, 🍞]

Filter (vegetarian): [🍞, πŸ₯¬, πŸ…, πŸ§€, 🍞]

Map (toast): [πŸžβ†’πŸ₯–, πŸ₯¬, πŸ…, πŸ§€, πŸžβ†’πŸ₯–]

Reduce (stack): πŸ₯ͺ

Each method serves a specific purpose in data transformation!

Method Chaining ⛓️

Combine Multiple Operations

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const result = numbers
  .filter(num => num % 2 === 0) // Keep evens
  .map(num => num * 3) // Triple them
  .reduce((sum, num) => sum + num, 0); // Sum all

console.log(result); // 90 (2*3 + 4*3 + 6*3 + 8*3 + 10*3)
Power Move: Chain methods for complex transformations in readable code!

Test-Driven Development (TDD) πŸ§ͺ

Write Tests First, Code Second

The TDD Cycle:

  1. πŸ”΄ Red: Write a failing test
  2. 🟒 Green: Write minimal code to pass
  3. πŸ”΅ Refactor: Improve the code
  4. πŸ” Repeat: Add next test
Why TDD? Catches bugs early, guides design, provides documentation

TDD in Action 🎯

// Step 1: Write the test first
test('sum adds two numbers', () => {
  expect(sum(2, 3)).toBe(5);
});

// Step 2: Test fails (function doesn't exist yet)

// Step 3: Write minimal code to pass
function sum(a, b) {
  return a + b;
}

// Step 4: Test passes! Now add more tests...
test('sum handles negative numbers', () => {
  expect(sum(-1, -2)).toBe(-3);
});

Meet Jest πŸƒ

JavaScript Testing Framework

// Basic Jest test structure
describe('Array exercises', () => {
  test('repeatString repeats text', () => {
    expect(repeatString('hey', 3)).toBe('heyheyhey');
  });

  test('repeatString handles empty string', () => {
    expect(repeatString('hi', 0)).toBe('');
  });

  test('repeatString returns ERROR for negative', () => {
    expect(repeatString('hi', -1)).toBe('ERROR');
  });
});

Running Jest Tests ▢️

In Your Terminal:

# Install Jest (first time only)
npm install --save-dev jest

# Run all tests
npm test

# Run tests in watch mode (re-runs on save)
npm test -- --watch

# Run a specific test file
npm test repeatString.spec.js
Pro Tip: Use watch mode while developing - tests run automatically!

Understanding Test Results πŸ“Š

βœ… Passing Test

PASS ./repeatString.spec.js
  βœ“ repeats text (2 ms)
  βœ“ handles zero (1 ms)

Test Suites: 1 passed
Tests: 2 passed
Time: 0.5s

❌ Failing Test

FAIL ./repeatString.spec.js
  βœ• handles negative (5 ms)

Expected: "ERROR"
Received: "hihihi..."

Test Suites: 1 failed
Tests: 1 failed, 2 passed

Read error messages carefully - they tell you exactly what went wrong!

This Week's Exercises πŸ“

JavaScript Exercises Repository:

  1. 06_repeatString - String manipulation & loops
  2. 07_reverseString - Array methods practice
  3. 08_removeFromArray - Filter & includes
  4. 09_sumAll - Reduce & validation
  5. 10_leapYears - Logic & edge cases
  6. 11_tempConversion - Math & rounding
Remember: Read each README carefully before starting!

How to Approach Each Exercise 🎯

The Winning Strategy:

  1. πŸ“– Read the README completely
  2. πŸ‘€ Examine the test cases
  3. πŸ’­ Plan your approach (pseudocode)
  4. ⌨️ Code incrementally
  5. πŸ§ͺ Test frequently
  6. πŸ” Debug failures using test output
  7. ✨ Refactor after passing
Pro Tip: Make one test pass at a time!

Practice Time! ⚑

15-Minute In-Class Exercise

Let's tackle repeatString together!

// Your function should:
repeatString('hey', 3) // returns 'heyheyhey'
repeatString('hello', 0) // returns ''
repeatString('hi', -1) // returns 'ERROR'

Hint: You'll need a loop or a clever string method!

Today's Key Takeaways 🎯

You Can Now:

Homework: Complete all exercises from the assignment list

Next Class: DOM Manipulation - Making pages interactive!