사실 이번 글을 이 카테고리에 써도 되나 모르겠다.
그래도 배우는 것이긴 하니 일단 여기에 쓴다.
1. Log
요즘 GPT 모르는 사람이 없다.
얘가 코드도 짜준다더라.
있는 걸 갖다 넣으면 리팩터링도 해주고.
그래서 내 기존 봇 코드를 이를 활용해 리팩터링 해 보기로 했다.
아래는 기존에 내가 작성한 코드다.
class types(Enum):
INFO = 1
ERROR = 2
DEBUG = 3
UNKNOWN = 4
class Colors:
BLACK = '[\033[30m'
RED = '[\033[31m'
GREEN = '[\033[32m'
YELLOW = '[\033[33m'
BLUE = '[\033[34m'
MAGENTA = '[\033[35m'
CYAN = '[\033[36m'
WHITE = '[\033[37m'
UNDERLINE = '[\033[4m'
RESET = '\033[0m]'
class Logger:
def __init__(self):
super().__init__()
Logger.KST = timezone('Asia/Seoul')
#Logging function
@staticmethod
def pushLog(lTypes, content, datetime):
from Database.dynamo import awsDynamo as ad
handle = ad()
data = {
"LOG": "LOG",
"logNumber": handle.getLogNumber() + 1,
"content": content,
"dateTime": f'{datetime}',
"logType": lTypes
}
handle.push(data, 'log')
@staticmethod
def info(content):
today = datetime.now().astimezone(Logger.KST)
lt = Colors.BLUE + types.INFO.name + Colors.RESET
Logger.pushLog(types.INFO.name, content, today)
# Print log on terminal
print(f'[{today}]', end=" ")
print('{type:<18} {str}'.format(type = lt, str = content))
이때만 해도 동작에 문제가 없고 내가 다 알아볼 수 있으니 그만이라고 생각했다.
이걸 리팩터링을 돌려봤더니,
class LogType(Enum):
INFO = 'INFO'
ERROR = 'ERROR'
DEBUG = 'DEBUG'
UNKNOWN = 'UNKNOWN'
class Colors:
BLACK = '\033[30m'
RED = '\033[31m'
GREEN = '\033[32m'
YELLOW = '\033[33m'
BLUE = '\033[34m'
MAGENTA = '\033[35m'
CYAN = '\033[36m'
WHITE = '\033[37m'
UNDERLINE = '\033[4m'
RESET = '\033[0m'
class Logger:
KST = timezone('Asia/Seoul')
@staticmethod
def push_log(log_type, content, datetime):
from Database.dynamo import awsDynamo as ad
handle = ad()
data = {
"LOG": "LOG",
"logNumber": handle.getLogNumber() + 1,
"content": content,
"dateTime": f'{datetime}',
"logType": log_type.value
}
handle.push(data, 'log')
@staticmethod
def log(log_type, content):
today = datetime.now(Logger.KST)
color = {
LogType.INFO: Colors.BLUE,
LogType.ERROR: Colors.RED,
LogType.DEBUG: Colors.GREEN,
LogType.UNKNOWN: Colors.YELLOW
}.get(log_type, Colors.RESET)
Logger.push_log(log_type, content, today)
# Print log on terminal
print(f'[{today}]', end=" ")
print('{type:<18} {str}'.format(type=color + log_type.value + Colors.RESET, str=content))
@staticmethod
def info(content):
Logger.log(LogType.INFO, content)
이런 식으로 리팩터링을 해 줬다.
아... 확실해 내가 해 놓은 것보다 간결하다고 생각했다.
특히 색깔을 설정하는 부분에 있어서 「get(log_type, Colors.RESET)」이 부분은 정말 생각지도 못했다.
생각지도 못한 것이 아니라 아예 몰랐다고 해야겠다.
다음에 코드를 짤 때 이는 활용할 듯하다.
2. Button
다른 코드들도 리팩터링을 진행했고, 이번엔 버튼 클래스 리팩터링에 대해 다룬다.
아래는 기존 내가 작성한 코드다.
# Entry a draw
@discord.ui.button(label="줄 서기", style=discord.ButtonStyle.green, custom_id='entry')
async def doEntry(self, btnInteraction: discord.Interaction, button: discord.ui.Button):
if(self.ebdIntr.user.id != btnInteraction.user.id):
# Append user info to entryList in Tuple
if(not self.ad.checkExist(self.lNum, btnInteraction.user.id)):
start_time = int(time.time())
data = {
"linenumber": self.lNum,
"entryuserID": btnInteraction.user.id,
"entryuserName": btnInteraction.user.display_name,
"entrytime": f'{datetime.datetime.fromtimestamp(start_time)}'
}
self.ad.push(data, 'entrylist')
lg.info(f"{btnInteraction.user.display_name} Entry at {self.ebdIntr.user.display_name}'s {self.prize} Line.")
await btnInteraction.response.send_message("줄 서기 완료!", ephemeral=True)
else:
await btnInteraction.response.send_message("이미 줄 스신거 같은데...", ephemeral=True)
else:
await btnInteraction.response.send_message("줄 세운 사람이 줄 스면 어쩌나?", ephemeral=True)
사실 예전부터 저 불필요한 네스팅을 없애려고 했다.
그런데 네스팅이 엄청 큰 코드에서 이루어진 것이 아니고, 오버헤드란 게 없다시피 하기 때문에 방치했었다.
사실 귀찮았는데, 이를 GPT는 아래와 같이 리팩터링 해 줬다.
if self.ebdIntr.user.id == btnInteraction.user.id:
await btnInteraction.response.send_message("줄 세운 사람이 줄 스면 어쩌나?", ephemeral=True)
return
if self.ad.checkExist(self.lNum, btnInteraction.user.id):
await btnInteraction.response.send_message("이미 줄 스신거 같은데...", ephemeral=True)
return
start_time = int(time.time())
data = {
"linenumber": self.lNum,
"entryuserID": btnInteraction.user.id,
"entryuserName": btnInteraction.user.display_name,
"entrytime": f'{datetime.datetime.fromtimestamp(start_time)}'
}
self.ad.push(data, 'entrylist')
lg.info(f"{btnInteraction.user.display_name} joined {self.ebdIntr.user.display_name}'s {self.prize} line.")
await btnInteraction.response.send_message("줄 서기 완료!", ephemeral=True)
Brilliant!
내가 표준어로 작성하지 않은 피드백 부분도 알아서 AI가 무슨 말인지 캐치하고 영어로 작성해 주더라.
그래서 일단 그 부분은 내가 기존에 쓰던 스트링으로 다시 교체를 했다.
불필요한 네스팅도 해결해 주고, 문법적 오류도 다 잡아주니 거 참 이걸 쓰지 아니할 이유가 없다 하겠다.
3. 컨벤션
이 녀석은 심지어 각 언어별 통용되는 컨벤션에 맞게 코드도 고쳐준다.
대체 너의 힘은 어디까지인 거냐?
예를 들어보면 아래와 같다.
# 기존의 C스타일의 냄새가 남은 코드
if(len(res) != 0):
for tmp in res:
# Get each user's display name
tmp = tmp['entryuserID']
tmpList.append(f'<@{tmp}>')
tmpStr = '\n'.join(tmpList)
# Print users' display name by tagging
await btnInteraction.response.send_message(tmpStr, ephemeral=True)
else:
await btnInteraction.response.send_message("참가자가 없어요.", ephemeral=True)
# AI가 작성한 파이썬 스타일의 코드
if not res:
await btnInteraction.response.send_message("There are no participants in this line.", ephemeral=True)
return
participants = [f'<@{entry["entryuserID"]}>' for entry in res]
participant_list = '\n'.join(participants)
await btnInteraction.response.send_message(f"{self.ebdIntr.user.display_name}의 {self.prize} 줄의 참가자:\n{participant_list}", ephemeral=True)
난 프로그래밍 공부의 첫걸음을 C로 떼었고, 이 봇을 만들기 전까지도 C++과 C# 위주의 프로그램만 작성했다.
그럼 당연히 C의 스타일이 몸에 밸 수밖에 없다.
조건문을 작성할 때도 파이썬의 not이나 and가 아닌 !와 &가 편하다.
반복문을 돌리는 것도 for(int i = 0; ・・・)가 편하다.
하지만 파이썬에선 for_each 스타일의 반복문을 사용하게 된다.
이는 정말 적응이 힘들었다.
함수 이름도 생각해 보자.
여기서도 C냄새가 나는 함수 네이밍을 파이썬 컨벤션에 맞게 고쳐준다.
앞으로 파이썬으로 뭘 만들진 모르겠지만 이런 컨벤션을 지키도록 노력해 봐야겠다.
4. 마무리
여하튼 리팩터링을 통해 자신이 얼마나 C스타일로 파이썬 코드를 짜고 있는지 실감했다.
그리고 프로그래밍에 LLM을 활용한다는 것에 신기함을 느끼기도 했다.
이런 후회도 들었다.
대학 시절 내 지도교수님이 자연어 처리에 대한 연구를 하시는 분이었는데,
대학원까지 따라가서 공부했다면 재밌지 않았을까 하는... 후회.
그땐 뭘 잘 몰랐었다.
사람말을 알아듣고 그에 맞게 처리해 주는 기계라니 재밌지 않을 수 없지 않은가.
앞으로의 프로그래밍에 이를 활용하여 나의 부족한 부분을 보완해 나갈 수 있다니...
마치 구글, 스택 오버플로우 그리고 인도인 수학 유튜브 영상을 작은 곳에 집약한 느낌이라
참으로 든든하다는 생각이 든다.
'Study > Python' 카테고리의 다른 글
[Python] DeepL 번역 API 써보기 (0) | 2023.06.02 |
---|---|
[Python] 단위 변환 (0) | 2023.05.21 |
[Python, AWS] csv에서 DynamoDB에로의 교체 (0) | 2023.05.10 |
[Python] 로깅 클래스 추가 (0) | 2023.04.03 |
[Python] 봇에 Epoch Converter 추가 (0) | 2023.03.29 |