Add files via upload

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

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

@ -23,12 +23,8 @@ def is_exist(name:str) -> bool:
# 如果文件存在则下载到本地并命名为shixun_id_answer
def download(name):
# 先检查本地文件是否存在,如果存在,则不下载
if os.path.exists(name):
return
else:
# 将云端文件下载到本地并命名为shixun_id_answer.json
bucket.get_object_to_file(name, name)
# 将云端文件下载到本地并命名为shixun_id.json
bucket.get_object_to_file(name, name)
# 上传函数,用于获得答案后上传到云端,此步骤在获得答案后调用
# (to do)如果用户将答案认证为正确则将本地json中的verified参数改为True后再上传并覆盖云端文件
def upload(name):
@ -48,9 +44,7 @@ def delete(name):
if is_exist(name):
bucket.delete_object(name)
if __name__ == '__main__':
print('测试用')
# 测试用
# print(is_exist('18503.json'))
#download('18503.json')
# delete('18503.json')
#download('18503.json')

@ -9,32 +9,32 @@ import os
import json
import asyncio
from cloud import download,delete
download('apis.json')
import base64
#读取当前目录下的json文件
#获得指定目录下的所有json文件的文件名
def get_json(file):
return [i for i in os.listdir(file) if i.endswith('.json')]
#将file指定为当前目录
file = os.getcwd()
#获得指定目录下的所有数字开头的json文件的文件名
def get_json(file:str) -> list:
'''
file:指定目录
'''
return [i for i in os.listdir(file) if i.endswith('.json') and i[0].isdigit()]
#获得json文件名因为程序逻辑是每次只有一个json文件所以直接取第一个
'''
后续准备与云服务器连接先判断当前json是否已在云服务器上如果在则直接调用
与云服务器连接先判断当前json是否已在云服务器上如果在则直接调用
节省调用API的时间和资费否则调用API获得答案并将答案存入云服务器
12.4晚更新
阿里云服务器申请成功
'''
json_name = get_json(file)[0]
# 以下封装成函数
#读取json文件并转换为字典
with open(json_name,'r',encoding='utf-8') as f:
data = json.load(f)
with open('apis.json','r',encoding='utf-8') as f:
apis = json.load(f)
#获得api_key
api_key = apis['openaiapi']
#删除本地的apis.json文件
os.remove('apis.json')
def load_json_data(json_name:str) -> dict:
with open(json_name,'r',encoding='utf-8') as f: # json_name为无答案的json文件名
data = json.load(f)
return data
def load_api_key() -> str:
with open('apis.json','r',encoding='utf-8') as f: # apis.json为存储api_key的json文件名
return json.load(f)['openaiapi']
#遍历字典,获得每一关的参数,构造请求,获得答案
'''
用于构造请求的参数describe,require,code
@ -52,17 +52,23 @@ promot = '现在我想让你扮演一个Python程序员来解一个问题
# 初始化异步客户端
client = AsyncOpenAI(
api_key=api_key,
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:
'''
jsonfile:本地json文件
client:异步客户端
promot:问题模板
'''
data = jsonfile
client = client
promot = promot
# 异步函数来获取答案
async def get_answer(key,value):
async def get_answer(key,value) -> str:
cid = key
des, req, code = value['describe'], value['require'], value['code']
# code 是base64编码的字符串需要解码
des, req, code = value['describe'], value['require'], base64.b64decode(value['code']).decode('utf-8')
question = f'问题描述:{des}\n任务需求:{req}\n根据上面的需求,你需要补充并完善代码:\n{code}'
try:
response = await client.chat.completions.create(
@ -85,7 +91,7 @@ def get_answer_from_api(jsonfile:dict,client:AsyncOpenAI,promot:str) -> dict:
answers = sorted(answers,key=lambda x:int(x.split('/')[0]))
# 在data的每个value中新增一个键值对键为answer值为答案并作为返回值返回
for i in range(len(answers)):
ansewer_data[list(ansewer_data.keys())[i]]['answer'].split('/')[-1] = answers[i]
ansewer_data[list(ansewer_data.keys())[i]]['answer'] = answers[i].split('/')[-1]
return ansewer_data
@ -93,9 +99,9 @@ def get_answer_from_api(jsonfile:dict,client:AsyncOpenAI,promot:str) -> dict:
# 运行主函数
return asyncio.run(main(data=data))
if __name__ == '__main__':
new_data = get_answer_from_api(jsonfile=data,client=client,promot=promot)
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(json_name,'w',encoding='utf-8') as f:
with open(get_json(os.getcwd())[0],'w',encoding='utf-8') as f:
json.dump(new_data,f,ensure_ascii=False,indent=4)

@ -23,6 +23,8 @@ from lxml import etree
import time
import requests
from cloud import is_exist,download
global retry
retry = 0
#配置参数
opt = Options()
opt.add_experimental_option('detach', True)
@ -95,7 +97,7 @@ def get_parameters(url:str,user_name:str,password:str):
if os.path.exists(f'{shixun_id}.json'):
print('下载完成')
safari.quit()
exit()
return
break
except Exception as e:
print(e)
@ -105,15 +107,18 @@ def get_parameters(url:str,user_name:str,password:str):
print('云端文件不存在,正在爬取')
#获取关卡数
#点击展开关卡页面
time.sleep(3)
safari.find_element(By.XPATH,'//*[@id="task-left-panel"]/div[1]/a[1]').click()
time.sleep(2)
#关卡数量由 class = "flex-container challenge-title space-between" 的元素数量决定
time.sleep(3)
htmltxt = safari.page_source
html = etree.HTML(htmltxt)
task_num = html.xpath('count(//*[@class="flex-container challenge-title space-between"])')
task_num = int(task_num)
#关闭关卡页面
safari.find_element(By.XPATH,'//*[@id="task-left-panel"]/div[3]/div[1]').click()
print(f'关卡数量为{task_num}')
#回到第一关
time.sleep(3)
safari.find_element(By.XPATH,'//*[@id="task-left-panel"]/div[3]/div[3]/div/div/div/div/div[1]/div[1]/a').click()
#对于每一关,获取参数
#每一关的参数由以下元素组成:
'''
@ -127,13 +132,6 @@ def get_parameters(url:str,user_name:str,password:str):
i=1
try:
while i <= task_num:
safari.implicitly_wait(10)
safari.find_element(By.XPATH, '//*[@id="task-left-panel"]/div[1]/a[1]').click()
safari.implicitly_wait(10)
safari.find_element(By.XPATH,f'/html/body/div[1]/div/div/div/div[2]/section[1]/div[3]/div[3]/div/div/div/div/div[{i}]/div[1]/a').click()
time.sleep(3)
#获取课程id -> 根据url中?前面的,最后一个/后面的那部分参数构造请求同时似乎还需要用到cookieUser-Agent和Referer参数这些统一用selenium在登陆后获取并组装成headers
#获取cookieUser-Agent和Referer
cur_url=Referer = safari.current_url
identity = cur_url.split('/')[-1].split('?')[0]
id_url = f'https://data.educoder.net/api/tasks/{identity}.json?'
@ -150,13 +148,14 @@ def get_parameters(url:str,user_name:str,password:str):
except BaseException:
print('获取课程id失败')
#获取任务描述(如果存在的话)
time.sleep(3)
page_source = safari.page_source
describe = obj1.findall(page_source)
#获取编程要求(如果存在的话)
require = obj2.findall(page_source)
#获取编辑器中的代码,由于代码都是class = "view-line"的div,先找到所有class = "view-line"的div获取其中的所有文本再把不同行的代码用\n连接起来
code = safari.find_elements(By.CLASS_NAME,'view-line')
code = '\n'.join([i.text for i in code]).lstrip('\n')
#获取编辑器中的代码,采用requests抓取https://data.educoder.net/api/tasks/{identity}/rep_content.json中的content中的content
# 然后然后这个content是一个base64编码的字符串需要解码
code = requests.get(f'https://data.educoder.net/api/tasks/{identity}/rep_content.json',headers=headers).json()['content']['content']
#把参数存入字典再转换为json格式
task = {
'describe':describe[0] if len(describe) != 0 else '',
@ -168,19 +167,31 @@ def get_parameters(url:str,user_name:str,password:str):
#把每一关的参数存入总的字典中
total[challenge_id] = task
#去往下一关
i += 1
except BaseException:
print(f'{challenge_id}参数获取参数失败')
#判断爬取到的代码是否存在空值,如果存在空值,则重新爬取
for value in total.values():
if value['code'] == '':
print('检测到代码参数为空值,重新爬取')
safari.close()
# 再次执行本程序
if 'Windows' in platf:
os.system('python get_params.py')
safari.implicitly_wait(10)
if i == 1:
i += 1
safari.find_element(By.XPATH,f'//*[@id="task-right-panel"]/div[4]/div/div[2]/a').click()
elif i<task_num:
i += 1
safari.find_element(By.XPATH,f'//*[@id="task-right-panel"]/div[4]/div/div[2]/a[2]').click()
else:
os.system('python3 get_params.py')
i += 1
except Exception as e:
print(e)
print(f'{i}关参数获取参数失败')
#判断爬取到的代码是否存在空值或者键的数量是否与关卡数量相等,如果不相等,则说明爬取失败,需要重新爬取
# if len(total) != task_num:
# print('参数爬取失败,正在重新爬取')
# get_parameters(url,user_name,password)
# else:
# for i,j in total.items():
# if j['code'] == '':
# print('参数爬取失败,正在重新爬取')
# get_parameters(url,user_name,password)
#把参数写入本地json文件中文件名字与shixun_name相同键为course_id值为一个列表列表中每个元素为一个字典字典中包含每一关的参数
with open(f'{shixun_id}.json','w',encoding='utf-8') as f:
json.dump(total,f,ensure_ascii=False,indent=4)
@ -189,9 +200,9 @@ def get_parameters(url:str,user_name:str,password:str):
safari.quit()
else:
print('这不是一个实训作业')
exit()
return
if __name__ == '__main__':
url = 'https://www.educoder.net/tasks/27V4D95N/1191515/vmxpzae734bj?coursesId=27V4D95N'
url = 'https://www.educoder.net/tasks/27V4D95N/1191512/lfi2gqtnueb8?coursesId=27V4D95N'
user_name = 'hnu202311020126'
password = 'hzy123456'
get_parameters(url,user_name,password)

@ -5,6 +5,7 @@ import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QPushButton, QVBoxLayout, QHBoxLayout, QLabel
from PyQt5.QtCore import Qt,QTimer
from PyQt5.QtGui import QPixmap, QPainter
from PyQt5.QtWidgets import QCheckBox
import platform
from solve_path import b2_path, b2txt_path
import json
@ -23,15 +24,20 @@ class MyApp(QWidget):
# 创建一个垂直布局
mainLayout = QVBoxLayout()
self.showPasswordCheckbox = QCheckBox("显示密码", self)
self.showPasswordCheckbox.stateChanged.connect(self.togglePasswordVisibility)
# 创建三个文本框并设置占位符
self.nameEdit = QLineEdit()
self.pwdEdit = QLineEdit()
self.urlEdit = QLineEdit()
self.pwdEdit.setEchoMode(QLineEdit.Password)
# 创建一个按钮并连接信号
btn = QPushButton('提交')
btn.clicked.connect(self.onSubmit)
mainLayout.addWidget(self.showPasswordCheckbox, 0, Qt.AlignCenter)
# 创建一个用于显示错误信息的标签
self.errorLabel = QLabel('', self)
self.errorLabel.hide() # 初始时隐藏该标签
@ -63,6 +69,12 @@ class MyApp(QWidget):
# 应用样式
self.applyStyles()
def togglePasswordVisibility(self):
if self.showPasswordCheckbox.isChecked():
self.pwdEdit.setEchoMode(QLineEdit.Normal)
else:
self.pwdEdit.setEchoMode(QLineEdit.Password)
def paintEvent(self, event):
painter = QPainter(self)
painter.drawPixmap(self.rect(), self.background)

@ -1,69 +1,83 @@
# '''
# 主程序:整合各个模块
# 1、ui文件调用相应ui模块
# 2、get_params.py获取参数
# 3、get_answer.py获取答案
# 4、cloud.py将json文件存入云端
# '''
# # 生成图形化界面,引导用户登陆并输入实训网址
# # 调用get_params.py获取参数这一步同时隐含了云端获取答案的过程
# # 如果云端答案不存在则调用get_answer.py获取答案并展示给用户
# # 用户verif选项确认后调用cloud.py将json文件存入云端
'''
主程序整合各个模块
1ui文件调用相应ui模块
2get_params.py获取参数
3get_answer.py获取答案
4cloud.py将json文件存入云端
'''
# 生成图形化界面,引导用户登陆并输入实训网址
# 调用get_params.py获取参数这一步同时隐含了云端获取答案的过程
# 如果云端答案不存在则调用get_answer.py获取答案并展示给用户
# 用户verif选项确认后调用cloud.py将json文件存入云端
# 导入所需模块
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 login_ui import show_login,show_image,MyApp
from trans_to_txt import transToTxt,readJson
import json
import os
from printtxt import print_txt,get_all_txt_file
global finished
finished = False
# 调用login_ui获得用户输入的用户名、密码和实训网址
show_image()
show_login()
# # 导入所需模块
# 检查userinfo.json文件是否存在存在则程序继续
assert os.path.exists('userinfo.json'), 'userinfo.json文件不存在,请检查'
# from get_params import get_parameters
# from get_answer import get_answer_from_api,promot,client
# from login_ui import show_login,show_image,MyApp
# from trans_to_txt import transToTxt,readJson
# 先读取userinfo.json文件获得用户名、密码和实训网址
with open('userinfo.json', 'r') as f:
userinfo = json.load(f)
user_name = userinfo['name']
password = userinfo['pwd']
url = userinfo['url']
# import json
# import os
# 调用get_params.py获得参数完成后本地应该有一个json文件里面有参数
get_parameters(url,user_name,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)
# # 调用login_ui获得用户输入的用户名、密码和实训网址
# show_image()
# show_login()
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
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)
# # 检查userinfo.json文件是否存在存在则程序继续
# assert os.path.exists('userinfo.json'), 'userinfo.json文件不存在,请检查'
# # 先读取userinfo.json文件获得用户名、密码和实训网址
# with open('userinfo.json', 'r') as f:
# userinfo = json.load(f)
# user_name = userinfo['name']
# password = userinfo['pwd']
# url = userinfo['url']
# # 调用get_params.py获得参数完成后本地应该有一个json文件里面有参数
# get_parameters(url,user_name,password)
# # 获得本地所有数字开头的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
# if is_exist_answer(json_data):
# pass
# else:
# # 调用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)
# # 上面的判断执行完后本地的json文件中已经有answer了下面实现信息展示
# # 使用readJson函数读取当前目录下的所有json文件
# JSONS = readJson()
# # 构建txt文件
# # transToTxt(JSONS)
# # 展示txt文件
print('哈哈终于要写完了')
import haha
#询问用户是否认证答案正确(下午新开一个模块实现)
# 上面的判断执行完后本地的json文件中已经有answer了下面实现信息展示
# 先删除本地api.json文件
os.remove('apis.json')
# 使用readJson函数读取当前目录下的所有json文件
JSS = readJson()
# 构建txt文件
transToTxt(JSS)
# 展示txt文件
# print('哈哈终于要写完了')
print_txt(get_all_txt_file(os.getcwd()))
# #打印完删除本地txt和json文件
for i in JSS:
os.remove(i)
# 删除本地所有数字开头的txt文件
for i in os.listdir():
if i.split('.')[0].isdigit() and i.endswith('.txt'):
os.remove(i)
# 判断云端是否存在答案json如果不存在则上传
if not is_exist(j_name):
upload(j_name)

@ -89,12 +89,13 @@ def print_txt(json_path: list): # 传入json文件路径
def get_all_txt_file(path):
file_list = []
file_list = ['0Atip.txt']
for root, dirs, files in os.walk(path):
for file in files:
if file.endswith('.txt') and file[0].isdigit():
file_list.append(os.path.join(root, file))
file_list.sort(key=lambda x:x.split('.')[0])
return file_list
print_txt(get_all_txt_file(os.getcwd()))
if __name__ == '__main__':
print_txt(get_all_txt_file(os.getcwd()))

@ -0,0 +1 @@
WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.ID, "someElementID")))

@ -0,0 +1 @@
# 我真甜蜜地服了互联网上一群傻逼到处TMD跟喷史一样到处拉史一样的垃圾信息就TM配置个代理一帮牛马讲得TMD的天花乱坠什么TM云函数Cloudfare代理Njanx反向代理真NMSL的一群人。好不容易TND有几个人直接给TM代理地址又不说明要加/v1官方文档也TM是一堆SB写的吗API用法更新了就TM给几个示例代码是怕GitHub存储费用太高吗社区和和论坛也是一帮勾石东西TM跟东晋士大夫一样搁哪清谈半天NM一个给代码示例的人都没有屈指可数的几个代码又是API1.2版本之前的用不了一点捏。我TM找整整2天就差冲OpenAI官网的时候无意间看到CSDN上的[这篇帖子](https://blog.csdn.net/qq_36265860/article/details/130111351)。WC什么叫清晰什么叫对比什么叫做程序员的自我修养TM我那么简单的一个问题就只有这个老哥给出解答。我NM真的当时真的想嫁给这个哥了。我宣布CSDN就是世界第一技术论坛那些说看CSDN是屎里淘食的人下赛季池史。以后多看书再上网查这种技术问题我也是SB。暂时就想到那么多哈哈。
Loading…
Cancel
Save