From 199d262a761713469867cccec8f3bda3a0f50806 Mon Sep 17 00:00:00 2001 From: alisha1510 Date: Mon, 20 Oct 2025 16:41:35 +0530 Subject: [PATCH 1/2] expense tracker project --- .../MiniProjects/expense_tracker/README.md | 42 ++++++ .../MiniProjects/expense_tracker/index.html | 100 ++++++++++++++ .../MiniProjects/expense_tracker/script.js | 122 ++++++++++++++++++ .../MiniProjects/expense_tracker/style.css | 45 +++++++ 4 files changed, 309 insertions(+) create mode 100644 Domains/Frontend/MiniProjects/expense_tracker/README.md create mode 100644 Domains/Frontend/MiniProjects/expense_tracker/index.html create mode 100644 Domains/Frontend/MiniProjects/expense_tracker/script.js create mode 100644 Domains/Frontend/MiniProjects/expense_tracker/style.css diff --git a/Domains/Frontend/MiniProjects/expense_tracker/README.md b/Domains/Frontend/MiniProjects/expense_tracker/README.md new file mode 100644 index 00000000..09d51f63 --- /dev/null +++ b/Domains/Frontend/MiniProjects/expense_tracker/README.md @@ -0,0 +1,42 @@ +**Contributor:** alisha1510 + +# Expense Tracker + +A dynamic web application to help users track their income, expenses, and balance in real-time. Features interactive charts, a clean interface, and a user-friendly way to manage personal finances. + +## 🌟 Features + +* **Real-Time Tracking** – Add income and expenses instantly, see updates in your balance. +* **Transaction History** – View, sort, and delete past transactions easily. + + +## 🎯 How to Use + +1.Open the web application in a browser. +2.Add a transaction using the Add Transaction form (income or expense). +3.Enter description, amount, and type. +4.Submit to update your balance and charts instantly. +5.View your transaction history below and delete items if needed. + + +## ⚠️ Important Disclaimer + +**For personal finance tracking only!** + +This project is intended to help manage budgets and track expenses. Please do not use this app for financial advice or professional accounting purposes. + + +## 🤝 Contributing + +Contributions, issues, and feature requests are welcome! Feel free to check the issues page. + +## 👤 Author + +**Alisha Sheikh** +- GitHub: [@alisha1510](https://github.com/alisha1510) + + +--- + + +Made with 💜 for Hacktoberfest and the Open Source Community \ No newline at end of file diff --git a/Domains/Frontend/MiniProjects/expense_tracker/index.html b/Domains/Frontend/MiniProjects/expense_tracker/index.html new file mode 100644 index 00000000..9eeca12e --- /dev/null +++ b/Domains/Frontend/MiniProjects/expense_tracker/index.html @@ -0,0 +1,100 @@ + + + + + + Dynamic Expense Tracker + + + + + + + +
+
+ +

+ BudgetFlow Tracker +

+ +

Manage your money in real-time.

+

Authenticating...

+
+ + +
+
+ +

Balance

+

--

+
+
+ +

Income

+

--

+
+
+ +

Expenses

+

--

+
+
+ + +
+ +

Add New Transaction

+
+
+ + + + +
+
+
+ + + + +
+
+ + + + +
+
+ + +
+ + +
+ + +
+ +

Transaction History

+
+ + +

Loading transactions...

+
+
+
+ + + + + diff --git a/Domains/Frontend/MiniProjects/expense_tracker/script.js b/Domains/Frontend/MiniProjects/expense_tracker/script.js new file mode 100644 index 00000000..778820e1 --- /dev/null +++ b/Domains/Frontend/MiniProjects/expense_tracker/script.js @@ -0,0 +1,122 @@ +document.addEventListener("DOMContentLoaded", () => { + let localTransactions = []; + + const userInfo = document.getElementById("user-info"); + const form = document.getElementById("transaction-form"); + const list = document.getElementById("transactions-list"); + const errorMessage = document.getElementById("error-message"); + + const balanceEl = document.getElementById("balance"); + const incomeEl = document.getElementById("income"); + const expenseEl = document.getElementById("expense"); + + userInfo.textContent = "Local Mode (Data will not save)"; + console.log("Running in Local Mode. Data is temporary."); + + const renderTransactions = () => { + list.innerHTML = ""; + + if (localTransactions.length === 0) { + list.innerHTML = `

No transactions yet. Data is temporary.

`; + return; + } + + localTransactions.forEach((t) => { + const isExpense = t.amount < 0; + const sign = isExpense ? "-" : "+"; + const colorClass = isExpense ? "text-rose-400" : "text-emerald-400"; + const formattedAmount = `$${Math.abs(t.amount).toFixed(2)}`; + + const item = document.createElement("div"); + item.id = `transaction-${t.id}`; + item.className = + "flex justify-between items-center p-4 rounded-xl main-card transition-all duration-300 hover:bg-gray-700/50 group"; + item.innerHTML = ` +
+

${t.description}

+

${new Date(t.timestamp).toLocaleDateString()}

+
+
+ + ${sign}${formattedAmount} + + +
+ `; + list.appendChild(item); + }); + }; + + const updateSummary = () => { + const income = localTransactions + .filter((t) => t.amount > 0) + .reduce((acc, t) => acc + t.amount, 0); + const expense = localTransactions + .filter((t) => t.amount < 0) + .reduce((acc, t) => acc + t.amount, 0); + + const totalExpense = Math.abs(expense); + const balance = income + expense; + + incomeEl.textContent = `$${income.toFixed(2)}`; + expenseEl.textContent = `$${totalExpense.toFixed(2)}`; + balanceEl.textContent = `$${balance.toFixed(2)}`; + balanceEl.className = `text-3xl font-bold mt-1 ${ + balance >= 0 ? "text-blue-400" : "text-rose-500" + }`; + }; + + const addTransaction = (e) => { + e.preventDefault(); + const description = document.getElementById("description").value.trim(); + const amountInput = document.getElementById("amount"); + const type = document.getElementById("type").value; + + let amount = parseFloat(amountInput.value); + if (!description || isNaN(amount) || amount <= 0) { + errorMessage.textContent = + "Please enter a valid description and amount."; + errorMessage.classList.remove("hidden"); + return; + } + + errorMessage.classList.add("hidden"); + const sign = type === "expense" ? -1 : 1; + amount = amount * sign; + + const transaction = { + id: crypto.randomUUID(), + description, + amount, + type, + timestamp: new Date().toISOString(), + }; + + localTransactions.unshift(transaction); + renderTransactions(); + updateSummary(); + + form.reset(); + errorMessage.textContent = + "Added successfully! (Temporary data - local mode)"; + errorMessage.classList.remove("hidden"); + setTimeout(() => errorMessage.classList.add("hidden"), 3000); + }; + + window.deleteTransaction = (id) => { + localTransactions = localTransactions.filter((t) => t.id !== id); + renderTransactions(); + updateSummary(); + }; + + form.addEventListener("submit", addTransaction); + + // Initial render + renderTransactions(); + updateSummary(); +}); diff --git a/Domains/Frontend/MiniProjects/expense_tracker/style.css b/Domains/Frontend/MiniProjects/expense_tracker/style.css new file mode 100644 index 00000000..1fda8d6d --- /dev/null +++ b/Domains/Frontend/MiniProjects/expense_tracker/style.css @@ -0,0 +1,45 @@ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&display=swap'); +body { + font-family: 'Inter', sans-serif; + /* Blue gradient background */ + background: linear-gradient(135deg, #1f2937 0%, #0f172a 100%); + min-height: 100vh; + /* Light text color */ + color: #e5e7eb; + overflow-x: hidden; /* Prevent horizontal scroll */ + /* Padding to allow scrolling space at the bottom */ + padding-bottom: 2rem; +} +/* Custom Scrollbar for dark aesthetics */ +::-webkit-scrollbar { + width: 8px; +} +::-webkit-scrollbar-track { + background: #111827; +} +::-webkit-scrollbar-thumb { + background: #4b5563; + border-radius: 10px; +} +::-webkit-scrollbar-thumb:hover { + background: #6b7280; +} + +/* Custom Button Animation */ +.animated-btn { + transition: all 0.2s ease-in-out; +} +.animated-btn:hover { + transform: translateY(-2px) scale(1.02); + box-shadow: 0 10px 15px -3px rgba(16, 185, 129, 0.2), 0 4px 6px -2px rgba(16, 185, 129, 0.1); +} +.animated-btn:active { + transform: translateY(0) scale(0.98); + box-shadow: none; +} +/* Custom styling for the main card - dark background */ +.main-card { + background-color: #1f2937; + box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.3), 0 10px 10px -5px rgba(0, 0, 0, 0.1); + border: 1px solid #374151; +} From e04eb5fed55a0719968e532104217034abb2b76c Mon Sep 17 00:00:00 2001 From: alisha1510 Date: Mon, 20 Oct 2025 16:48:26 +0530 Subject: [PATCH 2/2] email spam detection --- .../MiniProjects/email_spam_filter/README.md | Bin 0 -> 1418 bytes .../MiniProjects/email_spam_filter/main.py | 147 ++++++++++++++++++ .../MiniProjects/email_spam_filter/sample.csv | 16 ++ 3 files changed, 163 insertions(+) create mode 100644 Domains/AI-ML/MiniProjects/email_spam_filter/README.md create mode 100644 Domains/AI-ML/MiniProjects/email_spam_filter/main.py create mode 100644 Domains/AI-ML/MiniProjects/email_spam_filter/sample.csv diff --git a/Domains/AI-ML/MiniProjects/email_spam_filter/README.md b/Domains/AI-ML/MiniProjects/email_spam_filter/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ac0da242f791612828cadbc33b528ff6fc523fc4 GIT binary patch literal 1418 zcmaKs%}(1;5QS%5sgF?UR%{?@pk1&*qH2UnvnVPO-60lE?EI*4Ok)ScyY#`bXkVr9 zow>Pjh!C=zT+jcUGjkvRcdTP)R@vMdTiDbFw&YZCK0(v5V42O3*EZqw$&PtH+FN_$ z@1E^p@zqLnQ|y9W*)8Xi)459;D~Ofsd&q0#B~~*u!7lBAd=sxAc;?FENS5&(Y{++p zm;6S&1*gDoo3nITjn#Oqm3{E~ugK7|i*+yRE6V#@(tWzGJXgK0{s60`XPgsL7zDd_ zRC4Q5QH55B1@Ka?!g9_f@|^R`4mTY~gwBzwnGzwqed@sn>MH}`tQLd=!Bb&RYm z6`c#Ygl&eUG72MMy^BE1uMB5c%&2(jD2fdslX?lnRYkwi7sMRGMr0v)Cy~9I8 z1)7Op_~>8ksq;4LB~dH8Lnl0xQ56S|6JuuNYWTiGFOJoF&2OBF5hpPf>y=&PVUG1Z z^4HjJtN4!JnCcpQip@FJBJ{*bz16W8FYE)F8a$@>W$^pFq5&3TuSc~ku-xVP^XlC{ z;l8_5v4^w?FX4Z=>}iSH4Tc8B)kxvaG5 zLVtp02%nPZ{JetTbEn p_word_given_ham: + ratio = p_word_given_spam / p_word_given_ham + # Log the ratio to prevent numbers from exploding, and add to the score + spam_score += np.log(ratio) + print(f" - '{word}': Spam Likely (Score added: {np.log(ratio):.2f})") + else: + print(f" - '{word}': Ham Likely") + + return spam_score + +# --- MAIN EXECUTION --- +if __name__ == "__main__": + try: + # NumPy is needed for the log function, which keeps numbers manageable + import numpy as np + + # 1. Load Data from CSV + DATA = load_data_from_csv() + + if not DATA: + print("\n[Execution Halted] Cannot proceed without training data.") + else: + # 2. Train the Classifier + s_counts, h_counts, t_spam, t_ham = train_classifier(DATA) + + # 3. Set the threshold (a score above this is classified as SPAM) + SPAM_THRESHOLD = 1.0 + + # 4. Interactive Testing + print("\n--- Interactive Spam Tester ---") + print(f"Prediction Threshold: Score > {SPAM_THRESHOLD} is SPAM") + print("Enter 'quit' to exit.") + + while True: + test_text = input("\nEnter email subject/body: ") + if test_text.lower() == 'quit': + break + + final_score = predict_spam_score(test_text, s_counts, h_counts, t_spam, t_ham) + + print(f"\nFINAL SPAM SCORE: {final_score:.3f}") + + if final_score > SPAM_THRESHOLD: + print("CLASSIFICATION: 🚨 SPAM") + else: + print("CLASSIFICATION: ✅ HAM") + print("-" * 30) + + except ImportError: + print("\n[CRITICAL ERROR] NumPy is required for this script (for log function).") + print("Please ensure your Python environment has NumPy installed.") + except Exception as e: + print(f"[ERROR] An unexpected error occurred: {e}") diff --git a/Domains/AI-ML/MiniProjects/email_spam_filter/sample.csv b/Domains/AI-ML/MiniProjects/email_spam_filter/sample.csv new file mode 100644 index 00000000..4c3ee993 --- /dev/null +++ b/Domains/AI-ML/MiniProjects/email_spam_filter/sample.csv @@ -0,0 +1,16 @@ +Text,Label +Win a free gift card now,1 +Meeting scheduled for 2 PM,0 +URGENT: Your account verification,1 +Please review the project report,0 +Claim your guaranteed prize money,1 +Lunch plans confirmed tomorrow,0 +Special offer, click now,1 +Remember to submit your hours,0 +Click to renew your subscription immediately,1 +Congratulations you've won a $1000 voucher,1 +Here is the link to the quarterly budget,0 +Earn millions working from home today,1 +Your package delivery failed, update address,1 +Quick question about your vacation dates,0 +Did you send the attachment I asked for,0 \ No newline at end of file