CSC/ECE 517 Fall 2017/E1794. Student-generated questions added to rubric

From Expertiza_Wiki
Jump to navigation Jump to search

Introduction

Instructors make up rubrics in Expertiza. They can ask about anything that is relevant to all the projects that will be submitted. But sometimes students want specific advice on aspects of their work that may be different from the work or topics that other students are working on. It would be more convinient if students can add their own questionnaire to ask feedback for some specific functionalities regarding their project.

Changes implemented

Note: These changes are covered in Use Case section.

  • Added a button 'Manage Supplementary Rubric' on the page which appears when the student clicks on the 'Your Work' link.





  • This button takes the student to the create/edit Review Questionnaire page. The student then can create a new rubric.
  • Added a new field called 'supplementary_rubric' to the 'teams' table so that the supplementary rubric could be stored.
  • Supplementary rubric questions are visible along with instructor generated rubrics.





  • “View” function for a rubric displays answers submitted for the Supplementary rubric questions along with Review Questionnaire for Reviewer.





  • “Your Scores” function for the Reviewee displays answers submitted for the Supplementary rubric questions along with Review Questionnaire.





  • "Alternate View" for "Your scores" should also include Supplemenraty Rubric questionnaire.



    Design Principles to be Followed

    1. MVC - The project is implemented in Ruby on Rails that uses MVC architecture. It separates an application’s data model, user interface, and control logic into three distinct components (model, view and controller, respectively).
    2. Dry Principle - We are trying to reuse the existing functionalities in Expertiza, thus avoiding code duplication. Whenever possible, code modification based on the existing classes, controllers, or tables will be done instead of creating the new one.
    3. Polymorphism
    4. Inheritance

    Use Case

    Here SRQ is used for newly added field supplementaryReviewQuestions in the Teams table and it is initially set as null for all the table entries.Once a student adds a specific Questionnaire to his project this field stores the id of that Questionnaire which is stored in the Questionnaires table.

    Use Case to Add Questionnaire Functionality: In the "Your Work" section, Student will be shown a button "Manage Rubric", when clicked, if the supplementaryReviewQuestions column in Teams table is null for that team, Questionnaire will be created and SRQ in Teams table will be updated to contain the Questionnaire ID. The student will be directed to the Edit Questionnaire page with exsiting logic.
    Use Case for Show Questionnaire Functionality: When the student orders for new reviews, if the supplementaryReviewQuestions column in Teams table is not null for the assigned team, extract the questionnaire for supplementary reviews and append in a new section below normal Questionnaire.
    Use Case for Show Review( and Scores) Functionality: When the Student or the Instructor checks the reviews and scores on rubric, if the supplementaryReviewQuestions column in Teams table is not null for the team, extract the questionnaire review for supplementary questions and append in a new section below normal Questionnaire Reviews.

    To provide the view for the scores of a team we will add one more partition containing the scores for the supplementary questionnaire and implement the already build logic to get and display the scores.


    Files edited:

  • Controllers:
    grades_controller.rb
    response_controller.rb
    submitted_content_controller.rb
  • Model:
    response.rb
    team.rb
  • Views:
    grades/view_team.html.erb
    response/response.html.erb
    submitted_content/_main.html.erb
  • Config:
    routes.rb
  • DB:
    migration script
  • Javascript:
    view_team_in_grades.js

    Implementation

    1. Created a migration script to add a new column 'supplementary_rubric' to the Teams table

    2. To add supplementary rubric: In submitted_content_controller.rb: created a new function 'manage_supplementary_rubric'


     def manage_supplementary_rubric
       @participant = AssignmentParticipant.find(params[:id])
       @team = Team.find(@participant.team.id)
       if @team.supplementary_rubric.nil? then
         @questionnaire = Questionnaire.new
         @questionnaire.private = false
         @questionnaire.name = "SR_" + @team.id.to_s
         @questionnaire.instructor_id = @team.id
         @questionnaire.min_question_score = 0
         @questionnaire.max_question_score = 5
         @questionnaire.type = "ReviewQuestionnaire"
         @questionnaire.display_type = "Review"
         @questionnaire.instruction_loc = Questionnaire::DEFAULT_QUESTIONNAIRE_URL
         begin
           @questionnaire.save
           @team.supplementary_rubric = @questionnaire.id
           @team.save
           flash[:success] = 'You have successfully created a questionnaire!'
         rescue
           flash[:error] = $ERROR_INFO
         end
       else
         @questionnaire = Questionnaire.find(@team.supplementary_rubric)
       end
       redirect_to controller: 'questionnaires', action: 'edit', id: @questionnaire.id
     end
    

    In the view, submitted_content/_mail.html.erb: Created a button 'Manage Supplementary rubric' to be shown in 'your work' tab


      <% if stage != "Finished" %>
       <%= button_to :action => "manage_supplementary_rubric", :id => participant.id do %>
           Manage Supplementary Rubric
       <% end %>
      <% end  %>
    

    After this, the same functionality of adding a rubric and questions is used as before.

    3. To display the supplementary rubric questions: In response_controller.rb: Changes in create, set_content, set_questionnaire_for_new_response, set_questionnaire

    # For Supp Questions
       unless @supp_questionnaire.nil?
         questions_supp = sort_questions(@supp_questionnaire.questions)
         questions = questions+questions_supp
       end
       ###
    

    in set content

    # For supp Questionnaire
       unless @supp_questionnaire.nil?
         @questions_supp = sort_questions(@supp_questionnaire.questions)
       end
       ###
    

    in set_questionnaire_for_new_response

    # For supp Questionnaire
         @supp_questionnaire_id = Team.supplementary_rubric_by_team_id(@contributor.id)
         unless @supp_questionnaire_id.nil?
           @supp_questionnaire = Questionnaire.find(@supp_questionnaire_id)
         end
         ###
    

    in set_questionnaire

       answer_supp = @response.scores.last
       @supp_questionnaire = Questionnaire.find(@supp_questionnaire_id)
       @supp_questionnaire = @response.questionnaire_by_answer(answer_supp)
    


    In View, response/response.html.erb: added code to display supplementary questions.


       <% unless @questions_supp.nil?%>
           
           <%@questions_supp.each do |question| %>
               <% answer = Answer.where(question_id: question.id, response_id: @response.id).first if !@response.nil?%>
               <% if question.instance_of? Criterion%>
                   <%= question.complete(i, answer, @questionnaire.min_question_score, @questionnaire.max_question_score, @dropdown_or_scale) %>
               <% elsif question.instance_of? Scale %>
                   <%= question.complete(i, answer, @questionnaire.min_question_score, @questionnaire.max_question_score) %>
               <% elsif question.instance_of? UploadFile %>
               <% else %>
                   <%= question.complete(i, answer) %>
               <% end %>
               <% i += 1%>
           <% end %>
       <% end %>
    

    4. To edit a review if saved: In response_controller.rb: Changes in edit, update

    # For Supp Questions
         questions_supp = sort_questions(@supp_questionnaire.questions)
         all_questions = questions+questions_supp
    

    5. For the reviewer and the reviewee to view the completed review: Model: response.rb: Created new function, display_html_helper.

    def display_html_helper(questions, answers, questionnaire_max)
       count = 0
       code = 
       questions.each do |question|
         count += 1 if !question.is_a? QuestionnaireHeader and question.break_before == true
         answer = answers.find {|a| a.question_id == question.id }
         row_class = count.even? ? "info" : "warning"
         row_class = "" if question.is_a? QuestionnaireHeader
    
    code += ''
         if !answer.nil? or question.is_a? QuestionnaireHeader
           code += if question.instance_of? Criterion or question.instance_of? Scale
                     question.view_completed_question(count, answer, questionnaire_max)
                   else
                     question.view_completed_question(count, answer)
                   end
         end
    
    code += '' end return code end and made changes in display_as_html function. # For supp_questionnaire response_map = self.map reviewee_id = response_map.reviewee_id supp_questionnaire_id = Team.supplementary_rubric_by_team_id(reviewee_id) unless supp_questionnaire_id.nil? supp_questionnaire = Questionnaire.find(supp_questionnaire_id) supp_questions = supp_questionnaire.questions.sort {|a, b| a.seq <=> b.seq } end 6. For the reviewee to see the review in heat chart: grades_controller.rb: view_team function, added code for supplementary questions, # For Supp questionnaire supp_questionnaire_id = Team.supplementary_rubric_by_team_id(@team_id) if not supp_questionnaire_id.nil? supp = VmQuestionResponse.new(questionnaire, @round, @assignment.rounds_of_reviews) supp_questionnaire = Questionnaire.find(supp_questionnaire_id) supp_questions = supp_questionnaire.questions supp.add_questions(supp_questions) supp.add_team_members(@team) supp.add_reviews(@participant, @team, @assignment.varying_rubrics_by_round?) supp.get_number_of_comments_greater_than_10_words @supplist << supp else @supplist << nil end ### created separate VmQuestionResponse for supplentary questions.

    Test Plan

    Because of the addition of supplementary questions, some of the original spec tests failed. So we started by fixing it.

    1. Due to addition of one more column in the teams table, we had to fix spec/models/assignment_spec.rb, where we added another field called supplementary_rubric in the final expected result describe '#scores' do

       context 'when assignment is varying rubric by round assignment' do
         it 'calculates scores in each round of each team in current assignment' do
           allow(participant).to receive(:scores).with(review1: [question]).and_return(98)
           allow(assignment).to receive(:varying_rubrics_by_round?).and_return(true)
           allow(assignment).to receive(:num_review_rounds).and_return(1)
           allow(ReviewResponseMap).to receive(:get_responses_for_team_round).with(team, 1).and_return([response])
           allow(Answer).to receive(:compute_scores).with([response], [question]).and_return(max: 95, min: 88, avg: 90)
           expect(assignment.scores(review1: [question]).inspect).to eq("{:participants=>{:\"1\"=>98}, :teams=>{:\"0\"=>{:team=>#<AssignmentTeam id: 1, "\
             "name: \"no team\", parent_id: 1, type: \"AssignmentTeam\", comments_for_advertisement: nil, advertise_for_partner: nil, "\
             "submitted_hyperlinks: \"---\\n- https://www.expertiza.ncsu.edu\", directory_num: 0, grade_for_submission: nil, "\
             "comment_for_submission: nil, supplementary_rubric: nil>, :scores=>{:max=>95, :min=>88, :avg=>90.0}}}}")
         end
       end
    
       context 'when assignment is not varying rubric by round assignment' do
         it 'calculates scores of each team in current assignment' do
           allow(participant).to receive(:scores).with(review: [question]).and_return(98)
           allow(assignment).to receive(:varying_rubrics_by_round?).and_return(false)
           allow(ReviewResponseMap).to receive(:get_assessments_for).with(team).and_return([response])
           allow(Answer).to receive(:compute_scores).with([response], [question]).and_return(max: 95, min: 88, avg: 90)
           expect(assignment.scores(review: [question]).inspect).to eq("{:participants=>{:\"1\"=>98}, :teams=>{:\"0\"=>{:team=>#<AssignmentTeam id: 1, "\
             "name: \"no team\", parent_id: 1, type: \"AssignmentTeam\", comments_for_advertisement: nil, advertise_for_partner: nil, "\
             "submitted_hyperlinks: \"---\\n- https://www.expertiza.ncsu.edu\", directory_num: 0, grade_for_submission: nil, "\
             "comment_for_submission: nil, supplementary_rubric: nil>, :scores=>{:max=>95, :min=>88, :avg=>90}}}}")
         end
       end
     end
    

    2. We also changed spec/controllers/response_controller_spec.rb in which due to addition of supplementary questionnaire, we had now 2 answers in the expected results.
    expect(controller.instance_variable_get(:@review_scores)).to eq([answer, answer])

    We added a couple of rspec tests for the code to check the sanity of changes in supplementary questionnaire:
    1. To check if "Manage Supplementary Rubric" is being displayed in the Your work page of a student participating in an assignment.
    2. To check if clicking on "Manage Supplementary Rubric button" creates a questionnaire id in Supplementary rubric column of Teams Table.
    3. To check if a reviewer creates a Rubric, the assigned student is able to see the Supplementary Review Questionnaire whenever he/she logs in and tries to review it.
    To make the code DRY we created a new TopicHelper.rb to make signup to a topic and submit content reusable.

    We created a new spec file supplementary_rubric_spec.rb for testing the added functionality.

     include TopicHelper
     describe "supplementary rubric testing" do
     before(:each) do
       # create assignment and topic
       create(:assignment, name: "TestAssignment", directory_path: "TestAssignment")
       create_list(:participant, 3)
       create(:assignment_team)
       create(:team_user, user: User.where(role_id: 2).first, team: AssignmentTeam.first)
       create(:topic, topic_name: "TestTopic")
       create(:deadline_type, name: "submission")
       create(:deadline_type, name: "review")
       create(:deadline_type, name: "metareview")
       create(:deadline_type, name: "drop_topic")
       create(:deadline_type, name: "signup")
       create(:deadline_type, name: "team_formation")
       create(:deadline_right)
       create(:deadline_right, name: 'Late')
       create(:deadline_right, name: 'OK')
       create(:assignment_questionnaire)
       create(:questionnaire)
       create(:question)
       create(:assignment_due_date, deadline_type: DeadlineType.where(name: "submission").first, due_at: DateTime.now.in_time_zone + 1.day)
     end
    
     it "has manage rubric button to add/edit supplementary questionnaire" do
       signup_topic
       expect(page).to have_content "Manage Supplementary Rubric"
     end
    
     it "add supplementary questionnaire to teams model" do
       signup_topic
       click_button "Manage Supplementary Rubric"
       assert !Team.supplementary_rubric_by_team_id(2).nil?
     end
    
     it "should display Supplementary Questionnaire to assigned student" do
       submit_to_topic
       click_button "Manage Supplementary Rubric"
       click_button "Add"
       click_button "Save review questionnaire"
       user = User.find_by(name: "student2066")
       stub_current_user(user, user.role.name, user.role)
       visit '/student_task/list'
       click_link "TestAssignment"
       click_link "Others' work"
       find(:css, "#i_dont_care").set(true)
       click_button "Request a new submission to review"
       click_link "Begin"
       expect(page).to have_content "Supplementary Reviewee Generated Questions"
     end
    end