From 4f01b1195a8df4fcafbe8e1cbce3fe6335f84846 Mon Sep 17 00:00:00 2001 From: Diana Chukhrai Date: Mon, 2 Feb 2026 21:09:27 +0100 Subject: [PATCH] task4 --- .gitignore | 2 + .hyf/README.md | 2 +- .hyf/score.example.json | 2 +- .prettierrc | 7 +++ README.md | 6 +- finance-tracker/app.js | 1 - finance-tracker/data.js | 45 +++++++++++++- finance-tracker/finance.js | 121 ++++++++++++++++++++++++++++++++++--- package-lock.json | 105 ++++++++++++++++++++++++++++++++ package.json | 28 +++++++++ 10 files changed, 305 insertions(+), 14 deletions(-) create mode 100644 .prettierrc create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.gitignore b/.gitignore index 2b76d7c..f2f1ecf 100644 --- a/.gitignore +++ b/.gitignore @@ -156,3 +156,5 @@ dist vite.config.js.timestamp-* vite.config.ts.timestamp-* +node_modules/ + 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 2de48c5..d410295 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # Core program week 4 assignment + The week 4 assignment for the HackYourFuture Core program can be found at the following link: https://hub.hackyourfuture.nl/core-program-week-4-assignment ## Implementation Instructions -- Implement the requirements in the `finance-tracker` folder. -- Use the existing file structure. + +- Implement the requirements in the `finance-tracker` folder. +- Use the existing file structure. - You are allowed to create additional files if needed. diff --git a/finance-tracker/app.js b/finance-tracker/app.js index 7cfcd07..4a75396 100644 --- a/finance-tracker/app.js +++ b/finance-tracker/app.js @@ -1,3 +1,2 @@ // This is the entrypoint for your application. // node app.js - diff --git a/finance-tracker/data.js b/finance-tracker/data.js index d7863ff..6495994 100644 --- a/finance-tracker/data.js +++ b/finance-tracker/data.js @@ -1,2 +1,45 @@ // Place here the transaction data array. Use it in your application as needed. -const transactions = []; \ No newline at end of file +const transactions = [ + { + id: 1, + type: 'income', + category: 'salary', + amount: 3000, + description: 'Monthly salary', + date: '2025-01-15', + }, + { + id: 2, + type: 'expense', + category: 'housing', + amount: 1200, + description: 'Rent', + date: '2025-01-16', + }, + { + id: 3, + type: 'expense', + category: 'food', + amount: 300, + description: 'Groceries', + date: '2025-01-17', + }, + { + id: 4, + type: 'income', + category: 'side-income', + amount: 500, + description: 'Freelance', + date: '2025-01-18', + }, + { + id: 5, + type: 'expense', + category: 'bills', + amount: 150, + description: 'Utilities', + date: '2025-01-19', + }, +]; + +export { transactions }; \ No newline at end of file diff --git a/finance-tracker/finance.js b/finance-tracker/finance.js index ac2118f..289509e 100644 --- a/finance-tracker/finance.js +++ b/finance-tracker/finance.js @@ -1,27 +1,132 @@ +import { transactions } from './data.js'; + + +import chalk from 'chalk'; + +console.log(chalk.bold('💰 PERSONAL FINANCE TRACKER 💰')); +console.log(''); +console.log('Transactions count:', transactions.length); + + function addTransaction(transaction) { - // TODO: Implement this function + transactions.push({ ...transaction }); } function getTotalIncome() { - // TODO: Implement this function + let totalIncome = 0; + + for (const transaction of transactions) { + if (transaction.type === 'income') { + totalIncome += transaction.amount; + } + } + + return totalIncome; } +// console.log('Total income:', getTotalIncome()); + + function getTotalExpenses() { - // TODO: Implement this function + let totalExpenses = 0; + + for (let i = 0; i < transactions.length; i++) { + if (transactions[i].type === 'expense') { + totalExpenses += transactions[i].amount; + } + } + + return totalExpenses; } function getBalance() { - // TODO: Implement this function + const income = getTotalIncome(); + const expenses = getTotalExpenses(); + + return income - expenses; } +// console.log('Balance:', getBalance()); function getTransactionsByCategory(category) { - // TODO: Implement this function + const result = []; + + for (const transaction of transactions) { + if (transaction.category === category) { + result.push(transaction); + } + } + + return result; } +// console.log('Food transactions:', getTransactionsByCategory('food')); function getLargestExpense() { - // TODO: Implement this function + let largest = null; + + for (const transaction of transactions) { + if (transaction.type === 'expense') { + if (largest === null || transaction.amount > largest.amount) { + largest = transaction; + } + } + } + + return largest; } +// console.log('Largest expense:', getLargestExpense()); function printAllTransactions() { - // TODO: Implement this function -} \ No newline at end of file + console.log(chalk.bold('All Transactions:')); + + for (const transaction of transactions) { + const { id, type, description, amount, category } = transaction; + + const label = `[${type.toUpperCase()}]`; + + const amountText = + type === 'income' ? chalk.green(`€${amount}`) : chalk.red(`€${amount}`); + + const categoryText = chalk.yellow(category); + + console.log(`${id}. ${label} ${description} - ${amountText} (${categoryText})`); + } + + console.log(''); +} + +printAllTransactions(); + + + +function printSummary() { + const totalIncome = getTotalIncome(); + const totalExpenses = getTotalExpenses(); + const balance = getBalance(); + const count = transactions.length; + const largestExpense = getLargestExpense(); + + console.log(chalk.bold('📊 FINANCIAL SUMMARY 📊')); + + console.log(chalk.bold(`Total income: €${totalIncome}`)); + console.log(chalk.bold(`Total expenses: €${totalExpenses}`)); + + const balanceText = + balance >= 0 ? chalk.cyan(`€${balance}`) : chalk.red(`€${balance}`); + console.log(chalk.bold(`Current balance: ${balanceText}`)); + + console.log(chalk.bold(`Total transactions: ${count}`)); + + if (largestExpense) { + console.log( + chalk.bold( + `Largest expense: ${largestExpense.description} (€${largestExpense.amount})` + ) + ); + } else { + console.log(chalk.bold('Largest expense: none')); + } + + console.log(''); +} + +printSummary(); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..228d484 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,105 @@ +{ + "name": "c55-core-week-4", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "c55-core-week-4", + "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..c29aeef --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "c55-core-week-4", + "version": "1.0.0", + "description": "The week 4 assignment for the HackYourFuture Core program can be found at the following link: https://hub.hackyourfuture.nl/core-program-week-4-assignment", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "format": "prettier --write ." + }, + "repository": { + "type": "git", + "url": "git+https://github.com/dianadenwik/c55-core-week-4.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "module", + "bugs": { + "url": "https://github.com/dianadenwik/c55-core-week-4/issues" + }, + "homepage": "https://github.com/dianadenwik/c55-core-week-4#readme", + "dependencies": { + "chalk": "^4.1.2" + }, + "devDependencies": { + "prettier": "^3.8.1" + } +}