cannect 1.0.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.
Files changed (58) hide show
  1. cannect/__init__.py +30 -0
  2. cannect/api/__init__.py +0 -0
  3. cannect/config.py +114 -0
  4. cannect/core/__init__.py +0 -0
  5. cannect/core/ascet/__init__.py +3 -0
  6. cannect/core/ascet/amd.py +698 -0
  7. cannect/core/ascet/formula.py +33 -0
  8. cannect/core/ascet/oid.py +29 -0
  9. cannect/core/ascet/ws.py +154 -0
  10. cannect/core/can/__init__.py +2 -0
  11. cannect/core/can/ascet/__init__.py +3 -0
  12. cannect/core/can/ascet/_db2code.py +344 -0
  13. cannect/core/can/ascet/_db2elem.py +399 -0
  14. cannect/core/can/ascet/comdef.py +256 -0
  15. cannect/core/can/ascet/comrx.py +139 -0
  16. cannect/core/can/ascet/diag.py +691 -0
  17. cannect/core/can/db/__init__.py +4 -0
  18. cannect/core/can/db/reader.py +148 -0
  19. cannect/core/can/db/schema.py +269 -0
  20. cannect/core/can/db/specification/__init__.py +0 -0
  21. cannect/core/can/db/specification/message.py +230 -0
  22. cannect/core/can/db/specification/styles.py +81 -0
  23. cannect/core/can/db/specification/wrapper.py +161 -0
  24. cannect/core/can/db/vcs.py +104 -0
  25. cannect/core/can/rule.py +229 -0
  26. cannect/core/can/testcase/__init__.py +0 -0
  27. cannect/core/can/testcase/unitcase/__init__.py +0 -0
  28. cannect/core/can/testcase/unitcase/asw2can.py +48 -0
  29. cannect/core/can/testcase/unitcase/decode.py +63 -0
  30. cannect/core/can/testcase/unitcase/diagnosis.py +479 -0
  31. cannect/core/can/testcase/unitcase/encode.py +60 -0
  32. cannect/core/ir/__init__.py +2 -0
  33. cannect/core/ir/changehistory.py +310 -0
  34. cannect/core/ir/delivereables.py +71 -0
  35. cannect/core/ir/diff.py +97 -0
  36. cannect/core/ir/ir.py +581 -0
  37. cannect/core/ir/sdd.py +148 -0
  38. cannect/core/mdf.py +66 -0
  39. cannect/core/subversion.py +136 -0
  40. cannect/core/testcase/__init__.py +3 -0
  41. cannect/core/testcase/plotter.py +181 -0
  42. cannect/core/testcase/style.py +981 -0
  43. cannect/core/testcase/testcase.py +160 -0
  44. cannect/core/testcase/unitcase.py +227 -0
  45. cannect/errors.py +20 -0
  46. cannect/schema/__init__.py +5 -0
  47. cannect/schema/candb.py +226 -0
  48. cannect/schema/datadictionary.py +60 -0
  49. cannect/utils/__init__.py +3 -0
  50. cannect/utils/excel.py +29 -0
  51. cannect/utils/logger.py +81 -0
  52. cannect/utils/ppt.py +236 -0
  53. cannect/utils/tools.py +207 -0
  54. cannect-1.0.0.dist-info/METADATA +214 -0
  55. cannect-1.0.0.dist-info/RECORD +58 -0
  56. cannect-1.0.0.dist-info/WHEEL +5 -0
  57. cannect-1.0.0.dist-info/licenses/LICENSE +21 -0
  58. cannect-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,310 @@
1
+ from cannect.utils.ppt import PptRW
2
+ from pandas import DataFrame
3
+ from typing import Iterable, List
4
+ import pygetwindow as gw
5
+ import pyautogui as gui
6
+ import time
7
+
8
+
9
+ class ChangeHistoryManager(PptRW):
10
+
11
+ @classmethod
12
+ def routine_capture(cls, ppt:str='', size:int=26, *hotkey):
13
+ """
14
+ 최초 픽픽 또는 기타 툴로 최초 캡쳐가 되어 있어야 함.
15
+ 반복 캡쳐는 단축키로 수행이 가능해야 함
16
+ @param ppt : 변경내역서 파일명
17
+ @param size :
18
+ """
19
+ windows = gw.getAllTitles()
20
+ ascet_diff = None
21
+ pptx = []
22
+ for title in windows:
23
+ if title and title == "ASCET-DIFF":
24
+ ascet_diff = title
25
+ if title and '.pptx' in title:
26
+ pptx.append(title)
27
+
28
+ if ascet_diff is None:
29
+ raise OSError('ASCET-DIFF 를 찾을 수 없습니다')
30
+ if not pptx:
31
+ raise OSError('변경내역서를 찾을 수 없습니다')
32
+ if len(pptx) >= 2 and not ppt:
33
+ raise OSError('열려있는 pptx가 2개 이상이며 변경내역서를 특정할 수 없습니다. @ppt = ""')
34
+ pptx = [_ppt for _ppt in pptx if _ppt.startswith(ppt)][0]
35
+
36
+ window = gw.getWindowsWithTitle(ascet_diff)[0]
37
+ window.activate()
38
+
39
+ if not hotkey:
40
+ hotkey = 'shift', 'ctrl', 'd'
41
+ gui.hotkey(*hotkey)
42
+ time.sleep(0.5)
43
+
44
+ report = gw.getWindowsWithTitle(pptx)[0]
45
+ report.activate()
46
+ gui.hotkey('ctrl', 'v')
47
+ time.sleep(0.5)
48
+
49
+ gui.hotkey('alt', '6')
50
+ time.sleep(0.2)
51
+
52
+ gui.write(str(size))
53
+ gui.press('enter')
54
+ time.sleep(0.2)
55
+
56
+ return
57
+
58
+ def resize_cover(self):
59
+ """
60
+ | n == 7 | n == 3 |
61
+ | n == 8 | n == 4 |
62
+ | n == 9 | n == 5 |
63
+ | n == 10 | n == 6 |
64
+ :return:
65
+ """
66
+ for n, shape in enumerate(self.ppt.Slides.Item(1).Shapes, start=1):
67
+ if shape.HasTable:
68
+ if n in [7, 8, 9, 10]:
69
+ shape.Left = 0.76 * 28.346
70
+ shape.Top = {7:2.77, 8:8.1, 9:11.86, 10:15.53}[n] * 28.346
71
+ if n in [3, 4, 5, 6]:
72
+ shape.Width = 22.4 * 28.346
73
+ shape.Left = 4.36 * 28.346
74
+ shape.Top = {3: 2.77, 4: 8.1, 5: 11.86, 6: 15.53}[n] * 28.346
75
+ if n == 3:
76
+ shape.Table.Rows(5).Height = 1.69 * 28.346
77
+ else:
78
+ shape.Height = {4:3.6, 5:3.5, 6:2.36}[n] * 28.346
79
+
80
+
81
+ @property
82
+ def title(self) -> str:
83
+ return self.__dict__.get('_title', '')
84
+
85
+ @title.setter
86
+ def title(self, title:str):
87
+ self.__dict__['_title'] = title
88
+ self.set_text(n_slide=1, n_shape=1, text=title, pos='new')
89
+ self.set_text_font(n_slide=1, n_shape=1, size=24)
90
+ n_regulation = self.get_slide_n('법규 정합성')
91
+ if n_regulation:
92
+ self.set_text_in_table(n_slide=n_regulation[0], n_table=1, cell=(1, 2), text=title, pos='new')
93
+ n_checklist = self.get_slide_n('SW변경내역서 Check List')
94
+ if n_checklist:
95
+ self.set_text_in_table(n_slide=n_checklist[0], n_table=1, cell=(1, 2), text=title, pos='new')
96
+
97
+ @property
98
+ def developer(self) -> str:
99
+ return self.__dict__.get('_developer', '')
100
+
101
+ @developer.setter
102
+ def developer(self, developer:str):
103
+ self.__dict__['_developer'] = developer
104
+ self.set_text_in_table(n_slide=1, n_table=1, cell=(2, 1), text=developer, pos='new')
105
+ self.set_table_font(n_slide=1, n_table=1, cell=(2, 1), size=10)
106
+
107
+ @property
108
+ def function(self) -> str:
109
+ return self.__dict__.get('_function', '')
110
+
111
+ @function.setter
112
+ def function(self, functions:Iterable):
113
+ self.set_text_in_table(n_slide=1, n_table=2, cell=(3, 2), text=", ".join(functions), pos='new')
114
+ self.set_table_font(n_slide=1, n_table=2, cell=(3, 2), size=10)
115
+
116
+ @property
117
+ def issue(self) -> str:
118
+ return self.__dict__.get('_issue', '')
119
+
120
+ @issue.setter
121
+ def issue(self, issue:str):
122
+ self.__dict__['_issue'] = issue
123
+ self.set_table_font(n_slide=1, n_table=2, cell=(3, 8), name="현대하모니 L")
124
+ self.set_text_in_table(n_slide=1, n_table=2, cell=(3, 8), text=issue, pos='new')
125
+
126
+ @property
127
+ def lcr(self) -> str:
128
+ return self.__dict__.get('_lcr', '')
129
+
130
+ @lcr.setter
131
+ def lcr(self, lcr:str):
132
+ self.__dict__['_lcr'] = lcr
133
+ self.set_text_in_table(n_slide=1, n_table=2, cell=(4, 8), text=lcr, pos='before')
134
+ n_regulation = self.get_slide_n('법규 정합성')
135
+ if n_regulation:
136
+ self.set_text_in_table(n_slide=n_regulation[0], n_table=1, cell=(1, 4), text=lcr, pos='new')
137
+ n_checklist = self.get_slide_n('SW변경내역서 Check List')
138
+ if n_checklist:
139
+ self.set_text_in_table(n_slide=n_checklist[0], n_table=1, cell=(1, 4), text=lcr, pos='new')
140
+
141
+ @property
142
+ def problem(self) -> str:
143
+ return self.__dict__.get('_problem', '')
144
+
145
+ @problem.setter
146
+ def problem(self, problem:str):
147
+ self.set_text_in_table(n_slide=1, n_table=2, cell=(5, 1), text=problem, pos='new')
148
+
149
+ @property
150
+ def prev_model_description(self) -> str:
151
+ return self.__dict__.get('_prev_model_description', '')
152
+
153
+ @prev_model_description.setter
154
+ def prev_model_description(self, models:DataFrame):
155
+ text = ''
156
+ for n in models.index:
157
+ text += f'%{models.loc[n, "FunctionName"]} <r.{models.loc[n, "SCMRev"]}>\x0b\x0b\n'
158
+ text = text[:-1]
159
+ self.set_text_in_table(n_slide=2, n_table=1, cell=(2, 1), text=text, pos='new')
160
+
161
+ @property
162
+ def post_model_description(self) -> str:
163
+ return self.__dict__.get('_post_model_description', '')
164
+
165
+ @post_model_description.setter
166
+ def post_model_description(self, models: DataFrame):
167
+ text = ''
168
+ for n in models.index:
169
+ text += f'%{models.loc[n, "FunctionName"]} <r.{models.loc[n, "SCMRev"]}>\x0b-\x0b\n'
170
+ text = text[:-1]
171
+ self.set_text_in_table(n_slide=2, n_table=1, cell=(2, 2), text=text, pos='new')
172
+
173
+ def set_model_slides(self, ir:DataFrame):
174
+ if self.log is not None:
175
+ self.log('>>> GENERATING MODEL SLIDES...')
176
+ self.set_shape(n_slide=3, n_shape=1, width=26.1 * 28.346, left=0.8 * 28.346)
177
+ self.set_text_font(n_slide=3, n_shape=1, name="현대하모니 M", size=20)
178
+ self.set_table_height(n_slide=3, n_table=1, row=2, height=11 * 28.346)
179
+ self.set_table_height(n_slide=3, n_table=1, row=3, height=3 * 28.346)
180
+ self.set_table_text_align(n_slide=3, n_table=1, cell=(3, 1))
181
+ self.set_table_text_align(n_slide=3, n_table=1, cell=(3, 2))
182
+ self.set_table_font(n_slide=3, n_table=1, cell=(3, 1), size=12)
183
+ self.set_table_font(n_slide=3, n_table=1, cell=(3, 2), size=12)
184
+ for n in range(3 * len(ir) - 1):
185
+ self.ppt.Slides(3).Duplicate()
186
+
187
+ # if self.ppt.SectionProperties.Count == 0:
188
+ # self.ppt.SectionProperties.AddSection(1, f'기본 구역')
189
+ for n, i in enumerate(ir.index, start=1):
190
+ n_default = 3 * i + 3
191
+ n_element = 3 * i + 4
192
+ n_formula = 3 * i + 5
193
+ name = ir.loc[i]["FunctionName"]
194
+ self.ppt.SectionProperties.AddBeforeSlide(n_default, f'%{name}')
195
+ self.set_text(n_slide=n_default, n_shape=1, text=f'SW 변경 내용 상세: %{name} /', pos='new')
196
+ self.set_text(n_slide=n_element, n_shape=1, text=f'SW 변경 내용 상세: %{name} / Element', pos='new')
197
+ self.set_text(n_slide=n_formula, n_shape=1, text=f'SW 변경 내용 상세: %{name} / Implementation', pos='new')
198
+ self.set_text_in_table(n_slide=n_element, n_table=1, cell=(3, 1), text="Element 삭제\x0b", pos="new")
199
+ self.set_text_in_table(n_slide=n_element, n_table=1, cell=(3, 2), text="Element 추가\x0b", pos="new")
200
+ self.set_text_in_table(n_slide=n_formula, n_table=1, cell=(3, 1), text="Impl. 삭제\x0b", pos="new")
201
+ self.set_text_in_table(n_slide=n_formula, n_table=1, cell=(3, 2), text="Impl. 추가\x0b", pos="new")
202
+ self.ppt.SectionProperties.AddBeforeSlide(self.get_slide_n('Calibration')[0], 'Calibration Guide')
203
+ return
204
+
205
+ @property
206
+ def prev_model_details(self):
207
+ return self.__dict__.get('_prev_model_details', '')
208
+
209
+ @prev_model_details.setter
210
+ def prev_model_details(self, models:DataFrame):
211
+ if self.log is not None:
212
+ self.log('>>> WRITING PREVIOUS MODEL DETAILS...')
213
+ for n in models.index:
214
+ name, rev = models.loc[n, "FunctionName"], models.loc[n, "SCMRev"]
215
+ if self.log is not None:
216
+ self.log(f'>>> ... {name} @{rev}')
217
+ slides = self.get_slide_n(f'{name} ')
218
+ for slide in slides:
219
+ self.replace_text_in_table(
220
+ n_slide=slide,
221
+ n_table=1,
222
+ cell=(1, 1),
223
+ prev="Rev.",
224
+ post=f"Rev.{rev}"
225
+ )
226
+
227
+ @property
228
+ def post_model_details(self):
229
+ return self.__dict__.get('_post_model_details', '')
230
+
231
+ @post_model_details.setter
232
+ def post_model_details(self, models:DataFrame):
233
+ if self.log is not None:
234
+ self.log('>>> WRITING POST MODEL DETAILS...')
235
+ for n in models.index:
236
+ name, rev = models.loc[n, "FunctionName"], models.loc[n, "SCMRev"]
237
+ if self.log is not None:
238
+ self.log(f'>>> ... {name} @{rev}')
239
+ slides = self.get_slide_n(f'{name} ')
240
+ for slide in slides:
241
+ self.replace_text_in_table(
242
+ n_slide=slide,
243
+ n_table=1,
244
+ cell=(1, 2),
245
+ prev="Rev.",
246
+ post=f"Rev.{rev}"
247
+ )
248
+ slides = self.get_slide_n(f'{name} / Element')
249
+ for slide in slides:
250
+ self.set_text_in_table(
251
+ n_slide=slide,
252
+ n_table=1,
253
+ cell=(3, 1),
254
+ text='Element 삭제\x0b' + models.loc[n, "ElementDeleted"],
255
+ pos="new"
256
+ )
257
+ self.set_text_in_table(
258
+ n_slide=slide,
259
+ n_table=1,
260
+ cell=(3, 2),
261
+ text='Element 추가\x0b' + models.loc[n, "ElementAdded"],
262
+ pos="new"
263
+ )
264
+
265
+ @property
266
+ def parameters(self) -> List[DataFrame]:
267
+ return self.__dict__.get('_parameters', [])
268
+
269
+ @parameters.setter
270
+ def parameters(self, parameters: List[DataFrame]):
271
+ if len(parameters) == 0:
272
+ return
273
+ self.__dict__['_parameters'] = parameters
274
+ if self.log is not None:
275
+ self.log('>>> WRITING CALIBRATION PARAMETERS...')
276
+
277
+ n_param = self.get_slide_n('Calibration')[0]
278
+ for n in range(len(parameters) - 1):
279
+ self.ppt.Slides(n_param).Duplicate()
280
+
281
+ for n, param in enumerate(parameters):
282
+ table = self._get_table(n_param + n, 1)
283
+ if len(param) > 3:
284
+ for _ in range(len(param) - 3):
285
+ table.Rows.Add()
286
+ table.Columns(1).Width = 5.0 * 28.346
287
+ table.Columns(2).Width = 7.0 * 28.346
288
+ table.Columns(3).Width = 4.0 * 28.346
289
+ table.Columns(5).Width = 2.0 * 28.346
290
+ table.Columns(6).Width = 2.0 * 28.346
291
+ table.Columns(7).Width = 2.0 * 28.346
292
+ for r, index in enumerate(param.index, start=1):
293
+ row = param.loc[index]
294
+ for c, val in enumerate(row.values, start=1):
295
+ cell = table.Cell(r + 1, c).Shape
296
+ cell.TextFrame.TextRange.Text = str(val)
297
+ cell.TextFrame.TextRange.Font.Name = "현대하모니 L"
298
+ cell.TextFrame.TextRange.Font.Size = 10
299
+
300
+ cell.TextFrame.TextRange.ParagraphFormat.Alignment = 1 if c == 2 else 2
301
+ cell.TextFrame.VerticalAnchor = 3
302
+ return
303
+
304
+
305
+ if __name__ == "__main__":
306
+ # ChangeHistoryManager.routine_capture('0000_CNGPIO_통신_인터페이스_개발.pptx', 13)
307
+ chm = ChangeHistoryManager(
308
+ path = r"D:\Archive\00_프로젝트\2017 통신개발-\2026\DS0127 CR10787035 DTC별 IUMPR 표출 조건 변경 ICE\0000_CAN_ICE_IUMPR표출_DEM조건_추가.pptx"
309
+ )
310
+ chm.resize_cover()
@@ -0,0 +1,71 @@
1
+ from cannect.config import env
2
+ from cannect.utils import tools
3
+ from pathlib import Path
4
+ from datetime import datetime
5
+ import os
6
+
7
+
8
+ class Deliverables:
9
+
10
+ # Resources = { U | Formula, Conf-Data, BSW-Auxiliary, SDD-Note, OS-Task-Info }
11
+ __slots__ = (
12
+ "Root",
13
+ "Requirement", "BuildEnv", "Workspace", "Model",
14
+ "Resources", "CGen", "ROM", "Test", "Others"
15
+ )
16
+
17
+ def __init__(self, base_path: str=''):
18
+ """
19
+ IR 산출물 관리 폴더 생성,
20
+ @base_path 경로 입력 시 하위에 @sub_path 이름으로 폴더 생성
21
+ @base_path 미 입력 시, "다운로드"폴더 하위에 "{생성 날짜}_IR_산출물" 이름으로 자동 폴더
22
+ 생성 후 @sub_paths 이름의 하위 폴더 생성
23
+ @sub_paths 하위 폴더 리스트 미 지정 시 디폴트 값 자동 할당
24
+
25
+ @base_path : [str] 산출물 관리 경로
26
+ """
27
+ if base_path:
28
+ self.Root = Path(base_path)
29
+ else:
30
+ self.Root = Path(env.DOWNLOADS / f'{datetime.now().strftime("%Y%m%d")}_IR_산출물')
31
+ root = self.Root
32
+
33
+ os.makedirs(root, exist_ok=True)
34
+ for n, path in enumerate(self.__slots__, start=0):
35
+ if path == "Root":
36
+ continue
37
+ full_path = Path(os.path.join(root, f'{str(n).zfill(2)}_{path}'))
38
+ setattr(self, path, full_path)
39
+
40
+ os.makedirs(full_path, exist_ok=True)
41
+ if path == "Model":
42
+ os.makedirs(os.path.join(full_path, f'Prev'), exist_ok=True)
43
+ os.makedirs(os.path.join(full_path, f'Post'), exist_ok=True)
44
+
45
+ if not any(file.endswith('.xlsm') for file in os.listdir(root)):
46
+ try:
47
+ tools.copy_to(env.SVN_IR / '0000_HNB_SW_IR_.xlsm', root)
48
+ except PermissionError:
49
+ pass
50
+
51
+ if not any(file.endswith('.pptx') for file in os.listdir(root)):
52
+ try:
53
+ tools.copy_to(env.SVN_HISTORY / '0000_변경내역서 양식.pptx', root)
54
+ except PermissionError:
55
+ pass
56
+ return
57
+
58
+ def __getitem__(self, item):
59
+ return self.Root / item
60
+
61
+ def __str__(self) -> str:
62
+ indent = max(len(path) for path in self.__slots__)
63
+ return "\n".join(f'{path:>{indent}}: {self.__getattribute__(path)}' for path in self.__slots__)
64
+
65
+ @property
66
+ def change_history(self) -> str:
67
+ for file in os.listdir(self.Root):
68
+ if file.endswith('.pptx'):
69
+ return os.path.join(self.Root, file)
70
+ raise FileExistsError('변경 내역서 없음')
71
+
@@ -0,0 +1,97 @@
1
+ from cannect.core.ascet import Amd
2
+ from pandas import DataFrame
3
+ from typing import List
4
+ import os, hashlib
5
+
6
+
7
+ class AmdDiff:
8
+
9
+ @classmethod
10
+ def parameters2table(cls, elem:DataFrame, value:DataFrame):
11
+ elem = elem[
12
+ (elem['kind'] == 'parameter') &
13
+ (elem['scope'] != 'imported')
14
+ ]
15
+ elem.set_index(keys='OID', inplace=True)
16
+
17
+ data = value[value['elementName'].isin(elem['name'])]
18
+ data.set_index(keys='elementOID', inplace=True)
19
+ elem = elem.join(data[['value']], how='left')
20
+ elem = elem[["name", "comment", "model", "value"]]
21
+ elem.columns = ['Name', 'Description', 'Module', 'Recommendation Cal']
22
+ elem['Default Cal'] = elem['Recommendation Cal']
23
+ elem['Disable Cal'] = '-'
24
+ elem['Remark'] = '-'
25
+ return elem
26
+
27
+ def __init__(
28
+ self,
29
+ prev:str,
30
+ post:str,
31
+ exclude_imported:bool=True
32
+ ):
33
+ self.prev = prev = Amd(prev)
34
+ self.post = post = Amd(post)
35
+ self.prev_elem = prev.main.dataframe('Element')
36
+ self.post_elem = post.main.dataframe('Element')
37
+ if exclude_imported:
38
+ self.prev_elem = self.prev_elem[self.prev_elem['scope'] != 'imported']
39
+ self.post_elem = self.post_elem[self.post_elem['scope'] != 'imported']
40
+
41
+ self.prev_data = prev.data.dataframe('DataEntry')
42
+ self.post_data = post.data.dataframe('DataEntry')
43
+ return
44
+
45
+ @property
46
+ def is_equal(self) -> bool:
47
+ def _hash(file):
48
+ _md5 = hashlib.md5()
49
+ with open(file, "rb") as f:
50
+ for chunk in iter(lambda: f.read(4096), b""):
51
+ _md5.update(chunk)
52
+ return _md5.hexdigest()
53
+ if os.path.getsize(self.prev.main.path) != os.path.getsize(self.post.main.path):
54
+ return False
55
+ return _hash(self.prev.main.path) == _hash(self.post.main.path)
56
+
57
+ @property
58
+ def deleted(self) -> List[str]:
59
+ return list(set(self.prev_elem['name']) - set(self.post_elem['name']))
60
+
61
+ @property
62
+ def added(self) -> List[str]:
63
+ if self.is_equal:
64
+ return self.post_elem['name'].tolist()
65
+ return list(set(self.post_elem['name']) - set(self.prev_elem['name']))
66
+
67
+ @property
68
+ def added_parameters(self) -> DataFrame:
69
+ elem = self.post_elem[self.post_elem['name'].isin(self.added)]
70
+ data = self.post_data[self.post_data['elementName'].isin(elem['name'])]
71
+ return self.parameters2table(elem, data)
72
+ # elem = self.post_elem[
73
+ # self.post_elem['name'].isin(self.added) &
74
+ # (self.post_elem['kind'] == 'parameter') &
75
+ # (self.post_elem['scope'] != 'imported')
76
+ # ]
77
+ # elem.set_index(keys='OID', inplace=True)
78
+ # data = self.post_data[self.post_data['elementName'].isin(elem['name'])]
79
+ # data.set_index(keys='elementOID', inplace=True)
80
+ # elem = elem.join(data[['value']], how='left')
81
+ # elem = elem[["name", "comment", "model", "value"]]
82
+ # elem.columns = ['Name', 'Description', 'Module', 'Recommendation Cal']
83
+ # elem['Default Cal'] = elem['Recommendation Cal']
84
+ # elem['Disable Cal'] = '-'
85
+ # elem['Remark'] = '-'
86
+ # return elem
87
+
88
+
89
+ if __name__ == "__main__":
90
+ from pandas import set_option
91
+ set_option('display.expand_frame_repr', False)
92
+
93
+ diff = AmdDiff(
94
+ r"D:\Archive\00_프로젝트\2017 통신개발-\2025\DS1201 IUMPR 미표출 ICE CANFD\02_Model\Prev\CanBMSD_48V.main.amd",
95
+ r"D:\Archive\00_프로젝트\2017 통신개발-\2025\DS1201 IUMPR 미표출 ICE CANFD\02_Model\Post\CanBMSD_48V\CanBMSD_48V.main.amd",
96
+ )
97
+ print(diff.added_parameters)