aliceblue11 commited on
Commit
6d3a484
·
verified ·
1 Parent(s): 31a97a4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +366 -0
app.py CHANGED
@@ -0,0 +1,366 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import datetime
3
+ from datetime import datetime, timedelta
4
+ import requests
5
+ import json
6
+
7
+ class SajuCalculator:
8
+ def __init__(self):
9
+ # 천간 (하늘줄기)
10
+ self.heavenly_stems = ['갑', '을', '병', '정', '무', '기', '경', '신', '임', '계']
11
+
12
+ # 지지 (땅가지)
13
+ self.earthly_branches = ['자', '축', '인', '묘', '진', '사', '오', '미', '신', '유', '술', '해']
14
+
15
+ # 오행
16
+ self.five_elements = {
17
+ '갑': '목', '을': '목', '병': '화', '정': '화', '무': '토',
18
+ '기': '토', '경': '금', '신': '금', '임': '수', '계': '수',
19
+ '자': '수', '축': '토', '인': '목', '묘': '목', '진': '토',
20
+ '사': '화', '오': '화', '미': '토', '신': '금', '유': '금',
21
+ '술': '토', '해': '수'
22
+ }
23
+
24
+ # 십신
25
+ self.ten_gods = {
26
+ '목': {'목': '비견/겁재', '화': '식신/상관', '토': '편재/정재', '금': '편관/정관', '수': '편인/정인'},
27
+ '화': {'목': '편인/정인', '화': '비견/겁재', '토': '식신/상관', '금': '편재/정재', '수': '편관/정관'},
28
+ '토': {'목': '편관/정관', '화': '편인/정인', '토': '비견/겁재', '금': '식신/상관', '수': '편재/정재'},
29
+ '금': {'목': '편재/정재', '화': '편관/정관', '토': '편인/정인', '금': '비견/겁재', '수': '식신/상관'},
30
+ '수': {'목': '식신/상관', '화': '편재/정재', '토': '편관/정관', '금': '편인/정인', '수': '비견/겁재'}
31
+ }
32
+
33
+ # 색상 매핑
34
+ self.element_colors = {
35
+ '목': '#28a745', # 녹색
36
+ '화': '#dc3545', # 빨강
37
+ '토': '#ffc107', # 노랑
38
+ '금': '#6c757d', # 회색
39
+ '수': '#007bff' # 파랑
40
+ }
41
+
42
+ def get_ganzhi(self, year, month, day, hour):
43
+ """간지 계산"""
44
+ # 기준일: 1900년 1월 1일 (경자년 정축월 갑인일)
45
+ base_date = datetime(1900, 1, 1)
46
+ target_date = datetime(year, month, day)
47
+
48
+ days_diff = (target_date - base_date).days
49
+
50
+ # 연주 계산
51
+ year_stem_index = (year - 1900 + 6) % 10 # 1900년이 경년(6)
52
+ year_branch_index = (year - 1900 + 0) % 12 # 1900년이 자년(0)
53
+
54
+ # 월주 계산 (절기 고려해야 하지만 간단히 처리)
55
+ month_stem_index = (year_stem_index * 2 + month + 1) % 10
56
+ month_branch_index = (month + 1) % 12
57
+
58
+ # 일주 계산
59
+ day_stem_index = (days_diff + 10) % 10 # 1900.1.1이 갑일
60
+ day_branch_index = (days_diff + 2) % 12 # 1900.1.1이 인일
61
+
62
+ # 시주 계산
63
+ hour_branch_index = ((hour + 1) // 2) % 12
64
+ hour_stem_index = (day_stem_index * 2 + hour_branch_index) % 10
65
+
66
+ return {
67
+ 'year': (self.heavenly_stems[year_stem_index], self.earthly_branches[year_branch_index]),
68
+ 'month': (self.heavenly_stems[month_stem_index], self.earthly_branches[month_branch_index]),
69
+ 'day': (self.heavenly_stems[day_stem_index], self.earthly_branches[day_branch_index]),
70
+ 'hour': (self.heavenly_stems[hour_stem_index], self.earthly_branches[hour_branch_index])
71
+ }
72
+
73
+ def analyze_elements(self, ganzhi):
74
+ """오행 분석"""
75
+ elements = []
76
+ for pillar in ganzhi.values():
77
+ stem_element = self.five_elements[pillar[0]]
78
+ branch_element = self.five_elements[pillar[1]]
79
+ elements.extend([stem_element, branch_element])
80
+
81
+ element_count = {}
82
+ for element in ['목', '화', '토', '금', '수']:
83
+ element_count[element] = elements.count(element)
84
+
85
+ return element_count
86
+
87
+ def get_ten_gods_analysis(self, ganzhi):
88
+ """십신 분석"""
89
+ day_stem = ganzhi['day'][0]
90
+ day_element = self.five_elements[day_stem]
91
+
92
+ analysis = {}
93
+ for pillar_name, pillar in ganzhi.items():
94
+ stem_element = self.five_elements[pillar[0]]
95
+ branch_element = self.five_elements[pillar[1]]
96
+
97
+ stem_relation = self.ten_gods[day_element][stem_element]
98
+ branch_relation = self.ten_gods[day_element][branch_element]
99
+
100
+ analysis[pillar_name] = {
101
+ 'stem_relation': stem_relation,
102
+ 'branch_relation': branch_relation
103
+ }
104
+
105
+ return analysis
106
+
107
+ def calculate_daeun(self, birth_year, gender):
108
+ """대운 계산 (간단한 버전)"""
109
+ daeun_list = []
110
+ start_age = 8 if gender == '남' else 7 # 간단히 설정
111
+
112
+ for i in range(8): # 8개 대운
113
+ age_start = start_age + i * 10
114
+ age_end = age_start + 9
115
+ year_start = birth_year + age_start
116
+ year_end = birth_year + age_end
117
+
118
+ # 대운 간지는 월주를 기준으로 순행/역행
119
+ daeun_list.append({
120
+ 'period': f"{age_start}-{age_end}세",
121
+ 'years': f"{year_start}-{year_end}년",
122
+ 'ganzhi': f"대운{i+1}" # 실제로는 복잡한 계산 필요
123
+ })
124
+
125
+ return daeun_list
126
+
127
+ def calculate_saju(birth_date, birth_time, gender, birth_place):
128
+ """사주 계산 메인 함수"""
129
+ try:
130
+ # 날짜 파싱
131
+ birth_datetime = datetime.strptime(f"{birth_date} {birth_time}", "%Y-%m-%d %H:%M")
132
+
133
+ calculator = SajuCalculator()
134
+
135
+ # 간지 계산
136
+ ganzhi = calculator.get_ganzhi(
137
+ birth_datetime.year,
138
+ birth_datetime.month,
139
+ birth_datetime.day,
140
+ birth_datetime.hour
141
+ )
142
+
143
+ # 오행 분석
144
+ elements = calculator.analyze_elements(ganzhi)
145
+
146
+ # 십신 분석
147
+ ten_gods = calculator.get_ten_gods_analysis(ganzhi)
148
+
149
+ # 대운 계산
150
+ daeun = calculator.calculate_daeun(birth_datetime.year, gender)
151
+
152
+ # 결과 포맷팅
153
+ result = format_saju_result(ganzhi, elements, ten_gods, daeun, birth_datetime, gender, birth_place)
154
+
155
+ return result
156
+
157
+ except Exception as e:
158
+ return f"❌ 계산 중 오류가 발생했습니다: {str(e)}"
159
+
160
+ def format_saju_result(ganzhi, elements, ten_gods, daeun, birth_datetime, gender, birth_place):
161
+ """사주 결과 포맷팅"""
162
+
163
+ result = f"""
164
+ # 🔮 사주명리 만세력 분석결과
165
+
166
+ ## 📋 기본정보
167
+ - **생년월일**: {birth_datetime.strftime('%Y년 %m월 %d일')}
168
+ - **출생시간**: {birth_datetime.strftime('%H시 %M분')}
169
+ - **성별**: {gender}
170
+ - **출생지**: {birth_place}
171
+
172
+ ## 🏛️ 사주(四柱) - 만세력
173
+
174
+ ### 연주(年柱) - 뿌리, 조상
175
+ **{ganzhi['year'][0]}{ganzhi['year'][1]}**
176
+ - 천간: {ganzhi['year'][0]} ({calculator.five_elements[ganzhi['year'][0]]})
177
+ - 지지: {ganzhi['year'][1]} ({calculator.five_elements[ganzhi['year'][1]]})
178
+
179
+ ### 월주(月柱) - 줄기, 부모
180
+ **{ganzhi['month'][0]}{ganzhi['month'][1]}**
181
+ - 천간: {ganzhi['month'][0]} ({calculator.five_elements[ganzhi['month'][0]]})
182
+ - 지지: {ganzhi['month'][1]} ({calculator.five_elements[ganzhi['month'][1]]})
183
+
184
+ ### 일주(日柱) - 본인, 배우자
185
+ **{ganzhi['day'][0]}{ganzhi['day'][1]}** (일간: {ganzhi['day'][0]})
186
+ - 천간: {ganzhi['day'][0]} ({calculator.five_elements[ganzhi['day'][0]]})
187
+ - 지지: {ganzhi['day'][1]} ({calculator.five_elements[ganzhi['day'][1]]})
188
+
189
+ ### 시주(時柱) - 꽃, 자식
190
+ **{ganzhi['hour'][0]}{ganzhi['hour'][1]}**
191
+ - 천간: {ganzhi['hour'][0]} ({calculator.five_elements[ganzhi['hour'][0]]})
192
+ - 지지: {ganzhi['hour'][1]} ({calculator.five_elements[ganzhi['hour'][1]]})
193
+
194
+ ## 🌟 오행(五行) 분석
195
+
196
+ """
197
+
198
+ calculator = SajuCalculator()
199
+
200
+ # 오행 분석 추가
201
+ total_elements = sum(elements.values())
202
+ for element, count in elements.items():
203
+ percentage = (count / total_elements * 100) if total_elements > 0 else 0
204
+ result += f"- **{element}**: {count}개 ({percentage:.1f}%)\n"
205
+
206
+ # 오행 균형 분석
207
+ max_element = max(elements, key=elements.get)
208
+ min_element = min(elements, key=elements.get)
209
+
210
+ result += f"""
211
+ ### 오행 균형 분석
212
+ - **가장 강한 오행**: {max_element} ({elements[max_element]}개)
213
+ - **가장 약한 오행**: {min_element} ({elements[min_element]}개)
214
+ """
215
+
216
+ # 십신 분석 추가
217
+ result += """
218
+ ## 🎭 십신(十神) 분석
219
+
220
+ """
221
+
222
+ pillar_names = {'year': '연주', 'month': '월주', 'day': '일주', 'hour': '시주'}
223
+ for pillar_name, pillar_kr in pillar_names.items():
224
+ result += f"### {pillar_kr}\n"
225
+ result += f"- 천간: {ten_gods[pillar_name]['stem_relation']}\n"
226
+ result += f"- 지지: {ten_gods[pillar_name]['branch_relation']}\n\n"
227
+
228
+ # 대운 정보 추가
229
+ result += """
230
+ ## 🔄 대운(大運) 정보
231
+
232
+ """
233
+
234
+ for i, du in enumerate(daeun[:4]): # 처음 4개 대운만 표시
235
+ result += f"**{du['period']}** ({du['years']})\n"
236
+
237
+ # 기본 해석 추가
238
+ result += f"""
239
+
240
+ ## 💡 기본 해석
241
+
242
+ ### 성격 특성
243
+ - **일간**: {ganzhi['day'][0]} ({calculator.five_elements[ganzhi['day'][0]]})
244
+ - 일간이 {calculator.five_elements[ganzhi['day'][0]]}이므로, {get_element_personality(calculator.five_elements[ganzhi['day'][0]])}
245
+
246
+ ### 오행 조화
247
+ {get_element_balance_advice(elements)}
248
+
249
+ ### 주의사항
250
+ - 이 분석은 기본적인 사주명리학 원리에 따른 것입니다.
251
+ - 정확한 해석을 위해서는 전문가의 상담을 받으시기 바랍니다.
252
+ - 절기, 시간대, 지역별 차이 등이 고려되지 않았을 수 있습니다.
253
+
254
+ ---
255
+ *생성일시: {datetime.now().strftime('%Y년 %m월 %d일 %H시 %M분')}*
256
+ """
257
+
258
+ return result
259
+
260
+ def get_element_personality(element):
261
+ """오행별 성격 특성"""
262
+ personalities = {
263
+ '목': "창의적이고 성장 지향적이며, 유연하고 협력적인 성격을 가지고 있습니다.",
264
+ '화': "열정적이고 활동적이며, 밝고 사교적인 성격을 가지고 있습니다.",
265
+ '토': "안정적이고 신중하며, 포용력이 있고 책임감이 강한 성격을 가지고 있습니다.",
266
+ '금': "원칙적이고 정의로우며, 결단력이 있고 리더십이 강한 성격을 가지고 있습니다.",
267
+ '수': "지혜롭고 적응력이 있으며, 깊이 있고 신중한 성격을 가지고 있습니다."
268
+ }
269
+ return personalities.get(element, "균형 잡힌 성격을 가지고 있습니다.")
270
+
271
+ def get_element_balance_advice(elements):
272
+ """오행 균형에 따른 조언"""
273
+ max_element = max(elements, key=elements.get)
274
+ min_element = min(elements, key=elements.get)
275
+
276
+ advice = f"현재 {max_element}가 가장 강하고 {min_element}가 가장 약합니다. "
277
+
278
+ if elements[max_element] - elements[min_element] > 2:
279
+ advice += f"{min_element}를 보강하고 {max_element}의 기운을 조절하는 것이 좋겠습니다."
280
+ else:
281
+ advice += "전체적으로 균형이 잘 잡혀 있는 편입니다."
282
+
283
+ return advice
284
+
285
+ # Gradio 인터페이스 생성
286
+ def create_interface():
287
+ with gr.Blocks(title="🔮 사주명리 만세력 시스템", theme=gr.themes.Soft()) as demo:
288
+ gr.HTML("""
289
+ <div style="text-align: center; padding: 20px;">
290
+ <h1>🔮 사주명리학 만세력 분석 시스템</h1>
291
+ <p>생년월일시와 출생지 정보를 입력하시면 상세한 만세력을 분석해드립니다.</p>
292
+ </div>
293
+ """)
294
+
295
+ with gr.Row():
296
+ with gr.Column(scale=1):
297
+ gr.HTML("<h3>📝 정보 입력</h3>")
298
+
299
+ birth_date = gr.Date(
300
+ label="생년월일",
301
+ info="양력 기준으로 입력해주세요"
302
+ )
303
+
304
+ birth_time = gr.Textbox(
305
+ label="태어난 시간",
306
+ placeholder="14:30",
307
+ info="24시간 형식 (예: 14:30)"
308
+ )
309
+
310
+ gender = gr.Radio(
311
+ choices=["남", "여"],
312
+ label="성별",
313
+ value="남"
314
+ )
315
+
316
+ birth_place = gr.Textbox(
317
+ label="출생지",
318
+ placeholder="서울특별시",
319
+ info="시/도 단위로 입력해주세요"
320
+ )
321
+
322
+ calculate_btn = gr.Button(
323
+ "🔮 만세력 분석하기",
324
+ variant="primary",
325
+ size="lg"
326
+ )
327
+
328
+ with gr.Row():
329
+ with gr.Column():
330
+ result_output = gr.Markdown(
331
+ label="분석 결과",
332
+ elem_classes=["saju-result"]
333
+ )
334
+
335
+ # 이벤트 연결
336
+ calculate_btn.click(
337
+ fn=calculate_saju,
338
+ inputs=[birth_date, birth_time, gender, birth_place],
339
+ outputs=result_output
340
+ )
341
+
342
+ # 예시 데이터로 자동 실행
343
+ demo.load(
344
+ fn=lambda: calculate_saju("1990-05-15", "14:30", "남", "서울특별시"),
345
+ outputs=result_output
346
+ )
347
+
348
+ gr.HTML("""
349
+ <div style="text-align: center; padding: 20px; margin-top: 30px; border-top: 1px solid #eee;">
350
+ <p><small>※ 본 시스템은 전통 사주명리학을 기반으로 하며, 참고용으로만 활용해주시기 바랍니다.</small></p>
351
+ <p><small>※ 정확한 해석을 위해서는 전문가의 상담을 받으시기 바랍니다.</small></p>
352
+ </div>
353
+ """)
354
+
355
+ return demo
356
+
357
+ # 전역 변수로 계산기 인스턴스 생성
358
+ calculator = SajuCalculator()
359
+
360
+ if __name__ == "__main__":
361
+ demo = create_interface()
362
+ demo.launch(
363
+ server_name="0.0.0.0",
364
+ server_port=7860,
365
+ share=True
366
+ )