오늘은 프로그래밍 주차 개인과제를 마무리하고 튜터님 강의를 통해서 복습을 했다. 개인과제 마지막 단계를 하면서 어떻게 짤지 고민하는 가진 뒤에 코드를 작성했는데, 코드를 살펴보니 개선 점이 많아서 기존에 공부했던 내용들을 복습하고 함수들을 찾아보면서 어떻게 하면 더 나은 코드를 만들 수 있을 지 고민을 많이 했던 것 같다.
1) 2-4 가장 많이 판매된 제품의 이름과 수량을 반환하는 함수 작성
def find_top_seller(sales_data):
key = list(sales_data.keys()) # key값 리스트
value = list(sales_data.values()) # value값 리스트
max_sales = max(value) # 최대 value 탐색
top_product = key[value.index(max_sales)] # 최대 value의 index로 key값을 추적
return top_product, max_sales
# 예시 데이터
sales_data = {
"Motherboard": 50,
"SSD": 2,
"Graphics Card": 30,
}
print("가장 많이 판매된 제품과 수량 :", find_top_seller(sales_data))
아이디어
1. key와 value값을 각각 분리하여 리스트화 함
2. 분리하고 나서도 index 위치는 동일하므로 그 점을 이용하여 value값의 index로 key값을 찾아냄
우선 지난 주에 위와 같은 아이디어를 바탕으로 작성했던 코드이다.
# 예시 데이터
sales_data = {
"Motherboard": 50,
"SSD": 2,
"Graphics Card": 30,
"HDD": 50,
"RAM": 50
}
하지만 예시 데이터를 위의 내용처럼 top_product에 해당하는 항목이 2개 이상이 되었을 때
가장 많이 판매된 제품과 수량 : ('Motherboard', 50)
출력 값이 하나만 나온다는 문제점이 있었다. 따라서 새로운 예시 데이터에서 (['Motherboard','HDD','RAM'], 50)와 같은 결과를 얻기 위해 코드를 보완할 필요가 있었다.

for i in range (len(value)):
if value[i] != max_sales: # max value값을 가지지 않을 경우
top_products.remove(key[i]) # 해당하는 key를 제거
지난주에 생각해 두었던 아이디어를 가져와서, 실제로 코드를 작성해보니
1. for문에서 remove가 실행되면서 리스트의 길이가 줄어들었고
2. 이미 리스트가 짧아졌는데 key[i]는 여전히 원래 인덱스를 찾으려고 하여
3. 존재하지 않는 번호를 부르니 **IndexError**가 발생했다
for i in range (len(value)):
if value[i] == max_sales: # max value값을 가지지 않을 경우
top_products.append(key[i]) # 해당하는 key를 추가
따라서 오류 해결을 위해, 기존의 리스트를 remove 하는것 대신 append로 새로운 리스트에 추가하는 방식을 채택했다.
def find_top_seller(sales_data):
key = list(sales_data.keys()) # key값 리스트
value = list(sales_data.values()) # value값 리스트
max_sales = max(value)
top_products = []
for i in range (len(value)):
if value[i] == max_sales: # max value값을 가지지 않을 경우
top_products.append(key[i]) # 해당하는 key를 추가
return top_products, max_sales
# 새로운 데이터
sales_data = {
"Motherboard": 50,
"SSD": 2,
"Graphics Card": 30,
"HDD": 50, # 가장 많이 판매된 제품 추가
"RAM": 50
}
print("가장 많이 판매된 제품과 수량 :", find_top_seller(sales_data))
그렇게 기존 코드를 수정하여 top_products를 리스트의 형태로 반환하도록 고쳐줬고
가장 많이 판매된 제품과 수량 : (['Motherboard', 'HDD', 'RAM'], 50)
의도대로 결과물을 얻을 수 있었다.
하지만, 여기서 끝이 아니다.
key = list(sales_data.keys()) # key값 리스트
value = list(sales_data.values()) # value값 리스트
복습을 하다보니, 다른 딕서녀리의 관련 예제에서는 key값과 value값을 따로 나눠서 사용하지 않고 items() 함수를 이용하여
튜플 형태로 반환받아 사용하고 있었다.
def find_top_seller(sales_data):
max_sales = max(sales_data.values())
top_products = []
for product, sales in sales_data.items():
if sales == max_sales:
top_products.append(product) # 해당하는 key를 추가
return top_products, max_sales
결과적으로 items()를 채용하여 불필요한 변수를 제거하여 코드를 더 깔끔하게 작성할 수 있었다.
> remove를 통해 기존 코드를 제거하는 것보다 append를 통하여 추가하는 것이 안전성면에서 중요.
> 딕셔너리를 이용할 때 items()와 두개의 변수를 받는 for문을 이용하여 코드를 줄일 수 있음.
2) 3-1 무게 데이터 단위 표준화

오늘은 대망의 3단계 과제를 시작했는데, 1~2 단계 과제와 다르게 코드를 조금더 자율적으로 작성할 수 있었다.
아이디어
1. g, kg 단위는 항상 맨 뒤에 붙는다
2. '-2' index에서 'k'의 여부를 확인해준다.
3. k가 존재할 경우 kg으로 판단하고 존재하지 않을 경우 g으로 판단하여 변환해준다.
def normalize_weights(weight_list):
new_list = []
for w in weight_list:
if w[-2]=="k": # endswith("kg")으로 대체 가능해보임
new_list.append(int(float(w[:-2])*1000)) #0.5kg가 정수가 아니므로 float으로 변환해서 곱해주고 int로 다시 변환
else:
new_list.append(int(w[:-1]))
return new_list
# 제품 무게 리스트
weight_list = ["0.5kg", "500g", "1kg", "750g", "2kg"]
# 단위 통일 실행
normalize_weights(weight_list)
간단하게 코드를 작성하고 실행했을 때, 코드에 오류가 났는데
그 이유는 0.5kg의 경우 kg의 단위를 제외하고 봤을때 float 자료형이었기 때문이다.
int(float(w[:-2])*1000)
따라서 str을 float 자료형으로 변환해 연산을 진행해주고 이후 다시 int로 변환해 전체 데이터를 통일해 주었다.
[500, 500, 1000, 750, 2000]
결과적으로 목표에 맞게 알맞은 결과물을 얻을 수 있었다.
하지만, 여기서 끝이 아니다.
1. 끝 부분만 슬라이싱으로 추출하는 것은 단위가 바뀌거나 했을 때 유동적으로 코드를 사용하기 힘들어 보였고
2. kg, g와 같이 숫자와 문제가 혼용되는 경우 데이터의 전처리가 필수적이었다.
3. 따라서 데이터 전처리 후 if 변수 in ~ 의 조건문을 활용해보자고 생각했다.
w = w.strip().lower() # 데이터 전처리 (공백 제거, 소문자로 변경)
우선 2 kg처럼 사이에 공백이 있을 수 있으므로 공백을 제거해 주었고
Kg, kG, G 처럼 대문자 소문자가 섞여서 들어올 수 있으므로 소문자로 변경하여 데이터를 전처리 해주었다.
if "kg" in w:
w_new = w.replace("kg","") # replace는 반환값이 있어 w를 직접 수정하지는 않으므로 새로운 변수 필요
new_list.append(int(float(w_new)*1000))
elif "g" in w:
w_new = w.replace("g","")
new_list.append(w_new)
이후 if "str" in 을 통해서 kg을 찾아준 뒤, replace를 통해서 문자를 제거해주었다.
이때, replace를 실행시키는 것만으로는 "kg"이 제거 되지 않기 때문에 새로운 변수 w_new에 return 값을 넣어주었다.
def normalize_weights(weight_list):
new_list=[]
for w in weight_list:
w = w.strip().lower() # 데이터 전처리 (공백 제거, 소문자로 변경)
if "kg" in w:
w_new = w.replace("kg","") # replace는 반환값이 있어 w를 직접 수정하지는 않으므로 새로운 변수 필요
new_list.append(int(float(w_new)*1000))
elif "g" in w:
w_new = w.replace("g","")
new_list.append(w_new)
return new_list
"g'의 경우에도 동일한 방법으로 코드를 작성해서 더욱 완성도 있는 코드를 만들 수 있었다.
3) 3-2 혼합된 설비 코드를 전처리하는 프로그램 구현

딱 마지막 코드는 목표를 읽자마자 if문을 떠올렸고, 쉬운 문제구나 ! 이렇게 생각을 했다.
> 데이터 전처리를 신경쓸것 (대소문자 통일, 공백 제거 등)
> replace는 ""를 이용하여 문자의 일부를 제거할 수 있음
아이디어
1. 코드 리스트에서 하나의 코드 추출 (for문 이용), 이후 코드에서 한 글자 씩 추출하여 검사 (이중 for문)
2. 검사 결과 한글 숫자 여부를 판단하고 아라비아 숫자로 변환
def equipment_code_decoder(code_list):
code_return=[]
for code in code_list:
converted_code=""
for in_code in code:
if in_code=="영" or in_code=="0":
converted_code+="0"
elif in_code=="일" or in_code=="1":
converted_code+="1"
elif in_code=="이" or in_code=="2":
converted_code+="2"
elif in_code=="삼" or in_code=="3":
converted_code+="3"
elif in_code=="사" or in_code=="4":
converted_code+="4"
elif in_code=="오" or in_code=="5":
converted_code+="5"
elif in_code=="육" or in_code=="6":
converted_code+="6"
elif in_code=="칠" or in_code=="7":
converted_code+="7"
elif in_code=="팔" or in_code=="8":
converted_code+="8"
elif in_code=="구" or in_code=="9":
converted_code+="9"
code_return.append(converted_code) # 변환된 코드 리스트를 마지막에 return 해주기 위해서 추가함
print(f"[{code}]에 대한 설비 코드는 [{converted_code}]입니다.")
return code_return
# 설비 코드 목록
code_list = [
"삼5이사",
"0오6칠",
"48삼구",
"이74팔",
"9일이삼"
]
# 코드 변환 함수 실행
equipment_code_decoder(code_list)
아이디어를 바탕으로 코드를 작성한 결과. 누가봐도 코드에 너무 많은 반복이 있었다.
if in_code=="영" or in_code=="0":
심지어 if 문에서도 삼5이사의 경우, 한글숫자만 변환되어 324 이런식으로 출력되었기 때문에 or을 추가해서 더 복잡하고
'복사 붙여넣기' 코드가 되어버렸다.
그래서 문자열을 숫자로 변환하는 방법을 구글링해봤는데 여려가지 많은 방법중 두가지를 적용해보았다.
첫번째는, 딕셔너리 활용이다.
convert = {
"영": "0", "일": "1", "이": "2", "삼": "3", "사": "4",
"오": "5", "육": "6", "칠": "7", "팔": "8", "구": "9"
}
1. 이런식으로 key:value를 변환대상:변환값으로 정리하여 딕셔너리로 만들어두고
2. 코드의 값에 하나씩 접근하면서 딕셔너리의 key값과 비교한 뒤
3. 한글숫자일 경우 value값으로 바꿔주면 되는 것이다.
def equipment_code_decoder(code_list):
code_return=[]
for code in code_list:
converted_code=""
for char in code:
if char in convert:
converted_code+=convert[char]
else:
converted_code+=char
code_return.append(converted_code)
print(f"[{code}]에 대한 설비 코드는 [{converted_code}]입니다.")
return code_return
convert = {
"영": "0", "일": "1", "이": "2", "삼": "3", "사": "4",
"오": "5", "육": "6", "칠": "7", "팔": "8", "구": "9"
}
if 문으로 code의 한 글자씩 가져와 딕셔너리의 key에 동일한 값이 있으면 value값을 넘겨주고,
아니라면 code의 한 글자를 그대로 넘겨주는 방식으로 코드를 훨씬 더 깔끔하게 작성할 수 있었다.
하지만, 여기서 끝이 아니다.
두 번째 방법으로, 지금과 같은 상황에 쓰기 적합한 translate를 발견했다.
trans_code = str.maketrans("영일이삼사오육칠팔구", "0123456789")
위의 내용처럼 index의 길이가 동일한 두 문자열을 넣어두면, index 위치에 따라 1대1로 대응이되어 변환이 되는 것이다.
def equipment_code_decoder(code_list):
code_return=[]
trans_code = str.maketrans("영일이삼사오육칠팔구", "0123456789")
for code in code_list:
converted_code = code.translate(trans_code)
code_return.append(converted_code)
print(f"[{code}]에 대한 설비 코드는 [{converted_code}]입니다.")
return code_return
code.translate(trans_code)를 통해 문자열에 한글숫자가 있으면 편리하게 아라비아 숫자로 변환이 되었고, 결과적으로 매우 짧고 간단한 코드를 작성할 수 있었다.
> 문자열 치환을 할때 딕셔너리나 translate와 같은 함수를 사용하면 더욱 쉽고 간단하게 수행할 수 있음
오늘은 이렇게 개인과제를 마무리 했고 코드를 어떻게 하면 개선할 수 있을지 혹은 데이터가 바뀌었을때도 적용할 수 있는지 실제로 고민해보며 파이썬 실력을 키운 것 같다. 앞으로도 이런 사고방식을 바탕으로 파이썬을 배워나가야겠다.
'내일배움캠프 > TIL(Today I Learned)' 카테고리의 다른 글
| [2026/03/25] 내일배움캠프 13일차 TIL (0) | 2026.03.25 |
|---|---|
| [2026/03/24] 내일배움캠프 12일차 TIL (0) | 2026.03.24 |
| [2026/03/20] 내일배움캠프 10일차 TIL (0) | 2026.03.20 |
| [2026/03/19] 내일배움캠프 9일차 TIL (0) | 2026.03.19 |
| [2026/03/18] 내일배움캠프 8일차 TIL (0) | 2026.03.18 |