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 Night-Bus Report

Porting the Night-Bus Report

In this project, you ported the night-bus report’s first three sections from Python to JavaScript, and left the supervisors for the exercise.

  • The data carries over with property names unquoted and lowercase false and true. The lists become const arrays. The routes are listed busiest first, by riders.
  • Every loop header declares its variable: for (const trip of trips). Python’s loop creates the name for you, but JavaScript’s doesn’t. Leave the const out, and the module stops with ReferenceError: trip is not defined, because ES modules run in strict mode.
  • .append() becomes .push(), and enumerate(late, start=1) becomes late.entries(), with index + 1 where a person reads the number.
  • Objects have no fromkeys(), so a short loop starts each route at 0. Python’s .items() becomes Object.entries(), destructured in the header. Route names keep their order in an object; number-like keys, such as hours, come out sorted, and a Map keeps them in order.
  • JavaScript loops have no else. Ported with } else { after the loop, the file stops with SyntaxError: Unexpected token 'else'. JavaScript checks the whole file before it runs any of it, so even the sections above the loop don’t print. A loop that only searches becomes .find(), which returns undefined when nothing matches, so an ordinary if...else takes over.

Here are the report’s sections in JavaScript, as you left them. They read last night’s trips, which the full file at the end of this page lists:

Language: JavaScript
const routes = ["N3", "N7", "N26"]; // busiest first
const supervisors = ["Priya", "Joel", "Marta"];

// Late departures, numbered for the morning call
const late = [];
for (const trip of trips) {
  if (trip.delay > 0) {
    const where = `${trip.route} left ${trip.stop}`;
    late.push(`${where} ${trip.delay} min late`);
  }
}
for (const [index, line] of late.entries()) {
  console.log(`${index + 1}. ${line}`);
}

// Delay totals per route
const totals = {};
for (const route of routes) {
  totals[route] = 0;
}
for (const trip of trips) {
  totals[trip.route] += trip.delay;
}
for (const [route, total] of Object.entries(totals)) {
  console.log(`${route}: ${total} min late in total`);
}

// The first canceled trip on the busiest route
const busiest = routes[0];
const first = trips.find(
  (trip) => trip.route === busiest && trip.canceled,
);
if (first !== undefined) {
  console.log(`Canceled on ${busiest}: ${first.departs}`);
} else {
  console.log(`No canceled trips on ${busiest}`);
}

// Each route's supervisor: your turn in the exercise

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:01 In this project, you’ll port the whole night-bus report to JavaScript, one section at a time, with the loops you’ve learned. Here’s the Python script the team runs every morning.

00:13 At the top are last night’s trips: eleven departures on three routes. Then the routes, busiest first by riders, and the supervisor on duty for each. Below them, the report has four sections, each a loop you’ve already ported on its own.

00:29 Run it, and Python prints the morning report. You’ll rebuild the first three sections here, and pair up the supervisors yourself in the exercise that follows.

00:43 In the JavaScript file, the data ports the way you’ve seen. Property names lose their quotes, and Python’s False becomes lowercase false. The two lists become const arrays.

00:58 The first section collects the late trips. Port its loop at speed, and it’s tempting to keep the header the way Python wrote it. Node stops on that line: ReferenceError, trip is not defined.

01:13 Python’s loop creates trip for you. JavaScript’s doesn’t, and a module runs in strict mode, so the loop variable needs its const. Inside the loop, append becomes push, and the f-strings become template literals.

01:29 Then Python’s enumerate numbers the lines. JavaScript asks the array for its entries, and adds one where a person reads the number. Run it, and Node prints the same five late departures as Python.

01:46 The next section totals the delays per route.

01:51 Python starts every route at zero with fromkeys.

01:56 A JavaScript object has no fromkeys, so a short loop sets each route to zero.

02:03 The loop that adds each trip’s delay ports line for line. To print the pairs, Python’s items becomes Object.entries, and the header destructures each pair into a route and its total.

02:18 Node prints the three totals in Python’s order. Route names like N3 aren’t number-like, so the object keeps them in the order they went in. Hours as keys would come out sorted, and that’s a job for a Map.

02:34 The third section looks for the first canceled trip on the busiest route, the first in the list.

02:42 Python’s loop ends in an else, for when no trip matches.

02:49 Port it line by line, else and all. Node rejects the whole file: SyntaxError, unexpected token else. Node checks the whole file before it runs any of it, so not even the first two sections print.

03:05 JavaScript loops have no else. This loop only searches, so ask the array instead. Find takes an arrow function that checks the route and the canceled flag, joined with a double ampersand.

03:21 When nothing matches, find returns undefined, so an ordinary if and else takes over the loop’s else. Node prints the report’s first three sections, down to the trip canceled at ten past midnight.

03:37 One section is left. Python’s zip pairs each route with its supervisor, and it stops at the end of the shorter list. JavaScript has no zip, so you’ll write the pairing yourself, and choose where it stops.

03:51 So here’s the report the JavaScript way. Every loop declares its variable.

03:59 Entries gives you positions, and Object.entries gives you an object’s pairs. And a search that Python ends with else becomes find, with a check for undefined.

04:11 Next up is the exercise, Finish the Night-Bus Report. There, you’ll pair the routes with their supervisors and run the whole report in Node.

Become a Member to join the conversation.