7~10주차 — 딕셔너리와 집합 · 문자열 다루기 · 함수 기초 · 기초 종합 실습
키로 값을 빠르게 찾는 딕셔너리, 자주 쓰는 메서드(get, items, in), 중복 없는 집합과 합/교/차/대칭차 연산, 그리고 자료구조 선택 기준을 익힙니다. 문자열 인덱싱/슬라이싱, 자주 쓰는 메서드(split/join/strip/replace), f-string 심화(정렬·자릿수·진법), 이스케이프 문자(\n \t)를 익힙니다. def 로 함수를 정의하고 호출, 매개변수와 인수의 차이, 기본값/키워드 인수, return으로 값 반환, 그리고 지역/전역 변수의 스코프를 익힙니다. 지금까지 배운 입력·조건·반복·자료구조·함수를 자연스럽게 조합해 작은 프로그램을 완성합니다. To-Do List, 단어장 퀴즈, 가계부, 숫자 야구 중 하나를 골라 만들어보세요.
이 강의에서 배우는 것
- 1딕셔너리 생성·키 접근·수정
- 2자주 쓰는 메서드 (get, items, keys)
- 3집합(set) 연산 (합집합/교집합/차집합)
- 4자료구조 선택 기준
- 5문자열 인덱싱·슬라이싱
- 6자주 쓰는 메서드 (split, join, strip, replace 등)
- 7f-string 심화 (정렬·자릿수)
- 8이스케이프 문자 (\n, \t)
- 9def 로 함수를 정의하고 호출한다
- 10매개변수와 인수의 차이를 안다
- 11기본값 매개변수, 키워드 인수를 사용한다
- 12return 으로 값을 반환한다
- 13변수의 스코프(지역/전역)를 이해한다
- 14지금까지 배운 모든 내용을 합쳐 작은 프로그램을 완성한다
- 15입력·조건·반복·자료구조·함수를 자연스럽게 조합한다
- 16디버깅과 코드 정리 경험을 쌓는다
7주차 — 딕셔너리와 집합
키로 값을 빠르게 찾는 딕셔너리, 자주 쓰는 메서드(get, items, in), 중복 없는 집합과 합/교/차/대칭차 연산, 그리고 자료구조 선택 기준을 익힙니다.
1. 딕셔너리란
키(key) → 값(value) 의 매핑. 순서 X (3.7+ 부터는 입력 순서 유지). 중괄호 {...}.
student = {"name": "홍길동", "age": 20, "major": "CS"}
print(student["name"]) # 홍길동
student["age"] = 21 # 수정
student["email"] = "..." # 추가
del student["major"] # 삭제키는 보통 문자열 또는 숫자, 값은 어떤 타입이든 가능.
2. 자주 쓰는 메서드
d = {"a": 1, "b": 2, "c": 3}
print(d.keys()) # dict_keys(['a', 'b', 'c'])
print(d.values()) # dict_values([1, 2, 3])
print(d.items()) # dict_items([('a', 1), ...])
# get: 안전하게 조회 (키 없어도 에러 X)
print(d.get("z")) # None
print(d.get("z", "기본값")) # 기본값
# in: 키 존재 확인
print("a" in d) # True3. 딕셔너리 순회
for key in d: # 키만
print(key)
for key, value in d.items(): # 키-값 동시
print(f"{key} = {value}")4. 집합 (set)
중복 없는 원소의 모음. 순서 X. 중괄호 {...} (단, 빈 set은 set()).
fruits = {"사과", "바나나", "포도"}
fruits.add("딸기")
fruits.discard("바나나") # 없으면 무시
print(len(fruits))
# 중복 자동 제거
nums = [1, 2, 2, 3, 3, 3]
unique = set(nums) # {1, 2, 3}5. 집합 연산
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a | b) # 합집합 {1,2,3,4,5,6}
print(a & b) # 교집합 {3,4}
print(a - b) # 차집합 {1,2}
print(a ^ b) # 대칭차 {1,2,5,6}6. 자료구조 선택 기준
| 상황 | 선택 |
|---|---|
| 순서 중요, 인덱스로 접근 | 리스트 |
| 변경 불필요, 빠르게 | 튜플 |
| 키로 값 조회 | 딕셔너리 |
| 중복 제거, 멤버십 검사 | 집합 |
7. 자주 하는 실수
1) 존재하지 않는 키 접근
d = {"a": 1}
print(d["z"]) # KeyError→ d.get("z") 사용 또는 if "z" in d:
2) 빈 set을 {}로 만들기
s = {} # 빈 딕셔너리!
s = set() # 빈 set3) set에 리스트 넣기
{[1, 2]} # TypeError: unhashable type: 'list'
{(1, 2)} # 튜플은 OK4) 딕셔너리 순회 중 수정
for k in d:
del d[k] # RuntimeError→ 키 목록을 미리 복사: for k in list(d):
8. FAQ
Q1. 딕셔너리의 키 중복 시?
마지막 값으로 덮어씀. 키는 유일해야 함.
Q2. 딕셔너리는 정렬되나요?
Python 3.7+ 부터 입력 순서 유지. 정렬은 sorted(d.items()).
Q3. 집합과 딕셔너리 둘 다 {} 인데 어떻게 구분?
: 가 있으면 딕셔너리, 없으면 집합. {1, 2} = set, {1: "a"} = dict.
8주차 — 문자열 다루기
문자열 인덱싱/슬라이싱, 자주 쓰는 메서드(split/join/strip/replace), f-string 심화(정렬·자릿수·진법), 이스케이프 문자(\n \t)를 익힙니다.
1. 문자열 기초
문자열은 변경 불가능(immutable). 인덱싱과 슬라이싱은 리스트와 동일.
s = "Python"
print(s[0]) # P
print(s[-1]) # n
print(s[1:4]) # yth
print(len(s)) # 6
# s[0] = "X" # TypeError — 변경 불가2. 자주 쓰는 메서드
| 메서드 | 동작 | 예시 |
|---|---|---|
| lower() / upper() | 소/대문자 | "Hi".upper() → "HI" |
| strip() | 양쪽 공백 제거 | " hi ".strip() → "hi" |
| lstrip() / rstrip() | 좌/우 공백 제거 | |
| split(sep) | 분리 → 리스트 | "a,b,c".split(",") → ["a","b","c"] |
| join(seq) | 리스트 → 문자열 | ",".join(["a","b"]) → "a,b" |
| replace(old, new) | 치환 | "foo".replace("o", "*") → "f**" |
| find(x) / index(x) | 위치 찾기 | "hello".find("l") → 2 |
| count(x) | 개수 | "hello".count("l") → 2 |
| startswith / endswith | 시작/끝 검사 | "abc".endswith("c") → True |
| isdigit / isalpha | 숫자/문자 검사 |
3. f-string 심화
name = "Alice"
score = 92.345
print(f"{name:<10}|") # 좌측 정렬 폭 10
print(f"{name:>10}|") # 우측 정렬
print(f"{name:^10}|") # 가운데
print(f"{name:*^10}|") # 채움 문자 * 가운데
print(f"{score:.2f}") # 92.35 (소수점 둘째)
print(f"{1234567:,}") # 1,234,567 (천 단위 콤마)
print(f"{0.85:.0%}") # 85%
print(f"{255:b} {255:x}") # 2진수, 16진수4. 이스케이프 문자
| 표기 | 의미 |
|---|---|
| \n | 줄바꿈 |
| \t | 탭 |
| \\ | 백슬래시 |
| \" | 큰따옴표 |
| \' | 작은따옴표 |
print("줄1\n줄2") # 두 줄
print("이름\t나이") # 탭으로 구분
print("경로: C:\\dev") # C:\dev
# raw string: 이스케이프 무시
print(r"C:\dev\new") # C:\dev\new5. 문자열 ↔ 리스트 변환
csv = "사과,바나나,포도"
fruits = csv.split(",") # ['사과', '바나나', '포도']
joined = " | ".join(fruits) # "사과 | 바나나 | 포도"6. 자주 하는 실수
1) 문자열 원본을 수정하려 함
s = "hello"
s.replace("l", "L") # s는 그대로!
s = s.replace("l", "L") # 결과를 다시 할당2) split() 인자 누락
"a b c".split() 은 공백 분리. "a,b".split() 은 분리 안 됨.
3) find vs index
find 는 없으면 -1, index 는 ValueError.
4) 따옴표 안에 같은 따옴표
s = "say "hi"" # SyntaxError
s = 'say "hi"' # OK
s = "say \"hi\"" # OK5) f-string 중괄호 출력
print(f"{name}") # 변수
print(f"{{name}}") # 그냥 {name} 출력7. FAQ
Q1. 문자열 길이는 한글도 1글자로?
len() 은 코드 포인트 단위라 보통 1글자. 이모지·결합문자는 예외 있음.
Q2. 대소문자 무시 비교는?
s1.lower() == s2.lower() 또는 s1.casefold() == s2.casefold() (더 정확).
Q3. 문자열 안에 변수 값을 넣는 방법이 여럿?
옛 방식: %, .format(). 현재 권장: f-string (가장 빠르고 가독성 좋음).
9주차 — 함수 기초
def 로 함수를 정의하고 호출, 매개변수와 인수의 차이, 기본값/키워드 인수, return으로 값 반환, 그리고 지역/전역 변수의 스코프를 익힙니다.
1. 함수란
같은 동작을 여러 번 쓰지 않고 이름 붙여 재사용. 코드를 짧고 명확하게 만든다.
def greet(name):
print(f"안녕, {name}!")
greet("홍길동")
greet("김영희")2. 매개변수와 인수
- 매개변수(parameter): 함수 정의의 변수 (name)
- 인수(argument): 함수 호출 시 전달하는 값 ("홍길동")
def add(a, b): # a, b: 매개변수
return a + b
result = add(3, 5) # 3, 5: 인수3. return
함수가 값을 돌려줍니다. return 만나면 즉시 종료.
def square(x):
return x * x
n = square(5) # 25return 없으면 자동으로 None 반환.
4. 기본값 매개변수
호출 시 인수 생략하면 기본값 사용.
def greet(name, greeting="안녕"):
return f"{greeting}, {name}님!"
print(greet("길동")) # 안녕, 길동님!
print(greet("Alice", "Hello")) # Hello, Alice님!5. 키워드 인수
순서 대신 이름으로 전달.
def make_user(name, age, city):
return {"name": name, "age": age, "city": city}
# 위치 인수
u1 = make_user("홍길동", 20, "서울")
# 키워드 인수 (순서 무관, 가독성 좋음)
u2 = make_user(city="부산", name="김영희", age=25)6. 여러 값 반환 (튜플)
def min_max(nums):
return min(nums), max(nums)
lo, hi = min_max([3, 1, 4, 1, 5])
print(lo, hi) # 1 57. 변수 스코프
함수 안에서 만든 변수는 지역 변수 — 밖에서 안 보임.
def f():
x = 10 # 지역
print(x)
f()
# print(x) # NameError함수 안에서 전역 변수를 수정하려면 global 키워드:
total = 0
def add(n):
global total
total += n(가능하면 global 은 피하고, 함수가 값을 받아서 반환하는 형태 권장.)
8. 자주 하는 실수
1) 함수 호출에 () 빠뜨림
def hi():
print("hi")
hi # 함수 객체. 실행 안 됨
hi() # 실행2) return 없는데 결과 사용
def show(x):
print(x)
y = show(5) # y = None3) 기본값에 가변 객체
def add_to(item, lst=[]): # ⚠️ 함정!
lst.append(item)
return lst
add_to(1) # [1]
add_to(2) # [1, 2] — 같은 리스트 공유→ 기본값은 None 으로 두고 함수 안에서 새로 생성:
def add_to(item, lst=None):
if lst is None:
lst = []
...4) 이름 충돌
def list(): # 내장 list 가려짐
...→ print, list, sum 같은 내장 이름은 변수·함수명으로 쓰지 말 것.
9. FAQ
Q1. 함수는 몇 줄이 적절한가요?
권장 5~30줄. 너무 길면 더 작은 함수로 분리.
Q2. print 와 return 의 차이?
print 는 화면에 출력, return 은 값을 반환. 함수가 값 자체가 필요할 때는 return.
Q3. 함수 안에서 함수를 호출할 수 있나요?
네. 자신을 호출(재귀)도 가능 (중급에서 다룸).
10주차 — 기초 종합 실습
지금까지 배운 입력·조건·반복·자료구조·함수를 자연스럽게 조합해 작은 프로그램을 완성합니다. To-Do List, 단어장 퀴즈, 가계부, 숫자 야구 중 하나를 골라 만들어보세요.
1. 프로젝트 설계 절차
- 요구사항 정리 — 무엇을 만드는지, 어떤 입출력인지 종이에 적기
- 데이터 구조 결정 — 리스트? 딕셔너리? 둘 다?
- 함수 분리 — 작은 단위로 (입력 받기, 처리, 출력 등)
- 흐름 작성 — main 루프, 종료 조건
- 점진적으로 만들기 — 한 번에 다 짜지 말고 한 기능씩 동작 확인
2. 디버깅 기초
print 디버깅
가장 단순하고 강력한 방법.
def calc(x, y):
print(f"DEBUG: x={x}, y={y}")
result = x / y
print(f"DEBUG: result={result}")
return result에러 메시지 읽기
가장 아래의 한 줄이 핵심.
Traceback (most recent call last):
File "main.py", line 10, in <module>
print(scores[5])
IndexError: list index out of range→ "10번째 줄에서 리스트 인덱스 범위 초과"
3. 골격 예제 — 미니 To-Do List
examples/todo_skeleton.py 참고. 함수로 분리하고, 메인 루프에서 조립.
4. 자주 하는 실수
- 한꺼번에 모든 기능 구현 시도 — 작게 잘라서 단계별로
- 함수 분리 없이 한 덩어리 코드 — 읽기 어렵고 디버깅 힘듦
- 에러를 try: ... except: pass 로 숨김 — 어디서 뭐가 잘못됐는지 모름
- 변수명을 a, b, temp 로 — 의미 있는 이름 (scores, user_input)
5. FAQ
Q1. 어디서부터 시작해야 할지 모르겠어요.
"프로그램이 시작되면 무엇이 화면에 나오는가" → "사용자가 무엇을 입력하는가" → 그 흐름을 그대로 코드로.
Q2. 막히면 어떻게 해요?
한 줄씩 print로 출력해서 데이터를 확인. 그래도 안 되면 검색 (StackOverflow). 그래도 안 되면 질문.
6. 다음 단계
기초 과정을 마쳤습니다! 🎉
- 중급 과정 — 함수 심화, OOP, 파일 I/O
- 실습 도전 — Lv1 기초응용, Lv2 자료구조 콘솔 프로젝트
💻 예제 (examples)
실제로 실행해 결과를 확인할 수 있는 예제 코드입니다.
student = {"name": "홍길동", "age": 20, "major": "CS"}
print(student["name"])
student["age"] = 21
student["email"] = "h@example.com"
del student["major"]
print(student)
홍길동
{'name': '홍길동', 'age': 21, 'email': 'h@example.com'}d = {"a": 1, "b": 2, "c": 3}
print(d.keys())
print(d.values())
print(d.items())
print(d.get("z")) # None
print(d.get("z", "기본값")) # 기본값
print("a" in d) # True
for k, v in d.items():
print(f"{k} = {v}")
dict_keys(['a', 'b', 'c'])
dict_values([1, 2, 3])
dict_items([('a', 1), ('b', 2), ('c', 3)])
None
기본값
True
a = 1
b = 2
c = 3a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a | b) # 합집합
print(a & b) # 교집합
print(a - b) # 차집합
print(a ^ b) # 대칭차
# 리스트 중복 제거
nums = [1, 2, 2, 3, 3, 3]
print(list(set(nums)))
{1, 2, 3, 4, 5, 6}
{3, 4}
{1, 2}
{1, 2, 5, 6}
[1, 2, 3]text = "apple banana apple cherry banana apple"
words = text.split()
count = {}
for w in words:
count[w] = count.get(w, 0) + 1
print(count)
{'apple': 3, 'banana': 2, 'cherry': 1}s = " Hello, World! "
print(s.strip()) # "Hello, World!"
print(s.upper()) # " HELLO, WORLD! "
print(s.lower()) # " hello, world! "
print(s.replace("World", "Python")) # " Hello, Python! "
print("hello".startswith("he")) # True
print("hello".endswith("lo")) # True
print("123".isdigit()) # True
print("abc".isalpha()) # True
Hello, World!
HELLO, WORLD!
hello, world!
Hello, Python!
True
True
True
True# split
csv = "사과,바나나,포도"
fruits = csv.split(",")
print(fruits)
words = "Hello World Python".split() # 공백 분리
print(words)
# join
joined = " | ".join(fruits)
print(joined)
print("-".join(["010", "1234", "5678"]))
['사과', '바나나', '포도']
['Hello', 'World', 'Python']
사과 | 바나나 | 포도
010-1234-5678name = "Alice"
score = 92.345
print(f"{name:<10}|")
print(f"{name:>10}|")
print(f"{name:^10}|")
print(f"{name:*^10}|")
print(f"{score:.2f}")
print(f"{1234567:,}")
print(f"{0.85:.0%}")
print(f"{255:b} {255:x}")
Alice |
Alice|
Alice |
**Alice***|
92.35
1,234,567
85%
11111111 ffprint("줄1\n줄2")
print("이름\t나이")
print("경로: C:\\dev\\app")
# raw string
print(r"C:\dev\new")
# 따옴표 안의 따옴표
print("she said \"hi\"")
print('she said "hi"')
줄1
줄2
이름 나이
경로: C:\dev\app
C:\dev\new
she said "hi"
she said "hi"def greet(name):
print(f"안녕, {name}!")
def add(a, b):
return a + b
greet("홍길동")
greet("김영희")
print(add(3, 5))
안녕, 홍길동!
안녕, 김영희!
8def greet(name, greeting="안녕"):
return f"{greeting}, {name}님!"
print(greet("길동"))
print(greet("Alice", "Hello"))
print(greet(name="민수", greeting="반가워"))
안녕, 길동님!
Hello, Alice님!
반가워, 민수님!def square(x):
return x * x
def min_max(nums):
return min(nums), max(nums)
print(square(5))
lo, hi = min_max([3, 1, 4, 1, 5])
print(lo, hi)
25
1 5total = 0
def add(n):
global total
total += n
add(10)
add(20)
print(total) # 30
def local_demo():
x = 100
print(x)
local_demo()
# print(x) # NameError
30
100def show_menu():
print("\n[명령] add / list / done <번호> / del <번호> / quit")
def add_todo(todos, text):
todos.append({"text": text, "done": False})
def show_list(todos):
if not todos:
print("(비어 있음)")
return
for i, t in enumerate(todos, start=1):
mark = "x" if t["done"] else " "
print(f"{i}. [{mark}] {t['text']}")
def main():
todos = []
while True:
show_menu()
cmd = input("> ").strip()
if cmd == "quit":
break
elif cmd == "list":
show_list(todos)
elif cmd.startswith("add "):
add_todo(todos, cmd[4:])
print("추가됨")
# done, del 도 비슷한 패턴
if __name__ == "__main__":
main()
[명령] add / list / done <번호> / del <번호> / quit
> add 우유 사기
추가됨
> list
1. [ ] 우유 사기
> quitdef divide(a, b):
print(f"DEBUG: a={a}, b={b}")
try:
result = a / b
except ZeroDivisionError as e:
print(f"에러: {e}")
return None
print(f"DEBUG: result={result}")
return result
print(divide(10, 2))
print(divide(10, 0))
DEBUG: a=10, b=2
DEBUG: result=5.0
5.0
DEBUG: a=10, b=0
에러: division by zero
None📝 과제 (exercises)
직접 풀어보고, 막힐 때 정답을 펼쳐 비교해보세요.
연락처 프로그램
목표: 이름으로 전화번호를 저장/조회/삭제하는 CLI.
- 데이터: {"이름": "전화번호"} 딕셔너리
- 명령: add, find, del, list, quit
- find 시 없는 이름은 "찾을 수 없습니다"
명령: add
이름: 홍길동
전화: 010-1234-5678
추가됨
명령: find
이름: 홍길동
홍길동: 010-1234-5678
명령: list
1. 홍길동: 010-1234-5678▶정답 코드 펼치기 / 접기
contacts = {}
while True:
cmd = input("명령(add/find/del/list/quit): ")
if cmd == "quit":
break
elif cmd == "add":
name = input("이름: ")
phone = input("전화: ")
contacts[name] = phone
print("추가됨")
elif cmd == "find":
name = input("이름: ")
if name in contacts:
print(f"{name}: {contacts[name]}")
else:
print("찾을 수 없습니다")
elif cmd == "del":
name = input("이름: ")
if name in contacts:
del contacts[name]
print("삭제됨")
else:
print("찾을 수 없습니다")
elif cmd == "list":
for i, (name, phone) in enumerate(contacts.items(), start=1):
print(f"{i}. {name}: {phone}")
명령(add/find/del/list/quit): add
이름: 홍길동
전화: 010-1234-5678
추가됨
명령(add/find/del/list/quit): list
1. 홍길동: 010-1234-5678
명령(add/find/del/list/quit): quit단어 빈도 Top 3
목표: 긴 문장에서 가장 많이 등장한 단어 3개를 출력한다.
- 입력은 코드 안에 변수로 (긴 문장)
- 단어는 공백으로 분리
- 빈도 내림차순으로 정렬, 상위 3개
sorted(d.items(), key=lambda x: x[1], reverse=True) 로 값 기준 정렬
1. apple: 5번
2. banana: 3번
3. cherry: 2번▶정답 코드 펼치기 / 접기
text = "apple banana apple cherry banana apple cherry apple banana apple"
words = text.split()
count = {}
for w in words:
count[w] = count.get(w, 0) + 1
top3 = sorted(count.items(), key=lambda x: x[1], reverse=True)[:3]
for i, (word, n) in enumerate(top3, start=1):
print(f"{i}. {word}: {n}번")
1. apple: 5번
2. banana: 3번
3. cherry: 2번중복 제거 (순서 유지)
목표: 리스트에서 중복을 제거하되 원래 입력 순서를 유지한다.
- 입력: ["a", "b", "a", "c", "b", "d"]
- 출력: ["a", "b", "c", "d"]
- set() 만으로는 순서가 깨질 수 있음 → 딕셔너리 활용
dict.fromkeys(리스트) 활용
▶정답 코드 펼치기 / 접기
items = ["a", "b", "a", "c", "b", "d"]
# 방법 1: dict.fromkeys (가장 간결, 순서 유지)
result = list(dict.fromkeys(items))
print(result)
# 방법 2: 직접 순회
seen = set()
result2 = []
for x in items:
if x not in seen:
seen.add(x)
result2.append(x)
print(result2)
['a', 'b', 'c', 'd']
['a', 'b', 'c', 'd']회문(palindrome) 판별
목표: 입력 문자열이 앞뒤가 같은지 확인한다.
- 공백, 대소문자 무시
- 회문이면 "회문입니다", 아니면 "회문이 아닙니다"
문자열: 기러기
회문입니다
문자열: A man a plan a canal Panama
회문입니다▶정답 코드 펼치기 / 접기
s = input("문자열: ")
clean = s.replace(" ", "").lower()
if clean == clean[::-1]:
print("회문입니다")
else:
print("회문이 아닙니다")
문자열: A man a plan a canal Panama
회문입니다이메일 형식 검증
목표: 이메일 주소가 형식에 맞는지 간단히 확인한다.
- @ 가 정확히 1개
- . 이 @ 뒤에 1개 이상
- 공백 없음
이메일: hong@example.com
유효한 이메일
이메일: foo@@bar.com
잘못된 형식▶정답 코드 펼치기 / 접기
email = input("이메일: ")
if " " in email:
print("잘못된 형식 (공백)")
elif email.count("@") != 1:
print("잘못된 형식 (@ 개수)")
else:
local, domain = email.split("@")
if "." not in domain or not local:
print("잘못된 형식")
else:
print("유효한 이메일")
이메일: hong@example.com
유효한 이메일텍스트 통계
목표: 문장을 입력받아 글자 수, 단어 수, 평균 단어 길이를 출력한다.
- 글자 수는 공백 제외
- 단어 수는 공백으로 분리한 결과
- 평균 단어 길이는 소수점 둘째 자리
문장: Hello Python world
글자 수(공백 제외): 16
단어 수: 3
평균 단어 길이: 5.33▶정답 코드 펼치기 / 접기
text = input("문장: ")
chars = len(text.replace(" ", ""))
words = text.split()
word_count = len(words)
avg = sum(len(w) for w in words) / word_count
print(f"글자 수(공백 제외): {chars}")
print(f"단어 수: {word_count}")
print(f"평균 단어 길이: {avg:.2f}")
문장: Hello Python world
글자 수(공백 제외): 16
단어 수: 3
평균 단어 길이: 5.33계산기 함수 모음
목표: 사칙연산 함수를 만들고 메뉴형 계산기로 사용한다.
- 함수 4개: add, sub, mul, div
- div 는 0으로 나누면 None 반환 (또는 메시지)
- main 흐름: 메뉴 → 두 수 입력 → 결과 출력 → 종료
[메뉴] 1.+ 2.- 3.* 4./ 5.종료
선택: 1
첫 번째 수: 10
두 번째 수: 5
결과: 15▶정답 코드 펼치기 / 접기
def add(a, b): return a + b
def sub(a, b): return a - b
def mul(a, b): return a * b
def div(a, b):
if b == 0:
return None
return a / b
while True:
print("\n[메뉴] 1.+ 2.- 3.* 4./ 5.종료")
choice = input("선택: ")
if choice == "5":
break
a = float(input("첫 번째 수: "))
b = float(input("두 번째 수: "))
if choice == "1":
print("결과:", add(a, b))
elif choice == "2":
print("결과:", sub(a, b))
elif choice == "3":
print("결과:", mul(a, b))
elif choice == "4":
result = div(a, b)
print("결과:", "0으로 나눌 수 없습니다" if result is None else result)
[메뉴] 1.+ 2.- 3.* 4./ 5.종료
선택: 1
첫 번째 수: 10
두 번째 수: 5
결과: 15.0입력 검증 함수
목표: is_valid_age(value) 함수를 만든다.
- 0~120 사이의 정수면 True, 아니면 False
- 문자열이 들어와도 처리 ("abc" → False)
True
True
True
False
False
False▶정답 코드 펼치기 / 접기
def is_valid_age(value):
try:
n = int(value)
except (ValueError, TypeError):
return False
return 0 <= n <= 120
print(is_valid_age(20))
print(is_valid_age(0))
print(is_valid_age(120))
print(is_valid_age(-1))
print(is_valid_age(150))
print(is_valid_age("abc"))
True
True
True
False
False
False소수 판별 함수
목표: is_prime(n) 함수를 작성하고, 1~50 중 소수만 출력한다.
- 1과 0 이하: 소수 아님
- 2: 소수
- 짝수(2 제외): 소수 아님
- 그 외: 3부터 √n 까지 홀수로 나누어 보기
1~50 사이의 소수:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47▶정답 코드 펼치기 / 접기
def is_prime(n):
if n <= 1:
return False
if n == 2:
return True
if n % 2 == 0:
return False
i = 3
while i * i <= n:
if n % i == 0:
return False
i += 2
return True
primes = [str(n) for n in range(1, 51) if is_prime(n)]
print("1~50 사이의 소수:")
print(" ".join(primes))
1~50 사이의 소수:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47콘솔 To-Do List
목표: 할 일 추가/조회/완료/삭제 명령이 모두 동작하는 콘솔 프로그램.
- 데이터 구조: 리스트 + 딕셔너리 조합
- 명령: add, list, done <번호>, del <번호>, quit
- 잘못된 명령 / 존재하지 않는 번호 처리
> add 우유 사기
추가됨
> list
1. [ ] 우유 사기
2. [x] 책 읽기
> done 1
1번 완료
> del 2
2번 삭제- · 5개 명령 모두 동작 — 60%
- · 잘못된 입력 처리 — 20%
- · 코드 정리(함수 분리) — 20%
▶정답 코드 펼치기 / 접기
def add_todo(todos, text):
todos.append({"text": text, "done": False})
def list_todos(todos):
if not todos:
print("(비어 있음)")
return
for i, t in enumerate(todos, start=1):
mark = "x" if t["done"] else " "
print(f"{i}. [{mark}] {t['text']}")
def done_todo(todos, idx):
if 1 <= idx <= len(todos):
todos[idx-1]["done"] = True
print(f"{idx}번 완료")
else:
print("번호 오류")
def del_todo(todos, idx):
if 1 <= idx <= len(todos):
del todos[idx-1]
print(f"{idx}번 삭제")
else:
print("번호 오류")
def main():
todos = []
while True:
cmd = input("> ").strip()
if cmd == "quit":
break
elif cmd == "list":
list_todos(todos)
elif cmd.startswith("add "):
add_todo(todos, cmd[4:])
print("추가됨")
elif cmd.startswith("done "):
try:
done_todo(todos, int(cmd[5:]))
except ValueError:
print("숫자를 입력하세요")
elif cmd.startswith("del "):
try:
del_todo(todos, int(cmd[4:]))
except ValueError:
print("숫자를 입력하세요")
else:
print("알 수 없는 명령")
main()
> add 우유 사기
추가됨
> list
1. [ ] 우유 사기
> done 1
1번 완료
> quit단어장 퀴즈
목표: 영-한 단어장으로 랜덤 퀴즈를 출제한다.
- 단어장은 코드 안에 딕셔너리로 (10개 이상)
- 10문제 출제 (중복 가능)
- 정답/오답 즉시 알림
- 마지막에 점수 출력
[1/10] apple의 뜻은? 사과
정답!
[2/10] book의 뜻은? 가방
오답. 정답: 책
...
총점: 7 / 10▶정답 코드 펼치기 / 접기
import random
vocab = {
"apple": "사과", "book": "책", "cat": "고양이", "dog": "강아지",
"egg": "달걀", "fish": "물고기", "garden": "정원", "house": "집",
"ice": "얼음", "jacket": "재킷",
}
words = list(vocab.keys())
score = 0
for i in range(1, 11):
word = random.choice(words)
answer = input(f"[{i}/10] {word}의 뜻은? ").strip()
if answer == vocab[word]:
print("정답!")
score += 1
else:
print(f"오답. 정답: {vocab[word]}")
print(f"\n총점: {score} / 10")
[1/10] apple의 뜻은? 사과
정답!
[2/10] book의 뜻은? 가방
오답. 정답: 책
...
총점: 7 / 10간이 가계부
목표: 수입/지출을 기록하고 잔액과 카테고리별 합계를 보여준다.
- 데이터: [{type, amount, category, memo}, ...]
- 명령: add, list, summary, quit
- summary: 수입 합계, 지출 합계, 잔액, 카테고리별 지출
> add
수입/지출: 지출
금액: 5000
카테고리: 식비
메모: 점심
추가됨
> summary
수입: 100,000원
지출: 35,000원
잔액: 65,000원
[지출 카테고리별]
식비: 20,000원
교통: 10,000원
기타: 5,000원▶정답 코드 펼치기 / 접기
entries = []
def add_entry():
t = input("수입/지출: ")
amount = int(input("금액: "))
category = input("카테고리: ")
memo = input("메모: ")
entries.append({"type": t, "amount": amount, "category": category, "memo": memo})
print("추가됨")
def show_summary():
income = sum(e["amount"] for e in entries if e["type"] == "수입")
expense = sum(e["amount"] for e in entries if e["type"] == "지출")
print(f"수입: {income:,}원")
print(f"지출: {expense:,}원")
print(f"잔액: {income - expense:,}원")
cat = {}
for e in entries:
if e["type"] == "지출":
cat[e["category"]] = cat.get(e["category"], 0) + e["amount"]
print("\n[지출 카테고리별]")
for c, v in sorted(cat.items(), key=lambda x: -x[1]):
print(f"{c}: {v:,}원")
while True:
cmd = input("> ").strip()
if cmd == "quit":
break
elif cmd == "add":
add_entry()
elif cmd == "summary":
show_summary()
elif cmd == "list":
for i, e in enumerate(entries, start=1):
print(f"{i}. {e['type']} {e['amount']:,}원 ({e['category']}) {e['memo']}")
> add
수입/지출: 수입
금액: 100000
카테고리: 월급
메모: 11월 월급
추가됨
> summary
수입: 100,000원
지출: 0원
잔액: 100,000원
> quit댓글 0
아직 댓글이 없습니다. 첫 댓글을 남겨 주세요.
댓글은 회원만 쓸 수 있습니다.
광고·욕설·비방·개인정보·불법 내용이 담긴 댓글은 숨기거나 지웁니다. 댓글은 닉네임과 함께 공개됩니다. 개인정보처리방침