From 590b1d118430cbcbced8f00185d6eef48ff4190c Mon Sep 17 00:00:00 2001 From: Diana Chukhrai Date: Wed, 18 Feb 2026 22:53:03 +0100 Subject: [PATCH 1/2] task completed --- .prettierignore | 1 + .prettierrc | 9 +++ package-lock.json | 105 ++++++++++++++++++++++++ package.json | 27 +++++++ reading-list-manager/app.js | 34 ++++++-- reading-list-manager/books.json | 45 ++++++++++- reading-list-manager/readingList.js | 121 +++++++++++++++++++++++----- 7 files changed, 314 insertions(+), 28 deletions(-) create mode 100644 .prettierignore create mode 100644 .prettierrc create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ + diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..23fb4a6 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,9 @@ + +{ + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "es5", + "printWidth": 80 +} + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..5707c1a --- /dev/null +++ b/package-lock.json @@ -0,0 +1,105 @@ +{ + "name": "c55-core-week-6", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "c55-core-week-6", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "chalk": "^4.1.2" + }, + "devDependencies": { + "prettier": "^3.8.1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/prettier": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..88c4ddb --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "devDependencies": { + "prettier": "^3.8.1" + }, + "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": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/dianadenwik/c55-core-week-6.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "module", + "bugs": { + "url": "https://github.com/dianadenwik/c55-core-week-6/issues" + }, + "homepage": "https://github.com/dianadenwik/c55-core-week-6#readme", + "dependencies": { + "chalk": "^4.1.2" + } +} diff --git a/reading-list-manager/app.js b/reading-list-manager/app.js index b0365ef..c0826f1 100644 --- a/reading-list-manager/app.js +++ b/reading-list-manager/app.js @@ -1,13 +1,37 @@ // This is the entrypoint for your application. // node app.js -// TODO: Implement the main application logic here +// Your implementation here + +import chalk from 'chalk'; + +import { + loadBooks, + printAllBooks, + printSummary, + getUnreadBooks, + getBooksByGenre, + markAsRead, + hasUnreadBooks, + addBook, +} from './readingList.js'; + // 1. Load books on startup +loadBooks(); +console.log('šŸ“š MY READING LIST šŸ“š\n'); + // 2. Display all books +printAllBooks(); + // 3. Show summary statistics -// 4. Add example of filtering by genre or read/unread status -// 5. Add example of marking a book as read +printSummary(); -console.log('šŸ“š MY READING LIST šŸ“š\n'); +// 4. 4. Add example of filtering by genre or read/unread status +console.log(chalk.bold('\nšŸ“– Unread Books:')); +const unread = getUnreadBooks(); +console.log(unread); + +console.log(chalk.bold('\nšŸ” Sci-Fi Books:')); +const scifi = getBooksByGenre('Sci-Fi'); +console.log(scifi); -// Your implementation here diff --git a/reading-list-manager/books.json b/reading-list-manager/books.json index 0637a08..397f17e 100644 --- a/reading-list-manager/books.json +++ b/reading-list-manager/books.json @@ -1 +1,44 @@ -[] \ No newline at end of file +[ + { + "id": 1, + "title": "1984", + "author": "George Orwell", + "genre": "Fiction", + "read": false + }, + { + "id": 2, + "title": "Dune", + "author": "Frank Herbert", + "genre": "Sci-Fi", + "read": true + }, + { + "id": 3, + "title": "The Hobbit", + "author": "J.R.R. Tolkien", + "genre": "Fantasy", + "read": true + }, + { + "id": 4, + "title": "The Great Gatsby", + "author": "F. Scott Fitzgerald", + "genre": "Fiction", + "read": true + }, + { + "id": 5, + "title": "Brave New World", + "author": "Aldous Huxley", + "genre": "Sci-Fi", + "read": false + }, + { + "id": 6, + "title": "Harry Potter", + "author": "J.K. Rowling", + "genre": "Fantasy", + "read": true + } +] \ No newline at end of file diff --git a/reading-list-manager/readingList.js b/reading-list-manager/readingList.js index 84febab..837770f 100644 --- a/reading-list-manager/readingList.js +++ b/reading-list-manager/readingList.js @@ -1,53 +1,130 @@ // Place here the file operation functions for loading and saving books +import fs from 'node:fs' +import path from 'node:path' +import chalk from 'chalk' + +const dataDir = '.' +const BOOKS = path.join(dataDir, 'books.json') + + + 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 data = fs.readFileSync(BOOKS, 'utf-8') + return JSON.parse(data) + } catch (error) { + if (error.code === 'ENOENT') { + console.log('books.json not found. Starting with empty list.') + return [] + } + if (error.name === "SyntaxError") { + console.log('Invalid JSON in books.json. Starting with empty list.') + return [] + } + throw error + } } + + function saveBooks(books) { - // TODO: Implement this function - // Write books array to books.json - // Use try-catch for error handling + try { + fs.writeFileSync(BOOKS, JSON.stringify(books, null, 2)) + } catch (error) { + console.log('Error saving books:', error.message) + } } + function addBook(book) { - // TODO: Implement this function + const books = loadBooks() + books.push(book) + saveBooks(books) } + + function getUnreadBooks() { - // TODO: Implement this function using filter() + const books = loadBooks() + return books.filter(function(book) { + return book.read === false + }) } function getBooksByGenre(genre) { - // TODO: Implement this function using filter() + const books = loadBooks() + return books.filter(function(book) { + return book.genre === genre + }) } + function markAsRead(id) { - // TODO: Implement this function using map() + const books = loadBooks() + + const updatedBooks = books.map(function(book) { + if (book.id === id) { + return { ...book, read: true } + } + return book + }) + + saveBooks(updatedBooks) } + + function getTotalBooks() { - // TODO: Implement this function using length + const books = loadBooks() + return books.length } function hasUnreadBooks() { - // TODO: Implement this function using some() + const books = loadBooks() + return books.some(function(book) { + return book.read === false + }) } function printAllBooks() { - // TODO: Implement this function - // Loop through and display with chalk - // Use green for read books, yellow for unread - // Use cyan for titles + const books = loadBooks() + + console.log('\nAll Books:') + + books.forEach(function(book) { + const title = chalk.cyan(book.title) + const info = `${book.id}. ${title} by ${book.author} (${book.genre})` + + if (book.read === true) { + console.log(chalk.green(info + ' āœ“ Read')) + } else { + console.log(chalk.yellow(info + ' ⚠ 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 unread = getUnreadBooks().length + const read = total - unread + + console.log(chalk.bold('\nšŸ“Š SUMMARY šŸ“Š')) + console.log(chalk.bold('Total Books: ' + total)) + console.log(chalk.bold.green('Read: ' + read)) + console.log(chalk.bold.yellow('Unread: ' + unread)) +} + + +export { + loadBooks, + saveBooks, + addBook, + getUnreadBooks, + getBooksByGenre, + markAsRead, + getTotalBooks, + hasUnreadBooks, + printAllBooks, + printSummary } \ No newline at end of file From 0ff61544d8b92bbd498bdde5aa9487e39c928ea6 Mon Sep 17 00:00:00 2001 From: Diana Chukhrai Date: Wed, 18 Feb 2026 23:15:22 +0100 Subject: [PATCH 2/2] task completed --- reading-list-manager/readingList.js | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/reading-list-manager/readingList.js b/reading-list-manager/readingList.js index 837770f..00f6877 100644 --- a/reading-list-manager/readingList.js +++ b/reading-list-manager/readingList.js @@ -47,29 +47,24 @@ function addBook(book) { function getUnreadBooks() { const books = loadBooks() - return books.filter(function(book) { - return book.read === false - }) + return books.filter((book) => book.read === false) } function getBooksByGenre(genre) { const books = loadBooks() - return books.filter(function(book) { - return book.genre === genre - }) + return books.filter((book) => book.genre === genre) } function markAsRead(id) { const books = loadBooks() - - const updatedBooks = books.map(function(book) { + const updatedBooks = books.map((book) => { if (book.id === id) { - return { ...book, read: true } + return { ...book, read: true } } - return book + return book }) - + saveBooks(updatedBooks) } @@ -82,20 +77,18 @@ function getTotalBooks() { function hasUnreadBooks() { const books = loadBooks() - return books.some(function(book) { - return book.read === false - }) + return books.some((book) => book.read === false) } + function printAllBooks() { const books = loadBooks() console.log('\nAll Books:') - - books.forEach(function(book) { + books.forEach((book) => { const title = chalk.cyan(book.title) const info = `${book.id}. ${title} by ${book.author} (${book.genre})` - + if (book.read === true) { console.log(chalk.green(info + ' āœ“ Read')) } else {