topsis-nitin-102303918 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
topsis/__init__.py ADDED
File without changes
topsis/cli.py ADDED
@@ -0,0 +1,130 @@
1
+ import argparse
2
+ import pandas as pd
3
+ import numpy as np
4
+ import sys
5
+
6
+ def main():
7
+
8
+ parser = argparse.ArgumentParser(
9
+ description="TOPSIS Multi-Criteria Decision Making Tool"
10
+ )
11
+
12
+ parser.add_argument("input_file", help="Input data file (.csv or .xlsx)")
13
+ parser.add_argument("weights", help="Comma-separated weights")
14
+ parser.add_argument("impacts", help="Comma-separated impacts (+ or -)")
15
+ parser.add_argument("output_file", help="Output result file (.csv or .xlsx)")
16
+
17
+ args = parser.parse_args()
18
+
19
+ input_file = args.input_file
20
+ weights = args.weights
21
+ impacts = args.impacts
22
+ output_file = args.output_file
23
+
24
+ # ---------- FILE READING ----------
25
+ try:
26
+ if input_file.endswith(".csv"):
27
+ df = pd.read_csv(input_file)
28
+ elif input_file.endswith(".xlsx"):
29
+ df = pd.read_excel(input_file)
30
+ else:
31
+ print("Error: Only CSV or XLSX files are supported.")
32
+ sys.exit(1)
33
+ except FileNotFoundError:
34
+ print("Error: File not found.")
35
+ sys.exit(1)
36
+
37
+ # ---------- CLEAN DATA ----------
38
+ df = df.dropna(axis=1, how='all')
39
+ df.columns = df.columns.str.strip()
40
+ df = df.loc[:, (df.columns != '') & (~df.columns.str.contains('^Unnamed'))]
41
+
42
+ # ---------- VALIDATIONS ----------
43
+ if df.shape[1] < 3:
44
+ print("Error: Input file must contain at least 3 columns.")
45
+ sys.exit(1)
46
+
47
+ criteria_data = df.iloc[:, 1:]
48
+
49
+ if criteria_data.apply(pd.to_numeric, errors='coerce').isnull().values.any():
50
+ print("Error: Non-numeric values found in criteria columns.")
51
+ sys.exit(1)
52
+
53
+ # ---------- SPLIT INPUTS ----------
54
+ weights_list = [w.strip() for w in weights.split(',')]
55
+ impacts_list = [i.strip() for i in impacts.split(',')]
56
+
57
+ criteria_count = df.shape[1] - 1
58
+
59
+ if not (len(weights_list) == len(impacts_list) == criteria_count):
60
+ print("Error: Number of weights, impacts and criteria columns must be the same.")
61
+ sys.exit(1)
62
+
63
+ for impact in impacts_list:
64
+ if impact not in ['+', '-']:
65
+ print("Error: Impacts must be either '+' or '-'.")
66
+ sys.exit(1)
67
+
68
+ try:
69
+ weights_list = [float(w) for w in weights_list]
70
+ except ValueError:
71
+ print("Error: Weights must be numeric.")
72
+ sys.exit(1)
73
+
74
+ # ---------- TOPSIS CALCULATION ----------
75
+
76
+ matrix = criteria_data.astype(float).values
77
+
78
+ # Step 1: Normalize
79
+ norm_matrix = matrix / np.sqrt((matrix ** 2).sum(axis=0))
80
+
81
+ # Step 2: Multiply Weights
82
+ weighted_matrix = norm_matrix * weights_list
83
+
84
+ # Step 3: Ideal Best & Worst
85
+ ideal_best = []
86
+ ideal_worst = []
87
+
88
+ for i in range(criteria_count):
89
+ if impacts_list[i] == '+':
90
+ ideal_best.append(weighted_matrix[:, i].max())
91
+ ideal_worst.append(weighted_matrix[:, i].min())
92
+ else:
93
+ ideal_best.append(weighted_matrix[:, i].min())
94
+ ideal_worst.append(weighted_matrix[:, i].max())
95
+
96
+ ideal_best = np.array(ideal_best)
97
+ ideal_worst = np.array(ideal_worst)
98
+
99
+ # Step 4: Distance Calculation
100
+ dist_best = np.sqrt(((weighted_matrix - ideal_best) ** 2).sum(axis=1))
101
+ dist_worst = np.sqrt(((weighted_matrix - ideal_worst) ** 2).sum(axis=1))
102
+
103
+ # Step 5: Score
104
+ scores = dist_worst / (dist_best + dist_worst)
105
+
106
+ # Step 6: Rank
107
+ ranks = scores.argsort()[::-1] + 1
108
+
109
+ # ---------- OUTPUT ----------
110
+ df['Topsis Score'] = scores
111
+ df['Rank'] = ranks
112
+
113
+ try:
114
+ if output_file.endswith(".csv"):
115
+ df.to_csv(output_file, index=False)
116
+ elif output_file.endswith(".xlsx"):
117
+ df.to_excel(output_file, index=False)
118
+ else:
119
+ print("Error: Output file must be CSV or XLSX.")
120
+ sys.exit(1)
121
+ except Exception as e:
122
+ print("Error saving file:", e)
123
+ sys.exit(1)
124
+
125
+ print("TOPSIS calculation completed successfully!")
126
+ print("Results saved to:", output_file)
127
+
128
+
129
+ if __name__ == "__main__":
130
+ main()
@@ -0,0 +1,80 @@
1
+ Metadata-Version: 2.4
2
+ Name: topsis-nitin-102303918
3
+ Version: 0.1.0
4
+ Summary: TOPSIS CLI Tool
5
+ Author: Nitin Malhotra
6
+ Requires-Python: >=3.8
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: pandas
9
+ Requires-Dist: numpy
10
+ Requires-Dist: openpyxl
11
+
12
+ # Topsis-Nitin-102303918
13
+
14
+ A command-line Python implementation of the **TOPSIS (Technique for Order Preference by Similarity to Ideal Solution)** algorithm used in **Multi-Criteria Decision Making (MCDM)**.
15
+
16
+ ---
17
+
18
+ ## Features
19
+
20
+ - Supports **CSV** and **Excel (.xlsx)** input files
21
+ - Implements full TOPSIS ranking method
22
+ - Validates user input and handles common errors
23
+ - Produces decision scores and ranks
24
+ - Lightweight and easy-to-use CLI tool
25
+
26
+ ---
27
+
28
+ ## About TOPSIS
29
+
30
+ TOPSIS is a popular decision-making technique that ranks alternatives based on their distance from the **ideal best** and **ideal worst** solutions.
31
+
32
+ ---
33
+
34
+ ## Installation
35
+ pip install topsis-nitin-102303918
36
+
37
+ ---
38
+
39
+ ## Usage
40
+
41
+ topsis <inputfile> <weights> <impacts> <outputfile>
42
+
43
+ EXAMPLE:
44
+ topsis data.xlsx "1,1,1,1" "+,+,+,+" result.csv
45
+
46
+ ---
47
+
48
+ ## Input Rules
49
+
50
+ 1. First column → Alternative names
51
+ 2. Remaining columns → Numeric criteria only
52
+ 3. Minimum 3 columns required
53
+ 4. Number of weights must equal number of criteria
54
+ 5. Number of impacts must equal number of criteria
55
+ 6. Impacts must be:
56
+ + → Benefit criterion
57
+ - → Cost criterion
58
+
59
+ ---
60
+
61
+ ## Output
62
+
63
+ The output file contains:
64
+ Original dataset
65
+ Topsis Score
66
+ Rank
67
+ **Higher score indicates a better alternative.**
68
+
69
+ ---
70
+
71
+ ## Dependencies
72
+
73
+ Automatically installed with the package:
74
+ pandas
75
+ numpy
76
+ openpyxl
77
+
78
+ ## Author
79
+
80
+ **Nitin Malhotra**
@@ -0,0 +1,7 @@
1
+ topsis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ topsis/cli.py,sha256=N7sdmRsg9GIGFVJ2AuvmPeWBQR0rPUBW9WQOoLykeMQ,4115
3
+ topsis_nitin_102303918-0.1.0.dist-info/METADATA,sha256=SaI46u6xhqT8E1Rwcl-SOHrQVGO_6g_nE2mdipAEn7g,1704
4
+ topsis_nitin_102303918-0.1.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
5
+ topsis_nitin_102303918-0.1.0.dist-info/entry_points.txt,sha256=3V2j6YZrfUJiVjtMbz-vudKNFoHSC28wmceJjvj3iCw,43
6
+ topsis_nitin_102303918-0.1.0.dist-info/top_level.txt,sha256=ol7AZ-3jpBeKNxw8WZBbIF4dSQOBGkuzmZDZaufWR4Q,7
7
+ topsis_nitin_102303918-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.10.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ topsis = topsis.cli:main
@@ -0,0 +1 @@
1
+ topsis