mattoofahaddcube commited on
Commit
73c78bc
0 Parent(s):

adding file to the repo

Browse files
Files changed (5) hide show
  1. .gitignore +106 -0
  2. functions.py +53 -0
  3. readme.md +55 -0
  4. requirements.txt +1 -0
  5. 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()