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 00000000..ac0da242 Binary files /dev/null and b/Domains/AI-ML/MiniProjects/email_spam_filter/README.md differ diff --git a/Domains/AI-ML/MiniProjects/email_spam_filter/main.py b/Domains/AI-ML/MiniProjects/email_spam_filter/main.py new file mode 100644 index 00000000..ccfad275 --- /dev/null +++ b/Domains/AI-ML/MiniProjects/email_spam_filter/main.py @@ -0,0 +1,147 @@ +# Simple Spam Classifier based on Word Frequency (Easy ML/Statistics) +import numpy as np +import csv + +# --- 1. DATA LOADING FUNCTION --- + +def load_data_from_csv(filename="sample.csv"): + """ + Reads text and label data from a specified CSV file. + Expects two columns: Text (str) and Label (int 0 or 1). + """ + data = [] + try: + with open(filename, mode='r', encoding='utf-8') as file: + reader = csv.reader(file) + next(reader) # Skip the header row (e.g., "Text,Label") + for row in reader: + if len(row) == 2: + text = row[0].strip() + # Convert label to integer + try: + label = int(row[1].strip()) + data.append((text, label)) + except ValueError: + print(f"[Warning] Skipping row with non-integer label: {row}") + except FileNotFoundError: + print(f"[CRITICAL ERROR] The file '{filename}' was not found.") + print("Please ensure the CSV file is in the same directory as the script.") + return [] + except Exception as e: + print(f"[ERROR] An error occurred while reading the CSV: {e}") + return [] + + return data + +# --- 2. TRAIN THE CLASSIFIER (Counting) --- + +def train_classifier(data): + """ + Counts the frequency of words in spam and ham messages. + """ + spam_word_counts = {} + ham_word_counts = {} + total_spam_messages = 0 + total_ham_messages = 0 + + print("--- Training Model (Counting Words) ---") + + for text, label in data: + # Convert text to lowercase and split into words + words = text.lower().split() + + if label == 1: + total_spam_messages += 1 + counts = spam_word_counts + else: + total_ham_messages += 1 + counts = ham_word_counts + + for word in words: + # Use a basic dictionary to store word frequency + counts[word] = counts.get(word, 0) + 1 + + print(f"Total Spam Messages: {total_spam_messages}") + print(f"Total Ham Messages: {total_ham_messages}") + print("[Training Complete]") + + return spam_word_counts, ham_word_counts, total_spam_messages, total_ham_messages + +# --- 3. PREDICTION LOGIC --- + +def predict_spam_score(text, spam_counts, ham_counts, total_spam, total_ham): + """ + Scores a new message based on how many "spam words" it contains. + The score is the ratio of spam-words found. + """ + words = text.lower().split() + spam_score = 0 + + print(f"\nAnalyzing Text: '{text}'") + + for word in words: + # Calculate the simple probability of this word being in spam vs ham + + # Count how many times this word appeared in spam and ham training data + spam_hits = spam_counts.get(word, 0) + ham_hits = ham_counts.get(word, 0) + + # Simple probability: P(word|Spam) + # Add '1' (Laplace smoothing) to avoid dividing by zero if a word wasn't seen + p_word_given_spam = (spam_hits + 1) / (total_spam + 2) + p_word_given_ham = (ham_hits + 1) / (total_ham + 2) + + # Calculate the ratio: How much more likely is this word to be spam? + if p_word_given_spam > 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 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 @@ + + +
+ + +Manage your money in real-time.
+Authenticating...
+--
+--
+--
+Loading transactions...
+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()}
+