使用Sqlite3+Express.js+React实现在线答题(上)

将word格式的题库转为txt格式,导入至sqlite3中,使用Express.js做服务端提供json格式数据,使用React做前端获取服务端数据。本文为第一部分,实现导入数据和服务端提供数据API接口。

数据导入

源格式

源题库为word格式,题型分别为单选、多选和判断题。

使用Sqlite3+Express.js+React实现在线答题(上)_第1张图片
单选题
使用Sqlite3+Express.js+React实现在线答题(上)_第2张图片
多选题
判断题

转为txt格式

为便于读取,word格式另存为txt格式,文件名为questions.txt

建立数据库

我使用的IPython来建立数据库:

import sqlite3
conn=sqlite3.connect('mydb.db')
c=conn.cursor()
c.execute('''create table (
                 id int primary key, // 主键 
                 description text,  // 题目
                 answer text,  // 答案
                 A text, //选择项A。判断题时,A为正确。
                 B text, //选择项B。判断题时,B为错误。
                 C text, //选择项C
                 D text, //选择项D
                 E text, //选择项E。默认最多5个选择项。
             )''')
c.commit()

从txt文件中提取试题信息

txt题库中,每道题都以阿拉伯数字+.开始,形如1.,选择题题干中正确答案在全角括号中,形如(ABCD),判断题题干行中会有×符合,据此提取数据。代码如下:

import re // 导入正则表达式模块
p1=re.compile("\d+.")  // 判断是否为新的题干的正则表达式
p2=re.compile("((.+))") // 提取正确答案的正则表达式
f=open('questions.txt','r') // 打开文本文件
lines=f.readlines()  // 读取全部文本
questions = [] // 建立空题库,在遍历文本中追加
description='' // 初始化题目
answer='' // 初始化答案
A='' // 初始化选项
B=''
C=''
D=''
E=''
for line in lines:
    if p1.match(s): // 该行以数字+.开始,遇到一道新题
        if description != '': // 确定题目非空
            questions.append([description,answer,answerA,   // 新题追加到题库中,
                answerB,answerC,answerD,answerE,remark])
        question=''  // 然后清空各字段
        answer=''
        answerA=''
        answerB=''
        answerC=''
        answerD=''
        answerE=''
        remark=''
        if '×' in s or '√' in line: // 这是一道判断题吗
                description=s[:s.find('(')] // 提取题目表述
                answerA='√'
                answerB='×'
                remark='2' // 为便于排序,备注中判断题标记为2
                if '×' in s:  // 答案为×
                    answer='B'
                elif '√' in s:
                    answer='A'
                continue // 判断题没有选择项,所以直接跳到下一个循环
        else: // 不是判断,那就是选择题了
                  description=s[:s.find('(')+1]+s[s.find(')'):] // 提取题目描述
                  answer=p2.search(s).group(1).strip()
                  if len(answer)>1:
                       remark='1' // 多选题标记为1
                  else:
                       remark='0' // 单选题标记为0
    else: // 该行不是以数字+.开始,是选择项
        answers = s.split() // 选择项之间以空格分开
        for an in answers:
            if an.startswith('A'): // 选项A
                answerA=an
            elif an.startswith('B'): // 选项B
                answerB=an
            elif an.startswith('C'): // 选项C
                answerC=an
            elif an.startswith('D'): // 选项D
                answerD=an 
            elif an.startswith('E'): // 选项E
                      answerE=an

试题信息导入数据库

现在,所有题目都在questions数组中,可以插入到数据库中了:

conn = sqlite3.connect('mydb.db') // 连接数据库
c=conn.cursor()  // 获取游标
i=1 // 计数器,做ID赋值用
for q in questions:
    // 执行插入
    c.execute("insert into question(id,description,answer,A,B,C,D,E,remark) values(%d,'%s','%s','%s','%s','%s','%s','%s','%s')"%(i,q[0],q[1],q[2],q[3],q[4],q[5],q[6],q[7]))                                                 
    i=i+1
conn.commit() // 提交

使用express.js建立服务端

新建目录express-sqlite3:

$ mkdir express-sqlite3 ; cd express-sqlite3

建立新文件package.json,输入以下内容:

{
  "name": "express-sqlite3",
  "version": "1.0.0",
  "description": "",
  "main": "restapi.js",
  "dependencies": {
    "express": "^4.13.1",
    "sqlite3": "https://github.com/mapbox/node-sqlite3/tarball/master"
  },
  "devDependencies": {},
  "scripts": {
    "start": "node restapi.js"
  },
  "author": "",
  "license": "ISC"
}

执行npm install安装包。
新建db目录,将上一步生成的mydb.db文件拷贝至此目录内。
新建restapi.js文件,输入以下内容:

var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('db/mydb.db');

var express = require('express');
var restapi = express();

restapi.get('/data', function(req, res){
    results = [];
    db.all("SELECT * from question order by remark,description", function(err, rows){
        rows.map((row)=>{
        results.push({"id":row.id,
                  "description":row.description,
                  "answer":row.answer,
                  "A":row.A,
                  "B":row.B,
                  "C":row.C,
                  "D":row.D,
                  "E":row.E,
                  "remark":row.remark,})
        });
        res.json(results);
    });
});

restapi.listen(3000); // 在3000端口监听

console.log("Submit GET to http://localhost:3000/data");

在命令行执行:

npm start
> [email protected] start /home/fanzhh/projects/express-sqlite3
> node restapi.js
Submit GET to http://localhost:3000/data

此时在浏览器输入地址http://localhost:3000/data,页面显示如下:

使用Sqlite3+Express.js+React实现在线答题(上)_第3张图片
json数据

OK。下一章我们将用React实现前端的在线答题。

你可能感兴趣的:(使用Sqlite3+Express.js+React实现在线答题(上))