From 3e80a8b4ef6fa03bc79f7250a0e9206a2ca7183e Mon Sep 17 00:00:00 2001 From: HackYourFuture Date: Wed, 4 Feb 2026 20:43:37 +0100 Subject: [PATCH 1/4] finance tracker --- .prettierrc | 8 ++++ finance-tracker/app.js | 41 +++++++++++++++++- finance-tracker/data.js | 43 ++++++++++++++++++- finance-tracker/finance.js | 67 ++++++++++++++++++++++------- package-lock.json | 86 ++++++++++++++++++++++++++++++++++++++ package.json | 24 +++++++++++ 6 files changed, 252 insertions(+), 17 deletions(-) create mode 100644 .prettierrc create mode 100644 package-lock.json create mode 100644 package.json diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..2e00431 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,8 @@ + +{ + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "trailingComma": "es5", + "printWidth": 80 +} \ No newline at end of file diff --git a/finance-tracker/app.js b/finance-tracker/app.js index 7cfcd07..cfc82a9 100644 --- a/finance-tracker/app.js +++ b/finance-tracker/app.js @@ -1,3 +1,40 @@ -// This is the entrypoint for your application. -// node app.js +const chalk = require('chalk'); +const data = require('./data'); +const transactions = data.transactions; +const { + addTransaction, + getTotalIncome, + getTotalExpenses, + getBalance, + getTransactionsByCategory, + getLargestExpense, + printAllTransactions +} = require('./finance'); + +// Example usage of the functions +console.log(chalk.blue('šŸ’° PERSONAL FINANCE TRACKER šŸ’°')); + +printAllTransactions(transactions); + +console.log('\nšŸ“Š FINANCIAL SUMMARY šŸ“Š'); +console.log(chalk.bold('Total Income:') + chalk.green(` €${getTotalIncome(transactions)}`)); +console.log(chalk.bold('Total Expenses:') + chalk.red(` €${getTotalExpenses(transactions)}`)); +console.log(chalk.bold('Current Balance:') + (getBalance(transactions) < 0 ? chalk.red : chalk.cyan)(` €${getBalance(transactions)}`)); + +const largest = getLargestExpense(transactions); +if (largest) { + console.log(chalk.bold(`\nLargest Expense: ${largest.category} (€${largest.amount})`)); +} + + +console.log(chalk.bold(`Total Transactions: ${transactions.length}`)); + +addTransaction({ + id: 6, + type: 'expense', + category: 'entertainment', + amount: 200, + description: 'Concert tickets', + date: '2025-02-05' +}); diff --git a/finance-tracker/data.js b/finance-tracker/data.js index d7863ff..b1cc698 100644 --- a/finance-tracker/data.js +++ b/finance-tracker/data.js @@ -1,2 +1,43 @@ // 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: 'salary', + date: '2025-01-15' + }, + {id: 2, + type: 'expense', + category: 'Rent', + amount: 1200, + description: 'housing', + date: '2025-01-25' + }, + {id: 3, + type: 'expense', + category: 'Groceries', + amount: 300, + description: 'food', + date: '2025-01-20' + }, + + {id: 4, + type: 'income', + category: 'Freelance', + amount: 500, + description: 'side-income', + date: '2025-01-28' + }, + {id: 5, + type: 'expense', + category: 'Utilities', + amount: 150, + description: 'bills', + date: '2025-01-30' + } +]; + +module.exports = { + transactions +}; \ No newline at end of file diff --git a/finance-tracker/finance.js b/finance-tracker/finance.js index ac2118f..73397c7 100644 --- a/finance-tracker/finance.js +++ b/finance-tracker/finance.js @@ -1,27 +1,66 @@ +const chalk = require('chalk'); +let transactions = []; + + +function filterByType(transactions, type) { + return transactions.filter(tx => tx.type === type); +} + +function filterByCategory(transactions, category) { + return transactions.filter(tx => tx.category === category); +} + + +function calculateTotal(transactions) { + return transactions.reduce((total, tx) => total + tx.amount, 0); +} + function addTransaction(transaction) { - // TODO: Implement this function + transactions.push({ ...transaction }); +} + +function getTotalIncome(transactions) { + return calculateTotal(filterByType(transactions, 'income')); } -function getTotalIncome() { - // TODO: Implement this function +function getTotalExpenses(transactions) { + return calculateTotal(filterByType(transactions, 'expense')); } -function getTotalExpenses() { - // TODO: Implement this function +function getBalance(transactions) { + return getTotalIncome(transactions) - getTotalExpenses(transactions); } -function getBalance() { - // TODO: Implement this function +function getTransactionsByCategory(category, transactions) { + return filterByCategory(transactions, category); } -function getTransactionsByCategory(category) { - // TODO: Implement this function +function getLargestExpense(transactions) { + const expenses = filterByType(transactions, 'expense'); + return expenses.length > 0 + ? expenses.reduce((largest, tx) => tx.amount > largest.amount ? tx : largest) + : null; } -function getLargestExpense() { - // TODO: Implement this function +function printAllTransactions(transactions) { + console.log('\nAll Transactions:'); + + transactions.forEach((tx, index) => { + const { type, category, amount, description } = tx; + const typeLabel = type === 'income' ? chalk.green('Income') : chalk.red('Expense'); + const coloredAmount = type === 'income' ? chalk.green(`€${amount}`) : chalk.red(`€${amount}`); + const coloredCategory = chalk.yellow(category); + + console.log(`${index + 1}. [${typeLabel}] ${coloredCategory} - ${coloredAmount} (${description})`); + }); } -function printAllTransactions() { - // TODO: Implement this function -} \ No newline at end of file +module.exports = { + addTransaction, + getTotalIncome, + getTotalExpenses, + getBalance, + getTransactionsByCategory, + getLargestExpense, + printAllTransactions +}; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..52239c6 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,86 @@ +{ + "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" + } + }, + "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/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..f20dbfc --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "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" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/Yusuprozimemet/c55-core-week-4.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "type": "commonjs", + "bugs": { + "url": "https://github.com/Yusuprozimemet/c55-core-week-4/issues" + }, + "homepage": "https://github.com/Yusuprozimemet/c55-core-week-4#readme", + "dependencies": { + "chalk": "^4.1.2" + } +} From 4698d5f627cbbd2b273499c646bf7aa6b9c057e2 Mon Sep 17 00:00:00 2001 From: HackYourFuture Date: Wed, 4 Feb 2026 20:47:27 +0100 Subject: [PATCH 2/4] some fixes --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 2b76d7c..566b73c 100644 --- a/.gitignore +++ b/.gitignore @@ -56,7 +56,7 @@ bower_components build/Release # Dependency directories -node_modules/ + jspm_packages/ # Snowpack dependency directory (https://snowpack.dev/) From 70607d3a4184bef31d83ac739adf08eec94a5e76 Mon Sep 17 00:00:00 2001 From: HackYourFuture Date: Wed, 4 Feb 2026 20:48:09 +0100 Subject: [PATCH 3/4] update --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 566b73c..2b76d7c 100644 --- a/.gitignore +++ b/.gitignore @@ -56,7 +56,7 @@ bower_components build/Release # Dependency directories - +node_modules/ jspm_packages/ # Snowpack dependency directory (https://snowpack.dev/) From 40557b25bc975b9f6839e1a354e9c7ced32088f3 Mon Sep 17 00:00:00 2001 From: HackYourFuture Date: Wed, 4 Feb 2026 21:02:28 +0100 Subject: [PATCH 4/4] updated again --- finance-tracker/finance.js | 77 ++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 32 deletions(-) diff --git a/finance-tracker/finance.js b/finance-tracker/finance.js index 73397c7..6a4511a 100644 --- a/finance-tracker/finance.js +++ b/finance-tracker/finance.js @@ -1,58 +1,71 @@ const chalk = require('chalk'); -let transactions = []; +let transactions = []; -function filterByType(transactions, type) { - return transactions.filter(tx => tx.type === type); -} - -function filterByCategory(transactions, category) { - return transactions.filter(tx => tx.category === category); -} - - -function calculateTotal(transactions) { - return transactions.reduce((total, tx) => total + tx.amount, 0); -} - -function addTransaction(transaction) { - transactions.push({ ...transaction }); +function addTransaction(singleTransaction) { + const newTransaction = { ...singleTransaction }; + transactions.push(newTransaction); } function getTotalIncome(transactions) { - return calculateTotal(filterByType(transactions, 'income')); + let total = 0; + for (const singleTransaction of transactions) { + if(singleTransaction.type === 'income') { + total += singleTransaction.amount; + } + } + return total; } function getTotalExpenses(transactions) { - return calculateTotal(filterByType(transactions, 'expense')); + let total = 0; + for (const singleTransaction of transactions) { + if(singleTransaction.type === 'expense') { + total += singleTransaction.amount; + } + } + return total; } function getBalance(transactions) { - return getTotalIncome(transactions) - getTotalExpenses(transactions); + const income = getTotalIncome(transactions); + const expenses = getTotalExpenses(transactions); + return income - expenses; } function getTransactionsByCategory(category, transactions) { - return filterByCategory(transactions, category); + const results = []; + for (const singleTransaction of transactions) { + if(singleTransaction.category === category) { + results.push(singleTransaction); + } + } + return results; } function getLargestExpense(transactions) { - const expenses = filterByType(transactions, 'expense'); - return expenses.length > 0 - ? expenses.reduce((largest, tx) => tx.amount > largest.amount ? tx : largest) - : null; + let largest = null; + for (const singleTransaction of transactions) { + if(singleTransaction.type === 'expense') { + if(largest === null || singleTransaction.amount > largest.amount) { + largest = singleTransaction; + } + } + } + return largest; } function printAllTransactions(transactions) { console.log('\nAll Transactions:'); - - transactions.forEach((tx, index) => { - const { type, category, amount, description } = tx; + let index = 1; + for (const singleTransaction of transactions) { + const {id, type, category, amount, description} = singleTransaction; const typeLabel = type === 'income' ? chalk.green('Income') : chalk.red('Expense'); - const coloredAmount = type === 'income' ? chalk.green(`€${amount}`) : chalk.red(`€${amount}`); - const coloredCategory = chalk.yellow(category); - - console.log(`${index + 1}. [${typeLabel}] ${coloredCategory} - ${coloredAmount} (${description})`); - }); + const coloredAmount = type === 'income' ? chalk.green(`${amount}`) : chalk.red(`${amount}`); + const coloredCategory = chalk.yellow(`${category}`); + console.log(`${index}. [${typeLabel}] ${coloredCategory} - ${coloredAmount} (${description})`); + index++; + } } module.exports = {