pyjallib.namePart

namePart 모듈 - 이름의 각 부분을 표현하는 기능 제공 이름 부분의 사전 정의된 값과 가중치 매핑을 관리하는 클래스 구현

  1#!/usr/bin/env python
  2# -*- coding: utf-8 -*-
  3
  4"""
  5namePart 모듈 - 이름의 각 부분을 표현하는 기능 제공
  6이름 부분의 사전 정의된 값과 가중치 매핑을 관리하는 클래스 구현
  7"""
  8
  9from typing import List, Dict, Any, Optional, Union
 10from enum import Enum, auto
 11
 12class NamePartType(Enum):
 13    """
 14    이름 부분(name part)의 유형을 정의하는 열거형 클래스.
 15    
 16    - PREFIX: RealName 앞에 오는 부분, 사전 정의 값 필수
 17    - SUFFIX: RealName 뒤에 오는 부분, 사전 정의 값 필수
 18    - REALNAME: 실제 이름 부분, 자유 텍스트 가능
 19    - INDEX: 숫자만 허용되는 부분
 20    - UNDEFINED: 정의되지 않은 타입 (기본값)
 21    """
 22    PREFIX = auto()
 23    SUFFIX = auto()
 24    REALNAME = auto()
 25    INDEX = auto()
 26    UNDEFINED = auto()
 27
 28class NamePart:
 29    """
 30    이름 부분(name part)을 관리하기 위한 클래스.
 31    이름과 해당 부분에 대한 사전 선언된 값들을 관리합니다.
 32    """
 33    
 34    def __init__(self, inName="", inType=NamePartType.UNDEFINED, inPredefinedValues=None, inDescriptions=None, inIsDirection=False, inKoreanDescriptions=None):
 35        """
 36        NamePart 클래스 초기화
 37        
 38        Args:
 39            inName: 이름 부분의 이름 (예: "Base", "Type", "Side" 등)
 40            inPredefinedValues: 사전 선언된 값 목록 (기본값: None, 빈 리스트로 초기화)
 41            inType: NamePart의 타입 (NamePartType 열거형 값)
 42            inDescriptions: 사전 선언된 값들의 설명 목록 (기본값: None, 빈 리스트로 초기화)
 43            inIsDirection: 방향성 여부 (기본값: False)
 44            inKoreanDescriptions: 사전 선언된 값들의 한국어 설명 목록 (기본값: None, 빈 리스트로 초기화)
 45        """
 46        self._name = inName
 47        self._predefinedValues = inPredefinedValues if inPredefinedValues is not None else []
 48        self._weights = []
 49        self._type = inType
 50        self._descriptions = inDescriptions if inDescriptions is not None else [""] * len(self._predefinedValues)
 51        self._koreanDescriptions = inKoreanDescriptions if inKoreanDescriptions is not None else [""] * len(self._predefinedValues) # Add korean descriptions
 52        self._isDirection = inIsDirection if inIsDirection is True else False  # 방향성 여부 (기본값: False)
 53        
 54        # 길이 일치 확인 (Descriptions)
 55        if len(self._descriptions) < len(self._predefinedValues):
 56            self._descriptions.extend([""] * (len(self._predefinedValues) - len(self._descriptions)))
 57        elif len(self._descriptions) > len(self._predefinedValues):
 58            self._descriptions = self._descriptions[:len(self._predefinedValues)]
 59
 60        # 길이 일치 확인 (Korean Descriptions)
 61        if len(self._koreanDescriptions) < len(self._predefinedValues):
 62            self._koreanDescriptions.extend([""] * (len(self._predefinedValues) - len(self._koreanDescriptions)))
 63        elif len(self._koreanDescriptions) > len(self._predefinedValues):
 64            self._koreanDescriptions = self._koreanDescriptions[:len(self._predefinedValues)]
 65        
 66        # 타입에 따른 기본 값 설정
 67        self._initialize_type_defaults()
 68        self._update_weights()
 69    
 70    def _initialize_type_defaults(self):
 71        """타입에 따른 기본 설정을 초기화합니다."""
 72        if self._type == NamePartType.INDEX:
 73            # Index 타입은 숫자만 처리하므로 predefined values는 사용하지 않음
 74            self._predefinedValues = []
 75            self._descriptions = []
 76            self._koreanDescriptions = [] # Clear korean descriptions
 77            self._weights = []
 78        elif self._type == NamePartType.REALNAME:
 79            # RealName 타입은 predefined values를 사용하지 않음
 80            self._predefinedValues = []
 81            self._descriptions = []
 82            self._koreanDescriptions = [] # Clear korean descriptions
 83            self._weights = []
 84    
 85    def _update_weights(self):
 86        """
 87        predefined values의 순서에 따라 자동으로 가중치를 설정합니다.
 88        값들은 5부터 시작해서 5씩 증가하는 가중치를 갖습니다.
 89        """
 90        # REALNAME이나 INDEX 타입인 경우 weights를 사용하지 않음
 91        if self._type == NamePartType.REALNAME or self._type == NamePartType.INDEX:
 92            self._weights = []
 93            return
 94            
 95        self._weights = []
 96        # 가중치는 5부터 시작해서 5씩 증가 (순서대로 내림차순 가중치)
 97        num_values = len(self._predefinedValues)
 98        for i in range(num_values):
 99            weight_value = 5 * (i + 1)  # 내림차순 가중치
100            self._weights.append(weight_value)
101    
102    def set_name(self, inName):
103        """
104        이름 부분의 이름을 설정합니다.
105        
106        Args:
107            inName: 설정할 이름
108        """
109        self._name = inName
110    
111    def get_name(self):
112        """
113        이름 부분의 이름을 반환합니다.
114        
115        Returns:
116            이름 부분의 이름
117        """
118        return self._name
119    
120    def set_type(self, inType):
121        """
122        이름 부분의 타입을 설정합니다.
123        
124        Args:
125            inType: 설정할 타입 (NamePartType 열거형 값)
126        """
127        self._type = inType
128        self._initialize_type_defaults()
129        self._update_weights()
130    
131    def get_type(self):
132        """
133        이름 부분의 타입을 반환합니다.
134        
135        Returns:
136            이름 부분의 타입 (NamePartType 열거형 값)
137        """
138        return self._type
139    
140    def is_prefix(self):
141        """
142        이름 부분이 PREFIX 타입인지 확인합니다.
143        
144        Returns:
145            PREFIX 타입이면 True, 아니면 False
146        """
147        return self._type == NamePartType.PREFIX
148    
149    def is_suffix(self):
150        """
151        이름 부분이 SUFFIX 타입인지 확인합니다.
152        
153        Returns:
154            SUFFIX 타입이면 True, 아니면 False
155        """
156        return self._type == NamePartType.SUFFIX
157    
158    def is_realname(self):
159        """
160        이름 부분이 REALNAME 타입인지 확인합니다.
161        
162        Returns:
163            REALNAME 타입이면 True, 아니면 False
164        """
165        return self._type == NamePartType.REALNAME
166    
167    def is_index(self):
168        """
169        이름 부분이 INDEX 타입인지 확인합니다.
170        
171        Returns:
172            INDEX 타입이면 True, 아니면 False
173        """
174        return self._type == NamePartType.INDEX
175    
176    def add_predefined_value(self, inValue, inDescription="", inKoreanDescription=""):
177        """
178        사전 선언된 값 목록에 새 값을 추가합니다.
179        
180        Args:
181            inValue: 추가할 값
182            inDescription: 추가할 값에 대한 설명 (기본값: 빈 문자열)
183            inKoreanDescription: 추가할 값에 대한 한국어 설명 (기본값: 빈 문자열)
184            
185        Returns:
186            추가 성공 여부 (이미 존재하는 경우 False)
187        """
188        # REALNAME이나 INDEX 타입인 경우 predefined values를 사용하지 않음
189        if self._type == NamePartType.REALNAME or self._type == NamePartType.INDEX:
190            return False
191            
192        if inValue not in self._predefinedValues:
193            self._predefinedValues.append(inValue)
194            self._descriptions.append(inDescription)
195            self._koreanDescriptions.append(inKoreanDescription) # Add korean description
196            self._update_weights()  # 가중치 자동 업데이트
197            return True
198        return False
199    
200    def remove_predefined_value(self, inValue):
201        """
202        사전 선언된 값 목록에서 값을 제거합니다.
203        
204        Args:
205            inValue: 제거할 값
206            
207        Returns:
208            제거 성공 여부 (존재하지 않는 경우 False)
209        """
210        if inValue in self._predefinedValues:
211            index = self._predefinedValues.index(inValue)
212            self._predefinedValues.remove(inValue)
213            self._descriptions.pop(index)
214            self._koreanDescriptions.pop(index) # Remove korean description
215            if index < len(self._weights):
216                self._weights.pop(index)
217            self._update_weights()  # 가중치 자동 업데이트
218            return True
219        return False
220    
221    def set_predefined_values(self, inValues, inDescriptions=None, inKoreanDescriptions=None):
222        """
223        사전 선언된 값 목록을 설정합니다.
224        
225        Args:
226            inValues: 설정할 값 목록
227            inDescriptions: 설정할 값들의 설명 목록 (기본값: None, 빈 문자열로 초기화)
228            inKoreanDescriptions: 설정할 값들의 한국어 설명 목록 (기본값: None, 빈 문자열로 초기화)
229        """
230        # REALNAME이나 INDEX 타입인 경우 predefined values를 사용하지 않음
231        if self._type == NamePartType.REALNAME or self._type == NamePartType.INDEX:
232            return
233            
234        self._predefinedValues = inValues.copy() if inValues else []
235        
236        # 설명 세팅
237        if inDescriptions:
238            self._descriptions = inDescriptions.copy()
239            # 길이 일치 확인
240            if len(self._descriptions) < len(self._predefinedValues):
241                self._descriptions.extend([""] * (len(self._predefinedValues) - len(self._descriptions)))
242            elif len(self._descriptions) > len(self._predefinedValues):
243                self._descriptions = self._descriptions[:len(self._predefinedValues)]
244        else:
245            self._descriptions = [""] * len(self._predefinedValues)
246
247        # 한국어 설명 세팅
248        if inKoreanDescriptions:
249            self._koreanDescriptions = inKoreanDescriptions.copy()
250            # 길이 일치 확인
251            if len(self._koreanDescriptions) < len(self._predefinedValues):
252                self._koreanDescriptions.extend([""] * (len(self._predefinedValues) - len(self._koreanDescriptions)))
253            elif len(self._koreanDescriptions) > len(self._predefinedValues):
254                self._koreanDescriptions = self._koreanDescriptions[:len(self._predefinedValues)]
255        else:
256            self._koreanDescriptions = [""] * len(self._predefinedValues)
257        
258        # 가중치 자동 업데이트
259        self._update_weights()
260    
261    def get_predefined_values(self):
262        """
263        사전 선언된 값 목록을 반환합니다.
264        
265        Returns:
266            사전 선언된 값 목록
267        """
268        return self._predefinedValues.copy()
269    
270    def contains_value(self, inValue):
271        """
272        특정 값이 사전 선언된 값 목록에 있는지 확인합니다.
273        
274        Args:
275            inValue: 확인할 값
276            
277        Returns:
278            값이 존재하면 True, 아니면 False
279        """
280        # INDEX 타입인 경우 숫자인지 확인
281        if self._type == NamePartType.INDEX:
282            return isinstance(inValue, str) and inValue.isdigit()
283            
284        return inValue in self._predefinedValues
285    
286    def get_value_at_index(self, inIndex):
287        """
288        지정된 인덱스의 사전 선언된 값을 반환합니다.
289        
290        Args:
291            inIndex: 값의 인덱스
292            
293        Returns:
294            값 (인덱스가 범위를 벗어나면 None)
295        """
296        if 0 <= inIndex < len(self._predefinedValues):
297            return self._predefinedValues[inIndex]
298        return None
299    
300    def get_value_count(self):
301        """
302        사전 선언된 값의 개수를 반환합니다.
303        
304        Returns:
305            값 개수
306        """
307        return len(self._predefinedValues)
308    
309    def clear_predefined_values(self):
310        """
311        모든 사전 선언된 값을 제거합니다.
312        """
313        # REALNAME이나 INDEX 타입인 경우 아무것도 하지 않음
314        if self._type == NamePartType.REALNAME or self._type == NamePartType.INDEX:
315            return
316            
317        self._predefinedValues.clear()
318        self._descriptions.clear()
319        self._koreanDescriptions.clear() # Clear korean descriptions
320        self._weights.clear()  # 가중치도 초기화
321    
322    # 가중치 매핑 관련 메서드들
323    
324    def get_value_by_weight(self, inRank=0):
325        returnStr = ""
326        if len(self._predefinedValues) != len(self._weights) or len(self._predefinedValues) <= 0:
327            return returnStr
328        foundIndex = self._weights.index(inRank)
329        returnStr = self._predefinedValues[foundIndex] if foundIndex >= 0 else self._predefinedValues[0]
330        
331        return returnStr
332    
333    def get_most_different_weight_value(self, inValue):
334        """
335        주어진 값의 가중치와 가장 차이가 큰 값을 반환합니다.
336        
337        Args:
338            inValue: 기준이 되는 값
339            
340        Returns:
341            가중치 차이가 가장 큰 값, 없으면 빈 문자열
342        """
343        if len(self._predefinedValues) != len(self._weights) or len(self._predefinedValues) <= 0:
344            return ""
345            
346        if inValue not in self._predefinedValues:
347            return ""
348            
349        # 값의 가중치 가져오기
350        index = self._predefinedValues.index(inValue)
351        currentWeight = self._weights[index]
352            
353        maxDiff = -1
354        maxDiffValue = ""
355        
356        # 가중치 차이가 가장 큰 값 찾기
357        for i, predValue in enumerate(self._predefinedValues):
358            if predValue == inValue:
359                continue
360                
361            predWeight = self._weights[i] if i < len(self._weights) else 0
362            diff = abs(currentWeight - predWeight)
363            if diff > maxDiff:
364                maxDiff = diff
365                maxDiffValue = predValue
366                
367        return maxDiffValue
368    
369    def get_value_by_min_weight(self):
370        """
371        가중치가 가장 낮은 값을 반환합니다.
372        
373        Returns:
374            가중치가 가장 낮은 값, 없으면 빈 문자열
375        """
376        if len(self._predefinedValues) != len(self._weights) or len(self._predefinedValues) <= 0:
377            return ""
378        return self._predefinedValues[0]
379    
380    def get_value_by_max_weight(self):
381        """
382        가중치가 가장 높은 값을 반환합니다.
383        
384        Returns:
385            가중치가 가장 높은 값, 없으면 빈 문자열
386        """
387        if len(self._predefinedValues) != len(self._weights) or len(self._predefinedValues) <= 0:
388            return ""
389        return self._predefinedValues[-1]
390    
391    def validate_value(self, inValue):
392        """
393        값이 이 NamePart 타입에 유효한지 검증합니다.
394        
395        Args:
396            inValue: 검증할 값
397            
398        Returns:
399            유효하면 True, 아니면 False
400        """
401        # INDEX 타입은 숫자 문자열만 유효
402        if self._type == NamePartType.INDEX:
403            return isinstance(inValue, str) and inValue.isdigit()
404            
405        # PREFIX와 SUFFIX 타입은 predefined values 중 하나여야 함
406        if (self._type == NamePartType.PREFIX or self._type == NamePartType.SUFFIX) and self._predefinedValues:
407            return inValue in self._predefinedValues
408            
409        # REALNAME 타입은 모든 문자열 유효
410        if self._type == NamePartType.REALNAME:
411            return isinstance(inValue, str)
412            
413        # 정의되지 않은 타입이면 기존 동작대로 처리
414        return True
415    
416    # 추가: 설명 관련 메서드들
417    
418    def set_description(self, inValue, inDescription):
419        """
420        특정 predefined value의 설명을 설정합니다.
421        
422        Args:
423            inValue: 설명을 설정할 값
424            inDescription: 설정할 설명
425            
426        Returns:
427            설정 성공 여부 (값이 존재하지 않는 경우 False)
428        """
429        if inValue in self._predefinedValues:
430            index = self._predefinedValues.index(inValue)
431            self._descriptions[index] = inDescription
432            return True
433        return False
434    
435    def get_description_by_value(self, inValue):
436        """
437        특정 predefined value의 설명을 반환합니다.
438        
439        Args:
440            inValue: 설명을 가져올 값
441            
442        Returns:
443            해당 값의 설명, 값이 존재하지 않으면 빈 문자열
444        """
445        if inValue in self._predefinedValues:
446            index = self._predefinedValues.index(inValue)
447            return self._descriptions[index]
448        return ""
449    
450    def get_descriptions(self):
451        """
452        모든 설명을 반환합니다.
453        
454        Returns:
455            설명 목록
456        """
457        return self._descriptions.copy()
458    
459    def get_value_by_description(self, inDescription):
460        """
461        특정 설명에 해당하는 값을 반환합니다.
462        
463        Args:
464            inDescription: 찾을 설명
465            
466        Returns:
467            해당 설명의 값, 없으면 빈 문자열
468        """
469        if inDescription in self._descriptions:
470            index = self._descriptions.index(inDescription)
471            return self._predefinedValues[index]
472        return ""
473    
474    def get_value_with_description(self, inIndex):
475        """
476        지정된 인덱스의 값과 설명을 튜플로 반환합니다.
477        
478        Args:
479            inIndex: 값의 인덱스
480            
481        Returns:
482            (값, 설명) 튜플, 인덱스가 범위를 벗어나면 (None, None)
483        """
484        if 0 <= inIndex < len(self._predefinedValues):
485            return (self._predefinedValues[inIndex], self._descriptions[inIndex])
486        return (None, None)
487    
488    def get_values_with_descriptions(self):
489        """
490        모든 값과 설명의 튜플 리스트를 반환합니다.
491        
492        Returns:
493            (값, 설명) 튜플의 리스트
494        """
495        return list(zip(self._predefinedValues, self._descriptions))
496
497    # 추가: 한국어 설명 관련 메서드들
498    
499    def set_korean_description(self, inValue, inKoreanDescription):
500        """
501        특정 predefined value의 한국어 설명을 설정합니다.
502        
503        Args:
504            inValue: 설명을 설정할 값
505            inKoreanDescription: 설정할 한국어 설명
506            
507        Returns:
508            설정 성공 여부 (값이 존재하지 않는 경우 False)
509        """
510        if inValue in self._predefinedValues:
511            index = self._predefinedValues.index(inValue)
512            self._koreanDescriptions[index] = inKoreanDescription
513            return True
514        return False
515    
516    def get_korean_description_by_value(self, inValue):
517        """
518        특정 predefined value의 한국어 설명을 반환합니다.
519        
520        Args:
521            inValue: 설명을 가져올 값
522            
523        Returns:
524            해당 값의 한국어 설명, 값이 존재하지 않으면 빈 문자열
525        """
526        if inValue in self._predefinedValues:
527            index = self._predefinedValues.index(inValue)
528            return self._koreanDescriptions[index]
529        return ""
530    
531    def get_korean_descriptions(self):
532        """
533        모든 한국어 설명을 반환합니다.
534        
535        Returns:
536            한국어 설명 목록
537        """
538        return self._koreanDescriptions.copy()
539    
540    def get_value_by_korean_description(self, inKoreanDescription):
541        """
542        특정 한국어 설명에 해당하는 값을 반환합니다.
543        
544        Args:
545            inKoreanDescription: 찾을 한국어 설명
546            
547        Returns:
548            해당 설명의 값, 없으면 빈 문자열
549        """
550        if inKoreanDescription in self._koreanDescriptions:
551            index = self._koreanDescriptions.index(inKoreanDescription)
552            return self._predefinedValues[index]
553        return ""
554    
555    def get_value_with_korean_description(self, inIndex):
556        """
557        지정된 인덱스의 값과 한국어 설명을 튜플로 반환합니다.
558        
559        Args:
560            inIndex: 값의 인덱스
561            
562        Returns:
563            (값, 한국어 설명) 튜플, 인덱스가 범위를 벗어나면 (None, None)
564        """
565        if 0 <= inIndex < len(self._predefinedValues):
566            return (self._predefinedValues[inIndex], self._koreanDescriptions[inIndex])
567        return (None, None)
568    
569    def get_values_with_korean_descriptions(self):
570        """
571        모든 값과 한국어 설명의 튜플 리스트를 반환합니다.
572        
573        Returns:
574            (값, 한국어 설명) 튜플의 리스트
575        """
576        return list(zip(self._predefinedValues, self._koreanDescriptions))
577    
578    def is_direction(self):
579        """
580        방향성 여부를 반환합니다.
581        
582        Returns:
583            방향성 여부 (True/False)
584        """
585        return self._isDirection
586    
587    def to_dict(self):
588        """
589        NamePart 객체를 사전 형태로 변환합니다.
590        
591        Returns:
592            사전 형태의 NamePart 정보
593        """
594        return {
595            "name": self._name,
596            "predefinedValues": self._predefinedValues.copy(),
597            "weights": self._weights.copy(),  # 가중치를 리스트 형태로 직접 전달
598            "type": self._type.name if hasattr(self._type, 'name') else str(self._type),
599            "descriptions": self._descriptions.copy(),
600            "koreanDescriptions": self._koreanDescriptions.copy(), # Add korean descriptions
601            "isDirection": self._isDirection
602        }
603    
604    @staticmethod
605    def from_dict(inData):
606        """
607        사전 형태의 데이터로부터 NamePart 객체를 생성합니다.
608        
609        Args:
610            inData: 사전 형태의 NamePart 정보
611            
612        Returns:
613            NamePart 객체
614        """
615        if isinstance(inData, dict) and "name" in inData:
616            # 타입 변환 (문자열 -> NamePartType 열거형)
617            type_str = inData.get("type", "UNDEFINED")
618            try:
619                part_type = NamePartType[type_str] if isinstance(type_str, str) else NamePartType.UNDEFINED
620            except KeyError:
621                part_type = NamePartType.UNDEFINED
622                
623            result = NamePart(
624                inData["name"],
625                part_type,  # 두 번째 인자로 타입 전달
626                inData.get("predefinedValues", []),  # 세 번째 인자로 predefinedValues 전달
627                inData.get("descriptions", []),  # 네 번째 인자로 descriptions 전달
628                inData.get("isDirection", False),  # 다섯 번째 인자로 isDirection 전달
629                inData.get("koreanDescriptions", []) # 여섯 번째 인자로 koreanDescriptions 전달
630            )
631            
632            return result
633        return NamePart()
class NamePartType(enum.Enum):
13class NamePartType(Enum):
14    """
15    이름 부분(name part)의 유형을 정의하는 열거형 클래스.
16    
17    - PREFIX: RealName 앞에 오는 부분, 사전 정의 값 필수
18    - SUFFIX: RealName 뒤에 오는 부분, 사전 정의 값 필수
19    - REALNAME: 실제 이름 부분, 자유 텍스트 가능
20    - INDEX: 숫자만 허용되는 부분
21    - UNDEFINED: 정의되지 않은 타입 (기본값)
22    """
23    PREFIX = auto()
24    SUFFIX = auto()
25    REALNAME = auto()
26    INDEX = auto()
27    UNDEFINED = auto()

이름 부분(name part)의 유형을 정의하는 열거형 클래스.

  • PREFIX: RealName 앞에 오는 부분, 사전 정의 값 필수
  • SUFFIX: RealName 뒤에 오는 부분, 사전 정의 값 필수
  • REALNAME: 실제 이름 부분, 자유 텍스트 가능
  • INDEX: 숫자만 허용되는 부분
  • UNDEFINED: 정의되지 않은 타입 (기본값)
PREFIX = <NamePartType.PREFIX: 1>
SUFFIX = <NamePartType.SUFFIX: 2>
REALNAME = <NamePartType.REALNAME: 3>
INDEX = <NamePartType.INDEX: 4>
UNDEFINED = <NamePartType.UNDEFINED: 5>
class NamePart:
 29class NamePart:
 30    """
 31    이름 부분(name part)을 관리하기 위한 클래스.
 32    이름과 해당 부분에 대한 사전 선언된 값들을 관리합니다.
 33    """
 34    
 35    def __init__(self, inName="", inType=NamePartType.UNDEFINED, inPredefinedValues=None, inDescriptions=None, inIsDirection=False, inKoreanDescriptions=None):
 36        """
 37        NamePart 클래스 초기화
 38        
 39        Args:
 40            inName: 이름 부분의 이름 (예: "Base", "Type", "Side" 등)
 41            inPredefinedValues: 사전 선언된 값 목록 (기본값: None, 빈 리스트로 초기화)
 42            inType: NamePart의 타입 (NamePartType 열거형 값)
 43            inDescriptions: 사전 선언된 값들의 설명 목록 (기본값: None, 빈 리스트로 초기화)
 44            inIsDirection: 방향성 여부 (기본값: False)
 45            inKoreanDescriptions: 사전 선언된 값들의 한국어 설명 목록 (기본값: None, 빈 리스트로 초기화)
 46        """
 47        self._name = inName
 48        self._predefinedValues = inPredefinedValues if inPredefinedValues is not None else []
 49        self._weights = []
 50        self._type = inType
 51        self._descriptions = inDescriptions if inDescriptions is not None else [""] * len(self._predefinedValues)
 52        self._koreanDescriptions = inKoreanDescriptions if inKoreanDescriptions is not None else [""] * len(self._predefinedValues) # Add korean descriptions
 53        self._isDirection = inIsDirection if inIsDirection is True else False  # 방향성 여부 (기본값: False)
 54        
 55        # 길이 일치 확인 (Descriptions)
 56        if len(self._descriptions) < len(self._predefinedValues):
 57            self._descriptions.extend([""] * (len(self._predefinedValues) - len(self._descriptions)))
 58        elif len(self._descriptions) > len(self._predefinedValues):
 59            self._descriptions = self._descriptions[:len(self._predefinedValues)]
 60
 61        # 길이 일치 확인 (Korean Descriptions)
 62        if len(self._koreanDescriptions) < len(self._predefinedValues):
 63            self._koreanDescriptions.extend([""] * (len(self._predefinedValues) - len(self._koreanDescriptions)))
 64        elif len(self._koreanDescriptions) > len(self._predefinedValues):
 65            self._koreanDescriptions = self._koreanDescriptions[:len(self._predefinedValues)]
 66        
 67        # 타입에 따른 기본 값 설정
 68        self._initialize_type_defaults()
 69        self._update_weights()
 70    
 71    def _initialize_type_defaults(self):
 72        """타입에 따른 기본 설정을 초기화합니다."""
 73        if self._type == NamePartType.INDEX:
 74            # Index 타입은 숫자만 처리하므로 predefined values는 사용하지 않음
 75            self._predefinedValues = []
 76            self._descriptions = []
 77            self._koreanDescriptions = [] # Clear korean descriptions
 78            self._weights = []
 79        elif self._type == NamePartType.REALNAME:
 80            # RealName 타입은 predefined values를 사용하지 않음
 81            self._predefinedValues = []
 82            self._descriptions = []
 83            self._koreanDescriptions = [] # Clear korean descriptions
 84            self._weights = []
 85    
 86    def _update_weights(self):
 87        """
 88        predefined values의 순서에 따라 자동으로 가중치를 설정합니다.
 89        값들은 5부터 시작해서 5씩 증가하는 가중치를 갖습니다.
 90        """
 91        # REALNAME이나 INDEX 타입인 경우 weights를 사용하지 않음
 92        if self._type == NamePartType.REALNAME or self._type == NamePartType.INDEX:
 93            self._weights = []
 94            return
 95            
 96        self._weights = []
 97        # 가중치는 5부터 시작해서 5씩 증가 (순서대로 내림차순 가중치)
 98        num_values = len(self._predefinedValues)
 99        for i in range(num_values):
100            weight_value = 5 * (i + 1)  # 내림차순 가중치
101            self._weights.append(weight_value)
102    
103    def set_name(self, inName):
104        """
105        이름 부분의 이름을 설정합니다.
106        
107        Args:
108            inName: 설정할 이름
109        """
110        self._name = inName
111    
112    def get_name(self):
113        """
114        이름 부분의 이름을 반환합니다.
115        
116        Returns:
117            이름 부분의 이름
118        """
119        return self._name
120    
121    def set_type(self, inType):
122        """
123        이름 부분의 타입을 설정합니다.
124        
125        Args:
126            inType: 설정할 타입 (NamePartType 열거형 값)
127        """
128        self._type = inType
129        self._initialize_type_defaults()
130        self._update_weights()
131    
132    def get_type(self):
133        """
134        이름 부분의 타입을 반환합니다.
135        
136        Returns:
137            이름 부분의 타입 (NamePartType 열거형 값)
138        """
139        return self._type
140    
141    def is_prefix(self):
142        """
143        이름 부분이 PREFIX 타입인지 확인합니다.
144        
145        Returns:
146            PREFIX 타입이면 True, 아니면 False
147        """
148        return self._type == NamePartType.PREFIX
149    
150    def is_suffix(self):
151        """
152        이름 부분이 SUFFIX 타입인지 확인합니다.
153        
154        Returns:
155            SUFFIX 타입이면 True, 아니면 False
156        """
157        return self._type == NamePartType.SUFFIX
158    
159    def is_realname(self):
160        """
161        이름 부분이 REALNAME 타입인지 확인합니다.
162        
163        Returns:
164            REALNAME 타입이면 True, 아니면 False
165        """
166        return self._type == NamePartType.REALNAME
167    
168    def is_index(self):
169        """
170        이름 부분이 INDEX 타입인지 확인합니다.
171        
172        Returns:
173            INDEX 타입이면 True, 아니면 False
174        """
175        return self._type == NamePartType.INDEX
176    
177    def add_predefined_value(self, inValue, inDescription="", inKoreanDescription=""):
178        """
179        사전 선언된 값 목록에 새 값을 추가합니다.
180        
181        Args:
182            inValue: 추가할 값
183            inDescription: 추가할 값에 대한 설명 (기본값: 빈 문자열)
184            inKoreanDescription: 추가할 값에 대한 한국어 설명 (기본값: 빈 문자열)
185            
186        Returns:
187            추가 성공 여부 (이미 존재하는 경우 False)
188        """
189        # REALNAME이나 INDEX 타입인 경우 predefined values를 사용하지 않음
190        if self._type == NamePartType.REALNAME or self._type == NamePartType.INDEX:
191            return False
192            
193        if inValue not in self._predefinedValues:
194            self._predefinedValues.append(inValue)
195            self._descriptions.append(inDescription)
196            self._koreanDescriptions.append(inKoreanDescription) # Add korean description
197            self._update_weights()  # 가중치 자동 업데이트
198            return True
199        return False
200    
201    def remove_predefined_value(self, inValue):
202        """
203        사전 선언된 값 목록에서 값을 제거합니다.
204        
205        Args:
206            inValue: 제거할 값
207            
208        Returns:
209            제거 성공 여부 (존재하지 않는 경우 False)
210        """
211        if inValue in self._predefinedValues:
212            index = self._predefinedValues.index(inValue)
213            self._predefinedValues.remove(inValue)
214            self._descriptions.pop(index)
215            self._koreanDescriptions.pop(index) # Remove korean description
216            if index < len(self._weights):
217                self._weights.pop(index)
218            self._update_weights()  # 가중치 자동 업데이트
219            return True
220        return False
221    
222    def set_predefined_values(self, inValues, inDescriptions=None, inKoreanDescriptions=None):
223        """
224        사전 선언된 값 목록을 설정합니다.
225        
226        Args:
227            inValues: 설정할 값 목록
228            inDescriptions: 설정할 값들의 설명 목록 (기본값: None, 빈 문자열로 초기화)
229            inKoreanDescriptions: 설정할 값들의 한국어 설명 목록 (기본값: None, 빈 문자열로 초기화)
230        """
231        # REALNAME이나 INDEX 타입인 경우 predefined values를 사용하지 않음
232        if self._type == NamePartType.REALNAME or self._type == NamePartType.INDEX:
233            return
234            
235        self._predefinedValues = inValues.copy() if inValues else []
236        
237        # 설명 세팅
238        if inDescriptions:
239            self._descriptions = inDescriptions.copy()
240            # 길이 일치 확인
241            if len(self._descriptions) < len(self._predefinedValues):
242                self._descriptions.extend([""] * (len(self._predefinedValues) - len(self._descriptions)))
243            elif len(self._descriptions) > len(self._predefinedValues):
244                self._descriptions = self._descriptions[:len(self._predefinedValues)]
245        else:
246            self._descriptions = [""] * len(self._predefinedValues)
247
248        # 한국어 설명 세팅
249        if inKoreanDescriptions:
250            self._koreanDescriptions = inKoreanDescriptions.copy()
251            # 길이 일치 확인
252            if len(self._koreanDescriptions) < len(self._predefinedValues):
253                self._koreanDescriptions.extend([""] * (len(self._predefinedValues) - len(self._koreanDescriptions)))
254            elif len(self._koreanDescriptions) > len(self._predefinedValues):
255                self._koreanDescriptions = self._koreanDescriptions[:len(self._predefinedValues)]
256        else:
257            self._koreanDescriptions = [""] * len(self._predefinedValues)
258        
259        # 가중치 자동 업데이트
260        self._update_weights()
261    
262    def get_predefined_values(self):
263        """
264        사전 선언된 값 목록을 반환합니다.
265        
266        Returns:
267            사전 선언된 값 목록
268        """
269        return self._predefinedValues.copy()
270    
271    def contains_value(self, inValue):
272        """
273        특정 값이 사전 선언된 값 목록에 있는지 확인합니다.
274        
275        Args:
276            inValue: 확인할 값
277            
278        Returns:
279            값이 존재하면 True, 아니면 False
280        """
281        # INDEX 타입인 경우 숫자인지 확인
282        if self._type == NamePartType.INDEX:
283            return isinstance(inValue, str) and inValue.isdigit()
284            
285        return inValue in self._predefinedValues
286    
287    def get_value_at_index(self, inIndex):
288        """
289        지정된 인덱스의 사전 선언된 값을 반환합니다.
290        
291        Args:
292            inIndex: 값의 인덱스
293            
294        Returns:
295            값 (인덱스가 범위를 벗어나면 None)
296        """
297        if 0 <= inIndex < len(self._predefinedValues):
298            return self._predefinedValues[inIndex]
299        return None
300    
301    def get_value_count(self):
302        """
303        사전 선언된 값의 개수를 반환합니다.
304        
305        Returns:
306            값 개수
307        """
308        return len(self._predefinedValues)
309    
310    def clear_predefined_values(self):
311        """
312        모든 사전 선언된 값을 제거합니다.
313        """
314        # REALNAME이나 INDEX 타입인 경우 아무것도 하지 않음
315        if self._type == NamePartType.REALNAME or self._type == NamePartType.INDEX:
316            return
317            
318        self._predefinedValues.clear()
319        self._descriptions.clear()
320        self._koreanDescriptions.clear() # Clear korean descriptions
321        self._weights.clear()  # 가중치도 초기화
322    
323    # 가중치 매핑 관련 메서드들
324    
325    def get_value_by_weight(self, inRank=0):
326        returnStr = ""
327        if len(self._predefinedValues) != len(self._weights) or len(self._predefinedValues) <= 0:
328            return returnStr
329        foundIndex = self._weights.index(inRank)
330        returnStr = self._predefinedValues[foundIndex] if foundIndex >= 0 else self._predefinedValues[0]
331        
332        return returnStr
333    
334    def get_most_different_weight_value(self, inValue):
335        """
336        주어진 값의 가중치와 가장 차이가 큰 값을 반환합니다.
337        
338        Args:
339            inValue: 기준이 되는 값
340            
341        Returns:
342            가중치 차이가 가장 큰 값, 없으면 빈 문자열
343        """
344        if len(self._predefinedValues) != len(self._weights) or len(self._predefinedValues) <= 0:
345            return ""
346            
347        if inValue not in self._predefinedValues:
348            return ""
349            
350        # 값의 가중치 가져오기
351        index = self._predefinedValues.index(inValue)
352        currentWeight = self._weights[index]
353            
354        maxDiff = -1
355        maxDiffValue = ""
356        
357        # 가중치 차이가 가장 큰 값 찾기
358        for i, predValue in enumerate(self._predefinedValues):
359            if predValue == inValue:
360                continue
361                
362            predWeight = self._weights[i] if i < len(self._weights) else 0
363            diff = abs(currentWeight - predWeight)
364            if diff > maxDiff:
365                maxDiff = diff
366                maxDiffValue = predValue
367                
368        return maxDiffValue
369    
370    def get_value_by_min_weight(self):
371        """
372        가중치가 가장 낮은 값을 반환합니다.
373        
374        Returns:
375            가중치가 가장 낮은 값, 없으면 빈 문자열
376        """
377        if len(self._predefinedValues) != len(self._weights) or len(self._predefinedValues) <= 0:
378            return ""
379        return self._predefinedValues[0]
380    
381    def get_value_by_max_weight(self):
382        """
383        가중치가 가장 높은 값을 반환합니다.
384        
385        Returns:
386            가중치가 가장 높은 값, 없으면 빈 문자열
387        """
388        if len(self._predefinedValues) != len(self._weights) or len(self._predefinedValues) <= 0:
389            return ""
390        return self._predefinedValues[-1]
391    
392    def validate_value(self, inValue):
393        """
394        값이 이 NamePart 타입에 유효한지 검증합니다.
395        
396        Args:
397            inValue: 검증할 값
398            
399        Returns:
400            유효하면 True, 아니면 False
401        """
402        # INDEX 타입은 숫자 문자열만 유효
403        if self._type == NamePartType.INDEX:
404            return isinstance(inValue, str) and inValue.isdigit()
405            
406        # PREFIX와 SUFFIX 타입은 predefined values 중 하나여야 함
407        if (self._type == NamePartType.PREFIX or self._type == NamePartType.SUFFIX) and self._predefinedValues:
408            return inValue in self._predefinedValues
409            
410        # REALNAME 타입은 모든 문자열 유효
411        if self._type == NamePartType.REALNAME:
412            return isinstance(inValue, str)
413            
414        # 정의되지 않은 타입이면 기존 동작대로 처리
415        return True
416    
417    # 추가: 설명 관련 메서드들
418    
419    def set_description(self, inValue, inDescription):
420        """
421        특정 predefined value의 설명을 설정합니다.
422        
423        Args:
424            inValue: 설명을 설정할 값
425            inDescription: 설정할 설명
426            
427        Returns:
428            설정 성공 여부 (값이 존재하지 않는 경우 False)
429        """
430        if inValue in self._predefinedValues:
431            index = self._predefinedValues.index(inValue)
432            self._descriptions[index] = inDescription
433            return True
434        return False
435    
436    def get_description_by_value(self, inValue):
437        """
438        특정 predefined value의 설명을 반환합니다.
439        
440        Args:
441            inValue: 설명을 가져올 값
442            
443        Returns:
444            해당 값의 설명, 값이 존재하지 않으면 빈 문자열
445        """
446        if inValue in self._predefinedValues:
447            index = self._predefinedValues.index(inValue)
448            return self._descriptions[index]
449        return ""
450    
451    def get_descriptions(self):
452        """
453        모든 설명을 반환합니다.
454        
455        Returns:
456            설명 목록
457        """
458        return self._descriptions.copy()
459    
460    def get_value_by_description(self, inDescription):
461        """
462        특정 설명에 해당하는 값을 반환합니다.
463        
464        Args:
465            inDescription: 찾을 설명
466            
467        Returns:
468            해당 설명의 값, 없으면 빈 문자열
469        """
470        if inDescription in self._descriptions:
471            index = self._descriptions.index(inDescription)
472            return self._predefinedValues[index]
473        return ""
474    
475    def get_value_with_description(self, inIndex):
476        """
477        지정된 인덱스의 값과 설명을 튜플로 반환합니다.
478        
479        Args:
480            inIndex: 값의 인덱스
481            
482        Returns:
483            (값, 설명) 튜플, 인덱스가 범위를 벗어나면 (None, None)
484        """
485        if 0 <= inIndex < len(self._predefinedValues):
486            return (self._predefinedValues[inIndex], self._descriptions[inIndex])
487        return (None, None)
488    
489    def get_values_with_descriptions(self):
490        """
491        모든 값과 설명의 튜플 리스트를 반환합니다.
492        
493        Returns:
494            (값, 설명) 튜플의 리스트
495        """
496        return list(zip(self._predefinedValues, self._descriptions))
497
498    # 추가: 한국어 설명 관련 메서드들
499    
500    def set_korean_description(self, inValue, inKoreanDescription):
501        """
502        특정 predefined value의 한국어 설명을 설정합니다.
503        
504        Args:
505            inValue: 설명을 설정할 값
506            inKoreanDescription: 설정할 한국어 설명
507            
508        Returns:
509            설정 성공 여부 (값이 존재하지 않는 경우 False)
510        """
511        if inValue in self._predefinedValues:
512            index = self._predefinedValues.index(inValue)
513            self._koreanDescriptions[index] = inKoreanDescription
514            return True
515        return False
516    
517    def get_korean_description_by_value(self, inValue):
518        """
519        특정 predefined value의 한국어 설명을 반환합니다.
520        
521        Args:
522            inValue: 설명을 가져올 값
523            
524        Returns:
525            해당 값의 한국어 설명, 값이 존재하지 않으면 빈 문자열
526        """
527        if inValue in self._predefinedValues:
528            index = self._predefinedValues.index(inValue)
529            return self._koreanDescriptions[index]
530        return ""
531    
532    def get_korean_descriptions(self):
533        """
534        모든 한국어 설명을 반환합니다.
535        
536        Returns:
537            한국어 설명 목록
538        """
539        return self._koreanDescriptions.copy()
540    
541    def get_value_by_korean_description(self, inKoreanDescription):
542        """
543        특정 한국어 설명에 해당하는 값을 반환합니다.
544        
545        Args:
546            inKoreanDescription: 찾을 한국어 설명
547            
548        Returns:
549            해당 설명의 값, 없으면 빈 문자열
550        """
551        if inKoreanDescription in self._koreanDescriptions:
552            index = self._koreanDescriptions.index(inKoreanDescription)
553            return self._predefinedValues[index]
554        return ""
555    
556    def get_value_with_korean_description(self, inIndex):
557        """
558        지정된 인덱스의 값과 한국어 설명을 튜플로 반환합니다.
559        
560        Args:
561            inIndex: 값의 인덱스
562            
563        Returns:
564            (값, 한국어 설명) 튜플, 인덱스가 범위를 벗어나면 (None, None)
565        """
566        if 0 <= inIndex < len(self._predefinedValues):
567            return (self._predefinedValues[inIndex], self._koreanDescriptions[inIndex])
568        return (None, None)
569    
570    def get_values_with_korean_descriptions(self):
571        """
572        모든 값과 한국어 설명의 튜플 리스트를 반환합니다.
573        
574        Returns:
575            (값, 한국어 설명) 튜플의 리스트
576        """
577        return list(zip(self._predefinedValues, self._koreanDescriptions))
578    
579    def is_direction(self):
580        """
581        방향성 여부를 반환합니다.
582        
583        Returns:
584            방향성 여부 (True/False)
585        """
586        return self._isDirection
587    
588    def to_dict(self):
589        """
590        NamePart 객체를 사전 형태로 변환합니다.
591        
592        Returns:
593            사전 형태의 NamePart 정보
594        """
595        return {
596            "name": self._name,
597            "predefinedValues": self._predefinedValues.copy(),
598            "weights": self._weights.copy(),  # 가중치를 리스트 형태로 직접 전달
599            "type": self._type.name if hasattr(self._type, 'name') else str(self._type),
600            "descriptions": self._descriptions.copy(),
601            "koreanDescriptions": self._koreanDescriptions.copy(), # Add korean descriptions
602            "isDirection": self._isDirection
603        }
604    
605    @staticmethod
606    def from_dict(inData):
607        """
608        사전 형태의 데이터로부터 NamePart 객체를 생성합니다.
609        
610        Args:
611            inData: 사전 형태의 NamePart 정보
612            
613        Returns:
614            NamePart 객체
615        """
616        if isinstance(inData, dict) and "name" in inData:
617            # 타입 변환 (문자열 -> NamePartType 열거형)
618            type_str = inData.get("type", "UNDEFINED")
619            try:
620                part_type = NamePartType[type_str] if isinstance(type_str, str) else NamePartType.UNDEFINED
621            except KeyError:
622                part_type = NamePartType.UNDEFINED
623                
624            result = NamePart(
625                inData["name"],
626                part_type,  # 두 번째 인자로 타입 전달
627                inData.get("predefinedValues", []),  # 세 번째 인자로 predefinedValues 전달
628                inData.get("descriptions", []),  # 네 번째 인자로 descriptions 전달
629                inData.get("isDirection", False),  # 다섯 번째 인자로 isDirection 전달
630                inData.get("koreanDescriptions", []) # 여섯 번째 인자로 koreanDescriptions 전달
631            )
632            
633            return result
634        return NamePart()

이름 부분(name part)을 관리하기 위한 클래스. 이름과 해당 부분에 대한 사전 선언된 값들을 관리합니다.

NamePart( inName='', inType=<NamePartType.UNDEFINED: 5>, inPredefinedValues=None, inDescriptions=None, inIsDirection=False, inKoreanDescriptions=None)
35    def __init__(self, inName="", inType=NamePartType.UNDEFINED, inPredefinedValues=None, inDescriptions=None, inIsDirection=False, inKoreanDescriptions=None):
36        """
37        NamePart 클래스 초기화
38        
39        Args:
40            inName: 이름 부분의 이름 (예: "Base", "Type", "Side" 등)
41            inPredefinedValues: 사전 선언된 값 목록 (기본값: None, 빈 리스트로 초기화)
42            inType: NamePart의 타입 (NamePartType 열거형 값)
43            inDescriptions: 사전 선언된 값들의 설명 목록 (기본값: None, 빈 리스트로 초기화)
44            inIsDirection: 방향성 여부 (기본값: False)
45            inKoreanDescriptions: 사전 선언된 값들의 한국어 설명 목록 (기본값: None, 빈 리스트로 초기화)
46        """
47        self._name = inName
48        self._predefinedValues = inPredefinedValues if inPredefinedValues is not None else []
49        self._weights = []
50        self._type = inType
51        self._descriptions = inDescriptions if inDescriptions is not None else [""] * len(self._predefinedValues)
52        self._koreanDescriptions = inKoreanDescriptions if inKoreanDescriptions is not None else [""] * len(self._predefinedValues) # Add korean descriptions
53        self._isDirection = inIsDirection if inIsDirection is True else False  # 방향성 여부 (기본값: False)
54        
55        # 길이 일치 확인 (Descriptions)
56        if len(self._descriptions) < len(self._predefinedValues):
57            self._descriptions.extend([""] * (len(self._predefinedValues) - len(self._descriptions)))
58        elif len(self._descriptions) > len(self._predefinedValues):
59            self._descriptions = self._descriptions[:len(self._predefinedValues)]
60
61        # 길이 일치 확인 (Korean Descriptions)
62        if len(self._koreanDescriptions) < len(self._predefinedValues):
63            self._koreanDescriptions.extend([""] * (len(self._predefinedValues) - len(self._koreanDescriptions)))
64        elif len(self._koreanDescriptions) > len(self._predefinedValues):
65            self._koreanDescriptions = self._koreanDescriptions[:len(self._predefinedValues)]
66        
67        # 타입에 따른 기본 값 설정
68        self._initialize_type_defaults()
69        self._update_weights()

NamePart 클래스 초기화

Args: inName: 이름 부분의 이름 (예: "Base", "Type", "Side" 등) inPredefinedValues: 사전 선언된 값 목록 (기본값: None, 빈 리스트로 초기화) inType: NamePart의 타입 (NamePartType 열거형 값) inDescriptions: 사전 선언된 값들의 설명 목록 (기본값: None, 빈 리스트로 초기화) inIsDirection: 방향성 여부 (기본값: False) inKoreanDescriptions: 사전 선언된 값들의 한국어 설명 목록 (기본값: None, 빈 리스트로 초기화)

def set_name(self, inName):
103    def set_name(self, inName):
104        """
105        이름 부분의 이름을 설정합니다.
106        
107        Args:
108            inName: 설정할 이름
109        """
110        self._name = inName

이름 부분의 이름을 설정합니다.

Args: inName: 설정할 이름

def get_name(self):
112    def get_name(self):
113        """
114        이름 부분의 이름을 반환합니다.
115        
116        Returns:
117            이름 부분의 이름
118        """
119        return self._name

이름 부분의 이름을 반환합니다.

Returns: 이름 부분의 이름

def set_type(self, inType):
121    def set_type(self, inType):
122        """
123        이름 부분의 타입을 설정합니다.
124        
125        Args:
126            inType: 설정할 타입 (NamePartType 열거형 값)
127        """
128        self._type = inType
129        self._initialize_type_defaults()
130        self._update_weights()

이름 부분의 타입을 설정합니다.

Args: inType: 설정할 타입 (NamePartType 열거형 값)

def get_type(self):
132    def get_type(self):
133        """
134        이름 부분의 타입을 반환합니다.
135        
136        Returns:
137            이름 부분의 타입 (NamePartType 열거형 값)
138        """
139        return self._type

이름 부분의 타입을 반환합니다.

Returns: 이름 부분의 타입 (NamePartType 열거형 값)

def is_prefix(self):
141    def is_prefix(self):
142        """
143        이름 부분이 PREFIX 타입인지 확인합니다.
144        
145        Returns:
146            PREFIX 타입이면 True, 아니면 False
147        """
148        return self._type == NamePartType.PREFIX

이름 부분이 PREFIX 타입인지 확인합니다.

Returns: PREFIX 타입이면 True, 아니면 False

def is_suffix(self):
150    def is_suffix(self):
151        """
152        이름 부분이 SUFFIX 타입인지 확인합니다.
153        
154        Returns:
155            SUFFIX 타입이면 True, 아니면 False
156        """
157        return self._type == NamePartType.SUFFIX

이름 부분이 SUFFIX 타입인지 확인합니다.

Returns: SUFFIX 타입이면 True, 아니면 False

def is_realname(self):
159    def is_realname(self):
160        """
161        이름 부분이 REALNAME 타입인지 확인합니다.
162        
163        Returns:
164            REALNAME 타입이면 True, 아니면 False
165        """
166        return self._type == NamePartType.REALNAME

이름 부분이 REALNAME 타입인지 확인합니다.

Returns: REALNAME 타입이면 True, 아니면 False

def is_index(self):
168    def is_index(self):
169        """
170        이름 부분이 INDEX 타입인지 확인합니다.
171        
172        Returns:
173            INDEX 타입이면 True, 아니면 False
174        """
175        return self._type == NamePartType.INDEX

이름 부분이 INDEX 타입인지 확인합니다.

Returns: INDEX 타입이면 True, 아니면 False

def add_predefined_value(self, inValue, inDescription='', inKoreanDescription=''):
177    def add_predefined_value(self, inValue, inDescription="", inKoreanDescription=""):
178        """
179        사전 선언된 값 목록에 새 값을 추가합니다.
180        
181        Args:
182            inValue: 추가할 값
183            inDescription: 추가할 값에 대한 설명 (기본값: 빈 문자열)
184            inKoreanDescription: 추가할 값에 대한 한국어 설명 (기본값: 빈 문자열)
185            
186        Returns:
187            추가 성공 여부 (이미 존재하는 경우 False)
188        """
189        # REALNAME이나 INDEX 타입인 경우 predefined values를 사용하지 않음
190        if self._type == NamePartType.REALNAME or self._type == NamePartType.INDEX:
191            return False
192            
193        if inValue not in self._predefinedValues:
194            self._predefinedValues.append(inValue)
195            self._descriptions.append(inDescription)
196            self._koreanDescriptions.append(inKoreanDescription) # Add korean description
197            self._update_weights()  # 가중치 자동 업데이트
198            return True
199        return False

사전 선언된 값 목록에 새 값을 추가합니다.

Args: inValue: 추가할 값 inDescription: 추가할 값에 대한 설명 (기본값: 빈 문자열) inKoreanDescription: 추가할 값에 대한 한국어 설명 (기본값: 빈 문자열)

Returns: 추가 성공 여부 (이미 존재하는 경우 False)

def remove_predefined_value(self, inValue):
201    def remove_predefined_value(self, inValue):
202        """
203        사전 선언된 값 목록에서 값을 제거합니다.
204        
205        Args:
206            inValue: 제거할 값
207            
208        Returns:
209            제거 성공 여부 (존재하지 않는 경우 False)
210        """
211        if inValue in self._predefinedValues:
212            index = self._predefinedValues.index(inValue)
213            self._predefinedValues.remove(inValue)
214            self._descriptions.pop(index)
215            self._koreanDescriptions.pop(index) # Remove korean description
216            if index < len(self._weights):
217                self._weights.pop(index)
218            self._update_weights()  # 가중치 자동 업데이트
219            return True
220        return False

사전 선언된 값 목록에서 값을 제거합니다.

Args: inValue: 제거할 값

Returns: 제거 성공 여부 (존재하지 않는 경우 False)

def set_predefined_values(self, inValues, inDescriptions=None, inKoreanDescriptions=None):
222    def set_predefined_values(self, inValues, inDescriptions=None, inKoreanDescriptions=None):
223        """
224        사전 선언된 값 목록을 설정합니다.
225        
226        Args:
227            inValues: 설정할 값 목록
228            inDescriptions: 설정할 값들의 설명 목록 (기본값: None, 빈 문자열로 초기화)
229            inKoreanDescriptions: 설정할 값들의 한국어 설명 목록 (기본값: None, 빈 문자열로 초기화)
230        """
231        # REALNAME이나 INDEX 타입인 경우 predefined values를 사용하지 않음
232        if self._type == NamePartType.REALNAME or self._type == NamePartType.INDEX:
233            return
234            
235        self._predefinedValues = inValues.copy() if inValues else []
236        
237        # 설명 세팅
238        if inDescriptions:
239            self._descriptions = inDescriptions.copy()
240            # 길이 일치 확인
241            if len(self._descriptions) < len(self._predefinedValues):
242                self._descriptions.extend([""] * (len(self._predefinedValues) - len(self._descriptions)))
243            elif len(self._descriptions) > len(self._predefinedValues):
244                self._descriptions = self._descriptions[:len(self._predefinedValues)]
245        else:
246            self._descriptions = [""] * len(self._predefinedValues)
247
248        # 한국어 설명 세팅
249        if inKoreanDescriptions:
250            self._koreanDescriptions = inKoreanDescriptions.copy()
251            # 길이 일치 확인
252            if len(self._koreanDescriptions) < len(self._predefinedValues):
253                self._koreanDescriptions.extend([""] * (len(self._predefinedValues) - len(self._koreanDescriptions)))
254            elif len(self._koreanDescriptions) > len(self._predefinedValues):
255                self._koreanDescriptions = self._koreanDescriptions[:len(self._predefinedValues)]
256        else:
257            self._koreanDescriptions = [""] * len(self._predefinedValues)
258        
259        # 가중치 자동 업데이트
260        self._update_weights()

사전 선언된 값 목록을 설정합니다.

Args: inValues: 설정할 값 목록 inDescriptions: 설정할 값들의 설명 목록 (기본값: None, 빈 문자열로 초기화) inKoreanDescriptions: 설정할 값들의 한국어 설명 목록 (기본값: None, 빈 문자열로 초기화)

def get_predefined_values(self):
262    def get_predefined_values(self):
263        """
264        사전 선언된 값 목록을 반환합니다.
265        
266        Returns:
267            사전 선언된 값 목록
268        """
269        return self._predefinedValues.copy()

사전 선언된 값 목록을 반환합니다.

Returns: 사전 선언된 값 목록

def contains_value(self, inValue):
271    def contains_value(self, inValue):
272        """
273        특정 값이 사전 선언된 값 목록에 있는지 확인합니다.
274        
275        Args:
276            inValue: 확인할 값
277            
278        Returns:
279            값이 존재하면 True, 아니면 False
280        """
281        # INDEX 타입인 경우 숫자인지 확인
282        if self._type == NamePartType.INDEX:
283            return isinstance(inValue, str) and inValue.isdigit()
284            
285        return inValue in self._predefinedValues

특정 값이 사전 선언된 값 목록에 있는지 확인합니다.

Args: inValue: 확인할 값

Returns: 값이 존재하면 True, 아니면 False

def get_value_at_index(self, inIndex):
287    def get_value_at_index(self, inIndex):
288        """
289        지정된 인덱스의 사전 선언된 값을 반환합니다.
290        
291        Args:
292            inIndex: 값의 인덱스
293            
294        Returns:
295            값 (인덱스가 범위를 벗어나면 None)
296        """
297        if 0 <= inIndex < len(self._predefinedValues):
298            return self._predefinedValues[inIndex]
299        return None

지정된 인덱스의 사전 선언된 값을 반환합니다.

Args: inIndex: 값의 인덱스

Returns: 값 (인덱스가 범위를 벗어나면 None)

def get_value_count(self):
301    def get_value_count(self):
302        """
303        사전 선언된 값의 개수를 반환합니다.
304        
305        Returns:
306            값 개수
307        """
308        return len(self._predefinedValues)

사전 선언된 값의 개수를 반환합니다.

Returns: 값 개수

def clear_predefined_values(self):
310    def clear_predefined_values(self):
311        """
312        모든 사전 선언된 값을 제거합니다.
313        """
314        # REALNAME이나 INDEX 타입인 경우 아무것도 하지 않음
315        if self._type == NamePartType.REALNAME or self._type == NamePartType.INDEX:
316            return
317            
318        self._predefinedValues.clear()
319        self._descriptions.clear()
320        self._koreanDescriptions.clear() # Clear korean descriptions
321        self._weights.clear()  # 가중치도 초기화

모든 사전 선언된 값을 제거합니다.

def get_value_by_weight(self, inRank=0):
325    def get_value_by_weight(self, inRank=0):
326        returnStr = ""
327        if len(self._predefinedValues) != len(self._weights) or len(self._predefinedValues) <= 0:
328            return returnStr
329        foundIndex = self._weights.index(inRank)
330        returnStr = self._predefinedValues[foundIndex] if foundIndex >= 0 else self._predefinedValues[0]
331        
332        return returnStr
def get_most_different_weight_value(self, inValue):
334    def get_most_different_weight_value(self, inValue):
335        """
336        주어진 값의 가중치와 가장 차이가 큰 값을 반환합니다.
337        
338        Args:
339            inValue: 기준이 되는 값
340            
341        Returns:
342            가중치 차이가 가장 큰 값, 없으면 빈 문자열
343        """
344        if len(self._predefinedValues) != len(self._weights) or len(self._predefinedValues) <= 0:
345            return ""
346            
347        if inValue not in self._predefinedValues:
348            return ""
349            
350        # 값의 가중치 가져오기
351        index = self._predefinedValues.index(inValue)
352        currentWeight = self._weights[index]
353            
354        maxDiff = -1
355        maxDiffValue = ""
356        
357        # 가중치 차이가 가장 큰 값 찾기
358        for i, predValue in enumerate(self._predefinedValues):
359            if predValue == inValue:
360                continue
361                
362            predWeight = self._weights[i] if i < len(self._weights) else 0
363            diff = abs(currentWeight - predWeight)
364            if diff > maxDiff:
365                maxDiff = diff
366                maxDiffValue = predValue
367                
368        return maxDiffValue

주어진 값의 가중치와 가장 차이가 큰 값을 반환합니다.

Args: inValue: 기준이 되는 값

Returns: 가중치 차이가 가장 큰 값, 없으면 빈 문자열

def get_value_by_min_weight(self):
370    def get_value_by_min_weight(self):
371        """
372        가중치가 가장 낮은 값을 반환합니다.
373        
374        Returns:
375            가중치가 가장 낮은 값, 없으면 빈 문자열
376        """
377        if len(self._predefinedValues) != len(self._weights) or len(self._predefinedValues) <= 0:
378            return ""
379        return self._predefinedValues[0]

가중치가 가장 낮은 값을 반환합니다.

Returns: 가중치가 가장 낮은 값, 없으면 빈 문자열

def get_value_by_max_weight(self):
381    def get_value_by_max_weight(self):
382        """
383        가중치가 가장 높은 값을 반환합니다.
384        
385        Returns:
386            가중치가 가장 높은 값, 없으면 빈 문자열
387        """
388        if len(self._predefinedValues) != len(self._weights) or len(self._predefinedValues) <= 0:
389            return ""
390        return self._predefinedValues[-1]

가중치가 가장 높은 값을 반환합니다.

Returns: 가중치가 가장 높은 값, 없으면 빈 문자열

def validate_value(self, inValue):
392    def validate_value(self, inValue):
393        """
394        값이 이 NamePart 타입에 유효한지 검증합니다.
395        
396        Args:
397            inValue: 검증할 값
398            
399        Returns:
400            유효하면 True, 아니면 False
401        """
402        # INDEX 타입은 숫자 문자열만 유효
403        if self._type == NamePartType.INDEX:
404            return isinstance(inValue, str) and inValue.isdigit()
405            
406        # PREFIX와 SUFFIX 타입은 predefined values 중 하나여야 함
407        if (self._type == NamePartType.PREFIX or self._type == NamePartType.SUFFIX) and self._predefinedValues:
408            return inValue in self._predefinedValues
409            
410        # REALNAME 타입은 모든 문자열 유효
411        if self._type == NamePartType.REALNAME:
412            return isinstance(inValue, str)
413            
414        # 정의되지 않은 타입이면 기존 동작대로 처리
415        return True

값이 이 NamePart 타입에 유효한지 검증합니다.

Args: inValue: 검증할 값

Returns: 유효하면 True, 아니면 False

def set_description(self, inValue, inDescription):
419    def set_description(self, inValue, inDescription):
420        """
421        특정 predefined value의 설명을 설정합니다.
422        
423        Args:
424            inValue: 설명을 설정할 값
425            inDescription: 설정할 설명
426            
427        Returns:
428            설정 성공 여부 (값이 존재하지 않는 경우 False)
429        """
430        if inValue in self._predefinedValues:
431            index = self._predefinedValues.index(inValue)
432            self._descriptions[index] = inDescription
433            return True
434        return False

특정 predefined value의 설명을 설정합니다.

Args: inValue: 설명을 설정할 값 inDescription: 설정할 설명

Returns: 설정 성공 여부 (값이 존재하지 않는 경우 False)

def get_description_by_value(self, inValue):
436    def get_description_by_value(self, inValue):
437        """
438        특정 predefined value의 설명을 반환합니다.
439        
440        Args:
441            inValue: 설명을 가져올 값
442            
443        Returns:
444            해당 값의 설명, 값이 존재하지 않으면 빈 문자열
445        """
446        if inValue in self._predefinedValues:
447            index = self._predefinedValues.index(inValue)
448            return self._descriptions[index]
449        return ""

특정 predefined value의 설명을 반환합니다.

Args: inValue: 설명을 가져올 값

Returns: 해당 값의 설명, 값이 존재하지 않으면 빈 문자열

def get_descriptions(self):
451    def get_descriptions(self):
452        """
453        모든 설명을 반환합니다.
454        
455        Returns:
456            설명 목록
457        """
458        return self._descriptions.copy()

모든 설명을 반환합니다.

Returns: 설명 목록

def get_value_by_description(self, inDescription):
460    def get_value_by_description(self, inDescription):
461        """
462        특정 설명에 해당하는 값을 반환합니다.
463        
464        Args:
465            inDescription: 찾을 설명
466            
467        Returns:
468            해당 설명의 값, 없으면 빈 문자열
469        """
470        if inDescription in self._descriptions:
471            index = self._descriptions.index(inDescription)
472            return self._predefinedValues[index]
473        return ""

특정 설명에 해당하는 값을 반환합니다.

Args: inDescription: 찾을 설명

Returns: 해당 설명의 값, 없으면 빈 문자열

def get_value_with_description(self, inIndex):
475    def get_value_with_description(self, inIndex):
476        """
477        지정된 인덱스의 값과 설명을 튜플로 반환합니다.
478        
479        Args:
480            inIndex: 값의 인덱스
481            
482        Returns:
483            (값, 설명) 튜플, 인덱스가 범위를 벗어나면 (None, None)
484        """
485        if 0 <= inIndex < len(self._predefinedValues):
486            return (self._predefinedValues[inIndex], self._descriptions[inIndex])
487        return (None, None)

지정된 인덱스의 값과 설명을 튜플로 반환합니다.

Args: inIndex: 값의 인덱스

Returns: (값, 설명) 튜플, 인덱스가 범위를 벗어나면 (None, None)

def get_values_with_descriptions(self):
489    def get_values_with_descriptions(self):
490        """
491        모든 값과 설명의 튜플 리스트를 반환합니다.
492        
493        Returns:
494            (값, 설명) 튜플의 리스트
495        """
496        return list(zip(self._predefinedValues, self._descriptions))

모든 값과 설명의 튜플 리스트를 반환합니다.

Returns: (값, 설명) 튜플의 리스트

def set_korean_description(self, inValue, inKoreanDescription):
500    def set_korean_description(self, inValue, inKoreanDescription):
501        """
502        특정 predefined value의 한국어 설명을 설정합니다.
503        
504        Args:
505            inValue: 설명을 설정할 값
506            inKoreanDescription: 설정할 한국어 설명
507            
508        Returns:
509            설정 성공 여부 (값이 존재하지 않는 경우 False)
510        """
511        if inValue in self._predefinedValues:
512            index = self._predefinedValues.index(inValue)
513            self._koreanDescriptions[index] = inKoreanDescription
514            return True
515        return False

특정 predefined value의 한국어 설명을 설정합니다.

Args: inValue: 설명을 설정할 값 inKoreanDescription: 설정할 한국어 설명

Returns: 설정 성공 여부 (값이 존재하지 않는 경우 False)

def get_korean_description_by_value(self, inValue):
517    def get_korean_description_by_value(self, inValue):
518        """
519        특정 predefined value의 한국어 설명을 반환합니다.
520        
521        Args:
522            inValue: 설명을 가져올 값
523            
524        Returns:
525            해당 값의 한국어 설명, 값이 존재하지 않으면 빈 문자열
526        """
527        if inValue in self._predefinedValues:
528            index = self._predefinedValues.index(inValue)
529            return self._koreanDescriptions[index]
530        return ""

특정 predefined value의 한국어 설명을 반환합니다.

Args: inValue: 설명을 가져올 값

Returns: 해당 값의 한국어 설명, 값이 존재하지 않으면 빈 문자열

def get_korean_descriptions(self):
532    def get_korean_descriptions(self):
533        """
534        모든 한국어 설명을 반환합니다.
535        
536        Returns:
537            한국어 설명 목록
538        """
539        return self._koreanDescriptions.copy()

모든 한국어 설명을 반환합니다.

Returns: 한국어 설명 목록

def get_value_by_korean_description(self, inKoreanDescription):
541    def get_value_by_korean_description(self, inKoreanDescription):
542        """
543        특정 한국어 설명에 해당하는 값을 반환합니다.
544        
545        Args:
546            inKoreanDescription: 찾을 한국어 설명
547            
548        Returns:
549            해당 설명의 값, 없으면 빈 문자열
550        """
551        if inKoreanDescription in self._koreanDescriptions:
552            index = self._koreanDescriptions.index(inKoreanDescription)
553            return self._predefinedValues[index]
554        return ""

특정 한국어 설명에 해당하는 값을 반환합니다.

Args: inKoreanDescription: 찾을 한국어 설명

Returns: 해당 설명의 값, 없으면 빈 문자열

def get_value_with_korean_description(self, inIndex):
556    def get_value_with_korean_description(self, inIndex):
557        """
558        지정된 인덱스의 값과 한국어 설명을 튜플로 반환합니다.
559        
560        Args:
561            inIndex: 값의 인덱스
562            
563        Returns:
564            (값, 한국어 설명) 튜플, 인덱스가 범위를 벗어나면 (None, None)
565        """
566        if 0 <= inIndex < len(self._predefinedValues):
567            return (self._predefinedValues[inIndex], self._koreanDescriptions[inIndex])
568        return (None, None)

지정된 인덱스의 값과 한국어 설명을 튜플로 반환합니다.

Args: inIndex: 값의 인덱스

Returns: (값, 한국어 설명) 튜플, 인덱스가 범위를 벗어나면 (None, None)

def get_values_with_korean_descriptions(self):
570    def get_values_with_korean_descriptions(self):
571        """
572        모든 값과 한국어 설명의 튜플 리스트를 반환합니다.
573        
574        Returns:
575            (값, 한국어 설명) 튜플의 리스트
576        """
577        return list(zip(self._predefinedValues, self._koreanDescriptions))

모든 값과 한국어 설명의 튜플 리스트를 반환합니다.

Returns: (값, 한국어 설명) 튜플의 리스트

def is_direction(self):
579    def is_direction(self):
580        """
581        방향성 여부를 반환합니다.
582        
583        Returns:
584            방향성 여부 (True/False)
585        """
586        return self._isDirection

방향성 여부를 반환합니다.

Returns: 방향성 여부 (True/False)

def to_dict(self):
588    def to_dict(self):
589        """
590        NamePart 객체를 사전 형태로 변환합니다.
591        
592        Returns:
593            사전 형태의 NamePart 정보
594        """
595        return {
596            "name": self._name,
597            "predefinedValues": self._predefinedValues.copy(),
598            "weights": self._weights.copy(),  # 가중치를 리스트 형태로 직접 전달
599            "type": self._type.name if hasattr(self._type, 'name') else str(self._type),
600            "descriptions": self._descriptions.copy(),
601            "koreanDescriptions": self._koreanDescriptions.copy(), # Add korean descriptions
602            "isDirection": self._isDirection
603        }

NamePart 객체를 사전 형태로 변환합니다.

Returns: 사전 형태의 NamePart 정보

@staticmethod
def from_dict(inData):
605    @staticmethod
606    def from_dict(inData):
607        """
608        사전 형태의 데이터로부터 NamePart 객체를 생성합니다.
609        
610        Args:
611            inData: 사전 형태의 NamePart 정보
612            
613        Returns:
614            NamePart 객체
615        """
616        if isinstance(inData, dict) and "name" in inData:
617            # 타입 변환 (문자열 -> NamePartType 열거형)
618            type_str = inData.get("type", "UNDEFINED")
619            try:
620                part_type = NamePartType[type_str] if isinstance(type_str, str) else NamePartType.UNDEFINED
621            except KeyError:
622                part_type = NamePartType.UNDEFINED
623                
624            result = NamePart(
625                inData["name"],
626                part_type,  # 두 번째 인자로 타입 전달
627                inData.get("predefinedValues", []),  # 세 번째 인자로 predefinedValues 전달
628                inData.get("descriptions", []),  # 네 번째 인자로 descriptions 전달
629                inData.get("isDirection", False),  # 다섯 번째 인자로 isDirection 전달
630                inData.get("koreanDescriptions", []) # 여섯 번째 인자로 koreanDescriptions 전달
631            )
632            
633            return result
634        return NamePart()

사전 형태의 데이터로부터 NamePart 객체를 생성합니다.

Args: inData: 사전 형태의 NamePart 정보

Returns: NamePart 객체