|
|
|
|
|
import os |
|
import openai |
|
import gradio as gr |
|
from zhdate import ZhDate |
|
from datetime import datetime |
|
|
|
localrun = False |
|
DESKTOP_KEY = False |
|
|
|
|
|
solar_year = 1998 |
|
solar_month = 5 |
|
solar_day = 18 |
|
time_hour = 3 |
|
time_min = 14 |
|
gender = 0 |
|
|
|
|
|
zi_adjust = 2 |
|
|
|
''' |
|
排盤有以下幾個步驟 |
|
|
|
1. 安十二宮 |
|
|
|
2. 起寅首、定納音五行局 |
|
|
|
3. 定紫微星 |
|
|
|
4. 安主星 |
|
|
|
5. 安四化星 |
|
|
|
''' |
|
|
|
def gen_chart(solar_year, solar_month, solar_day, time_hour, time_min, gender): |
|
from datetime import timedelta, datetime |
|
|
|
|
|
fiveoldsong = [ 4, 2, 6, 4, 2, 6, 2, 6, 5, 2, 6, 5, 6, 5, 3, 6, 5, 3, 5, 3, 4, 5, 3, 4, 3, 4, 2, 3, 4, 2 ]; |
|
|
|
|
|
fiveway = ['水二局','木三局','金四局','土五局','火六局'] |
|
|
|
|
|
ziwei_table = [2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,1,1,2,2,3,3,4,4,5,5,2,3,6,3,4,7,4,5,8,5,6,9,6,7,10,7,8,11,8,9,12,9,10,1,10,11,2,11,12,12,5,2,3,1,6,3,4,2,7,4,5,3,8,5,6,4,9,6,7,5,10,7,8,6,11,8,9,7,12,7,12,5,2,3,8,1,6,3,4,9,2,7,4,5,10,3,8,5,6,11,5,9,6,7,12,5,10,7,8,10,7,12,5,2,3,11,8,1,6,3,4,12,9,2,7,4,5,1,10,3,8,5,6,2,11,4,9,6,7]; |
|
|
|
|
|
tianfu_table = [5,4,3,2,1,12,11,10,9,8,7,6] |
|
|
|
def get_year_hepos(birthdatetime): |
|
start_year = (birthdatetime.year - 3) % 60 |
|
hs_pos = start_year % 10 |
|
if hs_pos == 0: |
|
hs_pos = 10 |
|
gb_pos = start_year % 12 |
|
if gb_pos == 0: |
|
gb_pos = 12 |
|
year_hepos = [hs_pos, gb_pos] |
|
return year_hepos |
|
|
|
def get_birth_time_epos(birthdatetime): |
|
if birthdatetime.hour in range(23, 1): |
|
return 1 |
|
elif birthdatetime.hour in range(1, 3): |
|
return 2 |
|
elif birthdatetime.hour in range(3, 5): |
|
return 3 |
|
elif birthdatetime.hour in range(5, 7): |
|
return 4 |
|
elif birthdatetime.hour in range(7, 9): |
|
return 5 |
|
elif birthdatetime.hour in range(9, 11): |
|
return 6 |
|
elif birthdatetime.hour in range(11, 13): |
|
return 7 |
|
elif birthdatetime.hour in range(13, 15): |
|
return 8 |
|
elif birthdatetime.hour in range(15, 17): |
|
return 9 |
|
elif birthdatetime.hour in range(17, 19): |
|
return 10 |
|
elif birthdatetime.hour in range(19, 21): |
|
return 11 |
|
elif birthdatetime.hour in range(21, 23): |
|
return 12 |
|
return 1 |
|
|
|
def get_self_palace_epos(birthdatetime, isleap): |
|
|
|
month_position = birthdatetime.month |
|
hour_position = get_birth_time_epos(birthdatetime) |
|
|
|
|
|
if isleap == True: |
|
if Zwsetting.intercalary_month == 2: |
|
month_position += 1 |
|
elif Zwsetting.intercalary_month == 3: |
|
if birthdatetime.day > 15: |
|
month_position += 1 |
|
|
|
position = ( month_position + 3 - hour_position )%12 |
|
position = 12 if position == 0 else position |
|
|
|
return position |
|
|
|
def get_body_palace_epos(birthdatetime, isleap): |
|
|
|
month_position = birthdatetime.month |
|
hour_position = get_birth_time_epos(birthdatetime) |
|
|
|
|
|
if isleap == True: |
|
if Zwsetting.intercalary_month == 2: |
|
month_position += 1 |
|
elif Zwsetting.intercalary_month == 3: |
|
if birthdatetime.day > 15: |
|
month_position += 1 |
|
|
|
|
|
position = ( month_position + 1 + hour_position )%12 |
|
position = 12 if position == 0 else position |
|
return position |
|
|
|
def get_yin_hpos(birthdatetime): |
|
start_year = (birthdatetime.year - 3) % 60 |
|
hs_pos = start_year % 10 |
|
if hs_pos == 0: |
|
hs_pos = 10 |
|
self_hpos = ((1+hs_pos*2) % 10) |
|
return self_hpos |
|
|
|
|
|
|
|
|
|
solar_birth_datetime = datetime(int(solar_year), int(solar_month), int(solar_day), time_hour, time_min) |
|
|
|
|
|
if zi_adjust == 2 and time_hour >= 23 : |
|
solar_birth_datetime = solar_birth_datetime + timedelta(days=1) |
|
|
|
|
|
|
|
|
|
|
|
|
|
year_hepos = get_year_hepos(solar_birth_datetime) |
|
|
|
|
|
|
|
if gender == 2: |
|
gender_pos = 2 |
|
else: |
|
gender_pos = 3 |
|
|
|
|
|
yin_yang_pos = 0 if year_hepos[0] % 2 == 1 else 1 |
|
|
|
|
|
|
|
birth_time_epos = get_birth_time_epos(solar_birth_datetime) |
|
|
|
|
|
self_palace_epos = get_self_palace_epos(solar_birth_datetime, False) |
|
|
|
|
|
yin_hpos = get_yin_hpos(solar_birth_datetime) |
|
|
|
|
|
|
|
self_yin_dist = 0 |
|
if self_palace_epos >= 3: |
|
self_yin_dist = self_palace_epos - 3 |
|
else: |
|
self_yin_dist = self_palace_epos + 9 |
|
|
|
self_palace_hpos = 0 |
|
if (self_yin_dist + yin_hpos) > 10: |
|
self_palace_hpos = (self_yin_dist + yin_hpos) - 10 |
|
else: |
|
self_palace_hpos = self_yin_dist + yin_hpos |
|
|
|
|
|
|
|
body_palace_epos = get_body_palace_epos(solar_birth_datetime, False) |
|
|
|
|
|
fiveway_param_1 = int(( self_palace_hpos + 1) / 2 if self_palace_hpos % 2 == 1 else self_palace_hpos / 2 ) |
|
fiveway_param_2 = int(( self_palace_epos + 1) / 2 if self_palace_epos % 2 == 1 else self_palace_epos / 2 ) |
|
fiveway_pos = fiveoldsong[(fiveway_param_1 - 1) * 6 + fiveway_param_2 - 1] |
|
|
|
|
|
ziwei_pos = ziwei_table[(fiveway_pos -2) * 30 + int(solar_day)-1] |
|
|
|
|
|
tianfu_pos = tianfu_table[ziwei_pos-1] |
|
outstr=f'紫微在= {ziwei_pos} 五行局= {fiveway_pos} 命宮= {self_palace_epos}' |
|
|
|
return outstr |
|
|
|
''' |
|
# 產生 chat(命盤) 物件 |
|
chart = Chart( [self_palace_hpos, self_palace_epos], body_palace_epos) |
|
chart.birth_year_hepos = year_hepos |
|
chart.birth_time_epos = birth_time_epos |
|
chart.yin_hpos = yin_hpos |
|
chart.yin_yang_gender = [ yin_yang_pos, gender_pos] |
|
chart.ziwei_pos = ziwei_pos |
|
chart.fiveway_pos = fiveway_pos |
|
chart.lifechart_type = (chart.ziwei_pos -1)*12 + chart.self_palace_hepos[1] |
|
|
|
# 產生十二宮 (一共會產生 13宮,第 0 宮不使用) |
|
for i in range(0, 13, 1): |
|
chart.palaces.append(Palace(i)) |
|
|
|
# 排(產生)十二個主星 |
|
chart = gen_star(chart, ziwei_pos, tianfu_pos, year_hepos, birth_time_epos, solar_birth_datetime, Fasle) # lunar.isleap |
|
|
|
# 檢查星耀 (第 0 宮不使用) |
|
for p_index, palace in enumerate(chart.palaces): |
|
if p_index > 0: |
|
|
|
age_string = '['+str(palace.age[0])+'~'+str(palace.age[1])+']' |
|
name_string = '['+str(palace.name)+'-'+str(palace.pos[1])+']' |
|
|
|
for index, star in enumerate(palace.stars): |
|
star_weight_string = '('+str(Zwsetting.star_weight[star.weight])+')' |
|
return True |
|
''' |
|
|
|
def get_envkey(): |
|
from dotenv import load_dotenv, find_dotenv |
|
_ = load_dotenv(find_dotenv()) |
|
openai.api_key = os.environ['OPENAI_API_KEY'] |
|
print(openai.api_key) |
|
if openai.api_key: |
|
DESKTOP_KEY = openai.api_key |
|
print(DESKTOP_KEY) |
|
|
|
if localrun: |
|
get_envkey() |
|
|
|
|
|
z_mapping = { |
|
"1": "子", |
|
"2": "丑", |
|
"3": "寅", |
|
"4": "卯", |
|
"5": "辰", |
|
"6": "巳", |
|
"7": "午", |
|
"8": "未", |
|
"9": "申", |
|
"10": "酉", |
|
"11": "戌", |
|
"12": "亥", |
|
"0": "夜子" |
|
} |
|
|
|
|
|
def get_advice(bmi,temp, API_KEY, model="gpt-3.5-turbo"): |
|
if API_KEY: |
|
openai.api_key = API_KEY |
|
else: |
|
openai.api_key = DESKTOP_KEY |
|
print(openai.api_key) |
|
bmi = '' |
|
gw_main_star = '像一個獨裁霸道的君王,無法聽進別人的意見' |
|
gw_main_star = f'''天機星像一個足智多謀的軍師,ㄧ有時候會考慮太多而失去前進的勇氣 |
|
正面特徵 |
|
|
|
聰明伶俐:天機星是一顆智慧之星,因此命宮有天機的人通常聰明伶俐,善於思考。 |
|
善於交際:天機星也代表善於交際,因此命宮有天機的人通常口才好,能夠與他人建立良好的關係。 |
|
善於謀劃:天機星也代表機謀,因此命宮有天機的人通常善於謀劃,能夠在事業上取得成功。 |
|
適應能力強:天機星也代表變通,因此命宮有天機的人通常適應能力強,能夠在不同的環境中生存。 |
|
多才多藝:天機星也代表多才多藝,因此命宮有天機的人通常興趣愛好廣泛,能夠在多個領域取得成就。 |
|
人緣好:天機星也代表人緣,因此命宮有天機的人通常人緣好,能夠得到他人的幫助。 |
|
善解人意:天機星也代表體貼,因此命宮有天機的人通常善解人意,能夠理解他人的感受。 |
|
直覺敏銳:天機星也代表直覺,因此命宮有天機的人通常直覺敏銳,能夠在遇到問題時做出正確的判斷。 |
|
|
|
負面特徵 |
|
|
|
心神不定:天機星也代表不安,因此命宮有天機的人通常心神不定,容易三心二意。 |
|
缺乏耐心:天機星也代表急躁,因此命宮有天機的人通常缺乏耐心,容易半途而廢。 |
|
容易鑽牛角尖:天機星也代表鑽研,因此命宮有天機的人通常容易鑽牛角尖,容易陷入死胡同。 |
|
容易受他人影響:天機星也代表隨波逐流,因此命宮有天機的人通常容易受他人影響,容易失去自我。 |
|
好高騖遠:天機星也代表理想化,因此命宮有天機的人通常好高騖遠,容易不切實際。 |
|
''' |
|
messages = [{"role": "system", "content": "你是一個心理權威,你會根據用戶的個性,提供至少3個,不超過5個建議。"}, |
|
{"role": "user", "content": f'我的人生以紫微斗數星象來論述是 {gw_main_star}. 請總結該論述,提出幾條相對重要的重要特徵,給出一些待人處事的建議?'},] |
|
response = openai.chat.completions.create( |
|
model=model, |
|
max_tokens=1000, |
|
messages=messages, |
|
temperature=temp, |
|
) |
|
return response.choices[0].message.content |
|
|
|
|
|
def get_gym(bmi,slide, temp, API_KEY, model="gpt-3.5-turbo"): |
|
if API_KEY: |
|
openai.api_key = API_KEY |
|
else: |
|
openai.api_key = DESKTOP_KEY |
|
print(openai.api_key) |
|
messages = [{"role": "system", "content": "You are a great fitness coach and \ |
|
you will give users great fitness plans."}, |
|
{"role": "user", "content": f'My BMI is {bmi}. I want a {slide}-point weight\ |
|
loss plan, from 1 to 10. The higher the number, the faster the weight loss.'},] |
|
response = openai.chat.completions.create( |
|
model=model, |
|
max_tokens=200, |
|
messages=messages, |
|
temperature=temp, |
|
) |
|
return response.choices[0].message.content |
|
|
|
def GWAI(year, month, day, btime, sex) -> datetime: |
|
dt_date1 = datetime(int(year), int(month), int(day)) |
|
date_lunar = ZhDate.from_datetime(dt_date1) |
|
bstr = str(date_lunar) |
|
|
|
hour = int(btime.split(":")[0]) |
|
if hour >= 23: |
|
z = 0 |
|
else: |
|
z = int((hour + 1) / 2) + 1 |
|
result=z_mapping[str(z)] |
|
output=(bstr.replace('农历','農曆') + " " + result + "時") |
|
|
|
import re |
|
match = re.search(r'(\d+)年(\d+)月(\d+)日', output) |
|
|
|
if match: |
|
my_year = match.group(1) |
|
my_month = match.group(2) |
|
my_day = match.group(3) |
|
|
|
print('<<',my_year,my_month,my_day,'>>') |
|
output2=gen_chart(int(my_year), int(my_month), int(my_day), hour, int(10), int(2)) |
|
return output,output2 |
|
|
|
|
|
|
|
|
|
year = gr.Textbox( |
|
label="生年", |
|
info="輸入你的西元出生年份", |
|
placeholder="Input your birth year here...") |
|
|
|
month = gr.Textbox( |
|
label="生月", |
|
info="輸入你的出生月份", |
|
placeholder="Input your birthday month here...",) |
|
|
|
day = gr.Textbox( |
|
label="生日", |
|
info="輸入你的出生日子", |
|
placeholder="Input your birthday day here...",) |
|
|
|
btime = gr.Textbox( |
|
label="生時", |
|
info="輸入你的出生時間 HH:MM (幾點及約略幾分即可,請用24小時制)", |
|
placeholder="Input your birth time here...",) |
|
|
|
sex = gr.Textbox( |
|
label="性別", |
|
info="輸入你是男生或女生", |
|
placeholder="Input you are male or female here...",) |
|
|
|
output_gwai = gr.Textbox( |
|
value="", |
|
label="你的農曆生日及出生時辰", |
|
info="這是從西元換算出的農曆生日及出生時辰", |
|
placeholder="Date & Time") |
|
|
|
output2_gwai = gr.Textbox( |
|
value="", |
|
label="你的紫微斗數命宮星象", |
|
info="這是你的紫微斗數命盤上,命宮裡的主星的資訊", |
|
placeholder="Stars in your master plate.") |
|
|
|
advice = gr.Textbox( |
|
label="人生建議 Friendly Advice", |
|
info="AI 紫微根據你的命盤星象所提供的人生建議", |
|
placeholder="Ouput Text here...", |
|
lines=5,) |
|
|
|
btn = gr.Button( |
|
value="計算農曆生日及八字時辰", |
|
variant="primary", scale=1) |
|
|
|
btn_advice = gr.Button( |
|
value="AI 紫微的人生建議", |
|
variant="primary", scale=2) |
|
|
|
btn_gym = gr.Button( |
|
value="AI 紫微聊天室", |
|
variant="primary", scale=1) |
|
|
|
key_box = gr.Textbox( |
|
label="輸入你的 API 金鑰", |
|
info="You have to provide your own OPENAI_API_KEY for this app to function properly", |
|
placeholder="Type OpenAI API KEY here...", |
|
type="password") |
|
|
|
temperature = gr.Slider( |
|
minimum=0, |
|
maximum=1.0, |
|
value=0.3, |
|
step=0.05, |
|
label="Temperature", |
|
info=( |
|
"Temperature controls the degree of randomness in token selection. Lower " |
|
"temperatures are good for prompts that expect a true or correct response, " |
|
"while higher temperatures can lead to more diverse or unexpected results. " |
|
), |
|
) |
|
|
|
with gr.Blocks() as demo: |
|
gr.Markdown(""" |
|
# AI 紫微 |
|
起手式 - 轉換西元生日到農曆出生時辰 |
|
""") |
|
with gr.Column(): |
|
with gr.Row(): |
|
year.render() |
|
month.render() |
|
day.render() |
|
btime.render() |
|
sex.render() |
|
|
|
with gr.Row(): |
|
output_gwai.render() |
|
output2_gwai.render() |
|
|
|
btn.render() |
|
btn.click(fn=GWAI, |
|
inputs=[year, month, day, btime, sex], |
|
outputs=[output_gwai,output2_gwai]) |
|
|
|
advice.render() |
|
|
|
with gr.Row(): |
|
key_box.render() |
|
btn_advice.render() |
|
btn_advice.click(fn=get_advice, inputs=[output_gwai,temperature,key_box], outputs=advice) |
|
|
|
|
|
|
|
with gr.Accordion("settings", open=True): |
|
temperature.render() |
|
|
|
demo.launch() |
|
|