버그하우스
축하합니다. 당신은 Crooked Orbit의 기술 책임자가 되었습니다. 이곳은 의심스러운 우주비행사들과 더 의심스러운 코드로 운영되는 작고 약간 혼란스러운 우주 물류 회사입니다.
급여는 괜찮습니다. 코드베이스는 그렇지 않고요...
당신의 일은 이 문제들을 해결하는 것입니다: 버그, 망가진 함수, 기술적으로는 실행되지만 정말 그래선 안 되는 것들.
#1: 이름 포매터
.capitalize()를 호출하고 있고, 루프 안에 분명히 보이는데요. 이해가 안 돼요. 좀 봐주실 수 있나요? def format_name(full_name):
parts = full_name.split()
for part in parts:
part = part.capitalize()
return " ".join(parts)
print(format_name("alice van den berg"))기대 결과: Alice Van Den Berg
실제 결과: alice van den berg
무엇이 잘못되었고, 어떻게 고칠 수 있을까요?
힌트
for 루프 안에서 변수를 재할당하면 실제로 어떤 일이 일어나는지 생각해보세요. part를 바꾸면 그것이 나온 리스트에 영향을 줄까요?
해결 방법 한 가지
for part in parts라고 쓰면 Python은 리스트의 항목을 하나씩 차례로 줍니다. part는 현재 항목을 담고 있는 임시 변수일 뿐이에요. 리스트 자체와 직접 연결된 것이 아닙니다.
그래서 part = part.capitalize()라고 쓰면 part가 가리키는 것을 바꾸는 것일 뿐이에요. parts는 여전히 원래 문자열들을 가지고 있습니다. 리스트는 실제로 바뀐 적이 없어요.
이걸 명확하게 보여주는 예시입니다:
parts = ["alice", "van", "den", "berg"]
for part in parts:
part = part.capitalize()
print(parts)
# ['alice', 'van', 'den', 'berg'] # 아무것도 바뀌지 않음해결하려면 대문자화된 값으로 새로운 리스트를 만들어야 합니다. 리스트 컴프리헨션이 이걸 깔끔하게 해줍니다:
def format_name(full_name):
parts = full_name.split()
return " ".join(part.capitalize() for part in parts)
print(format_name("alice van den berg"))
# Alice Van Den Bergpart.capitalize() for part in parts는 각 이름을 거치면서 대문자화하고, 결과를 새로운 리스트로 모읍니다. 그런 다음 .join()이 공백으로 다시 합쳐줍니다.
#2: 최고 점수
None을 출력해요? 매번요. 루프를 다섯 번이나 검토해봤는데 로직은 괜찮아 보여요. 점수는 분명히 들어있고요. 무슨 일인지 모르겠어요 😅 def highest_score(scores):
best = 0
for score in scores:
if score > best:
best = score
results = [45, 92, 78, 88, 65]
print(f"Top score: {highest_score(results)}")기대 결과: Top score: 92
실제 결과: Top score: None
무엇이 잘못되었고, 어떻게 고칠 수 있을까요?
힌트
return 문을 작성하지 않으면 함수는 무엇을 반환할까요?
해결 방법 한 가지
루프는 괜찮습니다. 로직도 괜찮아요. 문제는 highest_score가 실제로 아무것도 돌려주지 않는다는 거예요. 최고 점수를 찾고는 그걸로 아무것도 하지 않습니다.
Python에서 함수에 return 문이 없으면 자동으로 None을 반환합니다. 그게 바로 당신이 출력하고 있는 것이에요.
수정은 마지막 한 줄이면 됩니다:
def highest_score(scores):
best = 0
for score in scores:
if score > best:
best = score
return best
results = [45, 92, 78, 88, 65]
print(f"Top score: {highest_score(results)}")
# Top score: 92이건 자주 발생합니다. 로직이 다 있어서 함수가 완성된 것처럼 보이지만, return이 없으면 함수가 끝날 때 결과가 그냥 사라져버립니다.
#3: 예산 체크
def check_budget(threshold):
spent = input("How much have you spent? ")
if spent >= threshold:
print("Over budget!")
else:
print("You're within budget.")
check_budget(500.0)에러:
TypeError: '>=' not supported between instances of 'str' and 'float'무엇이 잘못되었고, 어떻게 고칠 수 있을까요?
힌트
input()은 사용자가 무엇을 입력하든 상관없이 항상 어떤 타입을 반환하나요?
해결 방법 한 가지
input()은 항상 문자열을 반환합니다. 사용자가 숫자를 입력했는지는 상관없어요. Python은 그걸 모르거든요. 입력된 것을 그냥 텍스트로 돌려줄 뿐입니다.
그래서 코드가 spent >= threshold를 비교하려고 할 때 문자열과 float를 비교하게 되고, Python은 그걸 거부합니다. 그게 바로 TypeError예요.
해결책은 비교하기 전에 입력값을 숫자로 변환하는 것입니다. 소수점 값을 처리하려면 float()를 사용하세요:
def check_budget(threshold):
spent = float(input("How much have you spent? "))
if spent >= threshold:
print("Over budget!")
else:
print("You're within budget.")
check_budget(500.0)
# How much have you spent? 620
# Over budget!input()을 float()로 감싸면 문자열이 바로 숫자로 변환되어 비교가 예상대로 작동합니다.
이건 Python에서 가장 흔한 혼란 중 하나입니다: input()은 숫자를 읽는 것처럼 보이지만 항상 문자열을 줍니다. 직접 변환해야 합니다.
#4: 화물 라벨
def cargo_label(item, weight):
label = "Item: " + item + " | Weight: " + weight + "kg"
return label
print(cargo_label("Moon rocks", 42))에러:
TypeError: can only concatenate str (not "int") to str무엇이 잘못되었고, 어떻게 고칠 수 있을까요?
힌트
Python의 + 연산자는 숫자를 자동으로 문자열로 변환하지 않습니다. 합치기 전에 무엇을 해야 할까요?
해결 방법 한 가지
Python에서 +로 문자열을 합칠 때는 모든 값이 문자열이어야 합니다. weight는 정수이기 때문에 Python은 그것을 주변 텍스트에 붙이는 방법을 모릅니다. 추측하지 않고 거부합니다.
해결책은 str()로 weight를 문자열로 변환하는 것입니다:
def cargo_label(item, weight):
label = "Item: " + item + " | Weight: " + str(weight) + "kg"
return label
print(cargo_label("Moon rocks", 42))
# Item: Moon rocks | Weight: 42kg이런 경우에는 f-string이 더 깔끔합니다. 변환을 알아서 처리해주니까요:
def cargo_label(item, weight):
return f"Item: {item} | Weight: {weight}kg"
print(cargo_label("Moon rocks", 42))
# Item: Moon rocks | Weight: 42kg{} 안에서 Python은 값을 자동으로 문자열 표현으로 변환합니다. 그래서 str()이 전혀 필요 없어요.
#5: 승객 명단
def build_manifest(name, passengers=[]):
passengers.append(name)
return passengers
flight_1 = build_manifest("민준")
flight_2 = build_manifest("서연")
flight_3 = build_manifest("지호")
print(flight_1)
print(flight_2)
print(flight_3)기대 결과:
['민준']
['서연']
['지호']실제 결과:
['민준']
['민준', '서연']
['민준', '서연', '지호']무엇이 잘못되었고, 어떻게 고칠 수 있을까요?
힌트
Python의 기본 인자 값은 함수가 정의될 때 한 번만 평가됩니다. 함수가 호출될 때마다가 아니에요. 리스트 같은 가변 객체에 대해서는 이게 무엇을 의미할까요?
해결 방법 한 가지
이건 Python에서 가장 유명한 함정 중 하나입니다. passengers=[]를 기본 인자로 쓰면 Python은 함수가 정의될 때 그 리스트를 한 번만 만듭니다. 기본값을 사용하는 모든 호출은 정확히 똑같은 리스트 객체를 공유합니다. 그래서 한 호출에서 리스트에 추가하면 이후의 모든 호출에 영향을 줍니다.
표준 해결책은 기본값으로 None을 사용하고 함수 안에서 새 리스트를 만드는 것입니다:
def build_manifest(name, passengers=None):
if passengers is None:
passengers = []
passengers.append(name)
return passengers
flight_1 = build_manifest("민준")
flight_2 = build_manifest("서연")
flight_3 = build_manifest("지호")
print(flight_1) # ['민준']
print(flight_2) # ['서연']
print(flight_3) # ['지호']이제 리스트를 전달하지 않는 각 호출은 완전히 새로운 자신만의 리스트를 갖게 됩니다.
이건 모든 가변 기본값에 적용됩니다: 리스트, 딕셔너리, 집합. 매번 새로운 것을 원한다면 시그니처에 두지 마세요. None을 사용하고 함수 안에서 생성하세요.

