99 Bottles of Beer on the Wall : Frontend Coding Exercises

I’m not really that concerned about innerHTML because I don’t usually do cross origin (maybe I should be worried about man in the middle :thinking:)

I just do it for performance of the initial render… it’s about 4x faster to clone a node than createElement() or innerHTML =

It makes no performance difference for a few components but a list of 50+ items/ components has an effect. :slightly_smiling_face:

The syntax is not too bad e.g.:

static template = [
        { lvl: 0, tag: "my-custom", props: [ ] },
        { lvl: 1, tag: "SECTION", props: [{ prop: 'classList', key: 'class' } ] },
        { lvl: 2, tag: 'H1', props: [ ] }
        { lvl: 3, tag: 'textNode', key: 'text' },
]

static html = build_Template(myCustom.template)
1 Like

Yikes! Let me fix that in a few moments :sweat_smile:

You could do something similar with innerHTML and a string too. That can be lazily parsed into a template element and that template can be used to clone nodes into instances. In my component, moving the shadow DOM code to a static utility for this could look something like:

  static #template = null;
  static build(instance) {
  	if (!this.#template) {
      this.#template = document.createElement("template");
      this.#template.innerHTML = `
      <style>
      #wrap {
        display: flex;
        flex-direction: column;
      }
      </style>
      <div id="wrap">
        <output id="line1"></output>
        <output id="line2"></output>
        <input type="range" value="0">
      <div>
      `;
    }
    const shadow = instance.attachShadow({ mode: "open" });
    shadow.appendChild(this.#template.content.cloneNode(true));
    return shadow;
  }

This wouldn’t work if you wanted to include variables in the markup, but if you’re concerned about performance, you’d want to handle those through the DOM APIs anyway.

1 Like

That’s sweet, I didn’t realize you could pass in an instance into a static method (I’m a novice at OO :smile:)

I decided to make a very basic solution :stuck_out_tongue:

for (let i = 99; i >= 0; i--) {
  if (i >= 2) {
    console.log(`${i} bottles of beer on the wall, ${i} bottles of beer.`);
    console.log(`Take one down and pass it around, ${i - 1} bottles of beer on the wall.
    `);
  }

  if (i == 1) {
    console.log(`1 bottle of beer on the wall, 1 bottle of beer.`);
    console.log(`Take one down and pass it around, no more bottles of beer on the wall.
    `);
  }

  if (i == 0) {
    console.log(`No more bottles of beer on the wall, no more bottles of beer.`);
    console.log(`Go to the store and buy some more, 99 bottles of beer on the wall.
    `);
  }
}

I went ahead and recorded a video of it as well:

:crazy_face:

1 Like

This was fun!

bottles = c(paste(99:2, "bottles"), "1 bottle")
bottles2 = c(bottles, "no more bottles")
bottles = c(bottles, "No more bottles")
bottles3 = c(paste("Take one down and pass it around,", bottles2[-1], "of beer on the wall.\n\n"),
             "Go to the store and buy some more, 99 bottles of beer on the wall.")
cat(paste0(bottles, " of beer on the wall, ", bottles2, " of beer.\n",
           bottles3), sep = "")

2 Likes

Award granted! :stuck_out_tongue:

1 Like

That was fun :slight_smile:
Here is my solution:

const numberOfBeers = 99;

function printLyrics(numberOfBeers) {
  for (beerCounter = numberOfBeers; beerCounter >= 0; beerCounter--) {
    if (beerCounter >= 2) {
      console.log(
        `${beerCounter} bottles of beer on the wall, ${beerCounter} bottles of beer.`
      );
      console.log(
        `Take one down and pass it around, ${
          beerCounter - 1
        } bottles of beer on the wall.`
      );
    } else if (beerCounter == 1) {
      console.log(
        `${beerCounter} bottle of beer on the wall, ${beerCounter} bottle of beer.`
      );
      console.log(
        `Take one down and pass it around, no more bottles of beer on the wall.`
      );
    } else {
      console.error(
        "No more bottles of beer on the wall, no more bottles of beer."
      );
      console.info(
        `Go to the store and buy some more, ${beerCounter} bottles of beer on the wall.`
      );
    }
  }
}

printLyrics(numberOfBeers);
2 Likes

Badge granted!

Glad you liked it :slight_smile:

1 Like

Me 1337, me do one line…

  const beer = (amount) => Array.from(new Array(amount+1), (whocares, x) => x > 1 ? x + ' bottles of beer on the wall, ' + x + ' bottles of beer.\n' + 'Take one down and pass it around, ' + (x - 1) + ' bottles of beer on the wall.\n\n' : x== 1 ? '1 bottle of beer on the wall, 1 bottle of beer.\nTake one down and pass it around, no more bottles of beer on the wall.\n\n' : 'No more bottles of beer on the wall, no more bottles of beer.\nGo to the store and buy some more, ' + (amount) + ' bottles of beer on the wall.').reverse().join('');

console.log(beer(99))
2 Likes

Badge granted! Glad you are having fun with these.

Do you have any general feedback on these exercises and how to improve them?

Ta, and yeah they where fun.
Not really, just do you and if others find the task fun then great.

Thats some R voodoo magick you got going on there, took me some reading and ChatGPT to figure whats going on…like it :stuck_out_tongue_winking_eye:

The funny thing is I don’t even understand what’s going on anymore.

No more beers for you

1 Like

:hash:Shitfaced_rebase… :laughing:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>99 Bottles of Beer on the Wall</title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Architects+Daughter&family=Aref+Ruqaa+Ink:wght@400;700&family=Bagel+Fat+One&family=Chela+One&family=Chilanka&family=Coiny&family=Ewert&family=Gamja+Flower&family=Gloria+Hallelujah&family=Indie+Flower&family=Life+Savers:wght@400;700;800&family=Nosifer&family=Patrick+Hand&family=Quicksand:wght@300;500;700&family=Rubik+Vinyl&family=Yomogi&display=swap" rel="stylesheet">
    <style>
        body {
            background-color: darkcyan;
            color: cyan;
            word-spacing: 5px;
            font-family: 'Architects Daughter', cursive;
            /*
            font-family: 'Chilanka', cursive;
            font-family: 'Gamja Flower', cursive;
            font-family: 'Indie Flower', cursive;
            */
            padding: 2%;
        }
        h1 {
            font-size: 3rem;
            text-shadow: 2px 2px 2px plum;
            letter-spacing: 1px;
            width: 55%;
            border-bottom: 5px double plum;
        }
        h2 {
            font-size: 2.5rem;
            text-shadow: 2px 2px 2px plum;
            letter-spacing: 1px;
        }
        p {
            font-size: 1.5rem;
            font-family: 'Chilanka', cursive;
            line-height: 1.5;
            text-shadow: 2px 2px 2px slateblue;
            width: 60%;
        }
        @media screen and (max-width: 1400px) {
            h1 {
                width: 70%;
            }
        }
        @media screen and (max-width: 1000px) {
            p {
                width: 80%;
            }
        }
        @media screen and (max-width: 800px) {
            h1 {
                width: 90%;
            }
            p {
                width: 100%;
            }
        }
    </style>
</head>
<body>
    <center>
        <h1>99 Bottles of Beer on the Wall</h1>
        <h2>Instructions:</h2>
        <p>Print the entire song of "99 Bottles of Beer on the wall" into the console.  The lyrics go like this:</p>
        <p>"99 Bottles of Beer on the wall, 99 Bottles of beer.  Take one down, pass it around, 98 Bottles of beer on the wall.</p>
        <p>98 Bottles of Beer on the wall, 98 Bottles of beer.  Take one down, pass it around, 97 Bottles of beer on the wall.</p>
        <p>97 Bottles of Beer on the wall, 97 Bottles of beer.  Take one down, pass it around, 96 Bottles of beer on the wall..."</p>
        <p>Keep repeating this until it gets to 1 Bottle (remember to use singular form for "beer").  The song ends like this:</p>
        <p>"...1 bottle of beer on the wall, 1 bottle of beer.  Take one down, pass it around, no more bottles of beer on the wall.</p>
        <p>No more bottles of beer on the wall, no more bottles of beer. Go to the store and buy some more, 99 bottles of beer on the wall."</p>
        <p>...and with this, the song starts over.  But it doesn't have to be repeated in the console; just one loop through the entire song is <i>plenty</i>!</p>
    </center>
    <script>
        for (let i = 99; i > 0; i--) {
            if (i > 1) {
                console.log(`${i} bottles of beer on the wall, ${i} bottles of beer. Take one down, pass it around, ${i-1} bottles of beer on the wall.`);
            } else {
                console.log(`${i} bottle of beer on the wall, ${i} bottle of beer. Take one down, pass it around, no more bottles of beer on the wall.`);
                console.log(`No more bottles of beer on the wall, no more bottles of beer. Go to the store and buy some more, 99 bottles of beer on the wall.`);
            }
        }
    </script>
</body>
</html>

for (let i = 100; i > 1;i--) {

document.writeln(i + " bottles of beer on the wall, " + i + " bottles of beer.<br> Take one down and pass it around, " +  (i - 1) + " bottles of beer on the wall. <br><br>" );
}

document.writeln("1 bottle of beer on the wall, 1 bottle of beer. <br> Take one down and pass it around, no more bottles of beer on the wall. <br> <br> No more bottles of beer on the wall, no more bottles of beer.<br> Go to the store and buy some more, 99 bottles of beer on the wall.")

thank you so much

You got the badge! :slight_smile: