GWAI / app.py
Bargerya's picture
v0.5 almost done!
f83e3f8
raw
history blame
16.3 kB
## chatGPT with Gradio 起手式
## 在你的資料夾新增 .env 檔案,並在裡面寫入 API_KEY=你的API金鑰
import os
import openai
import gradio as gr
from zhdate import ZhDate
from datetime import datetime
localrun = False # 上傳到 Space 時要設定成 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
# 直接將月份 +3 的原因是: +2 是為了將寅起調整成子起,另外的 +1 是因為計算時間時本格也算一次,所以 +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)
#檢查是否為閏月(先不用管閏十二月,最接近的兩年 1889年,2500年)
if isleap == True:
if Zwsetting.intercalary_month == 2:
month_position += 1
elif Zwsetting.intercalary_month == 3:
if birthdatetime.day > 15:
month_position += 1
# 直接將月份 +1 的原因是: +2 是為了將寅起調整成子起,另外的 -1 是因為計算時間時本格也算一次,所以 -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
#chart_data = solar_year +'/'+ solar_month +'/'+ solar_day +'/'+ str(time_hour)+':'+str(time_min)+'/'+str(gender)
#print(str(chart_data))
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)
# 跳過 農曆轉換
#lunar = Zwbase.get_lunar_datetime(solar_birth_datetime)
#lunar_birth_datetime = LunarDatetime(lunar.lunarYear, lunar.lunarMonth, lunar.lunarDay, solar_birth_datetime.hour, solar_birth_datetime.minute, lunar.isleap)
# 取得生辰年干支位置
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) ## 閏年處理 lunar.isleap
# 取得寅宮天干位置
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] ## lunar.lunarDay - 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()) # read local .env file
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": "夜子"
}
## AI 建議
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, # this is the degree of randomness of the model's output
)
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, # this is the degree of randomness of the model's output
)
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
# 建立 components
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() # 顯示AI建議結果的文字框
with gr.Row():
key_box.render() # 顯示API金鑰輸入框
btn_advice.render() # 顯示AI建議按鈕
btn_advice.click(fn=get_advice, inputs=[output_gwai,temperature,key_box], outputs=advice)
#btn_gym.render() # 顯示AI健身計畫按鈕
#btn_gym.click(fn=get_gym, inputs=[output_gwai,slider,temperature, key_box], outputs=advice)
with gr.Accordion("settings", open=True):
temperature.render()
demo.launch()