<?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=Jlin36</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=Jlin36"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Jlin36"/>
	<updated>2026-07-01T07:21:39Z</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_2022_-_E2232:_Revision_planning_tool&amp;diff=145398</id>
		<title>CSC/ECE 517 Spring 2022 - E2232: Revision planning tool</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=145398"/>
		<updated>2022-04-26T03:41:06Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Project Goal==&lt;br /&gt;
The primary objective for this project is to create a tool that can be used for the revision of projects at a time after their original submission upon the delivery of constructive feedback from their peers or instructors. The revision planning tool is an important device that will be used to give students the ability to learn from the mistakes of their submissions, and improve the quality of their work prior to the due date. This will be done by completing the existing implementation for revision planning using the following project plan. &lt;br /&gt;
&lt;br /&gt;
==Project Plan==&lt;br /&gt;
To merge code for revision planning into current beta.&lt;br /&gt;
&lt;br /&gt;
E2152's work was to develop a revision planning tool and merge it into the beta branch of Expertiza. They completed their task but developed based on a previous beta branch version and thus could not be merged into the current beta. Our goal is to reimplement their change so that it merges into the current beta branch. We will first merge the modification in the following files to the current beta and solve the conflicts.&lt;br /&gt;
 &lt;br /&gt;
===Files to be merged===&lt;br /&gt;
* app/controllers/revision_plan_questionnaires_controller.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* app/controllers/grades_controller.rb&lt;br /&gt;
* app/helpers/grades_helper.rb&lt;br /&gt;
* app/models/assignment_participant.rb&lt;br /&gt;
* app/models/response_map.rb&lt;br /&gt;
* app/views/grades/_participant_charts.html.erb&lt;br /&gt;
* app/views/grades/view_team.html.erb&lt;br /&gt;
* app/views/student_task/view.html.erb&lt;br /&gt;
* app/controllers/response_controller.rb&lt;br /&gt;
* app/views/response/response.html.erb&lt;br /&gt;
* config/routes.rb&lt;br /&gt;
* db/schema.rb&lt;br /&gt;
* spec/models/response_spec.rb&lt;br /&gt;
* spec/models/review_response_map_spec.rb&lt;br /&gt;
* spec/features/assignment_creation_general_tab_spec.rb&lt;br /&gt;
* app/models/revision_plan_team_map.rb&lt;br /&gt;
* spec/controllers/advice_controller_spec.rb&lt;br /&gt;
* app/models/response.rb&lt;br /&gt;
&lt;br /&gt;
The following diagram shows the the revision planning tool's use:&lt;br /&gt;
&lt;br /&gt;
[[File:E2232_diagram.png]]&lt;br /&gt;
&lt;br /&gt;
==Current Project Implementation==&lt;br /&gt;
&lt;br /&gt;
The implementation of this now fits within the framework created by E2161 (Fall 2021). &lt;br /&gt;
&lt;br /&gt;
What it does: In the first round of Expertiza reviews, we ask reviewers to give authors some guidance on how to improve their work. Then in the second round, reviewers rate how well authors have followed their suggestions. Authors are now able to leave a plan of work attached to their reviews in order to indicate their plan to move forward with the criticism given by the peer reviews. This is done by utilizing controller classes for advice and response that are tasked with creating the objects, as implemented in the advice and response model classes respectively, saving them to the database and displaying them in the html files. We also ensure that response can only be performed by the appropriate members by indicating that actions are only permitted by those with instructor privilege (teaching assistants, admins, and instructors) as well as the student who has been assigned the review can alter them (seen here).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
  questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
  if(user_logged_in? &amp;amp;&amp;amp; questionnaire.owner?(session[:user].id))&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  current_user_has_ta_privileges?&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
Helper methods such as summary_helper.rb are used in order to receive values from existing objects, for example receiving the sentences as broken up into seperate array entries as is needed for the comments of the answers in the reviews.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def get_sentences(answer)&lt;br /&gt;
  if answer.nil?&lt;br /&gt;
    return nil&lt;br /&gt;
  end&lt;br /&gt;
  sentences = answer.comments.split(/[.,?,!]/) &lt;br /&gt;
  sentences.each{ |sentence| sentence.strip! }&lt;br /&gt;
&lt;br /&gt;
  sentences&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Rationale===&lt;br /&gt;
The general workflow will be maintained from the previous iterations working on this project. The workflow used by past semesters is as follows.&lt;br /&gt;
&lt;br /&gt;
[[File:E2152_Rationale.png|410px|center|Image from previous write up]]&lt;br /&gt;
&lt;br /&gt;
===Previous implementation===&lt;br /&gt;
This project was last done in Fall 2021 (E2152). However, related merged code from E2161 (link above) means the implementation this semester may need to be changed from how E2152 did it.&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/2131 Primary Pull Request for E2152]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/2152 Second Pull Request for Revision Planning]&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2152._Revision_planning_tool Previous write up for E2152]&lt;br /&gt;
&lt;br /&gt;
====Current Flow====&lt;br /&gt;
Current flow is dictated by previous iterations. The following content and images are created using those previous write ups.&lt;br /&gt;
&lt;br /&gt;
Prior to the round 2 submission, you could view your work, but not the revision plan.&lt;br /&gt;
[[File:211129-2.png|700px|thumb|center]]&lt;br /&gt;
If there is a round 2 submission, and we did not do the &amp;quot;Revision Planning&amp;quot;, then &amp;quot;Your work&amp;quot; becomes gray.&lt;br /&gt;
[[File:211129-5.png|700px|thumb|center]]&lt;br /&gt;
After editing the &amp;quot;Revision Planning&amp;quot;, we can submit our work.&lt;br /&gt;
[[File:211129-6.png|700px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=====Current User Interface=====&lt;br /&gt;
Current user interface has been put in place by the previous iterations, the following interface image is from those iterations.&lt;br /&gt;
&lt;br /&gt;
[[File:after1.png|700px|thumb|center|Reviews cannot be done during the submission phase]]&lt;br /&gt;
&lt;br /&gt;
====Design Changes====&lt;br /&gt;
Because the changes to the current implementation is limited to specific implementation, the UML design of the project will remain the same as the previous implementation.&lt;br /&gt;
&lt;br /&gt;
[[File:E2152_Design.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===Merge existing RSpec tests for revision planning into current beta===&lt;br /&gt;
We will first merge the existing RSpec tests of E2152 to the current beta, then run and pass these tests. More comments can be made in rspec tests as well. Observe the coverage of the individual tests. &lt;br /&gt;
Existing RSpec tests to be merged&lt;br /&gt;
* Controllers&lt;br /&gt;
** rspec spec/controllers/advice_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/grades_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/questionnaires_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/questions_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/student_teams_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/response_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/revision_plan_questionnaires_controller_spec.rb&lt;br /&gt;
** rspec spec/factories/revision_plan_factory.rb&lt;br /&gt;
* Models&lt;br /&gt;
** spec/models/response_spec.rb.&lt;br /&gt;
** spec/models/review_response_map_spec.rb&lt;br /&gt;
* Helpers&lt;br /&gt;
** rspec spec/heplers/grades_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Develop New RSpec Tests===&lt;br /&gt;
The RSpec tests are written to test both controllers and models. RSpec testing will be added in order to increase coverage. To do this we will test the flows associated with different user types. Currently the only passing tests are related to student flows and tests may be added that work with instructors. These may include editing the reviews once they are created, and ensuring that an instructor has the ability to make edits.&lt;br /&gt;
&lt;br /&gt;
Testing is done to ensure actions are allowed for teachers as well as the assigned student:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#action_allowed?' do&lt;br /&gt;
  let(:questionnaire) { build(:questionnaire, id: 1) }&lt;br /&gt;
  context 'when the role of current user is Super-Admin' do&lt;br /&gt;
    # Checking for Super-Admin&lt;br /&gt;
    it 'allows certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(super_admin, super_admin.role.name, super_admin.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_truthy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  context 'when the role of current user is Instructor' do&lt;br /&gt;
    # Checking for Instructor&lt;br /&gt;
    it 'allows certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(instructor1, instructor1.role.name, instructor1.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_truthy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  context 'when the role of current user is Student' do&lt;br /&gt;
    # Checking for Student&lt;br /&gt;
    it 'refuses certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(student1, student1.role.name, student1.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_falsey&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;
Testing is also done in order to ensure this in response controllers, and questionnaire controllers. Testing is done for model objects such as displaying as html (below) and ensuring fields are correctly returned&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when prefix is not nil, which means view_score page in instructor end' do&lt;br /&gt;
 it 'returns corresponding html code' do&lt;br /&gt;
    allow(response).to receive(:questionnaire_by_answer).with(answer).and_return(questionnaire)&lt;br /&gt;
    allow(questionnaire).to receive(:max_question_score).and_return(5)&lt;br /&gt;
    allow(questionnaire).to receive(:id).and_return(1)&lt;br /&gt;
    allow(assignment).to receive(:id).and_return(1)&lt;br /&gt;
    allow(question).to receive(:view_completed_question).with(1, answer, 5, nil, nil).and_return('Question HTML code')&lt;br /&gt;
    expect(response.display_as_html('Instructor end', 0)).to eq('&amp;lt;h4&amp;gt;&amp;lt;B&amp;gt;Review 0&amp;lt;/B&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;B&amp;gt;Reviewer: &amp;lt;/B&amp;gt;no one (no name)&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;'\&lt;br /&gt;
      &amp;quot;&amp;lt;a href=\&amp;quot;#\&amp;quot; name= \&amp;quot;review_Instructor end_1Link\&amp;quot; onClick=\&amp;quot;toggleElement('review_Instructor end_1','review');return false;\&amp;quot;&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;hide review&amp;lt;/a&amp;gt;&amp;lt;BR/&amp;gt;&amp;lt;h5&amp;gt;Review Responses&amp;lt;/h5&amp;gt;&amp;lt;table id=\&amp;quot;review_Instructor end_1\&amp;quot; class=\&amp;quot;table table-bordered\&amp;quot;&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;&amp;lt;tr class=\&amp;quot;warning\&amp;quot;&amp;gt;&amp;lt;td&amp;gt;Question HTML code&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;h5&amp;gt;Additional Comment&amp;lt;/h5&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;&amp;lt;table id=\&amp;quot;review_Instructor end_1\&amp;quot; class=\&amp;quot;table table-bordered\&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
rspec tests are also needed to validate saves for controller classes, and ensuring model functionality in response objects.&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
&lt;br /&gt;
* Instructor &lt;br /&gt;
** Can Review rubric varied by topic be enabled?&lt;br /&gt;
** Can different roles be chosen for each questionnaire? &lt;br /&gt;
** Can an assignment with revision planning enabled be created?&lt;br /&gt;
** Can an assignment with 2 rounds of review be set up?&lt;br /&gt;
&lt;br /&gt;
* Assignment participant &lt;br /&gt;
** If the revision-planning rubric can be edited or not?&lt;br /&gt;
** Are participants allowed to create/edit revision plan when round 1+ (1 or greater than 1) reviews have finished?&lt;br /&gt;
** Is revision plan editing disabled when the assignment is in review stage?&lt;br /&gt;
** Does participants show a summary of score for revision plan after review deadline has expired?&lt;br /&gt;
&lt;br /&gt;
* Assignment reviewer &lt;br /&gt;
** Does the rubric page show the topic-specific rubric?&lt;br /&gt;
** Does the rubric page show the revision plan rubric?&lt;br /&gt;
&lt;br /&gt;
==Team Information==&lt;br /&gt;
* Lawrence O'Brien (lpobrien)&lt;br /&gt;
* Joshua Lin (jlin36)&lt;br /&gt;
* Weiqi Sun (wsun23)&lt;br /&gt;
* Wyatt Plaga (wgplaga)&lt;br /&gt;
* '''Mentor:''' Nicholas Himes (nnhimes)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Pull request: https://github.com/expertiza/expertiza/pull/2395&lt;br /&gt;
* Github repo: https://github.com/wsun23/expertiza/tree/E2232&lt;br /&gt;
* VCL: http://152.7.99.215:8080/&lt;br /&gt;
* Screencast:&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=145391</id>
		<title>CSC/ECE 517 Spring 2022 - E2232: Revision planning tool</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=145391"/>
		<updated>2022-04-26T03:35:51Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: /* Develop New RSpec Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Project Goal==&lt;br /&gt;
The primary objective for this project is to create a tool that can be used for the revision of projects at a time after their original submission upon the delivery of constructive feedback from their peers or instructors. The revision planning tool is an important device that will be used to give students the ability to learn from the mistakes of their submissions, and improve the quality of their work prior to the due date. This will be done by completing the existing implementation for revision planning using the following project plan. &lt;br /&gt;
&lt;br /&gt;
==Project Plan==&lt;br /&gt;
To merge code for revision planning into current beta.&lt;br /&gt;
&lt;br /&gt;
E2152's work was to develop a revision planning tool and merge it into the beta branch of Expertiza. They completed their task but developed based on a previous beta branch version and thus could not be merged into the current beta. Our goal is to reimplement their change so that it merges into the current beta branch. We will first merge the modification in the following files to the current beta and solve the conflicts.&lt;br /&gt;
 &lt;br /&gt;
===Files to be merged===&lt;br /&gt;
* app/controllers/revision_plan_questionnaires_controller.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* app/controllers/grades_controller.rb&lt;br /&gt;
* app/helpers/grades_helper.rb&lt;br /&gt;
* app/models/assignment_participant.rb&lt;br /&gt;
* app/models/response_map.rb&lt;br /&gt;
* app/views/grades/_participant_charts.html.erb&lt;br /&gt;
* app/views/grades/view_team.html.erb&lt;br /&gt;
* app/views/student_task/view.html.erb&lt;br /&gt;
* app/controllers/response_controller.rb&lt;br /&gt;
* app/views/response/response.html.erb&lt;br /&gt;
* config/routes.rb&lt;br /&gt;
* db/schema.rb&lt;br /&gt;
* spec/models/response_spec.rb&lt;br /&gt;
* spec/models/review_response_map_spec.rb&lt;br /&gt;
* spec/features/assignment_creation_general_tab_spec.rb&lt;br /&gt;
* app/models/revision_plan_team_map.rb&lt;br /&gt;
* spec/controllers/advice_controller_spec.rb&lt;br /&gt;
* app/models/response.rb&lt;br /&gt;
&lt;br /&gt;
The following diagram shows the the revision planning tool's use:&lt;br /&gt;
&lt;br /&gt;
[[File:E2232_diagram.png]]&lt;br /&gt;
&lt;br /&gt;
==Current Project Implementation==&lt;br /&gt;
&lt;br /&gt;
The implementation of this now fits within the framework created by E2161 (Fall 2021). &lt;br /&gt;
&lt;br /&gt;
What it does: In the first round of Expertiza reviews, we ask reviewers to give authors some guidance on how to improve their work. Then in the second round, reviewers rate how well authors have followed their suggestions. Authors are now able to leave a plan of work attached to their reviews in order to indicate their plan to move forward with the criticism given by the peer reviews. This is done by utilizing controller classes for advice and response that are tasked with creating the objects, as implemented in the advice and response model classes respectively, saving them to the database and displaying them in the html files. We also ensure that response can only be performed by the appropriate members by indicating that actions are only permitted by those with instructor privilege (teaching assistants, admins, and instructors) as well as the student who has been assigned the review can alter them (seen here).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
  questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
  if(user_logged_in? &amp;amp;&amp;amp; questionnaire.owner?(session[:user].id))&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  current_user_has_ta_privileges?&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
Helper methods such as summary_helper.rb are used in order to receive values from existing objects, for example receiving the sentences as broken up into seperate array entries as is needed for the comments of the answers in the reviews.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def get_sentences(answer)&lt;br /&gt;
  if answer.nil?&lt;br /&gt;
    return nil&lt;br /&gt;
  end&lt;br /&gt;
  sentences = answer.comments.split(/[.,?,!]/) &lt;br /&gt;
  sentences.each{ |sentence| sentence.strip! }&lt;br /&gt;
&lt;br /&gt;
  sentences&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Rationale===&lt;br /&gt;
The general workflow will be maintained from the previous iterations working on this project. The workflow used by past semesters is as follows.&lt;br /&gt;
&lt;br /&gt;
[[File:E2152_Rationale.png|410px|center|Image from previous write up]]&lt;br /&gt;
&lt;br /&gt;
===Previous implementation===&lt;br /&gt;
This project was last done in Fall 2021 (E2152). However, related merged code from E2161 (link above) means the implementation this semester may need to be changed from how E2152 did it.&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/2131 Primary Pull Request for E2152]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/2152 Second Pull Request for Revision Planning]&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2152._Revision_planning_tool Previous write up for E2152]&lt;br /&gt;
&lt;br /&gt;
====Current Flow====&lt;br /&gt;
Current flow is dictated by previous iterations. The following content and images are created using those previous write ups.&lt;br /&gt;
&lt;br /&gt;
Prior to the round 2 submission, you could view your work, but not the revision plan.&lt;br /&gt;
[[File:211129-2.png|700px|thumb|center]]&lt;br /&gt;
If there is a round 2 submission, and we did not do the &amp;quot;Revision Planning&amp;quot;, then &amp;quot;Your work&amp;quot; becomes gray.&lt;br /&gt;
[[File:211129-5.png|700px|thumb|center]]&lt;br /&gt;
After editing the &amp;quot;Revision Planning&amp;quot;, we can submit our work.&lt;br /&gt;
[[File:211129-6.png|700px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=====Current User Interface=====&lt;br /&gt;
Current user interface has been put in place by the previous iterations, the following interface image is from those iterations.&lt;br /&gt;
&lt;br /&gt;
[[File:after1.png|700px|thumb|center|Reviews cannot be done during the submission phase]]&lt;br /&gt;
&lt;br /&gt;
====Design Changes====&lt;br /&gt;
Because the changes to the current implementation is limited to specific implementation, the UML design of the project will remain the same as the previous implementation.&lt;br /&gt;
&lt;br /&gt;
[[File:E2152_Design.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===Merge existing RSpec tests for revision planning into current beta===&lt;br /&gt;
We will first merge the existing RSpec tests of E2152 to the current beta, then run and pass these tests. More comments can be made in rspec tests as well. Observe the coverage of the individual tests. &lt;br /&gt;
Existing RSpec tests to be merged&lt;br /&gt;
* Controllers&lt;br /&gt;
** rspec spec/controllers/advice_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/grades_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/questionnaires_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/questions_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/student_teams_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/response_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/revision_plan_questionnaires_controller_spec.rb&lt;br /&gt;
** rspec spec/factories/revision_plan_factory.rb&lt;br /&gt;
* Models&lt;br /&gt;
** spec/models/response_spec.rb.&lt;br /&gt;
** spec/models/review_response_map_spec.rb&lt;br /&gt;
* Helpers&lt;br /&gt;
** rspec spec/heplers/grades_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Develop New RSpec Tests===&lt;br /&gt;
The RSpec tests are written to test both controllers and models. RSpec testing will be added in order to increase coverage. To do this we will test the flows associated with different user types. Currently the only passing tests are related to student flows and tests may be added that work with instructors. These may include editing the reviews once they are created, and ensuring that an instructor has the ability to make edits.&lt;br /&gt;
&lt;br /&gt;
Testing is done to ensure actions are allowed for teachers as well as the assigned student:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#action_allowed?' do&lt;br /&gt;
  let(:questionnaire) { build(:questionnaire, id: 1) }&lt;br /&gt;
  context 'when the role of current user is Super-Admin' do&lt;br /&gt;
    # Checking for Super-Admin&lt;br /&gt;
    it 'allows certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(super_admin, super_admin.role.name, super_admin.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_truthy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  context 'when the role of current user is Instructor' do&lt;br /&gt;
    # Checking for Instructor&lt;br /&gt;
    it 'allows certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(instructor1, instructor1.role.name, instructor1.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_truthy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  context 'when the role of current user is Student' do&lt;br /&gt;
    # Checking for Student&lt;br /&gt;
    it 'refuses certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(student1, student1.role.name, student1.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_falsey&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;
Testing is also done in order to ensure this in response controllers, and questionnaire controllers. Testing is done for model objects such as displaying as html (below) and ensuring fields are correctly returned&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when prefix is not nil, which means view_score page in instructor end' do&lt;br /&gt;
 it 'returns corresponding html code' do&lt;br /&gt;
    allow(response).to receive(:questionnaire_by_answer).with(answer).and_return(questionnaire)&lt;br /&gt;
    allow(questionnaire).to receive(:max_question_score).and_return(5)&lt;br /&gt;
    allow(questionnaire).to receive(:id).and_return(1)&lt;br /&gt;
    allow(assignment).to receive(:id).and_return(1)&lt;br /&gt;
    allow(question).to receive(:view_completed_question).with(1, answer, 5, nil, nil).and_return('Question HTML code')&lt;br /&gt;
    expect(response.display_as_html('Instructor end', 0)).to eq('&amp;lt;h4&amp;gt;&amp;lt;B&amp;gt;Review 0&amp;lt;/B&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;B&amp;gt;Reviewer: &amp;lt;/B&amp;gt;no one (no name)&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;'\&lt;br /&gt;
      &amp;quot;&amp;lt;a href=\&amp;quot;#\&amp;quot; name= \&amp;quot;review_Instructor end_1Link\&amp;quot; onClick=\&amp;quot;toggleElement('review_Instructor end_1','review');return false;\&amp;quot;&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;hide review&amp;lt;/a&amp;gt;&amp;lt;BR/&amp;gt;&amp;lt;h5&amp;gt;Review Responses&amp;lt;/h5&amp;gt;&amp;lt;table id=\&amp;quot;review_Instructor end_1\&amp;quot; class=\&amp;quot;table table-bordered\&amp;quot;&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;&amp;lt;tr class=\&amp;quot;warning\&amp;quot;&amp;gt;&amp;lt;td&amp;gt;Question HTML code&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;h5&amp;gt;Additional Comment&amp;lt;/h5&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;&amp;lt;table id=\&amp;quot;review_Instructor end_1\&amp;quot; class=\&amp;quot;table table-bordered\&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
rspec tests are also needed to validate saves for controller classes, and ensuring model functionality in response objects.&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
&lt;br /&gt;
* Instructor &lt;br /&gt;
** Can Review rubric varied by topic be enabled?&lt;br /&gt;
** Can different roles be chosen for each questionnaire? &lt;br /&gt;
** Can an assignment with revision planning enabled be created?&lt;br /&gt;
** Can an assignment with 2 rounds of review be set up?&lt;br /&gt;
&lt;br /&gt;
* Assignment participant &lt;br /&gt;
** If the revision-planning rubric can be edited or not?&lt;br /&gt;
** Are participants allowed to create/edit revision plan when round 1+ (1 or greater than 1) reviews have finished?&lt;br /&gt;
** Is revision plan editing disabled when the assignment is in review stage?&lt;br /&gt;
** Does participants show a summary of score for revision plan after review deadline has expired?&lt;br /&gt;
&lt;br /&gt;
* Assignment reviewer &lt;br /&gt;
** Does the rubric page show the topic-specific rubric?&lt;br /&gt;
** Does the rubric page show the revision plan rubric?&lt;br /&gt;
&lt;br /&gt;
==Team Information==&lt;br /&gt;
* Lawrence O'Brien (lpobrien)&lt;br /&gt;
* Joshua Lin (jlin36)&lt;br /&gt;
* Weiqi Sun (wsun23)&lt;br /&gt;
* Wyatt Plaga (wgplaga)&lt;br /&gt;
* '''Mentor:''' Nicholas Himes (nnhimes)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Pull request: https://github.com/expertiza/expertiza/pull/2395&lt;br /&gt;
* Github repo: https://github.com/wsun23/expertiza/tree/E2232&lt;br /&gt;
* VCL: http://152.7.99.215:8080/&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=145388</id>
		<title>CSC/ECE 517 Spring 2022 - E2232: Revision planning tool</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=145388"/>
		<updated>2022-04-26T03:32:31Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: /* Develop New RSpec Tests */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Project Goal==&lt;br /&gt;
The primary objective for this project is to create a tool that can be used for the revision of projects at a time after their original submission upon the delivery of constructive feedback from their peers or instructors. The revision planning tool is an important device that will be used to give students the ability to learn from the mistakes of their submissions, and improve the quality of their work prior to the due date. This will be done by completing the existing implementation for revision planning using the following project plan. &lt;br /&gt;
&lt;br /&gt;
==Project Plan==&lt;br /&gt;
To merge code for revision planning into current beta.&lt;br /&gt;
&lt;br /&gt;
E2152's work was to develop a revision planning tool and merge it into the beta branch of Expertiza. They completed their task but developed based on a previous beta branch version and thus could not be merged into the current beta. Our goal is to reimplement their change so that it merges into the current beta branch. We will first merge the modification in the following files to the current beta and solve the conflicts.&lt;br /&gt;
 &lt;br /&gt;
===Files to be merged===&lt;br /&gt;
* app/controllers/revision_plan_questionnaires_controller.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* app/controllers/grades_controller.rb&lt;br /&gt;
* app/helpers/grades_helper.rb&lt;br /&gt;
* app/models/assignment_participant.rb&lt;br /&gt;
* app/models/response_map.rb&lt;br /&gt;
* app/views/grades/_participant_charts.html.erb&lt;br /&gt;
* app/views/grades/view_team.html.erb&lt;br /&gt;
* app/views/student_task/view.html.erb&lt;br /&gt;
* app/controllers/response_controller.rb&lt;br /&gt;
* app/views/response/response.html.erb&lt;br /&gt;
* config/routes.rb&lt;br /&gt;
* db/schema.rb&lt;br /&gt;
* spec/models/response_spec.rb&lt;br /&gt;
* spec/models/review_response_map_spec.rb&lt;br /&gt;
* spec/features/assignment_creation_general_tab_spec.rb&lt;br /&gt;
* app/models/revision_plan_team_map.rb&lt;br /&gt;
* spec/controllers/advice_controller_spec.rb&lt;br /&gt;
* app/models/response.rb&lt;br /&gt;
&lt;br /&gt;
The following diagram shows the the revision planning tool's use:&lt;br /&gt;
&lt;br /&gt;
[[File:E2232_diagram.png]]&lt;br /&gt;
&lt;br /&gt;
==Current Project Implementation==&lt;br /&gt;
&lt;br /&gt;
The implementation of this now fits within the framework created by E2161 (Fall 2021). &lt;br /&gt;
&lt;br /&gt;
What it does: In the first round of Expertiza reviews, we ask reviewers to give authors some guidance on how to improve their work. Then in the second round, reviewers rate how well authors have followed their suggestions. Authors are now able to leave a plan of work attached to their reviews in order to indicate their plan to move forward with the criticism given by the peer reviews. This is done by utilizing controller classes for advice and response that are tasked with creating the objects, as implemented in the advice and response model classes respectively, saving them to the database and displaying them in the html files. We also ensure that response can only be performed by the appropriate members by indicating that actions are only permitted by those with instructor privilege (teaching assistants, admins, and instructors) as well as the student who has been assigned the review can alter them (seen here).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
  questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
  if(user_logged_in? &amp;amp;&amp;amp; questionnaire.owner?(session[:user].id))&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  current_user_has_ta_privileges?&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
Helper methods such as summary_helper.rb are used in order to receive values from existing objects, for example receiving the sentences as broken up into seperate array entries as is needed for the comments of the answers in the reviews.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def get_sentences(answer)&lt;br /&gt;
  if answer.nil?&lt;br /&gt;
    return nil&lt;br /&gt;
  end&lt;br /&gt;
  sentences = answer.comments.split(/[.,?,!]/) &lt;br /&gt;
  sentences.each{ |sentence| sentence.strip! }&lt;br /&gt;
&lt;br /&gt;
  sentences&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Rationale===&lt;br /&gt;
The general workflow will be maintained from the previous iterations working on this project. The workflow used by past semesters is as follows.&lt;br /&gt;
&lt;br /&gt;
[[File:E2152_Rationale.png|410px|center|Image from previous write up]]&lt;br /&gt;
&lt;br /&gt;
===Previous implementation===&lt;br /&gt;
This project was last done in Fall 2021 (E2152). However, related merged code from E2161 (link above) means the implementation this semester may need to be changed from how E2152 did it.&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/2131 Primary Pull Request for E2152]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/2152 Second Pull Request for Revision Planning]&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2152._Revision_planning_tool Previous write up for E2152]&lt;br /&gt;
&lt;br /&gt;
====Current Flow====&lt;br /&gt;
Current flow is dictated by previous iterations. The following content and images are created using those previous write ups.&lt;br /&gt;
&lt;br /&gt;
Prior to the round 2 submission, you could view your work, but not the revision plan.&lt;br /&gt;
[[File:211129-2.png|700px|thumb|center]]&lt;br /&gt;
If there is a round 2 submission, and we did not do the &amp;quot;Revision Planning&amp;quot;, then &amp;quot;Your work&amp;quot; becomes gray.&lt;br /&gt;
[[File:211129-5.png|700px|thumb|center]]&lt;br /&gt;
After editing the &amp;quot;Revision Planning&amp;quot;, we can submit our work.&lt;br /&gt;
[[File:211129-6.png|700px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=====Current User Interface=====&lt;br /&gt;
Current user interface has been put in place by the previous iterations, the following interface image is from those iterations.&lt;br /&gt;
&lt;br /&gt;
[[File:after1.png|700px|thumb|center|Reviews cannot be done during the submission phase]]&lt;br /&gt;
&lt;br /&gt;
====Design Changes====&lt;br /&gt;
Because the changes to the current implementation is limited to specific implementation, the UML design of the project will remain the same as the previous implementation.&lt;br /&gt;
&lt;br /&gt;
[[File:E2152_Design.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===Merge existing RSpec tests for revision planning into current beta===&lt;br /&gt;
We will first merge the existing RSpec tests of E2152 to the current beta, then run and pass these tests. More comments can be made in rspec tests as well. Observe the coverage of the individual tests. &lt;br /&gt;
Existing RSpec tests to be merged&lt;br /&gt;
* Controllers&lt;br /&gt;
** rspec spec/controllers/advice_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/grades_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/questionnaires_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/questions_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/student_teams_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/response_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/revision_plan_questionnaires_controller_spec.rb&lt;br /&gt;
** rspec spec/factories/revision_plan_factory.rb&lt;br /&gt;
* Models&lt;br /&gt;
** spec/models/response_spec.rb.&lt;br /&gt;
** spec/models/review_response_map_spec.rb&lt;br /&gt;
* Helpers&lt;br /&gt;
** rspec spec/heplers/grades_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Develop New RSpec Tests===&lt;br /&gt;
The RSpec tests are written to test both controllers and models. RSpec testing will be added in order to increase coverage. To do this we will test the flows associated with different user types. Currently the only passing tests are related to student flows and tests may be added that work with instructors. These may include editing the reviews once they are created, and ensuring that an instructor has the ability to make edits.&lt;br /&gt;
&lt;br /&gt;
Testing is done to ensure actions are allowed for teachers as well as the assigned student:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#action_allowed?' do&lt;br /&gt;
  let(:questionnaire) { build(:questionnaire, id: 1) }&lt;br /&gt;
  context 'when the role of current user is Super-Admin' do&lt;br /&gt;
    # Checking for Super-Admin&lt;br /&gt;
    it 'allows certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(super_admin, super_admin.role.name, super_admin.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_truthy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  context 'when the role of current user is Instructor' do&lt;br /&gt;
    # Checking for Instructor&lt;br /&gt;
    it 'allows certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(instructor1, instructor1.role.name, instructor1.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_truthy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  context 'when the role of current user is Student' do&lt;br /&gt;
    # Checking for Student&lt;br /&gt;
    it 'refuses certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(student1, student1.role.name, student1.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_falsey&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;
Testing is also done in order ensure this in response controllers, and questionnaire controllers. Testing is done for model objects such as displaying as html (below) and ensuring fields are correctly returned&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when prefix is not nil, which means view_score page in instructor end' do&lt;br /&gt;
 it 'returns corresponding html code' do&lt;br /&gt;
    allow(response).to receive(:questionnaire_by_answer).with(answer).and_return(questionnaire)&lt;br /&gt;
    allow(questionnaire).to receive(:max_question_score).and_return(5)&lt;br /&gt;
    allow(questionnaire).to receive(:id).and_return(1)&lt;br /&gt;
    allow(assignment).to receive(:id).and_return(1)&lt;br /&gt;
    allow(question).to receive(:view_completed_question).with(1, answer, 5, nil, nil).and_return('Question HTML code')&lt;br /&gt;
    expect(response.display_as_html('Instructor end', 0)).to eq('&amp;lt;h4&amp;gt;&amp;lt;B&amp;gt;Review 0&amp;lt;/B&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;B&amp;gt;Reviewer: &amp;lt;/B&amp;gt;no one (no name)&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;'\&lt;br /&gt;
      &amp;quot;&amp;lt;a href=\&amp;quot;#\&amp;quot; name= \&amp;quot;review_Instructor end_1Link\&amp;quot; onClick=\&amp;quot;toggleElement('review_Instructor end_1','review');return false;\&amp;quot;&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;hide review&amp;lt;/a&amp;gt;&amp;lt;BR/&amp;gt;&amp;lt;h5&amp;gt;Review Responses&amp;lt;/h5&amp;gt;&amp;lt;table id=\&amp;quot;review_Instructor end_1\&amp;quot; class=\&amp;quot;table table-bordered\&amp;quot;&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;&amp;lt;tr class=\&amp;quot;warning\&amp;quot;&amp;gt;&amp;lt;td&amp;gt;Question HTML code&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;h5&amp;gt;Additional Comment&amp;lt;/h5&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;&amp;lt;table id=\&amp;quot;review_Instructor end_1\&amp;quot; class=\&amp;quot;table table-bordered\&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
rspec tests are also needed for validing saves for controller classes, and ensuring model functionality in response objects.&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
&lt;br /&gt;
* Instructor &lt;br /&gt;
** Can Review rubric varied by topic be enabled?&lt;br /&gt;
** Can different roles be chosen for each questionnaire? &lt;br /&gt;
** Can an assignment with revision planning enabled be created?&lt;br /&gt;
** Can an assignment with 2 rounds of review be set up?&lt;br /&gt;
&lt;br /&gt;
* Assignment participant &lt;br /&gt;
** If the revision-planning rubric can be edited or not?&lt;br /&gt;
** Are participants allowed to create/edit revision plan when round 1+ (1 or greater than 1) reviews have finished?&lt;br /&gt;
** Is revision plan editing disabled when the assignment is in review stage?&lt;br /&gt;
** Does participants show a summary of score for revision plan after review deadline has expired?&lt;br /&gt;
&lt;br /&gt;
* Assignment reviewer &lt;br /&gt;
** Does the rubric page show the topic-specific rubric?&lt;br /&gt;
** Does the rubric page show the revision plan rubric?&lt;br /&gt;
&lt;br /&gt;
==Team Information==&lt;br /&gt;
* Lawrence O'Brien (lpobrien)&lt;br /&gt;
* Joshua Lin (jlin36)&lt;br /&gt;
* Weiqi Sun (wsun23)&lt;br /&gt;
* Wyatt Plaga (wgplaga)&lt;br /&gt;
* '''Mentor:''' Nicholas Himes (nnhimes)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Pull request: https://github.com/expertiza/expertiza/pull/2395&lt;br /&gt;
* Github repo: https://github.com/wsun23/expertiza/tree/E2232&lt;br /&gt;
* VCL: http://152.7.99.215:8080/&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=145387</id>
		<title>CSC/ECE 517 Spring 2022 - E2232: Revision planning tool</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=145387"/>
		<updated>2022-04-26T03:31:50Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: /* Merge existing RSpec tests for revision planning into current beta */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Project Goal==&lt;br /&gt;
The primary objective for this project is to create a tool that can be used for the revision of projects at a time after their original submission upon the delivery of constructive feedback from their peers or instructors. The revision planning tool is an important device that will be used to give students the ability to learn from the mistakes of their submissions, and improve the quality of their work prior to the due date. This will be done by completing the existing implementation for revision planning using the following project plan. &lt;br /&gt;
&lt;br /&gt;
==Project Plan==&lt;br /&gt;
To merge code for revision planning into current beta.&lt;br /&gt;
&lt;br /&gt;
E2152's work was to develop a revision planning tool and merge it into the beta branch of Expertiza. They completed their task but developed based on a previous beta branch version and thus could not be merged into the current beta. Our goal is to reimplement their change so that it merges into the current beta branch. We will first merge the modification in the following files to the current beta and solve the conflicts.&lt;br /&gt;
 &lt;br /&gt;
===Files to be merged===&lt;br /&gt;
* app/controllers/revision_plan_questionnaires_controller.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* app/controllers/grades_controller.rb&lt;br /&gt;
* app/helpers/grades_helper.rb&lt;br /&gt;
* app/models/assignment_participant.rb&lt;br /&gt;
* app/models/response_map.rb&lt;br /&gt;
* app/views/grades/_participant_charts.html.erb&lt;br /&gt;
* app/views/grades/view_team.html.erb&lt;br /&gt;
* app/views/student_task/view.html.erb&lt;br /&gt;
* app/controllers/response_controller.rb&lt;br /&gt;
* app/views/response/response.html.erb&lt;br /&gt;
* config/routes.rb&lt;br /&gt;
* db/schema.rb&lt;br /&gt;
* spec/models/response_spec.rb&lt;br /&gt;
* spec/models/review_response_map_spec.rb&lt;br /&gt;
* spec/features/assignment_creation_general_tab_spec.rb&lt;br /&gt;
* app/models/revision_plan_team_map.rb&lt;br /&gt;
* spec/controllers/advice_controller_spec.rb&lt;br /&gt;
* app/models/response.rb&lt;br /&gt;
&lt;br /&gt;
The following diagram shows the the revision planning tool's use:&lt;br /&gt;
&lt;br /&gt;
[[File:E2232_diagram.png]]&lt;br /&gt;
&lt;br /&gt;
==Current Project Implementation==&lt;br /&gt;
&lt;br /&gt;
The implementation of this now fits within the framework created by E2161 (Fall 2021). &lt;br /&gt;
&lt;br /&gt;
What it does: In the first round of Expertiza reviews, we ask reviewers to give authors some guidance on how to improve their work. Then in the second round, reviewers rate how well authors have followed their suggestions. Authors are now able to leave a plan of work attached to their reviews in order to indicate their plan to move forward with the criticism given by the peer reviews. This is done by utilizing controller classes for advice and response that are tasked with creating the objects, as implemented in the advice and response model classes respectively, saving them to the database and displaying them in the html files. We also ensure that response can only be performed by the appropriate members by indicating that actions are only permitted by those with instructor privilege (teaching assistants, admins, and instructors) as well as the student who has been assigned the review can alter them (seen here).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
  questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
  if(user_logged_in? &amp;amp;&amp;amp; questionnaire.owner?(session[:user].id))&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  current_user_has_ta_privileges?&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
Helper methods such as summary_helper.rb are used in order to receive values from existing objects, for example receiving the sentences as broken up into seperate array entries as is needed for the comments of the answers in the reviews.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def get_sentences(answer)&lt;br /&gt;
  if answer.nil?&lt;br /&gt;
    return nil&lt;br /&gt;
  end&lt;br /&gt;
  sentences = answer.comments.split(/[.,?,!]/) &lt;br /&gt;
  sentences.each{ |sentence| sentence.strip! }&lt;br /&gt;
&lt;br /&gt;
  sentences&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Rationale===&lt;br /&gt;
The general workflow will be maintained from the previous iterations working on this project. The workflow used by past semesters is as follows.&lt;br /&gt;
&lt;br /&gt;
[[File:E2152_Rationale.png|410px|center|Image from previous write up]]&lt;br /&gt;
&lt;br /&gt;
===Previous implementation===&lt;br /&gt;
This project was last done in Fall 2021 (E2152). However, related merged code from E2161 (link above) means the implementation this semester may need to be changed from how E2152 did it.&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/2131 Primary Pull Request for E2152]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/2152 Second Pull Request for Revision Planning]&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2152._Revision_planning_tool Previous write up for E2152]&lt;br /&gt;
&lt;br /&gt;
====Current Flow====&lt;br /&gt;
Current flow is dictated by previous iterations. The following content and images are created using those previous write ups.&lt;br /&gt;
&lt;br /&gt;
Prior to the round 2 submission, you could view your work, but not the revision plan.&lt;br /&gt;
[[File:211129-2.png|700px|thumb|center]]&lt;br /&gt;
If there is a round 2 submission, and we did not do the &amp;quot;Revision Planning&amp;quot;, then &amp;quot;Your work&amp;quot; becomes gray.&lt;br /&gt;
[[File:211129-5.png|700px|thumb|center]]&lt;br /&gt;
After editing the &amp;quot;Revision Planning&amp;quot;, we can submit our work.&lt;br /&gt;
[[File:211129-6.png|700px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=====Current User Interface=====&lt;br /&gt;
Current user interface has been put in place by the previous iterations, the following interface image is from those iterations.&lt;br /&gt;
&lt;br /&gt;
[[File:after1.png|700px|thumb|center|Reviews cannot be done during the submission phase]]&lt;br /&gt;
&lt;br /&gt;
====Design Changes====&lt;br /&gt;
Because the changes to the current implementation is limited to specific implementation, the UML design of the project will remain the same as the previous implementation.&lt;br /&gt;
&lt;br /&gt;
[[File:E2152_Design.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===Merge existing RSpec tests for revision planning into current beta===&lt;br /&gt;
We will first merge the existing RSpec tests of E2152 to the current beta, then run and pass these tests. More comments can be made in rspec tests as well. Observe the coverage of the individual tests. &lt;br /&gt;
Existing RSpec tests to be merged&lt;br /&gt;
* Controllers&lt;br /&gt;
** rspec spec/controllers/advice_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/grades_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/questionnaires_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/questions_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/student_teams_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/response_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/revision_plan_questionnaires_controller_spec.rb&lt;br /&gt;
** rspec spec/factories/revision_plan_factory.rb&lt;br /&gt;
* Models&lt;br /&gt;
** spec/models/response_spec.rb.&lt;br /&gt;
** spec/models/review_response_map_spec.rb&lt;br /&gt;
* Helpers&lt;br /&gt;
** rspec spec/heplers/grades_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Develop New RSpec Tests===&lt;br /&gt;
The RSpec tests are written to test both controllers and models. RSpec testing will be added in order to increase coverage. To do this we will test the flows associated with different user types. Currently the only passing tests are related to student flows and tests may be added that work with instructors. These may include editing the reviews once they are created, and ensuring that an instructor has the ability to make edits.&lt;br /&gt;
&lt;br /&gt;
Testing is done for ensuring actions are allowed for teachers as well as the assigned student:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#action_allowed?' do&lt;br /&gt;
  let(:questionnaire) { build(:questionnaire, id: 1) }&lt;br /&gt;
  context 'when the role of current user is Super-Admin' do&lt;br /&gt;
    # Checking for Super-Admin&lt;br /&gt;
    it 'allows certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(super_admin, super_admin.role.name, super_admin.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_truthy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  context 'when the role of current user is Instructor' do&lt;br /&gt;
    # Checking for Instructor&lt;br /&gt;
    it 'allows certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(instructor1, instructor1.role.name, instructor1.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_truthy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  context 'when the role of current user is Student' do&lt;br /&gt;
    # Checking for Student&lt;br /&gt;
    it 'refuses certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(student1, student1.role.name, student1.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_falsey&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;
Testing is also done in order ensure this in response controllers, and questionnaire controllers. Testing is done for model objects such as displaying as html (below) and ensuring fields are correctly returned&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when prefix is not nil, which means view_score page in instructor end' do&lt;br /&gt;
 it 'returns corresponding html code' do&lt;br /&gt;
    allow(response).to receive(:questionnaire_by_answer).with(answer).and_return(questionnaire)&lt;br /&gt;
    allow(questionnaire).to receive(:max_question_score).and_return(5)&lt;br /&gt;
    allow(questionnaire).to receive(:id).and_return(1)&lt;br /&gt;
    allow(assignment).to receive(:id).and_return(1)&lt;br /&gt;
    allow(question).to receive(:view_completed_question).with(1, answer, 5, nil, nil).and_return('Question HTML code')&lt;br /&gt;
    expect(response.display_as_html('Instructor end', 0)).to eq('&amp;lt;h4&amp;gt;&amp;lt;B&amp;gt;Review 0&amp;lt;/B&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;B&amp;gt;Reviewer: &amp;lt;/B&amp;gt;no one (no name)&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;'\&lt;br /&gt;
      &amp;quot;&amp;lt;a href=\&amp;quot;#\&amp;quot; name= \&amp;quot;review_Instructor end_1Link\&amp;quot; onClick=\&amp;quot;toggleElement('review_Instructor end_1','review');return false;\&amp;quot;&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;hide review&amp;lt;/a&amp;gt;&amp;lt;BR/&amp;gt;&amp;lt;h5&amp;gt;Review Responses&amp;lt;/h5&amp;gt;&amp;lt;table id=\&amp;quot;review_Instructor end_1\&amp;quot; class=\&amp;quot;table table-bordered\&amp;quot;&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;&amp;lt;tr class=\&amp;quot;warning\&amp;quot;&amp;gt;&amp;lt;td&amp;gt;Question HTML code&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;h5&amp;gt;Additional Comment&amp;lt;/h5&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;&amp;lt;table id=\&amp;quot;review_Instructor end_1\&amp;quot; class=\&amp;quot;table table-bordered\&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
rspec tests are also needed for validing saves for controller classes, and ensuring model functionality in response objects.&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
&lt;br /&gt;
* Instructor &lt;br /&gt;
** Can Review rubric varied by topic be enabled?&lt;br /&gt;
** Can different roles be chosen for each questionnaire? &lt;br /&gt;
** Can an assignment with revision planning enabled be created?&lt;br /&gt;
** Can an assignment with 2 rounds of review be set up?&lt;br /&gt;
&lt;br /&gt;
* Assignment participant &lt;br /&gt;
** If the revision-planning rubric can be edited or not?&lt;br /&gt;
** Are participants allowed to create/edit revision plan when round 1+ (1 or greater than 1) reviews have finished?&lt;br /&gt;
** Is revision plan editing disabled when the assignment is in review stage?&lt;br /&gt;
** Does participants show a summary of score for revision plan after review deadline has expired?&lt;br /&gt;
&lt;br /&gt;
* Assignment reviewer &lt;br /&gt;
** Does the rubric page show the topic-specific rubric?&lt;br /&gt;
** Does the rubric page show the revision plan rubric?&lt;br /&gt;
&lt;br /&gt;
==Team Information==&lt;br /&gt;
* Lawrence O'Brien (lpobrien)&lt;br /&gt;
* Joshua Lin (jlin36)&lt;br /&gt;
* Weiqi Sun (wsun23)&lt;br /&gt;
* Wyatt Plaga (wgplaga)&lt;br /&gt;
* '''Mentor:''' Nicholas Himes (nnhimes)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Pull request: https://github.com/expertiza/expertiza/pull/2395&lt;br /&gt;
* Github repo: https://github.com/wsun23/expertiza/tree/E2232&lt;br /&gt;
* VCL: http://152.7.99.215:8080/&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=145386</id>
		<title>CSC/ECE 517 Spring 2022 - E2232: Revision planning tool</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=145386"/>
		<updated>2022-04-26T03:27:37Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: /* Current Flow */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Project Goal==&lt;br /&gt;
The primary objective for this project is to create a tool that can be used for the revision of projects at a time after their original submission upon the delivery of constructive feedback from their peers or instructors. The revision planning tool is an important device that will be used to give students the ability to learn from the mistakes of their submissions, and improve the quality of their work prior to the due date. This will be done by completing the existing implementation for revision planning using the following project plan. &lt;br /&gt;
&lt;br /&gt;
==Project Plan==&lt;br /&gt;
To merge code for revision planning into current beta.&lt;br /&gt;
&lt;br /&gt;
E2152's work was to develop a revision planning tool and merge it into the beta branch of Expertiza. They completed their task but developed based on a previous beta branch version and thus could not be merged into the current beta. Our goal is to reimplement their change so that it merges into the current beta branch. We will first merge the modification in the following files to the current beta and solve the conflicts.&lt;br /&gt;
 &lt;br /&gt;
===Files to be merged===&lt;br /&gt;
* app/controllers/revision_plan_questionnaires_controller.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* app/controllers/grades_controller.rb&lt;br /&gt;
* app/helpers/grades_helper.rb&lt;br /&gt;
* app/models/assignment_participant.rb&lt;br /&gt;
* app/models/response_map.rb&lt;br /&gt;
* app/views/grades/_participant_charts.html.erb&lt;br /&gt;
* app/views/grades/view_team.html.erb&lt;br /&gt;
* app/views/student_task/view.html.erb&lt;br /&gt;
* app/controllers/response_controller.rb&lt;br /&gt;
* app/views/response/response.html.erb&lt;br /&gt;
* config/routes.rb&lt;br /&gt;
* db/schema.rb&lt;br /&gt;
* spec/models/response_spec.rb&lt;br /&gt;
* spec/models/review_response_map_spec.rb&lt;br /&gt;
* spec/features/assignment_creation_general_tab_spec.rb&lt;br /&gt;
* app/models/revision_plan_team_map.rb&lt;br /&gt;
* spec/controllers/advice_controller_spec.rb&lt;br /&gt;
* app/models/response.rb&lt;br /&gt;
&lt;br /&gt;
The following diagram shows the the revision planning tool's use:&lt;br /&gt;
&lt;br /&gt;
[[File:E2232_diagram.png]]&lt;br /&gt;
&lt;br /&gt;
==Current Project Implementation==&lt;br /&gt;
&lt;br /&gt;
The implementation of this now fits within the framework created by E2161 (Fall 2021). &lt;br /&gt;
&lt;br /&gt;
What it does: In the first round of Expertiza reviews, we ask reviewers to give authors some guidance on how to improve their work. Then in the second round, reviewers rate how well authors have followed their suggestions. Authors are now able to leave a plan of work attached to their reviews in order to indicate their plan to move forward with the criticism given by the peer reviews. This is done by utilizing controller classes for advice and response that are tasked with creating the objects, as implemented in the advice and response model classes respectively, saving them to the database and displaying them in the html files. We also ensure that response can only be performed by the appropriate members by indicating that actions are only permitted by those with instructor privilege (teaching assistants, admins, and instructors) as well as the student who has been assigned the review can alter them (seen here).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
  questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
  if(user_logged_in? &amp;amp;&amp;amp; questionnaire.owner?(session[:user].id))&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  current_user_has_ta_privileges?&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
Helper methods such as summary_helper.rb are used in order to receive values from existing objects, for example receiving the sentences as broken up into seperate array entries as is needed for the comments of the answers in the reviews.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def get_sentences(answer)&lt;br /&gt;
  if answer.nil?&lt;br /&gt;
    return nil&lt;br /&gt;
  end&lt;br /&gt;
  sentences = answer.comments.split(/[.,?,!]/) &lt;br /&gt;
  sentences.each{ |sentence| sentence.strip! }&lt;br /&gt;
&lt;br /&gt;
  sentences&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Rationale===&lt;br /&gt;
The general workflow will be maintained from the previous iterations working on this project. The workflow used by past semesters is as follows.&lt;br /&gt;
&lt;br /&gt;
[[File:E2152_Rationale.png|410px|center|Image from previous write up]]&lt;br /&gt;
&lt;br /&gt;
===Previous implementation===&lt;br /&gt;
This project was last done in Fall 2021 (E2152). However, related merged code from E2161 (link above) means the implementation this semester may need to be changed from how E2152 did it.&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/2131 Primary Pull Request for E2152]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/2152 Second Pull Request for Revision Planning]&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2152._Revision_planning_tool Previous write up for E2152]&lt;br /&gt;
&lt;br /&gt;
====Current Flow====&lt;br /&gt;
Current flow is dictated by previous iterations. The following content and images are created using those previous write ups.&lt;br /&gt;
&lt;br /&gt;
Prior to the round 2 submission, you could view your work, but not the revision plan.&lt;br /&gt;
[[File:211129-2.png|700px|thumb|center]]&lt;br /&gt;
If there is a round 2 submission, and we did not do the &amp;quot;Revision Planning&amp;quot;, then &amp;quot;Your work&amp;quot; becomes gray.&lt;br /&gt;
[[File:211129-5.png|700px|thumb|center]]&lt;br /&gt;
After editing the &amp;quot;Revision Planning&amp;quot;, we can submit our work.&lt;br /&gt;
[[File:211129-6.png|700px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=====Current User Interface=====&lt;br /&gt;
Current user interface has been put in place by the previous iterations, the following interface image is from those iterations.&lt;br /&gt;
&lt;br /&gt;
[[File:after1.png|700px|thumb|center|Reviews cannot be done during the submission phase]]&lt;br /&gt;
&lt;br /&gt;
====Design Changes====&lt;br /&gt;
Because the changes to the current implementation is limited to specific implementation, the UML design of the project will remain the same as the previous implementation.&lt;br /&gt;
&lt;br /&gt;
[[File:E2152_Design.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===Merge existing RSpec tests for revision planning into current beta===&lt;br /&gt;
We will first merge the existing RSpec tests of E2152 to the current beta, then run and pass these tests. More comments can be made in rspec tests as well. Observe the coverage of the individual tests. &lt;br /&gt;
Existing RSpec tests to be merged&lt;br /&gt;
* Controllers&lt;br /&gt;
** rspec spec/controllers/grades_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/questionnaires_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/questions_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/student_teams_controller_spec.rb&lt;br /&gt;
** spec/controllers/response_controller_spec.rb&lt;br /&gt;
** spec/controllers/revision_plan_questionnaires_controller_spec.rb&lt;br /&gt;
** spec/factories/revision_plan_factory.rb&lt;br /&gt;
* Models&lt;br /&gt;
** spec/models/response_spec.rb.&lt;br /&gt;
** spec/models/review_response_map_spec.rb&lt;br /&gt;
* Helpers&lt;br /&gt;
** rspec spec/heplers/grades_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Develop New RSpec Tests===&lt;br /&gt;
The RSpec tests are written to test both controllers and models. RSpec testing will be added in order to increase coverage. To do this we will test the flows associated with different user types. Currently the only passing tests are related to student flows and tests may be added that work with instructors. These may include editing the reviews once they are created, and ensuring that an instructor has the ability to make edits.&lt;br /&gt;
&lt;br /&gt;
Testing is done for ensuring actions are allowed for teachers as well as the assigned student:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#action_allowed?' do&lt;br /&gt;
  let(:questionnaire) { build(:questionnaire, id: 1) }&lt;br /&gt;
  context 'when the role of current user is Super-Admin' do&lt;br /&gt;
    # Checking for Super-Admin&lt;br /&gt;
    it 'allows certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(super_admin, super_admin.role.name, super_admin.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_truthy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  context 'when the role of current user is Instructor' do&lt;br /&gt;
    # Checking for Instructor&lt;br /&gt;
    it 'allows certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(instructor1, instructor1.role.name, instructor1.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_truthy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  context 'when the role of current user is Student' do&lt;br /&gt;
    # Checking for Student&lt;br /&gt;
    it 'refuses certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(student1, student1.role.name, student1.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_falsey&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;
Testing is also done in order ensure this in response controllers, and questionnaire controllers. Testing is done for model objects such as displaying as html (below) and ensuring fields are correctly returned&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when prefix is not nil, which means view_score page in instructor end' do&lt;br /&gt;
 it 'returns corresponding html code' do&lt;br /&gt;
    allow(response).to receive(:questionnaire_by_answer).with(answer).and_return(questionnaire)&lt;br /&gt;
    allow(questionnaire).to receive(:max_question_score).and_return(5)&lt;br /&gt;
    allow(questionnaire).to receive(:id).and_return(1)&lt;br /&gt;
    allow(assignment).to receive(:id).and_return(1)&lt;br /&gt;
    allow(question).to receive(:view_completed_question).with(1, answer, 5, nil, nil).and_return('Question HTML code')&lt;br /&gt;
    expect(response.display_as_html('Instructor end', 0)).to eq('&amp;lt;h4&amp;gt;&amp;lt;B&amp;gt;Review 0&amp;lt;/B&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;B&amp;gt;Reviewer: &amp;lt;/B&amp;gt;no one (no name)&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;'\&lt;br /&gt;
      &amp;quot;&amp;lt;a href=\&amp;quot;#\&amp;quot; name= \&amp;quot;review_Instructor end_1Link\&amp;quot; onClick=\&amp;quot;toggleElement('review_Instructor end_1','review');return false;\&amp;quot;&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;hide review&amp;lt;/a&amp;gt;&amp;lt;BR/&amp;gt;&amp;lt;h5&amp;gt;Review Responses&amp;lt;/h5&amp;gt;&amp;lt;table id=\&amp;quot;review_Instructor end_1\&amp;quot; class=\&amp;quot;table table-bordered\&amp;quot;&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;&amp;lt;tr class=\&amp;quot;warning\&amp;quot;&amp;gt;&amp;lt;td&amp;gt;Question HTML code&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;h5&amp;gt;Additional Comment&amp;lt;/h5&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;&amp;lt;table id=\&amp;quot;review_Instructor end_1\&amp;quot; class=\&amp;quot;table table-bordered\&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
rspec tests are also needed for validing saves for controller classes, and ensuring model functionality in response objects.&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
&lt;br /&gt;
* Instructor &lt;br /&gt;
** Can Review rubric varied by topic be enabled?&lt;br /&gt;
** Can different roles be chosen for each questionnaire? &lt;br /&gt;
** Can an assignment with revision planning enabled be created?&lt;br /&gt;
** Can an assignment with 2 rounds of review be set up?&lt;br /&gt;
&lt;br /&gt;
* Assignment participant &lt;br /&gt;
** If the revision-planning rubric can be edited or not?&lt;br /&gt;
** Are participants allowed to create/edit revision plan when round 1+ (1 or greater than 1) reviews have finished?&lt;br /&gt;
** Is revision plan editing disabled when the assignment is in review stage?&lt;br /&gt;
** Does participants show a summary of score for revision plan after review deadline has expired?&lt;br /&gt;
&lt;br /&gt;
* Assignment reviewer &lt;br /&gt;
** Does the rubric page show the topic-specific rubric?&lt;br /&gt;
** Does the rubric page show the revision plan rubric?&lt;br /&gt;
&lt;br /&gt;
==Team Information==&lt;br /&gt;
* Lawrence O'Brien (lpobrien)&lt;br /&gt;
* Joshua Lin (jlin36)&lt;br /&gt;
* Weiqi Sun (wsun23)&lt;br /&gt;
* Wyatt Plaga (wgplaga)&lt;br /&gt;
* '''Mentor:''' Nicholas Himes (nnhimes)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Pull request: https://github.com/expertiza/expertiza/pull/2395&lt;br /&gt;
* Github repo: https://github.com/wsun23/expertiza/tree/E2232&lt;br /&gt;
* VCL: http://152.7.99.215:8080/&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=145385</id>
		<title>CSC/ECE 517 Spring 2022 - E2232: Revision planning tool</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=145385"/>
		<updated>2022-04-26T03:25:47Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Project Goal==&lt;br /&gt;
The primary objective for this project is to create a tool that can be used for the revision of projects at a time after their original submission upon the delivery of constructive feedback from their peers or instructors. The revision planning tool is an important device that will be used to give students the ability to learn from the mistakes of their submissions, and improve the quality of their work prior to the due date. This will be done by completing the existing implementation for revision planning using the following project plan. &lt;br /&gt;
&lt;br /&gt;
==Project Plan==&lt;br /&gt;
To merge code for revision planning into current beta.&lt;br /&gt;
&lt;br /&gt;
E2152's work was to develop a revision planning tool and merge it into the beta branch of Expertiza. They completed their task but developed based on a previous beta branch version and thus could not be merged into the current beta. Our goal is to reimplement their change so that it merges into the current beta branch. We will first merge the modification in the following files to the current beta and solve the conflicts.&lt;br /&gt;
 &lt;br /&gt;
===Files to be merged===&lt;br /&gt;
* app/controllers/revision_plan_questionnaires_controller.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* app/controllers/grades_controller.rb&lt;br /&gt;
* app/helpers/grades_helper.rb&lt;br /&gt;
* app/models/assignment_participant.rb&lt;br /&gt;
* app/models/response_map.rb&lt;br /&gt;
* app/views/grades/_participant_charts.html.erb&lt;br /&gt;
* app/views/grades/view_team.html.erb&lt;br /&gt;
* app/views/student_task/view.html.erb&lt;br /&gt;
* app/controllers/response_controller.rb&lt;br /&gt;
* app/views/response/response.html.erb&lt;br /&gt;
* config/routes.rb&lt;br /&gt;
* db/schema.rb&lt;br /&gt;
* spec/models/response_spec.rb&lt;br /&gt;
* spec/models/review_response_map_spec.rb&lt;br /&gt;
* spec/features/assignment_creation_general_tab_spec.rb&lt;br /&gt;
* app/models/revision_plan_team_map.rb&lt;br /&gt;
* spec/controllers/advice_controller_spec.rb&lt;br /&gt;
* app/models/response.rb&lt;br /&gt;
&lt;br /&gt;
The following diagram shows the the revision planning tool's use:&lt;br /&gt;
&lt;br /&gt;
[[File:E2232_diagram.png]]&lt;br /&gt;
&lt;br /&gt;
==Current Project Implementation==&lt;br /&gt;
&lt;br /&gt;
The implementation of this now fits within the framework created by E2161 (Fall 2021). &lt;br /&gt;
&lt;br /&gt;
What it does: In the first round of Expertiza reviews, we ask reviewers to give authors some guidance on how to improve their work. Then in the second round, reviewers rate how well authors have followed their suggestions. Authors are now able to leave a plan of work attached to their reviews in order to indicate their plan to move forward with the criticism given by the peer reviews. This is done by utilizing controller classes for advice and response that are tasked with creating the objects, as implemented in the advice and response model classes respectively, saving them to the database and displaying them in the html files. We also ensure that response can only be performed by the appropriate members by indicating that actions are only permitted by those with instructor privilege (teaching assistants, admins, and instructors) as well as the student who has been assigned the review can alter them (seen here).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
  questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
  if(user_logged_in? &amp;amp;&amp;amp; questionnaire.owner?(session[:user].id))&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  current_user_has_ta_privileges?&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
Helper methods such as summary_helper.rb are used in order to receive values from existing objects, for example receiving the sentences as broken up into seperate array entries as is needed for the comments of the answers in the reviews.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def get_sentences(answer)&lt;br /&gt;
  if answer.nil?&lt;br /&gt;
    return nil&lt;br /&gt;
  end&lt;br /&gt;
  sentences = answer.comments.split(/[.,?,!]/) &lt;br /&gt;
  sentences.each{ |sentence| sentence.strip! }&lt;br /&gt;
&lt;br /&gt;
  sentences&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Rationale===&lt;br /&gt;
The general workflow will be maintained from the previous iterations working on this project. The workflow used by past semesters is as follows.&lt;br /&gt;
&lt;br /&gt;
[[File:E2152_Rationale.png|410px|center|Image from previous write up]]&lt;br /&gt;
&lt;br /&gt;
===Previous implementation===&lt;br /&gt;
This project was last done in Fall 2021 (E2152). However, related merged code from E2161 (link above) means the implementation this semester may need to be changed from how E2152 did it.&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/2131 Primary Pull Request for E2152]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/2152 Second Pull Request for Revision Planning]&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2152._Revision_planning_tool Previous write up for E2152]&lt;br /&gt;
&lt;br /&gt;
====Current Flow====&lt;br /&gt;
Current flow is dictated by previous iterations. The following content and images are created using those previous write ups.&lt;br /&gt;
&lt;br /&gt;
Prior to the round 2 submission, you can look into your work, but the revision plan.&lt;br /&gt;
[[File:211129-2.png|700px|thumb|center]]&lt;br /&gt;
If there is a round 2 submission, and we did not deal with the &amp;quot;Revision Planning&amp;quot;, then the &amp;quot;Your work&amp;quot; part becomes gray.&lt;br /&gt;
[[File:211129-5.png|700px|thumb|center]]&lt;br /&gt;
After editing the &amp;quot;Revision Planning&amp;quot;, we can submit our work.&lt;br /&gt;
[[File:211129-6.png|700px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=====Current User Interface=====&lt;br /&gt;
Current user interface has been put in place by the previous iterations, the following interface image is from those iterations.&lt;br /&gt;
&lt;br /&gt;
[[File:after1.png|700px|thumb|center|Reviews cannot be done during the submission phase]]&lt;br /&gt;
&lt;br /&gt;
====Design Changes====&lt;br /&gt;
Because the changes to the current implementation is limited to specific implementation, the UML design of the project will remain the same as the previous implementation.&lt;br /&gt;
&lt;br /&gt;
[[File:E2152_Design.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===Merge existing RSpec tests for revision planning into current beta===&lt;br /&gt;
We will first merge the existing RSpec tests of E2152 to the current beta, then run and pass these tests. More comments can be made in rspec tests as well. Observe the coverage of the individual tests. &lt;br /&gt;
Existing RSpec tests to be merged&lt;br /&gt;
* Controllers&lt;br /&gt;
** rspec spec/controllers/grades_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/questionnaires_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/questions_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/student_teams_controller_spec.rb&lt;br /&gt;
** spec/controllers/response_controller_spec.rb&lt;br /&gt;
** spec/controllers/revision_plan_questionnaires_controller_spec.rb&lt;br /&gt;
** spec/factories/revision_plan_factory.rb&lt;br /&gt;
* Models&lt;br /&gt;
** spec/models/response_spec.rb.&lt;br /&gt;
** spec/models/review_response_map_spec.rb&lt;br /&gt;
* Helpers&lt;br /&gt;
** rspec spec/heplers/grades_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Develop New RSpec Tests===&lt;br /&gt;
The RSpec tests are written to test both controllers and models. RSpec testing will be added in order to increase coverage. To do this we will test the flows associated with different user types. Currently the only passing tests are related to student flows and tests may be added that work with instructors. These may include editing the reviews once they are created, and ensuring that an instructor has the ability to make edits.&lt;br /&gt;
&lt;br /&gt;
Testing is done for ensuring actions are allowed for teachers as well as the assigned student:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#action_allowed?' do&lt;br /&gt;
  let(:questionnaire) { build(:questionnaire, id: 1) }&lt;br /&gt;
  context 'when the role of current user is Super-Admin' do&lt;br /&gt;
    # Checking for Super-Admin&lt;br /&gt;
    it 'allows certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(super_admin, super_admin.role.name, super_admin.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_truthy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  context 'when the role of current user is Instructor' do&lt;br /&gt;
    # Checking for Instructor&lt;br /&gt;
    it 'allows certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(instructor1, instructor1.role.name, instructor1.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_truthy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  context 'when the role of current user is Student' do&lt;br /&gt;
    # Checking for Student&lt;br /&gt;
    it 'refuses certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(student1, student1.role.name, student1.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_falsey&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;
Testing is also done in order ensure this in response controllers, and questionnaire controllers. Testing is done for model objects such as displaying as html (below) and ensuring fields are correctly returned&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when prefix is not nil, which means view_score page in instructor end' do&lt;br /&gt;
 it 'returns corresponding html code' do&lt;br /&gt;
    allow(response).to receive(:questionnaire_by_answer).with(answer).and_return(questionnaire)&lt;br /&gt;
    allow(questionnaire).to receive(:max_question_score).and_return(5)&lt;br /&gt;
    allow(questionnaire).to receive(:id).and_return(1)&lt;br /&gt;
    allow(assignment).to receive(:id).and_return(1)&lt;br /&gt;
    allow(question).to receive(:view_completed_question).with(1, answer, 5, nil, nil).and_return('Question HTML code')&lt;br /&gt;
    expect(response.display_as_html('Instructor end', 0)).to eq('&amp;lt;h4&amp;gt;&amp;lt;B&amp;gt;Review 0&amp;lt;/B&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;B&amp;gt;Reviewer: &amp;lt;/B&amp;gt;no one (no name)&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;'\&lt;br /&gt;
      &amp;quot;&amp;lt;a href=\&amp;quot;#\&amp;quot; name= \&amp;quot;review_Instructor end_1Link\&amp;quot; onClick=\&amp;quot;toggleElement('review_Instructor end_1','review');return false;\&amp;quot;&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;hide review&amp;lt;/a&amp;gt;&amp;lt;BR/&amp;gt;&amp;lt;h5&amp;gt;Review Responses&amp;lt;/h5&amp;gt;&amp;lt;table id=\&amp;quot;review_Instructor end_1\&amp;quot; class=\&amp;quot;table table-bordered\&amp;quot;&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;&amp;lt;tr class=\&amp;quot;warning\&amp;quot;&amp;gt;&amp;lt;td&amp;gt;Question HTML code&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;h5&amp;gt;Additional Comment&amp;lt;/h5&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;&amp;lt;table id=\&amp;quot;review_Instructor end_1\&amp;quot; class=\&amp;quot;table table-bordered\&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
rspec tests are also needed for validing saves for controller classes, and ensuring model functionality in response objects.&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
&lt;br /&gt;
* Instructor &lt;br /&gt;
** Can Review rubric varied by topic be enabled?&lt;br /&gt;
** Can different roles be chosen for each questionnaire? &lt;br /&gt;
** Can an assignment with revision planning enabled be created?&lt;br /&gt;
** Can an assignment with 2 rounds of review be set up?&lt;br /&gt;
&lt;br /&gt;
* Assignment participant &lt;br /&gt;
** If the revision-planning rubric can be edited or not?&lt;br /&gt;
** Are participants allowed to create/edit revision plan when round 1+ (1 or greater than 1) reviews have finished?&lt;br /&gt;
** Is revision plan editing disabled when the assignment is in review stage?&lt;br /&gt;
** Does participants show a summary of score for revision plan after review deadline has expired?&lt;br /&gt;
&lt;br /&gt;
* Assignment reviewer &lt;br /&gt;
** Does the rubric page show the topic-specific rubric?&lt;br /&gt;
** Does the rubric page show the revision plan rubric?&lt;br /&gt;
&lt;br /&gt;
==Team Information==&lt;br /&gt;
* Lawrence O'Brien (lpobrien)&lt;br /&gt;
* Joshua Lin (jlin36)&lt;br /&gt;
* Weiqi Sun (wsun23)&lt;br /&gt;
* Wyatt Plaga (wgplaga)&lt;br /&gt;
* '''Mentor:''' Nicholas Himes (nnhimes)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Pull request: https://github.com/expertiza/expertiza/pull/2395&lt;br /&gt;
* Github repo: https://github.com/wsun23/expertiza/tree/E2232&lt;br /&gt;
* VCL: http://152.7.99.215:8080/&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=145384</id>
		<title>CSC/ECE 517 Spring 2022 - E2232: Revision planning tool</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=145384"/>
		<updated>2022-04-26T03:20:53Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: /* Project Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Project Goal==&lt;br /&gt;
The primary objective for this project is to create a tool that can be used for the revision of projects at a time after their original submission upon the delivery of constructive feedback from their peers or instructors. The revision planning tool is an important device that will be used to give students the ability to learn from the mistakes of their submissions, and improve the quality of their work prior to the due date. This will be done by completing the existing implementation for revision planning using the following project plan. &lt;br /&gt;
&lt;br /&gt;
==Project Plan==&lt;br /&gt;
To merge code for revision planning into current beta.&lt;br /&gt;
&lt;br /&gt;
The functionality of E2152 works well but it was developed based on the previous beta and cannot be merged into the current beta. We will first merge the modification in the following files to the current beta and solve the conflicts.&lt;br /&gt;
 &lt;br /&gt;
===Files to be merged===&lt;br /&gt;
* app/controllers/revision_plan_questionnaires_controller.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* app/controllers/grades_controller.rb&lt;br /&gt;
* app/helpers/grades_helper.rb&lt;br /&gt;
* app/models/assignment_participant.rb&lt;br /&gt;
* app/models/response_map.rb&lt;br /&gt;
* app/views/grades/_participant_charts.html.erb&lt;br /&gt;
* app/views/grades/view_team.html.erb&lt;br /&gt;
* app/views/student_task/view.html.erb&lt;br /&gt;
* app/controllers/response_controller.rb&lt;br /&gt;
* app/views/response/response.html.erb&lt;br /&gt;
* config/routes.rb&lt;br /&gt;
* db/schema.rb&lt;br /&gt;
* spec/models/response_spec.rb&lt;br /&gt;
* spec/models/review_response_map_spec.rb&lt;br /&gt;
* spec/features/assignment_creation_general_tab_spec.rb&lt;br /&gt;
* app/models/revision_plan_team_map.rb&lt;br /&gt;
* spec/controllers/advice_controller_spec.rb&lt;br /&gt;
* app/models/response.rb&lt;br /&gt;
&lt;br /&gt;
Merge code for revision planning with code for role based reviewing and topic specific rubrics&lt;br /&gt;
 &lt;br /&gt;
The functionality of E2261 works well and has been merged into the current beta. By merging revision planning tool and topic specific rubrics, in the peer review process,&lt;br /&gt;
In the first round of review, the rubric is designed by the instructor and varies by topic &lt;br /&gt;
In the second round of review,  the rubric includes two parts: part 1 is designed by the instructor and varies by topic, part 2 is designed by the team based on the comments of the first round of review.&lt;br /&gt;
&lt;br /&gt;
[[File:E2232_diagram.png]]&lt;br /&gt;
&lt;br /&gt;
==Current Project Implementation==&lt;br /&gt;
&lt;br /&gt;
The implementation of this now fits within the framework created by E2161 (Fall 2021). &lt;br /&gt;
&lt;br /&gt;
What it does: In the first round of Expertiza reviews, we ask reviewers to give authors some guidance on how to improve their work. Then in the second round, reviewers rate how well authors have followed their suggestions. Authors are now able to leave a plan of work attached to their reviews in order to indicate their plan to move forward with the criticism given by the peer reviews. This is done by utilizing controller classes for advice and response that are tasked with creating the objects, as implemented in the advice and response model classes respectively, saving them to the database and displaying them in the html files. We also ensure that response can only be performed by the appropriate members by indicating that actions are only permitted by those with instructor privilege (teaching assistants, admins, and instructors) as well as the student who has been assigned the review can alter them (seen here).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
  questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
  if(user_logged_in? &amp;amp;&amp;amp; questionnaire.owner?(session[:user].id))&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  current_user_has_ta_privileges?&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
Helper methods such as summary_helper.rb are used in order to receive values from existing objects, for example receiving the sentences as broken up into seperate array entries as is needed for the comments of the answers in the reviews.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def get_sentences(answer)&lt;br /&gt;
  if answer.nil?&lt;br /&gt;
    return nil&lt;br /&gt;
  end&lt;br /&gt;
  sentences = answer.comments.split(/[.,?,!]/) &lt;br /&gt;
  sentences.each{ |sentence| sentence.strip! }&lt;br /&gt;
&lt;br /&gt;
  sentences&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Rationale===&lt;br /&gt;
The general workflow will be maintained from the previous iterations working on this project. The workflow used by past semesters is as follows.&lt;br /&gt;
&lt;br /&gt;
[[File:E2152_Rationale.png|410px|center|Image from previous write up]]&lt;br /&gt;
&lt;br /&gt;
===Previous implementation===&lt;br /&gt;
This project was last done in Fall 2021 (E2152). However, related merged code from E2161 (link above) means the implementation this semester may need to be changed from how E2152 did it.&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/2131 Primary Pull Request for E2152]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/2152 Second Pull Request for Revision Planning]&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2152._Revision_planning_tool Previous write up for E2152]&lt;br /&gt;
&lt;br /&gt;
====Current Flow====&lt;br /&gt;
Current flow is dictated by previous iterations. The following content and images are created using those previous write ups.&lt;br /&gt;
&lt;br /&gt;
Prior to the round 2 submission, you can look into your work, but the revision plan.&lt;br /&gt;
[[File:211129-2.png|700px|thumb|center]]&lt;br /&gt;
If there is a round 2 submission, and we did not deal with the &amp;quot;Revision Planning&amp;quot;, then the &amp;quot;Your work&amp;quot; part becomes gray.&lt;br /&gt;
[[File:211129-5.png|700px|thumb|center]]&lt;br /&gt;
After editing the &amp;quot;Revision Planning&amp;quot;, we can submit our work.&lt;br /&gt;
[[File:211129-6.png|700px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=====Current User Interface=====&lt;br /&gt;
Current user interface has been put in place by the previous iterations, the following interface image is from those iterations.&lt;br /&gt;
&lt;br /&gt;
[[File:after1.png|700px|thumb|center|Reviews cannot be done during the submission phase]]&lt;br /&gt;
&lt;br /&gt;
====Design Changes====&lt;br /&gt;
Because the changes to the current implementation is limited to specific implementation, the UML design of the project will remain the same as the previous implementation.&lt;br /&gt;
&lt;br /&gt;
[[File:E2152_Design.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===Merge existing RSpec tests for revision planning into current beta===&lt;br /&gt;
We will first merge the existing RSpec tests of E2152 to the current beta, then run and pass these tests. More comments can be made in rspec tests as well. Observe the coverage of the individual tests. &lt;br /&gt;
Existing RSpec tests to be merged&lt;br /&gt;
* Controllers&lt;br /&gt;
** rspec spec/controllers/grades_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/questionnaires_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/questions_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/student_teams_controller_spec.rb&lt;br /&gt;
** spec/controllers/response_controller_spec.rb&lt;br /&gt;
** spec/controllers/revision_plan_questionnaires_controller_spec.rb&lt;br /&gt;
** spec/factories/revision_plan_factory.rb&lt;br /&gt;
* Models&lt;br /&gt;
** spec/models/response_spec.rb.&lt;br /&gt;
** spec/models/review_response_map_spec.rb&lt;br /&gt;
* Helpers&lt;br /&gt;
** rspec spec/heplers/grades_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Develop New RSpec Tests===&lt;br /&gt;
The RSpec tests are written to test both controllers and models. RSpec testing will be added in order to increase coverage. To do this we will test the flows associated with different user types. Currently the only passing tests are related to student flows and tests may be added that work with instructors. These may include editing the reviews once they are created, and ensuring that an instructor has the ability to make edits.&lt;br /&gt;
&lt;br /&gt;
Testing is done for ensuring actions are allowed for teachers as well as the assigned student:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#action_allowed?' do&lt;br /&gt;
  let(:questionnaire) { build(:questionnaire, id: 1) }&lt;br /&gt;
  context 'when the role of current user is Super-Admin' do&lt;br /&gt;
    # Checking for Super-Admin&lt;br /&gt;
    it 'allows certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(super_admin, super_admin.role.name, super_admin.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_truthy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  context 'when the role of current user is Instructor' do&lt;br /&gt;
    # Checking for Instructor&lt;br /&gt;
    it 'allows certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(instructor1, instructor1.role.name, instructor1.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_truthy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  context 'when the role of current user is Student' do&lt;br /&gt;
    # Checking for Student&lt;br /&gt;
    it 'refuses certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(student1, student1.role.name, student1.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_falsey&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;
Testing is also done in order ensure this in response controllers, and questionnaire controllers. Testing is done for model objects such as displaying as html (below) and ensuring fields are correctly returned&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when prefix is not nil, which means view_score page in instructor end' do&lt;br /&gt;
 it 'returns corresponding html code' do&lt;br /&gt;
    allow(response).to receive(:questionnaire_by_answer).with(answer).and_return(questionnaire)&lt;br /&gt;
    allow(questionnaire).to receive(:max_question_score).and_return(5)&lt;br /&gt;
    allow(questionnaire).to receive(:id).and_return(1)&lt;br /&gt;
    allow(assignment).to receive(:id).and_return(1)&lt;br /&gt;
    allow(question).to receive(:view_completed_question).with(1, answer, 5, nil, nil).and_return('Question HTML code')&lt;br /&gt;
    expect(response.display_as_html('Instructor end', 0)).to eq('&amp;lt;h4&amp;gt;&amp;lt;B&amp;gt;Review 0&amp;lt;/B&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;B&amp;gt;Reviewer: &amp;lt;/B&amp;gt;no one (no name)&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;'\&lt;br /&gt;
      &amp;quot;&amp;lt;a href=\&amp;quot;#\&amp;quot; name= \&amp;quot;review_Instructor end_1Link\&amp;quot; onClick=\&amp;quot;toggleElement('review_Instructor end_1','review');return false;\&amp;quot;&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;hide review&amp;lt;/a&amp;gt;&amp;lt;BR/&amp;gt;&amp;lt;h5&amp;gt;Review Responses&amp;lt;/h5&amp;gt;&amp;lt;table id=\&amp;quot;review_Instructor end_1\&amp;quot; class=\&amp;quot;table table-bordered\&amp;quot;&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;&amp;lt;tr class=\&amp;quot;warning\&amp;quot;&amp;gt;&amp;lt;td&amp;gt;Question HTML code&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;h5&amp;gt;Additional Comment&amp;lt;/h5&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;&amp;lt;table id=\&amp;quot;review_Instructor end_1\&amp;quot; class=\&amp;quot;table table-bordered\&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
rspec tests are also needed for validing saves for controller classes, and ensuring model functionality in response objects.&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
&lt;br /&gt;
* Instructor &lt;br /&gt;
** Can Review rubric varied by topic be enabled?&lt;br /&gt;
** Can different roles be chosen for each questionnaire? &lt;br /&gt;
** Can an assignment with revision planning enabled be created?&lt;br /&gt;
** Can an assignment with 2 rounds of review be set up?&lt;br /&gt;
&lt;br /&gt;
* Assignment participant &lt;br /&gt;
** If the revision-planning rubric can be edited or not?&lt;br /&gt;
** Are participants allowed to create/edit revision plan when round 1+ (1 or greater than 1) reviews have finished?&lt;br /&gt;
** Is revision plan editing disabled when the assignment is in review stage?&lt;br /&gt;
** Does participants show a summary of score for revision plan after review deadline has expired?&lt;br /&gt;
&lt;br /&gt;
* Assignment reviewer &lt;br /&gt;
** Does the rubric page show the topic-specific rubric?&lt;br /&gt;
** Does the rubric page show the revision plan rubric?&lt;br /&gt;
&lt;br /&gt;
==Team Information==&lt;br /&gt;
* Lawrence O'Brien (lpobrien)&lt;br /&gt;
* Joshua Lin (jlin36)&lt;br /&gt;
* Weiqi Sun (wsun23)&lt;br /&gt;
* Wyatt Plaga (wgplaga)&lt;br /&gt;
* '''Mentor:''' Nicholas Himes (nnhimes)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Pull request: https://github.com/expertiza/expertiza/pull/2395&lt;br /&gt;
* Github repo: https://github.com/wsun23/expertiza/tree/E2232&lt;br /&gt;
* VCL: http://152.7.99.215:8080/&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=145382</id>
		<title>CSC/ECE 517 Spring 2022 - E2232: Revision planning tool</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=145382"/>
		<updated>2022-04-26T03:17:11Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: /* Files to be merged */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Project Goal==&lt;br /&gt;
The primary objective for this project is to create a tool that can be used for the revision of projects at a time after their original submission upon the delivery of constructive feedback from their peers or instructors. The revision planning tool is an important device that will be used to give students the ability to learn from the mistakes of their submissions, and improve the quality of their work prior to the due date. This will be done by completing the existing implementation for revision planning using the following project plan. &lt;br /&gt;
&lt;br /&gt;
==Project Plan==&lt;br /&gt;
Merge code for revision planning into current beta&lt;br /&gt;
&lt;br /&gt;
The functionality of E2152 works well but it was developed based on the previous beta and cannot be merged into the current beta. We will first merge the modification in the following files to the current beta and solve the conflicts.&lt;br /&gt;
 &lt;br /&gt;
===Files to be merged===&lt;br /&gt;
* app/controllers/revision_plan_questionnaires_controller.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* app/controllers/grades_controller.rb&lt;br /&gt;
* app/helpers/grades_helper.rb&lt;br /&gt;
* app/models/assignment_participant.rb&lt;br /&gt;
* app/models/response_map.rb&lt;br /&gt;
* app/views/grades/_participant_charts.html.erb&lt;br /&gt;
* app/views/grades/view_team.html.erb&lt;br /&gt;
* app/views/student_task/view.html.erb&lt;br /&gt;
* app/controllers/response_controller.rb&lt;br /&gt;
* app/views/response/response.html.erb&lt;br /&gt;
* config/routes.rb&lt;br /&gt;
* db/schema.rb&lt;br /&gt;
* spec/models/response_spec.rb&lt;br /&gt;
* spec/models/review_response_map_spec.rb&lt;br /&gt;
* spec/features/assignment_creation_general_tab_spec.rb&lt;br /&gt;
* app/models/revision_plan_team_map.rb&lt;br /&gt;
* spec/controllers/advice_controller_spec.rb&lt;br /&gt;
* app/models/response.rb&lt;br /&gt;
&lt;br /&gt;
Merge code for revision planning with code for role based reviewing and topic specific rubrics&lt;br /&gt;
 &lt;br /&gt;
The functionality of E2261 works well and has been merged into the current beta. By merging revision planning tool and topic specific rubrics, in the peer review process,&lt;br /&gt;
In the first round of review, the rubric is designed by the instructor and varies by topic &lt;br /&gt;
In the second round of review,  the rubric includes two parts: part 1 is designed by the instructor and varies by topic, part 2 is designed by the team based on the comments of the first round of review.&lt;br /&gt;
&lt;br /&gt;
[[File:E2232_diagram.png]]&lt;br /&gt;
&lt;br /&gt;
==Current Project Implementation==&lt;br /&gt;
&lt;br /&gt;
The implementation of this now fits within the framework created by E2161 (Fall 2021). &lt;br /&gt;
&lt;br /&gt;
What it does: In the first round of Expertiza reviews, we ask reviewers to give authors some guidance on how to improve their work. Then in the second round, reviewers rate how well authors have followed their suggestions. Authors are now able to leave a plan of work attached to their reviews in order to indicate their plan to move forward with the criticism given by the peer reviews. This is done by utilizing controller classes for advice and response that are tasked with creating the objects, as implemented in the advice and response model classes respectively, saving them to the database and displaying them in the html files. We also ensure that response can only be performed by the appropriate members by indicating that actions are only permitted by those with instructor privilege (teaching assistants, admins, and instructors) as well as the student who has been assigned the review can alter them (seen here).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def action_allowed?&lt;br /&gt;
  questionnaire = Questionnaire.find(params[:id])&lt;br /&gt;
  if(user_logged_in? &amp;amp;&amp;amp; questionnaire.owner?(session[:user].id))&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  current_user_has_ta_privileges?&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
Helper methods such as summary_helper.rb are used in order to receive values from existing objects, for example receiving the sentences as broken up into seperate array entries as is needed for the comments of the answers in the reviews.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
def get_sentences(answer)&lt;br /&gt;
  if answer.nil?&lt;br /&gt;
    return nil&lt;br /&gt;
  end&lt;br /&gt;
  sentences = answer.comments.split(/[.,?,!]/) &lt;br /&gt;
  sentences.each{ |sentence| sentence.strip! }&lt;br /&gt;
&lt;br /&gt;
  sentences&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Rationale===&lt;br /&gt;
The general workflow will be maintained from the previous iterations working on this project. The workflow used by past semesters is as follows.&lt;br /&gt;
&lt;br /&gt;
[[File:E2152_Rationale.png|410px|center|Image from previous write up]]&lt;br /&gt;
&lt;br /&gt;
===Previous implementation===&lt;br /&gt;
This project was last done in Fall 2021 (E2152). However, related merged code from E2161 (link above) means the implementation this semester may need to be changed from how E2152 did it.&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/2131 Primary Pull Request for E2152]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/2152 Second Pull Request for Revision Planning]&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2152._Revision_planning_tool Previous write up for E2152]&lt;br /&gt;
&lt;br /&gt;
====Current Flow====&lt;br /&gt;
Current flow is dictated by previous iterations. The following content and images are created using those previous write ups.&lt;br /&gt;
&lt;br /&gt;
Prior to the round 2 submission, you can look into your work, but the revision plan.&lt;br /&gt;
[[File:211129-2.png|700px|thumb|center]]&lt;br /&gt;
If there is a round 2 submission, and we did not deal with the &amp;quot;Revision Planning&amp;quot;, then the &amp;quot;Your work&amp;quot; part becomes gray.&lt;br /&gt;
[[File:211129-5.png|700px|thumb|center]]&lt;br /&gt;
After editing the &amp;quot;Revision Planning&amp;quot;, we can submit our work.&lt;br /&gt;
[[File:211129-6.png|700px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=====Current User Interface=====&lt;br /&gt;
Current user interface has been put in place by the previous iterations, the following interface image is from those iterations.&lt;br /&gt;
&lt;br /&gt;
[[File:after1.png|700px|thumb|center|Reviews cannot be done during the submission phase]]&lt;br /&gt;
&lt;br /&gt;
====Design Changes====&lt;br /&gt;
Because the changes to the current implementation is limited to specific implementation, the UML design of the project will remain the same as the previous implementation.&lt;br /&gt;
&lt;br /&gt;
[[File:E2152_Design.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===Merge existing RSpec tests for revision planning into current beta===&lt;br /&gt;
We will first merge the existing RSpec tests of E2152 to the current beta, then run and pass these tests. More comments can be made in rspec tests as well. Observe the coverage of the individual tests. &lt;br /&gt;
Existing RSpec tests to be merged&lt;br /&gt;
* Controllers&lt;br /&gt;
** rspec spec/controllers/grades_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/questionnaires_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/questions_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/student_teams_controller_spec.rb&lt;br /&gt;
** spec/controllers/response_controller_spec.rb&lt;br /&gt;
** spec/controllers/revision_plan_questionnaires_controller_spec.rb&lt;br /&gt;
** spec/factories/revision_plan_factory.rb&lt;br /&gt;
* Models&lt;br /&gt;
** spec/models/response_spec.rb.&lt;br /&gt;
** spec/models/review_response_map_spec.rb&lt;br /&gt;
* Helpers&lt;br /&gt;
** rspec spec/heplers/grades_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Develop New RSpec Tests===&lt;br /&gt;
The RSpec tests are written to test both controllers and models. RSpec testing will be added in order to increase coverage. To do this we will test the flows associated with different user types. Currently the only passing tests are related to student flows and tests may be added that work with instructors. These may include editing the reviews once they are created, and ensuring that an instructor has the ability to make edits.&lt;br /&gt;
&lt;br /&gt;
Testing is done for ensuring actions are allowed for teachers as well as the assigned student:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
describe '#action_allowed?' do&lt;br /&gt;
  let(:questionnaire) { build(:questionnaire, id: 1) }&lt;br /&gt;
  context 'when the role of current user is Super-Admin' do&lt;br /&gt;
    # Checking for Super-Admin&lt;br /&gt;
    it 'allows certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(super_admin, super_admin.role.name, super_admin.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_truthy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  context 'when the role of current user is Instructor' do&lt;br /&gt;
    # Checking for Instructor&lt;br /&gt;
    it 'allows certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(instructor1, instructor1.role.name, instructor1.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_truthy&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  context 'when the role of current user is Student' do&lt;br /&gt;
    # Checking for Student&lt;br /&gt;
    it 'refuses certain action' do&lt;br /&gt;
      controller.params = { id: '1' }&lt;br /&gt;
      stub_current_user(student1, student1.role.name, student1.role)&lt;br /&gt;
      expect(controller.send(:action_allowed?)).to be_falsey&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;
Testing is also done in order ensure this in response controllers, and questionnaire controllers. Testing is done for model objects such as displaying as html (below) and ensuring fields are correctly returned&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
context 'when prefix is not nil, which means view_score page in instructor end' do&lt;br /&gt;
 it 'returns corresponding html code' do&lt;br /&gt;
    allow(response).to receive(:questionnaire_by_answer).with(answer).and_return(questionnaire)&lt;br /&gt;
    allow(questionnaire).to receive(:max_question_score).and_return(5)&lt;br /&gt;
    allow(questionnaire).to receive(:id).and_return(1)&lt;br /&gt;
    allow(assignment).to receive(:id).and_return(1)&lt;br /&gt;
    allow(question).to receive(:view_completed_question).with(1, answer, 5, nil, nil).and_return('Question HTML code')&lt;br /&gt;
    expect(response.display_as_html('Instructor end', 0)).to eq('&amp;lt;h4&amp;gt;&amp;lt;B&amp;gt;Review 0&amp;lt;/B&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;B&amp;gt;Reviewer: &amp;lt;/B&amp;gt;no one (no name)&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;'\&lt;br /&gt;
      &amp;quot;&amp;lt;a href=\&amp;quot;#\&amp;quot; name= \&amp;quot;review_Instructor end_1Link\&amp;quot; onClick=\&amp;quot;toggleElement('review_Instructor end_1','review');return false;\&amp;quot;&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;hide review&amp;lt;/a&amp;gt;&amp;lt;BR/&amp;gt;&amp;lt;h5&amp;gt;Review Responses&amp;lt;/h5&amp;gt;&amp;lt;table id=\&amp;quot;review_Instructor end_1\&amp;quot; class=\&amp;quot;table table-bordered\&amp;quot;&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;&amp;lt;tr class=\&amp;quot;warning\&amp;quot;&amp;gt;&amp;lt;td&amp;gt;Question HTML code&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;h5&amp;gt;Additional Comment&amp;lt;/h5&amp;gt;&amp;quot;\&lt;br /&gt;
      &amp;quot;&amp;lt;table id=\&amp;quot;review_Instructor end_1\&amp;quot; class=\&amp;quot;table table-bordered\&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
rspec tests are also needed for validing saves for controller classes, and ensuring model functionality in response objects.&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
&lt;br /&gt;
* Instructor &lt;br /&gt;
** Can Review rubric varied by topic be enabled?&lt;br /&gt;
** Can different roles be chosen for each questionnaire? &lt;br /&gt;
** Can an assignment with revision planning enabled be created?&lt;br /&gt;
** Can an assignment with 2 rounds of review be set up?&lt;br /&gt;
&lt;br /&gt;
* Assignment participant &lt;br /&gt;
** If the revision-planning rubric can be edited or not?&lt;br /&gt;
** Are participants allowed to create/edit revision plan when round 1+ (1 or greater than 1) reviews have finished?&lt;br /&gt;
** Is revision plan editing disabled when the assignment is in review stage?&lt;br /&gt;
** Does participants show a summary of score for revision plan after review deadline has expired?&lt;br /&gt;
&lt;br /&gt;
* Assignment reviewer &lt;br /&gt;
** Does the rubric page show the topic-specific rubric?&lt;br /&gt;
** Does the rubric page show the revision plan rubric?&lt;br /&gt;
&lt;br /&gt;
==Team Information==&lt;br /&gt;
* Lawrence O'Brien (lpobrien)&lt;br /&gt;
* Joshua Lin (jlin36)&lt;br /&gt;
* Weiqi Sun (wsun23)&lt;br /&gt;
* Wyatt Plaga (wgplaga)&lt;br /&gt;
* '''Mentor:''' Nicholas Himes (nnhimes)&lt;br /&gt;
&lt;br /&gt;
==Links==&lt;br /&gt;
* Pull request: https://github.com/expertiza/expertiza/pull/2395&lt;br /&gt;
* Github repo: https://github.com/wsun23/expertiza/tree/E2232&lt;br /&gt;
* VCL: http://152.7.99.215:8080/&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=145260</id>
		<title>CSC/ECE 517 Spring 2022 - E2232: Revision planning tool</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=145260"/>
		<updated>2022-04-25T22:35:43Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Project Goal==&lt;br /&gt;
The primary objective for this project is to create a tool that can be used for the revision of projects at a time after their original submission upon the delivery of constructive feedback from their peers or instructors. The revision planning tool is an important device that will be used to give students the ability to learn from the mistakes of their submissions, and improve the quality of their work prior to the due date. This will be done by completing the existing implementation for revision planning using the following project plan. &lt;br /&gt;
&lt;br /&gt;
==Project Plan==&lt;br /&gt;
Merge code for revision planning into current beta&lt;br /&gt;
&lt;br /&gt;
The functionality of E2152 works well but it was developed based on the previous beta and cannot be merged into the current beta. We will first merge the modification in the following files to the current beta and solve the conflicts.&lt;br /&gt;
 &lt;br /&gt;
===Files to be merged===&lt;br /&gt;
* app/controllers/revision_plan_questionnaires_controller.rb&lt;br /&gt;
* app/models/team.rb&lt;br /&gt;
* app/controllers/grades_controller.rb&lt;br /&gt;
* app/helpers/grades_helper.rb&lt;br /&gt;
* app/models/assignment_participant.rb&lt;br /&gt;
* app/models/response_map.rb&lt;br /&gt;
* app/views/grades/_participant_charts.html.erb&lt;br /&gt;
* app/views/grades/view_team.html.erb&lt;br /&gt;
* app/views/student_task/view.html.erb&lt;br /&gt;
* app/controllers/response_controller.rb&lt;br /&gt;
* app/views/response/response.html.erb&lt;br /&gt;
* config/routes.rb&lt;br /&gt;
* db/schema.rb&lt;br /&gt;
* spec/models/response_spec.rb&lt;br /&gt;
* spec/models/review_response_map_spec.rb&lt;br /&gt;
* spec/features/assignment_creation_general_tab_spec.rb&lt;br /&gt;
* app/models/revision_plan_team_map.rb&lt;br /&gt;
&lt;br /&gt;
Merge code for revision planning with code for role based reviewing and topic specific rubrics&lt;br /&gt;
 &lt;br /&gt;
The functionality of E2261 works well and has been merged into the current beta. By merging revision planning tool and topic specific rubrics, in the peer review process,&lt;br /&gt;
In the first round of review, the rubric is designed by the instructor and varies by topic &lt;br /&gt;
In the second round of review,  the rubric includes two parts: part 1 is designed by the instructor and varies by topic, part 2 is designed by the team based on the comments of the first round of review.&lt;br /&gt;
&lt;br /&gt;
[[File:E2232_diagram.png]]&lt;br /&gt;
&lt;br /&gt;
==Current Project Implementation==&lt;br /&gt;
&lt;br /&gt;
The implementation of this needs to fit within the framework created by E2161 (Fall 2021). &lt;br /&gt;
&lt;br /&gt;
What it does: In the first round of Expertiza reviews, we ask reviewers to give authors some guidance on how to improve their work. Then in the second round, reviewers rate how well authors have followed their suggestions. We could carry the interaction one step further if we asked authors to make up a revision plan based on the first-round reviews. That is, authors would say what they were planning to do to improve their work. Then second-round reviewers would assess how well they did it. In essence, this means that authors would be adding criteria to the second-round rubric that applied only to their submission. We are interested in having this implemented and used in a class so that we can study its effect.&lt;br /&gt;
&lt;br /&gt;
===Rationale===&lt;br /&gt;
The general workflow will be maintained from the previous iterations working on this project. The workflow used by past semesters is as follows.&lt;br /&gt;
&lt;br /&gt;
[[File:E2152_Rationale.png|410px|center|Image from previous write up]]&lt;br /&gt;
&lt;br /&gt;
===Previous implementation===&lt;br /&gt;
This project was last done in Fall 2021 (E2152). However, related merged code from E2161 (link above) means the implementation this semester may need to be changed from how E2152 did it.&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/2131 Primary Pull Request for E2152]&lt;br /&gt;
* [https://github.com/expertiza/expertiza/pull/2152 Second Pull Request for Revision Planning]&lt;br /&gt;
* [https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2152._Revision_planning_tool Previous write up for E2152]&lt;br /&gt;
&lt;br /&gt;
====Current Flow====&lt;br /&gt;
Current flow is dictated by previous iterations. The following content and images are created using those previous write ups.&lt;br /&gt;
&lt;br /&gt;
Prior to the round 2 submission, you can look into your work, but the revision plan.&lt;br /&gt;
[[File:211129-2.png|700px|thumb|center]]&lt;br /&gt;
If there is a round 2 submission, and we did not deal with the &amp;quot;Revision Planning&amp;quot;, then the &amp;quot;Your work&amp;quot; part becomes gray.&lt;br /&gt;
[[File:211129-5.png|700px|thumb|center]]&lt;br /&gt;
After editing the &amp;quot;Revision Planning&amp;quot;, we can submit our work.&lt;br /&gt;
[[File:211129-6.png|700px|thumb|center]]&lt;br /&gt;
&lt;br /&gt;
=====Current User Interface=====&lt;br /&gt;
Current user interface has been put in place by the previous iterations, the following interface image is from those iterations.&lt;br /&gt;
&lt;br /&gt;
[[File:after1.png|700px|thumb|center|Reviews cannot be done during the submission phase]]&lt;br /&gt;
&lt;br /&gt;
===Implementation to be completed===&lt;br /&gt;
There are actually two E2152 pull requests in Expertiza right now - the PR we saw in the demo has less recent commits than the other. And the PR we did not see has less files changed as well. They started with last year's project, so the beta they started with was the beta from last year. The changes since then will show up as merge conflicts if this project is merged.&lt;br /&gt;
&lt;br /&gt;
The functionality of this project seems to work well and would be a valuable addition to Expertiza, but it cannot be merged in its current state. There are many artifacts in their PR from an old version of beta. This is because the team merged the previous teams' code into current beta, but did not remove the differences unrelated to their project. The team knew of these problems before the demo, but did not fix them.&lt;br /&gt;
&lt;br /&gt;
Because the existing functionality encompasses the intended instructions fairly clearly the work that needs to be done for our purposes would be to pass rspec tests that currently cause the build to fail. This functionality would involve us causing different flows based upon the type of user completing the review. Shown below. HTML changes must also be made in order to pass, specifically needing a change to the display_as_html, done_by_staff_participant and participant_scores methods to return the correct html values. Currently display_as_html is returning an unknown error causing a msitake in the html delivered. The done_by_staff_participant is not present in the code and therefore returns a method not found error. particpant_scores is returning an error that is the result of an incorrect calculation for total_scores. More work will need to be done for each of these bugs to investigate the root cause and establish a solution.&lt;br /&gt;
&lt;br /&gt;
Pull request E2131 is failing rspec tests in ReviewMappingHelper due to a currently unknown OpenSSL error. More work will be needed to determine the specific cause and nature of this error.&lt;br /&gt;
&lt;br /&gt;
More comments can be made in rspec tests as well. It is unclear what the coverage is of the individual tests. The file revision_plan_team_map_test.rb has nothing substantial in it.&lt;br /&gt;
&lt;br /&gt;
[[File:Failing_rspec.PNG|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
====Design Changes====&lt;br /&gt;
Because the changes to the current implementation is limited to specific implementation, the UML design of the project will remain the same as the previous implementation.&lt;br /&gt;
&lt;br /&gt;
[[File:E2152_Design.png|1000px|center]]&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
===Merge existing RSpec tests for revision planning into current beta===&lt;br /&gt;
We will first merge the existing RSpec tests of E2152 to the current beta, then run and pass these tests. More comments can be made in rspec tests as well. Observe the coverage of the individual tests. &lt;br /&gt;
Existing RSpec tests to be merged&lt;br /&gt;
* Controllers&lt;br /&gt;
** rspec spec/controllers/grades_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/questionnaires_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/questions_controller_spec.rb&lt;br /&gt;
** rspec spec/controllers/student_teams_controller_spec.rb&lt;br /&gt;
** spec/controllers/response_controller_spec.rb&lt;br /&gt;
** spec/controllers/revision_plan_questionnaires_controller_spec.rb&lt;br /&gt;
** spec/factories/revision_plan_factory.rb&lt;br /&gt;
* Models&lt;br /&gt;
** spec/models/response_spec.rb.&lt;br /&gt;
** spec/models/review_response_map_spec.rb&lt;br /&gt;
* Helpers&lt;br /&gt;
** rspec spec/heplers/grades_helper.rb&lt;br /&gt;
&lt;br /&gt;
===Develop New RSpec Tests===&lt;br /&gt;
The RSpec tests are written to test both controllers and models. RSpec testing will be added in order to increase coverage. To do this we will test the flows associated with different user types. Currently the only passing tests are related to student flows and tests may be added that work with instructors. These may include editing the reviews once they are created, and ensuring that an instructor has the ability to make edits.&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
&lt;br /&gt;
* Instructor &lt;br /&gt;
** Can Review rubric varied by topic be enabled?&lt;br /&gt;
** Can different roles be chosen for each questionnaire? &lt;br /&gt;
** Can an assignment with revision planning enabled be created?&lt;br /&gt;
** Can an assignment with 2 rounds of review be set up?&lt;br /&gt;
&lt;br /&gt;
* Assignment participant &lt;br /&gt;
** If the revision-planning rubric can be edited or not?&lt;br /&gt;
** Are participants allowed to create/edit revision plan when round 1+ (1 or greater than 1) reviews have finished?&lt;br /&gt;
** Is revision plan editing disabled when the assignment is in review stage?&lt;br /&gt;
** Does participants show a summary of score for revision plan after review deadline has expired?&lt;br /&gt;
&lt;br /&gt;
* Assignment reviewer &lt;br /&gt;
** Does the rubric page show the topic-specific rubric?&lt;br /&gt;
** Does the rubric page show the revision plan rubric?&lt;br /&gt;
&lt;br /&gt;
==Implementation By Team==&lt;br /&gt;
Halfway through the project deadline, there were new changes that were merged into Expertiza's beta branch. With these new changes in place, our code that was based off the old version of the beta branch started failing tests and causing errors. We fixed these changes that mainly occurred in advice_controller.rb. Some of these failures were also rolled over from the last team's implementation of this same project. Most of these errors occurred in response.rb&lt;br /&gt;
&lt;br /&gt;
==Team Information==&lt;br /&gt;
* Lawrence O'Brien (lpobrien)&lt;br /&gt;
* Joshua Lin (jlin36)&lt;br /&gt;
* Weiqi Sun (wsun23)&lt;br /&gt;
* Wyatt Plaga (wgplaga)&lt;br /&gt;
* '''Mentor:''' Nicholas Himes (nnhimes)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=144089</id>
		<title>CSC/ECE 517 Spring 2022 - E2232: Revision planning tool</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=144089"/>
		<updated>2022-04-05T22:37:49Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Project Goal: &lt;br /&gt;
&lt;br /&gt;
Project Plan:&lt;br /&gt;
&lt;br /&gt;
Other known information:&lt;br /&gt;
&lt;br /&gt;
Stuff:&lt;br /&gt;
&lt;br /&gt;
What it does: In the first round of Expertiza reviews, we ask reviewers to give authors some guidance on how to improve their work. Then in the second round, reviewers rate how well authors have followed their suggestions. We could carry the interaction one step further if we asked authors to make up a revision plan based on the first-round reviews. That is, authors would say what they were planning to do to improve their work. Then second-round reviewers would assess how well they did it. In essence, this means that authors would be adding criteria to the second-round rubric that applied only to their submission. We are interested in having this implemented and used in a class so that we can study its effect.&lt;br /&gt;
&lt;br /&gt;
The implementation of this needs to fit within the framework created by E2161 (Fall 2021). &lt;br /&gt;
&lt;br /&gt;
Previous implementation - E2152: This project was last done in Fall 2021. However, related merged code from E2161 (link above) means the implementation this semester may need to be changed from how E2152 did it.&lt;br /&gt;
https://github.com/expertiza/expertiza/pull/2152 (primary PR?)&lt;br /&gt;
https://github.com/expertiza/expertiza/pull/2131&lt;br /&gt;
https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2152._Revision_planning_tool&lt;br /&gt;
&lt;br /&gt;
Our comments on the implementation: &lt;br /&gt;
There are actually two E2152 pull requests in Expertiza right now - the PR we saw in the demo has less recent commits than the other. And the PR we did not see has less files changed as well. They started with last year's project, so the beta they started with was the beta from last year. The changes since then will show up as merge conflicts if this project is merged.&lt;br /&gt;
&lt;br /&gt;
The functionality of this project seems to work well and would be a valuable addition to Expertiza, but it cannot be merged in its current state. There are many artifacts in their PR from an old version of beta. This is because the team merged the previous teams' code into current beta, but did not remove the differences unrelated to their project. The team knew of these problems before the demo, but did not fix them.&lt;br /&gt;
&lt;br /&gt;
More comments can be made in rspec tests as well. It is unclear what the coverage is of the individual tests. The file revision_plan_team_map_test.rb has nothing substantial in it.&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=144088</id>
		<title>CSC/ECE 517 Spring 2022 - E2232: Revision planning tool</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=144088"/>
		<updated>2022-04-05T22:37:38Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Project Goal: &lt;br /&gt;
&lt;br /&gt;
Project Plan:&lt;br /&gt;
&lt;br /&gt;
Other known information:&lt;br /&gt;
&lt;br /&gt;
Stuff:&lt;br /&gt;
What it does: In the first round of Expertiza reviews, we ask reviewers to give authors some guidance on how to improve their work. Then in the second round, reviewers rate how well authors have followed their suggestions. We could carry the interaction one step further if we asked authors to make up a revision plan based on the first-round reviews. That is, authors would say what they were planning to do to improve their work. Then second-round reviewers would assess how well they did it. In essence, this means that authors would be adding criteria to the second-round rubric that applied only to their submission. We are interested in having this implemented and used in a class so that we can study its effect.&lt;br /&gt;
&lt;br /&gt;
The implementation of this needs to fit within the framework created by E2161 (Fall 2021). &lt;br /&gt;
&lt;br /&gt;
Previous implementation - E2152: This project was last done in Fall 2021. However, related merged code from E2161 (link above) means the implementation this semester may need to be changed from how E2152 did it.&lt;br /&gt;
https://github.com/expertiza/expertiza/pull/2152 (primary PR?)&lt;br /&gt;
https://github.com/expertiza/expertiza/pull/2131&lt;br /&gt;
https://expertiza.csc.ncsu.edu/index.php/CSC/ECE_517_Fall_2021_-_E2152._Revision_planning_tool&lt;br /&gt;
&lt;br /&gt;
Our comments on the implementation: &lt;br /&gt;
There are actually two E2152 pull requests in Expertiza right now - the PR we saw in the demo has less recent commits than the other. And the PR we did not see has less files changed as well. They started with last year's project, so the beta they started with was the beta from last year. The changes since then will show up as merge conflicts if this project is merged.&lt;br /&gt;
&lt;br /&gt;
The functionality of this project seems to work well and would be a valuable addition to Expertiza, but it cannot be merged in its current state. There are many artifacts in their PR from an old version of beta. This is because the team merged the previous teams' code into current beta, but did not remove the differences unrelated to their project. The team knew of these problems before the demo, but did not fix them.&lt;br /&gt;
&lt;br /&gt;
More comments can be made in rspec tests as well. It is unclear what the coverage is of the individual tests. The file revision_plan_team_map_test.rb has nothing substantial in it.&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=144082</id>
		<title>CSC/ECE 517 Spring 2022 - E2232: Revision planning tool</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=144082"/>
		<updated>2022-04-05T21:17:16Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Project Goal:&lt;br /&gt;
&lt;br /&gt;
Project Plan:&lt;br /&gt;
&lt;br /&gt;
Other known information:&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=144081</id>
		<title>CSC/ECE 517 Spring 2022 - E2232: Revision planning tool</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=144081"/>
		<updated>2022-04-05T21:17:04Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Project Goal:&lt;br /&gt;
Project Plan:&lt;br /&gt;
Other known information:&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=144080</id>
		<title>CSC/ECE 517 Spring 2022 - E2232: Revision planning tool</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2232:_Revision_planning_tool&amp;diff=144080"/>
		<updated>2022-04-05T21:12:58Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: Created page with &amp;quot;Testing&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Testing&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143785</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143785"/>
		<updated>2022-03-28T02:35:57Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: /* Coverage */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for student reviews to be accurate. The hamer algorithm was create for such purposes and returns a reputation weight associated with each reviewer. The instructor can then use the reputation weight value to either assert the reliability of a reviewer or use these values to compute a grade for a reviewer.&lt;br /&gt;
&lt;br /&gt;
=== System Design ===&lt;br /&gt;
&lt;br /&gt;
The hamer algorithm takes in a set of grades for assignments by reviewer and also any reputation weights (optional) associated with each reviewer to compute a reputation weight value for each reviewer. These reputation weight values indicate the accuracy and reliability of each reviewer. For example, a reviewer with a reputation weight of 3.0 is more accurate and reliable in their reviews compared to a 0.5 reputation weight of another reviewer. The following is an example from the paper [1] that describes the hamer algorithm:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Hamer Algorithm Inputs Outputs.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This algorithm is currently deployed to the following web server: http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms. To use the algorithm, a post request is sent to the peerlogic URL with a json body consisting of each assignment and the grades, and the reviewer who gave each grade. Once the request is sent, a json response is sent back with the corresponding hamer reputation weight values. The following is an example of a post request to the peerlogic URL to get back hamer reputation values:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer.png|1000px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
* Calculate reputation scores based on paper &amp;quot;Pluggable reputation systems for peer review: A web-service approach&amp;quot;&lt;br /&gt;
* Assert the accuracy of the reputation web server's hamer values through the URL http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms.&lt;br /&gt;
* Create a mock web server to return the correct hamer values if the reputation web server's hamer algorithm returns incorrect values.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
*reputation_web_server_hamer.rb&lt;br /&gt;
*reputation_mock_web_server_hamer.rb&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
=== Hamer Algorithm ===&lt;br /&gt;
[[File:Step1.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step2.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step3.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step4.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
We implemented the steps of this algorithm for our analytical validation, found in the section below.&lt;br /&gt;
== Test Plan - Initial Phase ==&lt;br /&gt;
In the initial phase, we were tasked with testing the reputation_web_service_controller. The work done by a previous project team was impacted by the web-service (peerlogic) not being available at that time.&lt;br /&gt;
This time, we were able to access the Peerlogic server at a late stage - therefore, our plan at this moment involved performing a series of unit tests to determine that the web-service was communicating &lt;br /&gt;
correctly with Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Plan, Object Creation ===&lt;br /&gt;
1. Since our focus in this phase was to conduct exploratory testing of the system, we wrote some conventional tests to examine Peerlogic functionality. At this stage, we realized that Peerlogic &lt;br /&gt;
would only accept and respond with JSON data.&lt;br /&gt;
&lt;br /&gt;
2. Therefore, a natural next step was to prepare a series of input data that simulated a general input scenario for the system, comprising of:&lt;br /&gt;
::a. Each reviewer has assigned scores to 3 reviewees (fellow students)&lt;br /&gt;
::b. There are a total of 3 reviewers, who have all graded each other in some fashion for 5 assignments&lt;br /&gt;
::c. Convert this scenario to JSON&lt;br /&gt;
::d. Write code to PUT this to Peerlogic, and receive a response&lt;br /&gt;
::e. Parse through this response to obtain the output values of the Hamer Algorithm, as calculated by Peerlogic.&lt;br /&gt;
::f. This output would be compared against actual data that we calculated based on the Research Paper for the Hamer Algorithm&lt;br /&gt;
'''''The code for the last step is shown below'''''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Conclusions ===&lt;br /&gt;
The results that are '''''actually''''' received from Peerlogic are presented below:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:json-ss.jpeg|600px]]&lt;br /&gt;
&lt;br /&gt;
The results from our python recreated Hamer Algorithm are as followed:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer2.png|250px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see, they do NOT match with expected results. &lt;br /&gt;
'''Therefore, our first conclusion is that the PeerLogic Webservice is implemented incorrectly.'''&lt;br /&gt;
This has been documented in the Conclusion section as the first point.&lt;br /&gt;
== Changes to Project Scope ==&lt;br /&gt;
&lt;br /&gt;
=== Test Plan - Second Phase, Object Creation ===&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
Additionally, this method was '''recommended by Dr. Gehringer''', our project mentor.&lt;br /&gt;
Finally, we also added a test case that ''mocks'' a webservice and asserts the output, done in 2 ways:&lt;br /&gt;
::a. In the first code snippet, we send JSON to a webservice that '''returns the correct Hamer output''', as Peerlogic should when fixed.&lt;br /&gt;
::b. In the form of an RSpec mock, in the second snippet below.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
#The following contains 4 reviewers who have scored 4 reviewees&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Input visualization:&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Reviewer-&amp;gt;  stu9999 stu9998 stu9997 stu9996&lt;br /&gt;
# Assignment&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
#&lt;br /&gt;
#Values that would be returned by a correct Hamer implementation&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
#sends API request to Peeerlogic&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port) do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
  #assertion fails, as expected&lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
#sends API request to Mock Hamer/Peerlogic Server&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
=== Second Phase Output ===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;webmock/rspec&amp;quot; # gem install webmock -v 2.2.0&lt;br /&gt;
&lt;br /&gt;
WebMock.disable_net_connect!(allow_localhost: true)&lt;br /&gt;
#Setting up test objects&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
#Result expectations are identical here, in order to maintain uniformity&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
#tests Peerlogic&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
        stub_request(:post, /peerlogic.csc.ncsu.edu/).&lt;br /&gt;
          to_return(status: 200, body: EXPECTED, headers: {})&lt;br /&gt;
      end&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
 #JSON conversion to ensure server compatibility&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
 #parse the JSON response body to access values for algorithm of choice, which is Hamer     &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
#our assertion proves this mock works&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Edge Cases &amp;amp; Scenarios ==&lt;br /&gt;
''We present these scenarios as possible test cases for an accurately working Peerlogic webservice.''&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
::alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
These have not been implemented as there is no point in testing a system further when positive flows do not work.&lt;br /&gt;
However, the code in the Initial Phase Section can be used to analytically calculate correct responses for future assertions.&lt;br /&gt;
We have provided outputs to these scenarios below:&lt;br /&gt;
&lt;br /&gt;
== Coverage ==&lt;br /&gt;
&lt;br /&gt;
We believe that after our edge cases are implemented for a working Peerlogic, and the assertions pass, that test coverage can then be adequately measured.&amp;lt;br&amp;gt;&lt;br /&gt;
At this moment, test coverage is not a relevant statistic as no positive or negative flows functions correctly, as do any edge cases.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
::1. In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong ::::(https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the ::paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already ::have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by ::code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected ::values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
::2. In addition, we also found out that the reputation_web_service_controller.rb currently is broken and needs refactoring. While the client side of the reputation web service page runs, any attempt to submit grades to the ::reputation web server side results in an error. &lt;br /&gt;
&lt;br /&gt;
::3. We provided scenarios for future teams to implement once Peerlogic is running correctly.&lt;br /&gt;
&lt;br /&gt;
::4. We mocked an accurate webservice and showed what the expected JSON should be like.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2357 here]&lt;br /&gt;
&lt;br /&gt;
Link to Github Project page: [https://github.com/joshlin5/expertiza/projects/2 here]&lt;br /&gt;
&lt;br /&gt;
Link to Testing Video: [https://youtu.be/VyeGGpxymXk here]&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143784</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143784"/>
		<updated>2022-03-28T02:34:57Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for student reviews to be accurate. The hamer algorithm was create for such purposes and returns a reputation weight associated with each reviewer. The instructor can then use the reputation weight value to either assert the reliability of a reviewer or use these values to compute a grade for a reviewer.&lt;br /&gt;
&lt;br /&gt;
=== System Design ===&lt;br /&gt;
&lt;br /&gt;
The hamer algorithm takes in a set of grades for assignments by reviewer and also any reputation weights (optional) associated with each reviewer to compute a reputation weight value for each reviewer. These reputation weight values indicate the accuracy and reliability of each reviewer. For example, a reviewer with a reputation weight of 3.0 is more accurate and reliable in their reviews compared to a 0.5 reputation weight of another reviewer. The following is an example from the paper [1] that describes the hamer algorithm:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Hamer Algorithm Inputs Outputs.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This algorithm is currently deployed to the following web server: http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms. To use the algorithm, a post request is sent to the peerlogic URL with a json body consisting of each assignment and the grades, and the reviewer who gave each grade. Once the request is sent, a json response is sent back with the corresponding hamer reputation weight values. The following is an example of a post request to the peerlogic URL to get back hamer reputation values:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer.png|1000px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
* Calculate reputation scores based on paper &amp;quot;Pluggable reputation systems for peer review: A web-service approach&amp;quot;&lt;br /&gt;
* Assert the accuracy of the reputation web server's hamer values through the URL http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms.&lt;br /&gt;
* Create a mock web server to return the correct hamer values if the reputation web server's hamer algorithm returns incorrect values.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
*reputation_web_server_hamer.rb&lt;br /&gt;
*reputation_mock_web_server_hamer.rb&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
=== Hamer Algorithm ===&lt;br /&gt;
[[File:Step1.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step2.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step3.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step4.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
We implemented the steps of this algorithm for our analytical validation, found in the section below.&lt;br /&gt;
== Test Plan - Initial Phase ==&lt;br /&gt;
In the initial phase, we were tasked with testing the reputation_web_service_controller. The work done by a previous project team was impacted by the web-service (peerlogic) not being available at that time.&lt;br /&gt;
This time, we were able to access the Peerlogic server at a late stage - therefore, our plan at this moment involved performing a series of unit tests to determine that the web-service was communicating &lt;br /&gt;
correctly with Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Plan, Object Creation ===&lt;br /&gt;
1. Since our focus in this phase was to conduct exploratory testing of the system, we wrote some conventional tests to examine Peerlogic functionality. At this stage, we realized that Peerlogic &lt;br /&gt;
would only accept and respond with JSON data.&lt;br /&gt;
&lt;br /&gt;
2. Therefore, a natural next step was to prepare a series of input data that simulated a general input scenario for the system, comprising of:&lt;br /&gt;
::a. Each reviewer has assigned scores to 3 reviewees (fellow students)&lt;br /&gt;
::b. There are a total of 3 reviewers, who have all graded each other in some fashion for 5 assignments&lt;br /&gt;
::c. Convert this scenario to JSON&lt;br /&gt;
::d. Write code to PUT this to Peerlogic, and receive a response&lt;br /&gt;
::e. Parse through this response to obtain the output values of the Hamer Algorithm, as calculated by Peerlogic.&lt;br /&gt;
::f. This output would be compared against actual data that we calculated based on the Research Paper for the Hamer Algorithm&lt;br /&gt;
'''''The code for the last step is shown below'''''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Conclusions ===&lt;br /&gt;
The results that are '''''actually''''' received from Peerlogic are presented below:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:json-ss.jpeg|600px]]&lt;br /&gt;
&lt;br /&gt;
The results from our python recreated Hamer Algorithm are as followed:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer2.png|250px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see, they do NOT match with expected results. &lt;br /&gt;
'''Therefore, our first conclusion is that the PeerLogic Webservice is implemented incorrectly.'''&lt;br /&gt;
This has been documented in the Conclusion section as the first point.&lt;br /&gt;
== Changes to Project Scope ==&lt;br /&gt;
&lt;br /&gt;
=== Test Plan - Second Phase, Object Creation ===&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
Additionally, this method was '''recommended by Dr. Gehringer''', our project mentor.&lt;br /&gt;
Finally, we also added a test case that ''mocks'' a webservice and asserts the output, done in 2 ways:&lt;br /&gt;
::a. In the first code snippet, we send JSON to a webservice that '''returns the correct Hamer output''', as Peerlogic should when fixed.&lt;br /&gt;
::b. In the form of an RSpec mock, in the second snippet below.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
#The following contains 4 reviewers who have scored 4 reviewees&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Input visualization:&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Reviewer-&amp;gt;  stu9999 stu9998 stu9997 stu9996&lt;br /&gt;
# Assignment&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
#&lt;br /&gt;
#Values that would be returned by a correct Hamer implementation&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
#sends API request to Peeerlogic&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port) do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
  #assertion fails, as expected&lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
#sends API request to Mock Hamer/Peerlogic Server&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
=== Second Phase Output ===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;webmock/rspec&amp;quot; # gem install webmock -v 2.2.0&lt;br /&gt;
&lt;br /&gt;
WebMock.disable_net_connect!(allow_localhost: true)&lt;br /&gt;
#Setting up test objects&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
#Result expectations are identical here, in order to maintain uniformity&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
#tests Peerlogic&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
        stub_request(:post, /peerlogic.csc.ncsu.edu/).&lt;br /&gt;
          to_return(status: 200, body: EXPECTED, headers: {})&lt;br /&gt;
      end&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
 #JSON conversion to ensure server compatibility&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
 #parse the JSON response body to access values for algorithm of choice, which is Hamer     &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
#our assertion proves this mock works&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Edge Cases &amp;amp; Scenarios ==&lt;br /&gt;
''We present these scenarios as possible test cases for an accurately working Peerlogic webservice.''&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
::alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
These have not been implemented as there is no point in testing a system further when positive flows do not work.&lt;br /&gt;
However, the code in the Initial Phase Section can be used to analytically calculate correct responses for future assertions.&lt;br /&gt;
We have provided outputs to these scenarios below:&lt;br /&gt;
&lt;br /&gt;
== Coverage ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
::1. In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong ::::(https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the ::paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already ::have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by ::code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected ::values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
::2. In addition, we also found out that the reputation_web_service_controller.rb currently is broken and needs refactoring. While the client side of the reputation web service page runs, any attempt to submit grades to the ::reputation web server side results in an error. &lt;br /&gt;
&lt;br /&gt;
::3. We provided scenarios for future teams to implement once Peerlogic is running correctly.&lt;br /&gt;
&lt;br /&gt;
::4. We mocked an accurate webservice and showed what the expected JSON should be like.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2357 here]&lt;br /&gt;
&lt;br /&gt;
Link to Github Project page: [https://github.com/joshlin5/expertiza/projects/2 here]&lt;br /&gt;
&lt;br /&gt;
Link to Testing Video: [https://youtu.be/VyeGGpxymXk here]&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143776</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143776"/>
		<updated>2022-03-28T02:20:44Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for student reviews to be accurate. The hamer algorithm was create for such purposes and returns a reputation weight associated with each reviewer. The instructor can then use the reputation weight value to either assert the reliability of a reviewer or use these values to compute a grade for a reviewer.&lt;br /&gt;
&lt;br /&gt;
=== System Design ===&lt;br /&gt;
&lt;br /&gt;
The hamer algorithm takes in a set of grades for assignments by reviewer and also any reputation weights (optional) associated with each reviewer to compute a reputation weight value for each reviewer. These reputation weight values indicate the accuracy and reliability of each reviewer. For example, a reviewer with a reputation weight of 3.0 is more accurate and reliable in their reviews compared to a 0.5 reputation weight of another reviewer. The following is an example from the paper [1] that describes the hamer algorithm:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Hamer Algorithm Inputs Outputs.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This algorithm is currently deployed to the following web server: http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms. To use the algorithm, a post request is sent to the peerlogic URL with a json body consisting of each assignment and the grades, and the reviewer who gave each grade. Once the request is sent, a json response is sent back with the corresponding hamer reputation weight values. The following is an example of a post request to the peerlogic URL to get back hamer reputation values:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer.png|1000px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
* Calculate reputation scores based on paper &amp;quot;Pluggable reputation systems for peer review: A web-service approach&amp;quot;&lt;br /&gt;
* Assert the accuracy of the reputation web server's hamer values through the URL http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms.&lt;br /&gt;
* Create a mock web server to return the correct hamer values if the reputation web server's hamer algorithm returns incorrect values.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
*reputation_web_server_hamer.rb&lt;br /&gt;
*reputation_mock_web_server_hamer.rb&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
=== Hamer Algorithm ===&lt;br /&gt;
[[File:Step1.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step2.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step3.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step4.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
We implemented the steps of this algorithm for our analytical validation, found in the section below.&lt;br /&gt;
== Test Plan - Initial Phase ==&lt;br /&gt;
In the initial phase, we were tasked with testing the reputation_web_service_controller. The work done by a previous project team was impacted by the web-service (peerlogic) not being available at that time.&lt;br /&gt;
This time, we were able to access the Peerlogic server at a late stage - therefore, our plan at this moment involved performing a series of unit tests to determine that the web-service was communicating &lt;br /&gt;
correctly with Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Plan ===&lt;br /&gt;
1. Since our focus in this phase was to conduct exploratory testing of the system, we wrote some conventional tests to examine Peerlogic functionality. At this stage, we realized that Peerlogic &lt;br /&gt;
would only accept and respond with JSON data.&lt;br /&gt;
&lt;br /&gt;
2. Therefore, a natural next step was to prepare a series of input data that simulated a general input scenario for the system, comprising of:&lt;br /&gt;
::a. Each reviewer has assigned scores to 3 reviewees (fellow students)&lt;br /&gt;
::b. There are a total of 3 reviewers, who have all graded each other in some fashion for 5 assignments&lt;br /&gt;
::c. Convert this scenario to JSON&lt;br /&gt;
::d. Write code to PUT this to Peerlogic, and receive a response&lt;br /&gt;
::e. Parse through this response to obtain the output values of the Hamer Algorithm, as calculated by Peerlogic.&lt;br /&gt;
::f. This output would be compared against actual data that we calculated based on the Research Paper for the Hamer Algorithm&lt;br /&gt;
'''''The code for the last step is shown below'''''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Conclusions ===&lt;br /&gt;
The results that are '''''actually''''' received from Peerlogic are presented below:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:json-ss.jpeg|600px]]&lt;br /&gt;
&lt;br /&gt;
The results from our python recreated Hamer Algorithm are as followed:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer2.png|250px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see, they do NOT match with expected results. &lt;br /&gt;
'''Therefore, our first conclusion is that the PeerLogic Webservice is implemented incorrectly.'''&lt;br /&gt;
This has been documented in the Conclusion section as the first point.&lt;br /&gt;
== Changes to Project Scope ==&lt;br /&gt;
&lt;br /&gt;
=== Test Plan - Second Phase ===&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
Additionally, this method was '''recommended by Dr. Gehringer''', our project mentor.&lt;br /&gt;
Finally, we also added a test case that ''mocks'' a webservice and asserts the output, done in 2 ways:&lt;br /&gt;
::a. In the first code snippet, we send JSON to a webservice that '''returns the correct Hamer output''', as Peerlogic should when fixed.&lt;br /&gt;
::b. In the form of an RSpec mock, in the second snippet below.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
#The following contains 4 reviewers who have scored 4 reviewees&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Input visualization:&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Reviewer-&amp;gt;  stu9999 stu9998 stu9997 stu9996&lt;br /&gt;
# Assignment&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
#&lt;br /&gt;
#Values that would be returned by a correct Hamer implementation&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
#sends API request to Peeerlogic&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port) do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
  #assertion fails, as expected&lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
#sends API request to Mock Hamer/Peerlogic Server&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;webmock/rspec&amp;quot; # gem install webmock -v 2.2.0&lt;br /&gt;
&lt;br /&gt;
WebMock.disable_net_connect!(allow_localhost: true)&lt;br /&gt;
#Setting up test objects&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
#Result expectations are identical here, in order to maintain uniformity&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
#tests Peerlogic&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
        stub_request(:post, /peerlogic.csc.ncsu.edu/).&lt;br /&gt;
          to_return(status: 200, body: EXPECTED, headers: {})&lt;br /&gt;
      end&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
 #JSON conversion to ensure server compatibility&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
 #parse the JSON response body to access values for algorithm of choice, which is Hamer     &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
#our assertion proves this mock works&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Edge Cases &amp;amp; Scenarios ==&lt;br /&gt;
''We present these scenarios as possible test cases for an accurately working Peerlogic webservice.''&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
These have not been implemented as there is no point in testing a system further when positive flows do not work.&lt;br /&gt;
However, the code in the Initial Phase Section can be used to analytically calculate correct responses for future assertions.&lt;br /&gt;
We have provided outputs to these scenarios below:&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
In addition, we also found out that the reputation_web_service_controller.rb currently is broken and needs refactoring. While the client side of the reputation web service page runs, any attempt to submit grades to the reputation web server side results in an error. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2357 here]&lt;br /&gt;
&lt;br /&gt;
Link to Github Project page: [https://github.com/joshlin5/expertiza/projects/2 here]&lt;br /&gt;
&lt;br /&gt;
Link to Testing Video: [https://youtu.be/VyeGGpxymXk here]&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143761</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143761"/>
		<updated>2022-03-28T01:59:56Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for student reviews to be accurate. The hamer algorithm was create for such purposes and returns a reputation weight associated with each reviewer. The instructor can then use the reputation weight value to either assert the reliability of a reviewer or use these values to compute a grade for a reviewer.&lt;br /&gt;
&lt;br /&gt;
=== System Design ===&lt;br /&gt;
&lt;br /&gt;
The hamer algorithm takes in a set of grades for assignments by reviewer and also any reputation weights (optional) associated with each reviewer to compute a reputation weight value for each reviewer. These reputation weight values indicate the accuracy and reliability of each reviewer. For example, a reviewer with a reputation weight of 3.0 is more accurate and reliable in their reviews compared to a 0.5 reputation weight of another reviewer. The following is an example from the paper [1] that describes the hamer algorithm:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Hamer Algorithm Inputs Outputs.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This algorithm is currently deployed to the following web server: http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms. To use the algorithm, a post request is sent to the peerlogic URL with a json body consisting of each assignment and the grades, and the reviewer who gave each grade. Once the request is sent, a json response is sent back with the corresponding hamer reputation weight values. The following is an example of a post request to the peerlogic URL to get back hamer reputation values:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer.png|1000px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
* Calculate reputation scores based on paper &amp;quot;Pluggable reputation systems for peer review: A web-service approach&amp;quot;&lt;br /&gt;
* Assert the accuracy of the reputation web server's hamer values through the URL http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms.&lt;br /&gt;
* Create a mock web server to return the correct hamer values if the reputation web server's hamer algorithm returns incorrect values.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
*reputation_web_server_hamer.rb&lt;br /&gt;
*reputation_mock_web_server_hamer.rb&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
=== Hamer Algorithm ===&lt;br /&gt;
[[File:Step1.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step2.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step3.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step4.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
We implemented the steps of this algorithm for our analytical validation, found in the section below.&lt;br /&gt;
== Test Plan - Initial Phase ==&lt;br /&gt;
In the initial phase, we were tasked with testing the reputation_web_service_controller. The work done by a previous project team was impacted by the web-service (peerlogic) not being available at that time.&lt;br /&gt;
This time, we were able to access the Peerlogic server at a late stage - therefore, our plan at this moment involved performing a series of unit tests to determine that the web-service was communicating &lt;br /&gt;
correctly with Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Plan ===&lt;br /&gt;
1. Since our focus in this phase was to conduct exploratory testing of the system, we wrote some conventional tests to examine Peerlogic functionality. At this stage, we realized that Peerlogic &lt;br /&gt;
would only accept and respond with JSON data.&lt;br /&gt;
&lt;br /&gt;
2. Therefore, a natural next step was to prepare a series of input data that simulated a general input scenario for the system, comprising of:&lt;br /&gt;
::a. Each reviewer has assigned scores to 3 reviewees (fellow students)&lt;br /&gt;
::b. There are a total of 3 reviewers, who have all graded each other in some fashion for 5 assignments&lt;br /&gt;
::c. Convert this scenario to JSON&lt;br /&gt;
::d. Write code to PUT this to Peerlogic, and receive a response&lt;br /&gt;
::e. Parse through this response to obtain the output values of the Hamer Algorithm, as calculated by Peerlogic.&lt;br /&gt;
::f. This output would be compared against actual data that we calculated based on the Research Paper for the Hamer Algorithm&lt;br /&gt;
'''''The code for the last step is shown below'''''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Conclusions ===&lt;br /&gt;
The results that are '''''actually''''' received from Peerlogic are presented below:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:json-ss.jpeg|600px]]&lt;br /&gt;
&lt;br /&gt;
The results from our python recreated Hamer Algorithm are as followed:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer2.png|250px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see, they do NOT match with expected results. &lt;br /&gt;
'''Therefore, our first conclusion is that the PeerLogic Webservice is implemented incorrectly.'''&lt;br /&gt;
This has been documented in the Conclusion section as the first point.&lt;br /&gt;
== Changes to Project Scope ==&lt;br /&gt;
&lt;br /&gt;
=== Test Plan - Second Phase ===&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
Additionally, this method was '''recommended by Dr. Gehringer''', our project mentor.&lt;br /&gt;
Finally, we also added a test case that ''mocks'' a webservice and asserts the output, done in 2 ways:&lt;br /&gt;
::a. In the first code snippet, we send JSON to a webservice that '''returns the correct Hamer output''', as Peerlogic should when fixed.&lt;br /&gt;
::b. In the form of an RSpec mock, in the second snippet below.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
#The following contains 4 reviewers who have scored 4 reviewees&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Input visualization:&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Reviewer-&amp;gt;  stu9999 stu9998 stu9997 stu9996&lt;br /&gt;
# Assignment&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
#&lt;br /&gt;
#Values that would be returned by a correct Hamer implementation&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
#sends API request to Peeerlogic&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port) do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
  #assertion fails, as expected&lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
#sends API request to Mock Hamer/Peerlogic Server&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;webmock/rspec&amp;quot; # gem install webmock -v 2.2.0&lt;br /&gt;
&lt;br /&gt;
WebMock.disable_net_connect!(allow_localhost: true)&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
        stub_request(:post, /peerlogic.csc.ncsu.edu/).&lt;br /&gt;
          to_return(status: 200, body: EXPECTED, headers: {})&lt;br /&gt;
      end&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
    &lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Edge Cases &amp;amp; Scenarios ==&lt;br /&gt;
''We present these scenarios as possible test cases for an accurately working Peerlogic webservice.''&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
These have not been implemented as there is no point in testing a system further when positive flows do not work.&lt;br /&gt;
However, the code in the Initial Phase Section can be used to analytically calculate correct responses for future assertions.&lt;br /&gt;
We have provided outputs to these scenarios below:&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
In addition, we also found out that the reputation_web_service_controller.rb currently is broken and needs refactoring. While the client side of the reputation web service page runs, any attempt to submit grades to the reputation web server side results in an error. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2355/checks here]&lt;br /&gt;
&lt;br /&gt;
Link to Github Project page: [https://github.com/joshlin5/expertiza/projects/2 here]&lt;br /&gt;
&lt;br /&gt;
Link to Testing Video: [https://youtu.be/VyeGGpxymXk here]&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143745</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143745"/>
		<updated>2022-03-28T01:50:18Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for student reviews to be accurate. The hamer algorithm was create for such purposes and returns a reputation weight associated with each reviewer. The instructor can then use the reputation weight value to either assert the reliability of a reviewer or use these values to compute a grade for a reviewer.&lt;br /&gt;
&lt;br /&gt;
=== System Design ===&lt;br /&gt;
&lt;br /&gt;
The hamer algorithm takes in a set of grades for assignments by reviewer and also any reputation weights (optional) associated with each reviewer to compute a reputation weight value for each reviewer. These reputation weight values indicate the accuracy and reliability of each reviewer. For example, a reviewer with a reputation weight of 3.0 is more accurate and reliable in their reviews compared to a 0.5 reputation weight of another reviewer. The following is an example from the paper [1] that describes the hamer algorithm:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Hamer Algorithm Inputs Outputs.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This algorithm is currently deployed to the following web server: http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms. To use the algorithm, a post request is sent to the peerlogic URL with a json body consisting of each assignment and the grades, and the reviewer who gave each grade. Once the request is sent, a json response is sent back with the corresponding hamer reputation weight values. The following is an example of a post request to the peerlogic URL to get back hamer reputation values:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer.png|1000px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
* Calculate reputation scores based on paper &amp;quot;Pluggable reputation systems for peer review: A web-service approach&amp;quot;&lt;br /&gt;
* Assert the accuracy of the reputation web server's hamer values through the URL http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms.&lt;br /&gt;
* Create a mock web server to return the correct hamer values if the reputation web server's hamer algorithm returns incorrect values.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
*reputation_web_server_hamer.rb&lt;br /&gt;
*reputation_mock_web_server_hamer.rb&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
=== Hamer Algorithm ===&lt;br /&gt;
[[File:Step1.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step2.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step3.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step4.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
We implemented the steps of this algorithm for our analytical validation, found in the section below.&lt;br /&gt;
== Test Plan - Initial Phase ==&lt;br /&gt;
In the initial phase, we were tasked with testing the reputation_web_service_controller. The work done by a previous project team was impacted by the web-service (peerlogic) not being available at that time.&lt;br /&gt;
This time, we were able to access the Peerlogic server at a late stage - therefore, our plan at this moment involved performing a series of unit tests to determine that the web-service was communicating &lt;br /&gt;
correctly with Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Plan ===&lt;br /&gt;
1. Since our focus in this phase was to conduct exploratory testing of the system, we wrote some conventional tests to examine Peerlogic functionality. At this stage, we realized that Peerlogic &lt;br /&gt;
would only accept and respond with JSON data.&lt;br /&gt;
&lt;br /&gt;
2. Therefore, a natural next step was to prepare a series of input data that simulated a general input scenario for the system, comprising of:&lt;br /&gt;
::a. Each reviewer has assigned scores to 3 reviewees (fellow students)&lt;br /&gt;
::b. There are a total of 3 reviewers, who have all graded each other in some fashion for 5 assignments&lt;br /&gt;
::c. Convert this scenario to JSON&lt;br /&gt;
::d. Write code to PUT this to Peerlogic, and receive a response&lt;br /&gt;
::e. Parse through this response to obtain the output values of the Hamer Algorithm, as calculated by Peerlogic.&lt;br /&gt;
::f. This output would be compared against actual data that we calculated based on the Research Paper for the Hamer Algorithm&lt;br /&gt;
'''''The code for the last step is shown below'''''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Conclusions ===&lt;br /&gt;
The results that are '''''actually''''' received from Peerlogic are presented below:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:json-ss.jpeg|600px]]&lt;br /&gt;
&lt;br /&gt;
The results from our python recreated Hamer Algorithm are as followed:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer2.png|250px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see, they do NOT match with expected results. &lt;br /&gt;
'''Therefore, our first conclusion is that the PeerLogic Webservice is implemented incorrectly.'''&lt;br /&gt;
This has been documented in the Conclusion section as the first point. &lt;br /&gt;
== Changes to Project Scope ==&lt;br /&gt;
&lt;br /&gt;
=== Test Plan - Second Phase ===&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
Additionally, this method was '''recommended by Dr. Gehringer''', our project mentor.&lt;br /&gt;
Finally, we also added a test case that ''mocks'' a webservice and asserts the output, done in 2 ways:&lt;br /&gt;
::a. In the first code snippet, we send JSON to a webservice that '''returns the correct Hamer output''', as Peerlogic should when fixed.&lt;br /&gt;
::b. In the form of an RSpec mock, in the second snippet below.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
#The following contains 4 reviewers who have scored 4 reviewees&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Input visualization:&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Reviewer-&amp;gt;  stu9999 stu9998 stu9997 stu9996&lt;br /&gt;
# Assignment&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
#&lt;br /&gt;
#Values that would be returned by a correct Hamer implementation&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
#sends API request to Peeerlogic&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port) do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
  #assertion fails, as expected&lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
#sends API request to Mock Hamer/Peerlogic Server&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;webmock/rspec&amp;quot; # gem install webmock -v 2.2.0&lt;br /&gt;
&lt;br /&gt;
WebMock.disable_net_connect!(allow_localhost: true)&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
        stub_request(:post, /peerlogic.csc.ncsu.edu/).&lt;br /&gt;
          to_return(status: 200, body: EXPECTED, headers: {})&lt;br /&gt;
      end&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
    &lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Edge Cases &amp;amp; Scenarios ==&lt;br /&gt;
''We present these scenarios as possible test cases for an accurately working Peerlogic webservice.''&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
These have not been implemented as there is no point in testing a system further when positive flows do not work.&lt;br /&gt;
However, the code in the Initial Phase Section can be used to analytically calculate correct responses for future assertions.&lt;br /&gt;
We have provided outputs to these scenarios below:&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2355/checks here]&lt;br /&gt;
&lt;br /&gt;
Link to Github Project page: [https://github.com/joshlin5/expertiza/projects/2 here]&lt;br /&gt;
&lt;br /&gt;
Link to Testing Video: [https://youtu.be/VyeGGpxymXk here]&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143743</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143743"/>
		<updated>2022-03-28T01:38:36Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for student reviews to be accurate. The hamer algorithm was create for such purposes and returns a reputation weight associated with each reviewer. The instructor can then use the reputation weight value to either assert the reliability of a reviewer or use these values to compute a grade for a reviewer.&lt;br /&gt;
&lt;br /&gt;
=== System Design ===&lt;br /&gt;
&lt;br /&gt;
The hamer algorithm takes in a set of grades for assignments by reviewer and also any reputation weights (optional) associated with each reviewer to compute a reputation weight value for each reviewer. These reputation weight values indicate the accuracy and reliability of each reviewer. For example, a reviewer with a reputation weight of 3.0 is more accurate and reliable in their reviews compared to a 0.5 reputation weight of another reviewer. The following is an example from the paper [1] that describes the hamer algorithm:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Hamer Algorithm Inputs Outputs.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This algorithm is currently deployed to the following web server: http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms. To use the algorithm, a post request is sent to the peerlogic URL with a json body consisting of each assignment and the grades, and the reviewer who gave each grade. Once the request is sent, a json response is sent back with the corresponding hamer reputation weight values. The following is an example of a post request to the peerlogic URL to get back hamer reputation values:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer.png|1000px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
* Calculate reputation scores based on paper &amp;quot;Pluggable reputation systems for peer review: A web-service approach&amp;quot;&lt;br /&gt;
* Assert the accuracy of the reputation web server's hamer values through the URL http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms.&lt;br /&gt;
* Create a mock web server to return the correct hamer values if the reputation web server's hamer algorithm returns incorrect values.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
*reputation_web_server_hamer.rb&lt;br /&gt;
*reputation_mock_web_server_hamer.rb&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
=== Hamer Algorithm ===&lt;br /&gt;
[[File:Step1.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step2.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step3.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step4.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
We implemented the steps of this algorithm for our analytical validation, found in the section below.&lt;br /&gt;
== Test Plan - Initial Phase ==&lt;br /&gt;
In the initial phase, we were tasked with testing the reputation_web_service_controller. The work done by a previous project team was impacted by the web-service (peerlogic) not being available at that time.&lt;br /&gt;
This time, we were able to access the Peerlogic server at a late stage - therefore, our plan at this moment involved performing a series of unit tests to determine that the web-service was communicating &lt;br /&gt;
correctly with Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Plan ===&lt;br /&gt;
1. Since our focus in this phase was to conduct exploratory testing of the system, we wrote some conventional tests to examine Peerlogic functionality. At this stage, we realized that Peerlogic &lt;br /&gt;
would only accept and respond with JSON data.&lt;br /&gt;
&lt;br /&gt;
2. Therefore, a natural next step was to prepare a series of input data that simulated a general input scenario for the system, comprising of:&lt;br /&gt;
::a. Each reviewer has assigned scores to 3 reviewees (fellow students)&lt;br /&gt;
::b. There are a total of 3 reviewers, who have all graded each other in some fashion for 5 assignments&lt;br /&gt;
::c. Convert this scenario to JSON&lt;br /&gt;
::d. Write code to PUT this to Peerlogic, and receive a response&lt;br /&gt;
::e. Parse through this response to obtain the output values of the Hamer Algorithm, as calculated by Peerlogic.&lt;br /&gt;
::f. This output would be compared against actual data that we calculated based on the Research Paper for the Hamer Algorithm&lt;br /&gt;
'''''The code for the last step is shown below'''''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Conclusions ===&lt;br /&gt;
The results that are '''''actually''''' received from Peerlogic are presented below:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:json-ss.jpeg|600px]]&lt;br /&gt;
&lt;br /&gt;
The results from our python recreated Hamer Algorithm are as followed:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer2.png|250px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see, they do NOT match with expected results. &lt;br /&gt;
'''Therefore, our first conclusion is that the PeerLogic Webservice is implemented incorrectly.'''&lt;br /&gt;
This has been documented in the Conclusion section as the first point. &lt;br /&gt;
== Changes to Project Scope ==&lt;br /&gt;
&lt;br /&gt;
=== Test Plan - Second Phase ===&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
Additionally, this method was '''recommended by Dr. Gehringer''', our project mentor.&lt;br /&gt;
Finally, we also added a test case that ''mocks'' a webservice and asserts the output, done in 2 ways:&lt;br /&gt;
::a. In the first code snippet, we send JSON to a webservice that '''returns the correct Hamer output''', as Peerlogic should when fixed.&lt;br /&gt;
::b. In the form of an RSpec mock, in the second snippet below.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
#The following contains 4 reviewers who have scored 4 reviewees&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Input visualization:&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Reviewer-&amp;gt;  stu9999 stu9998 stu9997 stu9996&lt;br /&gt;
# Assignment&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
#&lt;br /&gt;
#Values that would be returned by a correct Hamer implementation&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
#sends API request to Peeerlogic&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port) do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
  #assertion fails, as expected&lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
#sends API request to Mock Hamer/Peerlogic Server&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;webmock/rspec&amp;quot; # gem install webmock -v 2.2.0&lt;br /&gt;
&lt;br /&gt;
WebMock.disable_net_connect!(allow_localhost: true)&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
        stub_request(:post, /peerlogic.csc.ncsu.edu/).&lt;br /&gt;
          to_return(status: 200, body: EXPECTED, headers: {})&lt;br /&gt;
      end&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
    &lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Edge Cases &amp;amp; Scenarios ==&lt;br /&gt;
''We present these scenarios as possible test cases for an accurately working Peerlogic webservice.''&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
These have not been implemented as there is no point in testing a system further when positive flows do not work.&lt;br /&gt;
However, the code in the Initial Phase Section can be used to analytically calculate correct responses for future assertions.&lt;br /&gt;
We have provided outputs to these scenarios below:&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2355/checks here]&lt;br /&gt;
&lt;br /&gt;
Link to Github Project page: [https://github.com/joshlin5/expertiza/projects/2 here]&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143737</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143737"/>
		<updated>2022-03-28T01:24:55Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for student reviews to be accurate. The hamer algorithm was create for such purposes and returns a reputation weight associated with each reviewer. The instructor can then use the reputation weight value to either assert the reliability of a reviewer or use these values to compute a grade for a reviewer.&lt;br /&gt;
&lt;br /&gt;
=== System Design ===&lt;br /&gt;
&lt;br /&gt;
The hamer algorithm takes in a set of grades for assignments by reviewer and also any reputation weights (optional) associated with each reviewer to compute a reputation weight value for each reviewer. These reputation weight values indicate the accuracy and reliability of each reviewer. For example, a reviewer with a reputation weight of 3.0 is more accurate and reliable in their reviews compared to a 0.5 reputation weight of another reviewer. The following is an example from the paper [1] that describes the hamer algorithm:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Hamer Algorithm Inputs Outputs.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This algorithm is currently deployed to the following web server: http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms. To use the algorithm, a post request is sent to the peerlogic URL with a json body consisting of each assignment and the grades, and the reviewer who gave each grade. Once the request is sent, a json response is sent back with the corresponding hamer reputation weight values. The following is an example of a post request to the peerlogic URL to get back hamer reputation values:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer.png|1000px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
* Calculate reputation scores based on paper &amp;quot;Pluggable reputation systems for peer review: A web-service approach&amp;quot;&lt;br /&gt;
* Assert the accuracy of the reputation web server's hamer values through the URL http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms.&lt;br /&gt;
* Create a mock web server to return the correct hamer values if the reputation web server's hamer algorithm returns incorrect values.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
*reputation_web_server_hamer.rb&lt;br /&gt;
*reputation_mock_web_server_hamer.rb&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
=== Hamer Algorithm ===&lt;br /&gt;
[[File:Step1.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step2.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step3.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step4.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
We implemented the steps of this algorithm for our analytical validation, found in the section below.&lt;br /&gt;
== Test Plan - Initial Phase ==&lt;br /&gt;
In the initial phase, we were tasked with testing the reputation_web_service_controller. The work done by a previous project team was impacted by the web-service (peerlogic) not being available at that time.&lt;br /&gt;
This time, we were able to access the Peerlogic server at a late stage - therefore, our plan at this moment involved performing a series of unit tests to determine that the web-service was communicating &lt;br /&gt;
correctly with Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Plan ===&lt;br /&gt;
1. Since our focus in this phase was to conduct exploratory testing of the system, we wrote some conventional tests to examine Peerlogic functionality. At this stage, we realized that Peerlogic &lt;br /&gt;
would only accept and respond with JSON data.&lt;br /&gt;
&lt;br /&gt;
2. Therefore, a natural next step was to prepare a series of input data that simulated a general input scenario for the system, comprising of:&lt;br /&gt;
::a. Each reviewer has assigned scores to 3 reviewees (fellow students)&lt;br /&gt;
::b. There are a total of 3 reviewers, who have all graded each other in some fashion for 5 assignments&lt;br /&gt;
::c. Convert this scenario to JSON&lt;br /&gt;
::d. Write code to PUT this to Peerlogic, and receive a response&lt;br /&gt;
::e. Parse through this response to obtain the output values of the Hamer Algorithm, as calculated by Peerlogic.&lt;br /&gt;
::f. This output would be compared against actual data that we calculated based on the Research Paper for the Hamer Algorithm&lt;br /&gt;
'''''The code for the last step is shown below'''''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Reputation of Reviewer  1&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  2&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  3&lt;br /&gt;
1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Conclusions ===&lt;br /&gt;
The results that are '''''actually''''' received from Peerlogic are presented below:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:json-ss.jpeg|600px]]&lt;br /&gt;
&lt;br /&gt;
The results from our python recreated Hamer Algorithm are as followed:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer2.png|250px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see, they do NOT match with expected results. &lt;br /&gt;
'''Therefore, our first conclusion is that the PeerLogic Webservice is implemented incorrectly.'''&lt;br /&gt;
This has been documented in the Conclusion section as the first point. &lt;br /&gt;
== Changes to Project Scope ==&lt;br /&gt;
&lt;br /&gt;
=== Test Plan - Second Phase ===&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
Additionally, this method was '''recommended by Dr. Gehringer''', our project mentor.&lt;br /&gt;
Finally, we also added a test case that ''mocks'' a webservice and asserts the output, done in 2 ways:&lt;br /&gt;
::a. In the first code snippet, we send JSON to a webservice that '''returns the correct Hamer output''', as Peerlogic should when fixed.&lt;br /&gt;
::b. In the form of an RSpec mock, in the second snippet below.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port) do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
    &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;webmock/rspec&amp;quot; # gem install webmock -v 2.2.0&lt;br /&gt;
&lt;br /&gt;
WebMock.disable_net_connect!(allow_localhost: true)&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
        stub_request(:post, /peerlogic.csc.ncsu.edu/).&lt;br /&gt;
          to_return(status: 200, body: EXPECTED, headers: {})&lt;br /&gt;
      end&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
    &lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Edge Cases &amp;amp; Scenarios ==&lt;br /&gt;
''We present these scenarios as possible test cases for an accurately working Peerlogic webservice.''&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
These have not been implemented as there is no point in testing a system further when positive flows do not work.&lt;br /&gt;
However, the code in the Initial Phase Section can be used to analytically calculate correct responses for future assertions.&lt;br /&gt;
We have provided outputs to these scenarios below:&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2355/checks here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143736</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143736"/>
		<updated>2022-03-28T01:23:58Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for student reviews to be accurate. The hamer algorithm was create for such purposes and returns a reputation weight associated with each reviewer. The instructor can then use the reputation weight value to either assert the reliability of a reviewer or use these values to compute a grade for a reviewer.&lt;br /&gt;
&lt;br /&gt;
=== System Design ===&lt;br /&gt;
&lt;br /&gt;
The hamer algorithm takes in a set of grades for assignments by reviewer and also any reputation weights (optional) associated with each reviewer to compute a reputation weight value for each reviewer. These reputation weight values indicate the accuracy and reliability of each reviewer. For example, a reviewer with a reputation weight of 3.0 is more accurate and reliable in their reviews compared to a 0.5 reputation weight of another reviewer. The following is an example from the paper [1] that describes the hamer algorithm:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Hamer Algorithm Inputs Outputs.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This algorithm is currently deployed to the following web server: http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms. To use the algorithm, a post request is sent to the peerlogic URL with a json body consisting of each assignment and the grades, and the reviewer who gave each grade. Once the request is sent, a json response is sent back with the corresponding hamer reputation weight values. The following is an example of a post request to the peerlogic URL to get back hamer reputation values:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer.png|1000px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
* Calculate reputation scores based on paper &amp;quot;Pluggable reputation systems for peer review: A web-service approach&amp;quot;&lt;br /&gt;
* Assert the accuracy of the reputation web server's hamer values through the URL http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms.&lt;br /&gt;
* Create a mock web server to return the correct hamer values if the reputation web server's hamer algorithm returns incorrect values.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
*reputation_web_server_hamer.rb&lt;br /&gt;
*reputation_mock_web_server_hamer.rb&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
=== Hamer Algorithm ===&lt;br /&gt;
[[File:Step1.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step2.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step3.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step4.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
We implemented the steps of this algorithm for our analytical validation, found in the section below.&lt;br /&gt;
== Test Plan - Initial Phase ==&lt;br /&gt;
In the initial phase, we were tasked with testing the reputation_web_service_controller. The work done by a previous project team was impacted by the web-service (peerlogic) not being available at that time.&lt;br /&gt;
This time, we were able to access the Peerlogic server at a late stage - therefore, our plan at this moment involved performing a series of unit tests to determine that the web-service was communicating &lt;br /&gt;
correctly with Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Plan ===&lt;br /&gt;
1. Since our focus in this phase was to conduct exploratory testing of the system, we wrote some conventional tests to examine Peerlogic functionality. At this stage, we realized that Peerlogic &lt;br /&gt;
would only accept and respond with JSON data.&lt;br /&gt;
&lt;br /&gt;
2. Therefore, a natural next step was to prepare a series of input data that simulated a general input scenario for the system, comprising of:&lt;br /&gt;
::a. Each reviewer has assigned scores to 3 reviewees (fellow students)&lt;br /&gt;
::b. There are a total of 3 reviewers, who have all graded each other in some fashion for 5 assignments&lt;br /&gt;
::c. Convert this scenario to JSON&lt;br /&gt;
::d. Write code to PUT this to Peerlogic, and receive a response&lt;br /&gt;
::e. Parse through this response to obtain the output values of the Hamer Algorithm, as calculated by Peerlogic.&lt;br /&gt;
::f. This output would be compared against actual data that we calculated based on the Research Paper for the Hamer Algorithm&lt;br /&gt;
'''''The code for the last step is shown below'''''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Reputation of Reviewer  1&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  2&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  3&lt;br /&gt;
1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Conclusions ===&lt;br /&gt;
The results that are '''''actually''''' received from Peerlogic are presented below:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:json-ss.jpeg|600px]]&lt;br /&gt;
&lt;br /&gt;
The results from our python recreated Hamer Algorithm are as followed:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:rReputation web server hamer2.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see, they do NOT match with expected results. &lt;br /&gt;
'''Therefore, our first conclusion is that the PeerLogic Webservice is implemented incorrectly.'''&lt;br /&gt;
This has been documented in the Conclusion section as the first point. &lt;br /&gt;
== Changes to Project Scope ==&lt;br /&gt;
&lt;br /&gt;
=== Test Plan - Second Phase ===&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
Additionally, this method was '''recommended by Dr. Gehringer''', our project mentor.&lt;br /&gt;
Finally, we also added a test case that ''mocks'' a webservice and asserts the output, done in 2 ways:&lt;br /&gt;
::a. In the first code snippet, we send JSON to a webservice that '''returns the correct Hamer output''', as Peerlogic should when fixed.&lt;br /&gt;
::b. In the form of an RSpec mock, in the second snippet below.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port) do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
    &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;webmock/rspec&amp;quot; # gem install webmock -v 2.2.0&lt;br /&gt;
&lt;br /&gt;
WebMock.disable_net_connect!(allow_localhost: true)&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    before(:each) do&lt;br /&gt;
        stub_request(:post, /peerlogic.csc.ncsu.edu/).&lt;br /&gt;
          to_return(status: 200, body: EXPECTED, headers: {})&lt;br /&gt;
      end&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
    &lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Edge Cases &amp;amp; Scenarios ==&lt;br /&gt;
''We present these scenarios as possible test cases for an accurately working Peerlogic webservice.''&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
These have not been implemented as there is no point in testing a system further when positive flows do not work.&lt;br /&gt;
However, the code in the Initial Phase Section can be used to analytically calculate correct responses for future assertions.&lt;br /&gt;
We have provided outputs to these scenarios below:&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2355/checks here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Reputation_web_server_hamer2.png&amp;diff=143734</id>
		<title>File:Reputation web server hamer2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Reputation_web_server_hamer2.png&amp;diff=143734"/>
		<updated>2022-03-28T01:21:46Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143733</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143733"/>
		<updated>2022-03-28T01:21:34Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for student reviews to be accurate. The hamer algorithm was create for such purposes and returns a reputation weight associated with each reviewer. The instructor can then use the reputation weight value to either assert the reliability of a reviewer or use these values to compute a grade for a reviewer.&lt;br /&gt;
&lt;br /&gt;
=== System Design ===&lt;br /&gt;
&lt;br /&gt;
The hamer algorithm takes in a set of grades for assignments by reviewer and also any reputation weights (optional) associated with each reviewer to compute a reputation weight value for each reviewer. These reputation weight values indicate the accuracy and reliability of each reviewer. For example, a reviewer with a reputation weight of 3.0 is more accurate and reliable in their reviews compared to a 0.5 reputation weight of another reviewer. The following is an example from the paper [1] that describes the hamer algorithm:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Hamer Algorithm Inputs Outputs.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This algorithm is currently deployed to the following web server: http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms. To use the algorithm, a post request is sent to the peerlogic URL with a json body consisting of each assignment and the grades, and the reviewer who gave each grade. Once the request is sent, a json response is sent back with the corresponding hamer reputation weight values. The following is an example of a post request to the peerlogic URL to get back hamer reputation values:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer.png|1000px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
* Calculate reputation scores based on paper &amp;quot;Pluggable reputation systems for peer review: A web-service approach&amp;quot;&lt;br /&gt;
* Assert the accuracy of the reputation web server's hamer values through the URL http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms.&lt;br /&gt;
* Create a mock web server to return the correct hamer values if the reputation web server's hamer algorithm returns incorrect values.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
*reputation_web_server_hamer.rb&lt;br /&gt;
*reputation_mock_web_server_hamer.rb&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
=== Hamer Algorithm ===&lt;br /&gt;
[[File:Step1.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step2.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step3.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step4.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
We implemented the steps of this algorithm for our analytical validation, found in the section below.&lt;br /&gt;
== Test Plan - Initial Phase ==&lt;br /&gt;
In the initial phase, we were tasked with testing the reputation_web_service_controller. The work done by a previous project team was impacted by the web-service (peerlogic) not being available at that time.&lt;br /&gt;
This time, we were able to access the Peerlogic server at a late stage - therefore, our plan at this moment involved performing a series of unit tests to determine that the web-service was communicating &lt;br /&gt;
correctly with Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Plan ===&lt;br /&gt;
1. Since our focus in this phase was to conduct exploratory testing of the system, we wrote some conventional tests to examine Peerlogic functionality. At this stage, we realized that Peerlogic &lt;br /&gt;
would only accept and respond with JSON data.&lt;br /&gt;
&lt;br /&gt;
2. Therefore, a natural next step was to prepare a series of input data that simulated a general input scenario for the system, comprising of:&lt;br /&gt;
::a. Each reviewer has assigned scores to 3 reviewees (fellow students)&lt;br /&gt;
::b. There are a total of 3 reviewers, who have all graded each other in some fashion for 5 assignments&lt;br /&gt;
::c. Convert this scenario to JSON&lt;br /&gt;
::d. Write code to PUT this to Peerlogic, and receive a response&lt;br /&gt;
::e. Parse through this response to obtain the output values of the Hamer Algorithm, as calculated by Peerlogic.&lt;br /&gt;
::f. This output would be compared against actual data that we calculated based on the Research Paper for the Hamer Algorithm&lt;br /&gt;
'''''The code for the last step is shown below'''''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Reputation of Reviewer  1&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  2&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  3&lt;br /&gt;
1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Conclusions ===&lt;br /&gt;
The results that are '''''actually''''' received from Peerlogic are presented below:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:json-ss.jpeg|600px]]&lt;br /&gt;
&lt;br /&gt;
The results from our python recreated Hamer Algorithm are as followed:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:reputation_web_server_hamer2.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see, they do NOT match with expected results. &lt;br /&gt;
'''Therefore, our first conclusion is that the PeerLogic Webservice is implemented incorrectly.'''&lt;br /&gt;
This has been documented in the Conclusion section as the first point. &lt;br /&gt;
== Changes to Project Scope ==&lt;br /&gt;
&lt;br /&gt;
=== Test Plan - Second Phase ===&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
Additionally, this method was '''recommended by Dr. Gehringer''', our project mentor.&lt;br /&gt;
Finally, we also added a test case that ''mocks'' a webservice and asserts the output, done in 2 ways:&lt;br /&gt;
::a. In the first code snippet, we send JSON to a webservice that '''returns the correct Hamer output''', as Peerlogic should when fixed.&lt;br /&gt;
::b. In the form of an RSpec mock, in the second snippet below.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port) do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
    &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Edge Cases &amp;amp; Scenarios ==&lt;br /&gt;
''We present these scenarios as possible test cases for an accurately working Peerlogic webservice.''&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
These have not been implemented as there is no point in testing a system further when positive flows do not work.&lt;br /&gt;
However, the code in the Initial Phase Section can be used to analytically calculate correct responses for future assertions.&lt;br /&gt;
We have provided outputs to these scenarios below:&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2355/checks here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143732</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143732"/>
		<updated>2022-03-28T01:20:50Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for student reviews to be accurate. The hamer algorithm was create for such purposes and returns a reputation weight associated with each reviewer. The instructor can then use the reputation weight value to either assert the reliability of a reviewer or use these values to compute a grade for a reviewer.&lt;br /&gt;
&lt;br /&gt;
=== System Design ===&lt;br /&gt;
&lt;br /&gt;
The hamer algorithm takes in a set of grades for assignments by reviewer and also any reputation weights (optional) associated with each reviewer to compute a reputation weight value for each reviewer. These reputation weight values indicate the accuracy and reliability of each reviewer. For example, a reviewer with a reputation weight of 3.0 is more accurate and reliable in their reviews compared to a 0.5 reputation weight of another reviewer. The following is an example from the paper [1] that describes the hamer algorithm:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Hamer Algorithm Inputs Outputs.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This algorithm is currently deployed to the following web server: http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms. To use the algorithm, a post request is sent to the peerlogic URL with a json body consisting of each assignment and the grades, and the reviewer who gave each grade. Once the request is sent, a json response is sent back with the corresponding hamer reputation weight values. The following is an example of a post request to the peerlogic URL to get back hamer reputation values:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer.png|1000px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
* Calculate reputation scores based on paper &amp;quot;Pluggable reputation systems for peer review: A web-service approach&amp;quot;&lt;br /&gt;
* Assert the accuracy of the reputation web server's hamer values through the URL http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms.&lt;br /&gt;
* Create a mock web server to return the correct hamer values if the reputation web server's hamer algorithm returns incorrect values.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
*reputation_web_server_hamer.rb&lt;br /&gt;
*reputation_mock_web_server_hamer.rb&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
=== Hamer Algorithm ===&lt;br /&gt;
[[File:Step1.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step2.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step3.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step4.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
We implemented the steps of this algorithm for our analytical validation, found in the section below.&lt;br /&gt;
== Test Plan - Initial Phase ==&lt;br /&gt;
In the initial phase, we were tasked with testing the reputation_web_service_controller. The work done by a previous project team was impacted by the web-service (peerlogic) not being available at that time.&lt;br /&gt;
This time, we were able to access the Peerlogic server at a late stage - therefore, our plan at this moment involved performing a series of unit tests to determine that the web-service was communicating &lt;br /&gt;
correctly with Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Plan ===&lt;br /&gt;
1. Since our focus in this phase was to conduct exploratory testing of the system, we wrote some conventional tests to examine Peerlogic functionality. At this stage, we realized that Peerlogic &lt;br /&gt;
would only accept and respond with JSON data.&lt;br /&gt;
&lt;br /&gt;
2. Therefore, a natural next step was to prepare a series of input data that simulated a general input scenario for the system, comprising of:&lt;br /&gt;
::a. Each reviewer has assigned scores to 3 reviewees (fellow students)&lt;br /&gt;
::b. There are a total of 3 reviewers, who have all graded each other in some fashion for 5 assignments&lt;br /&gt;
::c. Convert this scenario to JSON&lt;br /&gt;
::d. Write code to PUT this to Peerlogic, and receive a response&lt;br /&gt;
::e. Parse through this response to obtain the output values of the Hamer Algorithm, as calculated by Peerlogic.&lt;br /&gt;
::f. This output would be compared against actual data that we calculated based on the Research Paper for the Hamer Algorithm&lt;br /&gt;
'''''The code for the last step is shown below'''''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Reputation of Reviewer  1&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  2&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  3&lt;br /&gt;
1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Conclusions ===&lt;br /&gt;
The results that are '''''actually''''' received from Peerlogic are presented below:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:json-ss.jpeg|600px]]&lt;br /&gt;
&lt;br /&gt;
The results from our python recreated Hamer Algorithm are as followed:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:reputation_web_server_hamer2.png|1000px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see, they do NOT match with expected results. &lt;br /&gt;
'''Therefore, our first conclusion is that the PeerLogic Webservice is implemented incorrectly.'''&lt;br /&gt;
This has been documented in the Conclusion section as the first point. &lt;br /&gt;
== Changes to Project Scope ==&lt;br /&gt;
&lt;br /&gt;
=== Test Plan - Second Phase ===&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
Additionally, this method was '''recommended by Dr. Gehringer''', our project mentor.&lt;br /&gt;
Finally, we also added a test case that ''mocks'' a webservice and asserts the output, done in 2 ways:&lt;br /&gt;
::a. In the first code snippet, we send JSON to a webservice that '''returns the correct Hamer output''', as Peerlogic should when fixed.&lt;br /&gt;
::b. In the form of an RSpec mock, in the second snippet below.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port) do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
    &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Edge Cases &amp;amp; Scenarios ==&lt;br /&gt;
''We present these scenarios as possible test cases for an accurately working Peerlogic webservice.''&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
These have not been implemented as there is no point in testing a system further when positive flows do not work.&lt;br /&gt;
However, the code in the Initial Phase Section can be used to analytically calculate correct responses for future assertions.&lt;br /&gt;
We have provided outputs to these scenarios below:&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2355/checks here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143731</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143731"/>
		<updated>2022-03-28T01:19:38Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for student reviews to be accurate. The hamer algorithm was create for such purposes and returns a reputation weight associated with each reviewer. The instructor can then use the reputation weight value to either assert the reliability of a reviewer or use these values to compute a grade for a reviewer.&lt;br /&gt;
&lt;br /&gt;
=== System Design ===&lt;br /&gt;
&lt;br /&gt;
The hamer algorithm takes in a set of grades for assignments by reviewer and also any reputation weights (optional) associated with each reviewer to compute a reputation weight value for each reviewer. These reputation weight values indicate the accuracy and reliability of each reviewer. For example, a reviewer with a reputation weight of 3.0 is more accurate and reliable in their reviews compared to a 0.5 reputation weight of another reviewer. The following is an example from the paper [1] that describes the hamer algorithm:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Hamer Algorithm Inputs Outputs.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This algorithm is currently deployed to the following web server: http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms. To use the algorithm, a post request is sent to the peerlogic URL with a json body consisting of each assignment and the grades, and the reviewer who gave each grade. Once the request is sent, a json response is sent back with the corresponding hamer reputation weight values. The following is an example of a post request to the peerlogic URL to get back hamer reputation values:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer.png|1000px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
* Calculate reputation scores based on paper &amp;quot;Pluggable reputation systems for peer review: A web-service approach&amp;quot;&lt;br /&gt;
* Assert the accuracy of the reputation web server's hamer values through the URL http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms.&lt;br /&gt;
* Create a mock web server to return the correct hamer values if the reputation web server's hamer algorithm returns incorrect values.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
*reputation_web_server_hamer.rb&lt;br /&gt;
*reputation_mock_web_server_hamer.rb&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
=== Hamer Algorithm ===&lt;br /&gt;
[[File:Step1.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step2.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step3.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step4.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
We implemented the steps of this algorithm for our analytical validation, found in the section below.&lt;br /&gt;
== Test Plan - Initial Phase ==&lt;br /&gt;
In the initial phase, we were tasked with testing the reputation_web_service_controller. The work done by a previous project team was impacted by the web-service (peerlogic) not being available at that time.&lt;br /&gt;
This time, we were able to access the Peerlogic server at a late stage - therefore, our plan at this moment involved performing a series of unit tests to determine that the web-service was communicating &lt;br /&gt;
correctly with Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Plan ===&lt;br /&gt;
1. Since our focus in this phase was to conduct exploratory testing of the system, we wrote some conventional tests to examine Peerlogic functionality. At this stage, we realized that Peerlogic &lt;br /&gt;
would only accept and respond with JSON data.&lt;br /&gt;
&lt;br /&gt;
2. Therefore, a natural next step was to prepare a series of input data that simulated a general input scenario for the system, comprising of:&lt;br /&gt;
::a. Each reviewer has assigned scores to 3 reviewees (fellow students)&lt;br /&gt;
::b. There are a total of 3 reviewers, who have all graded each other in some fashion for 5 assignments&lt;br /&gt;
::c. Convert this scenario to JSON&lt;br /&gt;
::d. Write code to PUT this to Peerlogic, and receive a response&lt;br /&gt;
::e. Parse through this response to obtain the output values of the Hamer Algorithm, as calculated by Peerlogic.&lt;br /&gt;
::f. This output would be compared against actual data that we calculated based on the Research Paper for the Hamer Algorithm&lt;br /&gt;
'''''The code for the last step is shown below'''''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Reputation of Reviewer  1&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  2&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  3&lt;br /&gt;
1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Conclusions ===&lt;br /&gt;
The results that are '''''actually''''' received from Peerlogic are presented below:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:json-ss.jpeg|600px]]&lt;br /&gt;
&lt;br /&gt;
The results from our python recreated Hamer Algorithm are as followed:&lt;br /&gt;
[[File:reputation_web_server_hamer.png|500px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see, they do NOT match with expected results. &lt;br /&gt;
'''Therefore, our first conclusion is that the PeerLogic Webservice is implemented incorrectly.'''&lt;br /&gt;
This has been documented in the Conclusion section as the first point. &lt;br /&gt;
== Changes to Project Scope ==&lt;br /&gt;
&lt;br /&gt;
=== Test Plan - Second Phase ===&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
Additionally, this method was '''recommended by Dr. Gehringer''', our project mentor.&lt;br /&gt;
Finally, we also added a test case that ''mocks'' a webservice and asserts the output, done in 2 ways:&lt;br /&gt;
::a. In the first code snippet, we send JSON to a webservice that '''returns the correct Hamer output''', as Peerlogic should when fixed.&lt;br /&gt;
::b. In the form of an RSpec mock, in the second snippet below.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port) do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
    &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Edge Cases &amp;amp; Scenarios ==&lt;br /&gt;
''We present these scenarios as possible test cases for an accurately working Peerlogic webservice.''&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
These have not been implemented as there is no point in testing a system further when positive flows do not work.&lt;br /&gt;
However, the code in the Initial Phase Section can be used to analytically calculate correct responses for future assertions.&lt;br /&gt;
We have provided outputs to these scenarios below:&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2355/checks here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143728</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143728"/>
		<updated>2022-03-28T01:12:11Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for student reviews to be accurate. The hamer algorithm was create for such purposes and returns a reputation weight associated with each reviewer. The instructor can then use the reputation weight value to either assert the reliability of a reviewer or use these values to compute a grade for a reviewer.&lt;br /&gt;
&lt;br /&gt;
=== System Design ===&lt;br /&gt;
&lt;br /&gt;
The hamer algorithm takes in a set of grades for assignments by reviewer and also any reputation weights (optional) associated with each reviewer to compute a reputation weight value for each reviewer. These reputation weight values indicate the accuracy and reliability of each reviewer. For example, a reviewer with a reputation weight of 3.0 is more accurate and reliable in their reviews compared to a 0.5 reputation weight of another reviewer. The following is an example from the paper [1] that describes the hamer algorithm:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Hamer Algorithm Inputs Outputs.png|500px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This algorithm is currently deployed to the following web server: http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms. To use the algorithm, a post request is sent to the peerlogic URL with a json body consisting of each assignment and the grades, and the reviewer who gave each grade. Once the request is sent, a json response is sent back with the corresponding hamer reputation weight values. The following is an example of a post request to the peerlogic URL to get back hamer reputation values:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer.png|1000px]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
* Calculate reputation scores based on paper &amp;quot;Pluggable reputation systems for peer review: A web-service approach&amp;quot;&lt;br /&gt;
* Assert the accuracy of the reputation web server's hamer values through the URL http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms.&lt;br /&gt;
* Create a mock web server to return the correct hamer values if the reputation web server's hamer algorithm returns incorrect values.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
*reputation_web_server_hamer.rb&lt;br /&gt;
*reputation_mock_web_server_hamer.rb&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
=== Hamer Algorithm ===&lt;br /&gt;
[[File:Step1.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step2.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step3.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step4.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
We implemented the steps of this algorithm for our analytical validation, found in the section below.&lt;br /&gt;
== Test Plan - Initial Phase ==&lt;br /&gt;
In the initial phase, we were tasked with testing the reputation_web_service_controller. The work done by a previous project team was impacted by the web-service (peerlogic) not being available at that time.&lt;br /&gt;
This time, we were able to access the Peerlogic server at a late stage - therefore, our plan at this moment involved performing a series of unit tests to determine that the web-service was communicating &lt;br /&gt;
correctly with Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Plan ===&lt;br /&gt;
1. Since our focus in this phase was to conduct exploratory testing of the system, we wrote some conventional tests to examine Peerlogic functionality. At this stage, we realized that Peerlogic &lt;br /&gt;
would only accept and respond with JSON data.&lt;br /&gt;
&lt;br /&gt;
2. Therefore, a natural next step was to prepare a series of input data that simulated a general input scenario for the system, comprising of:&lt;br /&gt;
::a. Each reviewer has assigned scores to 3 reviewees (fellow students)&lt;br /&gt;
::b. There are a total of 3 reviewers, who have all graded each other in some fashion for 5 assignments&lt;br /&gt;
::c. Convert this scenario to JSON&lt;br /&gt;
::d. Write code to PUT this to Peerlogic, and receive a response&lt;br /&gt;
::e. Parse through this response to obtain the output values of the Hamer Algorithm, as calculated by Peerlogic.&lt;br /&gt;
::f. This output would be compared against actual data that we calculated based on the Research Paper for the Hamer Algorithm&lt;br /&gt;
'''''The code for the last step is shown below'''''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Reputation of Reviewer  1&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  2&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  3&lt;br /&gt;
1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Conclusions ===&lt;br /&gt;
The results that are '''''actually''''' received from Peerlogic are presented below:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:json-ss.jpeg|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see, they do NOT match with expected results. &lt;br /&gt;
'''Therefore, our first conclusion is that the PeerLogic Webservice is implemented incorrectly.'''&lt;br /&gt;
This has been documented in the Conclusion section as the first point. &lt;br /&gt;
== Changes to Project Scope ==&lt;br /&gt;
&lt;br /&gt;
=== Second Phase ===&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port) do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
    &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Edge Cases &amp;amp; Scenarios ==&lt;br /&gt;
''We present these scenarios as possible test cases for an accurately working Peerlogic webservice.''&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
These have not been implemented as there is no point in testing a system further when positive flows do not work.&lt;br /&gt;
However, the code in the Initial Phase Section can be used to analytically calculate correct responses for future assertions.&lt;br /&gt;
We have provided outputs to these scenarios below:&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2355/checks here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Reputation_web_server_hamer.png&amp;diff=143726</id>
		<title>File:Reputation web server hamer.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Reputation_web_server_hamer.png&amp;diff=143726"/>
		<updated>2022-03-28T01:10:55Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143725</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143725"/>
		<updated>2022-03-28T01:10:34Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for student reviews to be accurate. The hamer algorithm was create for such purposes and returns a reputation weight associated with each reviewer. The instructor can then use the reputation weight value to either assert the reliability of a reviewer or use these values to compute a grade for a reviewr.&lt;br /&gt;
&lt;br /&gt;
=== System Design ===&lt;br /&gt;
&lt;br /&gt;
The hamer algorithm takes in a set of grades for assignments by reviewer and also any reputation weights (optional) associated with each reviewer to compute a reputation weight value for each reviewer. These reputation weight values indicate the accuracy and reliability of each reviewer. For example, a reviewer with a reputation weight of 3.0 is more accurate and reliable in their reviews compared to a 0.5 reputation weight of another reviewer. The following is an example from the paper [1] that describes the hamer algorithm:&lt;br /&gt;
&lt;br /&gt;
[[File:Hamer Algorithm Inputs Outputs.png|500px]]&lt;br /&gt;
&lt;br /&gt;
This algorithm is currently deployed to the following web server: http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms. To use the algorithm, a post request is sent to the peerlogic URL with a json body consisting of each assignment and the grades, and the reviewer who gave each grade. Once the request is sent, a json response is sent back with the corresponding hamer reputation weight values. The following is an example of a post request to the peerlogic URL to get back hamer reputation values:&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Reputation web server hamer.png|thumb|]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
* Calculate reputation scores based on paper &amp;quot;Pluggable reputation systems for peer review: A web-service approach&amp;quot;&lt;br /&gt;
* Assert the accuracy of the reputation web server's hamer values through the URL http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms.&lt;br /&gt;
* Create a mock web server to return the correct hamer values if the reputation web server's hamer algorithm returns incorrect values.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
*reputation_web_server_hamer.rb&lt;br /&gt;
*reputation_mock_web_server_hamer.rb&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
=== Hamer Algorithm ===&lt;br /&gt;
[[File:Step1.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step2.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step3.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step4.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
We implemented the steps of this algorithm for our analytical validation, found in the section below.&lt;br /&gt;
== Test Plan - Initial Phase ==&lt;br /&gt;
In the initial phase, we were tasked with testing the reputation_web_service_controller. The work done by a previous project team was impacted by the web-service (peerlogic) not being available at that time.&lt;br /&gt;
This time, we were able to access the Peerlogic server at a late stage - therefore, our plan at this moment involved performing a series of unit tests to determine that the web-service was communicating &lt;br /&gt;
correctly with Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Plan ===&lt;br /&gt;
1. Since our focus in this phase was to conduct exploratory testing of the system, we wrote some conventional tests to examine Peerlogic functionality. At this stage, we realized that Peerlogic &lt;br /&gt;
would only accept and respond with JSON data.&lt;br /&gt;
&lt;br /&gt;
2. Therefore, a natural next step was to prepare a series of input data that simulated a general input scenario for the system, comprising of:&lt;br /&gt;
::a. Each reviewer has assigned scores to 3 reviewees (fellow students)&lt;br /&gt;
::b. There are a total of 3 reviewers, who have all graded each other in some fashion for 5 assignments&lt;br /&gt;
::c. Convert this scenario to JSON&lt;br /&gt;
::d. Write code to PUT this to Peerlogic, and receive a response&lt;br /&gt;
::e. Parse through this response to obtain the output values of the Hamer Algorithm, as calculated by Peerlogic.&lt;br /&gt;
::f. This output would be compared against actual data that we calculated based on the Research Paper for the Hamer Algorithm&lt;br /&gt;
'''''The code for the last step is shown below'''''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Reputation of Reviewer  1&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  2&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  3&lt;br /&gt;
1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Conclusions ===&lt;br /&gt;
The results that are '''''actually''''' received from Peerlogic are presented below:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:json-ss.jpeg|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see, they do NOT match with expected results. &lt;br /&gt;
'''Therefore, our first conclusion is that the PeerLogic Webservice is implemented incorrectly.'''&lt;br /&gt;
This has been documented in the Conclusion section as the first point. &lt;br /&gt;
== Changes to Project Scope ==&lt;br /&gt;
&lt;br /&gt;
=== Second Phase ===&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port) do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
    &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Scenarios ==&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
We present these scenarios as possible test cases for an accurately working Peerlogic webservice.&lt;br /&gt;
These have not been implemented as there is no point in testing a system further when positive flows do not work.&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2355/checks here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143724</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143724"/>
		<updated>2022-03-28T01:09:16Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for student reviews to be accurate. The hamer algorithm was create for such purposes and returns a reputation weight associated with each reviewer. The instructor can then use the reputation weight value to either assert the reliability of a reviewer or use these values to compute a grade for a reviewr.&lt;br /&gt;
&lt;br /&gt;
=== System Design ===&lt;br /&gt;
&lt;br /&gt;
The hamer algorithm takes in a set of grades for assignments by reviewer and also any reputation weights (optional) associated with each reviewer to compute a reputation weight value for each reviewer. These reputation weight values indicate the accuracy and reliability of each reviewer. For example, a reviewer with a reputation weight of 3.0 is more accurate and reliable in their reviews compared to a 0.5 reputation weight of another reviewer. The following is an example from the paper [1] that describes the hamer algorithm:&lt;br /&gt;
[[File:Hamer Algorithm Inputs Outputs.png|1000px]]&lt;br /&gt;
&lt;br /&gt;
This algorithm is currently deployed to the following web server: http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms. To use the algorithm, a post request is sent to the peerlogic URL with a json body consisting of each assignment and the grades, and the reviewer who gave each grade. Once the request is sent, a json response is sent back with the corresponding hamer reputation weight values. The following is an example of a post request to the peerlogic URL to get back hamer reputation values:&lt;br /&gt;
[[File:Reputation web server hamer.png|thumb|]]&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
* Calculate reputation scores based on paper &amp;quot;Pluggable reputation systems for peer review: A web-service approach&amp;quot;&lt;br /&gt;
* Assert the accuracy of the reputation web server's hamer values through the URL http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms.&lt;br /&gt;
* Create a mock web server to return the correct hamer values if the reputation web server's hamer algorithm returns incorrect values.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
*reputation_web_server_hamer.rb&lt;br /&gt;
*reputation_mock_web_server_hamer.rb&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
=== Hamer Algorithm ===&lt;br /&gt;
[[File:Step1.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step2.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step3.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step4.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
We implemented the steps of this algorithm for our analytical validation, found in the section below.&lt;br /&gt;
== Test Plan - Initial Phase ==&lt;br /&gt;
In the initial phase, we were tasked with testing the reputation_web_service_controller. The work done by a previous project team was impacted by the web-service (peerlogic) not being available at that time.&lt;br /&gt;
This time, we were able to access the Peerlogic server at a late stage - therefore, our plan at this moment involved performing a series of unit tests to determine that the web-service was communicating &lt;br /&gt;
correctly with Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Plan ===&lt;br /&gt;
1. Since our focus in this phase was to conduct exploratory testing of the system, we wrote some conventional tests to examine Peerlogic functionality. At this stage, we realized that Peerlogic &lt;br /&gt;
would only accept and respond with JSON data.&lt;br /&gt;
&lt;br /&gt;
2. Therefore, a natural next step was to prepare a series of input data that simulated a general input scenario for the system, comprising of:&lt;br /&gt;
::a. Each reviewer has assigned scores to 3 reviewees (fellow students)&lt;br /&gt;
::b. There are a total of 3 reviewers, who have all graded each other in some fashion for 5 assignments&lt;br /&gt;
::c. Convert this scenario to JSON&lt;br /&gt;
::d. Write code to PUT this to Peerlogic, and receive a response&lt;br /&gt;
::e. Parse through this response to obtain the output values of the Hamer Algorithm, as calculated by Peerlogic.&lt;br /&gt;
::f. This output would be compared against actual data that we calculated based on the Research Paper for the Hamer Algorithm&lt;br /&gt;
'''''The code for the last step is shown below'''''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Reputation of Reviewer  1&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  2&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  3&lt;br /&gt;
1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Conclusions ===&lt;br /&gt;
The results that are '''''actually''''' received from Peerlogic are presented below:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:json-ss.jpeg|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see, they do NOT match with expected results. &lt;br /&gt;
'''Therefore, our first conclusion is that the PeerLogic Webservice is implemented incorrectly.'''&lt;br /&gt;
This has been documented in the Conclusion section as the first point. &lt;br /&gt;
== Changes to Project Scope ==&lt;br /&gt;
&lt;br /&gt;
=== Second Phase ===&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port) do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
    &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Scenarios ==&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
We present these scenarios as possible test cases for an accurately working Peerlogic webservice.&lt;br /&gt;
These have not been implemented as there is no point in testing a system further when positive flows do not work.&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2355/checks here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143723</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143723"/>
		<updated>2022-03-28T01:08:48Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for student reviews to be accurate. The hamer algorithm was create for such purposes and returns a reputation weight associated with each reviewer. The instructor can then use the reputation weight value to either assert the reliability of a reviewer or use these values to compute a grade for a reviewr.&lt;br /&gt;
&lt;br /&gt;
=== System Design ===&lt;br /&gt;
&lt;br /&gt;
The hamer algorithm takes in a set of grades for assignments by reviewer and also any reputation weights (optional) associated with each reviewer to compute a reputation weight value for each reviewer. These reputation weight values indicate the accuracy and reliability of each reviewer. For example, a reviewer with a reputation weight of 3.0 is more accurate and reliable in their reviews compared to a 0.5 reputation weight of another reviewer. The following is an example from the paper [1] that describes the hamer algorithm:&lt;br /&gt;
[[File:Hamer Algorithm Inputs Outputs.png]]&lt;br /&gt;
&lt;br /&gt;
This algorithm is currently deployed to the following web server: http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms. To use the algorithm, a post request is sent to the peerlogic URL with a json body consisting of each assignment and the grades, and the reviewer who gave each grade. Once the request is sent, a json response is sent back with the corresponding hamer reputation weight values. The following is an example of a post request to the peerlogic URL to get back hamer reputation values:&lt;br /&gt;
[[File:Reputation web server hamer.png|thumb|]]&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
* Calculate reputation scores based on paper &amp;quot;Pluggable reputation systems for peer review: A web-service approach&amp;quot;&lt;br /&gt;
* Assert the accuracy of the reputation web server's hamer values through the URL http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms.&lt;br /&gt;
* Create a mock web server to return the correct hamer values if the reputation web server's hamer algorithm returns incorrect values.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
*reputation_web_server_hamer.rb&lt;br /&gt;
*reputation_mock_web_server_hamer.rb&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
=== Hamer Algorithm ===&lt;br /&gt;
[[File:Step1.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step2.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step3.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step4.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
We implemented the steps of this algorithm for our analytical validation, found in the section below.&lt;br /&gt;
== Test Plan - Initial Phase ==&lt;br /&gt;
In the initial phase, we were tasked with testing the reputation_web_service_controller. The work done by a previous project team was impacted by the web-service (peerlogic) not being available at that time.&lt;br /&gt;
This time, we were able to access the Peerlogic server at a late stage - therefore, our plan at this moment involved performing a series of unit tests to determine that the web-service was communicating &lt;br /&gt;
correctly with Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Plan ===&lt;br /&gt;
1. Since our focus in this phase was to conduct exploratory testing of the system, we wrote some conventional tests to examine Peerlogic functionality. At this stage, we realized that Peerlogic &lt;br /&gt;
would only accept and respond with JSON data.&lt;br /&gt;
&lt;br /&gt;
2. Therefore, a natural next step was to prepare a series of input data that simulated a general input scenario for the system, comprising of:&lt;br /&gt;
::a. Each reviewer has assigned scores to 3 reviewees (fellow students)&lt;br /&gt;
::b. There are a total of 3 reviewers, who have all graded each other in some fashion for 5 assignments&lt;br /&gt;
::c. Convert this scenario to JSON&lt;br /&gt;
::d. Write code to PUT this to Peerlogic, and receive a response&lt;br /&gt;
::e. Parse through this response to obtain the output values of the Hamer Algorithm, as calculated by Peerlogic.&lt;br /&gt;
::f. This output would be compared against actual data that we calculated based on the Research Paper for the Hamer Algorithm&lt;br /&gt;
'''''The code for the last step is shown below'''''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Reputation of Reviewer  1&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  2&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  3&lt;br /&gt;
1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Conclusions ===&lt;br /&gt;
The results that are '''''actually''''' received from Peerlogic are presented below:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:json-ss.jpeg|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see, they do NOT match with expected results. &lt;br /&gt;
'''Therefore, our first conclusion is that the PeerLogic Webservice is implemented incorrectly.'''&lt;br /&gt;
This has been documented in the Conclusion section as the first point. &lt;br /&gt;
== Changes to Project Scope ==&lt;br /&gt;
&lt;br /&gt;
=== Second Phase ===&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port) do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
    &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Scenarios ==&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
We present these scenarios as possible test cases for an accurately working Peerlogic webservice.&lt;br /&gt;
These have not been implemented as there is no point in testing a system further when positive flows do not work.&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2355/checks here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Hamer_Algorithm_Inputs_Outputs.png&amp;diff=143721</id>
		<title>File:Hamer Algorithm Inputs Outputs.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Hamer_Algorithm_Inputs_Outputs.png&amp;diff=143721"/>
		<updated>2022-03-28T01:07:06Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143720</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143720"/>
		<updated>2022-03-28T01:05:58Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for student reviews to be accurate. The hamer algorithm was create for such purposes and returns a reputation weight associated with each reviewer. The instructor can then use the reputation weight value to either assert the reliability of a reviewer or use these values to compute a grade for a reviewr.&lt;br /&gt;
&lt;br /&gt;
=== System Design ===&lt;br /&gt;
&lt;br /&gt;
The hamer algorithm takes in a set of grades for assignments by reviewer and also any reputation weights (optional) associated with each reviewer to compute a reputation weight value for each reviewer. These reputation weight values indicate the accuracy and reliability of each reviewer. For example, a reviewer with a reputation weight of 3.0 is more accurate and reliable in their reviews compared to a 0.5 reputation weight of another reviewer. The following is an example from the paper [1] that describes the hamer algorithm:&lt;br /&gt;
[[File:Hamer_Algorithm_Inputs_Outputs.png]]&lt;br /&gt;
&lt;br /&gt;
This algorithm is currently deployed to the following web server: http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms. To use the algorithm, a post request is sent to the peerlogic URL with a json body consisting of each assignment and the grades, and the reviewer who gave each grade. Once the request is sent, a json response is sent back with the corresponding hamer reputation weight values. The following is an example of a post request to the peerlogic URL to get back hamer reputation values:&lt;br /&gt;
[[File:Reputation web server hamer.png|thumb|]]&lt;br /&gt;
&lt;br /&gt;
=== Objectives ===&lt;br /&gt;
&lt;br /&gt;
* Calculate reputation scores based on paper &amp;quot;Pluggable reputation systems for peer review: A web-service approach&amp;quot;&lt;br /&gt;
* Assert the accuracy of the reputation web server's hamer values through the URL http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms.&lt;br /&gt;
* Create a mock web server to return the correct hamer values if the reputation web server's hamer algorithm returns incorrect values.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
*reputation_web_server_hamer.rb&lt;br /&gt;
*reputation_mock_web_server_hamer.rb&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
=== Hamer Algorithm ===&lt;br /&gt;
[[File:Step1.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step2.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step3.PNG|400px]]&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Step4.PNG|400px]]&lt;br /&gt;
&lt;br /&gt;
We implemented the steps of this algorithm for our analytical validation, found in the section below.&lt;br /&gt;
== Test Plan - Initial Phase ==&lt;br /&gt;
In the initial phase, we were tasked with testing the reputation_web_service_controller. The work done by a previous project team was impacted by the web-service (peerlogic) not being available at that time.&lt;br /&gt;
This time, we were able to access the Peerlogic server at a late stage - therefore, our plan at this moment involved performing a series of unit tests to determine that the web-service was communicating &lt;br /&gt;
correctly with Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Plan ===&lt;br /&gt;
1. Since our focus in this phase was to conduct exploratory testing of the system, we wrote some conventional tests to examine Peerlogic functionality. At this stage, we realized that Peerlogic &lt;br /&gt;
would only accept and respond with JSON data.&lt;br /&gt;
&lt;br /&gt;
2. Therefore, a natural next step was to prepare a series of input data that simulated a general input scenario for the system, comprising of:&lt;br /&gt;
::a. Each reviewer has assigned scores to 3 reviewees (fellow students)&lt;br /&gt;
::b. There are a total of 3 reviewers, who have all graded each other in some fashion for 5 assignments&lt;br /&gt;
::c. Convert this scenario to JSON&lt;br /&gt;
::d. Write code to PUT this to Peerlogic, and receive a response&lt;br /&gt;
::e. Parse through this response to obtain the output values of the Hamer Algorithm, as calculated by Peerlogic.&lt;br /&gt;
::f. This output would be compared against actual data that we calculated based on the Research Paper for the Hamer Algorithm&lt;br /&gt;
'''''The code for the last step is shown below'''''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Reputation of Reviewer  1&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  2&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  3&lt;br /&gt;
1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Conclusions ===&lt;br /&gt;
The results that are '''''actually''''' received from Peerlogic are presented below:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:json-ss.jpeg|600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As you can see, they do NOT match with expected results. &lt;br /&gt;
'''Therefore, our first conclusion is that the PeerLogic Webservice is implemented incorrectly.'''&lt;br /&gt;
This has been documented in the Conclusion section as the first point. &lt;br /&gt;
== Changes to Project Scope ==&lt;br /&gt;
&lt;br /&gt;
=== Second Phase ===&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port) do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
    &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Scenarios ==&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
We present these scenarios as possible test cases for an accurately working Peerlogic webservice.&lt;br /&gt;
These have not been implemented as there is no point in testing a system further when positive flows do not work.&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2355/checks here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143680</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143680"/>
		<updated>2022-03-28T00:36:40Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for student reviews to be accurate. The hamer algorithm was create for such purposes and returns a reputation weight associated with each reviewer. The instructor can then use the reputation weight value to either assert the reliability of a reviewer or use these values to compute a grade for a reviewr.&lt;br /&gt;
&lt;br /&gt;
=== System Design ===&lt;br /&gt;
The hamer algorithm takes in a set of grades for assignments by reviewer and also any reputation weights (optional) associated with each reviewer to compute a reputation weight value for each reviewer. These reputation weight values indicate the accuracy and reliability of each reviewer. For example, a reviewer with a reputation weight of 3.0 is more accurate and reliable in their reviews compared to a 0.5 reputation weight of another reviewer. The following is an example from the paper [1] that describes the hamer algorithm:&lt;br /&gt;
[[File:Hamer_Algorithm_Inputs_Outputs.png]]&lt;br /&gt;
&lt;br /&gt;
This algorithm is currently deployed to the following web server: http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms. To use the algorithm, a post request is sent to the URL with&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
hamer.rb was the file that implemented one of the “reputation systems” that can be used to determine the reliability of peer reviewers. However, this file is no longer current, having been replaced by a web service in 2015. Therefore, we will be trying to describe and test this web service in the following sections.&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reputation System ==&lt;br /&gt;
Online peer-review systems are now in common use in higher education. They free the instructor and course staff from having to provide personally all the feedbackthat students receive on their work. However, if we want to assure that all students receive competent feedback, or even use peer-assigned grades, we need a way tojudge which peer reviewers are most credible. The solution is to use a reputation system. The reputation system is meant to provide objective value to student assigned peer review scores. Students select from a list of tasks to be performed and then preparetheir work and submit it to a peer-review system. The work is then reviewed by other students who offer comments/graded feedback to help the submitters improvetheir work. During the peer review period it is important to determine which reviews are more accurate and show higher quality. Reputation is one way to achieve thisgoal; it is a quantization measurement to judge which peer reviewers are more reliable. Peer reviewers can use expertiza to score an author. If Expertiza shows aconfidence ratings for grades based upon the reviewers reputation then authors can more easily determine the legitimacy of the peer assigned score. In addition, theteaching staff can examine the quality of each peer review based on reputation values and, potentially, crowd-source a significant portion of the grading function.Currently the reputation system is implemented in Expertiza through web-service.&lt;br /&gt;
The service does not work all the time although expertiza employees can sometimes run the system, we could not reach the service and values even though we tried it on our own local computer and vcl as well. Nevertheless, we have implement some test scenerios based on the algorithms used in the web service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
=== Initial Phase ===&lt;br /&gt;
In the initial phase, we were tasked with testing the reputation_web_service_controller. The work done by a previous project team was impacted by the web-service (peerlogic) not being available at that time.&lt;br /&gt;
This time, we were able to access the Peerlogic server at a late stage - therefore, our plan at this moment involved performing a series of unit tests to determine that the web-service was communicating &lt;br /&gt;
correctly with Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Outcomes ===&lt;br /&gt;
1. Since our focus in this phase was to conduct exploratory testing of the system, we wrote some conventional tests to examine Peerlogic functionality. At this stage, we realized that Peerlogic &lt;br /&gt;
would only accept and respond with JSON data.&lt;br /&gt;
&lt;br /&gt;
2. Therefore, a natural next step was to prepare a series of input data that simulated a general input scenario for the system, comprising of:&lt;br /&gt;
::a. Each reviewer has assigned scores to 4 reviewees (fellow students)&lt;br /&gt;
::b. There are a total of 4 reviewers, who have all graded each other in some fashion&lt;br /&gt;
::c. Convert this scenario to JSON&lt;br /&gt;
::d. Write code to PUT this to Peerlogic, and recieve a response&lt;br /&gt;
::e. Parse through this response to obtain the output values of the Hamer Algorithm, as calculated by Peerlogic&lt;br /&gt;
&lt;br /&gt;
'''''The code for this section is shown below'''''&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Reputation of Reviewer  1&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  2&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  3&lt;br /&gt;
1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Second Phase ===&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port) do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
    &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
== Simulation Code Segment to Test Web Service ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Reputation of Reviewer  1&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  2&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  3&lt;br /&gt;
1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Scenarios ==&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2355/checks here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143667</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143667"/>
		<updated>2022-03-28T00:26:13Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for student reviews to be accurate. The hamer algorithm was create for such purposes and returns a reputation weight associated with each reviewer. The instructor can then use the reputation weight value to either assert the reliability of a reviewer or use these values to compute a grade for a reviewr.&lt;br /&gt;
&lt;br /&gt;
=== System Design ===&lt;br /&gt;
The hamer algorithm [[File:Hamer_Algorithm_Inputs_Outputs.png]]takes in a set of grades for assignments by reviewer and also any reputation weights (optional) associated with each reviewer to compute a reputation weight value for each reviewer. These reputation weight values indicate the accuracy and reliability of each reviewer. For example, a reviewer with a reputation weight of 3.0 is more accurate and reliable in their reviews compared to a 0.5 reputation weight of another reviewer.&lt;br /&gt;
&lt;br /&gt;
==About Expertiza==&lt;br /&gt;
Expertiza is a multi-purpose web application built using Ruby on Rails for Students and Instructors. Instructors enrolled in Expertiza can create and customize classes, teams, assignments, quizzes, and many more. On the other hand, Students are also allowed to form teams, attempt quizzes, and complete assignments. Apart from that, Expertiza also allows students to provide peer reviews enabling them to work together to improve others' learning experiences. It is an open-source application and its Github repository is [https://github.com/expertiza/expertiza Expertiza].&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
hamer.rb was the file that implemented one of the “reputation systems” that can be used to determine the reliability of peer reviewers. However, this file is no longer current, having been replaced by a web service in 2015. Therefore, we will be trying to describe and test this web service in the following sections.&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reputation System ==&lt;br /&gt;
Online peer-review systems are now in common use in higher education. They free the instructor and course staff from having to provide personally all the feedbackthat students receive on their work. However, if we want to assure that all students receive competent feedback, or even use peer-assigned grades, we need a way tojudge which peer reviewers are most credible. The solution is to use a reputation system. The reputation system is meant to provide objective value to student assigned peer review scores. Students select from a list of tasks to be performed and then preparetheir work and submit it to a peer-review system. The work is then reviewed by other students who offer comments/graded feedback to help the submitters improvetheir work. During the peer review period it is important to determine which reviews are more accurate and show higher quality. Reputation is one way to achieve thisgoal; it is a quantization measurement to judge which peer reviewers are more reliable. Peer reviewers can use expertiza to score an author. If Expertiza shows aconfidence ratings for grades based upon the reviewers reputation then authors can more easily determine the legitimacy of the peer assigned score. In addition, theteaching staff can examine the quality of each peer review based on reputation values and, potentially, crowd-source a significant portion of the grading function.Currently the reputation system is implemented in Expertiza through web-service.&lt;br /&gt;
The service does not work all the time although expertiza employees can sometimes run the system, we could not reach the service and values even though we tried it on our own local computer and vcl as well. Nevertheless, we have implement some test scenerios based on the algorithms used in the web service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
=== Initial Phase ===&lt;br /&gt;
In the initial phase, we were tasked with testing the reputation_web_service_controller. The work done by a previous project team was impacted by the web-service (peerlogic) not being available at that time.&lt;br /&gt;
This time, we were able to access the Peerlogic server at a late stage - therefore, our plan at this moment involved performing a series of unit tests to determine that the web-service was communicating &lt;br /&gt;
correctly with Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Initial Testing Outcomes ===&lt;br /&gt;
1. Since our focus in this phase was to conduct exploratory testing of the system, we wrote some conventional tests to examine Peerlogic functionality. At this stage, we realized that Peerlogic &lt;br /&gt;
would only accept and respond with JSON data.&lt;br /&gt;
2. Therefore, a natural next step was to prepare a series of input data that simulated a general input scenario for the system, comprising of:&lt;br /&gt;
&amp;lt;br&amp;gt;a. Each reviewer has assigned scores to 4 reviewees (fellow students)&lt;br /&gt;
&amp;lt;br&amp;gt;b. There are a total of 4 reviewers, who have all graded each other in some fashion&lt;br /&gt;
&amp;lt;br&amp;gt;c. Convert this scenario to JSON&lt;br /&gt;
&amp;lt;br&amp;gt;d. Using an API testing software, PUT this to Peerlogic, and recieve a response&lt;br /&gt;
&amp;lt;br&amp;gt;e. Parse through this response to obtain the output values of the Hamer Algorithm, as calculated by Peerlogic&lt;br /&gt;
&lt;br /&gt;
=== Second Phase ===&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port) do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
    &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
== Simulation Code Segment to Test Web Service ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Reputation of Reviewer  1&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  2&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  3&lt;br /&gt;
1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Scenarios ==&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2355/checks here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143663</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143663"/>
		<updated>2022-03-28T00:20:38Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for student reviews to be accurate. The hamer algorithm takes in a set of grades for assignments by reviewer and also any reputation weights (optional) associated with each reviewer to compute a reputation weight value for each reviewer. These reputation weight values indicate the accuracy and reliability of each reviewer. For example, a reviewer with a reputation weight of 3.0 is more accurate and reliable in their reviews compared to a 0.5 reputation weight of another reviewer.&lt;br /&gt;
&lt;br /&gt;
==About Expertiza==&lt;br /&gt;
Expertiza is a multi-purpose web application built using Ruby on Rails for Students and Instructors. Instructors enrolled in Expertiza can create and customize classes, teams, assignments, quizzes, and many more. On the other hand, Students are also allowed to form teams, attempt quizzes, and complete assignments. Apart from that, Expertiza also allows students to provide peer reviews enabling them to work together to improve others' learning experiences. It is an open-source application and its Github repository is [https://github.com/expertiza/expertiza Expertiza].&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
hamer.rb was the file that implemented one of the “reputation systems” that can be used to determine the reliability of peer reviewers. However, this file is no longer current, having been replaced by a web service in 2015. Therefore, we will be trying to describe and test this web service in the following sections.&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reputation System ==&lt;br /&gt;
Online peer-review systems are now in common use in higher education. They free the instructor and course staff from having to provide personally all the feedbackthat students receive on their work. However, if we want to assure that all students receive competent feedback, or even use peer-assigned grades, we need a way tojudge which peer reviewers are most credible. The solution is to use a reputation system. The reputation system is meant to provide objective value to student assigned peer review scores. Students select from a list of tasks to be performed and then preparetheir work and submit it to a peer-review system. The work is then reviewed by other students who offer comments/graded feedback to help the submitters improvetheir work. During the peer review period it is important to determine which reviews are more accurate and show higher quality. Reputation is one way to achieve thisgoal; it is a quantization measurement to judge which peer reviewers are more reliable. Peer reviewers can use expertiza to score an author. If Expertiza shows aconfidence ratings for grades based upon the reviewers reputation then authors can more easily determine the legitimacy of the peer assigned score. In addition, theteaching staff can examine the quality of each peer review based on reputation values and, potentially, crowd-source a significant portion of the grading function.Currently the reputation system is implemented in Expertiza through web-service.&lt;br /&gt;
The service does not work all the time although expertiza employees can sometimes run the system, we could not reach the service and values even though we tried it on our own local computer and vcl as well. Nevertheless, we have implement some test scenerios based on the algorithms used in the web service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
= Initial Phase =&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port) do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        &lt;br /&gt;
    &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
        req = Net::HTTP::Post.new(uri)&lt;br /&gt;
        req.content_type = 'application/json'&lt;br /&gt;
        req.body = INPUTS&lt;br /&gt;
        &lt;br /&gt;
        response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl =&amp;gt; uri.scheme == 'https') do |http|&lt;br /&gt;
          http.request(req)&lt;br /&gt;
        end&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
== Simulation Code Segment to Test Web Service ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Reputation of Reviewer  1&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  2&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  3&lt;br /&gt;
1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Scenarios ==&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2355/checks here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143633</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143633"/>
		<updated>2022-03-27T23:00:38Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
Using student's reviews of a certain assignment as a more accurate grade has become more popular among professors and courses in universities. Not only does this method free the professor and TAs from days of work, but also allows for students to learn even more about an assignment through grading other's work. Unfortunately, many students may not take reviewing other's work seriously and may simply give 100 or 0 to other students. Since such reviews may skew a student's grade, a system to assert the correctness and credibility of a reviewer is necessary for this reviewing system to work.&lt;br /&gt;
&lt;br /&gt;
==About Expertiza==&lt;br /&gt;
Expertiza is a multi-purpose web application built using Ruby on Rails for Students and Instructors. Instructors enrolled in Expertiza can create and customize classes, teams, assignments, quizzes, and many more. On the other hand, Students are also allowed to form teams, attempt quizzes, and complete assignments. Apart from that, Expertiza also allows students to provide peer reviews enabling them to work together to improve others' learning experiences. It is an open-source application and its Github repository is [https://github.com/expertiza/expertiza Expertiza].&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
hamer.rb was the file that implemented one of the “reputation systems” that can be used to determine the reliability of peer reviewers. However, this file is no longer current, having been replaced by a web service in 2015. Therefore, we will be trying to describe and test this web service in the following sections.&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reputation System ==&lt;br /&gt;
Online peer-review systems are now in common use in higher education. They free the instructor and course staff from having to provide personally all the feedbackthat students receive on their work. However, if we want to assure that all students receive competent feedback, or even use peer-assigned grades, we need a way tojudge which peer reviewers are most credible. The solution is to use a reputation system. The reputation system is meant to provide objective value to student assigned peer review scores. Students select from a list of tasks to be performed and then preparetheir work and submit it to a peer-review system. The work is then reviewed by other students who offer comments/graded feedback to help the submitters improvetheir work. During the peer review period it is important to determine which reviews are more accurate and show higher quality. Reputation is one way to achieve thisgoal; it is a quantization measurement to judge which peer reviewers are more reliable. Peer reviewers can use expertiza to score an author. If Expertiza shows aconfidence ratings for grades based upon the reviewers reputation then authors can more easily determine the legitimacy of the peer assigned score. In addition, theteaching staff can examine the quality of each peer review based on reputation values and, potentially, crowd-source a significant portion of the grading function.Currently the reputation system is implemented in Expertiza through web-service.&lt;br /&gt;
The service does not work all the time although expertiza employees can sometimes run the system, we could not reach the service and values even though we tried it on our own local computer and vcl as well. Nevertheless, we have implement some test scenerios based on the algorithms used in the web service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
    &lt;br /&gt;
        response = Net::HTTP.post(uri, INPUTS, 'Content-Type' =&amp;gt; 'application/json')&lt;br /&gt;
    &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
    &lt;br /&gt;
        response = Net::HTTP.post(uri, INPUTS, 'Content-Type' =&amp;gt; 'application/json')&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
== Simulation Code Segment to Test Web Service ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Reputation of Reviewer  1&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  2&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  3&lt;br /&gt;
1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Scenarios ==&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2355/checks here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143631</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143631"/>
		<updated>2022-03-27T22:52:23Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&amp;lt;q&amp;gt;Online peer-review systems are now in common use in higher education. They free the instructor and course staff from having to provide personally all the feedback that students receive on their work. However, if we want to assure that all students receive competent feedback, or even use peer-assigned grades, we need a way to judge which peer reviewers are most credible. The solution is to use a reputation system.&amp;lt;/q&amp;gt; &amp;lt;br&amp;gt; The reputation system is meant to provide objective value to student assigned peer review scores. Students select from a list of tasks to be performed and then prepare their work and submit it to a peer-review system. The work is then reviewed by other students who offer comments/graded feedback to help the submitters improve their work.&lt;br /&gt;
During the peer review period it is important to determine which reviews are more accurate and show higher quality. Reputation is one way to achieve this goal; it is a quantization measurement to judge which peer reviewers are more reliable.&lt;br /&gt;
Peer reviewers can use expertiza to score an author. If Expertiza shows a confidence ratings for grades based upon the reviewers reputation then authors can more easily determine the legitimacy of the peer assigned score. In addition, the teaching staff can examine the quality of each peer review based on reputation values and, potentially, crowd-source a significant portion of the grading function.&lt;br /&gt;
Currently the reputation system is implemented in Expertiza through web-service, but there's no test written for it. Thus our goal is to set up assignments and reviews that would produce specific reputation scores, and test that the correct reputations are in fact being produced.&lt;br /&gt;
&lt;br /&gt;
==About Expertiza==&lt;br /&gt;
Expertiza is a multi-purpose web application built using Ruby on Rails for Students and Instructors. Instructors enrolled in Expertiza can create and customize classes, teams, assignments, quizzes, and many more. On the other hand, Students are also allowed to form teams, attempt quizzes, and complete assignments. Apart from that, Expertiza also allows students to provide peer reviews enabling them to work together to improve others' learning experiences. It is an open-source application and its Github repository is [https://github.com/expertiza/expertiza Expertiza].&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
hamer.rb was the file that implemented one of the “reputation systems” that can be used to determine the reliability of peer reviewers. However, this file is no longer current, having been replaced by a web service in 2015. Therefore, we will be trying to describe and test this web service in the following sections.&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reputation System ==&lt;br /&gt;
Online peer-review systems are now in common use in higher education. They free the instructor and course staff from having to provide personally all the feedbackthat students receive on their work. However, if we want to assure that all students receive competent feedback, or even use peer-assigned grades, we need a way tojudge which peer reviewers are most credible. The solution is to use a reputation system. The reputation system is meant to provide objective value to student assigned peer review scores. Students select from a list of tasks to be performed and then preparetheir work and submit it to a peer-review system. The work is then reviewed by other students who offer comments/graded feedback to help the submitters improvetheir work. During the peer review period it is important to determine which reviews are more accurate and show higher quality. Reputation is one way to achieve thisgoal; it is a quantization measurement to judge which peer reviewers are more reliable. Peer reviewers can use expertiza to score an author. If Expertiza shows aconfidence ratings for grades based upon the reviewers reputation then authors can more easily determine the legitimacy of the peer assigned score. In addition, theteaching staff can examine the quality of each peer review based on reputation values and, potentially, crowd-source a significant portion of the grading function.Currently the reputation system is implemented in Expertiza through web-service.&lt;br /&gt;
The service does not work all the time although expertiza employees can sometimes run the system, we could not reach the service and values even though we tried it on our own local computer and vcl as well. Nevertheless, we have implement some test scenerios based on the algorithms used in the web service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
    &lt;br /&gt;
        response = Net::HTTP.post(uri, INPUTS, 'Content-Type' =&amp;gt; 'application/json')&lt;br /&gt;
    &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
    &lt;br /&gt;
        response = Net::HTTP.post(uri, INPUTS, 'Content-Type' =&amp;gt; 'application/json')&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
== Simulation Code Segment to Test Web Service ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Reputation of Reviewer  1&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  2&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  3&lt;br /&gt;
1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Scenarios ==&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2355/checks here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143630</id>
		<title>CSC/ECE 517 Spring 2022 - E2212: Testing for hamer.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2022_-_E2212:_Testing_for_hamer.rb&amp;diff=143630"/>
		<updated>2022-03-27T22:51:24Z</updated>

		<summary type="html">&lt;p&gt;Jlin36: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the changes made for the Spring 2022 OSS Project E2212: Testing for hamer.rb&lt;br /&gt;
== Project Overview ==&lt;br /&gt;
&lt;br /&gt;
=== Introduction ===&lt;br /&gt;
&lt;br /&gt;
==About Expertiza==&lt;br /&gt;
Expertiza is a multi-purpose web application built using Ruby on Rails for Students and Instructors. Instructors enrolled in Expertiza can create and customize classes, teams, assignments, quizzes, and many more. On the other hand, Students are also allowed to form teams, attempt quizzes, and complete assignments. Apart from that, Expertiza also allows students to provide peer reviews enabling them to work together to improve others' learning experiences. It is an open-source application and its Github repository is [https://github.com/expertiza/expertiza Expertiza].&lt;br /&gt;
&lt;br /&gt;
== Description ==&lt;br /&gt;
hamer.rb was the file that implemented one of the “reputation systems” that can be used to determine the reliability of peer reviewers. However, this file is no longer current, having been replaced by a web service in 2015. Therefore, we will be trying to describe and test this web service in the following sections.&lt;br /&gt;
&lt;br /&gt;
=== Mentor ===&lt;br /&gt;
&lt;br /&gt;
Ed Gehringer, efg@ncsu.edu&lt;br /&gt;
&lt;br /&gt;
=== Team Members ===&lt;br /&gt;
&lt;br /&gt;
* Joshua Lin (jlin36@ncsu.edu)&lt;br /&gt;
* Muhammet Mustafa Olmez (molmez@ncsu.edu)&lt;br /&gt;
* Soumyadeep Chatterjee (schatte5@ncsu.edu)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Reputation System ==&lt;br /&gt;
Online peer-review systems are now in common use in higher education. They free the instructor and course staff from having to provide personally all the feedbackthat students receive on their work. However, if we want to assure that all students receive competent feedback, or even use peer-assigned grades, we need a way tojudge which peer reviewers are most credible. The solution is to use a reputation system. The reputation system is meant to provide objective value to student assigned peer review scores. Students select from a list of tasks to be performed and then preparetheir work and submit it to a peer-review system. The work is then reviewed by other students who offer comments/graded feedback to help the submitters improvetheir work. During the peer review period it is important to determine which reviews are more accurate and show higher quality. Reputation is one way to achieve thisgoal; it is a quantization measurement to judge which peer reviewers are more reliable. Peer reviewers can use expertiza to score an author. If Expertiza shows aconfidence ratings for grades based upon the reviewers reputation then authors can more easily determine the legitimacy of the peer assigned score. In addition, theteaching staff can examine the quality of each peer review based on reputation values and, potentially, crowd-source a significant portion of the grading function.Currently the reputation system is implemented in Expertiza through web-service.&lt;br /&gt;
The service does not work all the time although expertiza employees can sometimes run the system, we could not reach the service and values even though we tried it on our own local computer and vcl as well. Nevertheless, we have implement some test scenerios based on the algorithms used in the web service.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Algorithms ==&lt;br /&gt;
Reputation systems may take various factors into account:&lt;br /&gt;
• Does a reviewer assign scores that are similar to scores assigned by the instructor (on work that they both grade)?&lt;br /&gt;
• Does a reviewer assign scores that match those assigned by other reviewers?&lt;br /&gt;
• Does the reviewer assign different scores to different work?&lt;br /&gt;
• How competent has the reviewer been on other work done for the class? &lt;br /&gt;
&lt;br /&gt;
There are two algorithms used, the Hamer-peer algorithm has the lowest maximum absolute bias and the Lauw-peer algorithm has the lowest overall bias.This indicates, from theinstructor’s perspective, if there are further assignments of this kind, expert grading may not be necessary. It is observed in the article (https://ieeexplore.ieee.org/abstract/document/7344292) that the overall bias is a little bit higher, but the max. absolute bias is very high (more than 20). This indicates that for future similar courses, the instructor can trust most students’ peer grading, but should be aware that the students may give inflated grades. Therefore spot-checking is necessary. However, overall bias is quite low, as the students gave grades at least 16 points lower than expert grades. This may because either more training is needed, or the review rubric is inadequate. The results also suggest that for future courses of this kind, the instructor cannot trust the students' grades; expert grades are still necessary. &lt;br /&gt;
The main difference between the Hamer-peer and the Lauw-peer algorithm is that the Lauw-peer algorithm keeps track of the reviewer's leniency (“bias”), which can be either positive or negative. A positive leniency indicates the reviewer tends to give higher scores than average. Additionally, the range for Hamer’s algorithm is (0,∞) while for Lauw’s algorithm it is [0,1].&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
We followed the testing thought process recommended by Dr. Gehringer: &lt;br /&gt;
In testing this service, we used an external program to send requests to a simulated service, and inspected the returned data. &lt;br /&gt;
This decision was reached since our program of test was unfortunately not running, and could not be inspected in an ideal manner.&lt;br /&gt;
&lt;br /&gt;
The test below sends real JSON to both peerlogic and mock. http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms&lt;br /&gt;
&lt;br /&gt;
As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture.&lt;br /&gt;
This is what we are supposed to reach in this project.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Proof of working:&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Response_json_expected.jpeg]]&lt;br /&gt;
&lt;br /&gt;
Test Code Snippet:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
require &amp;quot;net/http&amp;quot;&lt;br /&gt;
require &amp;quot;json&amp;quot;&lt;br /&gt;
&lt;br /&gt;
INPUTS = {&lt;br /&gt;
    &amp;quot;submission9999&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 10,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 9,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9998&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 3,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 2,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9997&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    },&lt;br /&gt;
      &amp;quot;submission9996&amp;quot;: {&lt;br /&gt;
    &amp;quot;stu9999&amp;quot;: 6,&lt;br /&gt;
    &amp;quot;stu9998&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;stu9997&amp;quot;: 5,&lt;br /&gt;
    &amp;quot;stu9996&amp;quot;: 5&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
EXPECTED = {&lt;br /&gt;
    &amp;quot;Hamer&amp;quot;: {&lt;br /&gt;
    &amp;quot;9996&amp;quot;: 0.6,&lt;br /&gt;
    &amp;quot;9997&amp;quot;: 3.6,&lt;br /&gt;
    &amp;quot;9998&amp;quot;: 1.1,&lt;br /&gt;
    &amp;quot;9999&amp;quot;: 1.1&lt;br /&gt;
    }&lt;br /&gt;
}.to_json&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('http://peerlogic.csc.ncsu.edu/reputation/calculations/reputation_algorithms')&lt;br /&gt;
    &lt;br /&gt;
        response = Net::HTTP.post(uri, INPUTS, 'Content-Type' =&amp;gt; 'application/json')&lt;br /&gt;
    &lt;br /&gt;
        expect(JSON.parse(response.body)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
describe &amp;quot;Expertiza Web Service&amp;quot; do&lt;br /&gt;
    it &amp;quot;should return the correct Hamer calculation&amp;quot; do&lt;br /&gt;
        uri = URI('https://4dfaead4-a747-4be4-8683-3b10d1d2e0c0.mock.pstmn.io/reputation_web_service/default')&lt;br /&gt;
    &lt;br /&gt;
        response = Net::HTTP.post(uri, INPUTS, 'Content-Type' =&amp;gt; 'application/json')&lt;br /&gt;
        expect(JSON.parse(&amp;quot;#{response.body}}&amp;quot;)[&amp;quot;Hamer&amp;quot;]).to eq(JSON.parse(EXPECTED)[&amp;quot;Hamer&amp;quot;])&lt;br /&gt;
    end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition, this plan enables us to test the current functionality by treating this system as a black box, and is able to provide conclusions on &lt;br /&gt;
the accuracy of the implementation as a whole.&lt;br /&gt;
&lt;br /&gt;
Therefore, in the section below, we have provided code that showcases this plan in action. The values returned by the algorithm are to be inspected both by code and by hand.&lt;br /&gt;
&lt;br /&gt;
== Simulation Code Segment to Test Web Service ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
import math&lt;br /&gt;
&lt;br /&gt;
# Parameters: reviews list&lt;br /&gt;
# reviews list - a list of each reviewer's grades for each assignment&lt;br /&gt;
# Example:&lt;br /&gt;
# reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
# Corresponding reviewer and grade for each assignment table&lt;br /&gt;
# Essay          Reviewer1 Reviewer2 Reviewer3&lt;br /&gt;
# Assignment1    5         5          4&lt;br /&gt;
# Assignment2    4         3          3&lt;br /&gt;
# Assignment3    4         4          4&lt;br /&gt;
# Assignment4    3         4          3&lt;br /&gt;
# Assignment5    2         2          2&lt;br /&gt;
&lt;br /&gt;
# Reivewer's grades given to each assignment 2D array&lt;br /&gt;
# Each index of reviews is a reviewer. Each index in reviews[i] is a review grade&lt;br /&gt;
reviews = [[5,4,4,3,2],[5,3,4,4,2],[4,3,4,3,2]]&lt;br /&gt;
&lt;br /&gt;
# Number of reviewers&lt;br /&gt;
numReviewers = len(reviews)&lt;br /&gt;
# Number of assignments&lt;br /&gt;
numAssig = len(reviews[0])&lt;br /&gt;
# Initial empty grades for each assignment array&lt;br /&gt;
grades = []&lt;br /&gt;
# Initial empty delta R array&lt;br /&gt;
deltaR = []&lt;br /&gt;
# Weight prime&lt;br /&gt;
weightPrime = []&lt;br /&gt;
# Reviewer's reputation weight&lt;br /&gt;
weight= []&lt;br /&gt;
&lt;br /&gt;
# Calculating Average Weighted Grades per Reviewer&lt;br /&gt;
for numAssigIndex in range(numAssig):&lt;br /&gt;
    assignmentGradeAverage = 0&lt;br /&gt;
    for numReviewerIndex in range(numReviewers):&lt;br /&gt;
        assignmentGradeAverage += reviews[numReviewerIndex][numAssigIndex]&lt;br /&gt;
    grades.append(assignmentGradeAverage/numReviewers)&lt;br /&gt;
print(&amp;quot;Average Grades:&amp;quot;)&lt;br /&gt;
print(grades)&lt;br /&gt;
&lt;br /&gt;
# Calculating delta R&lt;br /&gt;
for numReviewerIndex in range(numReviewers):&lt;br /&gt;
    reviewerDeltaR = 0&lt;br /&gt;
    assignmentAverageGradeIndex = 0&lt;br /&gt;
    for reviewGrade in reviews[numReviewerIndex]:&lt;br /&gt;
        reviewerDeltaR += ((reviewGrade - grades[assignmentAverageGradeIndex]) ** 2)&lt;br /&gt;
        assignmentAverageGradeIndex += 1&lt;br /&gt;
    reviewerDeltaR /= numAssig&lt;br /&gt;
    deltaR.append(reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;deltaR:&amp;quot;)&lt;br /&gt;
print(deltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
averageDeltaR = 0&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    averageDeltaR += reviewerDeltaR&lt;br /&gt;
averageDeltaR /= numReviewers&lt;br /&gt;
print(&amp;quot;averageDeltaR:&amp;quot;)&lt;br /&gt;
print(averageDeltaR)&lt;br /&gt;
&lt;br /&gt;
# Calculating weight prime&lt;br /&gt;
for reviewerDeltaR in deltaR:&lt;br /&gt;
    weightPrime.append(averageDeltaR/reviewerDeltaR)&lt;br /&gt;
print(&amp;quot;weightPrime:&amp;quot;)&lt;br /&gt;
print(weightPrime)&lt;br /&gt;
    &lt;br /&gt;
# Calculating reputation weight&lt;br /&gt;
for reviewerWeightPrime in weightPrime:&lt;br /&gt;
    if reviewerWeightPrime &amp;lt;= 2:&lt;br /&gt;
        weight.append(reviewerWeightPrime)&lt;br /&gt;
    else:&lt;br /&gt;
        weight.append(2 + math.log(reviewerWeightPrime - 1))&lt;br /&gt;
print(&amp;quot;reputation per reviewer:&amp;quot;)&lt;br /&gt;
i = 1&lt;br /&gt;
for reviewerWeight in weight:&lt;br /&gt;
    print(&amp;quot;Reputation of Reviewer &amp;quot;, i)&lt;br /&gt;
    print(round(reviewerWeight,1))&lt;br /&gt;
    i += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Output&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Reputation of Reviewer  1&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  2&lt;br /&gt;
1.0&lt;br /&gt;
Reputation of Reviewer  3&lt;br /&gt;
1.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Scenarios ==&lt;br /&gt;
1) Reviewer gives all max scores &amp;lt;br&amp;gt;&lt;br /&gt;
2) Reviewer gives all min scores &amp;lt;br&amp;gt;&lt;br /&gt;
3) Reviewer completes no review &amp;lt;br&amp;gt;&lt;br /&gt;
alternative scenario - reviewer gives max scores even if no inputs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
We as a team figured out the algorithms and applications and write some test scenarious. However, we did not have chance to work on web service since it does not work due to module errors. What we had is undefined method strip on Reputation Web Service Controller. Although sometimes it works on expertiza team side, we were not able to see the web service working. We created some test scenarios and write a python code for simulate the algorithm.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
In the code segment written to simulate the hamer.rb algorithm as described in &amp;quot;A Method of Automatic Grade Calibration in Peer Assessment&amp;quot; by John Hamer Kenneth T.K. Ma Hugh H.F. Kwong (https://crpit.scem.westernsydney.edu.au/confpapers/CRPITV42Hamer.pdf), we take a list of reviewers and their grades for each assignment reviewed to compute the associated reputation weight. Since the algorithm described in the paper does not specify an original weight for first time reviewers, we coded it so the first time reviewers had an original weight of 1. In addition, this code does not have reviewer weights added in for reviewers who already have reputation weights but will be added in soon. Also, we followed the algorithm they mentioned in the paper to the dot, but even then the output values they wrote as the example did not match what we computed by hand and by code. In this situation, either we missed something completely or the algorithm has been changed. As we tested on the peerlogic and mock, current web-service is not correct, since the returned values do not match the expected values as can be seen in the picture. This can be what we are supposed to reach in this project.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==GitHub Links==&lt;br /&gt;
Link to Expertiza repository: [https://github.com/expertiza/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to the forked repository: [https://github.com/joshlin5/expertiza here]&lt;br /&gt;
&lt;br /&gt;
Link to pull request: [https://github.com/expertiza/expertiza/pull/2355/checks here]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
1. Expertiza on GitHub (https://github.com/expertiza/expertiza) &amp;lt;br&amp;gt;&lt;br /&gt;
2. The live Expertiza website (http://expertiza.ncsu.edu/) &amp;lt;br&amp;gt;&lt;br /&gt;
3. Pluggable reputation systems for peer review: A web-service approach (https://doi.org/10.1109/FIE.2015.7344292)&lt;/div&gt;</summary>
		<author><name>Jlin36</name></author>
	</entry>
</feed>