Spaces:
Sleeping
Sleeping
mattoofahaddcube
commited on
Commit
•
73c78bc
0
Parent(s):
adding file to the repo
Browse files- .gitignore +106 -0
- functions.py +53 -0
- readme.md +55 -0
- requirements.txt +1 -0
- salary_calculator.py +46 -0
.gitignore
ADDED
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Byte-compiled / optimized / DLL files
|
2 |
+
__pycache__/
|
3 |
+
*.py[cod]
|
4 |
+
*$py.class
|
5 |
+
|
6 |
+
# C extensions
|
7 |
+
*.so
|
8 |
+
|
9 |
+
# Distribution / packaging
|
10 |
+
.Python
|
11 |
+
build/
|
12 |
+
develop-eggs/
|
13 |
+
dist/
|
14 |
+
downloads/
|
15 |
+
eggs/
|
16 |
+
.eggs/
|
17 |
+
lib/
|
18 |
+
lib64/
|
19 |
+
parts/
|
20 |
+
sdist/
|
21 |
+
var/
|
22 |
+
wheels/
|
23 |
+
*.egg-info/
|
24 |
+
.installed.cfg
|
25 |
+
*.egg
|
26 |
+
MANIFEST
|
27 |
+
|
28 |
+
# PyInstaller
|
29 |
+
# Usually these files are written by a python script from a template
|
30 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
31 |
+
*.manifest
|
32 |
+
*.spec
|
33 |
+
|
34 |
+
# Installer logs
|
35 |
+
pip-log.txt
|
36 |
+
pip-delete-this-directory.txt
|
37 |
+
|
38 |
+
# Unit test / coverage reports
|
39 |
+
htmlcov/
|
40 |
+
.tox/
|
41 |
+
.coverage
|
42 |
+
.coverage.*
|
43 |
+
.cache
|
44 |
+
nosetests.xml
|
45 |
+
coverage.xml
|
46 |
+
*.cover
|
47 |
+
.hypothesis/
|
48 |
+
.pytest_cache/
|
49 |
+
|
50 |
+
# Translations
|
51 |
+
*.mo
|
52 |
+
*.pot
|
53 |
+
|
54 |
+
# Django stuff:
|
55 |
+
*.log
|
56 |
+
local_settings.py
|
57 |
+
db.sqlite3
|
58 |
+
|
59 |
+
# Flask stuff:
|
60 |
+
instance/
|
61 |
+
.webassets-cache
|
62 |
+
|
63 |
+
# Scrapy stuff:
|
64 |
+
.scrapy
|
65 |
+
|
66 |
+
# Sphinx documentation
|
67 |
+
docs/_build/
|
68 |
+
|
69 |
+
# PyBuilder
|
70 |
+
target/
|
71 |
+
|
72 |
+
# Jupyter Notebook
|
73 |
+
.ipynb_checkpoints
|
74 |
+
|
75 |
+
# pyenv
|
76 |
+
.python-version
|
77 |
+
|
78 |
+
# celery beat schedule file
|
79 |
+
celerybeat-schedule
|
80 |
+
|
81 |
+
# SageMath parsed files
|
82 |
+
*.sage.py
|
83 |
+
|
84 |
+
# Environments
|
85 |
+
.env
|
86 |
+
.venv
|
87 |
+
env/
|
88 |
+
venv/
|
89 |
+
ENV/
|
90 |
+
env.bak/
|
91 |
+
venv.bak/
|
92 |
+
|
93 |
+
# Spyder project settings
|
94 |
+
.spyderproject
|
95 |
+
.spyproject
|
96 |
+
|
97 |
+
# Rope project settings
|
98 |
+
.ropeproject
|
99 |
+
|
100 |
+
# mkdocs documentation
|
101 |
+
/site
|
102 |
+
|
103 |
+
# mypy
|
104 |
+
.mypy_cache/
|
105 |
+
|
106 |
+
.idea
|
functions.py
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
def calculate_monthly_tax(monthly_income):
|
2 |
+
annual_income = monthly_income * 12
|
3 |
+
tax_brackets = [
|
4 |
+
(0, 600000, 0),
|
5 |
+
(600000, 1200000, 0.05),
|
6 |
+
(1200000, 2200000, 0.15),
|
7 |
+
(2200000, 3200000, 0.25),
|
8 |
+
(3200000, 4100000, 0.30),
|
9 |
+
(4100000, float("inf"), 0.35),
|
10 |
+
]
|
11 |
+
total_tax = 0
|
12 |
+
remaining_income = annual_income
|
13 |
+
for lower, upper, rate in tax_brackets:
|
14 |
+
if remaining_income <= 0:
|
15 |
+
break
|
16 |
+
|
17 |
+
taxable_amount = min(remaining_income, upper - lower)
|
18 |
+
tax = taxable_amount * rate
|
19 |
+
total_tax += tax
|
20 |
+
remaining_income -= taxable_amount
|
21 |
+
monthly_tax = total_tax / 12
|
22 |
+
return round(monthly_tax, 2)
|
23 |
+
|
24 |
+
|
25 |
+
def calculate_net_salary(gross_salary):
|
26 |
+
return gross_salary - calculate_monthly_tax(gross_salary)
|
27 |
+
|
28 |
+
|
29 |
+
def calculated_initial_desired_net(
|
30 |
+
current_salary, desired_increment, daily_cost_of_travel, physical_days_per_week
|
31 |
+
):
|
32 |
+
return (current_salary + current_salary * desired_increment) + (
|
33 |
+
daily_cost_of_travel * physical_days_per_week * 4.5
|
34 |
+
)
|
35 |
+
|
36 |
+
|
37 |
+
def calculate_additional_amount(initial_desired_net):
|
38 |
+
gross_salary = initial_desired_net
|
39 |
+
max_iterations = 100
|
40 |
+
for _ in range(max_iterations):
|
41 |
+
net_salary = calculate_net_salary(gross_salary)
|
42 |
+
if abs(net_salary - initial_desired_net) < 0.01:
|
43 |
+
break
|
44 |
+
gross_salary += initial_desired_net - net_salary
|
45 |
+
additional_amount = gross_salary - initial_desired_net
|
46 |
+
|
47 |
+
return {
|
48 |
+
"initial_desired_net": round(initial_desired_net, 2),
|
49 |
+
"gross_salary_needed": round(gross_salary, 2),
|
50 |
+
"additional_amount": round(additional_amount, 2),
|
51 |
+
"tax": round(calculate_monthly_tax(gross_salary), 2),
|
52 |
+
"final_net_salary": round(calculate_net_salary(gross_salary), 2),
|
53 |
+
}
|
readme.md
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Salary Calculator
|
2 |
+
|
3 |
+
This Salary Calculator is a Python-based command-line tool designed to help users determine the additional amount needed on top of their desired salary to account for taxes. It takes into consideration factors such as current salary, desired increment, daily travel costs, and the number of physical workdays per week.
|
4 |
+
|
5 |
+
## Getting Started
|
6 |
+
|
7 |
+
### A. Prerequisites
|
8 |
+
|
9 |
+
- Conda environment manager
|
10 |
+
- Python version 3.11
|
11 |
+
|
12 |
+
### B. Setting Up the Environment
|
13 |
+
|
14 |
+
1. **Create and activate a Conda environment**:
|
15 |
+
- Create: `conda create -n salary_calc_env python=3.11 -y`
|
16 |
+
- Activate: `conda activate salary_calc_env`
|
17 |
+
- **Note**: You can replace `salary_calc_env` with your preferred environment name.
|
18 |
+
|
19 |
+
2. **Install required packages**:
|
20 |
+
```bash
|
21 |
+
pip install -r requirements.txt
|
22 |
+
```
|
23 |
+
|
24 |
+
### C. Running the Application
|
25 |
+
|
26 |
+
- Using default values:
|
27 |
+
```bash
|
28 |
+
python salary_calculator.py 90000
|
29 |
+
```
|
30 |
+
This uses default values of `desired_increment_percentage=0.3`, `daily_cost_of_travel=1500`, and `physical_days_per_week=5`.
|
31 |
+
|
32 |
+
- Using custom values:
|
33 |
+
```bash
|
34 |
+
python salary_calculator.py 220000 --desired-increment-percentage 0.10 --daily-cost-of-travel 2000 --physical-days-per-week 3
|
35 |
+
```
|
36 |
+
F
|
37 |
+
- For help and to see all available options:
|
38 |
+
```bash
|
39 |
+
python salary_calculator.py --help
|
40 |
+
```
|
41 |
+
|
42 |
+
## Features
|
43 |
+
|
44 |
+
- Calculates the additional amount needed to achieve the desired net salary after tax deductions
|
45 |
+
- Considers factors like current salary, desired increment, daily travel costs, and work schedule
|
46 |
+
- Provides a detailed breakdown of the calculation results
|
47 |
+
- Offers flexibility to use default values or specify custom inputs
|
48 |
+
|
49 |
+
## Contributing
|
50 |
+
|
51 |
+
Feel free to fork this project and submit pull requests with any enhancements or bug fixes. For major changes, please open an issue first to discuss the proposed changes.
|
52 |
+
|
53 |
+
## License
|
54 |
+
|
55 |
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
requirements.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
typer==0.12.3
|
salary_calculator.py
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import typer
|
2 |
+
from typing import Optional
|
3 |
+
|
4 |
+
from functions import calculated_initial_desired_net, calculate_additional_amount
|
5 |
+
|
6 |
+
app = typer.Typer()
|
7 |
+
|
8 |
+
|
9 |
+
@app.command()
|
10 |
+
def calculate_salary(
|
11 |
+
current_salary: int = typer.Argument(..., help="Current monthly salary in PKR"),
|
12 |
+
desired_increment_percentage: Optional[float] = typer.Option(
|
13 |
+
0.3, help="Desired salary increment as a decimal (e.g., 0.3 for 30%)"
|
14 |
+
),
|
15 |
+
daily_cost_of_travel: Optional[int] = typer.Option(
|
16 |
+
1500, help="Daily cost of travel in PKR"
|
17 |
+
),
|
18 |
+
physical_days_per_week: Optional[int] = typer.Option(
|
19 |
+
5, help="Number of physical days per week"
|
20 |
+
),
|
21 |
+
):
|
22 |
+
"""
|
23 |
+
Calculate the additional amount needed for desired salary after tax adjustment.
|
24 |
+
"""
|
25 |
+
initial_desired_net = calculated_initial_desired_net(
|
26 |
+
current_salary, desired_increment_percentage, daily_cost_of_travel, physical_days_per_week
|
27 |
+
)
|
28 |
+
result = calculate_additional_amount(initial_desired_net)
|
29 |
+
|
30 |
+
typer.echo("Salary Calculation Results")
|
31 |
+
typer.echo("--------------------------")
|
32 |
+
typer.echo(
|
33 |
+
f"{'Initial Desired Net Salary':<30} PKR {result['initial_desired_net']:>13,.2f}"
|
34 |
+
)
|
35 |
+
typer.echo(
|
36 |
+
f"{'Gross Salary Needed':<30} PKR {result['gross_salary_needed']:>13,.2f}"
|
37 |
+
)
|
38 |
+
typer.echo(
|
39 |
+
f"{'Additional Amount Needed':<30} PKR {result['additional_amount']:>13,.2f}"
|
40 |
+
)
|
41 |
+
typer.echo(f"{'Tax':<30} PKR {result['tax']:>13,.2f}")
|
42 |
+
typer.echo(f"{'Final Net Salary':<30} PKR {result['final_net_salary']:>13,.2f}")
|
43 |
+
|
44 |
+
|
45 |
+
if __name__ == "__main__":
|
46 |
+
app()
|