FAQ: Loops - The While Loop

hi Mtf, thank you so much for explaining. Now I understand it!!!

1 Like

Hi.
I’m a little confused in the below code. Since it says

currentCard != ‘spade’

, why do we still have ‘spade’ sometimes printed on the console when we run it multiple times?

const cards = [‘diamond’, ‘spade’, ‘heart’, ‘club’];

let currentCard;

while (currentCard != ‘spade’) {

currentCard = cards[Math.floor(Math.random() * 4)];

console.log(currentCard);

}

The loop doesn’t end immediately if currentCard is assigned the value 'spade' midway through an iteration. The loop condition is checked at the beginning of every iteration. If the condition fails, then the loop is exited.

Before entering the while loop, the statement let currentCard; declares a variable but doesn’t initialize it with any value. At this point, currentCard is undefined.

undefined doesn’t equal 'spade', so the condition is true and we enter the while loop. Within the loop, a random number in the range 0-3 is generated, (and using the random number as the index) a card is selected from the cards array and assigned to the variable currentCard. This card is logged to the console (even if it happens to be 'spade') and we move on to the next iteration. Now the condition is re-checked. If currentCard is 'spade', then the loop ends. In this version, the final card logged to the console will always be 'spade'.

In the present form, a card is randomly selected and logged to the console before the end of the iteration.

Suppose, we changed the order of the statements in the body of the loop moving the console statement above the selection of card,

let currentCard; 
while (currentCard != "spade") {
    console.log(currentCard);
    currentCard = cards[Math.floor(Math.random() * 4)];
}

Now, the very first time undefined will be printed. Then, a random card will be selected and the iteration will end. The loop condition will be re-checked. If currentCard is 'spade', then the loop ends. Otherwise, a new iteration will begin. The currentCard from the previous iteration will be printed and then, a new card will be selected. In this version, 'spade' will never be printed to the console because the console statement comes before a fresh card selection.

This was beautifully explained. Thanks a million. :heart:

1 Like

Thank you! I couldn’t figure out what this was doing…

const cards = [‘diamond’, ‘spade’, ‘heart’, ‘club’];

// Write your code below

let currentCard;

while (currentCard !== ‘spade’) {

currentCard = cards[Math.floor(Math.random() * 4)];

console.log(currentCard);

}

I don’t get this one. Isn’t it supposed to just print 1 single element? I get random elements, sometimes 2 elements, sometimes 3, 1… const cards = [‘diamond’, ‘spade’, ‘heart’, ‘club’];

let currentCard;

while(currentCard !== ‘spade’)

{

currentCard = cards[Math.floor(Math.random() * 4)];

console.log(currentCard);

}

It can take any number of iterations before ‘spade’ is generated, so yes, it can print multiple times.

My solution here. I changed the 4 from the example to the cards.length, so that, if the array grows in number, so does the number of possible card picks:

  1. Create a variable that will contain the current card pick
  2. While the value in currentCard is NOT ‘spade’ (since that’s what we’re looking for right now):
  3. Use the length of the cards array to generate a number between zero and said length (e.g. if the array has 4 elements, generate a number between 0-4) // our number could be 2.3243 that floored would turn into 2
  4. Use that number as the index for cards, which will allow us to randomly pick an element from the array
  5. Store the element you selected with this method into the currentCard variable you hadn’t initialized
  6. Finally, log the current value of currentCard to the console

In our example, our final random number was 2 (after being floored). Since ‘spade’ is on index=1, our while loop runs again, both a) overriding the value of currentCard and b) logging that new value to the console; the loop does this until the random number is 1 and we get ‘spade’ from our array. Which is why each time we run our program we get different values. We can blame Math.random() for that!

const cards = ['diamond', 'spade', 'heart', 'club']; // Write your code below let currentCard; while (currentCard !== 'spade') { currentCard = cards[Math.floor(Math.random() * cards.length)]; console.log(currentCard) }

Hello, I did the exercise correctly but one output gave me 8 card names. How did that happen?
code :
const cards = [‘diamond’, ‘spade’, ‘heart’, ‘club’];

// Write your code below
let currentCard ;

while (currentCard !== ‘spade’){
currentCard = cards[Math.floor(Math.random() * 4)];
console.log(currentCard)
}
//output: diamond
diamond
heart
heart
diamond
diamond
heart
diamond
diamond
club
heart
spade

Randomness is by definition not predictable. It is no small surprise that it took 9 tries to randomly generate a 1 given there is a probability of only 0.25. The more times you run the code, the more different results you can expect.

1 Like

Hey all! I don’t have a question about the exercise, but I do have an interesting math problem to pose to you all :slight_smile:

I started coding within the past couple of months, but I’m coming from a pure mathematics background and two degrees in math. So I thought about the following problem with this “currentCard” exercise on loops, here it is:

Suppose that I write this program and keep hitting “Run Code” over and over again. I’ll probably see lists of different lengths appearing on the output screen. The shortest possible list is a single entry for “Spade”, but it could be a list of three entries like: “Heart”, “Heart”, “Spade”.
What’s the Expected List Length of the output list?
(Hint: What’s the Expected Value of this probabilistic situation?)
Try it out!

I got back 4 :slight_smile:

for Loop:

The for loop is typically used when you know the number of iterations beforehand. It consists of three parts: initialization, condition, and iteration expression.

for (let i = 0; i < 5; i++) {
  console.log(i);  // Outputs 0, 1, 2, 3, 4
}
  1. Initialization: Executed once before the loop starts. It often initializes a counter variable. (let i = 0)
  2. Condition: Evaluated before each iteration. If it’s true, the loop continues; if false, the loop exits. (will only continue if i < 5, otherwise halts its operation)
  3. Iteration: Executed after each iteration, commonly increments or decrements the counter variable. (i++ which is equivalent to i += 1 or i = i + 1)

while Loop:

The while loop is used when the number of iterations is not known beforehand, and the loop continues as long as a specified condition is true.

let i = 0;
while (i < 5) {
  console.log(i);  // Outputs 0, 1, 2, 3, 4
  i++;
}

In this case, as long as i < 5 evaluates to true, the loop will continue its execution (i.e, displaying i to the console and incrementing i by 1)

Being as that is in iterator territory, one might instead choose Array.map

Other than that…

Some extra method exploration: one can also use Array.from to create a new Array instance from an array or iterable-like object.

> Array.from({length: 20}, (_, i) => String(i * 10)).join(" ")
<- "0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190"
  • The first argument is an object with a length property set to 20. This defines the length of the new array to be created.
  • The second argument is a mapping function, which takes two parameters:
    • The first parameter (_) is a placeholder for the array elements (not used in this case).
    • The second parameter (i) represents the index of the array element being created.
  • The mapping function returns String(i * 10), which converts each index i multiplied by 10 to a string.

Need more examples, feel free to browse link here: ^^

I have a question on the console result, why we get varying result every time we run the program.
why some time 3, why some time 6 or 9, how is this program running.

If you are seeing values other than ‘diamond’, ‘spade’, ‘heart’, ‘club’, you must be referring to the wrong lesson as those are the only 4 values which you will see displaying to the console. Here’s how it works:

let currentCard=’ ’
while (currentCard!==‘spade’){
  currentCard=cards[Math.floor(Math.random()*4)];
  console.log(currentCard)
}
  1. Math.random(): This function returns a random floating-point number between 0 (inclusive) and 1 (exclusive).
  2. Math.random() * 4: This expression generates a random floating-point number between 0 (inclusive) and 4 (exclusive).
  3. Math.floor(Math.random() * 4): This rounds down the random floating-point number to the nearest integer, resulting in 0, 1, 2, or 3.
  4. cards[Math.floor(Math.random() * 4)]: This expression selects a random index from the cards array, effectively picking a random card. (NOTE that the cards’ index positioning starts from 0)
  5. The while loop continues iterating until the currentCard is equal to ‘spade’.

For example, you might see outputs like ‘diamond’, ‘club’, ‘heart’, ‘spade’ in one run and ‘heart’, ‘spade’ in another run, and so on. The variability is due to the random nature of the card selection.


I just got a 21-item list as output, what are the chances? Looks like it’s approximately 1.53e-13 or 0.000000000000153%. I don’t think this will happen ever again so I’m posting it here.

Can you share your calculations?

In one trial, the chance of not picking a spade is 34 or 75%

In two trials, the chance of not picking a spade is (34)2 or 56.25%

In 21 trials, the chance of not picking a spade is (34)21 or approximately 0.2378%

I may be wrong, but that’s what I am thinking.

1 Like

We can check the math using logs:

Given that, log (m / n) == log m - log n; and, that, log a ** x == x log a, we have,

>>> from math import log, e
>>> x = (log (3) - log (4)) * 21
>>> e ** x
0.0023784089542005027
>>> 

Oh, darn, that’s Python.

const log = Math.log
const e = Math.E
const x = (log (3) - log (4)) * 21
console.log(e ** x)
//  0.002378408954200492
1 Like

0.002378408954200492 is correct, I was wrong the first time. Thanks guys. But still quite a low probability.

1 Like

Indeed, 24 in 10000 chance is very low.