<?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=Cladkins</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=Cladkins"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Cladkins"/>
	<updated>2026-07-16T14:34:22Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1929_Visualizations_for_Instructors&amp;diff=124607</id>
		<title>E1929 Visualizations for Instructors</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1929_Visualizations_for_Instructors&amp;diff=124607"/>
		<updated>2019-04-27T00:37:28Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
This [http://wiki.expertiza.ncsu.edu/index.php/Expertiza_documentation Expertiza] project, completed in the Spring of 2019, aimed to improve the charts instructors could view to see the grade statistics for a given assignment. Two charts already existed, one showing the grade distribution for all teams, and another simply showing the class average grade. Our goal for this project was to add a third chart, using [https://developers.google.com/chart/ Google Charts], which would show grade statistics for the various [https://en.wikipedia.org/wiki/Rubric_(academic) rubric] grades within that assignment. The chart is interactive so the user (instructor) can toggle which rubric criteria, and which statistics, to display.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Along with displaying the rubric criteria for a single assignment, we aimed to add a feature which would allow the comparison of compatible rubric grades from two different assignments. Again, this functionality is interactive, allowing the instructor to choose which statistics will be populated in the chart. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
By viewing our new visualization of rubric grades, an instructor can better judge which aspects of the course are well-understood, and which may need a bit more attention.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
'''E1929 - Visualizations for Instructors''' - Class performance on specific rubrics&lt;br /&gt;
&lt;br /&gt;
An interactive visualization or table that shows how a class performed on selected rubric criteria would be immensely helpful. It would show the instructor what he / she will need to focus more attention on. For example, could you create a graph showing the range and clustering of scores for the 5 main rubric criteria? And, if these same 5 criteria are used in the preliminary and final assignments, it would be nice to be able to compare performance between assignments in a visualization that showed the class results on 3 separate artifacts.&lt;br /&gt;
&lt;br /&gt;
Webpage: login as instructor -&amp;gt; Manage -&amp;gt; Assignments -&amp;gt; View scores&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Old Charts ===&lt;br /&gt;
[[File:Existing_Assignment_Grades_Wed.png|frame|centre|'''Figure 1: Existing assignment grade charts - '''The existing assignment grade charts show the average grade for the assignment and the grade distribution. During this project, we aimed to add a third chart which shows the distribution for specific rubric criteria within the assignment.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Accomplished ==&lt;br /&gt;
&lt;br /&gt;
=== Executed on Plans ===&lt;br /&gt;
We successfully executed all of the ideas we had during the planning phase:&lt;br /&gt;
* Add new feature to show mean and median data for rubric criteria in a given assignment&lt;br /&gt;
* Add new feature to show comparison&lt;br /&gt;
* Performed UI testing to ensure features were operational, including edge cases&lt;br /&gt;
* Added and ran RSpec and Capybara automated tests&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== New Charts Inserted ===&lt;br /&gt;
[[File:AnalyzeAssignmentWed.png|frame|centre|'''Figure 2: New Rubric Statistic Visualization - '''Added in the center of the existing two charts is an interactive chart the instructor can use to see the mean or median scores for whichever criteria they select. This is done on the &amp;quot;Analyze Assignment&amp;quot; tab, which is selected by default when the &amp;quot;View Scores&amp;quot; page is loaded.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CompareAssignmentsWed.png|frame|centre|'''Figure 3: New Rubric Cross-Assignment Comparison Visualization - '''The instructor can see a comparison between selected criteria between the current assignment and the selected assignment. The rubric criteria must be compatible in order for it to even show up in the selection list. This comparison visualization is done on the &amp;quot;Compare Assignments&amp;quot; tab which must be selected after the &amp;quot;View Scores&amp;quot; page has been loaded.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Extra Issues Fixed ===&lt;br /&gt;
&lt;br /&gt;
* Refactored [https://github.com/gshugh/expertiza/blob/OSS-HW4/app/views/grades/_team_charts.html.erb _team_charts.html.erb] partial view to use partials for each graphic. Previously both charts were defined together in _team_charts.html.erb, but now each graphic has its own partial view ([https://github.com/gshugh/expertiza/blob/OSS-HW4/app/views/grades/_team_charts_averages.html.erb _team_charts_averages.html.erb], [https://github.com/gshugh/expertiza/blob/OSS-HW4/app/views/grades/_team_charts_distribution.html.erb _team_charts_distribution.html.erb], [https://github.com/gshugh/expertiza/blob/OSS-HW4/app/views/grades/_team_charts_rubric_stats.html.erb _team_charts_rubric_stats.html.erb]). This allows more flexibility going forward, if it's decided one chart should move to a new place on the page, or to a new page.&lt;br /&gt;
* Updated [https://github.com/gshugh/expertiza/blob/OSS-HW4/app/views/grades/_team_charts.html.erb _team_charts.html.erb] so the &amp;quot;Hide stats&amp;quot; button on the View Scores page properly changes to &amp;quot;Show stats&amp;quot; when the statistic charts are hidden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Files Changed ===&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
We performed automated tests using RSpec Framework and Capybara. In addition, we performed manual tests of the user interface (UI), by using the app.&lt;br /&gt;
&lt;br /&gt;
=== RSpec Framework Tests ===&lt;br /&gt;
The RSpec Testing Framework, automated testing, was used to verify the models of the Expertiza web application feature set. Since this feature is dealing with visualizations (charts) that are intimately tied with Active Record models, we seeded the testing database with known data via FactoryBot gem. These changes were automatically rolled-back once the testing was complete.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to increase/maintain automated test coverage for the methods that we added into assignment and questionnaire models. Mocks and stubs were utilized in order to decouple the model under test from dependencies of other models. This will allow us to identify easily if our model updates are causing an issue.&lt;br /&gt;
&lt;br /&gt;
=== Capybara Tests ===&lt;br /&gt;
RSpec Capybara was used to provide integration testing of the charts. The Test Database was seeded with the appropriate information for executing the results of the charts. An additional GEM was needed, webdrivers, to utilize the predefined drivers of Selenium. The default web driver, Rack-Test, does not execute java scripts. Since the graphs that we are using require java script, thus soliciting the necessity of Selenium with its predefined web driver, selenium_chrome_headless. This provides the required functionality to process the java scripts and to automatically ensure that they exist in the DOM. &lt;br /&gt;
&lt;br /&gt;
In order to use the headless web driver with the seeded Test Database, a different database strategy was required. As a result, for this test only, the database strategy was changed to truncation. Ruby 2.2.7 is used in the current version of Expertiza. This version does not allow for sharing of the database thread, and thus requires the to be written to the database outside of a transaction block. This allows for the headless web driver to see that the data is persisted the Test Database and is able to run as normal. Once the test is completed, the database tables are truncated and all data is removed.&lt;br /&gt;
&lt;br /&gt;
=== UI Tests ===&lt;br /&gt;
In addition to the automated tests above we also performed manual testing of the newly added features to include:&lt;br /&gt;
&lt;br /&gt;
* Chart is displaying correctly&lt;br /&gt;
*# Bars are showing up where expected&lt;br /&gt;
*# Bar annotations are showing the expected value&lt;br /&gt;
*# Criteria labels are for the correct bar and displaying correct values&lt;br /&gt;
*# Hover text is displaying the correct values&lt;br /&gt;
*# Null values are not present on the chart&lt;br /&gt;
*# Correct colors are used for the multi-round view&lt;br /&gt;
* Show Labels checkbox works as expected&lt;br /&gt;
* Round Criteria is displaying correctly&lt;br /&gt;
*# Round dropdown menu shows all rounds for the assignment&lt;br /&gt;
*# Selecting a round changes the criteria checkboxes&lt;br /&gt;
*# All checkboxes are displayed with appropriate text&lt;br /&gt;
*# Checkboxes correctly remove or add criterion bars to the chart&lt;br /&gt;
&lt;br /&gt;
=== Testing Issues ===&lt;br /&gt;
Using the Ubuntu image, one issue was discovered was with the ScoreView view. The migration files is building the view out as a table instead of a view as required, this can be seen in the schema file. The Development database shows the ScoreView as a view, but the Test database shows it as an table. It appears that the Development database was altered outside of migrations to force the ScoreView to be a view instead of table. With this scenario, the automated integration testing was forced to seed the ScoreView as a table. Further gems are available to alleviate this issue.&lt;br /&gt;
&lt;br /&gt;
== Shortcomings ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Decisions ==&lt;br /&gt;
1. Put our new chart on the View Scores page, rather than on a new page&lt;br /&gt;
* Since it was able to fit on the existing page while displaying all the necessary info, we figured it'd be beneficial to have all grade statistics charts together.&lt;br /&gt;
2. Use GoogleCharts for our new charts&lt;br /&gt;
* The group who previously attempted this project chose GoogleCharts because it has a high compatibility and its charts look of similar quality to those already existing in Expertiza. We agreed with this, and determined GoogleCharts had all of the features we would need.&lt;br /&gt;
3. Added the AssignmentStats, CriterionStats, and ReviewRoundStats models&lt;br /&gt;
* This was a logical, structured way to organize the various data and methods we needed.&lt;br /&gt;
4. Encapsulation of the data within the new models&lt;br /&gt;
* Since the various statistics we needed to form our chart were stored in multiple models, there would be no good place to put the new methods we'd need. The way we did it promotes cohesion, since the new classes have the sole focus of computing statistics. This also allows for future refactoring of other sporadic statistics methods.&lt;br /&gt;
5. Placed AssignmentStats methods in assignment_stats_helper.rb rather than in the model or controller.&lt;br /&gt;
* The methods of interest were really not business logic, but more like massaging of data. For that reason it belonged more in the controller than the model. However, to keep things neat and clean in the controller, the methods were moved out to the helper file.&lt;br /&gt;
6. The exposure of mean and median as the metric_names in grades_controller.rb&lt;br /&gt;
* Since we are explicitly calling the avg_data and med_data methods in the controller, we thought it made sense to name the metric_names nearby, within the controller, rather than hidden off in the helper file.&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1440 Pull Request]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/gshugh/expertiza/tree/OSS-HW4 GitHub Repo]&lt;br /&gt;
&lt;br /&gt;
[https://docs.google.com/document/d/1Ozw2Bj2u_LyeKUdDqAyQtz1stEIKrxkmRnwmNyUgmzw/edit#heading=h.5kwrelqdnewh Problem Statement]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
* Akshay Ravichandran '''(Mentor)'''&lt;br /&gt;
* Chris Adkins&lt;br /&gt;
* Bobby DeMarco&lt;br /&gt;
* George Hugh&lt;br /&gt;
* John Warren&lt;br /&gt;
&lt;br /&gt;
== old Introduction ==&lt;br /&gt;
It is the desire of all instructors to emphasize course material that students have trouble understanding and de-emphasize those aspects of the course material which students readily grasp. One method used by instructors is the creation of questionnaires, or rubrics. A rubric consists of a number of questions, or criterion, that give instructors a glimpse into student understanding of course materials. Use of rubrics and their association with a course assignment allow instructors to fine-tune their lesson plans to their students' understanding.&lt;br /&gt;
&lt;br /&gt;
Creation of assignments, and their associated rubrics, can be a daunting task that can be made easier through the use of online platforms. Expertiza is one such online assignment grading platform. Within Expertiza, instructors create courses and assignments. For each assignment, instructors create one or more peer review rubrics for students to complete. After each round of rubrics, students can submit changes to their assignment based on these rubrics, with each submission and rubric considered a round. Hence, assignments have multiple rounds with each round associated with a rubric.&lt;br /&gt;
&lt;br /&gt;
Instructors use the association between the assignment and the submitted rubric(s) associated with the assignment to understand what subjects need more focus. For example, a low average score on a rubric's particular question, or criterion, can indicate that the class has issues with a particular part of the assignment. Currently, instructors using Expertiza display assignment scores on one pages, but need to visit a completely separate page to display rubric scores. This separation of information hinders the instructor's ability to fully comprehend the associations between the assignment scores and the rubric scores. This, in turn, minimizes the likelihood that instructors will integrate this information to fine-tune their course material.&lt;br /&gt;
&lt;br /&gt;
This project proposes to overcome this weakness in Expertiza by integrating the display of assignment scores and rubric scores onto a single page. This integration will allow instructors to more easily associate low rubric average scores with assignment scores. The ability to visualize assignment scores and rubric scores in a single location will reduce the workload on instructors when the scores. This, in turn, will increase the likelihood that instructors will change their lesson plans to reflect the students' understanding of the course material.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== old Proposed Changes ==&lt;br /&gt;
To help instructors understand the relationship between assignment scores and rubric scores, this project proposes two types of visualizations. The first type of visualization allows instructors to examine the rubric statistics for a single assignment. The second type of visualization allows instructors to compare the rubric statistics between two different assignments when the criteria for each assignment is the same.&lt;br /&gt;
&lt;br /&gt;
=== Existing Views ===&lt;br /&gt;
&lt;br /&gt;
In both cases, the project will add rubric statistics to the assignment grade view. The current assignment grade view consists of a header containing grade statistics followed by a table of the individual grades. In the assignment grade view header, the left side fo the header shows the average assignment grade as a circle, while the right side of the assignment grade view header shows the assignment grade distribution. Figure 1 shows the current header in the grade assignment view page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Existing_Assignment_Grades.JPG|frame|centre|'''Figure 1: Existing assignment grade page header - '''The existing assignment grade page header has both the average grade for the assignment and the grade distribution for the assignment. The left side shows the average as the percentage of a circle. The right side of the header shows the grade distribution for the assignment. The grade distribution shows the minimum and maximum grade for the assignment. Under the header is a list of the grades for each student.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The changes proposed by this project integrate rubric statistics to the above assignment grade view. Rubric statistic integration into the assignment grade view allow two types of visualizations. The first visualization allows the instructor to display rubric statistics within a single assignment. The second visualization allows the instructor to display rubric statistics between different assignments in the same course.&lt;br /&gt;
&lt;br /&gt;
=== Proposed Assignment Grade Visualization ===&lt;br /&gt;
&lt;br /&gt;
This project proposes the integration of rubric statistic visualization for both single assignments and multiple assignments into the assignment grade view. The integration occurs with a single change to the header of the assignment grade view, and retains the list of student grades. The following HTML mock-up shows the proposed changes to the header. The list of student grades is not changed and therefore not shown.&lt;br /&gt;
&lt;br /&gt;
==== Interactive Example ====&lt;br /&gt;
&lt;br /&gt;
   https://jwarren3.github.io/expertiza/tabs.html&lt;br /&gt;
&lt;br /&gt;
The upper part of the rubric statistic visualization displays a set of tabs that allow the instructor to analyze the rubric within a single assignment or to compare the rubric statistics between multiple assignments. The middle part of the rubric statistic visualization displays the statistics for each selected criteria as a bar graph. The heights of the bars are shown as a percentage of the maximum value for each criteria. The bottom part of the rubric statistic visualization displays a set of options that allow the instructor to filter the statistics shown in the bar graph. The left side (assignment average) and right side (assignment distribution) of the assignment grade view header are not changed.&lt;br /&gt;
&lt;br /&gt;
In the integration of the rubric statistic visualization mock-up within a single assignment, there are two rounds of rubrics for the students to fill out. The rubric in round 1 consisted of five criteria, while the rubric in round 2 consisted of 4 criteria. The round of interest is selected using the drop-down menu on the left side. The criteria shown in the bar graph are selected using radio buttons next to each criterion. Finally, the type of statistic shown is selected using a drop-down menu on the right side of the options. Currently, the statistic is limited to either mean or median. Hovering the mouse over each of the bars in the bar graph shows the numerical value of the chosen statistic.&lt;br /&gt;
&lt;br /&gt;
Visualizing the rubric statistics within a single assignment starts by selecting the left tab titled &amp;quot;Analyze Assignment&amp;quot;. The default displays the mean of all criteria from the first round. Changing the round, the type of statistic, and the particular criteria are controlled from the drop-down menus and radio buttons below the bar graph.&lt;br /&gt;
&lt;br /&gt;
Visualizing the rubric statistics between assignments starts by selecting the right tab titled &amp;quot;Compare Assignments&amp;quot;. The default displays the comparisons between round one and all criteria of an assignment in the same course. The default assignment is the chronologically earliest assignment. The current assignment is shown in red while the rubric being compared is shown in blue.&lt;br /&gt;
&lt;br /&gt;
==== New View Examples ====&lt;br /&gt;
&lt;br /&gt;
[[File:AnalyzeAssignmentNew.png|frame|centre|'''Figure 2: New Rubric Statistic Visualization - '''Added in the center of the existing two charts is an interactive chart the instructor can use to see the mean or median scores for whichever criteria they select. This is done on the &amp;quot;Analyze Assignment&amp;quot; tab, which is selected by default when the &amp;quot;View Scores&amp;quot; page is loaded.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CompareAssignmentsNew.png|frame|centre|'''Figure 3: New Rubric Cross-Assignment Comparison Visualization - '''The instructor can see a comparison between selected criteria between the current assignment and the selected assignment. The rubric criteria must be compatible in order for it to even show up in the selection list. This comparison visualization is done on the &amp;quot;Compare Assignments&amp;quot; tab which must be selected after the &amp;quot;View Scores&amp;quot; page has been loaded.]]&lt;br /&gt;
&lt;br /&gt;
== old Project Design ==&lt;br /&gt;
During the integration of rubric statistics and assignment grade statistics, this project expects to change controller files, view files and JavaScript files. For methods that are modified by this project, the team will also ensure that Code Climate (an automated code quality checker) issues are resolved. This project will also refactor changed methods to reflect common Ruby and Rails practices.&lt;br /&gt;
&lt;br /&gt;
=== Proposed Code Changes ===&lt;br /&gt;
The amount of methods and files to be changed during the integration of rubric statistics and assignment grade statistics is minimal. The team proposes changing a controller file, a view file, a JavaScript file, and an RSpec files. The team does not expect to change the database nor do we expect to change the model files. Other files will be changed as required to support the integration. A preliminary list of files to be changed is given below:&lt;br /&gt;
&lt;br /&gt;
    [https://github.com/gshugh/expertiza/blob/OSS-HW4/app/controllers/grades_controller.rb grades_controller.rb]&lt;br /&gt;
    [https://github.com/gshugh/expertiza/blob/OSS-HW4/app/assets/javascripts/grading.js grading.js]&lt;br /&gt;
    [https://github.com/gshugh/expertiza/blob/OSS-HW4/app/views/grades/_participant_charts.html.erb _participant_charts.html.erb]&lt;br /&gt;
    [https://github.com/gshugh/expertiza/blob/OSS-HW4/spec/controllers/grades_controller_spec.rb grades_controllers_spec.rb]&lt;br /&gt;
&lt;br /&gt;
=== Design Flow ===&lt;br /&gt;
[[File:DesignFlowSingle.png|frame|center|'''Figure 4: Rubric Statistic Design Flow - '''Instructor wants to view student scores on individual rubric criteria.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:DesignFlowCompare.png|frame|center|'''Figure 5: Cross-Assignment Comparison Design Flow - '''Instructor wants to compare student scores on individual rubric criteria between two compatible rounds of two different assignments.]]&lt;br /&gt;
&lt;br /&gt;
=== Tools and Design Choices ===&lt;br /&gt;
This project proposes using a third party JavaScript library for rendering the rubric statistics. This project proposes two requirements for the visualization library. The first requirement is to use a visualization library that performs client-side rendering. Using a client-side rendering library will minimize the number of server interactions as the instructor changes which rubric statistics to display. This minimization of server interaction will maximize the response time of Expertiza.&lt;br /&gt;
&lt;br /&gt;
The second requirement for the visualization library is compatibility with current Expertiza graphics. The compatibility requirement implies that the visualization library is one that is already being used in Expertiza or a visualization library that could be used to render the current graphics.&lt;br /&gt;
&lt;br /&gt;
Examples of client-side visualization libraries are given below:&lt;br /&gt;
&lt;br /&gt;
    [http://www.highcharts.com/ Highcharts]&lt;br /&gt;
    [http://g.raphaeljs.com/ RaphaelJS]&lt;br /&gt;
    [http://dygraphs.com/ dygraphs]&lt;br /&gt;
    [http://vis.stanford.edu/protovis/ Protovis]&lt;br /&gt;
    [http://grafico.kilianvalkhof.com/ Grafico]&lt;br /&gt;
    [https://chartkick.com/ ChartKick]&lt;br /&gt;
    [http://www.vancharts.com/ VanCharts]&lt;br /&gt;
    [https://developers.google.com/chart/ GoogleCharts]&lt;br /&gt;
&lt;br /&gt;
== old Test Plan ==&lt;br /&gt;
The team plans to perform automated tests using frameworks RSpec and Capybara. In addition, we will perform manual tests of the user interface (UI), by using the app.&lt;br /&gt;
&lt;br /&gt;
=== RSpec Framework Tests ===&lt;br /&gt;
The RSpec Testing Framework, automated testing, will be used to verify the Models of the Expertiza Rails Web application feature set. Since this feature is dealing with Visualizations (charts) that is intimately tied with an Active Record Models, we will seed the Testing Database with known data via RSpec. These changes will be automatically rolled-back once the testing is complete.  &lt;br /&gt;
&lt;br /&gt;
=== Capybara Tests ===&lt;br /&gt;
Another automated testing framework that will be used is Capybara. Capybara is an browser type test to simulate a user clicking through your site. We will use this testing framework to verify that our charting object is present on the page and contains the seeded data that we had loaded.&lt;br /&gt;
&lt;br /&gt;
=== UI Tests ===&lt;br /&gt;
In addition to the automated tests above we will also perform manual testing of the newly added features to include:&lt;br /&gt;
&lt;br /&gt;
* Chart is displaying correctly&lt;br /&gt;
*# Bars are showing up where expected&lt;br /&gt;
*# Bar annotations are showing the expected value&lt;br /&gt;
*# Criteria labels are for the correct bar and displaying correct values&lt;br /&gt;
*# Hover text is displaying the correct values&lt;br /&gt;
*# Null values are not present on the chart&lt;br /&gt;
*# Correct colors are used for the multi-round view&lt;br /&gt;
* Show Labels checkbox works as expected&lt;br /&gt;
* Round Criteria is displaying correctly&lt;br /&gt;
*# Round dropdown menu shows all rounds for the assignment&lt;br /&gt;
*# Selecting a round changes the criteria checkboxes&lt;br /&gt;
*# All checkboxes are displayed with appropriate text&lt;br /&gt;
*# Checkboxes correctly remove or add criterion bars to the chart&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1929_Visualizations_for_Instructors&amp;diff=124604</id>
		<title>E1929 Visualizations for Instructors</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1929_Visualizations_for_Instructors&amp;diff=124604"/>
		<updated>2019-04-27T00:27:30Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
This [http://wiki.expertiza.ncsu.edu/index.php/Expertiza_documentation Expertiza] project, completed in the Spring of 2019, aimed to improve the charts instructors could view to see the grade statistics for a given assignment. Two charts already existed, one showing the grade distribution for all teams, and another simply showing the class average grade. Our goal for this project was to add a third chart, using [https://developers.google.com/chart/ Google Charts], which would show grade statistics for the various [https://en.wikipedia.org/wiki/Rubric_(academic) rubric] grades within that assignment. The chart is interactive so the user (instructor) can toggle which rubric criteria, and which statistics, to display.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Along with displaying the rubric criteria for a single assignment, we aimed to add a feature which would allow the comparison of compatible rubric grades from two different assignments. Again, this functionality is interactive, allowing the instructor to choose which statistics will be populated in the chart. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
By viewing our new visualization of rubric grades, an instructor can better judge which aspects of the course are well-understood, and which may need a bit more attention.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Problem Statement ==&lt;br /&gt;
'''E1929 - Visualizations for Instructors''' - Class performance on specific rubrics&lt;br /&gt;
&lt;br /&gt;
An interactive visualization or table that shows how a class performed on selected rubric criteria would be immensely helpful. It would show the instructor what he / she will need to focus more attention on. For example, could you create a graph showing the range and clustering of scores for the 5 main rubric criteria? And, if these same 5 criteria are used in the preliminary and final assignments, it would be nice to be able to compare performance between assignments in a visualization that showed the class results on 3 separate artifacts.&lt;br /&gt;
&lt;br /&gt;
Webpage: login as instructor -&amp;gt; Manage -&amp;gt; Assignments -&amp;gt; View scores&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Old Charts ===&lt;br /&gt;
[[File:Existing_Assignment_Grades_Wed.png|frame|centre|'''Figure 1: Existing assignment grade charts - '''The existing assignment grade charts show the average grade for the assignment and the grade distribution. During this project, we aimed to add a third chart which shows the distribution for specific rubric criteria within the assignment.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Accomplished ==&lt;br /&gt;
&lt;br /&gt;
=== Executed on Plans ===&lt;br /&gt;
We successfully executed all of the ideas we had during the planning phase:&lt;br /&gt;
* Add new feature to show mean and median data for rubric criteria in a given assignment&lt;br /&gt;
* Add new feature to show comparison&lt;br /&gt;
* Performed UI testing to ensure features were operational, including edge cases&lt;br /&gt;
* Added and ran RSpec and Capybara automated tests&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== New Charts Inserted ===&lt;br /&gt;
[[File:AnalyzeAssignmentWed.png|frame|centre|'''Figure 2: New Rubric Statistic Visualization - '''Added in the center of the existing two charts is an interactive chart the instructor can use to see the mean or median scores for whichever criteria they select. This is done on the &amp;quot;Analyze Assignment&amp;quot; tab, which is selected by default when the &amp;quot;View Scores&amp;quot; page is loaded.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CompareAssignmentsWed.png|frame|centre|'''Figure 3: New Rubric Cross-Assignment Comparison Visualization - '''The instructor can see a comparison between selected criteria between the current assignment and the selected assignment. The rubric criteria must be compatible in order for it to even show up in the selection list. This comparison visualization is done on the &amp;quot;Compare Assignments&amp;quot; tab which must be selected after the &amp;quot;View Scores&amp;quot; page has been loaded.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Extra Issues Fixed ===&lt;br /&gt;
&lt;br /&gt;
* Refactored [https://github.com/gshugh/expertiza/blob/OSS-HW4/app/views/grades/_team_charts.html.erb _team_charts.html.erb] partial view to use partials for each graphic. Previously both charts were defined together in _team_charts.html.erb, but now each graphic has its own partial view ([https://github.com/gshugh/expertiza/blob/OSS-HW4/app/views/grades/_team_charts_averages.html.erb _team_charts_averages.html.erb], [https://github.com/gshugh/expertiza/blob/OSS-HW4/app/views/grades/_team_charts_distribution.html.erb _team_charts_distribution.html.erb], [https://github.com/gshugh/expertiza/blob/OSS-HW4/app/views/grades/_team_charts_rubric_stats.html.erb _team_charts_rubric_stats.html.erb]). This allows more flexibility going forward, if it's decided one chart should move to a new place on the page, or to a new page.&lt;br /&gt;
* Updated [https://github.com/gshugh/expertiza/blob/OSS-HW4/app/views/grades/_team_charts.html.erb _team_charts.html.erb] so the &amp;quot;Hide stats&amp;quot; button on the View Scores page properly changes to &amp;quot;Show stats&amp;quot; when the statistic charts are hidden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Files Changed ===&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
We performed automated tests using RSpec Framework and Capybara. In addition, we performed manual tests of the user interface (UI), by using the app.&lt;br /&gt;
&lt;br /&gt;
=== RSpec Framework Tests ===&lt;br /&gt;
The RSpec Testing Framework, automated testing, was used to verify the models of the Expertiza web application feature set. Since this feature is dealing with visualizations (charts) that are intimately tied with Active Record models, we seeded the testing database with known data via FactoryBot gem. These changes were automatically rolled-back once the testing was complete.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to increase/maintain automated test coverage for the methods that we added into assignment and questionnaire models. Mocks and stubs were utilized in order to decouple the model under test from dependencies of other models. This will allow us to identify easily if our model updates are causing an issue.&lt;br /&gt;
&lt;br /&gt;
=== Capybara Tests ===&lt;br /&gt;
RSpec Capybara was used to provide integration testing of the charts. The Test Database was seeded with the appropriate information for executing the results of the charts. An additional GEM was needed, webdrivers, to utilize the predefined drivers of Selenium. The default web driver, Rack-Test, does not execute java scripts. Since the graphs that we are using require java script, thus soliciting the necessity of Selenium with its predefined web driver, selenium_chrome_headless. This provides the required functionality to process the java scripts and to automatically ensure that they exist in the DOM. &lt;br /&gt;
&lt;br /&gt;
In order to use the headless web driver with the seeded Test Database, a different database strategy was required. As a result, for this test only, the database strategy was changed to truncation. Ruby 2.2.7 is used in the current version of Expertiza. This version does not allow for sharing of the database thread, and thus requires the to be written to the database outside of a transaction block. This allows for the headless web driver to see that the data is persisted the Test Database and is able to run as normal. Once the test is completed, the database tables are truncated and all data is removed.&lt;br /&gt;
&lt;br /&gt;
=== UI Tests ===&lt;br /&gt;
In addition to the automated tests above we also performed manual testing of the newly added features to include:&lt;br /&gt;
&lt;br /&gt;
* Chart is displaying correctly&lt;br /&gt;
*# Bars are showing up where expected&lt;br /&gt;
*# Bar annotations are showing the expected value&lt;br /&gt;
*# Criteria labels are for the correct bar and displaying correct values&lt;br /&gt;
*# Hover text is displaying the correct values&lt;br /&gt;
*# Null values are not present on the chart&lt;br /&gt;
*# Correct colors are used for the multi-round view&lt;br /&gt;
* Show Labels checkbox works as expected&lt;br /&gt;
* Round Criteria is displaying correctly&lt;br /&gt;
*# Round dropdown menu shows all rounds for the assignment&lt;br /&gt;
*# Selecting a round changes the criteria checkboxes&lt;br /&gt;
*# All checkboxes are displayed with appropriate text&lt;br /&gt;
*# Checkboxes correctly remove or add criterion bars to the chart&lt;br /&gt;
&lt;br /&gt;
== Shortcomings ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Decisions ==&lt;br /&gt;
1. Put our new chart on the View Scores page, rather than on a new page&lt;br /&gt;
* Since it was able to fit on the existing page while displaying all the necessary info, we figured it'd be beneficial to have all grade statistics charts together.&lt;br /&gt;
2. Use GoogleCharts for our new charts&lt;br /&gt;
* The group who previously attempted this project chose GoogleCharts because it has a high compatibility and its charts look of similar quality to those already existing in Expertiza. We agreed with this, and determined GoogleCharts had all of the features we would need.&lt;br /&gt;
3. Added the AssignmentStats, CriterionStats, and ReviewRoundStats models&lt;br /&gt;
* This was a logical, structured way to organize the various data and methods we needed.&lt;br /&gt;
4. Encapsulation of the data within the new models&lt;br /&gt;
* Since the various statistics we needed to form our chart were stored in multiple models, there would be no good place to put the new methods we'd need. The way we did it promotes cohesion, since the new classes have the sole focus of computing statistics. This also allows for future refactoring of other sporadic statistics methods.&lt;br /&gt;
5. Placed AssignmentStats methods in assignment_stats_helper.rb rather than in the model or controller.&lt;br /&gt;
* The methods of interest were really not business logic, but more like massaging of data. For that reason it belonged more in the controller than the model. However, to keep things neat and clean in the controller, the methods were moved out to the helper file.&lt;br /&gt;
6. The exposure of mean and median as the metric_names in grades_controller.rb&lt;br /&gt;
* Since we are explicitly calling the avg_data and med_data methods in the controller, we thought it made sense to name the metric_names nearby, within the controller, rather than hidden off in the helper file.&lt;br /&gt;
&lt;br /&gt;
== Documentation ==&lt;br /&gt;
[https://github.com/expertiza/expertiza/pull/1440 Pull Request]&lt;br /&gt;
&lt;br /&gt;
[https://github.com/gshugh/expertiza/tree/OSS-HW4 GitHub Repo]&lt;br /&gt;
&lt;br /&gt;
[https://docs.google.com/document/d/1Ozw2Bj2u_LyeKUdDqAyQtz1stEIKrxkmRnwmNyUgmzw/edit#heading=h.5kwrelqdnewh Problem Statement]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
* Akshay Ravichandran '''(Mentor)'''&lt;br /&gt;
* Chris Adkins&lt;br /&gt;
* Bobby DeMarco&lt;br /&gt;
* George Hugh&lt;br /&gt;
* John Warren&lt;br /&gt;
&lt;br /&gt;
== old Introduction ==&lt;br /&gt;
It is the desire of all instructors to emphasize course material that students have trouble understanding and de-emphasize those aspects of the course material which students readily grasp. One method used by instructors is the creation of questionnaires, or rubrics. A rubric consists of a number of questions, or criterion, that give instructors a glimpse into student understanding of course materials. Use of rubrics and their association with a course assignment allow instructors to fine-tune their lesson plans to their students' understanding.&lt;br /&gt;
&lt;br /&gt;
Creation of assignments, and their associated rubrics, can be a daunting task that can be made easier through the use of online platforms. Expertiza is one such online assignment grading platform. Within Expertiza, instructors create courses and assignments. For each assignment, instructors create one or more peer review rubrics for students to complete. After each round of rubrics, students can submit changes to their assignment based on these rubrics, with each submission and rubric considered a round. Hence, assignments have multiple rounds with each round associated with a rubric.&lt;br /&gt;
&lt;br /&gt;
Instructors use the association between the assignment and the submitted rubric(s) associated with the assignment to understand what subjects need more focus. For example, a low average score on a rubric's particular question, or criterion, can indicate that the class has issues with a particular part of the assignment. Currently, instructors using Expertiza display assignment scores on one pages, but need to visit a completely separate page to display rubric scores. This separation of information hinders the instructor's ability to fully comprehend the associations between the assignment scores and the rubric scores. This, in turn, minimizes the likelihood that instructors will integrate this information to fine-tune their course material.&lt;br /&gt;
&lt;br /&gt;
This project proposes to overcome this weakness in Expertiza by integrating the display of assignment scores and rubric scores onto a single page. This integration will allow instructors to more easily associate low rubric average scores with assignment scores. The ability to visualize assignment scores and rubric scores in a single location will reduce the workload on instructors when the scores. This, in turn, will increase the likelihood that instructors will change their lesson plans to reflect the students' understanding of the course material.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== old Proposed Changes ==&lt;br /&gt;
To help instructors understand the relationship between assignment scores and rubric scores, this project proposes two types of visualizations. The first type of visualization allows instructors to examine the rubric statistics for a single assignment. The second type of visualization allows instructors to compare the rubric statistics between two different assignments when the criteria for each assignment is the same.&lt;br /&gt;
&lt;br /&gt;
=== Existing Views ===&lt;br /&gt;
&lt;br /&gt;
In both cases, the project will add rubric statistics to the assignment grade view. The current assignment grade view consists of a header containing grade statistics followed by a table of the individual grades. In the assignment grade view header, the left side fo the header shows the average assignment grade as a circle, while the right side of the assignment grade view header shows the assignment grade distribution. Figure 1 shows the current header in the grade assignment view page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Existing_Assignment_Grades.JPG|frame|centre|'''Figure 1: Existing assignment grade page header - '''The existing assignment grade page header has both the average grade for the assignment and the grade distribution for the assignment. The left side shows the average as the percentage of a circle. The right side of the header shows the grade distribution for the assignment. The grade distribution shows the minimum and maximum grade for the assignment. Under the header is a list of the grades for each student.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The changes proposed by this project integrate rubric statistics to the above assignment grade view. Rubric statistic integration into the assignment grade view allow two types of visualizations. The first visualization allows the instructor to display rubric statistics within a single assignment. The second visualization allows the instructor to display rubric statistics between different assignments in the same course.&lt;br /&gt;
&lt;br /&gt;
=== Proposed Assignment Grade Visualization ===&lt;br /&gt;
&lt;br /&gt;
This project proposes the integration of rubric statistic visualization for both single assignments and multiple assignments into the assignment grade view. The integration occurs with a single change to the header of the assignment grade view, and retains the list of student grades. The following HTML mock-up shows the proposed changes to the header. The list of student grades is not changed and therefore not shown.&lt;br /&gt;
&lt;br /&gt;
==== Interactive Example ====&lt;br /&gt;
&lt;br /&gt;
   https://jwarren3.github.io/expertiza/tabs.html&lt;br /&gt;
&lt;br /&gt;
The upper part of the rubric statistic visualization displays a set of tabs that allow the instructor to analyze the rubric within a single assignment or to compare the rubric statistics between multiple assignments. The middle part of the rubric statistic visualization displays the statistics for each selected criteria as a bar graph. The heights of the bars are shown as a percentage of the maximum value for each criteria. The bottom part of the rubric statistic visualization displays a set of options that allow the instructor to filter the statistics shown in the bar graph. The left side (assignment average) and right side (assignment distribution) of the assignment grade view header are not changed.&lt;br /&gt;
&lt;br /&gt;
In the integration of the rubric statistic visualization mock-up within a single assignment, there are two rounds of rubrics for the students to fill out. The rubric in round 1 consisted of five criteria, while the rubric in round 2 consisted of 4 criteria. The round of interest is selected using the drop-down menu on the left side. The criteria shown in the bar graph are selected using radio buttons next to each criterion. Finally, the type of statistic shown is selected using a drop-down menu on the right side of the options. Currently, the statistic is limited to either mean or median. Hovering the mouse over each of the bars in the bar graph shows the numerical value of the chosen statistic.&lt;br /&gt;
&lt;br /&gt;
Visualizing the rubric statistics within a single assignment starts by selecting the left tab titled &amp;quot;Analyze Assignment&amp;quot;. The default displays the mean of all criteria from the first round. Changing the round, the type of statistic, and the particular criteria are controlled from the drop-down menus and radio buttons below the bar graph.&lt;br /&gt;
&lt;br /&gt;
Visualizing the rubric statistics between assignments starts by selecting the right tab titled &amp;quot;Compare Assignments&amp;quot;. The default displays the comparisons between round one and all criteria of an assignment in the same course. The default assignment is the chronologically earliest assignment. The current assignment is shown in red while the rubric being compared is shown in blue.&lt;br /&gt;
&lt;br /&gt;
==== New View Examples ====&lt;br /&gt;
&lt;br /&gt;
[[File:AnalyzeAssignmentNew.png|frame|centre|'''Figure 2: New Rubric Statistic Visualization - '''Added in the center of the existing two charts is an interactive chart the instructor can use to see the mean or median scores for whichever criteria they select. This is done on the &amp;quot;Analyze Assignment&amp;quot; tab, which is selected by default when the &amp;quot;View Scores&amp;quot; page is loaded.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CompareAssignmentsNew.png|frame|centre|'''Figure 3: New Rubric Cross-Assignment Comparison Visualization - '''The instructor can see a comparison between selected criteria between the current assignment and the selected assignment. The rubric criteria must be compatible in order for it to even show up in the selection list. This comparison visualization is done on the &amp;quot;Compare Assignments&amp;quot; tab which must be selected after the &amp;quot;View Scores&amp;quot; page has been loaded.]]&lt;br /&gt;
&lt;br /&gt;
== old Project Design ==&lt;br /&gt;
During the integration of rubric statistics and assignment grade statistics, this project expects to change controller files, view files and JavaScript files. For methods that are modified by this project, the team will also ensure that Code Climate (an automated code quality checker) issues are resolved. This project will also refactor changed methods to reflect common Ruby and Rails practices.&lt;br /&gt;
&lt;br /&gt;
=== Proposed Code Changes ===&lt;br /&gt;
The amount of methods and files to be changed during the integration of rubric statistics and assignment grade statistics is minimal. The team proposes changing a controller file, a view file, a JavaScript file, and an RSpec files. The team does not expect to change the database nor do we expect to change the model files. Other files will be changed as required to support the integration. A preliminary list of files to be changed is given below:&lt;br /&gt;
&lt;br /&gt;
    [https://github.com/gshugh/expertiza/blob/OSS-HW4/app/controllers/grades_controller.rb grades_controller.rb]&lt;br /&gt;
    [https://github.com/gshugh/expertiza/blob/OSS-HW4/app/assets/javascripts/grading.js grading.js]&lt;br /&gt;
    [https://github.com/gshugh/expertiza/blob/OSS-HW4/app/views/grades/_participant_charts.html.erb _participant_charts.html.erb]&lt;br /&gt;
    [https://github.com/gshugh/expertiza/blob/OSS-HW4/spec/controllers/grades_controller_spec.rb grades_controllers_spec.rb]&lt;br /&gt;
&lt;br /&gt;
=== Design Flow ===&lt;br /&gt;
[[File:DesignFlowSingle.png|frame|center|'''Figure 4: Rubric Statistic Design Flow - '''Instructor wants to view student scores on individual rubric criteria.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:DesignFlowCompare.png|frame|center|'''Figure 5: Cross-Assignment Comparison Design Flow - '''Instructor wants to compare student scores on individual rubric criteria between two compatible rounds of two different assignments.]]&lt;br /&gt;
&lt;br /&gt;
=== Tools and Design Choices ===&lt;br /&gt;
This project proposes using a third party JavaScript library for rendering the rubric statistics. This project proposes two requirements for the visualization library. The first requirement is to use a visualization library that performs client-side rendering. Using a client-side rendering library will minimize the number of server interactions as the instructor changes which rubric statistics to display. This minimization of server interaction will maximize the response time of Expertiza.&lt;br /&gt;
&lt;br /&gt;
The second requirement for the visualization library is compatibility with current Expertiza graphics. The compatibility requirement implies that the visualization library is one that is already being used in Expertiza or a visualization library that could be used to render the current graphics.&lt;br /&gt;
&lt;br /&gt;
Examples of client-side visualization libraries are given below:&lt;br /&gt;
&lt;br /&gt;
    [http://www.highcharts.com/ Highcharts]&lt;br /&gt;
    [http://g.raphaeljs.com/ RaphaelJS]&lt;br /&gt;
    [http://dygraphs.com/ dygraphs]&lt;br /&gt;
    [http://vis.stanford.edu/protovis/ Protovis]&lt;br /&gt;
    [http://grafico.kilianvalkhof.com/ Grafico]&lt;br /&gt;
    [https://chartkick.com/ ChartKick]&lt;br /&gt;
    [http://www.vancharts.com/ VanCharts]&lt;br /&gt;
    [https://developers.google.com/chart/ GoogleCharts]&lt;br /&gt;
&lt;br /&gt;
== old Test Plan ==&lt;br /&gt;
The team plans to perform automated tests using frameworks RSpec and Capybara. In addition, we will perform manual tests of the user interface (UI), by using the app.&lt;br /&gt;
&lt;br /&gt;
=== RSpec Framework Tests ===&lt;br /&gt;
The RSpec Testing Framework, automated testing, will be used to verify the Models of the Expertiza Rails Web application feature set. Since this feature is dealing with Visualizations (charts) that is intimately tied with an Active Record Models, we will seed the Testing Database with known data via RSpec. These changes will be automatically rolled-back once the testing is complete.  &lt;br /&gt;
&lt;br /&gt;
=== Capybara Tests ===&lt;br /&gt;
Another automated testing framework that will be used is Capybara. Capybara is an browser type test to simulate a user clicking through your site. We will use this testing framework to verify that our charting object is present on the page and contains the seeded data that we had loaded.&lt;br /&gt;
&lt;br /&gt;
=== UI Tests ===&lt;br /&gt;
In addition to the automated tests above we will also perform manual testing of the newly added features to include:&lt;br /&gt;
&lt;br /&gt;
* Chart is displaying correctly&lt;br /&gt;
*# Bars are showing up where expected&lt;br /&gt;
*# Bar annotations are showing the expected value&lt;br /&gt;
*# Criteria labels are for the correct bar and displaying correct values&lt;br /&gt;
*# Hover text is displaying the correct values&lt;br /&gt;
*# Null values are not present on the chart&lt;br /&gt;
*# Correct colors are used for the multi-round view&lt;br /&gt;
* Show Labels checkbox works as expected&lt;br /&gt;
* Round Criteria is displaying correctly&lt;br /&gt;
*# Round dropdown menu shows all rounds for the assignment&lt;br /&gt;
*# Selecting a round changes the criteria checkboxes&lt;br /&gt;
*# All checkboxes are displayed with appropriate text&lt;br /&gt;
*# Checkboxes correctly remove or add criterion bars to the chart&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1929_Visualizations_for_Instructors&amp;diff=123435</id>
		<title>E1929 Visualizations for Instructors</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1929_Visualizations_for_Instructors&amp;diff=123435"/>
		<updated>2019-04-07T20:20:03Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Expertiza is an online assignment grading platform. Instructors can create assignments and implement peer reviews for submitted assignments. This project concerns the creation of a system for visualizing student performance on those assignments, primarily as graded in peer reviews. Graphs will be made to show various rubric criteria and the class' performance on the criteria. If the criteria are the same for multiple stages of review, an instructor should be able to compare performance over time or between reviews. Our task is to provide an interactive visualization or a table for instructors that shows how their class performed on selected rubric criteria. Such feature would be immensely helpful for instructors as it would assist them to identify what they need to focus more attention on. For example, creating a graph showing the average scores for all or a certain subset of main rubric criteria (questionnaire). If the average score of the class on selected criteria (question) is low means the instructor can emphasize more on the learning materials related to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed Changes ==&lt;br /&gt;
The visualizations will be implemented as either a single or stacked bar chart with a bar for each of the selected criteria to be observed. If a single bar, then the height of the bar will be the total class average, but a stacked bar chart may be better to show the percentage of the class that received each score.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. On clicking Manage and then on assignments, following page appears.&lt;br /&gt;
&lt;br /&gt;
2. Click on 'view score' icon of an assignment. The summary report page of the selected assignment comes up.&lt;br /&gt;
&lt;br /&gt;
3. Following are mockup screens which we wish to create:&lt;br /&gt;
&lt;br /&gt;
a) Instructor would select the round and rubric criteria of the assignment for which he/she wants to view the class performance.&lt;br /&gt;
 &lt;br /&gt;
b) The bar graph of the class performance for those criteria would be displayed.&lt;br /&gt;
&lt;br /&gt;
== Project Design ==&lt;br /&gt;
 The changes made to the expertiza project will primarily include HTML/ERB changes to the view files to accommodate the added charts on the page and the necessary javascript to allow responsive design. Brief controller modifications will be made to facilitate database filtering to get the displayed data.&lt;br /&gt;
&lt;br /&gt;
=== Design Flow ===&lt;br /&gt;
The flowchart representing graphical flow of an instructor visiting view scores under assignments is given below:&lt;br /&gt;
&lt;br /&gt;
[[File:A3.png]]&lt;br /&gt;
&lt;br /&gt;
=== Tools and Design Choice ===&lt;br /&gt;
We have used the lightweight [https://developers.google.com/chart/ Google Charts] library for displaying the chart data on the page, with standard HTML for all of the options and dropdowns for option selection. Google Charts was chosen because of its high compatibility, full option set, and comparable graphical quality to the rest of expertiza while keeping a small JS footprint, which should help prevent slow page responsiveness.&lt;br /&gt;
&lt;br /&gt;
=== Visualization ===&lt;br /&gt;
The following graph shows the view of the 'view scores' page after the modifications. The instructor selects a subset of rubric criteria for which he/she wants to know how a class performed for a particular round. A bar graph of the average score of the class for that subset of criteria is displayed. &lt;br /&gt;
&lt;br /&gt;
The above graph shows an average score of the class for 10 rubric criteria in Round 1 for assignment &amp;quot;OSS project/Writing assignment 2&amp;quot; selected by the instructor. A live demo with randomly generated data can be found on [https://jsfiddle.net/Jereman/5uxqr92y/ JSFiddle]&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
The team plans to perform both automated tests using frameworks RSpec and Capybara. In addition, we will perform manual tests of the user interface (UI), using the app.&lt;br /&gt;
&lt;br /&gt;
=== RSpec Framework Tests ===&lt;br /&gt;
The RSpec Testing Framework, automated testing, will be used to verify the Models of the Expertiza Rails Web application feature set. Since this feature is dealing with Visualizations (charts) that is intimately tied with an Active Record Models, we will seed the Testing Database with known data via RSpec. These changes will be automatically rolled-back once the testing is complete.  &lt;br /&gt;
&lt;br /&gt;
=== Capybara Tests ===&lt;br /&gt;
Another automated testing framework that will be used is Capybara. Capybara is an browser type test to simulate a user clicking through your site. We will use this testing framework to verify that our charting object is present on the page and contains the seeded data that we had loaded.&lt;br /&gt;
&lt;br /&gt;
=== UI Tests ===&lt;br /&gt;
In addition to the automated tests above we will also perform manual testing of the newly added features to include:&lt;br /&gt;
&lt;br /&gt;
* Chart is displaying correctly&lt;br /&gt;
*# Bars are showing up where expected&lt;br /&gt;
*# Bar annotations are showing the expected value&lt;br /&gt;
*# Criteria labels are for the correct bar and displaying correct values&lt;br /&gt;
*# Hover text is displaying the correct values&lt;br /&gt;
*# Null values are not present on the chart&lt;br /&gt;
*# Correct colors are used for the multi-round view&lt;br /&gt;
* Show Labels checkbox works as expected&lt;br /&gt;
* Round Criteria is displaying correctly&lt;br /&gt;
*# Round dropdown menu shows all rounds for the assignment&lt;br /&gt;
*# Selecting a round changes the criteria checkboxes&lt;br /&gt;
*# All checkboxes are displayed with appropriate text&lt;br /&gt;
*# Checkboxes correctly remove or add criterion bars to the chart&lt;br /&gt;
&lt;br /&gt;
== Files Involved ==&lt;br /&gt;
We have implemented a new partial file criteria_charts to the team_chart that display the bar graph with existing data collected by the grades controller methods to the view page.&lt;br /&gt;
&lt;br /&gt;
Modified files:&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: inline-block&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app/controllers/grades_controller.rb&lt;br /&gt;
&lt;br /&gt;
app/views/grades/_teams.html.erb&lt;br /&gt;
&lt;br /&gt;
app/views/grades/_criteria_charts.html.erb&lt;br /&gt;
&lt;br /&gt;
app/views/grades/_team_charts.html.erb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== app/views/grades/_criteria_charts.html.erb ===&lt;br /&gt;
 &amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&lt;br /&gt;
 &amp;lt;%= content_tag :div, class: &amp;quot;chartdata_information&amp;quot;, data: {chartdata: @chartdata} do %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
 &amp;lt;%= content_tag :div, class: &amp;quot;text_information&amp;quot;, data: {text: @text} do %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;%= content_tag :div, class: &amp;quot;minmax_information&amp;quot;, data: {minmax: @minmax} do %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
 &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://www.gstatic.com/charts/loader.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
      google.charts.load('current', {packages: ['corechart', 'bar']});&lt;br /&gt;
       //Display Options&lt;br /&gt;
      var showLabels = true;&lt;br /&gt;
      var barColors = [ // Other colors generated from the expertiza base red&lt;br /&gt;
          '#A90201',    // using paletton.com&lt;br /&gt;
          '#018701',&lt;br /&gt;
          '#016565',&lt;br /&gt;
          '#A94D01'&lt;br /&gt;
      ];&lt;br /&gt;
      function getData(){ //Loads all chart data from the page&lt;br /&gt;
        chartData = $('.chartdata_information').data('chartdata');&lt;br /&gt;
        chartText = $('.text_information').data('text');&lt;br /&gt;
        chartRange = $('.minmax_information').data('minmax');&lt;br /&gt;
 for (var i = 0; i &amp;lt; chartData.length; i++){ //Set all the criteriaSelected to true&lt;br /&gt;
          var criteria = [];&lt;br /&gt;
          for (var j = 0; j &amp;lt; chartData[i].length; j++){&lt;br /&gt;
            criteria.push(true);&lt;br /&gt;
          }&lt;br /&gt;
          criteriaSelected.push(criteria);&lt;br /&gt;
        }&lt;br /&gt;
     }&lt;br /&gt;
       function generateData() {	//Generates random data for testing&lt;br /&gt;
        var rounds = 3;&lt;br /&gt;
        for(var i = 0; i &amp;lt; rounds; i++) {&lt;br /&gt;
  var criteriaNum = Math.floor(Math.random() * 5 + 5);  //Random number of criteria&lt;br /&gt;
          var round = [];&lt;br /&gt;
          var criteria = [];&lt;br /&gt;
          for(var j = 0; j &amp;lt; criteriaNum; j++) {&lt;br /&gt;
  round.push(Math.floor(Math.random() * 101));  //Random score for each criterion&lt;br /&gt;
            criteria.push(true);  //Everything starts out true&lt;br /&gt;
          }&lt;br /&gt;
          chartData.push(round);&lt;br /&gt;
          criteriaSelected.push(criteria);&lt;br /&gt;
 &lt;br /&gt;
        chartOptions = {		//Render options for the chart&lt;br /&gt;
          title: 'Class Average on Criteria',&lt;br /&gt;
          titleTextStyle: {&lt;br /&gt;
  fontName: 'arial',&lt;br /&gt;
            fontSize: 18,&lt;br /&gt;
            italic: false,&lt;br /&gt;
            bold: true&lt;br /&gt;
         chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));&lt;br /&gt;
        var checkBox = document.getElementById(&amp;quot;labelCheck&amp;quot;);&lt;br /&gt;
        checkBox.checked = true;&lt;br /&gt;
        checkBox.style.display = &amp;quot;inline&amp;quot;;&lt;br /&gt;
        updateChart(currentRound);&lt;br /&gt;
        loadRounds(); }&lt;br /&gt;
 function updateChart(roundNum) {	//Updates the chart with a new round number and renders&lt;br /&gt;
        currentRound = roundNum;&lt;br /&gt;
        renderChart();&lt;br /&gt;
        loadCriteria();&lt;br /&gt;
      function renderChart() {	//Renders the chart if changes have been made&lt;br /&gt;
          var data = loadData();&lt;br /&gt;
 chartOptions.vAxis.viewWindow.max = 5;&lt;br /&gt;
          chartOptions.vAxis.viewWindow.min = 0;&lt;br /&gt;
          if (chartRange[currentRound]) { //Set axis ranges if they exist&lt;br /&gt;
              if (chartRange[currentRound][1])&lt;br /&gt;
                  chartOptions.vAxis.viewWindow.max = chartRange[currentRound][1];&lt;br /&gt;
 if (chartRange[currentRound][0])&lt;br /&gt;
                  chartOptions.vAxis.viewWindow.min = chartRange[currentRound][0];&lt;br /&gt;
 }&lt;br /&gt;
          chart.draw(data, chartOptions);&lt;br /&gt;
      }&lt;br /&gt;
 &lt;br /&gt;
           chartOptions.hAxis.ticks = [];&lt;br /&gt;
          var rowCount = 1;&lt;br /&gt;
 for(var i = 0; i &amp;lt; chartData[currentRound].length; i++) { //Add a chart row for each criterion if not null&lt;br /&gt;
              if (criteriaSelected[currentRound][i] &amp;amp;&amp;amp; chartData[currentRound][i]) {&lt;br /&gt;
  data.addRow([rowCount, chartData[currentRound][i], barColors[0], (showLabels) ? chartData[currentRound][i].toFixed(1).toString() : &amp;quot;&amp;quot;]);&lt;br /&gt;
                  chartOptions.hAxis.ticks.push({v: rowCount++, f: (i+1).toString()});&lt;br /&gt;
              }&lt;br /&gt;
          }&lt;br /&gt;
 &lt;br /&gt;
          var data = new google.visualization.DataTable();&lt;br /&gt;
          data.addColumn('number', 'Criterion');&lt;br /&gt;
          var i;&lt;br /&gt;
 for(i = 0; i &amp;lt; roundNum; i++) { //Add all columns for the data&lt;br /&gt;
              data.addColumn('number', 'Round ' + (i+1).toString());&lt;br /&gt;
              data.addColumn({type: 'string', role: 'style'});	//column for specifying the bar color&lt;br /&gt;
              data.addColumn({type: 'string', role: 'annotation'});&lt;br /&gt;
 &lt;br /&gt;
              var newRow = [];&lt;br /&gt;
              var elementsAdded = false;&lt;br /&gt;
              newRow.push(rowCount);&lt;br /&gt;
 for(var j = 0; j &amp;lt; roundNum; j++) { //If the round has the criterion, add it&lt;br /&gt;
                  if (chartData[j][i]) {&lt;br /&gt;
                      newRow.push(chartData[j][i]);&lt;br /&gt;
                      elementsAdded = true;&lt;br /&gt;
                  } else {&lt;br /&gt;
                      newRow.push(null);&lt;br /&gt;
                  }&lt;br /&gt;
  newRow.push(barColors[j % barColors.length]); //Add column color&lt;br /&gt;
                  if (chartData[j] &amp;amp;&amp;amp; chartData[j][i] &amp;amp;&amp;amp; showLabels)&lt;br /&gt;
  newRow.push(chartData[j][i].toFixed(1).toString()); //Add column annotations&lt;br /&gt;
                  else&lt;br /&gt;
                      newRow.push(&amp;quot;&amp;quot;);&lt;br /&gt;
              }&lt;br /&gt;
       function loadCriteria() {	//Creates the criteria check boxes&lt;br /&gt;
          var form = document.getElementById(&amp;quot;chartCriteria&amp;quot;);&lt;br /&gt;
 while (form.firstChild) //Clear out the old check boxes&lt;br /&gt;
              form.removeChild(form.firstChild);&lt;br /&gt;
 if (currentRound == -1) //Don't show criteria for 'all rounds'&lt;br /&gt;
              return;&lt;br /&gt;
          chartData[currentRound].forEach(function(dat, i) {&lt;br /&gt;
              var checkbox = document.createElement('input');&lt;br /&gt;
              checkbox.type = &amp;quot;checkbox&amp;quot;;&lt;br /&gt;
              checkbox.id = &amp;quot;checkboxoption&amp;quot; + i;&lt;br /&gt;
 checkbox.onclick = function() { //Register callback to toggle the criterion&lt;br /&gt;
                  checkboxUpdate(i);&lt;br /&gt;
              }&lt;br /&gt;
              var label = document.createElement('label')&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;form id=&amp;quot;chartOptions&amp;quot; name=&amp;quot;chartOptions&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;select id=&amp;quot;chartRounds&amp;quot; name=&amp;quot;rounds&amp;quot; &lt;br /&gt;
 onChange=&amp;quot;updateChart(document.chartOptions.chartRounds.options[document.chartOptions.chartRounds.options.selectedIndex].value)&amp;quot; style = &amp;quot;display: none&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;/select&amp;gt;&lt;br /&gt;
 &amp;lt;label&amp;gt;&amp;lt;input type=&amp;quot;checkbox&amp;quot; id = &amp;quot;labelCheck&amp;quot; checked=&amp;quot;checked&amp;quot; style=&amp;quot;display: none&amp;quot; onclick=&amp;quot;showLabels = !showLabels; renderChart();&amp;quot;&amp;gt;Show &lt;br /&gt;
 Labels&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;/form&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;chartCriteria&amp;quot; name=&amp;quot;chartCriteria&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== app/controllers/grades_controller.rb ===&lt;br /&gt;
&lt;br /&gt;
 def action_allowed?&lt;br /&gt;
     case params[:action]&lt;br /&gt;
     when 'view_my_scores'&lt;br /&gt;
       ['Instructor',&lt;br /&gt;
        'Teaching Assistant',&lt;br /&gt;
        'Administrator',&lt;br /&gt;
        'Super-Administrator',&lt;br /&gt;
       'Student'].include? current_role_name and&lt;br /&gt;
        are_needed_authorizations_present?(params[:id], &amp;quot;reader&amp;quot;, &amp;quot;reviewer&amp;quot;) and&lt;br /&gt;
        check_self_review_status&lt;br /&gt;
 when 'view_team'&lt;br /&gt;
      if ['Student'].include? current_role_name # students can only see the head map for their own team&lt;br /&gt;
        participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
        session[:user].id == participant.user_id&lt;br /&gt;
      else&lt;br /&gt;
 true&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      ['Instructor',&lt;br /&gt;
       'Teaching Assistant',&lt;br /&gt;
       'Administrator',&lt;br /&gt;
       'Super-Administrator'].include? current_role_name&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
   # collects the question text for display on the chart&lt;br /&gt;
   # Added as part of E1859&lt;br /&gt;
   def assign_chart_text&lt;br /&gt;
     @text = []&lt;br /&gt;
     (1..@assignment.num_review_rounds).to_a.each do |round|&lt;br /&gt;
       question = @questions[('review' + round.to_s).to_sym]&lt;br /&gt;
       @text[round - 1] = []&lt;br /&gt;
       next if question.nil?&lt;br /&gt;
       (0..(question.length - 1)).to_a.each do |q|&lt;br /&gt;
         @text[round - 1][q] = question[q].txt&lt;br /&gt;
       end&lt;br /&gt;
     end&lt;br /&gt;
   end&lt;br /&gt;
 &lt;br /&gt;
   # find the maximum and minimum scores for each questionnaire round&lt;br /&gt;
   # Added as part of E1859&lt;br /&gt;
   def assign_minmax(questionnaires)&lt;br /&gt;
     @minmax = []&lt;br /&gt;
     questionnaires.each do |questionnaire|&lt;br /&gt;
      next if questionnaire.symbol != :review&lt;br /&gt;
      round = AssignmentQuestionnaire.where(assignment_id: @assignment.id, questionnaire_id: questionnaire.id).first.used_in_round&lt;br /&gt;
      next if round.nil?&lt;br /&gt;
  @minmax[round - 1] = []&lt;br /&gt;
      @minmax[round - 1][0] = if !questionnaire.min_question_score.nil? and questionnaire.min_question_score &amp;lt; 0&lt;br /&gt;
                                questionnaire.min_question_score&lt;br /&gt;
                              else&lt;br /&gt;
                                0&lt;br /&gt;
                              end&lt;br /&gt;
      @minmax[round - 1][1] = if !questionnaire.max_question_score.nil?&lt;br /&gt;
                                questionnaire.max_question_score&lt;br /&gt;
                              else&lt;br /&gt;
                                5&lt;br /&gt;
                              end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 # this method collects and averages all the review scores across teams&lt;br /&gt;
   # Added as part of E1859&lt;br /&gt;
   def assign_chart_data&lt;br /&gt;
     @rounds = @assignment.num_review_rounds&lt;br /&gt;
     @chartdata = []&lt;br /&gt;
     (1..@rounds).to_a.each do |round|&lt;br /&gt;
       @teams = AssignmentTeam.where(parent_id: @assignment.id)&lt;br /&gt;
       @teamids = []&lt;br /&gt;
       @result = []&lt;br /&gt;
       @responseids = []&lt;br /&gt;
       @scoreviews = []&lt;br /&gt;
       (0..(@teams.length - 1)).to_a.each do |t|&lt;br /&gt;
         @teamids[t] = @teams[t].id&lt;br /&gt;
         @result[t] = ResponseMap.find_by_sql [&amp;quot;SELECT id FROM response_maps&lt;br /&gt;
           WHERE type = 'ReviewResponseMap' AND reviewee_id = ?&amp;quot;, @teamids[t]]&lt;br /&gt;
         @responseids[t] = []&lt;br /&gt;
         @scoreviews[t] = []&lt;br /&gt;
         (0..(@result[t].length - 1)).to_a.each do |r|&lt;br /&gt;
           @responseids[t][r] = Response.find_by_sql [&amp;quot;SELECT id FROM responses&lt;br /&gt;
             WHERE round = ? AND map_id = ?&amp;quot;, round, @result[t][r]]&lt;br /&gt;
          @scoreviews[t][r] = Answer.where(response_id: @responseids[t][r][0]) unless @responseids[t][r].empty?&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @chartdata[round - 1] = []&lt;br /&gt;
      # because the nth first elements could be nil&lt;br /&gt;
      # iterate until a non-nil value is found or move to next round&lt;br /&gt;
      t = 0&lt;br /&gt;
      r = 0&lt;br /&gt;
 t += 1 while @scoreviews[t].nil?&lt;br /&gt;
      while t &amp;lt; @scoreviews.length and @scoreviews[t][r].nil?&lt;br /&gt;
        if r &amp;lt; @scoreviews[t].length - 1&lt;br /&gt;
          r += 1&lt;br /&gt;
        else&lt;br /&gt;
 def assign_chart_data&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      next if t &amp;gt;= @scoreviews.length&lt;br /&gt;
 (0..(@scoreviews[t][r].length - 1)).to_a.each do |q|&lt;br /&gt;
        sum = 0&lt;br /&gt;
        counter = 0&lt;br /&gt;
 def retrieve_questions(questionnaires)&lt;br /&gt;
    questionnaires.each do |questionnaire|&lt;br /&gt;
      round = AssignmentQuestionnaire.where(assignment_id: @assignment.id, questionnaire_id: questionnaire.id).first.used_in_round&lt;br /&gt;
      questionnaire_symbol = if !round.nil?&lt;br /&gt;
                         (questionnaire.symbol.to_s + round.to_s).to_sym&lt;br /&gt;
                             else&lt;br /&gt;
                               questionnaire.symbol&lt;br /&gt;
                             end&lt;br /&gt;
      @questions[questionnaire_symbol] = questionnaire.questions&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 def update&lt;br /&gt;
    if format(&amp;quot;%.2f&amp;quot;, total_score) != params[:participant][:grade]&lt;br /&gt;
      participant.update_attribute(:grade, params[:participant][:grade])&lt;br /&gt;
      message = if participant.grade.nil?&lt;br /&gt;
           &amp;quot;The computed score will be used for &amp;quot; + participant.user.name + &amp;quot;.&amp;quot;&lt;br /&gt;
                else&lt;br /&gt;
                  &amp;quot;A score of &amp;quot; + params[:participant][:grade] + &amp;quot;% has been saved for &amp;quot; + participant.user.name + &amp;quot;.&amp;quot;&lt;br /&gt;
                end&lt;br /&gt;
    end&lt;br /&gt;
    flash[:note] = message&lt;br /&gt;
    redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
&lt;br /&gt;
=== app/views/grades/_team_charts.html.erb ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;br&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;%= render :partial =&amp;gt; 'criteria_charts' %&amp;gt;&lt;br /&gt;
  &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;a href=&amp;quot;#&amp;quot; name='team-chartLink' onClick=&amp;quot;toggleElement('team-chart', 'stats');return false;&amp;quot;&amp;gt;Hide stats&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;TR style =&amp;quot;background-color: white;&amp;quot; class=&amp;quot;team&amp;quot; id=&amp;quot;team-chart&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div class=&amp;quot;circle&amp;quot; id=&amp;quot;average-score&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
      Class Average&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;TH COLSPAN=&amp;quot;8&amp;quot;&amp;gt;&lt;br /&gt;
    	&amp;lt;img src=&amp;quot;&amp;lt;%= @average_chart  %&amp;gt;&amp;quot; &amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
    	Class Distribution&lt;br /&gt;
    	&amp;lt;br&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;TH WIDTH=&amp;quot;9&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
    var myCircle = Circles.create({&lt;br /&gt;
      id:           'average-score',&lt;br /&gt;
      radius:       50,&lt;br /&gt;
      value:        &amp;lt;%= @avg_of_avg.to_i %&amp;gt;,&lt;br /&gt;
      maxValue:     100,&lt;br /&gt;
      width:        15,&lt;br /&gt;
      text:         '&amp;lt;%=@avg_of_avg.to_i%&amp;gt;',&lt;br /&gt;
      colors:       ['#FFEB99', '#FFCC00'],&lt;br /&gt;
      duration:       700,&lt;br /&gt;
      textClass:      'circles-final'&lt;br /&gt;
    });&lt;br /&gt;
  &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;style&amp;gt;&lt;br /&gt;
   .circles-final{&lt;br /&gt;
      font-size: 16px !important;&lt;br /&gt;
    }&lt;br /&gt;
  &amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test Results ==&lt;br /&gt;
The team ran both automated tests, using the RSpec framework, and manual tests of the user interface (UI), using the app. The automated tests helped to ensure that the basic functionality of the app still worked, while the UI tests ensured that the visualizations were correct.&lt;br /&gt;
&lt;br /&gt;
=== RSpec Test Results ===&lt;br /&gt;
In order to ensure that our changes did not affect basic functionality of the app, we made sure that all tests that passed before our changes also passed after our changes. Add statistics on the tests before our changes and matching statistics after our changes.&lt;br /&gt;
&lt;br /&gt;
=== UI Tests ===&lt;br /&gt;
To validate all functionality of the chart when adding new features or fixing old ones, the following criteria were tested manually for expected functionality:&lt;br /&gt;
&lt;br /&gt;
# Chart is displaying correctly&lt;br /&gt;
## Bars are showing up where expected&lt;br /&gt;
## Bar annotations are showing the expected value&lt;br /&gt;
## Criteria labels are for the correct bar and displaying correct values&lt;br /&gt;
## Hover text is displaying the correct values&lt;br /&gt;
## Null values are not present on the chart&lt;br /&gt;
## Correct colors are used for the multi-round view&lt;br /&gt;
# Show Labels checkbox works as expected&lt;br /&gt;
# Round Criteria is displaying correctly&lt;br /&gt;
## Round dropdown menu shows all rounds for the assignment&lt;br /&gt;
## Selecting a round changes the criteria checkboxes&lt;br /&gt;
## All checkboxes are displayed with appropriate text&lt;br /&gt;
## Checkboxes correctly remove or add criterion bars to the chart&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1929_Visualizations_for_Instructors&amp;diff=123434</id>
		<title>E1929 Visualizations for Instructors</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1929_Visualizations_for_Instructors&amp;diff=123434"/>
		<updated>2019-04-07T20:18:27Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Expertiza is an online assignment grading platform. Instructors can create assignments and implement peer reviews for submitted assignments. This project concerns the creation of a system for visualizing student performance on those assignments, primarily as graded in peer reviews. Graphs will be made to show various rubric criteria and the class' performance on the criteria. If the criteria are the same for multiple stages of review, an instructor should be able to compare performance over time or between reviews. Our task is to provide an interactive visualization or a table for instructors that shows how their class performed on selected rubric criteria. Such feature would be immensely helpful for instructors as it would assist them to identify what they need to focus more attention on. For example, creating a graph showing the average scores for all or a certain subset of main rubric criteria (questionnaire). If the average score of the class on selected criteria (question) is low means the instructor can emphasize more on the learning materials related to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed Changes ==&lt;br /&gt;
The visualizations will be implemented as either a single or stacked bar chart with a bar for each of the selected criteria to be observed. If a single bar, then the height of the bar will be the total class average, but a stacked bar chart may be better to show the percentage of the class that received each score.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. On clicking Manage and then on assignments, following page appears.&lt;br /&gt;
&lt;br /&gt;
2. Click on 'view score' icon of an assignment. The summary report page of the selected assignment comes up.&lt;br /&gt;
&lt;br /&gt;
3. Following are mockup screens which we wish to create:&lt;br /&gt;
&lt;br /&gt;
a) Instructor would select the round and rubric criteria of the assignment for which he/she wants to view the class performance.&lt;br /&gt;
 &lt;br /&gt;
b) The bar graph of the class performance for those criteria would be displayed.&lt;br /&gt;
&lt;br /&gt;
== Project Design ==&lt;br /&gt;
 The changes made to the expertiza project will primarily include HTML/ERB changes to the view files to accommodate the added charts on the page and the necessary javascript to allow responsive design. Brief controller modifications will be made to facilitate database filtering to get the displayed data.&lt;br /&gt;
&lt;br /&gt;
=== Design Flow ===&lt;br /&gt;
The flowchart representing graphical flow of an instructor visiting view scores under assignments is given below:&lt;br /&gt;
&lt;br /&gt;
[[File:A3.png]]&lt;br /&gt;
&lt;br /&gt;
=== Tools and Design Choice ===&lt;br /&gt;
We have used the lightweight [https://developers.google.com/chart/ Google Charts] library for displaying the chart data on the page, with standard HTML for all of the options and dropdowns for option selection. Google Charts was chosen because of its high compatibility, full option set, and comparable graphical quality to the rest of expertiza while keeping a small JS footprint, which should help prevent slow page responsiveness.&lt;br /&gt;
&lt;br /&gt;
=== Visualization ===&lt;br /&gt;
The following graph shows the view of the 'view scores' page after the modifications. The instructor selects a subset of rubric criteria for which he/she wants to know how a class performed for a particular round. A bar graph of the average score of the class for that subset of criteria is displayed. &lt;br /&gt;
&lt;br /&gt;
The above graph shows an average score of the class for 10 rubric criteria in Round 1 for assignment &amp;quot;OSS project/Writing assignment 2&amp;quot; selected by the instructor. A live demo with randomly generated data can be found on [https://jsfiddle.net/Jereman/5uxqr92y/ JSFiddle]&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
The team plans to perform both automated tests, using the RSpec framework, and manual tests of the user interface (UI), using the app.&lt;br /&gt;
&lt;br /&gt;
=== RSpec Framework Tests ===&lt;br /&gt;
The RSpec Testing Framework, automated testing, will be used to verify the Models of the Expertiza Rails Web application feature set. Since this feature is dealing with Visualizations (charts) that is intimately tied with an Active Record Models, we will seed the Testing Database with known data via RSpec. These changes will be automatically rolled-back once the testing is complete.  &lt;br /&gt;
&lt;br /&gt;
=== Capybara Tests ===&lt;br /&gt;
Another automated testing framework that will be used is Capybara. Capybara is an browser type test to simulate a user clicking through your site. We will use this testing framework to verify that our charting object is present on the page and contains the seeded data that we had loaded.&lt;br /&gt;
&lt;br /&gt;
=== UI Tests ===&lt;br /&gt;
In addition to the automated tests above we will also perform manual testing of the newly added features to include:&lt;br /&gt;
&lt;br /&gt;
* Chart is displaying correctly&lt;br /&gt;
*# Bars are showing up where expected&lt;br /&gt;
*# Bar annotations are showing the expected value&lt;br /&gt;
*# Criteria labels are for the correct bar and displaying correct values&lt;br /&gt;
*# Hover text is displaying the correct values&lt;br /&gt;
*# Null values are not present on the chart&lt;br /&gt;
*# Correct colors are used for the multi-round view&lt;br /&gt;
* Show Labels checkbox works as expected&lt;br /&gt;
* Round Criteria is displaying correctly&lt;br /&gt;
*# Round dropdown menu shows all rounds for the assignment&lt;br /&gt;
*# Selecting a round changes the criteria checkboxes&lt;br /&gt;
*# All checkboxes are displayed with appropriate text&lt;br /&gt;
*# Checkboxes correctly remove or add criterion bars to the chart&lt;br /&gt;
&lt;br /&gt;
== Files Involved ==&lt;br /&gt;
We have implemented a new partial file criteria_charts to the team_chart that display the bar graph with existing data collected by the grades controller methods to the view page.&lt;br /&gt;
&lt;br /&gt;
Modified files:&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: inline-block&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app/controllers/grades_controller.rb&lt;br /&gt;
&lt;br /&gt;
app/views/grades/_teams.html.erb&lt;br /&gt;
&lt;br /&gt;
app/views/grades/_criteria_charts.html.erb&lt;br /&gt;
&lt;br /&gt;
app/views/grades/_team_charts.html.erb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== app/views/grades/_criteria_charts.html.erb ===&lt;br /&gt;
 &amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&lt;br /&gt;
 &amp;lt;%= content_tag :div, class: &amp;quot;chartdata_information&amp;quot;, data: {chartdata: @chartdata} do %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
 &amp;lt;%= content_tag :div, class: &amp;quot;text_information&amp;quot;, data: {text: @text} do %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;%= content_tag :div, class: &amp;quot;minmax_information&amp;quot;, data: {minmax: @minmax} do %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
 &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://www.gstatic.com/charts/loader.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
      google.charts.load('current', {packages: ['corechart', 'bar']});&lt;br /&gt;
       //Display Options&lt;br /&gt;
      var showLabels = true;&lt;br /&gt;
      var barColors = [ // Other colors generated from the expertiza base red&lt;br /&gt;
          '#A90201',    // using paletton.com&lt;br /&gt;
          '#018701',&lt;br /&gt;
          '#016565',&lt;br /&gt;
          '#A94D01'&lt;br /&gt;
      ];&lt;br /&gt;
      function getData(){ //Loads all chart data from the page&lt;br /&gt;
        chartData = $('.chartdata_information').data('chartdata');&lt;br /&gt;
        chartText = $('.text_information').data('text');&lt;br /&gt;
        chartRange = $('.minmax_information').data('minmax');&lt;br /&gt;
 for (var i = 0; i &amp;lt; chartData.length; i++){ //Set all the criteriaSelected to true&lt;br /&gt;
          var criteria = [];&lt;br /&gt;
          for (var j = 0; j &amp;lt; chartData[i].length; j++){&lt;br /&gt;
            criteria.push(true);&lt;br /&gt;
          }&lt;br /&gt;
          criteriaSelected.push(criteria);&lt;br /&gt;
        }&lt;br /&gt;
     }&lt;br /&gt;
       function generateData() {	//Generates random data for testing&lt;br /&gt;
        var rounds = 3;&lt;br /&gt;
        for(var i = 0; i &amp;lt; rounds; i++) {&lt;br /&gt;
  var criteriaNum = Math.floor(Math.random() * 5 + 5);  //Random number of criteria&lt;br /&gt;
          var round = [];&lt;br /&gt;
          var criteria = [];&lt;br /&gt;
          for(var j = 0; j &amp;lt; criteriaNum; j++) {&lt;br /&gt;
  round.push(Math.floor(Math.random() * 101));  //Random score for each criterion&lt;br /&gt;
            criteria.push(true);  //Everything starts out true&lt;br /&gt;
          }&lt;br /&gt;
          chartData.push(round);&lt;br /&gt;
          criteriaSelected.push(criteria);&lt;br /&gt;
 &lt;br /&gt;
        chartOptions = {		//Render options for the chart&lt;br /&gt;
          title: 'Class Average on Criteria',&lt;br /&gt;
          titleTextStyle: {&lt;br /&gt;
  fontName: 'arial',&lt;br /&gt;
            fontSize: 18,&lt;br /&gt;
            italic: false,&lt;br /&gt;
            bold: true&lt;br /&gt;
         chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));&lt;br /&gt;
        var checkBox = document.getElementById(&amp;quot;labelCheck&amp;quot;);&lt;br /&gt;
        checkBox.checked = true;&lt;br /&gt;
        checkBox.style.display = &amp;quot;inline&amp;quot;;&lt;br /&gt;
        updateChart(currentRound);&lt;br /&gt;
        loadRounds(); }&lt;br /&gt;
 function updateChart(roundNum) {	//Updates the chart with a new round number and renders&lt;br /&gt;
        currentRound = roundNum;&lt;br /&gt;
        renderChart();&lt;br /&gt;
        loadCriteria();&lt;br /&gt;
      function renderChart() {	//Renders the chart if changes have been made&lt;br /&gt;
          var data = loadData();&lt;br /&gt;
 chartOptions.vAxis.viewWindow.max = 5;&lt;br /&gt;
          chartOptions.vAxis.viewWindow.min = 0;&lt;br /&gt;
          if (chartRange[currentRound]) { //Set axis ranges if they exist&lt;br /&gt;
              if (chartRange[currentRound][1])&lt;br /&gt;
                  chartOptions.vAxis.viewWindow.max = chartRange[currentRound][1];&lt;br /&gt;
 if (chartRange[currentRound][0])&lt;br /&gt;
                  chartOptions.vAxis.viewWindow.min = chartRange[currentRound][0];&lt;br /&gt;
 }&lt;br /&gt;
          chart.draw(data, chartOptions);&lt;br /&gt;
      }&lt;br /&gt;
 &lt;br /&gt;
           chartOptions.hAxis.ticks = [];&lt;br /&gt;
          var rowCount = 1;&lt;br /&gt;
 for(var i = 0; i &amp;lt; chartData[currentRound].length; i++) { //Add a chart row for each criterion if not null&lt;br /&gt;
              if (criteriaSelected[currentRound][i] &amp;amp;&amp;amp; chartData[currentRound][i]) {&lt;br /&gt;
  data.addRow([rowCount, chartData[currentRound][i], barColors[0], (showLabels) ? chartData[currentRound][i].toFixed(1).toString() : &amp;quot;&amp;quot;]);&lt;br /&gt;
                  chartOptions.hAxis.ticks.push({v: rowCount++, f: (i+1).toString()});&lt;br /&gt;
              }&lt;br /&gt;
          }&lt;br /&gt;
 &lt;br /&gt;
          var data = new google.visualization.DataTable();&lt;br /&gt;
          data.addColumn('number', 'Criterion');&lt;br /&gt;
          var i;&lt;br /&gt;
 for(i = 0; i &amp;lt; roundNum; i++) { //Add all columns for the data&lt;br /&gt;
              data.addColumn('number', 'Round ' + (i+1).toString());&lt;br /&gt;
              data.addColumn({type: 'string', role: 'style'});	//column for specifying the bar color&lt;br /&gt;
              data.addColumn({type: 'string', role: 'annotation'});&lt;br /&gt;
 &lt;br /&gt;
              var newRow = [];&lt;br /&gt;
              var elementsAdded = false;&lt;br /&gt;
              newRow.push(rowCount);&lt;br /&gt;
 for(var j = 0; j &amp;lt; roundNum; j++) { //If the round has the criterion, add it&lt;br /&gt;
                  if (chartData[j][i]) {&lt;br /&gt;
                      newRow.push(chartData[j][i]);&lt;br /&gt;
                      elementsAdded = true;&lt;br /&gt;
                  } else {&lt;br /&gt;
                      newRow.push(null);&lt;br /&gt;
                  }&lt;br /&gt;
  newRow.push(barColors[j % barColors.length]); //Add column color&lt;br /&gt;
                  if (chartData[j] &amp;amp;&amp;amp; chartData[j][i] &amp;amp;&amp;amp; showLabels)&lt;br /&gt;
  newRow.push(chartData[j][i].toFixed(1).toString()); //Add column annotations&lt;br /&gt;
                  else&lt;br /&gt;
                      newRow.push(&amp;quot;&amp;quot;);&lt;br /&gt;
              }&lt;br /&gt;
       function loadCriteria() {	//Creates the criteria check boxes&lt;br /&gt;
          var form = document.getElementById(&amp;quot;chartCriteria&amp;quot;);&lt;br /&gt;
 while (form.firstChild) //Clear out the old check boxes&lt;br /&gt;
              form.removeChild(form.firstChild);&lt;br /&gt;
 if (currentRound == -1) //Don't show criteria for 'all rounds'&lt;br /&gt;
              return;&lt;br /&gt;
          chartData[currentRound].forEach(function(dat, i) {&lt;br /&gt;
              var checkbox = document.createElement('input');&lt;br /&gt;
              checkbox.type = &amp;quot;checkbox&amp;quot;;&lt;br /&gt;
              checkbox.id = &amp;quot;checkboxoption&amp;quot; + i;&lt;br /&gt;
 checkbox.onclick = function() { //Register callback to toggle the criterion&lt;br /&gt;
                  checkboxUpdate(i);&lt;br /&gt;
              }&lt;br /&gt;
              var label = document.createElement('label')&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;form id=&amp;quot;chartOptions&amp;quot; name=&amp;quot;chartOptions&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;select id=&amp;quot;chartRounds&amp;quot; name=&amp;quot;rounds&amp;quot; &lt;br /&gt;
 onChange=&amp;quot;updateChart(document.chartOptions.chartRounds.options[document.chartOptions.chartRounds.options.selectedIndex].value)&amp;quot; style = &amp;quot;display: none&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;/select&amp;gt;&lt;br /&gt;
 &amp;lt;label&amp;gt;&amp;lt;input type=&amp;quot;checkbox&amp;quot; id = &amp;quot;labelCheck&amp;quot; checked=&amp;quot;checked&amp;quot; style=&amp;quot;display: none&amp;quot; onclick=&amp;quot;showLabels = !showLabels; renderChart();&amp;quot;&amp;gt;Show &lt;br /&gt;
 Labels&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;/form&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;chartCriteria&amp;quot; name=&amp;quot;chartCriteria&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== app/controllers/grades_controller.rb ===&lt;br /&gt;
&lt;br /&gt;
 def action_allowed?&lt;br /&gt;
     case params[:action]&lt;br /&gt;
     when 'view_my_scores'&lt;br /&gt;
       ['Instructor',&lt;br /&gt;
        'Teaching Assistant',&lt;br /&gt;
        'Administrator',&lt;br /&gt;
        'Super-Administrator',&lt;br /&gt;
       'Student'].include? current_role_name and&lt;br /&gt;
        are_needed_authorizations_present?(params[:id], &amp;quot;reader&amp;quot;, &amp;quot;reviewer&amp;quot;) and&lt;br /&gt;
        check_self_review_status&lt;br /&gt;
 when 'view_team'&lt;br /&gt;
      if ['Student'].include? current_role_name # students can only see the head map for their own team&lt;br /&gt;
        participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
        session[:user].id == participant.user_id&lt;br /&gt;
      else&lt;br /&gt;
 true&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      ['Instructor',&lt;br /&gt;
       'Teaching Assistant',&lt;br /&gt;
       'Administrator',&lt;br /&gt;
       'Super-Administrator'].include? current_role_name&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
   # collects the question text for display on the chart&lt;br /&gt;
   # Added as part of E1859&lt;br /&gt;
   def assign_chart_text&lt;br /&gt;
     @text = []&lt;br /&gt;
     (1..@assignment.num_review_rounds).to_a.each do |round|&lt;br /&gt;
       question = @questions[('review' + round.to_s).to_sym]&lt;br /&gt;
       @text[round - 1] = []&lt;br /&gt;
       next if question.nil?&lt;br /&gt;
       (0..(question.length - 1)).to_a.each do |q|&lt;br /&gt;
         @text[round - 1][q] = question[q].txt&lt;br /&gt;
       end&lt;br /&gt;
     end&lt;br /&gt;
   end&lt;br /&gt;
 &lt;br /&gt;
   # find the maximum and minimum scores for each questionnaire round&lt;br /&gt;
   # Added as part of E1859&lt;br /&gt;
   def assign_minmax(questionnaires)&lt;br /&gt;
     @minmax = []&lt;br /&gt;
     questionnaires.each do |questionnaire|&lt;br /&gt;
      next if questionnaire.symbol != :review&lt;br /&gt;
      round = AssignmentQuestionnaire.where(assignment_id: @assignment.id, questionnaire_id: questionnaire.id).first.used_in_round&lt;br /&gt;
      next if round.nil?&lt;br /&gt;
  @minmax[round - 1] = []&lt;br /&gt;
      @minmax[round - 1][0] = if !questionnaire.min_question_score.nil? and questionnaire.min_question_score &amp;lt; 0&lt;br /&gt;
                                questionnaire.min_question_score&lt;br /&gt;
                              else&lt;br /&gt;
                                0&lt;br /&gt;
                              end&lt;br /&gt;
      @minmax[round - 1][1] = if !questionnaire.max_question_score.nil?&lt;br /&gt;
                                questionnaire.max_question_score&lt;br /&gt;
                              else&lt;br /&gt;
                                5&lt;br /&gt;
                              end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 # this method collects and averages all the review scores across teams&lt;br /&gt;
   # Added as part of E1859&lt;br /&gt;
   def assign_chart_data&lt;br /&gt;
     @rounds = @assignment.num_review_rounds&lt;br /&gt;
     @chartdata = []&lt;br /&gt;
     (1..@rounds).to_a.each do |round|&lt;br /&gt;
       @teams = AssignmentTeam.where(parent_id: @assignment.id)&lt;br /&gt;
       @teamids = []&lt;br /&gt;
       @result = []&lt;br /&gt;
       @responseids = []&lt;br /&gt;
       @scoreviews = []&lt;br /&gt;
       (0..(@teams.length - 1)).to_a.each do |t|&lt;br /&gt;
         @teamids[t] = @teams[t].id&lt;br /&gt;
         @result[t] = ResponseMap.find_by_sql [&amp;quot;SELECT id FROM response_maps&lt;br /&gt;
           WHERE type = 'ReviewResponseMap' AND reviewee_id = ?&amp;quot;, @teamids[t]]&lt;br /&gt;
         @responseids[t] = []&lt;br /&gt;
         @scoreviews[t] = []&lt;br /&gt;
         (0..(@result[t].length - 1)).to_a.each do |r|&lt;br /&gt;
           @responseids[t][r] = Response.find_by_sql [&amp;quot;SELECT id FROM responses&lt;br /&gt;
             WHERE round = ? AND map_id = ?&amp;quot;, round, @result[t][r]]&lt;br /&gt;
          @scoreviews[t][r] = Answer.where(response_id: @responseids[t][r][0]) unless @responseids[t][r].empty?&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @chartdata[round - 1] = []&lt;br /&gt;
      # because the nth first elements could be nil&lt;br /&gt;
      # iterate until a non-nil value is found or move to next round&lt;br /&gt;
      t = 0&lt;br /&gt;
      r = 0&lt;br /&gt;
 t += 1 while @scoreviews[t].nil?&lt;br /&gt;
      while t &amp;lt; @scoreviews.length and @scoreviews[t][r].nil?&lt;br /&gt;
        if r &amp;lt; @scoreviews[t].length - 1&lt;br /&gt;
          r += 1&lt;br /&gt;
        else&lt;br /&gt;
 def assign_chart_data&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      next if t &amp;gt;= @scoreviews.length&lt;br /&gt;
 (0..(@scoreviews[t][r].length - 1)).to_a.each do |q|&lt;br /&gt;
        sum = 0&lt;br /&gt;
        counter = 0&lt;br /&gt;
 def retrieve_questions(questionnaires)&lt;br /&gt;
    questionnaires.each do |questionnaire|&lt;br /&gt;
      round = AssignmentQuestionnaire.where(assignment_id: @assignment.id, questionnaire_id: questionnaire.id).first.used_in_round&lt;br /&gt;
      questionnaire_symbol = if !round.nil?&lt;br /&gt;
                         (questionnaire.symbol.to_s + round.to_s).to_sym&lt;br /&gt;
                             else&lt;br /&gt;
                               questionnaire.symbol&lt;br /&gt;
                             end&lt;br /&gt;
      @questions[questionnaire_symbol] = questionnaire.questions&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 def update&lt;br /&gt;
    if format(&amp;quot;%.2f&amp;quot;, total_score) != params[:participant][:grade]&lt;br /&gt;
      participant.update_attribute(:grade, params[:participant][:grade])&lt;br /&gt;
      message = if participant.grade.nil?&lt;br /&gt;
           &amp;quot;The computed score will be used for &amp;quot; + participant.user.name + &amp;quot;.&amp;quot;&lt;br /&gt;
                else&lt;br /&gt;
                  &amp;quot;A score of &amp;quot; + params[:participant][:grade] + &amp;quot;% has been saved for &amp;quot; + participant.user.name + &amp;quot;.&amp;quot;&lt;br /&gt;
                end&lt;br /&gt;
    end&lt;br /&gt;
    flash[:note] = message&lt;br /&gt;
    redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
&lt;br /&gt;
=== app/views/grades/_team_charts.html.erb ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;br&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;%= render :partial =&amp;gt; 'criteria_charts' %&amp;gt;&lt;br /&gt;
  &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;a href=&amp;quot;#&amp;quot; name='team-chartLink' onClick=&amp;quot;toggleElement('team-chart', 'stats');return false;&amp;quot;&amp;gt;Hide stats&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;TR style =&amp;quot;background-color: white;&amp;quot; class=&amp;quot;team&amp;quot; id=&amp;quot;team-chart&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div class=&amp;quot;circle&amp;quot; id=&amp;quot;average-score&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
      Class Average&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;TH COLSPAN=&amp;quot;8&amp;quot;&amp;gt;&lt;br /&gt;
    	&amp;lt;img src=&amp;quot;&amp;lt;%= @average_chart  %&amp;gt;&amp;quot; &amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
    	Class Distribution&lt;br /&gt;
    	&amp;lt;br&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;TH WIDTH=&amp;quot;9&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
    var myCircle = Circles.create({&lt;br /&gt;
      id:           'average-score',&lt;br /&gt;
      radius:       50,&lt;br /&gt;
      value:        &amp;lt;%= @avg_of_avg.to_i %&amp;gt;,&lt;br /&gt;
      maxValue:     100,&lt;br /&gt;
      width:        15,&lt;br /&gt;
      text:         '&amp;lt;%=@avg_of_avg.to_i%&amp;gt;',&lt;br /&gt;
      colors:       ['#FFEB99', '#FFCC00'],&lt;br /&gt;
      duration:       700,&lt;br /&gt;
      textClass:      'circles-final'&lt;br /&gt;
    });&lt;br /&gt;
  &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;style&amp;gt;&lt;br /&gt;
   .circles-final{&lt;br /&gt;
      font-size: 16px !important;&lt;br /&gt;
    }&lt;br /&gt;
  &amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test Results ==&lt;br /&gt;
The team ran both automated tests, using the RSpec framework, and manual tests of the user interface (UI), using the app. The automated tests helped to ensure that the basic functionality of the app still worked, while the UI tests ensured that the visualizations were correct.&lt;br /&gt;
&lt;br /&gt;
=== RSpec Test Results ===&lt;br /&gt;
In order to ensure that our changes did not affect basic functionality of the app, we made sure that all tests that passed before our changes also passed after our changes. Add statistics on the tests before our changes and matching statistics after our changes.&lt;br /&gt;
&lt;br /&gt;
=== UI Tests ===&lt;br /&gt;
To validate all functionality of the chart when adding new features or fixing old ones, the following criteria were tested manually for expected functionality:&lt;br /&gt;
&lt;br /&gt;
# Chart is displaying correctly&lt;br /&gt;
## Bars are showing up where expected&lt;br /&gt;
## Bar annotations are showing the expected value&lt;br /&gt;
## Criteria labels are for the correct bar and displaying correct values&lt;br /&gt;
## Hover text is displaying the correct values&lt;br /&gt;
## Null values are not present on the chart&lt;br /&gt;
## Correct colors are used for the multi-round view&lt;br /&gt;
# Show Labels checkbox works as expected&lt;br /&gt;
# Round Criteria is displaying correctly&lt;br /&gt;
## Round dropdown menu shows all rounds for the assignment&lt;br /&gt;
## Selecting a round changes the criteria checkboxes&lt;br /&gt;
## All checkboxes are displayed with appropriate text&lt;br /&gt;
## Checkboxes correctly remove or add criterion bars to the chart&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1929_Visualizations_for_Instructors&amp;diff=123433</id>
		<title>E1929 Visualizations for Instructors</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1929_Visualizations_for_Instructors&amp;diff=123433"/>
		<updated>2019-04-07T20:15:42Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Expertiza is an online assignment grading platform. Instructors can create assignments and implement peer reviews for submitted assignments. This project concerns the creation of a system for visualizing student performance on those assignments, primarily as graded in peer reviews. Graphs will be made to show various rubric criteria and the class' performance on the criteria. If the criteria are the same for multiple stages of review, an instructor should be able to compare performance over time or between reviews. Our task is to provide an interactive visualization or a table for instructors that shows how their class performed on selected rubric criteria. Such feature would be immensely helpful for instructors as it would assist them to identify what they need to focus more attention on. For example, creating a graph showing the average scores for all or a certain subset of main rubric criteria (questionnaire). If the average score of the class on selected criteria (question) is low means the instructor can emphasize more on the learning materials related to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed Changes ==&lt;br /&gt;
The visualizations will be implemented as either a single or stacked bar chart with a bar for each of the selected criteria to be observed. If a single bar, then the height of the bar will be the total class average, but a stacked bar chart may be better to show the percentage of the class that received each score.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. On clicking Manage and then on assignments, following page appears.&lt;br /&gt;
&lt;br /&gt;
2. Click on 'view score' icon of an assignment. The summary report page of the selected assignment comes up.&lt;br /&gt;
&lt;br /&gt;
3. Following are mockup screens which we wish to create:&lt;br /&gt;
&lt;br /&gt;
a) Instructor would select the round and rubric criteria of the assignment for which he/she wants to view the class performance.&lt;br /&gt;
 &lt;br /&gt;
b) The bar graph of the class performance for those criteria would be displayed.&lt;br /&gt;
&lt;br /&gt;
== Project Design ==&lt;br /&gt;
 The changes made to the expertiza project will primarily include HTML/ERB changes to the view files to accommodate the added charts on the page and the necessary javascript to allow responsive design. Brief controller modifications will be made to facilitate database filtering to get the displayed data.&lt;br /&gt;
&lt;br /&gt;
=== Design Flow ===&lt;br /&gt;
The flowchart representing graphical flow of an instructor visiting view scores under assignments is given below:&lt;br /&gt;
&lt;br /&gt;
[[File:A3.png]]&lt;br /&gt;
&lt;br /&gt;
=== Tools and Design Choice ===&lt;br /&gt;
We have used the lightweight [https://developers.google.com/chart/ Google Charts] library for displaying the chart data on the page, with standard HTML for all of the options and dropdowns for option selection. Google Charts was chosen because of its high compatibility, full option set, and comparable graphical quality to the rest of expertiza while keeping a small JS footprint, which should help prevent slow page responsiveness.&lt;br /&gt;
&lt;br /&gt;
=== Visualization ===&lt;br /&gt;
The following graph shows the view of the 'view scores' page after the modifications. The instructor selects a subset of rubric criteria for which he/she wants to know how a class performed for a particular round. A bar graph of the average score of the class for that subset of criteria is displayed. &lt;br /&gt;
&lt;br /&gt;
The above graph shows an average score of the class for 10 rubric criteria in Round 1 for assignment &amp;quot;OSS project/Writing assignment 2&amp;quot; selected by the instructor. A live demo with randomly generated data can be found on [https://jsfiddle.net/Jereman/5uxqr92y/ JSFiddle]&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
The team plans to perform both automated tests, using the RSpec framework, and manual tests of the user interface (UI), using the app.&lt;br /&gt;
&lt;br /&gt;
=== RSpec Framework Tests ===&lt;br /&gt;
The RSpec Testing Framework, automated testing, will be used to verify the Models of the Expertiza Rails Web application feature set. Since this feature is dealing with Visualizations (charts) that is intimately tied with an Active Record Models, we will seed the Testing Database with known data via RSpec. These changes will be automatically rolled-back once the testing is complete.  &lt;br /&gt;
&lt;br /&gt;
=== Capybara Tests ===&lt;br /&gt;
Another automated testing framework that will be used is Capybara. Capybara is an browser type test to simulate a user clicking through your site. We will use this testing framework to verify that our charting object is present on the page and contains the seeded data that we had loaded.&lt;br /&gt;
&lt;br /&gt;
=== UI Tests ===&lt;br /&gt;
In addition to the automated tests above we will also perform manual testing of the newly added features to include:&lt;br /&gt;
&lt;br /&gt;
# Chart is displaying correctly&lt;br /&gt;
## Bars are showing up where expected&lt;br /&gt;
## Bar annotations are showing the expected value&lt;br /&gt;
## Criteria labels are for the correct bar and displaying correct values&lt;br /&gt;
## Hover text is displaying the correct values&lt;br /&gt;
## Null values are not present on the chart&lt;br /&gt;
## Correct colors are used for the multi-round view&lt;br /&gt;
# Show Labels checkbox works as expected&lt;br /&gt;
# Round Criteria is displaying correctly&lt;br /&gt;
## Round dropdown menu shows all rounds for the assignment&lt;br /&gt;
## Selecting a round changes the criteria checkboxes&lt;br /&gt;
## All checkboxes are displayed with appropriate text&lt;br /&gt;
## Checkboxes correctly remove or add criterion bars to the chart&lt;br /&gt;
&lt;br /&gt;
== Files Involved ==&lt;br /&gt;
We have implemented a new partial file criteria_charts to the team_chart that display the bar graph with existing data collected by the grades controller methods to the view page.&lt;br /&gt;
&lt;br /&gt;
Modified files:&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: inline-block&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app/controllers/grades_controller.rb&lt;br /&gt;
&lt;br /&gt;
app/views/grades/_teams.html.erb&lt;br /&gt;
&lt;br /&gt;
app/views/grades/_criteria_charts.html.erb&lt;br /&gt;
&lt;br /&gt;
app/views/grades/_team_charts.html.erb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== app/views/grades/_criteria_charts.html.erb ===&lt;br /&gt;
 &amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&lt;br /&gt;
 &amp;lt;%= content_tag :div, class: &amp;quot;chartdata_information&amp;quot;, data: {chartdata: @chartdata} do %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
 &amp;lt;%= content_tag :div, class: &amp;quot;text_information&amp;quot;, data: {text: @text} do %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;%= content_tag :div, class: &amp;quot;minmax_information&amp;quot;, data: {minmax: @minmax} do %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
 &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://www.gstatic.com/charts/loader.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
      google.charts.load('current', {packages: ['corechart', 'bar']});&lt;br /&gt;
       //Display Options&lt;br /&gt;
      var showLabels = true;&lt;br /&gt;
      var barColors = [ // Other colors generated from the expertiza base red&lt;br /&gt;
          '#A90201',    // using paletton.com&lt;br /&gt;
          '#018701',&lt;br /&gt;
          '#016565',&lt;br /&gt;
          '#A94D01'&lt;br /&gt;
      ];&lt;br /&gt;
      function getData(){ //Loads all chart data from the page&lt;br /&gt;
        chartData = $('.chartdata_information').data('chartdata');&lt;br /&gt;
        chartText = $('.text_information').data('text');&lt;br /&gt;
        chartRange = $('.minmax_information').data('minmax');&lt;br /&gt;
 for (var i = 0; i &amp;lt; chartData.length; i++){ //Set all the criteriaSelected to true&lt;br /&gt;
          var criteria = [];&lt;br /&gt;
          for (var j = 0; j &amp;lt; chartData[i].length; j++){&lt;br /&gt;
            criteria.push(true);&lt;br /&gt;
          }&lt;br /&gt;
          criteriaSelected.push(criteria);&lt;br /&gt;
        }&lt;br /&gt;
     }&lt;br /&gt;
       function generateData() {	//Generates random data for testing&lt;br /&gt;
        var rounds = 3;&lt;br /&gt;
        for(var i = 0; i &amp;lt; rounds; i++) {&lt;br /&gt;
  var criteriaNum = Math.floor(Math.random() * 5 + 5);  //Random number of criteria&lt;br /&gt;
          var round = [];&lt;br /&gt;
          var criteria = [];&lt;br /&gt;
          for(var j = 0; j &amp;lt; criteriaNum; j++) {&lt;br /&gt;
  round.push(Math.floor(Math.random() * 101));  //Random score for each criterion&lt;br /&gt;
            criteria.push(true);  //Everything starts out true&lt;br /&gt;
          }&lt;br /&gt;
          chartData.push(round);&lt;br /&gt;
          criteriaSelected.push(criteria);&lt;br /&gt;
 &lt;br /&gt;
        chartOptions = {		//Render options for the chart&lt;br /&gt;
          title: 'Class Average on Criteria',&lt;br /&gt;
          titleTextStyle: {&lt;br /&gt;
  fontName: 'arial',&lt;br /&gt;
            fontSize: 18,&lt;br /&gt;
            italic: false,&lt;br /&gt;
            bold: true&lt;br /&gt;
         chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));&lt;br /&gt;
        var checkBox = document.getElementById(&amp;quot;labelCheck&amp;quot;);&lt;br /&gt;
        checkBox.checked = true;&lt;br /&gt;
        checkBox.style.display = &amp;quot;inline&amp;quot;;&lt;br /&gt;
        updateChart(currentRound);&lt;br /&gt;
        loadRounds(); }&lt;br /&gt;
 function updateChart(roundNum) {	//Updates the chart with a new round number and renders&lt;br /&gt;
        currentRound = roundNum;&lt;br /&gt;
        renderChart();&lt;br /&gt;
        loadCriteria();&lt;br /&gt;
      function renderChart() {	//Renders the chart if changes have been made&lt;br /&gt;
          var data = loadData();&lt;br /&gt;
 chartOptions.vAxis.viewWindow.max = 5;&lt;br /&gt;
          chartOptions.vAxis.viewWindow.min = 0;&lt;br /&gt;
          if (chartRange[currentRound]) { //Set axis ranges if they exist&lt;br /&gt;
              if (chartRange[currentRound][1])&lt;br /&gt;
                  chartOptions.vAxis.viewWindow.max = chartRange[currentRound][1];&lt;br /&gt;
 if (chartRange[currentRound][0])&lt;br /&gt;
                  chartOptions.vAxis.viewWindow.min = chartRange[currentRound][0];&lt;br /&gt;
 }&lt;br /&gt;
          chart.draw(data, chartOptions);&lt;br /&gt;
      }&lt;br /&gt;
 &lt;br /&gt;
           chartOptions.hAxis.ticks = [];&lt;br /&gt;
          var rowCount = 1;&lt;br /&gt;
 for(var i = 0; i &amp;lt; chartData[currentRound].length; i++) { //Add a chart row for each criterion if not null&lt;br /&gt;
              if (criteriaSelected[currentRound][i] &amp;amp;&amp;amp; chartData[currentRound][i]) {&lt;br /&gt;
  data.addRow([rowCount, chartData[currentRound][i], barColors[0], (showLabels) ? chartData[currentRound][i].toFixed(1).toString() : &amp;quot;&amp;quot;]);&lt;br /&gt;
                  chartOptions.hAxis.ticks.push({v: rowCount++, f: (i+1).toString()});&lt;br /&gt;
              }&lt;br /&gt;
          }&lt;br /&gt;
 &lt;br /&gt;
          var data = new google.visualization.DataTable();&lt;br /&gt;
          data.addColumn('number', 'Criterion');&lt;br /&gt;
          var i;&lt;br /&gt;
 for(i = 0; i &amp;lt; roundNum; i++) { //Add all columns for the data&lt;br /&gt;
              data.addColumn('number', 'Round ' + (i+1).toString());&lt;br /&gt;
              data.addColumn({type: 'string', role: 'style'});	//column for specifying the bar color&lt;br /&gt;
              data.addColumn({type: 'string', role: 'annotation'});&lt;br /&gt;
 &lt;br /&gt;
              var newRow = [];&lt;br /&gt;
              var elementsAdded = false;&lt;br /&gt;
              newRow.push(rowCount);&lt;br /&gt;
 for(var j = 0; j &amp;lt; roundNum; j++) { //If the round has the criterion, add it&lt;br /&gt;
                  if (chartData[j][i]) {&lt;br /&gt;
                      newRow.push(chartData[j][i]);&lt;br /&gt;
                      elementsAdded = true;&lt;br /&gt;
                  } else {&lt;br /&gt;
                      newRow.push(null);&lt;br /&gt;
                  }&lt;br /&gt;
  newRow.push(barColors[j % barColors.length]); //Add column color&lt;br /&gt;
                  if (chartData[j] &amp;amp;&amp;amp; chartData[j][i] &amp;amp;&amp;amp; showLabels)&lt;br /&gt;
  newRow.push(chartData[j][i].toFixed(1).toString()); //Add column annotations&lt;br /&gt;
                  else&lt;br /&gt;
                      newRow.push(&amp;quot;&amp;quot;);&lt;br /&gt;
              }&lt;br /&gt;
       function loadCriteria() {	//Creates the criteria check boxes&lt;br /&gt;
          var form = document.getElementById(&amp;quot;chartCriteria&amp;quot;);&lt;br /&gt;
 while (form.firstChild) //Clear out the old check boxes&lt;br /&gt;
              form.removeChild(form.firstChild);&lt;br /&gt;
 if (currentRound == -1) //Don't show criteria for 'all rounds'&lt;br /&gt;
              return;&lt;br /&gt;
          chartData[currentRound].forEach(function(dat, i) {&lt;br /&gt;
              var checkbox = document.createElement('input');&lt;br /&gt;
              checkbox.type = &amp;quot;checkbox&amp;quot;;&lt;br /&gt;
              checkbox.id = &amp;quot;checkboxoption&amp;quot; + i;&lt;br /&gt;
 checkbox.onclick = function() { //Register callback to toggle the criterion&lt;br /&gt;
                  checkboxUpdate(i);&lt;br /&gt;
              }&lt;br /&gt;
              var label = document.createElement('label')&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;form id=&amp;quot;chartOptions&amp;quot; name=&amp;quot;chartOptions&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;select id=&amp;quot;chartRounds&amp;quot; name=&amp;quot;rounds&amp;quot; &lt;br /&gt;
 onChange=&amp;quot;updateChart(document.chartOptions.chartRounds.options[document.chartOptions.chartRounds.options.selectedIndex].value)&amp;quot; style = &amp;quot;display: none&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;/select&amp;gt;&lt;br /&gt;
 &amp;lt;label&amp;gt;&amp;lt;input type=&amp;quot;checkbox&amp;quot; id = &amp;quot;labelCheck&amp;quot; checked=&amp;quot;checked&amp;quot; style=&amp;quot;display: none&amp;quot; onclick=&amp;quot;showLabels = !showLabels; renderChart();&amp;quot;&amp;gt;Show &lt;br /&gt;
 Labels&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;/form&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;chartCriteria&amp;quot; name=&amp;quot;chartCriteria&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== app/controllers/grades_controller.rb ===&lt;br /&gt;
&lt;br /&gt;
 def action_allowed?&lt;br /&gt;
     case params[:action]&lt;br /&gt;
     when 'view_my_scores'&lt;br /&gt;
       ['Instructor',&lt;br /&gt;
        'Teaching Assistant',&lt;br /&gt;
        'Administrator',&lt;br /&gt;
        'Super-Administrator',&lt;br /&gt;
       'Student'].include? current_role_name and&lt;br /&gt;
        are_needed_authorizations_present?(params[:id], &amp;quot;reader&amp;quot;, &amp;quot;reviewer&amp;quot;) and&lt;br /&gt;
        check_self_review_status&lt;br /&gt;
 when 'view_team'&lt;br /&gt;
      if ['Student'].include? current_role_name # students can only see the head map for their own team&lt;br /&gt;
        participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
        session[:user].id == participant.user_id&lt;br /&gt;
      else&lt;br /&gt;
 true&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      ['Instructor',&lt;br /&gt;
       'Teaching Assistant',&lt;br /&gt;
       'Administrator',&lt;br /&gt;
       'Super-Administrator'].include? current_role_name&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
   # collects the question text for display on the chart&lt;br /&gt;
   # Added as part of E1859&lt;br /&gt;
   def assign_chart_text&lt;br /&gt;
     @text = []&lt;br /&gt;
     (1..@assignment.num_review_rounds).to_a.each do |round|&lt;br /&gt;
       question = @questions[('review' + round.to_s).to_sym]&lt;br /&gt;
       @text[round - 1] = []&lt;br /&gt;
       next if question.nil?&lt;br /&gt;
       (0..(question.length - 1)).to_a.each do |q|&lt;br /&gt;
         @text[round - 1][q] = question[q].txt&lt;br /&gt;
       end&lt;br /&gt;
     end&lt;br /&gt;
   end&lt;br /&gt;
 &lt;br /&gt;
   # find the maximum and minimum scores for each questionnaire round&lt;br /&gt;
   # Added as part of E1859&lt;br /&gt;
   def assign_minmax(questionnaires)&lt;br /&gt;
     @minmax = []&lt;br /&gt;
     questionnaires.each do |questionnaire|&lt;br /&gt;
      next if questionnaire.symbol != :review&lt;br /&gt;
      round = AssignmentQuestionnaire.where(assignment_id: @assignment.id, questionnaire_id: questionnaire.id).first.used_in_round&lt;br /&gt;
      next if round.nil?&lt;br /&gt;
  @minmax[round - 1] = []&lt;br /&gt;
      @minmax[round - 1][0] = if !questionnaire.min_question_score.nil? and questionnaire.min_question_score &amp;lt; 0&lt;br /&gt;
                                questionnaire.min_question_score&lt;br /&gt;
                              else&lt;br /&gt;
                                0&lt;br /&gt;
                              end&lt;br /&gt;
      @minmax[round - 1][1] = if !questionnaire.max_question_score.nil?&lt;br /&gt;
                                questionnaire.max_question_score&lt;br /&gt;
                              else&lt;br /&gt;
                                5&lt;br /&gt;
                              end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 # this method collects and averages all the review scores across teams&lt;br /&gt;
   # Added as part of E1859&lt;br /&gt;
   def assign_chart_data&lt;br /&gt;
     @rounds = @assignment.num_review_rounds&lt;br /&gt;
     @chartdata = []&lt;br /&gt;
     (1..@rounds).to_a.each do |round|&lt;br /&gt;
       @teams = AssignmentTeam.where(parent_id: @assignment.id)&lt;br /&gt;
       @teamids = []&lt;br /&gt;
       @result = []&lt;br /&gt;
       @responseids = []&lt;br /&gt;
       @scoreviews = []&lt;br /&gt;
       (0..(@teams.length - 1)).to_a.each do |t|&lt;br /&gt;
         @teamids[t] = @teams[t].id&lt;br /&gt;
         @result[t] = ResponseMap.find_by_sql [&amp;quot;SELECT id FROM response_maps&lt;br /&gt;
           WHERE type = 'ReviewResponseMap' AND reviewee_id = ?&amp;quot;, @teamids[t]]&lt;br /&gt;
         @responseids[t] = []&lt;br /&gt;
         @scoreviews[t] = []&lt;br /&gt;
         (0..(@result[t].length - 1)).to_a.each do |r|&lt;br /&gt;
           @responseids[t][r] = Response.find_by_sql [&amp;quot;SELECT id FROM responses&lt;br /&gt;
             WHERE round = ? AND map_id = ?&amp;quot;, round, @result[t][r]]&lt;br /&gt;
          @scoreviews[t][r] = Answer.where(response_id: @responseids[t][r][0]) unless @responseids[t][r].empty?&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @chartdata[round - 1] = []&lt;br /&gt;
      # because the nth first elements could be nil&lt;br /&gt;
      # iterate until a non-nil value is found or move to next round&lt;br /&gt;
      t = 0&lt;br /&gt;
      r = 0&lt;br /&gt;
 t += 1 while @scoreviews[t].nil?&lt;br /&gt;
      while t &amp;lt; @scoreviews.length and @scoreviews[t][r].nil?&lt;br /&gt;
        if r &amp;lt; @scoreviews[t].length - 1&lt;br /&gt;
          r += 1&lt;br /&gt;
        else&lt;br /&gt;
 def assign_chart_data&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      next if t &amp;gt;= @scoreviews.length&lt;br /&gt;
 (0..(@scoreviews[t][r].length - 1)).to_a.each do |q|&lt;br /&gt;
        sum = 0&lt;br /&gt;
        counter = 0&lt;br /&gt;
 def retrieve_questions(questionnaires)&lt;br /&gt;
    questionnaires.each do |questionnaire|&lt;br /&gt;
      round = AssignmentQuestionnaire.where(assignment_id: @assignment.id, questionnaire_id: questionnaire.id).first.used_in_round&lt;br /&gt;
      questionnaire_symbol = if !round.nil?&lt;br /&gt;
                         (questionnaire.symbol.to_s + round.to_s).to_sym&lt;br /&gt;
                             else&lt;br /&gt;
                               questionnaire.symbol&lt;br /&gt;
                             end&lt;br /&gt;
      @questions[questionnaire_symbol] = questionnaire.questions&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 def update&lt;br /&gt;
    if format(&amp;quot;%.2f&amp;quot;, total_score) != params[:participant][:grade]&lt;br /&gt;
      participant.update_attribute(:grade, params[:participant][:grade])&lt;br /&gt;
      message = if participant.grade.nil?&lt;br /&gt;
           &amp;quot;The computed score will be used for &amp;quot; + participant.user.name + &amp;quot;.&amp;quot;&lt;br /&gt;
                else&lt;br /&gt;
                  &amp;quot;A score of &amp;quot; + params[:participant][:grade] + &amp;quot;% has been saved for &amp;quot; + participant.user.name + &amp;quot;.&amp;quot;&lt;br /&gt;
                end&lt;br /&gt;
    end&lt;br /&gt;
    flash[:note] = message&lt;br /&gt;
    redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
&lt;br /&gt;
=== app/views/grades/_team_charts.html.erb ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;br&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;%= render :partial =&amp;gt; 'criteria_charts' %&amp;gt;&lt;br /&gt;
  &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;a href=&amp;quot;#&amp;quot; name='team-chartLink' onClick=&amp;quot;toggleElement('team-chart', 'stats');return false;&amp;quot;&amp;gt;Hide stats&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;TR style =&amp;quot;background-color: white;&amp;quot; class=&amp;quot;team&amp;quot; id=&amp;quot;team-chart&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div class=&amp;quot;circle&amp;quot; id=&amp;quot;average-score&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
      Class Average&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;TH COLSPAN=&amp;quot;8&amp;quot;&amp;gt;&lt;br /&gt;
    	&amp;lt;img src=&amp;quot;&amp;lt;%= @average_chart  %&amp;gt;&amp;quot; &amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
    	Class Distribution&lt;br /&gt;
    	&amp;lt;br&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;TH WIDTH=&amp;quot;9&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
    var myCircle = Circles.create({&lt;br /&gt;
      id:           'average-score',&lt;br /&gt;
      radius:       50,&lt;br /&gt;
      value:        &amp;lt;%= @avg_of_avg.to_i %&amp;gt;,&lt;br /&gt;
      maxValue:     100,&lt;br /&gt;
      width:        15,&lt;br /&gt;
      text:         '&amp;lt;%=@avg_of_avg.to_i%&amp;gt;',&lt;br /&gt;
      colors:       ['#FFEB99', '#FFCC00'],&lt;br /&gt;
      duration:       700,&lt;br /&gt;
      textClass:      'circles-final'&lt;br /&gt;
    });&lt;br /&gt;
  &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;style&amp;gt;&lt;br /&gt;
   .circles-final{&lt;br /&gt;
      font-size: 16px !important;&lt;br /&gt;
    }&lt;br /&gt;
  &amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test Results ==&lt;br /&gt;
The team ran both automated tests, using the RSpec framework, and manual tests of the user interface (UI), using the app. The automated tests helped to ensure that the basic functionality of the app still worked, while the UI tests ensured that the visualizations were correct.&lt;br /&gt;
&lt;br /&gt;
=== RSpec Test Results ===&lt;br /&gt;
In order to ensure that our changes did not affect basic functionality of the app, we made sure that all tests that passed before our changes also passed after our changes. Add statistics on the tests before our changes and matching statistics after our changes.&lt;br /&gt;
&lt;br /&gt;
=== UI Tests ===&lt;br /&gt;
To validate all functionality of the chart when adding new features or fixing old ones, the following criteria were tested manually for expected functionality:&lt;br /&gt;
&lt;br /&gt;
# Chart is displaying correctly&lt;br /&gt;
## Bars are showing up where expected&lt;br /&gt;
## Bar annotations are showing the expected value&lt;br /&gt;
## Criteria labels are for the correct bar and displaying correct values&lt;br /&gt;
## Hover text is displaying the correct values&lt;br /&gt;
## Null values are not present on the chart&lt;br /&gt;
## Correct colors are used for the multi-round view&lt;br /&gt;
# Show Labels checkbox works as expected&lt;br /&gt;
# Round Criteria is displaying correctly&lt;br /&gt;
## Round dropdown menu shows all rounds for the assignment&lt;br /&gt;
## Selecting a round changes the criteria checkboxes&lt;br /&gt;
## All checkboxes are displayed with appropriate text&lt;br /&gt;
## Checkboxes correctly remove or add criterion bars to the chart&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1929_Visualizations_for_Instructors&amp;diff=123432</id>
		<title>E1929 Visualizations for Instructors</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1929_Visualizations_for_Instructors&amp;diff=123432"/>
		<updated>2019-04-07T20:14:37Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* Test Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Expertiza is an online assignment grading platform. Instructors can create assignments and implement peer reviews for submitted assignments. This project concerns the creation of a system for visualizing student performance on those assignments, primarily as graded in peer reviews. Graphs will be made to show various rubric criteria and the class' performance on the criteria. If the criteria are the same for multiple stages of review, an instructor should be able to compare performance over time or between reviews. Our task is to provide an interactive visualization or a table for instructors that shows how their class performed on selected rubric criteria. Such feature would be immensely helpful for instructors as it would assist them to identify what they need to focus more attention on. For example, creating a graph showing the average scores for all or a certain subset of main rubric criteria (questionnaire). If the average score of the class on selected criteria (question) is low means the instructor can emphasize more on the learning materials related to it.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Proposed Changes ==&lt;br /&gt;
The visualizations will be implemented as either a single or stacked bar chart with a bar for each of the selected criteria to be observed. If a single bar, then the height of the bar will be the total class average, but a stacked bar chart may be better to show the percentage of the class that received each score.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. On clicking Manage and then on assignments, following page appears.&lt;br /&gt;
&lt;br /&gt;
2. Click on 'view score' icon of an assignment. The summary report page of the selected assignment comes up.&lt;br /&gt;
&lt;br /&gt;
3. Following are mockup screens which we wish to create:&lt;br /&gt;
&lt;br /&gt;
a) Instructor would select the round and rubric criteria of the assignment for which he/she wants to view the class performance.&lt;br /&gt;
 &lt;br /&gt;
b) The bar graph of the class performance for those criteria would be displayed.&lt;br /&gt;
&lt;br /&gt;
== Project Design ==&lt;br /&gt;
 The changes made to the expertiza project will primarily include HTML/ERB changes to the view files to accommodate the added charts on the page and the necessary javascript to allow responsive design. Brief controller modifications will be made to facilitate database filtering to get the displayed data.&lt;br /&gt;
&lt;br /&gt;
=== Design Flow ===&lt;br /&gt;
The flowchart representing graphical flow of an instructor visiting view scores under assignments is given below:&lt;br /&gt;
&lt;br /&gt;
[[File:A3.png]]&lt;br /&gt;
&lt;br /&gt;
=== Tools and Design Choice ===&lt;br /&gt;
We have used the lightweight [https://developers.google.com/chart/ Google Charts] library for displaying the chart data on the page, with standard HTML for all of the options and dropdowns for option selection. Google Charts was chosen because of its high compatibility, full option set, and comparable graphical quality to the rest of expertiza while keeping a small JS footprint, which should help prevent slow page responsiveness.&lt;br /&gt;
&lt;br /&gt;
=== Visualization ===&lt;br /&gt;
The following graph shows the view of the 'view scores' page after the modifications. The instructor selects a subset of rubric criteria for which he/she wants to know how a class performed for a particular round. A bar graph of the average score of the class for that subset of criteria is displayed. &lt;br /&gt;
&lt;br /&gt;
The above graph shows an average score of the class for 10 rubric criteria in Round 1 for assignment &amp;quot;OSS project/Writing assignment 2&amp;quot; selected by the instructor. A live demo with randomly generated data can be found on [https://jsfiddle.net/Jereman/5uxqr92y/ JSFiddle]&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
The team plans to perform both automated tests, using the RSpec framework, and manual tests of the user interface (UI), using the app.&lt;br /&gt;
&lt;br /&gt;
=== RSpec Framework Tests ===&lt;br /&gt;
The RSpec Testing Framework, automated testing, will be used to verify the Models of the Expertiza Rails Web application feature set. Since this feature is dealing with Visualizations (charts) that is intimately tied with an Active Record Models, we will seed the Testing Database with known data via RSpec. These changes will be automatically rolled-back once the testing is complete.  &lt;br /&gt;
&lt;br /&gt;
=== Capybara Tests ===&lt;br /&gt;
Another automated testing framework that will be used is Capybara. Capybara is browser type test to simulate a user click through your site. We will use this testing framework to verify that our charting object is present on the page and contains the seeded data that we had loaded.&lt;br /&gt;
&lt;br /&gt;
=== UI Tests ===&lt;br /&gt;
In addition to the automated tests above we will also perform manual testing of the newly added features to include:&lt;br /&gt;
&lt;br /&gt;
# Chart is displaying correctly&lt;br /&gt;
## Bars are showing up where expected&lt;br /&gt;
## Bar annotations are showing the expected value&lt;br /&gt;
## Criteria labels are for the correct bar and displaying correct values&lt;br /&gt;
## Hover text is displaying the correct values&lt;br /&gt;
## Null values are not present on the chart&lt;br /&gt;
## Correct colors are used for the multi-round view&lt;br /&gt;
# Show Labels checkbox works as expected&lt;br /&gt;
# Round Criteria is displaying correctly&lt;br /&gt;
## Round dropdown menu shows all rounds for the assignment&lt;br /&gt;
## Selecting a round changes the criteria checkboxes&lt;br /&gt;
## All checkboxes are displayed with appropriate text&lt;br /&gt;
## Checkboxes correctly remove or add criterion bars to the chart&lt;br /&gt;
&lt;br /&gt;
== Files Involved ==&lt;br /&gt;
We have implemented a new partial file criteria_charts to the team_chart that display the bar graph with existing data collected by the grades controller methods to the view page.&lt;br /&gt;
&lt;br /&gt;
Modified files:&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: inline-block&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
app/controllers/grades_controller.rb&lt;br /&gt;
&lt;br /&gt;
app/views/grades/_teams.html.erb&lt;br /&gt;
&lt;br /&gt;
app/views/grades/_criteria_charts.html.erb&lt;br /&gt;
&lt;br /&gt;
app/views/grades/_team_charts.html.erb&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== app/views/grades/_criteria_charts.html.erb ===&lt;br /&gt;
 &amp;lt;html&amp;gt;&lt;br /&gt;
  &amp;lt;head&amp;gt;&lt;br /&gt;
 &amp;lt;%= content_tag :div, class: &amp;quot;chartdata_information&amp;quot;, data: {chartdata: @chartdata} do %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
 &amp;lt;%= content_tag :div, class: &amp;quot;text_information&amp;quot;, data: {text: @text} do %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
    &amp;lt;%= content_tag :div, class: &amp;quot;minmax_information&amp;quot;, data: {minmax: @minmax} do %&amp;gt;&lt;br /&gt;
    &amp;lt;% end %&amp;gt;&lt;br /&gt;
 &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;https://www.gstatic.com/charts/loader.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
    &amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
      google.charts.load('current', {packages: ['corechart', 'bar']});&lt;br /&gt;
       //Display Options&lt;br /&gt;
      var showLabels = true;&lt;br /&gt;
      var barColors = [ // Other colors generated from the expertiza base red&lt;br /&gt;
          '#A90201',    // using paletton.com&lt;br /&gt;
          '#018701',&lt;br /&gt;
          '#016565',&lt;br /&gt;
          '#A94D01'&lt;br /&gt;
      ];&lt;br /&gt;
      function getData(){ //Loads all chart data from the page&lt;br /&gt;
        chartData = $('.chartdata_information').data('chartdata');&lt;br /&gt;
        chartText = $('.text_information').data('text');&lt;br /&gt;
        chartRange = $('.minmax_information').data('minmax');&lt;br /&gt;
 for (var i = 0; i &amp;lt; chartData.length; i++){ //Set all the criteriaSelected to true&lt;br /&gt;
          var criteria = [];&lt;br /&gt;
          for (var j = 0; j &amp;lt; chartData[i].length; j++){&lt;br /&gt;
            criteria.push(true);&lt;br /&gt;
          }&lt;br /&gt;
          criteriaSelected.push(criteria);&lt;br /&gt;
        }&lt;br /&gt;
     }&lt;br /&gt;
       function generateData() {	//Generates random data for testing&lt;br /&gt;
        var rounds = 3;&lt;br /&gt;
        for(var i = 0; i &amp;lt; rounds; i++) {&lt;br /&gt;
  var criteriaNum = Math.floor(Math.random() * 5 + 5);  //Random number of criteria&lt;br /&gt;
          var round = [];&lt;br /&gt;
          var criteria = [];&lt;br /&gt;
          for(var j = 0; j &amp;lt; criteriaNum; j++) {&lt;br /&gt;
  round.push(Math.floor(Math.random() * 101));  //Random score for each criterion&lt;br /&gt;
            criteria.push(true);  //Everything starts out true&lt;br /&gt;
          }&lt;br /&gt;
          chartData.push(round);&lt;br /&gt;
          criteriaSelected.push(criteria);&lt;br /&gt;
 &lt;br /&gt;
        chartOptions = {		//Render options for the chart&lt;br /&gt;
          title: 'Class Average on Criteria',&lt;br /&gt;
          titleTextStyle: {&lt;br /&gt;
  fontName: 'arial',&lt;br /&gt;
            fontSize: 18,&lt;br /&gt;
            italic: false,&lt;br /&gt;
            bold: true&lt;br /&gt;
         chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));&lt;br /&gt;
        var checkBox = document.getElementById(&amp;quot;labelCheck&amp;quot;);&lt;br /&gt;
        checkBox.checked = true;&lt;br /&gt;
        checkBox.style.display = &amp;quot;inline&amp;quot;;&lt;br /&gt;
        updateChart(currentRound);&lt;br /&gt;
        loadRounds(); }&lt;br /&gt;
 function updateChart(roundNum) {	//Updates the chart with a new round number and renders&lt;br /&gt;
        currentRound = roundNum;&lt;br /&gt;
        renderChart();&lt;br /&gt;
        loadCriteria();&lt;br /&gt;
      function renderChart() {	//Renders the chart if changes have been made&lt;br /&gt;
          var data = loadData();&lt;br /&gt;
 chartOptions.vAxis.viewWindow.max = 5;&lt;br /&gt;
          chartOptions.vAxis.viewWindow.min = 0;&lt;br /&gt;
          if (chartRange[currentRound]) { //Set axis ranges if they exist&lt;br /&gt;
              if (chartRange[currentRound][1])&lt;br /&gt;
                  chartOptions.vAxis.viewWindow.max = chartRange[currentRound][1];&lt;br /&gt;
 if (chartRange[currentRound][0])&lt;br /&gt;
                  chartOptions.vAxis.viewWindow.min = chartRange[currentRound][0];&lt;br /&gt;
 }&lt;br /&gt;
          chart.draw(data, chartOptions);&lt;br /&gt;
      }&lt;br /&gt;
 &lt;br /&gt;
           chartOptions.hAxis.ticks = [];&lt;br /&gt;
          var rowCount = 1;&lt;br /&gt;
 for(var i = 0; i &amp;lt; chartData[currentRound].length; i++) { //Add a chart row for each criterion if not null&lt;br /&gt;
              if (criteriaSelected[currentRound][i] &amp;amp;&amp;amp; chartData[currentRound][i]) {&lt;br /&gt;
  data.addRow([rowCount, chartData[currentRound][i], barColors[0], (showLabels) ? chartData[currentRound][i].toFixed(1).toString() : &amp;quot;&amp;quot;]);&lt;br /&gt;
                  chartOptions.hAxis.ticks.push({v: rowCount++, f: (i+1).toString()});&lt;br /&gt;
              }&lt;br /&gt;
          }&lt;br /&gt;
 &lt;br /&gt;
          var data = new google.visualization.DataTable();&lt;br /&gt;
          data.addColumn('number', 'Criterion');&lt;br /&gt;
          var i;&lt;br /&gt;
 for(i = 0; i &amp;lt; roundNum; i++) { //Add all columns for the data&lt;br /&gt;
              data.addColumn('number', 'Round ' + (i+1).toString());&lt;br /&gt;
              data.addColumn({type: 'string', role: 'style'});	//column for specifying the bar color&lt;br /&gt;
              data.addColumn({type: 'string', role: 'annotation'});&lt;br /&gt;
 &lt;br /&gt;
              var newRow = [];&lt;br /&gt;
              var elementsAdded = false;&lt;br /&gt;
              newRow.push(rowCount);&lt;br /&gt;
 for(var j = 0; j &amp;lt; roundNum; j++) { //If the round has the criterion, add it&lt;br /&gt;
                  if (chartData[j][i]) {&lt;br /&gt;
                      newRow.push(chartData[j][i]);&lt;br /&gt;
                      elementsAdded = true;&lt;br /&gt;
                  } else {&lt;br /&gt;
                      newRow.push(null);&lt;br /&gt;
                  }&lt;br /&gt;
  newRow.push(barColors[j % barColors.length]); //Add column color&lt;br /&gt;
                  if (chartData[j] &amp;amp;&amp;amp; chartData[j][i] &amp;amp;&amp;amp; showLabels)&lt;br /&gt;
  newRow.push(chartData[j][i].toFixed(1).toString()); //Add column annotations&lt;br /&gt;
                  else&lt;br /&gt;
                      newRow.push(&amp;quot;&amp;quot;);&lt;br /&gt;
              }&lt;br /&gt;
       function loadCriteria() {	//Creates the criteria check boxes&lt;br /&gt;
          var form = document.getElementById(&amp;quot;chartCriteria&amp;quot;);&lt;br /&gt;
 while (form.firstChild) //Clear out the old check boxes&lt;br /&gt;
              form.removeChild(form.firstChild);&lt;br /&gt;
 if (currentRound == -1) //Don't show criteria for 'all rounds'&lt;br /&gt;
              return;&lt;br /&gt;
          chartData[currentRound].forEach(function(dat, i) {&lt;br /&gt;
              var checkbox = document.createElement('input');&lt;br /&gt;
              checkbox.type = &amp;quot;checkbox&amp;quot;;&lt;br /&gt;
              checkbox.id = &amp;quot;checkboxoption&amp;quot; + i;&lt;br /&gt;
 checkbox.onclick = function() { //Register callback to toggle the criterion&lt;br /&gt;
                  checkboxUpdate(i);&lt;br /&gt;
              }&lt;br /&gt;
              var label = document.createElement('label')&lt;br /&gt;
 &lt;br /&gt;
    &amp;lt;form id=&amp;quot;chartOptions&amp;quot; name=&amp;quot;chartOptions&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;select id=&amp;quot;chartRounds&amp;quot; name=&amp;quot;rounds&amp;quot; &lt;br /&gt;
 onChange=&amp;quot;updateChart(document.chartOptions.chartRounds.options[document.chartOptions.chartRounds.options.selectedIndex].value)&amp;quot; style = &amp;quot;display: none&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;/select&amp;gt;&lt;br /&gt;
 &amp;lt;label&amp;gt;&amp;lt;input type=&amp;quot;checkbox&amp;quot; id = &amp;quot;labelCheck&amp;quot; checked=&amp;quot;checked&amp;quot; style=&amp;quot;display: none&amp;quot; onclick=&amp;quot;showLabels = !showLabels; renderChart();&amp;quot;&amp;gt;Show &lt;br /&gt;
 Labels&amp;lt;/label&amp;gt;&lt;br /&gt;
    &amp;lt;/form&amp;gt;&lt;br /&gt;
    &amp;lt;div id=&amp;quot;chartCriteria&amp;quot; name=&amp;quot;chartCriteria&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== app/controllers/grades_controller.rb ===&lt;br /&gt;
&lt;br /&gt;
 def action_allowed?&lt;br /&gt;
     case params[:action]&lt;br /&gt;
     when 'view_my_scores'&lt;br /&gt;
       ['Instructor',&lt;br /&gt;
        'Teaching Assistant',&lt;br /&gt;
        'Administrator',&lt;br /&gt;
        'Super-Administrator',&lt;br /&gt;
       'Student'].include? current_role_name and&lt;br /&gt;
        are_needed_authorizations_present?(params[:id], &amp;quot;reader&amp;quot;, &amp;quot;reviewer&amp;quot;) and&lt;br /&gt;
        check_self_review_status&lt;br /&gt;
 when 'view_team'&lt;br /&gt;
      if ['Student'].include? current_role_name # students can only see the head map for their own team&lt;br /&gt;
        participant = AssignmentParticipant.find(params[:id])&lt;br /&gt;
        session[:user].id == participant.user_id&lt;br /&gt;
      else&lt;br /&gt;
 true&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      ['Instructor',&lt;br /&gt;
       'Teaching Assistant',&lt;br /&gt;
       'Administrator',&lt;br /&gt;
       'Super-Administrator'].include? current_role_name&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
   # collects the question text for display on the chart&lt;br /&gt;
   # Added as part of E1859&lt;br /&gt;
   def assign_chart_text&lt;br /&gt;
     @text = []&lt;br /&gt;
     (1..@assignment.num_review_rounds).to_a.each do |round|&lt;br /&gt;
       question = @questions[('review' + round.to_s).to_sym]&lt;br /&gt;
       @text[round - 1] = []&lt;br /&gt;
       next if question.nil?&lt;br /&gt;
       (0..(question.length - 1)).to_a.each do |q|&lt;br /&gt;
         @text[round - 1][q] = question[q].txt&lt;br /&gt;
       end&lt;br /&gt;
     end&lt;br /&gt;
   end&lt;br /&gt;
 &lt;br /&gt;
   # find the maximum and minimum scores for each questionnaire round&lt;br /&gt;
   # Added as part of E1859&lt;br /&gt;
   def assign_minmax(questionnaires)&lt;br /&gt;
     @minmax = []&lt;br /&gt;
     questionnaires.each do |questionnaire|&lt;br /&gt;
      next if questionnaire.symbol != :review&lt;br /&gt;
      round = AssignmentQuestionnaire.where(assignment_id: @assignment.id, questionnaire_id: questionnaire.id).first.used_in_round&lt;br /&gt;
      next if round.nil?&lt;br /&gt;
  @minmax[round - 1] = []&lt;br /&gt;
      @minmax[round - 1][0] = if !questionnaire.min_question_score.nil? and questionnaire.min_question_score &amp;lt; 0&lt;br /&gt;
                                questionnaire.min_question_score&lt;br /&gt;
                              else&lt;br /&gt;
                                0&lt;br /&gt;
                              end&lt;br /&gt;
      @minmax[round - 1][1] = if !questionnaire.max_question_score.nil?&lt;br /&gt;
                                questionnaire.max_question_score&lt;br /&gt;
                              else&lt;br /&gt;
                                5&lt;br /&gt;
                              end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 # this method collects and averages all the review scores across teams&lt;br /&gt;
   # Added as part of E1859&lt;br /&gt;
   def assign_chart_data&lt;br /&gt;
     @rounds = @assignment.num_review_rounds&lt;br /&gt;
     @chartdata = []&lt;br /&gt;
     (1..@rounds).to_a.each do |round|&lt;br /&gt;
       @teams = AssignmentTeam.where(parent_id: @assignment.id)&lt;br /&gt;
       @teamids = []&lt;br /&gt;
       @result = []&lt;br /&gt;
       @responseids = []&lt;br /&gt;
       @scoreviews = []&lt;br /&gt;
       (0..(@teams.length - 1)).to_a.each do |t|&lt;br /&gt;
         @teamids[t] = @teams[t].id&lt;br /&gt;
         @result[t] = ResponseMap.find_by_sql [&amp;quot;SELECT id FROM response_maps&lt;br /&gt;
           WHERE type = 'ReviewResponseMap' AND reviewee_id = ?&amp;quot;, @teamids[t]]&lt;br /&gt;
         @responseids[t] = []&lt;br /&gt;
         @scoreviews[t] = []&lt;br /&gt;
         (0..(@result[t].length - 1)).to_a.each do |r|&lt;br /&gt;
           @responseids[t][r] = Response.find_by_sql [&amp;quot;SELECT id FROM responses&lt;br /&gt;
             WHERE round = ? AND map_id = ?&amp;quot;, round, @result[t][r]]&lt;br /&gt;
          @scoreviews[t][r] = Answer.where(response_id: @responseids[t][r][0]) unless @responseids[t][r].empty?&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      @chartdata[round - 1] = []&lt;br /&gt;
      # because the nth first elements could be nil&lt;br /&gt;
      # iterate until a non-nil value is found or move to next round&lt;br /&gt;
      t = 0&lt;br /&gt;
      r = 0&lt;br /&gt;
 t += 1 while @scoreviews[t].nil?&lt;br /&gt;
      while t &amp;lt; @scoreviews.length and @scoreviews[t][r].nil?&lt;br /&gt;
        if r &amp;lt; @scoreviews[t].length - 1&lt;br /&gt;
          r += 1&lt;br /&gt;
        else&lt;br /&gt;
 def assign_chart_data&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
      next if t &amp;gt;= @scoreviews.length&lt;br /&gt;
 (0..(@scoreviews[t][r].length - 1)).to_a.each do |q|&lt;br /&gt;
        sum = 0&lt;br /&gt;
        counter = 0&lt;br /&gt;
 def retrieve_questions(questionnaires)&lt;br /&gt;
    questionnaires.each do |questionnaire|&lt;br /&gt;
      round = AssignmentQuestionnaire.where(assignment_id: @assignment.id, questionnaire_id: questionnaire.id).first.used_in_round&lt;br /&gt;
      questionnaire_symbol = if !round.nil?&lt;br /&gt;
                         (questionnaire.symbol.to_s + round.to_s).to_sym&lt;br /&gt;
                             else&lt;br /&gt;
                               questionnaire.symbol&lt;br /&gt;
                             end&lt;br /&gt;
      @questions[questionnaire_symbol] = questionnaire.questions&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
 def update&lt;br /&gt;
    if format(&amp;quot;%.2f&amp;quot;, total_score) != params[:participant][:grade]&lt;br /&gt;
      participant.update_attribute(:grade, params[:participant][:grade])&lt;br /&gt;
      message = if participant.grade.nil?&lt;br /&gt;
           &amp;quot;The computed score will be used for &amp;quot; + participant.user.name + &amp;quot;.&amp;quot;&lt;br /&gt;
                else&lt;br /&gt;
                  &amp;quot;A score of &amp;quot; + params[:participant][:grade] + &amp;quot;% has been saved for &amp;quot; + participant.user.name + &amp;quot;.&amp;quot;&lt;br /&gt;
                end&lt;br /&gt;
    end&lt;br /&gt;
    flash[:note] = message&lt;br /&gt;
    redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
&lt;br /&gt;
=== app/views/grades/_team_charts.html.erb ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  &amp;lt;br&amp;gt; &amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;%= render :partial =&amp;gt; 'criteria_charts' %&amp;gt;&lt;br /&gt;
  &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;a href=&amp;quot;#&amp;quot; name='team-chartLink' onClick=&amp;quot;toggleElement('team-chart', 'stats');return false;&amp;quot;&amp;gt;Hide stats&amp;lt;/a&amp;gt;&lt;br /&gt;
  &amp;lt;br&amp;gt;&lt;br /&gt;
  &amp;lt;TR style =&amp;quot;background-color: white;&amp;quot; class=&amp;quot;team&amp;quot; id=&amp;quot;team-chart&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;th&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;div class=&amp;quot;circle&amp;quot; id=&amp;quot;average-score&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
      Class Average&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;TH COLSPAN=&amp;quot;8&amp;quot;&amp;gt;&lt;br /&gt;
    	&amp;lt;img src=&amp;quot;&amp;lt;%= @average_chart  %&amp;gt;&amp;quot; &amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
    	Class Distribution&lt;br /&gt;
    	&amp;lt;br&amp;gt;&lt;br /&gt;
    &amp;lt;/th&amp;gt;&lt;br /&gt;
    &amp;lt;TH WIDTH=&amp;quot;9&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/TR&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
    var myCircle = Circles.create({&lt;br /&gt;
      id:           'average-score',&lt;br /&gt;
      radius:       50,&lt;br /&gt;
      value:        &amp;lt;%= @avg_of_avg.to_i %&amp;gt;,&lt;br /&gt;
      maxValue:     100,&lt;br /&gt;
      width:        15,&lt;br /&gt;
      text:         '&amp;lt;%=@avg_of_avg.to_i%&amp;gt;',&lt;br /&gt;
      colors:       ['#FFEB99', '#FFCC00'],&lt;br /&gt;
      duration:       700,&lt;br /&gt;
      textClass:      'circles-final'&lt;br /&gt;
    });&lt;br /&gt;
  &amp;lt;/script&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;style&amp;gt;&lt;br /&gt;
   .circles-final{&lt;br /&gt;
      font-size: 16px !important;&lt;br /&gt;
    }&lt;br /&gt;
  &amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test Results ==&lt;br /&gt;
The team ran both automated tests, using the RSpec framework, and manual tests of the user interface (UI), using the app. The automated tests helped to ensure that the basic functionality of the app still worked, while the UI tests ensured that the visualizations were correct.&lt;br /&gt;
&lt;br /&gt;
=== RSpec Test Results ===&lt;br /&gt;
In order to ensure that our changes did not affect basic functionality of the app, we made sure that all tests that passed before our changes also passed after our changes. Add statistics on the tests before our changes and matching statistics after our changes.&lt;br /&gt;
&lt;br /&gt;
=== UI Tests ===&lt;br /&gt;
To validate all functionality of the chart when adding new features or fixing old ones, the following criteria were tested manually for expected functionality:&lt;br /&gt;
&lt;br /&gt;
# Chart is displaying correctly&lt;br /&gt;
## Bars are showing up where expected&lt;br /&gt;
## Bar annotations are showing the expected value&lt;br /&gt;
## Criteria labels are for the correct bar and displaying correct values&lt;br /&gt;
## Hover text is displaying the correct values&lt;br /&gt;
## Null values are not present on the chart&lt;br /&gt;
## Correct colors are used for the multi-round view&lt;br /&gt;
# Show Labels checkbox works as expected&lt;br /&gt;
# Round Criteria is displaying correctly&lt;br /&gt;
## Round dropdown menu shows all rounds for the assignment&lt;br /&gt;
## Selecting a round changes the criteria checkboxes&lt;br /&gt;
## All checkboxes are displayed with appropriate text&lt;br /&gt;
## Checkboxes correctly remove or add criterion bars to the chart&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121926</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121926"/>
		<updated>2019-03-24T21:27:12Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* Expertiza */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Expertiza is a peer to peer application whereby students gain knowledge through submitting their work into the system and review the work of others. This is system diverges from the customary systems where a instructor or body of teaching staff would grade the papers/assignments and provide feedback to the students. This process misses out on a learning opportunity for students performing reviews. Allowing students to see the work of others allows them to see more code examples and from different aspects. This exercise during the review process forces the student to think through lecture material and apply during the process. The Expertiza application can also be used as an iterative process from class to class. The examples of the current semester can be used by students of subsequent semesters to identify short comings and suggest further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Do not use ''Time.now'' / ''Time.parse'' without zone.&lt;br /&gt;
This is very common issue reported by Code Climate. Use one of ''Time.zone.now'' / ''Time.zone.parse''&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Specify a '':dependent'' option:&lt;br /&gt;
The [https://guides.rubyonrails.org/association_basics.html#the-has-many-association has_many] association should always be specified with one of the [https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Options :dependent] options, which specifies the behavior of the associated objects whenever their owner is destroyed. This is common practice and should be utilized adequately for the Expertiza app to work correctly. No specifying '':dependent'' option could lead to run time errors, unpredictable behavior of the app, and creating orphan objects that will never be referenced again. Specify a '':dependent'' option whenever utilizing ''has_many'' association. For example, (code sample is used from ''app/models/site_controller.rb'' file):&lt;br /&gt;
  # Bad - not specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions&lt;br /&gt;
  &lt;br /&gt;
  # Good - specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions, dependent: :destroy&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use a guard clause instead of wrapping the code inside a conditional expression.&lt;br /&gt;
This is very common issue reported by Code Climate that can be easily avoided by properly utilizing `if` statements applying some logic. In general, avoid using bulk of ''if/else'' statements whenever possible. For example, (code sample is used from ''app/models/sign_up_topic.rb'' file):&lt;br /&gt;
  # Bad - too many conditional expressions that also contain nested ones&lt;br /&gt;
  if !no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
    if topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # Good - use guard close&lt;br /&gt;
  return true if no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
  topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
Above is typical example when 9 lines of code (LoC) can be reduced to 2 LoC and overall code quality improved. &lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not place comments on the same line as the ''end'' keyword.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; ''end'' at ''xxx'', ''xx'' is not aligned with ''unless'' at ''xxx'', ''xx''&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Replace class var ''@@variable_name'' with a class instance var.&lt;br /&gt;
&amp;lt;li&amp;gt; Similar blocks of code found in 2 locations. Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
* Ruby [https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf]&lt;br /&gt;
* CodeClimate [https://docs.codeclimate.com/docs]&lt;br /&gt;
* Expertiza [https://github.com/expertiza/expertiza#expertiza]&lt;br /&gt;
* E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&lt;br /&gt;
* The ''has_many'' Association [https://guides.rubyonrails.org/association_basics.html#the-has-many-association]&lt;br /&gt;
* Module ActiveRecord::Associations::ClassMethods Options [https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Options]&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121925</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121925"/>
		<updated>2019-03-24T21:26:55Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* Expertiza */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Expertiza is a peer to peer whereby students gain knowledge through submitting their work into the system and review the work of others. This is system diverges from the customary systems where a instructor or body of teaching staff would grade the papers/assignments and provide feedback to the students. This process misses out on a learning opportunity for students performing reviews. Allowing students to see the work of others allows them to see more code examples and from different aspects. This exercise during the review process forces the student to think through lecture material and apply during the process. The Expertiza application can also be used as an iterative process from class to class. The examples of the current semester can be used by students of subsequent semesters to identify short comings and suggest further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Do not use ''Time.now'' / ''Time.parse'' without zone.&lt;br /&gt;
This is very common issue reported by Code Climate. Use one of ''Time.zone.now'' / ''Time.zone.parse''&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Specify a '':dependent'' option:&lt;br /&gt;
The [https://guides.rubyonrails.org/association_basics.html#the-has-many-association has_many] association should always be specified with one of the [https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Options :dependent] options, which specifies the behavior of the associated objects whenever their owner is destroyed. This is common practice and should be utilized adequately for the Expertiza app to work correctly. No specifying '':dependent'' option could lead to run time errors, unpredictable behavior of the app, and creating orphan objects that will never be referenced again. Specify a '':dependent'' option whenever utilizing ''has_many'' association. For example, (code sample is used from ''app/models/site_controller.rb'' file):&lt;br /&gt;
  # Bad - not specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions&lt;br /&gt;
  &lt;br /&gt;
  # Good - specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions, dependent: :destroy&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use a guard clause instead of wrapping the code inside a conditional expression.&lt;br /&gt;
This is very common issue reported by Code Climate that can be easily avoided by properly utilizing `if` statements applying some logic. In general, avoid using bulk of ''if/else'' statements whenever possible. For example, (code sample is used from ''app/models/sign_up_topic.rb'' file):&lt;br /&gt;
  # Bad - too many conditional expressions that also contain nested ones&lt;br /&gt;
  if !no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
    if topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # Good - use guard close&lt;br /&gt;
  return true if no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
  topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
Above is typical example when 9 lines of code (LoC) can be reduced to 2 LoC and overall code quality improved. &lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not place comments on the same line as the ''end'' keyword.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; ''end'' at ''xxx'', ''xx'' is not aligned with ''unless'' at ''xxx'', ''xx''&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Replace class var ''@@variable_name'' with a class instance var.&lt;br /&gt;
&amp;lt;li&amp;gt; Similar blocks of code found in 2 locations. Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
* Ruby [https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf]&lt;br /&gt;
* CodeClimate [https://docs.codeclimate.com/docs]&lt;br /&gt;
* Expertiza [https://github.com/expertiza/expertiza#expertiza]&lt;br /&gt;
* E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&lt;br /&gt;
* The ''has_many'' Association [https://guides.rubyonrails.org/association_basics.html#the-has-many-association]&lt;br /&gt;
* Module ActiveRecord::Associations::ClassMethods Options [https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Options]&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121918</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121918"/>
		<updated>2019-03-24T21:14:19Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about &amp;lt;ref&amp;gt;E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Specify a '':dependent'' option:&lt;br /&gt;
The [https://guides.rubyonrails.org/association_basics.html#the-has-many-association has_many] association should always be specified with one of the [https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Options :dependent] options, which specifies the behavior of the associated objects whenever their owner is destroyed. This is common practice and should be utilized adequately for the Expertiza app to work correctly. No specifying '':dependent'' option could lead to run time errors, unpredictable behavior of the app, and creating orphan objects that will never be referenced again. Specify a '':dependent'' option whenever utilizing ''has_many'' association. For example, (code sample is used from ''app/models/site_controller.rb'' file):&lt;br /&gt;
  # Bad - not specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions&lt;br /&gt;
  &lt;br /&gt;
  # Good - specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions, dependent: :destroy&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use a guard clause instead of wrapping the code inside a conditional expression.&lt;br /&gt;
This is very common issue reported by Code Climate that can be easily avoided by properly utilizing `if` statements applying some logic. In general, avoid using bulk of ''if/else'' statements whenever possible. For example, (code sample is used from ''app/models/sign_up_topic.rb'' file):&lt;br /&gt;
  # Bad - too many conditional expressions that also contain nested ones&lt;br /&gt;
  if !no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
    if topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # Good - use guard close&lt;br /&gt;
  return true if no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
  topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
Above is typical example when 9 lines of code (LoC) can be reduced to 2 LoC and overall code quality improved. &lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not place comments on the same line as the ''end'' keyword.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; ''end'' at ''xxx'', ''xx'' is not aligned with ''unless'' at ''xxx'', ''xx''&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Replace class var ''@@variable_name'' with a class instance var.&lt;br /&gt;
&amp;lt;li&amp;gt; Similar blocks of code found in 2 locations. Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
* Ruby [https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf]&lt;br /&gt;
* CodeClimate [https://docs.codeclimate.com/docs]&lt;br /&gt;
* Expertiza [https://github.com/expertiza/expertiza#expertiza]&lt;br /&gt;
* E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121917</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121917"/>
		<updated>2019-03-24T21:12:40Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about &amp;lt;ref&amp;gt;E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Specify a '':dependent'' option:&lt;br /&gt;
The [https://guides.rubyonrails.org/association_basics.html#the-has-many-association has_many] association should always be specified with one of the [https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Options :dependent] options, which specifies the behavior of the associated objects whenever their owner is destroyed. This is common practice and should be utilized adequately for the Expertiza app to work correctly. No specifying '':dependent'' option could lead to run time errors, unpredictable behavior of the app, and creating orphan objects that will never be referenced again. Specify a '':dependent'' option whenever utilizing ''has_many'' association. For example, (code sample is used from ''app/models/site_controller.rb'' file):&lt;br /&gt;
  # Bad - not specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions&lt;br /&gt;
  &lt;br /&gt;
  # Good - specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions, dependent: :destroy&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use a guard clause instead of wrapping the code inside a conditional expression.&lt;br /&gt;
This is very common issue reported by Code Climate that can be easily avoided by properly utilizing `if` statements applying some logic. In general, avoid using bulk of ''if/else'' statements whenever possible. For example, (code sample is used from ''app/models/sign_up_topic.rb'' file):&lt;br /&gt;
  # Bad - too many conditional expressions that also contain nested ones&lt;br /&gt;
  if !no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
    if topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # Good - use guard close&lt;br /&gt;
  return true if no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
  topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
Above is typical example when 9 lines of code (LoC) can be reduced to 2 LoC and overall code quality improved. &lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not place comments on the same line as the ''end'' keyword.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; ''end'' at ''xxx'', ''xx'' is not aligned with ''unless'' at ''xxx'', ''xx''&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Replace class var ''@@variable_name'' with a class instance var.&lt;br /&gt;
&amp;lt;li&amp;gt; Similar blocks of code found in 2 locations. Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
{{Reflist|refs=&lt;br /&gt;
&amp;lt;ref name=&amp;quot;refname1&amp;quot;&amp;gt;content1&amp;lt;/ref&amp;gt;&lt;br /&gt;
&amp;lt;ref name=&amp;quot;refname2&amp;quot;&amp;gt;content2&amp;lt;/ref&amp;gt;&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121916</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121916"/>
		<updated>2019-03-24T21:11:15Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about &amp;lt;ref&amp;gt;E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Specify a '':dependent'' option:&lt;br /&gt;
The [https://guides.rubyonrails.org/association_basics.html#the-has-many-association has_many] association should always be specified with one of the [https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Options :dependent] options, which specifies the behavior of the associated objects whenever their owner is destroyed. This is common practice and should be utilized adequately for the Expertiza app to work correctly. No specifying '':dependent'' option could lead to run time errors, unpredictable behavior of the app, and creating orphan objects that will never be referenced again. Specify a '':dependent'' option whenever utilizing ''has_many'' association. For example, (code sample is used from ''app/models/site_controller.rb'' file):&lt;br /&gt;
  # Bad - not specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions&lt;br /&gt;
  &lt;br /&gt;
  # Good - specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions, dependent: :destroy&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use a guard clause instead of wrapping the code inside a conditional expression.&lt;br /&gt;
This is very common issue reported by Code Climate that can be easily avoided by properly utilizing `if` statements applying some logic. In general, avoid using bulk of ''if/else'' statements whenever possible. For example, (code sample is used from ''app/models/sign_up_topic.rb'' file):&lt;br /&gt;
  # Bad - too many conditional expressions that also contain nested ones&lt;br /&gt;
  if !no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
    if topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # Good - use guard close&lt;br /&gt;
  return true if no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
  topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
Above is typical example when 9 lines of code (LoC) can be reduced to 2 LoC and overall code quality improved. &lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not place comments on the same line as the ''end'' keyword.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; ''end'' at ''xxx'', ''xx'' is not aligned with ''unless'' at ''xxx'', ''xx''&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Replace class var ''@@variable_name'' with a class instance var.&lt;br /&gt;
&amp;lt;li&amp;gt; Similar blocks of code found in 2 locations. Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
{{Reflist}}&lt;br /&gt;
&lt;br /&gt;
{{Refbegin}}&lt;br /&gt;
* reference 1&lt;br /&gt;
* reference 2&lt;br /&gt;
{{Refend}}&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121914</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121914"/>
		<updated>2019-03-24T21:10:27Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about &amp;lt;ref&amp;gt;E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Specify a '':dependent'' option:&lt;br /&gt;
The [https://guides.rubyonrails.org/association_basics.html#the-has-many-association has_many] association should always be specified with one of the [https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Options :dependent] options, which specifies the behavior of the associated objects whenever their owner is destroyed. This is common practice and should be utilized adequately for the Expertiza app to work correctly. No specifying '':dependent'' option could lead to run time errors, unpredictable behavior of the app, and creating orphan objects that will never be referenced again. Specify a '':dependent'' option whenever utilizing ''has_many'' association. For example, (code sample is used from ''app/models/site_controller.rb'' file):&lt;br /&gt;
  # Bad - not specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions&lt;br /&gt;
  &lt;br /&gt;
  # Good - specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions, dependent: :destroy&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use a guard clause instead of wrapping the code inside a conditional expression.&lt;br /&gt;
This is very common issue reported by Code Climate that can be easily avoided by properly utilizing `if` statements applying some logic. In general, avoid using bulk of ''if/else'' statements whenever possible. For example, (code sample is used from ''app/models/sign_up_topic.rb'' file):&lt;br /&gt;
  # Bad - too many conditional expressions that also contain nested ones&lt;br /&gt;
  if !no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
    if topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # Good - use guard close&lt;br /&gt;
  return true if no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
  topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
Above is typical example when 9 lines of code (LoC) can be reduced to 2 LoC and overall code quality improved. &lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not place comments on the same line as the ''end'' keyword.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; ''end'' at ''xxx'', ''xx'' is not aligned with ''unless'' at ''xxx'', ''xx''&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Replace class var ''@@variable_name'' with a class instance var.&lt;br /&gt;
&amp;lt;li&amp;gt; Similar blocks of code found in 2 locations. Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Reflist}}&lt;br /&gt;
&lt;br /&gt;
{{Refbegin}}&lt;br /&gt;
* Ruby https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&lt;br /&gt;
* CodeClimate https://docs.codeclimate.com/docs&lt;br /&gt;
* Expertiza [https://github.com/expertiza/expertiza#expertiza]&lt;br /&gt;
* E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&lt;br /&gt;
{{Refend}}&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121913</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121913"/>
		<updated>2019-03-24T21:07:43Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about &amp;lt;ref&amp;gt;E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Specify a '':dependent'' option:&lt;br /&gt;
The [https://guides.rubyonrails.org/association_basics.html#the-has-many-association has_many] association should always be specified with one of the [https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Options :dependent] options, which specifies the behavior of the associated objects whenever their owner is destroyed. This is common practice and should be utilized adequately for the Expertiza app to work correctly. No specifying '':dependent'' option could lead to run time errors, unpredictable behavior of the app, and creating orphan objects that will never be referenced again. Specify a '':dependent'' option whenever utilizing ''has_many'' association. For example, (code sample is used from ''app/models/site_controller.rb'' file):&lt;br /&gt;
  # Bad - not specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions&lt;br /&gt;
  &lt;br /&gt;
  # Good - specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions, dependent: :destroy&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use a guard clause instead of wrapping the code inside a conditional expression.&lt;br /&gt;
This is very common issue reported by Code Climate that can be easily avoided by properly utilizing `if` statements applying some logic. In general, avoid using bulk of ''if/else'' statements whenever possible. For example, (code sample is used from ''app/models/sign_up_topic.rb'' file):&lt;br /&gt;
  # Bad - too many conditional expressions that also contain nested ones&lt;br /&gt;
  if !no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
    if topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # Good - use guard close&lt;br /&gt;
  return true if no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
  topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
Above is typical example when 9 lines of code (LoC) can be reduced to 2 LoC and overall code quality improved. &lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not place comments on the same line as the ''end'' keyword.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; ''end'' at ''xxx'', ''xx'' is not aligned with ''unless'' at ''xxx'', ''xx''&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Replace class var ''@@variable_name'' with a class instance var.&lt;br /&gt;
&amp;lt;li&amp;gt; Similar blocks of code found in 2 locations. Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Reflist}}&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121911</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121911"/>
		<updated>2019-03-24T21:05:31Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about &amp;lt;ref&amp;gt;E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Specify a '':dependent'' option:&lt;br /&gt;
The [https://guides.rubyonrails.org/association_basics.html#the-has-many-association has_many] association should always be specified with one of the [https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Options :dependent] options, which specifies the behavior of the associated objects whenever their owner is destroyed. This is common practice and should be utilized adequately for the Expertiza app to work correctly. No specifying '':dependent'' option could lead to run time errors, unpredictable behavior of the app, and creating orphan objects that will never be referenced again. Specify a '':dependent'' option whenever utilizing ''has_many'' association. For example, (code sample is used from ''app/models/site_controller.rb'' file):&lt;br /&gt;
  # Bad - not specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions&lt;br /&gt;
  &lt;br /&gt;
  # Good - specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions, dependent: :destroy&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use a guard clause instead of wrapping the code inside a conditional expression.&lt;br /&gt;
This is very common issue reported by Code Climate that can be easily avoided by properly utilizing `if` statements applying some logic. In general, avoid using bulk of ''if/else'' statements whenever possible. For example, (code sample is used from ''app/models/sign_up_topic.rb'' file):&lt;br /&gt;
  # Bad - too many conditional expressions that also contain nested ones&lt;br /&gt;
  if !no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
    if topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # Good - use guard close&lt;br /&gt;
  return true if no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
  topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
Above is typical example when 9 lines of code (LoC) can be reduced to 2 LoC and overall code quality improved. &lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not place comments on the same line as the ''end'' keyword.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; ''end'' at ''xxx'', ''xx'' is not aligned with ''unless'' at ''xxx'', ''xx''&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Replace class var ''@@variable_name'' with a class instance var.&lt;br /&gt;
&amp;lt;li&amp;gt; Similar blocks of code found in 2 locations. Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
{{Reflist}}&lt;br /&gt;
* {{Reflist|1}} https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&lt;br /&gt;
* {{Reflist|2}} https://docs.codeclimate.com/docs&lt;br /&gt;
* {{Reflist|3}} Expertiza - https://github.com/expertiza/expertiza#expertiza&lt;br /&gt;
* {{Reflist|4}} E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121910</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121910"/>
		<updated>2019-03-24T21:03:58Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about &amp;lt;ref&amp;gt;E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Specify a '':dependent'' option:&lt;br /&gt;
The [https://guides.rubyonrails.org/association_basics.html#the-has-many-association has_many] association should always be specified with one of the [https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Options :dependent] options, which specifies the behavior of the associated objects whenever their owner is destroyed. This is common practice and should be utilized adequately for the Expertiza app to work correctly. No specifying '':dependent'' option could lead to run time errors, unpredictable behavior of the app, and creating orphan objects that will never be referenced again. Specify a '':dependent'' option whenever utilizing ''has_many'' association. For example, (code sample is used from ''app/models/site_controller.rb'' file):&lt;br /&gt;
  # Bad - not specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions&lt;br /&gt;
  &lt;br /&gt;
  # Good - specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions, dependent: :destroy&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use a guard clause instead of wrapping the code inside a conditional expression.&lt;br /&gt;
This is very common issue reported by Code Climate that can be easily avoided by properly utilizing `if` statements applying some logic. In general, avoid using bulk of ''if/else'' statements whenever possible. For example, (code sample is used from ''app/models/sign_up_topic.rb'' file):&lt;br /&gt;
  # Bad - too many conditional expressions that also contain nested ones&lt;br /&gt;
  if !no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
    if topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # Good - use guard close&lt;br /&gt;
  return true if no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
  topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
Above is typical example when 9 lines of code (LoC) can be reduced to 2 LoC and overall code quality improved. &lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not place comments on the same line as the ''end'' keyword.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; ''end'' at ''xxx'', ''xx'' is not aligned with ''unless'' at ''xxx'', ''xx''&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Replace class var ''@@variable_name'' with a class instance var.&lt;br /&gt;
&amp;lt;li&amp;gt; Similar blocks of code found in 2 locations. Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* {{Reflist|1}} https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&lt;br /&gt;
* {{Reflist|2}} https://docs.codeclimate.com/docs&lt;br /&gt;
* {{Reflist|3}} Expertiza - https://github.com/expertiza/expertiza#expertiza&lt;br /&gt;
* {{Reflist|4}} E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121902</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121902"/>
		<updated>2019-03-24T20:55:00Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* Expertiza */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about &amp;lt;ref&amp;gt;E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Specify a '':dependent'' option:&lt;br /&gt;
The [https://guides.rubyonrails.org/association_basics.html#the-has-many-association has_many] association should always be specified with one of the [https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Options :dependent] options, which specifies the behavior of the associated objects whenever their owner is destroyed. This is common practice and should be utilized adequately for the Expertiza app to work correctly. No specifying '':dependent'' option could lead to run time errors, unpredictable behavior of the app, and creating orphan objects that will never be referenced again. Specify a '':dependent'' option whenever utilizing ''has_many'' association. For example, (code sample is used from ''app/models/site_controller.rb'' file):&lt;br /&gt;
  # Bad - not specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions&lt;br /&gt;
  &lt;br /&gt;
  # Good - specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions, dependent: :destroy&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use a guard clause instead of wrapping the code inside a conditional expression.&lt;br /&gt;
This is very common issue reported by Code Climate that can be easily avoided by properly utilizing `if` statements applying some logic. In general, avoid using bulk of ''if/else'' statements whenever possible. For example, (code sample is used from ''app/models/sign_up_topic.rb'' file):&lt;br /&gt;
  # Bad - too many conditional expressions that also contain nested ones&lt;br /&gt;
  if !no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
    if topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # Good - use guard close&lt;br /&gt;
  return true if no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
  topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
Above is typical example when 9 lines of code (LoC) can be reduced to 2 LoC and overall code quality improved. &lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not place comments on the same line as the ''end'' keyword.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; ''end'' at ''xxx'', ''xx'' is not aligned with ''unless'' at ''xxx'', ''xx''&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Replace class var ''@@variable_name'' with a class instance var.&lt;br /&gt;
&amp;lt;li&amp;gt; Similar blocks of code found in 2 locations. Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&lt;br /&gt;
* https://docs.codeclimate.com/docs&lt;br /&gt;
* Expertiza - https://github.com/expertiza/expertiza#expertiza&lt;br /&gt;
* {{Reflist|2}} E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121901</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121901"/>
		<updated>2019-03-24T20:54:00Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* Expertiza */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about &amp;lt;references&amp;gt;E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&amp;lt;/references&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Specify a '':dependent'' option:&lt;br /&gt;
The [https://guides.rubyonrails.org/association_basics.html#the-has-many-association has_many] association should always be specified with one of the [https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Options :dependent] options, which specifies the behavior of the associated objects whenever their owner is destroyed. This is common practice and should be utilized adequately for the Expertiza app to work correctly. No specifying '':dependent'' option could lead to run time errors, unpredictable behavior of the app, and creating orphan objects that will never be referenced again. Specify a '':dependent'' option whenever utilizing ''has_many'' association. For example, (code sample is used from ''app/models/site_controller.rb'' file):&lt;br /&gt;
  # Bad - not specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions&lt;br /&gt;
  &lt;br /&gt;
  # Good - specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions, dependent: :destroy&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use a guard clause instead of wrapping the code inside a conditional expression.&lt;br /&gt;
This is very common issue reported by Code Climate that can be easily avoided by properly utilizing `if` statements applying some logic. In general, avoid using bulk of ''if/else'' statements whenever possible. For example, (code sample is used from ''app/models/sign_up_topic.rb'' file):&lt;br /&gt;
  # Bad - too many conditional expressions that also contain nested ones&lt;br /&gt;
  if !no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
    if topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # Good - use guard close&lt;br /&gt;
  return true if no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
  topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
Above is typical example when 9 lines of code (LoC) can be reduced to 2 LoC and overall code quality improved. &lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not place comments on the same line as the ''end'' keyword.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; ''end'' at ''xxx'', ''xx'' is not aligned with ''unless'' at ''xxx'', ''xx''&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Replace class var ''@@variable_name'' with a class instance var.&lt;br /&gt;
&amp;lt;li&amp;gt; Similar blocks of code found in 2 locations. Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&lt;br /&gt;
* https://docs.codeclimate.com/docs&lt;br /&gt;
* Expertiza - https://github.com/expertiza/expertiza#expertiza&lt;br /&gt;
* {{Reflist|2}} E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121900</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121900"/>
		<updated>2019-03-24T20:53:27Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about &amp;lt;ref&amp;gt;E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Specify a '':dependent'' option:&lt;br /&gt;
The [https://guides.rubyonrails.org/association_basics.html#the-has-many-association has_many] association should always be specified with one of the [https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Options :dependent] options, which specifies the behavior of the associated objects whenever their owner is destroyed. This is common practice and should be utilized adequately for the Expertiza app to work correctly. No specifying '':dependent'' option could lead to run time errors, unpredictable behavior of the app, and creating orphan objects that will never be referenced again. Specify a '':dependent'' option whenever utilizing ''has_many'' association. For example, (code sample is used from ''app/models/site_controller.rb'' file):&lt;br /&gt;
  # Bad - not specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions&lt;br /&gt;
  &lt;br /&gt;
  # Good - specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions, dependent: :destroy&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use a guard clause instead of wrapping the code inside a conditional expression.&lt;br /&gt;
This is very common issue reported by Code Climate that can be easily avoided by properly utilizing `if` statements applying some logic. In general, avoid using bulk of ''if/else'' statements whenever possible. For example, (code sample is used from ''app/models/sign_up_topic.rb'' file):&lt;br /&gt;
  # Bad - too many conditional expressions that also contain nested ones&lt;br /&gt;
  if !no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
    if topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # Good - use guard close&lt;br /&gt;
  return true if no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
  topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
Above is typical example when 9 lines of code (LoC) can be reduced to 2 LoC and overall code quality improved. &lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not place comments on the same line as the ''end'' keyword.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; ''end'' at ''xxx'', ''xx'' is not aligned with ''unless'' at ''xxx'', ''xx''&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Replace class var ''@@variable_name'' with a class instance var.&lt;br /&gt;
&amp;lt;li&amp;gt; Similar blocks of code found in 2 locations. Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&lt;br /&gt;
* https://docs.codeclimate.com/docs&lt;br /&gt;
* Expertiza - https://github.com/expertiza/expertiza#expertiza&lt;br /&gt;
* {{Reflist|2}} E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121895</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121895"/>
		<updated>2019-03-24T20:50:13Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* Expertiza */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about &amp;lt;ref&amp;gt;E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Specify a '':dependent'' option:&lt;br /&gt;
The [https://guides.rubyonrails.org/association_basics.html#the-has-many-association has_many] association should always be specified with one of the [https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Options :dependent] options, which specifies the behavior of the associated objects whenever their owner is destroyed. This is common practice and should be utilized adequately for the Expertiza app to work correctly. No specifying '':dependent'' option could lead to run time errors, unpredictable behavior of the app, and creating orphan objects that will never be referenced again. Specify a '':dependent'' option whenever utilizing ''has_many'' association. For example, (code sample is used from ''app/models/site_controller.rb'' file):&lt;br /&gt;
  # Bad - not specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions&lt;br /&gt;
  &lt;br /&gt;
  # Good - specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions, dependent: :destroy&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use a guard clause instead of wrapping the code inside a conditional expression.&lt;br /&gt;
This is very common issue reported by Code Climate that can be easily avoided by properly utilizing `if` statements applying some logic. In general, avoid using bulk of ''if/else'' statements whenever possible. For example, (code sample is used from ''app/models/sign_up_topic.rb'' file):&lt;br /&gt;
  # Bad - too many conditional expressions that also contain nested ones&lt;br /&gt;
  if !no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
    if topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # Good - use guard close&lt;br /&gt;
  return true if no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
  topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
Above is typical example when 9 lines of code (LoC) can be reduced to 2 LoC and overall code quality improved. &lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not place comments on the same line as the ''end'' keyword.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; ''end'' at ''xxx'', ''xx'' is not aligned with ''unless'' at ''xxx'', ''xx''&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Replace class var ''@@variable_name'' with a class instance var.&lt;br /&gt;
&amp;lt;li&amp;gt; Similar blocks of code found in 2 locations. Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&lt;br /&gt;
* https://docs.codeclimate.com/docs&lt;br /&gt;
* Expertiza - https://github.com/expertiza/expertiza#expertiza&lt;br /&gt;
* E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121894</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121894"/>
		<updated>2019-03-24T20:49:28Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about &amp;lt;ref&amp;gt;Expertiza - [https://github.com/expertiza/expertiza#expertiza]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Specify a '':dependent'' option:&lt;br /&gt;
The [https://guides.rubyonrails.org/association_basics.html#the-has-many-association has_many] association should always be specified with one of the [https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Options :dependent] options, which specifies the behavior of the associated objects whenever their owner is destroyed. This is common practice and should be utilized adequately for the Expertiza app to work correctly. No specifying '':dependent'' option could lead to run time errors, unpredictable behavior of the app, and creating orphan objects that will never be referenced again. Specify a '':dependent'' option whenever utilizing ''has_many'' association. For example, (code sample is used from ''app/models/site_controller.rb'' file):&lt;br /&gt;
  # Bad - not specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions&lt;br /&gt;
  &lt;br /&gt;
  # Good - specifying a :dependent option&lt;br /&gt;
  class SiteController &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_many :controller_actions, dependent: :destroy&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use a guard clause instead of wrapping the code inside a conditional expression.&lt;br /&gt;
This is very common issue reported by Code Climate that can be easily avoided by properly utilizing `if` statements applying some logic. In general, avoid using bulk of ''if/else'' statements whenever possible. For example, (code sample is used from ''app/models/sign_up_topic.rb'' file):&lt;br /&gt;
  # Bad - too many conditional expressions that also contain nested ones&lt;br /&gt;
  if !no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
    if topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # Good - use guard close&lt;br /&gt;
  return true if no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
  topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
Above is typical example when 9 lines of code (LoC) can be reduced to 2 LoC and overall code quality improved. &lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not place comments on the same line as the ''end'' keyword.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; ''end'' at ''xxx'', ''xx'' is not aligned with ''unless'' at ''xxx'', ''xx''&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Replace class var ''@@variable_name'' with a class instance var.&lt;br /&gt;
&amp;lt;li&amp;gt; Similar blocks of code found in 2 locations. Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&lt;br /&gt;
* https://docs.codeclimate.com/docs&lt;br /&gt;
* Expertiza - https://github.com/expertiza/expertiza#expertiza&lt;br /&gt;
* E. F. Gehringer, L. M. Ehresman, S. G. Conger and P. A. Wagle, &amp;quot;Work in Progress: Reusable Learning Objects Through Peer Review: The Expertiza Approach,&amp;quot; Proceedings. Frontiers in Education. 36th Annual Conference, San Diego, CA, 2006, pp. 1-2. [http://ieeexplore.ieee.org.prox.lib.ncsu.edu/stamp/stamp.jsp?tp=&amp;amp;arnumber=4117076&amp;amp;isnumber=4116830]&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121891</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121891"/>
		<updated>2019-03-24T20:29:51Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* Expertiza */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about &amp;lt;ref&amp;gt;Expertiza - [https://github.com/expertiza/expertiza#expertiza]&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use a guard clause instead of wrapping the code inside a conditional expression.&lt;br /&gt;
This is very common issue reported by Code Climate that can be easily avoided by properly utilizing `if` statements applying some logic. In general, avoid using bulk of ''if/else'' statements whenever possible. For example, (code sample is used from ''app/models/sign_up_topic.rb'' file):&lt;br /&gt;
  # Bad - too many conditional expressions that also contain nested ones&lt;br /&gt;
  if !no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
    if topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # Good - use guard close&lt;br /&gt;
  return true if no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
  topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
Above is typical example when 9 lines of code (LoC) can be reduced to 2 LoC and overall code quality improved. &lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not place comments on the same line as the ''end'' keyword.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; ''end'' at ''xxx'', ''xx'' is not aligned with ''unless'' at ''xxx'', ''xx''&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Replace class var ''@@variable_name'' with a class instance var.&lt;br /&gt;
&amp;lt;li&amp;gt; Similar blocks of code found in 2 locations. Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&lt;br /&gt;
* https://docs.codeclimate.com/docs&lt;br /&gt;
* Expertiza - https://github.com/expertiza/expertiza#expertiza&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121888</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121888"/>
		<updated>2019-03-24T20:27:51Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use a guard clause instead of wrapping the code inside a conditional expression.&lt;br /&gt;
This is very common issue reported by Code Climate that can be easily avoided by properly utilizing `if` statements applying some logic. In general, avoid using bulk of ''if/else'' statements whenever possible. For example, (code sample is used from ''app/models/sign_up_topic.rb'' file):&lt;br /&gt;
  # Bad - too many conditional expressions that also contain nested ones&lt;br /&gt;
  if !no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
    if topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # Good - use guard close&lt;br /&gt;
  return true if no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
  topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
Above is typical example when 9 lines of code (LoC) can be reduced to 2 LoC and overall code quality improved. &lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not place comments on the same line as the ''end'' keyword.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; ''end'' at ''xxx'', ''xx'' is not aligned with ''unless'' at ''xxx'', ''xx''&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Replace class var ''@@variable_name'' with a class instance var.&lt;br /&gt;
&amp;lt;li&amp;gt; Similar blocks of code found in 2 locations. Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Specify a '':dependent'' option.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&lt;br /&gt;
* https://docs.codeclimate.com/docs&lt;br /&gt;
* Expertiza - https://github.com/expertiza/expertiza#expertiza&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121882</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121882"/>
		<updated>2019-03-24T20:14:08Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use a guard clause instead of wrapping the code inside a conditional expression.&lt;br /&gt;
This is very common issue reported by Code Climate that can be easily avoided by properly utilizing `if` statements applying some logic. In general, avoid using bulk of ''if/else'' statements whenever possible. For example, (code sample is used from ''app/models/sign_up_topic.rb'' file):&lt;br /&gt;
  # Bad - too many conditional expressions that also contain nested ones&lt;br /&gt;
  if !no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
    if topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  # Good - use guard close&lt;br /&gt;
  return true if no_of_students_who_selected_the_topic.nil?&lt;br /&gt;
  topic.max_choosers &amp;gt; no_of_students_who_selected_the_topic.size&lt;br /&gt;
Above is typical example when 9 lines of code (LoC) can be reduced to 2 LoC and overall code quality improved. &lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Specify an '':inverse_of option''.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1.    https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&amp;lt;br&amp;gt;&lt;br /&gt;
2.    https://docs.codeclimate.com/docs&amp;lt;br&amp;gt;&lt;br /&gt;
3.    Expertiza - https://github.com/expertiza/expertiza#expertiza&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121879</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121879"/>
		<updated>2019-03-24T20:09:00Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Specify an '':inverse_of option''.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1.    https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&amp;lt;br&amp;gt;&lt;br /&gt;
2.    https://docs.codeclimate.com/docs&amp;lt;br&amp;gt;&lt;br /&gt;
3.    https://github.com/expertiza/expertiza#expertiza&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121878</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121878"/>
		<updated>2019-03-24T20:08:31Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Specify an '':inverse_of option''.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1.    https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&amp;lt;br&amp;gt;&lt;br /&gt;
2.    https://docs.codeclimate.com/docs&amp;lt;br&amp;gt;&lt;br /&gt;
3.    https://docs.codeclimate.com/docs&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121877</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121877"/>
		<updated>2019-03-24T20:04:17Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Specify an '':inverse_of option''.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI.&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1.    https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&amp;lt;br&amp;gt;&lt;br /&gt;
2.    https://docs.codeclimate.com/docs&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121876</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121876"/>
		<updated>2019-03-24T20:02:44Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid more than 3 levels of block nesting.&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; Line is too long.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Specify an '':inverse_of option''.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1.    https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&amp;lt;br&amp;gt;&lt;br /&gt;
2.    https://docs.codeclimate.com/docs&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121873</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121873"/>
		<updated>2019-03-24T19:58:12Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* Code Climate */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Code Climate is an analysis software used to improve the quality and security of your code. The Code Climate results for the Expertiza project can be found [https://codeclimate.com/github/expertiza/expertiza/code here].&lt;br /&gt;
&lt;br /&gt;
Code Climate will use various engines to analyze your code to look for issues that may concern potential security issues, (.i.e. marking code to html_safe), or add to maintainability issues (.i.e number of lines in method exceeding 25 lines). Some of the engines include: RuboCop, Brakeman, Bundler-Audit, [https://docs.codeclimate.com/docs/list-of-engines etc.]&lt;br /&gt;
&lt;br /&gt;
Code Climate can ran from either a 3rd party remote server of via the local application using CLI. The Expertiza project uses the 3rd party remote server to analyze the code. In order to use CodeClimate via remote server, you have to register your repository. Following [https://docs.codeclimate.com/docs this] process will allow you to check your code for quality issues after Pushing your code to the monitored repository.&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Prefer ''each'' over ''for'':&lt;br /&gt;
We noticed there is a lot of iteration in the code using ''for'' loop instead of ''each''. Generally, you want to avoid any ''for'' loops and use ''each'', ''each_index'', ''each_with_index'', ''upto'' and etc. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for user_signup_topic in user_signup&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of each&lt;br /&gt;
  user_signup.each do |user_signup_topic|&lt;br /&gt;
    return false if user_signup_topic.is_waitlisted == false&lt;br /&gt;
Similarly, if you need to iterate the given block, passing in integer as an index, utilize ''each_index'', ''each_with_index'', ''upto'' instead of ''for''. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' file):&lt;br /&gt;
  # Bad - use of for loop&lt;br /&gt;
  for round in 1..@review_rounds&lt;br /&gt;
    process_review_round(assignment_id, due_date, round, topic)&lt;br /&gt;
  &lt;br /&gt;
  # Good - use of upto&lt;br /&gt;
  1.upto(@review_rounds) do |r|&lt;br /&gt;
    process_review_round(assignment_id, due_date, r, topic)&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example, (code sample is used from ''app/models/teams_user.rb'' and ''app/models/team_user_node.rb'' files respectively):&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Tagging a string as html safe may be a security risk:&lt;br /&gt;
For example,&lt;br /&gt;
  html.html_safe # George can you please talk about it how you fixed it&lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
* Use ''snake_case'' for method names and for variable names:&lt;br /&gt;
There are a lot of instances where developers use ''camelCase'' instead of ''snake_case'' in the Expertiza project naming methods and variables. Since Expertiza project is based on RoR, it is  preferred to use ''snake_case'' for all method and variable names. For example, (code sample is used from ''app/models/sign_up_sheet.rb'' and ''app/models/sign_up_topic.rb'' files receptively):&lt;br /&gt;
  # Bad method name - camelCase&lt;br /&gt;
  def self.slotAvailable?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  def self.slot_available?(topic_id)&lt;br /&gt;
  &lt;br /&gt;
  # Bad variable name - camelCase&lt;br /&gt;
  dropDate = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
  &lt;br /&gt;
  # Good method name - snake_case&lt;br /&gt;
  drop_date = AssignmentDueDate.where(parent_id: assignment.id, deadline_type_id: '6').first&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Avoid using ''update_attribute'' because it skips validations. &lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Specify an '':inverse_of option''.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1.    https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121819</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121819"/>
		<updated>2019-03-24T16:49:51Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about what is Code Climate [https://codeclimate.com/github/expertiza/expertiza/code Code Climate]&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example,&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer ''each'' over ''for''.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Specify an '':inverse_of option''.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Use snake_case for method names.&lt;br /&gt;
&amp;lt;li&amp;gt; Use snake_case for variable names.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
There we 2 types of frame works that we used to verify our code modifications/creation within the models: RSpec and Travis CI&lt;br /&gt;
&lt;br /&gt;
RSpec was used to locally test the changes we had implemented without having to Push the change to the GitHub, this is discussed more in-depth in the section below.&lt;br /&gt;
&lt;br /&gt;
Travis CI is a more comprehensive testing used by the Expetiza team to verify code changes from multiple sources, (.i.e forks from students). Travis CI will analyze the code once you Push your changes to the GitHub server for your given repository. Travis CI will need to be setup independently for your repository&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1.    https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121816</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121816"/>
		<updated>2019-03-24T15:59:54Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* Rspec Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about what is Code Climate [https://codeclimate.com/github/expertiza/expertiza/code Code Climate]&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example,&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer ''each'' over ''for''.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Specify an '':inverse_of option''.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Use snake_case for method names.&lt;br /&gt;
&amp;lt;li&amp;gt; Use snake_case for variable names.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
This produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1.    https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121815</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121815"/>
		<updated>2019-03-24T15:59:33Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* Rspec Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about what is Code Climate [https://codeclimate.com/github/expertiza/expertiza/code Code Climate]&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example,&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer ''each'' over ''for''.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Specify an '':inverse_of option''.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Use snake_case for method names.&lt;br /&gt;
&amp;lt;li&amp;gt; Use snake_case for variable names.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the models already had existing RSpecs Tests already created. For those, we just simply ran the corresponding test via the terminal window. Example&lt;br /&gt;
   rspec spec/models/tag_prompt_spec.rb&lt;br /&gt;
   &lt;br /&gt;
   *rspec path/to/spec/file.rb*&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This would execute the RSpec test for the tag_prompt.rb file located in the app/models folder. As you can see, there is a particular format that is used when naming the RSpec file: &lt;br /&gt;
    model_name_spec.rb&lt;br /&gt;
&lt;br /&gt;
Once the execution of the RSpec model testing is completed, results will be display&lt;br /&gt;
    $ rspec spec/models/tag_prompt_spec.rb                                                                                                                                                     [10:45:15]&lt;br /&gt;
    [Coveralls] Set up the SimpleCov formatter.&lt;br /&gt;
    [Coveralls] Using SimpleCov's 'rails' settings.&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    .........&lt;br /&gt;
    Finished in 3.35 seconds (files took 23.23 seconds to load)&lt;br /&gt;
    9 examples, 0 failures&lt;br /&gt;
    Randomized with seed 19443&lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 1254 / 17313 LOC (7.24%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In addition to running the individual RSpec Test, we also executed broader in scope testing. To achieve this, we executed the following command in the terminal window:&lt;br /&gt;
    $ bundle exec rspec --seed 5114  &lt;br /&gt;
&lt;br /&gt;
The produces the following results:&lt;br /&gt;
&lt;br /&gt;
    Finished in 1 minute 11.23 seconds (files took 23.19 seconds to load)&lt;br /&gt;
    131 examples, 1 failure, 1 pending&lt;br /&gt;
    &lt;br /&gt;
    Failed examples:&lt;br /&gt;
    &lt;br /&gt;
    rspec ./spec/features/assignment_creation_spec.rb:707 # assignment function check to find if the assignment can be added to a course&lt;br /&gt;
    &lt;br /&gt;
    Randomized with seed 5114&lt;br /&gt;
        &lt;br /&gt;
    Coverage report generated for RSpec to /home/expertiza_developer/RubymineProjects/expertiza_testbed/coverage. 2998 / 14031 LOC (21.37%) covered.&lt;br /&gt;
    [Coveralls] Outside the CI environment, not sending data.&lt;br /&gt;
    FAIL: 1&lt;br /&gt;
&lt;br /&gt;
As you can see from the examples above there are failures. However, we are only looking for failures caused by the code we modified/created in a given model. In this case, all code we have created/modified is not causing failures.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1.    https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121809</id>
		<title>E1920 Fix Code Climate Issues</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=E1920_Fix_Code_Climate_Issues&amp;diff=121809"/>
		<updated>2019-03-24T13:22:43Z</updated>

		<summary type="html">&lt;p&gt;Cladkins: /* Rspec Testing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page describes the changes are made in the Expertiza source code to implement E1920 OSS Project, &amp;quot;Fix Code Climate issues in models with names beginning with 'Se' thru 'Z'&amp;quot; in the Spring 2019 semester, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
This is intro section. We can talk about what is our project and how we got started.&lt;br /&gt;
&lt;br /&gt;
=== Expertiza ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about Expertiza.&lt;br /&gt;
&lt;br /&gt;
=== Code Climate ===&lt;br /&gt;
&lt;br /&gt;
Briefly talk about what is Code Climate [https://codeclimate.com/github/expertiza/expertiza/code Code Climate]&lt;br /&gt;
&lt;br /&gt;
== Project Description ==&lt;br /&gt;
&lt;br /&gt;
Some of the Expertiza source code violates many of the [https://rubyonrails.org/ Ruby on Rails] best practices and must be rectified to improve code readability, robustness and maintainability of the Expertiza application.&lt;br /&gt;
&lt;br /&gt;
Our team was assigned to fix ''all'' code smells detected by [https://codeclimate.com/github/expertiza/expertiza/code Code Climate] in the given set of Expertiza source code files.&lt;br /&gt;
&lt;br /&gt;
=== Files Involved ===&lt;br /&gt;
&lt;br /&gt;
All files in the [https://github.com/expertiza/expertiza/tree/master/app/models app/models] directory with names beginning with '''Se''' (e.g. [https://github.com/expertiza/expertiza/blob/master/app/models/section_header.rb section_header.rb]) through '''Z''', except [https://github.com/expertiza/expertiza/blob/master/app/controllers/users_controller.rb users_controller.rb] file were targeted by our team to be Code Climate issue free files. Therefore, our team was assigned exactly with 50 (fifty) files to fix in total. Some of the files had no issues reported by the Code Climate to begin with, and hence were not modified. However, changes/improvements performed on other files had an affect globally on the files outside of the app/models scope and also had to be modified to adapt changes we implemented. For example, renaming method ''is_leaf'' as follows:&lt;br /&gt;
  def leaf?&lt;br /&gt;
in the [https://github.com/expertiza/expertiza/blob/master/app/models/team_user_node.rb team_user_node.rb] file require to change all callers to this method in different files accordingly. Such changes had to be done in the following files (for this particular example):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; models/assignment_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; models/questionnaire_node.rb&lt;br /&gt;
&amp;lt;li&amp;gt; views/tree_display/_row_header.html.erb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These files are outside of the requirements specifications, but we had to modify them in order to maintain correct behavior of the App. There were few such cases when we had to modify multiple files to fix one or more Code Climate issue(s). The list of all of files changed can be found in the Pull Request discussed in this article.&lt;br /&gt;
&lt;br /&gt;
=== Ignored Code Climate Smells ===&lt;br /&gt;
&lt;br /&gt;
There are some Code Climate issues that were ignored and not resolved intentionally.&lt;br /&gt;
&lt;br /&gt;
The following issues are exempt based the given requirements specifications and were not fixed:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Assignment Branch Condition size for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Perceived complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Cyclomatic complexity for [method name] is too high.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has a Cognitive Complexity of ''XX'' (exceeds 5 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; File [file name] has ''XXX''  lines of code (exceeds 250 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Class [class name] has ''XX'' methods (exceeds 20 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;li&amp;gt; Method [method name] has ''XX'' lines of code (exceeds 25 allowed). Consider refactoring.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are also two Code Climate issues that our team decided to ignore after consulting our mentor and discussing their impact on the existing code and Expertiza project. It was determined that the following Code Climate issues reported as False Positive and may not need to be resolved:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Mass assignment is not restricted using attr_accessible.&lt;br /&gt;
&amp;lt;li&amp;gt; Potentially dangerous attribute available for mass assignment.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, there was a duplicate code issue that was ignored due to a future project. The following files have a duplicate method, self.export_fields(options):&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; user.rb&lt;br /&gt;
&amp;lt;li&amp;gt; participant.rb&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For further clarification with regard to ignored Code Climate issues please contact our mentor.&lt;br /&gt;
&lt;br /&gt;
== Project Implementation ==&lt;br /&gt;
&lt;br /&gt;
Talk about how we fixed the most common issues reported by Code Climate.&lt;br /&gt;
&lt;br /&gt;
=== Most Common Issues Reported by Code Climate ===&lt;br /&gt;
&lt;br /&gt;
As we worked on the Code Climate issues for the Expertiza project, we noticed a set of common code smells and issues made by software developers. Since these issues can easily be avoided and most importantly, avoiding them improves code quality, we decided to ''warn'' all Expertiza developers about them by providing the list of these issues, their descriptions, how they can be avoided, and how the code quality can be improved.&lt;br /&gt;
&lt;br /&gt;
* Specify an '':inverse_of option'':&lt;br /&gt;
Whenever there are two models defined with many|one-to-one relationship (''has_many''|''has_one'' and ''belongs_to'' association) out of scope of each other or with certain options used (e.g. ''foreign_key:'' and etc.), Active Record is unable to determine the inverse association of them. This would cause redundant look up operation performed on the database for the same object. It is not really an issue that could cause significant problems, but for such massive application like Experiza, it could affect performance and cause delay in response. Therefore, the '':inverse_of'' option must be specified manually to use the associated object in memory instead of loading it from database twice. For example,&lt;br /&gt;
  class TeamsUser &amp;lt; ActiveRecord::Base&lt;br /&gt;
    has_one :team_user_node, foreign_key: 'node_object_id', dependent: :destroy, inverse_of: 'node_object'&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  class TeamUserNode &amp;lt; Node&lt;br /&gt;
    belongs_to :node_object, class_name: 'TeamsUser', inverse_of: :team_user_node&lt;br /&gt;
  end&lt;br /&gt;
* Use ''find_by'' instead of ''where.first'':&lt;br /&gt;
Always use ''find_by'' with an attempt to find the first record matching the specified conditions. However, keep in mind that ''find_by'' and ''where_first'' return different object IFF no record was found based on specified conditions.&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.find_by'' - if there is a record match, returns the object. If there is no record match, returns ''nil''&lt;br /&gt;
&amp;lt;li&amp;gt; ''Model.where.first'' - if there is a record match, returns first ActiveRecord::Relation matched. If there is no record match, returns an Empty ActiveRecord::Relation&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Therefore, always handle ''nil'' appropriately if there is no record match (with ''if/else'' block and etc.) Do not assume that the record will always be found. For example,&lt;br /&gt;
  user = User.find_by(name: row_hash[index.to_sym].to_s)&lt;br /&gt;
  raise ImportError, &amp;quot;The user, &amp;quot; + row_hash[index.to_sym].to_s.strip + &amp;quot;, was not found.&amp;quot; if user.nil?&lt;br /&gt;
&lt;br /&gt;
=== Resolved Code Climate Issues ===&lt;br /&gt;
&lt;br /&gt;
Along with [http://wiki.expertiza.ncsu.edu/index.php/E1920_Fix_Code_Climate_Issues#Most_Common_Issues_Reported_by_Code_Climate Most Common Issues Reported by Code Climate] we also fixed and verified numerous other code smells. The following is the list of all issues we have resolved:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Convert ''if'' nested inside ''else'' to ''elsif''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not prefix reader method names with ''get_''.&lt;br /&gt;
&amp;lt;li&amp;gt; Do not use ''DateTime.parse.strftime'' without zone. Use one of ''Time.zone.parse.strftime'', ''DateTime.current'', ''DateTime.parse.strftime.in_time_zone'', ''DateTime.parse.strftime.utc'', ''DateTime.parse.strftime.getlocal'', ''DateTime.parse.strftime.iso8601'', ''DateTime.parse.strftime.jisx0301'', ''DateTime.parse.strftime.rfc3339'', ''DateTime.parse.strftime.to_i'', ''DateTime.parse.strftime.to_f'' instead.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer ''each'' over ''for''.&lt;br /&gt;
&amp;lt;li&amp;gt; Prefer Date or Time over DateTime.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''has_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Rename ''is_x'' to ''x?''.&lt;br /&gt;
&amp;lt;li&amp;gt; Specify an '':inverse_of option''.&lt;br /&gt;
&amp;lt;li&amp;gt; Unnecessary spacing detected.&lt;br /&gt;
&amp;lt;li&amp;gt; Use ''find_by'' instead of ''where.first''.&lt;br /&gt;
&amp;lt;li&amp;gt; Use snake_case for method names.&lt;br /&gt;
&amp;lt;li&amp;gt; Use snake_case for variable names.&lt;br /&gt;
&amp;lt;li&amp;gt; Useless assignment to variable - ''x''.&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Additional Improvements ===&lt;br /&gt;
&lt;br /&gt;
Talk about additional improvements if there are any ( I(Nikolay) had some some I will include them here).&lt;br /&gt;
&lt;br /&gt;
=== Remaining Issues ===&lt;br /&gt;
&lt;br /&gt;
Talk about remaining issues and further improvements.&lt;br /&gt;
&lt;br /&gt;
=== Further Suggestions ===&lt;br /&gt;
&lt;br /&gt;
Talk about suggestions you have on files that you fixed if there are any? May be break down some methods into several and etc?&lt;br /&gt;
&lt;br /&gt;
=== Pull Request ===&lt;br /&gt;
&lt;br /&gt;
Let's add some info about pull request&lt;br /&gt;
&lt;br /&gt;
== Testing ==&lt;br /&gt;
&lt;br /&gt;
Talk about Testing we performed&lt;br /&gt;
&lt;br /&gt;
=== Rspec Testing ===&lt;br /&gt;
&lt;br /&gt;
To verify the code changes we made did not break the existing application, we used the RSpec Testing Framework. Several of the model already had existing models in created. For those, we just simply ran the corresponding test via the terminal window.&lt;br /&gt;
&lt;br /&gt;
=== UI Testing ===&lt;br /&gt;
&lt;br /&gt;
We concentrated our UI testing based on how changes to Code Climate issues affected the interface between callers and methods. Two main culprits were found. The first was the change from Time.parse to Time.zone.parse. While Time.parse returns an error for invalid or unknown times, Time.zone.parse returns nil for those types. The second culprit was changing where().first to find_by(). Using where().first return empty records if nothing is found, while find_by() returns nil is nothing is found.&lt;br /&gt;
&lt;br /&gt;
The user interface testing concentrated on three type of user stories. The first set of user stories was general functionality, could users still access the basic menu items from before. The second set of user stories were those that dealt with time issues, such as sorting. The third set of user stories were those that dealt with searching.&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Talk about conclusion.&lt;br /&gt;
&lt;br /&gt;
== Team Contacts and Contribution ==&lt;br /&gt;
&lt;br /&gt;
We have 3 (three) members in our team and 1 (one) mentor was assigned to us. For any project-related questions/concerns please contact us:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Christopher Adkins - cladkins@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; George Hugh - gshugh@ncsu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Nikolay G. Titov - ngtitov@ncu.edu&lt;br /&gt;
&amp;lt;li&amp;gt; Zachariah Mathews (mentor) - zmathew@ncsu.edu&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have questions or concerns related to a specific file that was improved/modified by our team, please contact an engineer who worked on the file based on the [https://docs.google.com/spreadsheets/d/1bX2XizitGGoajFT6Br_y6MQjAwBCsX5WCVlx3xg8Jp8/edit?ts=5c87a06c#gid=0 Assignment Grid] we created to keep track of our progress and contribution. Please CC in email all team members and our mentor.&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
1.    https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Rails/InverseOf&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cladkins</name></author>
	</entry>
</feed>