Update app.py
Browse files
app.py
CHANGED
|
@@ -1 +1,239 @@
|
|
| 1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
|
| 3 |
+
# MBTI 질문 데이터 (각 차원당 5개씩 총 20개)
|
| 4 |
+
questions = [
|
| 5 |
+
# E vs I (외향 vs 내향)
|
| 6 |
+
{"text": "새로운 사람들을 만나는 것이 즐겁고 에너지가 충전된다.", "dimension": "EI", "direction": "E"},
|
| 7 |
+
{"text": "혼자만의 시간을 보내는 것이 더 편하고 재충전된다.", "dimension": "EI", "direction": "I"},
|
| 8 |
+
{"text": "파티나 모임에서 먼저 다가가서 대화를 시작하는 편이다.", "dimension": "EI", "direction": "E"},
|
| 9 |
+
{"text": "깊은 대화를 나눌 수 있는 소수의 친구를 선호한다.", "dimension": "EI", "direction": "I"},
|
| 10 |
+
{"text": "여러 사람과 함께 있을 때 활기차고 말이 많아진다.", "dimension": "EI", "direction": "E"},
|
| 11 |
+
|
| 12 |
+
# S vs N (감각 vs 직관)
|
| 13 |
+
{"text": "구체적이고 현실적인 사실들에 집중하는 편이다.", "dimension": "SN", "direction": "S"},
|
| 14 |
+
{"text": "가능성과 미래의 잠재력을 상상하는 것을 좋아한다.", "dimension": "SN", "direction": "N"},
|
| 15 |
+
{"text": "세부사항과 구체적인 정보를 중요하게 여긴다.", "dimension": "SN", "direction": "S"},
|
| 16 |
+
{"text": "패턴을 찾고 숨겨진 의미를 해석하는 것을 즐긴다.", "dimension": "SN", "direction": "N"},
|
| 17 |
+
{"text": "경험을 통해 배운 검증된 방법을 신뢰한다.", "dimension": "SN", "direction": "S"},
|
| 18 |
+
|
| 19 |
+
# T vs F (사고 vs 감정)
|
| 20 |
+
{"text": "결정을 내릴 때 논리와 객관적 기준을 우선시한다.", "dimension": "TF", "direction": "T"},
|
| 21 |
+
{"text": "결정을 내릴 때 사람들의 감정과 조화를 고려한다.", "dimension": "TF", "direction": "F"},
|
| 22 |
+
{"text": "비판적으로 분석하고 문제점을 찾아내는 것을 잘한다.", "dimension": "TF", "direction": "T"},
|
| 23 |
+
{"text": "다른 사람의 감정을 쉽게 공감하고 이해한다.", "dimension": "TF", "direction": "F"},
|
| 24 |
+
{"text": "공정함과 원칙이 인간관계보다 중요하다고 생각한다.", "dimension": "TF", "direction": "T"},
|
| 25 |
+
|
| 26 |
+
# J vs P (판단 vs 인식)
|
| 27 |
+
{"text": "계획을 세우고 일정에 맞춰 진행하는 것을 선호한다.", "dimension": "JP", "direction": "J"},
|
| 28 |
+
{"text": "융통성 있게 상황에 맞춰 대응하는 것을 좋아한다.", "dimension": "JP", "direction": "P"},
|
| 29 |
+
{"text": "마감 기한을 여유 있게 두고 미리미리 처리한다.", "dimension": "JP", "direction": "J"},
|
| 30 |
+
{"text": "여러 가능성을 열어두고 마지막 순간에 결정한다.", "dimension": "JP", "direction": "P"},
|
| 31 |
+
{"text": "체계적이고 조직적인 환경을 선호한다.", "dimension": "JP", "direction": "J"},
|
| 32 |
+
]
|
| 33 |
+
|
| 34 |
+
# MBTI 유형별 설명
|
| 35 |
+
mbti_descriptions = {
|
| 36 |
+
"INTJ": {
|
| 37 |
+
"title": "전략가 (Architect)",
|
| 38 |
+
"description": "상상력이 풍부하고 전략적인 사고를 가진 완벽주의자입니다.",
|
| 39 |
+
"strengths": "논리적, 독립적, 결단력 있음, 창의적 문제 해결",
|
| 40 |
+
"weaknesses": "지나치게 비판적, 감정 표현 어려움, 고집스러움"
|
| 41 |
+
},
|
| 42 |
+
"INTP": {
|
| 43 |
+
"title": "논리술사 (Logician)",
|
| 44 |
+
"description": "혁신적인 발명가로 끊임없는 지식의 갈증을 가지고 있습니다.",
|
| 45 |
+
"strengths": "분석적, 객관적, 창의적, 열린 마음",
|
| 46 |
+
"weaknesses": "실용성 부족, 감정 둔감, 우유부단함"
|
| 47 |
+
},
|
| 48 |
+
"ENTJ": {
|
| 49 |
+
"title": "통솔자 (Commander)",
|
| 50 |
+
"description": "대담하고 상상력이 풍부한 강력한 지도자입니다.",
|
| 51 |
+
"strengths": "리더십, 효율적, 자신감, 전략적 사고",
|
| 52 |
+
"weaknesses": "참을성 부족, 오만함, 감정 무시"
|
| 53 |
+
},
|
| 54 |
+
"ENTP": {
|
| 55 |
+
"title": "변론가 (Debater)",
|
| 56 |
+
"description": "똑똑하고 호기심 많은 사색가로 지적 도전을 즐깁니다.",
|
| 57 |
+
"strengths": "창의적, 카리스마, 에너지 넘침, 논쟁 능력",
|
| 58 |
+
"weaknesses": "논쟁적, 무감각, 집중력 부족"
|
| 59 |
+
},
|
| 60 |
+
"INFJ": {
|
| 61 |
+
"title": "옹호자 (Advocate)",
|
| 62 |
+
"description": "조용하고 신비로우며 사람들에게 영감을 주는 이상주의자입니다.",
|
| 63 |
+
"strengths": "통찰력, 결단력, 이타적, 창의적",
|
| 64 |
+
"weaknesses": "민감함, 완벽주의, 소진되기 쉬움"
|
| 65 |
+
},
|
| 66 |
+
"INFP": {
|
| 67 |
+
"title": "중재자 (Mediator)",
|
| 68 |
+
"description": "항상 선을 행할 준비가 되어 있는 이타적이고 부드러운 사람입니다.",
|
| 69 |
+
"strengths": "공감 능력, 창의적, 열정적, 헌신적",
|
| 70 |
+
"weaknesses": "비현실적, 자기비판적, 감정적"
|
| 71 |
+
},
|
| 72 |
+
"ENFJ": {
|
| 73 |
+
"title": "선도자 (Protagonist)",
|
| 74 |
+
"description": "카리스마 있고 영감을 주는 지도자로 청중을 사로잡습니다.",
|
| 75 |
+
"strengths": "카리스마, 이타적, 영감을 줌, 자연스러운 리더",
|
| 76 |
+
"weaknesses": "지나치게 이상적, 자기희생적, 민감함"
|
| 77 |
+
},
|
| 78 |
+
"ENFP": {
|
| 79 |
+
"title": "활동가 (Campaigner)",
|
| 80 |
+
"description": "열정적이고 창의적이며 긍정적인 자유로운 영혼입니다.",
|
| 81 |
+
"strengths": "열정적, 창의적, 사교적, 낙관적",
|
| 82 |
+
"weaknesses": "산만함, 스트레스 취약, 지나친 감정 이입"
|
| 83 |
+
},
|
| 84 |
+
"ISTJ": {
|
| 85 |
+
"title": "현실주의자 (Logistician)",
|
| 86 |
+
"description": "실용적이고 사실에 기반한 믿음직한 사람입니다.",
|
| 87 |
+
"strengths": "책임감, 정직함, 실용적, 차분함",
|
| 88 |
+
"weaknesses": "고집스러움, 둔감함, 규칙 고수"
|
| 89 |
+
},
|
| 90 |
+
"ISFJ": {
|
| 91 |
+
"title": "수호자 (Defender)",
|
| 92 |
+
"description": "헌신적이고 따뜻한 수호자로 소중한 사람들을 지킵니다.",
|
| 93 |
+
"strengths": "지지적, 신뢰할 수 있음, 인내심, 실용적",
|
| 94 |
+
"weaknesses": "겸손함, 변화 회피, 과부하"
|
| 95 |
+
},
|
| 96 |
+
"ESTJ": {
|
| 97 |
+
"title": "경영자 (Executive)",
|
| 98 |
+
"description": "뛰어난 관리자로 사람들이나 일을 관리하는 데 타고났습니다.",
|
| 99 |
+
"strengths": "조직력, 정직함, 헌신적, 결단력",
|
| 100 |
+
"weaknesses": "완고함, 감정 무시, 비판적"
|
| 101 |
+
},
|
| 102 |
+
"ESFJ": {
|
| 103 |
+
"title": "집정관 (Consul)",
|
| 104 |
+
"description": "배려심이 많고 사교적이며 인기가 많은 사람입니다.",
|
| 105 |
+
"strengths": "지지적, 책임감, 충성스러움, 민감함",
|
| 106 |
+
"weaknesses": "걱정 많음, 비판에 취약, 자기주장 어려움"
|
| 107 |
+
},
|
| 108 |
+
"ISTP": {
|
| 109 |
+
"title": "장인 (Virtuoso)",
|
| 110 |
+
"description": "대담하고 실용적인 실험가로 모든 도구를 다룹니다.",
|
| 111 |
+
"strengths": "낙관적, 창의적, 실용적, 자발적",
|
| 112 |
+
"weaknesses": "완고함, 둔감함, 쉽게 지루함"
|
| 113 |
+
},
|
| 114 |
+
"ISFP": {
|
| 115 |
+
"title": "모험가 (Adventurer)",
|
| 116 |
+
"description": "유연하고 매력적인 예술가로 새로운 것을 탐험할 준비가 되어 있습니다.",
|
| 117 |
+
"strengths": "매력적, 민감함, 상상력, 호기심",
|
| 118 |
+
"weaknesses": "섬세함, 독립적 과함, 예측 불가능"
|
| 119 |
+
},
|
| 120 |
+
"ESTP": {
|
| 121 |
+
"title": "사업가 (Entrepreneur)",
|
| 122 |
+
"description": "영리하고 에너지 넘치며 매우 지각적인 사람입니다.",
|
| 123 |
+
"strengths": "대담함, 실용적, 직관적, 사교적",
|
| 124 |
+
"weaknesses": "무감각함, 참을성 없음, 위험 감수"
|
| 125 |
+
},
|
| 126 |
+
"ESFP": {
|
| 127 |
+
"title": "연예인 (Entertainer)",
|
| 128 |
+
"description": "자발적이고 에너지 넘치며 열정적인 엔터테이너입니다.",
|
| 129 |
+
"strengths": "대담함, 독창적, 실용적, 관찰력",
|
| 130 |
+
"weaknesses": "민감함, 갈등 회피, 쉽게 지루함"
|
| 131 |
+
}
|
| 132 |
+
}
|
| 133 |
+
|
| 134 |
+
def calculate_mbti(answers):
|
| 135 |
+
"""답변을 바탕으로 MBTI 유형 계산"""
|
| 136 |
+
scores = {"E": 0, "I": 0, "S": 0, "N": 0, "T": 0, "F": 0, "J": 0, "P": 0}
|
| 137 |
+
|
| 138 |
+
for i, answer in enumerate(answers):
|
| 139 |
+
if answer is None:
|
| 140 |
+
continue
|
| 141 |
+
question = questions[i]
|
| 142 |
+
dimension = question["dimension"]
|
| 143 |
+
direction = question["direction"]
|
| 144 |
+
|
| 145 |
+
# 5점 척도: 1(전혀 아니다) ~ 5(매우 그렇다)
|
| 146 |
+
scores[direction] += answer
|
| 147 |
+
|
| 148 |
+
# MBTI 유형 결정
|
| 149 |
+
mbti_type = ""
|
| 150 |
+
mbti_type += "E" if scores["E"] > scores["I"] else "I"
|
| 151 |
+
mbti_type += "S" if scores["S"] > scores["N"] else "N"
|
| 152 |
+
mbti_type += "T" if scores["T"] > scores["F"] else "F"
|
| 153 |
+
mbti_type += "J" if scores["J"] > scores["P"] else "P"
|
| 154 |
+
|
| 155 |
+
return mbti_type, scores
|
| 156 |
+
|
| 157 |
+
def format_result(mbti_type, scores):
|
| 158 |
+
"""결과를 포맷팅"""
|
| 159 |
+
info = mbti_descriptions[mbti_type]
|
| 160 |
+
|
| 161 |
+
result = f"""
|
| 162 |
+
# 🎯 당신의 MBTI 유형: {mbti_type}
|
| 163 |
+
|
| 164 |
+
## {info['title']}
|
| 165 |
+
|
| 166 |
+
### 📝 설명
|
| 167 |
+
{info['description']}
|
| 168 |
+
|
| 169 |
+
### ✨ 강점
|
| 170 |
+
{info['strengths']}
|
| 171 |
+
|
| 172 |
+
### ⚠️ 약점
|
| 173 |
+
{info['weaknesses']}
|
| 174 |
+
|
| 175 |
+
### 📊 세부 점수
|
| 176 |
+
- **외향(E) vs 내향(I)**: E={scores['E']}, I={scores['I']} → **{'E' if scores['E'] > scores['I'] else 'I'}**
|
| 177 |
+
- **감각(S) vs 직관(N)**: S={scores['S']}, N={scores['N']} → **{'S' if scores['S'] > scores['N'] else 'N'}**
|
| 178 |
+
- **사고(T) vs 감정(F)**: T={scores['T']}, F={scores['F']} → **{'T' if scores['T'] > scores['F'] else 'F'}**
|
| 179 |
+
- **판단(J) vs 인식(P)**: J={scores['J']}, P={scores['P']} → **{'J' if scores['J'] > scores['P'] else 'P'}**
|
| 180 |
+
"""
|
| 181 |
+
return result
|
| 182 |
+
|
| 183 |
+
def submit_test(*answers):
|
| 184 |
+
"""테스트 제출 및 결과 계산"""
|
| 185 |
+
if None in answers:
|
| 186 |
+
return "⚠️ 모든 질문에 답변해주세요!"
|
| 187 |
+
|
| 188 |
+
mbti_type, scores = calculate_mbti(answers)
|
| 189 |
+
return format_result(mbti_type, scores)
|
| 190 |
+
|
| 191 |
+
# Gradio 인터페이스 구성
|
| 192 |
+
with gr.Blocks(title="MBTI 성격 유형 테스트", theme=gr.themes.Soft()) as demo:
|
| 193 |
+
gr.Markdown("""
|
| 194 |
+
# 🧠 MBTI 성격 유형 테스트
|
| 195 |
+
|
| 196 |
+
각 질문에 대해 자신의 성향을 솔직하게 평가해주세요.
|
| 197 |
+
|
| 198 |
+
**평가 기준:**
|
| 199 |
+
- 1 = 전혀 아니다
|
| 200 |
+
- 2 = 아니다
|
| 201 |
+
- 3 = 보통이다
|
| 202 |
+
- 4 = 그렇다
|
| 203 |
+
- 5 = 매우 그렇다
|
| 204 |
+
""")
|
| 205 |
+
|
| 206 |
+
# 질문 슬라���더 생성
|
| 207 |
+
sliders = []
|
| 208 |
+
for i, q in enumerate(questions):
|
| 209 |
+
with gr.Row():
|
| 210 |
+
slider = gr.Slider(
|
| 211 |
+
minimum=1,
|
| 212 |
+
maximum=5,
|
| 213 |
+
step=1,
|
| 214 |
+
value=3,
|
| 215 |
+
label=f"질문 {i+1}: {q['text']}",
|
| 216 |
+
info="1=전혀 아니다, 5=매우 그렇다"
|
| 217 |
+
)
|
| 218 |
+
sliders.append(slider)
|
| 219 |
+
|
| 220 |
+
# 제출 버튼
|
| 221 |
+
submit_btn = gr.Button("🎯 결과 확인", variant="primary", size="lg")
|
| 222 |
+
|
| 223 |
+
# 결과 표시
|
| 224 |
+
result_output = gr.Markdown(label="테스트 결과")
|
| 225 |
+
|
| 226 |
+
# 버튼 클릭 이벤트
|
| 227 |
+
submit_btn.click(
|
| 228 |
+
fn=submit_test,
|
| 229 |
+
inputs=sliders,
|
| 230 |
+
outputs=result_output
|
| 231 |
+
)
|
| 232 |
+
|
| 233 |
+
gr.Markdown("""
|
| 234 |
+
---
|
| 235 |
+
💡 **참고**: 이 테스트는 간단한 MBTI 성향 파악을 위한 것이며, 공식 MBTI 검사를 대체하지 않습니다.
|
| 236 |
+
""")
|
| 237 |
+
|
| 238 |
+
if __name__ == "__main__":
|
| 239 |
+
demo.launch(share=True)
|