## 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()