cf.completefrontendCode editorOpen lab
THE JAVASCRIPT FIELD GUIDE

Thinking like a developer

Learn the developer habit of restating a problem, planning with pseudocode, building small functions, and testing assumptions before trusting your code.

By the end, you’ll be able to
  • 01
    Restate a problem clearlyName the inputs, output, examples, and constraints before you code.
  • 02
    Turn a plan into small functionsUse pseudocode to split one task into testable helper functions.
  • 03
    Check assumptions earlyTry normal cases and edge cases so surprises appear while the code is still small.

The developer habit

New developers often ask, “What code do I write?” Experienced developers ask one question earlier: what problem am I actually solving? That pause is not procrastination. It is the habit that keeps you from typing ten lines, discovering the target moved, and then deleting them.

In this lesson we will solve one small problem all the way through: split a restaurant bill with a tip. The inputs are the bill amount, the tip percent, and the number of people. The output is the amount each person should pay, rounded to two decimal places (paise for rupee values). We will restate the problem, write pseudocode, turn the plan into small functions, and test assumptions with real JavaScript.

The short version

Thinking like a developer means turning a fuzzy request into a clear input, output, plan, and set of checks before you trust the code.

Real-life analogyPlanning a road trip

If you want to drive somewhere new, you do not start by pressing random pedals. You pick the destination, check where you are, note constraints, then choose a route. Coding is similar: destination first, route second, typing third.

In real life: Destination
In JavaScript: The output you need
In real life: Starting point and passengers
In JavaScript: The inputs you receive
In real life: Fuel, tolls, and road closures
In JavaScript: Constraints and edge cases
In real life: Stops on the route
In JavaScript: Pseudocode steps and helper functions

Where the analogy stops: A trip plan can change while you drive. A program follows the instructions you wrote, so unclear steps become wrong results until you change the code.

This lesson is the last stop in Stage 1. You have already seen first programs, the console, code structure, strict mode, browser interaction, style, linting, and debugging. The next stage starts with variables in depth. Here we use a few simple functions and if checks early, but only as tools for problem solving. Full lessons on functions, control flow, and loops come later.

Understanding the problem

SORT

The first job is not to write JavaScript. It is to turn the request into plain language that can be checked. A good restatement names four things:

  • Inputs: the information the code receives.
  • Output: the answer the code should produce.
  • Examples: concrete numbers worked by hand.
  • Constraints: rules and limits, especially awkward ones.
Restated problemText
// Problem statement// Given a bill amount, tip percent, and number of people,// return how much each person pays, rounded to two decimal places. // Example: bill 80, tip 20%, people 4 -> 24

Work one example by hand before you code. For a bill of 80, a 20% tip adds 16, making the total 96. Four people share it, so each person pays 24. That example becomes your first reality check. If your code gives 20, 96, or 2400, you know which step probably went wrong.

Input, output, or constraint?
  • The bill amount, such as 80
  • The tip percent, such as 20
  • The number of people sharing the bill
  • The amount each person pays
  • Print or return 24 for the hand-worked example
  • Round the answer to two decimal places
  • There must be at least one person
Try it yourself
0 of 7 correct

Sort each piece of the bill problem. This is how you train your eye before writing code.

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Good clarifying questions are not annoying; they are part of the work. Ask: Should the bill ever be negative? Is a negative tip allowed? What should happen if there are zero people? Do we round each person’s share or the total bill? If nobody can answer yet, write down your assumption so you can test it.

Pseudocode: a recipe before syntax

INTERACTIVE

Pseudocode is a plan written in ordinary words. It is not JavaScript, so the browser will not run it. That is the point: you can focus on the order of the steps without worrying about commas, parentheses, or exact function names.

Real-life analogyPseudocode is a recipe draft

Before cooking a new dish, you might sketch the recipe: chop vegetables, heat the pan, add sauce, taste. You are not measuring every gram yet. You are checking that the steps make sense in order.

In real life: List ingredients
In JavaScript: Name the inputs
In real life: Write cooking steps
In JavaScript: Write the algorithm in plain words
In real life: Taste and adjust
In JavaScript: Test assumptions and edge cases

Where the analogy stops: A recipe can say “cook until done,” but a program needs exact rules. Pseudocode is a bridge, not the finished code.

Bill splitter pseudocodePseudocode
Start with the bill amount, tip percent, and number of people.Check that the number of people is more than 0.Add the tip to get the total.Divide the total by the number of people.Round the answer to two decimal places.Return the amount each person pays.

The order matters. You cannot split before the total includes the tip, and you should not round before dividing because the smallest currency unit can move around. Try putting the plan back together below.

Plan the steps before code
Plain-English planPseudocode
Start with the bill amount, tip percent, and number of people.Check that the number of people is more than 0.Add the tip to get the total.Divide the total by the number of people.Round the answer to two decimal places.Return the amount each person pays.
Shuffled stepskeep planning
  1. Divide the total by the number of people.
  2. Restate the goal: amount per person, rounded to two decimal places.
  3. Try normal cases and edge cases.
  4. Add the tip to get the total.
  5. Round the answer to two decimal places.
  6. Work one example by hand: 80 + 20% = 96, then 96 / 4 = 24.
Try it yourself
1 of 6 in the best spot

Work one example by hand before choosing code steps. It gives you numbers to compare with.

Reorder the plan with buttons. The feedback points out dependency problems, like trying to split before the tip has been added.

If you get stuck, rubber-duck the plan: explain it out loud to a person, a pet, or a literal rubber duck. Saying “then I divide by people” often makes the missing check obvious: what if people is 0?

Small functions are LEGO bricks

STEP THROUGH

Now turn the pseudocode into JavaScript. A function is a named chunk of code you can call with inputs and get a return value from. A small function does one job: add a tip, split a total, or round a number. When each brick is simple, the whole build is easier to test and debug.

Real-life analogySmall functions are LEGO bricks

You can build a big model from many small bricks. If one brick is wrong, you replace that brick instead of melting the whole model. Small functions give your code the same advantage.

In real life: One brick has a simple shape
In JavaScript: One function has one clear job
In real life: A model is built by combining bricks
In JavaScript: A program combines helper functions
In real life: A broken brick is easy to spot
In JavaScript: A small function is easy to test

Where the analogy stops: Real LEGO bricks never surprise you. Functions can, especially when inputs are unexpected, so you still need tests.

Small function versionPop out in the code editor (opens in a new tab)JavaScript
function addTip(bill, tipPercent) {  return bill + (bill * tipPercent) / 100;} function splitBill(total, people) {  return total / people;} function roundCurrency(amount) {  return Math.round(amount * 100) / 100;} function calculateShare(bill, tipPercent, people) {  const totalWithTip = addTip(bill, tipPercent);  const each = splitBill(totalWithTip, people);  return roundCurrency(each);} console.log(calculateShare(80, 20, 4));

Step through the same code. The “Running in” label shows which helper is currently being recorded. This is a guided replay of our instrumented example, not a full browser debugger, but every value is produced by the real functions.

Step through the helper functions
Step 0 of 12Ready
Your turn: follow the blue line

Predict the amount per person. Then step through the helper calls and watch the plan become real values.

Running in
  1. script
Next: line 17
Click the blue line to take the next stepPop out in the code editor (opens in a new tab)JavaScript
function addTip(bill, tipPercent) {  return bill + (bill * tipPercent) / 100;} function splitBill(total, people) {  return total / people;} function roundCurrency(amount) {  return Math.round(amount * 100) / 100;} function calculateShare(bill, tipPercent, people) {  const totalWithTip = addTip(bill, tipPercent);  const each = splitBill(totalWithTip, people);  return roundCurrency(each); console.log(calculateShare(80, 20, 4));
CallStoreChangeResultRun = next line. Ran = already executed.
Recent returnsNothing yet. Start with the blue line.
Choose the input values for line 17

Changing the inputs starts a fresh recording. Try the zero-people case after the normal one.

A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.
Make it work, then make it right

First make a tiny version work for the normal example. Then make it right: improve names, split helpers, add guards, and test edge cases. “Make it work” is not permission to ignore bugs; it is permission to learn from a small working slice before polishing.

Testing your assumptions

INTERACTIVE

Assumptions are quiet bugs. The first bill splitter assumes people is more than 0, the tip is not negative, and rounding to two decimal places is enough. Real JavaScript will not always complain when those assumptions are false. It may give you a value like Infinity and keep going.

Tasting the soup

Testing assumptions is like tasting soup as you cook. You do not wait until the bowl reaches the table to find out whether you forgot salt. Try a normal case, a small case, a large case, and the awkward case you hope never happens.

Guard checks before the mathPop out in the code editor (opens in a new tab)JavaScript
function calculateShareGuarded(bill, tipPercent, people) {  if (people <= 0) return "Add at least one person";  if (bill < 0) return "Bill must be zero or more";  if (tipPercent < 0) return "Tip cannot be negative";   const totalWithTip = addTip(bill, tipPercent);  const each = splitBill(totalWithTip, people);  return roundCurrency(each);}

The first three lines inside the function are guards. An if asks a yes-or-no question. If the condition is true, return stops the function early with a clear message. You will learn if fully in Stage 2; here it is a safety gate before the math.

Test assumptions against real outputs
Guarded versionPop out in the code editor (opens in a new tab)JavaScript
function calculateShareGuarded(bill, tipPercent, people) {  if (people <= 0) return "Add at least one person";  if (bill < 0) return "Bill must be zero or more";  if (tipPercent < 0) return "Tip cannot be negative";   const totalWithTip = addTip(bill, tipPercent);  const each = splitBill(totalWithTip, people);  return roundCurrency(each);}
Real outputs2 cases
CaseExpectedUnsafeGuarded
Normal dinner242424
Thirds need rounding3.333.333.33
Try it yourself

The unsafe function is useful for learning because it shows real JavaScript surprises. The guarded version checks assumptions before doing the math.

Toggle edge cases. Infinity and negative totals are not syntax errors, but they are wrong answers for this problem.

Notice the difference between a JavaScript error and a problem-domain error. 90 / 0 is valid JavaScript and produces Infinity. It is still the wrong answer to “split this bill.” Testing connects the language’s behavior to the real-world meaning you need.

Where you’ll use this

This habit appears everywhere in front-end work. Before you write code for a form, restate what the form needs: inputs, output, constraints, and examples. Before you debug, restate what you expected, what actually happened, and the smallest step that could explain the gap.

Problem-solving moves in everyday JavaScript
SituationQuestion to askSmall next step
A button should show a menuWhat state changes when the button is clicked?Name the state, then log it before changing the page
A form rejects good inputWhich constraint is failing?Try one input and print the rule result
A calculation is off by a centWhere exactly do we round?Work one example by hand and compare every step
A bug report says it is brokenWhat are the exact inputs and output?Ask for a reproduction, then reduce it to a tiny case

You can also use this lesson with the published debugging lessons. First use the Code structure habit of reading top to bottom. Then use your browser console from the Interaction lesson, and when code gets bigger, use the browser debugger to inspect one assumption at a time.

Common misconceptions

“Real developers just know the code immediately.”

Professionals spend a lot of time clarifying, sketching examples, and deleting first attempts. Thinking before typing is part of the job.

“Pseudocode is wasted time because it does not run.”

That is its strength. It lets you fix the plan while changes are cheap, before syntax details hide the bigger mistake.

“One big function is simpler.”

It can feel simpler at first, but it is harder to test. Small helpers let you ask, “Did adding the tip work?” without running the whole program.

“If JavaScript did not throw an error, the answer is okay.”

JavaScript may produce Infinity, NaN, or a surprising rounded number. The language result still needs to match the problem.

“Tests are only for finished code.”

Tiny tests are useful while you are still thinking. A hand-worked example and a console output can guide the next line you write.

Plan, pseudocode, and code
ItemWhat it answersExample
RestatementWhat are we solving?Split a tipped bill into a per-person amount
PseudocodeWhat are the steps?Add tip, divide by people, round
JavaScriptHow does the computer do it exactly?return Math.round(amount * 100) / 100;

Practice: solve before typing

5 EXERCISES
Exercise 1 · Warm-upWrite pseudocode for a snack order

A shop needs a total for one kind of snack: price, quantity, and tax percent go in; total price comes out. Write pseudocode before code.

    Exercise 2 · PracticeImplement one small function

    Paste the starter code into your console or editor. It should print the result of addTip(50, 20). Type the number it should return.

    Starter codePop out in the code editor (opens in a new tab)JavaScript
    function addTip(bill, tipPercent) {
      return bill + (bill * tipPercent) / 100;
    }
    console.log(addTip(50, 20));

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticeFind the unhandled edge case

      Predict the real output. Do not answer what the function should do; answer what this unguarded JavaScript actually prints.

      Starter codePop out in the code editor (opens in a new tab)JavaScript
      function splitBill(total, people) {
        return total / people;
      }
      console.log(splitBill(90, 0));

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · PracticeWrite three test cases

        Write three cases you would use before trusting the bill splitter. Include the inputs and expected output for each one.

          Exercise 5 · ChallengeFix a rounding assumption

          The final answer should be rounded to two decimal places, not whole rupees. What should this program print?

          Starter codePop out in the code editor (opens in a new tab)JavaScript
          function roundCurrency(amount) {
            return Math.round(amount * 100) / 100;
          }
          console.log(roundCurrency(10 / 3));

          Answer, then press Check. Spacing and letter case don’t matter.

            Quiz: check your understanding

            7 QUESTIONS

            Every choice explains itself. If you miss one, read the explanation and tie it back to the plan: inputs, output, steps, assumptions.

            Lesson quiz · 7 questionsScore: first tries count
            1. Question 1 of 7What is the first thing to do when a coding problem feels fuzzy?

              Choose an answer to see the explanation.

            2. Question 2 of 7In the bill example, which item is an output?

              Choose an answer to see the explanation.

            3. Question 3 of 7What does this program print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              function splitBill(total, people) {
                return total / people;
              }
              console.log(splitBill(90, 0));

              Choose an answer to see the explanation.

            4. Question 4 of 7Why write pseudocode before JavaScript?

              Choose an answer to see the explanation.

            5. Question 5 of 7What does the rounding program print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              function roundCurrency(amount) {
                return Math.round(amount * 100) / 100;
              }
              console.log(roundCurrency(10 / 3));

              Choose an answer to see the explanation.

            6. Question 6 of 7Which helper has the smallest single job?

              Choose an answer to see the explanation.

            7. Question 7 of 7Which assumption should you test before trusting the first bill splitter?

              Choose an answer to see the explanation.

            Key takeaways

            • Restate the problem before coding: inputs, output, examples, constraints.
            • Pseudocode is plain-language planning. It keeps syntax out of the way.
            • Small functions are easier to name, test, debug, and reuse.
            • Test assumptions with normal cases and edge cases; valid JavaScript can still be the wrong answer.
            • Rubber-duck explanations and hand-worked examples reveal missing steps quickly.

            Remember the one-liner.
            A developer turns “make it work” into a clear target, a small plan, and checks that prove the result.

            Up next: Variables: let, const & var.

            CompleteFrontend Clear concepts. Working examples.