chtoolbox 0.2.4__tar.gz → 1.1.0__tar.gz

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.
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Christian Hågenvik
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Christian Hågenvik
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,23 @@
1
+ Metadata-Version: 2.1
2
+ Name: chtoolbox
3
+ Version: 1.1.0
4
+ Summary: UNKNOWN
5
+ Home-page: https://github.com/chagenvik/chtoolbox
6
+ License: UNKNOWN
7
+ Description: # chtoolbox
8
+ chtoolbox is a library containing various python tools used in my daily work
9
+
10
+ ## Installation
11
+ To install chtoolbox, use pip:
12
+
13
+ ```sh
14
+ pip install chtoolbox
15
+ ```
16
+
17
+ ## Usage
18
+ Examples are provided in the `examples` folder in the repository.
19
+
20
+ ## License
21
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
22
+ Platform: UNKNOWN
23
+ Description-Content-Type: text/markdown
@@ -0,0 +1,15 @@
1
+ # chtoolbox
2
+ chtoolbox is a library containing various python tools used in my daily work
3
+
4
+ ## Installation
5
+ To install chtoolbox, use pip:
6
+
7
+ ```sh
8
+ pip install chtoolbox
9
+ ```
10
+
11
+ ## Usage
12
+ Examples are provided in the `examples` folder in the repository.
13
+
14
+ ## License
15
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
@@ -0,0 +1,26 @@
1
+ """MIT License
2
+
3
+ Copyright (c) 2025 Christian Hågenvik
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+ """
23
+
24
+ from . import misc
25
+ from . import testing
26
+ from .add_license import add_license_to_python_files
@@ -0,0 +1,83 @@
1
+ """MIT License
2
+
3
+ Copyright (c) 2025 Christian Hågenvik
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+ """
23
+
24
+ def add_license_to_python_files(license_file_path='LICENSE', directory='.', gitignore_path='.gitignore'):
25
+ """
26
+ Adds the LICENSE text to all Python files in the specified directory where it is not already present.
27
+
28
+ Parameters:
29
+ - license_file_path (str): Path to the LICENSE file. Default is 'LICENSE'.
30
+ - directory (str): Directory to search for Python files. Default is '.'.
31
+ - gitignore_path (str): Path to the .gitignore file. Default is '.gitignore'.
32
+ """
33
+
34
+ import os
35
+ import pathspec
36
+
37
+ # Check if the LICENSE file exists
38
+ if not os.path.isfile(license_file_path):
39
+ raise FileNotFoundError(f"LICENSE file not found at {license_file_path}")
40
+
41
+ # Check if the .gitignore file exists
42
+ if not os.path.isfile(gitignore_path):
43
+ raise FileNotFoundError(f".gitignore file not found at {gitignore_path}")
44
+
45
+ # Read the LICENSE text with UTF-8 encoding
46
+ with open(license_file_path, 'r', encoding='utf-8') as file:
47
+ license_text = file.read()
48
+
49
+ # Read the .gitignore file
50
+ with open(gitignore_path, 'r') as file:
51
+ gitignore = file.read()
52
+
53
+ # Create a pathspec from the .gitignore file
54
+ spec = pathspec.PathSpec.from_lines('gitwildmatch', gitignore.splitlines())
55
+
56
+ # Iterate over all files in the directory
57
+ for root, _, files in os.walk(directory):
58
+ for file in files:
59
+ file_path = os.path.join(root, file)
60
+
61
+ # Skip files and directories listed in .gitignore
62
+ if spec.match_file(file_path):
63
+ continue
64
+
65
+ if file.endswith('.py'):
66
+ # Read the original content of the file with UTF-8 encoding
67
+ with open(file_path, 'r', encoding='utf-8') as original_file:
68
+ original_content = original_file.read()
69
+
70
+ # Check if the LICENSE text is already present
71
+ if license_text not in original_content:
72
+ # Prepend the LICENSE text to the original content
73
+ new_content = f'"""{license_text}"""\n\n{original_content}'
74
+
75
+ # Write the new content back to the file with UTF-8 encoding
76
+ with open(file_path, 'w', encoding='utf-8') as modified_file:
77
+ modified_file.write(new_content)
78
+
79
+ print("LICENSE text added to all Python files where it was not already present.")
80
+
81
+
82
+ if __name__ == '__main__':
83
+ add_license_to_python_files()
@@ -1,158 +1,208 @@
1
- import pandas as pd
2
-
3
- def clipboard_to_dict(print_dict=True):
4
- """
5
- Converts clipboard content to a dictionary.
6
- If print_dict is True, the dictionary is printed.
7
- This function reads the clipboard content into a pandas DataFrame and converts it to a dictionary.
8
- If the DataFrame has two columns, it converts it to a flat dictionary.
9
- If the DataFrame has more than two columns, it converts it to a nested dictionary with 'index' orientation.
10
- Returns:
11
- dict: A dictionary representation of the clipboard content.
12
-
13
- Example 1:
14
-
15
- >>> # Copy a range in excel containing thw following to the clipboard:
16
- idx col_a col_b col_c
17
- row_a 1 4 7
18
- row_b 2 5 8
19
- row_c 3 6 9
20
-
21
- >>> clipboard_to_dict()
22
- {'row_a': {'col_a': 1, 'col_b': 4, 'col_c': 7},
23
- 'row_b': {'col_a': 2, 'col_b': 5, 'col_c': 8},
24
- 'row_c': {'col_a': 3, 'col_b': 6, 'col_c': 9}}
25
-
26
- Example 2:
27
- >>> # Copy a range in excel containing thw following to the clipboard:
28
- idx col_a
29
- row_a 1
30
- row_b 2
31
- row_c 3
32
-
33
- >>> clipboard_to_dict()
34
- {'row_a': 1, 'row_b': 2, 'row_c': 3}
35
- """
36
- # Read the clipboard content into a DataFrame
37
- df = pd.read_clipboard(header=None)
38
-
39
- if df.shape[1] == 2:
40
- # Convert the DataFrame to a flat dictionary
41
- dictionary = dict(zip(df[0], df[1]))
42
- else:
43
- # Check if the first column header is empty
44
- if pd.isna(df.iloc[0, 0]):
45
- df.columns = ['idx'] + list(df.iloc[0, 1:])
46
- df = df[1:]
47
- else:
48
- df.columns = df.iloc[0]
49
- df = df[1:]
50
-
51
- # Set the first column as the index
52
- df.set_index(df.columns[0], inplace=True)
53
-
54
- # Convert the DataFrame to a nested dictionary with 'index' orientation
55
- dictionary = df.to_dict(orient='index')
56
-
57
- if print_dict:
58
- print(dictionary)
59
-
60
- return dictionary
61
-
62
-
63
- def clipboard_to_list():
64
- """
65
- Retrieve data from the system clipboard and convert it to a list.
66
- This function reads the clipboard content into a pandas DataFrame,
67
- converts the DataFrame values into a one-dimensional list, and returns the list.
68
- Returns:
69
- list: A list containing the clipboard data.
70
- """
71
-
72
- # Read clipboard data into a DataFrame
73
- df = pd.read_clipboard(header=None)
74
-
75
- # Convert DataFrame values to a one-dimensional list
76
- data_list = df.values.flatten().tolist()
77
-
78
- # Print the list
79
- return data_list
80
-
81
-
82
- def compare_lists_from_clipboard():
83
- """
84
- A function used to select and copy a table from Excel.
85
- The table is converted into lists (one list per column in the Excel range).
86
- Then it compares all the lists and finds the unique elements that are not present in all the lists.
87
- Useful for comparing large amounts of elements from Excel.
88
- Dictionary containing one list per column in the clipboard (Excel range).
89
- """
90
- '''
91
- En funksjon som brukes ved å merke og kopiere en tabell fra excel.
92
- Tabellen konverteres til lister (en liste per kolonne i excel rangen)
93
- Deretter så sammenligner den alle listene og finner de unike elementene som ikke finnes i alle listene
94
-
95
- Nyttig for å sammenligne store mengder med elementer fra excel
96
-
97
- Returns
98
- -------
99
- list_dict : dict
100
- Dictionary containing one list per column in clipboard (excel range).
101
- unique_items : list
102
- A list of items that are not present in all the lists.
103
- common_items : list
104
- A list of items that are present in all the lists.
105
-
106
- '''
107
- # Read clipboard data as a DataFrame and convert it to dictionary
108
- data = pd.read_clipboard(header=None)
109
- list_dict = {}
110
- for col in data.columns:
111
- col_values = data[col].tolist()
112
- col_values = [value for value in col_values if not pd.isna(value)]
113
- list_dict[col] = col_values
114
-
115
- # Find values not present in all lists
116
- common_items = set.intersection(*(set(values) for values in list_dict.values()))
117
- unique_items = []
118
- for values in list_dict.values():
119
- for value in values:
120
- if value not in common_items and value not in unique_items:
121
- unique_items.append(value)
122
-
123
- # Print the resulting dictionary
124
- return list_dict, unique_items, list(common_items)
125
-
126
-
127
- def add_two_numbers(a,b):
128
- """
129
- Add two numbers together.
130
- Args:
131
- a (int): The first number.
132
- b (int): The second number.
133
- Returns:
134
- int: The sum of the two numbers.
135
- """
136
- return a + b
137
-
138
- def multiply_two_numbers(a,b):
139
- """
140
- Multiply two numbers together.
141
- Args:
142
- a (int): The first number.
143
- b (int): The second number.
144
- Returns:
145
- int: The product of the two numbers.
146
- """
147
- return a * b
148
-
149
- def subtract_two_numbers(a,b):
150
- """
151
- Subtract two numbers.
152
- Args:
153
- a (int): The first number.
154
- b (int): The second number.
155
- Returns:
156
- int: The difference between the two numbers.
157
- """
158
- return a - b
1
+ """MIT License
2
+
3
+ Copyright (c) 2025 Christian Hågenvik
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+ """
23
+
24
+ import pandas as pd
25
+ from itertools import product
26
+
27
+ def clipboard_to_dict(print_dict=True):
28
+ """
29
+ Converts clipboard content to a dictionary.
30
+ If print_dict is True, the dictionary is printed.
31
+ This function reads the clipboard content into a pandas DataFrame and converts it to a dictionary.
32
+ If the DataFrame has two columns, it converts it to a flat dictionary.
33
+ If the DataFrame has more than two columns, it converts it to a nested dictionary with 'index' orientation.
34
+ Returns:
35
+ dict: A dictionary representation of the clipboard content.
36
+
37
+ Example 1:
38
+
39
+ >>> # Copy a range in excel containing thw following to the clipboard:
40
+ idx col_a col_b col_c
41
+ row_a 1 4 7
42
+ row_b 2 5 8
43
+ row_c 3 6 9
44
+
45
+ >>> clipboard_to_dict()
46
+ {'row_a': {'col_a': 1, 'col_b': 4, 'col_c': 7},
47
+ 'row_b': {'col_a': 2, 'col_b': 5, 'col_c': 8},
48
+ 'row_c': {'col_a': 3, 'col_b': 6, 'col_c': 9}}
49
+
50
+ Example 2:
51
+ >>> # Copy a range in excel containing thw following to the clipboard:
52
+ idx col_a
53
+ row_a 1
54
+ row_b 2
55
+ row_c 3
56
+
57
+ >>> clipboard_to_dict()
58
+ {'row_a': 1, 'row_b': 2, 'row_c': 3}
59
+ """
60
+ # Read the clipboard content into a DataFrame
61
+ df = pd.read_clipboard(header=None)
62
+
63
+ if df.shape[1] == 2:
64
+ # Convert the DataFrame to a flat dictionary
65
+ dictionary = dict(zip(df[0], df[1]))
66
+ else:
67
+ # Check if the first column header is empty
68
+ if pd.isna(df.iloc[0, 0]):
69
+ df.columns = ['idx'] + list(df.iloc[0, 1:])
70
+ df = df[1:]
71
+ else:
72
+ df.columns = df.iloc[0]
73
+ df = df[1:]
74
+
75
+ # Set the first column as the index
76
+ df.set_index(df.columns[0], inplace=True)
77
+
78
+ # Convert the DataFrame to a nested dictionary with 'index' orientation
79
+ dictionary = df.to_dict(orient='index')
80
+
81
+ if print_dict:
82
+ print(dictionary)
83
+
84
+ return dictionary
85
+
86
+
87
+ def clipboard_to_list():
88
+ """
89
+ Retrieve data from the system clipboard and convert it to a list.
90
+ This function reads the clipboard content into a pandas DataFrame,
91
+ converts the DataFrame values into a one-dimensional list, and returns the list.
92
+ Returns:
93
+ list: A list containing the clipboard data.
94
+ """
95
+
96
+ # Read clipboard data into a DataFrame
97
+ df = pd.read_clipboard(header=None)
98
+
99
+ # Convert DataFrame values to a one-dimensional list
100
+ data_list = df.values.flatten().tolist()
101
+
102
+ # Print the list
103
+ return data_list
104
+
105
+
106
+ def compare_lists_from_clipboard():
107
+ """
108
+ A function used to select and copy a table from Excel.
109
+ The table is converted into lists (one list per column in the Excel range).
110
+ Then it compares all the lists and finds the unique elements that are not present in all the lists.
111
+ Useful for comparing large amounts of elements from Excel.
112
+ Dictionary containing one list per column in the clipboard (Excel range).
113
+ """
114
+ '''
115
+ En funksjon som brukes ved å merke og kopiere en tabell fra excel.
116
+ Tabellen konverteres til lister (en liste per kolonne i excel rangen)
117
+ Deretter så sammenligner den alle listene og finner de unike elementene som ikke finnes i alle listene
118
+
119
+ Nyttig for å sammenligne store mengder med elementer fra excel
120
+
121
+ Returns
122
+ -------
123
+ list_dict : dict
124
+ Dictionary containing one list per column in clipboard (excel range).
125
+ unique_items : list
126
+ A list of items that are not present in all the lists.
127
+ common_items : list
128
+ A list of items that are present in all the lists.
129
+
130
+ '''
131
+ # Read clipboard data as a DataFrame and convert it to dictionary
132
+ data = pd.read_clipboard(header=None)
133
+ list_dict = {}
134
+ for col in data.columns:
135
+ col_values = data[col].tolist()
136
+ col_values = [value for value in col_values if not pd.isna(value)]
137
+ list_dict[col] = col_values
138
+
139
+ # Find values not present in all lists
140
+ common_items = set.intersection(*(set(values) for values in list_dict.values()))
141
+ unique_items = []
142
+ for values in list_dict.values():
143
+ for value in values:
144
+ if value not in common_items and value not in unique_items:
145
+ unique_items.append(value)
146
+
147
+ # Print the resulting dictionary
148
+ return list_dict, unique_items, list(common_items)
149
+
150
+
151
+ def generate_combination_matrix(input_dict):
152
+ """
153
+ Generate a DataFrame containing all possible combinations of input parameters.
154
+ This function takes a dictionary of input parameters, where the keys are parameter names
155
+ and the values are lists of possible values for those parameters. It generates all possible
156
+ combinations of the parameter values and returns them as a pandas DataFrame.
157
+ Parameters
158
+ ----------
159
+ input_dict : dict
160
+ A dictionary where keys are parameter names (str) and values are lists of possible
161
+ values for those parameters. For example:
162
+ {
163
+ 'pressure': [10, 20],
164
+ 'GVF': [10, 20, 30],
165
+ 'WLR': [40, 60, 80],
166
+ }
167
+ Returns
168
+ -------
169
+ pandas.DataFrame
170
+ A DataFrame where each row represents a unique combination of the input parameter values.
171
+ The columns correspond to the keys of the input dictionary.
172
+ Examples
173
+ --------
174
+ >>> input_dict = {
175
+ ... 'pressure': [10, 20],
176
+ ... 'GVF': [10, 20, 30],
177
+ ... 'WLR': [40, 60, 80],
178
+ ... }
179
+ >>> generate_combination_matrix(input_dict)
180
+ pressure GVF WLR
181
+ 0 10 10 40
182
+ 1 10 10 60
183
+ 2 10 10 80
184
+ 3 10 20 40
185
+ 4 10 20 60
186
+ 5 10 20 80
187
+ 6 10 30 40
188
+ 7 10 30 60
189
+ 8 10 30 80
190
+ 9 20 10 40
191
+ 10 20 10 60
192
+ 11 20 10 80
193
+ 12 20 20 40
194
+ 13 20 20 60
195
+ 14 20 20 80
196
+ 15 20 30 40
197
+ 16 20 30 60
198
+ 17 20 30 80
199
+ """
200
+
201
+
202
+ # Generate all combinations using itertools.product
203
+ combinations = product(*input_dict.values())
204
+
205
+ # Create a DataFrame from the combinations
206
+ df = pd.DataFrame(combinations, columns=input_dict.keys())
207
+
208
+ return df
@@ -0,0 +1,148 @@
1
+ """MIT License
2
+
3
+ Copyright (c) 2025 Christian Hågenvik
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+ """
23
+
24
+ import pandas as pd
25
+ import itertools
26
+ import numpy as np
27
+
28
+ def generate_test_results(my_function, cases, print_cases=True):
29
+ """
30
+ Generates test results by applying a given function to a set of cases, returning both the input and output.
31
+ The results dictionary is intended to use as input to tests in the `pytest` framework.
32
+
33
+ Parameters
34
+ ----------
35
+ my_function : callable
36
+ The function to be tested. It should accept keyword arguments.
37
+ cases : dict or str
38
+ A dictionary where keys are case names and values are dictionaries of parameters,
39
+ or a string representing the path to a CSV file containing the cases.
40
+ The CSV file should have the following format:
41
+ Example:
42
+ ```
43
+ case,a,b,c
44
+ case1,1,4,7
45
+ case2,2,5,8
46
+ case3,3,6,9
47
+ ```
48
+
49
+ print_cases : bool, optional
50
+ If True, prints the results of each case. Default is True.
51
+ Returns
52
+ -------
53
+ dict
54
+ A dictionary containing the input parameters and the corresponding output for each case.
55
+ Raises
56
+ ------
57
+ ValueError
58
+ If `cases` is neither a dictionary nor a path to a CSV file.
59
+
60
+ Examples
61
+ --------
62
+ >>> def add(a, b):
63
+ ... return {'sum': a + b}
64
+ >>> cases = {
65
+ ... 'case1': {'a': 1, 'b': 2},
66
+ ... 'case2': {'a': 3, 'b': 4}
67
+ ... }
68
+ >>> generate_test_data(add, cases)
69
+ {'case1': {'input': {'a': 1, 'b': 2}, 'output': {'sum': 3}},
70
+ 'case2': {'input': {'a': 3, 'b': 4}, 'output': {'sum': 7}}}
71
+ """
72
+
73
+
74
+
75
+ if type(cases) is str and cases[-4:] =='.csv':
76
+ cases = pd.read_csv(cases, index_col=0)
77
+ cases = cases.to_dict(orient='index')
78
+ elif type(cases) is dict:
79
+ pass
80
+ else:
81
+ raise ValueError('Cases must be a dictionary or a csv file')
82
+
83
+ results = {key : {'input' : value} for key, value in cases.items()}
84
+
85
+ for case_name, params in cases.items():
86
+ result = my_function(**params)
87
+
88
+ results[case_name]['output'] = {}
89
+
90
+ if type(result) is dict:
91
+ for key, val in result.items():
92
+ results[case_name]['output'][key] = val
93
+ else:
94
+ results[case_name]['output'] = result
95
+
96
+ if print_cases:
97
+ # Print the results
98
+ print('{')
99
+ for case_name, params in results.items():
100
+ print(f"'{case_name}': {params},")
101
+ print('}')
102
+
103
+ return results
104
+
105
+
106
+ def create_test_cases(inputs, print_cases=True):
107
+ """
108
+ Generate test cases from input parameters.
109
+ Parameters
110
+ ----------
111
+ inputs : dict
112
+ A dictionary where keys are parameter names and values are lists or numpy arrays of parameter values.
113
+ print_cases : bool, optional
114
+ If True, print the generated test cases. Default is True.
115
+ Returns
116
+ -------
117
+ dict
118
+ A dictionary where keys are case names (e.g., 'case1', 'case2', ...) and values are dictionaries of parameter combinations.
119
+ Examples
120
+ --------
121
+ >>> inputs = {
122
+ ... 'param1': [1, 2],
123
+ ... 'param2': np.array([3, 4])
124
+ ... }
125
+ >>> create_test_cases(inputs)
126
+ {
127
+ 'case1': {'param1': 1, 'param2': 3},
128
+ 'case2': {'param1': 1, 'param2': 4},
129
+ 'case3': {'param1': 2, 'param2': 3},
130
+ 'case4': {'param1': 2, 'param2': 4}
131
+ }
132
+ """
133
+
134
+ keys = inputs.keys()
135
+ values = [v.tolist() if isinstance(v, np.ndarray) else v for v in inputs.values()]
136
+ combinations = list(itertools.product(*values))
137
+ df = pd.DataFrame(combinations, columns=keys)
138
+ df.index = [f'case{i}' for i in range(1, len(df) + 1)]
139
+
140
+ cases = df.to_dict(orient='index')
141
+
142
+ if print_cases:
143
+ print('{')
144
+ for case_name, params in cases.items():
145
+ print(f"'{case_name}': {params},")
146
+ print('}')
147
+
148
+ return cases
@@ -0,0 +1,23 @@
1
+ Metadata-Version: 2.1
2
+ Name: chtoolbox
3
+ Version: 1.1.0
4
+ Summary: UNKNOWN
5
+ Home-page: https://github.com/chagenvik/chtoolbox
6
+ License: UNKNOWN
7
+ Description: # chtoolbox
8
+ chtoolbox is a library containing various python tools used in my daily work
9
+
10
+ ## Installation
11
+ To install chtoolbox, use pip:
12
+
13
+ ```sh
14
+ pip install chtoolbox
15
+ ```
16
+
17
+ ## Usage
18
+ Examples are provided in the `examples` folder in the repository.
19
+
20
+ ## License
21
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
22
+ Platform: UNKNOWN
23
+ Description-Content-Type: text/markdown
@@ -2,9 +2,13 @@ LICENSE
2
2
  README.md
3
3
  setup.py
4
4
  chtoolbox/__init__.py
5
+ chtoolbox/add_license.py
5
6
  chtoolbox/misc.py
7
+ chtoolbox/testing.py
6
8
  chtoolbox.egg-info/PKG-INFO
7
9
  chtoolbox.egg-info/SOURCES.txt
8
10
  chtoolbox.egg-info/dependency_links.txt
9
11
  chtoolbox.egg-info/requires.txt
10
- chtoolbox.egg-info/top_level.txt
12
+ chtoolbox.egg-info/top_level.txt
13
+ tests/__init__.py
14
+ tests/test_testing.py
@@ -0,0 +1,3 @@
1
+ numpy>=1.26.2
2
+ pandas>=2.1.4
3
+ pathspec>=0.12.1
@@ -1,4 +1,4 @@
1
- [egg_info]
2
- tag_build =
3
- tag_date = 0
4
-
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,46 @@
1
+ """MIT License
2
+
3
+ Copyright (c) 2025 Christian Hågenvik
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+ """
23
+
24
+ from setuptools import setup, find_packages
25
+ from pathlib import Path
26
+
27
+ # Read the requirements from the requirements.txt file
28
+ requirements_path = Path(__file__).parent / 'requirements.txt'
29
+ with requirements_path.open() as requirements_file:
30
+ requirements = requirements_file.read().splitlines()
31
+
32
+ # Read the contents of the README file
33
+ readme_path = Path(__file__).parent / 'README.md'
34
+ with readme_path.open() as readme_file:
35
+ long_description = readme_file.read()
36
+
37
+ setup(
38
+ name='chtoolbox',
39
+ version='1.1.0',
40
+ packages=find_packages(),
41
+ install_requires=requirements,
42
+ long_description=long_description,
43
+ long_description_content_type='text/markdown',
44
+ url='https://github.com/chagenvik/chtoolbox'
45
+ )
46
+
@@ -0,0 +1,23 @@
1
+ """MIT License
2
+
3
+ Copyright (c) 2025 Christian Hågenvik
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+ """
23
+
@@ -0,0 +1,62 @@
1
+ """MIT License
2
+
3
+ Copyright (c) 2025 Christian Hågenvik
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+ """
23
+
24
+ from chtoolbox import testing
25
+ import os
26
+
27
+ def test_generate_test_results():
28
+ cases = {'case1': {'a': 1, 'b': 2},
29
+ 'case2': {'a': 3, 'b': 4},
30
+ 'case3': {'a': 5, 'b': 6}}
31
+
32
+ def add(a, b):
33
+ return a+b
34
+
35
+ res = testing.generate_test_results(add, cases)
36
+
37
+ for key, value in res.items():
38
+ assert value['output'] == value['input']['a'] + value['input']['b']
39
+
40
+ def test_generate_test_results_csv():
41
+ cases = os.path.join(os.path.dirname(__file__), 'data', 'data.csv')
42
+
43
+ f1 = lambda a,b,c: a+b-c
44
+
45
+ res1 = testing.generate_test_results(f1, cases)
46
+
47
+ for key, value in res1.items():
48
+ assert value['output'] == value['input']['a'] + value['input']['b'] - value['input']['c']
49
+
50
+ def f2(a,b,c):
51
+ x = {'sum': a+b,
52
+ 'diff': a-b}
53
+
54
+ return x
55
+
56
+ res2 = testing.generate_test_results(f2, cases)
57
+
58
+ for key, value in res2.items():
59
+ assert value['output']['sum'] == value['input']['a'] + value['input']['b']
60
+ assert value['output']['diff'] == value['input']['a'] - value['input']['b']
61
+
62
+
chtoolbox-0.2.4/PKG-INFO DELETED
@@ -1,4 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: chtoolbox
3
- Version: 0.2.4
4
- License-File: LICENSE
chtoolbox-0.2.4/README.md DELETED
@@ -1,2 +0,0 @@
1
- # chtoolbox
2
- chtoolbox is a library containing various python tools used in my daily work
@@ -1 +0,0 @@
1
- from . import misc
@@ -1,4 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: chtoolbox
3
- Version: 0.2.4
4
- License-File: LICENSE
@@ -1,2 +0,0 @@
1
- numpy
2
- pandas
chtoolbox-0.2.4/setup.py DELETED
@@ -1,12 +0,0 @@
1
- from setuptools import setup, find_packages
2
-
3
- setup(
4
- name='chtoolbox',
5
- version='0.2.4',
6
- packages=find_packages(),
7
- install_requires=[
8
- 'numpy',
9
- 'pandas',
10
- ]
11
- )
12
-