diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 68ebedab..c278f136 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -28,4 +28,4 @@ If this is your first time contributing to an open source project, check out thi
 
 ## Code of Conduct
 
-We strive to maintain a welcoming and inclusive community. Please read and respect our [Code of Conduct](https://github.com/DhanushNehru/Python-Scripts/blob/master/CODE_OF_CONDUCT.md) in all your interactions.
+We strive to maintain a welcoming and inclusive community. Please read and respect our [Code of Conduct](https://github.com/DhanushNehru/Python-Scripts/blob/main/CODE_OF_CONDUCT.md) in all your interactions.
diff --git a/CSV_TO_NDJSON/README.md b/CSV_TO_NDJSON/README.md
new file mode 100644
index 00000000..4aaebdbe
--- /dev/null
+++ b/CSV_TO_NDJSON/README.md
@@ -0,0 +1,38 @@
+# README.md
+
+# CSV to NDJSON Converter
+
+This Python script converts a CSV file located in this folder into an NDJSON file saved in the same folder.
+
+## What is NDJSON?
+
+NDJSON (Newline Delimited JSON) is a convenient format for streaming JSON objects, where each line is a valid JSON object.  
+It’s widely used in data pipelines and tools such as **Google Cloud BigQuery**, **ElasticSearch**, and many other data processing platforms.
+
+## How to use
+
+1. Place your CSV file in this folder.
+2. Make sure you have Python 3 installed.
+3. Run the script from this folder with:
+
+   ```bash
+   python csv_to_ndjson.py input.csv output.ndjson
+
+
+#### Example 
+If you have a CSV file like this:
+
+```csv
+name,age,city
+Alice,30,New York
+Bob,25,Los Angeles
+```
+
+The output NDJSON will be:
+
+```json
+{"name":"Alice","age":"30","city":"New York"}
+{"name":"Bob","age":"25","city":"Los Angeles"}
+```
+
+Feel free to modify or extend it as needed.
diff --git a/CSV_TO_NDJSON/csv_to_ndjson.py b/CSV_TO_NDJSON/csv_to_ndjson.py
new file mode 100644
index 00000000..100da9c8
--- /dev/null
+++ b/CSV_TO_NDJSON/csv_to_ndjson.py
@@ -0,0 +1,39 @@
+# csv_to_ndjson.py
+import csv
+import json
+import sys
+import os
+
+
+def csv_to_ndjson(csv_filename, ndjson_filename):
+    base_dir = os.path.dirname(os.path.abspath(__file__))
+
+    csv_path = os.path.join(base_dir, csv_filename)
+    ndjson_path = os.path.join(base_dir, ndjson_filename)
+
+    try:
+        with (
+            open(csv_path, mode="r", encoding="utf-8") as f_csv,
+            open(ndjson_path, mode="w", encoding="utf-8") as f_ndjson,
+        ):
+            reader = csv.DictReader(f_csv)
+            for row in reader:
+                f_ndjson.write(
+                    json.dumps(row, ensure_ascii=False, separators=(",", ":")) + "\n"
+                )
+
+        print(f"Successfully converted '{csv_path}' to '{ndjson_path}'")
+
+    except FileNotFoundError:
+        print(f"Error: CSV file '{csv_path}' not found.")
+    except Exception as e:
+        print(f"An error occurred: {e}")
+
+
+if __name__ == "__main__":
+    if len(sys.argv) != 3:
+        print("Usage: python csv_to_ndjson.py input.csv output.ndjson")
+    else:
+        csv_file = sys.argv[1]
+        ndjson_file = sys.argv[2]
+        csv_to_ndjson(csv_file, ndjson_file)
diff --git a/Currency Script/.idea/Currency Script.iml b/Currency Script/.idea/Currency Script.iml
index f552a87a..1d27ed66 100644
--- a/Currency Script/.idea/Currency Script.iml	
+++ b/Currency Script/.idea/Currency Script.iml	
@@ -1,7 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <module type="PYTHON_MODULE" version="4">
   <component name="NewModuleRootManager">
-    <content url="file://$MODULE_DIR$" />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
     <orderEntry type="jdk" jdkName="Python 3.13 (github)" jdkType="Python SDK" />
     <orderEntry type="sourceFolder" forTests="false" />
   </component>
diff --git a/Currency Script/.idea/misc.xml b/Currency Script/.idea/misc.xml
index 84dd86c7..e939a18e 100644
--- a/Currency Script/.idea/misc.xml	
+++ b/Currency Script/.idea/misc.xml	
@@ -1,4 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
+  <component name="Black">
+    <option name="sdkName" value="Python 3.13 (github)" />
+  </component>
   <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.13 (github)" project-jdk-type="Python SDK" />
 </project>
\ No newline at end of file
diff --git a/Currency Script/main.py b/Currency Script/main.py
index ed705b92..f3643030 100644
--- a/Currency Script/main.py	
+++ b/Currency Script/main.py	
@@ -1,2 +1,38 @@
-# TODO IMPORT API / CONVERTER / CURRENCY MODULES
-# TODO UPDATE / POPULATE MAIN TO ENSURE THERE IS A INTUITIVE SIMPLE UI
\ No newline at end of file
+"""
+main.py - Simple CLI interface for Currency Converter
+
+Prompts user for input currencies and amount, and displays the converted value.
+"""
+
+from converter import CurrencyConverter
+
+def main():
+    """
+    Run the interactive currency converter CLI loop.
+    Prompts user for source and target currencies and amount to convert.
+    Continues until the user types 'no' to exit.
+    """
+    print("Welcome to the Currency Converter\n")
+
+    converter = CurrencyConverter()
+
+    while True:
+        try:
+            from_currency = input("Enter source currency code (e.g., AUD): ").strip().upper()
+            to_currency = input("Enter target currency code (e.g., USD): ").strip().upper()
+            amount = float(input(f"Enter amount in {from_currency}: "))
+
+            converted = converter.convert(from_currency, to_currency, amount)
+            print(f"\n✅ {amount} {from_currency} = {converted} {to_currency}\n")
+
+        except ValueError as e:
+            print(f"❌ Error: {e}\n")
+
+        # Ask to convert another or exit
+        again = input("Do you want to convert another amount? (yes/no): ").strip().lower()
+        if again != "yes":
+            print("Thank you for using the Currency Converter. Goodbye!")
+            break
+
+if __name__ == "__main__":
+    main()
diff --git a/Currency Script/readme.md b/Currency Script/readme.md
new file mode 100644
index 00000000..8fed1611
--- /dev/null
+++ b/Currency Script/readme.md	
@@ -0,0 +1,57 @@
+Currency Converter
+==================
+
+A simple Python CLI application that converts an amount from one currency to another
+using live exchange rates fetched from an open API.
+
+Modules:
+--------
+
+1. **api_handler.py**
+   - Handles fetching exchange rate data from the online API.
+
+2. **currencies.py**
+   - Provides utility functions to list supported currencies and validate currency codes.
+
+3. **converter.py**
+   - Contains the core logic to convert between currencies using the exchange rates.
+
+4. **main.py**
+   - CLI interface where users input the currencies and amount to convert.
+
+5. **test_*.py**
+   - Unit tests for each module to ensure functionality.
+
+Requirements:
+-------------
+- Python 3.7+
+- `requests` library
+
+Install dependencies:
+---------------------
+Run the following command to install dependencies:
+- pip install -r requirements.txt
+
+How to Use:
+-----------
+Run the main script from the terminal:
+
+Follow the prompts to enter:
+- Source currency code (e.g., USD)
+- Target currency code (e.g., AUD)
+- Amount to convert
+
+The app will display the converted amount and allow you to repeat or exit.
+
+Testing:
+--------
+To run tests:
+- python -m unittest discover
+
+Note:
+-----
+The conversion is based on live exchange rates retrieved from:
+https://open.er-api.com/v6/latest
+
+Make sure you are connected to the internet when running the app.
+
diff --git a/Currency Script/readme.txt b/Currency Script/readme.txt
deleted file mode 100644
index 3202240d..00000000
--- a/Currency Script/readme.txt	
+++ /dev/null
@@ -1 +0,0 @@
-# TODO - UPDATE README
\ No newline at end of file
diff --git a/Currency Script/requirements.txt b/Currency Script/requirements.txt
index ef92400b..663bd1f6 100644
--- a/Currency Script/requirements.txt	
+++ b/Currency Script/requirements.txt	
@@ -1 +1 @@
-# TODO - UPDATE REQUIREMENTS TO NOTE INSTALLS ARE NOTED
\ No newline at end of file
+requests
\ No newline at end of file
diff --git a/Currency Script/setup.py b/Currency Script/setup.py
index d1322786..de3a6108 100644
--- a/Currency Script/setup.py	
+++ b/Currency Script/setup.py	
@@ -1 +1,9 @@
-# UPDATE SETUP TO NOTE SET UP / PACKAGES
\ No newline at end of file
+from setuptools import setup
+
+setup(
+    name="currency_converter",
+    version="0.1",
+    install_requires=[
+        "requests"
+    ],
+)
\ No newline at end of file
diff --git a/Currency Script/src/api_handler.py b/Currency Script/src/api_handler.py
index 226c88d8..8a8f192f 100644
--- a/Currency Script/src/api_handler.py	
+++ b/Currency Script/src/api_handler.py	
@@ -1,18 +1,29 @@
 import requests
-import json
 
-def get_exchange_data(api_url: str = "https://theratesapi.com/api/latest/") -> dict:
-    """Fetch latest exchange data from the API."""
+def get_exchange_data(api_url: str = "https://open.er-api.com/v6/latest") -> dict:
+    """
+    Retrieve the latest foreign exchange rates from the specified API.
+
+    Args:
+        api_url (str): Endpoint to fetch exchange data from. Defaults to the open.er-api URL.
+
+    Returns:
+        dict: A dictionary containing the base currency, timestamp, and exchange rates.
+
+    Raises:
+        Exception: If the API request fails or returns a non-200 status.
+    """
     response = requests.get(api_url)
     if response.status_code != 200:
         raise Exception(f"API request failed with status {response.status_code}")
 
     data = response.json()
-    return data  # This includes 'base', 'date', and 'rates'
+
+    return data  # Includes 'base_code', 'time_last_update_utc', and 'rates'
 
 # NOTE - for logging & debugging
 if __name__ == "__main__":
     exchange_data = get_exchange_data()
-    print("Base currency:", exchange_data["base"])
-    print("Date:", exchange_data["date"])
+    print("Base currency:", exchange_data["base_code"])
+    print("Date:", exchange_data["time_last_update_utc"])
     print("Rates:", list(exchange_data["rates"].items())[:5])
diff --git a/Currency Script/src/converter.py b/Currency Script/src/converter.py
index fbcc0274..df03f702 100644
--- a/Currency Script/src/converter.py	
+++ b/Currency Script/src/converter.py	
@@ -1,39 +1,49 @@
-# TODO REVIEW AND ENSURE THE PURPOSE OF THIS MODULE IS TO CONVERT
-# Python program to convert the currency
-# of one country to that of another country
-
-# Import the modules needed
-import requests
-
-class Currency_convertor:
-    # empty dict to store the conversion rates
-    rates = {}
-    
-    def __init__(self, url):
-        data = requests.get(url).json()
-        # Extracting only the rates from the json data
+from api_handler import get_exchange_data
+
+class CurrencyConverter:
+    def __init__(self):
+        data = get_exchange_data()
         self.rates = data["rates"]
 
-    # function to do a simple cross multiplication between
-    # the amount and the conversion rates
-    def convert(self, from_currency, to_currency, amount):
-        initial_amount = amount
-        if from_currency != 'EUR':
-            amount = amount / self.rates[from_currency]
+    def convert(self, from_currency: str, to_currency: str, amount: float) -> float:
+        """
+        Convert amount between two currencies.
+
+        Args:
+            from_currency: Source currency code (e.g., 'USD')
+            to_currency: Target currency code (e.g., 'AUD')
+            amount: Amount to convert
+
+        Returns:
+            Converted amount as float
+
+        Raises:
+            ValueError: If a currency code is invalid
+        """
+        from_currency = from_currency.upper()
+        to_currency = to_currency.upper()
+
+        if from_currency not in self.rates or to_currency not in self.rates:
+            raise ValueError("Invalid currency code.")
 
-        # limiting the precision to 2 decimal places
-        amount = round(amount * self.rates[to_currency], 2)
-        print('{} {} = {} {}'.format(initial_amount, from_currency, amount, to_currency))
+        # Convert amount to base (EUR), then to target
+        amount_in_base = amount if from_currency == "EUR" else amount / self.rates[from_currency]
+        converted_amount = round(amount_in_base * self.rates[to_currency], 2)
+        return converted_amount
 
-# Driver code
+# --- DEBUG / MANUAL TEST SECTION ---
+# This section runs only when you run this file directly (not when imported elsewhere)
 if __name__ == "__main__":
+    print("Running manual test for CurrencyConverter...\n")
 
-    YOUR_ACCESS_KEY = 'YOUR_ACCESS_KEY_HERE'  # Define your access key
-    url = f'http://data.fixer.io/api/latest?access_key={YOUR_ACCESS_KEY}'  # Use f-string for cleaner concatenation
-    c = Currency_convertor(url)
-    
-    from_country = input("From Country (currency code): ")
-    to_country = input("To Country (currency code): ")
-    amount = float(input("Amount: "))  # Use float for decimal support
+    converter = CurrencyConverter()
+    from_cur = "USD"
+    to_cur = "AUD"
+    amt = 100.0
 
-    c.convert(from_country, to_country, amount)
+    print(f"Converting {amt} {from_cur} to {to_cur}...")
+    try:
+        result = converter.convert(from_cur, to_cur, amt)
+        print(f"{amt} {from_cur} = {result} {to_cur}")
+    except ValueError as e:
+        print("Error during conversion:", e)
\ No newline at end of file
diff --git a/Currency Script/src/currencies.py b/Currency Script/src/currencies.py
index 409605f7..ba5be173 100644
--- a/Currency Script/src/currencies.py	
+++ b/Currency Script/src/currencies.py	
@@ -1,56 +1,46 @@
-# TODO REVIEW BELOW CODE TO ENSURE THAT WHAT IS IN THIS MODULE FOR FUNCTION RECALLING CURRENCY FROM API
-# Importing necessary modules for currency formatting and HTTP requests
-from locale import currency
-import requests
-import json
-
-# Get the base currency input from the user and convert it to lowercase
-currency = input("Enter the base currency (e.g., USD, EUR): ").lower()
-
-# Initialize an empty cache to store exchange rates
-cache = {}
-
-# Infinite loop to process exchange requests until the user exits
-while True:
-
-    # Get the target currency input from the user and convert it to lowercase
-    currency_exch = input("Enter the currency to exchange to (leave blank to exit): ").lower()
-
-    # If the input is blank, break out of the loop (exit condition)
-    if currency_exch == '':
-        break
-
-    # Get the amount to exchange from the user
-    amount_to_exch = int(input("Enter the amount to exchange: "))
-
-    # URL for getting exchange rates from floatrates.com
-    URL = f'http://www.floatrates.com/daily/{currency}.json'
-
-    # Fetch the exchange rates in JSON format
-    exch = json.loads(requests.get(URL).text)
-
-    # Update cache for USD and EUR based on the base currency
-    if currency == 'usd':
-        # If base currency is USD, cache EUR rate
-        cache.update(eur=exch['eur']['rate'])
-    elif currency == 'eur':
-        # If base currency is EUR, cache USD rate
-        cache.update(usd=exch['usd']['rate'])
-    else:
-        # For other base currencies, cache both USD and EUR rates
-        cache.update(usd=exch['usd']['rate'], eur=exch['eur']['rate'])
-
-    print("Checking the cache...")
-
-    # Check if the target currency's rate is in the cache
-    if currency_exch in cache:
-        # If the rate is in the cache, calculate the exchanged amount
-        rate = round(amount_to_exch * cache[currency_exch], 2)
-        print("Oh! It is in the cache!")
-        print(f"You received {rate} {currency_exch.upper()}.")
-    else:
-        # If the rate is not in the cache, fetch it from the exchange rates and store it in cache
-        print("Sorry, but it is not in the cache!")
-        cache[currency_exch] = exch[currency_exch]['rate']
-        rate = round(amount_to_exch * cache[currency_exch], 2)
-        print(f"You received {rate} {currency_exch.upper()}.")
+from api_handler import get_exchange_data
+
+def get_supported_currencies(rates):
+    """
+    Return a list of supported currency codes from the rates dictionary.
+
+    Args:
+        rates (dict): Dictionary of currency codes and their exchange rates.
+
+    Returns:
+        list: List of supported currency codes (e.g., ['USD', 'EUR']).
+    """
+    return list(rates.keys())
+
+def is_valid_currency(currency_code, rates):
+    """
+    Check if the given currency code is valid and supported.
+
+    Args:
+        currency_code (str): Currency code to validate (e.g., 'USD').
+        rates (dict): Dictionary of available exchange rates.
+
+    Returns:
+        bool: True if the currency code exists in the rates, False otherwise.
+    """
+    return currency_code.upper() in rates
+
+# --- DEBUG / MANUAL TEST SECTION ---
+# This section runs only when you run this file directly (not when imported elsewhere)
+if __name__ == "__main__":
+    # Fetch live exchange data from the API
+    exchange_data = get_exchange_data()
+
+    # Print the first 5 currencies for quick inspection
+    print("Sample of live rates from API:")
+    print(list(exchange_data["rates"].items())[:5])
+
+    # Sample rates dictionary for local testing
+    rates_example = {"USD": 1.12, "EUR": 1.0, "GBP": 0.87}
+
+    # Print supported currencies
+    print("\nSupported currencies:", get_supported_currencies(rates_example))
+
+    # Check a few currency codes
+    print("Is 'usd' valid?", is_valid_currency("usd", rates_example))   # True
+    print("Is 'AUD' valid?", is_valid_currency("AUD", rates_example))  # False
\ No newline at end of file
diff --git a/Currency Script/tests/__init__.py b/Currency Script/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/Currency Script/tests/__pycache__/__init__.cpython-313.pyc b/Currency Script/tests/__pycache__/__init__.cpython-313.pyc
new file mode 100644
index 00000000..52c26ecd
Binary files /dev/null and b/Currency Script/tests/__pycache__/__init__.cpython-313.pyc differ
diff --git a/Currency Script/tests/__pycache__/test_api_handler.cpython-313-pytest-8.3.5.pyc b/Currency Script/tests/__pycache__/test_api_handler.cpython-313-pytest-8.3.5.pyc
new file mode 100644
index 00000000..adca8b35
Binary files /dev/null and b/Currency Script/tests/__pycache__/test_api_handler.cpython-313-pytest-8.3.5.pyc differ
diff --git a/Currency Script/tests/__pycache__/test_converter.cpython-313-pytest-8.3.5.pyc b/Currency Script/tests/__pycache__/test_converter.cpython-313-pytest-8.3.5.pyc
new file mode 100644
index 00000000..020a50ff
Binary files /dev/null and b/Currency Script/tests/__pycache__/test_converter.cpython-313-pytest-8.3.5.pyc differ
diff --git a/Currency Script/tests/__pycache__/test_currencies.cpython-313-pytest-8.3.5.pyc b/Currency Script/tests/__pycache__/test_currencies.cpython-313-pytest-8.3.5.pyc
new file mode 100644
index 00000000..adf1456a
Binary files /dev/null and b/Currency Script/tests/__pycache__/test_currencies.cpython-313-pytest-8.3.5.pyc differ
diff --git a/Currency Script/tests/test_api_handler.py b/Currency Script/tests/test_api_handler.py
new file mode 100644
index 00000000..50faa775
--- /dev/null
+++ b/Currency Script/tests/test_api_handler.py	
@@ -0,0 +1,37 @@
+import sys
+import os
+sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../src')))
+
+import unittest
+from unittest.mock import patch
+from src.api_handler import get_exchange_data
+
+class TestAPIHandler(unittest.TestCase):
+    """
+    Unit tests for the get_exchange_data function in api_handler.py.
+    """
+    @patch("api_handler.requests.get")
+    def test_get_exchange_data_success(self, mock_get):
+        mock_get.return_value.status_code = 200
+        mock_get.return_value.json.return_value = {
+            "base": "EUR",
+            "date": "2025-06-02",
+            "rates": {"USD": 1.14, "GBP": 0.84}
+        }
+
+        data = get_exchange_data()
+        self.assertEqual(data["base"], "EUR")
+        self.assertIn("USD", data["rates"])
+
+    @patch("api_handler.requests.get")
+    def test_get_exchange_data_failure(self, mock_get):
+        """
+        Test that get_exchange_data raises an exception when API response fails.
+        """
+        mock_get.return_value.status_code = 404
+        with self.assertRaises(Exception):
+            get_exchange_data()
+
+if __name__ == "__main__":
+    unittest.main()
+
diff --git a/Currency Script/tests/test_converter.py b/Currency Script/tests/test_converter.py
new file mode 100644
index 00000000..c6c4707f
--- /dev/null
+++ b/Currency Script/tests/test_converter.py	
@@ -0,0 +1,33 @@
+import unittest
+from converter import CurrencyConverter
+
+class TestCurrencyConverter(unittest.TestCase):
+    """Unit tests for CurrencyConverter class."""
+
+    @classmethod
+    def setUpClass(cls):
+        """Initialize converter once for all tests."""
+        cls.converter = CurrencyConverter()
+
+    def test_valid_conversion(self):
+        """Test converting from USD to EUR returns a float value."""
+        result = self.converter.convert("USD", "EUR", 100)
+        self.assertIsInstance(result, float)
+        self.assertGreater(result, 0)
+
+    def test_same_currency(self):
+        """Test converting a currency to itself returns the same amount."""
+        amount = 50
+        result = self.converter.convert("USD", "USD", amount)
+        self.assertAlmostEqual(result, amount, places=2)
+
+    def test_invalid_currency(self):
+        """Test invalid currency codes raise ValueError."""
+        with self.assertRaises(ValueError):
+            self.converter.convert("XXX", "EUR", 100)
+
+        with self.assertRaises(ValueError):
+            self.converter.convert("USD", "YYY", 100)
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/Currency Script/tests/test_currencies.py b/Currency Script/tests/test_currencies.py
new file mode 100644
index 00000000..f79a1164
--- /dev/null
+++ b/Currency Script/tests/test_currencies.py	
@@ -0,0 +1,33 @@
+import unittest
+from currencies import get_supported_currencies, is_valid_currency
+
+class TestCurrencies(unittest.TestCase):
+    """Unit tests for currency helper functions."""
+
+    def setUp(self):
+        """Set up sample rates dictionary for use in tests."""
+        self.sample_rates = {
+            "USD": 1.1,
+            "EUR": 1.0,
+            "GBP": 0.85,
+            "JPY": 150.0
+        }
+
+    def test_get_supported_currencies(self):
+        """Test that all currency codes are returned correctly."""
+        expected = ["USD", "EUR", "GBP", "JPY"]
+        result = get_supported_currencies(self.sample_rates)
+        self.assertListEqual(sorted(result), sorted(expected))
+
+    def test_is_valid_currency_true(self):
+        """Test that valid currency codes return True."""
+        self.assertTrue(is_valid_currency("usd", self.sample_rates))
+        self.assertTrue(is_valid_currency("EUR", self.sample_rates))
+
+    def test_is_valid_currency_false(self):
+        """Test that unsupported currency codes return False."""
+        self.assertFalse(is_valid_currency("ABC", self.sample_rates))
+        self.assertFalse(is_valid_currency("xyz", self.sample_rates))
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/README.md b/README.md
index 7e0f2397..6f9cbe51 100644
--- a/README.md
+++ b/README.md
@@ -53,6 +53,7 @@ More information on contributing and the general code of conduct for discussion
 | Countdown Timer                          | [Countdown Timer](https://github.com/DhanushNehru/Python-Scripts/tree/main/Countdown%20Timer)                                                          | Displays a message when the Input time elapses.                                                                                                                   |
 | Crop Images                              | [Crop Images](https://github.com/DhanushNehru/Python-Scripts/tree/main/Crop%20Images)                                                                  | A Python script to crop a given image.                                                                                                                            |
 | CSV to Excel                             | [CSV to Excel](https://github.com/DhanushNehru/Python-Scripts/tree/main/CSV%20to%20Excel)                                                              | A Python script to convert a CSV to an Excel file.                                                                                                                |
+| CSV_TO_NDJSON                             | [CSV to Excel](https://github.com/DhanushNehru/Python-Scripts/tree/main/CSV_TO_NDJSON)                                                              | A Python script to convert a CSV to an NDJSON files file.                                                                                                                |
 | Currency Script                          | [Currency Script](https://github.com/DhanushNehru/Python-Scripts/tree/main/Currency%20Script)                                                          | A Python script to convert the currency of one country to that of another.                                                                                        |
 | Digital Clock                            | [Digital Clock](https://github.com/DhanushNehru/Python-Scripts/tree/main/Digital%20Clock)                                                              | A Python script to preview a digital clock in the terminal.                                                                                                       |
 | Display Popup Window                     | [Display Popup Window](https://github.com/DhanushNehru/Python-Scripts/tree/main/Display%20Popup%20Window)                                              | A Python script to preview a GUI interface to the user.                                                                                                           |
@@ -127,8 +128,9 @@ More information on contributing and the general code of conduct for discussion
 | Rock Paper Scissor 1                     | [Rock Paper Scissor 1](https://github.com/DhanushNehru/Python-Scripts/tree/main/Rock%20Paper%20Scissor%201)                                            | A game of Rock Paper Scissors.                                                                                                                                    |
 | Rock Paper Scissor 2                     | [Rock Paper Scissor 2](https://github.com/DhanushNehru/Python-Scripts/tree/main/Rock%20Paper%20Scissor%202)                                            | A new version game of Rock Paper Scissors.                                                                                                                        |
 | Run Then Notify                          | [Run Then Notify](https://github.com/DhanushNehru/Python-Scripts/tree/main/Run%20Then%20Notify)                                                        | Runs a slow command and emails you when it completes execution.                                                                                                   |
+| Save File To Drive                       | [Save File To Drive](https://github.com/DhanushNehru/Python-Scripts/tree/master/Save%20file%20to%20Drive)                                              | Saves all files and folder with proper structure from a folder to drive easily through a python script .                                                          |
 | Selfie with Python                       | [Selfie with Python](https://github.com/DhanushNehru/Python-Scripts/tree/main/Selfie%20with%20Python)                                                  | Take your selfie with python .                                                                                                                                    |
-| Simple DDOS                              | [Simple DDOS](https://github.com/VanshajR/Python-Scripts/tree/main/Simple%20DDOS)                                                                      | The code allows you to send multiple HTTP requests concurrently for a specified duration.                                                                         |
+| Simple DDOS                              | [Simple DDOS](https://github.com/DhanushNehru/Python-Scripts/tree/main/Simple%20DDOS)                                                                      | The code allows you to send multiple HTTP requests concurrently for a specified duration.                                                                         |
 | Simple TCP Chat Server                   | [Simple TCP Chat Server](https://github.com/DhanushNehru/Python-Scripts/tree/main/TCP%20Chat%20Server)                                                 | Creates a local server on your LAN for receiving and sending messages!                                                                                            |
 | Smart Attendance System                  | [Smart Attendance System](https://github.com/DhanushNehru/Python-Scripts/tree/main/Smart%20Attendance%20System)                                        | This OpenCV framework is for Smart Attendance by actively decoding a student's QR Code.                                                                           |
 | Snake Game                               | [Snake Game](https://github.com/DhanushNehru/Python-Scripts/tree/main/Snake%20Game)                                                                    | Classic snake game using python.                                                                                                                                  |
@@ -139,6 +141,7 @@ More information on contributing and the general code of conduct for discussion
 | Take a break                             | [Take a break](https://github.com/DhanushNehru/Python-Scripts/tree/main/Take%20A%20Break)                                                              | Python code to take a break while working long hours.                                                                                                             |
 | Text Recognition                         | [Text Recognition](https://github.com/DhanushNehru/Python-Scripts/tree/Text-Recognition/Text%20Recognition)                                              | A Image Text Recognition ML Model to extract text from Images                                                                                                     |
 | Text to Image                            | [Text to Image](https://github.com/DhanushNehru/Python-Scripts/tree/main/Text%20to%20Image)                                                            | A Python script that will take your text and convert it to a JPEG.                                                                                                |
+| Thread Progress                          | [Thread Progress](https://github.com/DhanushNehru/Python-Scripts/tree/main/Thread%20Progress)                                                              | A Python script demonstrating safe multithreading by using a lock to update a shared progress variable concurrently.                                                           |
 | Tic Tac Toe 1                            | [Tic Tac Toe 1](https://github.com/DhanushNehru/Python-Scripts/tree/main/Tic-Tac-Toe%201)                                                              | A game of Tic Tac Toe.                                                                                                                                            |
 | Tik Tac Toe 2                            | [Tik Tac Toe 2](https://github.com/DhanushNehru/Python-Scripts/tree/main/Tic-Tac-Toe%202)                                                              | A game of Tik Tac Toe.                                                                                                                                            |
 | Turtle Art & Patterns                    | [Turtle Art](https://github.com/DhanushNehru/Python-Scripts/tree/main/Turtle%20Art)                                                                    | Scripts to view turtle art also have prompt-based ones.                                                                                                           |
@@ -155,7 +158,7 @@ More information on contributing and the general code of conduct for discussion
 | Website Blocker                          | [Website Blocker](https://github.com/DhanushNehru/Python-Scripts/tree/main/Website%20Blocker)                                                          | Downloads the website and loads it on your homepage in your local IP.                                                                                             |
 | Website Cloner                           | [Website Cloner](https://github.com/DhanushNehru/Python-Scripts/tree/main/Website%20Cloner)                                                            | Clones any website and opens the site in your local IP.                                                                                                           |
 | Web Scraper                              | [Web Scraper](https://github.com/DhanushNehru/Python-Scripts/tree/main/Web%20Scraper)                                                                        | A Python script that scrapes blog titles from [Python.org](https://www.python.org/) and saves them to a file.                                                                                |
-| Weight Converter                         | [Weight Converter](https://github.com/WatashiwaSid/Python-Scripts/tree/main/Weight%20Converter)                                                        | Simple GUI script to convert weight in different measurement units.                                                                                               |
+| Weight Converter                         | [Weight Converter](https://github.com/DhanushNehru/Python-Scripts/tree/main/Weight%20Converter)                                                        | Simple GUI script to convert weight in different measurement units.                                                                                               |
 | Wikipedia Data Extractor                 | [Wikipedia Data Extractor](https://github.com/DhanushNehru/Python-Scripts/tree/main/Wikipedia%20Data%20Extractor)                                      | A simple Wikipedia data extractor script to get output in your IDE.                                                                                               |
 | Word to PDF                              | [Word to PDF](https://github.com/DhanushNehru/Python-Scripts/tree/main/Word%20to%20PDF%20converter)                                                    | A Python script to convert an MS Word file to a PDF file.                                                                                                         |
 | Youtube Downloader                       | [Youtube Downloader](https://github.com/DhanushNehru/Python-Scripts/tree/main/Youtube%20Downloader)                                                    | Downloads any video from [YouTube](https://youtube.com) in video or audio format!                                                                                 |
@@ -173,7 +176,6 @@ You can use Gitpod in the cloud [![Gitpod Ready-to-Code](https://img.shields.io/
 <img src="https://contrib.rocks/image?repo=DhanushNehru/Python-Scripts" />
 </a>
 
-</br>
 
 If you liked this repository, support it by starring ⭐
 
diff --git a/Save file to Drive/drive/hello.txt b/Save file to Drive/drive/hello.txt
new file mode 100644
index 00000000..5e1c309d
--- /dev/null
+++ b/Save file to Drive/drive/hello.txt	
@@ -0,0 +1 @@
+Hello World
\ No newline at end of file
diff --git a/Save file to Drive/drive/hello/hello2.txt b/Save file to Drive/drive/hello/hello2.txt
new file mode 100644
index 00000000..e69de29b
diff --git a/Save file to Drive/drive/hello/hello3.txt b/Save file to Drive/drive/hello/hello3.txt
new file mode 100644
index 00000000..e69de29b
diff --git a/Save file to Drive/main.py b/Save file to Drive/main.py
new file mode 100644
index 00000000..881e97c3
--- /dev/null
+++ b/Save file to Drive/main.py	
@@ -0,0 +1,77 @@
+from pydrive.auth import GoogleAuth
+from pydrive.drive import GoogleDrive
+import os
+
+# Authenticate
+gauth = GoogleAuth()
+gauth.LocalWebserverAuth()
+drive = GoogleDrive(gauth)
+
+# === Prompt for target folder ===
+target_folder_name = input("Enter the name of the target folder in Google Drive: ").strip()
+
+def get_or_create_drive_folder(folder_name, parent_id='root'):
+    """Get Drive folder ID by name or create it under given parent"""
+    query = (
+        f"title='{folder_name}' and "
+        f"mimeType='application/vnd.google-apps.folder' and "
+        f"'{parent_id}' in parents and trashed=false"
+    )
+    file_list = drive.ListFile({'q': query}).GetList()
+    if file_list:
+        print(f"Folder '{folder_name}' found in Google Drive.")
+        return file_list[0]['id']
+    else:
+        print(f"Folder '{folder_name}' not found. Creating it...")
+        folder_metadata = {
+            'title': folder_name,
+            'parents': [{'id': parent_id}],
+            'mimeType': 'application/vnd.google-apps.folder'
+        }
+        folder = drive.CreateFile(folder_metadata)
+        folder.Upload()
+        return folder['id']
+
+# === Configuration ===
+local_root = r"drive"  # Your local folder name
+drive_root_id = get_or_create_drive_folder(target_folder_name)
+
+# Folder mapping cache
+folder_mapping = {local_root: drive_root_id}
+
+# Recursively walk and upload
+for root, dirs, files in os.walk(local_root):
+    rel_path = os.path.relpath(root, local_root)
+    
+    if rel_path == '.':
+        parent_id = drive_root_id
+    else:
+        parent_local = os.path.dirname(root)
+        parent_id = folder_mapping.get(parent_local, drive_root_id)
+
+        folder_name = os.path.basename(root)
+        folder_id = get_or_create_drive_folder(folder_name, parent_id)
+        folder_mapping[root] = folder_id
+
+    for file_name in files:
+        file_path = os.path.join(root, file_name)
+
+        # === Check if file already exists in this Drive folder ===
+        query = (
+            f"title='{file_name}' and "
+            f"'{folder_mapping[root]}' in parents and "
+            f"trashed=false"
+        )
+        existing_files = drive.ListFile({'q': query}).GetList()
+        if existing_files:
+            print(f"⏩ File '{file_name}' already exists in '{rel_path}', skipping.")
+            continue
+
+        print(f"⬆️ Uploading '{file_name}' to '{rel_path}'...")
+        file_drive = drive.CreateFile({
+            'title': file_name,
+            'parents': [{'id': folder_mapping[root]}]
+        })
+        file_drive.SetContentFile(file_path)
+        file_drive.Upload()
+        file_drive = None
diff --git a/Save file to Drive/readme.md b/Save file to Drive/readme.md
new file mode 100644
index 00000000..2b0872f4
--- /dev/null
+++ b/Save file to Drive/readme.md	
@@ -0,0 +1,69 @@
+
+
+# 📁 Save File and Folder to Drive
+
+A simple utility to interact with Google Drive. This project uses the Google Drive API and requires authentication via  `client_secret.json` file.
+
+## 🚀 Features
+
+* Upload files and folders to Google Drive.
+* Doesn't change folder structure
+* Easy setup for Google Drive API.
+
+---
+
+## 🛠️ Setup Instructions
+
+### 1. Install Dependencies
+
+Make sure you have Python 3 installed.
+
+```bash
+pip install -r requirements.txt
+```
+
+### 2. Generate `client_secret.json` (Google OAuth Credentials)
+
+To access Google Drive, you’ll need OAuth 2.0 credentials:
+
+1. Go to the **Google Cloud Console**:
+   👉 [Create OAuth Credentials](https://console.cloud.google.com/apis/credentials)
+
+2. Steps:
+   * Don't forget to check project name, create new project.
+   * Search **Google Drive API**, don't get confused with Google Drive Analytics API
+   * Click Enable
+   * Go to **Credentials** on left sidebar, click **Create Credential** on top and select **OAuth client ID**
+   * You might be asked to **configure consent screen**
+   * Click on it and click Get Started
+   * Add necessary details like app name and emails, Name example: test123
+   * Click **Create**
+   * Now select **Create OAuth Client**
+   * Choose application type as **Desktop app** and leave name as it is
+   * Download the JSON file and **rename it to `client_secret.json`**
+   * Place the file in the project directory
+   * Now you would have to create test user for using this API.
+   * Select **Audience** from left Sidebar
+   * Add all necessary emails under test email and save it
+
+📝 Official Guide:
+[Using OAuth 2.0 for Installed Applications](https://developers.google.com/identity/protocols/oauth2)
+
+---
+
+## ▶️ Running the Script
+
+Once everything is set up:
+
+```bash
+python main.py
+```
+
+---
+
+## 📎 Notes
+
+* Make sure to enable the **Google Drive API** in your Google Cloud Console.
+
+---
+
diff --git a/Save file to Drive/requirements.txt b/Save file to Drive/requirements.txt
new file mode 100644
index 00000000..7524380f
Binary files /dev/null and b/Save file to Drive/requirements.txt differ
diff --git a/Thread Progress/README.md b/Thread Progress/README.md
new file mode 100644
index 00000000..1430bf2c
--- /dev/null
+++ b/Thread Progress/README.md	
@@ -0,0 +1,19 @@
+## Thread Progress
+
+This script demonstrates the use of **Python threads** to simulate parallel progress updates using a shared variable and a `Lock` to avoid race conditions.
+
+### 🧠 Concepts Covered
+
+- Python `threading.Thread`
+- Synchronization with `threading.Lock`
+- Global variables and shared state
+- Simulated concurrent work using `time.sleep`
+
+### 📝 Description
+
+Two threads increment a shared `progress` variable by `10` in a loop. A `Lock` ensures only one thread can modify the shared variable at a time, preventing race conditions.
+
+### 👉 Run
+```
+python3 thread_progress.py
+```
diff --git a/Thread Progress/thread_progress.py b/Thread Progress/thread_progress.py
new file mode 100644
index 00000000..4b272e89
--- /dev/null
+++ b/Thread Progress/thread_progress.py	
@@ -0,0 +1,28 @@
+import threading
+import time
+
+# Shared variable
+progress = 0
+lock = threading.Lock()
+
+def increase_by_10():
+    global progress
+    for _ in range(10):
+        time.sleep(0.01)  # Simulate work
+        with lock:  # Only one thread can change `progress` at a time
+            progress += 10
+            print(f"{threading.current_thread().name}: progress = {progress}%")
+
+# Create two threads
+thread1 = threading.Thread(target=increase_by_10, name="Thread-1")
+thread2 = threading.Thread(target=increase_by_10, name="Thread-2")
+
+# Start the threads
+thread1.start()
+thread2.start()
+
+# Wait for both threads to finish
+thread1.join()
+thread2.join()
+
+print(f"Final progress: {progress}%")
