You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
educoder/app/helpers/exercises_helper.rb

796 lines
33 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

module ExercisesHelper
# include GitHelper
#获取每个学生对每个题的答案状态
def get_each_student_exercise(exercise_id,exercise_questions,user_id)
@exercise_user = ExerciseUser.current_exercise_user(user_id,exercise_id)&.first
exercise_obj_status = exercise_questions.find_objective_questions
@ex_obj_array = []
exercise_obj_status.each do |q|
q_type = q.question_type
if q_type == Exercise::PRACTICAL
answers_content = q.exercise_shixun_answers.search_shixun_answers("user_id",user_id)
else
answers_content = q.exercise_answers.search_answer_users("user_id",user_id)
end
if q_type <= Exercise::JUDGMENT
if answers_content.present? #学生有回答时
answer_choice_array = []
answers_content.each do |a|
answer_choice_array.push(a.exercise_choice.choice_position) #学生答案的位置
end
user_answer_content = answer_choice_array.sort
standard_answer = q.exercise_standard_answers.pluck(:exercise_choice_id).sort #该问题的标准答案,可能有多个
if user_answer_content == standard_answer #答案一致,多选或单选才给分,答案不对不给分
ques_score = q.question_score
else
ques_score = 0.0
end
else
ques_score = 0.0
end
else
ques_score = answers_content.select(:score).pluck(:score).sum
end
if ques_score >= q.question_score #满分作答为正确
ques_score = q.question_score
stand_answer = 1
elsif ques_score > 0.0 #部分作答
stand_answer = 2
else
stand_answer = 0
end
ques_option = {
"q_id":q.id, #该问题的id
"q_type":q.question_type,
"q_position":q.question_number, #该问题的位置
"stand_status":stand_answer, #用户是否回答
"user_score":ques_score.round(1).to_s #每个问题的总得分
}
@ex_obj_array.push(ques_option)
end
exercise_sub_status = exercise_questions.find_by_custom("question_type",Exercise::SUBJECTIVE) #主观题
@ex_sub_array = [] #主观题的已答/未答
exercise_sub_status.each do |s|
sub_answer = s.exercise_answers.search_answer_users("user_id",user_id) #主观题只有一个回答
if sub_answer.present? && sub_answer.first.score >= 0.0
if s.question_score <= sub_answer.first.score
stand_status = 1
else
stand_status = 2
end
sub_answer_score = sub_answer.first.score
else
stand_status = 0
sub_answer_score = nil
end
sub_score = {
"q_id":s.id,
"q_type":s.question_type,
"q_position":s.question_number,
"stand_status":stand_status,
"user_score":sub_answer_score.present? ? sub_answer_score.round(1).to_s : nil
}
@ex_sub_array.push(sub_score)
end
@ex_obj_array = @ex_obj_array.sort_by {|k| k[:q_position]}
@ex_sub_array = @ex_sub_array.sort_by {|k| k[:q_position]}
end
#试卷的统计结果页面计算各题的
def exercise_commit_result(questions,user_ids)
question_infos = []
percent = 0.0
questions.includes(:exercise_choices).each do |ex|
ex_total_score = user_ids.count * ex&.question_score.to_f #该试卷的已回答的总分
# ex_answers = ex.exercise_answers
if ex.question_type != Exercise::PRACTICAL
ques_title = ex.question_title
ques_less_title = nil
ex_answers = ex.exercise_answers
effictive_users = ex_answers.search_answer_users("user_id",user_ids)
else
ques_title = ex.shixun.name
ques_less_title = ex.question_title
ex_answers = ex.exercise_shixun_answers
effictive_users = ex_answers.search_shixun_answers("user_id",user_ids)
end
effictive_users_count = effictive_users.size #有效回答数可能有重复的用户id这里仅统计是否回答这个问题的全部人数
ex_answered_scores = effictive_users.score_reviewed.pluck(:score).sum #该问题的全部得分
if ex.question_type > Exercise::COMPLETION #当为主观题和实训题时,
percent = (ex_total_score == 0.0 ? 0.0 : (ex_answered_scores / ex_total_score.to_f).round(3) * 100) #正确率
end
question_answer_infos = []
if ex.question_type <= Exercise::JUDGMENT #选择题和判断题
ex_choices = ex.exercise_choices
standard_answer = ex.exercise_standard_answers.pluck(:exercise_choice_id).sort #标准答案的位置
right_users_count = 0
#该问题的正确率
if ex.question_type == Exercise::MULTIPLE #多选题
user_ids.each do |user_id|
ex_choice_ids = effictive_users.map{|e| e.exercise_choice_id if e.user_id == user_id}.reject(&:blank?).uniq
answer_choice_array = ex_choices.map{|a| a.choice_position if ex_choice_ids.include?(a.id)}.reject(&:blank?).uniq
if answer_choice_array.sort == standard_answer
right_users_count += 1
end
end
else #单选题和判断题
standard_answer_choice_id = ex.exercise_choices.find_by(choice_position: standard_answer.first)&.id
right_users_count = effictive_users.select{|answer| answer.exercise_choice_id == standard_answer_choice_id}.size
end
percent = effictive_users_count > 0 ? (right_users_count / effictive_users_count.to_f).round(3)*100 : 0.0
#每个选项的正确率
ex_choices.each do |c|
right_answer = standard_answer.include?(c.choice_position) #选项的标准答案为选项的位置
answer_users_count = effictive_users.select{|answer| answer.exercise_choice_id == c.id}.size
answer_percent = (effictive_users_count == 0 ? 0.0 : (answer_users_count / effictive_users_count.to_f ).round(3))
answer_option = {
:choice_position => c.choice_position,
:choice_text => c.choice_text,
:choice_users_count => answer_users_count,
:choice_percent => answer_percent.round(1).to_s,
:right_answer => right_answer
}
question_answer_infos.push(answer_option)
end
elsif ex.question_type == Exercise::COMPLETION #填空题
ex_ordered = ex.is_ordered
null_standard_answer = ex.exercise_standard_answers
null_stand_choice = null_standard_answer.pluck(:exercise_choice_id) #一个exercise_choice_id可能对应多个answer_text
null_stand_text = null_standard_answer.pluck(:answer_text)
standard_answer_count = 0
all_user_count = 0
null_stand_choice.each_with_index do |s,index|
user_count = 0
s_choice_text = null_stand_text[index]
if ex_ordered #有序排列
user_ids.each do |u|
user_answers = ex_answers.where(user_id:u,exercise_choice_id:s).select(:answer_text)
user_answers_choice = user_answers.exists? ? user_answers&.first&.answer_text.to_s : ""
if s_choice_text == user_answers_choice
user_count += 1
end
end
else
user_count = user_count + effictive_users.select{|answer| answer.answer_text == s_choice_text }.size #回答了标准答案的用户
end
answer_percent = ((effictive_users_count == 0) ? 0.0 : (user_count / effictive_users_count.to_f ).round(3))
answer_option = {
:choice_position => index+1,
:choice_text => s_choice_text,
:choice_users_count => user_count,
:choice_percent => answer_percent.round(1).to_s,
:right_answer => true
}
question_answer_infos.push(answer_option)
all_user_count += user_count
standard_answer_count += 1
end
percent = effictive_users_count > 0 ? (all_user_count / effictive_users_count.to_f).round(3)*100 : 0.0
user_wrong_count = (effictive_users_count - all_user_count )
if effictive_users_count > 0 && user_wrong_count >= 0
wrong_percent = (user_wrong_count / effictive_users_count.to_f ).round(3)
else
wrong_percent = 0.0
end
wrong_answer_position = {
:choice_position => (standard_answer_count + 1),
:choice_text => "wrong",
:choice_users_count => user_wrong_count,
:choice_percent => wrong_percent.round(1).to_s,
:right_answer => false
}
question_answer_infos.push(wrong_answer_position)
elsif ex.question_type == Exercise::SUBJECTIVE #主观题
ex_score = ex&.question_score
full_scores = effictive_users.search_exercise_answer("score",ex_score).size #满分人数
no_full_scores = effictive_users.exercise_no_full_scores(ex_score).size #部分分数人数
zero_scores = effictive_users.search_exercise_answer("score",0.0).size #包含为0分的及未评阅的
un_review_scores = effictive_users_count - full_scores - no_full_scores - zero_scores #未评阅数
if un_review_scores < 0
un_review_scores = 0
end
main_scores_array = [full_scores,no_full_scores,zero_scores,un_review_scores]
main_scores_array.each_with_index do |s,index|
right_answer = (index == 0)
if effictive_users_count == 0 || s < 0
s = 0
score_percent = 0.0
else
score_percent = (s.to_i / effictive_users_count.to_f ).round(3)
end
answer_option = {
:choice_position => index+1,
:choice_text => index+1,
:choice_users_count => s,
:choice_percent => score_percent.round(1).to_s,
:right_answer => right_answer
}
question_answer_infos.push(answer_option)
end
elsif ex.question_type == Exercise::PRACTICAL #实训题
ex.exercise_shixun_challenges.each do |c|
cha_score = c&.question_score
cha_shixun_answer = effictive_users.search_shixun_keys("exercise_shixun_challenge_id",c.id)
effictive_users_count = cha_shixun_answer.size #实训题的每个关卡的有效填写量
full_scores = cha_shixun_answer.search_shixun_keys("score",cha_score).size #满分人数
no_full_scores = cha_shixun_answer.shixun_no_full_scores(cha_score).size #部分分数人数c
all_zero_scores = cha_shixun_answer.search_shixun_keys("score",0.0).size #零分人数
shixun_scores = user_ids.count * cha_score
shixun_answered_scores = cha_shixun_answer.score_reviewed.pluck(:score).sum #该问题的全部得分
game_percent = (shixun_answered_scores == 0.0 ? 0.0 : (shixun_answered_scores / shixun_scores.to_f).round(3) * 100) #正确率
shixun_score_array = [full_scores,no_full_scores,all_zero_scores]
shixun_chas = []
shixun_score_array.each_with_index do |s,index|
right_answer = (index == 0)
score_percent = (effictive_users_count == 0 ? 0.0 : (s.to_i / effictive_users_count.to_f ).round(3))
answer_option = {
:choice_position => index+1,
:choice_text => index+1,
:choice_users_count => s,
:choice_percent => score_percent.round(1).to_s,
:right_answer => right_answer
}
shixun_chas.push(answer_option)
end
shixun_new_chas = {
:cha_id => c.challenge_id,
:cha_name => c.challenge.subject,
:cha_position => c.position,
:cha_details => shixun_chas,
:cha_percent => game_percent.round(1).to_s
}
question_answer_infos.push(shixun_new_chas)
end
end
ques_option = {
:ques_title => ques_title,
:ques_less_title => ques_less_title, #副标题,仅实训题才有
:type => ex.question_type,
:position => ex.question_number,
:percent => percent.round(1).to_s,
:ques_effictive_counts => effictive_users_count,
:ques_details => question_answer_infos
}
question_infos.push(ques_option)
end
question_infos
end
#获取试卷的已答/未答人数
def get_exercise_answers(ex_users, status)
@exercise_answers = 0
@exercise_unanswers = 0
unless status == Exercise::UNPUBLISHED
@exercise_answers = ex_users.commit_exercise_by_status(1).size #表示已经提交了的用户
course_all_members_count = ex_users.size
@exercise_unanswers = (course_all_members_count - @exercise_answers)
end
end
def exercise_index_show(exercise,course,is_teacher_or,user)
# lock_icon 0出现锁1不出现锁
ex_show_text = []
if course.is_end #课堂停止后,试卷显示为已结束
exercise_status = 4
elsif is_teacher_or == 1 #当前为老师的时候,显示的是老师身份的对应试卷的状态,因为该试卷,可能对应老师的多个分班
exercise_status = exercise.exercise_status
else
exercise_status = exercise.get_exercise_status(user) #当前用户查看的试卷的发布状态
end
case exercise_status
when 2
ex_show_text.push("提交中")
when 3
ex_show_text.push("已截止")
when 4
ex_show_text.push("已结束")
else
ex_show_text
end
if is_teacher_or == 1
exercise_users_list = exercise.all_exercise_users(user.id) #当前老师所在班级的全部学生
unreview_count = exercise_status == 1 ? 0 : exercise_users_list.exercise_unreview.size
get_exercise_answers(exercise_users_list, exercise_status)
ex_pb_time = exercise.get_exercise_times(user.id,true)
exercise_publish_time = ex_pb_time[:publish_time]
exercise_end_time = ex_pb_time[:end_time]
current_status = 3
lock_icon = 0
if exercise_status == 1
ex_show_text.push("未发布")
elsif exercise_status == 3
ex_show_text.push("评阅中")
end
elsif is_teacher_or == 2
exercise_users_list = exercise.get_stu_exercise_users
get_exercise_answers(exercise_users_list, exercise_status) # 未答和已答的
unreview_count = exercise_status == 1 ? 0 : exercise_users_list.exercise_unreview.size
ex_pb_time = exercise.get_exercise_times(user.id,false)
exercise_publish_time = ex_pb_time[:publish_time]
exercise_end_time = ex_pb_time[:end_time]
current_status = exercise.check_user_answer_status(user)
lock_icon = 0
if current_status == 4
ex_show_text.push("未提交")
end
else
exercise_users_list = exercise.get_stu_exercise_users
get_exercise_answers(exercise_users_list, exercise_status) # 未答和已答的
exercise_publish_time = exercise.publish_time
exercise_end_time = exercise.end_time
unreview_count = nil
if exercise.is_public
current_status = exercise.check_user_answer_status(user)
lock_icon = 1 #不出现锁
if current_status == 4
ex_show_text.push("未提交")
end
else
current_status = 4
lock_icon = 0
end
end
if (course.is_public == 1) && exercise.is_public
lock_icon = 1
end
if exercise_status > 1
show_unreview_count = unreview_count
else
show_unreview_count = nil
end
if exercise_status == 2 && exercise_end_time.present?
ex_left_time = how_much_time(exercise_end_time)
else #已截止后不显示时间
ex_left_time = nil
end
{
"publish_time":exercise_publish_time,
"end_time":exercise_end_time,
"exercise_answer":@exercise_answers,
"exercise_unanswer":@exercise_unanswers,
"current_status":current_status,
"lock_icon":lock_icon,
"unreview_count": show_unreview_count,
"ex_status":exercise_status,
"ex_tips":ex_show_text,
"ex_left_time": ex_left_time
}
end
#计算试卷的总分和试卷的答题状态
def calculate_student_score(exercise,user)
score1 = 0.0 #选择题/判断题
score2 = 0.0 #填空题
score5 = 0.0 #实训题
ques_stand = [] #问题是否正确
exercise_questions = exercise.exercise_questions.includes(:exercise_answers,:exercise_shixun_answers,:exercise_standard_answers,:exercise_shixun_challenges)
exercise_questions&.each do |q|
begin
if q.question_type != 5
answers_content = q.exercise_answers.where(user_id: user.id) #学生的答案
else
answers_content = q.exercise_shixun_answers.where(user_id: user.id) #学生的答案
end
if q.question_type <= 2 #为选择题或判断题时
if answers_content.present? #学生有回答时
answer_choice_array = []
answers_content.each do |a|
answer_choice_array.push(a.exercise_choice.choice_position) #学生答案的位置
end
user_answer_content = answer_choice_array.sort
standard_answer = q.exercise_standard_answers.pluck(:exercise_choice_id).sort #该问题的标准答案,可能有多个
if user_answer_content == standard_answer #答案一致,多选或单选才给分,答案不对不给分
if standard_answer.size > 0
q_score_1 = q.question_score
# q_score_1 = (q.question_score.to_f / standard_answer.count) #当多选答案正确时每个answer的分数均摊。
else
q_score_1 = 0.0
end
answers_content.update_all(:score => q_score_1)
score1 = score1 + q.question_score
else
answers_content.update_all(:score => -1.0)
score1 += 0.0
end
else
score1 += 0.0
end
elsif q.question_type == 3 #填空题
if answers_content.present?
null_standard_answer = q.exercise_standard_answers
standard_answer_array = null_standard_answer.select(:exercise_choice_id,:answer_text)
standard_answer_ids = standard_answer_array.pluck(:exercise_choice_id).reject(&:blank?).uniq #标准答案的exercise_choice_id数组
standard_answer_count = standard_answer_ids.count
if standard_answer_count > 0 #存在标准答案时才有分数
q_score_2 = (q.question_score.to_f / standard_answer_count) #每一空的得分
else
q_score_2 = 0.0
end
if q.is_ordered
answers_content.each do |u|
i_standard_answer = standard_answer_array.where(exercise_choice_id:u.exercise_choice_id).pluck(:answer_text).reject(&:blank?).map!(&:downcase) #该选项的全部标准答案
if i_standard_answer.include?(u.answer_text.downcase) #该空的标准答案包含用户的答案才有分数
u.update_column('score',q_score_2)
score2 = score2 + q_score_2
else
u.update_column('score',-1.0)
score2 += 0.0
end
end
else
st_answer_text = standard_answer_array.pluck(:answer_text).reject(&:blank?).map!(&:downcase)
answers_content.each do |u|
u_answer_text = u.answer_text.downcase
if st_answer_text.include?(u_answer_text) #只要标准答案包含用户的答案,就有分数。同时,下一次循环时,就会删除该标准答案。防止用户的相同答案获分
u.update_column("score",q_score_2)
score2 = score2 + q_score_2
st_answer_text.delete(u_answer_text)
else
u.update_column('score',-1.0)
score2 += 0.0
end
end
end
else
score2 += 0.0
end
elsif q.question_type == 5 #实训题时,主观题这里不评分
q.exercise_shixun_challenges&.each do |exercise_cha|
game = Game.user_games(user.id,exercise_cha.challenge_id)&.first #当前用户的关卡
if game.present?
exercise_cha_score = 0.0
answer_status = 0
# if game.status == 2 && game.final_score >= 0
if game.final_score > 0
exercise_cha_score = game.real_score(exercise_cha.question_score)
# exercise_cha_score = exercise_cha.question_score #每一关卡的得分
answer_status = 1
end
ex_shixun_answer_content = answers_content&.where(exercise_shixun_challenge_id: exercise_cha.id)
code = nil
if exercise_cha.challenge&.path.present?
cha_path = challenge_path(exercise_cha.challenge&.path)
game_challenge = game.game_codes.search_challenge_path(cha_path)&.first
if game_challenge.present?
game_code = game_challenge
code = game_code.try(:new_code)
else
code = git_fle_content(game.myshixun.repo_path,cha_path)
end
end
if ex_shixun_answer_content.blank? #把关卡的答案存入试卷的实训里
### Todo 实训题的_shixun_details里的代码是不是直接从这里取出就可以了涉及到code的多个版本库的修改
sx_option = {
:exercise_question_id => q.id,
:exercise_shixun_challenge_id => exercise_cha.id,
:user_id => user.id,
:score => exercise_cha_score.round(1),
:answer_text => code,
:status => answer_status
}
ExerciseShixunAnswer.create(sx_option)
else
ex_shixun_answer_content.first.update_attributes(score:exercise_cha_score.round(1),answer_text:code)
end
score5 += exercise_cha_score
else
score5 += 0.0
end
end
end
user_scores = answers_content.blank? ? 0.0 : answers_content.score_reviewed.pluck(:score).sum
if user_scores > 0.0
stand_answer = 1
else
stand_answer = 0
end
ques_option = {
"q_id":q.id, #该问题的id
"q_type":q.question_type,
"q_position":q.question_number, #该问题的位置
"stand_status":stand_answer, #该问题是否正确,1为正确0为错误
"user_score":user_scores.round(1) #每个问题的总得分
}
ques_stand.push(ques_option)
rescue Exception => e
Rails.logger.info("calcuclate_score_have_error____________________________#{e}")
next
end
end
total_score = score1 + score2 + score5
{
"total_score":total_score.round(1),
"stand_status":ques_stand
}
end
#获取用户的相关信息
def exercise_use_info(ex_user,user_status,exercise)
course = exercise.course
current_user_group_id = ""
current_user_group_name = ""
ex_user_user = ex_user.user
exercise_user_name = ex_user_user.real_name
exercise_user_id = ex_user_user.id
ex_user_exercise_status = exercise.get_exercise_status(ex_user_user)
ex_user_student_id = ex_user_user.student_id
if ex_user.start_at.present? && (ex_user.commit_status == 0) #用户已回答,但未提交
commit_status = 2 #继续答题
else
commit_status = ex_user.commit_status
end
ex_user_end_at = ex_user.end_at
course_member = course.students.course_find_by_ids("user_id",ex_user.user.id)
current_user_group_id = course_member.first.course_group_id if course_member.present?
if current_user_group_id == 0
current_user_group_name = "未分班"
else
course_group = course.course_groups.by_group_ids(current_user_group_id)
current_user_group_name = course_group.first.name if course_group.present?
end
teacher_review = ex_user.subjective_score < 0.0 ? false : true
if (user_status == 0 && commit_status == 1) || (user_status == 1 && ex_user_exercise_status == 3 && commit_status == 1) #老师都可以看,学生,需在试卷已提交,且已截止的情况下看
ex_object_score = ex_user.objective_score < 0.0 ? 0.0 : ex_user.objective_score.round(1).to_s
ex_subject_score = ex_user.subjective_score < 0.0 ? nil : ex_user.subjective_score.round(1).to_s
score = ex_user.score.present? ? ex_user.score.round(1).to_s : 0.0.to_s
else
ex_object_score = nil
ex_subject_score = nil
score = nil
end
{
"user_name":exercise_user_name,
"login":ex_user_user.login,
"user_group_id":current_user_group_id,
"user_group_name":current_user_group_name,
"teacher_review":teacher_review,
"ex_object_score":ex_object_score,
"ex_subject_score":ex_subject_score,
"score":score,
"user_id":exercise_user_id,
"commit_status":commit_status,
"student_id":ex_user_student_id,
"end_at":ex_user_end_at
}
end
#公用tab页的相关信息
def ex_common_header(is_teacher_or,exercise)
exercise_url_status = []
if is_teacher_or == 1 #当为老师的
common_tabs = %w(1 2 3 4)
else
if exercise.show_statistic #开启了公开统计
common_tabs = %w(1 2)
else
common_tabs = %w(1)
end
end
common_tabs.each do |c|
if request.url.include?("exercise_lists")
active_status = 1
elsif request.url.include?("exercises_result")
active_status = 1
elsif request.url.include?("exercise_setting")
active_status = 1
elsif request.url == exercise_path(exercise)
active_status = 1
else
active_status = 0
end
common_tab = {
:common_tab => c,
:active_status => active_status
}
exercise_url_status.push(common_tab)
end
exercise_url_status
end
#试卷/问卷 设置页面的发布规则返回内容
def get_user_setting_course(user_published_setting,user_course_groups)
loop_course_publish_time = []
total_array_groups = []
user_published_setting.each do |u|
new_json_array_group = {}
setting_group_name = user_course_groups.detect{|g| g[:group_id] == u.course_group_id}
if loop_course_publish_time.length > 0
time_length = loop_course_publish_time.length #问卷发布时间和截止时间相同的集合
(1..time_length).each do |i|
if (loop_course_publish_time[i-1][:publish_time] == u.publish_time) && (loop_course_publish_time[i-1][:end_time] == u.end_time) #当起止时间已存在时,直接更新
loop_course_ids = total_array_groups[i-1][:course_group_id] +[u.course_group_id]
loop_course_names = total_array_groups[i-1][:course_group_name] + [setting_group_name[:group_name]]
new_json_array_group = {
"loop_times":i-1,
"course_group_id":loop_course_ids,
"course_group_name":loop_course_names,
}
end
end
if new_json_array_group.length > 0
loop_times = new_json_array_group[:loop_times]
total_array_groups[loop_times][:course_group_id] = new_json_array_group[:course_group_id]
total_array_groups[loop_times][:course_group_name] = new_json_array_group[:course_group_name]
else
loop_course_times = {
"publish_time":u.publish_time,
"end_time": u.end_time
}
loop_course_publish_time.push(loop_course_times)
json_array_group = {
"course_group_id":[u.course_group_id],
"course_group_name":[setting_group_name[:group_name]],
"course_publish_time":u.publish_time,
"course_end_time":u.end_time
}
total_array_groups.push(json_array_group)
end
else #第一次循环获得初始值 第一步
loop_course_times = {
"publish_time":u.publish_time,
"end_time": u.end_time
}
loop_course_publish_time.push(loop_course_times)
json_array_group = { #第一个问卷发布规则的第一条记录
"course_group_id":[u.course_group_id],
"course_group_name":[setting_group_name[:group_name]],
"course_publish_time":u.publish_time,
"course_end_time":u.end_time
}
total_array_groups.push(json_array_group)
end
end
total_array_groups
end
#学生的分数状态及回答的内容
def user_question_answers(q,ex_answerer_id,student_status,is_teacher_or,ex_status,ques_type,ex_type)
answered_content = []
user_score = nil
shixun_type = 0
question_comment = []
# user_score_pre = nil
if ques_type == 5
exercise_answers = q.exercise_shixun_answers.search_shixun_answers("user_id",ex_answerer_id)
else
exercise_answers = q.exercise_answers.search_exercise_answer("user_id",ex_answerer_id) #试卷用户的回答
end
if student_status == 2 #当前为老师,或为学生且已提交
user_score_pre = exercise_answers.score_reviewed
if ques_type == 4 #主观题时且没有大于0的分数时为空
user_score = user_score_pre.present? ? user_score_pre.pluck(:score).sum : nil
elsif ques_type == 5 || ques_type == 3
user_score = user_score_pre.present? ? user_score_pre.pluck(:score).sum : 0.0
else
if exercise_answers.present? #判断题和选择题时,
answer_choice_array = []
exercise_answers.each do |a|
answer_choice_array.push(a.exercise_choice.choice_position) #学生答案的位置
end
user_answer_content = answer_choice_array.sort
standard_answer = q.exercise_standard_answers.pluck(:exercise_choice_id).sort #该问题的标准答案,可能有多个
if user_answer_content == standard_answer #答案一致,多选或单选才给分,答案不对不给分
user_score = q.question_score
else
user_score = 0.0
end
else
user_score = 0.0
end
end
end
if user_score.present? && (user_score > q.question_score)
user_score = q.question_score
end
if ques_type <= 2
answered_content = exercise_answers&.pluck(:exercise_choice_id)
elsif ques_type == 3
exercise_answers&.each do |a|
u_answer = {
"choice_id":a.exercise_choice_id,
"answer_text": a.answer_text
}
answered_content.push(u_answer)
end
elsif ques_type == 4
answered_content = exercise_answers&.pluck(:answer_text)
end
if ques_type == 5 #存在实训题,及已经做了实训题的
if ex_status == 3 || is_teacher_or == 1 #如果试卷已截止,则可以看到分数,否则不能查看分数
shixun_type = 2
elsif ex_status == 2 && q.exercise_shixun_answers.present? #试卷未截止,且用户已回答的,则能看到答题的状态
shixun_type =1
end
end
if ex_type == 4 #填空题/主观题/实训题有评论的
q_answer_id = exercise_answers.present? ? exercise_answers.first.id : nil
question_comment = q.exercise_answer_comments.search_answer_comments("exercise_answer_id",q_answer_id)
end
{
"user_score": (user_score.present? ? user_score.round(1).to_s : nil),
"answered_content":answered_content,
"shixun_type":shixun_type,
"question_comment":question_comment
}
end
def convert_to_char(str)
result = ""
length = str.length
unless str.nil?
if length === 1
result += (str.to_i + 64).chr
return result
elsif length > 1
for i in 0...length
result += (str[i].to_i + 64).chr
end
return result
end
end
result
end
def get_exercise_left_time(exercise,user)
ex_time = exercise.time
user_left_time = nil
time_now_i = Time.now.to_i
if ex_time > 0
exercise_user = exercise.exercise_users.find_by(user_id:user.id)
time_mill = ex_time * 60 #转为秒
exercise_end_time = exercise.end_time.present? ? exercise.end_time.to_i : 0
exercise_user_start = exercise_user&.start_at.present? ? exercise_user.start_at.to_i : 0
#用户未开始答题时即exercise_user_start为0
if exercise_user_start == 0
if (exercise_end_time - time_now_i) > time_mill
user_left_time = time_mill
else
user_left_time = (exercise_end_time < time_now_i) ? nil : (exercise_end_time - time_now_i)
end
else
if (exercise_user_start + time_mill) > exercise_end_time
time_mill = exercise_end_time - exercise_user_start #如果开始答题时间加试卷的限时长大于试卷的截止时间,则以试卷的截止时间到开始答题时间为试卷的限时
end
exercise_user_left_time = time_now_i - exercise_user_start #用户已回答的时间
user_left_time = (time_mill < exercise_user_left_time) ? nil : (time_mill - exercise_user_left_time) #当前用户对试卷的回答剩余时间
end
end
user_left_time
end
#实训题学生代码的行数
def content_line(content)
content.split(/\r?\n/).length + 1
end
end