[코담]
웹개발·실전 프로젝트·AI까지, 파이썬·장고의 모든것을 담아낸 강의와 개발 노트
미니프로젝트 5 | ✅저자: 이유정(박사)
프로젝트 코드명: FeedbackAnalyzer
프로젝트 유형: 텍스트 분석 도구
(콘솔 앱)
🖥️ 프로젝트 개요
사용자들의 피드백(의견, 리뷰 등)을 자동으로 분석하여 다음 정보를 출력하는 간단한 데이터 처리 시스템을 구축한다.
입력은 여러 줄의 문자열 데이터이며, 이 데이터에서 자주 등장하는 단어, 문장의 길이, 긍정/부정 키워드 포함 여부 등을 집계한다.
◽ 이 프로젝트를 통해 자연스럽게 적용되는 내용
적용 요소 | 사용 이유 |
---|---|
반복문 , 조건문 |
문자열 분할, 조건 검사 |
이터레이터 , next() |
문장 순차 접근 |
리스트 컴프리헨션 |
필터링된 단어 수집 |
딕셔너리 컴프리헨션 |
단어별 등장 횟수 집계 |
내장함수(sum, max, len, enumerate, reversed) |
집계 및 정렬 처리 |
문자열 조작 함수 (split, lower, count) |
데이터 정제 |
형변환 함수 (list, set, dict) |
자료형 변환 |
📄 기능 요구사항 (Functional Requirements)
- 사용자 피드백(여러 줄의 문자열)을 리스트 형태로 입력받는다.
- 각 피드백 문장에서 등장하는 단어 수를 계산한다.
- 모든 문장에서 가장 많이 등장한 단어 TOP 3를 출력한다.
- 각 피드백에
"good"
,"bad"
키워드가 포함되어 있는지 분석하여,- 긍정 또는 부정 여부를 출력한다.
- 가장 긴 문장과 짧은 문장을 각각 출력한다.
- 피드백 중 짝수 인덱스만 골라 거꾸로 출력한다 (
reversed()
+enumerate()
응용). - 입력받은 피드백 중
callable()
한 항목이 있는지 확인한다 (함수형 오브젝트가 입력된 경우 대비).
📄 비기능 요구사항 (Non-Functional Requirements)
- 코드 내 함수는 역할에 따라 최소 2개 이상 정의되어야 함.
- 결과는 포맷을 맞춰 가독성 있게 출력되어야 함.
- 사용자 입력 없이 코드 내 고정 데이터 사용 (테스트 자동화 목적).
- 컴프리헨션, 이터레이터, 내장함수 최소 1회 이상 사용.
피드백 데이터
feedbacks = [
"The product quality is excellent and service was good.",
"Fast delivery and great quality!",
"The customer service was extremely slow and unhelpful.",
"Good.",
"Bad experience. The support team was unresponsive."
]
✅ 출력 포맷 구성:
피드백 분석 요약
-------------------------
1. 피드백 문장 수: 5개
2. 가장 많이 등장한 단어 TOP 3: ['service', 'good', 'slow']
3. 긍정 문장: 3개 / 부정 문장: 2개
4. 가장 긴 문장: "The customer service was extremely slow and unhelpful."
5. 가장 짧은 문장: "Good."
6. 짝수 인덱스 피드백 거꾸로 출력:
- Feedback #4: "Good."
- Feedback #2: "Fast delivery and great quality!"
- Feedback #0: "The product quality is excellent and service was good."
7. callable한 항목 존재 여부: False
✅ 정답 코드: 기본 버전
feedbacks = [
"The product quality is excellent and service was good.",
"Fast delivery and great quality!",
"The customer service was extremely slow and unhelpful.",
"Good.",
"Bad experience. The support team was unresponsive."
]
def count_words(text):
return len(text.split())
def word_frequency(feedbacks):
words = [word.lower().strip(".,!?") for f in feedbacks for word in f.split()]
freq = {}
for w in words:
freq[w] = freq.get(w, 0) + 1
return freq
def polarity_check(fb):
fb = fb.lower()
if "good" in fb:
return "긍정"
elif "bad" in fb:
return "부정"
return "중립"
# 단어 빈도
freq = word_frequency(feedbacks)
top3 = sorted(freq.items(), key=lambda x: x[1], reverse=True)[:3]
# 긍정/부정 판단
polarities = [polarity_check(f) for f in feedbacks]
positive = polarities.count("긍정")
negative = polarities.count("부정")
# 문장 길이 기준
longest = max(feedbacks, key=lambda x: len(x))
shortest = min(feedbacks, key=lambda x: len(x))
# 짝수 인덱스 거꾸로 출력
even_feedbacks = [f for i, f in enumerate(feedbacks) if i % 2 == 0]
even_feedbacks = list(reversed(even_feedbacks))
# callable 테스트용
callable_found = any(callable(f) for f in feedbacks)
# 출력
print("🔍 피드백 분석 요약\n" + "-"*25)
print(f"1. 피드백 문장 수: {len(feedbacks)}개")
print(f"2. 가장 많이 등장한 단어 TOP 3: {[word for word, _ in top3]}")
print(f"3. 긍정 문장: {positive}개 / 부정 문장: {negative}개")
print(f"4. 가장 긴 문장: \"{longest}\"")
print(f"5. 가장 짧은 문장: \"{shortest}\"")
print(f"6. 짝수 인덱스 피드백 거꾸로 출력:")
for i, line in enumerate(even_feedbacks):
print(f" - Feedback #{len(feedbacks) - 1 - i*2}: \"{line}\"")
print(f"7. callable한 항목 존재 여부: {callable_found}")