<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Rkaur</id>
	<title>Expertiza_Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Rkaur"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Rkaur"/>
	<updated>2026-08-08T08:24:27Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124617</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124617"/>
		<updated>2019-04-27T00:54:04Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: /* Important Links */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, and it links to the review or submission which initiated the notification. It gives the link in raw HTML, but it should give it as a link associated with text, such as the text “this new review” linking to the page that shows the review.The email send to the instructor should also link to page that shows data on each of the reviews done on this team.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.With every review submitted for an assignment of a particular student, the average is updated.The mail sent to the instructor contains the links to the conflicted review and a summary of the reviews.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view exists to analyze the conflict report===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the reviews but there is no view where the instructor can see all the conflicts and analyze them.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which will contain links to the conflicting review, summary link, and a link to report which can be used for analyzing. The new report will have the information like the Team(having conflicts), the standard deviation for the team review score and pictorial representation of all the review scores. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The email sent to the instructor should link to a page that shows the data on each of the reviews done on this team:&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members (user-IDs and/or names)&lt;br /&gt;
* One line for each review received.In this line would be&lt;br /&gt;
# The name of the person (or team) that submitted the review, which would be hyperlinked to the review itself&lt;br /&gt;
# The score given for the review&lt;br /&gt;
# A bar chart showing pictorial view&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Review scores that are outside some “tolerance” limit should be highlighted, e.g., boldfaced or shown in a different color.Probably the tolerance should be, perhaps, one or two standard deviations from the mean.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
*'''Feature 1:''' New page to show the conflict report&lt;br /&gt;
A new view page of the report which will have the following information:-&amp;lt;br&amp;gt;&lt;br /&gt;
# The name of the team.&lt;br /&gt;
# The members of the team.&lt;br /&gt;
# The name of the reviewer which would be hyperlinked to the review itself.&lt;br /&gt;
# The score given for the review.&lt;br /&gt;
# A bar chart showing pictorial view of all the reviews for a particular team.&lt;br /&gt;
# The average score received from reviewers.&lt;br /&gt;
# The standard deviation of the score received from reviewers.&lt;br /&gt;
# Conflicting reviewers are highlighted.These are those which are two standard deviations away from the mean.&lt;br /&gt;
&lt;br /&gt;
This view have a report of all the teams on one page.This report link is added to the mail that is already being sent whenever some conflict happens.This report page will be also accessible from the reports drop-down in the instructor view.&lt;br /&gt;
 &lt;br /&gt;
*A new partial is created for this view -&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;color:green;text-align:adjust&amp;quot;&amp;gt;&lt;br /&gt;
  Note: &amp;lt;br&amp;gt;&lt;br /&gt;
  X- axis represents precentage score of the team&amp;lt;br&amp;gt;&lt;br /&gt;
  Y- axis represents the reviewers &amp;lt;br&amp;gt;&lt;br /&gt;
  Highlighted reviewers are outside the tolerance limit&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;table id=&amp;quot;myTable&amp;quot; border=&amp;quot;1px solid black&amp;quot; margin-top=&amp;quot;-9px&amp;quot;  width=&amp;quot;100%&amp;quot; cellspacing='0' cellpadding='2' border='0'&amp;gt;&lt;br /&gt;
  &amp;lt;thead&amp;gt;&lt;br /&gt;
  &amp;lt;tr bgcolor='#CCCCCC'&amp;gt;&lt;br /&gt;
    &amp;lt;!-- class value decides whether the column should be sortable or not  --&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;30%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot;&amp;gt;Team &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;70%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot; &amp;gt;Reviewers/Metrics &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;/thead&amp;gt;&lt;br /&gt;
  &amp;lt;tbody&amp;gt;&lt;br /&gt;
  &amp;lt;% max_scores= max_assignment_review_score_per_round(@id) %&amp;gt;&lt;br /&gt;
  &amp;lt;%@reviewers.keys.each do |team_name| %&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td style=&amp;quot;padding-left: 50px;&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;% members = team_members(team_name, @id)%&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Name: &amp;lt;/strong&amp;gt;&amp;lt;%= team_name %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Members: &amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
	&amp;lt;% members.each do |member|%&amp;gt;&lt;br /&gt;
          &amp;lt;%=User.find(member.user_id).fullname %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;%= render 'review_conflict_metric' , team_name: team_name , max_scores: max_scores %&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Partial for the display for reviewers,scores and metrics&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot; border=&amp;quot;0&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;%question_answers = review_score_for_team(@id, team_name) %&amp;gt;&lt;br /&gt;
        &amp;lt;% i = 1 %&amp;gt;&lt;br /&gt;
        &amp;lt;% question_answers.each do |question_answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% average = average_of_round(question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% std = std_of_round(average,question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% upper_tolerance_limit = (average+(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;% lower_tolerance_limit = (average-(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;tr&amp;gt;&lt;br /&gt;
                &amp;lt;td width=&amp;quot;30%&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;strong&amp;gt;Reviewers with scores&amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
            &amp;lt;ol&amp;gt;&lt;br /&gt;
            &amp;lt;% question_answer.each do |reviewer, answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% if answer &amp;gt; upper_tolerance_limit or answer &amp;lt; lower_tolerance_limit  %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;mark style=&amp;quot;background-color:#FFFF00&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&amp;lt;/mark&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% else %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;/ol&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Max Review Score: &amp;lt;/strong&amp;gt;&amp;lt;%=max_scores[i-1]%&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Average Score: &amp;lt;/strong&amp;gt;&amp;lt;%=  average.to_s %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Standard Deviation: &amp;lt;/strong&amp;gt;&amp;lt;%=  std.to_s %&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;&amp;lt;u&amp;gt;&amp;lt;%= &amp;quot;Round: &amp;quot; + i.to_s %&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
          &amp;lt;%= generate_score_chart(max_scores[i-1], question_answer) %&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;% i+=1 %&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Sample view of the new report  -&lt;br /&gt;
[[File: Oodd report.PNG|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get all the answers(scores) for a reviewee on an assignment for a particular round &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.answers_by_round_for_reviewee(assignment_id, reviewee_id,round)&lt;br /&gt;
    #get all answers for a reviewee on an assignment for a particular round&lt;br /&gt;
    question_answers = Answer.select(&amp;quot;answers.answer, response_maps.reviewer_id&amp;quot;)&lt;br /&gt;
                          .joins(&amp;quot;join responses on responses.id = answers.response_id&amp;quot;)&lt;br /&gt;
                          .joins(&amp;quot;join response_maps on responses.map_id = response_maps.id&amp;quot;)&lt;br /&gt;
                          .where(&amp;quot;response_maps.reviewed_object_id = ? and&lt;br /&gt;
                                           response_maps.reviewee_id = ? and&lt;br /&gt;
                                           responses.round = ?&amp;quot;, assignment_id, reviewee_id,round)&lt;br /&gt;
    question_answers&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the maximum score for an assignment and for a particular round&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def max_score_of_assignment_per_round(assignment,round)&lt;br /&gt;
      rubric = get_questions_by_assignment(assignment)&lt;br /&gt;
      rubric_questions_used = rubric[assignment.varying_rubrics_by_round? ? round : 0]&lt;br /&gt;
      assignment_max_score_per_round = 0&lt;br /&gt;
      rubric_questions_used.each do |q|&lt;br /&gt;
        next if q.type.eql?(&amp;quot;SectionHeader&amp;quot;)&lt;br /&gt;
        q_max_score = get_max_score_for_question(q)&lt;br /&gt;
        assignment_max_score_per_round += q_max_score&lt;br /&gt;
      end&lt;br /&gt;
      assignment_max_score_per_round&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def max_assignment_review_score_per_round(reviewed_object_id)&lt;br /&gt;
      assignment = Assignment.find(reviewed_object_id)&lt;br /&gt;
      total_rounds = assignment.rounds_of_reviews&lt;br /&gt;
      review_max_scores = Array.new(total_rounds)&lt;br /&gt;
      (0..total_rounds-1).each do |round|&lt;br /&gt;
        review_max_scores[round] = SummaryHelper::Summary.new.max_score_of_assignment_per_round(assignment, round)&lt;br /&gt;
      end&lt;br /&gt;
      review_max_scores&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to create the bar chart showing the review scores per round&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def generate_score_chart(review_max_score, question_answer)&lt;br /&gt;
    scores = Array.new&lt;br /&gt;
    question_answer.each do |reviewer,answer|&lt;br /&gt;
      scores &amp;lt;&amp;lt; ((answer.to_f/review_max_score.to_f)*100).round(2)&lt;br /&gt;
    end&lt;br /&gt;
    labels = (1..scores.length).to_a&lt;br /&gt;
    data = {&lt;br /&gt;
        labels: labels,&lt;br /&gt;
        datasets: [&lt;br /&gt;
            {&lt;br /&gt;
                label: &amp;quot;score%&amp;quot;,&lt;br /&gt;
                backgroundColor: &amp;quot;rgba(255,99,132,0.8)&amp;quot;,&lt;br /&gt;
                borderWidth: 1,&lt;br /&gt;
                data: scores,&lt;br /&gt;
                hoverBackgroundColor: &amp;quot;orange&amp;quot;,&lt;br /&gt;
                yAxisID: &amp;quot;bar-y-axis1&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
    options = {&lt;br /&gt;
      legend: {&lt;br /&gt;
        position: 'top',&lt;br /&gt;
        labels: {&lt;br /&gt;
          usePointStyle: true&lt;br /&gt;
        }&lt;br /&gt;
      },&lt;br /&gt;
      width: &amp;quot;125&amp;quot;,&lt;br /&gt;
      height: &amp;quot;75&amp;quot;,&lt;br /&gt;
      scales: {&lt;br /&gt;
            yAxes: [{&lt;br /&gt;
                        stacked: true,&lt;br /&gt;
                        id: &amp;quot;bar-y-axis1&amp;quot;,&lt;br /&gt;
                        barThickness: 10&lt;br /&gt;
                    }, {&lt;br /&gt;
                        display: false,&lt;br /&gt;
                        stacked: true,&lt;br /&gt;
                        id: &amp;quot;bar-y-axis2&amp;quot;,&lt;br /&gt;
                        barThickness: 15,&lt;br /&gt;
                        type: 'category',&lt;br /&gt;
                        categoryPercentage: 0.8,&lt;br /&gt;
                        barPercentage: 0.9,&lt;br /&gt;
                        gridLines: {&lt;br /&gt;
                            offsetGridLines: true&lt;br /&gt;
                        }&lt;br /&gt;
                    }],&lt;br /&gt;
            xAxes: [{&lt;br /&gt;
                        stacked: false,&lt;br /&gt;
                        ticks: {	&lt;br /&gt;
			    beginAtZero: true,&lt;br /&gt;
                            stepSize: 10,&lt;br /&gt;
                            max: 100&lt;br /&gt;
                        }&lt;br /&gt;
                    }]&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    horizontal_bar_chart data, options&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the team members&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def team_members(team_name, assignment_id)&lt;br /&gt;
    team_id = Team.select(:id).where(name: team_name)&lt;br /&gt;
    members = TeamsUser.where(team_id: team_id)&lt;br /&gt;
    members&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to find the standard deviation&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def std_of_round(average,question_answer)&lt;br /&gt;
	accum=0.0&lt;br /&gt;
	i=0&lt;br /&gt;
        question_answer.each do |reviewer,answer|&lt;br /&gt;
		accum+=(answer-average)**2&lt;br /&gt;
		i+=1&lt;br /&gt;
	end&lt;br /&gt;
	if i != 0&lt;br /&gt;
		accum=Math.sqrt(accum/i)&lt;br /&gt;
	end &lt;br /&gt;
	accum.round(2)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to find the average score per round per team&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def average_of_round(question_answer)&lt;br /&gt;
	average=0.0&lt;br /&gt;
	i=0&lt;br /&gt;
	question_answer.each do |reviewer,answer|&lt;br /&gt;
		average+=answer&lt;br /&gt;
		i+=1&lt;br /&gt;
  	end&lt;br /&gt;
	if i != 0&lt;br /&gt;
		average=average/i&lt;br /&gt;
	end&lt;br /&gt;
	average.round(2)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the review score for each round of particular team&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def review_score_for_team(reviewed_object_id, team_name)&lt;br /&gt;
    question_answers=[]&lt;br /&gt;
    reviewee_id = Team.select(:id).where(name: team_name, parent_id: reviewed_object_id)&lt;br /&gt;
    reviewee_id.each do |reviewee|&lt;br /&gt;
      total_rounds = Assignment.find(reviewed_object_id).rounds_of_reviews&lt;br /&gt;
      question_answers = Array.new(total_rounds)&lt;br /&gt;
      (0..total_rounds-1).each do |round|&lt;br /&gt;
        temp_values = Answer.answers_by_round_for_reviewee(reviewed_object_id, reviewee,round+1)&lt;br /&gt;
	      question_answers[round] = review_score_helper_for_team(temp_values)&lt;br /&gt;
	    end&lt;br /&gt;
    end&lt;br /&gt;
    question_answers&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def review_score_helper_for_team(temp_values)&lt;br /&gt;
	question_answers={}&lt;br /&gt;
	temp_values.each do |temp_value|&lt;br /&gt;
          if question_answers.key?(temp_value[:reviewer_id])&lt;br /&gt;
            if temp_value[:answer].nil?&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] += 0&lt;br /&gt;
            else&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] += temp_value[:answer]&lt;br /&gt;
            end&lt;br /&gt;
          else&lt;br /&gt;
            if temp_value[:answer].nil?&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] = 0&lt;br /&gt;
            else&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] = temp_value[:answer]&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
	question_answers&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to create a response map for the reviewers and reviewee as well as the teams and the reviewee_id&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def review_conflict_response_map(params, _session = nil)&lt;br /&gt;
    assign_basics(params)&lt;br /&gt;
    teams = Team.select(:id, :name).where(parent_id: @id).order(:name)&lt;br /&gt;
    @teams = ({})&lt;br /&gt;
    @reviewers = ({})&lt;br /&gt;
    teams.each do |reviewee|&lt;br /&gt;
      @reviewers[reviewee.name] = reviewers_name_id_by_reviewee_and_assignment(reviewee, @id)&lt;br /&gt;
      @teams[reviewee.name] = reviewee.id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the reviewers of a particular assignment and particular reviewee&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def reviewers_name_id_by_reviewee_and_assignment(reviewee, id)&lt;br /&gt;
    temp_reviewers = User.select(&amp;quot; DISTINCT participants.id, users.name&amp;quot;)&lt;br /&gt;
                    .joins(&amp;quot;JOIN participants ON participants.user_id = users.id&amp;quot;)&lt;br /&gt;
                    .joins(&amp;quot;JOIN response_maps ON response_maps.reviewer_id = participants.id&amp;quot;)&lt;br /&gt;
                    .where(&amp;quot;response_maps.reviewee_id = ? and response_maps.reviewed_object_id = ?&amp;quot;, reviewee.id, id)&lt;br /&gt;
    reviewers = ({})&lt;br /&gt;
    temp_reviewers.each do |reviewer|&lt;br /&gt;
      reviewers[reviewer[:id].to_s] = reviewer[:name]&lt;br /&gt;
    end&lt;br /&gt;
    reviewers&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Feature 2:''' No hardcoded URLs &lt;br /&gt;
Hardcoded URLs are be managed by the config file in order to make these links functional on every server running Expertiza and raw URLs will be given some meaningful names.&lt;br /&gt;
&lt;br /&gt;
* Code changed for removing the hardcoded URLs&lt;br /&gt;
[[File:Harcord link.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we had done the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*UI testing for the new functionality&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
&lt;br /&gt;
All the existing related rspec tests have tested and they all passed wit 0 failures.&lt;br /&gt;
Majority of the new functionality concerns with the new view,so we have mainly done the UI testing shown below.Some of the Rspec test added are shown below:&lt;br /&gt;
&lt;br /&gt;
*Rspec Tests for Answer Model&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let(:response_map) { create(:review_response_map, id: 1, reviewed_object_id: 1, reviewer_id: 1) }&lt;br /&gt;
it &amp;quot;returns answers by reviewer for reviewee in round from db which is not empty&amp;quot; do&lt;br /&gt;
      expect(Answer.answers_by_round_for_reviewee(@assignment_id, @reviewee_id,@round)).not_to be_empty&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Rspec Tests for Report Formatter Helper methods&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe 'review_conflict_response_map' do&lt;br /&gt;
      context 'when type is ReviewConflictResponseMap' do&lt;br /&gt;
        it 'renders response_report page with corresponding data' do&lt;br /&gt;
          allow(Team).to receive(:where).with(parent_id: '1').and_return([integer('id')]).ordered&lt;br /&gt;
          params = {&lt;br /&gt;
              id: 1,&lt;br /&gt;
              report: {type: 'ReviewResponseMap'},&lt;br /&gt;
              user: 'no one'&lt;br /&gt;
          }&lt;br /&gt;
          get :response_report, params&lt;br /&gt;
          expect(response).to render_template(:response_report)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    describe &amp;quot;reviewers_name_id_by_reviewee_and_assignment&amp;quot; do&lt;br /&gt;
      before(:each) do&lt;br /&gt;
        @assignment_id = 1&lt;br /&gt;
        @reviewee_id = 1&lt;br /&gt;
      end&lt;br /&gt;
      it &amp;quot;returns reviewers name from Answer by reviewee ans assignment id from db which is not empty&amp;quot; do&lt;br /&gt;
        expect(allow(User).to receive(:where).with(@reviewee_id, @assignment_id).and_return([integer('id')])).not_to be_empty&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
&lt;br /&gt;
We have created a [https://cl.ly/ab6b9c8bac36 Demo Video] showing the new functionality.&lt;br /&gt;
&lt;br /&gt;
=Files changed in this Project=&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/controllers/response_controller.rb Response Controller]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/report_formatter_helper.rb Report Formatter Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/review_mapping_helper.rb Review Mapping Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/summary_helper.rb Summary Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/mailers/mailer.rb Mailer]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/models/answer.rb Answer model]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/models/response.rb Response Model]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/mailer/notify_grade_conflict_message.html.erb Notify Grade Conflict Message View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_conflict_metric.html.erb Review Conflict Metric View] (New Created)&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_conflict_report.html.erb Review Conflict Report View] (New Created)&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_report.html.erb Review Report View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_searchbox.html.erb Searchbox View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/response_report.html.haml Response Report View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/spec/controllers/reports_controller_spec.rb Reports Controller Spec]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/spec/models/answer_spec.rb Answer model spec]&lt;br /&gt;
&lt;br /&gt;
=Important Links=&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1445 Pull Request]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza Expertiza Github Repo]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
* [https://github.com/expertiza/expertiza expertiza]&lt;br /&gt;
* [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2018-_Project_E1865._Conflict_Notification Previous Work]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1329 Previous Pull Request]&lt;br /&gt;
* [https://rubygems.org/gems/standard-deviation/versions/0.1.1 Standard-Deviation gem]&lt;br /&gt;
* [https://github.com/jtescher/descriptive-statistics descriptive-statistics gem]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124616</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124616"/>
		<updated>2019-04-27T00:53:42Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, and it links to the review or submission which initiated the notification. It gives the link in raw HTML, but it should give it as a link associated with text, such as the text “this new review” linking to the page that shows the review.The email send to the instructor should also link to page that shows data on each of the reviews done on this team.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.With every review submitted for an assignment of a particular student, the average is updated.The mail sent to the instructor contains the links to the conflicted review and a summary of the reviews.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view exists to analyze the conflict report===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the reviews but there is no view where the instructor can see all the conflicts and analyze them.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which will contain links to the conflicting review, summary link, and a link to report which can be used for analyzing. The new report will have the information like the Team(having conflicts), the standard deviation for the team review score and pictorial representation of all the review scores. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The email sent to the instructor should link to a page that shows the data on each of the reviews done on this team:&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members (user-IDs and/or names)&lt;br /&gt;
* One line for each review received.In this line would be&lt;br /&gt;
# The name of the person (or team) that submitted the review, which would be hyperlinked to the review itself&lt;br /&gt;
# The score given for the review&lt;br /&gt;
# A bar chart showing pictorial view&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Review scores that are outside some “tolerance” limit should be highlighted, e.g., boldfaced or shown in a different color.Probably the tolerance should be, perhaps, one or two standard deviations from the mean.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
*'''Feature 1:''' New page to show the conflict report&lt;br /&gt;
A new view page of the report which will have the following information:-&amp;lt;br&amp;gt;&lt;br /&gt;
# The name of the team.&lt;br /&gt;
# The members of the team.&lt;br /&gt;
# The name of the reviewer which would be hyperlinked to the review itself.&lt;br /&gt;
# The score given for the review.&lt;br /&gt;
# A bar chart showing pictorial view of all the reviews for a particular team.&lt;br /&gt;
# The average score received from reviewers.&lt;br /&gt;
# The standard deviation of the score received from reviewers.&lt;br /&gt;
# Conflicting reviewers are highlighted.These are those which are two standard deviations away from the mean.&lt;br /&gt;
&lt;br /&gt;
This view have a report of all the teams on one page.This report link is added to the mail that is already being sent whenever some conflict happens.This report page will be also accessible from the reports drop-down in the instructor view.&lt;br /&gt;
 &lt;br /&gt;
*A new partial is created for this view -&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;color:green;text-align:adjust&amp;quot;&amp;gt;&lt;br /&gt;
  Note: &amp;lt;br&amp;gt;&lt;br /&gt;
  X- axis represents precentage score of the team&amp;lt;br&amp;gt;&lt;br /&gt;
  Y- axis represents the reviewers &amp;lt;br&amp;gt;&lt;br /&gt;
  Highlighted reviewers are outside the tolerance limit&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;table id=&amp;quot;myTable&amp;quot; border=&amp;quot;1px solid black&amp;quot; margin-top=&amp;quot;-9px&amp;quot;  width=&amp;quot;100%&amp;quot; cellspacing='0' cellpadding='2' border='0'&amp;gt;&lt;br /&gt;
  &amp;lt;thead&amp;gt;&lt;br /&gt;
  &amp;lt;tr bgcolor='#CCCCCC'&amp;gt;&lt;br /&gt;
    &amp;lt;!-- class value decides whether the column should be sortable or not  --&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;30%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot;&amp;gt;Team &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;70%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot; &amp;gt;Reviewers/Metrics &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;/thead&amp;gt;&lt;br /&gt;
  &amp;lt;tbody&amp;gt;&lt;br /&gt;
  &amp;lt;% max_scores= max_assignment_review_score_per_round(@id) %&amp;gt;&lt;br /&gt;
  &amp;lt;%@reviewers.keys.each do |team_name| %&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td style=&amp;quot;padding-left: 50px;&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;% members = team_members(team_name, @id)%&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Name: &amp;lt;/strong&amp;gt;&amp;lt;%= team_name %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Members: &amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
	&amp;lt;% members.each do |member|%&amp;gt;&lt;br /&gt;
          &amp;lt;%=User.find(member.user_id).fullname %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;%= render 'review_conflict_metric' , team_name: team_name , max_scores: max_scores %&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Partial for the display for reviewers,scores and metrics&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot; border=&amp;quot;0&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;%question_answers = review_score_for_team(@id, team_name) %&amp;gt;&lt;br /&gt;
        &amp;lt;% i = 1 %&amp;gt;&lt;br /&gt;
        &amp;lt;% question_answers.each do |question_answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% average = average_of_round(question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% std = std_of_round(average,question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% upper_tolerance_limit = (average+(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;% lower_tolerance_limit = (average-(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;tr&amp;gt;&lt;br /&gt;
                &amp;lt;td width=&amp;quot;30%&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;strong&amp;gt;Reviewers with scores&amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
            &amp;lt;ol&amp;gt;&lt;br /&gt;
            &amp;lt;% question_answer.each do |reviewer, answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% if answer &amp;gt; upper_tolerance_limit or answer &amp;lt; lower_tolerance_limit  %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;mark style=&amp;quot;background-color:#FFFF00&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&amp;lt;/mark&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% else %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;/ol&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Max Review Score: &amp;lt;/strong&amp;gt;&amp;lt;%=max_scores[i-1]%&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Average Score: &amp;lt;/strong&amp;gt;&amp;lt;%=  average.to_s %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Standard Deviation: &amp;lt;/strong&amp;gt;&amp;lt;%=  std.to_s %&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;&amp;lt;u&amp;gt;&amp;lt;%= &amp;quot;Round: &amp;quot; + i.to_s %&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
          &amp;lt;%= generate_score_chart(max_scores[i-1], question_answer) %&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;% i+=1 %&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Sample view of the new report  -&lt;br /&gt;
[[File: Oodd report.PNG|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get all the answers(scores) for a reviewee on an assignment for a particular round &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.answers_by_round_for_reviewee(assignment_id, reviewee_id,round)&lt;br /&gt;
    #get all answers for a reviewee on an assignment for a particular round&lt;br /&gt;
    question_answers = Answer.select(&amp;quot;answers.answer, response_maps.reviewer_id&amp;quot;)&lt;br /&gt;
                          .joins(&amp;quot;join responses on responses.id = answers.response_id&amp;quot;)&lt;br /&gt;
                          .joins(&amp;quot;join response_maps on responses.map_id = response_maps.id&amp;quot;)&lt;br /&gt;
                          .where(&amp;quot;response_maps.reviewed_object_id = ? and&lt;br /&gt;
                                           response_maps.reviewee_id = ? and&lt;br /&gt;
                                           responses.round = ?&amp;quot;, assignment_id, reviewee_id,round)&lt;br /&gt;
    question_answers&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the maximum score for an assignment and for a particular round&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def max_score_of_assignment_per_round(assignment,round)&lt;br /&gt;
      rubric = get_questions_by_assignment(assignment)&lt;br /&gt;
      rubric_questions_used = rubric[assignment.varying_rubrics_by_round? ? round : 0]&lt;br /&gt;
      assignment_max_score_per_round = 0&lt;br /&gt;
      rubric_questions_used.each do |q|&lt;br /&gt;
        next if q.type.eql?(&amp;quot;SectionHeader&amp;quot;)&lt;br /&gt;
        q_max_score = get_max_score_for_question(q)&lt;br /&gt;
        assignment_max_score_per_round += q_max_score&lt;br /&gt;
      end&lt;br /&gt;
      assignment_max_score_per_round&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def max_assignment_review_score_per_round(reviewed_object_id)&lt;br /&gt;
      assignment = Assignment.find(reviewed_object_id)&lt;br /&gt;
      total_rounds = assignment.rounds_of_reviews&lt;br /&gt;
      review_max_scores = Array.new(total_rounds)&lt;br /&gt;
      (0..total_rounds-1).each do |round|&lt;br /&gt;
        review_max_scores[round] = SummaryHelper::Summary.new.max_score_of_assignment_per_round(assignment, round)&lt;br /&gt;
      end&lt;br /&gt;
      review_max_scores&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to create the bar chart showing the review scores per round&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def generate_score_chart(review_max_score, question_answer)&lt;br /&gt;
    scores = Array.new&lt;br /&gt;
    question_answer.each do |reviewer,answer|&lt;br /&gt;
      scores &amp;lt;&amp;lt; ((answer.to_f/review_max_score.to_f)*100).round(2)&lt;br /&gt;
    end&lt;br /&gt;
    labels = (1..scores.length).to_a&lt;br /&gt;
    data = {&lt;br /&gt;
        labels: labels,&lt;br /&gt;
        datasets: [&lt;br /&gt;
            {&lt;br /&gt;
                label: &amp;quot;score%&amp;quot;,&lt;br /&gt;
                backgroundColor: &amp;quot;rgba(255,99,132,0.8)&amp;quot;,&lt;br /&gt;
                borderWidth: 1,&lt;br /&gt;
                data: scores,&lt;br /&gt;
                hoverBackgroundColor: &amp;quot;orange&amp;quot;,&lt;br /&gt;
                yAxisID: &amp;quot;bar-y-axis1&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
    options = {&lt;br /&gt;
      legend: {&lt;br /&gt;
        position: 'top',&lt;br /&gt;
        labels: {&lt;br /&gt;
          usePointStyle: true&lt;br /&gt;
        }&lt;br /&gt;
      },&lt;br /&gt;
      width: &amp;quot;125&amp;quot;,&lt;br /&gt;
      height: &amp;quot;75&amp;quot;,&lt;br /&gt;
      scales: {&lt;br /&gt;
            yAxes: [{&lt;br /&gt;
                        stacked: true,&lt;br /&gt;
                        id: &amp;quot;bar-y-axis1&amp;quot;,&lt;br /&gt;
                        barThickness: 10&lt;br /&gt;
                    }, {&lt;br /&gt;
                        display: false,&lt;br /&gt;
                        stacked: true,&lt;br /&gt;
                        id: &amp;quot;bar-y-axis2&amp;quot;,&lt;br /&gt;
                        barThickness: 15,&lt;br /&gt;
                        type: 'category',&lt;br /&gt;
                        categoryPercentage: 0.8,&lt;br /&gt;
                        barPercentage: 0.9,&lt;br /&gt;
                        gridLines: {&lt;br /&gt;
                            offsetGridLines: true&lt;br /&gt;
                        }&lt;br /&gt;
                    }],&lt;br /&gt;
            xAxes: [{&lt;br /&gt;
                        stacked: false,&lt;br /&gt;
                        ticks: {	&lt;br /&gt;
			    beginAtZero: true,&lt;br /&gt;
                            stepSize: 10,&lt;br /&gt;
                            max: 100&lt;br /&gt;
                        }&lt;br /&gt;
                    }]&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    horizontal_bar_chart data, options&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the team members&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def team_members(team_name, assignment_id)&lt;br /&gt;
    team_id = Team.select(:id).where(name: team_name)&lt;br /&gt;
    members = TeamsUser.where(team_id: team_id)&lt;br /&gt;
    members&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to find the standard deviation&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def std_of_round(average,question_answer)&lt;br /&gt;
	accum=0.0&lt;br /&gt;
	i=0&lt;br /&gt;
        question_answer.each do |reviewer,answer|&lt;br /&gt;
		accum+=(answer-average)**2&lt;br /&gt;
		i+=1&lt;br /&gt;
	end&lt;br /&gt;
	if i != 0&lt;br /&gt;
		accum=Math.sqrt(accum/i)&lt;br /&gt;
	end &lt;br /&gt;
	accum.round(2)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to find the average score per round per team&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def average_of_round(question_answer)&lt;br /&gt;
	average=0.0&lt;br /&gt;
	i=0&lt;br /&gt;
	question_answer.each do |reviewer,answer|&lt;br /&gt;
		average+=answer&lt;br /&gt;
		i+=1&lt;br /&gt;
  	end&lt;br /&gt;
	if i != 0&lt;br /&gt;
		average=average/i&lt;br /&gt;
	end&lt;br /&gt;
	average.round(2)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the review score for each round of particular team&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def review_score_for_team(reviewed_object_id, team_name)&lt;br /&gt;
    question_answers=[]&lt;br /&gt;
    reviewee_id = Team.select(:id).where(name: team_name, parent_id: reviewed_object_id)&lt;br /&gt;
    reviewee_id.each do |reviewee|&lt;br /&gt;
      total_rounds = Assignment.find(reviewed_object_id).rounds_of_reviews&lt;br /&gt;
      question_answers = Array.new(total_rounds)&lt;br /&gt;
      (0..total_rounds-1).each do |round|&lt;br /&gt;
        temp_values = Answer.answers_by_round_for_reviewee(reviewed_object_id, reviewee,round+1)&lt;br /&gt;
	      question_answers[round] = review_score_helper_for_team(temp_values)&lt;br /&gt;
	    end&lt;br /&gt;
    end&lt;br /&gt;
    question_answers&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def review_score_helper_for_team(temp_values)&lt;br /&gt;
	question_answers={}&lt;br /&gt;
	temp_values.each do |temp_value|&lt;br /&gt;
          if question_answers.key?(temp_value[:reviewer_id])&lt;br /&gt;
            if temp_value[:answer].nil?&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] += 0&lt;br /&gt;
            else&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] += temp_value[:answer]&lt;br /&gt;
            end&lt;br /&gt;
          else&lt;br /&gt;
            if temp_value[:answer].nil?&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] = 0&lt;br /&gt;
            else&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] = temp_value[:answer]&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
	question_answers&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to create a response map for the reviewers and reviewee as well as the teams and the reviewee_id&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def review_conflict_response_map(params, _session = nil)&lt;br /&gt;
    assign_basics(params)&lt;br /&gt;
    teams = Team.select(:id, :name).where(parent_id: @id).order(:name)&lt;br /&gt;
    @teams = ({})&lt;br /&gt;
    @reviewers = ({})&lt;br /&gt;
    teams.each do |reviewee|&lt;br /&gt;
      @reviewers[reviewee.name] = reviewers_name_id_by_reviewee_and_assignment(reviewee, @id)&lt;br /&gt;
      @teams[reviewee.name] = reviewee.id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the reviewers of a particular assignment and particular reviewee&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def reviewers_name_id_by_reviewee_and_assignment(reviewee, id)&lt;br /&gt;
    temp_reviewers = User.select(&amp;quot; DISTINCT participants.id, users.name&amp;quot;)&lt;br /&gt;
                    .joins(&amp;quot;JOIN participants ON participants.user_id = users.id&amp;quot;)&lt;br /&gt;
                    .joins(&amp;quot;JOIN response_maps ON response_maps.reviewer_id = participants.id&amp;quot;)&lt;br /&gt;
                    .where(&amp;quot;response_maps.reviewee_id = ? and response_maps.reviewed_object_id = ?&amp;quot;, reviewee.id, id)&lt;br /&gt;
    reviewers = ({})&lt;br /&gt;
    temp_reviewers.each do |reviewer|&lt;br /&gt;
      reviewers[reviewer[:id].to_s] = reviewer[:name]&lt;br /&gt;
    end&lt;br /&gt;
    reviewers&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Feature 2:''' No hardcoded URLs &lt;br /&gt;
Hardcoded URLs are be managed by the config file in order to make these links functional on every server running Expertiza and raw URLs will be given some meaningful names.&lt;br /&gt;
&lt;br /&gt;
* Code changed for removing the hardcoded URLs&lt;br /&gt;
[[File:Harcord link.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we had done the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*UI testing for the new functionality&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
&lt;br /&gt;
All the existing related rspec tests have tested and they all passed wit 0 failures.&lt;br /&gt;
Majority of the new functionality concerns with the new view,so we have mainly done the UI testing shown below.Some of the Rspec test added are shown below:&lt;br /&gt;
&lt;br /&gt;
*Rspec Tests for Answer Model&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let(:response_map) { create(:review_response_map, id: 1, reviewed_object_id: 1, reviewer_id: 1) }&lt;br /&gt;
it &amp;quot;returns answers by reviewer for reviewee in round from db which is not empty&amp;quot; do&lt;br /&gt;
      expect(Answer.answers_by_round_for_reviewee(@assignment_id, @reviewee_id,@round)).not_to be_empty&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Rspec Tests for Report Formatter Helper methods&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe 'review_conflict_response_map' do&lt;br /&gt;
      context 'when type is ReviewConflictResponseMap' do&lt;br /&gt;
        it 'renders response_report page with corresponding data' do&lt;br /&gt;
          allow(Team).to receive(:where).with(parent_id: '1').and_return([integer('id')]).ordered&lt;br /&gt;
          params = {&lt;br /&gt;
              id: 1,&lt;br /&gt;
              report: {type: 'ReviewResponseMap'},&lt;br /&gt;
              user: 'no one'&lt;br /&gt;
          }&lt;br /&gt;
          get :response_report, params&lt;br /&gt;
          expect(response).to render_template(:response_report)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    describe &amp;quot;reviewers_name_id_by_reviewee_and_assignment&amp;quot; do&lt;br /&gt;
      before(:each) do&lt;br /&gt;
        @assignment_id = 1&lt;br /&gt;
        @reviewee_id = 1&lt;br /&gt;
      end&lt;br /&gt;
      it &amp;quot;returns reviewers name from Answer by reviewee ans assignment id from db which is not empty&amp;quot; do&lt;br /&gt;
        expect(allow(User).to receive(:where).with(@reviewee_id, @assignment_id).and_return([integer('id')])).not_to be_empty&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
&lt;br /&gt;
We have created a [https://cl.ly/ab6b9c8bac36 Demo Video] showing the new functionality.&lt;br /&gt;
&lt;br /&gt;
=Files changed in this Project=&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/controllers/response_controller.rb Response Controller]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/report_formatter_helper.rb Report Formatter Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/review_mapping_helper.rb Review Mapping Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/summary_helper.rb Summary Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/mailers/mailer.rb Mailer]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/models/answer.rb Answer model]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/models/response.rb Response Model]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/mailer/notify_grade_conflict_message.html.erb Notify Grade Conflict Message View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_conflict_metric.html.erb Review Conflict Metric View] (New Created)&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_conflict_report.html.erb Review Conflict Report View] (New Created)&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_report.html.erb Review Report View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_searchbox.html.erb Searchbox View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/response_report.html.haml Response Report View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/spec/controllers/reports_controller_spec.rb Reports Controller Spec]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/spec/models/answer_spec.rb Answer model spec]&lt;br /&gt;
&lt;br /&gt;
=Important Links=&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1445 Pull Request]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza Expertiza Github]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
* [https://github.com/expertiza/expertiza expertiza]&lt;br /&gt;
* [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2018-_Project_E1865._Conflict_Notification Previous Work]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1329 Previous Pull Request]&lt;br /&gt;
* [https://rubygems.org/gems/standard-deviation/versions/0.1.1 Standard-Deviation gem]&lt;br /&gt;
* [https://github.com/jtescher/descriptive-statistics descriptive-statistics gem]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124609</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124609"/>
		<updated>2019-04-27T00:39:18Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: /* UI Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, and it links to the review or submission which initiated the notification. It gives the link in raw HTML, but it should give it as a link associated with text, such as the text “this new review” linking to the page that shows the review.The email send to the instructor should also link to page that shows data on each of the reviews done on this team.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.With every review submitted for an assignment of a particular student, the average is updated.The mail sent to the instructor contains the links to the conflicted review and a summary of the reviews.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view exists to analyze the conflict report===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the reviews but there is no view where the instructor can see all the conflicts and analyze them.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which will contain links to the conflicting review, summary link, and a link to report which can be used for analyzing. The new report will have the information like the Team(having conflicts), the standard deviation for the team review score and pictorial representation of all the review scores. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The email sent to the instructor should link to a page that shows the data on each of the reviews done on this team:&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members (user-IDs and/or names)&lt;br /&gt;
* One line for each review received.In this line would be&lt;br /&gt;
# The name of the person (or team) that submitted the review, which would be hyperlinked to the review itself&lt;br /&gt;
# The score given for the review&lt;br /&gt;
# A bar chart showing pictorial view&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Review scores that are outside some “tolerance” limit should be highlighted, e.g., boldfaced or shown in a different color.Probably the tolerance should be, perhaps, one or two standard deviations from the mean.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
*'''Feature 1:''' New page to show the conflict report&lt;br /&gt;
A new view page of the report which will have the following information:-&amp;lt;br&amp;gt;&lt;br /&gt;
# The name of the team.&lt;br /&gt;
# The members of the team.&lt;br /&gt;
# The name of the reviewer which would be hyperlinked to the review itself.&lt;br /&gt;
# The score given for the review.&lt;br /&gt;
# A bar chart showing pictorial view of all the reviews for a particular team.&lt;br /&gt;
# The average score received from reviewers.&lt;br /&gt;
# The standard deviation of the score received from reviewers.&lt;br /&gt;
# Conflicting reviewers are highlighted.These are those which are two standard deviations away from the mean.&lt;br /&gt;
&lt;br /&gt;
This view have a report of all the teams on one page.This report link is added to the mail that is already being sent whenever some conflict happens.This report page will be also accessible from the reports drop-down in the instructor view.&lt;br /&gt;
 &lt;br /&gt;
*A new partial is created for this view -&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;color:green;text-align:adjust&amp;quot;&amp;gt;&lt;br /&gt;
  Note: &amp;lt;br&amp;gt;&lt;br /&gt;
  X- axis represents precentage score of the team&amp;lt;br&amp;gt;&lt;br /&gt;
  Y- axis represents the reviewers &amp;lt;br&amp;gt;&lt;br /&gt;
  Highlighted reviewers are outside the tolerance limit&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;table id=&amp;quot;myTable&amp;quot; border=&amp;quot;1px solid black&amp;quot; margin-top=&amp;quot;-9px&amp;quot;  width=&amp;quot;100%&amp;quot; cellspacing='0' cellpadding='2' border='0'&amp;gt;&lt;br /&gt;
  &amp;lt;thead&amp;gt;&lt;br /&gt;
  &amp;lt;tr bgcolor='#CCCCCC'&amp;gt;&lt;br /&gt;
    &amp;lt;!-- class value decides whether the column should be sortable or not  --&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;30%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot;&amp;gt;Team &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;70%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot; &amp;gt;Reviewers/Metrics &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;/thead&amp;gt;&lt;br /&gt;
  &amp;lt;tbody&amp;gt;&lt;br /&gt;
  &amp;lt;% max_scores= max_assignment_review_score_per_round(@id) %&amp;gt;&lt;br /&gt;
  &amp;lt;%@reviewers.keys.each do |team_name| %&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td style=&amp;quot;padding-left: 50px;&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;% members = team_members(team_name, @id)%&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Name: &amp;lt;/strong&amp;gt;&amp;lt;%= team_name %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Members: &amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
	&amp;lt;% members.each do |member|%&amp;gt;&lt;br /&gt;
          &amp;lt;%=User.find(member.user_id).fullname %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;%= render 'review_conflict_metric' , team_name: team_name , max_scores: max_scores %&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Partial for the display for reviewers,scores and metrics&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot; border=&amp;quot;0&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;%question_answers = review_score_for_team(@id, team_name) %&amp;gt;&lt;br /&gt;
        &amp;lt;% i = 1 %&amp;gt;&lt;br /&gt;
        &amp;lt;% question_answers.each do |question_answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% average = average_of_round(question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% std = std_of_round(average,question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% upper_tolerance_limit = (average+(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;% lower_tolerance_limit = (average-(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;tr&amp;gt;&lt;br /&gt;
                &amp;lt;td width=&amp;quot;30%&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;strong&amp;gt;Reviewers with scores&amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
            &amp;lt;ol&amp;gt;&lt;br /&gt;
            &amp;lt;% question_answer.each do |reviewer, answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% if answer &amp;gt; upper_tolerance_limit or answer &amp;lt; lower_tolerance_limit  %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;mark style=&amp;quot;background-color:#FFFF00&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&amp;lt;/mark&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% else %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;/ol&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Max Review Score: &amp;lt;/strong&amp;gt;&amp;lt;%=max_scores[i-1]%&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Average Score: &amp;lt;/strong&amp;gt;&amp;lt;%=  average.to_s %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Standard Deviation: &amp;lt;/strong&amp;gt;&amp;lt;%=  std.to_s %&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;&amp;lt;u&amp;gt;&amp;lt;%= &amp;quot;Round: &amp;quot; + i.to_s %&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
          &amp;lt;%= generate_score_chart(max_scores[i-1], question_answer) %&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;% i+=1 %&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Sample view of the new report  -&lt;br /&gt;
[[File: Oodd report.PNG|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get all the answers(scores) for a reviewee on an assignment for a particular round &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.answers_by_round_for_reviewee(assignment_id, reviewee_id,round)&lt;br /&gt;
    #get all answers for a reviewee on an assignment for a particular round&lt;br /&gt;
    question_answers = Answer.select(&amp;quot;answers.answer, response_maps.reviewer_id&amp;quot;)&lt;br /&gt;
                          .joins(&amp;quot;join responses on responses.id = answers.response_id&amp;quot;)&lt;br /&gt;
                          .joins(&amp;quot;join response_maps on responses.map_id = response_maps.id&amp;quot;)&lt;br /&gt;
                          .where(&amp;quot;response_maps.reviewed_object_id = ? and&lt;br /&gt;
                                           response_maps.reviewee_id = ? and&lt;br /&gt;
                                           responses.round = ?&amp;quot;, assignment_id, reviewee_id,round)&lt;br /&gt;
    question_answers&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the maximum score for an assignment and for a particular round&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def max_score_of_assignment_per_round(assignment,round)&lt;br /&gt;
      rubric = get_questions_by_assignment(assignment)&lt;br /&gt;
      rubric_questions_used = rubric[assignment.varying_rubrics_by_round? ? round : 0]&lt;br /&gt;
      assignment_max_score_per_round = 0&lt;br /&gt;
      rubric_questions_used.each do |q|&lt;br /&gt;
        next if q.type.eql?(&amp;quot;SectionHeader&amp;quot;)&lt;br /&gt;
        q_max_score = get_max_score_for_question(q)&lt;br /&gt;
        assignment_max_score_per_round += q_max_score&lt;br /&gt;
      end&lt;br /&gt;
      assignment_max_score_per_round&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def max_assignment_review_score_per_round(reviewed_object_id)&lt;br /&gt;
      assignment = Assignment.find(reviewed_object_id)&lt;br /&gt;
      total_rounds = assignment.rounds_of_reviews&lt;br /&gt;
      review_max_scores = Array.new(total_rounds)&lt;br /&gt;
      (0..total_rounds-1).each do |round|&lt;br /&gt;
        review_max_scores[round] = SummaryHelper::Summary.new.max_score_of_assignment_per_round(assignment, round)&lt;br /&gt;
      end&lt;br /&gt;
      review_max_scores&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to create the bar chart showing the review scores per round&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def generate_score_chart(review_max_score, question_answer)&lt;br /&gt;
    scores = Array.new&lt;br /&gt;
    question_answer.each do |reviewer,answer|&lt;br /&gt;
      scores &amp;lt;&amp;lt; ((answer.to_f/review_max_score.to_f)*100).round(2)&lt;br /&gt;
    end&lt;br /&gt;
    labels = (1..scores.length).to_a&lt;br /&gt;
    data = {&lt;br /&gt;
        labels: labels,&lt;br /&gt;
        datasets: [&lt;br /&gt;
            {&lt;br /&gt;
                label: &amp;quot;score%&amp;quot;,&lt;br /&gt;
                backgroundColor: &amp;quot;rgba(255,99,132,0.8)&amp;quot;,&lt;br /&gt;
                borderWidth: 1,&lt;br /&gt;
                data: scores,&lt;br /&gt;
                hoverBackgroundColor: &amp;quot;orange&amp;quot;,&lt;br /&gt;
                yAxisID: &amp;quot;bar-y-axis1&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
    options = {&lt;br /&gt;
      legend: {&lt;br /&gt;
        position: 'top',&lt;br /&gt;
        labels: {&lt;br /&gt;
          usePointStyle: true&lt;br /&gt;
        }&lt;br /&gt;
      },&lt;br /&gt;
      width: &amp;quot;125&amp;quot;,&lt;br /&gt;
      height: &amp;quot;75&amp;quot;,&lt;br /&gt;
      scales: {&lt;br /&gt;
            yAxes: [{&lt;br /&gt;
                        stacked: true,&lt;br /&gt;
                        id: &amp;quot;bar-y-axis1&amp;quot;,&lt;br /&gt;
                        barThickness: 10&lt;br /&gt;
                    }, {&lt;br /&gt;
                        display: false,&lt;br /&gt;
                        stacked: true,&lt;br /&gt;
                        id: &amp;quot;bar-y-axis2&amp;quot;,&lt;br /&gt;
                        barThickness: 15,&lt;br /&gt;
                        type: 'category',&lt;br /&gt;
                        categoryPercentage: 0.8,&lt;br /&gt;
                        barPercentage: 0.9,&lt;br /&gt;
                        gridLines: {&lt;br /&gt;
                            offsetGridLines: true&lt;br /&gt;
                        }&lt;br /&gt;
                    }],&lt;br /&gt;
            xAxes: [{&lt;br /&gt;
                        stacked: false,&lt;br /&gt;
                        ticks: {	&lt;br /&gt;
			    beginAtZero: true,&lt;br /&gt;
                            stepSize: 10,&lt;br /&gt;
                            max: 100&lt;br /&gt;
                        }&lt;br /&gt;
                    }]&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    horizontal_bar_chart data, options&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the team members&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def team_members(team_name, assignment_id)&lt;br /&gt;
    team_id = Team.select(:id).where(name: team_name)&lt;br /&gt;
    members = TeamsUser.where(team_id: team_id)&lt;br /&gt;
    members&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to find the standard deviation&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def std_of_round(average,question_answer)&lt;br /&gt;
	accum=0.0&lt;br /&gt;
	i=0&lt;br /&gt;
        question_answer.each do |reviewer,answer|&lt;br /&gt;
		accum+=(answer-average)**2&lt;br /&gt;
		i+=1&lt;br /&gt;
	end&lt;br /&gt;
	if i != 0&lt;br /&gt;
		accum=Math.sqrt(accum/i)&lt;br /&gt;
	end &lt;br /&gt;
	accum.round(2)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to find the average score per round per team&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def average_of_round(question_answer)&lt;br /&gt;
	average=0.0&lt;br /&gt;
	i=0&lt;br /&gt;
	question_answer.each do |reviewer,answer|&lt;br /&gt;
		average+=answer&lt;br /&gt;
		i+=1&lt;br /&gt;
  	end&lt;br /&gt;
	if i != 0&lt;br /&gt;
		average=average/i&lt;br /&gt;
	end&lt;br /&gt;
	average.round(2)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the review score for each round of particular team&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def review_score_for_team(reviewed_object_id, team_name)&lt;br /&gt;
    question_answers=[]&lt;br /&gt;
    reviewee_id = Team.select(:id).where(name: team_name, parent_id: reviewed_object_id)&lt;br /&gt;
    reviewee_id.each do |reviewee|&lt;br /&gt;
      total_rounds = Assignment.find(reviewed_object_id).rounds_of_reviews&lt;br /&gt;
      question_answers = Array.new(total_rounds)&lt;br /&gt;
      (0..total_rounds-1).each do |round|&lt;br /&gt;
        temp_values = Answer.answers_by_round_for_reviewee(reviewed_object_id, reviewee,round+1)&lt;br /&gt;
	      question_answers[round] = review_score_helper_for_team(temp_values)&lt;br /&gt;
	    end&lt;br /&gt;
    end&lt;br /&gt;
    question_answers&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def review_score_helper_for_team(temp_values)&lt;br /&gt;
	question_answers={}&lt;br /&gt;
	temp_values.each do |temp_value|&lt;br /&gt;
          if question_answers.key?(temp_value[:reviewer_id])&lt;br /&gt;
            if temp_value[:answer].nil?&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] += 0&lt;br /&gt;
            else&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] += temp_value[:answer]&lt;br /&gt;
            end&lt;br /&gt;
          else&lt;br /&gt;
            if temp_value[:answer].nil?&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] = 0&lt;br /&gt;
            else&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] = temp_value[:answer]&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
	question_answers&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to create a response map for the reviewers and reviewee as well as the teams and the reviewee_id&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def review_conflict_response_map(params, _session = nil)&lt;br /&gt;
    assign_basics(params)&lt;br /&gt;
    teams = Team.select(:id, :name).where(parent_id: @id).order(:name)&lt;br /&gt;
    @teams = ({})&lt;br /&gt;
    @reviewers = ({})&lt;br /&gt;
    teams.each do |reviewee|&lt;br /&gt;
      @reviewers[reviewee.name] = reviewers_name_id_by_reviewee_and_assignment(reviewee, @id)&lt;br /&gt;
      @teams[reviewee.name] = reviewee.id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the reviewers of a particular assignment and particular reviewee&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def reviewers_name_id_by_reviewee_and_assignment(reviewee, id)&lt;br /&gt;
    temp_reviewers = User.select(&amp;quot; DISTINCT participants.id, users.name&amp;quot;)&lt;br /&gt;
                    .joins(&amp;quot;JOIN participants ON participants.user_id = users.id&amp;quot;)&lt;br /&gt;
                    .joins(&amp;quot;JOIN response_maps ON response_maps.reviewer_id = participants.id&amp;quot;)&lt;br /&gt;
                    .where(&amp;quot;response_maps.reviewee_id = ? and response_maps.reviewed_object_id = ?&amp;quot;, reviewee.id, id)&lt;br /&gt;
    reviewers = ({})&lt;br /&gt;
    temp_reviewers.each do |reviewer|&lt;br /&gt;
      reviewers[reviewer[:id].to_s] = reviewer[:name]&lt;br /&gt;
    end&lt;br /&gt;
    reviewers&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Feature 2:''' No hardcoded URLs &lt;br /&gt;
Hardcoded URLs are be managed by the config file in order to make these links functional on every server running Expertiza and raw URLs will be given some meaningful names.&lt;br /&gt;
&lt;br /&gt;
* Code changed for removing the hardcoded URLs&lt;br /&gt;
[[File:Harcord link.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we had done the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*UI testing for the new functionality&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
&lt;br /&gt;
All the existing related rspec tests have tested and they all passed wit 0 failures.&lt;br /&gt;
Majority of the new functionality concerns with the new view,so we have mainly done the UI testing shown below.Some of the Rspec test added are shown below:&lt;br /&gt;
&lt;br /&gt;
*Rspec Tests for Answer Model&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let(:response_map) { create(:review_response_map, id: 1, reviewed_object_id: 1, reviewer_id: 1) }&lt;br /&gt;
it &amp;quot;returns answers by reviewer for reviewee in round from db which is not empty&amp;quot; do&lt;br /&gt;
      expect(Answer.answers_by_round_for_reviewee(@assignment_id, @reviewee_id,@round)).not_to be_empty&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Rspec Tests for Report Formatter Helper methods&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe 'review_conflict_response_map' do&lt;br /&gt;
      context 'when type is ReviewConflictResponseMap' do&lt;br /&gt;
        it 'renders response_report page with corresponding data' do&lt;br /&gt;
          allow(Team).to receive(:where).with(parent_id: '1').and_return([integer('id')]).ordered&lt;br /&gt;
          params = {&lt;br /&gt;
              id: 1,&lt;br /&gt;
              report: {type: 'ReviewResponseMap'},&lt;br /&gt;
              user: 'no one'&lt;br /&gt;
          }&lt;br /&gt;
          get :response_report, params&lt;br /&gt;
          expect(response).to render_template(:response_report)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    describe &amp;quot;reviewers_name_id_by_reviewee_and_assignment&amp;quot; do&lt;br /&gt;
      before(:each) do&lt;br /&gt;
        @assignment_id = 1&lt;br /&gt;
        @reviewee_id = 1&lt;br /&gt;
      end&lt;br /&gt;
      it &amp;quot;returns reviewers name from Answer by reviewee ans assignment id from db which is not empty&amp;quot; do&lt;br /&gt;
        expect(allow(User).to receive(:where).with(@reviewee_id, @assignment_id).and_return([integer('id')])).not_to be_empty&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
&lt;br /&gt;
We have created a [https://cl.ly/ab6b9c8bac36 Demo Video] showing the new functionality.&lt;br /&gt;
&lt;br /&gt;
=Files changed in this Project=&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/controllers/response_controller.rb Response Controller]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/report_formatter_helper.rb Report Formatter Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/review_mapping_helper.rb Review Mapping Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/summary_helper.rb Summary Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/mailers/mailer.rb Mailer]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/models/answer.rb Answer model]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/models/response.rb Response Model]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/mailer/notify_grade_conflict_message.html.erb Notify Grade Conflict Message View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_conflict_metric.html.erb Review Conflict Metric View] (New Created)&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_conflict_report.html.erb Review Conflict Report View] (New Created)&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_report.html.erb Review Report View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_searchbox.html.erb Searchbox View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/response_report.html.haml Response Report View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/spec/controllers/reports_controller_spec.rb Reports Controller Spec]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/spec/models/answer_spec.rb Answer model spec]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
* [https://github.com/expertiza/expertiza expertiza]&lt;br /&gt;
* [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2018-_Project_E1865._Conflict_Notification Previous Work]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1329 Previous Pull Request]&lt;br /&gt;
* [https://rubygems.org/gems/standard-deviation/versions/0.1.1 Standard-Deviation gem]&lt;br /&gt;
* [https://github.com/jtescher/descriptive-statistics descriptive-statistics gem]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124608</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124608"/>
		<updated>2019-04-27T00:38:53Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: /* UI Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, and it links to the review or submission which initiated the notification. It gives the link in raw HTML, but it should give it as a link associated with text, such as the text “this new review” linking to the page that shows the review.The email send to the instructor should also link to page that shows data on each of the reviews done on this team.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.With every review submitted for an assignment of a particular student, the average is updated.The mail sent to the instructor contains the links to the conflicted review and a summary of the reviews.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view exists to analyze the conflict report===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the reviews but there is no view where the instructor can see all the conflicts and analyze them.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which will contain links to the conflicting review, summary link, and a link to report which can be used for analyzing. The new report will have the information like the Team(having conflicts), the standard deviation for the team review score and pictorial representation of all the review scores. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The email sent to the instructor should link to a page that shows the data on each of the reviews done on this team:&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members (user-IDs and/or names)&lt;br /&gt;
* One line for each review received.In this line would be&lt;br /&gt;
# The name of the person (or team) that submitted the review, which would be hyperlinked to the review itself&lt;br /&gt;
# The score given for the review&lt;br /&gt;
# A bar chart showing pictorial view&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Review scores that are outside some “tolerance” limit should be highlighted, e.g., boldfaced or shown in a different color.Probably the tolerance should be, perhaps, one or two standard deviations from the mean.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
*'''Feature 1:''' New page to show the conflict report&lt;br /&gt;
A new view page of the report which will have the following information:-&amp;lt;br&amp;gt;&lt;br /&gt;
# The name of the team.&lt;br /&gt;
# The members of the team.&lt;br /&gt;
# The name of the reviewer which would be hyperlinked to the review itself.&lt;br /&gt;
# The score given for the review.&lt;br /&gt;
# A bar chart showing pictorial view of all the reviews for a particular team.&lt;br /&gt;
# The average score received from reviewers.&lt;br /&gt;
# The standard deviation of the score received from reviewers.&lt;br /&gt;
# Conflicting reviewers are highlighted.These are those which are two standard deviations away from the mean.&lt;br /&gt;
&lt;br /&gt;
This view have a report of all the teams on one page.This report link is added to the mail that is already being sent whenever some conflict happens.This report page will be also accessible from the reports drop-down in the instructor view.&lt;br /&gt;
 &lt;br /&gt;
*A new partial is created for this view -&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;color:green;text-align:adjust&amp;quot;&amp;gt;&lt;br /&gt;
  Note: &amp;lt;br&amp;gt;&lt;br /&gt;
  X- axis represents precentage score of the team&amp;lt;br&amp;gt;&lt;br /&gt;
  Y- axis represents the reviewers &amp;lt;br&amp;gt;&lt;br /&gt;
  Highlighted reviewers are outside the tolerance limit&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;table id=&amp;quot;myTable&amp;quot; border=&amp;quot;1px solid black&amp;quot; margin-top=&amp;quot;-9px&amp;quot;  width=&amp;quot;100%&amp;quot; cellspacing='0' cellpadding='2' border='0'&amp;gt;&lt;br /&gt;
  &amp;lt;thead&amp;gt;&lt;br /&gt;
  &amp;lt;tr bgcolor='#CCCCCC'&amp;gt;&lt;br /&gt;
    &amp;lt;!-- class value decides whether the column should be sortable or not  --&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;30%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot;&amp;gt;Team &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;70%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot; &amp;gt;Reviewers/Metrics &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;/thead&amp;gt;&lt;br /&gt;
  &amp;lt;tbody&amp;gt;&lt;br /&gt;
  &amp;lt;% max_scores= max_assignment_review_score_per_round(@id) %&amp;gt;&lt;br /&gt;
  &amp;lt;%@reviewers.keys.each do |team_name| %&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td style=&amp;quot;padding-left: 50px;&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;% members = team_members(team_name, @id)%&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Name: &amp;lt;/strong&amp;gt;&amp;lt;%= team_name %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Members: &amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
	&amp;lt;% members.each do |member|%&amp;gt;&lt;br /&gt;
          &amp;lt;%=User.find(member.user_id).fullname %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;%= render 'review_conflict_metric' , team_name: team_name , max_scores: max_scores %&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Partial for the display for reviewers,scores and metrics&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot; border=&amp;quot;0&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;%question_answers = review_score_for_team(@id, team_name) %&amp;gt;&lt;br /&gt;
        &amp;lt;% i = 1 %&amp;gt;&lt;br /&gt;
        &amp;lt;% question_answers.each do |question_answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% average = average_of_round(question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% std = std_of_round(average,question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% upper_tolerance_limit = (average+(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;% lower_tolerance_limit = (average-(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;tr&amp;gt;&lt;br /&gt;
                &amp;lt;td width=&amp;quot;30%&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;strong&amp;gt;Reviewers with scores&amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
            &amp;lt;ol&amp;gt;&lt;br /&gt;
            &amp;lt;% question_answer.each do |reviewer, answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% if answer &amp;gt; upper_tolerance_limit or answer &amp;lt; lower_tolerance_limit  %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;mark style=&amp;quot;background-color:#FFFF00&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&amp;lt;/mark&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% else %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;/ol&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Max Review Score: &amp;lt;/strong&amp;gt;&amp;lt;%=max_scores[i-1]%&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Average Score: &amp;lt;/strong&amp;gt;&amp;lt;%=  average.to_s %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Standard Deviation: &amp;lt;/strong&amp;gt;&amp;lt;%=  std.to_s %&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;&amp;lt;u&amp;gt;&amp;lt;%= &amp;quot;Round: &amp;quot; + i.to_s %&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
          &amp;lt;%= generate_score_chart(max_scores[i-1], question_answer) %&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;% i+=1 %&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Sample view of the new report  -&lt;br /&gt;
[[File: Oodd report.PNG|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get all the answers(scores) for a reviewee on an assignment for a particular round &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.answers_by_round_for_reviewee(assignment_id, reviewee_id,round)&lt;br /&gt;
    #get all answers for a reviewee on an assignment for a particular round&lt;br /&gt;
    question_answers = Answer.select(&amp;quot;answers.answer, response_maps.reviewer_id&amp;quot;)&lt;br /&gt;
                          .joins(&amp;quot;join responses on responses.id = answers.response_id&amp;quot;)&lt;br /&gt;
                          .joins(&amp;quot;join response_maps on responses.map_id = response_maps.id&amp;quot;)&lt;br /&gt;
                          .where(&amp;quot;response_maps.reviewed_object_id = ? and&lt;br /&gt;
                                           response_maps.reviewee_id = ? and&lt;br /&gt;
                                           responses.round = ?&amp;quot;, assignment_id, reviewee_id,round)&lt;br /&gt;
    question_answers&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the maximum score for an assignment and for a particular round&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def max_score_of_assignment_per_round(assignment,round)&lt;br /&gt;
      rubric = get_questions_by_assignment(assignment)&lt;br /&gt;
      rubric_questions_used = rubric[assignment.varying_rubrics_by_round? ? round : 0]&lt;br /&gt;
      assignment_max_score_per_round = 0&lt;br /&gt;
      rubric_questions_used.each do |q|&lt;br /&gt;
        next if q.type.eql?(&amp;quot;SectionHeader&amp;quot;)&lt;br /&gt;
        q_max_score = get_max_score_for_question(q)&lt;br /&gt;
        assignment_max_score_per_round += q_max_score&lt;br /&gt;
      end&lt;br /&gt;
      assignment_max_score_per_round&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def max_assignment_review_score_per_round(reviewed_object_id)&lt;br /&gt;
      assignment = Assignment.find(reviewed_object_id)&lt;br /&gt;
      total_rounds = assignment.rounds_of_reviews&lt;br /&gt;
      review_max_scores = Array.new(total_rounds)&lt;br /&gt;
      (0..total_rounds-1).each do |round|&lt;br /&gt;
        review_max_scores[round] = SummaryHelper::Summary.new.max_score_of_assignment_per_round(assignment, round)&lt;br /&gt;
      end&lt;br /&gt;
      review_max_scores&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to create the bar chart showing the review scores per round&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def generate_score_chart(review_max_score, question_answer)&lt;br /&gt;
    scores = Array.new&lt;br /&gt;
    question_answer.each do |reviewer,answer|&lt;br /&gt;
      scores &amp;lt;&amp;lt; ((answer.to_f/review_max_score.to_f)*100).round(2)&lt;br /&gt;
    end&lt;br /&gt;
    labels = (1..scores.length).to_a&lt;br /&gt;
    data = {&lt;br /&gt;
        labels: labels,&lt;br /&gt;
        datasets: [&lt;br /&gt;
            {&lt;br /&gt;
                label: &amp;quot;score%&amp;quot;,&lt;br /&gt;
                backgroundColor: &amp;quot;rgba(255,99,132,0.8)&amp;quot;,&lt;br /&gt;
                borderWidth: 1,&lt;br /&gt;
                data: scores,&lt;br /&gt;
                hoverBackgroundColor: &amp;quot;orange&amp;quot;,&lt;br /&gt;
                yAxisID: &amp;quot;bar-y-axis1&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
    options = {&lt;br /&gt;
      legend: {&lt;br /&gt;
        position: 'top',&lt;br /&gt;
        labels: {&lt;br /&gt;
          usePointStyle: true&lt;br /&gt;
        }&lt;br /&gt;
      },&lt;br /&gt;
      width: &amp;quot;125&amp;quot;,&lt;br /&gt;
      height: &amp;quot;75&amp;quot;,&lt;br /&gt;
      scales: {&lt;br /&gt;
            yAxes: [{&lt;br /&gt;
                        stacked: true,&lt;br /&gt;
                        id: &amp;quot;bar-y-axis1&amp;quot;,&lt;br /&gt;
                        barThickness: 10&lt;br /&gt;
                    }, {&lt;br /&gt;
                        display: false,&lt;br /&gt;
                        stacked: true,&lt;br /&gt;
                        id: &amp;quot;bar-y-axis2&amp;quot;,&lt;br /&gt;
                        barThickness: 15,&lt;br /&gt;
                        type: 'category',&lt;br /&gt;
                        categoryPercentage: 0.8,&lt;br /&gt;
                        barPercentage: 0.9,&lt;br /&gt;
                        gridLines: {&lt;br /&gt;
                            offsetGridLines: true&lt;br /&gt;
                        }&lt;br /&gt;
                    }],&lt;br /&gt;
            xAxes: [{&lt;br /&gt;
                        stacked: false,&lt;br /&gt;
                        ticks: {	&lt;br /&gt;
			    beginAtZero: true,&lt;br /&gt;
                            stepSize: 10,&lt;br /&gt;
                            max: 100&lt;br /&gt;
                        }&lt;br /&gt;
                    }]&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    horizontal_bar_chart data, options&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the team members&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def team_members(team_name, assignment_id)&lt;br /&gt;
    team_id = Team.select(:id).where(name: team_name)&lt;br /&gt;
    members = TeamsUser.where(team_id: team_id)&lt;br /&gt;
    members&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to find the standard deviation&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def std_of_round(average,question_answer)&lt;br /&gt;
	accum=0.0&lt;br /&gt;
	i=0&lt;br /&gt;
        question_answer.each do |reviewer,answer|&lt;br /&gt;
		accum+=(answer-average)**2&lt;br /&gt;
		i+=1&lt;br /&gt;
	end&lt;br /&gt;
	if i != 0&lt;br /&gt;
		accum=Math.sqrt(accum/i)&lt;br /&gt;
	end &lt;br /&gt;
	accum.round(2)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to find the average score per round per team&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def average_of_round(question_answer)&lt;br /&gt;
	average=0.0&lt;br /&gt;
	i=0&lt;br /&gt;
	question_answer.each do |reviewer,answer|&lt;br /&gt;
		average+=answer&lt;br /&gt;
		i+=1&lt;br /&gt;
  	end&lt;br /&gt;
	if i != 0&lt;br /&gt;
		average=average/i&lt;br /&gt;
	end&lt;br /&gt;
	average.round(2)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the review score for each round of particular team&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def review_score_for_team(reviewed_object_id, team_name)&lt;br /&gt;
    question_answers=[]&lt;br /&gt;
    reviewee_id = Team.select(:id).where(name: team_name, parent_id: reviewed_object_id)&lt;br /&gt;
    reviewee_id.each do |reviewee|&lt;br /&gt;
      total_rounds = Assignment.find(reviewed_object_id).rounds_of_reviews&lt;br /&gt;
      question_answers = Array.new(total_rounds)&lt;br /&gt;
      (0..total_rounds-1).each do |round|&lt;br /&gt;
        temp_values = Answer.answers_by_round_for_reviewee(reviewed_object_id, reviewee,round+1)&lt;br /&gt;
	      question_answers[round] = review_score_helper_for_team(temp_values)&lt;br /&gt;
	    end&lt;br /&gt;
    end&lt;br /&gt;
    question_answers&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def review_score_helper_for_team(temp_values)&lt;br /&gt;
	question_answers={}&lt;br /&gt;
	temp_values.each do |temp_value|&lt;br /&gt;
          if question_answers.key?(temp_value[:reviewer_id])&lt;br /&gt;
            if temp_value[:answer].nil?&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] += 0&lt;br /&gt;
            else&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] += temp_value[:answer]&lt;br /&gt;
            end&lt;br /&gt;
          else&lt;br /&gt;
            if temp_value[:answer].nil?&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] = 0&lt;br /&gt;
            else&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] = temp_value[:answer]&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
	question_answers&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to create a response map for the reviewers and reviewee as well as the teams and the reviewee_id&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def review_conflict_response_map(params, _session = nil)&lt;br /&gt;
    assign_basics(params)&lt;br /&gt;
    teams = Team.select(:id, :name).where(parent_id: @id).order(:name)&lt;br /&gt;
    @teams = ({})&lt;br /&gt;
    @reviewers = ({})&lt;br /&gt;
    teams.each do |reviewee|&lt;br /&gt;
      @reviewers[reviewee.name] = reviewers_name_id_by_reviewee_and_assignment(reviewee, @id)&lt;br /&gt;
      @teams[reviewee.name] = reviewee.id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the reviewers of a particular assignment and particular reviewee&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def reviewers_name_id_by_reviewee_and_assignment(reviewee, id)&lt;br /&gt;
    temp_reviewers = User.select(&amp;quot; DISTINCT participants.id, users.name&amp;quot;)&lt;br /&gt;
                    .joins(&amp;quot;JOIN participants ON participants.user_id = users.id&amp;quot;)&lt;br /&gt;
                    .joins(&amp;quot;JOIN response_maps ON response_maps.reviewer_id = participants.id&amp;quot;)&lt;br /&gt;
                    .where(&amp;quot;response_maps.reviewee_id = ? and response_maps.reviewed_object_id = ?&amp;quot;, reviewee.id, id)&lt;br /&gt;
    reviewers = ({})&lt;br /&gt;
    temp_reviewers.each do |reviewer|&lt;br /&gt;
      reviewers[reviewer[:id].to_s] = reviewer[:name]&lt;br /&gt;
    end&lt;br /&gt;
    reviewers&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Feature 2:''' No hardcoded URLs &lt;br /&gt;
Hardcoded URLs are be managed by the config file in order to make these links functional on every server running Expertiza and raw URLs will be given some meaningful names.&lt;br /&gt;
&lt;br /&gt;
* Code changed for removing the hardcoded URLs&lt;br /&gt;
[[File:Harcord link.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we had done the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*UI testing for the new functionality&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
&lt;br /&gt;
All the existing related rspec tests have tested and they all passed wit 0 failures.&lt;br /&gt;
Majority of the new functionality concerns with the new view,so we have mainly done the UI testing shown below.Some of the Rspec test added are shown below:&lt;br /&gt;
&lt;br /&gt;
*Rspec Tests for Answer Model&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let(:response_map) { create(:review_response_map, id: 1, reviewed_object_id: 1, reviewer_id: 1) }&lt;br /&gt;
it &amp;quot;returns answers by reviewer for reviewee in round from db which is not empty&amp;quot; do&lt;br /&gt;
      expect(Answer.answers_by_round_for_reviewee(@assignment_id, @reviewee_id,@round)).not_to be_empty&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Rspec Tests for Report Formatter Helper methods&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe 'review_conflict_response_map' do&lt;br /&gt;
      context 'when type is ReviewConflictResponseMap' do&lt;br /&gt;
        it 'renders response_report page with corresponding data' do&lt;br /&gt;
          allow(Team).to receive(:where).with(parent_id: '1').and_return([integer('id')]).ordered&lt;br /&gt;
          params = {&lt;br /&gt;
              id: 1,&lt;br /&gt;
              report: {type: 'ReviewResponseMap'},&lt;br /&gt;
              user: 'no one'&lt;br /&gt;
          }&lt;br /&gt;
          get :response_report, params&lt;br /&gt;
          expect(response).to render_template(:response_report)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    describe &amp;quot;reviewers_name_id_by_reviewee_and_assignment&amp;quot; do&lt;br /&gt;
      before(:each) do&lt;br /&gt;
        @assignment_id = 1&lt;br /&gt;
        @reviewee_id = 1&lt;br /&gt;
      end&lt;br /&gt;
      it &amp;quot;returns reviewers name from Answer by reviewee ans assignment id from db which is not empty&amp;quot; do&lt;br /&gt;
        expect(allow(User).to receive(:where).with(@reviewee_id, @assignment_id).and_return([integer('id')])).not_to be_empty&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
&lt;br /&gt;
We have crated a [https://cl.ly/ab6b9c8bac36 Demo Video] showing the new functionality.&lt;br /&gt;
&lt;br /&gt;
=Files changed in this Project=&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/controllers/response_controller.rb Response Controller]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/report_formatter_helper.rb Report Formatter Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/review_mapping_helper.rb Review Mapping Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/summary_helper.rb Summary Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/mailers/mailer.rb Mailer]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/models/answer.rb Answer model]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/models/response.rb Response Model]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/mailer/notify_grade_conflict_message.html.erb Notify Grade Conflict Message View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_conflict_metric.html.erb Review Conflict Metric View] (New Created)&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_conflict_report.html.erb Review Conflict Report View] (New Created)&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_report.html.erb Review Report View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_searchbox.html.erb Searchbox View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/response_report.html.haml Response Report View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/spec/controllers/reports_controller_spec.rb Reports Controller Spec]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/spec/models/answer_spec.rb Answer model spec]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
* [https://github.com/expertiza/expertiza expertiza]&lt;br /&gt;
* [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2018-_Project_E1865._Conflict_Notification Previous Work]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1329 Previous Pull Request]&lt;br /&gt;
* [https://rubygems.org/gems/standard-deviation/versions/0.1.1 Standard-Deviation gem]&lt;br /&gt;
* [https://github.com/jtescher/descriptive-statistics descriptive-statistics gem]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124606</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124606"/>
		<updated>2019-04-27T00:35:41Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, and it links to the review or submission which initiated the notification. It gives the link in raw HTML, but it should give it as a link associated with text, such as the text “this new review” linking to the page that shows the review.The email send to the instructor should also link to page that shows data on each of the reviews done on this team.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.With every review submitted for an assignment of a particular student, the average is updated.The mail sent to the instructor contains the links to the conflicted review and a summary of the reviews.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view exists to analyze the conflict report===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the reviews but there is no view where the instructor can see all the conflicts and analyze them.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which will contain links to the conflicting review, summary link, and a link to report which can be used for analyzing. The new report will have the information like the Team(having conflicts), the standard deviation for the team review score and pictorial representation of all the review scores. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The email sent to the instructor should link to a page that shows the data on each of the reviews done on this team:&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members (user-IDs and/or names)&lt;br /&gt;
* One line for each review received.In this line would be&lt;br /&gt;
# The name of the person (or team) that submitted the review, which would be hyperlinked to the review itself&lt;br /&gt;
# The score given for the review&lt;br /&gt;
# A bar chart showing pictorial view&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Review scores that are outside some “tolerance” limit should be highlighted, e.g., boldfaced or shown in a different color.Probably the tolerance should be, perhaps, one or two standard deviations from the mean.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
*'''Feature 1:''' New page to show the conflict report&lt;br /&gt;
A new view page of the report which will have the following information:-&amp;lt;br&amp;gt;&lt;br /&gt;
# The name of the team.&lt;br /&gt;
# The members of the team.&lt;br /&gt;
# The name of the reviewer which would be hyperlinked to the review itself.&lt;br /&gt;
# The score given for the review.&lt;br /&gt;
# A bar chart showing pictorial view of all the reviews for a particular team.&lt;br /&gt;
# The average score received from reviewers.&lt;br /&gt;
# The standard deviation of the score received from reviewers.&lt;br /&gt;
# Conflicting reviewers are highlighted.These are those which are two standard deviations away from the mean.&lt;br /&gt;
&lt;br /&gt;
This view have a report of all the teams on one page.This report link is added to the mail that is already being sent whenever some conflict happens.This report page will be also accessible from the reports drop-down in the instructor view.&lt;br /&gt;
 &lt;br /&gt;
*A new partial is created for this view -&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;color:green;text-align:adjust&amp;quot;&amp;gt;&lt;br /&gt;
  Note: &amp;lt;br&amp;gt;&lt;br /&gt;
  X- axis represents precentage score of the team&amp;lt;br&amp;gt;&lt;br /&gt;
  Y- axis represents the reviewers &amp;lt;br&amp;gt;&lt;br /&gt;
  Highlighted reviewers are outside the tolerance limit&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;table id=&amp;quot;myTable&amp;quot; border=&amp;quot;1px solid black&amp;quot; margin-top=&amp;quot;-9px&amp;quot;  width=&amp;quot;100%&amp;quot; cellspacing='0' cellpadding='2' border='0'&amp;gt;&lt;br /&gt;
  &amp;lt;thead&amp;gt;&lt;br /&gt;
  &amp;lt;tr bgcolor='#CCCCCC'&amp;gt;&lt;br /&gt;
    &amp;lt;!-- class value decides whether the column should be sortable or not  --&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;30%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot;&amp;gt;Team &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;70%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot; &amp;gt;Reviewers/Metrics &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;/thead&amp;gt;&lt;br /&gt;
  &amp;lt;tbody&amp;gt;&lt;br /&gt;
  &amp;lt;% max_scores= max_assignment_review_score_per_round(@id) %&amp;gt;&lt;br /&gt;
  &amp;lt;%@reviewers.keys.each do |team_name| %&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td style=&amp;quot;padding-left: 50px;&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;% members = team_members(team_name, @id)%&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Name: &amp;lt;/strong&amp;gt;&amp;lt;%= team_name %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Members: &amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
	&amp;lt;% members.each do |member|%&amp;gt;&lt;br /&gt;
          &amp;lt;%=User.find(member.user_id).fullname %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;%= render 'review_conflict_metric' , team_name: team_name , max_scores: max_scores %&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Partial for the display for reviewers,scores and metrics&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot; border=&amp;quot;0&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;%question_answers = review_score_for_team(@id, team_name) %&amp;gt;&lt;br /&gt;
        &amp;lt;% i = 1 %&amp;gt;&lt;br /&gt;
        &amp;lt;% question_answers.each do |question_answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% average = average_of_round(question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% std = std_of_round(average,question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% upper_tolerance_limit = (average+(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;% lower_tolerance_limit = (average-(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;tr&amp;gt;&lt;br /&gt;
                &amp;lt;td width=&amp;quot;30%&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;strong&amp;gt;Reviewers with scores&amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
            &amp;lt;ol&amp;gt;&lt;br /&gt;
            &amp;lt;% question_answer.each do |reviewer, answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% if answer &amp;gt; upper_tolerance_limit or answer &amp;lt; lower_tolerance_limit  %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;mark style=&amp;quot;background-color:#FFFF00&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&amp;lt;/mark&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% else %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;/ol&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Max Review Score: &amp;lt;/strong&amp;gt;&amp;lt;%=max_scores[i-1]%&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Average Score: &amp;lt;/strong&amp;gt;&amp;lt;%=  average.to_s %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Standard Deviation: &amp;lt;/strong&amp;gt;&amp;lt;%=  std.to_s %&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;&amp;lt;u&amp;gt;&amp;lt;%= &amp;quot;Round: &amp;quot; + i.to_s %&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
          &amp;lt;%= generate_score_chart(max_scores[i-1], question_answer) %&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;% i+=1 %&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Sample view of the new report  -&lt;br /&gt;
[[File: Oodd report.PNG|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get all the answers(scores) for a reviewee on an assignment for a particular round &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.answers_by_round_for_reviewee(assignment_id, reviewee_id,round)&lt;br /&gt;
    #get all answers for a reviewee on an assignment for a particular round&lt;br /&gt;
    question_answers = Answer.select(&amp;quot;answers.answer, response_maps.reviewer_id&amp;quot;)&lt;br /&gt;
                          .joins(&amp;quot;join responses on responses.id = answers.response_id&amp;quot;)&lt;br /&gt;
                          .joins(&amp;quot;join response_maps on responses.map_id = response_maps.id&amp;quot;)&lt;br /&gt;
                          .where(&amp;quot;response_maps.reviewed_object_id = ? and&lt;br /&gt;
                                           response_maps.reviewee_id = ? and&lt;br /&gt;
                                           responses.round = ?&amp;quot;, assignment_id, reviewee_id,round)&lt;br /&gt;
    question_answers&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the maximum score for an assignment and for a particular round&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def max_score_of_assignment_per_round(assignment,round)&lt;br /&gt;
      rubric = get_questions_by_assignment(assignment)&lt;br /&gt;
      rubric_questions_used = rubric[assignment.varying_rubrics_by_round? ? round : 0]&lt;br /&gt;
      assignment_max_score_per_round = 0&lt;br /&gt;
      rubric_questions_used.each do |q|&lt;br /&gt;
        next if q.type.eql?(&amp;quot;SectionHeader&amp;quot;)&lt;br /&gt;
        q_max_score = get_max_score_for_question(q)&lt;br /&gt;
        assignment_max_score_per_round += q_max_score&lt;br /&gt;
      end&lt;br /&gt;
      assignment_max_score_per_round&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def max_assignment_review_score_per_round(reviewed_object_id)&lt;br /&gt;
      assignment = Assignment.find(reviewed_object_id)&lt;br /&gt;
      total_rounds = assignment.rounds_of_reviews&lt;br /&gt;
      review_max_scores = Array.new(total_rounds)&lt;br /&gt;
      (0..total_rounds-1).each do |round|&lt;br /&gt;
        review_max_scores[round] = SummaryHelper::Summary.new.max_score_of_assignment_per_round(assignment, round)&lt;br /&gt;
      end&lt;br /&gt;
      review_max_scores&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to create the bar chart showing the review scores per round&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def generate_score_chart(review_max_score, question_answer)&lt;br /&gt;
    scores = Array.new&lt;br /&gt;
    question_answer.each do |reviewer,answer|&lt;br /&gt;
      scores &amp;lt;&amp;lt; ((answer.to_f/review_max_score.to_f)*100).round(2)&lt;br /&gt;
    end&lt;br /&gt;
    labels = (1..scores.length).to_a&lt;br /&gt;
    data = {&lt;br /&gt;
        labels: labels,&lt;br /&gt;
        datasets: [&lt;br /&gt;
            {&lt;br /&gt;
                label: &amp;quot;score%&amp;quot;,&lt;br /&gt;
                backgroundColor: &amp;quot;rgba(255,99,132,0.8)&amp;quot;,&lt;br /&gt;
                borderWidth: 1,&lt;br /&gt;
                data: scores,&lt;br /&gt;
                hoverBackgroundColor: &amp;quot;orange&amp;quot;,&lt;br /&gt;
                yAxisID: &amp;quot;bar-y-axis1&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
    options = {&lt;br /&gt;
      legend: {&lt;br /&gt;
        position: 'top',&lt;br /&gt;
        labels: {&lt;br /&gt;
          usePointStyle: true&lt;br /&gt;
        }&lt;br /&gt;
      },&lt;br /&gt;
      width: &amp;quot;125&amp;quot;,&lt;br /&gt;
      height: &amp;quot;75&amp;quot;,&lt;br /&gt;
      scales: {&lt;br /&gt;
            yAxes: [{&lt;br /&gt;
                        stacked: true,&lt;br /&gt;
                        id: &amp;quot;bar-y-axis1&amp;quot;,&lt;br /&gt;
                        barThickness: 10&lt;br /&gt;
                    }, {&lt;br /&gt;
                        display: false,&lt;br /&gt;
                        stacked: true,&lt;br /&gt;
                        id: &amp;quot;bar-y-axis2&amp;quot;,&lt;br /&gt;
                        barThickness: 15,&lt;br /&gt;
                        type: 'category',&lt;br /&gt;
                        categoryPercentage: 0.8,&lt;br /&gt;
                        barPercentage: 0.9,&lt;br /&gt;
                        gridLines: {&lt;br /&gt;
                            offsetGridLines: true&lt;br /&gt;
                        }&lt;br /&gt;
                    }],&lt;br /&gt;
            xAxes: [{&lt;br /&gt;
                        stacked: false,&lt;br /&gt;
                        ticks: {	&lt;br /&gt;
			    beginAtZero: true,&lt;br /&gt;
                            stepSize: 10,&lt;br /&gt;
                            max: 100&lt;br /&gt;
                        }&lt;br /&gt;
                    }]&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    horizontal_bar_chart data, options&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the team members&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def team_members(team_name, assignment_id)&lt;br /&gt;
    team_id = Team.select(:id).where(name: team_name)&lt;br /&gt;
    members = TeamsUser.where(team_id: team_id)&lt;br /&gt;
    members&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to find the standard deviation&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def std_of_round(average,question_answer)&lt;br /&gt;
	accum=0.0&lt;br /&gt;
	i=0&lt;br /&gt;
        question_answer.each do |reviewer,answer|&lt;br /&gt;
		accum+=(answer-average)**2&lt;br /&gt;
		i+=1&lt;br /&gt;
	end&lt;br /&gt;
	if i != 0&lt;br /&gt;
		accum=Math.sqrt(accum/i)&lt;br /&gt;
	end &lt;br /&gt;
	accum.round(2)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to find the average score per round per team&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def average_of_round(question_answer)&lt;br /&gt;
	average=0.0&lt;br /&gt;
	i=0&lt;br /&gt;
	question_answer.each do |reviewer,answer|&lt;br /&gt;
		average+=answer&lt;br /&gt;
		i+=1&lt;br /&gt;
  	end&lt;br /&gt;
	if i != 0&lt;br /&gt;
		average=average/i&lt;br /&gt;
	end&lt;br /&gt;
	average.round(2)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the review score for each round of particular team&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def review_score_for_team(reviewed_object_id, team_name)&lt;br /&gt;
    question_answers=[]&lt;br /&gt;
    reviewee_id = Team.select(:id).where(name: team_name, parent_id: reviewed_object_id)&lt;br /&gt;
    reviewee_id.each do |reviewee|&lt;br /&gt;
      total_rounds = Assignment.find(reviewed_object_id).rounds_of_reviews&lt;br /&gt;
      question_answers = Array.new(total_rounds)&lt;br /&gt;
      (0..total_rounds-1).each do |round|&lt;br /&gt;
        temp_values = Answer.answers_by_round_for_reviewee(reviewed_object_id, reviewee,round+1)&lt;br /&gt;
	      question_answers[round] = review_score_helper_for_team(temp_values)&lt;br /&gt;
	    end&lt;br /&gt;
    end&lt;br /&gt;
    question_answers&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def review_score_helper_for_team(temp_values)&lt;br /&gt;
	question_answers={}&lt;br /&gt;
	temp_values.each do |temp_value|&lt;br /&gt;
          if question_answers.key?(temp_value[:reviewer_id])&lt;br /&gt;
            if temp_value[:answer].nil?&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] += 0&lt;br /&gt;
            else&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] += temp_value[:answer]&lt;br /&gt;
            end&lt;br /&gt;
          else&lt;br /&gt;
            if temp_value[:answer].nil?&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] = 0&lt;br /&gt;
            else&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] = temp_value[:answer]&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
	question_answers&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to create a response map for the reviewers and reviewee as well as the teams and the reviewee_id&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def review_conflict_response_map(params, _session = nil)&lt;br /&gt;
    assign_basics(params)&lt;br /&gt;
    teams = Team.select(:id, :name).where(parent_id: @id).order(:name)&lt;br /&gt;
    @teams = ({})&lt;br /&gt;
    @reviewers = ({})&lt;br /&gt;
    teams.each do |reviewee|&lt;br /&gt;
      @reviewers[reviewee.name] = reviewers_name_id_by_reviewee_and_assignment(reviewee, @id)&lt;br /&gt;
      @teams[reviewee.name] = reviewee.id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the reviewers of a particular assignment and particular reviewee&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def reviewers_name_id_by_reviewee_and_assignment(reviewee, id)&lt;br /&gt;
    temp_reviewers = User.select(&amp;quot; DISTINCT participants.id, users.name&amp;quot;)&lt;br /&gt;
                    .joins(&amp;quot;JOIN participants ON participants.user_id = users.id&amp;quot;)&lt;br /&gt;
                    .joins(&amp;quot;JOIN response_maps ON response_maps.reviewer_id = participants.id&amp;quot;)&lt;br /&gt;
                    .where(&amp;quot;response_maps.reviewee_id = ? and response_maps.reviewed_object_id = ?&amp;quot;, reviewee.id, id)&lt;br /&gt;
    reviewers = ({})&lt;br /&gt;
    temp_reviewers.each do |reviewer|&lt;br /&gt;
      reviewers[reviewer[:id].to_s] = reviewer[:name]&lt;br /&gt;
    end&lt;br /&gt;
    reviewers&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Feature 2:''' No hardcoded URLs &lt;br /&gt;
Hardcoded URLs are be managed by the config file in order to make these links functional on every server running Expertiza and raw URLs will be given some meaningful names.&lt;br /&gt;
&lt;br /&gt;
* Code changed for removing the hardcoded URLs&lt;br /&gt;
[[File:Harcord link.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we had done the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*UI testing for the new functionality&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
&lt;br /&gt;
All the existing related rspec tests have tested and they all passed wit 0 failures.&lt;br /&gt;
Majority of the new functionality concerns with the new view,so we have mainly done the UI testing shown below.Some of the Rspec test added are shown below:&lt;br /&gt;
&lt;br /&gt;
*Rspec Tests for Answer Model&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let(:response_map) { create(:review_response_map, id: 1, reviewed_object_id: 1, reviewer_id: 1) }&lt;br /&gt;
it &amp;quot;returns answers by reviewer for reviewee in round from db which is not empty&amp;quot; do&lt;br /&gt;
      expect(Answer.answers_by_round_for_reviewee(@assignment_id, @reviewee_id,@round)).not_to be_empty&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Rspec Tests for Report Formatter Helper methods&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe 'review_conflict_response_map' do&lt;br /&gt;
      context 'when type is ReviewConflictResponseMap' do&lt;br /&gt;
        it 'renders response_report page with corresponding data' do&lt;br /&gt;
          allow(Team).to receive(:where).with(parent_id: '1').and_return([integer('id')]).ordered&lt;br /&gt;
          params = {&lt;br /&gt;
              id: 1,&lt;br /&gt;
              report: {type: 'ReviewResponseMap'},&lt;br /&gt;
              user: 'no one'&lt;br /&gt;
          }&lt;br /&gt;
          get :response_report, params&lt;br /&gt;
          expect(response).to render_template(:response_report)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    describe &amp;quot;reviewers_name_id_by_reviewee_and_assignment&amp;quot; do&lt;br /&gt;
      before(:each) do&lt;br /&gt;
        @assignment_id = 1&lt;br /&gt;
        @reviewee_id = 1&lt;br /&gt;
      end&lt;br /&gt;
      it &amp;quot;returns reviewers name from Answer by reviewee ans assignment id from db which is not empty&amp;quot; do&lt;br /&gt;
        expect(allow(User).to receive(:where).with(@reviewee_id, @assignment_id).and_return([integer('id')])).not_to be_empty&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
&lt;br /&gt;
We have crated a video showing the new functionality.&lt;br /&gt;
&lt;br /&gt;
=Files changed in this Project=&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/controllers/response_controller.rb Response Controller]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/report_formatter_helper.rb Report Formatter Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/review_mapping_helper.rb Review Mapping Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/summary_helper.rb Summary Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/mailers/mailer.rb Mailer]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/models/answer.rb Answer model]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/models/response.rb Response Model]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/mailer/notify_grade_conflict_message.html.erb Notify Grade Conflict Message View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_conflict_metric.html.erb Review Conflict Metric View] (New Created)&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_conflict_report.html.erb Review Conflict Report View] (New Created)&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_report.html.erb Review Report View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_searchbox.html.erb Searchbox View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/response_report.html.haml Response Report View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/spec/controllers/reports_controller_spec.rb Reports Controller Spec]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/spec/models/answer_spec.rb Answer model spec]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
* [https://github.com/expertiza/expertiza expertiza]&lt;br /&gt;
* [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2018-_Project_E1865._Conflict_Notification Previous Work]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1329 Previous Pull Request]&lt;br /&gt;
* [https://rubygems.org/gems/standard-deviation/versions/0.1.1 Standard-Deviation gem]&lt;br /&gt;
* [https://github.com/jtescher/descriptive-statistics descriptive-statistics gem]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124605</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124605"/>
		<updated>2019-04-27T00:35:06Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, and it links to the review or submission which initiated the notification. It gives the link in raw HTML, but it should give it as a link associated with text, such as the text “this new review” linking to the page that shows the review.The email send to the instructor should also link to page that shows data on each of the reviews done on this team.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.With every review submitted for an assignment of a particular student, the average is updated.The mail sent to the instructor contains the links to the conflicted review and a summary of the reviews.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view exists to analyze the conflict report===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the reviews but there is no view where the instructor can see all the conflicts and analyze them.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which will contain links to the conflicting review, summary link, and a link to report which can be used for analyzing. The new report will have the information like the Team(having conflicts), the standard deviation for the team review score and pictorial representation of all the review scores. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The email sent to the instructor should link to a page that shows the data on each of the reviews done on this team:&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members (user-IDs and/or names)&lt;br /&gt;
* One line for each review received.In this line would be&lt;br /&gt;
# The name of the person (or team) that submitted the review, which would be hyperlinked to the review itself&lt;br /&gt;
# The score given for the review&lt;br /&gt;
# A bar chart showing pictorial view&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Review scores that are outside some “tolerance” limit should be highlighted, e.g., boldfaced or shown in a different color.Probably the tolerance should be, perhaps, one or two standard deviations from the mean.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
*'''Feature 1:''' New page to show the conflict report&lt;br /&gt;
A new view page of the report which will have the following information:-&amp;lt;br&amp;gt;&lt;br /&gt;
# The name of the team.&lt;br /&gt;
# The members of the team.&lt;br /&gt;
# The name of the reviewer which would be hyperlinked to the review itself.&lt;br /&gt;
# The score given for the review.&lt;br /&gt;
# A bar chart showing pictorial view of all the reviews for a particular team.&lt;br /&gt;
# The average score received from reviewers.&lt;br /&gt;
# The standard deviation of the score received from reviewers.&lt;br /&gt;
# Conflicting reviewers are highlighted.These are those which are two standard deviations away from the mean.&lt;br /&gt;
&lt;br /&gt;
This view have a report of all the teams on one page.This report link is added to the mail that is already being sent whenever some conflict happens.This report page will be also accessible from the reports drop-down in the instructor view.&lt;br /&gt;
 &lt;br /&gt;
*A new partial is created for this view -&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;color:green;text-align:adjust&amp;quot;&amp;gt;&lt;br /&gt;
  Note: &amp;lt;br&amp;gt;&lt;br /&gt;
  X- axis represents precentage score of the team&amp;lt;br&amp;gt;&lt;br /&gt;
  Y- axis represents the reviewers &amp;lt;br&amp;gt;&lt;br /&gt;
  Highlighted reviewers are outside the tolerance limit&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;table id=&amp;quot;myTable&amp;quot; border=&amp;quot;1px solid black&amp;quot; margin-top=&amp;quot;-9px&amp;quot;  width=&amp;quot;100%&amp;quot; cellspacing='0' cellpadding='2' border='0'&amp;gt;&lt;br /&gt;
  &amp;lt;thead&amp;gt;&lt;br /&gt;
  &amp;lt;tr bgcolor='#CCCCCC'&amp;gt;&lt;br /&gt;
    &amp;lt;!-- class value decides whether the column should be sortable or not  --&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;30%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot;&amp;gt;Team &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;70%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot; &amp;gt;Reviewers/Metrics &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;/thead&amp;gt;&lt;br /&gt;
  &amp;lt;tbody&amp;gt;&lt;br /&gt;
  &amp;lt;% max_scores= max_assignment_review_score_per_round(@id) %&amp;gt;&lt;br /&gt;
  &amp;lt;%@reviewers.keys.each do |team_name| %&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td style=&amp;quot;padding-left: 50px;&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;% members = team_members(team_name, @id)%&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Name: &amp;lt;/strong&amp;gt;&amp;lt;%= team_name %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Members: &amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
	&amp;lt;% members.each do |member|%&amp;gt;&lt;br /&gt;
          &amp;lt;%=User.find(member.user_id).fullname %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;%= render 'review_conflict_metric' , team_name: team_name , max_scores: max_scores %&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Partial for the display for reviewers,scores and metrics&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot; border=&amp;quot;0&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;%question_answers = review_score_for_team(@id, team_name) %&amp;gt;&lt;br /&gt;
        &amp;lt;% i = 1 %&amp;gt;&lt;br /&gt;
        &amp;lt;% question_answers.each do |question_answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% average = average_of_round(question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% std = std_of_round(average,question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% upper_tolerance_limit = (average+(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;% lower_tolerance_limit = (average-(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;tr&amp;gt;&lt;br /&gt;
                &amp;lt;td width=&amp;quot;30%&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;strong&amp;gt;Reviewers with scores&amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
            &amp;lt;ol&amp;gt;&lt;br /&gt;
            &amp;lt;% question_answer.each do |reviewer, answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% if answer &amp;gt; upper_tolerance_limit or answer &amp;lt; lower_tolerance_limit  %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;mark style=&amp;quot;background-color:#FFFF00&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&amp;lt;/mark&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% else %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;/ol&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Max Review Score: &amp;lt;/strong&amp;gt;&amp;lt;%=max_scores[i-1]%&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Average Score: &amp;lt;/strong&amp;gt;&amp;lt;%=  average.to_s %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Standard Deviation: &amp;lt;/strong&amp;gt;&amp;lt;%=  std.to_s %&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;&amp;lt;u&amp;gt;&amp;lt;%= &amp;quot;Round: &amp;quot; + i.to_s %&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
          &amp;lt;%= generate_score_chart(max_scores[i-1], question_answer) %&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;% i+=1 %&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Sample view of the new report  -&lt;br /&gt;
[[File: Oodd report.PNG|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get all the answers(scores) for a reviewee on an assignment for a particular round &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.answers_by_round_for_reviewee(assignment_id, reviewee_id,round)&lt;br /&gt;
    #get all answers for a reviewee on an assignment for a particular round&lt;br /&gt;
    question_answers = Answer.select(&amp;quot;answers.answer, response_maps.reviewer_id&amp;quot;)&lt;br /&gt;
                          .joins(&amp;quot;join responses on responses.id = answers.response_id&amp;quot;)&lt;br /&gt;
                          .joins(&amp;quot;join response_maps on responses.map_id = response_maps.id&amp;quot;)&lt;br /&gt;
                          .where(&amp;quot;response_maps.reviewed_object_id = ? and&lt;br /&gt;
                                           response_maps.reviewee_id = ? and&lt;br /&gt;
                                           responses.round = ?&amp;quot;, assignment_id, reviewee_id,round)&lt;br /&gt;
    question_answers&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the maximum score for an assignment and for a particular round&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def max_score_of_assignment_per_round(assignment,round)&lt;br /&gt;
      rubric = get_questions_by_assignment(assignment)&lt;br /&gt;
      rubric_questions_used = rubric[assignment.varying_rubrics_by_round? ? round : 0]&lt;br /&gt;
      assignment_max_score_per_round = 0&lt;br /&gt;
      rubric_questions_used.each do |q|&lt;br /&gt;
        next if q.type.eql?(&amp;quot;SectionHeader&amp;quot;)&lt;br /&gt;
        q_max_score = get_max_score_for_question(q)&lt;br /&gt;
        assignment_max_score_per_round += q_max_score&lt;br /&gt;
      end&lt;br /&gt;
      assignment_max_score_per_round&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    def max_assignment_review_score_per_round(reviewed_object_id)&lt;br /&gt;
      assignment = Assignment.find(reviewed_object_id)&lt;br /&gt;
      total_rounds = assignment.rounds_of_reviews&lt;br /&gt;
      review_max_scores = Array.new(total_rounds)&lt;br /&gt;
      (0..total_rounds-1).each do |round|&lt;br /&gt;
        review_max_scores[round] = SummaryHelper::Summary.new.max_score_of_assignment_per_round(assignment, round)&lt;br /&gt;
      end&lt;br /&gt;
      review_max_scores&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to create the bar chart showing the review scores per round&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def generate_score_chart(review_max_score, question_answer)&lt;br /&gt;
    scores = Array.new&lt;br /&gt;
    question_answer.each do |reviewer,answer|&lt;br /&gt;
      scores &amp;lt;&amp;lt; ((answer.to_f/review_max_score.to_f)*100).round(2)&lt;br /&gt;
    end&lt;br /&gt;
    labels = (1..scores.length).to_a&lt;br /&gt;
    data = {&lt;br /&gt;
        labels: labels,&lt;br /&gt;
        datasets: [&lt;br /&gt;
            {&lt;br /&gt;
                label: &amp;quot;score%&amp;quot;,&lt;br /&gt;
                backgroundColor: &amp;quot;rgba(255,99,132,0.8)&amp;quot;,&lt;br /&gt;
                borderWidth: 1,&lt;br /&gt;
                data: scores,&lt;br /&gt;
                hoverBackgroundColor: &amp;quot;orange&amp;quot;,&lt;br /&gt;
                yAxisID: &amp;quot;bar-y-axis1&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
    options = {&lt;br /&gt;
      legend: {&lt;br /&gt;
        position: 'top',&lt;br /&gt;
        labels: {&lt;br /&gt;
          usePointStyle: true&lt;br /&gt;
        }&lt;br /&gt;
      },&lt;br /&gt;
      width: &amp;quot;125&amp;quot;,&lt;br /&gt;
      height: &amp;quot;75&amp;quot;,&lt;br /&gt;
      scales: {&lt;br /&gt;
            yAxes: [{&lt;br /&gt;
                        stacked: true,&lt;br /&gt;
                        id: &amp;quot;bar-y-axis1&amp;quot;,&lt;br /&gt;
                        barThickness: 10&lt;br /&gt;
                    }, {&lt;br /&gt;
                        display: false,&lt;br /&gt;
                        stacked: true,&lt;br /&gt;
                        id: &amp;quot;bar-y-axis2&amp;quot;,&lt;br /&gt;
                        barThickness: 15,&lt;br /&gt;
                        type: 'category',&lt;br /&gt;
                        categoryPercentage: 0.8,&lt;br /&gt;
                        barPercentage: 0.9,&lt;br /&gt;
                        gridLines: {&lt;br /&gt;
                            offsetGridLines: true&lt;br /&gt;
                        }&lt;br /&gt;
                    }],&lt;br /&gt;
            xAxes: [{&lt;br /&gt;
                        stacked: false,&lt;br /&gt;
                        ticks: {	&lt;br /&gt;
			    beginAtZero: true,&lt;br /&gt;
                            stepSize: 10,&lt;br /&gt;
                            max: 100&lt;br /&gt;
                        }&lt;br /&gt;
                    }]&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    horizontal_bar_chart data, options&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the team members&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def team_members(team_name, assignment_id)&lt;br /&gt;
    team_id = Team.select(:id).where(name: team_name)&lt;br /&gt;
    members = TeamsUser.where(team_id: team_id)&lt;br /&gt;
    members&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to find the standard deviation&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def std_of_round(average,question_answer)&lt;br /&gt;
	accum=0.0&lt;br /&gt;
	i=0&lt;br /&gt;
        question_answer.each do |reviewer,answer|&lt;br /&gt;
		accum+=(answer-average)**2&lt;br /&gt;
		i+=1&lt;br /&gt;
	end&lt;br /&gt;
	if i != 0&lt;br /&gt;
		accum=Math.sqrt(accum/i)&lt;br /&gt;
	end &lt;br /&gt;
	accum.round(2)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to find the average score per round per team&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def average_of_round(question_answer)&lt;br /&gt;
	average=0.0&lt;br /&gt;
	i=0&lt;br /&gt;
	question_answer.each do |reviewer,answer|&lt;br /&gt;
		average+=answer&lt;br /&gt;
		i+=1&lt;br /&gt;
  	end&lt;br /&gt;
	if i != 0&lt;br /&gt;
		average=average/i&lt;br /&gt;
	end&lt;br /&gt;
	average.round(2)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the review score for each round of particular team&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def review_score_for_team(reviewed_object_id, team_name)&lt;br /&gt;
    question_answers=[]&lt;br /&gt;
    reviewee_id = Team.select(:id).where(name: team_name, parent_id: reviewed_object_id)&lt;br /&gt;
    reviewee_id.each do |reviewee|&lt;br /&gt;
      total_rounds = Assignment.find(reviewed_object_id).rounds_of_reviews&lt;br /&gt;
      question_answers = Array.new(total_rounds)&lt;br /&gt;
      (0..total_rounds-1).each do |round|&lt;br /&gt;
        temp_values = Answer.answers_by_round_for_reviewee(reviewed_object_id, reviewee,round+1)&lt;br /&gt;
	      question_answers[round] = review_score_helper_for_team(temp_values)&lt;br /&gt;
	    end&lt;br /&gt;
    end&lt;br /&gt;
    question_answers&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def review_score_helper_for_team(temp_values)&lt;br /&gt;
	question_answers={}&lt;br /&gt;
	temp_values.each do |temp_value|&lt;br /&gt;
          if question_answers.key?(temp_value[:reviewer_id])&lt;br /&gt;
            if temp_value[:answer].nil?&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] += 0&lt;br /&gt;
            else&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] += temp_value[:answer]&lt;br /&gt;
            end&lt;br /&gt;
          else&lt;br /&gt;
            if temp_value[:answer].nil?&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] = 0&lt;br /&gt;
            else&lt;br /&gt;
              question_answers[temp_value[:reviewer_id]] = temp_value[:answer]&lt;br /&gt;
            end&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
	question_answers&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to create a response map for the reviewers and reviewee as well as the teams and the reviewee_id&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def review_conflict_response_map(params, _session = nil)&lt;br /&gt;
    assign_basics(params)&lt;br /&gt;
    teams = Team.select(:id, :name).where(parent_id: @id).order(:name)&lt;br /&gt;
    @teams = ({})&lt;br /&gt;
    @reviewers = ({})&lt;br /&gt;
    teams.each do |reviewee|&lt;br /&gt;
      @reviewers[reviewee.name] = reviewers_name_id_by_reviewee_and_assignment(reviewee, @id)&lt;br /&gt;
      @teams[reviewee.name] = reviewee.id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the reviewers of a particular assignment and particular reviewee&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def reviewers_name_id_by_reviewee_and_assignment(reviewee, id)&lt;br /&gt;
    temp_reviewers = User.select(&amp;quot; DISTINCT participants.id, users.name&amp;quot;)&lt;br /&gt;
                    .joins(&amp;quot;JOIN participants ON participants.user_id = users.id&amp;quot;)&lt;br /&gt;
                    .joins(&amp;quot;JOIN response_maps ON response_maps.reviewer_id = participants.id&amp;quot;)&lt;br /&gt;
                    .where(&amp;quot;response_maps.reviewee_id = ? and response_maps.reviewed_object_id = ?&amp;quot;, reviewee.id, id)&lt;br /&gt;
    reviewers = ({})&lt;br /&gt;
    temp_reviewers.each do |reviewer|&lt;br /&gt;
      reviewers[reviewer[:id].to_s] = reviewer[:name]&lt;br /&gt;
    end&lt;br /&gt;
    reviewers&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''Feature 2:''' No hardcoded URLs &lt;br /&gt;
Hardcoded URLs are be managed by the config file in order to make these links functional on every server running Expertiza and raw URLs will be given some meaningful names.&lt;br /&gt;
&lt;br /&gt;
* Code changed for removing the hardcoded URLs&lt;br /&gt;
[[File:Harcord link.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we had done the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*UI testing for the new functionality&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
&lt;br /&gt;
All the existing related rspec tests have tested and they all passed wit 0 failures.&lt;br /&gt;
Majority of the new functionality concerns with the new view,so we have mainly done the UI testing shown below.Some of the Rspec test added are shown below:&lt;br /&gt;
&lt;br /&gt;
*Rspec Tests for Answer Model&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let(:response_map) { create(:review_response_map, id: 1, reviewed_object_id: 1, reviewer_id: 1) }&lt;br /&gt;
it &amp;quot;returns answers by reviewer for reviewee in round from db which is not empty&amp;quot; do&lt;br /&gt;
      expect(Answer.answers_by_round_for_reviewee(@assignment_id, @reviewee_id,@round)).not_to be_empty&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Rspec Tests for Report Formatter Helper methods&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe 'review_conflict_response_map' do&lt;br /&gt;
      context 'when type is ReviewConflictResponseMap' do&lt;br /&gt;
        it 'renders response_report page with corresponding data' do&lt;br /&gt;
          allow(Team).to receive(:where).with(parent_id: '1').and_return([integer('id')]).ordered&lt;br /&gt;
          params = {&lt;br /&gt;
              id: 1,&lt;br /&gt;
              report: {type: 'ReviewResponseMap'},&lt;br /&gt;
              user: 'no one'&lt;br /&gt;
          }&lt;br /&gt;
          get :response_report, params&lt;br /&gt;
          expect(response).to render_template(:response_report)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    describe &amp;quot;reviewers_name_id_by_reviewee_and_assignment&amp;quot; do&lt;br /&gt;
      before(:each) do&lt;br /&gt;
        @assignment_id = 1&lt;br /&gt;
        @reviewee_id = 1&lt;br /&gt;
      end&lt;br /&gt;
      it &amp;quot;returns reviewers name from Answer by reviewee ans assignment id from db which is not empty&amp;quot; do&lt;br /&gt;
        expect(allow(User).to receive(:where).with(@reviewee_id, @assignment_id).and_return([integer('id')])).not_to be_empty&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to &lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
&lt;br /&gt;
We have crated a video showing the new functionality.&lt;br /&gt;
&lt;br /&gt;
=Files changed in this Project=&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/controllers/response_controller.rb Response Controller]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/report_formatter_helper.rb Report Formatter Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/review_mapping_helper.rb Review Mapping Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/summary_helper.rb Summary Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/mailers/mailer.rb Mailer]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/models/answer.rb Answer model]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/models/response.rb Response Model]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/mailer/notify_grade_conflict_message.html.erb Notify Grade Conflict Message View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_conflict_metric.html.erb Review Conflict Metric View] (New Created)&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_conflict_report.html.erb Review Conflict Report View] (New Created)&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_report.html.erb Review Report View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_searchbox.html.erb Searchbox View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/response_report.html.haml Response Report View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/spec/controllers/reports_controller_spec.rb Reports Controller Spec]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/spec/models/answer_spec.rb Answer model spec]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
* [https://github.com/expertiza/expertiza expertiza]&lt;br /&gt;
* [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2018-_Project_E1865._Conflict_Notification Previous Work]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1329 Previous Pull Request]&lt;br /&gt;
* [https://rubygems.org/gems/standard-deviation/versions/0.1.1 Standard-Deviation gem]&lt;br /&gt;
* [https://github.com/jtescher/descriptive-statistics descriptive-statistics gem]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124603</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124603"/>
		<updated>2019-04-27T00:25:17Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, and it links to the review or submission which initiated the notification. It gives the link in raw HTML, but it should give it as a link associated with text, such as the text “this new review” linking to the page that shows the review.The email send to the instructor should also link to page that shows data on each of the reviews done on this team.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.With every review submitted for an assignment of a particular student, the average is updated.The mail sent to the instructor contains the links to the conflicted review and a summary of the reviews.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view exists to analyze the conflict report===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the reviews but there is no view where the instructor can see all the conflicts and analyze them.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which will contain links to the conflicting review, summary link, and a link to report which can be used for analyzing. The new report will have the information like the Team(having conflicts), the standard deviation for the team review score and pictorial representation of all the review scores. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The email sent to the instructor should link to a page that shows the data on each of the reviews done on this team:&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members (user-IDs and/or names)&lt;br /&gt;
* One line for each review received.In this line would be&lt;br /&gt;
# The name of the person (or team) that submitted the review, which would be hyperlinked to the review itself&lt;br /&gt;
# The score given for the review&lt;br /&gt;
# A bar chart showing pictorial view&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Review scores that are outside some “tolerance” limit should be highlighted, e.g., boldfaced or shown in a different color.Probably the tolerance should be, perhaps, one or two standard deviations from the mean.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
*'''Feature 1:''' New page to show the conflict report&lt;br /&gt;
A new view page of the report which will have the following information:-&amp;lt;br&amp;gt;&lt;br /&gt;
# The name of the team.&lt;br /&gt;
# The members of the team.&lt;br /&gt;
# The name of the reviewer which would be hyperlinked to the review itself.&lt;br /&gt;
# The score given for the review.&lt;br /&gt;
# A bar chart showing pictorial view of all the reviews for a particular team.&lt;br /&gt;
# The average score received from reviewers.&lt;br /&gt;
# The standard deviation of the score received from reviewers.&lt;br /&gt;
# Conflicting reviewers are highlighted.These are those which are two standard deviations away from the mean.&lt;br /&gt;
&lt;br /&gt;
This view have a report of all the teams on one page.This report link is added to the mail that is already being sent whenever some conflict happens.This report page will be also accessible from the reports drop-down in the instructor view.&lt;br /&gt;
 &lt;br /&gt;
*A new partial is created for this view -&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;color:green;text-align:adjust&amp;quot;&amp;gt;&lt;br /&gt;
  Note: &amp;lt;br&amp;gt;&lt;br /&gt;
  X- axis represents precentage score of the team&amp;lt;br&amp;gt;&lt;br /&gt;
  Y- axis represents the reviewers &amp;lt;br&amp;gt;&lt;br /&gt;
  Highlighted reviewers are outside the tolerance limit&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;table id=&amp;quot;myTable&amp;quot; border=&amp;quot;1px solid black&amp;quot; margin-top=&amp;quot;-9px&amp;quot;  width=&amp;quot;100%&amp;quot; cellspacing='0' cellpadding='2' border='0'&amp;gt;&lt;br /&gt;
  &amp;lt;thead&amp;gt;&lt;br /&gt;
  &amp;lt;tr bgcolor='#CCCCCC'&amp;gt;&lt;br /&gt;
    &amp;lt;!-- class value decides whether the column should be sortable or not  --&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;30%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot;&amp;gt;Team &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;70%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot; &amp;gt;Reviewers/Metrics &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;/thead&amp;gt;&lt;br /&gt;
  &amp;lt;tbody&amp;gt;&lt;br /&gt;
  &amp;lt;% max_scores= max_assignment_review_score_per_round(@id) %&amp;gt;&lt;br /&gt;
  &amp;lt;%@reviewers.keys.each do |team_name| %&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td style=&amp;quot;padding-left: 50px;&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;% members = team_members(team_name, @id)%&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Name: &amp;lt;/strong&amp;gt;&amp;lt;%= team_name %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Members: &amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
	&amp;lt;% members.each do |member|%&amp;gt;&lt;br /&gt;
          &amp;lt;%=User.find(member.user_id).fullname %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;%= render 'review_conflict_metric' , team_name: team_name , max_scores: max_scores %&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Partial for the display for reviewers,scores and metrics&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot; border=&amp;quot;0&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;%question_answers = review_score_for_team(@id, team_name) %&amp;gt;&lt;br /&gt;
        &amp;lt;% i = 1 %&amp;gt;&lt;br /&gt;
        &amp;lt;% question_answers.each do |question_answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% average = average_of_round(question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% std = std_of_round(average,question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% upper_tolerance_limit = (average+(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;% lower_tolerance_limit = (average-(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;tr&amp;gt;&lt;br /&gt;
                &amp;lt;td width=&amp;quot;30%&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;strong&amp;gt;Reviewers with scores&amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
            &amp;lt;ol&amp;gt;&lt;br /&gt;
            &amp;lt;% question_answer.each do |reviewer, answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% if answer &amp;gt; upper_tolerance_limit or answer &amp;lt; lower_tolerance_limit  %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;mark style=&amp;quot;background-color:#FFFF00&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&amp;lt;/mark&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% else %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;/ol&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Max Review Score: &amp;lt;/strong&amp;gt;&amp;lt;%=max_scores[i-1]%&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Average Score: &amp;lt;/strong&amp;gt;&amp;lt;%=  average.to_s %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Standard Deviation: &amp;lt;/strong&amp;gt;&amp;lt;%=  std.to_s %&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;&amp;lt;u&amp;gt;&amp;lt;%= &amp;quot;Round: &amp;quot; + i.to_s %&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
          &amp;lt;%= generate_score_chart(max_scores[i-1], question_answer) %&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;% i+=1 %&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Sample view of the new report  -&lt;br /&gt;
[[File: Oodd report.PNG|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get all the answers(scores) for a reviewee on an assignment for a particular round &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def self.answers_by_round_for_reviewee(assignment_id, reviewee_id,round)&lt;br /&gt;
    #get all answers for a reviewee on an assignment for a particular round&lt;br /&gt;
    question_answers = Answer.select(&amp;quot;answers.answer, response_maps.reviewer_id&amp;quot;)&lt;br /&gt;
                          .joins(&amp;quot;join responses on responses.id = answers.response_id&amp;quot;)&lt;br /&gt;
                          .joins(&amp;quot;join response_maps on responses.map_id = response_maps.id&amp;quot;)&lt;br /&gt;
                          .where(&amp;quot;response_maps.reviewed_object_id = ? and&lt;br /&gt;
                                           response_maps.reviewee_id = ? and&lt;br /&gt;
                                           responses.round = ?&amp;quot;, assignment_id, reviewee_id,round)&lt;br /&gt;
    question_answers&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to get the maximum score for an assignment and for a particular round&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    def max_score_of_assignment_per_round(assignment,round)&lt;br /&gt;
      rubric = get_questions_by_assignment(assignment)&lt;br /&gt;
      rubric_questions_used = rubric[assignment.varying_rubrics_by_round? ? round : 0]&lt;br /&gt;
      assignment_max_score_per_round = 0&lt;br /&gt;
      rubric_questions_used.each do |q|&lt;br /&gt;
        next if q.type.eql?(&amp;quot;SectionHeader&amp;quot;)&lt;br /&gt;
        q_max_score = get_max_score_for_question(q)&lt;br /&gt;
        assignment_max_score_per_round += q_max_score&lt;br /&gt;
      end&lt;br /&gt;
      assignment_max_score_per_round&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Method to create the bar chart showing the review scores per round&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def generate_score_chart(review_max_score, question_answer)&lt;br /&gt;
    scores = Array.new&lt;br /&gt;
    question_answer.each do |reviewer,answer|&lt;br /&gt;
      scores &amp;lt;&amp;lt; ((answer.to_f/review_max_score.to_f)*100).round(2)&lt;br /&gt;
    end&lt;br /&gt;
    labels = (1..scores.length).to_a&lt;br /&gt;
    data = {&lt;br /&gt;
        labels: labels,&lt;br /&gt;
        datasets: [&lt;br /&gt;
            {&lt;br /&gt;
                label: &amp;quot;score%&amp;quot;,&lt;br /&gt;
                backgroundColor: &amp;quot;rgba(255,99,132,0.8)&amp;quot;,&lt;br /&gt;
                borderWidth: 1,&lt;br /&gt;
                data: scores,&lt;br /&gt;
                hoverBackgroundColor: &amp;quot;orange&amp;quot;,&lt;br /&gt;
                yAxisID: &amp;quot;bar-y-axis1&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        ]&lt;br /&gt;
    }&lt;br /&gt;
    options = {&lt;br /&gt;
      legend: {&lt;br /&gt;
        position: 'top',&lt;br /&gt;
        labels: {&lt;br /&gt;
          usePointStyle: true&lt;br /&gt;
        }&lt;br /&gt;
      },&lt;br /&gt;
      width: &amp;quot;125&amp;quot;,&lt;br /&gt;
      height: &amp;quot;75&amp;quot;,&lt;br /&gt;
      scales: {&lt;br /&gt;
            yAxes: [{&lt;br /&gt;
                        stacked: true,&lt;br /&gt;
                        id: &amp;quot;bar-y-axis1&amp;quot;,&lt;br /&gt;
                        barThickness: 10&lt;br /&gt;
                    }, {&lt;br /&gt;
                        display: false,&lt;br /&gt;
                        stacked: true,&lt;br /&gt;
                        id: &amp;quot;bar-y-axis2&amp;quot;,&lt;br /&gt;
                        barThickness: 15,&lt;br /&gt;
                        type: 'category',&lt;br /&gt;
                        categoryPercentage: 0.8,&lt;br /&gt;
                        barPercentage: 0.9,&lt;br /&gt;
                        gridLines: {&lt;br /&gt;
                            offsetGridLines: true&lt;br /&gt;
                        }&lt;br /&gt;
                    }],&lt;br /&gt;
            xAxes: [{&lt;br /&gt;
                        stacked: false,&lt;br /&gt;
                        ticks: {	&lt;br /&gt;
			    beginAtZero: true,&lt;br /&gt;
                            stepSize: 10,&lt;br /&gt;
                            max: 100&lt;br /&gt;
                        }&lt;br /&gt;
                    }]&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    horizontal_bar_chart data, options&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Feature 2:''' No hardcoded URLs &lt;br /&gt;
Hardcoded URLs are be managed by the config file in order to make these links functional on every server running Expertiza and raw URLs will be given some meaningful names.&lt;br /&gt;
&lt;br /&gt;
* Code changed for removing the hardcoded URLs&lt;br /&gt;
[[File:Harcord link.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we had done the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*UI testing for the new functionality&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
&lt;br /&gt;
All the existing related rspec tests have tested and they all passed wit 0 failures.&lt;br /&gt;
Majority of the new functionality concerns with the new view,so we have mainly done the UI testing shown below.Some of the Rspec test added are shown below:&lt;br /&gt;
&lt;br /&gt;
*Rspec Tests for Answer Model&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let(:response_map) { create(:review_response_map, id: 1, reviewed_object_id: 1, reviewer_id: 1) }&lt;br /&gt;
it &amp;quot;returns answers by reviewer for reviewee in round from db which is not empty&amp;quot; do&lt;br /&gt;
      expect(Answer.answers_by_round_for_reviewee(@assignment_id, @reviewee_id,@round)).not_to be_empty&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Rspec Tests for Report Formatter Helper methods&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe 'review_conflict_response_map' do&lt;br /&gt;
      context 'when type is ReviewConflictResponseMap' do&lt;br /&gt;
        it 'renders response_report page with corresponding data' do&lt;br /&gt;
          allow(Team).to receive(:where).with(parent_id: '1').and_return([integer('id')]).ordered&lt;br /&gt;
          params = {&lt;br /&gt;
              id: 1,&lt;br /&gt;
              report: {type: 'ReviewResponseMap'},&lt;br /&gt;
              user: 'no one'&lt;br /&gt;
          }&lt;br /&gt;
          get :response_report, params&lt;br /&gt;
          expect(response).to render_template(:response_report)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    describe &amp;quot;reviewers_name_id_by_reviewee_and_assignment&amp;quot; do&lt;br /&gt;
      before(:each) do&lt;br /&gt;
        @assignment_id = 1&lt;br /&gt;
        @reviewee_id = 1&lt;br /&gt;
      end&lt;br /&gt;
      it &amp;quot;returns reviewers name from Answer by reviewee ans assignment id from db which is not empty&amp;quot; do&lt;br /&gt;
        expect(allow(User).to receive(:where).with(@reviewee_id, @assignment_id).and_return([integer('id')])).not_to be_empty&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
&lt;br /&gt;
We have crated a video showing the new functionality.&lt;br /&gt;
&lt;br /&gt;
=Files changed in this Project=&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/controllers/response_controller.rb Response Controller]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/report_formatter_helper.rb Report Formatter Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/review_mapping_helper.rb Review Mapping Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/summary_helper.rb Summary Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/mailers/mailer.rb Mailer]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/models/answer.rb Answer model]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/models/response.rb Response Model]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/mailer/notify_grade_conflict_message.html.erb Notify Grade Conflict Message View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_conflict_metric.html.erb Review Conflict Metric View] (New Created)&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_conflict_report.html.erb Review Conflict Report View] (New Created)&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_report.html.erb Review Report View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_searchbox.html.erb Searchbox View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/response_report.html.haml Response Report View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/spec/controllers/reports_controller_spec.rb Reports Controller Spec]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/spec/models/answer_spec.rb Answer model spec]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
* [https://github.com/expertiza/expertiza expertiza]&lt;br /&gt;
* [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2018-_Project_E1865._Conflict_Notification Previous Work]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1329 Previous Pull Request]&lt;br /&gt;
* [https://rubygems.org/gems/standard-deviation/versions/0.1.1 Standard-Deviation gem]&lt;br /&gt;
* [https://github.com/jtescher/descriptive-statistics descriptive-statistics gem]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124594</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124594"/>
		<updated>2019-04-27T00:13:43Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, and it links to the review or submission which initiated the notification. It gives the link in raw HTML, but it should give it as a link associated with text, such as the text “this new review” linking to the page that shows the review.The email send to the instructor should also link to page that shows data on each of the reviews done on this team.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.With every review submitted for an assignment of a particular student, the average is updated.The mail sent to the instructor contains the links to the conflicted review and a summary of the reviews.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view exists to analyze the conflict report===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the reviews but there is no view where the instructor can see all the conflicts and analyze them.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which will contain links to the conflicting review, summary link, and a link to report which can be used for analyzing. The new report will have the information like the Team(having conflicts), the standard deviation for the team review score and pictorial representation of all the review scores. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The email sent to the instructor should link to a page that shows the data on each of the reviews done on this team:&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members (user-IDs and/or names)&lt;br /&gt;
* One line for each review received.In this line would be&lt;br /&gt;
# The name of the person (or team) that submitted the review, which would be hyperlinked to the review itself&lt;br /&gt;
# The score given for the review&lt;br /&gt;
# A bar chart showing pictorial view&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Review scores that are outside some “tolerance” limit should be highlighted, e.g., boldfaced or shown in a different color.Probably the tolerance should be, perhaps, one or two standard deviations from the mean.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
*'''Feature 1:''' New page to show the conflict report&lt;br /&gt;
A new view page of the report which will have the following information:-&amp;lt;br&amp;gt;&lt;br /&gt;
# The name of the team.&lt;br /&gt;
# The members of the team.&lt;br /&gt;
# The name of the reviewer which would be hyperlinked to the review itself.&lt;br /&gt;
# The score given for the review.&lt;br /&gt;
# A bar chart showing pictorial view of all the reviews for a particular team.&lt;br /&gt;
# The average score received from reviewers.&lt;br /&gt;
# The standard deviation of the score received from reviewers.&lt;br /&gt;
# Conflicting reviewers are highlighted.These are those which are two standard deviations away from the mean.&lt;br /&gt;
&lt;br /&gt;
This view have a report of all the teams on one page.This report link is added to the mail that is already being sent whenever some conflict happens.This report page will be also accessible from the reports drop-down in the instructor view.&lt;br /&gt;
 &lt;br /&gt;
*A new partial is created for this view -&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;color:green;text-align:adjust&amp;quot;&amp;gt;&lt;br /&gt;
  Note: &amp;lt;br&amp;gt;&lt;br /&gt;
  X- axis represents precentage score of the team&amp;lt;br&amp;gt;&lt;br /&gt;
  Y- axis represents the reviewers &amp;lt;br&amp;gt;&lt;br /&gt;
  Highlighted reviewers are outside the tolerance limit&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;table id=&amp;quot;myTable&amp;quot; border=&amp;quot;1px solid black&amp;quot; margin-top=&amp;quot;-9px&amp;quot;  width=&amp;quot;100%&amp;quot; cellspacing='0' cellpadding='2' border='0'&amp;gt;&lt;br /&gt;
  &amp;lt;thead&amp;gt;&lt;br /&gt;
  &amp;lt;tr bgcolor='#CCCCCC'&amp;gt;&lt;br /&gt;
    &amp;lt;!-- class value decides whether the column should be sortable or not  --&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;30%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot;&amp;gt;Team &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;70%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot; &amp;gt;Reviewers/Metrics &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;/thead&amp;gt;&lt;br /&gt;
  &amp;lt;tbody&amp;gt;&lt;br /&gt;
  &amp;lt;% max_scores= max_assignment_review_score_per_round(@id) %&amp;gt;&lt;br /&gt;
  &amp;lt;%@reviewers.keys.each do |team_name| %&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td style=&amp;quot;padding-left: 50px;&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;% members = team_members(team_name, @id)%&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Name: &amp;lt;/strong&amp;gt;&amp;lt;%= team_name %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Members: &amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
	&amp;lt;% members.each do |member|%&amp;gt;&lt;br /&gt;
          &amp;lt;%=User.find(member.user_id).fullname %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;%= render 'review_conflict_metric' , team_name: team_name , max_scores: max_scores %&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Partial for the display for reviewers,scores and metrics&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot; border=&amp;quot;0&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;%question_answers = review_score_for_team(@id, team_name) %&amp;gt;&lt;br /&gt;
        &amp;lt;% i = 1 %&amp;gt;&lt;br /&gt;
        &amp;lt;% question_answers.each do |question_answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% average = average_of_round(question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% std = std_of_round(average,question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% upper_tolerance_limit = (average+(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;% lower_tolerance_limit = (average-(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;tr&amp;gt;&lt;br /&gt;
                &amp;lt;td width=&amp;quot;30%&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;strong&amp;gt;Reviewers with scores&amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
            &amp;lt;ol&amp;gt;&lt;br /&gt;
            &amp;lt;% question_answer.each do |reviewer, answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% if answer &amp;gt; upper_tolerance_limit or answer &amp;lt; lower_tolerance_limit  %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;mark style=&amp;quot;background-color:#FFFF00&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&amp;lt;/mark&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% else %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;/ol&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Max Review Score: &amp;lt;/strong&amp;gt;&amp;lt;%=max_scores[i-1]%&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Average Score: &amp;lt;/strong&amp;gt;&amp;lt;%=  average.to_s %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Standard Deviation: &amp;lt;/strong&amp;gt;&amp;lt;%=  std.to_s %&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;&amp;lt;u&amp;gt;&amp;lt;%= &amp;quot;Round: &amp;quot; + i.to_s %&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
          &amp;lt;%= generate_score_chart(max_scores[i-1], question_answer) %&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;% i+=1 %&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Sample view of the new report  -&lt;br /&gt;
[[File: Oodd report.PNG|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Feature 2:''' No hardcoded URLs &lt;br /&gt;
Hardcoded URLs are be managed by the config file in order to make these links functional on every server running Expertiza and raw URLs will be given some meaningful names.&lt;br /&gt;
&lt;br /&gt;
* Code changed for removing the hardcoded URLs&lt;br /&gt;
[[File:Harcord link.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we had done the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*UI testing for the new functionality&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
&lt;br /&gt;
All the existing related rspec tests have tested and they all passed wit 0 failures.&lt;br /&gt;
Majority of the new functionality concerns with the new view,so we have mainly done the UI testing shown below.Some of the Rspec test added are shown below:&lt;br /&gt;
&lt;br /&gt;
*Rspec Tests for Answer Model&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
let(:response_map) { create(:review_response_map, id: 1, reviewed_object_id: 1, reviewer_id: 1) }&lt;br /&gt;
it &amp;quot;returns answers by reviewer for reviewee in round from db which is not empty&amp;quot; do&lt;br /&gt;
      expect(Answer.answers_by_round_for_reviewee(@assignment_id, @reviewee_id,@round)).not_to be_empty&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Rspec Tests for Report Formatter Helper methods&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe 'review_conflict_response_map' do&lt;br /&gt;
      context 'when type is ReviewConflictResponseMap' do&lt;br /&gt;
        it 'renders response_report page with corresponding data' do&lt;br /&gt;
          allow(Team).to receive(:where).with(parent_id: '1').and_return([integer('id')]).ordered&lt;br /&gt;
          params = {&lt;br /&gt;
              id: 1,&lt;br /&gt;
              report: {type: 'ReviewResponseMap'},&lt;br /&gt;
              user: 'no one'&lt;br /&gt;
          }&lt;br /&gt;
          get :response_report, params&lt;br /&gt;
          expect(response).to render_template(:response_report)&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    describe &amp;quot;reviewers_name_id_by_reviewee_and_assignment&amp;quot; do&lt;br /&gt;
      before(:each) do&lt;br /&gt;
        @assignment_id = 1&lt;br /&gt;
        @reviewee_id = 1&lt;br /&gt;
      end&lt;br /&gt;
      it &amp;quot;returns reviewers name from Answer by reviewee ans assignment id from db which is not empty&amp;quot; do&lt;br /&gt;
        expect(allow(User).to receive(:where).with(@reviewee_id, @assignment_id).and_return([integer('id')])).not_to be_empty&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
&lt;br /&gt;
We have crated a video showing the new functionality.&lt;br /&gt;
&lt;br /&gt;
=Files changed in this Project=&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/controllers/response_controller.rb Response Controller]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/report_formatter_helper.rb Report Formatter Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/review_mapping_helper.rb Review Mapping Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/summary_helper.rb Summary Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/mailers/mailer.rb Mailer]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/models/answer.rb Answer model]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/models/response.rb Response Model]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/mailer/notify_grade_conflict_message.html.erb Notify Grade Conflict Message View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_conflict_metric.html.erb Review Conflict Metric View] (New Created)&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_conflict_report.html.erb Review Conflict Report View] (New Created)&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_report.html.erb Review Report View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_searchbox.html.erb Searchbox View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/response_report.html.haml Response Report View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/spec/controllers/reports_controller_spec.rb Reports Controller Spec]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/spec/models/answer_spec.rb Answer model spec]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
* [https://github.com/expertiza/expertiza expertiza]&lt;br /&gt;
* [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2018-_Project_E1865._Conflict_Notification Previous Work]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1329 Previous Pull Request]&lt;br /&gt;
* [https://rubygems.org/gems/standard-deviation/versions/0.1.1 Standard-Deviation gem]&lt;br /&gt;
* [https://github.com/jtescher/descriptive-statistics descriptive-statistics gem]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124590</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124590"/>
		<updated>2019-04-27T00:00:50Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, and it links to the review or submission which initiated the notification. It gives the link in raw HTML, but it should give it as a link associated with text, such as the text “this new review” linking to the page that shows the review.The email send to the instructor should also link to page that shows data on each of the reviews done on this team.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.With every review submitted for an assignment of a particular student, the average is updated.The mail sent to the instructor contains the links to the conflicted review and a summary of the reviews.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view exists to analyze the conflict report===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the reviews but there is no view where the instructor can see all the conflicts and analyze them.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which will contain links to the conflicting review, summary link, and a link to report which can be used for analyzing. The new report will have the information like the Team(having conflicts), the standard deviation for the team review score and pictorial representation of all the review scores. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The email sent to the instructor should link to a page that shows the data on each of the reviews done on this team:&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members (user-IDs and/or names)&lt;br /&gt;
* One line for each review received.In this line would be&lt;br /&gt;
# The name of the person (or team) that submitted the review, which would be hyperlinked to the review itself&lt;br /&gt;
# The score given for the review&lt;br /&gt;
# A bar chart showing pictorial view&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Review scores that are outside some “tolerance” limit should be highlighted, e.g., boldfaced or shown in a different color.Probably the tolerance should be, perhaps, one or two standard deviations from the mean.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
*'''Feature 1:''' New page to show the conflict report&lt;br /&gt;
A new view page of the report which will have the following information:-&amp;lt;br&amp;gt;&lt;br /&gt;
# The name of the team.&lt;br /&gt;
# The members of the team.&lt;br /&gt;
# The name of the reviewer which would be hyperlinked to the review itself.&lt;br /&gt;
# The score given for the review.&lt;br /&gt;
# A bar chart showing pictorial view of all the reviews for a particular team.&lt;br /&gt;
# The average score received from reviewers.&lt;br /&gt;
# The standard deviation of the score received from reviewers.&lt;br /&gt;
# Conflicting reviewers are highlighted.These are those which are two standard deviations away from the mean.&lt;br /&gt;
&lt;br /&gt;
This view have a report of all the teams on one page.This report link is added to the mail that is already being sent whenever some conflict happens.This report page will be also accessible from the reports drop-down in the instructor view.&lt;br /&gt;
 &lt;br /&gt;
*A new partial is created for this view -&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;color:green;text-align:adjust&amp;quot;&amp;gt;&lt;br /&gt;
  Note: &amp;lt;br&amp;gt;&lt;br /&gt;
  X- axis represents precentage score of the team&amp;lt;br&amp;gt;&lt;br /&gt;
  Y- axis represents the reviewers &amp;lt;br&amp;gt;&lt;br /&gt;
  Highlighted reviewers are outside the tolerance limit&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;table id=&amp;quot;myTable&amp;quot; border=&amp;quot;1px solid black&amp;quot; margin-top=&amp;quot;-9px&amp;quot;  width=&amp;quot;100%&amp;quot; cellspacing='0' cellpadding='2' border='0'&amp;gt;&lt;br /&gt;
  &amp;lt;thead&amp;gt;&lt;br /&gt;
  &amp;lt;tr bgcolor='#CCCCCC'&amp;gt;&lt;br /&gt;
    &amp;lt;!-- class value decides whether the column should be sortable or not  --&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;30%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot;&amp;gt;Team &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;70%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot; &amp;gt;Reviewers/Metrics &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;/thead&amp;gt;&lt;br /&gt;
  &amp;lt;tbody&amp;gt;&lt;br /&gt;
  &amp;lt;% max_scores= max_assignment_review_score_per_round(@id) %&amp;gt;&lt;br /&gt;
  &amp;lt;%@reviewers.keys.each do |team_name| %&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td style=&amp;quot;padding-left: 50px;&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;% members = team_members(team_name, @id)%&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Name: &amp;lt;/strong&amp;gt;&amp;lt;%= team_name %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Members: &amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
	&amp;lt;% members.each do |member|%&amp;gt;&lt;br /&gt;
          &amp;lt;%=User.find(member.user_id).fullname %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;%= render 'review_conflict_metric' , team_name: team_name , max_scores: max_scores %&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Partial for the display for reviewers,scores and metrics&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot; border=&amp;quot;0&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;%question_answers = review_score_for_team(@id, team_name) %&amp;gt;&lt;br /&gt;
        &amp;lt;% i = 1 %&amp;gt;&lt;br /&gt;
        &amp;lt;% question_answers.each do |question_answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% average = average_of_round(question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% std = std_of_round(average,question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% upper_tolerance_limit = (average+(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;% lower_tolerance_limit = (average-(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;tr&amp;gt;&lt;br /&gt;
                &amp;lt;td width=&amp;quot;30%&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;strong&amp;gt;Reviewers with scores&amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
            &amp;lt;ol&amp;gt;&lt;br /&gt;
            &amp;lt;% question_answer.each do |reviewer, answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% if answer &amp;gt; upper_tolerance_limit or answer &amp;lt; lower_tolerance_limit  %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;mark style=&amp;quot;background-color:#FFFF00&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&amp;lt;/mark&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% else %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;/ol&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Max Review Score: &amp;lt;/strong&amp;gt;&amp;lt;%=max_scores[i-1]%&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Average Score: &amp;lt;/strong&amp;gt;&amp;lt;%=  average.to_s %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Standard Deviation: &amp;lt;/strong&amp;gt;&amp;lt;%=  std.to_s %&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;&amp;lt;u&amp;gt;&amp;lt;%= &amp;quot;Round: &amp;quot; + i.to_s %&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
          &amp;lt;%= generate_score_chart(max_scores[i-1], question_answer) %&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;% i+=1 %&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Sample view of the new report  -&lt;br /&gt;
[[File: Oodd report.PNG|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Feature 2:''' No hardcoded URLs &lt;br /&gt;
Hardcoded URLs are be managed by the config file in order to make these links functional on every server running Expertiza and raw URLs will be given some meaningful names.&lt;br /&gt;
&lt;br /&gt;
* Code changed for removing the hardcoded URLs&lt;br /&gt;
[[File:Harcord link.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
=Files changed in this Project=&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/controllers/response_controller.rb Response Controller]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/report_formatter_helper.rb Report Formatter Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/review_mapping_helper.rb Review Mapping Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/helpers/summary_helper.rb Summary Helper]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/mailers/mailer.rb Mailer]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/models/answer.rb Answer model]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/models/response.rb Response Model]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/mailer/notify_grade_conflict_message.html.erb Notify Grade Conflict Message View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_conflict_metric.html.erb Review Conflict Metric View] (New Created)&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_conflict_report.html.erb Review Conflict Report View] (New Created)&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_review_report.html.erb Review Report View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/_searchbox.html.erb Searchbox View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/app/views/reports/response_report.html.haml Response Report View]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/spec/controllers/reports_controller_spec.rb Reports Controller Spec]&lt;br /&gt;
* [https://github.com/AryaAbhishek/expertiza/blob/beta/spec/models/answer_spec.rb Answer model spec]&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we plan to do the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
*UI testing on the deployed project&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
Rspec test files to be updated - &lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/controllers/reports_controller_spec.rb Reports Controller Spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/controllers/response_controller_spec.rb Response Controller Spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/models/response_spec.rb Response spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/models/mailer_spec.rb mailer spec]&lt;br /&gt;
&lt;br /&gt;
[Screenshots to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
[Screenshots/video to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
* [https://github.com/expertiza/expertiza expertiza]&lt;br /&gt;
* [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2018-_Project_E1865._Conflict_Notification Previous Work]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1329 Previous Pull Request]&lt;br /&gt;
* [https://rubygems.org/gems/standard-deviation/versions/0.1.1 Standard-Deviation gem]&lt;br /&gt;
* [https://github.com/jtescher/descriptive-statistics descriptive-statistics gem]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124588</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124588"/>
		<updated>2019-04-26T23:44:06Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, and it links to the review or submission which initiated the notification. It gives the link in raw HTML, but it should give it as a link associated with text, such as the text “this new review” linking to the page that shows the review.The email send to the instructor should also link to page that shows data on each of the reviews done on this team.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.With every review submitted for an assignment of a particular student, the average is updated.The mail sent to the instructor contains the links to the conflicted review and a summary of the reviews.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view exists to analyze the conflict report===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the reviews but there is no view where the instructor can see all the conflicts and analyze them.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which will contain links to the conflicting review, summary link, and a link to report which can be used for analyzing. The new report will have the information like the Team(having conflicts), the standard deviation for the team review score and pictorial representation of all the review scores. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The email sent to the instructor should link to a page that shows the data on each of the reviews done on this team:&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members (user-IDs and/or names)&lt;br /&gt;
* One line for each review received.In this line would be&lt;br /&gt;
# The name of the person (or team) that submitted the review, which would be hyperlinked to the review itself&lt;br /&gt;
# The score given for the review&lt;br /&gt;
# A bar chart showing pictorial view&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Review scores that are outside some “tolerance” limit should be highlighted, e.g., boldfaced or shown in a different color.Probably the tolerance should be, perhaps, one or two standard deviations from the mean.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
*'''Feature 1:''' New page to show the conflict report&lt;br /&gt;
A new view page of the report which will have the following information:-&amp;lt;br&amp;gt;&lt;br /&gt;
# The name of the team.&lt;br /&gt;
# The members of the team.&lt;br /&gt;
# The name of the reviewer which would be hyperlinked to the review itself.&lt;br /&gt;
# The score given for the review.&lt;br /&gt;
# A bar chart showing pictorial view of all the reviews for a particular team.&lt;br /&gt;
# The average score received from reviewers.&lt;br /&gt;
# The standard deviation of the score received from reviewers.&lt;br /&gt;
# Conflicting reviewers are highlighted.These are those which are two standard deviations away from the mean.&lt;br /&gt;
&lt;br /&gt;
This view have a report of all the teams on one page.This report link is added to the mail that is already being sent whenever some conflict happens.This report page will be also accessible from the reports drop-down in the instructor view.&lt;br /&gt;
 &lt;br /&gt;
*A new partial is created for this view -&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;color:green;text-align:adjust&amp;quot;&amp;gt;&lt;br /&gt;
  Note: &amp;lt;br&amp;gt;&lt;br /&gt;
  X- axis represents precentage score of the team&amp;lt;br&amp;gt;&lt;br /&gt;
  Y- axis represents the reviewers &amp;lt;br&amp;gt;&lt;br /&gt;
  Highlighted reviewers are outside the tolerance limit&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;table id=&amp;quot;myTable&amp;quot; border=&amp;quot;1px solid black&amp;quot; margin-top=&amp;quot;-9px&amp;quot;  width=&amp;quot;100%&amp;quot; cellspacing='0' cellpadding='2' border='0'&amp;gt;&lt;br /&gt;
  &amp;lt;thead&amp;gt;&lt;br /&gt;
  &amp;lt;tr bgcolor='#CCCCCC'&amp;gt;&lt;br /&gt;
    &amp;lt;!-- class value decides whether the column should be sortable or not  --&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;30%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot;&amp;gt;Team &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;70%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot; &amp;gt;Reviewers/Metrics &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;/thead&amp;gt;&lt;br /&gt;
  &amp;lt;tbody&amp;gt;&lt;br /&gt;
  &amp;lt;% max_scores= max_assignment_review_score_per_round(@id) %&amp;gt;&lt;br /&gt;
  &amp;lt;%@reviewers.keys.each do |team_name| %&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td style=&amp;quot;padding-left: 50px;&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;% members = team_members(team_name, @id)%&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Name: &amp;lt;/strong&amp;gt;&amp;lt;%= team_name %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Members: &amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
	&amp;lt;% members.each do |member|%&amp;gt;&lt;br /&gt;
          &amp;lt;%=User.find(member.user_id).fullname %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;%= render 'review_conflict_metric' , team_name: team_name , max_scores: max_scores %&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Partial for the display for reviewers,scores and metrics&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;table width=&amp;quot;100%&amp;quot; border=&amp;quot;0&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;%question_answers = review_score_for_team(@id, team_name) %&amp;gt;&lt;br /&gt;
        &amp;lt;% i = 1 %&amp;gt;&lt;br /&gt;
        &amp;lt;% question_answers.each do |question_answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% average = average_of_round(question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% std = std_of_round(average,question_answer) %&amp;gt;&lt;br /&gt;
                &amp;lt;% upper_tolerance_limit = (average+(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;% lower_tolerance_limit = (average-(2*std)).round(2) %&amp;gt;&lt;br /&gt;
                &amp;lt;tr&amp;gt;&lt;br /&gt;
                &amp;lt;td width=&amp;quot;30%&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;div&amp;gt;&lt;br /&gt;
                  &amp;lt;strong&amp;gt;Reviewers with scores&amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
            &amp;lt;ol&amp;gt;&lt;br /&gt;
            &amp;lt;% question_answer.each do |reviewer, answer| %&amp;gt;&lt;br /&gt;
                &amp;lt;% if answer &amp;gt; upper_tolerance_limit or answer &amp;lt; lower_tolerance_limit  %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;mark style=&amp;quot;background-color:#FFFF00&amp;quot;&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&amp;lt;/mark&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% else %&amp;gt;&lt;br /&gt;
                        &amp;lt;li&amp;gt;&amp;lt;% response_id = response_id_review_conflict(reviewer, @teams[team_name], @id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= link_to &amp;quot;(&amp;quot;+@reviewers[team_name.to_s][reviewer.to_s].to_s+&amp;quot;)&amp;quot;, :controller =&amp;gt; 'popup', :action =&amp;gt; 'team_users_popup', :id =&amp;gt; @teams[team_name], :id2 =&amp;gt; response_id, :assignment_id=&amp;gt;@id %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= list_review_submissions(reviewer, @teams[team_name], response_id) %&amp;gt;&lt;br /&gt;
                        &amp;lt;%= &amp;quot;: &amp;quot; + answer.to_s %&amp;gt;&lt;br /&gt;
                        &amp;lt;/li&amp;gt;&lt;br /&gt;
                &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;% end %&amp;gt;&lt;br /&gt;
            &amp;lt;/ol&amp;gt;&lt;br /&gt;
            &amp;lt;/div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Max Review Score: &amp;lt;/strong&amp;gt;&amp;lt;%=max_scores[i-1]%&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Average Score: &amp;lt;/strong&amp;gt;&amp;lt;%=  average.to_s %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;Standard Deviation: &amp;lt;/strong&amp;gt;&amp;lt;%=  std.to_s %&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
          &amp;lt;strong&amp;gt;&amp;lt;u&amp;gt;&amp;lt;%= &amp;quot;Round: &amp;quot; + i.to_s %&amp;gt;&amp;lt;/u&amp;gt;&amp;lt;/strong&amp;gt;&lt;br /&gt;
          &amp;lt;%= generate_score_chart(max_scores[i-1], question_answer) %&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&lt;br /&gt;
    &amp;lt;% i+=1 %&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Sample view of the new report  -&lt;br /&gt;
[[File: Oodd report.PNG|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*'''Feature 2:''' No hardcoded URLs &lt;br /&gt;
Hardcoded URLs are be managed by the config file in order to make these links functional on every server running Expertiza and raw URLs will be given some meaningful names.&lt;br /&gt;
&lt;br /&gt;
* Code changed for removing the hardcoded URLs&lt;br /&gt;
[[File:Harcord link.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
=Files changed in this Project=&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/mailers/mailer.rb mailer.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/config Config File]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/response.rb response.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/controllers/reports_controller.rb Response Controller]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/helpers/report_formatter_helper.rb Report Format Helper]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/app/views/reports/ Reports View]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/review_response_map.rb review_response_map.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/helpers/review_mapping_helper.rb review_mapping_helper.rb]&lt;br /&gt;
A new option will be added to view the conflict report in the _searchbox.html.erb.A new view will be added to the same.&amp;lt;br&amp;gt;&lt;br /&gt;
A new view partial _review_conflict_report.html.erb will be added in report views.&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we plan to do the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
*UI testing on the deployed project&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
Rspec test files to be updated - &lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/controllers/reports_controller_spec.rb Reports Controller Spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/controllers/response_controller_spec.rb Response Controller Spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/models/response_spec.rb Response spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/models/mailer_spec.rb mailer spec]&lt;br /&gt;
&lt;br /&gt;
[Screenshots to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
[Screenshots/video to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
* [https://github.com/expertiza/expertiza expertiza]&lt;br /&gt;
* [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2018-_Project_E1865._Conflict_Notification Previous Work]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1329 Previous Pull Request]&lt;br /&gt;
* [https://rubygems.org/gems/standard-deviation/versions/0.1.1 Standard-Deviation gem]&lt;br /&gt;
* [https://github.com/jtescher/descriptive-statistics descriptive-statistics gem]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Harcord_link.PNG&amp;diff=124587</id>
		<title>File:Harcord link.PNG</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Harcord_link.PNG&amp;diff=124587"/>
		<updated>2019-04-26T23:43:28Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Oodd_report.PNG&amp;diff=124586</id>
		<title>File:Oodd report.PNG</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Oodd_report.PNG&amp;diff=124586"/>
		<updated>2019-04-26T23:33:56Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124585</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124585"/>
		<updated>2019-04-26T23:31:16Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, and it links to the review or submission which initiated the notification. It gives the link in raw HTML, but it should give it as a link associated with text, such as the text “this new review” linking to the page that shows the review.The email send to the instructor should also link to page that shows data on each of the reviews done on this team.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.With every review submitted for an assignment of a particular student, the average is updated.The mail sent to the instructor contains the links to the conflicted review and a summary of the reviews.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view exists to analyze the conflict report===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the reviews but there is no view where the instructor can see all the conflicts and analyze them.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which will contain links to the conflicting review, summary link, and a link to report which can be used for analyzing. The new report will have the information like the Team(having conflicts), the standard deviation for the team review score and pictorial representation of all the review scores. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The email sent to the instructor should link to a page that shows the data on each of the reviews done on this team:&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members (user-IDs and/or names)&lt;br /&gt;
* One line for each review received.In this line would be&lt;br /&gt;
# The name of the person (or team) that submitted the review, which would be hyperlinked to the review itself&lt;br /&gt;
# The score given for the review&lt;br /&gt;
# A bar chart showing pictorial view&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Review scores that are outside some “tolerance” limit should be highlighted, e.g., boldfaced or shown in a different color.Probably the tolerance should be, perhaps, one or two standard deviations from the mean.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
*'''Feature 1:''' New page to show the conflict report&lt;br /&gt;
A new view page of the report which will have the following information:-&amp;lt;br&amp;gt;&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members of the team.&lt;br /&gt;
* The name of the reviewer which would be hyperlinked to the review itself.&lt;br /&gt;
* The score given for the review.&lt;br /&gt;
* A bar chart showing pictorial view of all the reviews for a particular team.&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Conflicting reviewers are highlighted.These are those which are two standard deviations away from the mean.&lt;br /&gt;
&lt;br /&gt;
This view have a report of all the teams on one page.This report link is added to the mail that is already being sent whenever some conflict happens.This report page will be also accessible from the reports drop-down in the instructor view.&lt;br /&gt;
 &lt;br /&gt;
*A new partial is created for this view -&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;color:green;text-align:adjust&amp;quot;&amp;gt;&lt;br /&gt;
  Note: &amp;lt;br&amp;gt;&lt;br /&gt;
  X- axis represents precentage score of the team&amp;lt;br&amp;gt;&lt;br /&gt;
  Y- axis represents the reviewers &amp;lt;br&amp;gt;&lt;br /&gt;
  Highlighted reviewers are outside the tolerance limit&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;table id=&amp;quot;myTable&amp;quot; border=&amp;quot;1px solid black&amp;quot; margin-top=&amp;quot;-9px&amp;quot;  width=&amp;quot;100%&amp;quot; cellspacing='0' cellpadding='2' border='0'&amp;gt;&lt;br /&gt;
  &amp;lt;thead&amp;gt;&lt;br /&gt;
  &amp;lt;tr bgcolor='#CCCCCC'&amp;gt;&lt;br /&gt;
    &amp;lt;!-- class value decides whether the column should be sortable or not  --&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;30%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot;&amp;gt;Team &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;th width=&amp;quot;70%&amp;quot; class=&amp;quot;sorter-false&amp;quot; border=&amp;quot;1px black solid&amp;quot; style=&amp;quot;text-align:center&amp;quot; &amp;gt;Reviewers/Metrics &amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;/thead&amp;gt;&lt;br /&gt;
  &amp;lt;tbody&amp;gt;&lt;br /&gt;
  &amp;lt;% max_scores= max_assignment_review_score_per_round(@id) %&amp;gt;&lt;br /&gt;
  &amp;lt;%@reviewers.keys.each do |team_name| %&amp;gt;&lt;br /&gt;
    &amp;lt;tr&amp;gt;&lt;br /&gt;
      &amp;lt;td style=&amp;quot;padding-left: 50px;&amp;quot; &amp;gt;&lt;br /&gt;
        &amp;lt;% members = team_members(team_name, @id)%&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Name: &amp;lt;/strong&amp;gt;&amp;lt;%= team_name %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;strong&amp;gt;Team Members: &amp;lt;/strong&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
	&amp;lt;% members.each do |member|%&amp;gt;&lt;br /&gt;
          &amp;lt;%=User.find(member.user_id).fullname %&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
        &amp;lt;% end %&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
      &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;%= render 'review_conflict_metric' , team_name: team_name , max_scores: max_scores %&amp;gt;&lt;br /&gt;
  &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;% end %&amp;gt;&lt;br /&gt;
  &amp;lt;/tbody&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
*Sample view of the new report  -&lt;br /&gt;
[[File: Capture.PNG|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
*'''Feature 2:''' No hardcoded URLs &lt;br /&gt;
Hardcoded URLs are be managed by the config file in order to make these links functional on every server running Expertiza and raw URLs will be given some meaningful names.&lt;br /&gt;
&lt;br /&gt;
=Files changed in this Project=&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/mailers/mailer.rb mailer.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/config Config File]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/response.rb response.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/controllers/reports_controller.rb Response Controller]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/helpers/report_formatter_helper.rb Report Format Helper]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/app/views/reports/ Reports View]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/review_response_map.rb review_response_map.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/helpers/review_mapping_helper.rb review_mapping_helper.rb]&lt;br /&gt;
A new option will be added to view the conflict report in the _searchbox.html.erb.A new view will be added to the same.&amp;lt;br&amp;gt;&lt;br /&gt;
A new view partial _review_conflict_report.html.erb will be added in report views.&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we plan to do the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
*UI testing on the deployed project&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
Rspec test files to be updated - &lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/controllers/reports_controller_spec.rb Reports Controller Spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/controllers/response_controller_spec.rb Response Controller Spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/models/response_spec.rb Response spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/models/mailer_spec.rb mailer spec]&lt;br /&gt;
&lt;br /&gt;
[Screenshots to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
[Screenshots/video to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
* [https://github.com/expertiza/expertiza expertiza]&lt;br /&gt;
* [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2018-_Project_E1865._Conflict_Notification Previous Work]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1329 Previous Pull Request]&lt;br /&gt;
* [https://rubygems.org/gems/standard-deviation/versions/0.1.1 Standard-Deviation gem]&lt;br /&gt;
* [https://github.com/jtescher/descriptive-statistics descriptive-statistics gem]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124584</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124584"/>
		<updated>2019-04-26T23:08:47Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: /* Implementation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, and it links to the review or submission which initiated the notification. It gives the link in raw HTML, but it should give it as a link associated with text, such as the text “this new review” linking to the page that shows the review.The email send to the instructor should also link to page that shows data on each of the reviews done on this team.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.With every review submitted for an assignment of a particular student, the average is updated.The mail sent to the instructor contains the links to the conflicted review and a summary of the reviews.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view exists to analyze the conflict report===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the reviews but there is no view where the instructor can see all the conflicts and analyze them.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which will contain links to the conflicting review, summary link, and a link to report which can be used for analyzing. The new report will have the information like the Team(having conflicts), the standard deviation for the team review score and pictorial representation of all the review scores. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The email sent to the instructor should link to a page that shows the data on each of the reviews done on this team:&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members (user-IDs and/or names)&lt;br /&gt;
* One line for each review received.In this line would be&lt;br /&gt;
# The name of the person (or team) that submitted the review, which would be hyperlinked to the review itself&lt;br /&gt;
# The score given for the review&lt;br /&gt;
# A bar chart showing pictorial view&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Review scores that are outside some “tolerance” limit should be highlighted, e.g., boldfaced or shown in a different color.Probably the tolerance should be, perhaps, one or two standard deviations from the mean.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
*'''Feature 1:''' New page to show the conflict report&lt;br /&gt;
A new view page of the report which will have the following information:-&amp;lt;br&amp;gt;&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members of the team.&lt;br /&gt;
* The name of the reviewer which would be hyperlinked to the review itself.&lt;br /&gt;
* The score given for the review.&lt;br /&gt;
* A bar chart showing pictorial view of all the reviews for a particular team.&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Conflicting reviewers are highlighted.These are those which are two standard deviations away from the mean.&lt;br /&gt;
&lt;br /&gt;
This view will have a report of all the teams on one page.This report link is added to the mail that is already being sent whenever some conflict happens.This report page will be also accessible from the reports drop-down in the instructor view.&lt;br /&gt;
 &lt;br /&gt;
*Sample view of the new report  -&lt;br /&gt;
[[File: Capture.PNG|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
*'''Feature 2:''' No hardcoded URLs &lt;br /&gt;
Hardcoded URLs are be managed by the config file in order to make these links functional on every server running Expertiza and raw URLs will be given some meaningful names.&lt;br /&gt;
&lt;br /&gt;
=Files changed in this Project=&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/mailers/mailer.rb mailer.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/config Config File]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/response.rb response.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/controllers/reports_controller.rb Response Controller]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/helpers/report_formatter_helper.rb Report Format Helper]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/app/views/reports/ Reports View]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/review_response_map.rb review_response_map.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/helpers/review_mapping_helper.rb review_mapping_helper.rb]&lt;br /&gt;
A new option will be added to view the conflict report in the _searchbox.html.erb.A new view will be added to the same.&amp;lt;br&amp;gt;&lt;br /&gt;
A new view partial _review_conflict_report.html.erb will be added in report views.&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we plan to do the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
*UI testing on the deployed project&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
Rspec test files to be updated - &lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/controllers/reports_controller_spec.rb Reports Controller Spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/controllers/response_controller_spec.rb Response Controller Spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/models/response_spec.rb Response spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/models/mailer_spec.rb mailer spec]&lt;br /&gt;
&lt;br /&gt;
[Screenshots to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
[Screenshots/video to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
* [https://github.com/expertiza/expertiza expertiza]&lt;br /&gt;
* [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2018-_Project_E1865._Conflict_Notification Previous Work]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1329 Previous Pull Request]&lt;br /&gt;
* [https://rubygems.org/gems/standard-deviation/versions/0.1.1 Standard-Deviation gem]&lt;br /&gt;
* [https://github.com/jtescher/descriptive-statistics descriptive-statistics gem]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124582</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124582"/>
		<updated>2019-04-26T23:00:22Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, and it links to the review or submission which initiated the notification. It gives the link in raw HTML, but it should give it as a link associated with text, such as the text “this new review” linking to the page that shows the review.The email send to the instructor should also link to page that shows data on each of the reviews done on this team.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.With every review submitted for an assignment of a particular student, the average is updated.The mail sent to the instructor contains the links to the conflicted review and a summary of the reviews.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view exists to analyze the conflict report===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the reviews but there is no view where the instructor can see all the conflicts and analyze them.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which will contain links to the conflicting review, summary link, and a link to report which can be used for analyzing. The new report will have the information like the Team(having conflicts), the standard deviation for the team review score and pictorial representation of all the review scores. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The email sent to the instructor should link to a page that shows the data on each of the reviews done on this team:&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members (user-IDs and/or names)&lt;br /&gt;
* One line for each review received.In this line would be&lt;br /&gt;
# The name of the person (or team) that submitted the review, which would be hyperlinked to the review itself&lt;br /&gt;
# The score given for the review&lt;br /&gt;
# A bar chart showing pictorial view&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Review scores that are outside some “tolerance” limit should be highlighted, e.g., boldfaced or shown in a different color.Probably the tolerance should be, perhaps, one or two standard deviations from the mean.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
*'''Feature 1:''' New page to show the conflict report&lt;br /&gt;
 A new view page of the report which will have the following information:-&amp;lt;br&amp;gt;&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members of the team.&lt;br /&gt;
* The name of the reviewer which would be hyperlinked to the review itself.&lt;br /&gt;
* The score given for the review.&lt;br /&gt;
* A bar chart showing pictorial view of all the reviews for a particular team.&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Conflicting reviewers are highlighted.These are those which are two standard deviations away from the mean.&lt;br /&gt;
&lt;br /&gt;
This view will have a report of all the teams on one page.This report link is added to the mail that is already being sent whenever some conflict happens.This report page will be also accessible from the reports drop-down in the instructor view.&lt;br /&gt;
 &lt;br /&gt;
*Sample view of the new report  -&lt;br /&gt;
[[File: Capture.PNG|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
*'''Feature 2:''' No hardcoded URLs &lt;br /&gt;
Hardcoded URLs are be managed by the config file in order to make these links functional on every server running Expertiza and raw URLs will be given some meaningful names.&lt;br /&gt;
&lt;br /&gt;
=Files changed in this Project=&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/mailers/mailer.rb mailer.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/config Config File]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/response.rb response.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/controllers/reports_controller.rb Response Controller]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/helpers/report_formatter_helper.rb Report Format Helper]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/app/views/reports/ Reports View]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/review_response_map.rb review_response_map.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/helpers/review_mapping_helper.rb review_mapping_helper.rb]&lt;br /&gt;
A new option will be added to view the conflict report in the _searchbox.html.erb.A new view will be added to the same.&amp;lt;br&amp;gt;&lt;br /&gt;
A new view partial _review_conflict_report.html.erb will be added in report views.&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we plan to do the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
*UI testing on the deployed project&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
Rspec test files to be updated - &lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/controllers/reports_controller_spec.rb Reports Controller Spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/controllers/response_controller_spec.rb Response Controller Spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/models/response_spec.rb Response spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/models/mailer_spec.rb mailer spec]&lt;br /&gt;
&lt;br /&gt;
[Screenshots to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
[Screenshots/video to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
* [https://github.com/expertiza/expertiza expertiza]&lt;br /&gt;
* [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2018-_Project_E1865._Conflict_Notification Previous Work]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1329 Previous Pull Request]&lt;br /&gt;
* [https://rubygems.org/gems/standard-deviation/versions/0.1.1 Standard-Deviation gem]&lt;br /&gt;
* [https://github.com/jtescher/descriptive-statistics descriptive-statistics gem]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124580</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124580"/>
		<updated>2019-04-26T22:56:06Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, and it links to the review or submission which initiated the notification. It gives the link in raw HTML, but it should give it as a link associated with text, such as the text “this new review” linking to the page that shows the review.The email send to the instructor should also link to page that shows data on each of the reviews done on this team.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.&lt;br /&gt;
With every review submitted for an assignment of a particular student, the average is updated.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view exists to analyze the conflict report===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the reviews but there is no view where the instructor can see all the conflicts and analyze them.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which will contain links to the conflicting review, summary link, and a link to report which can be used for analyzing. The new report will have the information like the Team(having conflicts), the standard deviation for the team review score and pictorial representation of all the review scores. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The email sent to the instructor should link to a page that shows the data on each of the reviews done on this team:&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members (user-IDs and/or names)&lt;br /&gt;
* One line for each review received.In this line would be&lt;br /&gt;
# The name of the person (or team) that submitted the review, which would be hyperlinked to the review itself&lt;br /&gt;
# The score given for the review&lt;br /&gt;
# A bar chart showing pictorial view&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Review scores that are outside some “tolerance” limit should be highlighted, e.g., boldfaced or shown in a different color.Probably the tolerance should be, perhaps, one or two standard deviations from the mean.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
*'''Feature 1:''' New page to show the conflict report&lt;br /&gt;
 A new view page of the report which will have the following information:-&amp;lt;br&amp;gt;&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members of the team.&lt;br /&gt;
* The name of the reviewer which would be hyperlinked to the review itself.&lt;br /&gt;
* The score given for the review.&lt;br /&gt;
* A bar chart showing pictorial view of all the reviews for a particular team.&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Conflicting reviewers are highlighted.These are those which are two standard deviations away from the mean.&lt;br /&gt;
&lt;br /&gt;
This view will have a report of all the teams on one page.This report link is added to the mail that is already being sent whenever some conflict happens.This report page will be also accessible from the reports drop-down in the instructor view.&lt;br /&gt;
 &lt;br /&gt;
*Sample view of the new report  -&lt;br /&gt;
[[File: Capture.PNG|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
*'''Feature 2:''' No hardcoded URLs &lt;br /&gt;
Hardcoded URLs are be managed by the config file in order to make these links functional on every server running Expertiza and raw URLs will be given some meaningful names.&lt;br /&gt;
&lt;br /&gt;
=Files changed in this Project=&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/mailers/mailer.rb mailer.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/config Config File]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/response.rb response.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/controllers/reports_controller.rb Response Controller]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/helpers/report_formatter_helper.rb Report Format Helper]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/app/views/reports/ Reports View]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/review_response_map.rb review_response_map.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/helpers/review_mapping_helper.rb review_mapping_helper.rb]&lt;br /&gt;
A new option will be added to view the conflict report in the _searchbox.html.erb.A new view will be added to the same.&amp;lt;br&amp;gt;&lt;br /&gt;
A new view partial _review_conflict_report.html.erb will be added in report views.&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we plan to do the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
*UI testing on the deployed project&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
Rspec test files to be updated - &lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/controllers/reports_controller_spec.rb Reports Controller Spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/controllers/response_controller_spec.rb Response Controller Spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/models/response_spec.rb Response spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/models/mailer_spec.rb mailer spec]&lt;br /&gt;
&lt;br /&gt;
[Screenshots to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
[Screenshots/video to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
* [https://github.com/expertiza/expertiza expertiza]&lt;br /&gt;
* [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2018-_Project_E1865._Conflict_Notification Previous Work]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1329 Previous Pull Request]&lt;br /&gt;
* [https://rubygems.org/gems/standard-deviation/versions/0.1.1 Standard-Deviation gem]&lt;br /&gt;
* [https://github.com/jtescher/descriptive-statistics descriptive-statistics gem]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124559</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124559"/>
		<updated>2019-04-26T21:53:46Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, and it links to the review or submission which initiated the notification. It gives the link in raw HTML, but it should give it as a link associated with text, such as the text “this new review” linking to the page that shows the review.The email send to the instructor should also link to page that shows data on each of the reviews done on this team.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.&lt;br /&gt;
With every review submitted for an assignment of a particular student, the average is updated.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view exists to analyze the conflict report===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the reviews but there is no view where the instructor can see all the conflicts and analyze them.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Summary of all the reviews&lt;br /&gt;
[[File:SUMMARY.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which will contain links to the conflicting review, summary link, and a link to report which can be used for analyzing. The new report will have the information like the Team(having conflicts), the standard deviation for the team review score and pictorial representation of all the review scores. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The email sent to the instructor should link to a page that shows the data on each of the reviews done on this team:&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members (user-IDs and/or names)&lt;br /&gt;
* One line for each review received.In this line would be&lt;br /&gt;
# The name of the person (or team) that submitted the review, which would be hyperlinked to the review itself&lt;br /&gt;
# The score given for the review&lt;br /&gt;
# A bar chart showing pictorial view&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Review scores that are outside some “tolerance” limit should be highlighted, e.g., boldfaced or shown in a different color.Probably the tolerance should be, perhaps, one or two standard deviations from the mean.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
*'''Feature 1:''' New page to show the conflict report&lt;br /&gt;
 A new view page of the report which will have the following information:-&amp;lt;br&amp;gt;&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members of the team.&lt;br /&gt;
* The name of the reviewer which would be hyperlinked to the review itself.&lt;br /&gt;
* The score given for the review.&lt;br /&gt;
* A bar chart showing pictorial view of all the reviews for a particular team.&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Conflicting reviewers are highlighted.These are those which are two standard deviations away from the mean.&lt;br /&gt;
&lt;br /&gt;
This view will have a report of all the teams on one page.This report link is added to the mail that is already being sent whenever some conflict happens.This report page will be also accessible from the reports drop-down in the instructor view.&lt;br /&gt;
 &lt;br /&gt;
*Sample view of the new report  -&lt;br /&gt;
[[File: Capture.PNG|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
*'''Feature 2:''' No hardcoded URLs &lt;br /&gt;
Hardcoded URLs are be managed by the config file in order to make these links functional on every server running Expertiza and raw URLs will be given some meaningful names.&lt;br /&gt;
&lt;br /&gt;
=Files changed in this Project=&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/mailers/mailer.rb mailer.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/config Config File]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/response.rb response.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/controllers/reports_controller.rb Response Controller]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/helpers/report_formatter_helper.rb Report Format Helper]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/app/views/reports/ Reports View]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/review_response_map.rb review_response_map.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/helpers/review_mapping_helper.rb review_mapping_helper.rb]&lt;br /&gt;
A new option will be added to view the conflict report in the _searchbox.html.erb.A new view will be added to the same.&amp;lt;br&amp;gt;&lt;br /&gt;
A new view partial _review_conflict_report.html.erb will be added in report views.&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we plan to do the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
*UI testing on the deployed project&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
Rspec test files to be updated - &lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/controllers/reports_controller_spec.rb Reports Controller Spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/controllers/response_controller_spec.rb Response Controller Spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/models/response_spec.rb Response spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/models/mailer_spec.rb mailer spec]&lt;br /&gt;
&lt;br /&gt;
[Screenshots to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
[Screenshots/video to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
* [https://github.com/expertiza/expertiza expertiza]&lt;br /&gt;
* [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2018-_Project_E1865._Conflict_Notification Previous Work]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1329 Previous Pull Request]&lt;br /&gt;
* [https://rubygems.org/gems/standard-deviation/versions/0.1.1 Standard-Deviation gem]&lt;br /&gt;
* [https://github.com/jtescher/descriptive-statistics descriptive-statistics gem]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124557</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124557"/>
		<updated>2019-04-26T21:51:42Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, and it links to the review or submission which initiated the notification. It gives the link in raw HTML, but it should give it as a link associated with text, such as the text “this new review” linking to the page that shows the review.The email send to the instructor should also link to page that shows data on each of the reviews done on this team.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.&lt;br /&gt;
With every review submitted for an assignment of a particular student, the average is updated.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view exists to analyze the conflict report===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the reviews but there is no view where the instructor can see all the conflicts and analyze them.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Summary of all the reviews&lt;br /&gt;
[[File:SUMMARY.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which will contain links to the conflicting review, summary link, and a link to report which can be used for analyzing. The new report will have the information like the Team(having conflicts), the standard deviation for the team review score and pictorial representation of all the review scores. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The email sent to the instructor should link to a page that shows the data on each of the reviews done on this team:&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members (user-IDs and/or names)&lt;br /&gt;
* One line for each review received.In this line would be&lt;br /&gt;
# The name of the person (or team) that submitted the review, which would be hyperlinked to the review itself&lt;br /&gt;
# The score given for the review&lt;br /&gt;
# A bar chart showing pictorial view&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Review scores that are outside some “tolerance” limit should be highlighted, e.g., boldfaced or shown in a different color.Probably the tolerance should be, perhaps, one or two standard deviations from the mean.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
*'''Feature 1:''' New page to show the conflict report&lt;br /&gt;
A new view page of the report which will have the following information:-&amp;lt;br&amp;gt;&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members of the team.&lt;br /&gt;
* The name of the reviewer which would be hyperlinked to the review itself.&lt;br /&gt;
* The score given for the review.&lt;br /&gt;
* A bar chart showing pictorial view of all the reviews for a particular team.&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Conflicting reviewers are highlighted.These are those which are two standard deviations away from the mean.&lt;br /&gt;
&lt;br /&gt;
This view will have a report of all the teams on one page.This report link is added to the mail that is already being sent whenever some conflict happens.This report page will be also accessible from the reports drop-down in the instructor view.&lt;br /&gt;
 &lt;br /&gt;
*Sample view of the new report (The view will contain all the columns as mentioned above)-&lt;br /&gt;
[[File: Capture.PNG|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
*'''Feature 2:''' No hardcoded URLs &lt;br /&gt;
Hardcoded URLs will be managed by the config file in order to make these links functional on every server running Expertiza and raw URLs will be given some meaningful names&lt;br /&gt;
&lt;br /&gt;
=Files to be changed in this Project=&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/mailers/mailer.rb mailer.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/config Config File]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/response.rb response.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/controllers/reports_controller.rb Response Controller]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/helpers/report_formatter_helper.rb Report Format Helper]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/app/views/reports/ Reports View]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/review_response_map.rb review_response_map.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/helpers/review_mapping_helper.rb review_mapping_helper.rb]&lt;br /&gt;
A new option will be added to view the conflict report in the _searchbox.html.erb.A new view will be added to the same.&amp;lt;br&amp;gt;&lt;br /&gt;
A new view partial _review_conflict_report.html.erb will be added in report views.&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we plan to do the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
*UI testing on the deployed project&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
Rspec test files to be updated - &lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/controllers/reports_controller_spec.rb Reports Controller Spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/controllers/response_controller_spec.rb Response Controller Spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/models/response_spec.rb Response spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/models/mailer_spec.rb mailer spec]&lt;br /&gt;
&lt;br /&gt;
[Screenshots to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
[Screenshots/video to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
* [https://github.com/expertiza/expertiza expertiza]&lt;br /&gt;
* [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2018-_Project_E1865._Conflict_Notification Previous Work]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1329 Previous Pull Request]&lt;br /&gt;
* [https://rubygems.org/gems/standard-deviation/versions/0.1.1 Standard-Deviation gem]&lt;br /&gt;
* [https://github.com/jtescher/descriptive-statistics descriptive-statistics gem]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124544</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=124544"/>
		<updated>2019-04-26T21:14:12Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, and it links to the review or submission which initiated the notification. It gives the link in raw HTML, but it should give it as a link associated with text, such as the text “this new review” linking to the page that shows the review.The email send to the instructor should also link to page that shows data on each of the reviews done on this team.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.&lt;br /&gt;
With every review submitted for an assignment of a particular student, the average is updated.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view exists to analyze the conflict report===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the reviews but there is no view where the instructor can see all the conflicts and analyze them.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Summary of all the reviews&lt;br /&gt;
[[File:SUMMARY.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which will contain links to the conflicting review, summary link, and a link to report which can be used for analyzing. The new report will have the information like the Team(having conflicts), the standard deviation for the team review score and pictorial representation of all the review scores. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The email sent to the instructor should link to a page that shows the data on each of the reviews done on this team:&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members (user-IDs and/or names)&lt;br /&gt;
* One line for each review received.In this line would be&lt;br /&gt;
# The name of the person (or team) that submitted the review, which would be hyperlinked to the review itself&lt;br /&gt;
# The score given for the review&lt;br /&gt;
# A bar chart showing pictorial view&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
* Review scores that are outside some “tolerance” limit should be highlighted, e.g., boldfaced or shown in a different color.Probably the tolerance should be, perhaps, one or two standard deviations from the mean.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
*'''Feature 1:''' New page to show the conflict report&lt;br /&gt;
A new view of the report which will have the following information:-&amp;lt;br&amp;gt;&lt;br /&gt;
* The name of the team.&lt;br /&gt;
* The members (user-IDs and/or names)&lt;br /&gt;
* The name of the person (or team) that submitted the review, which would be hyperlinked to the review itself,&lt;br /&gt;
* The score given for the review,&lt;br /&gt;
* A bar chart showing pictorial view&lt;br /&gt;
* The average score received from reviewers.&lt;br /&gt;
* The standard deviation of the score received from reviewers.&lt;br /&gt;
&lt;br /&gt;
This view will have a report of all the teams on one page.&lt;br /&gt;
This report link will be added to the mail that is already being sent whenever some conflict happens.&lt;br /&gt;
This report will be also accessible from the reports dropdown for the instructor. &lt;br /&gt;
*Sample view of the new report (The view will contain all the columns as mentioned above)-&lt;br /&gt;
[[File: Capture.PNG|center]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
*'''Feature 2:''' No hardcoded URLs &lt;br /&gt;
Hardcoded URLs will be managed by the config file in order to make these links functional on every server running Expertiza and raw URLs will be given some meaningful names&lt;br /&gt;
&lt;br /&gt;
=Files to be changed in this Project=&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/mailers/mailer.rb mailer.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/config Config File]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/response.rb response.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/controllers/reports_controller.rb Response Controller]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/helpers/report_formatter_helper.rb Report Format Helper]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/app/views/reports/ Reports View]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/review_response_map.rb review_response_map.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/helpers/review_mapping_helper.rb review_mapping_helper.rb]&lt;br /&gt;
A new option will be added to view the conflict report in the _searchbox.html.erb.A new view will be added to the same.&amp;lt;br&amp;gt;&lt;br /&gt;
A new view partial _review_conflict_report.html.erb will be added in report views.&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we plan to do the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
*UI testing on the deployed project&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
Rspec test files to be updated - &lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/controllers/reports_controller_spec.rb Reports Controller Spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/controllers/response_controller_spec.rb Response Controller Spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/models/response_spec.rb Response spec]&lt;br /&gt;
*[https://github.com/expertiza/expertiza/blob/master/spec/models/mailer_spec.rb mailer spec]&lt;br /&gt;
&lt;br /&gt;
[Screenshots to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
[Screenshots/video to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
* [https://github.com/expertiza/expertiza expertiza]&lt;br /&gt;
* [http://wiki.expertiza.ncsu.edu/index.php/CSC/ECE_517_Fall_2018-_Project_E1865._Conflict_Notification Previous Work]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/1329 Previous Pull Request]&lt;br /&gt;
* [https://rubygems.org/gems/standard-deviation/versions/0.1.1 Standard-Deviation gem]&lt;br /&gt;
* [https://github.com/jtescher/descriptive-statistics descriptive-statistics gem]&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123923</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123923"/>
		<updated>2019-04-12T23:23:11Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ &amp;quot;significantly&amp;quot; on their scoring (the threshold is specified in the &amp;quot;Notification limit&amp;quot; on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, however, it does not link to the particular review or submission which initiated the notification.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.&lt;br /&gt;
With every review submitted for an assignment of a particular student, the average is updated.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view exists to analyze the conflict report===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the reviews but there is no view where the instructor can see all the conflicts and analyze them.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Summary of all the reviews&lt;br /&gt;
[[File:SUMMARY.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which will contain links to the conflicting review, summary link, and a link to report which can be used for analyzing. The new report will have the information like the Team(having conflicts), the standard deviation for the team review score and pictorial representation of all the review scores.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
*'''Feature 1:''' No hardcoded URLs &lt;br /&gt;
Hardcoded URLs will be managed by the config file in order to make these links functional on every server running Expertiza&lt;br /&gt;
&lt;br /&gt;
*'''Feature 2:''' New view to show the conflict report&lt;br /&gt;
A new view of the report which will have the following information:-&amp;lt;br&amp;gt;&lt;br /&gt;
*Name of the team&amp;lt;br&amp;gt;&lt;br /&gt;
*Standard deviation&amp;lt;br&amp;gt;&lt;br /&gt;
*Graph showing a plot of the review scores vs the team name&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This view will have a report of all the teams on one page.&lt;br /&gt;
This report link will be added to the mail that is already being sent whenever some conflict happens.&lt;br /&gt;
*Sample view of the new report -&lt;br /&gt;
[[File: Capture.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
=Files to be changed in this Project=&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/mailers/mailer.rb mailer.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/config Config File]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/response.rb response.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/controllers/reports_controller.rb Response Controller]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/helpers/report_formatter_helper.rb Report Format Helper]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/app/views/reports Reports View]&lt;br /&gt;
A new option will be added to view the conflict report in the _searchbox.html.erb.A new view will be added for the same.&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we plan to do the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
*UI testing on the deployed project&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123903</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123903"/>
		<updated>2019-04-12T22:43:40Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ &amp;quot;significantly&amp;quot; on their scoring (the threshold is specified in the &amp;quot;Notification limit&amp;quot; on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, however, it does not link to the particular review or submission which initiated the notification.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.&lt;br /&gt;
With every review submitted for an assignment of a particular student, the average is updated.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view to analyze the conflicts===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the views.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Summary of all the reviews&lt;br /&gt;
[[File:SUMMARY.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which contains links to two reviews. One of which is the newly submitted review that differs by more than the notification limit where such a conflict has occurred. The email should state that a new conflicting review has been made.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
*  '''Problem''' - Inefficient calculation of conflicts: &amp;lt;br&amp;gt;&lt;br /&gt;
'''Solution:''' Instead of relying on the average, we will iterate through all previous submissions and will check conflict comparing them with the latest review. This logic will be implemented in the separate model.&lt;br /&gt;
&lt;br /&gt;
* '''Problem''' - Incorrect email message links:&amp;lt;br&amp;gt; &lt;br /&gt;
'''Solution:''' Hardcoded URLs will be managed by the config file in order to make these links functional on every server running Expertiza&lt;br /&gt;
&lt;br /&gt;
*  '''Problem''' - No separate view exist to show conflicts: &lt;br /&gt;
'''Solution:''' Separate view will be created to address this issue.&lt;br /&gt;
&lt;br /&gt;
=Files to be changed in this Project=&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/mailers/mailer.rb mailer.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/config Config File]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/response.rb response.rb]&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we plan to do the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
*UI testing on the deployed project&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123902</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123902"/>
		<updated>2019-04-12T22:42:37Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ &amp;quot;significantly&amp;quot; on their scoring (the threshold is specified in the &amp;quot;Notification limit&amp;quot; on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, however, it does not link to the particular review or submission which initiated the notification.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.&lt;br /&gt;
With every review submitted for an assignment of a particular student, the average is updated.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
&lt;br /&gt;
===No view to see the analyze the conflicts===&lt;br /&gt;
Currently whenever the conflict happens,a summary link is sent to the instructor which contains the score of all the views.&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Summary of all the reviews&lt;br /&gt;
[[File:SUMMARY.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which contains links to two reviews. One of which is the newly submitted review that differs by more than the notification limit where such a conflict has occurred. The email should state that a new conflicting review has been made.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
*  '''Problem''' - Inefficient calculation of conflicts: &amp;lt;br&amp;gt;&lt;br /&gt;
'''Solution:''' Instead of relying on the average, we will iterate through all previous submissions and will check conflict comparing them with the latest review. This logic will be implemented in the separate model.&lt;br /&gt;
&lt;br /&gt;
* '''Problem''' - Incorrect email message links:&amp;lt;br&amp;gt; &lt;br /&gt;
'''Solution:''' Hardcoded URLs will be managed by the config file in order to make these links functional on every server running Expertiza&lt;br /&gt;
&lt;br /&gt;
*  '''Problem''' - No separate view exist to show conflicts: &lt;br /&gt;
'''Solution:''' Separate view will be created to address this issue.&lt;br /&gt;
&lt;br /&gt;
=Files to be changed in this Project=&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/mailers/mailer.rb mailer.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/config Config File]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/response.rb response.rb]&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we plan to do the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
*UI testing on the deployed project&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123380</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123380"/>
		<updated>2019-04-06T22:00:18Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ &amp;quot;significantly&amp;quot; on their scoring (the threshold is specified in the &amp;quot;Notification limit&amp;quot; on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, however, it does not link to the particular review or submission which initiated the notification.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.&lt;br /&gt;
With every review submitted for an assignment of a particular student, the average is updated.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
===Inefficient calculation of conflicts=== &lt;br /&gt;
The existing method calculates the average of the review scores and then uses it to check if the difference between the new review score and the existing average is more than the threshold limit set. This implementation is inefficient. For example, consider two reviews with scores 0 and 5, the average score will be 2.5. Now, if the new submission is made with score 2.5, the implementation will not consider this as a conflict where it should have considered it as a conflict. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
===No separate view exist to show conflicts===&lt;br /&gt;
The existing implementation shows the conflicts in the same view of the response. Ideally, it should be rendered in a separate view.&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Summary of all the reviews&lt;br /&gt;
[[File:SUMMARY.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which contains links to two reviews. One of which is the newly submitted review that differs by more than the notification limit where such a conflict has occurred. The email should state that a new conflicting review has been made.&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
*  '''Problem''' - Inefficient calculation of conflicts: &amp;lt;br&amp;gt;&lt;br /&gt;
'''Solution:''' Instead of relying on the average, we will iterate through all previous submissions and will check conflict comparing them with the latest review. This logic will be implemented in the separate model.&lt;br /&gt;
&lt;br /&gt;
* '''Problem''' - Incorrect email message links:&amp;lt;br&amp;gt; &lt;br /&gt;
'''Solution:''' Hardcoded URLs will be managed by the config file in order to make these links functional on every server running Expertiza&lt;br /&gt;
&lt;br /&gt;
*  '''Problem''' - No separate view exist to show conflicts: &lt;br /&gt;
'''Solution:''' Separate view will be created to address this issue.&lt;br /&gt;
&lt;br /&gt;
=Files to be changed in this Project=&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/mailers/mailer.rb mailer.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/config Config File]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/response.rb response.rb]&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we plan to do the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
*UI testing on the deployed project&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;br /&gt;
&lt;br /&gt;
=Team=&lt;br /&gt;
&lt;br /&gt;
[mailto:aarya@ncsu.edu Abhishek Arya]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:bbdeshpa@ncsu.edu Bhargav Deshpande]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:uschatto@ncsu.edu Udita Chattopadhyay]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123377</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123377"/>
		<updated>2019-04-06T21:48:52Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ &amp;quot;significantly&amp;quot; on their scoring (the threshold is specified in the &amp;quot;Notification limit&amp;quot; on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, however, it does not link to the particular review or submission which initiated the notification.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.&lt;br /&gt;
With every review submitted for an assignment of a particular student, the average is updated.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
===Inefficient calculation of conflicts=== &lt;br /&gt;
The existing method calculates the average of the review scores and then uses it to check if the difference between the new review score and the existing average is more than the threshold limit set. This implementation is inefficient. For example, consider two reviews with scores 0 and 5, the average score will be 2.5. Now, if the new submission is made with score 2.5, the implementation will not consider this as a conflict where it should have considered it as a conflict. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:EMAIL.png|center]]&lt;br /&gt;
&lt;br /&gt;
===No separate view exist to show conflicts===&lt;br /&gt;
The existing implementation shows the conflicts in the same view of the response. Ideally, it should be rendered in a separate view.&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Summary of all the reviews&lt;br /&gt;
[[File:SUMMARY.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which contains links to two reviews. One of which is the newly submitted review that differs by more than the notification limit where such a conflict has occurred. The email should state that a new conflicting review has been made.&lt;br /&gt;
&lt;br /&gt;
=Files to be changed in this Project=&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/mailers/mailer.rb mailer.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/config Config File]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/response.rb response.rb]&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we plan to do the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
*UI testing on the deployed project&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:EMAIL.png&amp;diff=123376</id>
		<title>File:EMAIL.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:EMAIL.png&amp;diff=123376"/>
		<updated>2019-04-06T21:48:19Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123375</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123375"/>
		<updated>2019-04-06T21:46:05Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ &amp;quot;significantly&amp;quot; on their scoring (the threshold is specified in the &amp;quot;Notification limit&amp;quot; on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, however, it does not link to the particular review or submission which initiated the notification.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently, this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.&lt;br /&gt;
With every review submitted for an assignment of a particular student, the average is updated.&lt;br /&gt;
&lt;br /&gt;
==Flaws with the existing Implementation==&lt;br /&gt;
===Inefficient calculation of conflicts=== &lt;br /&gt;
The existing method calculates the average of the review scores and then uses it to check if the difference between the new review score and the existing average is more than the threshold limit set. This implementation is inefficient. For example, consider two reviews with scores 0 and 5, the average score will be 2.5. Now, if the new submission is made with score 2.5, the implementation will not consider this as a conflict where it should have considered it as a conflict. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Incorrect email message links===&lt;br /&gt;
The existing email body uses hardcoded URLs mentioned in models/response.rb file in the method notify_instructor_on_difference. Being hardcoded, these links wouldn't work on other servers where Expertiza is running. For Example, if the setup is done on localhost, the links will not be functional.&lt;br /&gt;
&lt;br /&gt;
[[File:Email.png]]&lt;br /&gt;
&lt;br /&gt;
===No separate view exist to show conflicts===&lt;br /&gt;
The existing implementation shows the conflicts in the same view of the response. Ideally, it should be rendered in a separate view.&lt;br /&gt;
&lt;br /&gt;
*Conflicting Review which triggered the mail&lt;br /&gt;
[[File:Score conflicting.png|center]]&lt;br /&gt;
&lt;br /&gt;
*Summary of all the reviews&lt;br /&gt;
[[File:SUMMARY.png|center]]&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which contains links to two reviews. One of which is the newly submitted review that differs by more than the notification limit where such a conflict has occurred. The email should state that a new conflicting review has been made.&lt;br /&gt;
&lt;br /&gt;
=Files to be changed in this Project=&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/mailers/mailer.rb mailer.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/config Config File]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/response.rb response.rb]&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we plan to do the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
*UI testing on the deployed project&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Score_conflicting.png&amp;diff=123374</id>
		<title>File:Score conflicting.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Score_conflicting.png&amp;diff=123374"/>
		<updated>2019-04-06T21:44:36Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:SUMMARY.png&amp;diff=123373</id>
		<title>File:SUMMARY.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:SUMMARY.png&amp;diff=123373"/>
		<updated>2019-04-06T21:43:52Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Email.png&amp;diff=123372</id>
		<title>File:Email.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Email.png&amp;diff=123372"/>
		<updated>2019-04-06T21:39:36Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: uploaded a new version of &amp;amp;quot;File:Email.png&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Flowwork.PNG&amp;diff=123371</id>
		<title>File:Flowwork.PNG</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Flowwork.PNG&amp;diff=123371"/>
		<updated>2019-04-06T21:38:11Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: uploaded a new version of &amp;amp;quot;File:Flowwork.PNG&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123366</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123366"/>
		<updated>2019-04-06T21:07:50Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ &amp;quot;significantly&amp;quot; on their scoring (the threshold is specified in the &amp;quot;Notification limit&amp;quot; on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, however, it does not link to the particular review or submission which initiated the notification.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:Flowwork.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Whenever a new review is submitted, it is compared with the average of the previously submitted reviews. If the difference between the new submission and existing average is more than the threshold limit set, then a mail is sent to the instructor.&lt;br /&gt;
With every review submitted for an assignment of a particular student, the average is updated.&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
The scope of this project is to send an email notification to instructor which contains links to two reviews. One of which is the newly submitted review that differs by more than the notification limit where such a conflict has occurred. The email should state that a new conflicting review has been made.&lt;br /&gt;
&lt;br /&gt;
=Files to be changed in this Project=&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/mailers/mailer.rb mailer.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/config Config File]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/response.rb response.rb]&lt;br /&gt;
&lt;br /&gt;
=Previous Project and its problems=&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we plan to do the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
*UI testing on the deployed project&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Flowwork.PNG&amp;diff=123365</id>
		<title>File:Flowwork.PNG</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Flowwork.PNG&amp;diff=123365"/>
		<updated>2019-04-06T21:05:21Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: uploaded a new version of &amp;amp;quot;File:Flowwork.PNG&amp;amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Flowwork.PNG&amp;diff=123364</id>
		<title>File:Flowwork.PNG</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Flowwork.PNG&amp;diff=123364"/>
		<updated>2019-04-06T21:04:02Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123359</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123359"/>
		<updated>2019-04-06T20:44:51Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ &amp;quot;significantly&amp;quot; on their scoring (the threshold is specified in the &amp;quot;Notification limit&amp;quot; on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, however, it does not link to the particular review or submission which initiated the notification. The scope of this project is to send an email notification to instructor which contains links to two reviews (one of which is the newly submitted review) that differ by more than the notification limit where such a conflict has occurred. The email should state that a new conflicting review has been made.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
Whenever a student gives a review which differs by more than the threshold limit set,then a mail is sent to the instructor.&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Files to be changed in this Project=&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/mailers/mailer.rb mailer.rb]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/tree/master/config Config File]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/blob/master/app/models/response.rb response.rb]&lt;br /&gt;
&lt;br /&gt;
=Previous Project and its problems=&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we plan to do the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
*UI testing on the deployed project&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123358</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123358"/>
		<updated>2019-04-06T20:25:13Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ &amp;quot;significantly&amp;quot; on their scoring (the threshold is specified in the &amp;quot;Notification limit&amp;quot; on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, however, it does not link to the particular review or submission which initiated the notification. The scope of this project is to send an email notification to instructor which contains links to two reviews (one of which is the newly submitted review) that differ by more than the notification limit where such a conflict has occurred. The email should state that a new conflicting review has been made.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
Currently this feature works as follows:&lt;br /&gt;
&lt;br /&gt;
Whenever a student gives a review which differs by more than the threshold limit set,then a mail is sent to the instructor.&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=UML Diagram=&lt;br /&gt;
&lt;br /&gt;
=Files to be changed in this Project=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we plan to do the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
*UI testing on the deployed project&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123357</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123357"/>
		<updated>2019-04-06T20:19:56Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ &amp;quot;significantly&amp;quot; on their scoring (the threshold is specified in the &amp;quot;Notification limit&amp;quot; on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, however, it does not link to the particular review or submission which initiated the notification. The scope of this project is to send an email notification to instructor which contains links to two reviews (one of which is the newly submitted review) that differ by more than the notification limit where such a conflict has occurred. The email should state that a new conflicting review has been made.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
&lt;br /&gt;
=UML Diagram=&lt;br /&gt;
&lt;br /&gt;
=Files to be changed in this Project=&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=Implementation=&lt;br /&gt;
&lt;br /&gt;
=Test Plan=&lt;br /&gt;
&lt;br /&gt;
To test code implementation and correctness of the modified feature, we plan to do the following tests:-&lt;br /&gt;
&lt;br /&gt;
*Run and pass existing RSpec Tests&lt;br /&gt;
*Develop New RSpec Tests for the new code&lt;br /&gt;
*UI testing on the deployed project&lt;br /&gt;
&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
==UI Testing==&lt;br /&gt;
[to be populated after coding is complete]&lt;br /&gt;
&lt;br /&gt;
=References=&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123356</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123356"/>
		<updated>2019-04-06T20:03:26Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=Problem Statement=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, however, it does not link to the particular review or submission which initiated the notification. The scope of this project is to send an email notification to instructor which contains links to two reviews (one of which is the newly submitted review) that differ by more than the notification limit where such a conflict has occurred. The email should state that a new conflicting review has been made.&lt;br /&gt;
&lt;br /&gt;
=Existing Feature Description=&lt;br /&gt;
=What needs to be done=&lt;br /&gt;
=UML Diagram=&lt;br /&gt;
=Files to be changed in this Project=&lt;br /&gt;
=Test Plan=&lt;br /&gt;
=Implementation=&lt;br /&gt;
==Rspec Testing==&lt;br /&gt;
==UI Testing==&lt;br /&gt;
=References=&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123355</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123355"/>
		<updated>2019-04-06T19:56:14Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
=''Problem Statement''=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, however, it does not link to the particular review or submission which initiated the notification. The scope of this project is to send an email notification to instructor which contains links to two reviews (one of which is the newly submitted review) that differ by more than the notification limit where such a conflict has occurred. The email should state that a new conflicting review has been made.&lt;br /&gt;
&lt;br /&gt;
=''Existing Feature Description''=&lt;br /&gt;
=''What needs to be done''=&lt;br /&gt;
=''UML Diagram''=&lt;br /&gt;
=''Files to be changed in this Project''=&lt;br /&gt;
=''Test Plan''=&lt;br /&gt;
=''Implementation''=&lt;br /&gt;
==''Rspec Testing''==&lt;br /&gt;
==''UI Testing''==&lt;br /&gt;
=''References''=&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123354</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1931. Conflict notification</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1931._Conflict_notification&amp;diff=123354"/>
		<updated>2019-04-06T19:43:14Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under ECE517 SPRING 2019 PROJECT E1931 CONFLICT NOTIFICATIONS&lt;br /&gt;
&lt;br /&gt;
='''Problem Statement'''=&lt;br /&gt;
&lt;br /&gt;
Current conflict notification sends an email to the instructor whenever two reviews for the same submission differ “significantly” on their scoring (the threshold is specified in the “Notification limit” on the Rubrics tab of assignment creation). Right now an email is sent at any such time one of these conflicts happen, however, it does not link to the particular review or submission which initiated the notification. The scope of this project is to send an email notification to instructor which contains links to two reviews (one of which is the newly submitted review) that differ by more than the notification limit where such a conflict has occurred. The email should state that a new conflicting review has been made.&lt;br /&gt;
&lt;br /&gt;
='''Existing Feature Description'''=&lt;br /&gt;
='''UML Diagram'''=&lt;br /&gt;
='''Files to be changed in this Project'''=&lt;br /&gt;
='''Test Plan'''=&lt;br /&gt;
='''Implementation'''=&lt;br /&gt;
=='''Rspec Testing'''==&lt;br /&gt;
=='''UI Testing'''==&lt;br /&gt;
='''References'''=&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122688</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1906. Refactor stage deadlines in Assignment.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122688"/>
		<updated>2019-03-30T21:42:41Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1906 OSS assignment for Spring 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
=='''Expertiza Background'''==&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application developed using Ruby on Rails Framework whose creation and maintenance is taken care of by students as well as the faculty of NCSU.It's code is available on Github [https://github.com/expertiza/expertiza Expertiza on GitHub].Expertiza allows the instructor to create and edit new as well as existing assignments.This also includes creating a wide range of topics under each assignment which students can sign up for.They can also publish surveys and reviews,view statistical results, set deadlines for assignments and make announcements.It provides a platform for students to signup for topics,form teams,view and submit assignments and give peer reviews and feedback.&lt;br /&gt;
&lt;br /&gt;
=='''Stage Deadline Background'''==&lt;br /&gt;
An assignment in Expertiza has many deadlines possible: deadlines for submission and review in each round,deadlines for signing up and dropping topics,submitting meta-reviews,etc.Depending on what the next deadline is,an Expertiza assignment is said to be in a particular kind of what is called &amp;quot;stage&amp;quot;.For example,if the next deadline(after the current time) is a submission deadline which is a DueDate object,then the assignment is said to be in a &amp;quot;submission&amp;quot; phase.&lt;br /&gt;
&lt;br /&gt;
[[File: StageBackground.png|center]]&lt;br /&gt;
&lt;br /&gt;
Depending on which stage an assignment is in, certain activities may be permissible or impermissible.For example, the default for a submission stage is to allow submission but not review,and in a review stage,the default is to allow review but not submission.These defaults may be changed by checking the relevant boxes on the Due Dates tab of assignment creation or editing.In the figure below it can be seen the &amp;quot;Other's work&amp;quot; link is grayed out as review is not permissible during submission phase.&lt;br /&gt;
&lt;br /&gt;
[[File: Statusinadeadline.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Important Links'''==&lt;br /&gt;
&lt;br /&gt;
[http://oss.flazzle.com/ Deployed_Project_Link]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/jwboykin/expertiza Expertiza_Link_for_this_Project]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1376 Pull_request_link]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
E1906 is an Expertiza based OSS project which deals basically with refactoring stage deadlines in assignment.rb file.Class assignment.rb has several methods for checking what kind of stage an assignment is in at the current time.These are:&lt;br /&gt;
&lt;br /&gt;
* current_stage_name(topic_id = nil)&lt;br /&gt;
* find_current_stage(topic_id = nil)&lt;br /&gt;
* get_current_stage(topic_id = nil)&lt;br /&gt;
* link_for_current_stage(topic_id = nil)&lt;br /&gt;
* stage_deadline(topic_id = nil)&lt;br /&gt;
&lt;br /&gt;
The goal of the project focuses on refactoring some of the above more complex methods, modifying some of the language to make it more Ruby friendly, removing some redundant code. This project is basically an attempt to make this part of the application easier to read and maintain.&lt;br /&gt;
&lt;br /&gt;
=='''Files modified in this project'''==&lt;br /&gt;
&lt;br /&gt;
*assignment.rb&lt;br /&gt;
*assignment_spec.rb&lt;br /&gt;
&lt;br /&gt;
=='''Solutions Implemented'''==&lt;br /&gt;
&lt;br /&gt;
==='''Problem 1'''===&lt;br /&gt;
&lt;br /&gt;
Multiple functions in the code were calling DueDate.get_next_due_date(self.id, topic_id). &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
A new private function next_due_date was added. Other calls to the DueDate.get_next_due_date were replaced.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #returns the next due date&lt;br /&gt;
  def next_due_date(topic_id = nil)&lt;br /&gt;
    DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*One example of refactoring &lt;br /&gt;
[[File:Duedate E1906.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 2'''===&lt;br /&gt;
&lt;br /&gt;
The above five methods were being used at various places to check if the assignment is 'Finished' which made the code very redundant. Assignment is said to be finished if the next_due_date is nil.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have created a new method &amp;quot;finished?&amp;quot; that checks if the next_due_date is nil (which means that the assignment is &amp;quot;finished&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # New function to check if the assignment is finished&lt;br /&gt;
  def finished?( topic_id = nil )&lt;br /&gt;
    next_due_date(topic_id).nil?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have called this method at all the places where previously different methods were being used to check the same thing.&lt;br /&gt;
&lt;br /&gt;
*Signup sheet table uses assignment finished? method instead of current_stage_name&lt;br /&gt;
[[File:Problem1_1.png‎|center]]&lt;br /&gt;
&lt;br /&gt;
*Use assignment finished? method where only a comparison to &amp;quot;Finished&amp;quot; was being done using get_current_stage and find_current_stage&lt;br /&gt;
[[File:Problem1_2.png|center]] [[File:Problem1_3.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 3'''===&lt;br /&gt;
&lt;br /&gt;
The check for a topic_id to be nil when it is a staggered assignment and return 'Unknown' when it is true was being done at many places.This was not following Ruby and Rails rules.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
To make the code DRY and more easy to understand,we have created a new private method &amp;quot;topic_missing?&amp;quot; to check if the topic_id is nil in case of staggered assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # Function to check if topic id is null when its a staggered assignment&lt;br /&gt;
  def topic_missing?( topic_id = nil)&lt;br /&gt;
    topic_id.nil? and self.staggered_deadline?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactoring with new method topic_missing?&lt;br /&gt;
&lt;br /&gt;
[[File:Topic missing.png|center]]&lt;br /&gt;
&lt;br /&gt;
*stage_deadline( topic_id = nil) changed according to the modifications done&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the next stage deadline date and nil if its finished assignment &lt;br /&gt;
  def stage_deadline(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    return nil if finished?(topic_id)&lt;br /&gt;
    next_due_date(topic_id).due_at.to_s&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Problem 4'''===&lt;br /&gt;
&lt;br /&gt;
find_current_stage(topic_id=nil) method is being used only locally in the assignment.rb and once in the student_teams controller to check to check whether to display or not the reviews option for team members.This method was calling another function to get the next_due_date for an assignment that was like nesting of calls and not very Ruby standard.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have removed this function and replaced it with finished? method in the student_teams controller(shown in screenshot above in Problem 2) and with DueDate.get_next_due_date where the next due date was required.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Before :&lt;br /&gt;
 due_date = find_current_stage(topic_id)&lt;br /&gt;
 &lt;br /&gt;
 After :&lt;br /&gt;
 due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Problem 5'''===&lt;br /&gt;
&lt;br /&gt;
get_current_stage method is returning the stage name which the assignment is in at current time.This is not very clear from the name of the method.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have changed the method name to current_stage_name(topic_id=nil) to make it more clear to understand.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the current stage name of the assignment&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = next_due_date(topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactored get_current_stage with current_stage_name&lt;br /&gt;
&lt;br /&gt;
[[File:Current stage name new.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 6'''===&lt;br /&gt;
&lt;br /&gt;
current_stage_name(topic_id=nil)[This is the initial one] method was implementing things which was already being done by other methods and thus this method was redundant. &lt;br /&gt;
The initial code given was:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if self.staggered_deadline?&lt;br /&gt;
      return (topic_id.nil? ? 'Unknown' : get_current_stage(topic_id))&lt;br /&gt;
    end&lt;br /&gt;
    due_date = find_current_stage(topic_id)&lt;br /&gt;
&lt;br /&gt;
    unless self.staggered_deadline?&lt;br /&gt;
      if due_date != 'Finished' &amp;amp;&amp;amp; !due_date.nil? &amp;amp;&amp;amp; !due_date.deadline_name.nil?&lt;br /&gt;
        return due_date.deadline_name&lt;br /&gt;
      else&lt;br /&gt;
        return get_current_stage(topic_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First thing we noticed was that due_date.deadline_name was always nil because there was no field to enter the deadline name on the form, and therefore, the statement  &amp;lt;pre&amp;gt; return due_date.deadline_name &amp;lt;/pre&amp;gt; was never getting executed. &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
This method was checking for the due_date.deadline_name which was always nil. After removing the dead code, we get:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if topic_missing?(topic_id)&lt;br /&gt;
      return 'Unknown'&lt;br /&gt;
    else&lt;br /&gt;
      get_current_stage(topic_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Looking at the current_stage_name(topic_id=nil)[New one] method shown below and comparing it to what we have above, this code was surely redundant.That is why we removed this code and made appropriate changes wherever required within assignment.rb.&lt;br /&gt;
*Below is the current_stage_name method for reference&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the current stage name of the assignment&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = next_due_date(topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The associated rspec tests that tested the old current_stage_name method were also no longer needed.&lt;br /&gt;
&lt;br /&gt;
==='''Problem 7'''===&lt;br /&gt;
&lt;br /&gt;
link_for_current_stage function served no purpose. The function checked to see if any given due date had a link (presumably web URL) and would return it. The database had no values and there is no where in the application this URL could be provided. There doesn't appear to be any use for having a separate URL for each stage.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
Removed function. &lt;br /&gt;
&lt;br /&gt;
[[File:Big1.png|center]]&lt;br /&gt;
&lt;br /&gt;
Removed test related to the function. Removed the one call to this function.&lt;br /&gt;
&lt;br /&gt;
[[File:big2.png|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Automated Testing using RSPEC'''==&lt;br /&gt;
&lt;br /&gt;
We have created and modified the tests as per the changes done in our project.We have added the tests to the file [https://github.com/jwboykin/expertiza/blob/master/spec/models/assignment_spec.rb expertiza/spec/models/assignment_spec.rb] and they are passing 100%.&lt;br /&gt;
&lt;br /&gt;
===='''Tests for get_current_stage_name'''====&lt;br /&gt;
&lt;br /&gt;
The current version of expertiza did not have any tests for get_current_stage(topic_id=nil) method.Now as we have changed it to current_stage_name(topic_id=nil),we have added its tests as well.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#current_stage_name' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.current_stage_name).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns Finished' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Finished')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns current stage name' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:topic_missing?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          deadline = create(:deadline_type, id: 1, name:&amp;quot;Review&amp;quot;)&lt;br /&gt;
          allow(DeadlineType).to receive(:find).with(1).and_return(deadline)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Review')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===='''Tests for finished?'''====&lt;br /&gt;
&lt;br /&gt;
We have added tests for the new method that we have added finished?.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when assignment next due date is nil' do&lt;br /&gt;
      it 'returns True' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1, 123).and_return(nil)&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when there is a next due date' do&lt;br /&gt;
      it 'returns False' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1,123).and_return('2021-11-11 11:11:11')&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(false)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As topic_missing? method is made private,there was no need to test this.&lt;br /&gt;
&lt;br /&gt;
===='''Tests for stage_deadline'''====&lt;br /&gt;
&lt;br /&gt;
We also have corrected the tests for stage_deadline according to the modifications done(It is using finished? and topic_missing? methods).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#stage_deadline' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.stage_deadline).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns nil' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to be nil&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns due date' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to match('2011-11-11 11:11:11')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Team'''==&lt;br /&gt;
&lt;br /&gt;
[mailto:jwboykin@ncsu.edu Jimmy Boykin]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:sbasnet2@ncsu.edu Sushan Basnet]&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122555</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1906. Refactor stage deadlines in Assignment.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122555"/>
		<updated>2019-03-27T05:30:08Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1906 OSS assignment for Spring 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
=='''Expertiza Background'''==&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application developed using Ruby on Rails Framework whose creation and maintenance is taken care of by students as well as the faculty of NCSU.It's code is available on Github [https://github.com/expertiza/expertiza Expertiza on GitHub].Expertiza allows the instructor to create and edit new as well as existing assignments.This also includes creating a wide range of topics under each assignment which students can sign up for.They can also publish surveys and reviews,view statistical results, set deadlines for assignments and make announcements.It provides a platform for students to signup for topics,form teams,view and submit assignments and give peer reviews and feedback.&lt;br /&gt;
&lt;br /&gt;
=='''Stage Deadline Background'''==&lt;br /&gt;
An assignment in Expertiza has many deadlines possible: deadlines for submission and review in each round,deadlines for signing up and dropping topics,submitting meta-reviews,etc.Depending on what the next deadline is,an Expertiza assignment is said to be in a particular kind of what is called &amp;quot;stage&amp;quot;.For example,if the next deadline(after the current time) is a submission deadline which is a DueDate object,then the assignment is said to be in a &amp;quot;submission&amp;quot; phase.&lt;br /&gt;
&lt;br /&gt;
[[File: StageBackground.png|center]]&lt;br /&gt;
&lt;br /&gt;
Depending on which stage an assignment is in, certain activities may be permissible or impermissible.For example, the default for a submission stage is to allow submission but not review,and in a review stage,the default is to allow review but not submission.These defaults may be changed by checking the relevant boxes on the Due Dates tab of assignment creation or editing.In the figure below it can be seen the &amp;quot;Other's work&amp;quot; link is grayed out as review is not permissible during submission phase.&lt;br /&gt;
&lt;br /&gt;
[[File: Statusinadeadline.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Important Links'''==&lt;br /&gt;
&lt;br /&gt;
[http://oss.flazzle.com/ Deployed_Project_Link]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/jwboykin/expertiza Expertiza_Link_for_this_Project]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1376 Pull_request_link]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
E1906 is an Expertiza based OSS project which deals basically with refactoring stage deadlines in assignment.rb file.Class assignment.rb has several methods for checking what kind of stage an assignment is in at the current time.These are:&lt;br /&gt;
&lt;br /&gt;
* current_stage_name(topic_id = nil)&lt;br /&gt;
* find_current_stage(topic_id = nil)&lt;br /&gt;
* get_current_stage(topic_id = nil)&lt;br /&gt;
* link_for_current_stage(topic_id = nil)&lt;br /&gt;
* stage_deadline(topic_id = nil)&lt;br /&gt;
&lt;br /&gt;
The goal of the project focuses on refactoring some of the above more complex methods, modifying some of the language to make it more Ruby friendly, removing some redundant code. This project is basically an attempt to make this part of the application easier to read and maintain.&lt;br /&gt;
&lt;br /&gt;
=='''Solutions Implemented'''==&lt;br /&gt;
&lt;br /&gt;
==='''Problem 1'''===&lt;br /&gt;
&lt;br /&gt;
Multiple functions in the code were calling DueDate.get_next_due_date(self.id, topic_id). &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
A new private function next_due_date was added. Other calls to the DueDate.get_next_due_date were replaced.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #returns the next due date&lt;br /&gt;
  def next_due_date(topic_id = nil)&lt;br /&gt;
    DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*One example of refactoring &lt;br /&gt;
[[File:Duedate E1906.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 2'''===&lt;br /&gt;
&lt;br /&gt;
The above five methods were being used at various places to check if the assignment is 'Finished' which made the code very redundant. Assignment is said to be finished if the next_due_date is nil.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have created a new method &amp;quot;finished?&amp;quot; that checks if the next_due_date is nil (which means that the assignment is &amp;quot;finished&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # New function to check if the assignment is finished&lt;br /&gt;
  def finished?( topic_id = nil )&lt;br /&gt;
    next_due_date(topic_id).nil?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have called this method at all the places where previously different methods were being used to check the same thing.&lt;br /&gt;
&lt;br /&gt;
*Signup sheet table uses assignment finished? method instead of current_stage_name&lt;br /&gt;
[[File:Problem1_1.png‎|center]]&lt;br /&gt;
&lt;br /&gt;
*Use assignment finished? method where only a comparison to &amp;quot;Finished&amp;quot; was being done using get_current_stage and find_current_stage&lt;br /&gt;
[[File:Problem1_2.png|center]] [[File:Problem1_3.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 3'''===&lt;br /&gt;
&lt;br /&gt;
The check for a topic_id to be nil when it is a staggered assignment and return 'Unknown' when it is true was being done at many places.This was not following Ruby and Rails rules.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
To make the code DRY and more easy to understand,we have created a new private method &amp;quot;topic_missing?&amp;quot; to check if the topic_id is nil in case of staggered assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # Function to check if topic id is null when its a staggered assignment&lt;br /&gt;
  def topic_missing?( topic_id = nil)&lt;br /&gt;
    topic_id.nil? and self.staggered_deadline?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactoring with new method topic_missing?&lt;br /&gt;
&lt;br /&gt;
[[File:Topic missing.png|center]]&lt;br /&gt;
&lt;br /&gt;
*stage_deadline( topic_id = nil) changed according to the modifications done&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the next stage deadline date and nil if its finished assignment &lt;br /&gt;
  def stage_deadline(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    return nil if finished?(topic_id)&lt;br /&gt;
    next_due_date(topic_id).due_at.to_s&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Problem 4'''===&lt;br /&gt;
&lt;br /&gt;
find_current_stage(topic_id=nil) method is being used only locally in the assignment.rb and once in the student_teams controller to check to check whether to display or not the reviews option for team members.This method was calling another function to get the next_due_date for an assignment that was like nesting of calls and not very Ruby standard.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have removed this function and replaced it with finished? method in the student_teams controller(shown in screenshot above in Problem 2) and with DueDate.get_next_due_date where the next due date was required.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Before :&lt;br /&gt;
 due_date = find_current_stage(topic_id)&lt;br /&gt;
 &lt;br /&gt;
 After :&lt;br /&gt;
 due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Problem 5'''===&lt;br /&gt;
&lt;br /&gt;
get_current_stage method is returning the stage name which the assignment is in at current time.This is not very clear from the name of the method.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have changed the method name to current_stage_name(topic_id=nil) to make it more clear to understand.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the current stage name of the assignment&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = next_due_date(topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactored get_current_stage with current_stage_name&lt;br /&gt;
&lt;br /&gt;
[[File:Current stage name new.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 6'''===&lt;br /&gt;
&lt;br /&gt;
current_stage_name(topic_id=nil)[This is the initial one] method was implementing things which was already being done by other methods and thus this method was redundant. &lt;br /&gt;
The initial code given was:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if self.staggered_deadline?&lt;br /&gt;
      return (topic_id.nil? ? 'Unknown' : get_current_stage(topic_id))&lt;br /&gt;
    end&lt;br /&gt;
    due_date = find_current_stage(topic_id)&lt;br /&gt;
&lt;br /&gt;
    unless self.staggered_deadline?&lt;br /&gt;
      if due_date != 'Finished' &amp;amp;&amp;amp; !due_date.nil? &amp;amp;&amp;amp; !due_date.deadline_name.nil?&lt;br /&gt;
        return due_date.deadline_name&lt;br /&gt;
      else&lt;br /&gt;
        return get_current_stage(topic_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First thing we noticed was that due_date.deadline_name was always nil because there was no field to enter the deadline name on the form, and therefore, the statement  &amp;lt;pre&amp;gt; return due_date.deadline_name &amp;lt;/pre&amp;gt; was never getting executed. &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
This method was checking for the due_date.deadline_name which was always nil. After removing the dead code, we get:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if topic_missing?(topic_id)&lt;br /&gt;
      return 'Unknown'&lt;br /&gt;
    else&lt;br /&gt;
      get_current_stage(topic_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Looking at the current_stage_name(topic_id=nil)[New one] method shown below and comparing it to what we have above, this code was surely redundant.That is why we removed this code and made appropriate changes wherever required within assignment.rb.&lt;br /&gt;
*Below is the current_stage_name method for reference&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the current stage name of the assignment&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = next_due_date(topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The associated rspec tests that tested the old current_stage_name method were also no longer needed.&lt;br /&gt;
&lt;br /&gt;
==='''Problem 7'''===&lt;br /&gt;
&lt;br /&gt;
link_for_current_stage function served no purpose. The function checked to see if any given due date had a link (presumably web URL) and would return it. The database had no values and there is no where in the application this URL could be provided. There doesn't appear to be any use for having a separate URL for each stage.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
Removed function. &lt;br /&gt;
&lt;br /&gt;
[[File:Big1.png|center]]&lt;br /&gt;
&lt;br /&gt;
Removed test related to the function. Removed the one call to this function.&lt;br /&gt;
&lt;br /&gt;
[[File:big2.png|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Automated Testing using RSPEC'''==&lt;br /&gt;
&lt;br /&gt;
We have created and modified the tests as per the changes done in our project.We have added the tests to the file [https://github.com/jwboykin/expertiza/blob/master/spec/models/assignment_spec.rb expertiza/spec/models/assignment_spec.rb] and they are passing 100%.&lt;br /&gt;
&lt;br /&gt;
===='''Tests for get_current_stage_name'''====&lt;br /&gt;
&lt;br /&gt;
The current version of expertiza did not have any tests for get_current_stage(topic_id=nil) method.Now as we have changed it to current_stage_name(topic_id=nil),we have added its tests as well.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#current_stage_name' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.current_stage_name).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns Finished' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Finished')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns current stage name' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:topic_missing?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          deadline = create(:deadline_type, id: 1, name:&amp;quot;Review&amp;quot;)&lt;br /&gt;
          allow(DeadlineType).to receive(:find).with(1).and_return(deadline)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Review')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===='''Tests for finished?'''====&lt;br /&gt;
&lt;br /&gt;
We have added tests for the new method that we have added finished?.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when assignment next due date is nil' do&lt;br /&gt;
      it 'returns True' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1, 123).and_return(nil)&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when there is a next due date' do&lt;br /&gt;
      it 'returns False' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1,123).and_return('2021-11-11 11:11:11')&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(false)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As topic_missing? method is made private,there was no need to test this.&lt;br /&gt;
&lt;br /&gt;
===='''Tests for stage_deadline'''====&lt;br /&gt;
&lt;br /&gt;
We also have corrected the tests for stage_deadline according to the modifications done(It is using finished? and topic_missing? methods).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#stage_deadline' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.stage_deadline).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns nil' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to be nil&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns due date' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to match('2011-11-11 11:11:11')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Team'''==&lt;br /&gt;
&lt;br /&gt;
[mailto:jwboykin@ncsu.edu Jimmy Boykin]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:sbasnet2@ncsu.edu Sushan Basnet]&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122361</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1906. Refactor stage deadlines in Assignment.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122361"/>
		<updated>2019-03-26T00:52:21Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1906 OSS assignment for Spring 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
=='''Expertiza Background'''==&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application developed using Ruby on Rails Framework whose creation and maintenance is taken care of by students as well as the faculty of NCSU.It's code is available on Github [https://github.com/expertiza/expertiza Expertiza on GitHub].Expertiza allows the instructor to create and edit new as well as existing assignments.This also includes creating a wide range of topics under each assignment which students can sign up for.They can also publish surveys and reviews,view statistical results, set deadlines for assignments and make announcements.It provides a platform for students to signup for topics,form teams,view and submit assignments and give peer reviews and feedback.&lt;br /&gt;
&lt;br /&gt;
=='''Stage Deadline Background'''==&lt;br /&gt;
An assignment in Expertiza has many deadlines possible: deadlines for submission and review in each round,deadlines for signing up and dropping topics,submitting meta-reviews,etc.Depending on what the next deadline is,an Expertiza assignment is said to be in a particular kind of what is called &amp;quot;stage&amp;quot;.For example,if the next deadline(after the current time) is a submission deadline which is a DueDate object,then the assignment is said to be in a &amp;quot;submission&amp;quot; phase.&lt;br /&gt;
&lt;br /&gt;
[[File: StageBackground.png|center]]&lt;br /&gt;
&lt;br /&gt;
Depending on which stage an assignment is in, certain activities may be permissible or impermissible.For example, the default for a submission stage is to allow submission but not review,and in a review stage,the default is to allow review but not submission.These defaults may be changed by checking the relevant boxes on the Due Dates tab of assignment creation or editing.In the figure below it can be seen the &amp;quot;Other's work&amp;quot; link is grayed out as review is not permissible during submission phase.&lt;br /&gt;
&lt;br /&gt;
[[File: Statusinadeadline.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Important Links'''==&lt;br /&gt;
&lt;br /&gt;
[http://oss.flazzle.com/ Deployed_Project_Link]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/jwboykin/expertiza Expertiza_Link_for_this_Project]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1376 Pull_request_link]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
E1906 is an Expertiza based OSS project which deals basically with refactoring stage deadlines in assignment.rb file.Class assignment.rb has several methods for checking what kind of stage an assignment is in at the current time.These are:&lt;br /&gt;
&lt;br /&gt;
* current_stage_name(topic_id = nil)&lt;br /&gt;
* find_current_stage(topic_id = nil)&lt;br /&gt;
* get_current_stage(topic_id = nil)&lt;br /&gt;
* link_for_current_stage(topic_id = nil)&lt;br /&gt;
* stage_deadline(topic_id = nil)&lt;br /&gt;
&lt;br /&gt;
The goal of the project focuses on refactoring some of the above more complex methods, modifying some of the language to make it more Ruby friendly, removing some redundant code. This project is basically an attempt to make this part of the application easier to read and maintain.&lt;br /&gt;
&lt;br /&gt;
=='''Solutions Implemented'''==&lt;br /&gt;
&lt;br /&gt;
==='''Problem 1'''===&lt;br /&gt;
&lt;br /&gt;
Multiple functions in the code were calling DueDate.get_next_due_date(self.id, topic_id). &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
A new private function next_due_date was added. Other calls to the DueDate.get_next_due_date were replaced.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #returns the next due date&lt;br /&gt;
  def next_due_date(topic_id = nil)&lt;br /&gt;
    DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*One example of refactoring &lt;br /&gt;
[[File:Duedate E1906.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 2'''===&lt;br /&gt;
&lt;br /&gt;
The above five methods were being used at various places to check if the assignment is 'Finished' which made the code very redundant. Assignment is said to be finished if the next_due_date is nil.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have created a new method &amp;quot;finished?&amp;quot; that checks if the next_due_date is nil (which means that the assignment is &amp;quot;finished&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # New function to check if the assignment is finished&lt;br /&gt;
  def finished?( topic_id = nil )&lt;br /&gt;
    next_due_date(topic_id).nil?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have called this method at all the places where previously different methods were being used to check the same thing.&lt;br /&gt;
&lt;br /&gt;
*Signup sheet table uses assignment finished? method instead of current_stage_name&lt;br /&gt;
[[File:Problem1_1.png‎|center]]&lt;br /&gt;
&lt;br /&gt;
*Use assignment finished? method where only a comparison to &amp;quot;Finished&amp;quot; was being done using get_current_stage and find_current_stage&lt;br /&gt;
[[File:Problem1_2.png|center]] [[File:Problem1_3.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 3'''===&lt;br /&gt;
&lt;br /&gt;
The check for a topic_id to be nil when it is a staggered assignment and return 'Unknown' when it is true was being done at many places.This was not following Ruby and Rails rules.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
To make the code DRY and more easy to understand,we have created a new private method &amp;quot;topic_missing?&amp;quot; to check if the topic_id is nil in case of staggered assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # Function to check if topic id is null when its a staggered assignment&lt;br /&gt;
  def topic_missing?( topic_id = nil)&lt;br /&gt;
    topic_id.nil? and self.staggered_deadline?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactoring with new method topic_missing?&lt;br /&gt;
&lt;br /&gt;
[[File:Topic missing.png|center]]&lt;br /&gt;
&lt;br /&gt;
*stage_deadline( topic_id = nil) changed according to the modifications done&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the next stage deadline date and nil if its finished assignment &lt;br /&gt;
  def stage_deadline(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    return nil if finished?(topic_id)&lt;br /&gt;
    next_due_date(topic_id).due_at.to_s&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Problem 4'''===&lt;br /&gt;
&lt;br /&gt;
find_current_stage(topic_id=nil) method is being used only locally in the assignment.rb and once in the student_teams controller to check to check whether to display or not the reviews option for team members.This method was calling another function to get the next_due_date for an assignment that was like nesting of calls and not very Ruby standard.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have removed this function and replaced it with finished? method in the student_teams controller(shown in screenshot above in Problem 2) and with DueDate.get_next_due_date where the next due date was required.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Before :&lt;br /&gt;
 due_date = find_current_stage(topic_id)&lt;br /&gt;
 &lt;br /&gt;
 After :&lt;br /&gt;
 due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Problem 5'''===&lt;br /&gt;
&lt;br /&gt;
get_current_stage method is returning the stage name which the assignment is in at current time.This is not very clear from the name of the method.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have changed the method name to current_stage_name(topic_id=nil) to make it more clear to understand.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the current stage name of the assignment&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = next_due_date(topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactored get_current_stage with current_stage_name&lt;br /&gt;
&lt;br /&gt;
[[File:Current stage name new.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 6'''===&lt;br /&gt;
&lt;br /&gt;
current_stage_name(topic_id=nil)[This is the initial one] method was implementing things which was already being done by other methods and thus this method was redundant. &lt;br /&gt;
The initial code given was:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if self.staggered_deadline?&lt;br /&gt;
      return (topic_id.nil? ? 'Unknown' : get_current_stage(topic_id))&lt;br /&gt;
    end&lt;br /&gt;
    due_date = find_current_stage(topic_id)&lt;br /&gt;
&lt;br /&gt;
    unless self.staggered_deadline?&lt;br /&gt;
      if due_date != 'Finished' &amp;amp;&amp;amp; !due_date.nil? &amp;amp;&amp;amp; !due_date.deadline_name.nil?&lt;br /&gt;
        return due_date.deadline_name&lt;br /&gt;
      else&lt;br /&gt;
        return get_current_stage(topic_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First thing we noticed was that due_date.deadline_name was always nil because there was no field to enter the deadline name on the form, and therefore, the statement  &amp;lt;pre&amp;gt; return due_date.deadline_name &amp;lt;/pre&amp;gt; was never getting executed. &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
This method was checking for the due_date.deadline_name which was always nil. After removing the dead code, we get:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if topic_missing?(topic_id)&lt;br /&gt;
      return 'Unknown'&lt;br /&gt;
    else&lt;br /&gt;
      get_current_stage(topic_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Looking at the current_stage_name(topic_id=nil)[New one] method shown below and comparing it to what we have above, this code was surely redundant.That is why we removed this code and made appropriate changes wherever required within assignment.rb.&lt;br /&gt;
*Below is the current_stage_name method for reference&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the current stage name of the assignment&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = next_due_date(topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The associated rspec tests that tested the old current_stage_name method were also no longer needed.&lt;br /&gt;
&lt;br /&gt;
==='''Problem 7'''===&lt;br /&gt;
&lt;br /&gt;
link_for_current_stage function served no purpose. The function checked to see if any given due date had a link (presumably web URL) and would return it. The database had no values and there is no where in the application this URL could be provided. There doesn't appear to be any use for having a separate URL for each stage.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
Removed function. &lt;br /&gt;
&lt;br /&gt;
[[File:Big1.png|center]]&lt;br /&gt;
&lt;br /&gt;
Removed test related to the function. Removed the one call to this function.&lt;br /&gt;
&lt;br /&gt;
[[File:big2.png|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Automated Testing using RSPEC'''==&lt;br /&gt;
&lt;br /&gt;
===='''Tests for get_current_stage_name'''====&lt;br /&gt;
&lt;br /&gt;
The current version of expertiza did not have any tests for get_current_stage(topic_id=nil) method.Now as we have changed it to current_stage_name(topic_id=nil),we have added its tests as well.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#current_stage_name' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.current_stage_name).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns Finished' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Finished')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns current stage name' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:topic_missing?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          deadline = create(:deadline_type, id: 1, name:&amp;quot;Review&amp;quot;)&lt;br /&gt;
          allow(DeadlineType).to receive(:find).with(1).and_return(deadline)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Review')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===='''Tests for finished?'''====&lt;br /&gt;
&lt;br /&gt;
We have added tests for the new method that we have added finished?.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when assignment next due date is nil' do&lt;br /&gt;
      it 'returns True' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1, 123).and_return(nil)&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when there is a next due date' do&lt;br /&gt;
      it 'returns False' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1,123).and_return('2021-11-11 11:11:11')&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(false)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As topic_missing? method is made private,there was no need to test this.&lt;br /&gt;
&lt;br /&gt;
===='''Tests for stage_deadline'''====&lt;br /&gt;
&lt;br /&gt;
We also have corrected the tests for stage_deadline according to the modifications done(It is using finished? and topic_missing? methods).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#stage_deadline' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.stage_deadline).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns nil' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to be nil&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns due date' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to match('2011-11-11 11:11:11')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Team'''==&lt;br /&gt;
&lt;br /&gt;
[mailto:jwboykin@ncsu.edu Jimmy Boykin]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:sbasnet2@ncsu.edu Sushan Basnet]&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122297</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1906. Refactor stage deadlines in Assignment.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122297"/>
		<updated>2019-03-25T23:26:48Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1906 OSS assignment for Spring 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
=='''Expertiza Background'''==&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application developed using Ruby on Rails Framework whose creation and maintenance is taken care of by students as well as the faculty of NCSU.It's code is available on Github [https://github.com/expertiza/expertiza Expertiza on GitHub].Expertiza allows the instructor to create and edit new as well as existing assignments.This also includes creating a wide range of topics under each assignment which students can sign up for.They can also publish surveys and reviews,view statistical results, set deadlines for assignments and make announcements.It provides a platform for students to signup for topics,form teams,view and submit assignments and give peer reviews and feedback.&lt;br /&gt;
&lt;br /&gt;
=='''Stage Deadline Background'''==&lt;br /&gt;
An assignment in Expertiza has many deadlines possible: deadlines for submission and review in each round,deadlines for signing up and dropping topics,submitting meta-reviews,etc.Depending on what the next deadline is,an Expertiza assignment is said to be in a particular kind of what is called &amp;quot;stage&amp;quot;.For example,if the next deadline(after the current time) is a submission deadline which is a DueDate object,then the assignment is said to be in a &amp;quot;submission&amp;quot; phase.&lt;br /&gt;
&lt;br /&gt;
[[File: StageBackground.png|center]]&lt;br /&gt;
&lt;br /&gt;
Depending on which stage an assignment is in, certain activities may be permissible or impermissible.For example, the default for a submission stage is to allow submission but not review,and in a review stage,the default is to allow review but not submission.These defaults may be changed by checking the relevant boxes on the Due Dates tab of assignment creation or editing.In the figure below it can be seen the &amp;quot;Other's work&amp;quot; link is grayed out as review is not permissible during submission phase.&lt;br /&gt;
&lt;br /&gt;
[[File: Statusinadeadline.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Important Links'''==&lt;br /&gt;
&lt;br /&gt;
[http://oss.flazzle.com/ Deployed_Project_Link]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/jwboykin/expertiza Expertiza_Link_for_this_Project]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
E1906 is an Expertiza based OSS project which deals basically with refactoring stage deadlines in assignment.rb file.Class assignment.rb has several methods for checking what kind of stage an assignment is in at the current time.These are:&lt;br /&gt;
&lt;br /&gt;
* current_stage_name(topic_id = nil)&lt;br /&gt;
* find_current_stage(topic_id = nil)&lt;br /&gt;
* get_current_stage(topic_id = nil)&lt;br /&gt;
* link_for_current_stage(topic_id = nil)&lt;br /&gt;
* stage_deadline(topic_id = nil)&lt;br /&gt;
&lt;br /&gt;
The goal of the project focuses on refactoring some of the above more complex methods, modifying some of the language to make it more Ruby friendly, removing some redundant code. This project is basically an attempt to make this part of the application easier to read and maintain.&lt;br /&gt;
&lt;br /&gt;
=='''Solutions Implemented'''==&lt;br /&gt;
&lt;br /&gt;
==='''Problem 1'''===&lt;br /&gt;
&lt;br /&gt;
Multiple functions in the code were calling DueDate.get_next_due_date(self.id, topic_id). &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
A new private function next_due_date was added. Other calls to the DueDate.get_next_due_date were replaced.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #returns the next due date&lt;br /&gt;
  def next_due_date(topic_id = nil)&lt;br /&gt;
    DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*One example of refactoring &lt;br /&gt;
[[File:Duedate E1906.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 2'''===&lt;br /&gt;
&lt;br /&gt;
The above five methods were being used at various places to check if the assignment is 'Finished' which made the code very redundant. Assignment is said to be finished if the next_due_date is nil.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have created a new method &amp;quot;finished?&amp;quot; that checks if the next_due_date is nil (which means that the assignment is &amp;quot;finished&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # New function to check if the assignment is finished&lt;br /&gt;
  def finished?( topic_id = nil )&lt;br /&gt;
    next_due_date(topic_id).nil?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have called this method at all the places where previously different methods were being used to check the same thing.&lt;br /&gt;
&lt;br /&gt;
*Signup sheet table uses assignment finished? method instead of current_stage_name&lt;br /&gt;
[[File:Problem1_1.png‎|center]]&lt;br /&gt;
&lt;br /&gt;
*Use assignment finished? method where only a comparison to &amp;quot;Finished&amp;quot; was being done using get_current_stage and find_current_stage&lt;br /&gt;
[[File:Problem1_2.png|center]] [[File:Problem1_3.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 3'''===&lt;br /&gt;
&lt;br /&gt;
The check for a topic_id to be nil when it is a staggered assignment and return 'Unknown' when it is true was being done at many places.This was not following Ruby and Rails rules.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
To make the code DRY and more easy to understand,we have created a new private method &amp;quot;topic_missing?&amp;quot; to check if the topic_id is nil in case of staggered assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # Function to check if topic id is null when its a staggered assignment&lt;br /&gt;
  def topic_missing?( topic_id = nil)&lt;br /&gt;
    topic_id.nil? and self.staggered_deadline?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactoring with new method topic_missing?&lt;br /&gt;
&lt;br /&gt;
[[File:Topic missing.png|center]]&lt;br /&gt;
&lt;br /&gt;
*stage_deadline( topic_id = nil) changed according to the modifications done&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the next stage deadline date and nil if its finished assignment &lt;br /&gt;
  def stage_deadline(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    return nil if finished?(topic_id)&lt;br /&gt;
    next_due_date(topic_id).due_at.to_s&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Problem 4'''===&lt;br /&gt;
&lt;br /&gt;
find_current_stage(topic_id=nil) method is being used only locally in the assignment.rb and once in the student_teams controller to check to check whether to display or not the reviews option for team members.This method was calling another function to get the next_due_date for an assignment that was like nesting of calls and not very Ruby standard.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have removed this function and replaced it with finished? method in the student_teams controller(shown in screenshot above in Problem 2) and with DueDate.get_next_due_date where the next due date was required.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Before :&lt;br /&gt;
 due_date = find_current_stage(topic_id)&lt;br /&gt;
 &lt;br /&gt;
 After :&lt;br /&gt;
 due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Problem 5'''===&lt;br /&gt;
&lt;br /&gt;
get_current_stage method is returning the stage name which the assignment is in at current time.This is not very clear from the name of the method.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have changed the method name to current_stage_name(topic_id=nil) to make it more clear to understand.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the current stage name of the assignment&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = next_due_date(topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactored get_current_stage with current_stage_name&lt;br /&gt;
&lt;br /&gt;
[[File:Current stage name new.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 6'''===&lt;br /&gt;
&lt;br /&gt;
current_stage_name(topic_id=nil)[This is the initial one] method was implementing things which was already being done by other methods and thus this method was redundant. &lt;br /&gt;
The initial code given was:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if self.staggered_deadline?&lt;br /&gt;
      return (topic_id.nil? ? 'Unknown' : get_current_stage(topic_id))&lt;br /&gt;
    end&lt;br /&gt;
    due_date = find_current_stage(topic_id)&lt;br /&gt;
&lt;br /&gt;
    unless self.staggered_deadline?&lt;br /&gt;
      if due_date != 'Finished' &amp;amp;&amp;amp; !due_date.nil? &amp;amp;&amp;amp; !due_date.deadline_name.nil?&lt;br /&gt;
        return due_date.deadline_name&lt;br /&gt;
      else&lt;br /&gt;
        return get_current_stage(topic_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First thing we noticed was that due_date.deadline_name was always nil because there was no field to enter the deadline name on the form, and therefore, the statement  &amp;lt;pre&amp;gt; return due_date.deadline_name &amp;lt;/pre&amp;gt; was never getting executed. &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
This method was checking for the due_date.deadline_name which was always nil. After removing the dead code, we get:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if topic_missing?(topic_id)&lt;br /&gt;
      return 'Unknown'&lt;br /&gt;
    else&lt;br /&gt;
      get_current_stage(topic_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Looking at the current_stage_name(topic_id=nil)[New one] method shown below and comparing it to what we have above, this code was surely redundant.That is why we removed this code and made appropriate changes wherever required within assignment.rb.&lt;br /&gt;
*Below is the current_stage_name method for reference&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the current stage name of the assignment&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = next_due_date(topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The associated rspec tests that tested the old current_stage_name method were also no longer needed.&lt;br /&gt;
&lt;br /&gt;
==='''Problem 7'''===&lt;br /&gt;
&lt;br /&gt;
link_for_current_stage function served no purpose. The function checked to see if any given due date had a link (presumably web URL) and would return it. The database had no values and there is no where in the application this URL could be provided. There doesn't appear to be any use for having a separate URL for each stage.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
Removed function. &lt;br /&gt;
&lt;br /&gt;
[[File:Big1.png|center]]&lt;br /&gt;
&lt;br /&gt;
Removed test related to the function. Removed the one call to this function.&lt;br /&gt;
&lt;br /&gt;
[[File:big2.png|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Automated Testing using RSPEC'''==&lt;br /&gt;
&lt;br /&gt;
===='''Tests for get_current_stage_name'''====&lt;br /&gt;
&lt;br /&gt;
The current version of expertiza did not have any tests for get_current_stage(topic_id=nil) method.Now as we have changed it to current_stage_name(topic_id=nil),we have added its tests as well.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#current_stage_name' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.current_stage_name).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns Finished' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Finished')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns current stage name' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:topic_missing?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          deadline = create(:deadline_type, id: 1, name:&amp;quot;Review&amp;quot;)&lt;br /&gt;
          allow(DeadlineType).to receive(:find).with(1).and_return(deadline)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Review')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===='''Tests for finished?'''====&lt;br /&gt;
&lt;br /&gt;
We have added tests for the new method that we have added finished?.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when assignment next due date is nil' do&lt;br /&gt;
      it 'returns True' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1, 123).and_return(nil)&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when there is a next due date' do&lt;br /&gt;
      it 'returns False' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1,123).and_return('2021-11-11 11:11:11')&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(false)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As topic_missing? method is made private,there was no need to test this.&lt;br /&gt;
&lt;br /&gt;
===='''Tests for stage_deadline'''====&lt;br /&gt;
&lt;br /&gt;
We also have corrected the tests for stage_deadline according to the modifications done(It is using finished? and topic_missing? methods).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#stage_deadline' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.stage_deadline).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns nil' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to be nil&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns due date' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to match('2011-11-11 11:11:11')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Team'''==&lt;br /&gt;
&lt;br /&gt;
[mailto:jwboykin@ncsu.edu Jimmy Boykin]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:sbasnet2@ncsu.edu Sushan Basnet]&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122296</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1906. Refactor stage deadlines in Assignment.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122296"/>
		<updated>2019-03-25T23:26:11Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1906 OSS assignment for Spring 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
=='''Expertiza Background'''==&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application developed using Ruby on Rails Framework whose creation and maintenance is taken care of by students as well as the faculty of NCSU.It's code is available on Github [https://github.com/expertiza/expertiza Expertiza on GitHub].Expertiza allows the instructor to create and edit new as well as existing assignments.This also includes creating a wide range of topics under each assignment which students can sign up for.They can also publish surveys and reviews,view statistical results, set deadlines for assignments and make announcements.It provides a platform for students to signup for topics,form teams,view and submit assignments and give peer reviews and feedback.&lt;br /&gt;
&lt;br /&gt;
=='''Stage Deadline Background'''==&lt;br /&gt;
An assignment in Expertiza has many deadlines possible: deadlines for submission and review in each round,deadlines for signing up and dropping topics,submitting meta-reviews,etc.Depending on what the next deadline is,an Expertiza assignment is said to be in a particular kind of what is called &amp;quot;stage&amp;quot;.For example,if the next deadline(after the current time) is a submission deadline which is a DueDate object,then the assignment is said to be in a &amp;quot;submission&amp;quot; phase.&lt;br /&gt;
&lt;br /&gt;
[[File: StageBackground.png|center]]&lt;br /&gt;
&lt;br /&gt;
Depending on which stage an assignment is in, certain activities may be permissible or impermissible.For example, the default for a submission stage is to allow submission but not review,and in a review stage,the default is to allow review but not submission.These defaults may be changed by checking the relevant boxes on the Due Dates tab of assignment creation or editing.In the figure below it can be seen the &amp;quot;Other's work&amp;quot; link is grayed out as review is not permissible during submission phase.&lt;br /&gt;
&lt;br /&gt;
[[File: Statusinadeadline.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Important Links'''==&lt;br /&gt;
&lt;br /&gt;
[http://oss.flazzle.com/ Deployed_Project_Link]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/jwboykin/expertiza Expertiza_Link_for_this_Project]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
E1906 is an Expertiza based OSS project which deals basically with refactoring stage deadlines in assignment.rb file.Class assignment.rb has several methods for checking what kind of stage an assignment is in at the current time.These are:&lt;br /&gt;
&lt;br /&gt;
* current_stage_name(topic_id = nil)&lt;br /&gt;
* find_current_stage(topic_id = nil)&lt;br /&gt;
* get_current_stage(topic_id = nil)&lt;br /&gt;
* link_for_current_stage(topic_id = nil)&lt;br /&gt;
* stage_deadline(topic_id = nil)&lt;br /&gt;
&lt;br /&gt;
The goal of the project focuses on refactoring some of the above more complex methods, modifying some of the language to make it more Ruby friendly, removing some redundant code. This project is basically an attempt to make this part of the application easier to read and maintain.&lt;br /&gt;
&lt;br /&gt;
=='''Solutions Implemented'''==&lt;br /&gt;
&lt;br /&gt;
==='''Problem 1'''===&lt;br /&gt;
&lt;br /&gt;
Multiple functions in the code were calling DueDate.get_next_due_date(self.id, topic_id). &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
A new private function next_due_date was added. Other calls to the DueDate.get_next_due_date were replaced.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #returns the next due date&lt;br /&gt;
  def next_due_date(topic_id = nil)&lt;br /&gt;
    DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*One example of refactoring &lt;br /&gt;
[[File:Duedate E1906.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 2'''===&lt;br /&gt;
&lt;br /&gt;
The above five methods were being used at various places to check if the assignment is 'Finished' which made the code very redundant. Assignment is said to be finished if the next_due_date is nil.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have created a new method &amp;quot;finished?&amp;quot; that checks if the next_due_date is nil (which means that the assignment is &amp;quot;finished&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # New function to check if the assignment is finished&lt;br /&gt;
  def finished?( topic_id = nil )&lt;br /&gt;
    next_due_date(topic_id).nil?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have called this method at all the places where previously different methods were being used to check the same thing.&lt;br /&gt;
&lt;br /&gt;
*Signup sheet table uses assignment finished? method instead of current_stage_name&lt;br /&gt;
[[File:Problem1_1.png‎|center]]&lt;br /&gt;
&lt;br /&gt;
*Use assignment finished? method where only a comparison to &amp;quot;Finished&amp;quot; was being done using get_current_stage and find_current_stage&lt;br /&gt;
[[File:Problem1_2.png|center]] [[File:Problem1_3.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 3'''===&lt;br /&gt;
&lt;br /&gt;
The check for a topic_id to be nil when it is a staggered assignment and return 'Unknown' when it is true was being done at many places.This was not following Ruby and Rails rules.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
To make the code DRY and more easy to understand,we have created a new private method &amp;quot;topic_missing?&amp;quot; to check if the topic_id is nil in case of staggered assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # Function to check if topic id is null when its a staggered assignment&lt;br /&gt;
  def topic_missing?( topic_id = nil)&lt;br /&gt;
    topic_id.nil? and self.staggered_deadline?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactoring with new method topic_missing?&lt;br /&gt;
&lt;br /&gt;
[[File:Topic missing.png|center]]&lt;br /&gt;
&lt;br /&gt;
*stage_deadline( topic_id = nil) changed according to the modifications done&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the next stage deadline date and nil if its finished assignment &lt;br /&gt;
  def stage_deadline(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    return nil if finished?(topic_id)&lt;br /&gt;
    next_due_date(topic_id).due_at.to_s&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Problem 4'''===&lt;br /&gt;
&lt;br /&gt;
find_current_stage(topic_id=nil) method is being used only locally in the assignment.rb and once in the student_teams controller to check to check whether to display or not the reviews option for team members.This method was calling another function to get the next_due_date for an assignment that was like nesting of calls and not very Ruby standard.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have removed this function and replaced it with finished? method in the student_teams controller(shown in screenshot above in Problem 2) and with DueDate.get_next_due_date where the next due date was required.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Before :&lt;br /&gt;
 due_date = find_current_stage(topic_id)&lt;br /&gt;
 &lt;br /&gt;
 After :&lt;br /&gt;
 due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Problem 5'''===&lt;br /&gt;
&lt;br /&gt;
get_current_stage method is returning the stage name which the assignment is in at current time.This is not very clear from the name of the method.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have changed the method name to current_stage_name(topic_id=nil) to make it more clear to understand.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the current stage name of the assignment&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = next_due_date(topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactored get_current_stage with current_stage_name&lt;br /&gt;
&lt;br /&gt;
[[File:Current stage name new.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 6'''===&lt;br /&gt;
&lt;br /&gt;
current_stage_name(topic_id=nil)[This is the initial one] method was implementing things which was already being done by other methods and thus this method was redundant. &lt;br /&gt;
The initial code given was:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if self.staggered_deadline?&lt;br /&gt;
      return (topic_id.nil? ? 'Unknown' : get_current_stage(topic_id))&lt;br /&gt;
    end&lt;br /&gt;
    due_date = find_current_stage(topic_id)&lt;br /&gt;
&lt;br /&gt;
    unless self.staggered_deadline?&lt;br /&gt;
      if due_date != 'Finished' &amp;amp;&amp;amp; !due_date.nil? &amp;amp;&amp;amp; !due_date.deadline_name.nil?&lt;br /&gt;
        return due_date.deadline_name&lt;br /&gt;
      else&lt;br /&gt;
        return get_current_stage(topic_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First thing we noticed was that due_date.deadline_name was always nil because there was no field to enter the deadline name on the form, and therefore, the statement  &amp;lt;pre&amp;gt; return due_date.deadline_name &amp;lt;/pre&amp;gt; was never getting executed. &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
This method was checking for the due_date.deadline_name which was always nil. After removing the dead code, we get:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if topic_missing?(topic_id)&lt;br /&gt;
      return 'Unknown'&lt;br /&gt;
    else&lt;br /&gt;
      get_current_stage(topic_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Looking at the current_stage_name(topic_id=nil)[New one] method shown below and comparing it to what we have above, this code was surely redundant.That is why we removed this code and made appropriate changes wherever required within assignment.rb.&lt;br /&gt;
*Below is the current_stage_name method for reference&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the current stage name of the assignment&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = next_due_date(topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The associated rspec tests that tested the old current_stage_name method were also no longer needed.&lt;br /&gt;
&lt;br /&gt;
==='''Problem 7'''===&lt;br /&gt;
&lt;br /&gt;
link_for_current_stage function served no purpose. The function checked to see if any given due date had a link (presumably web URL) and would return it. The database had no values and there is no where in the application this URL could be provided. There doesn't appear to be any use for having a separate URL for each stage.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
Removed function. &lt;br /&gt;
&lt;br /&gt;
[[File:Big1.png|center]]&lt;br /&gt;
&lt;br /&gt;
Removed test related to the function. Removed the one call to this function.&lt;br /&gt;
&lt;br /&gt;
[[File:big2.png|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Automated Testing using RSPEC'''==&lt;br /&gt;
&lt;br /&gt;
===='''Tests for get_current_stage_name'''====&lt;br /&gt;
&lt;br /&gt;
The current version of expertiza did not have any tests for get_current_stage(topic_id=nil) method.Now as we have changed it to current_stage_name(topic_id=nil),we have added its tests as well.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#current_stage_name' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.current_stage_name).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns Finished' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Finished')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns current stage name' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:topic_missing?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          deadline = create(:deadline_type, id: 1, name:&amp;quot;Review&amp;quot;)&lt;br /&gt;
          allow(DeadlineType).to receive(:find).with(1).and_return(deadline)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Review')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===='''Tests for finished?'''====&lt;br /&gt;
&lt;br /&gt;
We have added tests for the new method that we have added finished?.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when assignment next due date is nil' do&lt;br /&gt;
      it 'returns True' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1, 123).and_return(nil)&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when there is a next due date' do&lt;br /&gt;
      it 'returns False' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1,123).and_return('2021-11-11 11:11:11')&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(false)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As topic_missing? method is made private,there was no need to test this.&lt;br /&gt;
&lt;br /&gt;
===='''Tests for stage_deadline'''====&lt;br /&gt;
&lt;br /&gt;
We also have corrected the tests for stage_deadline according to the modifications done(It is using finished? and topic_missing? methods).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#stage_deadline' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.stage_deadline).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns nil' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to be nil&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns due date' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to match('2011-11-11 11:11:11')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Team'''==&lt;br /&gt;
&lt;br /&gt;
[mailto:jwboykin@ncsu.edu Jimmy Boykin]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:sbasnet2@ncsu.edu Sushan Basnet]&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122294</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1906. Refactor stage deadlines in Assignment.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122294"/>
		<updated>2019-03-25T23:20:15Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1906 OSS assignment for Spring 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
=='''Expertiza Background'''==&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application developed using Ruby on Rails Framework whose creation and maintenance is taken care of by students as well as the faculty of NCSU.It's code is available on Github [https://github.com/expertiza/expertiza Expertiza on GitHub].Expertiza allows the instructor to create and edit new as well as existing assignments.This also includes creating a wide range of topics under each assignment which students can sign up for.They can also publish surveys and reviews,view statistical results, set deadlines for assignments and make announcements.It provides a platform for students to signup for topics,form teams,view and submit assignments and give peer reviews and feedback.&lt;br /&gt;
&lt;br /&gt;
=='''Stage Deadline Background'''==&lt;br /&gt;
An assignment in Expertiza has many deadlines possible: deadlines for submission and review in each round,deadlines for signing up and dropping topics,submitting meta-reviews,etc.Depending on what the next deadline is,an Expertiza assignment is said to be in a particular kind of what is called &amp;quot;stage&amp;quot;.For example,if the next deadline(after the current time) is a submission deadline which is a DueDate object,then the assignment is said to be in a &amp;quot;submission&amp;quot; phase.&lt;br /&gt;
&lt;br /&gt;
[[File: StageBackground.png|center]]&lt;br /&gt;
&lt;br /&gt;
Depending on which stage an assignment is in, certain activities may be permissible or impermissible.For example, the default for a submission stage is to allow submission but not review,and in a review stage,the default is to allow review but not submission.These defaults may be changed by checking the relevant boxes on the Due Dates tab of assignment creation or editing.In the figure below it can be seen the &amp;quot;Other's work&amp;quot; link is grayed out as review is not permissible during submission phase.&lt;br /&gt;
&lt;br /&gt;
[[File: Statusinadeadline.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Important Links'''==&lt;br /&gt;
&lt;br /&gt;
[http://oss.flazzle.com/ Deployed_Project_Link]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/jwboykin/expertiza Expertiza_Link_for_this_Project]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
E1906 is an Expertiza based OSS project which deals basically with refactoring stage deadlines in assignment.rb file.Class assignment.rb has several methods for checking what kind of stage an assignment is in at the current time.These are:&lt;br /&gt;
&lt;br /&gt;
* current_stage_name(topic_id = nil)&lt;br /&gt;
* find_current_stage(topic_id = nil)&lt;br /&gt;
* get_current_stage(topic_id = nil)&lt;br /&gt;
* link_for_current_stage(topic_id = nil)&lt;br /&gt;
* stage_deadline(topic_id = nil)&lt;br /&gt;
&lt;br /&gt;
The goal of the project focuses on refactoring some of the above more complex methods, modifying some of the language to make it more Ruby friendly, removing some redundant code. This project is basically an attempt to make this part of the application easier to read and maintain.&lt;br /&gt;
&lt;br /&gt;
=='''Solutions Implemented'''==&lt;br /&gt;
&lt;br /&gt;
==='''Problem 1'''===&lt;br /&gt;
&lt;br /&gt;
Multiple functions in the code were calling DueDate.get_next_due_date(self.id, topic_id). &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
A new private function next_due_date was added. Other calls to the DueDate.get_next_due_date were replaced.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #returns the next due date&lt;br /&gt;
  def next_due_date(topic_id = nil)&lt;br /&gt;
    DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*One example of refactoring &lt;br /&gt;
[[File:Duedate E1906.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 2'''===&lt;br /&gt;
&lt;br /&gt;
The above five methods were being used at various places to check if the assignment is 'Finished' which made the code very redundant. Assignment is said to be finished if the next_due_date is nil.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have created a new method &amp;quot;finished?&amp;quot; that checks if the next_due_date is nil (which means that the assignment is &amp;quot;finished&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # New function to check if the assignment is finished&lt;br /&gt;
  def finished?( topic_id = nil )&lt;br /&gt;
    next_due_date(topic_id).nil?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have called this method at all the places where previously different methods were being used to check the same thing.&lt;br /&gt;
&lt;br /&gt;
*Signup sheet table uses assignment finished? method instead of current_stage_name&lt;br /&gt;
[[File:Problem1_1.png‎|center]]&lt;br /&gt;
&lt;br /&gt;
*Use assignment finished? method where only a comparison to &amp;quot;Finished&amp;quot; was being done using get_current_stage and find_current_stage&lt;br /&gt;
[[File:Problem1_2.png|center]] [[File:Problem1_3.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 3'''===&lt;br /&gt;
&lt;br /&gt;
The check for a topic_id to be nil when it is a staggered assignment and return 'Unknown' when it is true was being done at many places.This was not following Ruby and Rails rules.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
To make the code DRY and more easy to understand,we have created a new private method &amp;quot;topic_missing?&amp;quot; to check if the topic_id is nil in case of staggered assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # Function to check if topic id is null when its a staggered assignment&lt;br /&gt;
  def topic_missing?( topic_id = nil)&lt;br /&gt;
    topic_id.nil? and self.staggered_deadline?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactoring with new method topic_missing?&lt;br /&gt;
&lt;br /&gt;
[[File:Topic missing.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Problem 4'''===&lt;br /&gt;
&lt;br /&gt;
find_current_stage(topic_id=nil) method is being used only locally in the assignment.rb and once in the student_teams controller to check to check whether to display or not the reviews option for team members.This method was calling another function to get the next_due_date for an assignment that was like nesting of calls and not very Ruby standard.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have removed this function and replaced it with finished? method in the student_teams controller(shown in screenshot above in Problem 2) and with DueDate.get_next_due_date where the next due date was required.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Before :&lt;br /&gt;
 due_date = find_current_stage(topic_id)&lt;br /&gt;
 &lt;br /&gt;
 After :&lt;br /&gt;
 due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Problem 5'''===&lt;br /&gt;
&lt;br /&gt;
get_current_stage method is returning the stage name which the assignment is in at current time.This is not very clear from the name of the method.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have changed the method name to current_stage_name(topic_id=nil) to make it more clear to understand.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the current stage name of the assignment&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = next_due_date(topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactored get_current_stage with current_stage_name&lt;br /&gt;
&lt;br /&gt;
[[File:Current stage name new.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 6'''===&lt;br /&gt;
&lt;br /&gt;
current_stage_name(topic_id=nil)[This is the initial one] method was implementing things which was already being done by other methods and thus this method was redundant. &lt;br /&gt;
The initial code given was:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if self.staggered_deadline?&lt;br /&gt;
      return (topic_id.nil? ? 'Unknown' : get_current_stage(topic_id))&lt;br /&gt;
    end&lt;br /&gt;
    due_date = find_current_stage(topic_id)&lt;br /&gt;
&lt;br /&gt;
    unless self.staggered_deadline?&lt;br /&gt;
      if due_date != 'Finished' &amp;amp;&amp;amp; !due_date.nil? &amp;amp;&amp;amp; !due_date.deadline_name.nil?&lt;br /&gt;
        return due_date.deadline_name&lt;br /&gt;
      else&lt;br /&gt;
        return get_current_stage(topic_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First thing we noticed was that due_date.deadline_name was always nil because there was no field to enter the deadline name on the form, and therefore, the statement  &amp;lt;pre&amp;gt; return due_date.deadline_name &amp;lt;/pre&amp;gt; was never getting executed. &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
This method was checking for the due_date.deadline_name which was always nil. After removing the dead code, we get:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if topic_missing?(topic_id)&lt;br /&gt;
      return 'Unknown'&lt;br /&gt;
    else&lt;br /&gt;
      get_current_stage(topic_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Looking at the current_stage_name(topic_id=nil)[New one] method shown below and comparing it to what we have above, this code was surely redundant.That is why we removed this code and made appropriate changes wherever required within assignment.rb.&lt;br /&gt;
*Below is the current_stage_name method for reference&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the current stage name of the assignment&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = next_due_date(topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The associated rspec tests that tested the old current_stage_name method were also no longer needed.&lt;br /&gt;
&lt;br /&gt;
==='''Problem 7'''===&lt;br /&gt;
&lt;br /&gt;
link_for_current_stage function served no purpose. The function checked to see if any given due date had a link (presumably web URL) and would return it. The database had no values and there is no where in the application this URL could be provided. There doesn't appear to be any use for having a separate URL for each stage.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
Removed function. &lt;br /&gt;
&lt;br /&gt;
[[File:Big1.png|center]]&lt;br /&gt;
&lt;br /&gt;
Removed test related to the function. Removed the one call to this function.&lt;br /&gt;
&lt;br /&gt;
[[File:big2.png|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Automated Testing using RSPEC'''==&lt;br /&gt;
&lt;br /&gt;
===='''Tests for get_current_stage_name'''====&lt;br /&gt;
&lt;br /&gt;
The current version of expertiza did not have any tests for get_current_stage(topic_id=nil) method.Now as we have changed it to current_stage_name(topic_id=nil),we have added its tests as well.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#current_stage_name' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.current_stage_name).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns Finished' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Finished')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns current stage name' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:topic_missing?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          deadline = create(:deadline_type, id: 1, name:&amp;quot;Review&amp;quot;)&lt;br /&gt;
          allow(DeadlineType).to receive(:find).with(1).and_return(deadline)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Review')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===='''Tests for finished?'''====&lt;br /&gt;
&lt;br /&gt;
We have added tests for the new method that we have added finished?.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when assignment next due date is nil' do&lt;br /&gt;
      it 'returns True' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1, 123).and_return(nil)&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when there is a next due date' do&lt;br /&gt;
      it 'returns False' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1,123).and_return('2021-11-11 11:11:11')&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(false)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As topic_missing? method is made private,there was no need to test this.&lt;br /&gt;
&lt;br /&gt;
===='''Tests for stage_deadline'''====&lt;br /&gt;
&lt;br /&gt;
We also have corrected the tests for stage_deadline according to the modifications done(It is using finished? and topic_missing? methods).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#stage_deadline' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.stage_deadline).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns nil' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to be nil&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns due date' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to match('2011-11-11 11:11:11')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Team'''==&lt;br /&gt;
&lt;br /&gt;
[mailto:jwboykin@ncsu.edu Jimmy Boykin]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:sbasnet2@ncsu.edu Sushan Basnet]&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122289</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1906. Refactor stage deadlines in Assignment.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122289"/>
		<updated>2019-03-25T23:18:15Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1906 OSS assignment for Spring 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
=='''Expertiza Background'''==&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application developed using Ruby on Rails Framework whose creation and maintenance is taken care of by students as well as the faculty of NCSU.It's code is available on Github [https://github.com/expertiza/expertiza Expertiza on GitHub].Expertiza allows the instructor to create and edit new as well as existing assignments.This also includes creating a wide range of topics under each assignment which students can sign up for.They can also publish surveys and reviews,view statistical results, set deadlines for assignments and make announcements.It provides a platform for students to signup for topics,form teams,view and submit assignments and give peer reviews and feedback.&lt;br /&gt;
&lt;br /&gt;
=='''Stage Deadline Background'''==&lt;br /&gt;
An assignment in Expertiza has many deadlines possible: deadlines for submission and review in each round,deadlines for signing up and dropping topics,submitting meta-reviews,etc.Depending on what the next deadline is,an Expertiza assignment is said to be in a particular kind of what is called &amp;quot;stage&amp;quot;.For example,if the next deadline(after the current time) is a submission deadline which is a DueDate object,then the assignment is said to be in a &amp;quot;submission&amp;quot; phase.&lt;br /&gt;
&lt;br /&gt;
[[File: StageBackground.png|center]]&lt;br /&gt;
&lt;br /&gt;
Depending on which stage an assignment is in, certain activities may be permissible or impermissible.For example, the default for a submission stage is to allow submission but not review,and in a review stage,the default is to allow review but not submission.These defaults may be changed by checking the relevant boxes on the Due Dates tab of assignment creation or editing.In the figure below it can be seen the &amp;quot;Other's work&amp;quot; link is grayed out as review is not permissible during submission phase.&lt;br /&gt;
&lt;br /&gt;
[[File: Statusinadeadline.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Important Links'''==&lt;br /&gt;
&lt;br /&gt;
[http://oss.flazzle.com/ Deployed_Project_Link]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/jwboykin/expertiza Expertiza_Link_for_this_Project]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
E1906 is an Expertiza based OSS project which deals basically with refactoring stage deadlines in assignment.rb file.Class assignment.rb has several methods for checking what kind of stage an assignment is in at the current time.These are:&lt;br /&gt;
&lt;br /&gt;
* current_stage_name(topic_id = nil)&lt;br /&gt;
* find_current_stage(topic_id = nil)&lt;br /&gt;
* get_current_stage(topic_id = nil)&lt;br /&gt;
* link_for_current_stage(topic_id = nil)&lt;br /&gt;
* stage_deadline(topic_id = nil)&lt;br /&gt;
&lt;br /&gt;
The goal of the project focuses on refactoring some of the above more complex methods, modifying some of the language to make it more Ruby friendly, removing some redundant code. This project is basically an attempt to make this part of the application easier to read and maintain.&lt;br /&gt;
&lt;br /&gt;
=='''Solutions Implemented'''==&lt;br /&gt;
&lt;br /&gt;
==='''Problem 1'''===&lt;br /&gt;
&lt;br /&gt;
Multiple functions in the code were calling DueDate.get_next_due_date(self.id, topic_id). &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
A new private function next_due_date was added. Other calls to the DueDate.get_next_due_date were replaced.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #returns the next due date&lt;br /&gt;
  def next_due_date(topic_id = nil)&lt;br /&gt;
    DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*One example of refactoring &lt;br /&gt;
[[File:Duedate E1906.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 2'''===&lt;br /&gt;
&lt;br /&gt;
The above five methods were being used at various places to check if the assignment is 'Finished' which made the code very redundant. Assignment is said to be finished if the next_due_date is nil.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have created a new method &amp;quot;finished?&amp;quot; that checks if the next_due_date is nil (which means that the assignment is &amp;quot;finished&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # New function to check if the assignment is finished&lt;br /&gt;
  def finished?( topic_id = nil )&lt;br /&gt;
    next_due_date(topic_id).nil?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have called this method at all the places where previously different methods were being used to check the same thing.&lt;br /&gt;
&lt;br /&gt;
*Signup sheet table uses assignment finished? method instead of current_stage_name&lt;br /&gt;
[[File:Problem1_1.png‎|center]]&lt;br /&gt;
&lt;br /&gt;
*Use assignment finished? method where only a comparison to &amp;quot;Finished&amp;quot; was being done using get_current_stage and find_current_stage&lt;br /&gt;
[[File:Problem1_2.png|center]] [[File:Problem1_3.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 3'''===&lt;br /&gt;
&lt;br /&gt;
The check for a topic_id to be nil when it is a staggered assignment and return 'Unknown' when it is true was being done at many places.This was not following Ruby and Rails rules.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
To make the code DRY and more easy to understand,we have created a new private method &amp;quot;topic_missing?&amp;quot; to check if the topic_id is nil in case of staggered assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # Function to check if topic id is null when its a staggered assignment&lt;br /&gt;
  def topic_missing?( topic_id = nil)&lt;br /&gt;
    topic_id.nil? and self.staggered_deadline?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactoring with new method topic_missing?&lt;br /&gt;
&lt;br /&gt;
[[File:Topic missing.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Problem 4'''===&lt;br /&gt;
&lt;br /&gt;
find_current_stage(topic_id=nil) method is being used only locally in the assignment.rb and once in the student_teams controller to check to check whether to display or not the reviews option for team members.This method was calling another function to get the next_due_date for an assignment that was like nesting of calls and not very Ruby standard.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have removed this function and replaced it with finished? method in the student_teams controller(shown in screenshot above in Problem 2) and with DueDate.get_next_due_date where the next due date was required.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Before :&lt;br /&gt;
 due_date = find_current_stage(topic_id)&lt;br /&gt;
 &lt;br /&gt;
 After :&lt;br /&gt;
 due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Problem 5'''===&lt;br /&gt;
&lt;br /&gt;
get_current_stage method is returning the stage name which the assignment is in at current time.This is not very clear from the name of the method.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have changed the method name to current_stage_name(topic_id=nil) to make it more clear to understand.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the current stage name of the assignment&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = next_due_date(topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactored get_current_stage with current_stage_name&lt;br /&gt;
&lt;br /&gt;
[[File:Current stage name new.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 6'''===&lt;br /&gt;
&lt;br /&gt;
current_stage_name(topic_id=nil)[This is the initial one] method was implementing things which was already being done by other methods and thus this method was redundant. &lt;br /&gt;
The initial code given was:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if self.staggered_deadline?&lt;br /&gt;
      return (topic_id.nil? ? 'Unknown' : get_current_stage(topic_id))&lt;br /&gt;
    end&lt;br /&gt;
    due_date = find_current_stage(topic_id)&lt;br /&gt;
&lt;br /&gt;
    unless self.staggered_deadline?&lt;br /&gt;
      if due_date != 'Finished' &amp;amp;&amp;amp; !due_date.nil? &amp;amp;&amp;amp; !due_date.deadline_name.nil?&lt;br /&gt;
        return due_date.deadline_name&lt;br /&gt;
      else&lt;br /&gt;
        return get_current_stage(topic_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First thing we noticed was that due_date.deadline_name was always nil because there was no field to enter the deadline name on the form, and therefore, the statement  &amp;lt;pre&amp;gt; return due_date.deadline_name &amp;lt;/pre&amp;gt; was never getting executed. &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
This method was checking for the due_date.deadline_name which was always nil. After removing the dead code, we get:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if topic_missing?(topic_id)&lt;br /&gt;
      return 'Unknown'&lt;br /&gt;
    else&lt;br /&gt;
      get_current_stage(topic_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Looking at the current_stage_name(topic_id=nil)[New one] method shown below and comparing it to what we have above, this code was surely redundant.That is why we removed this code and made appropriate changes wherever required within assignment.rb.&lt;br /&gt;
*Below is the current_stage_name method for reference&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the current stage name of the assignment&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = next_due_date(topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The associated rspec tests that tested the old current_stage_name method were also no longer needed.&lt;br /&gt;
&lt;br /&gt;
==='''Problem 7'''===&lt;br /&gt;
&lt;br /&gt;
link_for_current_stage function served no purpose. The function checked to see if any given due date had a link (presumably web URL) and would return it. The database had no values and there is no where in the application this URL could be provided. There doesn't appear to be any use for having a separate URL for each stage.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
Removed function. &lt;br /&gt;
&lt;br /&gt;
[[File:Big1.png|center]]&lt;br /&gt;
&lt;br /&gt;
Removed test related to the function. Removed the one call to this function.&lt;br /&gt;
&lt;br /&gt;
[[File:big2.png|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Automated Testing using RSPEC'''==&lt;br /&gt;
&lt;br /&gt;
===='''Tests for get_current_stage_name'''====&lt;br /&gt;
&lt;br /&gt;
The current version of expertiza did not have any tests for get_current_stage(topic_id=nil) method.Now as we have changed it to current_stage_name(topic_id=nil),we have added its tests as well.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#current_stage_name' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.current_stage_name).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns Finished' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Finished')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns current stage name' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:topic_missing?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          deadline = create(:deadline_type, id: 1, name:&amp;quot;Review&amp;quot;)&lt;br /&gt;
          allow(DeadlineType).to receive(:find).with(1).and_return(deadline)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Review')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===='''Tests for finished?'''====&lt;br /&gt;
&lt;br /&gt;
We have added tests for the new method that we have added finished?.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when assignment next due date is nil' do&lt;br /&gt;
      it 'returns True' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1, 123).and_return(nil)&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when there is a next due date' do&lt;br /&gt;
      it 'returns False' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1,123).and_return('2021-11-11 11:11:11')&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(false)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As topic_missing? method is made private,there was no need to test this.&lt;br /&gt;
&lt;br /&gt;
===='''Tests for stage_deadline'''====&lt;br /&gt;
&lt;br /&gt;
We also have corrected the tests for stage_deadline according to the modifications done(It is using finished? and topic_missing? methods).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#stage_deadline' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.stage_deadline).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns nil' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to be nil&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns due date' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to match('2011-11-11 11:11:11')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Team'''==&lt;br /&gt;
[mailto:jwboykin@ncsu.edu Jimmy Boykin]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:sbasnet2@ncsu.edu Sushan Basnet]&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122287</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1906. Refactor stage deadlines in Assignment.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122287"/>
		<updated>2019-03-25T23:17:34Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1906 OSS assignment for Spring 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
=='''Expertiza Background'''==&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application developed using Ruby on Rails Framework whose creation and maintenance is taken care of by students as well as the faculty of NCSU.It's code is available on Github [https://github.com/expertiza/expertiza Expertiza on GitHub].Expertiza allows the instructor to create and edit new as well as existing assignments.This also includes creating a wide range of topics under each assignment which students can sign up for.They can also publish surveys and reviews,view statistical results, set deadlines for assignments and make announcements.It provides a platform for students to signup for topics,form teams,view and submit assignments and give peer reviews and feedback.&lt;br /&gt;
&lt;br /&gt;
=='''Stage Deadline Background'''==&lt;br /&gt;
An assignment in Expertiza has many deadlines possible: deadlines for submission and review in each round,deadlines for signing up and dropping topics,submitting meta-reviews,etc.Depending on what the next deadline is,an Expertiza assignment is said to be in a particular kind of what is called &amp;quot;stage&amp;quot;.For example,if the next deadline(after the current time) is a submission deadline which is a DueDate object,then the assignment is said to be in a &amp;quot;submission&amp;quot; phase.&lt;br /&gt;
&lt;br /&gt;
[[File: StageBackground.png|center]]&lt;br /&gt;
&lt;br /&gt;
Depending on which stage an assignment is in, certain activities may be permissible or impermissible.For example, the default for a submission stage is to allow submission but not review,and in a review stage,the default is to allow review but not submission.These defaults may be changed by checking the relevant boxes on the Due Dates tab of assignment creation or editing.In the figure below it can be seen the &amp;quot;Other's work&amp;quot; link is grayed out as review is not permissible during submission phase.&lt;br /&gt;
&lt;br /&gt;
[[File: Statusinadeadline.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Important Links'''==&lt;br /&gt;
&lt;br /&gt;
[http://oss.flazzle.com/ Deployed_Project_Link]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/jwboykin/expertiza Expertiza_Link_for_this_Project]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
E1906 is an Expertiza based OSS project which deals basically with refactoring stage deadlines in assignment.rb file.Class assignment.rb has several methods for checking what kind of stage an assignment is in at the current time.These are:&lt;br /&gt;
&lt;br /&gt;
* current_stage_name(topic_id = nil)&lt;br /&gt;
* find_current_stage(topic_id = nil)&lt;br /&gt;
* get_current_stage(topic_id = nil)&lt;br /&gt;
* link_for_current_stage(topic_id = nil)&lt;br /&gt;
* stage_deadline(topic_id = nil)&lt;br /&gt;
&lt;br /&gt;
The goal of the project focuses on refactoring some of the above more complex methods, modifying some of the language to make it more Ruby friendly, removing some redundant code. This project is basically an attempt to make this part of the application easier to read and maintain.&lt;br /&gt;
&lt;br /&gt;
=='''Solutions Implemented'''==&lt;br /&gt;
&lt;br /&gt;
==='''Problem 1'''===&lt;br /&gt;
&lt;br /&gt;
Multiple functions in the code were calling DueDate.get_next_due_date(self.id, topic_id). &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
A new private function next_due_date was added. Other calls to the DueDate.get_next_due_date were replaced.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #returns the next due date&lt;br /&gt;
  def next_due_date(topic_id = nil)&lt;br /&gt;
    DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*One example of refactoring &lt;br /&gt;
[[File:Duedate E1906.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 2'''===&lt;br /&gt;
&lt;br /&gt;
The above five methods were being used at various places to check if the assignment is 'Finished' which made the code very redundant. Assignment is said to be finished if the next_due_date is nil.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have created a new method &amp;quot;finished?&amp;quot; that checks if the next_due_date is nil (which means that the assignment is &amp;quot;finished&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # New function to check if the assignment is finished&lt;br /&gt;
  def finished?( topic_id = nil )&lt;br /&gt;
    next_due_date(topic_id).nil?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have called this method at all the places where previously different methods were being used to check the same thing.&lt;br /&gt;
&lt;br /&gt;
*Signup sheet table uses assignment finished? method instead of current_stage_name&lt;br /&gt;
[[File:Problem1_1.png‎|center]]&lt;br /&gt;
&lt;br /&gt;
*Use assignment finished? method where only a comparison to &amp;quot;Finished&amp;quot; was being done using get_current_stage and find_current_stage&lt;br /&gt;
[[File:Problem1_2.png|center]] [[File:Problem1_3.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 3'''===&lt;br /&gt;
&lt;br /&gt;
The check for a topic_id to be nil when it is a staggered assignment and return 'Unknown' when it is true was being done at many places.This was not following Ruby and Rails rules.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
To make the code DRY and more easy to understand,we have created a new private method &amp;quot;topic_missing?&amp;quot; to check if the topic_id is nil in case of staggered assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # Function to check if topic id is null when its a staggered assignment&lt;br /&gt;
  def topic_missing?( topic_id = nil)&lt;br /&gt;
    topic_id.nil? and self.staggered_deadline?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactoring with new method topic_missing?&lt;br /&gt;
&lt;br /&gt;
[[File:Topic missing.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Problem 4'''===&lt;br /&gt;
&lt;br /&gt;
find_current_stage(topic_id=nil) method is being used only locally in the assignment.rb and once in the student_teams controller to check to check whether to display or not the reviews option for team members.This method was calling another function to get the next_due_date for an assignment that was like nesting of calls and not very Ruby standard.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have removed this function and replaced it with finished? method in the student_teams controller(shown in screenshot above in Problem 2) and with DueDate.get_next_due_date where the next due date was required.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Before :&lt;br /&gt;
 due_date = find_current_stage(topic_id)&lt;br /&gt;
 &lt;br /&gt;
 After :&lt;br /&gt;
 due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Problem 5'''===&lt;br /&gt;
&lt;br /&gt;
get_current_stage method is returning the stage name which the assignment is in at current time.This is not very clear from the name of the method.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have changed the method name to current_stage_name(topic_id=nil) to make it more clear to understand.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the current stage name of the assignment&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = next_due_date(topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactored get_current_stage with current_stage_name&lt;br /&gt;
&lt;br /&gt;
[[File:Current stage name new.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 6'''===&lt;br /&gt;
&lt;br /&gt;
current_stage_name(topic_id=nil)[This is the initial one] method was implementing things which was already being done by other methods and thus this method was redundant. &lt;br /&gt;
The initial code given was:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if self.staggered_deadline?&lt;br /&gt;
      return (topic_id.nil? ? 'Unknown' : get_current_stage(topic_id))&lt;br /&gt;
    end&lt;br /&gt;
    due_date = find_current_stage(topic_id)&lt;br /&gt;
&lt;br /&gt;
    unless self.staggered_deadline?&lt;br /&gt;
      if due_date != 'Finished' &amp;amp;&amp;amp; !due_date.nil? &amp;amp;&amp;amp; !due_date.deadline_name.nil?&lt;br /&gt;
        return due_date.deadline_name&lt;br /&gt;
      else&lt;br /&gt;
        return get_current_stage(topic_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First thing we noticed was that due_date.deadline_name was always nil because there was no field to enter the deadline name on the form, and therefore, the statement  &amp;lt;pre&amp;gt; return due_date.deadline_name &amp;lt;/pre&amp;gt; was never getting executed. &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
This method was checking for the due_date.deadline_name which was always nil. After removing the dead code, we get:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if topic_missing?(topic_id)&lt;br /&gt;
      return 'Unknown'&lt;br /&gt;
    else&lt;br /&gt;
      get_current_stage(topic_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Looking at the current_stage_name(topic_id=nil)[New one] method shown below and comparing it to what we have above, this code was surely redundant.That is why we removed this code and made appropriate changes wherever required within assignment.rb.&lt;br /&gt;
*Below is the current_stage_name method for reference&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the current stage name of the assignment&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = next_due_date(topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The associated rspec tests that tested the old current_stage_name method were also no longer needed.&lt;br /&gt;
&lt;br /&gt;
==='''Problem 7'''===&lt;br /&gt;
&lt;br /&gt;
link_for_current_stage function served no purpose. The function checked to see if any given due date had a link (presumably web URL) and would return it. The database had no values and there is no where in the application this URL could be provided. There doesn't appear to be any use for having a separate URL for each stage.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
Removed function. &lt;br /&gt;
&lt;br /&gt;
[[File:Big1.png|center]]&lt;br /&gt;
&lt;br /&gt;
Removed test related to the function. Removed the one call to this function.&lt;br /&gt;
&lt;br /&gt;
[[File:big2.png|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Automated Testing using RSPEC'''==&lt;br /&gt;
&lt;br /&gt;
===='''Tests for get_current_stage_name'''====&lt;br /&gt;
&lt;br /&gt;
The current version of expertiza did not have any tests for get_current_stage(topic_id=nil) method.Now as we have changed it to current_stage_name(topic_id=nil),we have added its tests as well.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#current_stage_name' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.current_stage_name).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns Finished' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Finished')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns current stage name' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:topic_missing?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          deadline = create(:deadline_type, id: 1, name:&amp;quot;Review&amp;quot;)&lt;br /&gt;
          allow(DeadlineType).to receive(:find).with(1).and_return(deadline)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Review')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===='''Tests for finished?'''====&lt;br /&gt;
&lt;br /&gt;
We have added tests for the new method that we have added finished?.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when assignment next due date is nil' do&lt;br /&gt;
      it 'returns True' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1, 123).and_return(nil)&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when there is a next due date' do&lt;br /&gt;
      it 'returns False' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1,123).and_return('2021-11-11 11:11:11')&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(false)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As topic_missing? method is made private,there was no need to test this.&lt;br /&gt;
&lt;br /&gt;
===='''Tests for stage_deadline'''====&lt;br /&gt;
&lt;br /&gt;
We also have corrected the tests for stage_deadline according to the modifications done(It is using finished? and topic_missing? methods).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#stage_deadline' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.stage_deadline).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns nil' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to be nil&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns due date' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to match('2011-11-11 11:11:11')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Team'''==&lt;br /&gt;
[mailto:jwboykin@ncsu.edu Jimmy Boykin]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:sbasnet2@ncsu.edu Sushan Basnet]&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122279</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1906. Refactor stage deadlines in Assignment.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122279"/>
		<updated>2019-03-25T23:13:28Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1906 OSS assignment for Spring 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
=='''Expertiza Background'''==&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application developed using Ruby on Rails Framework whose creation and maintenance is taken care of by students as well as the faculty of NCSU.It's code is available on Github [https://github.com/expertiza/expertiza Expertiza on GitHub].Expertiza allows the instructor to create and edit new as well as existing assignments.This also includes creating a wide range of topics under each assignment which students can sign up for.They can also publish surveys and reviews,view statistical results, set deadlines for assignments and make announcements.It provides a platform for students to signup for topics,form teams,view and submit assignments and give peer reviews and feedback.&lt;br /&gt;
&lt;br /&gt;
=='''Stage Deadline Background'''==&lt;br /&gt;
An assignment in Expertiza has many deadlines possible: deadlines for submission and review in each round,deadlines for signing up and dropping topics,submitting meta-reviews,etc.Depending on what the next deadline is,an Expertiza assignment is said to be in a particular kind of what is called &amp;quot;stage&amp;quot;.For example,if the next deadline(after the current time) is a submission deadline which is a DueDate object,then the assignment is said to be in a &amp;quot;submission&amp;quot; phase.&lt;br /&gt;
&lt;br /&gt;
[[File: StageBackground.png|center]]&lt;br /&gt;
&lt;br /&gt;
Depending on which stage an assignment is in, certain activities may be permissible or impermissible.For example, the default for a submission stage is to allow submission but not review,and in a review stage,the default is to allow review but not submission.These defaults may be changed by checking the relevant boxes on the Due Dates tab of assignment creation or editing.In the figure below it can be seen the &amp;quot;Other's work&amp;quot; link is grayed out as review is not permissible during submission phase.&lt;br /&gt;
&lt;br /&gt;
[[File: Statusinadeadline.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Important Links'''==&lt;br /&gt;
&lt;br /&gt;
[http://oss.flazzle.com/ Deployed_Project_Link]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/jwboykin/expertiza Expertiza_Link_for_this_Project]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
E1906 is an Expertiza based OSS project which deals basically with refactoring stage deadlines in assignment.rb file.Class assignment.rb has several methods for checking what kind of stage an assignment is in at the current time.These are:&lt;br /&gt;
&lt;br /&gt;
* current_stage_name(topic_id = nil)&lt;br /&gt;
* find_current_stage(topic_id = nil)&lt;br /&gt;
* get_current_stage(topic_id = nil)&lt;br /&gt;
* link_for_current_stage(topic_id = nil)&lt;br /&gt;
* stage_deadline(topic_id = nil)&lt;br /&gt;
&lt;br /&gt;
The goal of the project focuses on refactoring some of the above more complex methods, modifying some of the language to make it more Ruby friendly, removing some redundant code. This project is basically an attempt to make this part of the application easier to read and maintain.&lt;br /&gt;
&lt;br /&gt;
=='''Solutions Implemented'''==&lt;br /&gt;
&lt;br /&gt;
==='''Problem 1'''===&lt;br /&gt;
&lt;br /&gt;
Multiple functions in the code were calling DueDate.get_next_due_date(self.id, topic_id). &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
A new private function next_due_date was added. Other calls to the DueDate.get_next_due_date were replaced.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #returns the next due date&lt;br /&gt;
  def next_due_date(topic_id = nil)&lt;br /&gt;
    DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*One example of refactoring &lt;br /&gt;
[[File:Duedate E1906.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 2'''===&lt;br /&gt;
&lt;br /&gt;
The above five methods were being used at various places to check if the assignment is 'Finished' which made the code very redundant. Assignment is said to be finished if the next_due_date is nil.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have created a new method &amp;quot;finished?&amp;quot; that checks if the next_due_date is nil (which means that the assignment is &amp;quot;finished&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # New function to check if the assignment is finished&lt;br /&gt;
  def finished?( topic_id = nil )&lt;br /&gt;
    next_due_date(topic_id).nil?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have called this method at all the places where previously different methods were being used to check the same thing.&lt;br /&gt;
&lt;br /&gt;
*Signup sheet table uses assignment finished? method instead of current_stage_name&lt;br /&gt;
[[File:Problem1_1.png‎|center]]&lt;br /&gt;
&lt;br /&gt;
*Use assignment finished? method where only a comparison to &amp;quot;Finished&amp;quot; was being done using get_current_stage and find_current_stage&lt;br /&gt;
[[File:Problem1_2.png|center]] [[File:Problem1_3.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 3'''===&lt;br /&gt;
&lt;br /&gt;
The check for a topic_id to be nil when it is a staggered assignment and return 'Unknown' when it is true was being done at many places.This was not following Ruby and Rails rules.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
To make the code DRY and more easy to understand,we have created a new private method &amp;quot;topic_missing?&amp;quot; to check if the topic_id is nil in case of staggered assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # Function to check if topic id is null when its a staggered assignment&lt;br /&gt;
  def topic_missing?( topic_id = nil)&lt;br /&gt;
    topic_id.nil? and self.staggered_deadline?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactoring with new method topic_missing?&lt;br /&gt;
&lt;br /&gt;
[[File:Topic missing.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Problem 4'''===&lt;br /&gt;
&lt;br /&gt;
find_current_stage(topic_id=nil) method is being used only locally in the assignment.rb and once in the student_teams controller to check to check whether to display or not the reviews option for team members.This method was calling another function to get the next_due_date for an assignment that was like nesting of calls and not very Ruby standard.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have removed this function and replaced it with finished? method in the student_teams controller(shown in screenshot above in Problem 2) and with DueDate.get_next_due_date where the next due date was required.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Before :&lt;br /&gt;
 due_date = find_current_stage(topic_id)&lt;br /&gt;
 &lt;br /&gt;
 After :&lt;br /&gt;
 due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Problem 5'''===&lt;br /&gt;
&lt;br /&gt;
get_current_stage method is returning the stage name which the assignment is in at current time.This is not very clear from the name of the method.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have changed the method name to current_stage_name(topic_id=nil) to make it more clear to understand.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #Gives the current stage name of the assignment&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = next_due_date(topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactored get_current_stage with current_stage_name&lt;br /&gt;
&lt;br /&gt;
[[File:Current stage name new.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 6'''===&lt;br /&gt;
&lt;br /&gt;
current_stage_name(topic_id=nil)[This is the initial one] method was implementing things which was already being done by other methods and thus this method was redundant. &lt;br /&gt;
The initial code given was:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if self.staggered_deadline?&lt;br /&gt;
      return (topic_id.nil? ? 'Unknown' : get_current_stage(topic_id))&lt;br /&gt;
    end&lt;br /&gt;
    due_date = find_current_stage(topic_id)&lt;br /&gt;
&lt;br /&gt;
    unless self.staggered_deadline?&lt;br /&gt;
      if due_date != 'Finished' &amp;amp;&amp;amp; !due_date.nil? &amp;amp;&amp;amp; !due_date.deadline_name.nil?&lt;br /&gt;
        return due_date.deadline_name&lt;br /&gt;
      else&lt;br /&gt;
        return get_current_stage(topic_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First thing we noticed was that due_date.deadline_name was always nil because there was no field to enter the deadline name on the form, and therefore, the statement  &amp;lt;pre&amp;gt; return due_date.deadline_name &amp;lt;/pre&amp;gt; was never getting executed. &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
This method was checking for the due_date.deadline_name which was always nil. After removing the dead code, we get:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if topic_missing?(topic_id)&lt;br /&gt;
      return 'Unknown'&lt;br /&gt;
    else&lt;br /&gt;
      get_current_stage(topic_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Looking at the get_current_stage_name(topic_id=nil) method shown below and comparing it to what we have above, this code was surely redundant.That is why we removed this code and made appropriate changes wherever required within assignment.rb.&lt;br /&gt;
*Below is the get_current_stage_name method for reference&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The associated rspec tests that tested the current_stage method were also no longer needed.&lt;br /&gt;
&lt;br /&gt;
==='''Problem 7'''===&lt;br /&gt;
&lt;br /&gt;
link_for_current_stage function served no purpose. The function checked to see if any given due date had a link (presumably web URL) and would return it. The database had no values and there is no where in the application this URL could be provided. There doesn't appear to be any use for having a separate URL for each stage.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
Removed function. &lt;br /&gt;
&lt;br /&gt;
[[File:Big1.png|center]]&lt;br /&gt;
&lt;br /&gt;
Removed test related to the function. Removed the one call to this function.&lt;br /&gt;
&lt;br /&gt;
[[File:big2.png|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Automated Testing using RSPEC'''==&lt;br /&gt;
&lt;br /&gt;
===='''Tests for get_current_stage_name'''====&lt;br /&gt;
&lt;br /&gt;
The current version of expertiza did not have any tests for get_current_stage(topic_id=nil) method.Now as we have changed it to current_stage_name(topic_id=nil),we have added its tests as well.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#current_stage_name' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.current_stage_name).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns Finished' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Finished')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns current stage name' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:topic_missing?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          deadline = create(:deadline_type, id: 1, name:&amp;quot;Review&amp;quot;)&lt;br /&gt;
          allow(DeadlineType).to receive(:find).with(1).and_return(deadline)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Review')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===='''Tests for finished?'''====&lt;br /&gt;
&lt;br /&gt;
We have added tests for the new method that we have added finished?.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when assignment next due date is nil' do&lt;br /&gt;
      it 'returns True' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1, 123).and_return(nil)&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when there is a next due date' do&lt;br /&gt;
      it 'returns False' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1,123).and_return('2021-11-11 11:11:11')&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(false)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As topic_missing? method is made private,there was no need to test this.&lt;br /&gt;
&lt;br /&gt;
===='''Tests for stage_deadline'''====&lt;br /&gt;
&lt;br /&gt;
We also have corrected the tests for stage_deadline according to the modifications done(It is using finished? and topic_missing? methods).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#stage_deadline' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.stage_deadline).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns nil' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to be nil&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns due date' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to match('2011-11-11 11:11:11')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Team'''==&lt;br /&gt;
[mailto:jwboykin@ncsu.edu Jimmy Boykin]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:sbasnet2@ncsu.edu Sushan Basnet]&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122278</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1906. Refactor stage deadlines in Assignment.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122278"/>
		<updated>2019-03-25T23:09:30Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1906 OSS assignment for Spring 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
=='''Expertiza Background'''==&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application developed using Ruby on Rails Framework whose creation and maintenance is taken care of by students as well as the faculty of NCSU.It's code is available on Github [https://github.com/expertiza/expertiza Expertiza on GitHub].Expertiza allows the instructor to create and edit new as well as existing assignments.This also includes creating a wide range of topics under each assignment which students can sign up for.They can also publish surveys and reviews,view statistical results, set deadlines for assignments and make announcements.It provides a platform for students to signup for topics,form teams,view and submit assignments and give peer reviews and feedback.&lt;br /&gt;
&lt;br /&gt;
=='''Stage Deadline Background'''==&lt;br /&gt;
An assignment in Expertiza has many deadlines possible: deadlines for submission and review in each round,deadlines for signing up and dropping topics,submitting meta-reviews,etc.Depending on what the next deadline is,an Expertiza assignment is said to be in a particular kind of what is called &amp;quot;stage&amp;quot;.For example,if the next deadline(after the current time) is a submission deadline which is a DueDate object,then the assignment is said to be in a &amp;quot;submission&amp;quot; phase.&lt;br /&gt;
&lt;br /&gt;
[[File: StageBackground.png|center]]&lt;br /&gt;
&lt;br /&gt;
Depending on which stage an assignment is in, certain activities may be permissible or impermissible.For example, the default for a submission stage is to allow submission but not review,and in a review stage,the default is to allow review but not submission.These defaults may be changed by checking the relevant boxes on the Due Dates tab of assignment creation or editing.In the figure below it can be seen the &amp;quot;Other's work&amp;quot; link is grayed out as review is not permissible during submission phase.&lt;br /&gt;
&lt;br /&gt;
[[File: Statusinadeadline.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Important Links'''==&lt;br /&gt;
&lt;br /&gt;
[http://oss.flazzle.com/ Deployed_Project_Link]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/jwboykin/expertiza Expertiza_Link_for_this_Project]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
E1906 is an Expertiza based OSS project which deals basically with refactoring stage deadlines in assignment.rb file.Class assignment.rb has several methods for checking what kind of stage an assignment is in at the current time.These are:&lt;br /&gt;
&lt;br /&gt;
* current_stage_name(topic_id = nil)&lt;br /&gt;
* find_current_stage(topic_id = nil)&lt;br /&gt;
* get_current_stage(topic_id = nil)&lt;br /&gt;
* link_for_current_stage(topic_id = nil)&lt;br /&gt;
* stage_deadline(topic_id = nil)&lt;br /&gt;
&lt;br /&gt;
The goal of the project focuses on refactoring some of the above more complex methods, modifying some of the language to make it more Ruby friendly, removing some redundant code. This project is basically an attempt to make this part of the application easier to read and maintain.&lt;br /&gt;
&lt;br /&gt;
=='''Solutions Implemented'''==&lt;br /&gt;
&lt;br /&gt;
==='''Problem 1'''===&lt;br /&gt;
&lt;br /&gt;
Multiple functions in the code were calling DueDate.get_next_due_date(self.id, topic_id). &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
A new private function next_due_date was added. Other calls to the DueDate.get_next_due_date were replaced.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #returns the next due date&lt;br /&gt;
  def next_due_date(topic_id = nil)&lt;br /&gt;
    DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*One example of refactoring &lt;br /&gt;
[[File:Duedate E1906.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 2'''===&lt;br /&gt;
&lt;br /&gt;
The above five methods were being used at various places to check if the assignment is 'Finished' which made the code very redundant. Assignment is said to be finished if the next_due_date is nil.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have created a new method &amp;quot;finished?&amp;quot; that checks if the next_due_date is nil (which means that the assignment is &amp;quot;finished&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # New function to check if the assignment is finished&lt;br /&gt;
  def finished?( topic_id = nil )&lt;br /&gt;
    next_due_date(topic_id).nil?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have called this method at all the places where previously different methods were being used to check the same thing.&lt;br /&gt;
&lt;br /&gt;
*Signup sheet table uses assignment finished? method instead of current_stage_name&lt;br /&gt;
[[File:Problem1_1.png‎|center]]&lt;br /&gt;
&lt;br /&gt;
*Use assignment finished? method where only a comparison to &amp;quot;Finished&amp;quot; was being done using get_current_stage and find_current_stage&lt;br /&gt;
[[File:Problem1_2.png|center]] [[File:Problem1_3.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 3'''===&lt;br /&gt;
&lt;br /&gt;
The check for a topic_id to be nil when it is a staggered assignment and return 'Unknown' when it is true was being done at many places.This was not following Ruby and Rails rules.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
To make the code DRY and more easy to understand,we have created a new private method &amp;quot;topic_missing?&amp;quot; to check if the topic_id is nil in case of staggered assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # Function to check if topic id is null when its a staggered assignment&lt;br /&gt;
  def topic_missing?( topic_id = nil)&lt;br /&gt;
    topic_id.nil? and self.staggered_deadline?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactoring with new method topic_missing?&lt;br /&gt;
&lt;br /&gt;
[[File:Topic missing.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Problem 4'''===&lt;br /&gt;
&lt;br /&gt;
find_current_stage(topic_id=nil) method is being used only locally in the assignment.rb and once in the student_teams controller to check to check whether to display or not the reviews option for team members.This method was calling another function to get the next_due_date for an assignment that was like nesting of calls and not very Ruby standard.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have removed this function and replaced it with finished? method in the student_teams controller(shown in screenshot above in Problem 2) and with DueDate.get_next_due_date where the next due date was required.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Before :&lt;br /&gt;
 due_date = find_current_stage(topic_id)&lt;br /&gt;
 &lt;br /&gt;
 After :&lt;br /&gt;
 due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Problem 5'''===&lt;br /&gt;
&lt;br /&gt;
get_current_stage method is returning the stage name which the assignment is in at current time.This is not very clear from the name of the method.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have changed the method name to current_stage_name(topic_id=nil) to make it more clear to understand.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = next_due_date(topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactored get_current_stage with current_stage_name&lt;br /&gt;
&lt;br /&gt;
[[File:Current stage name new.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 6'''===&lt;br /&gt;
&lt;br /&gt;
current_stage_name(topic_id=nil)[This is the initial one] method was implementing things which was already being done by other methods and thus this method was redundant. &lt;br /&gt;
The initial code given was:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if self.staggered_deadline?&lt;br /&gt;
      return (topic_id.nil? ? 'Unknown' : get_current_stage(topic_id))&lt;br /&gt;
    end&lt;br /&gt;
    due_date = find_current_stage(topic_id)&lt;br /&gt;
&lt;br /&gt;
    unless self.staggered_deadline?&lt;br /&gt;
      if due_date != 'Finished' &amp;amp;&amp;amp; !due_date.nil? &amp;amp;&amp;amp; !due_date.deadline_name.nil?&lt;br /&gt;
        return due_date.deadline_name&lt;br /&gt;
      else&lt;br /&gt;
        return get_current_stage(topic_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First thing we noticed was that due_date.deadline_name was always nil because there was no field to enter the deadline name on the form, and therefore, the statement  &amp;lt;pre&amp;gt; return due_date.deadline_name &amp;lt;/pre&amp;gt; was never getting executed. &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
This method was checking for the due_date.deadline_name which was always nil. After removing the dead code, we get:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if topic_missing?(topic_id)&lt;br /&gt;
      return 'Unknown'&lt;br /&gt;
    else&lt;br /&gt;
      get_current_stage(topic_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Looking at the get_current_stage_name(topic_id=nil) method shown below and comparing it to what we have above, this code was surely redundant.That is why we removed this code and made appropriate changes wherever required within assignment.rb.&lt;br /&gt;
*Below is the get_current_stage_name method for reference&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The associated rspec tests that tested the current_stage method were also no longer needed.&lt;br /&gt;
&lt;br /&gt;
==='''Problem 7'''===&lt;br /&gt;
&lt;br /&gt;
link_for_current_stage function served no purpose. The function checked to see if any given due date had a link (presumably web URL) and would return it. The database had no values and there is no where in the application this URL could be provided. There doesn't appear to be any use for having a separate URL for each stage.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
Removed function. &lt;br /&gt;
&lt;br /&gt;
[[File:Big1.png|center]]&lt;br /&gt;
&lt;br /&gt;
Removed test related to the function. Removed the one call to this function.&lt;br /&gt;
&lt;br /&gt;
[[File:big2.png|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Automated Testing using RSPEC'''==&lt;br /&gt;
&lt;br /&gt;
===='''Tests for get_current_stage_name'''====&lt;br /&gt;
&lt;br /&gt;
The current version of expertiza did not have any tests for get_current_stage(topic_id=nil) method.Now as we have changed it to current_stage_name(topic_id=nil),we have added its tests as well.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#current_stage_name' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.current_stage_name).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns Finished' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Finished')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns current stage name' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:topic_missing?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          deadline = create(:deadline_type, id: 1, name:&amp;quot;Review&amp;quot;)&lt;br /&gt;
          allow(DeadlineType).to receive(:find).with(1).and_return(deadline)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Review')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===='''Tests for finished?'''====&lt;br /&gt;
&lt;br /&gt;
We have added tests for the new method that we have added finished?.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when assignment next due date is nil' do&lt;br /&gt;
      it 'returns True' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1, 123).and_return(nil)&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when there is a next due date' do&lt;br /&gt;
      it 'returns False' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1,123).and_return('2021-11-11 11:11:11')&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(false)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As topic_missing? method is made private,there was no need to test this.&lt;br /&gt;
&lt;br /&gt;
===='''Tests for stage_deadline'''====&lt;br /&gt;
&lt;br /&gt;
We also have corrected the tests for stage_deadline according to the modifications done(It is using finished? and topic_missing? methods).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#stage_deadline' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.stage_deadline).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns nil' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to be nil&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns due date' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to match('2011-11-11 11:11:11')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Team'''==&lt;br /&gt;
[mailto:jwboykin@ncsu.edu Jimmy Boykin]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:sbasnet2@ncsu.edu Sushan Basnet]&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122277</id>
		<title>CSC/ECE 517 Spring 2019 - Project E1906. Refactor stage deadlines in Assignment.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2019_-_Project_E1906._Refactor_stage_deadlines_in_Assignment.rb&amp;diff=122277"/>
		<updated>2019-03-25T22:57:34Z</updated>

		<summary type="html">&lt;p&gt;Rkaur: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E1906 OSS assignment for Spring 2019, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
=='''Expertiza Background'''==&lt;br /&gt;
[http://expertiza.ncsu.edu/ Expertiza] is a web application developed using Ruby on Rails Framework whose creation and maintenance is taken care of by students as well as the faculty of NCSU.It's code is available on Github [https://github.com/expertiza/expertiza Expertiza on GitHub].Expertiza allows the instructor to create and edit new as well as existing assignments.This also includes creating a wide range of topics under each assignment which students can sign up for.They can also publish surveys and reviews,view statistical results, set deadlines for assignments and make announcements.It provides a platform for students to signup for topics,form teams,view and submit assignments and give peer reviews and feedback.&lt;br /&gt;
&lt;br /&gt;
=='''Stage Deadline Background'''==&lt;br /&gt;
An assignment in Expertiza has many deadlines possible: deadlines for submission and review in each round,deadlines for signing up and dropping topics,submitting meta-reviews,etc.Depending on what the next deadline is,an Expertiza assignment is said to be in a particular kind of what is called &amp;quot;stage&amp;quot;.For example,if the next deadline(after the current time) is a submission deadline which is a DueDate object,then the assignment is said to be in a &amp;quot;submission&amp;quot; phase.&lt;br /&gt;
&lt;br /&gt;
[[File: StageBackground.png|center]]&lt;br /&gt;
&lt;br /&gt;
Depending on which stage an assignment is in, certain activities may be permissible or impermissible.For example, the default for a submission stage is to allow submission but not review,and in a review stage,the default is to allow review but not submission.These defaults may be changed by checking the relevant boxes on the Due Dates tab of assignment creation or editing.In the figure below it can be seen the &amp;quot;Other's work&amp;quot; link is grayed out as review is not permissible during submission phase.&lt;br /&gt;
&lt;br /&gt;
[[File: Statusinadeadline.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Important Links'''==&lt;br /&gt;
&lt;br /&gt;
[http://oss.flazzle.com/ Deployed_Project_Link]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/jwboykin/expertiza Expertiza_Link_for_this_Project]&lt;br /&gt;
&lt;br /&gt;
=='''Problem Statement'''==&lt;br /&gt;
E1906 is an Expertiza based OSS project which deals basically with refactoring stage deadlines in assignment.rb file.Class assignment.rb has several methods for checking what kind of stage an assignment is in at the current time.These are:&lt;br /&gt;
&lt;br /&gt;
* current_stage_name(topic_id = nil)&lt;br /&gt;
* find_current_stage(topic_id = nil)&lt;br /&gt;
* get_current_stage(topic_id = nil)&lt;br /&gt;
* link_for_current_stage(topic_id = nil)&lt;br /&gt;
* stage_deadline(topic_id = nil)&lt;br /&gt;
&lt;br /&gt;
The goal of the project focuses on refactoring some of the above more complex methods, modifying some of the language to make it more Ruby friendly, removing some redundant code. This project is basically an attempt to make this part of the application easier to read and maintain.&lt;br /&gt;
&lt;br /&gt;
=='''Solutions Implemented'''==&lt;br /&gt;
&lt;br /&gt;
==='''Problem 1'''===&lt;br /&gt;
&lt;br /&gt;
Multiple functions in the code were calling DueDate.get_next_due_date(self.id, topic_id). &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
A new private function next_due_date was added. Other calls to the DueDate.get_next_due_date were replaced.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  #returns the next due date&lt;br /&gt;
  def next_due_date(topic_id = nil)&lt;br /&gt;
    DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*One example of refactoring &lt;br /&gt;
[[File:Duedate E1906.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 2'''===&lt;br /&gt;
&lt;br /&gt;
The above five methods were being used at various places to check if the assignment is 'Finished' which made the code very redundant. Assignment is said to be finished if the next_due_date is nil.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have created a new method &amp;quot;finished?&amp;quot; that checks if the next_due_date is nil (which means that the assignment is &amp;quot;finished&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # New function to check if the assignment is finished&lt;br /&gt;
  def finished?( topic_id = nil )&lt;br /&gt;
    next_due_date(topic_id).nil?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We have called this method at all the places where previously different methods were being used to check the same thing.&lt;br /&gt;
&lt;br /&gt;
*Signup sheet table uses assignment finished? method instead of current_stage_name&lt;br /&gt;
[[File:Problem1_1.png‎|center]]&lt;br /&gt;
&lt;br /&gt;
*Use assignment finished? method where only a comparison to &amp;quot;Finished&amp;quot; was being done using get_current_stage and find_current_stage&lt;br /&gt;
[[File:Problem1_2.png|center]] [[File:Problem1_3.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 3'''===&lt;br /&gt;
&lt;br /&gt;
The check for a topic_id to be nil when it is a staggered assignment and return 'Unknown' when it is true was being done at many places.This was not following Ruby and Rails rules.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
To make the code DRY and more easy to understand,we have created a new private method &amp;quot;topic_missing?&amp;quot; to check if the topic_id is nil in case of staggered assignment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # Function to check if topic id is null when its a staggered assignment&lt;br /&gt;
  def topic_missing?( topic_id = nil)&lt;br /&gt;
    topic_id.nil? and self.staggered_deadline?&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactoring with new method topic_missing?&lt;br /&gt;
&lt;br /&gt;
[[File:Topic missing.png|center]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==='''Problem 4'''===&lt;br /&gt;
&lt;br /&gt;
find_current_stage(topic_id=nil) method is being used only locally in the assignment.rb and once in the student_teams controller to check to check whether to display or not the reviews option for team members.This method was calling another function to get the next_due_date for an assignment that was like nesting of calls and not very Ruby standard.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have removed this function.We have replaced it with finished? method in the student_teams controller(shown in screenshot above in Problem 1) and with DueDate.get_next_due_date where the next due date was required.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 Before :&lt;br /&gt;
 due_date = find_current_stage(topic_id)&lt;br /&gt;
 &lt;br /&gt;
 After :&lt;br /&gt;
 due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==='''Problem 5'''===&lt;br /&gt;
&lt;br /&gt;
get_current_stage method is returning the stage name which the assignment is in at current time.This is not very clear from the name of the method.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
We have changed the method name to current_stage_name(topic_id=nil) to make it more clear to understand.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Refactored get_current_stage with current_stage_name&lt;br /&gt;
&lt;br /&gt;
[[File:Current stage name new.png|center]]&lt;br /&gt;
&lt;br /&gt;
==='''Problem 6'''===&lt;br /&gt;
&lt;br /&gt;
current_stage_name(topic_id=nil)[This is the initial one] method was implementing things which was already being done by other methods and thus this method was redundant. &lt;br /&gt;
The initial code given was:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if self.staggered_deadline?&lt;br /&gt;
      return (topic_id.nil? ? 'Unknown' : get_current_stage(topic_id))&lt;br /&gt;
    end&lt;br /&gt;
    due_date = find_current_stage(topic_id)&lt;br /&gt;
&lt;br /&gt;
    unless self.staggered_deadline?&lt;br /&gt;
      if due_date != 'Finished' &amp;amp;&amp;amp; !due_date.nil? &amp;amp;&amp;amp; !due_date.deadline_name.nil?&lt;br /&gt;
        return due_date.deadline_name&lt;br /&gt;
      else&lt;br /&gt;
        return get_current_stage(topic_id)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First thing we noticed was that due_date.deadline_name was always nil because there was no field to enter the deadline name on the form, and therefore, the statement  &amp;lt;pre&amp;gt; return due_date.deadline_name &amp;lt;/pre&amp;gt; was never getting executed. &lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
This method was checking for the due_date.deadline_name which was always nil. After removing the dead code, we get:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    if topic_missing?(topic_id)&lt;br /&gt;
      return 'Unknown'&lt;br /&gt;
    else&lt;br /&gt;
      get_current_stage(topic_id)&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Looking at the get_current_stage_name(topic_id=nil) method shown below and comparing it to what we have above, this code was surely redundant.That is why we removed this code and made appropriate changes wherever required within assignment.rb.&lt;br /&gt;
*Below is the get_current_stage_name method for reference&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  def current_stage_name(topic_id = nil)&lt;br /&gt;
    return 'Unknown' if topic_missing?(topic_id)&lt;br /&gt;
    due_date = DueDate.get_next_due_date(self.id, topic_id)&lt;br /&gt;
    finished?(topic_id)? &amp;quot;Finished&amp;quot; : DeadlineType.find(due_date.deadline_type_id).name&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The associated rspec tests that tested the current_stage method were also no longer needed.&lt;br /&gt;
&lt;br /&gt;
==='''Problem 7'''===&lt;br /&gt;
&lt;br /&gt;
link_for_current_stage function served no purpose. The function checked to see if any given due date had a link (presumably web URL) and would return it. The database had no values and there is no where in the application this URL could be provided. There doesn't appear to be any use for having a separate URL for each stage.&lt;br /&gt;
&lt;br /&gt;
===='''Solution'''====&lt;br /&gt;
&lt;br /&gt;
Removed function. &lt;br /&gt;
&lt;br /&gt;
[[File:Big1.png|center]]&lt;br /&gt;
&lt;br /&gt;
Removed test related to the function. Removed the one call to this function.&lt;br /&gt;
&lt;br /&gt;
[[File:big2.png|center]]&lt;br /&gt;
&lt;br /&gt;
=='''Automated Testing using RSPEC'''==&lt;br /&gt;
&lt;br /&gt;
===='''Tests for get_current_stage_name'''====&lt;br /&gt;
&lt;br /&gt;
The current version of expertiza did not have any tests for get_current_stage(topic_id=nil) method.Now as we have changed it to current_stage_name(topic_id=nil),we have added its tests as well.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#current_stage_name' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.current_stage_name).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns Finished' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Finished')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns current stage name' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:topic_missing?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          deadline = create(:deadline_type, id: 1, name:&amp;quot;Review&amp;quot;)&lt;br /&gt;
          allow(DeadlineType).to receive(:find).with(1).and_return(deadline)&lt;br /&gt;
          expect(assignment.current_stage_name(123)).to eq('Review')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===='''Tests for finished?'''====&lt;br /&gt;
&lt;br /&gt;
We have added tests for the new method that we have added finished?.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when assignment next due date is nil' do&lt;br /&gt;
      it 'returns True' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1, 123).and_return(nil)&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(true)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  describe '#finished?' do&lt;br /&gt;
    context 'when there is a next due date' do&lt;br /&gt;
      it 'returns False' do&lt;br /&gt;
        allow(DueDate).to receive(:get_next_due_date).with(1,123).and_return('2021-11-11 11:11:11')&lt;br /&gt;
        expect(assignment.finished?(123)).to eq(false)&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As topic_missing? method is made private,there was no need to test this.&lt;br /&gt;
&lt;br /&gt;
===='''Tests for stage_deadline'''====&lt;br /&gt;
&lt;br /&gt;
We also have corrected the tests for stage_deadline according to the modifications done(It is using finished? and topic_missing? methods).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  describe '#stage_deadline' do&lt;br /&gt;
    context 'when topic id is nil and current assignment has staggered deadline' do&lt;br /&gt;
      it 'returns Unknown' do&lt;br /&gt;
        allow(assignment).to receive(:topic_missing?).and_return(true)&lt;br /&gt;
        expect(assignment.stage_deadline).to eq('Unknown')&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    context 'when current assignment does not have staggered deadline' do&lt;br /&gt;
      context 'when due date is nil' do&lt;br /&gt;
        it 'returns nil' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(true)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to be nil&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
&lt;br /&gt;
      context 'when due date is not nil and due date is not equal to Finished' do&lt;br /&gt;
        it 'returns due date' do&lt;br /&gt;
          allow(assignment).to receive(:finished?).with(123).and_return(false)&lt;br /&gt;
          allow(assignment).to receive(:next_due_date).with(123).and_return(assignment_due_date)&lt;br /&gt;
          expect(assignment.stage_deadline(123)).to match('2011-11-11 11:11:11')&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=='''Team'''==&lt;br /&gt;
[mailto:jwboykin@ncsu.edu Jimmy Boykin]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:rkaur@ncsu.edu Ramandeep Kaur]&amp;lt;br&amp;gt;&lt;br /&gt;
[mailto:sbasnet2@ncsu.edu Sushan Basnet]&lt;/div&gt;</summary>
		<author><name>Rkaur</name></author>
	</entry>
</feed>