From 5b4aeb4323908cb91084c02db53aca9e7794dcc2 Mon Sep 17 00:00:00 2001 From: Muna Nasher Date: Wed, 18 Feb 2026 22:00:21 +0100 Subject: [PATCH] MunaNasher --- .hyf/README.md | 2 +- .hyf/score.example.json | 2 +- .prettierrc | 7 ++ README.md | 8 ++- package-lock.json | 105 ++++++++++++++++++++++++++++ package.json | 27 +++++++ reading-list-manager/app.js | 13 +++- reading-list-manager/books.json | 38 +++++++++- reading-list-manager/readingList.js | 96 +++++++++++++++++++------ 9 files changed, 268 insertions(+), 30 deletions(-) create mode 100644 .prettierrc create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.hyf/README.md b/.hyf/README.md index 38f1a4d..7475329 100644 --- a/.hyf/README.md +++ b/.hyf/README.md @@ -1,6 +1,7 @@ # Auto grade tool ## How it works + 1. The auto grade tool runs the `test.sh` script located in this directory. 2. `test.sh` should write to a file named `score.json` with following JSON format: ```json @@ -12,4 +13,3 @@ ``` All scores are out of 100. It is up to the assignment to determine how to calculate the score. 3. The auto grade runs via a github action on PR creation and updates the PR with the score. - diff --git a/.hyf/score.example.json b/.hyf/score.example.json index 8d931f5..e048aec 100644 --- a/.hyf/score.example.json +++ b/.hyf/score.example.json @@ -2,4 +2,4 @@ "score": 75, "pass": true, "passingScore": 50 -} \ No newline at end of file +} diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..b0ec5b3 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "es5", + "printWidth": 80 +} diff --git a/README.md b/README.md index c0b5992..9dcb586 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # Core program week 6 assignment + 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 ## Implementation Instructions -- Implement the requirements in the `reading-list-manager` folder. -- Use the existing file structure. -- You are allowed to create additional files if needed. \ No newline at end of file + +- Implement the requirements in the `reading-list-manager` folder. +- Use the existing file structure. +- You are allowed to create additional files if needed. 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..ae22cc2 --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "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/MunaNasher/c55-core-week-6.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "commonjs", + "bugs": { + "url": "https://github.com/MunaNasher/c55-core-week-6/issues" + }, + "homepage": "https://github.com/MunaNasher/c55-core-week-6#readme", + "dependencies": { + "chalk": "^4.1.2" + }, + "devDependencies": { + "prettier": "^3.8.1" + } +} diff --git a/reading-list-manager/app.js b/reading-list-manager/app.js index b0365ef..2ced481 100644 --- a/reading-list-manager/app.js +++ b/reading-list-manager/app.js @@ -1,3 +1,12 @@ +const { + printAllBooks, + printSummary, + getUnreadBooks, + getBooksByGenre, + markAsRead, + addBook, +} = require('./readingList.js'); // تأكدي من المسار صحيح + // This is the entrypoint for your application. // node app.js @@ -10,4 +19,6 @@ console.log('📚 MY READING LIST 📚\n'); -// Your implementation here +printAllBooks(); + +printSummary(); diff --git a/reading-list-manager/books.json b/reading-list-manager/books.json index 0637a08..3b950eb 100644 --- a/reading-list-manager/books.json +++ b/reading-list-manager/books.json @@ -1 +1,37 @@ -[] \ 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": false + }, + { + "id": 4, + "title": "Clean Code", + "author": "Robert C. Martin", + "genre": "Programming", + "read": true + }, + { + "id": 5, + "title": "Atomic Habits", + "author": "James Clear", + "genre": "Self-Help", + "read": false + } +] diff --git a/reading-list-manager/readingList.js b/reading-list-manager/readingList.js index 84febab..b5e58f0 100644 --- a/reading-list-manager/readingList.js +++ b/reading-list-manager/readingList.js @@ -1,53 +1,103 @@ // Place here the file operation functions for loading and saving books +module.exports = { + loadBooks, + saveBooks, + addBook, + getUnreadBooks, + getBooksByGenre, + markAsRead, + getTotalBooks, + hasUnreadBooks, + printAllBooks, + printSummary, +}; +const fs = require('fs'); 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 dataBuffer = fs.readFileSync('books.json'); + const dataJSON = dataBuffer.toString(); + return JSON.parse(dataJSON); + } catch (error) { + return []; + } } function saveBooks(books) { - // TODO: Implement this function - // Write books array to books.json - // Use try-catch for error handling + try { + const dataJSON = JSON.stringify(books, null, 2); + fs.writeFileSync('books.json', dataJSON); + } catch (error) { + console.log('❌ Error saving data:', error.message); + } } function addBook(book) { - // TODO: Implement this function + const books = loadBooks(); + books.push(book); + saveBooks(books); + console.log(`✅ The book "${book.title}" was added successfully!`); } function getUnreadBooks() { - // TODO: Implement this function using filter() + const books = loadBooks(); + return books.filter((book) => !book.read); } function getBooksByGenre(genre) { - // TODO: Implement this function using filter() + const books = loadBooks(); + return books.filter((book) => book.genre === genre); } function markAsRead(id) { - // TODO: Implement this function using map() + const books = loadBooks(); + + const updatedBooks = books.map((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((book) => !book.read); } +const chalk = require('chalk'); 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(); + + books.forEach((book) => { + const status = book.read ? chalk.green('✓ Read') : chalk.yellow('⚠ Unread'); + + console.log( + chalk.cyan(book.title), + 'by', + book.author, + `(${book.genre})`, + status + ); + }); } function printSummary() { - // TODO: Implement this function - // Show statistics with chalk - // Display total books, read count, unread count - // Use bold for stats -} \ No newline at end of file + const books = loadBooks(); + + const total = books.length; + const read = books.filter((book) => book.read).length; + const unread = total - read; + + console.log(chalk.bold('\n📊 SUMMARY 📊')); + console.log('Total Books:', total); + console.log('Read:', read); + console.log('Unread:', unread); +}