Locked learning resources

Join us and get access to thousands of tutorials and a community of expert JavaScript developers.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert JavaScript developers.

Unlock This Lesson

Porting the Quote Lines

Porting the Quote Lines

In this lesson, you rebuilt most of the translator’s Python quote script in JavaScript, from the top down, with the pieces this course ported one at a time.

  • Her Python script, quote_lines.py, holds the rules in a turnaround helper, a quote function, two formatters, and a quote line that puts them together. Run with the day’s three requests, it prints a line each for Bauer Legal, Café Linde, and Nordwind GmbH.
  • The turnaround helper ports as it did the first time: def becomes function, the body goes in braces, and the math moves to Math.floor() and Math.max(). The early return stays inside the if block, so Bauer Legal’s rush job leaves early. rush gets its default, rush = false, as in Python.
  • JavaScript has no keyword arguments, so quote() takes one options object and destructures it by name, each option with its default. The = {} after the pattern lets a call skip the options object altogether.
  • In the body, the minimum uses Math.max(), and Python’s conditional expression becomes the conditional operator: the condition first, then a question mark and the two values. The days come from the turnaround helper, as in the defaults lesson.
  • Ported line by line, return fee, days would hand back only the days, so the pair goes in an array, return [fee, days];.
  • The check call for Bauer Legal’s quote without the rush, quote(6200), passes no options object at all, and it logs [ 744, 5 ]. The empty object stood in for the missing options, so every option took its default. The per-word fee clears the minimum, and each full 2,000 words adds a day to the two.
  • With the check line gone, Python’s euro formatting, f"€{amount:,.2f}", becomes a euro formatter made once with new Intl.NumberFormat() in the currency style. The "en-US" locale gives the € in front and the comma grouping Python’s format string writes. The email formatter is an arrow over that formatter’s .format() method. With no braces after the arrow, it returns that text without return.
  • quoteLine() takes the client and the word count by position, and its one option, rush, in an options object defaulting to an empty object, and it unpacks the pair as Python unpacks its tuple, with array destructuring.
  • Python passes the rush on by name, but in a JavaScript call, rush = rush would be an assignment, as in “Passing Options by Name”, and Bauer Legal would quietly lose its rush, so the port passes { rush }, written with shorthand. At the bottom, rush=True becomes { rush: true }. Written as an assignment, that call would stop with a ReferenceError, because this ES module runs in strict mode.
  • For now, the quote line calls the email formatter itself. Run the port, and the JavaScript prints Python’s first two lines, character for character.

Here’s the finished port:

Language: JavaScript
function workingDays(words, rush = false) {
  const days = 2 + Math.floor(words / 2000);
  if (rush) {
    return Math.max(Math.floor(days / 2), 1);
  }
  return days;
}

function quote(
  words,
  { rate = 0.12, rush = false, minimum = 40 } = {},
) {
  const base = Math.max(words * rate, minimum);
  const fee = rush ? base * 1.5 : base;
  const days = workingDays(words, rush);
  return [fee, days];
}

const euroFormat = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "EUR",
});
const forEmail = (amount) => euroFormat.format(amount);

function quoteLine(client, words, { rush = false } = {}) {
  const [fee, days] = quote(words, { rush });
  return `${client}: ${forEmail(fee)}, ${days} working days`;
}

console.log(quoteLine("Bauer Legal", 6200, { rush: true }));
console.log(quoteLine("Café Linde", 180));

Locked learning resources

Join us and get access to thousands of tutorials and a community of expert JavaScript developers.

Unlock This Lesson

Already a member? Sign-In

Locked learning resources

The full lesson is for members only. Join us and get access to thousands of tutorials and a community of expert JavaScript developers.

Unlock This Lesson

Already a member? Sign-In

00:02 The translator’s quote form needs all her rules in JavaScript, and you’ve ported every piece of them in this course. Here’s her whole Python script: the turnaround helper, the quote function, two formatters, and the quote line that puts them together.

00:17 In this lesson, you’ll rebuild most of it in JavaScript. Run it with the day’s three requests. It prints a line each for Bauer Legal, Café Linde, and Nordwind.

00:30 Your port aims at the first two. The sheet line is yours afterward.

00:37 Start at the top, with the turnaround helper you ported first. def becomes function, the body goes in braces, and the math moves to the Math.floor() and Math.max() calls.

00:49 The early return stays inside the if block, so Bauer Legal’s rush job leaves early, with half the days. And rush gets its default of false, as in Python, so a call can leave it out.

01:03 Next comes the quote function. In Python, a caller can pass the rate, rush, and minimum by name. JavaScript has no keyword arguments, so the port takes one options object and destructures it by name, each option with its default.

01:19 The empty object after it lets a call skip the options object. In the body, the minimum moves to Math.max(). Python’s conditional expression turns into the conditional operator: the condition first, then a question mark and the two values.

01:37 The days come from the helper, as in the defaults lesson. A line-by-line return would hand back only the days, as you saw when returning two results, so the pair goes in an array.

01:50 A check line at the bottom asks for Bauer Legal’s quote without the rush. The call passes no options object. What pair does it log? Your turn: pause the video and predict.

02:08 It logs 744 and 5.

02:12 The empty object stood in for the missing options, so every option took its default. The per-word fee clears the minimum, and each full 2,000 words adds a day to the two.

02:26 The check line is done. Next come the formatters. Python’s formatting, with its euro sign, comma and two decimals, becomes a euro formatter, made once in the currency style.

02:39 The email formatter is an arrow over that formatter’s format method. With no braces after the arrow, it returns that text without a return keyword. The sheet formatter waits for the exercise.

02:54 Then the quote line. It takes the client and the word count by position, and rush in an options object defaulting to an empty object. It unpacks the pair as Python does, with array destructuring.

03:08 Python passes the rush on by name, but in JavaScript, rush = rush would be an assignment, as you saw when passing options by name, and Bauer Legal would quietly lose its rush.

03:19 So the port builds a small object, written with shorthand. For now, the line calls the email formatter itself. The format option is the exercise’s. At the bottom, Bauer Legal’s rush becomes an options object.

03:35 Written as an assignment, that call would stop with a reference error. Café Linde’s call passes no options.

03:45 The port is complete for the first two lines. Will its lines match Python’s, character for character? Your turn: pause the video and predict.

04:00 Run it. They match. Bauer Legal pays 1,116 euros for two working days, and Café Linde pays the minimum.

04:11 Each Python habit took its JavaScript form: an array for the pair, an options object for the names, and arrows for the small formatters.

04:21 Next up is Finish the Quote Lines, an exercise. You’ll add the sheet formatter, the quote line’s format option with the email formatter as its default, and the Nordwind GmbH line, so your port prints all three lines.

Become a Member to join the conversation.