Add files via upload

master
JesterHey 2 years ago committed by GitHub
parent c7e28e2199
commit 4b6518fe03
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,3 +1,3 @@
注意WARNING
答案信息由生成式预训练模型生成并不一定100%准确,甚至可能存在错误,仅作为代码参考!
并且只适用于实训编程作业。matplotlib等绘图相关作业请参见网https://github.com/JesterHey/img_file/blob/main/educoder.md
并且只适用于实训编程作业。matplotlib等绘图相关作业请参见网址[https://github.com/JesterHey/img_file/blob/main/educoder.md]

@ -47,4 +47,6 @@ if __name__ == '__main__':
print('测试用')
# 测试用
# print(is_exist('18503.json'))
#download('18503.json')
#download('18503.json')
#检查云端所有文件
print([i for i in bucket.list_objects()])

@ -0,0 +1,5 @@
import os
def getalljsons() -> list:
return [i for i in os.listdir() if i.endswith('.json')]
for i in getalljsons():
os.remove(i)

@ -11,21 +11,55 @@ import asyncio
from cloud import download,delete
import base64
#读取当前目录下的json文件
#获得指定目录下的所有数字开头的json文件的文件名
def get_json(file:str) -> list:
#获得指定目录下的所有数字开头的json文件
def get_shixunjson(file:str) -> list:
'''
file:指定目录
file:文件夹路径
'''
return [i for i in os.listdir(file) if i.endswith('.json') and i[0].isdigit()]
#获得json文件名因为程序逻辑是每次只有一个json文件所以直接取第一个
files = os.listdir(file)
jsonfiles = []
for i in files:
if i.endswith('.json') and i[0].isdigit():
jsonfiles.append(i)
return jsonfiles
#获得指定目录下的所有pro开头的json文件
def get_programmingjson(file:str) -> list:
'''
file:文件夹路径
'''
files = os.listdir(file)
jsonfiles = []
for i in files:
if i.endswith('.json') and i.startswith('pro'):
jsonfiles.append(i)
return jsonfiles
'''
与云服务器连接先判断当前json是否已在云服务器上如果在则直接调用
节省调用API的时间和资费否则调用API获得答案并将答案存入云服务器
12.4晚更新
阿里云服务器申请成功
'''
# 以下封装成函数
# 重写本地json文件
def rewrite_shixun_json(json_name:str,new_data:dict):
with open(json_name,'w',encoding='utf-8') as f:
json.dump(new_data,f,ensure_ascii=False)
def rewrite_programming_json(json_names:list,new_data:list):
'''
函数用于把new_data中的答案写入对应的json中
json_names:本地所有pro开头的json文件名
new_data:与json_names中每个文件对应的答案所构成的列表
'''
# 检查json_names和new_data元素数量是否一致
if len(json_names) == len(new_data):
i=0
while i< len(json_names):
with open(json_names[i],'w',encoding='utf-8') as f:
json.dump(new_data[i],f,ensure_ascii=False)
i+=1
#读取json文件并转换为字典
def load_json_data(json_name:str) -> dict:
with open(json_name,'r',encoding='utf-8') as f: # json_name为无答案的json文件名
@ -41,7 +75,8 @@ def load_api_key() -> str:
向GPT提问的格式promot + 参数模板化的问题
'''
promot = '现在我想让你扮演一个Python程序员来解一个问题我的问题将由三个部分组成第一部分是问题的描述第二部分是问题的需求第三部分是问题的代码我需要你按照我的模板编写代码。并且你返回的代码应当是带有注释的'
promot1 = '现在我想让你扮演一个Python程序员来解一个问题我的问题将由三个部分组成第一部分是问题的描述第二部分是问题的需求第三部分是问题的代码我需要你按照我的模板编写代码。并且你返回的代码应当是带有注释的。再次注意请返回完整的格式正确的可读的代码'
promot2 = '现在我想让你扮演一个Python程序员来解一个问题我的问题会有两个部分组成第一部分是问题的描述第二部分是你需要补全或者完善的代码。你需要阅读理解我的问题描述然后补全或者完善代码。再次注意请返回完整的格式正确的输入由用户给出的可读的代码'
#构造问题模板
#遍历字典,获得每一关的参数,构造请求,获得答案
#使用异步函数提升效率
@ -55,7 +90,7 @@ client = AsyncOpenAI(
api_key=load_api_key(),
base_url='https://api.op-enai.com/v1'
)
def get_answer_from_api(jsonfile:dict,client:AsyncOpenAI,promot:str) -> dict:
def get_shixunanswer_from_api(jsonfile:dict,client:AsyncOpenAI,promot:str) -> dict:
'''
jsonfile:本地json文件
client:异步客户端
@ -66,15 +101,19 @@ def get_answer_from_api(jsonfile:dict,client:AsyncOpenAI,promot:str) -> dict:
promot = promot
# 异步函数来获取答案
async def get_answer(key,value) -> str:
'''
key:关卡id
value:关卡参数
'''
cid = key
# code 是base64编码的字符串需要解码
des, req, code = value['describe'], value['require'], base64.b64decode(value['code']).decode('utf-8')
question = f'问题描述:{des}\n任务需求:{req}\n根据上面的需求,你需要补充并完善代码:\n{code}'
question = f'问题描述:{des}\n任务需求:{req}\n根据上面的需求,以下是你需要补充并完善代码:\n{code}'
try:
response = await client.chat.completions.create(
model='gpt-3.5-turbo',
model='gpt-4-1106-preview',
messages=[
{'role': 'system', 'content': promot},
{'role': 'system', 'content': promot1},
{'role': 'user', 'content': question}
]
)
@ -98,10 +137,67 @@ def get_answer_from_api(jsonfile:dict,client:AsyncOpenAI,promot:str) -> dict:
# 运行主函数
return asyncio.run(main(data=data))
# 由于编程作业会涉及到多个文件,整合为一个文件池文件池中的每个json就是异步的最小任务单元
# 这样可以多个文件请求并发,异步协程,提升效率
def get_programming_answer_from_api(jsonfile:list,client:AsyncOpenAI,promot:str) -> list:
'''
jsonfile:本地json文件
client:异步客户端
promot:问题模板
'''
data = jsonfile
# 异步函数来获取答案
async def get_answer(value:dict) -> str:
value = value
pro_id = value['id']
# code 是base64编码的字符串需要解码
des,code = value['describe'],base64.b64decode(value['code']).decode('utf-8')
question = f'问题描述:{des}\n根据上面的需求,以下是你需要补充并完善代码:\n{code}'
try:
response = await client.chat.completions.create(
#model='gpt-4-1106-preview',
model = 'gpt-3.5-turbo',
messages=[
{'role': 'system', 'content': promot2},
{'role': 'user', 'content': question}
]
)
return f'{pro_id}/{response.choices[0].message.content}'
except Exception as e:
print(f'错误信息:{e}')
# 主函数
async def main(datalist:list) -> list:
# 由于编程作业会涉及到多个文件,整合为一个文件池
'''
data:本地json文件池
'''
# 把data中的每个json文件读取为字典
datalist = [load_json_data(i) for i in datalist]
# 把每个字典扔给get_answer函数获得答案,异步获取信息
tasks = [get_answer(value) for value in datalist]
answers = await asyncio.gather(*tasks) # answers是一个列表列表中的每个元素为每个异步任务的返回值
# 由于异步获得的答案顺序不确定,需要处理,先把答案按照pro_id排序
answers = sorted(answers,key=lambda x:x.split('/')[0])
# 在datalist中的每个字典中新增一个键值对键为answer值为答案并作为返回值返回
for i in range(len(answers)):
datalist[i]['answer'] = answers[i].split('/')[-1]
# 返回datalist
return datalist
# 运行主函数,返回一个列表,列表中的每个元素为每个异步任务的返回值,即重写的字典
return asyncio.run(main(datalist=data))
if __name__ == '__main__':
new_data = get_answer_from_api(jsonfile=load_json_data(get_json(os.getcwd())[0]),client=client,promot=promot)
print(new_data)
#重写本地json文件
with open(get_json(os.getcwd())[0],'w',encoding='utf-8') as f:
json.dump(new_data,f,ensure_ascii=False,indent=4)
ans=get_programming_answer_from_api(jsonfile=get_programmingjson(os.getcwd()),client=client,promot=promot2)
print(ans)
rewrite_programming_json(json_names=get_programmingjson(os.getcwd()),new_data=ans)
#new_data = get_programming_answer_from_api(get_programmingjson(os.getcwd()),client=client,promot=promot2)

@ -28,12 +28,7 @@ retry = 0
#配置参数
opt = Options()
opt.add_experimental_option('detach', True)
#opt.add_argument('--headless')
chrome_driver = 'D:\ChromeDownload\chromedriver-win64\chromedriver-win64'
# 发行版时改为调用userinfo.json文件中的用户名和密码
# url = 'https://www.educoder.net/tasks/27V4D95N/1191515/vmxpzae734bj?coursesId=27V4D95N'
# user_name = 'hnu202311020126'
# password = 'hzy123456'
opt.add_argument('--headless')
platf = platform.platform()
def is_practice(url:str) -> bool:
obj=re.compile(r'www.educoder.net/tasks')
@ -41,10 +36,22 @@ def is_practice(url:str) -> bool:
return True
else:
return False
def is_programming(url:str) -> bool:
obj=re.compile(r'www.educoder.net/myproblems')
if obj.search(url):
return True
else:
return False
# 另外目前好像只有实训作业有这些参数其他的作业例如编程作业就没有所以先判断一下是否为实训作业可以通过用户输入的url判断
# 主要是看educoder.net/后面是否有tasks如果有则是实训作业否则不是实训作业
#为方便main.py调用将判断函数写入函数中以下部分封装为函数
def get_parameters(url:str,user_name:str,password:str):
'''
用于获得实训作业的参数
url:实训网址
user_name:用户名
password:密码
'''
url = url
user_name = user_name
password = password
@ -65,11 +72,11 @@ def get_parameters(url:str,user_name:str,password:str):
print('登录失败 请检查输入信息是否正确')
# 关闭浏览器
safari.quit()
#重新调用login_ui.py
if 'Windows' in platf:
os.system('python login_ui.py')
else:
os.system('python3 login_ui.py')
# #重新调用login_ui.py
# if 'Windows' in platf:
# os.system('python login_ui.py')
# else:
# os.system('python3 login_ui.py')
#获取cookieUser-Agent
Cookie = safari.get_cookies()
User_Agent = safari.execute_script('return navigator.userAgent')
@ -201,8 +208,124 @@ def get_parameters(url:str,user_name:str,password:str):
else:
print('这不是一个实训作业')
return
def get_parameters_of_programming(url:str,user_name:str,password:str):
'''
用于获得编程作业的参数
url:实训网址
user_name:用户名
password:密码
'''
url = url
user_name = user_name
password = password
# 检查是否为编程作业
if is_programming(url):
# 构造selenium对象
#构造selenium对象
safari = Chrome(options=opt)
safari.get(url)
#模拟登录
safari.implicitly_wait(10)
safari.find_element(By.ID, 'login').send_keys(user_name)
safari.find_element(By.ID, 'password').send_keys(password)
safari.find_element(By.ID, 'password').send_keys(Keys.ENTER)
time.sleep(2)
#判断是否登录成功
try:
safari.find_element(By.XPATH,'//*[@id="root"]/div/div/div/div/div/div/div/section[1]/div/div[4]')
except BaseException:
print('登录失败 请检查输入信息是否正确')
# 关闭浏览器
safari.quit()
# #重新调用login_ui.py
# if 'Windows' in platf:
# os.system('python login_ui.py')
# else:
# os.system('python3 login_ui.py')
#获取cookieUser-Agent
Cookie = safari.get_cookies()
User_Agent = safari.execute_script('return navigator.userAgent')
cookie = f'autologin_trustie={Cookie[1]["value"]}; _educoder_session={Cookie[0]["value"]}'
heders = {
'Cookie':cookie,
'User-Agent':User_Agent,
'Referer':url
}
# 由于编程作业往往是题库的题目组合的没有直接编程作业的总ID所以要先访问每个题目界面获得相应的ID题干代码等参数
# 最终上传时,记得在要区别于已经上传的实训作业,可以在文件名前加上'pro'前缀
# 获得题目数量
# 展开关卡页面
safari.find_element(By.XPATH,'//*[@id="root"]/div/div/div/div/div/div/div/section[1]/div/div[4]').click()
# <div class="list___PXTsq ">
# 可见关卡数量是根据class="list___PXTsq "的元素数量决定的直接用xpath获取即可
time.sleep(1)
htmltxt = safari.page_source
html = etree.HTML(htmltxt)
task_num = html.xpath('count(//*[@class="list___PXTsq "])')
task_num = int(task_num) + 1
# 回到第一关
# //*[@id="educoder"]/body/div[6]/div/div[3]/div/div/div[2]/div[1]
# //*[@id="educoder"]/body/div[7]/div/div[3]/div/div/div[2]/div[2]
for i in range(1,10):
try:
if safari.find_element(By.XPATH,f'//*[@id="educoder"]/body/div[{i}]/div/div[3]/div/div/div[2]/div[1]'):
safari.find_element(By.XPATH,f'//*[@id="educoder"]/body/div[{i}]/div/div[3]/div/div/div[2]/div[1]').click()
break
except:
continue
i = 1
while i<=task_num:
# 对于每一关,获取参数
cur_url = safari.current_url
identity = cur_url.split('/')[-1].split('?')[0]
resp = requests.get(f'https://data.educoder.net/api/myproblems/{identity}.json',headers=heders)
# 提取resp中的题目id题干代码等参数
problem_data = resp.json()
# 初始化一个字典,用于存放所有关卡的参数
total = {}
# 题目id
pro_id = problem_data['hack']['id']
# 获取id后判断云端是否存在该文件如果存在则跳过如果不存在则继续执行本程序
exist = is_exist(f'pro_{pro_id}.json')
if exist:
print('云端文件已存在,正在下载')
download(f'pro_{pro_id}.json')
print(f'pro_{pro_id}.json下载完成')
continue
else:
print('云端文件不存在,正在爬取')
# 题干
describe = problem_data['hack']['description']
# 代码(base64编码)
code = problem_data['hack']['code']
total = {
'id':pro_id,
'describe':describe,
'code':code,
'verified': False, #这个参数是用来标记答案是否被用户认证为正确答案的初始值为False(暂时没啥用)
'last_modified': time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())) #这个参数是用来标记答案最后一次被修改的时间,初始值为当前时间
}
# 写入本地json命名为pro_pro_id.json
with open(f'pro_{pro_id}.json','w',encoding='utf-8') as f:
json.dump(total,f,ensure_ascii=False)
print(f'{pro_id}完成')
# 去往下一关
try:
i+=1
safari.implicitly_wait(10)
safari.find_element(By.ID,'oj-next').click()
time.sleep(2)
except BaseException:
print('参数爬取完成') # 完成后本地会有若干个pro_pro_id.json文件
safari.quit()
else:
print('不是编程作业')
if __name__ == '__main__':
url = 'https://www.educoder.net/tasks/27V4D95N/1191512/lfi2gqtnueb8?coursesId=27V4D95N'
url = 'https://www.educoder.net/myproblems/9kwnlzvcegsa?type=1'
user_name = 'hnu202311020126'
password = 'hzy123456'
get_parameters(url,user_name,password)
get_parameters_of_programming(url,user_name,password)
print('结束测试')

@ -14,10 +14,10 @@ from cloud import upload,download,is_exist
print('处理api相关中...')
download('apis.json')
print('处理完成!')
from get_params import get_parameters
from get_answer import get_answer_from_api,promot,client,get_json,load_api_key,load_json_data
from get_params import get_parameters,get_parameters_of_programming,is_practice
from get_answer import get_shixunanswer_from_api,get_programming_answer_from_api,promot1,promot2,client,rewrite_programming_json,rewrite_shixun_json
from login_ui import show_login,show_image,MyApp
from trans_to_txt import transToTxt,readJson
from trans_to_txt import transToTxt,transToTxt_programming,get_programmingjson,get_shixunjson
import json
import os
from printtxt import print_txt,get_all_txt_file
@ -36,49 +36,78 @@ with open('userinfo.json', 'r') as f:
user_name = userinfo['name']
password = userinfo['pwd']
url = userinfo['url']
# 调用get_params.py获得参数完成后本地应该有一个json文件里面有参数
get_parameters(url,user_name,password)
print('到这一步,参数获取完成!')
ispractice = is_practice(url=url)
if ispractice:
# 调用get_params.py获得参数完成后本地应该有一个json文件里面有参数
get_parameters(url,user_name,password)
else:
get_parameters_of_programming(url=url,user_name=user_name,password=password)
print('参数获取完成!')
# 获得刚才get_params.py生成的json文件名
j_name = readJson()[0]
# 判断j_name文件中是否有answer
with open(j_name,'r',encoding='utf-8') as f:
json_data = json.load(f)
def is_exist_answer(data:dict) -> bool:
for i,j in data.items():
if 'answer' in j.keys():
return True
return False
print('到这一步,判断是否存在答案')
if is_exist_answer(json_data):
pass
def is_exist_answer_programming(data:dict) -> bool:
for i in data.keys():
if i == 'answer':
continue
else:
return False
return True
if ispractice:
j_name = get_shixunjson(os.getcwd())[0]
# 判断j_name文件中是否有answer
with open(j_name,'r',encoding='utf-8') as f:
json_data = json.load(f)
if is_exist_answer(json_data):
pass
else:
print('调用api获取答案中请耐心等待...')
new_data = get_shixunanswer_from_api(jsonfile=json_data,client=client,promot=promot1)
# 重写本地json文件
rewrite_shixun_json(json_name=j_name,new_data=new_data)
else:
print('到这一步,调用api获取答案')
new_data = get_answer_from_api(jsonfile=json_data,client=client,promot=promot)
# 重写本地json文件
with open(j_name,'w',encoding='utf-8') as f:
json.dump(new_data,f,ensure_ascii=False,indent=4)
j_names = get_programmingjson(os.getcwd())
# 判断是否有answer
for j in j_names:
with open(j,'r',encoding='utf-8') as f1:
j_data = json.load(f1)
if not is_exist_answer_programming(j_data):
break
print('调用api获取答案中请耐心等待...')
new_data = get_programming_answer_from_api(jsonfile=j_names,client=client,promot=promot2)
# 重写本地接送文件
rewrite_programming_json(json_names=j_names,new_data=new_data)
# 上面的判断执行完后本地的json文件中已经有answer了下面实现信息展示
# 先删除本地api.json文件
os.remove('apis.json')
# 使用readJson函数读取当前目录下的所有json文件
JSS = readJson()
# 构建txt文件
transToTxt(JSS)
# 展示txt文件
# print('哈哈终于要写完了')
print('答案获取完毕,开始展示')
print_txt(get_all_txt_file(os.getcwd()))
# 函数读取当前目录下的所有json文件
if ispractice:
JSS = get_shixunjson(os.getcwd())[0]
# 构建txt文件
transToTxt(JSS)
# 展示txt文件
# 判断云端是否存在答案json如果不存在则上传
print('答案获取完毕,开始展示')
print_txt(get_all_txt_file(os.getcwd()))
if not is_exist(JSS):
upload(JSS)
else:
JSS = get_programmingjson(os.getcwd())
transToTxt_programming(JSS)
print('答案获取完毕,开始展示')
print_txt(get_all_txt_file(os.getcwd()))
if not is_exist(JSS):
upload(JSS)
# #打印完删除本地txt和json文件
for i in JSS:
def getalljsons() -> list:
return [i for i in os.listdir() if i.endswith('.json')]
for i in getalljsons():
os.remove(i)
# 删除本地所有数字开头的txt文件
# 删除本地所有数字命名的txt文件
for i in os.listdir():
if i.split('.')[0].isdigit() and i.endswith('.txt'):
if i.split('.')[0].isdigit() or i.startswith('pro') and i.endswith('.txt'):
os.remove(i)
# 判断云端是否存在答案json如果不存在则上传
if not is_exist(j_name):
upload(j_name)

@ -89,7 +89,7 @@ def print_txt(json_path: list): # 传入json文件路径
def get_all_txt_file(path):
file_list = ['0Atip.txt']
file_list = []
for root, dirs, files in os.walk(path):
for file in files:
if file.endswith('.txt') and file[0].isdigit():

@ -1,5 +1,5 @@
lxml==4.9.3
openai==1.3.7
openai==1.3.8
oss2==2.18.3
pycryptodome==3.19.0
PyQt5==5.15.10

@ -1,25 +1,49 @@
import os
import json
#读取当前下的所有以数字命名的json文件
def readJson():
files = os.listdir()
jsons = []
for file in files:
if file.endswith('.json') and file[0].isdigit():
jsons.append(file)
return jsons
#这就是我们的答案json文件提取每个键盘对应的值的answer键对应的值写入不同的txt文件
def get_shixunjson(file:str) -> list:
'''
file:文件夹路径
'''
files = os.listdir(file)
jsonfiles = []
for i in files:
if i.endswith('.json') and i[0].isdigit():
jsonfiles.append(i)
return jsonfiles
#获得指定目录下的所有pro开头的json文件
def get_programmingjson(file:str) -> list:
'''
file:文件夹路径
'''
files = os.listdir(file)
jsonfiles = []
for i in files:
if i.endswith('.json') and i.startswith('pro'):
jsonfiles.append(i)
return jsonfiles
def transToTxt(jsons:list):
'''
用于将jsons中的所有json中的answer信息写入txt
'''
for j in jsons:
with open(j,'r',encoding='utf-8') as f:
data = json.load(f)
with open(j,'r',encoding='utf-8') as f1:
data = json.load(f1)
i=1
for key in data.keys():
if key != 'answer':
with open(f'{i}.txt','w',encoding='utf-8') as f:
f.write(data[key]['answer'])
with open(f'{i}.txt','w',encoding='utf-8') as f2:
f2.write(data[key]['answer'])
i+=1
f.close()
def transToTxt_programming(jsons:list):
for j in range(len(jsons)):
with open(jsons[j],'r',encoding='utf-8') as f1:
data = json.load(f1)
with open(f'{j+1}.txt','w',encoding='utf-8') as f2 :
f2.write(data['answer'])
if __name__ == '__main__':
jsons = readJson()
transToTxt(jsons)
print('测试部分')
# jsons = get_shixunjson(os.getcwd())
# transToTxt(jsons)
# transToTxt_programming(jsons=jsons)
Loading…
Cancel
Save