web端实战案例分享(57个挑战之57part5)
web端实战案例分享(57个挑战之57part5)一次性把所有题目 答案都发给客户端,让客户端JS 做判断,如果正确,则取下一个数,如果答题错误则统计并终止循环。1.实现方法1:(所有问题 答案一次发送到web端,js逻辑判断)https://www.toutiao.com/article/7128604966595920414/https://www.toutiao.com/article/7128196832081183236/这两天先写了下前后端的逻辑 相关的实现函数,在缓存题库这个事情上产生了疑问。
上题目
接前面:
https://www.toutiao.com/article/7131944951776150056/
https://www.toutiao.com/article/7129048315920335399/
https://www.toutiao.com/article/7128604966595920414/
https://www.toutiao.com/article/7128196832081183236/
这两天先写了下前后端的逻辑 相关的实现函数,在缓存题库这个事情上产生了疑问。
1.实现方法1:(所有问题 答案一次发送到web端,js逻辑判断)
一次性把所有题目 答案都发给客户端,让客户端JS 做判断,如果正确,则取下一个数,如果答题错误则统计并终止循环。
(这个方法有个漏洞,操作的时候,所有题库的信息都发给客户端了,容易作弊)
2.实现方法2:(一次性发一个题目及答案到web端,js逻辑判断这个题目答案是否正确,如果正确,则向python客户端申请读取下一个问题。)
方法2的好处是,每次给web 客户端,只提供一道题,如果答对了才能往下走。
实现方法2需要做一个会话的识别,也就是说,识别web端的身份,不同的客户拿到的题库是不一样的,而同样的客户题库是一样的。
如果要实现上面的要求,一个方法是采用token,识别客户身份,如果身份匹配则继续答题。
另外,根据身份来缓存题库,python 客户端从服务端获取到题库后,根据每个客户token做一个缓存.
具体的调度逻辑如下:
图1:业务调度逻辑
这里包括了客户端和服务端互相调度的逻辑。
客户端逻辑:
import requests
import random
from flask import Flask request render_template url_for redirect
app = Flask(__name__)
def get_data():
"""
函数作用:从服务端读入题库,以JSON格式返回
输入:无
返回:从服务端题库随机读取10个题目,并返回
"""
print("start process get_data")
url = "http://127.0.0.1:8008/get"
ret = requests.post(url)
dic1 = ret.json()
print("end process get_data")
return dic1
def orderlize(questionlist):
"""
函数作用:读入列表,并把列表做处理,按照列表中每个字典的‘R’(难度) 大小排序。
输入:问题list列表
返回:根据'R‘排序后的问题列表
"""
print("start process orderlize")
print("列表通过难度值进行排序")
sortedlist = sorted(questionlist key = lambda i : i['R'])
print(sortedlist)
print("end process orderlize")
return sortedlist
def randomlize_input(dic1):
"""
函数作用:输入问题,对这个问题里面的答案和干扰项目做随机化,并返回给展示界面,包含问题、正确答案、随机化的答案 干扰项目
输入:问题list 列表中的每一个对象(字典对象)
输出:返回这个字典
"""
list1 = [dic1['A'] dic1['D1'] dic1['D2'] dic1['D3']]
listrandom = random.sample(list1 4)
return dic1['Q'] dic1['A'] listrandom
@app.route('/' methods=['GET' 'POST'])
def start_html():
"""
1.get请求打开首页,选择开始答题。
介绍规则,选择10道题,然后从容易往复杂进行答复,如果答题错误则结束。
2.post请求 展示开始答题
跳转到函数答题
"""
#逻辑1:点击开始答题,读取题库信息
if request.method == "POST":
return redirect('/question')
if request.method == "GET":
#1.展示首页,展示"开始答题"
#1.1 点击开始答题发送请求到后端开始答题
return render_template('index57.html')
@app.route('/question' methods=['GET' 'POST'])
def start_question():
if request.method == "POST":
totalcorrectquestion = request.json["count"]
print("total answered correct question is {0}".format(totalcorrectquestion))
#2.1 接收用户选择,
#2.2判断第一道题答案是否正确
#2.3 如果正确,累计答题正确数 1,且调度下一道题
#2.5 如果失败,统计答题正确数right,传递到展示展示界面
return render_template('statistics.html' totalcorrectquestion=totalcorrectquestion)
if request.method == "GET":
# 2.1 接收传入的字典信息,
try:
print(sortedlist)
except NameError:
print("sortedlist is not exist")
print("initialize")
dic1 = get_data()
print(dic1)
questionlist = dic1['data']
sortedlist = orderlize(questionlist)
print(sortedlist)
#2.2 展示第一道题
try:
print(i)
i = i 1
except NameError:
i = 0
Q A listrandom = randomlize_input(sortedlist[i])
return render_template('start_question4.html' Q=Q A=A listrandom=listrandom)
@app.route('/statistics')
def take_account(right):
# 展示正确答案
return 1
if __name__ =='__main__':
app.run(host='0.0.0.0' port=80 debug = True)
服务端逻辑:
import copy
import flask pymongo
from flask import Flask jsonify request
app = Flask(__name__)
def insert_mongo(list1):
myclient = pymongo.MongoClient('mongodb://127.0.0.1:27017/')
mydb= myclient.client["lukedb5"]
mycol = mydb["site"]
x = mycol.insert_many(list1)
print(x.inserted_ids)
return "success"
def get_mongo():
myclient = pymongo.MongoClient('mongodb://127.0.0.1:27017/')
mydb= myclient.client["lukedb5"]
mycol = mydb["site"]
list2 =[]
for x in mycol.aggregate([{'$sample':{'size':10}}]):
del x['_id'] #把id项目删除
list2.append(x)
print(list2)
return list2 "success"
def getall_mongo():
myclient = pymongo.MongoClient('mongodb://127.0.0.1:27017/')
mydb= myclient.client["lukedb5"]
mycol = mydb["site"]
list3 =[]
for x in mycol.find({} {"_id":0}):#把id项目删除
list3.append(x)
print(list3)
return list3 "success"
def update_mongo(listold listnew):
myclient = pymongo.MongoClient('mongodb://127.0.0.1:27017/')
mydb= myclient.client["lukedb5"]
mycol = mydb["site"]
for x in range(0 len(listold)):#把id项目删除
myquery = listold[x]
newvalues = {"$set":listnew[x]}
mycol.update_one(myquery newvalues)
return "success"
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route('/get' methods=['POST'])
def get():
#调用查询逻辑
#获取题目10个
#获取难度3个容易,5个中等,2个难题
list2 info = get_mongo()
return jsonify({"info":info "data":list2})
@app.route('/append' methods=['GET' 'POST'])
def append():
#调用插入逻辑
list1 = request.json["list"]
#dic1 = {"Q":"How old is Republic of China1" "A":"73" "D1":"72" "D2":"74" "D3":"111"}
#list1 =[dic1]
list2 = copy.deepcopy(list1)
info = insert_mongo(list1)
#print(info)
#print(dic1)
#print(list2)
return jsonify({"info":info "data":list2})
@app.route('/getall' methods=['POST'])
def getall():
# 调用抽取接口,把题库数据读出来
list3 info = getall_mongo()
return jsonify({"whole question lib is":list3 "info":info})
@app.route('/update' methods=['POST'])
def update():
# 调用update 接口,修改题目
listold = request.json["listold"]
listnew = request.json["listnew"]
info = update_mongo(listold listnew)
return jsonify({"info": info "oldinfo":listold "newinfo":listnew})
if __name__ =='__main__':
app.run(host='0.0.0.0' port=8008 debug = True)
web端逻辑:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>start_question3.html</title>
<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
问题是:<div id="q"> </div>
<form action="">
<input type="radio" name="sex" value="0" id="a1"> <label for="a1" id="c1" onclick="doPost(0)">Huey</label><br>
<input type="radio" name="sex" value="1" id="a2"> <label for="a2" id="c2" onclick="doPost(1)">Huey</label><br>
<input type="radio" name="sex" value="2" id="a3"> <label for="a3" id="c3" onclick="doPost(2)">Huey</label><br>
<input type="radio" name="sex" value="3" id="a4"> <label for="a4" id="c4" onclick="doPost(3)">Huey</label><br>
</form>
<script>
function myFunction(){
var list1 = {{listrandom|tojson}};
var question = {{Q|tojson}}
document.getElementById("q").innerHTML=question "()";
document.getElementById("c1").innerHTML=list1[0];
document.getElementById("c2").innerHTML=list1[1];
document.getElementById("c3").innerHTML=list1[2];
document.getElementById("c4").innerHTML=list1[3];
}
window.onload=myFunction();
//执行脚本,向后台发送数据
function doPost(data)
{
var list1 = {{listrandom|tojson}};
var answer = list1[data];
var correct = {{A|tojson}};
console.log("come to doPost() function");
console.log("the choice is " answer);
console.log("the correct answer is " correct);
if("undefined" == typeof count) //如果未定义,字符赋0
{ var count=0;}
if(answer == correct) //如果答案是正确的,则做下一道题
{
var count = count 1;
url = "http://127.0.0.1/question";
$.ajax({
type:"GET"
url:url
async:false
contentType:"application/json"
success:function()
{
//window.location.href="http://127.0.0.1/download";
}
});
}
if(answer !=correct) //如果答案是错误的,则到统计界面
{
var jsondoc = {"count":count};
url ="http://127.0.0.1/question";
$.ajax({
type:"POST"
url:url
async:false
contentType:"application/json"
data:JSON.stringify(jsondoc)
success:function()
{
//window.location.href="http://127.0.0.1/download";
}
});
}
}
</script>
</body>
</html>
当前这段代码有个问题,就是没有缓存会话的逻辑,后续需要优化:
问题1:
后续准备根据图1,准备一个python客户端本地缓存到redis的逻辑,另外做一个python 客户端判断token的逻辑,及js端制作token的逻辑。
逻辑图图片不够清晰,放大了重新贴一下