Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 80
}
105 changes: 105 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

28 changes: 28 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"name": "c55-core-week-6",
"version": "1.0.0",
"description": "The week 6 assignment for the HackYourFuture Core program can be found at the following link: https://hub.hackyourfuture.nl/core-program-week-6-assignment",
"main": "index.js",
"scripts": {
"format": "prettier --write .",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/noneeeed/c55-core-week-6.git"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "module",
"bugs": {
"url": "https://github.com/noneeeed/c55-core-week-6/issues"
},
"homepage": "https://github.com/noneeeed/c55-core-week-6#readme",
"dependencies": {
"chalk": "^4.1.2"
},
"devDependencies": {
"prettier": "^3.8.1"
}
}
30 changes: 30 additions & 0 deletions reading-list-manager/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,33 @@
console.log('📚 MY READING LIST 📚\n');

// Your implementation here
import {
printAllBooks,
printSummary,
getUnreadBooks,
addBook,
books,
getBooksByGenre,
markAsRead,
} from './readingList.js';
import chalk from 'chalk';

console.log('All Books:');
printAllBooks();
printSummary();

console.log(chalk.bold('\nUnread books:'));
console.log(getUnreadBooks());
console.log(chalk.bold('\nBooks by genre (fiction):'));
console.log(getBooksByGenre('fiction'));
const newBook = addBook({
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done using the other methods! ⭐

title: 'The Catcher in the Rye',
author: 'J.D. Salinger',
genre: 'fiction',
read: false,
});
console.log('New Book Added!)');
console.log('Current Library:', books);
console.log(chalk.bold('\nAfter marking new book as read:'));
markAsRead(6);
printAllBooks();
38 changes: 37 additions & 1 deletion reading-list-manager/books.json
Original file line number Diff line number Diff line change
@@ -1 +1,37 @@
[]
[
{
"id": 1,
"title": "The Great Gatsby",
"author": "F. Scott Fitzgerald",
"genre": "Novel",
"read": true
},
{
"id": 2,
"title": "To Kill a Mockingbird",
"author": "Harper Lee",
"genre": "Novel",
"read": false
},
{
"id": 3,
"title": "1984",
"author": "George Orwell",
"genre": "fiction",
"read": true
},
{
"id": 4,
"title": "Moby Dick",
"author": "Herman Melville",
"genre": "fiction",
"read": false
},
{
"id": 5,
"title": "Pride and Prejudice",
"author": "Jane Austen",
"genre": "Romance",
"read": true
}
]
101 changes: 77 additions & 24 deletions reading-list-manager/readingList.js
Original file line number Diff line number Diff line change
@@ -1,53 +1,106 @@
// Place here the file operation functions for loading and saving books
import fs from 'node:fs';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This import will also work with just import fs from 'fs'; It's not necessary to specify node:

import chalk from 'chalk';

function loadBooks() {
// TODO: Implement this function
// Read from books.json
// Handle missing file (create empty array)
// Handle invalid JSON (notify user, use empty array)
// Use try-catch for error handling
try {
const books = fs.readFileSync('books.json', 'utf8');
return JSON.parse(books);
} catch (error) {
if (error.code === 'ENOENT') {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good use of catching different error types and handling it accordingly ⭐

console.log('books.json not found. Creating an empty array.');
return [];
} else {
console.log('Error reading books.json:', error.message);
return [];
}
}
}
const books = loadBooks();

function saveBooks(books) {
// TODO: Implement this function
// Write books array to books.json
// Use try-catch for error handling
try {
const booksArray = JSON.stringify(books, null, 2);
fs.writeFileSync('books.json', booksArray, 'utf8');
} catch (error) {
console.log('Error saving books.json:', error.message);
}
}

function addBook(book) {
// TODO: Implement this function
const maxId = books.reduce((max, b) => (b.id > max ? b.id : max), 0);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice use of reduce() to calculate the id

const newBook = { ...book, id: maxId + 1 };
books.push(newBook);
saveBooks(books);
}

function getUnreadBooks() {
// TODO: Implement this function using filter()
const unreadBooks = books.filter((book) => !book.read);
return unreadBooks.map((book) => book.title);
}

function getBooksByGenre(genre) {
// TODO: Implement this function using filter()
const booksByGenre = books.filter(
(book) => book.genre.toLowerCase() === genre.toLowerCase()
);
return booksByGenre.map((book) => book.title);
}

function markAsRead(id) {
// TODO: Implement this function using map()
const markRead = books.map((book) => {
if (book.id === id) {
return { ...book, read: true };
}
return book;
});
for (let i = 0; i < markRead.length; i++) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This for loop can be removed. map() returns a new array. This can be passed to saveBooks().

More info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map

books[i] = markRead[i];
}
saveBooks(books);
return books;
}

function getTotalBooks() {
// TODO: Implement this function using length
return books.length;
}

function hasUnreadBooks() {
// TODO: Implement this function using some()
return books.some((book) => !book.read);
}

function printAllBooks() {
// TODO: Implement this function
// Loop through and display with chalk
// Use green for read books, yellow for unread
// Use cyan for titles
books.forEach((book) => {
const title = chalk.cyan(
`${book.id}. ${book.title} by ${book.author} (${book.genre})`
);
if (book.read) {
console.log(chalk.green(`${title} ✓ Read`));
} else {
console.log(chalk.yellow(`${title} ⚠ Unread`));
}
});
}

function printSummary() {
// TODO: Implement this function
// Show statistics with chalk
// Display total books, read count, unread count
// Use bold for stats
}
const total = getTotalBooks();
const readCount = books.filter((book) => book.read).length;
const unreadCount = getUnreadBooks().length;

console.log(chalk.bold('\n📊 SUMMARY 📊'));
console.log(chalk.bold(`Total Books: ${total}`));
console.log(chalk.bold.green(`Read: ${readCount}`));
console.log(chalk.bold.yellow(`Unread: ${unreadCount}`));
}

export {
loadBooks,
saveBooks,
addBook,
books,
getUnreadBooks,
getBooksByGenre,
markAsRead,
getTotalBooks,
hasUnreadBooks,
printAllBooks,
printSummary,
};