Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,8 +1,6 @@
|
|
1 |
import gradio as gr
|
2 |
import datetime
|
3 |
-
|
4 |
-
import requests
|
5 |
-
import json
|
6 |
|
7 |
class SajuCalculator:
|
8 |
def __init__(self):
|
@@ -29,35 +27,92 @@ class SajuCalculator:
|
|
29 |
'금': {'목': '편재/정재', '화': '편관/정관', '토': '편인/정인', '금': '비견/겁재', '수': '식신/상관'},
|
30 |
'수': {'목': '식신/상관', '화': '편재/정재', '토': '편관/정관', '금': '편인/정인', '수': '비견/겁재'}
|
31 |
}
|
|
|
|
|
|
|
|
|
|
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
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
|
52 |
-
year_branch_index = (year - 1900 + 0) % 12
|
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
|
60 |
-
day_branch_index = (days_diff + 2) % 12
|
61 |
|
62 |
# 시주 계산
|
63 |
hour_branch_index = ((hour + 1) // 2) % 12
|
@@ -104,189 +159,60 @@ class SajuCalculator:
|
|
104 |
|
105 |
return analysis
|
106 |
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
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 parse_flexible_date(date_str):
|
128 |
-
"""유연한 날짜 파싱"""
|
129 |
-
import re
|
130 |
-
|
131 |
-
# 모든 공백 제거
|
132 |
-
date_str = date_str.replace(' ', '')
|
133 |
-
|
134 |
-
# 숫자만 추출
|
135 |
-
numbers = re.findall(r'\d+', date_str)
|
136 |
-
|
137 |
-
if len(numbers) == 0:
|
138 |
-
raise ValueError("숫자를 찾을 수 없습니다.")
|
139 |
-
|
140 |
-
# 하나의 긴 숫자 문자열인 경우 (예: 19900515, 900515)
|
141 |
-
if len(numbers) == 1:
|
142 |
-
num_str = numbers[0]
|
143 |
-
|
144 |
-
if len(num_str) == 8: # YYYYMMDD
|
145 |
-
year = int(num_str[:4])
|
146 |
-
month = int(num_str[4:6])
|
147 |
-
day = int(num_str[6:8])
|
148 |
-
elif len(num_str) == 6: # YYMMDD 또는 YYYYMM
|
149 |
-
if int(num_str[:2]) > 30: # 년도가 30보다 크면 19XX
|
150 |
-
year = 1900 + int(num_str[:2])
|
151 |
-
month = int(num_str[2:4])
|
152 |
-
day = int(num_str[4:6])
|
153 |
-
else: # YYYYMM 형태로 해석
|
154 |
-
year = int(num_str[:4])
|
155 |
-
month = int(num_str[4:6])
|
156 |
-
day = 1 # 기본값
|
157 |
-
elif len(num_str) == 5: # YMMDD
|
158 |
-
year = 1900 + int(num_str[0])
|
159 |
-
month = int(num_str[1:3])
|
160 |
-
day = int(num_str[3:5])
|
161 |
-
else:
|
162 |
-
raise ValueError(f"날짜 형식을 인식할 수 없습니다: {num_str}")
|
163 |
-
|
164 |
-
# 여러 숫자로 분리된 경우 (예: 1990-5-15)
|
165 |
-
elif len(numbers) >= 3:
|
166 |
-
year = int(numbers[0])
|
167 |
-
month = int(numbers[1])
|
168 |
-
day = int(numbers[2])
|
169 |
-
|
170 |
-
# 연도가 2자리인 경우 처리
|
171 |
-
if year < 100:
|
172 |
-
if year > 30:
|
173 |
-
year += 1900
|
174 |
-
else:
|
175 |
-
year += 2000
|
176 |
-
|
177 |
-
elif len(numbers) == 2:
|
178 |
-
# 년월만 있는 경우
|
179 |
-
year = int(numbers[0])
|
180 |
-
month = int(numbers[1])
|
181 |
-
day = 1
|
182 |
-
|
183 |
-
if year < 100:
|
184 |
-
if year > 30:
|
185 |
-
year += 1900
|
186 |
-
else:
|
187 |
-
year += 2000
|
188 |
-
|
189 |
-
else:
|
190 |
-
raise ValueError("날짜 정보가 부족합니다.")
|
191 |
-
|
192 |
-
return year, month, day
|
193 |
|
194 |
-
def
|
195 |
-
"""
|
196 |
-
|
197 |
-
|
198 |
-
if not time_str:
|
199 |
-
return 12, 0
|
200 |
-
|
201 |
-
# 모든 공백 제거
|
202 |
-
time_str = time_str.replace(' ', '')
|
203 |
-
|
204 |
-
# 숫자만 추출
|
205 |
-
numbers = re.findall(r'\d+', time_str)
|
206 |
-
|
207 |
-
if len(numbers) == 0:
|
208 |
-
return 12, 0
|
209 |
-
|
210 |
-
# 하나의 숫자인 경우
|
211 |
-
if len(numbers) == 1:
|
212 |
-
time_num = numbers[0]
|
213 |
-
|
214 |
-
if len(time_num) == 4: # HHMM
|
215 |
-
hour = int(time_num[:2])
|
216 |
-
minute = int(time_num[2:4])
|
217 |
-
elif len(time_num) == 3: # HMM
|
218 |
-
hour = int(time_num[0])
|
219 |
-
minute = int(time_num[1:3])
|
220 |
-
elif len(time_num) <= 2: # HH
|
221 |
-
hour = int(time_num)
|
222 |
-
minute = 0
|
223 |
-
else:
|
224 |
-
hour = 12
|
225 |
-
minute = 0
|
226 |
|
227 |
-
|
228 |
-
elif len(numbers) >= 2:
|
229 |
-
hour = int(numbers[0])
|
230 |
-
minute = int(numbers[1])
|
231 |
|
|
|
|
|
232 |
else:
|
233 |
-
|
234 |
-
minute = 0
|
235 |
-
|
236 |
-
# 24시간 형식으로 조정
|
237 |
-
if hour > 24:
|
238 |
-
hour = hour % 24
|
239 |
|
240 |
-
return
|
241 |
|
242 |
def calculate_saju(birth_date, birth_time, gender, birth_place):
|
243 |
"""사주 계산 메인 함수"""
|
|
|
|
|
|
|
244 |
try:
|
245 |
# 입력 검증
|
246 |
if not birth_date:
|
247 |
return "❌ 생년월일을 입력해주세요."
|
248 |
|
249 |
-
#
|
250 |
-
|
251 |
|
252 |
-
#
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
if day < 1 or day > 31:
|
263 |
-
return f"❌ 일은 1~31 사이여야 합니다. 입력된 일: {day}"
|
264 |
-
|
265 |
-
except Exception as e:
|
266 |
-
return f"❌ 날짜 파싱 오류: {str(e)}\n입력값: '{birth_date}'\n💡 다음과 같이 입력해보세요:\n- 19900515 (8자리 숫자)\n- 1990-5-15 (하이픈 구분)\n- 1990/5/15 (슬래시 구분)"
|
267 |
-
|
268 |
-
# 유연한 시간 파싱
|
269 |
-
if birth_time:
|
270 |
-
try:
|
271 |
-
hour, minute = parse_flexible_time(birth_time)
|
272 |
-
except:
|
273 |
-
hour, minute = 12, 0 # 기본값
|
274 |
-
else:
|
275 |
-
hour, minute = 12, 0 # 시간 입력이 없으면 정오로 설정
|
276 |
|
277 |
# datetime 객체 생성
|
278 |
-
|
279 |
-
birth_datetime = datetime(year, month, day, hour, minute)
|
280 |
-
except ValueError as e:
|
281 |
-
return f"❌ 유효하지 않은 날짜입니다: {year}년 {month}월 {day}일\n{str(e)}"
|
282 |
|
283 |
# 간지 계산
|
284 |
-
ganzhi = calculator.get_ganzhi(
|
285 |
-
birth_datetime.year,
|
286 |
-
birth_datetime.month,
|
287 |
-
birth_datetime.day,
|
288 |
-
birth_datetime.hour
|
289 |
-
)
|
290 |
|
291 |
# 오행 분석
|
292 |
elements = calculator.analyze_elements(ganzhi)
|
@@ -294,18 +220,18 @@ def calculate_saju(birth_date, birth_time, gender, birth_place):
|
|
294 |
# 십신 분석
|
295 |
ten_gods = calculator.get_ten_gods_analysis(ganzhi)
|
296 |
|
297 |
-
# 대운 계산
|
298 |
-
daeun = calculator.calculate_daeun(birth_datetime.year, gender)
|
299 |
-
|
300 |
# 결과 포맷팅
|
301 |
-
result = format_saju_result(ganzhi, elements, ten_gods,
|
302 |
|
303 |
return result
|
304 |
|
|
|
|
|
|
|
305 |
except Exception as e:
|
306 |
-
return f"❌ 계산 중 오류가 발생했습니다: {str(e)}
|
307 |
|
308 |
-
def format_saju_result(ganzhi, elements, ten_gods,
|
309 |
"""사주 결과 포맷팅"""
|
310 |
|
311 |
result = f"""
|
@@ -343,8 +269,6 @@ def format_saju_result(ganzhi, elements, ten_gods, daeun, birth_datetime, gender
|
|
343 |
|
344 |
"""
|
345 |
|
346 |
-
calculator = SajuCalculator()
|
347 |
-
|
348 |
# 오행 분석 추가
|
349 |
total_elements = sum(elements.values())
|
350 |
for element, count in elements.items():
|
@@ -359,10 +283,7 @@ def format_saju_result(ganzhi, elements, ten_gods, daeun, birth_datetime, gender
|
|
359 |
### 오행 균형 분석
|
360 |
- **가장 강한 오행**: {max_element} ({elements[max_element]}개)
|
361 |
- **가장 약한 오행**: {min_element} ({elements[min_element]}개)
|
362 |
-
"""
|
363 |
|
364 |
-
# 십신 분석 추가
|
365 |
-
result += """
|
366 |
## 🎭 십신(十神) 분석
|
367 |
|
368 |
"""
|
@@ -373,18 +294,8 @@ def format_saju_result(ganzhi, elements, ten_gods, daeun, birth_datetime, gender
|
|
373 |
result += f"- 천간: {ten_gods[pillar_name]['stem_relation']}\n"
|
374 |
result += f"- 지지: {ten_gods[pillar_name]['branch_relation']}\n\n"
|
375 |
|
376 |
-
# 대운 정보 추가
|
377 |
-
result += """
|
378 |
-
## 🔄 대운(大運) 정보
|
379 |
-
|
380 |
-
"""
|
381 |
-
|
382 |
-
for i, du in enumerate(daeun[:4]): # 처음 4개 대운만 표시
|
383 |
-
result += f"**{du['period']}** ({du['years']})\n"
|
384 |
-
|
385 |
# 기본 해석 추가
|
386 |
result += f"""
|
387 |
-
|
388 |
## 💡 기본 해석
|
389 |
|
390 |
### 성격 특���
|
@@ -400,38 +311,13 @@ def format_saju_result(ganzhi, elements, ten_gods, daeun, birth_datetime, gender
|
|
400 |
- 절기, 시간대, 지역별 차이 등이 고려되지 않았을 수 있습니다.
|
401 |
|
402 |
---
|
403 |
-
*생성일시: {datetime.now().strftime('%Y년 %m월 %d일 %H시 %M분')}*
|
404 |
"""
|
405 |
|
406 |
return result
|
407 |
|
408 |
-
def get_element_personality(element):
|
409 |
-
"""오행별 성격 특성"""
|
410 |
-
personalities = {
|
411 |
-
'목': "창의적이고 성장 지향적이며, 유연하고 협력적인 성격을 가지고 있습니다.",
|
412 |
-
'화': "열정적이고 활동적이며, 밝고 사교적인 성격을 가지고 있습니다.",
|
413 |
-
'토': "안정적이고 신중하며, 포용력이 있고 책임감이 강한 성격을 가지고 있습니다.",
|
414 |
-
'금': "원칙적이고 정의로우며, 결단력이 있고 리더십이 강한 성격을 가지고 있습니다.",
|
415 |
-
'수': "지혜롭고 적응력이 있으며, 깊이 있고 신중한 성격을 가지고 있습니다."
|
416 |
-
}
|
417 |
-
return personalities.get(element, "균형 잡힌 성격을 가지고 있습니다.")
|
418 |
-
|
419 |
-
def get_element_balance_advice(elements):
|
420 |
-
"""오행 균형에 따른 조언"""
|
421 |
-
max_element = max(elements, key=elements.get)
|
422 |
-
min_element = min(elements, key=elements.get)
|
423 |
-
|
424 |
-
advice = f"현재 {max_element}가 가장 강하고 {min_element}가 가장 약합니다. "
|
425 |
-
|
426 |
-
if elements[max_element] - elements[min_element] > 2:
|
427 |
-
advice += f"{min_element}를 보강하고 {max_element}의 기운을 조절하는 것이 좋겠습니다."
|
428 |
-
else:
|
429 |
-
advice += "전체적으로 균형이 잘 잡혀 있는 편입니다."
|
430 |
-
|
431 |
-
return advice
|
432 |
-
|
433 |
-
# Gradio 인터페이스 생성
|
434 |
def create_interface():
|
|
|
435 |
with gr.Blocks(title="🔮 사주명리 만세력 시스템") as demo:
|
436 |
gr.HTML("""
|
437 |
<div style="text-align: center; padding: 20px;">
|
@@ -446,14 +332,14 @@ def create_interface():
|
|
446 |
|
447 |
birth_date = gr.Textbox(
|
448 |
label="생년월일",
|
449 |
-
placeholder="
|
450 |
-
info="
|
451 |
)
|
452 |
|
453 |
birth_time = gr.Textbox(
|
454 |
label="태어난 시간 (선택사항)",
|
455 |
-
placeholder="
|
456 |
-
info="
|
457 |
)
|
458 |
|
459 |
gender = gr.Radio(
|
@@ -464,7 +350,7 @@ def create_interface():
|
|
464 |
|
465 |
birth_place = gr.Textbox(
|
466 |
label="출생지",
|
467 |
-
placeholder="
|
468 |
info="시/도 단위로 입력해주세요"
|
469 |
)
|
470 |
|
@@ -488,7 +374,7 @@ def create_interface():
|
|
488 |
|
489 |
# 예시 데이터로 자동 실행
|
490 |
demo.load(
|
491 |
-
fn=lambda: calculate_saju("
|
492 |
outputs=result_output
|
493 |
)
|
494 |
|
@@ -501,9 +387,6 @@ def create_interface():
|
|
501 |
|
502 |
return demo
|
503 |
|
504 |
-
# 전역 변수로 계산기 인스턴스 생성
|
505 |
-
calculator = SajuCalculator()
|
506 |
-
|
507 |
if __name__ == "__main__":
|
508 |
demo = create_interface()
|
509 |
demo.launch(
|
|
|
1 |
import gradio as gr
|
2 |
import datetime
|
3 |
+
import re
|
|
|
|
|
4 |
|
5 |
class SajuCalculator:
|
6 |
def __init__(self):
|
|
|
27 |
'금': {'목': '편재/정재', '화': '편관/정관', '토': '편인/정인', '금': '비견/겁재', '수': '식신/상관'},
|
28 |
'수': {'목': '식신/상관', '화': '편재/정재', '토': '편관/정관', '금': '편인/정인', '수': '비견/겁재'}
|
29 |
}
|
30 |
+
|
31 |
+
def parse_date(self, date_str):
|
32 |
+
"""날짜 파싱"""
|
33 |
+
# 숫자만 추출
|
34 |
+
numbers = re.findall(r'\d+', str(date_str))
|
35 |
|
36 |
+
if not numbers:
|
37 |
+
raise ValueError("날짜에서 숫자를 찾을 수 없습니다")
|
38 |
+
|
39 |
+
# 하나의 긴 숫자인 경우
|
40 |
+
if len(numbers) == 1:
|
41 |
+
num_str = numbers[0]
|
42 |
+
if len(num_str) == 8: # YYYYMMDD
|
43 |
+
year = int(num_str[:4])
|
44 |
+
month = int(num_str[4:6])
|
45 |
+
day = int(num_str[6:8])
|
46 |
+
elif len(num_str) == 6: # YYMMDD
|
47 |
+
year_part = int(num_str[:2])
|
48 |
+
year = 1900 + year_part if year_part > 30 else 2000 + year_part
|
49 |
+
month = int(num_str[2:4])
|
50 |
+
day = int(num_str[4:6])
|
51 |
+
else:
|
52 |
+
raise ValueError(f"날짜 형식을 인식할 수 없습니다: {num_str}")
|
53 |
+
|
54 |
+
# 여러 숫자로 분리된 경우
|
55 |
+
elif len(numbers) >= 3:
|
56 |
+
year = int(numbers[0])
|
57 |
+
month = int(numbers[1])
|
58 |
+
day = int(numbers[2])
|
59 |
+
|
60 |
+
if year < 100:
|
61 |
+
year = 1900 + year if year > 30 else 2000 + year
|
62 |
+
else:
|
63 |
+
raise ValueError("날짜 정보가 부족합니다")
|
64 |
+
|
65 |
+
return year, month, day
|
66 |
+
|
67 |
+
def parse_time(self, time_str):
|
68 |
+
"""시간 파싱"""
|
69 |
+
if not time_str:
|
70 |
+
return 12, 0
|
71 |
+
|
72 |
+
numbers = re.findall(r'\d+', str(time_str))
|
73 |
+
|
74 |
+
if not numbers:
|
75 |
+
return 12, 0
|
76 |
+
|
77 |
+
if len(numbers) == 1:
|
78 |
+
time_num = numbers[0]
|
79 |
+
if len(time_num) == 4: # HHMM
|
80 |
+
hour = int(time_num[:2])
|
81 |
+
minute = int(time_num[2:4])
|
82 |
+
elif len(time_num) == 3: # HMM
|
83 |
+
hour = int(time_num[0])
|
84 |
+
minute = int(time_num[1:3])
|
85 |
+
else: # H or HH
|
86 |
+
hour = int(time_num)
|
87 |
+
minute = 0
|
88 |
+
else:
|
89 |
+
hour = int(numbers[0])
|
90 |
+
minute = int(numbers[1]) if len(numbers) > 1 else 0
|
91 |
+
|
92 |
+
# 24시간 형식 조정
|
93 |
+
hour = hour % 24
|
94 |
+
|
95 |
+
return hour, minute
|
96 |
|
97 |
def get_ganzhi(self, year, month, day, hour):
|
98 |
"""간지 계산"""
|
99 |
+
# 기준일: 1900년 1월 1일
|
100 |
+
base_date = datetime.datetime(1900, 1, 1)
|
101 |
+
target_date = datetime.datetime(year, month, day)
|
102 |
|
103 |
days_diff = (target_date - base_date).days
|
104 |
|
105 |
# 연주 계산
|
106 |
+
year_stem_index = (year - 1900 + 6) % 10
|
107 |
+
year_branch_index = (year - 1900 + 0) % 12
|
108 |
|
109 |
+
# 월주 계산
|
110 |
month_stem_index = (year_stem_index * 2 + month + 1) % 10
|
111 |
month_branch_index = (month + 1) % 12
|
112 |
|
113 |
# 일주 계산
|
114 |
+
day_stem_index = (days_diff + 10) % 10
|
115 |
+
day_branch_index = (days_diff + 2) % 12
|
116 |
|
117 |
# 시주 계산
|
118 |
hour_branch_index = ((hour + 1) // 2) % 12
|
|
|
159 |
|
160 |
return analysis
|
161 |
|
162 |
+
def get_element_personality(element):
|
163 |
+
"""오행별 성격 특성"""
|
164 |
+
personalities = {
|
165 |
+
'목': "창의적이고 성장 지향적이며, 유연하고 협력적인 성격을 가지고 있습니다.",
|
166 |
+
'화': "열정적이고 활동적이며, 밝고 사교적인 성격을 가지고 있습니다.",
|
167 |
+
'토': "안정적이고 신중하며, 포용력이 있고 책임감이 강한 성격을 가지고 있습니다.",
|
168 |
+
'금': "원칙적이고 정의로우며, 결단력이 있고 리더십이 강한 성격을 가지고 있습니다.",
|
169 |
+
'수': "지혜롭고 적응력이 있으며, 깊이 있고 신중한 성격을 가지고 있습니다."
|
170 |
+
}
|
171 |
+
return personalities.get(element, "균형 잡힌 성격을 가지고 있습니다.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
|
173 |
+
def get_element_balance_advice(elements):
|
174 |
+
"""오행 균형에 따른 조언"""
|
175 |
+
max_element = max(elements, key=elements.get)
|
176 |
+
min_element = min(elements, key=elements.get)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
177 |
|
178 |
+
advice = f"현재 {max_element}가 가장 강하고 {min_element}가 가장 약합니다. "
|
|
|
|
|
|
|
179 |
|
180 |
+
if elements[max_element] - elements[min_element] > 2:
|
181 |
+
advice += f"{min_element}를 보강하고 {max_element}의 기운을 조절하는 것이 좋겠습니다."
|
182 |
else:
|
183 |
+
advice += "전체적으로 균형이 잘 잡혀 있는 편입니다."
|
|
|
|
|
|
|
|
|
|
|
184 |
|
185 |
+
return advice
|
186 |
|
187 |
def calculate_saju(birth_date, birth_time, gender, birth_place):
|
188 |
"""사주 계산 메인 함수"""
|
189 |
+
# SajuCalculator 인스턴스 생성
|
190 |
+
calculator = SajuCalculator()
|
191 |
+
|
192 |
try:
|
193 |
# 입력 검증
|
194 |
if not birth_date:
|
195 |
return "❌ 생년월일을 입력해주세요."
|
196 |
|
197 |
+
# 날짜 파싱
|
198 |
+
year, month, day = calculator.parse_date(birth_date)
|
199 |
|
200 |
+
# 시간 파싱
|
201 |
+
hour, minute = calculator.parse_time(birth_time)
|
202 |
+
|
203 |
+
# 날짜 유효성 검사
|
204 |
+
if year < 1900 or year > 2100:
|
205 |
+
return f"❌ 연도는 1900~2100 사이여야 합니다. 입력된 연도: {year}"
|
206 |
+
if month < 1 or month > 12:
|
207 |
+
return f"❌ 월은 1~12 사이여야 합니다. 입력된 월: {month}"
|
208 |
+
if day < 1 or day > 31:
|
209 |
+
return f"❌ 일은 1~31 사이여야 합니다. 입력된 일: {day}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
210 |
|
211 |
# datetime 객체 생성
|
212 |
+
birth_datetime = datetime.datetime(year, month, day, hour, minute)
|
|
|
|
|
|
|
213 |
|
214 |
# 간지 계산
|
215 |
+
ganzhi = calculator.get_ganzhi(year, month, day, hour)
|
|
|
|
|
|
|
|
|
|
|
216 |
|
217 |
# 오행 분석
|
218 |
elements = calculator.analyze_elements(ganzhi)
|
|
|
220 |
# 십신 분석
|
221 |
ten_gods = calculator.get_ten_gods_analysis(ganzhi)
|
222 |
|
|
|
|
|
|
|
223 |
# 결과 포맷팅
|
224 |
+
result = format_saju_result(ganzhi, elements, ten_gods, birth_datetime, gender, birth_place, calculator)
|
225 |
|
226 |
return result
|
227 |
|
228 |
+
except ValueError as ve:
|
229 |
+
return f"❌ 입력 오류: {str(ve)}\n\n💡 입력 예시:\n- 생년월일: 19900207, 1990-2-7\n- 시간: 0815, 8:15"
|
230 |
+
|
231 |
except Exception as e:
|
232 |
+
return f"❌ 계산 중 오류가 발생했습니다: {str(e)}"
|
233 |
|
234 |
+
def format_saju_result(ganzhi, elements, ten_gods, birth_datetime, gender, birth_place, calculator):
|
235 |
"""사주 결과 포맷팅"""
|
236 |
|
237 |
result = f"""
|
|
|
269 |
|
270 |
"""
|
271 |
|
|
|
|
|
272 |
# 오행 분석 추가
|
273 |
total_elements = sum(elements.values())
|
274 |
for element, count in elements.items():
|
|
|
283 |
### 오행 균형 분석
|
284 |
- **가장 강한 오행**: {max_element} ({elements[max_element]}개)
|
285 |
- **가장 약한 오행**: {min_element} ({elements[min_element]}개)
|
|
|
286 |
|
|
|
|
|
287 |
## 🎭 십신(十神) 분석
|
288 |
|
289 |
"""
|
|
|
294 |
result += f"- 천간: {ten_gods[pillar_name]['stem_relation']}\n"
|
295 |
result += f"- 지지: {ten_gods[pillar_name]['branch_relation']}\n\n"
|
296 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
297 |
# 기본 해석 추가
|
298 |
result += f"""
|
|
|
299 |
## 💡 기본 해석
|
300 |
|
301 |
### 성격 특���
|
|
|
311 |
- 절기, 시간대, 지역별 차이 등이 고려되지 않았을 수 있습니다.
|
312 |
|
313 |
---
|
314 |
+
*생성일시: {datetime.datetime.now().strftime('%Y년 %m월 %d일 %H시 %M분')}*
|
315 |
"""
|
316 |
|
317 |
return result
|
318 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
319 |
def create_interface():
|
320 |
+
"""Gradio 인터페이스 생성"""
|
321 |
with gr.Blocks(title="🔮 사주명리 만세력 시스템") as demo:
|
322 |
gr.HTML("""
|
323 |
<div style="text-align: center; padding: 20px;">
|
|
|
332 |
|
333 |
birth_date = gr.Textbox(
|
334 |
label="생년월일",
|
335 |
+
placeholder="19900207 또는 1990-2-7",
|
336 |
+
info="8자리 숫자 또는 구분자 포함하여 입력"
|
337 |
)
|
338 |
|
339 |
birth_time = gr.Textbox(
|
340 |
label="태어난 시간 (선택사항)",
|
341 |
+
placeholder="0815 또는 8:15",
|
342 |
+
info="4자리 숫자 또는 구분자 포함하여 입력. 비우면 정오로 설정"
|
343 |
)
|
344 |
|
345 |
gender = gr.Radio(
|
|
|
350 |
|
351 |
birth_place = gr.Textbox(
|
352 |
label="출생지",
|
353 |
+
placeholder="대구",
|
354 |
info="시/도 단위로 입력해주세요"
|
355 |
)
|
356 |
|
|
|
374 |
|
375 |
# 예시 데이터로 자동 실행
|
376 |
demo.load(
|
377 |
+
fn=lambda: calculate_saju("19900207", "0815", "여", "대구"),
|
378 |
outputs=result_output
|
379 |
)
|
380 |
|
|
|
387 |
|
388 |
return demo
|
389 |
|
|
|
|
|
|
|
390 |
if __name__ == "__main__":
|
391 |
demo = create_interface()
|
392 |
demo.launch(
|