Spaces:
Sleeping
Sleeping
import gradio as gr | |
import datetime | |
import re | |
from calendar import monthrange | |
class SajuCalculator: | |
def __init__(self): | |
# 천간 (하늘줄기) | |
self.heavenly_stems = ['갑', '을', '병', '정', '무', '기', '경', '신', '임', '계'] | |
# 지지 (땅가지) | |
self.earthly_branches = ['자', '축', '인', '묘', '진', '사', '오', '미', '신', '유', '술', '해'] | |
# 오행 | |
self.five_elements = { | |
'갑': '목', '을': '목', '병': '화', '정': '화', '무': '토', | |
'기': '토', '경': '금', '신': '금', '임': '수', '계': '수', | |
'자': '수', '축': '토', '인': '목', '묘': '목', '진': '토', | |
'사': '화', '오': '화', '미': '토', '신': '금', '유': '금', | |
'술': '토', '해': '수' | |
} | |
# 십신 | |
self.ten_gods = { | |
'목': {'목': '비견', '화': '식신', '토': '편재', '금': '편관', '수': '편인'}, | |
'화': {'목': '편인', '화': '비견', '토': '식신', '금': '편재', '수': '편관'}, | |
'토': {'목': '편관', '화': '편인', '토': '비견', '금': '식신', '수': '편재'}, | |
'금': {'목': '편재', '화': '편관', '토': '편인', '금': '비견', '수': '식신'}, | |
'수': {'목': '식신', '화': '편재', '토': '편관', '금': '편인', '수': '비견'} | |
} | |
# 지장간 (지지 안에 숨어있는 천간들) | |
self.hidden_stems = { | |
'자': ['계'], '축': ['기', '계', '신'], '인': ['갑', '병', '무'], '묘': ['을'], | |
'진': ['무', '을', '계'], '사': ['병', '무', '경'], '오': ['정', '기'], '미': ['기', '정', '을'], | |
'신': ['경', '임', '무'], '유': ['신'], '술': ['무', '신', '정'], '해': ['임', '갑'] | |
} | |
# 12운성 | |
self.twelve_phases = ['장생', '목욕', '관대', '건록', '제왕', '쇠', '병', '사', '묘', '절', '태', '양'] | |
# 절기 정보 (월별 대략적인 날짜 - 실제로는 년도별로 다름) | |
self.seasonal_divisions = { | |
1: {'소한': 6, '대한': 21}, | |
2: {'입춘': 4, '우수': 19}, | |
3: {'경칩': 6, '춘분': 21}, | |
4: {'청명': 5, '곡우': 20}, | |
5: {'입하': 6, '소만': 21}, | |
6: {'망종': 6, '하지': 21}, | |
7: {'소서': 7, '대서': 23}, | |
8: {'입추': 8, '처서': 23}, | |
9: {'백로': 8, '추분': 23}, | |
10: {'한로': 8, '상강': 24}, | |
11: {'입동': 7, '소설': 22}, | |
12: {'대설': 7, '동지': 22} | |
} | |
# 지역별 시간 보정 (서울 기준 분 단위) | |
self.location_offsets = { | |
'서울': 0, '서울특별시': 0, '경기': 0, '경기도': 0, '인천': 0, '인천광역시': 0, | |
'강원': +12, '강원도': +12, '춘천': +12, '원주': +8, '강릉': +20, | |
'충북': -8, '충청북도': -8, '청주': -8, '충주': 0, | |
'충남': -16, '충청남도': -16, '대전': -12, '대전광역시': -12, '천안': -12, | |
'전북': -20, '전라북도': -20, '전주': -20, '군산': -24, | |
'전남': -24, '전라남도': -24, '광주': -20, '광주광역시': -20, '목포': -32, '여수': -16, | |
'경북': +8, '경상북도': +8, '대구': +4, '대구광역시': +4, '포항': +20, '경주': +16, | |
'경남': -4, '경상남도': -4, '부산': +12, '부산광역시': +12, '울산': +16, '울산광역시': +16, '창원': +4, '마산': +4, '진주': -8, | |
'제주': -20, '제주도': -20, '제주시': -20, '서귀포': -20 | |
} | |
def get_location_offset(self, location): | |
"""출생지에 따른 시간 보정값 반환 (분 단위)""" | |
if not location: | |
return 0 | |
location = location.strip() | |
# 정확한 매칭 시도 | |
if location in self.location_offsets: | |
return self.location_offsets[location] | |
# 부분 매칭 시도 | |
for key, offset in self.location_offsets.items(): | |
if key in location or location in key: | |
return offset | |
return 0 # 기본값 (서울 기준) | |
def parse_date(self, date_str): | |
"""날짜 파싱""" | |
numbers = re.findall(r'\d+', str(date_str)) | |
if not numbers: | |
raise ValueError("날짜에서 숫자를 찾을 수 없습니다") | |
if len(numbers) == 1: | |
num_str = numbers[0] | |
if len(num_str) == 8: # YYYYMMDD | |
year = int(num_str[:4]) | |
month = int(num_str[4:6]) | |
day = int(num_str[6:8]) | |
elif len(num_str) == 6: # YYMMDD | |
year_part = int(num_str[:2]) | |
year = 1900 + year_part if year_part > 30 else 2000 + year_part | |
month = int(num_str[2:4]) | |
day = int(num_str[4:6]) | |
else: | |
raise ValueError(f"날짜 형식을 인식할 수 없습니다: {num_str}") | |
elif len(numbers) >= 3: | |
year = int(numbers[0]) | |
month = int(numbers[1]) | |
day = int(numbers[2]) | |
if year < 100: | |
year = 1900 + year if year > 30 else 2000 + year | |
else: | |
raise ValueError("날짜 정보가 부족합니다") | |
return year, month, day | |
def parse_time(self, time_str): | |
"""시간 파싱""" | |
if not time_str: | |
return 12, 0 | |
numbers = re.findall(r'\d+', str(time_str)) | |
if not numbers: | |
return 12, 0 | |
if len(numbers) == 1: | |
time_num = numbers[0] | |
if len(time_num) == 4: # HHMM | |
hour = int(time_num[:2]) | |
minute = int(time_num[2:4]) | |
elif len(time_num) == 3: # HMM | |
hour = int(time_num[0]) | |
minute = int(time_num[1:3]) | |
else: # H or HH | |
hour = int(time_num) | |
minute = 0 | |
else: | |
hour = int(numbers[0]) | |
minute = int(numbers[1]) if len(numbers) > 1 else 0 | |
hour = hour % 24 | |
return hour, minute | |
def get_seasonal_month(self, year, month, day): | |
"""절기를 고려한 월주 계산""" | |
# 간단한 절기 계산 (정확하지 않지만 대략적) | |
seasonal_month = month | |
# 입춘(2월 4일경) 기준으로 월 조정 | |
if month == 1: | |
seasonal_month = 12 # 12월 (축월) | |
elif month == 2: | |
if day < 4: # 입춘 전 | |
seasonal_month = 12 | |
else: # 입춘 후 | |
seasonal_month = 1 # 1월 (인월) | |
else: | |
seasonal_month = month - 1 | |
return seasonal_month | |
def get_ganzhi(self, year, month, day, hour): | |
"""간지 계산 (절기 고려)""" | |
base_date = datetime.datetime(1900, 1, 1) | |
target_date = datetime.datetime(year, month, day) | |
days_diff = (target_date - base_date).days | |
# 연주 계산 | |
year_stem_index = (year - 1900 + 6) % 10 | |
year_branch_index = (year - 1900 + 0) % 12 | |
# 월주 계산 (절기 고려) | |
seasonal_month = self.get_seasonal_month(year, month, day) | |
month_branch_index = (seasonal_month + 1) % 12 # 인월부터 시작 | |
month_stem_index = (year_stem_index * 2 + seasonal_month) % 10 | |
# 일주 계산 | |
day_stem_index = (days_diff + 10) % 10 | |
day_branch_index = (days_diff + 2) % 12 | |
# 시주 계산 | |
hour_branch_index = ((hour + 1) // 2) % 12 | |
hour_stem_index = (day_stem_index * 2 + hour_branch_index) % 10 | |
return { | |
'year': (self.heavenly_stems[year_stem_index], self.earthly_branches[year_branch_index]), | |
'month': (self.heavenly_stems[month_stem_index], self.earthly_branches[month_branch_index]), | |
'day': (self.heavenly_stems[day_stem_index], self.earthly_branches[day_branch_index]), | |
'hour': (self.heavenly_stems[hour_stem_index], self.earthly_branches[hour_branch_index]) | |
} | |
def analyze_elements(self, ganzhi): | |
"""오행 분석 (지장간 포함)""" | |
element_count = {'목': 0, '화': 0, '토': 0, '금': 0, '수': 0} | |
# 천간 오행 (가중치 1.0) | |
for pillar in ganzhi.values(): | |
stem_element = self.five_elements[pillar[0]] | |
element_count[stem_element] += 1.0 | |
# 지지 오행 (가중치 0.8) | |
for pillar in ganzhi.values(): | |
branch_element = self.five_elements[pillar[1]] | |
element_count[branch_element] += 0.8 | |
# 지장간 오행 (가중치 0.3) | |
for pillar in ganzhi.values(): | |
hidden = self.hidden_stems[pillar[1]] | |
for stem in hidden: | |
stem_element = self.five_elements[stem] | |
element_count[stem_element] += 0.3 / len(hidden) | |
return element_count | |
def get_ten_gods_analysis(self, ganzhi): | |
"""십신 분석 (지장간 포함)""" | |
day_stem = ganzhi['day'][0] | |
day_element = self.five_elements[day_stem] | |
analysis = {} | |
for pillar_name, pillar in ganzhi.items(): | |
stem_element = self.five_elements[pillar[0]] | |
branch_element = self.five_elements[pillar[1]] | |
stem_relation = self.ten_gods[day_element][stem_element] | |
branch_relation = self.ten_gods[day_element][branch_element] | |
# 지장간 십신 | |
hidden_relations = [] | |
for hidden_stem in self.hidden_stems[pillar[1]]: | |
hidden_element = self.five_elements[hidden_stem] | |
hidden_relation = self.ten_gods[day_element][hidden_element] | |
hidden_relations.append(f"{hidden_stem}({hidden_relation})") | |
analysis[pillar_name] = { | |
'stem_relation': stem_relation, | |
'branch_relation': branch_relation, | |
'hidden_relations': hidden_relations | |
} | |
return analysis | |
def get_element_personality(element): | |
"""오행별 성격 특성""" | |
personalities = { | |
'목': "창의적이고 성장 지향적이며, 유연하고 협력적인 성격을 가지고 있습니다.", | |
'화': "열정적이고 활동적이며, 밝고 사교적인 성격을 가지고 있습니다.", | |
'토': "안정적이고 신중하며, 포용력이 있고 책임감이 강한 성격을 가지고 있습니다.", | |
'금': "원칙적이고 정의로우며, 결단력이 있고 리더십이 강한 성격을 가지고 있습니다.", | |
'수': "지혜롭고 적응력이 있으며, 깊이 있고 신중한 성격을 가지고 있습니다." | |
} | |
return personalities.get(element, "균형 잡힌 성격을 가지고 있습니다.") | |
def get_element_balance_advice(elements): | |
"""오행 균형에 따른 조언""" | |
max_element = max(elements, key=elements.get) | |
min_element = min(elements, key=elements.get) | |
advice = f"현재 {max_element}가 가장 강하고 {min_element}가 가장 약합니다. " | |
if elements[max_element] - elements[min_element] > 2: | |
advice += f"{min_element}를 보강하고 {max_element}의 기운을 조절하는 것이 좋겠습니다." | |
else: | |
advice += "전체적으로 균형이 잘 잡혀 있는 편입니다." | |
return advice | |
def format_saju_result(calculator, ganzhi, elements, ten_gods, birth_info): | |
"""사주 결과 포맷팅 - 전문적인 표 형태로 출력""" | |
# 오행별 색상 설정 | |
element_colors = { | |
'목': '#28a745', # 녹색 | |
'화': '#dc3545', # 빨강 | |
'토': '#ffc107', # 노랑 | |
'금': '#6c757d', # 회색 | |
'수': '#007bff' # 파랑 | |
} | |
def get_colored_element(char, element): | |
color = element_colors.get(element, '#000000') | |
return f'<span style="color: {color}; font-weight: bold;">{char}</span>' | |
def get_colored_ganzhi(stem, branch): | |
stem_element = calculator.five_elements[stem] | |
branch_element = calculator.five_elements[branch] | |
colored_stem = get_colored_element(stem, stem_element) | |
colored_branch = get_colored_element(branch, branch_element) | |
return f'{colored_stem}{colored_branch}' | |
# 시간 보정 정보 | |
time_correction_info = "" | |
if birth_info['location_offset'] != 0: | |
sign = "+" if birth_info['location_offset'] > 0 else "" | |
time_correction_info = f""" | |
### ⏰ 출생지 시간 보정 | |
- **입력 시간**: {birth_info['original_time']} | |
- **보정 시간**: {birth_info['corrected_time']} ({birth_info['birth_place']} 기준 {sign}{birth_info['location_offset']}분 보정) | |
""" | |
birth_datetime = birth_info['birth_datetime'] | |
gender = birth_info['gender'] | |
birth_place = birth_info['birth_place'] | |
corrected_time = birth_info['corrected_time'] | |
result = f""" | |
# 🔮 사주명리 만세력 분석결과 | |
## 📋 기본정보 | |
- **생년월일**: {birth_datetime.strftime('%Y년 %m월 %d일')} | |
- **출생시간**: {corrected_time} ({birth_place}) | |
- **성별**: {gender} | |
{time_correction_info} | |
## 🏛️ 사주(四柱) 만세력표 | |
<div style="text-align: center; font-size: 16px;"> | |
| 구분 | **시주(時柱)** | **일주(日柱)** | **월주(月柱)** | **연주(年柱)** | | |
|:---:|:---:|:---:|:---:|:---:| | |
| **천간** | {get_colored_element(ganzhi['hour'][0], calculator.five_elements[ganzhi['hour'][0]])} | {get_colored_element(ganzhi['day'][0], calculator.five_elements[ganzhi['day'][0]])} | {get_colored_element(ganzhi['month'][0], calculator.five_elements[ganzhi['month'][0]])} | {get_colored_element(ganzhi['year'][0], calculator.five_elements[ganzhi['year'][0]])} | | |
| **십신** | {ten_gods['hour']['stem_relation']} | {ten_gods['day']['stem_relation']} | {ten_gods['month']['stem_relation']} | {ten_gods['year']['stem_relation']} | | |
| **지지** | {get_colored_element(ganzhi['hour'][1], calculator.five_elements[ganzhi['hour'][1]])} | {get_colored_element(ganzhi['day'][1], calculator.five_elements[ganzhi['day'][1]])} | {get_colored_element(ganzhi['month'][1], calculator.five_elements[ganzhi['month'][1]])} | {get_colored_element(ganzhi['year'][1], calculator.five_elements[ganzhi['year'][1]])} | | |
| **십신** | {ten_gods['hour']['branch_relation']} | {ten_gods['day']['branch_relation']} | {ten_gods['month']['branch_relation']} | {ten_gods['year']['branch_relation']} | | |
| **간지** | **{get_colored_ganzhi(ganzhi['hour'][0], ganzhi['hour'][1])}** | **{get_colored_ganzhi(ganzhi['day'][0], ganzhi['day'][1])}** | **{get_colored_ganzhi(ganzhi['month'][0], ganzhi['month'][1])}** | **{get_colored_ganzhi(ganzhi['year'][0], ganzhi['year'][1])}** | | |
| **지장간** | {"·".join(calculator.hidden_stems[ganzhi['hour'][1]])} | {"·".join(calculator.hidden_stems[ganzhi['day'][1]])} | {"·".join(calculator.hidden_stems[ganzhi['month'][1]])} | {"·".join(calculator.hidden_stems[ganzhi['year'][1]])} | | |
</div> | |
**💫 사주 구성** | |
- **일간(日干)**: {get_colored_element(ganzhi['day'][0], calculator.five_elements[ganzhi['day'][0]])} - 본인을 나타내는 핵심 요소 | |
- **월령(月令)**: {get_colored_element(ganzhi['month'][1], calculator.five_elements[ganzhi['month'][1]])} - 계절의 기운과 성장 환경 | |
## 🌟 오행(五行) 분석 | |
<div style="text-align: center;"> | |
| 오행 | 천간+지지+지장간 | 비율 | 상태 | 특징 | | |
|:---:|:---:|:---:|:---:|:---:| | |
| {get_colored_element('목', '목')} | {elements['목']:.1f}점 | {(elements['목']/sum(elements.values())*100):.1f}% | {'매우강함' if elements['목'] >= 3 else '강함' if elements['목'] >= 2 else '보통' if elements['목'] >= 1 else '약함'} | 성장, 창의, 인자함 | | |
| {get_colored_element('화', '화')} | {elements['화']:.1f}점 | {(elements['화']/sum(elements.values())*100):.1f}% | {'매우강함' if elements['화'] >= 3 else '강함' if elements['화'] >= 2 else '보통' if elements['화'] >= 1 else '약함'} | 열정, 활동, 표현력 | | |
| {get_colored_element('토', '토')} | {elements['토']:.1f}점 | {(elements['토']/sum(elements.values())*100):.1f}% | {'매우강함' if elements['토'] >= 3 else '강함' if elements['토'] >= 2 else '보통' if elements['토'] >= 1 else '약함'} | 안정, 포용, 신뢰 | | |
| {get_colored_element('금', '금')} | {elements['금']:.1f}점 | {(elements['금']/sum(elements.values())*100):.1f}% | {'매우강함' if elements['금'] >= 3 else '강함' if elements['금'] >= 2 else '보통' if elements['금'] >= 1 else '약함'} | 의지, 결단, 정의 | | |
| {get_colored_element('수', '수')} | {elements['수']:.1f}점 | {(elements['수']/sum(elements.values())*100):.1f}% | {'매우강함' if elements['수'] >= 3 else '강함' if elements['수'] >= 2 else '보통' if elements['수'] >= 1 else '약함'} | 지혜, 유연, 깊이 | | |
</div> | |
### 오행 균형 분석 | |
""" | |
max_element = max(elements, key=elements.get) | |
min_element = min(elements, key=elements.get) | |
result += f"- **가장 강한 오행**: {get_colored_element(max_element, max_element)} ({elements[max_element]:.1f}점)\n" | |
result += f"- **가장 약한 오행**: {get_colored_element(min_element, min_element)} ({elements[min_element]:.1f}점)\n" | |
result += """ | |
## 🎭 십신(十神) 세부 분석 | |
<div style="text-align: center;"> | |
| 구분 | **시주** | **일주** | **월주** | **연주** | | |
|:---:|:---:|:---:|:---:|:---:|""" | |
result += f""" | |
| **천간 십신** | {ten_gods['hour']['stem_relation']} | {ten_gods['day']['stem_relation']} | {ten_gods['month']['stem_relation']} | {ten_gods['year']['stem_relation']} | | |
| **지지 십신** | {ten_gods['hour']['branch_relation']} | {ten_gods['day']['branch_relation']} | {ten_gods['month']['branch_relation']} | {ten_gods['year']['branch_relation']} | | |
| **지장간** | {' '.join(ten_gods['hour']['hidden_relations'])} | {' '.join(ten_gods['day']['hidden_relations'])} | {' '.join(ten_gods['month']['hidden_relations'])} | {' '.join(ten_gods['year']['hidden_relations'])} | | |
</div> | |
## 💡 종합 해석 | |
### 일간 분석 | |
- **일간**: {get_colored_element(ganzhi['day'][0], calculator.five_elements[ganzhi['day'][0]])} ({calculator.five_elements[ganzhi['day'][0]]}행) | |
- **성격**: {get_element_personality(calculator.five_elements[ganzhi['day'][0]])} | |
### 오행 조화 분석 | |
{get_element_balance_advice(elements)} | |
### 십신 구성 특징 | |
- **관성(편관/정관)**: {"있음" if any("관" in str(ten_gods[p]['stem_relation']) or "관" in str(ten_gods[p]['branch_relation']) for p in ten_gods) else "없음"} - 리더십, 책임감 | |
- **재성(편재/정재)**: {"있음" if any("재" in str(ten_gods[p]['stem_relation']) or "재" in str(ten_gods[p]['branch_relation']) for p in ten_gods) else "없음"} - 재물운, 실용성 | |
- **인성(편인/정인)**: {"있음" if any("인" in str(ten_gods[p]['stem_relation']) or "인" in str(ten_gods[p]['branch_relation']) for p in ten_gods) else "없음"} - 학습력, 지혜 | |
- **식상(식신/상관)**: {"있음" if any("식" in str(ten_gods[p]['stem_relation']) or "상" in str(ten_gods[p]['branch_relation']) for p in ten_gods) else "없음"} - 창의력, 표현력 | |
--- | |
### 📌 주의사항 | |
- 본 분석은 절기를 고려한 전통 사주명리학 원리에 따른 것입니다 | |
- 지장간과 십신 관계를 포함한 종합적 분석입니다 | |
- 정확한 운세 해석을 위해서는 전문가 상담을 권장합니다 | |
*분석 일시: {datetime.datetime.now().strftime('%Y년 %m월 %d일 %H시 %M분')}* | |
""" | |
return result | |
def calculate_saju(birth_date, birth_time, gender, birth_place): | |
"""사주 계산 메인 함수""" | |
# SajuCalculator 인스턴스 생성 | |
calculator = SajuCalculator() | |
try: | |
# 입력 검증 | |
if not birth_date: | |
return "❌ 생년월일을 입력해주세요." | |
# 날짜 파싱 | |
year, month, day = calculator.parse_date(birth_date) | |
# 시간 파싱 | |
hour, minute = calculator.parse_time(birth_time) | |
# 출생지에 따른 시간 보정 | |
location_offset = calculator.get_location_offset(birth_place) | |
# 보정된 시간 계산 | |
corrected_minute = minute + location_offset | |
corrected_hour = hour | |
# 분이 60을 넘거나 0 미만인 경우 시간 조정 | |
if corrected_minute >= 60: | |
corrected_hour += corrected_minute // 60 | |
corrected_minute = corrected_minute % 60 | |
elif corrected_minute < 0: | |
corrected_hour -= (-corrected_minute - 1) // 60 + 1 | |
corrected_minute = 60 + (corrected_minute % 60) | |
# 시간이 24를 넘거나 0 미만인 경우 조정 | |
corrected_hour = corrected_hour % 24 | |
# 날짜 유효성 검사 | |
if year < 1900 or year > 2100: | |
return f"❌ 연도는 1900~2100 사이여야 합니다. 입력된 연도: {year}" | |
if month < 1 or month > 12: | |
return f"❌ 월은 1~12 사이여야 합니다. 입력된 월: {month}" | |
if day < 1 or day > 31: | |
return f"❌ 일은 1~31 사이여야 합니다. 입력된 일: {day}" | |
# datetime 객체 생성 (보정된 시간 사용) | |
birth_datetime = datetime.datetime(year, month, day, corrected_hour, corrected_minute) | |
original_time = f"{hour:02d}:{minute:02d}" | |
corrected_time = f"{corrected_hour:02d}:{corrected_minute:02d}" | |
# 출생 정보 딕셔너리 | |
birth_info = { | |
'birth_datetime': birth_datetime, | |
'gender': gender, | |
'birth_place': birth_place, | |
'original_time': original_time, | |
'corrected_time': corrected_time, | |
'location_offset': location_offset | |
} | |
# 간지 계산 (절기 고려) | |
ganzhi = calculator.get_ganzhi(year, month, day, corrected_hour) | |
# 오행 분석 (지장간 포함) | |
elements = calculator.analyze_elements(ganzhi) | |
# 십신 분석 (지장간 포함) | |
ten_gods = calculator.get_ten_gods_analysis(ganzhi) | |
# 결과 포맷팅 | |
result = format_saju_result(calculator, ganzhi, elements, ten_gods, birth_info) | |
return result | |
except ValueError as ve: | |
return f"❌ 입력 오류: {str(ve)}\n\n💡 입력 예시:\n- 생년월일: 19851015, 1985-10-15\n- 시간: 1430, 14:30" | |
except Exception as e: | |
return f"❌ 계산 중 오류가 발생했습니다: {str(e)}" | |
def create_interface(): | |
"""Gradio 인터페이스 생성""" | |
with gr.Blocks(title="🔮 전문 사주명리 만세력 시스템") as demo: | |
gr.HTML(""" | |
<div style="text-align: center; padding: 20px;"> | |
<h1>🔮 전문 사주명리학 만세력 분석 시스템</h1> | |
<p><strong>절기 고려 · 지장간 분석 · 출생지 시간 보정</strong></p> | |
<p>생년월일시와 출생지 정보를 입력하시면 전문적인 만세력을 분석해드립니다.</p> | |
</div> | |
""") | |
with gr.Row(): | |
with gr.Column(scale=1): | |
gr.HTML("<h3>📝 정보 입력</h3>") | |
birth_date = gr.Textbox( | |
label="생년월일", | |
placeholder="19851015 또는 1985-10-15", | |
info="8자리 숫자 또는 구분자 포함하여 입력 (양력 기준)" | |
) | |
birth_time = gr.Textbox( | |
label="태어난 시간 (선택사항)", | |
placeholder="1430 또는 14:30", | |
info="정확한 시간을 입력하세요. 비우면 정오(12시)로 설정됩니다." | |
) | |
gender = gr.Radio( | |
choices=["남", "여"], | |
label="성별", | |
value="남" | |
) | |
birth_place = gr.Textbox( | |
label="출생지", | |
placeholder="서울특별시", | |
info="정확한 출생지를 입력하면 시간 보정이 적용됩니다" | |
) | |
calculate_btn = gr.Button( | |
"🔮 전문 만세력 분석하기", | |
variant="primary" | |
) | |
with gr.Row(): | |
with gr.Column(): | |
result_output = gr.Markdown( | |
label="분석 결과", | |
value="👆 위의 정보를 입력하고 '전문 만세력 분석하기' 버튼을 클릭하세요." | |
) | |
# 이벤트 연결 | |
calculate_btn.click( | |
fn=calculate_saju, | |
inputs=[birth_date, birth_time, gender, birth_place], | |
outputs=result_output | |
) | |
gr.HTML(""" | |
<div style="text-align: center; padding: 20px; margin-top: 30px; border-top: 1px solid #eee;"> | |
<h4>🔍 시스템 특징</h4> | |
<div style="display: flex; justify-content: center; gap: 30px; flex-wrap: wrap;"> | |
<div>✅ <strong>절기 고려</strong><br>정확한 월주 계산</div> | |
<div>✅ <strong>지장간 분석</strong><br>지지 안 숨은 천간</div> | |
<div>✅ <strong>십신 세분화</strong><br>천간/지지/지장간별</div> | |
<div>✅ <strong>시간 보정</strong><br>전국 지역별 적용</div> | |
<div>✅ <strong>오행 가중치</strong><br>천간/지지/지장간</div> | |
</div> | |
<p style="margin-top: 15px;"><small>※ 본 시스템은 전통 사주명리학을 기반으로 하며, 참고용으로만 활용해주시기 바랍니다.</small></p> | |
</div> | |
""") | |
return demo | |
if __name__ == "__main__": | |
demo = create_interface() | |
demo.launch( | |
server_name="0.0.0.0", | |
server_port=7860, | |
share=True | |
) |