Update: sync with server data

#1
by sim-so - opened
__pycache__/app.cpython-310.pyc ADDED
Binary file (5.82 kB). View file
 
app.py CHANGED
@@ -1,57 +1,50 @@
1
- import os
2
  import time
3
  import json
4
- import random
 
5
 
6
  import pandas as pd
7
  import gradio as gr
8
  import openai
9
 
10
- from src.semantle import get_puzzle, evaluate_guess
11
  from src.functions import get_functions
 
12
 
13
  GPT_MODEL = "gpt-3.5-turbo"
14
  TITLE = "やりとりSemantle"
15
- puzzle_numbers = [88]
16
- puzzle = get_puzzle(random.choice(puzzle_numbers))
17
- print(puzzle.secret)
18
 
19
- guesses = pd.DataFrame.from_dict({"order":[], "guess":[], "sim":[], "rank":[]})
 
 
20
 
21
- system_content_prefix = """今がら言葉ゲーム始めます。ユーザーが正解を答えるようにチャレンジする間、進行を手伝うのが役割です。
22
 
23
- まず、"""
24
- system_content=f"""ユーザーからの話を聞いて、答えるのか、ヒントを欲しがっているのか、やめようといるのかを判断してください。
25
- ユーザーが答えする場合、答えの点数を評価しておく。その後、{guesses}がら今まで答えた結果の流れを見て、状況を一言で話してください。
26
- ユーザーがヒントを欲しがっている場合、正解の「{puzzle.secret}」に関する間接的な情報を提供してください。
27
  ユーザーが正解を聞いたりやめると言いたりする場合、やめてもいいかをもう一度確認してください。
 
28
 
29
  ゲームのルール:
30
- 正解は一つの言葉で決めている。ユーザーはどんな言葉が正解か推測して、単語を一つずつ答えする。
31
- 正解を出すと成功としてゲームが終わる。推測した言葉がハズレだったら、推測したのが正解とどのぐらい近いかをヒントとしてもらえる。
32
-
33
- ゲームと関係ない話は答えないでください。
34
  """
35
- system_message = [{"role": "system", "content": system_content_prefix+system_content}]
36
- chat_messages = []
 
 
37
 
38
- def add_guess(guess_result):
39
- if guess_result["rank"] == " 正解!":
40
- return "正解です。"
41
- if guess_result["sim"]:
42
- guesses.loc[guesses.shape[0]] = [guesses.shape[0]] + [v for v in guess_result.values()]
43
- print(guesses.head())
44
- return guesses.to_json()
45
- else:
46
- return "1,000以内に入っていないようです。"
47
 
48
  def create_chat(user_input, chat_history, api_key):
49
  openai.api_key = api_key
50
- user_content = [{"role": "user", "content": user_input}]
51
- chat_messages.extend(user_content)
52
  response = openai.ChatCompletion.create(
53
  model=GPT_MODEL,
54
- messages=system_message+chat_messages,
55
  functions=get_functions()
56
  )
57
  response_message = response.choices[0].message
@@ -61,16 +54,17 @@ def create_chat(user_input, chat_history, api_key):
61
  # Step 3: call the function
62
  # Note: the JSON response may not always be valid; be sure to handle errors
63
  available_functions = {
64
- "evaluate_guess": evaluate_guess,
65
  }
66
  function_name = response_message["function_call"]["name"]
67
  function_to_call = available_functions[function_name]
68
  function_args = json.loads(response_message["function_call"]["arguments"])
69
  function_response = function_to_call(
70
  word=function_args.get("word"),
71
- puzzle=puzzle
72
  )
73
- guess_result = add_guess(function_response)
 
74
  # Step 4: send the info on the function call and function response to GPT
75
  chat_messages.append(response_message.to_dict()) # extend conversation with assistant's reply
76
  chat_messages.append(
@@ -80,12 +74,15 @@ def create_chat(user_input, chat_history, api_key):
80
  ) # extend conversation with function response
81
  second_response = openai.ChatCompletion.create(
82
  model=GPT_MODEL,
83
- messages=system_message+chat_messages,
84
  ) # get a new response from GPT where it can se the function response
85
- return second_response["choices"][0]["message"].to_dict()
 
 
86
 
87
  chat_messages.append(response_message.to_dict())
88
- return response_message.to_dict()
 
89
 
90
  with gr.Blocks() as demo:
91
  with gr.Row():
@@ -106,7 +103,7 @@ with gr.Blocks() as demo:
106
  with gr.Column():
107
  api_key = gr.Textbox(placeholder="sk-...", label="OPENAI_API_KEY", value=None, type="password")
108
  guesses_table = gr.DataFrame(
109
- value=guesses,
110
  headers=["#", "答え", "スコア", "ランク"],
111
  datatype=["number", "str", "str", "str"],
112
  elem_id="guesses-table"
@@ -125,21 +122,20 @@ with gr.Blocks() as demo:
125
  def greet():
126
  return "", [("[START]", "ゲームを始まります!好きな言葉をひとつだけいってみてください。")]
127
 
128
- def respond(user_input, chat_history, api_key):
129
  reply = create_chat(user_input, chat_history, api_key)
130
- chat_history.append((user_input, reply["content"]))
131
  time.sleep(2)
132
- return "", chat_history
133
  def update_guesses():
134
- return guesses_table.update(value=guesses)
135
 
136
  api_key.change(unfreeze, [], [msg]).then(greet, [], [msg, chatbot])
137
  msg.submit(respond, [msg, chatbot, api_key], [msg, chatbot]).then(update_guesses, [], [guesses_table])
138
 
139
-
140
  gr.Examples(
141
  [
142
- [puzzle.nearests_words[-1]],
143
  ["どんなヒントが貰える?"],
144
  ["正解と「近い」とはどういう意味?"],
145
  ["何から始めたらいい?"],
 
 
1
  import time
2
  import json
3
+ from datetime import date, datetime
4
+ from pytz import utc, timezone
5
 
6
  import pandas as pd
7
  import gradio as gr
8
  import openai
9
 
10
+ from src.semantle import get_guess, get_secret
11
  from src.functions import get_functions
12
+ from src.utils import add_guess
13
 
14
  GPT_MODEL = "gpt-3.5-turbo"
15
  TITLE = "やりとりSemantle"
16
+ FIRST_DAY = date(2023, 4, 2)
17
+ puzzle_num = (utc.localize(datetime.utcnow()).astimezone(timezone('Asia/Tokyo')).date() - FIRST_DAY).days
18
+ secret = get_secret(puzzle_num)
19
 
20
+ class play:
21
+ guessed = set()
22
+ guesses = pd.DataFrame(columns=["#", "答え", "スコア", "ランク"])
23
 
24
+ task_background = f"""今から言葉をします。ユーザがゲームすることを手伝ってください。
25
 
26
+ """
27
+ task_description=f"""まず、ユーザーからの話を聞いて、答えるのか、ヒントを欲しがっているのか、やめようといるのかを判断してください。
28
+ ユーザーが答えする場合、答えの点数を評価してください。そのあと結果を一言に要約してください。
29
+ ユーザーがヒントを欲しがっている場合、正解に関する間接的な情報を提供してください。
30
  ユーザーが正解を聞いたりやめると言いたりする場合、やめてもいいかをもう一度確認してください。
31
+ そのほか話は答えないでください。
32
 
33
  ゲームのルール:
34
+ 正解は一つの言葉である。ユーザーはどんな言葉が正解か推測して、単語を一つずつ答えする。答えた単語のスコアが100点で、正解と一致すると成功としてゲームが終わる。
 
 
 
35
  """
36
+ system_content = task_background+task_description
37
+ system_message = [{"role": "system", "content": system_content}]
38
+ chat_history = []
39
+ n_history = 8
40
 
 
 
 
 
 
 
 
 
 
41
 
42
  def create_chat(user_input, chat_history, api_key):
43
  openai.api_key = api_key
44
+ chat_messages = [{"role": "user", "content": user_input}]
 
45
  response = openai.ChatCompletion.create(
46
  model=GPT_MODEL,
47
+ messages=system_message+chat_history+chat_messages,
48
  functions=get_functions()
49
  )
50
  response_message = response.choices[0].message
 
54
  # Step 3: call the function
55
  # Note: the JSON response may not always be valid; be sure to handle errors
56
  available_functions = {
57
+ "evaluate_guess": get_guess,
58
  }
59
  function_name = response_message["function_call"]["name"]
60
  function_to_call = available_functions[function_name]
61
  function_args = json.loads(response_message["function_call"]["arguments"])
62
  function_response = function_to_call(
63
  word=function_args.get("word"),
64
+ puzzle_num=puzzle_num
65
  )
66
+ guess_result = add_guess(function_response, play)
67
+ print(guess_result)
68
  # Step 4: send the info on the function call and function response to GPT
69
  chat_messages.append(response_message.to_dict()) # extend conversation with assistant's reply
70
  chat_messages.append(
 
74
  ) # extend conversation with function response
75
  second_response = openai.ChatCompletion.create(
76
  model=GPT_MODEL,
77
+ messages=system_message+chat_history+chat_messages,
78
  ) # get a new response from GPT where it can se the function response
79
+ chat_messages.append(second_response["choices"][0]["message"].to_dict())
80
+ chat_history = chat_history[-8:] + chat_messages
81
+ return chat_messages[-1]
82
 
83
  chat_messages.append(response_message.to_dict())
84
+ chat_history = chat_history[-8:] + chat_messages
85
+ return chat_messages[-1]
86
 
87
  with gr.Blocks() as demo:
88
  with gr.Row():
 
103
  with gr.Column():
104
  api_key = gr.Textbox(placeholder="sk-...", label="OPENAI_API_KEY", value=None, type="password")
105
  guesses_table = gr.DataFrame(
106
+ value=play.guesses,
107
  headers=["#", "答え", "スコア", "ランク"],
108
  datatype=["number", "str", "str", "str"],
109
  elem_id="guesses-table"
 
122
  def greet():
123
  return "", [("[START]", "ゲームを始まります!好きな言葉をひとつだけいってみてください。")]
124
 
125
+ def respond(user_input, chatbot, api_key):
126
  reply = create_chat(user_input, chat_history, api_key)
127
+ chatbot.append((user_input, reply["content"]))
128
  time.sleep(2)
129
+ return "", chatbot
130
  def update_guesses():
131
+ return guesses_table.update(value=play.guesses.sort_values(by="スコア", ascending=False),)
132
 
133
  api_key.change(unfreeze, [], [msg]).then(greet, [], [msg, chatbot])
134
  msg.submit(respond, [msg, chatbot, api_key], [msg, chatbot]).then(update_guesses, [], [guesses_table])
135
 
 
136
  gr.Examples(
137
  [
138
+ ["猫"],
139
  ["どんなヒントが貰える?"],
140
  ["正解と「近い」とはどういう意味?"],
141
  ["何から始めたらいい?"],
example/88.dat DELETED
Binary file (75.2 kB)
 
src/__pycache__/functions.cpython-310.pyc ADDED
Binary file (764 Bytes). View file
 
src/__pycache__/semantle.cpython-310.pyc ADDED
Binary file (801 Bytes). View file
 
src/__pycache__/utils.cpython-310.pyc ADDED
Binary file (998 Bytes). View file
 
src/functions.py CHANGED
@@ -5,11 +5,11 @@ evaluate_guess = {"name": "evaluate_guess",
5
  "properties": {
6
  "word": {
7
  "type": "string",
8
- "description": "A word, noun, verb, adverb or adjective. e.g. 空, 近い, 行く, etc."
9
  },
10
  "puzzle": {
11
  "type": "object",
12
- "description": "A puzzle data containing scores and ranks of words."
13
  }
14
  },
15
  "required": ["word", "puzzle"]
 
5
  "properties": {
6
  "word": {
7
  "type": "string",
8
+ "description": "A single Japanese word, which is can be a noun, verb, adverb or adjective. e.g. 空, 近い, 行く, etc."
9
  },
10
  "puzzle": {
11
  "type": "object",
12
+ "description": "A class containing information about the puzzle; a secret word and scores/ranks for other words."
13
  }
14
  },
15
  "required": ["word", "puzzle"]
src/semantle.py CHANGED
@@ -1,23 +1,19 @@
1
- import pickle
2
- from typing import Tuple, List, Dict
3
 
4
- class Puzzle:
5
- secret: str = ""
6
- nearests: Dict = dict()
7
- nearests_words: List = list()
 
 
 
8
 
9
- def get_puzzle(puzzle_num: int):
10
- puzzle = Puzzle()
11
- with open(f'example/{puzzle_num}.dat', 'rb') as f:
12
- puzzle.nearests, _ = pickle.load(f)
13
- puzzle.nearests_words = [word for word in puzzle.nearests.keys()]
14
- puzzle.secret = puzzle.nearests_words[0]
15
- return puzzle
16
-
17
- def evaluate_guess(word: str, puzzle):
18
- rtn = {"guess": word, "sim": None, "rank": None}
19
- # check most similar
20
- if word in puzzle.nearests:
21
- rtn["sim"] = puzzle.nearests[word][1]
22
- rtn["rank"] = puzzle.nearests[word][0]
23
- return rtn
 
1
+ import requests
 
2
 
3
+ def get_secret(puzzle_num: int):
4
+ request_url = f"https://semantoru.com/yesterday/{puzzle_num+1}"
5
+ response = requests.get(request_url)
6
+ if response.status_code == 200:
7
+ return response.content
8
+ else:
9
+ print("Not found error.")
10
 
11
+ def get_guess(word: str, puzzle_num: int):
12
+ request_url = f"https://semantoru.com/guess/{puzzle_num}/{word}"
13
+ response = requests.get(request_url)
14
+ print(response.status_code)
15
+ if response.status_code == 200:
16
+ output = response.json()
17
+ return output["guess"], output["sim"], output["rank"]
18
+ else:
19
+ return word, None, None
 
 
 
 
 
 
src/utils.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ def add_guess(guess_result, play):
2
+ word, sim, rank = guess_result
3
+ if sim:
4
+ if word not in play.guessed:
5
+ sim = round(sim, 2)
6
+ rank = "情報なし" if rank == 1001 else rank
7
+ play.guesses.loc[len(play.guessed)] = ([len(play.guessed), word, sim, rank])
8
+ play.guessed.add(word)
9
+ cur_result = format_result(word, sim, rank)
10
+ else:
11
+ cur_result = "不正解: 正しくない単語"
12
+ return "\n".join([cur_result, "最高スコア:", format_table(play.guesses)])
13
+
14
+ def format_result(word, sim, rank):
15
+ return f"{word}: スコア {sim}, ランク {rank}"
16
+
17
+ def format_table(table, n_rows=10):
18
+ top_results = table.sort_values(by="スコア", ascending=False).head(n_rows)
19
+ return top_results.to_markdown(index=False)