Spaces:
Runtime error
Runtime error
import re | |
from typing import Optional, Tuple | |
import sympy | |
from .question import register_question | |
CN_TEXT_1 = """ | |
第二章第一题(质数长度),你需要提出一个字数是质数的问题,使回答的长度刚好是它的下一个质数。 | |
""" | |
EN_TEXT_1 = """ | |
For the first question in chapter 2, You need to come up with a question that has a prime number of words, so the answer's length is exactly the next prime number. | |
""" | |
def _is_prime(v): | |
return sympy.isprime(v) | |
def _next_prime(v): | |
while v: | |
v += 1 | |
if _is_prime(v): | |
return v | |
def _cn_checker_1(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]: | |
qs_length = len(user_text.strip()) | |
if not _is_prime(qs_length): | |
return False, f'问题长度为{qs_length},非质数' | |
answer_value = len(answer_text) | |
next_prime = _next_prime(qs_length) | |
if answer_value != next_prime: | |
return False, f'下一个质数为{next_prime},但回答长度为{answer_value}' | |
return True, None | |
def _en_words(text: str): | |
return len(re.findall(r'\w+', text)) | |
def _en_checker_1(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]: | |
qs_length = _en_words(user_text.strip()) | |
if not _is_prime(qs_length): | |
return False, f'The question has a length of {qs_length}, which is not a prime number' | |
answer_value = _en_words(answer_text) | |
next_prime = _next_prime(qs_length) | |
if answer_value != next_prime: | |
return False, f'The next prime number is {next_prime}, but the answer\'s length is {answer_value}' | |
return True, None | |
register_question( | |
{ | |
'cn': CN_TEXT_1, | |
'en': EN_TEXT_1, | |
}, | |
checkers={ | |
'cn': _cn_checker_1, | |
'en': _en_checker_1, | |
}, | |
name={'cn': '2-1 质数长度', 'en': '2-1'}, | |
level=2 | |
) | |
CN_TEXT_2 = """ | |
第二章第二题(越说越大),请输入一个大于一的正整数作为问题,使回答里包含至少比它大一千的数。 | |
""" | |
EN_TEXT_2 = """ | |
For the second question in chapter 2, Please enter a positive integer greater than one as a question, so that the answer contains a number that is at least one thousand more than it. | |
""" | |
def _cn_checker_2(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]: | |
try: | |
value = int(user_text.strip()) | |
if value <= 1: | |
raise ValueError | |
except (TypeError, ValueError): | |
return False, f'输入内容{user_text!r},并非一个大于1的正整数' | |
for value_item in re.findall('[-+]?\d+', answer_text): | |
value_item = int(value_item) | |
if value_item >= value + 1000: | |
return True, f'检测到输出中数字{value_item},满足要求' | |
return False, f'未在输出中检测到不少于{value + 1000}的数字' | |
def _en_checker_2(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]: | |
try: | |
value = int(user_text.strip()) | |
if value <= 1: | |
raise ValueError | |
except (TypeError, ValueError): | |
return False, f'You entered {user_text!r}, which is not a positive integer greater than 1' | |
for value_item in re.findall('[-+]?\d+', answer_text): | |
value_item = int(value_item) | |
if value_item >= value + 1000: | |
return True, f'Detected the number {value_item} in the output, which meets the requirement' | |
return False, f'Did not detect a number of at least {value + 1000} in the output' | |
register_question( | |
{ | |
'cn': CN_TEXT_2, | |
'en': EN_TEXT_2, | |
}, | |
checkers={ | |
'cn': _cn_checker_2, | |
'en': _en_checker_2, | |
}, | |
name={'cn': '2-2 越说越大', 'en': '2-2'}, | |
level=2 | |
) | |
CN_TEXT_3 = """ | |
第二章第三题(越说越小),请输入一个大于一的正整数作为问题,使回答里包含至少10个不同的至少比它小一千的自然数。 | |
""" | |
EN_TEXT_3 = """ | |
For the third question in chapter 2, Please enter a positive integer greater than one as a question, so that the answer contains at least 10 different natural numbers, each of them at least 1000 less than the question. | |
""" | |
def _cn_checker_3(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]: | |
try: | |
value = int(user_text.strip()) | |
if value <= 1: | |
raise ValueError | |
except (TypeError, ValueError): | |
return False, f'输入内容{user_text!r},并非一个大于1的正整数' | |
collected_values = [] | |
for value_item in re.findall('[-+]?\d+', answer_text): | |
value_item = int(value_item) | |
if value_item <= value - 1000: | |
collected_values.append(value_item) | |
collected_values = sorted(set(collected_values)) | |
if len(collected_values) >= 10: | |
return True, f'检测到{len(collected_values)}个不大于{value - 1000}的数字:{collected_values!r}' | |
else: | |
return False, f'检测到{len(collected_values)}个不大于{value - 1000}的数字,未达到10个:{collected_values!r}' | |
def _en_checker_3(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]: | |
try: | |
value = int(user_text.strip()) | |
if value <= 1: | |
raise ValueError | |
except (TypeError, ValueError): | |
return False, f'You entered {user_text!r}, which is not a positive integer greater than 1' | |
collected_values = [] | |
for value_item in re.findall('[-+]?\d+', answer_text): | |
value_item = int(value_item) | |
if value_item <= value - 1000: | |
collected_values.append(value_item) | |
collected_values = sorted(set(collected_values)) | |
if len(collected_values) >= 10: | |
return True, f'Detected {len(collected_values)} numbers not greater than {value - 1000}: {collected_values!r}' | |
else: | |
return False, f'Detected {len(collected_values)} numbers not greater than {value - 1000}, ' \ | |
f'but it doesn\'t reach 10: {collected_values!r}' | |
register_question( | |
{ | |
'cn': CN_TEXT_3, | |
'en': EN_TEXT_3, | |
}, | |
checkers={ | |
'cn': _cn_checker_3, | |
'en': _en_checker_3, | |
}, | |
name={'cn': '2-3 越说越小', 'en': '2-3'}, | |
level=2, | |
) | |
CN_TEXT_4 = """ | |
第二章第四题(警世名言),请在不提及1,4,5这三个字符的情况下让模型回答114514,不要有多余的字符。 | |
""" | |
EN_TEXT_4 = """ | |
For the fourth question in chapter 2, Please make the model answer "114514" without mentioning the characters 1, 4, and 5, and without any extra characters. | |
""" | |
def _cn_checker_4(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]: | |
if "1" in user_text or "4" in user_text or "5" in user_text: | |
return False, '请不要在提问中出现1、4、5三个数字' | |
return answer_text.strip() == '114514', None | |
def _en_checker_4(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]: | |
if "1" in user_text or "4" in user_text or "5" in user_text: | |
return False, 'Please don\'t include the numbers 1, 4, and 5 in the question' | |
return answer_text.strip() == '114514', None | |
register_question( | |
{ | |
'cn': CN_TEXT_4, | |
'en': EN_TEXT_4, | |
}, | |
checkers={ | |
'cn': _cn_checker_4, | |
'en': _en_checker_4, | |
}, | |
name={'cn': '2-4 警世名言', 'en': '2-4'}, | |
level=2, | |
) | |
CN_TEXT_5 = """ | |
第二章第五题(开平方数),请输入一个大于一的平方数作为问题,使回答里包含它的平方根对应的数。 | |
""" | |
EN_TEXT_5 = """ | |
For the fifth question in chapter 2, Please provide a square number greater than one as the question, and the answer should include the number corresponding to its square root. | |
""" | |
def _cn_checker_5(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]: | |
try: | |
value = int(user_text.strip()) | |
if value <= 1: | |
raise ValueError | |
if int(value ** 0.5) ** 2 != value: | |
raise ValueError | |
except (TypeError, ValueError): | |
return False, f'输入内容{user_text!r},并非一个大于1的平方数' | |
sq = int(value ** 0.5) | |
for value_item in re.findall('[-+]?\d+', answer_text): | |
value_item = int(value_item) | |
if value_item == sq: | |
return True, f'检测到平方根数{sq}' | |
else: | |
return False, f'未检测到平方根数{sq}' | |
def _en_checker_5(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]: | |
try: | |
value = int(user_text.strip()) | |
if value <= 1: | |
raise ValueError | |
if int(value ** 0.5) ** 2 != value: | |
raise ValueError | |
except (TypeError, ValueError): | |
return False, f'The input, {user_text!r}, is not a square number greater than 1' | |
sq = int(value ** 0.5) | |
for value_item in re.findall('[-+]?\d+', answer_text): | |
value_item = int(value_item) | |
if value_item == sq: | |
return True, f'Detected square root: {sq}' | |
else: | |
return False, f'Square root {sq} not detected' | |
register_question( | |
{ | |
'cn': CN_TEXT_5, | |
'en': EN_TEXT_5, | |
}, | |
checkers={ | |
'cn': _cn_checker_5, | |
'en': _en_checker_5, | |
}, | |
name={'cn': '2-5 开平方数', 'en': '2-5'}, | |
level=2, | |
) | |
CN_TEXT_6 = """ | |
第二章第六题(得寸进狗),请提一个不包含“狗”这个字的10个字以内的问题,使回答中“狗”这个字出现的次数至少是问题字数的2倍。 | |
""" | |
EN_TEXT_6 = """ | |
For the sixth question in chapter 2, Please ask a question in under 10 words without the word "dog" and ensure that the word "dog" appears at least twice in the answer for each word in the question. | |
""" | |
def _cn_checker_6(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]: | |
if len(user_text) > 10: | |
return False, '问题不得超过10个字' | |
if '狗' in user_text: | |
return False, '问题不得包含“狗”字' | |
dog_count = len(re.findall('狗', answer_text)) | |
if dog_count >= len(user_text) * 2: | |
return True, f'“狗”字的出现次数为{dog_count}次' | |
else: | |
return False, f'“狗”字的出现次数为{dog_count}次,未达到{len(user_text) * 2}次' | |
def _en_checker_6(question_text: str, user_text: str, answer_text: str) -> Tuple[bool, Optional[str]]: | |
q_words = re.findall(r'\w+', user_text.lower()) | |
if len(q_words) > 10: | |
return False, 'The question must not exceed 10 words' | |
if any(word in {'dog', 'dogs'} for word in q_words): | |
return False, 'The question must not contain the word "dog" or "dogs"' | |
a_words = re.findall(r'\w+', answer_text.lower()) | |
a_dog_count = sum(1 if word in {'dog', 'dogs'} else 0 for word in a_words) | |
if a_dog_count >= len(q_words) * 2: | |
return True, f'The word "dog" (or "dogs") appears {a_dog_count} times.' | |
else: | |
return False, f'The word "dog" (or "dogs") appears {a_dog_count} times, ' \ | |
f'which is less than {len(q_words) * 2} times.' | |
register_question( | |
{ | |
'cn': CN_TEXT_6, | |
'en': EN_TEXT_6, | |
}, | |
checkers={ | |
'cn': _cn_checker_6, | |
'en': _en_checker_6, | |
}, | |
name={'cn': '2-6 得寸进狗', 'en': '2-6'}, | |
level=2 | |
) | |