pyjallib.naming API documentation

# pyjallib.naming

Naming 모듈 - 이름 규칙 관리 및 적용 기능 제공 NamePart 객체를 기반으로 조직화된 이름 생성 및 분석 기능 구현

View Source

       1#!/usr/bin/env python
       2# -*- coding: utf-8 -*-
       3
       4"""
       5Naming 모듈 - 이름 규칙 관리 및 적용 기능 제공
       6NamePart 객체를 기반으로 조직화된 이름 생성 및 분석 기능 구현
       7"""
       8
       9import os
      10import re
      11from dataclasses import dataclass
      12from typing import List, Dict, Any, Optional, Union, Tuple
      13
      14# NamePart와 NamingConfig 임포트
      15from pyjallib.namePart import NamePart, NamePartType
      16from pyjallib.namingConfig import NamingConfig
      17
      18class Naming:
      19    """
      20    노드 이름을 관리하기 위한 기본 클래스.
      21    기본적인 이름 구성 요소를 정의하고 관리합니다.
      22    이 클래스는 하위 클래스에서 확장하여 특정 목적에 맞게 사용할 수 있습니다.
      23    """
      24
      25    def __init__(self, configPath=None):
      26        """
      27        클래스 초기화 및 기본 설정값 정의
      28
      29        Args:
      30            configPath: 설정 파일 경로 (기본값: None)
      31                        설정 파일이 제공되면 해당 파일에서 설정을 로드함
      32        """
      33        # 기본 설정값
      34        self._paddingNum = 2
      35        self._configPath = configPath
      36
      37        # 기본 namePart 초기화 (각 부분에 사전 정의 값 직접 설정)
      38        self._nameParts = []
      39
      40        # Prefix 부분 (PREFIX 타입)
      41        prefixPart = NamePart("Prefix", NamePartType.PREFIX, ["Pr"], ["Prefix"])
      42
      43        # RealName 부분 (REALNAME 타입)
      44        realNamePart = NamePart("RealName", NamePartType.REALNAME, [], [])
      45
      46        # Index 부분 (INDEX 타입)
      47        indexPart = NamePart("Index", NamePartType.INDEX, [], [])
      48
      49        # Suffix 부분 (SUFFIX 타입)
      50        suffixPart = NamePart("Suffix", NamePartType.SUFFIX, ["Su"], ["Suffix"])
      51
      52        # 기본 순서대로 설정
      53        self._nameParts = [prefixPart, realNamePart, indexPart, suffixPart]
      54
      55        # 설정 파일이 제공된 경우 로드
      56        if configPath:
      57            self.load_from_config_file(configPath)
      58        else:
      59            # 기본 JSON 설정 파일 로드 시도
      60            self.load_default_config()
      61
      62    # ---- String 관련 메소드들 (내부 사용 헬퍼 메소드) ----
      63
      64    def _split_into_string_and_digit(self, inStr):
      65        """
      66        문자열을 문자부분과 숫자부분으로 분리
      67
      68        Args:
      69            inStr: 분리할 문자열
      70
      71        Returns:
      72            튜플 (문자부분, 숫자부분)
      73        """
      74        match = re.match(r'^(.*?)(\d*)$', inStr)
      75        if match:
      76            return match.group(1), match.group(2)
      77        return inStr, ""
      78
      79    def _compare_string(self, inStr1, inStr2):
      80        """
      81        대소문자 구분 없이 문자열 비교
      82
      83        Args:
      84            inStr1: 첫 번째 문자열
      85            inStr2: 두 번째 문자열
      86
      87        Returns:
      88            비교 결과 (inStr1 < inStr2: 음수, inStr1 == inStr2: 0, inStr1 > inStr2: 양수)
      89        """
      90        # Python에서는 대소문자 구분 없는 비교를 위해 lower() 메서드 사용
      91        if inStr1.lower() < inStr2.lower():
      92            return -1
      93        elif inStr1.lower() > inStr2.lower():
      94            return 1
      95        return 0
      96
      97    def _sort_by_alphabet(self, inArray):
      98        """
      99        배열 내 문자열을 알파벳 순으로 정렬
     100
     101        Args:
     102            inArray: 정렬할 배열
     103
     104        Returns:
     105            정렬된 배열
     106        """
     107        # Python의 sorted 함수와 lambda를 사용하여 대소문자 구분 없이 정렬
     108        return sorted(inArray, key=lambda x: x.lower())
     109
     110    def _get_filtering_char(self, inStr):
     111        """
     112        문자열에서 사용된 구분자 문자 찾기
     113
     114        Args:
     115            inStr: 확인할 문자열
     116
     117        Returns:
     118            구분자 문자 (' ' 또는 '_' 또는 '')
     119        """
     120        if ' ' in inStr:
     121            return ' '
     122        if '_' in inStr:
     123            return '_'
     124        return ''
     125
     126    def _filter_by_filtering_char(self, inStr):
     127        """
     128        구분자 문자로 문자열 분할
     129
     130        Args:
     131            inStr: 분할할 문자열
     132
     133        Returns:
     134            분할된 문자열 리스트
     135        """
     136        filChar = self._get_filtering_char(inStr)
     137
     138        if not filChar:
     139            return [inStr]
     140
     141        # 빈 문자열 제거하며 분할
     142        return [part for part in inStr.split(filChar) if part]
     143
     144    def _filter_by_upper_case(self, inStr):
     145        """
     146        대문자로 시작하는 부분을 기준으로 문자열 분할
     147
     148        Args:
     149            inStr: 분할할 문자열
     150
     151        Returns:
     152            분할된 문자열 리스트
     153        """
     154        if not inStr:
     155            return []
     156
     157        result = []
     158        currentPart = inStr[0]
     159
     160        for i in range(1, len(inStr)):
     161            if inStr[i].isupper():
     162                result.append(currentPart)
     163                currentPart = inStr[i]
     164            else:
     165                currentPart += inStr[i]
     166
     167        if currentPart:
     168            result.append(currentPart)
     169
     170        return result
     171
     172    def _has_digit(self, inStr):
     173        """
     174        문자열에 숫자가 포함되어 있는지 확인
     175
     176        Args:
     177            inStr: 확인할 문자열
     178
     179        Returns:
     180            숫자가 포함되어 있으면 True, 아니면 False
     181        """
     182        return any(char.isdigit() for char in inStr)
     183
     184    def _split_to_array(self, inStr):
     185        """
     186        문자열을 구분자 또는 대문자로 분할하고 숫자 부분도 분리
     187
     188        Args:
     189            inStr: 분할할 문자열
     190
     191        Returns:
     192            분할된 문자열 리스트
     193        """
     194        filChar = self._get_filtering_char(inStr)
     195
     196        if not filChar:
     197            # 구분자가 없을 경우 대문자로 분할
     198            resultArray = self._filter_by_upper_case(inStr)
     199            tempArray = []
     200
     201            for item in resultArray:
     202                if self._has_digit(item):
     203                    stringPart, digitPart = self._split_into_string_and_digit(item)
     204                    if stringPart:
     205                        tempArray.append(stringPart)
     206                    if digitPart:
     207                        tempArray.append(digitPart)
     208                else:
     209                    tempArray.append(item)
     210
     211            return tempArray
     212        else:
     213            # 구분자가 있을 경우 구분자로 분할
     214            return self._filter_by_filtering_char(inStr)
     215
     216    def _remove_empty_string_in_array(self, inArray):
     217        """
     218        배열에서 빈 문자열 제거
     219
     220        Args:
     221            inArray: 처리할 배열
     222
     223        Returns:
     224            빈 문자열이 제거된 배열
     225        """
     226        return [item for item in inArray if item]
     227
     228    def _combine(self, inArray, inFilChar=" "):
     229        """
     230        문자열 배열을 하나의 문자열로 결합
     231
     232        Args:
     233            inArray: 결합할 문자열 배열
     234            filChar: 구분자 (기본값: 공백)
     235
     236        Returns:
     237            결합된 문자열
     238        """
     239        refinedArray = self._remove_empty_string_in_array(inArray)
     240
     241        if not refinedArray:
     242            return ""
     243
     244        if len(refinedArray) == 1:
     245            return refinedArray[0]
     246
     247        return inFilChar.join(refinedArray)
     248
     249    # ---- Name 관련 메서드들 ----
     250
     251    # 사전 정의 값 편집 메서드 제거 (namingConfig를 통해서만 변경 가능)
     252
     253    def get_padding_num(self):
     254        """
     255        패딩 숫자 가져오기
     256
     257        Returns:
     258            패딩 숫자
     259        """
     260        return self._paddingNum
     261
     262    def get_name_part(self, inNamePartName):
     263        """
     264        namePart 이름으로 NamePart 객체 가져오기
     265
     266        Args:
     267            namePart: 가져올 NamePart의 이름 ("Prefix", "RealName", "Suffix", "Index" 등)
     268
     269        Returns:
     270            해당 NamePart 객체, 존재하지 않으면 None
     271        """
     272        for part in self._nameParts:
     273            if part.get_name() == inNamePartName:
     274                return part
     275        return None
     276
     277    def get_name_part_index(self, inNamePartName):
     278        """
     279        namePart 이름으로 인덱스 가져오기
     280
     281        Args:
     282            namePart: 가져올 NamePart의 이름 ("Prefix", "RealName", "Suffix", "Index" 등)
     283
     284        Returns:
     285            해당 NamePart의 인덱스, 존재하지 않으면 -1
     286        """
     287        for i, part in enumerate(self._nameParts):
     288            if part.get_name() == inNamePartName:
     289                return i
     290        return -1
     291
     292    def get_name_part_predefined_values(self, inNamePartName):
     293        """
     294        namePart의 사전 정의 값 가져오기
     295
     296        Args:
     297            namePart: 가져올 NamePart의 이름 ("Prefix", "RealName", "Suffix", "Index" 등)
     298
     299        Returns:
     300            해당 NamePart의 사전 정의 값 리스트, 존재하지 않으면 빈 리스트
     301        """
     302        partObj = self.get_name_part(inNamePartName)
     303        if partObj:
     304            return partObj.get_predefined_values()
     305        return []
     306
     307    def is_in_name_part_predefined_values(self, inNamePartName, inStr):
     308        """
     309        지정된 namePart에 해당하는 부분이 문자열에 포함되어 있는지 확인
     310
     311        Args:
     312            namePart: 확인할 namePart 이름 ("Base", "Type", "Side" 등)
     313            inStr: 확인할 문자열
     314
     315        Returns:
     316            포함되어 있으면 True, 아니면 False
     317        """
     318        partObj = self.get_name_part(inNamePartName)
     319        if not partObj:
     320            return False
     321
     322        partType = partObj.get_type()
     323        if not partType:
     324            return False
     325
     326        partValues = partObj.get_predefined_values()
     327
     328        if partType == NamePartType.PREFIX or partType == NamePartType.SUFFIX:
     329            return any(item in inStr for item in partValues)
     330
     331        return False
     332
     333    def get_name_part_value_by_description(self, inNamePartName, inDescription):
     334        """
     335        지정된 namePart에 해당하는 부분을 문자열에서 추출
     336
     337        Args:
     338            namePart: 추출할 namePart 이름 ("Base", "Type", "Side" 등)
     339            inDescription: predefined value에서 찾기위한 description 문자열
     340
     341        Returns:
     342            지정된 namePart에 해당하는 문자열
     343        """
     344        partObj = self.get_name_part(inNamePartName)
     345        if not partObj:
     346            return ""
     347
     348        partType = partObj.get_type()
     349        if not partType:
     350            return ""
     351
     352        partValues = partObj.get_predefined_values()
     353
     354        if partType == NamePartType.PREFIX or partType == NamePartType.SUFFIX:
     355            try:
     356                foundIndex = partObj._descriptions.index(inDescription)
     357                return partValues[foundIndex]
     358            except ValueError:
     359                # Description not found in the list
     360                return ""
     361
     362    def pick_name(self, inNamePartName, inStr):
     363        nameArray = self._split_to_array(inStr)
     364        returnStr = ""
     365
     366        # namePart 문자열 목록 가져오기
     367        partObj = self.get_name_part(inNamePartName)
     368        if not partObj:
     369            return returnStr
     370
     371        partType = partObj.get_type()
     372        if not partType:
     373            return returnStr
     374
     375        partValues = partObj.get_predefined_values()
     376        if partType != NamePartType.INDEX and partType != NamePartType.REALNAME and not partValues:
     377            return returnStr
     378
     379        if partType == NamePartType.PREFIX:
     380            for item in nameArray:
     381                if item in partValues:
     382                    returnStr = item
     383                    break
     384
     385        if partType == NamePartType.SUFFIX:
     386            for i in range(len(nameArray) - 1, -1, -1):
     387                if nameArray[i] in partValues:
     388                    returnStr = nameArray[i]
     389                    break
     390
     391        if partType == NamePartType.INDEX:
     392            if self.get_name_part_index("Index") > self.get_name_part_index("RealName"):
     393                for i in range(len(nameArray) - 1, -1, -1):
     394                    if nameArray[i].isdigit():
     395                        returnStr = nameArray[i]
     396                        break
     397            else:
     398                for item in nameArray:
     399                    if item.isdigit():
     400                        returnStr = item
     401                        break
     402
     403        return returnStr
     404
     405    def get_name(self, inNamePartName, inStr):
     406        """
     407        지정된 namePart에 해당하는 부분을 문자열에서 추출
     408
     409        Args:
     410            namePart: 추출할 namePart 이름 ("Base", "Type", "Side" 등)
     411            inStr: 처리할 문자열
     412
     413        Returns:
     414            지정된 namePart에 해당하는 문자열
     415        """
     416        nameArray = self._split_to_array(inStr)
     417        returnStr = ""
     418
     419        partType = self.get_name_part(inNamePartName).get_type()
     420
     421        foundName = self.pick_name(inNamePartName, inStr)
     422        if foundName == "":
     423            return returnStr
     424        partIndex = self.get_name_part_index(inNamePartName)
     425        foundIndex = nameArray.index(foundName)
     426
     427        if partType == NamePartType.PREFIX:
     428            if foundIndex >= 0:
     429                prevNameParts = self._nameParts[:partIndex]
     430                prevNames = [self.pick_name(part.get_name(), inStr) for part in prevNameParts]
     431                prevNamesInNameArray = nameArray[:foundIndex]
     432                for prevName in prevNames:
     433                    if prevName in prevNamesInNameArray:
     434                        prevNamesInNameArray.remove(prevName)
     435                if len(prevNamesInNameArray) == 0 :
     436                    returnStr = foundName
     437
     438        if partType == NamePartType.SUFFIX:
     439            if foundIndex >= 0:
     440                nextNameParts = self._nameParts[partIndex + 1:]
     441                nextNames = [self.pick_name(part.get_name(), inStr) for part in nextNameParts]
     442                nextNamesInNameArray = nameArray[foundIndex + 1:]
     443                for nextName in nextNames:
     444                    if nextName in nextNamesInNameArray:
     445                        nextNamesInNameArray.remove(nextName)
     446                if len(nextNamesInNameArray) == 0 :
     447                    returnStr = foundName
     448
     449        if partType == NamePartType.INDEX:
     450            returnStr = self.pick_name(inNamePartName, inStr)
     451
     452        return returnStr
     453
     454    def combine(self, inPartsDict={}, inFilChar=" "):
     455        """
     456        namingConfig에서 정의된 nameParts와 그 순서에 따라 이름 부분들을 조합하여 완전한 이름 생성
     457
     458        Args:
     459            parts_dict: namePart 이름과 값의 딕셔너리 (예: {"Base": "b", "Type": "P", "Side": "L"})
     460            inFilChar: 구분자 문자 (기본값: " ")
     461
     462        Returns:
     463            조합된 이름 문자열
     464        """
     465        # 결과 배열 초기화 (빈 문자열로)
     466        combinedNameArray = [""] * len(self._nameParts)
     467
     468        # 각 namePart에 대해
     469        for i, part in enumerate(self._nameParts):
     470            partName = part.get_name()
     471            # 딕셔너리에서 해당 부분의 값 가져오기 (없으면 빈 문자열 사용)
     472            if partName in inPartsDict:
     473                combinedNameArray[i] = inPartsDict[partName]
     474
     475        # 배열을 문자열로 결합
     476        newName = self._combine(combinedNameArray, inFilChar)
     477        newName = self.set_index_padding_num(newName)
     478        return newName
     479
     480    def get_RealName(self, inStr):
     481        """
     482        문자열에서 실제 이름 부분 추출
     483
     484        Args:
     485            inStr: 처리할 문자열
     486
     487        Returns:
     488            실제 이름 부분 문자열
     489        """
     490        filChar = self._get_filtering_char(inStr)
     491        nameArray = self._split_to_array(inStr)
     492
     493        # 모든 nameParts 중 RealName이 아닌 것들의 값을 수집
     494        nonRealNameArray = []
     495        for part in self._nameParts:
     496            partName = part.get_name()
     497            partType = part.get_type()
     498            if partType != NamePartType.REALNAME:
     499                foundName = self.get_name(partName, inStr)
     500                nonRealNameArray.append(foundName)
     501
     502        for item in nonRealNameArray:
     503            if item in nameArray:
     504                nameArray.remove(item)
     505
     506        # 구분자로 결합
     507        return self._combine(nameArray, filChar)
     508
     509    def get_non_RealName(self, inStr):
     510        """
     511        실제 이름 부분을 제외한 이름 가져오기
     512
     513        Args:
     514            inStr: 처리할 이름 문자열
     515
     516        Returns:
     517            실제 이름이 제외된 이름 문자열
     518        """
     519        filChar = self._get_filtering_char(inStr)
     520
     521        # 모든 nameParts 중 RealName이 아닌 것들의 값을 수집
     522        nonRealNameArray = []
     523        for part in self._nameParts:
     524            partName = part.get_name()
     525            partType = part.get_type()
     526            if partType != NamePartType.REALNAME:
     527                foundName = self.get_name(partName, inStr)
     528                nonRealNameArray.append(foundName)
     529
     530        return self._combine(nonRealNameArray, filChar)
     531
     532    def convert_name_to_array(self, inStr):
     533        """
     534        문자열 이름을 이름 부분 배열로 변환
     535
     536        Args:
     537            inStr: 변환할 이름 문자열
     538
     539        Returns:
     540            이름 부분 배열 (Base, Type, Side, FrontBack, RealName, Index, Nub 등)
     541        """
     542        returnArray = [""] * len(self._nameParts)
     543
     544        # 각 namePart에 대해 처리
     545        for i, part in enumerate(self._nameParts):
     546            partName = part.get_name()
     547
     548            # 특수 케이스인 RealName은 마지막에 처리하기 위해 저장
     549            if partName == "RealName":
     550                realNameIndex = i
     551                continue
     552
     553            # get_name 메소드를 사용하여 해당 부분 추출
     554            partValue = self.get_name(partName, inStr)
     555            returnArray[i] = partValue
     556
     557        # 마지막으로 RealName 처리 (다른 모든 부분을 찾은 후에 수행해야 함)
     558        if 'realNameIndex' in locals():
     559            realNameStr = self.get_RealName(inStr)
     560            returnArray[realNameIndex] = realNameStr
     561
     562        return returnArray
     563
     564    def convert_to_dictionary(self, inStr):
     565        """
     566        문자열 이름을 이름 부분 딕셔너리로 변환
     567
     568        Args:
     569            inStr: 변환할 이름 문자열
     570
     571        Returns:
     572            이름 부분 딕셔너리 (키: namePart 이름, 값: 추출된 값)
     573            예: {"Base": "b", "Type": "P", "Side": "L", "RealName": "Arm", ...}
     574        """
     575        returnDict = {}
     576
     577        # 각 namePart에 대해 처리
     578        for part in self._nameParts:
     579            partName = part.get_name()
     580
     581            # 특수 케이스인 RealName은 마지막에 처리하기 위해 저장
     582            if partName == "RealName":
     583                continue
     584
     585            # get_name 메소드를 사용하여 해당 부분 추출
     586            partValue = self.get_name(partName, inStr)
     587            returnDict[partName] = partValue
     588
     589        # 마지막으로 RealName 처리 (다른 모든 부분을 찾은 후에 수행해야 함)
     590        realNameStr = self.get_RealName(inStr)
     591        returnDict["RealName"] = realNameStr
     592
     593        return returnDict
     594
     595    def convert_to_description(self, inStr):
     596        """
     597        문자열 이름을 설명으로 변환
     598
     599        Args:
     600            inStr: 변환할 이름 문자열
     601
     602        Returns:
     603            설명 문자열 (예: "b_P_L_Arm")
     604        """
     605        nameDic = self.convert_to_dictionary(inStr)
     606        descriptionDic = {}
     607        filteringChar = self._get_filtering_char(inStr)
     608        descName = inStr
     609        if nameDic:
     610            for namePartName, value in nameDic.items():
     611                namePart = self.get_name_part(namePartName)
     612                desc = namePart.get_description_by_value(value)
     613
     614                if desc == "" and value != "":
     615                    desc = value
     616
     617                descriptionDic[namePartName] = desc # Store in dictionary for later use
     618
     619            descName = self.combine(descriptionDic, filteringChar)
     620
     621        return descName
     622
     623    def convert_to_korean_description(self, inStr):
     624        """
     625        문자열 이름을 한국어 설명으로 변환
     626
     627        Args:
     628            inStr: 변환할 이름 문자열
     629
     630        Returns:
     631            한국어 설명 문자열 (예: "팔_왼쪽_팔")
     632        """
     633        nameDic = self.convert_to_dictionary(inStr)
     634        korDescDic = {}
     635        filteringChar = self._get_filtering_char(inStr)
     636        korDescName = inStr
     637        if nameDic:
     638            for namePartName, value in nameDic.items():
     639                namePart = self.get_name_part(namePartName)
     640                desc = namePart.get_description_by_value(value)
     641                korDesc = namePart.get_korean_description_by_value(value)
     642
     643                if korDesc == "" and desc != "":
     644                    korDesc = desc
     645
     646                korDescDic[namePartName] = korDesc # Store in dictionary for later use
     647
     648            korDescName = self.combine(korDescDic, filteringChar)
     649
     650        return korDescName
     651
     652    def has_name_part(self, inPart, inStr):
     653        """
     654        문자열에 특정 namePart가 포함되어 있는지 확인
     655
     656        Args:
     657            inPart: 확인할 namePart 이름 ("Base", "Type", "Side", "FrontBack", "RealName", "Index")
     658            inStr: 확인할 문자열
     659
     660        Returns:
     661            포함되어 있으면 True, 아니면 False
     662        """
     663        return self.get_name(inPart, inStr) != ""
     664
     665    def add_prefix_to_name_part(self, inPart, inStr, inPrefix):
     666        """
     667        이름의 특정 부분에 접두사 추가
     668
     669        Args:
     670            inPart: 수정할 부분 ("Base", "Type", "Side", "FrontBack", "RealName", "Index")
     671            inStr: 처리할 이름 문자열
     672            inPrefix: 추가할 접두사
     673
     674        Returns:
     675            수정된 이름 문자열
     676        """
     677        returnStr = inStr
     678
     679        if inPrefix:
     680            filChar = self._get_filtering_char(inStr)
     681            nameArray = self.convert_name_to_array(inStr)
     682            partIndex = self.get_name_part_index(inPart)
     683
     684            nameArray[partIndex] = inPrefix + nameArray[partIndex]
     685
     686            returnStr = self._combine(nameArray, filChar)
     687
     688        return returnStr
     689
     690    def add_suffix_to_name_part(self, inPart, inStr, inSuffix):
     691        """
     692        이름의 특정 부분에 접미사 추가
     693
     694        Args:
     695            inPart: 수정할 부분 ("Base", "Type", "Side", "FrontBack", "RealName", "Index")
     696            inStr: 처리할 이름 문자열
     697            inSuffix: 추가할 접미사
     698
     699        Returns:
     700            수정된 이름 문자열
     701        """
     702        returnStr = inStr
     703
     704        if inSuffix:
     705            filChar = self._get_filtering_char(inStr)
     706            nameArray = self.convert_name_to_array(inStr)
     707            partIndex = self.get_name_part_index(inPart)
     708
     709            nameArray[partIndex] = nameArray[partIndex] + inSuffix
     710
     711            returnStr = self._combine(nameArray, filChar)
     712
     713        return returnStr
     714
     715    def add_prefix_to_real_name(self, inStr, inPrefix):
     716        """
     717        실제 이름 부분에 접두사 추가
     718
     719        Args:
     720            inStr: 처리할 이름 문자열
     721            inPrefix: 추가할 접두사
     722
     723        Returns:
     724            수정된 이름 문자열
     725        """
     726        return self.add_prefix_to_name_part("RealName", inStr, inPrefix)
     727
     728    def add_suffix_to_real_name(self, inStr, inSuffix):
     729        """
     730        실제 이름 부분에 접미사 추가
     731
     732        Args:
     733            inStr: 처리할 이름 문자열
     734            inSuffix: 추가할 접미사
     735
     736        Returns:
     737            수정된 이름 문자열
     738        """
     739        return self.add_suffix_to_name_part("RealName", inStr, inSuffix)
     740
     741    def convert_digit_into_padding_string(self, inDigit, inPaddingNum=None):
     742        """
     743        숫자를 패딩된 문자열로 변환
     744
     745        Args:
     746            inDigit: 변환할 숫자 또는 숫자 문자열
     747            inPaddingNum: 패딩 자릿수 (기본값: 클래스의 _paddingNum)
     748
     749        Returns:
     750            패딩된 문자열
     751        """
     752        if inPaddingNum is None:
     753            inPaddingNum = self._paddingNum
     754
     755        digitNum = 0
     756
     757        if isinstance(inDigit, int):
     758            digitNum = inDigit
     759        elif isinstance(inDigit, str):
     760            if inDigit.isdigit():
     761                digitNum = int(inDigit)
     762
     763        # Python의 문자열 포맷팅을 사용하여 패딩
     764        return f"{digitNum:0{inPaddingNum}d}"
     765
     766    def set_index_padding_num(self, inStr, inPaddingNum=None):
     767        """
     768        이름의 인덱스 부분 패딩 설정
     769
     770        Args:
     771            inStr: 처리할 이름 문자열
     772            inPaddingNum: 설정할 패딩 자릿수 (기본값: 클래스의 _paddingNum)
     773
     774        Returns:
     775            패딩이 적용된 이름 문자열
     776        """
     777        if inPaddingNum is None:
     778            inPaddingNum = self._paddingNum
     779
     780        filChar = self._get_filtering_char(inStr)
     781        nameArray = self.convert_name_to_array(inStr)
     782        indexIndex = self.get_name_part_index("Index")
     783        indexStr = self.get_name("Index", inStr)
     784
     785        if indexStr:
     786            indexStr = self.convert_digit_into_padding_string(indexStr, inPaddingNum)
     787            nameArray[indexIndex] = indexStr
     788
     789        return self._combine(nameArray, filChar)
     790
     791    def get_index_padding_num(self, inStr):
     792        """
     793        이름의 인덱스 부분 패딩 자릿수 가져오기
     794
     795        Args:
     796            inStr: 처리할 이름 문자열
     797
     798        Returns:
     799            인덱스 패딩 자릿수
     800        """
     801        indexVal = self.get_name("Index", inStr)
     802
     803        if indexVal:
     804            return len(indexVal)
     805
     806        return 1
     807
     808    def increase_index(self, inStr, inAmount):
     809        """
     810        이름의 인덱스 부분 값 증가
     811
     812        Args:
     813            inStr: 처리할 이름 문자열
     814            inAmount: 증가시킬 값
     815
     816        Returns:
     817            인덱스가 증가된 이름 문자열
     818        """
     819        newName = inStr
     820        filChar = self._get_filtering_char(inStr)
     821        nameArray = self.convert_name_to_array(inStr)
     822        indexIndex = self.get_name_part_index("Index")
     823
     824        if indexIndex >= 0:
     825            indexStr = ""
     826            indexPaddingNum = self._paddingNum
     827            indexNum = -99999
     828
     829            if not nameArray[indexIndex]:
     830                indexNum = -1
     831            else:
     832                try:
     833                    indexNum = int(nameArray[indexIndex])
     834                    indexPaddingNum = len(nameArray[indexIndex])
     835                except ValueError:
     836                    pass
     837
     838            indexNum += inAmount
     839
     840            if indexNum < 0:
     841                indexNum = 0
     842
     843            # Python의 문자열 포맷팅을 사용하여 패딩
     844            indexStr = f"{indexNum:0{indexPaddingNum}d}"
     845            nameArray[indexIndex] = indexStr
     846            newName = self._combine(nameArray, filChar)
     847            newName = self.set_index_padding_num(newName)
     848
     849        return newName
     850
     851    def get_index_as_digit(self, inStr):
     852        """
     853        이름의 인덱스를 숫자로 변환
     854
     855        Args:
     856            inStr: 변환할 이름 문자열
     857
     858        Returns:
     859            숫자로 변환된 인덱스 (넙이 있으면 -1, 인덱스가 없으면 False)
     860        """
     861        indexStr = self.get_name("Index", inStr)
     862
     863        if indexStr:
     864            try:
     865                return int(indexStr)
     866            except ValueError:
     867                pass
     868
     869        return False
     870
     871    def sort_by_index(self, inNameArray):
     872        """
     873        이름 배열을 인덱스 기준으로 정렬
     874
     875        Args:
     876            inNameArray: 정렬할 이름 배열
     877
     878        Returns:
     879            인덱스 기준으로 정렬된 이름 배열
     880        """
     881        if not inNameArray:
     882            return []
     883
     884        # 정렬을 위한 보조 클래스 정의
     885        @dataclass
     886        class IndexSorting:
     887            oriIndex: int
     888            newIndex: int
     889
     890        # 각 이름의 인덱스를 추출하여 정렬 정보 생성
     891        structArray = []
     892
     893        for i, name in enumerate(inNameArray):
     894            tempIndex = self.get_index_as_digit(name)
     895
     896            if tempIndex is False:
     897                structArray.append(IndexSorting(i, 0))
     898            else:
     899                structArray.append(IndexSorting(i, tempIndex))
     900
     901        # 인덱스 기준으로 정렬
     902        structArray.sort(key=lambda x: x.newIndex)
     903
     904        # 정렬된 순서로 결과 배열 생성
     905        sortedNameArray = []
     906        for struct in structArray:
     907            sortedNameArray.append(inNameArray[struct.oriIndex])
     908
     909        return sortedNameArray
     910
     911    def get_string(self, inStr):
     912        """
     913        인덱스 부분을 제외한 이름 문자열 가져오기
     914
     915        Args:
     916            inStr: 처리할 이름 문자열
     917
     918        Returns:
     919            인덱스가 제외된 이름 문자열
     920        """
     921        filChar = self._get_filtering_char(inStr)
     922        nameArray = self.convert_name_to_array(inStr)
     923        indexOrder = self.get_name_part_index("Index")
     924
     925        # 인덱스 부분 제거
     926        returnNameArray = nameArray.copy()
     927        returnNameArray[indexOrder] = ""
     928
     929        return self._combine(returnNameArray, filChar)
     930
     931    def gen_mirroring_name(self, inStr):
     932        """
     933        미러링된 이름 생성 (측면 또는 앞/뒤 변경)
     934
     935        이름에서 Side와 FrontBack namePart를 자동으로 검색하고,
     936        발견된 값의 semanticmapping weight와 가장 차이가 큰 값으로 교체합니다.
     937
     938        Args:
     939            inStr: 처리할 이름 문자열
     940
     941        Returns:
     942            미러링된 이름 문자열
     943        """
     944        nameArray = self.convert_name_to_array(inStr)
     945
     946        for part in self._nameParts:
     947            partName = part.get_name()
     948            partType = part.get_type()
     949            if (partType != NamePartType.REALNAME or partType != NamePartType.INDEX) and part.is_direction():
     950                partIndex = self.get_name_part_index(partName)
     951                foundName = self.get_name(partName, inStr)
     952                opositeName = part.get_most_different_weight_value(foundName)
     953                if opositeName and foundName != opositeName:
     954                    nameArray[partIndex] = opositeName
     955
     956        returnName = self._combine(nameArray, self._get_filtering_char(inStr))
     957
     958        return returnName
     959
     960    def replace_filtering_char(self, inStr, inNewFilChar):
     961        """
     962        이름의 구분자 문자 변경
     963
     964        Args:
     965            inStr: 처리할 이름 문자열
     966            inNewFilChar: 새 구분자 문자
     967
     968        Returns:
     969            구분자가 변경된 이름 문자열
     970        """
     971        nameArray = self.convert_name_to_array(inStr)
     972        return self._combine(nameArray, inNewFilChar)
     973
     974    def replace_name_part(self, inPart, inStr, inNewName):
     975        """
     976        이름의 특정 부분을 새 이름으로 변경
     977
     978        Args:
     979            inPart: 수정할 부분 ("Base", "Type", "Side", "FrontBack", "RealName", "Index")
     980            inStr: 처리할 이름 문자열
     981            inNewName: 새 이름
     982
     983        Returns:
     984            수정된 이름 문자열
     985        """
     986        nameArray = self.convert_name_to_array(inStr)
     987        partIndex = self.get_name_part_index(inPart)
     988
     989        if partIndex >= 0:
     990            nameArray[partIndex] = inNewName
     991
     992        newName = self._combine(nameArray, self._get_filtering_char(inStr))
     993        newName = self.set_index_padding_num(newName)
     994
     995        return newName
     996
     997    def remove_name_part(self, inPart, inStr):
     998        """
     999        이름의 특정 부분 제거
    1000
    1001        Args:
    1002            inPart: 제거할 부분 ("Base", "Type", "Side", "FrontBack", "RealName", "Index")
    1003            inStr: 처리할 이름 문자열
    1004
    1005        Returns:
    1006            수정된 이름 문자열
    1007        """
    1008        nameArray = self.convert_name_to_array(inStr)
    1009        partIndex = self.get_name_part_index(inPart)
    1010
    1011        if partIndex >= 0:
    1012            nameArray[partIndex] = ""
    1013
    1014        newName = self._combine(nameArray, self._get_filtering_char(inStr))
    1015        newName = self.set_index_padding_num(newName)
    1016
    1017        return newName
    1018
    1019    def load_from_config_file(self, configPath=None):
    1020        """
    1021        설정 파일에서 설정 로드
    1022
    1023        Args:
    1024            configPath: 설정 파일 경로 (기본값: self._configPath)
    1025
    1026        Returns:
    1027            로드 성공 여부 (True/False)
    1028        """
    1029        # 경로가 없으면 인스턴스 생성 시 설정된 경로 사용
    1030        if not configPath:
    1031            configPath = self._configPath
    1032
    1033        if not configPath:
    1034            print("설정 파일 경로가 제공되지 않았습니다.")
    1035            return False
    1036
    1037        # NamingConfig 인스턴스 생성 및 설정 로드
    1038        config = NamingConfig()
    1039        if config.load(configPath):
    1040            # 설정을 Naming 인스턴스에 적용
    1041            result = config.apply_to_naming(self)
    1042            if result:
    1043                self._configPath = configPath  # 성공적으로 로드한 경로 저장
    1044            return result
    1045        else:
    1046            print(f"설정 파일 로드 실패: {configPath}")
    1047            return False
    1048
    1049    def load_default_config(self):
    1050        """
    1051        기본 설정 로드 (현재는 아무 작업도 수행하지 않음)
    1052
    1053        Returns:
    1054            항상 True 반환 (기본 설정은 __init__에서 이미 설정됨)
    1055        """
    1056        # 이 메소드는 현재 __init__에서 설정한 기본값을 그대로 사용하므로
    1057        # 아무 작업도 수행하지 않습니다.
    1058        return True
    1059
    1060    def get_config_path(self):
    1061        """
    1062        현재 설정 파일 경로 가져오기
    1063
    1064        Returns:
    1065            설정 파일 경로 (없으면 빈 문자열)
    1066        """
    1067        return self._configPath or ""

class Naming: View Source

      19class Naming:
      20    """
      21    노드 이름을 관리하기 위한 기본 클래스.
      22    기본적인 이름 구성 요소를 정의하고 관리합니다.
      23    이 클래스는 하위 클래스에서 확장하여 특정 목적에 맞게 사용할 수 있습니다.
      24    """
      25
      26    def __init__(self, configPath=None):
      27        """
      28        클래스 초기화 및 기본 설정값 정의
      29
      30        Args:
      31            configPath: 설정 파일 경로 (기본값: None)
      32                        설정 파일이 제공되면 해당 파일에서 설정을 로드함
      33        """
      34        # 기본 설정값
      35        self._paddingNum = 2
      36        self._configPath = configPath
      37
      38        # 기본 namePart 초기화 (각 부분에 사전 정의 값 직접 설정)
      39        self._nameParts = []
      40
      41        # Prefix 부분 (PREFIX 타입)
      42        prefixPart = NamePart("Prefix", NamePartType.PREFIX, ["Pr"], ["Prefix"])
      43
      44        # RealName 부분 (REALNAME 타입)
      45        realNamePart = NamePart("RealName", NamePartType.REALNAME, [], [])
      46
      47        # Index 부분 (INDEX 타입)
      48        indexPart = NamePart("Index", NamePartType.INDEX, [], [])
      49
      50        # Suffix 부분 (SUFFIX 타입)
      51        suffixPart = NamePart("Suffix", NamePartType.SUFFIX, ["Su"], ["Suffix"])
      52
      53        # 기본 순서대로 설정
      54        self._nameParts = [prefixPart, realNamePart, indexPart, suffixPart]
      55
      56        # 설정 파일이 제공된 경우 로드
      57        if configPath:
      58            self.load_from_config_file(configPath)
      59        else:
      60            # 기본 JSON 설정 파일 로드 시도
      61            self.load_default_config()
      62
      63    # ---- String 관련 메소드들 (내부 사용 헬퍼 메소드) ----
      64
      65    def _split_into_string_and_digit(self, inStr):
      66        """
      67        문자열을 문자부분과 숫자부분으로 분리
      68
      69        Args:
      70            inStr: 분리할 문자열
      71
      72        Returns:
      73            튜플 (문자부분, 숫자부분)
      74        """
      75        match = re.match(r'^(.*?)(\d*)$', inStr)
      76        if match:
      77            return match.group(1), match.group(2)
      78        return inStr, ""
      79
      80    def _compare_string(self, inStr1, inStr2):
      81        """
      82        대소문자 구분 없이 문자열 비교
      83
      84        Args:
      85            inStr1: 첫 번째 문자열
      86            inStr2: 두 번째 문자열
      87
      88        Returns:
      89            비교 결과 (inStr1 < inStr2: 음수, inStr1 == inStr2: 0, inStr1 > inStr2: 양수)
      90        """
      91        # Python에서는 대소문자 구분 없는 비교를 위해 lower() 메서드 사용
      92        if inStr1.lower() < inStr2.lower():
      93            return -1
      94        elif inStr1.lower() > inStr2.lower():
      95            return 1
      96        return 0
      97
      98    def _sort_by_alphabet(self, inArray):
      99        """
     100        배열 내 문자열을 알파벳 순으로 정렬
     101
     102        Args:
     103            inArray: 정렬할 배열
     104
     105        Returns:
     106            정렬된 배열
     107        """
     108        # Python의 sorted 함수와 lambda를 사용하여 대소문자 구분 없이 정렬
     109        return sorted(inArray, key=lambda x: x.lower())
     110
     111    def _get_filtering_char(self, inStr):
     112        """
     113        문자열에서 사용된 구분자 문자 찾기
     114
     115        Args:
     116            inStr: 확인할 문자열
     117
     118        Returns:
     119            구분자 문자 (' ' 또는 '_' 또는 '')
     120        """
     121        if ' ' in inStr:
     122            return ' '
     123        if '_' in inStr:
     124            return '_'
     125        return ''
     126
     127    def _filter_by_filtering_char(self, inStr):
     128        """
     129        구분자 문자로 문자열 분할
     130
     131        Args:
     132            inStr: 분할할 문자열
     133
     134        Returns:
     135            분할된 문자열 리스트
     136        """
     137        filChar = self._get_filtering_char(inStr)
     138
     139        if not filChar:
     140            return [inStr]
     141
     142        # 빈 문자열 제거하며 분할
     143        return [part for part in inStr.split(filChar) if part]
     144
     145    def _filter_by_upper_case(self, inStr):
     146        """
     147        대문자로 시작하는 부분을 기준으로 문자열 분할
     148
     149        Args:
     150            inStr: 분할할 문자열
     151
     152        Returns:
     153            분할된 문자열 리스트
     154        """
     155        if not inStr:
     156            return []
     157
     158        result = []
     159        currentPart = inStr[0]
     160
     161        for i in range(1, len(inStr)):
     162            if inStr[i].isupper():
     163                result.append(currentPart)
     164                currentPart = inStr[i]
     165            else:
     166                currentPart += inStr[i]
     167
     168        if currentPart:
     169            result.append(currentPart)
     170
     171        return result
     172
     173    def _has_digit(self, inStr):
     174        """
     175        문자열에 숫자가 포함되어 있는지 확인
     176
     177        Args:
     178            inStr: 확인할 문자열
     179
     180        Returns:
     181            숫자가 포함되어 있으면 True, 아니면 False
     182        """
     183        return any(char.isdigit() for char in inStr)
     184
     185    def _split_to_array(self, inStr):
     186        """
     187        문자열을 구분자 또는 대문자로 분할하고 숫자 부분도 분리
     188
     189        Args:
     190            inStr: 분할할 문자열
     191
     192        Returns:
     193            분할된 문자열 리스트
     194        """
     195        filChar = self._get_filtering_char(inStr)
     196
     197        if not filChar:
     198            # 구분자가 없을 경우 대문자로 분할
     199            resultArray = self._filter_by_upper_case(inStr)
     200            tempArray = []
     201
     202            for item in resultArray:
     203                if self._has_digit(item):
     204                    stringPart, digitPart = self._split_into_string_and_digit(item)
     205                    if stringPart:
     206                        tempArray.append(stringPart)
     207                    if digitPart:
     208                        tempArray.append(digitPart)
     209                else:
     210                    tempArray.append(item)
     211
     212            return tempArray
     213        else:
     214            # 구분자가 있을 경우 구분자로 분할
     215            return self._filter_by_filtering_char(inStr)
     216
     217    def _remove_empty_string_in_array(self, inArray):
     218        """
     219        배열에서 빈 문자열 제거
     220
     221        Args:
     222            inArray: 처리할 배열
     223
     224        Returns:
     225            빈 문자열이 제거된 배열
     226        """
     227        return [item for item in inArray if item]
     228
     229    def _combine(self, inArray, inFilChar=" "):
     230        """
     231        문자열 배열을 하나의 문자열로 결합
     232
     233        Args:
     234            inArray: 결합할 문자열 배열
     235            filChar: 구분자 (기본값: 공백)
     236
     237        Returns:
     238            결합된 문자열
     239        """
     240        refinedArray = self._remove_empty_string_in_array(inArray)
     241
     242        if not refinedArray:
     243            return ""
     244
     245        if len(refinedArray) == 1:
     246            return refinedArray[0]
     247
     248        return inFilChar.join(refinedArray)
     249
     250    # ---- Name 관련 메서드들 ----
     251
     252    # 사전 정의 값 편집 메서드 제거 (namingConfig를 통해서만 변경 가능)
     253
     254    def get_padding_num(self):
     255        """
     256        패딩 숫자 가져오기
     257
     258        Returns:
     259            패딩 숫자
     260        """
     261        return self._paddingNum
     262
     263    def get_name_part(self, inNamePartName):
     264        """
     265        namePart 이름으로 NamePart 객체 가져오기
     266
     267        Args:
     268            namePart: 가져올 NamePart의 이름 ("Prefix", "RealName", "Suffix", "Index" 등)
     269
     270        Returns:
     271            해당 NamePart 객체, 존재하지 않으면 None
     272        """
     273        for part in self._nameParts:
     274            if part.get_name() == inNamePartName:
     275                return part
     276        return None
     277
     278    def get_name_part_index(self, inNamePartName):
     279        """
     280        namePart 이름으로 인덱스 가져오기
     281
     282        Args:
     283            namePart: 가져올 NamePart의 이름 ("Prefix", "RealName", "Suffix", "Index" 등)
     284
     285        Returns:
     286            해당 NamePart의 인덱스, 존재하지 않으면 -1
     287        """
     288        for i, part in enumerate(self._nameParts):
     289            if part.get_name() == inNamePartName:
     290                return i
     291        return -1
     292
     293    def get_name_part_predefined_values(self, inNamePartName):
     294        """
     295        namePart의 사전 정의 값 가져오기
     296
     297        Args:
     298            namePart: 가져올 NamePart의 이름 ("Prefix", "RealName", "Suffix", "Index" 등)
     299
     300        Returns:
     301            해당 NamePart의 사전 정의 값 리스트, 존재하지 않으면 빈 리스트
     302        """
     303        partObj = self.get_name_part(inNamePartName)
     304        if partObj:
     305            return partObj.get_predefined_values()
     306        return []
     307
     308    def is_in_name_part_predefined_values(self, inNamePartName, inStr):
     309        """
     310        지정된 namePart에 해당하는 부분이 문자열에 포함되어 있는지 확인
     311
     312        Args:
     313            namePart: 확인할 namePart 이름 ("Base", "Type", "Side" 등)
     314            inStr: 확인할 문자열
     315
     316        Returns:
     317            포함되어 있으면 True, 아니면 False
     318        """
     319        partObj = self.get_name_part(inNamePartName)
     320        if not partObj:
     321            return False
     322
     323        partType = partObj.get_type()
     324        if not partType:
     325            return False
     326
     327        partValues = partObj.get_predefined_values()
     328
     329        if partType == NamePartType.PREFIX or partType == NamePartType.SUFFIX:
     330            return any(item in inStr for item in partValues)
     331
     332        return False
     333
     334    def get_name_part_value_by_description(self, inNamePartName, inDescription):
     335        """
     336        지정된 namePart에 해당하는 부분을 문자열에서 추출
     337
     338        Args:
     339            namePart: 추출할 namePart 이름 ("Base", "Type", "Side" 등)
     340            inDescription: predefined value에서 찾기위한 description 문자열
     341
     342        Returns:
     343            지정된 namePart에 해당하는 문자열
     344        """
     345        partObj = self.get_name_part(inNamePartName)
     346        if not partObj:
     347            return ""
     348
     349        partType = partObj.get_type()
     350        if not partType:
     351            return ""
     352
     353        partValues = partObj.get_predefined_values()
     354
     355        if partType == NamePartType.PREFIX or partType == NamePartType.SUFFIX:
     356            try:
     357                foundIndex = partObj._descriptions.index(inDescription)
     358                return partValues[foundIndex]
     359            except ValueError:
     360                # Description not found in the list
     361                return ""
     362
     363    def pick_name(self, inNamePartName, inStr):
     364        nameArray = self._split_to_array(inStr)
     365        returnStr = ""
     366
     367        # namePart 문자열 목록 가져오기
     368        partObj = self.get_name_part(inNamePartName)
     369        if not partObj:
     370            return returnStr
     371
     372        partType = partObj.get_type()
     373        if not partType:
     374            return returnStr
     375
     376        partValues = partObj.get_predefined_values()
     377        if partType != NamePartType.INDEX and partType != NamePartType.REALNAME and not partValues:
     378            return returnStr
     379
     380        if partType == NamePartType.PREFIX:
     381            for item in nameArray:
     382                if item in partValues:
     383                    returnStr = item
     384                    break
     385
     386        if partType == NamePartType.SUFFIX:
     387            for i in range(len(nameArray) - 1, -1, -1):
     388                if nameArray[i] in partValues:
     389                    returnStr = nameArray[i]
     390                    break
     391
     392        if partType == NamePartType.INDEX:
     393            if self.get_name_part_index("Index") > self.get_name_part_index("RealName"):
     394                for i in range(len(nameArray) - 1, -1, -1):
     395                    if nameArray[i].isdigit():
     396                        returnStr = nameArray[i]
     397                        break
     398            else:
     399                for item in nameArray:
     400                    if item.isdigit():
     401                        returnStr = item
     402                        break
     403
     404        return returnStr
     405
     406    def get_name(self, inNamePartName, inStr):
     407        """
     408        지정된 namePart에 해당하는 부분을 문자열에서 추출
     409
     410        Args:
     411            namePart: 추출할 namePart 이름 ("Base", "Type", "Side" 등)
     412            inStr: 처리할 문자열
     413
     414        Returns:
     415            지정된 namePart에 해당하는 문자열
     416        """
     417        nameArray = self._split_to_array(inStr)
     418        returnStr = ""
     419
     420        partType = self.get_name_part(inNamePartName).get_type()
     421
     422        foundName = self.pick_name(inNamePartName, inStr)
     423        if foundName == "":
     424            return returnStr
     425        partIndex = self.get_name_part_index(inNamePartName)
     426        foundIndex = nameArray.index(foundName)
     427
     428        if partType == NamePartType.PREFIX:
     429            if foundIndex >= 0:
     430                prevNameParts = self._nameParts[:partIndex]
     431                prevNames = [self.pick_name(part.get_name(), inStr) for part in prevNameParts]
     432                prevNamesInNameArray = nameArray[:foundIndex]
     433                for prevName in prevNames:
     434                    if prevName in prevNamesInNameArray:
     435                        prevNamesInNameArray.remove(prevName)
     436                if len(prevNamesInNameArray) == 0 :
     437                    returnStr = foundName
     438
     439        if partType == NamePartType.SUFFIX:
     440            if foundIndex >= 0:
     441                nextNameParts = self._nameParts[partIndex + 1:]
     442                nextNames = [self.pick_name(part.get_name(), inStr) for part in nextNameParts]
     443                nextNamesInNameArray = nameArray[foundIndex + 1:]
     444                for nextName in nextNames:
     445                    if nextName in nextNamesInNameArray:
     446                        nextNamesInNameArray.remove(nextName)
     447                if len(nextNamesInNameArray) == 0 :
     448                    returnStr = foundName
     449
     450        if partType == NamePartType.INDEX:
     451            returnStr = self.pick_name(inNamePartName, inStr)
     452
     453        return returnStr
     454
     455    def combine(self, inPartsDict={}, inFilChar=" "):
     456        """
     457        namingConfig에서 정의된 nameParts와 그 순서에 따라 이름 부분들을 조합하여 완전한 이름 생성
     458
     459        Args:
     460            parts_dict: namePart 이름과 값의 딕셔너리 (예: {"Base": "b", "Type": "P", "Side": "L"})
     461            inFilChar: 구분자 문자 (기본값: " ")
     462
     463        Returns:
     464            조합된 이름 문자열
     465        """
     466        # 결과 배열 초기화 (빈 문자열로)
     467        combinedNameArray = [""] * len(self._nameParts)
     468
     469        # 각 namePart에 대해
     470        for i, part in enumerate(self._nameParts):
     471            partName = part.get_name()
     472            # 딕셔너리에서 해당 부분의 값 가져오기 (없으면 빈 문자열 사용)
     473            if partName in inPartsDict:
     474                combinedNameArray[i] = inPartsDict[partName]
     475
     476        # 배열을 문자열로 결합
     477        newName = self._combine(combinedNameArray, inFilChar)
     478        newName = self.set_index_padding_num(newName)
     479        return newName
     480
     481    def get_RealName(self, inStr):
     482        """
     483        문자열에서 실제 이름 부분 추출
     484
     485        Args:
     486            inStr: 처리할 문자열
     487
     488        Returns:
     489            실제 이름 부분 문자열
     490        """
     491        filChar = self._get_filtering_char(inStr)
     492        nameArray = self._split_to_array(inStr)
     493
     494        # 모든 nameParts 중 RealName이 아닌 것들의 값을 수집
     495        nonRealNameArray = []
     496        for part in self._nameParts:
     497            partName = part.get_name()
     498            partType = part.get_type()
     499            if partType != NamePartType.REALNAME:
     500                foundName = self.get_name(partName, inStr)
     501                nonRealNameArray.append(foundName)
     502
     503        for item in nonRealNameArray:
     504            if item in nameArray:
     505                nameArray.remove(item)
     506
     507        # 구분자로 결합
     508        return self._combine(nameArray, filChar)
     509
     510    def get_non_RealName(self, inStr):
     511        """
     512        실제 이름 부분을 제외한 이름 가져오기
     513
     514        Args:
     515            inStr: 처리할 이름 문자열
     516
     517        Returns:
     518            실제 이름이 제외된 이름 문자열
     519        """
     520        filChar = self._get_filtering_char(inStr)
     521
     522        # 모든 nameParts 중 RealName이 아닌 것들의 값을 수집
     523        nonRealNameArray = []
     524        for part in self._nameParts:
     525            partName = part.get_name()
     526            partType = part.get_type()
     527            if partType != NamePartType.REALNAME:
     528                foundName = self.get_name(partName, inStr)
     529                nonRealNameArray.append(foundName)
     530
     531        return self._combine(nonRealNameArray, filChar)
     532
     533    def convert_name_to_array(self, inStr):
     534        """
     535        문자열 이름을 이름 부분 배열로 변환
     536
     537        Args:
     538            inStr: 변환할 이름 문자열
     539
     540        Returns:
     541            이름 부분 배열 (Base, Type, Side, FrontBack, RealName, Index, Nub 등)
     542        """
     543        returnArray = [""] * len(self._nameParts)
     544
     545        # 각 namePart에 대해 처리
     546        for i, part in enumerate(self._nameParts):
     547            partName = part.get_name()
     548
     549            # 특수 케이스인 RealName은 마지막에 처리하기 위해 저장
     550            if partName == "RealName":
     551                realNameIndex = i
     552                continue
     553
     554            # get_name 메소드를 사용하여 해당 부분 추출
     555            partValue = self.get_name(partName, inStr)
     556            returnArray[i] = partValue
     557
     558        # 마지막으로 RealName 처리 (다른 모든 부분을 찾은 후에 수행해야 함)
     559        if 'realNameIndex' in locals():
     560            realNameStr = self.get_RealName(inStr)
     561            returnArray[realNameIndex] = realNameStr
     562
     563        return returnArray
     564
     565    def convert_to_dictionary(self, inStr):
     566        """
     567        문자열 이름을 이름 부분 딕셔너리로 변환
     568
     569        Args:
     570            inStr: 변환할 이름 문자열
     571
     572        Returns:
     573            이름 부분 딕셔너리 (키: namePart 이름, 값: 추출된 값)
     574            예: {"Base": "b", "Type": "P", "Side": "L", "RealName": "Arm", ...}
     575        """
     576        returnDict = {}
     577
     578        # 각 namePart에 대해 처리
     579        for part in self._nameParts:
     580            partName = part.get_name()
     581
     582            # 특수 케이스인 RealName은 마지막에 처리하기 위해 저장
     583            if partName == "RealName":
     584                continue
     585
     586            # get_name 메소드를 사용하여 해당 부분 추출
     587            partValue = self.get_name(partName, inStr)
     588            returnDict[partName] = partValue
     589
     590        # 마지막으로 RealName 처리 (다른 모든 부분을 찾은 후에 수행해야 함)
     591        realNameStr = self.get_RealName(inStr)
     592        returnDict["RealName"] = realNameStr
     593
     594        return returnDict
     595
     596    def convert_to_description(self, inStr):
     597        """
     598        문자열 이름을 설명으로 변환
     599
     600        Args:
     601            inStr: 변환할 이름 문자열
     602
     603        Returns:
     604            설명 문자열 (예: "b_P_L_Arm")
     605        """
     606        nameDic = self.convert_to_dictionary(inStr)
     607        descriptionDic = {}
     608        filteringChar = self._get_filtering_char(inStr)
     609        descName = inStr
     610        if nameDic:
     611            for namePartName, value in nameDic.items():
     612                namePart = self.get_name_part(namePartName)
     613                desc = namePart.get_description_by_value(value)
     614
     615                if desc == "" and value != "":
     616                    desc = value
     617
     618                descriptionDic[namePartName] = desc # Store in dictionary for later use
     619
     620            descName = self.combine(descriptionDic, filteringChar)
     621
     622        return descName
     623
     624    def convert_to_korean_description(self, inStr):
     625        """
     626        문자열 이름을 한국어 설명으로 변환
     627
     628        Args:
     629            inStr: 변환할 이름 문자열
     630
     631        Returns:
     632            한국어 설명 문자열 (예: "팔_왼쪽_팔")
     633        """
     634        nameDic = self.convert_to_dictionary(inStr)
     635        korDescDic = {}
     636        filteringChar = self._get_filtering_char(inStr)
     637        korDescName = inStr
     638        if nameDic:
     639            for namePartName, value in nameDic.items():
     640                namePart = self.get_name_part(namePartName)
     641                desc = namePart.get_description_by_value(value)
     642                korDesc = namePart.get_korean_description_by_value(value)
     643
     644                if korDesc == "" and desc != "":
     645                    korDesc = desc
     646
     647                korDescDic[namePartName] = korDesc # Store in dictionary for later use
     648
     649            korDescName = self.combine(korDescDic, filteringChar)
     650
     651        return korDescName
     652
     653    def has_name_part(self, inPart, inStr):
     654        """
     655        문자열에 특정 namePart가 포함되어 있는지 확인
     656
     657        Args:
     658            inPart: 확인할 namePart 이름 ("Base", "Type", "Side", "FrontBack", "RealName", "Index")
     659            inStr: 확인할 문자열
     660
     661        Returns:
     662            포함되어 있으면 True, 아니면 False
     663        """
     664        return self.get_name(inPart, inStr) != ""
     665
     666    def add_prefix_to_name_part(self, inPart, inStr, inPrefix):
     667        """
     668        이름의 특정 부분에 접두사 추가
     669
     670        Args:
     671            inPart: 수정할 부분 ("Base", "Type", "Side", "FrontBack", "RealName", "Index")
     672            inStr: 처리할 이름 문자열
     673            inPrefix: 추가할 접두사
     674
     675        Returns:
     676            수정된 이름 문자열
     677        """
     678        returnStr = inStr
     679
     680        if inPrefix:
     681            filChar = self._get_filtering_char(inStr)
     682            nameArray = self.convert_name_to_array(inStr)
     683            partIndex = self.get_name_part_index(inPart)
     684
     685            nameArray[partIndex] = inPrefix + nameArray[partIndex]
     686
     687            returnStr = self._combine(nameArray, filChar)
     688
     689        return returnStr
     690
     691    def add_suffix_to_name_part(self, inPart, inStr, inSuffix):
     692        """
     693        이름의 특정 부분에 접미사 추가
     694
     695        Args:
     696            inPart: 수정할 부분 ("Base", "Type", "Side", "FrontBack", "RealName", "Index")
     697            inStr: 처리할 이름 문자열
     698            inSuffix: 추가할 접미사
     699
     700        Returns:
     701            수정된 이름 문자열
     702        """
     703        returnStr = inStr
     704
     705        if inSuffix:
     706            filChar = self._get_filtering_char(inStr)
     707            nameArray = self.convert_name_to_array(inStr)
     708            partIndex = self.get_name_part_index(inPart)
     709
     710            nameArray[partIndex] = nameArray[partIndex] + inSuffix
     711
     712            returnStr = self._combine(nameArray, filChar)
     713
     714        return returnStr
     715
     716    def add_prefix_to_real_name(self, inStr, inPrefix):
     717        """
     718        실제 이름 부분에 접두사 추가
     719
     720        Args:
     721            inStr: 처리할 이름 문자열
     722            inPrefix: 추가할 접두사
     723
     724        Returns:
     725            수정된 이름 문자열
     726        """
     727        return self.add_prefix_to_name_part("RealName", inStr, inPrefix)
     728
     729    def add_suffix_to_real_name(self, inStr, inSuffix):
     730        """
     731        실제 이름 부분에 접미사 추가
     732
     733        Args:
     734            inStr: 처리할 이름 문자열
     735            inSuffix: 추가할 접미사
     736
     737        Returns:
     738            수정된 이름 문자열
     739        """
     740        return self.add_suffix_to_name_part("RealName", inStr, inSuffix)
     741
     742    def convert_digit_into_padding_string(self, inDigit, inPaddingNum=None):
     743        """
     744        숫자를 패딩된 문자열로 변환
     745
     746        Args:
     747            inDigit: 변환할 숫자 또는 숫자 문자열
     748            inPaddingNum: 패딩 자릿수 (기본값: 클래스의 _paddingNum)
     749
     750        Returns:
     751            패딩된 문자열
     752        """
     753        if inPaddingNum is None:
     754            inPaddingNum = self._paddingNum
     755
     756        digitNum = 0
     757
     758        if isinstance(inDigit, int):
     759            digitNum = inDigit
     760        elif isinstance(inDigit, str):
     761            if inDigit.isdigit():
     762                digitNum = int(inDigit)
     763
     764        # Python의 문자열 포맷팅을 사용하여 패딩
     765        return f"{digitNum:0{inPaddingNum}d}"
     766
     767    def set_index_padding_num(self, inStr, inPaddingNum=None):
     768        """
     769        이름의 인덱스 부분 패딩 설정
     770
     771        Args:
     772            inStr: 처리할 이름 문자열
     773            inPaddingNum: 설정할 패딩 자릿수 (기본값: 클래스의 _paddingNum)
     774
     775        Returns:
     776            패딩이 적용된 이름 문자열
     777        """
     778        if inPaddingNum is None:
     779            inPaddingNum = self._paddingNum
     780
     781        filChar = self._get_filtering_char(inStr)
     782        nameArray = self.convert_name_to_array(inStr)
     783        indexIndex = self.get_name_part_index("Index")
     784        indexStr = self.get_name("Index", inStr)
     785
     786        if indexStr:
     787            indexStr = self.convert_digit_into_padding_string(indexStr, inPaddingNum)
     788            nameArray[indexIndex] = indexStr
     789
     790        return self._combine(nameArray, filChar)
     791
     792    def get_index_padding_num(self, inStr):
     793        """
     794        이름의 인덱스 부분 패딩 자릿수 가져오기
     795
     796        Args:
     797            inStr: 처리할 이름 문자열
     798
     799        Returns:
     800            인덱스 패딩 자릿수
     801        """
     802        indexVal = self.get_name("Index", inStr)
     803
     804        if indexVal:
     805            return len(indexVal)
     806
     807        return 1
     808
     809    def increase_index(self, inStr, inAmount):
     810        """
     811        이름의 인덱스 부분 값 증가
     812
     813        Args:
     814            inStr: 처리할 이름 문자열
     815            inAmount: 증가시킬 값
     816
     817        Returns:
     818            인덱스가 증가된 이름 문자열
     819        """
     820        newName = inStr
     821        filChar = self._get_filtering_char(inStr)
     822        nameArray = self.convert_name_to_array(inStr)
     823        indexIndex = self.get_name_part_index("Index")
     824
     825        if indexIndex >= 0:
     826            indexStr = ""
     827            indexPaddingNum = self._paddingNum
     828            indexNum = -99999
     829
     830            if not nameArray[indexIndex]:
     831                indexNum = -1
     832            else:
     833                try:
     834                    indexNum = int(nameArray[indexIndex])
     835                    indexPaddingNum = len(nameArray[indexIndex])
     836                except ValueError:
     837                    pass
     838
     839            indexNum += inAmount
     840
     841            if indexNum < 0:
     842                indexNum = 0
     843
     844            # Python의 문자열 포맷팅을 사용하여 패딩
     845            indexStr = f"{indexNum:0{indexPaddingNum}d}"
     846            nameArray[indexIndex] = indexStr
     847            newName = self._combine(nameArray, filChar)
     848            newName = self.set_index_padding_num(newName)
     849
     850        return newName
     851
     852    def get_index_as_digit(self, inStr):
     853        """
     854        이름의 인덱스를 숫자로 변환
     855
     856        Args:
     857            inStr: 변환할 이름 문자열
     858
     859        Returns:
     860            숫자로 변환된 인덱스 (넙이 있으면 -1, 인덱스가 없으면 False)
     861        """
     862        indexStr = self.get_name("Index", inStr)
     863
     864        if indexStr:
     865            try:
     866                return int(indexStr)
     867            except ValueError:
     868                pass
     869
     870        return False
     871
     872    def sort_by_index(self, inNameArray):
     873        """
     874        이름 배열을 인덱스 기준으로 정렬
     875
     876        Args:
     877            inNameArray: 정렬할 이름 배열
     878
     879        Returns:
     880            인덱스 기준으로 정렬된 이름 배열
     881        """
     882        if not inNameArray:
     883            return []
     884
     885        # 정렬을 위한 보조 클래스 정의
     886        @dataclass
     887        class IndexSorting:
     888            oriIndex: int
     889            newIndex: int
     890
     891        # 각 이름의 인덱스를 추출하여 정렬 정보 생성
     892        structArray = []
     893
     894        for i, name in enumerate(inNameArray):
     895            tempIndex = self.get_index_as_digit(name)
     896
     897            if tempIndex is False:
     898                structArray.append(IndexSorting(i, 0))
     899            else:
     900                structArray.append(IndexSorting(i, tempIndex))
     901
     902        # 인덱스 기준으로 정렬
     903        structArray.sort(key=lambda x: x.newIndex)
     904
     905        # 정렬된 순서로 결과 배열 생성
     906        sortedNameArray = []
     907        for struct in structArray:
     908            sortedNameArray.append(inNameArray[struct.oriIndex])
     909
     910        return sortedNameArray
     911
     912    def get_string(self, inStr):
     913        """
     914        인덱스 부분을 제외한 이름 문자열 가져오기
     915
     916        Args:
     917            inStr: 처리할 이름 문자열
     918
     919        Returns:
     920            인덱스가 제외된 이름 문자열
     921        """
     922        filChar = self._get_filtering_char(inStr)
     923        nameArray = self.convert_name_to_array(inStr)
     924        indexOrder = self.get_name_part_index("Index")
     925
     926        # 인덱스 부분 제거
     927        returnNameArray = nameArray.copy()
     928        returnNameArray[indexOrder] = ""
     929
     930        return self._combine(returnNameArray, filChar)
     931
     932    def gen_mirroring_name(self, inStr):
     933        """
     934        미러링된 이름 생성 (측면 또는 앞/뒤 변경)
     935
     936        이름에서 Side와 FrontBack namePart를 자동으로 검색하고,
     937        발견된 값의 semanticmapping weight와 가장 차이가 큰 값으로 교체합니다.
     938
     939        Args:
     940            inStr: 처리할 이름 문자열
     941
     942        Returns:
     943            미러링된 이름 문자열
     944        """
     945        nameArray = self.convert_name_to_array(inStr)
     946
     947        for part in self._nameParts:
     948            partName = part.get_name()
     949            partType = part.get_type()
     950            if (partType != NamePartType.REALNAME or partType != NamePartType.INDEX) and part.is_direction():
     951                partIndex = self.get_name_part_index(partName)
     952                foundName = self.get_name(partName, inStr)
     953                opositeName = part.get_most_different_weight_value(foundName)
     954                if opositeName and foundName != opositeName:
     955                    nameArray[partIndex] = opositeName
     956
     957        returnName = self._combine(nameArray, self._get_filtering_char(inStr))
     958
     959        return returnName
     960
     961    def replace_filtering_char(self, inStr, inNewFilChar):
     962        """
     963        이름의 구분자 문자 변경
     964
     965        Args:
     966            inStr: 처리할 이름 문자열
     967            inNewFilChar: 새 구분자 문자
     968
     969        Returns:
     970            구분자가 변경된 이름 문자열
     971        """
     972        nameArray = self.convert_name_to_array(inStr)
     973        return self._combine(nameArray, inNewFilChar)
     974
     975    def replace_name_part(self, inPart, inStr, inNewName):
     976        """
     977        이름의 특정 부분을 새 이름으로 변경
     978
     979        Args:
     980            inPart: 수정할 부분 ("Base", "Type", "Side", "FrontBack", "RealName", "Index")
     981            inStr: 처리할 이름 문자열
     982            inNewName: 새 이름
     983
     984        Returns:
     985            수정된 이름 문자열
     986        """
     987        nameArray = self.convert_name_to_array(inStr)
     988        partIndex = self.get_name_part_index(inPart)
     989
     990        if partIndex >= 0:
     991            nameArray[partIndex] = inNewName
     992
     993        newName = self._combine(nameArray, self._get_filtering_char(inStr))
     994        newName = self.set_index_padding_num(newName)
     995
     996        return newName
     997
     998    def remove_name_part(self, inPart, inStr):
     999        """
    1000        이름의 특정 부분 제거
    1001
    1002        Args:
    1003            inPart: 제거할 부분 ("Base", "Type", "Side", "FrontBack", "RealName", "Index")
    1004            inStr: 처리할 이름 문자열
    1005
    1006        Returns:
    1007            수정된 이름 문자열
    1008        """
    1009        nameArray = self.convert_name_to_array(inStr)
    1010        partIndex = self.get_name_part_index(inPart)
    1011
    1012        if partIndex >= 0:
    1013            nameArray[partIndex] = ""
    1014
    1015        newName = self._combine(nameArray, self._get_filtering_char(inStr))
    1016        newName = self.set_index_padding_num(newName)
    1017
    1018        return newName
    1019
    1020    def load_from_config_file(self, configPath=None):
    1021        """
    1022        설정 파일에서 설정 로드
    1023
    1024        Args:
    1025            configPath: 설정 파일 경로 (기본값: self._configPath)
    1026
    1027        Returns:
    1028            로드 성공 여부 (True/False)
    1029        """
    1030        # 경로가 없으면 인스턴스 생성 시 설정된 경로 사용
    1031        if not configPath:
    1032            configPath = self._configPath
    1033
    1034        if not configPath:
    1035            print("설정 파일 경로가 제공되지 않았습니다.")
    1036            return False
    1037
    1038        # NamingConfig 인스턴스 생성 및 설정 로드
    1039        config = NamingConfig()
    1040        if config.load(configPath):
    1041            # 설정을 Naming 인스턴스에 적용
    1042            result = config.apply_to_naming(self)
    1043            if result:
    1044                self._configPath = configPath  # 성공적으로 로드한 경로 저장
    1045            return result
    1046        else:
    1047            print(f"설정 파일 로드 실패: {configPath}")
    1048            return False
    1049
    1050    def load_default_config(self):
    1051        """
    1052        기본 설정 로드 (현재는 아무 작업도 수행하지 않음)
    1053
    1054        Returns:
    1055            항상 True 반환 (기본 설정은 __init__에서 이미 설정됨)
    1056        """
    1057        # 이 메소드는 현재 __init__에서 설정한 기본값을 그대로 사용하므로
    1058        # 아무 작업도 수행하지 않습니다.
    1059        return True
    1060
    1061    def get_config_path(self):
    1062        """
    1063        현재 설정 파일 경로 가져오기
    1064
    1065        Returns:
    1066            설정 파일 경로 (없으면 빈 문자열)
    1067        """
    1068        return self._configPath or ""

노드 이름을 관리하기 위한 기본 클래스. 기본적인 이름 구성 요소를 정의하고 관리합니다. 이 클래스는 하위 클래스에서 확장하여 특정 목적에 맞게 사용할 수 있습니다.

Naming(configPath=None) View Source

    26    def __init__(self, configPath=None):
    27        """
    28        클래스 초기화 및 기본 설정값 정의
    29
    30        Args:
    31            configPath: 설정 파일 경로 (기본값: None)
    32                        설정 파일이 제공되면 해당 파일에서 설정을 로드함
    33        """
    34        # 기본 설정값
    35        self._paddingNum = 2
    36        self._configPath = configPath
    37
    38        # 기본 namePart 초기화 (각 부분에 사전 정의 값 직접 설정)
    39        self._nameParts = []
    40
    41        # Prefix 부분 (PREFIX 타입)
    42        prefixPart = NamePart("Prefix", NamePartType.PREFIX, ["Pr"], ["Prefix"])
    43
    44        # RealName 부분 (REALNAME 타입)
    45        realNamePart = NamePart("RealName", NamePartType.REALNAME, [], [])
    46
    47        # Index 부분 (INDEX 타입)
    48        indexPart = NamePart("Index", NamePartType.INDEX, [], [])
    49
    50        # Suffix 부분 (SUFFIX 타입)
    51        suffixPart = NamePart("Suffix", NamePartType.SUFFIX, ["Su"], ["Suffix"])
    52
    53        # 기본 순서대로 설정
    54        self._nameParts = [prefixPart, realNamePart, indexPart, suffixPart]
    55
    56        # 설정 파일이 제공된 경우 로드
    57        if configPath:
    58            self.load_from_config_file(configPath)
    59        else:
    60            # 기본 JSON 설정 파일 로드 시도
    61            self.load_default_config()

클래스 초기화 및 기본 설정값 정의

Args: configPath: 설정 파일 경로 (기본값: None) 설정 파일이 제공되면 해당 파일에서 설정을 로드함

def get_padding_num(self): View Source

    254    def get_padding_num(self):
    255        """
    256        패딩 숫자 가져오기
    257
    258        Returns:
    259            패딩 숫자
    260        """
    261        return self._paddingNum

패딩 숫자 가져오기

Returns: 패딩 숫자

def get_name_part(self, inNamePartName): View Source

    263    def get_name_part(self, inNamePartName):
    264        """
    265        namePart 이름으로 NamePart 객체 가져오기
    266
    267        Args:
    268            namePart: 가져올 NamePart의 이름 ("Prefix", "RealName", "Suffix", "Index" 등)
    269
    270        Returns:
    271            해당 NamePart 객체, 존재하지 않으면 None
    272        """
    273        for part in self._nameParts:
    274            if part.get_name() == inNamePartName:
    275                return part
    276        return None

namePart 이름으로 NamePart 객체 가져오기

Args: namePart: 가져올 NamePart의 이름 ("Prefix", "RealName", "Suffix", "Index" 등)

Returns: 해당 NamePart 객체, 존재하지 않으면 None

def get_name_part_index(self, inNamePartName): View Source

    278    def get_name_part_index(self, inNamePartName):
    279        """
    280        namePart 이름으로 인덱스 가져오기
    281
    282        Args:
    283            namePart: 가져올 NamePart의 이름 ("Prefix", "RealName", "Suffix", "Index" 등)
    284
    285        Returns:
    286            해당 NamePart의 인덱스, 존재하지 않으면 -1
    287        """
    288        for i, part in enumerate(self._nameParts):
    289            if part.get_name() == inNamePartName:
    290                return i
    291        return -1

namePart 이름으로 인덱스 가져오기

Args: namePart: 가져올 NamePart의 이름 ("Prefix", "RealName", "Suffix", "Index" 등)

Returns: 해당 NamePart의 인덱스, 존재하지 않으면 -1

def get_name_part_predefined_values(self, inNamePartName): View Source

    293    def get_name_part_predefined_values(self, inNamePartName):
    294        """
    295        namePart의 사전 정의 값 가져오기
    296
    297        Args:
    298            namePart: 가져올 NamePart의 이름 ("Prefix", "RealName", "Suffix", "Index" 등)
    299
    300        Returns:
    301            해당 NamePart의 사전 정의 값 리스트, 존재하지 않으면 빈 리스트
    302        """
    303        partObj = self.get_name_part(inNamePartName)
    304        if partObj:
    305            return partObj.get_predefined_values()
    306        return []

namePart의 사전 정의 값 가져오기

Args: namePart: 가져올 NamePart의 이름 ("Prefix", "RealName", "Suffix", "Index" 등)

Returns: 해당 NamePart의 사전 정의 값 리스트, 존재하지 않으면 빈 리스트

def is_in_name_part_predefined_values(self, inNamePartName, inStr): View Source

    308    def is_in_name_part_predefined_values(self, inNamePartName, inStr):
    309        """
    310        지정된 namePart에 해당하는 부분이 문자열에 포함되어 있는지 확인
    311
    312        Args:
    313            namePart: 확인할 namePart 이름 ("Base", "Type", "Side" 등)
    314            inStr: 확인할 문자열
    315
    316        Returns:
    317            포함되어 있으면 True, 아니면 False
    318        """
    319        partObj = self.get_name_part(inNamePartName)
    320        if not partObj:
    321            return False
    322
    323        partType = partObj.get_type()
    324        if not partType:
    325            return False
    326
    327        partValues = partObj.get_predefined_values()
    328
    329        if partType == NamePartType.PREFIX or partType == NamePartType.SUFFIX:
    330            return any(item in inStr for item in partValues)
    331
    332        return False

지정된 namePart에 해당하는 부분이 문자열에 포함되어 있는지 확인

Args: namePart: 확인할 namePart 이름 ("Base", "Type", "Side" 등) inStr: 확인할 문자열

Returns: 포함되어 있으면 True, 아니면 False

def get_name_part_value_by_description(self, inNamePartName, inDescription): View Source

    334    def get_name_part_value_by_description(self, inNamePartName, inDescription):
    335        """
    336        지정된 namePart에 해당하는 부분을 문자열에서 추출
    337
    338        Args:
    339            namePart: 추출할 namePart 이름 ("Base", "Type", "Side" 등)
    340            inDescription: predefined value에서 찾기위한 description 문자열
    341
    342        Returns:
    343            지정된 namePart에 해당하는 문자열
    344        """
    345        partObj = self.get_name_part(inNamePartName)
    346        if not partObj:
    347            return ""
    348
    349        partType = partObj.get_type()
    350        if not partType:
    351            return ""
    352
    353        partValues = partObj.get_predefined_values()
    354
    355        if partType == NamePartType.PREFIX or partType == NamePartType.SUFFIX:
    356            try:
    357                foundIndex = partObj._descriptions.index(inDescription)
    358                return partValues[foundIndex]
    359            except ValueError:
    360                # Description not found in the list
    361                return ""

지정된 namePart에 해당하는 부분을 문자열에서 추출

Args: namePart: 추출할 namePart 이름 ("Base", "Type", "Side" 등) inDescription: predefined value에서 찾기위한 description 문자열

Returns: 지정된 namePart에 해당하는 문자열

def pick_name(self, inNamePartName, inStr): View Source

    363    def pick_name(self, inNamePartName, inStr):
    364        nameArray = self._split_to_array(inStr)
    365        returnStr = ""
    366
    367        # namePart 문자열 목록 가져오기
    368        partObj = self.get_name_part(inNamePartName)
    369        if not partObj:
    370            return returnStr
    371
    372        partType = partObj.get_type()
    373        if not partType:
    374            return returnStr
    375
    376        partValues = partObj.get_predefined_values()
    377        if partType != NamePartType.INDEX and partType != NamePartType.REALNAME and not partValues:
    378            return returnStr
    379
    380        if partType == NamePartType.PREFIX:
    381            for item in nameArray:
    382                if item in partValues:
    383                    returnStr = item
    384                    break
    385
    386        if partType == NamePartType.SUFFIX:
    387            for i in range(len(nameArray) - 1, -1, -1):
    388                if nameArray[i] in partValues:
    389                    returnStr = nameArray[i]
    390                    break
    391
    392        if partType == NamePartType.INDEX:
    393            if self.get_name_part_index("Index") > self.get_name_part_index("RealName"):
    394                for i in range(len(nameArray) - 1, -1, -1):
    395                    if nameArray[i].isdigit():
    396                        returnStr = nameArray[i]
    397                        break
    398            else:
    399                for item in nameArray:
    400                    if item.isdigit():
    401                        returnStr = item
    402                        break
    403
    404        return returnStr

def get_name(self, inNamePartName, inStr): View Source

    406    def get_name(self, inNamePartName, inStr):
    407        """
    408        지정된 namePart에 해당하는 부분을 문자열에서 추출
    409
    410        Args:
    411            namePart: 추출할 namePart 이름 ("Base", "Type", "Side" 등)
    412            inStr: 처리할 문자열
    413
    414        Returns:
    415            지정된 namePart에 해당하는 문자열
    416        """
    417        nameArray = self._split_to_array(inStr)
    418        returnStr = ""
    419
    420        partType = self.get_name_part(inNamePartName).get_type()
    421
    422        foundName = self.pick_name(inNamePartName, inStr)
    423        if foundName == "":
    424            return returnStr
    425        partIndex = self.get_name_part_index(inNamePartName)
    426        foundIndex = nameArray.index(foundName)
    427
    428        if partType == NamePartType.PREFIX:
    429            if foundIndex >= 0:
    430                prevNameParts = self._nameParts[:partIndex]
    431                prevNames = [self.pick_name(part.get_name(), inStr) for part in prevNameParts]
    432                prevNamesInNameArray = nameArray[:foundIndex]
    433                for prevName in prevNames:
    434                    if prevName in prevNamesInNameArray:
    435                        prevNamesInNameArray.remove(prevName)
    436                if len(prevNamesInNameArray) == 0 :
    437                    returnStr = foundName
    438
    439        if partType == NamePartType.SUFFIX:
    440            if foundIndex >= 0:
    441                nextNameParts = self._nameParts[partIndex + 1:]
    442                nextNames = [self.pick_name(part.get_name(), inStr) for part in nextNameParts]
    443                nextNamesInNameArray = nameArray[foundIndex + 1:]
    444                for nextName in nextNames:
    445                    if nextName in nextNamesInNameArray:
    446                        nextNamesInNameArray.remove(nextName)
    447                if len(nextNamesInNameArray) == 0 :
    448                    returnStr = foundName
    449
    450        if partType == NamePartType.INDEX:
    451            returnStr = self.pick_name(inNamePartName, inStr)
    452
    453        return returnStr

지정된 namePart에 해당하는 부분을 문자열에서 추출

Args: namePart: 추출할 namePart 이름 ("Base", "Type", "Side" 등) inStr: 처리할 문자열

Returns: 지정된 namePart에 해당하는 문자열

def combine(self, inPartsDict={}, inFilChar=' '): View Source

    455    def combine(self, inPartsDict={}, inFilChar=" "):
    456        """
    457        namingConfig에서 정의된 nameParts와 그 순서에 따라 이름 부분들을 조합하여 완전한 이름 생성
    458
    459        Args:
    460            parts_dict: namePart 이름과 값의 딕셔너리 (예: {"Base": "b", "Type": "P", "Side": "L"})
    461            inFilChar: 구분자 문자 (기본값: " ")
    462
    463        Returns:
    464            조합된 이름 문자열
    465        """
    466        # 결과 배열 초기화 (빈 문자열로)
    467        combinedNameArray = [""] * len(self._nameParts)
    468
    469        # 각 namePart에 대해
    470        for i, part in enumerate(self._nameParts):
    471            partName = part.get_name()
    472            # 딕셔너리에서 해당 부분의 값 가져오기 (없으면 빈 문자열 사용)
    473            if partName in inPartsDict:
    474                combinedNameArray[i] = inPartsDict[partName]
    475
    476        # 배열을 문자열로 결합
    477        newName = self._combine(combinedNameArray, inFilChar)
    478        newName = self.set_index_padding_num(newName)
    479        return newName

namingConfig에서 정의된 nameParts와 그 순서에 따라 이름 부분들을 조합하여 완전한 이름 생성

Args: parts_dict: namePart 이름과 값의 딕셔너리 (예: {"Base": "b", "Type": "P", "Side": "L"}) inFilChar: 구분자 문자 (기본값: " ")

Returns: 조합된 이름 문자열

def get_RealName(self, inStr): View Source

    481    def get_RealName(self, inStr):
    482        """
    483        문자열에서 실제 이름 부분 추출
    484
    485        Args:
    486            inStr: 처리할 문자열
    487
    488        Returns:
    489            실제 이름 부분 문자열
    490        """
    491        filChar = self._get_filtering_char(inStr)
    492        nameArray = self._split_to_array(inStr)
    493
    494        # 모든 nameParts 중 RealName이 아닌 것들의 값을 수집
    495        nonRealNameArray = []
    496        for part in self._nameParts:
    497            partName = part.get_name()
    498            partType = part.get_type()
    499            if partType != NamePartType.REALNAME:
    500                foundName = self.get_name(partName, inStr)
    501                nonRealNameArray.append(foundName)
    502
    503        for item in nonRealNameArray:
    504            if item in nameArray:
    505                nameArray.remove(item)
    506
    507        # 구분자로 결합
    508        return self._combine(nameArray, filChar)

문자열에서 실제 이름 부분 추출

Args: inStr: 처리할 문자열

Returns: 실제 이름 부분 문자열

def get_non_RealName(self, inStr): View Source

    510    def get_non_RealName(self, inStr):
    511        """
    512        실제 이름 부분을 제외한 이름 가져오기
    513
    514        Args:
    515            inStr: 처리할 이름 문자열
    516
    517        Returns:
    518            실제 이름이 제외된 이름 문자열
    519        """
    520        filChar = self._get_filtering_char(inStr)
    521
    522        # 모든 nameParts 중 RealName이 아닌 것들의 값을 수집
    523        nonRealNameArray = []
    524        for part in self._nameParts:
    525            partName = part.get_name()
    526            partType = part.get_type()
    527            if partType != NamePartType.REALNAME:
    528                foundName = self.get_name(partName, inStr)
    529                nonRealNameArray.append(foundName)
    530
    531        return self._combine(nonRealNameArray, filChar)

실제 이름 부분을 제외한 이름 가져오기

Args: inStr: 처리할 이름 문자열

Returns: 실제 이름이 제외된 이름 문자열

def convert_name_to_array(self, inStr): View Source

    533    def convert_name_to_array(self, inStr):
    534        """
    535        문자열 이름을 이름 부분 배열로 변환
    536
    537        Args:
    538            inStr: 변환할 이름 문자열
    539
    540        Returns:
    541            이름 부분 배열 (Base, Type, Side, FrontBack, RealName, Index, Nub 등)
    542        """
    543        returnArray = [""] * len(self._nameParts)
    544
    545        # 각 namePart에 대해 처리
    546        for i, part in enumerate(self._nameParts):
    547            partName = part.get_name()
    548
    549            # 특수 케이스인 RealName은 마지막에 처리하기 위해 저장
    550            if partName == "RealName":
    551                realNameIndex = i
    552                continue
    553
    554            # get_name 메소드를 사용하여 해당 부분 추출
    555            partValue = self.get_name(partName, inStr)
    556            returnArray[i] = partValue
    557
    558        # 마지막으로 RealName 처리 (다른 모든 부분을 찾은 후에 수행해야 함)
    559        if 'realNameIndex' in locals():
    560            realNameStr = self.get_RealName(inStr)
    561            returnArray[realNameIndex] = realNameStr
    562
    563        return returnArray

문자열 이름을 이름 부분 배열로 변환

Args: inStr: 변환할 이름 문자열

Returns: 이름 부분 배열 (Base, Type, Side, FrontBack, RealName, Index, Nub 등)

def convert_to_dictionary(self, inStr): View Source

    565    def convert_to_dictionary(self, inStr):
    566        """
    567        문자열 이름을 이름 부분 딕셔너리로 변환
    568
    569        Args:
    570            inStr: 변환할 이름 문자열
    571
    572        Returns:
    573            이름 부분 딕셔너리 (키: namePart 이름, 값: 추출된 값)
    574            예: {"Base": "b", "Type": "P", "Side": "L", "RealName": "Arm", ...}
    575        """
    576        returnDict = {}
    577
    578        # 각 namePart에 대해 처리
    579        for part in self._nameParts:
    580            partName = part.get_name()
    581
    582            # 특수 케이스인 RealName은 마지막에 처리하기 위해 저장
    583            if partName == "RealName":
    584                continue
    585
    586            # get_name 메소드를 사용하여 해당 부분 추출
    587            partValue = self.get_name(partName, inStr)
    588            returnDict[partName] = partValue
    589
    590        # 마지막으로 RealName 처리 (다른 모든 부분을 찾은 후에 수행해야 함)
    591        realNameStr = self.get_RealName(inStr)
    592        returnDict["RealName"] = realNameStr
    593
    594        return returnDict

문자열 이름을 이름 부분 딕셔너리로 변환

Args: inStr: 변환할 이름 문자열

Returns: 이름 부분 딕셔너리 (키: namePart 이름, 값: 추출된 값) 예: {"Base": "b", "Type": "P", "Side": "L", "RealName": "Arm", ...}

def convert_to_description(self, inStr): View Source

    596    def convert_to_description(self, inStr):
    597        """
    598        문자열 이름을 설명으로 변환
    599
    600        Args:
    601            inStr: 변환할 이름 문자열
    602
    603        Returns:
    604            설명 문자열 (예: "b_P_L_Arm")
    605        """
    606        nameDic = self.convert_to_dictionary(inStr)
    607        descriptionDic = {}
    608        filteringChar = self._get_filtering_char(inStr)
    609        descName = inStr
    610        if nameDic:
    611            for namePartName, value in nameDic.items():
    612                namePart = self.get_name_part(namePartName)
    613                desc = namePart.get_description_by_value(value)
    614
    615                if desc == "" and value != "":
    616                    desc = value
    617
    618                descriptionDic[namePartName] = desc # Store in dictionary for later use
    619
    620            descName = self.combine(descriptionDic, filteringChar)
    621
    622        return descName

문자열 이름을 설명으로 변환

Args: inStr: 변환할 이름 문자열

Returns: 설명 문자열 (예: "b_P_L_Arm")

def convert_to_korean_description(self, inStr): View Source

    624    def convert_to_korean_description(self, inStr):
    625        """
    626        문자열 이름을 한국어 설명으로 변환
    627
    628        Args:
    629            inStr: 변환할 이름 문자열
    630
    631        Returns:
    632            한국어 설명 문자열 (예: "팔_왼쪽_팔")
    633        """
    634        nameDic = self.convert_to_dictionary(inStr)
    635        korDescDic = {}
    636        filteringChar = self._get_filtering_char(inStr)
    637        korDescName = inStr
    638        if nameDic:
    639            for namePartName, value in nameDic.items():
    640                namePart = self.get_name_part(namePartName)
    641                desc = namePart.get_description_by_value(value)
    642                korDesc = namePart.get_korean_description_by_value(value)
    643
    644                if korDesc == "" and desc != "":
    645                    korDesc = desc
    646
    647                korDescDic[namePartName] = korDesc # Store in dictionary for later use
    648
    649            korDescName = self.combine(korDescDic, filteringChar)
    650
    651        return korDescName

문자열 이름을 한국어 설명으로 변환

Args: inStr: 변환할 이름 문자열

Returns: 한국어 설명 문자열 (예: "팔_왼쪽_팔")

def has_name_part(self, inPart, inStr): View Source

    653    def has_name_part(self, inPart, inStr):
    654        """
    655        문자열에 특정 namePart가 포함되어 있는지 확인
    656
    657        Args:
    658            inPart: 확인할 namePart 이름 ("Base", "Type", "Side", "FrontBack", "RealName", "Index")
    659            inStr: 확인할 문자열
    660
    661        Returns:
    662            포함되어 있으면 True, 아니면 False
    663        """
    664        return self.get_name(inPart, inStr) != ""

문자열에 특정 namePart가 포함되어 있는지 확인

Args: inPart: 확인할 namePart 이름 ("Base", "Type", "Side", "FrontBack", "RealName", "Index") inStr: 확인할 문자열

Returns: 포함되어 있으면 True, 아니면 False

def add_prefix_to_name_part(self, inPart, inStr, inPrefix): View Source

    666    def add_prefix_to_name_part(self, inPart, inStr, inPrefix):
    667        """
    668        이름의 특정 부분에 접두사 추가
    669
    670        Args:
    671            inPart: 수정할 부분 ("Base", "Type", "Side", "FrontBack", "RealName", "Index")
    672            inStr: 처리할 이름 문자열
    673            inPrefix: 추가할 접두사
    674
    675        Returns:
    676            수정된 이름 문자열
    677        """
    678        returnStr = inStr
    679
    680        if inPrefix:
    681            filChar = self._get_filtering_char(inStr)
    682            nameArray = self.convert_name_to_array(inStr)
    683            partIndex = self.get_name_part_index(inPart)
    684
    685            nameArray[partIndex] = inPrefix + nameArray[partIndex]
    686
    687            returnStr = self._combine(nameArray, filChar)
    688
    689        return returnStr

이름의 특정 부분에 접두사 추가

Args: inPart: 수정할 부분 ("Base", "Type", "Side", "FrontBack", "RealName", "Index") inStr: 처리할 이름 문자열 inPrefix: 추가할 접두사

Returns: 수정된 이름 문자열

def add_suffix_to_name_part(self, inPart, inStr, inSuffix): View Source

    691    def add_suffix_to_name_part(self, inPart, inStr, inSuffix):
    692        """
    693        이름의 특정 부분에 접미사 추가
    694
    695        Args:
    696            inPart: 수정할 부분 ("Base", "Type", "Side", "FrontBack", "RealName", "Index")
    697            inStr: 처리할 이름 문자열
    698            inSuffix: 추가할 접미사
    699
    700        Returns:
    701            수정된 이름 문자열
    702        """
    703        returnStr = inStr
    704
    705        if inSuffix:
    706            filChar = self._get_filtering_char(inStr)
    707            nameArray = self.convert_name_to_array(inStr)
    708            partIndex = self.get_name_part_index(inPart)
    709
    710            nameArray[partIndex] = nameArray[partIndex] + inSuffix
    711
    712            returnStr = self._combine(nameArray, filChar)
    713
    714        return returnStr

이름의 특정 부분에 접미사 추가

Args: inPart: 수정할 부분 ("Base", "Type", "Side", "FrontBack", "RealName", "Index") inStr: 처리할 이름 문자열 inSuffix: 추가할 접미사

Returns: 수정된 이름 문자열

def add_prefix_to_real_name(self, inStr, inPrefix): View Source

    716    def add_prefix_to_real_name(self, inStr, inPrefix):
    717        """
    718        실제 이름 부분에 접두사 추가
    719
    720        Args:
    721            inStr: 처리할 이름 문자열
    722            inPrefix: 추가할 접두사
    723
    724        Returns:
    725            수정된 이름 문자열
    726        """
    727        return self.add_prefix_to_name_part("RealName", inStr, inPrefix)

실제 이름 부분에 접두사 추가

Args: inStr: 처리할 이름 문자열 inPrefix: 추가할 접두사

Returns: 수정된 이름 문자열

def add_suffix_to_real_name(self, inStr, inSuffix): View Source

    729    def add_suffix_to_real_name(self, inStr, inSuffix):
    730        """
    731        실제 이름 부분에 접미사 추가
    732
    733        Args:
    734            inStr: 처리할 이름 문자열
    735            inSuffix: 추가할 접미사
    736
    737        Returns:
    738            수정된 이름 문자열
    739        """
    740        return self.add_suffix_to_name_part("RealName", inStr, inSuffix)

실제 이름 부분에 접미사 추가

Args: inStr: 처리할 이름 문자열 inSuffix: 추가할 접미사

Returns: 수정된 이름 문자열

def convert_digit_into_padding_string(self, inDigit, inPaddingNum=None): View Source

    742    def convert_digit_into_padding_string(self, inDigit, inPaddingNum=None):
    743        """
    744        숫자를 패딩된 문자열로 변환
    745
    746        Args:
    747            inDigit: 변환할 숫자 또는 숫자 문자열
    748            inPaddingNum: 패딩 자릿수 (기본값: 클래스의 _paddingNum)
    749
    750        Returns:
    751            패딩된 문자열
    752        """
    753        if inPaddingNum is None:
    754            inPaddingNum = self._paddingNum
    755
    756        digitNum = 0
    757
    758        if isinstance(inDigit, int):
    759            digitNum = inDigit
    760        elif isinstance(inDigit, str):
    761            if inDigit.isdigit():
    762                digitNum = int(inDigit)
    763
    764        # Python의 문자열 포맷팅을 사용하여 패딩
    765        return f"{digitNum:0{inPaddingNum}d}"

숫자를 패딩된 문자열로 변환

Args: inDigit: 변환할 숫자 또는 숫자 문자열 inPaddingNum: 패딩 자릿수 (기본값: 클래스의 _paddingNum)

Returns: 패딩된 문자열

def set_index_padding_num(self, inStr, inPaddingNum=None): View Source

    767    def set_index_padding_num(self, inStr, inPaddingNum=None):
    768        """
    769        이름의 인덱스 부분 패딩 설정
    770
    771        Args:
    772            inStr: 처리할 이름 문자열
    773            inPaddingNum: 설정할 패딩 자릿수 (기본값: 클래스의 _paddingNum)
    774
    775        Returns:
    776            패딩이 적용된 이름 문자열
    777        """
    778        if inPaddingNum is None:
    779            inPaddingNum = self._paddingNum
    780
    781        filChar = self._get_filtering_char(inStr)
    782        nameArray = self.convert_name_to_array(inStr)
    783        indexIndex = self.get_name_part_index("Index")
    784        indexStr = self.get_name("Index", inStr)
    785
    786        if indexStr:
    787            indexStr = self.convert_digit_into_padding_string(indexStr, inPaddingNum)
    788            nameArray[indexIndex] = indexStr
    789
    790        return self._combine(nameArray, filChar)

이름의 인덱스 부분 패딩 설정

Args: inStr: 처리할 이름 문자열 inPaddingNum: 설정할 패딩 자릿수 (기본값: 클래스의 _paddingNum)

Returns: 패딩이 적용된 이름 문자열

def get_index_padding_num(self, inStr): View Source

    792    def get_index_padding_num(self, inStr):
    793        """
    794        이름의 인덱스 부분 패딩 자릿수 가져오기
    795
    796        Args:
    797            inStr: 처리할 이름 문자열
    798
    799        Returns:
    800            인덱스 패딩 자릿수
    801        """
    802        indexVal = self.get_name("Index", inStr)
    803
    804        if indexVal:
    805            return len(indexVal)
    806
    807        return 1

이름의 인덱스 부분 패딩 자릿수 가져오기

Args: inStr: 처리할 이름 문자열

Returns: 인덱스 패딩 자릿수

def increase_index(self, inStr, inAmount): View Source

    809    def increase_index(self, inStr, inAmount):
    810        """
    811        이름의 인덱스 부분 값 증가
    812
    813        Args:
    814            inStr: 처리할 이름 문자열
    815            inAmount: 증가시킬 값
    816
    817        Returns:
    818            인덱스가 증가된 이름 문자열
    819        """
    820        newName = inStr
    821        filChar = self._get_filtering_char(inStr)
    822        nameArray = self.convert_name_to_array(inStr)
    823        indexIndex = self.get_name_part_index("Index")
    824
    825        if indexIndex >= 0:
    826            indexStr = ""
    827            indexPaddingNum = self._paddingNum
    828            indexNum = -99999
    829
    830            if not nameArray[indexIndex]:
    831                indexNum = -1
    832            else:
    833                try:
    834                    indexNum = int(nameArray[indexIndex])
    835                    indexPaddingNum = len(nameArray[indexIndex])
    836                except ValueError:
    837                    pass
    838
    839            indexNum += inAmount
    840
    841            if indexNum < 0:
    842                indexNum = 0
    843
    844            # Python의 문자열 포맷팅을 사용하여 패딩
    845            indexStr = f"{indexNum:0{indexPaddingNum}d}"
    846            nameArray[indexIndex] = indexStr
    847            newName = self._combine(nameArray, filChar)
    848            newName = self.set_index_padding_num(newName)
    849
    850        return newName

이름의 인덱스 부분 값 증가

Args: inStr: 처리할 이름 문자열 inAmount: 증가시킬 값

Returns: 인덱스가 증가된 이름 문자열

def get_index_as_digit(self, inStr): View Source

    852    def get_index_as_digit(self, inStr):
    853        """
    854        이름의 인덱스를 숫자로 변환
    855
    856        Args:
    857            inStr: 변환할 이름 문자열
    858
    859        Returns:
    860            숫자로 변환된 인덱스 (넙이 있으면 -1, 인덱스가 없으면 False)
    861        """
    862        indexStr = self.get_name("Index", inStr)
    863
    864        if indexStr:
    865            try:
    866                return int(indexStr)
    867            except ValueError:
    868                pass
    869
    870        return False

이름의 인덱스를 숫자로 변환

Args: inStr: 변환할 이름 문자열

Returns: 숫자로 변환된 인덱스 (넙이 있으면 -1, 인덱스가 없으면 False)

def sort_by_index(self, inNameArray): View Source

    872    def sort_by_index(self, inNameArray):
    873        """
    874        이름 배열을 인덱스 기준으로 정렬
    875
    876        Args:
    877            inNameArray: 정렬할 이름 배열
    878
    879        Returns:
    880            인덱스 기준으로 정렬된 이름 배열
    881        """
    882        if not inNameArray:
    883            return []
    884
    885        # 정렬을 위한 보조 클래스 정의
    886        @dataclass
    887        class IndexSorting:
    888            oriIndex: int
    889            newIndex: int
    890
    891        # 각 이름의 인덱스를 추출하여 정렬 정보 생성
    892        structArray = []
    893
    894        for i, name in enumerate(inNameArray):
    895            tempIndex = self.get_index_as_digit(name)
    896
    897            if tempIndex is False:
    898                structArray.append(IndexSorting(i, 0))
    899            else:
    900                structArray.append(IndexSorting(i, tempIndex))
    901
    902        # 인덱스 기준으로 정렬
    903        structArray.sort(key=lambda x: x.newIndex)
    904
    905        # 정렬된 순서로 결과 배열 생성
    906        sortedNameArray = []
    907        for struct in structArray:
    908            sortedNameArray.append(inNameArray[struct.oriIndex])
    909
    910        return sortedNameArray

이름 배열을 인덱스 기준으로 정렬

Args: inNameArray: 정렬할 이름 배열

Returns: 인덱스 기준으로 정렬된 이름 배열

def get_string(self, inStr): View Source

    912    def get_string(self, inStr):
    913        """
    914        인덱스 부분을 제외한 이름 문자열 가져오기
    915
    916        Args:
    917            inStr: 처리할 이름 문자열
    918
    919        Returns:
    920            인덱스가 제외된 이름 문자열
    921        """
    922        filChar = self._get_filtering_char(inStr)
    923        nameArray = self.convert_name_to_array(inStr)
    924        indexOrder = self.get_name_part_index("Index")
    925
    926        # 인덱스 부분 제거
    927        returnNameArray = nameArray.copy()
    928        returnNameArray[indexOrder] = ""
    929
    930        return self._combine(returnNameArray, filChar)

인덱스 부분을 제외한 이름 문자열 가져오기

Args: inStr: 처리할 이름 문자열

Returns: 인덱스가 제외된 이름 문자열

def gen_mirroring_name(self, inStr): View Source

    932    def gen_mirroring_name(self, inStr):
    933        """
    934        미러링된 이름 생성 (측면 또는 앞/뒤 변경)
    935
    936        이름에서 Side와 FrontBack namePart를 자동으로 검색하고,
    937        발견된 값의 semanticmapping weight와 가장 차이가 큰 값으로 교체합니다.
    938
    939        Args:
    940            inStr: 처리할 이름 문자열
    941
    942        Returns:
    943            미러링된 이름 문자열
    944        """
    945        nameArray = self.convert_name_to_array(inStr)
    946
    947        for part in self._nameParts:
    948            partName = part.get_name()
    949            partType = part.get_type()
    950            if (partType != NamePartType.REALNAME or partType != NamePartType.INDEX) and part.is_direction():
    951                partIndex = self.get_name_part_index(partName)
    952                foundName = self.get_name(partName, inStr)
    953                opositeName = part.get_most_different_weight_value(foundName)
    954                if opositeName and foundName != opositeName:
    955                    nameArray[partIndex] = opositeName
    956
    957        returnName = self._combine(nameArray, self._get_filtering_char(inStr))
    958
    959        return returnName

미러링된 이름 생성 (측면 또는 앞/뒤 변경)

이름에서 Side와 FrontBack namePart를 자동으로 검색하고, 발견된 값의 semanticmapping weight와 가장 차이가 큰 값으로 교체합니다.

Args: inStr: 처리할 이름 문자열

Returns: 미러링된 이름 문자열

def replace_filtering_char(self, inStr, inNewFilChar): View Source

    961    def replace_filtering_char(self, inStr, inNewFilChar):
    962        """
    963        이름의 구분자 문자 변경
    964
    965        Args:
    966            inStr: 처리할 이름 문자열
    967            inNewFilChar: 새 구분자 문자
    968
    969        Returns:
    970            구분자가 변경된 이름 문자열
    971        """
    972        nameArray = self.convert_name_to_array(inStr)
    973        return self._combine(nameArray, inNewFilChar)

이름의 구분자 문자 변경

Args: inStr: 처리할 이름 문자열 inNewFilChar: 새 구분자 문자

Returns: 구분자가 변경된 이름 문자열

def replace_name_part(self, inPart, inStr, inNewName): View Source

    975    def replace_name_part(self, inPart, inStr, inNewName):
    976        """
    977        이름의 특정 부분을 새 이름으로 변경
    978
    979        Args:
    980            inPart: 수정할 부분 ("Base", "Type", "Side", "FrontBack", "RealName", "Index")
    981            inStr: 처리할 이름 문자열
    982            inNewName: 새 이름
    983
    984        Returns:
    985            수정된 이름 문자열
    986        """
    987        nameArray = self.convert_name_to_array(inStr)
    988        partIndex = self.get_name_part_index(inPart)
    989
    990        if partIndex >= 0:
    991            nameArray[partIndex] = inNewName
    992
    993        newName = self._combine(nameArray, self._get_filtering_char(inStr))
    994        newName = self.set_index_padding_num(newName)
    995
    996        return newName

이름의 특정 부분을 새 이름으로 변경

Args: inPart: 수정할 부분 ("Base", "Type", "Side", "FrontBack", "RealName", "Index") inStr: 처리할 이름 문자열 inNewName: 새 이름

Returns: 수정된 이름 문자열

def remove_name_part(self, inPart, inStr): View Source

     998    def remove_name_part(self, inPart, inStr):
     999        """
    1000        이름의 특정 부분 제거
    1001
    1002        Args:
    1003            inPart: 제거할 부분 ("Base", "Type", "Side", "FrontBack", "RealName", "Index")
    1004            inStr: 처리할 이름 문자열
    1005
    1006        Returns:
    1007            수정된 이름 문자열
    1008        """
    1009        nameArray = self.convert_name_to_array(inStr)
    1010        partIndex = self.get_name_part_index(inPart)
    1011
    1012        if partIndex >= 0:
    1013            nameArray[partIndex] = ""
    1014
    1015        newName = self._combine(nameArray, self._get_filtering_char(inStr))
    1016        newName = self.set_index_padding_num(newName)
    1017
    1018        return newName

이름의 특정 부분 제거

Args: inPart: 제거할 부분 ("Base", "Type", "Side", "FrontBack", "RealName", "Index") inStr: 처리할 이름 문자열

Returns: 수정된 이름 문자열

def load_from_config_file(self, configPath=None): View Source

    1020    def load_from_config_file(self, configPath=None):
    1021        """
    1022        설정 파일에서 설정 로드
    1023
    1024        Args:
    1025            configPath: 설정 파일 경로 (기본값: self._configPath)
    1026
    1027        Returns:
    1028            로드 성공 여부 (True/False)
    1029        """
    1030        # 경로가 없으면 인스턴스 생성 시 설정된 경로 사용
    1031        if not configPath:
    1032            configPath = self._configPath
    1033
    1034        if not configPath:
    1035            print("설정 파일 경로가 제공되지 않았습니다.")
    1036            return False
    1037
    1038        # NamingConfig 인스턴스 생성 및 설정 로드
    1039        config = NamingConfig()
    1040        if config.load(configPath):
    1041            # 설정을 Naming 인스턴스에 적용
    1042            result = config.apply_to_naming(self)
    1043            if result:
    1044                self._configPath = configPath  # 성공적으로 로드한 경로 저장
    1045            return result
    1046        else:
    1047            print(f"설정 파일 로드 실패: {configPath}")
    1048            return False

설정 파일에서 설정 로드

Args: configPath: 설정 파일 경로 (기본값: self._configPath)

Returns: 로드 성공 여부 (True/False)

def load_default_config(self): View Source

    1050    def load_default_config(self):
    1051        """
    1052        기본 설정 로드 (현재는 아무 작업도 수행하지 않음)
    1053
    1054        Returns:
    1055            항상 True 반환 (기본 설정은 __init__에서 이미 설정됨)
    1056        """
    1057        # 이 메소드는 현재 __init__에서 설정한 기본값을 그대로 사용하므로
    1058        # 아무 작업도 수행하지 않습니다.
    1059        return True

기본 설정 로드 (현재는 아무 작업도 수행하지 않음)

Returns: 항상 True 반환 (기본 설정은 __init__에서 이미 설정됨)

def get_config_path(self): View Source

    1061    def get_config_path(self):
    1062        """
    1063        현재 설정 파일 경로 가져오기
    1064
    1065        Returns:
    1066            설정 파일 경로 (없으면 빈 문자열)
    1067        """
    1068        return self._configPath or ""

현재 설정 파일 경로 가져오기

Returns: 설정 파일 경로 (없으면 빈 문자열)