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:
defbecomesfunction, the body goes in braces, and the math moves toMath.floor()andMath.max(). The earlyreturnstays inside theifblock, so Bauer Legal’s rush job leaves early.rushgets 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, dayswould 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 withnew 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 withoutreturn. 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 = rushwould 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=Truebecomes{ rush: true }. Written as an assignment, that call would stop with aReferenceError, 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:
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));