Skip to content

Commit

Permalink
feat: add answer
Browse files Browse the repository at this point in the history
  • Loading branch information
zrll12 committed Aug 18, 2024
1 parent 20eb13a commit 7be07fb
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 18 deletions.
3 changes: 3 additions & 0 deletions src/model/generated/question.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,11 @@ pub struct Model {
#[sea_orm(column_type = "Text", nullable)]
pub condition: Option<String>,
pub required: bool,
#[serde(skip_serializing)]
pub answer: Option<String>,
#[serde(skip_serializing)]
pub all_points: i32,
#[serde(skip_serializing)]
pub sub_points: Option<i32>,
}

Expand Down
31 changes: 25 additions & 6 deletions src/model/question.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,20 @@ pub struct Question {
#[serde(skip_serializing_if = "Option::is_none")]
pub condition: Option<Vec<Condition>>,
pub required: bool,
#[serde(skip_serializing)]
pub answer: Option<Answer>,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Condition {
pub r#type: ConditionType,
pub conditions: Vec<ConditionInner>
pub conditions: Vec<ConditionInner>,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct ConditionInner {
pub id: Uuid,
pub value: String
pub value: String,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
Expand All @@ -46,16 +48,24 @@ pub enum QuestionType {
File = 4,
}

#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Answer {
pub all_points: i32,
pub sub_points: Option<i32>,
pub answer: String,
}

impl Question {
pub fn new(question_type: QuestionType, content: ValueWithTitle, values: Option<Vec<ValueWithTitle>>,
condition: Option<Vec<Condition>>, required: bool) -> Self {
condition: Option<Vec<Condition>>, required: bool, answer: Option<Answer>) -> Self {
Self {
id: Uuid::new_v4(),
content,
r#type: question_type,
values,
condition,
required,
answer,
}
}
}
Expand All @@ -75,15 +85,23 @@ impl TryFrom<u8> for QuestionType {
}

impl TryFrom<Model> for Question {

type Error = String;

fn try_from(value: Model) -> Result<Self, Self::Error> {
let content: ValueWithTitle = serde_json::from_value(value.content).unwrap();
let values: Option<Vec<ValueWithTitle>> = value.values.map(|values|
let values: Option<Vec<ValueWithTitle>> = value.values.map(|values|
values.iter().map(|v| serde_json::from_value(v.clone()).unwrap()).collect());
let condition: Option<Vec<Condition>> = value.condition.map(|condition|
let condition: Option<Vec<Condition>> = value.condition.map(|condition|
serde_json::from_str(&condition).unwrap());
let answer = if let Some(answer) = value.answer {
Some(Answer {
all_points: value.all_points,
sub_points: value.sub_points,
answer,
})
} else {
None
};

Ok(Question {
id: Uuid::from_str(&value.id).unwrap(),
Expand All @@ -92,6 +110,7 @@ impl TryFrom<Model> for Question {
values,
condition,
required: value.required,
answer,
})
}
}
95 changes: 83 additions & 12 deletions src/service/judge.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,87 @@
use std::collections::HashMap;
use crate::model::generated::prelude::Answer;
use crate::model::question::Question;
use tracing::debug;
use crate::model::question::{Question, QuestionType};

pub async fn judge_subjectives(questions: Vec<Question>, answer: HashMap<String, String>) {
// let mut score = 0;
// for question in questions {
// if let Some(ans) = answer.get(&question.id) {
// if ans == question.answer {
// score += 1;
// }
// }
// }
// score
pub async fn judge_subjectives(questions: Vec<Question>, answer: HashMap<String, String>) -> i32 {
let mut score = 0;
let mut full_score = 0;

for question in questions {
if let Some(ans) = question.answer {
full_score += ans.all_points;

match question.r#type {
QuestionType::MultipleChoice => {
let point = judge_multiple_choice(&ans.answer, answer.get(&question.id.to_string()).unwrap());
match point {
PointType::All => {
score += ans.all_points;
}
PointType::Sub => {
if let Some(sub) = ans.sub_points {
score += sub;
}
}
PointType::None => {}
}
}
QuestionType::SingleChoice => {
let point = judge_single_choice(&ans.answer, answer.get(&question.id.to_string()).unwrap());
match point {
PointType::All => {
score += ans.all_points;
}
PointType::None => {}
_ => {}
}
}
_ => {}
}
}
}
score
}

pub fn judge_multiple_choice(answer: &str, user: &str) -> PointType {
let answer: Vec<String> = serde_json::from_str(answer).unwrap();
let user: Vec<String> = serde_json::from_str(user).unwrap();
debug!("answer: {:?}, user: {:?}", answer, user);
let mut missing_flag = false;
let mut wrong_flag = false;

for ans in &answer {
if !user.contains(ans) {
missing_flag = true;
break;
}
}

for u in &user {
if !answer.contains(u) {
wrong_flag = true;
break;
}
}

if wrong_flag {
PointType::None
} else if missing_flag {
PointType::Sub
} else {
PointType::All
}
}

pub fn judge_single_choice(answer: &str, user: &str) -> PointType {
if answer == user {
PointType::All
} else {
PointType::None
}
}

pub enum PointType {
All,
Sub,
None,
}

0 comments on commit 7be07fb

Please sign in to comment.