瀏覽代碼

提交前睡眠

jason 1 年之前
父節點
當前提交
df62966c2e
共有 4 個文件被更改,包括 310 次插入0 次删除
  1. 2 0
      common.yaml
  2. 2 0
      config/config.go
  3. 139 0
      student/question_file.go
  4. 167 0
      student/student.go

+ 2 - 0
common.yaml

@@ -9,6 +9,8 @@ specialCourses:
 - "医用基础化学"
 channel: 1
 visitCount: 0
+NewStyle: false
+SleepTime: 60
 
 codeManual: true
 #target 1 视频和题目都处理 2 只拉视频 3 只刷题

+ 2 - 0
config/config.go

@@ -124,6 +124,8 @@ type Configure struct {
 	Timeout        int
 	QuestionCount  int
 	QuestionRandom bool
+	NewStyle       bool
+	SleepTime      int
 }
 
 var Conf *Configure

+ 139 - 0
student/question_file.go

@@ -4,6 +4,7 @@ import (
 	"bufio"
 	"errors"
 	"fmt"
+	"ouchn/config"
 	"sync"
 	//"github.com/syndtr/goleveldb/leveldb"
 	"io"
@@ -43,7 +44,10 @@ func getTag(questionType string) string {
 
 var CourseMap map[string]int
 var CourseMapArray []map[string][]string
+var CourseMapNew map[string]int
+var CourseMapArrayNew []map[string][]string
 var mutex sync.Mutex
+var mutexNew sync.Mutex
 
 func TrimSpace(data string) string {
 
@@ -70,6 +74,9 @@ func TrimSpace(data string) string {
 }
 
 func LoadXlsx(filename string) (map[string][]string, error) {
+	if config.Conf.NewStyle {
+		return LoadXlsxNew(filename)
+	}
 	mutex.Lock()
 	defer mutex.Unlock()
 	if true {
@@ -129,6 +136,7 @@ func LoadXlsx(filename string) (map[string][]string, error) {
 		questionName = TrimSpace(questionName)
 		questionName = ParseHan(questionName)
 		ret[tag+"-"+questionName] = []string{}
+
 		for i := 2; i < len(cells); i++ {
 			answer := cells[i].Value
 			answer = TrimSpace(answer)
@@ -144,6 +152,137 @@ func LoadXlsx(filename string) (map[string][]string, error) {
 	return ret, nil
 }
 
+var SelectAnswerFlagMap = map[string]int{
+	"A": 0,
+	"a": 0,
+	"B": 1,
+	"b": 1,
+	"C": 2,
+	"c": 2,
+	"D": 3,
+	"d": 3,
+	"E": 4,
+	"e": 4,
+	"F": 5,
+	"f": 5,
+	"G": 6,
+	"g": 6,
+	"H": 7,
+	"h": 7,
+	"I": 8,
+	"i": 8,
+	"J": 9,
+	"j": 9,
+	"K": 10,
+	"k": 10,
+	"L": 11,
+	"l": 11,
+	"M": 12,
+	"m": 12,
+	"N": 13,
+	"n": 13,
+}
+var JudgeAnswerMap = map[string]int{
+	"Y": 0,
+	"y": 0,
+	"是": 0,
+	"N": 1,
+	"n": 1,
+	"否": 1,
+}
+
+func LoadXlsxNew(filename string) (map[string][]string, error) {
+	mutexNew.Lock()
+	defer mutexNew.Unlock()
+	if true {
+		CourseMapNew = map[string]int{}
+		CourseMapArrayNew = []map[string][]string{}
+	}
+	if CourseMapNew == nil {
+		CourseMapNew = map[string]int{}
+		CourseMapArrayNew = []map[string][]string{}
+	}
+	if index, ok := CourseMapNew[filename]; ok {
+		return CourseMapArrayNew[index], nil
+	}
+
+	ef, err := xlsx.OpenFile(filename)
+	if err != nil {
+		fmt.Printf("err:%v\n", err)
+		return nil, err
+	}
+	if len(ef.Sheets) == 0 {
+		return nil, errors.New("excel empty sheet")
+	}
+	sheet := ef.Sheets[0]
+	rows := sheet.Rows
+	if len(rows) == 0 {
+		return nil, errors.New("excel empty rows")
+	}
+	ret := map[string][]string{}
+	for i, row := range rows {
+		if i == 0 {
+			continue
+		}
+		cells := row.Cells
+		if len(cells) == 0 {
+			continue
+		}
+		emptyCells := true
+		for _, v := range cells {
+			if TrimSpace(v.Value) != "" {
+				emptyCells = false
+				break
+			}
+		}
+		if emptyCells {
+			continue
+		}
+
+		if len(cells) < 5 {
+			return nil, errors.New(fmt.Sprintf("第%d行信息不足", i+1))
+		}
+		questionType := cells[0].Value
+		if questionType == "" {
+			break
+		}
+		tag := getTag(questionType)
+		if tag == "" {
+			return nil, errors.New(fmt.Sprintf("第%d行题目类型错误", i+1))
+		}
+		questionName := cells[1].Value
+		questionName = TrimSpace(questionName)
+		questionName = ParseHan(questionName)
+		ret[tag+"-"+questionName] = []string{}
+		answers := cells[4].Value
+		answers = TrimSpace(answers)
+		if answers == "" {
+			return nil, errors.New(fmt.Sprintf("第%d行答案为空", i+1))
+		}
+
+		switch tag {
+		case "1":
+			ret[tag+"-"+questionName] = append(ret[tag+"-"+questionName], answers)
+		case "2":
+			ret[tag+"-"+questionName] = append(ret[tag+"-"+questionName], answers)
+		case "3":
+			array := strings.Split(answers, "|")
+			for _, answer := range array {
+				if answer == "" {
+					continue
+				}
+				ret[tag+"-"+questionName] = append(ret[tag+"-"+questionName], answer)
+			}
+		default:
+			ret[tag+"-"+questionName] = append(ret[tag+"-"+questionName], answers)
+		}
+
+	}
+	CourseMapArrayNew = append(CourseMapArrayNew, ret)
+	CourseMapNew[filename] = len(CourseMapArrayNew) - 1
+	return ret, nil
+}
+
 // 从txt 导入 execel
 func LoadQuestionFile(filename string) error {
 

+ 167 - 0
student/student.go

@@ -647,6 +647,9 @@ func random(count int) int {
 }
 
 func chooseAnswer2(wd selenium.WebDriver, questions []QuestionInfo, questionM map[string][]string) error {
+	if config.Conf.NewStyle {
+		return chooseAnswer2New(wd, questions, questionM)
+	}
 	emptyCount := 0
 	if false {
 		emptyCount = 3
@@ -804,6 +807,167 @@ func chooseAnswer2(wd selenium.WebDriver, questions []QuestionInfo, questionM ma
 	return nil
 }
 
+func chooseAnswer2New(wd selenium.WebDriver, questions []QuestionInfo, questionM map[string][]string) error {
+	emptyCount := 0
+	if false {
+		emptyCount = 3
+	}
+	// 选择或判断题目号
+	originNumber := map[int]bool{}
+	// 选择或判断最大题目号
+	maxNumber := 0
+	// 先收集答案
+	for i, _ := range questions {
+		questions[i].ChoosedAnswer = []int{}
+		fmt.Printf("\n题目类型:%s\n", getTagName(questions[i].Tag))
+		fmt.Printf("题目:%s\n", questions[i].Text)
+
+		for _, v := range questions[i].AnswerArray {
+			fmt.Printf("选项:%s\n", v.Text)
+		}
+		if questions[i].Tag == 4 {
+			shortAnswer(questions[i], questionM)
+			continue
+		}
+
+		if len(questions[i].AnswerArray) == 0 {
+			return errors.New(fmt.Sprintf("%s 选项为空", questions[i].Text))
+
+		}
+		str := TrimSpace(questions[i].Text)
+		str = ParseHan(str)
+		//str = trimQuestionPrefix(str)
+		str = fmt.Sprintf("%d-", questions[i].Tag) + str
+
+		answerstrs, _ := questionM[str]
+
+		if len(answerstrs) == 0 || answerstrs[0] == "" {
+			emptyCount++
+			if emptyCount > config.Conf.QuestionCount {
+				return errors.New(fmt.Sprintf("%s 题库答案为空", questions[i].Text))
+			}
+			fmt.Printf("%s 题库答案为空, 空答案数小于%d,进行随机选择", questions[i].Text, config.Conf.QuestionCount)
+			questions[i].ChoosedAnswer = append(questions[i].ChoosedAnswer, random(len(questions[i].AnswerArray)))
+			continue
+
+		}
+		find := 0
+		// 单选
+		if questions[i].Tag == 1 {
+			//answerstrs = answerstrs[:1]
+		}
+		if questions[i].Tag == 3 {
+			//fmt.Printf("*****************************************:%s,%v\n", questions[i].Text,answerstrs)
+		}
+
+		for _, answerstr := range answerstrs {
+			if answerstr == "" {
+				continue
+			}
+			for j, _ := range questions[i].AnswerArray {
+				if questions[i].Tag == 1 && find > 0 {
+					break
+				}
+				right := false
+				if questions[i].Tag == 1 || questions[i].Tag == 3 {
+					//right = TrimSpace(answerstr) == TrimSpace(v.Text)
+					right = j == SelectAnswerFlagMap[answerstr]
+
+				} else {
+					//right = tryEqual(answerstr, TrimSpace(v.Text))
+					right = j == JudgeAnswerMap[answerstr]
+				}
+
+				if right {
+					fmt.Printf("选择答案:%s\n", answerstr)
+					questions[i].ChoosedAnswer = append(questions[i].ChoosedAnswer, j)
+					originNumber[i] = true
+					maxNumber = i
+					//ppp, _ := v.Radio.Element.FindElement(selenium.ByXPATH, "./following-sibling::span")
+					//txt, _ := ppp.Text()
+					//fmt.Printf("kkkkkkkkkkkkkkkkkkk:%s,%s\n", txt, answerstr)
+					if questions[i].Tag == 3 {
+						//time.Sleep(10*time.Second)
+					}
+					find++
+					//time.Sleep(1 * time.Second)
+					break
+				}
+			}
+		}
+
+		if find == 0 {
+			emptyCount++
+			if emptyCount > config.Conf.QuestionCount {
+				return errors.New(fmt.Sprintf("%s 题库答案为空2", questions[i].Text))
+			}
+			fmt.Printf("未找到匹配答案,题库中的答案有:%v\n", answerstrs)
+			questions[i].ChoosedAnswer = append(questions[i].ChoosedAnswer, random(len(questions[i].AnswerArray)))
+			continue
+			//return errors.New(fmt.Sprintf("%s 未找到匹配答案", questions[i].Text))
+		}
+	}
+
+	// 选择答案, 先随机生成需故意填错的错误题号
+	errorNumber := getRandErrorNumber(emptyCount, originNumber, maxNumber)
+	defer func() {
+		errorNumber = nil
+	}()
+
+	for i, _ := range questions {
+		if len(questions[i].ChoosedAnswer) == 0 {
+			continue
+		}
+		// 不需要故意填错
+		if !errorNumber[i] {
+			for _, v := range questions[i].ChoosedAnswer {
+				err := tryClick(wd, questions[i].AnswerArray[v].Radio.Element)
+				if err != nil {
+					fmt.Printf("点击答案错误:%v\n", err)
+					return err
+				}
+				time.Sleep(1 * time.Second)
+			}
+			continue
+		}
+		// 需要故意填错时,随机选择错误答案
+
+		// 正确答案map
+		cm := map[int]bool{}
+		for _, j := range questions[i].ChoosedAnswer {
+			cm[j] = true
+		}
+
+		// 可供选择的错误答案
+		array := []int{}
+		for j, _ := range questions[i].AnswerArray {
+			if !cm[j] {
+				array = append(array, j)
+			}
+		}
+
+		// 随机生成索引
+		arrayIndex := random(len(array))
+
+		// 获取错误答案索引
+		errorIndex := 0
+		if len(array) > 0 {
+			errorIndex = array[arrayIndex]
+		} else {
+			errorIndex = random(len(questions[i].AnswerArray))
+		}
+		err := tryClick(wd, questions[i].AnswerArray[errorIndex].Radio.Element)
+		if err != nil {
+			fmt.Printf("点击答案错误:%v\n", err)
+			return err
+		}
+		time.Sleep(1 * time.Second)
+
+	}
+
+	return nil
+}
+
 func chooseAnswer(wd selenium.WebDriver, questions []QuestionInfo, questionM map[string][]string) error {
 	// 正常选择答案
 	if !config.Conf.QuestionRandom {
@@ -1698,6 +1862,9 @@ func examHandle(wd selenium.WebDriver, courseId, moduleId, id string, qustionM m
 	}
 
 	// 提交试卷
+	if config.Conf.SleepTime > 0 {
+		time.Sleep(time.Duration(config.Conf.SleepTime) * time.Second)
+	}
 	fmt.Printf("开始提交\n")
 	err = examHandleSubmit(wd)
 	fmt.Printf("examHandleSubmit:%v\n", err)