Skip to content

Commit 9279c99

Browse files
authored
Merge branch 'main' into master
2 parents e1707ec + c5ccc03 commit 9279c99

File tree

10 files changed

+185
-89
lines changed

10 files changed

+185
-89
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ If this is your first time contributing to an open source project, check out thi
2828

2929
## Code of Conduct
3030

31-
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.
31+
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.

CSV_TO_NDJSON/README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# README.md
2+
3+
# CSV to NDJSON Converter
4+
5+
This Python script converts a CSV file located in this folder into an NDJSON file saved in the same folder.
6+
7+
## What is NDJSON?
8+
9+
NDJSON (Newline Delimited JSON) is a convenient format for streaming JSON objects, where each line is a valid JSON object.
10+
It’s widely used in data pipelines and tools such as **Google Cloud BigQuery**, **ElasticSearch**, and many other data processing platforms.
11+
12+
## How to use
13+
14+
1. Place your CSV file in this folder.
15+
2. Make sure you have Python 3 installed.
16+
3. Run the script from this folder with:
17+
18+
```bash
19+
python csv_to_ndjson.py input.csv output.ndjson
20+
21+
22+
#### Example
23+
If you have a CSV file like this:
24+
25+
```csv
26+
name,age,city
27+
Alice,30,New York
28+
Bob,25,Los Angeles
29+
```
30+
31+
The output NDJSON will be:
32+
33+
```json
34+
{"name":"Alice","age":"30","city":"New York"}
35+
{"name":"Bob","age":"25","city":"Los Angeles"}
36+
```
37+
38+
Feel free to modify or extend it as needed.

CSV_TO_NDJSON/csv_to_ndjson.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# csv_to_ndjson.py
2+
import csv
3+
import json
4+
import sys
5+
import os
6+
7+
8+
def csv_to_ndjson(csv_filename, ndjson_filename):
9+
base_dir = os.path.dirname(os.path.abspath(__file__))
10+
11+
csv_path = os.path.join(base_dir, csv_filename)
12+
ndjson_path = os.path.join(base_dir, ndjson_filename)
13+
14+
try:
15+
with (
16+
open(csv_path, mode="r", encoding="utf-8") as f_csv,
17+
open(ndjson_path, mode="w", encoding="utf-8") as f_ndjson,
18+
):
19+
reader = csv.DictReader(f_csv)
20+
for row in reader:
21+
f_ndjson.write(
22+
json.dumps(row, ensure_ascii=False, separators=(",", ":")) + "\n"
23+
)
24+
25+
print(f"Successfully converted '{csv_path}' to '{ndjson_path}'")
26+
27+
except FileNotFoundError:
28+
print(f"Error: CSV file '{csv_path}' not found.")
29+
except Exception as e:
30+
print(f"An error occurred: {e}")
31+
32+
33+
if __name__ == "__main__":
34+
if len(sys.argv) != 3:
35+
print("Usage: python csv_to_ndjson.py input.csv output.ndjson")
36+
else:
37+
csv_file = sys.argv[1]
38+
ndjson_file = sys.argv[2]
39+
csv_to_ndjson(csv_file, ndjson_file)

Currency Script/.idea/Currency Script.iml

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Currency Script/.idea/misc.xml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Currency Script/src/api_handler.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
import requests
2-
import json
32

4-
def get_exchange_data(api_url: str = "https://theratesapi.com/api/latest/") -> dict:
3+
def get_exchange_data(api_url: str = "https://open.er-api.com/v6/latest") -> dict:
54
"""Fetch latest exchange data from the API."""
65
response = requests.get(api_url)
76
if response.status_code != 200:
87
raise Exception(f"API request failed with status {response.status_code}")
98

109
data = response.json()
11-
return data # This includes 'base', 'date', and 'rates'
10+
# Ensure response was successful
11+
if data.get("result") != "success":
12+
raise Exception(f"API returned error: {data.get('error-type', 'Unknown error')}")
13+
14+
return data # Includes 'base_code', 'time_last_update_utc', and 'rates'
1215

1316
# NOTE - for logging & debugging
1417
if __name__ == "__main__":
1518
exchange_data = get_exchange_data()
16-
print("Base currency:", exchange_data["base"])
17-
print("Date:", exchange_data["date"])
19+
print("Base currency:", exchange_data["base_code"])
20+
print("Date:", exchange_data["time_last_update_utc"])
1821
print("Rates:", list(exchange_data["rates"].items())[:5])

Currency Script/src/converter.py

Lines changed: 45 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,52 @@
1-
# TODO REVIEW AND ENSURE THE PURPOSE OF THIS MODULE IS TO CONVERT
2-
# Python program to convert the currency
3-
# of one country to that of another country
4-
5-
# Import the modules needed
6-
import requests
7-
8-
class Currency_convertor:
9-
# empty dict to store the conversion rates
10-
rates = {}
11-
12-
def __init__(self, url):
13-
data = requests.get(url).json()
14-
# Extracting only the rates from the json data
1+
"""
2+
CurrencyConverter: Converts an amount from one currency to another using live exchange rates.
3+
"""
4+
5+
from api_handler import get_exchange_data
6+
7+
class CurrencyConverter:
8+
def __init__(self):
9+
data = get_exchange_data()
1510
self.rates = data["rates"]
1611

17-
# function to do a simple cross multiplication between
18-
# the amount and the conversion rates
19-
def convert(self, from_currency, to_currency, amount):
20-
initial_amount = amount
21-
if from_currency != 'EUR':
22-
amount = amount / self.rates[from_currency]
12+
def convert(self, from_currency: str, to_currency: str, amount: float) -> float:
13+
"""
14+
Convert amount between two currencies.
15+
16+
Args:
17+
from_currency: Source currency code (e.g., 'USD')
18+
to_currency: Target currency code (e.g., 'AUD')
19+
amount: Amount to convert
20+
21+
Returns:
22+
Converted amount as float
23+
24+
Raises:
25+
ValueError: If a currency code is invalid
26+
"""
27+
from_currency = from_currency.upper()
28+
to_currency = to_currency.upper()
29+
30+
if from_currency not in self.rates or to_currency not in self.rates:
31+
raise ValueError("Invalid currency code.")
2332

24-
# limiting the precision to 2 decimal places
25-
amount = round(amount * self.rates[to_currency], 2)
26-
print('{} {} = {} {}'.format(initial_amount, from_currency, amount, to_currency))
33+
# Convert amount to base (EUR), then to target
34+
amount_in_base = amount if from_currency == "EUR" else amount / self.rates[from_currency]
35+
converted_amount = round(amount_in_base * self.rates[to_currency], 2)
36+
return converted_amount
2737

28-
# Driver code
38+
# --- DEBUG / MANUAL TEST ---
2939
if __name__ == "__main__":
40+
print("Running manual test for CurrencyConverter...\n")
3041

31-
YOUR_ACCESS_KEY = 'YOUR_ACCESS_KEY_HERE' # Define your access key
32-
url = f'http://data.fixer.io/api/latest?access_key={YOUR_ACCESS_KEY}' # Use f-string for cleaner concatenation
33-
c = Currency_convertor(url)
34-
35-
from_country = input("From Country (currency code): ")
36-
to_country = input("To Country (currency code): ")
37-
amount = float(input("Amount: ")) # Use float for decimal support
42+
converter = CurrencyConverter()
43+
from_cur = "USD"
44+
to_cur = "AUD"
45+
amt = 100.0
3846

39-
c.convert(from_country, to_country, amount)
47+
print(f"Converting {amt} {from_cur} to {to_cur}...")
48+
try:
49+
result = converter.convert(from_cur, to_cur, amt)
50+
print(f"{amt} {from_cur} = {result} {to_cur}")
51+
except ValueError as e:
52+
print("Error during conversion:", e)

Currency Script/src/currencies.py

Lines changed: 22 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,29 @@
1-
# TODO REVIEW BELOW CODE TO ENSURE THAT WHAT IS IN THIS MODULE FOR FUNCTION RECALLING CURRENCY FROM API
2-
# Importing necessary modules for currency formatting and HTTP requests
3-
from locale import currency
4-
import requests
5-
import json
1+
from api_handler import get_exchange_data
62

7-
# Get the base currency input from the user and convert it to lowercase
8-
currency = input("Enter the base currency (e.g., USD, EUR): ").lower()
3+
# Returns a list of all supported currency codes.
4+
def get_supported_currencies(rates):
5+
return list(rates.keys())
96

10-
# Initialize an empty cache to store exchange rates
11-
cache = {}
7+
# Checks if a currency code is supported.
8+
def is_valid_currency(currency_code, rates):
9+
return currency_code.upper() in rates
1210

13-
# Infinite loop to process exchange requests until the user exits
14-
while True:
11+
# --- DEBUG / MANUAL TEST SECTION ---
12+
# This section runs only when you run this file directly (not when imported elsewhere)
13+
if __name__ == "__main__":
14+
# Fetch live exchange data from the API
15+
exchange_data = get_exchange_data()
1516

16-
# Get the target currency input from the user and convert it to lowercase
17-
currency_exch = input("Enter the currency to exchange to (leave blank to exit): ").lower()
17+
# Print the first 5 currencies for quick inspection
18+
print("Sample of live rates from API:")
19+
print(list(exchange_data["rates"].items())[:5])
1820

19-
# If the input is blank, break out of the loop (exit condition)
20-
if currency_exch == '':
21-
break
21+
# Sample rates dictionary for local testing
22+
rates_example = {"USD": 1.12, "EUR": 1.0, "GBP": 0.87}
2223

23-
# Get the amount to exchange from the user
24-
amount_to_exch = int(input("Enter the amount to exchange: "))
24+
# Print supported currencies
25+
print("\nSupported currencies:", get_supported_currencies(rates_example))
2526

26-
# URL for getting exchange rates from floatrates.com
27-
URL = f'http://www.floatrates.com/daily/{currency}.json'
28-
29-
# Fetch the exchange rates in JSON format
30-
exch = json.loads(requests.get(URL).text)
31-
32-
# Update cache for USD and EUR based on the base currency
33-
if currency == 'usd':
34-
# If base currency is USD, cache EUR rate
35-
cache.update(eur=exch['eur']['rate'])
36-
elif currency == 'eur':
37-
# If base currency is EUR, cache USD rate
38-
cache.update(usd=exch['usd']['rate'])
39-
else:
40-
# For other base currencies, cache both USD and EUR rates
41-
cache.update(usd=exch['usd']['rate'], eur=exch['eur']['rate'])
42-
43-
print("Checking the cache...")
44-
45-
# Check if the target currency's rate is in the cache
46-
if currency_exch in cache:
47-
# If the rate is in the cache, calculate the exchanged amount
48-
rate = round(amount_to_exch * cache[currency_exch], 2)
49-
print("Oh! It is in the cache!")
50-
print(f"You received {rate} {currency_exch.upper()}.")
51-
else:
52-
# If the rate is not in the cache, fetch it from the exchange rates and store it in cache
53-
print("Sorry, but it is not in the cache!")
54-
cache[currency_exch] = exch[currency_exch]['rate']
55-
rate = round(amount_to_exch * cache[currency_exch], 2)
56-
print(f"You received {rate} {currency_exch.upper()}.")
27+
# Check a few currency codes
28+
print("Is 'usd' valid?", is_valid_currency("usd", rates_example)) # True
29+
print("Is 'AUD' valid?", is_valid_currency("AUD", rates_example)) # False

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ More information on contributing and the general code of conduct for discussion
128128
| 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. |
129129
| 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. |
130130
| 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. |
131-
| 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 .
131+
| 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 . |
132132
| Selfie with Python | [Selfie with Python](https://github.com/DhanushNehru/Python-Scripts/tree/main/Selfie%20with%20Python) | Take your selfie with python . |
133133
| 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. |
134134
| 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! |

update_master_to_main.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import os
2+
3+
def update_readme():
4+
if not os.path.exists('README.md'):
5+
print("README.md not found")
6+
return
7+
8+
with open('README.md', 'r', encoding='utf-8') as f:
9+
content = f.read()
10+
11+
with open('README.md.backup', 'w', encoding='utf-8') as f:
12+
f.write(content)
13+
14+
updated = content.replace('/master/', '/main/')
15+
updated = updated.replace('/blob/master/', '/blob/main/')
16+
updated = updated.replace('/tree/master/', '/tree/main/')
17+
18+
with open('README.md', 'w', encoding='utf-8') as f:
19+
f.write(updated)
20+
21+
changes = content.count('/master/') - updated.count('/master/')
22+
print(f"Updated {changes} references")
23+
24+
if __name__ == "__main__":
25+
update_readme()

0 commit comments

Comments
 (0)