<?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=Adas9</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=Adas9"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Adas9"/>
	<updated>2026-08-14T17:41:52Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Usecasediagram.png&amp;diff=142260</id>
		<title>File:Usecasediagram.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Usecasediagram.png&amp;diff=142260"/>
		<updated>2021-11-30T03:12:46Z</updated>

		<summary type="html">&lt;p&gt;Adas9: Adas9 uploaded a new version of File:Usecasediagram.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2159._Expertiza_internationalization&amp;diff=142256</id>
		<title>CSC/ECE 517 Fall 2021 - E2159. Expertiza internationalization</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2159._Expertiza_internationalization&amp;diff=142256"/>
		<updated>2021-11-30T03:09:08Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Database Modification */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction - Purpose &amp;amp; Problem ==&lt;br /&gt;
&lt;br /&gt;
Currently, all Expertiza screens can only be viewed in English. Many Expertiza users are from other countries. This is a problem since this limits the accessibility of Expertiza. An important step in solving this problem is by making Expertiza available in more languages, which is a form of internationalization.&lt;br /&gt;
W3C defines [https://www.w3.org/International/questions/qa-i18n internationalization] as “''the design and development of a product, application or document content that enables easy localization for target audiences that vary in culture, region, or language.''”&lt;br /&gt;
&lt;br /&gt;
[[File:country_pie.png|none|500px|]]&amp;lt;br&amp;gt;&lt;br /&gt;
Survey of home country of Expertiza users for a given course&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Scope:''' The scope of this project is limited however only to static strings. i.e. user-generated content will not be automatically translated to other languages.&lt;br /&gt;
&lt;br /&gt;
'''Breaking down internationalization into 3 sequential subproblems:'''&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Twophase2.jpg|none|700px]]&amp;lt;br&amp;gt;&lt;br /&gt;
'''1. Language selection'''&amp;lt;br&amp;gt;&lt;br /&gt;
Every user has an option to set a language preference in the User Profile Information Edit page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:ProfileEditPage.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
There is also an option where the instructor can choose a default language for a course. &lt;br /&gt;
&lt;br /&gt;
[[File:language2inter.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thus, the language not only varies from user to user but also across screens for the same user. Thus we need to recompute the language in which the page is to be rendered. If the student has given a language preference, then the choice is given weightage over the course default language chosen by the instructor. &lt;br /&gt;
&lt;br /&gt;
'''2. Rendering the language'''&amp;lt;br&amp;gt;&lt;br /&gt;
'''How do we go about rendering the screen in that language?''' &amp;lt;br&amp;gt;&lt;br /&gt;
In the previous step, we’ve identified the language in which a view is to be rendered. It is important to note that this language may not only differ for a different user, but also for a different page for the same user. The question now becomes, how do we render the screen in this language?&amp;lt;br&amp;gt;&lt;br /&gt;
To tackle this question, we explore 2 fundamental concepts:&amp;lt;br&amp;gt;&lt;br /&gt;
'''2.1 Views are composed of independent language elements'''&amp;lt;br&amp;gt;&lt;br /&gt;
While this is something we typically take for granted, it becomes especially important in the context of translation. That is, a view is not a single contiguous block of text, nor is it an atomic visualization of information (unlike a screenshot), but rather a carefully organized collection of individual elements such as texts, buttons, etc that each contain language that needs to be translated separately. Crucially, this means that we cannot swap out a page in one language in its entirety for a page in another language in its entirety. Instead, each individual element needs to be swapped out individually so as to only impact the language and not the structural composition of the page itself.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
'''2.2 Views require translation at a large number of call sites'''&amp;lt;br&amp;gt;&lt;br /&gt;
Given that a view is composed of individual elements, this also means that the computation of how to translate such an element such as a button’s text would need to be done separately for each element. This would result in not only a single centralized &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3. Translation gaps'''&lt;br /&gt;
&lt;br /&gt;
What if the translation for the target language is not available?&lt;br /&gt;
Even translation for a language like Hindi may be available in general, the translation for a given text may not be available Hindi. This may be due to a variety of reasons:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
The specific text may have been accidentally missed out (remember the translation is not being done at runtime through an API, but rather curated by the developer)&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
The given text is non-trivial to translate to the target language&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Our design would thus need to accommodate this by seamlessly falling back on another language whose translation is available.&lt;br /&gt;
&lt;br /&gt;
== Scope ==&lt;br /&gt;
The scope of this project is limited however only to static strings. I.e. user-generated content will not be automatically translated to other languages.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
'''Proposed Solution''' &amp;lt;br&amp;gt;&lt;br /&gt;
We explore and solve each of the three problems above in isolation:&lt;br /&gt;
&lt;br /&gt;
'''''1. Language selection'''''&amp;lt;br&amp;gt;&lt;br /&gt;
The language in which the page is rendered depends on a set of conditions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;If the user has set a language preference all pages are displayed in that language.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;If the user has not set a language preference and the user is an instructor, all the pages are displayed in English.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;If the user has not set a language preference and the user is a student who is on a page that is specific to a course for which the instructor has added a default language, the page is displayed in the course’s default language.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The below functions are added and called before page rendering to bring in this logic.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  before_action :set_locale&lt;br /&gt;
&lt;br /&gt;
  def set_locale&lt;br /&gt;
    # Checks whether the user is logged in, else the default locale is used&lt;br /&gt;
    if logged_in?&lt;br /&gt;
      # If the current user has set his preferred language, the locale is set according to their preference&lt;br /&gt;
      if @current_user.locale != &amp;quot;no_pref&amp;quot;&lt;br /&gt;
        I18n.locale = @current_user.locale&lt;br /&gt;
        # If the user doesn't have any preference, the locale is taken from the course locale, if the current page is a course specific page or else default locale is used&lt;br /&gt;
      elsif current_user_role? &amp;amp;&amp;amp; current_user_role.student? &amp;amp;&amp;amp; [&amp;quot;student_task&amp;quot;, &amp;quot;sign_up_sheet&amp;quot;, &amp;quot;student_teams&amp;quot;, &amp;quot;student_review&amp;quot;, &amp;quot;grades&amp;quot;, &amp;quot;submitted_content&amp;quot;, &amp;quot;participants&amp;quot;].include?(params[:controller])&lt;br /&gt;
        set_new_locale_for_student&lt;br /&gt;
      else&lt;br /&gt;
        I18n.locale = I18n.default_locale&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      I18n.locale = I18n.default_locale&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_new_locale_for_student&lt;br /&gt;
    # Gets participant using student from params&lt;br /&gt;
    if !params[:id].nil? || !params[:student_id].nil?&lt;br /&gt;
      participant_id = params[:id] || params[:student_id]&lt;br /&gt;
      participant = AssignmentParticipant.find_by(id: participant_id)&lt;br /&gt;
      # If id or student_id not correct, revert to locale based on courses.&lt;br /&gt;
      if participant.nil?&lt;br /&gt;
        find_locale_from_courses&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      # Find assignment from participant and find locale from the assigment&lt;br /&gt;
      assignment = participant.assignment&lt;br /&gt;
      if !assignment.course.nil?&lt;br /&gt;
        new_locale = assignment.course.locale&lt;br /&gt;
        if !new_locale.nil?&lt;br /&gt;
          I18n.locale = new_locale&lt;br /&gt;
        else&lt;br /&gt;
          I18n.locale = I18n.default_locale&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        I18n.locale = I18n.default_locale&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      find_locale_from_courses&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def find_locale_from_courses&lt;br /&gt;
    # If the page is a course or assignment page with no specific student id, every course of that student is checked and if&lt;br /&gt;
    # the language for all these course are same, the page is displayed in that language&lt;br /&gt;
  courseParticipants = CourseParticipant.where(user_id: current_user.id)&lt;br /&gt;
    courseParticipantsLocales = courseParticipants.map { |cp| cp.course.locale }&lt;br /&gt;
    # If no tasks, then possible to have no courses assigned.&lt;br /&gt;
    if courseParticipantsLocales.uniq.length == 1 #&amp;amp;&amp;amp; !@tasks.empty?&lt;br /&gt;
      course = courseParticipants.first.course&lt;br /&gt;
      if course.locale?&lt;br /&gt;
        I18n.locale = course.locale&lt;br /&gt;
      else&lt;br /&gt;
        I18n.locale = I18n.default_locale&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      I18n.locale = I18n.default_locale&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;If the student user has not set a language preference and is not on a course-specific page, then the page is displayed in English.&lt;br /&gt;
If a language preference is obtained by following the above conditions but some keys in the page don't have a translation for the language, the English translation for that key is returned as a fallback.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''2. Rendering the language'''''&amp;lt;br&amp;gt;&lt;br /&gt;
Once we have determined the language in which to render the page, we now need to update the rails view code to actually generate the appropriate HTML in the target language. This is the responsibility of the view. However, currently, the actual content of the HTML is hardcoded in (red) English. For example:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;Summary Report for assignment: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Team: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
As discussed earlier, “Views are composed of independent language elements” and so we cannot simply swap out the entire page content for a separate page in another language (Why? - See “swap out the entire view” in the alternative approaches section):&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;Rapport de synthèse pour l'affectation: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Équipe: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Instead, the better approach is to have a single unified view that dynamically changes based on the selected language:&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;&amp;lt;%=language==’en’ ? ‘Summary Report for assignment’ : ‘Rapport de synthèse pour l'affectation’&amp;gt;: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;&amp;lt;%=language==’en’ ? ‘Team’ : ‘Équipe’&amp;gt;: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;However this is clearly infeasible considering the number of call sites where we have to apply this logic. Thus, in order to maximize how concise the call site is, we can pull out this logic into a common helper function:&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;&amp;lt;%=localized(“report_summary.page_header”)&amp;gt;: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;&amp;lt;%=localized(“report_summary.team_label”)&amp;gt;: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;Here the assumption is that the localized(“key”) is aware of the currently selected language and that “report_summary.page_header” is the key for the header which is available in English and Hindi. The helper intelligently selects and returns the right text based on the currently selected language. Through this approach, we are able to render the view in multiple possible languages without any significant increase in the verbosity of the view.&lt;br /&gt;
&lt;br /&gt;
What’s more, is that the above problem is a common problem for user-facing applications and a standard library for doing the above and much more already exists for rails applications called i18n&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''I18n - Internationalisation, How are we using I18n in Ruby on Rail'''''&amp;lt;br&amp;gt;&lt;br /&gt;
I18n is a ruby library/gem which helps us render the static string on the view dynamically. Dynamicity means that based on a local decision of choosing the current language of the view, the library returns the strings of that particular language at runtime.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
These strings, instead of hardcoding in the view.rb, are provided in external .yml files. Now at the View level, we can pass an id to the 't' function and the I18n library returns the string for that id of the current set language(called as locale). &amp;lt;br&amp;gt;&lt;br /&gt;
[[File:i18n.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
For this purpose, we have to provide .yml files for each language and in those language-specific .yml, we have to provide a map of key-value pairs where the key is the id of the string and value is the string in that particular language. By default the language or locale is set to be English(:en). &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
THE GREATEST BENEFITS of using this library are - &amp;lt;br&amp;gt;&lt;br /&gt;
*The strings aren't hardcoded in the code/build. The strings are being fetched from external files which can be easily modified. For example, if one needs to change the text from 'Please Help' to 'Help', then one just needs to make a change in the .yml file and the change would reflect on the browser. For this change, we didn't need to redeploy the server. We just Decoupled the view when and where from what content is to be shown. &lt;br /&gt;
*Adding more languages is now super easy. Adding support for another language is just one line change in the config and adding a .yml file (having all the key-value pairs for the strings) for the new language. By doing this we can extend the language support as much as we want.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
'''''3. Translation gaps'''''&lt;br /&gt;
&amp;lt;br&amp;gt;Also, if the language is set to be Hindi or any other language but the key-value pair is not set for that particular string then, automatically the library returns the default which is the English text.&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;config.i18n.fallbacks = [:en]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Alternate approaches ==&lt;br /&gt;
&lt;br /&gt;
'''1. Why not simply swap out the entire view for another language instead of each text?'''&amp;lt;br&amp;gt;&lt;br /&gt;
A view is an organized collection of multiple separate elements, views often involve dynamic generation and some level of sophistication. If we were to swap out one page in its entirety for another page this would often violate the '''DRY''' principle since we would have to have two separate implementations of the view in each language. Thus in the worst case, you have a complex view that has to be replicated dozens of times in various languages.&lt;br /&gt;
The majority of complexity of the page is not in the content itself but rather the code that executes to generate that content, thus it makes sense to instead maintain a single view and embed the language switching logic at each location where translation needs to occur to avoid replication of everything around it.&lt;br /&gt;
&lt;br /&gt;
'''2. Why did we pick i18n over implementing it ourselves?'''&amp;lt;br&amp;gt;&lt;br /&gt;
Doing it ourselves felt like a great option. But i18n not just selects a language string at runtime for us it does a lot more under the hood which makes our lives easier. For example, it manages locale over the session for us, even if we change the urls and shift tabs and other stuff it manages our locale. &amp;lt;br&amp;gt;&lt;br /&gt;
Also there is a great principle that says - “ If it isn’t broken, Don’t fix it”. The library manages the registering of different language yml files, points to the right right text at runtime, manages session locale and a lot more. So we want to explore this library instead of reimplementing the same thing again.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3, Why did we store the default language choices in database instead of in session?'''&amp;lt;br&amp;gt;&lt;br /&gt;
We had to decide on whether to keep the student’s language preference in the database or in the session. We have thought about both approaches and below listed are the advantages and disadvantages.&lt;br /&gt;
&lt;br /&gt;
In the work done by the previous team, they added a dropdown in the navbar where a student can choose the preferred language. One of the changes that we did was to move this field to the user profile page. The earlier team used session storage to store the preferred language. This session resets on every logout, but since the preferred language can easily be set from any page this wasn't much of an issue.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;Storing user language preference in database.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	If we are moving the language preference field to the user profile page, it will create some user experience issues if the preference is stored in session. The student will have to visit the user profile page every time they log in. To avoid this scenario, it’s better to keep the language preference in the database, so that the preference stays saved across sessions.&lt;br /&gt;
	The disadvantage of moving the language preference to the database is that it brings forth a schema change and this always requires a very careful going through to ensure that nothing else is affected. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;Storing language preference in session storage.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main advantage of storing the language preference in session storage is that no schema change is involved. This decreases the chance of other features being affected. The main disadvantage is that the student will have to go to the user profile page every time they log in to set the preference, causing a user experience issue. Keep in mind that we’re moving the field away from the navbar to a user profile page.&lt;br /&gt;
&lt;br /&gt;
After considering these points, we finally decided to go store the user preference in the database itself as the project requires us to add a language preference field in user profile page.&lt;br /&gt;
&lt;br /&gt;
== Use Case Diagram ==&lt;br /&gt;
&amp;lt;li&amp;gt;An instructor can add a default language to any course. English is the default choice.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;The user has an option to change their preferred language at any time. They have the option to do so in their profile page. &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;All pages including the course-related and non-course-related pages are displayed in the user preferred language for any user other than student&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;Every non-course-related page is displayed in the student’s preferred language. Keys for which a translation is not found are displayed in the default language that is English&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;Every course-related page is displayed in the student’s preferred language. If the student doesn’t have a preferred language, the course is displayed in the course’s preferred language. Keys for which a translation is not found are displayed in the default language that is English.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:usecasediagram.png|2000px|865px]]&lt;br /&gt;
&lt;br /&gt;
== Major design patterns and principles used ==&lt;br /&gt;
&lt;br /&gt;
'''1. DRY: The i18n ‘t’ function'''&amp;lt;br&amp;gt;&lt;br /&gt;
We observe an extreme case of DRY with the t function of i18n.&lt;br /&gt;
For some background, the t function of the library takes in a key representing a text and returns the content referred to by that key in the preferred language of the user. It also performs many other functions such as falling back to a backup language if the translation for the preferred language has not been configured for that specific key. Thus since this logic has to be applied at every element of the view, it would behove us to extract this logic into a reusable function which is what the designers of the i18n library have employed&lt;br /&gt;
&lt;br /&gt;
'''2. Chain of responsibility'''&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Chainofresp.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The I18n library gives us an option to have many fall back options. When the required text for a given language is not found, we then move on to find the text for the next language in the chain and so on until we find it. And in the end we will put english as default language. So if the key value pair for the text is not found in none of the yml files then the text will be fetched from the English language yml file.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''3. Open closed principle &amp;amp; Strategy Pattern'''&amp;lt;br&amp;gt;&lt;br /&gt;
As discussed in the “Language selection&amp;quot; design proposal above, if the user has not selected a preferred language, we do not simply default the view to render in the application language (English). Instead, the project requirements state that for course specific screens such as the assignment view, we would need to render the view in the course’s language.&lt;br /&gt;
While we could implement this code into the application controller that checks the controller being access and accordingly applies overrides on the default language, this violates the open closed principle since we would need to extend this logic any time we introduce a new course specific screen. Instead a better approach is to delegate the decision of selecting the language to the view itself since the view would be most aware of whether the view is course specific or not. We can also preserve the DRYness through mix-ins.&lt;br /&gt;
&lt;br /&gt;
== Database Design ==&lt;br /&gt;
We add the locale field to the users and courses tables which has the default values 0 and 1, which is no preference and en_US respectively.&lt;br /&gt;
&lt;br /&gt;
The migrations will look as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class AddLangLocaleToUsers &amp;lt; ActiveRecord::Migration&lt;br /&gt;
  def change&lt;br /&gt;
    add_column :users, :locale, :integer, default: 0&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class AddLocaleToCourses &amp;lt; ActiveRecord::Migration&lt;br /&gt;
  def change&lt;br /&gt;
    add_column :courses, :locale, :integer, default: 1&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Database Modification ==&lt;br /&gt;
We add a new integer field to the users table to store the user preferred language. The integer will be hashed to the supported languages. The default value in the table will be 0, which will be no_pref.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
enum locale: {&lt;br /&gt;
      no_pref: 0,&lt;br /&gt;
      en_US: 1,&lt;br /&gt;
      hi_IN: 2&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We also add a new integer field to the courses table to store the course preferred language. The integer will be hashed to the supported languages. The default value in the table will be 1, which will be en_US.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
enum locale: {&lt;br /&gt;
      en_US: 1,&lt;br /&gt;
      hi_IN: 2&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hence the updated courses table will look like following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
create_table &amp;quot;courses&amp;quot;, force: :cascade do |t|&lt;br /&gt;
    t.string   &amp;quot;name&amp;quot;,            limit: 255&lt;br /&gt;
    t.integer  &amp;quot;instructor_id&amp;quot;,   limit: 4&lt;br /&gt;
    t.string   &amp;quot;directory_path&amp;quot;,  limit: 255&lt;br /&gt;
    t.text     &amp;quot;info&amp;quot;,            limit: 65535&lt;br /&gt;
    t.datetime &amp;quot;created_at&amp;quot;&lt;br /&gt;
    t.datetime &amp;quot;updated_at&amp;quot;&lt;br /&gt;
    t.boolean  &amp;quot;private&amp;quot;,                       default: false, null: false&lt;br /&gt;
    t.integer  &amp;quot;institutions_id&amp;quot;, limit: 4&lt;br /&gt;
    t.integer  &amp;quot;locale&amp;quot;,          limit: 4,     default: 1&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While the updated users table will look like the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
create_table &amp;quot;users&amp;quot;, force: :cascade do |t|&lt;br /&gt;
    t.string  &amp;quot;name&amp;quot;,                      limit: 255,      default: &amp;quot;&amp;quot;,    null: false&lt;br /&gt;
    t.string  &amp;quot;crypted_password&amp;quot;,          limit: 40,       default: &amp;quot;&amp;quot;,    null: false&lt;br /&gt;
    t.integer &amp;quot;role_id&amp;quot;,                   limit: 4,        default: 0,     null: false&lt;br /&gt;
    t.string  &amp;quot;password_salt&amp;quot;,             limit: 255&lt;br /&gt;
    t.string  &amp;quot;fullname&amp;quot;,                  limit: 255&lt;br /&gt;
    t.string  &amp;quot;email&amp;quot;,                     limit: 255&lt;br /&gt;
    t.integer &amp;quot;parent_id&amp;quot;,                 limit: 4&lt;br /&gt;
    t.boolean &amp;quot;private_by_default&amp;quot;,                         default: false&lt;br /&gt;
    t.string  &amp;quot;mru_directory_path&amp;quot;,        limit: 128&lt;br /&gt;
    t.boolean &amp;quot;email_on_review&amp;quot;&lt;br /&gt;
    t.boolean &amp;quot;email_on_submission&amp;quot;&lt;br /&gt;
    t.boolean &amp;quot;email_on_review_of_review&amp;quot;&lt;br /&gt;
    t.boolean &amp;quot;is_new_user&amp;quot;,                                default: true,  null: false&lt;br /&gt;
    t.integer &amp;quot;master_permission_granted&amp;quot;, limit: 1,        default: 0&lt;br /&gt;
    t.string  &amp;quot;handle&amp;quot;,                    limit: 255&lt;br /&gt;
    t.text    &amp;quot;digital_certificate&amp;quot;,       limit: 16777215&lt;br /&gt;
    t.string  &amp;quot;persistence_token&amp;quot;,         limit: 255&lt;br /&gt;
    t.string  &amp;quot;timezonepref&amp;quot;,              limit: 255&lt;br /&gt;
    t.text    &amp;quot;public_key&amp;quot;,                limit: 16777215&lt;br /&gt;
    t.boolean &amp;quot;copy_of_emails&amp;quot;,                             default: false&lt;br /&gt;
    t.integer &amp;quot;institution_id&amp;quot;,            limit: 4&lt;br /&gt;
    t.boolean &amp;quot;preference_home_flag&amp;quot;,                       default: true&lt;br /&gt;
    t.integer &amp;quot;locale&amp;quot;,                    limit: 4,        default: 0&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The locale field is the last column on both tables:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
    courses:&amp;gt; t.integer  &amp;quot;locale&amp;quot;,  limit: 4,    default: 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      users:&amp;gt; t.integer &amp;quot;locale&amp;quot;,   limit: 4,    default: 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
&lt;br /&gt;
Through manual testing, we aim to identify if all the features of the application are working as intended when the language conversion occurs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Scenario 1&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Log in to Expertiza as a student.&lt;br /&gt;
&lt;br /&gt;
2. Go to the “user profile” page and change “preferred language” to Hindi.&lt;br /&gt;
&lt;br /&gt;
3. Check to see if the English strings on the profile page are translated to Hindi.&lt;br /&gt;
&lt;br /&gt;
4. Check if a page for which Hindi translation keys are added has its English static strings translated to Hindi.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Scenario 2&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Log in to Expertiza as a student.&lt;br /&gt;
&lt;br /&gt;
2. Go to the “user profile” page and change “preferred language” to Nil.&lt;br /&gt;
&lt;br /&gt;
3.  Check to see if the English strings on the page are unchanged, as the “user profile” translates only if the student has a preference.&lt;br /&gt;
&lt;br /&gt;
4. Go to an assignment page for which Hindi translation keys are added, which is under a course with the default language set to Hindi, and check whether the English strings are translated to Hindi.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Scenario 3&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Log in to Expertiza as a student.&lt;br /&gt;
&lt;br /&gt;
2. Go to the “user profile” page and change “preferred language” to Nil.&lt;br /&gt;
&lt;br /&gt;
3.  Check to see if the English strings on the page are unchanged, as the “user profile” translates only if the student has a preference.&lt;br /&gt;
&lt;br /&gt;
4. Go to a non-course-specific page and verify that the page is displayed in English itself, as non of the default languages set for any of the courses should have any role.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Scenario 4&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Log in to Expertiza as a student.&lt;br /&gt;
&lt;br /&gt;
2. Go to the “user profile” page and change “preferred language” to Hindi.&lt;br /&gt;
&lt;br /&gt;
3.  Go to a page where translation keys aren’t added completely and make sure that the unspecified keys display strings in English as a fallback.&lt;br /&gt;
&lt;br /&gt;
== Future Scope==&lt;br /&gt;
'''1. Expand to more languages'''&amp;lt;br&amp;gt;&lt;br /&gt;
As part of this project we have targetted Hindi as a second language, however our work makes it easy to extend to other languages as well.&lt;br /&gt;
&lt;br /&gt;
'''2. Identify and implement the course language override on more course specific screens'''&amp;lt;br&amp;gt;&lt;br /&gt;
As part of this project, we have introduced a generic framework by which any view can provide a preferred language in which it should be rendered, this is required by this project for the course language feature set by the instructor.&lt;br /&gt;
We have currently made the assignment screen display in the course’s language, however other screens such as the “Your work” screen and so on are also specific to the course could also be rendered in the course language when the user has not provided a preference.&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
&lt;br /&gt;
'''Team Members'''&lt;br /&gt;
&lt;br /&gt;
Reuben M. V. John [[mailto:rmjohn2@ncsu.edu rmjohn2@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Renji Joseph Sabu [[mailto:rsabu@ncsu.edu rsabu@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Ashwin Das [[mailto:adas9@ncsu.edu adas9@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Arnav Julka [[mailto:ajulka@ncsu.edu ajulka@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Mentor'''&lt;br /&gt;
&lt;br /&gt;
Jialin Cui [[mailto:jcui9@ncsu.edu jcui9@ncsu.edu]]&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2159._Expertiza_internationalization&amp;diff=142177</id>
		<title>CSC/ECE 517 Fall 2021 - E2159. Expertiza internationalization</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2159._Expertiza_internationalization&amp;diff=142177"/>
		<updated>2021-11-30T01:31:57Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Database Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction - Purpose &amp;amp; Problem ==&lt;br /&gt;
&lt;br /&gt;
Currently, all Expertiza screens can only be viewed in English. Many Expertiza users are from other countries. This is a problem since this limits the accessibility of Expertiza. An important step in solving this problem is by making Expertiza available in more languages, which is a form of internationalization.&lt;br /&gt;
W3C defines [https://www.w3.org/International/questions/qa-i18n internationalization] as “''the design and development of a product, application or document content that enables easy localization for target audiences that vary in culture, region, or language.''”&lt;br /&gt;
&lt;br /&gt;
[[File:country_pie.png|none|500px|]]&amp;lt;br&amp;gt;&lt;br /&gt;
Survey of home country of Expertiza users for a given course&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Scope:''' The scope of this project is limited however only to static strings. i.e. user-generated content will not be automatically translated to other languages.&lt;br /&gt;
&lt;br /&gt;
'''Breaking down internationalization into 3 sequential subproblems:'''&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Twophase2.jpg|none|700px]]&amp;lt;br&amp;gt;&lt;br /&gt;
'''1. Language selection'''&amp;lt;br&amp;gt;&lt;br /&gt;
Every user has an option to set a language preference in the User Profile Information Edit page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:ProfileEditPage.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
There is also an option where the instructor can choose a default language for a course. &lt;br /&gt;
&lt;br /&gt;
[[File:language2inter.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thus, the language not only varies from user to user but also across screens for the same user. Thus we need to recompute the language in which the page is to be rendered. If the student has given a language preference, then the choice is given weightage over the course default language chosen by the instructor. &lt;br /&gt;
&lt;br /&gt;
'''2. Rendering the language'''&amp;lt;br&amp;gt;&lt;br /&gt;
'''How do we go about rendering the screen in that language?''' &amp;lt;br&amp;gt;&lt;br /&gt;
In the previous step, we’ve identified the language in which a view is to be rendered. It is important to note that this language may not only differ for a different user, but also for a different page for the same user. The question now becomes, how do we render the screen in this language?&amp;lt;br&amp;gt;&lt;br /&gt;
To tackle this question, we explore 2 fundamental concepts:&amp;lt;br&amp;gt;&lt;br /&gt;
'''2.1 Views are composed of independent language elements'''&amp;lt;br&amp;gt;&lt;br /&gt;
While this is something we typically take for granted, it becomes especially important in the context of translation. That is, a view is not a single contiguous block of text, nor is it an atomic visualization of information (unlike a screenshot), but rather a carefully organized collection of individual elements such as texts, buttons, etc that each contain language that needs to be translated separately. Crucially, this means that we cannot swap out a page in one language in its entirety for a page in another language in its entirety. Instead, each individual element needs to be swapped out individually so as to only impact the language and not the structural composition of the page itself.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
'''2.2 Views require translation at a large number of call sites'''&amp;lt;br&amp;gt;&lt;br /&gt;
Given that a view is composed of individual elements, this also means that the computation of how to translate such an element such as a button’s text would need to be done separately for each element. This would result in not only a single centralized &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3. Translation gaps'''&lt;br /&gt;
&lt;br /&gt;
What if the translation for the target language is not available?&lt;br /&gt;
Even translation for a language like Hindi may be available in general, the translation for a given text may not be available Hindi. This may be due to a variety of reasons:&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
The specific text may have been accidentally missed out (remember the translation is not being done at runtime through an API, but rather curated by the developer)&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&lt;br /&gt;
The given text is non-trivial to translate to the target language&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
Our design would thus need to accommodate this by seamlessly falling back on another language whose translation is available.&lt;br /&gt;
&lt;br /&gt;
== Scope ==&lt;br /&gt;
The scope of this project is limited however only to static strings. I.e. user-generated content will not be automatically translated to other languages.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
'''Proposed Solution''' &amp;lt;br&amp;gt;&lt;br /&gt;
We explore and solve each of the three problems above in isolation:&lt;br /&gt;
&lt;br /&gt;
'''''1. Language selection'''''&amp;lt;br&amp;gt;&lt;br /&gt;
The language in which the page is rendered depends on a set of conditions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;If the user has set a language preference all pages are displayed in that language.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;If the user has not set a language preference and the user is an instructor, all the pages are displayed in English.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;If the user has not set a language preference and the user is a student who is on a page that is specific to a course for which the instructor has added a default language, the page is displayed in the course’s default language.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The below functions are added and called before page rendering to bring in this logic.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  before_action :set_locale&lt;br /&gt;
&lt;br /&gt;
  def set_locale&lt;br /&gt;
    # Checks whether the user is logged in, else the default locale is used&lt;br /&gt;
    if logged_in?&lt;br /&gt;
      # If the current user has set his preferred language, the locale is set according to their preference&lt;br /&gt;
      if @current_user.locale != &amp;quot;no_pref&amp;quot;&lt;br /&gt;
        I18n.locale = @current_user.locale&lt;br /&gt;
        # If the user doesn't have any preference, the locale is taken from the course locale, if the current page is a course specific page or else default locale is used&lt;br /&gt;
      elsif current_user_role? &amp;amp;&amp;amp; current_user_role.student? &amp;amp;&amp;amp; [&amp;quot;student_task&amp;quot;, &amp;quot;sign_up_sheet&amp;quot;, &amp;quot;student_teams&amp;quot;, &amp;quot;student_review&amp;quot;, &amp;quot;grades&amp;quot;, &amp;quot;submitted_content&amp;quot;, &amp;quot;participants&amp;quot;].include?(params[:controller])&lt;br /&gt;
        set_new_locale_for_student&lt;br /&gt;
      else&lt;br /&gt;
        I18n.locale = I18n.default_locale&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      I18n.locale = I18n.default_locale&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def set_new_locale_for_student&lt;br /&gt;
    # Gets participant using student from params&lt;br /&gt;
    if !params[:id].nil? || !params[:student_id].nil?&lt;br /&gt;
      participant_id = params[:id] || params[:student_id]&lt;br /&gt;
      participant = AssignmentParticipant.find_by(id: participant_id)&lt;br /&gt;
      # If id or student_id not correct, revert to locale based on courses.&lt;br /&gt;
      if participant.nil?&lt;br /&gt;
        find_locale_from_courses&lt;br /&gt;
        return&lt;br /&gt;
      end&lt;br /&gt;
      # Find assignment from participant and find locale from the assigment&lt;br /&gt;
      assignment = participant.assignment&lt;br /&gt;
      if !assignment.course.nil?&lt;br /&gt;
        new_locale = assignment.course.locale&lt;br /&gt;
        if !new_locale.nil?&lt;br /&gt;
          I18n.locale = new_locale&lt;br /&gt;
        else&lt;br /&gt;
          I18n.locale = I18n.default_locale&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        I18n.locale = I18n.default_locale&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      find_locale_from_courses&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  def find_locale_from_courses&lt;br /&gt;
    # If the page is a course or assignment page with no specific student id, every course of that student is checked and if&lt;br /&gt;
    # the language for all these course are same, the page is displayed in that language&lt;br /&gt;
  courseParticipants = CourseParticipant.where(user_id: current_user.id)&lt;br /&gt;
    courseParticipantsLocales = courseParticipants.map { |cp| cp.course.locale }&lt;br /&gt;
    # If no tasks, then possible to have no courses assigned.&lt;br /&gt;
    if courseParticipantsLocales.uniq.length == 1 #&amp;amp;&amp;amp; !@tasks.empty?&lt;br /&gt;
      course = courseParticipants.first.course&lt;br /&gt;
      if course.locale?&lt;br /&gt;
        I18n.locale = course.locale&lt;br /&gt;
      else&lt;br /&gt;
        I18n.locale = I18n.default_locale&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      I18n.locale = I18n.default_locale&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;If the student user has not set a language preference and is not on a course-specific page, then the page is displayed in English.&lt;br /&gt;
If a language preference is obtained by following the above conditions but some keys in the page don't have a translation for the language, the English translation for that key is returned as a fallback.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''2. Rendering the language'''''&amp;lt;br&amp;gt;&lt;br /&gt;
Once we have determined the language in which to render the page, we now need to update the rails view code to actually generate the appropriate HTML in the target language. This is the responsibility of the view. However, currently, the actual content of the HTML is hardcoded in (red) English. For example:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;Summary Report for assignment: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Team: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
As discussed earlier, “Views are composed of independent language elements” and so we cannot simply swap out the entire page content for a separate page in another language (Why? - See “swap out the entire view” in the alternative approaches section):&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;Rapport de synthèse pour l'affectation: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Équipe: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Instead, the better approach is to have a single unified view that dynamically changes based on the selected language:&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;&amp;lt;%=language==’en’ ? ‘Summary Report for assignment’ : ‘Rapport de synthèse pour l'affectation’&amp;gt;: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;&amp;lt;%=language==’en’ ? ‘Team’ : ‘Équipe’&amp;gt;: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;However this is clearly infeasible considering the number of call sites where we have to apply this logic. Thus, in order to maximize how concise the call site is, we can pull out this logic into a common helper function:&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;&amp;lt;%=localized(“report_summary.page_header”)&amp;gt;: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;&amp;lt;%=localized(“report_summary.team_label”)&amp;gt;: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;Here the assumption is that the localized(“key”) is aware of the currently selected language and that “report_summary.page_header” is the key for the header which is available in English and Hindi. The helper intelligently selects and returns the right text based on the currently selected language. Through this approach, we are able to render the view in multiple possible languages without any significant increase in the verbosity of the view.&lt;br /&gt;
&lt;br /&gt;
What’s more, is that the above problem is a common problem for user-facing applications and a standard library for doing the above and much more already exists for rails applications called i18n&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''I18n - Internationalisation, How are we using I18n in Ruby on Rail'''''&amp;lt;br&amp;gt;&lt;br /&gt;
I18n is a ruby library/gem which helps us render the static string on the view dynamically. Dynamicity means that based on a local decision of choosing the current language of the view, the library returns the strings of that particular language at runtime.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
These strings, instead of hardcoding in the view.rb, are provided in external .yml files. Now at the View level, we can pass an id to the 't' function and the I18n library returns the string for that id of the current set language(called as locale). &amp;lt;br&amp;gt;&lt;br /&gt;
[[File:i18n.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
For this purpose, we have to provide .yml files for each language and in those language-specific .yml, we have to provide a map of key-value pairs where the key is the id of the string and value is the string in that particular language. By default the language or locale is set to be English(:en). &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
THE GREATEST BENEFITS of using this library are - &amp;lt;br&amp;gt;&lt;br /&gt;
*The strings aren't hardcoded in the code/build. The strings are being fetched from external files which can be easily modified. For example, if one needs to change the text from 'Please Help' to 'Help', then one just needs to make a change in the .yml file and the change would reflect on the browser. For this change, we didn't need to redeploy the server. We just Decoupled the view when and where from what content is to be shown. &lt;br /&gt;
*Adding more languages is now super easy. Adding support for another language is just one line change in the config and adding a .yml file (having all the key-value pairs for the strings) for the new language. By doing this we can extend the language support as much as we want.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
'''''3. Translation gaps'''''&lt;br /&gt;
&amp;lt;br&amp;gt;Also, if the language is set to be Hindi or any other language but the key-value pair is not set for that particular string then, automatically the library returns the default which is the English text.&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;config.i18n.fallbacks = [:en]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Alternate approaches ==&lt;br /&gt;
&lt;br /&gt;
'''1. Why not simply swap out the entire view for another language instead of each text?'''&amp;lt;br&amp;gt;&lt;br /&gt;
A view is an organized collection of multiple separate elements, views often involve dynamic generation and some level of sophistication. If we were to swap out one page in its entirety for another page this would often violate the '''DRY''' principle since we would have to have two separate implementations of the view in each language. Thus in the worst case, you have a complex view that has to be replicated dozens of times in various languages.&lt;br /&gt;
The majority of complexity of the page is not in the content itself but rather the code that executes to generate that content, thus it makes sense to instead maintain a single view and embed the language switching logic at each location where translation needs to occur to avoid replication of everything around it.&lt;br /&gt;
&lt;br /&gt;
'''2. Why did we pick i18n over implementing it ourselves?'''&amp;lt;br&amp;gt;&lt;br /&gt;
Doing it ourselves felt like a great option. But i18n not just selects a language string at runtime for us it does a lot more under the hood which makes our lives easier. For example, it manages locale over the session for us, even if we change the urls and shift tabs and other stuff it manages our locale. &amp;lt;br&amp;gt;&lt;br /&gt;
Also there is a great principle that says - “ If it isn’t broken, Don’t fix it”. The library manages the registering of different language yml files, points to the right right text at runtime, manages session locale and a lot more. So we want to explore this library instead of reimplementing the same thing again.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3, Do we store the language preference, in the session or in the database?'''&amp;lt;br&amp;gt;&lt;br /&gt;
We are still deciding on whether to keep the student’s language preference in the database or in the session. We have thought about both approaches and below listed are the advantages and disadvantages.&lt;br /&gt;
&lt;br /&gt;
In the work done by the previous team, they added a dropdown in the navbar where a student can choose the preferred language. One of the changes that we intend to do is move this field to the user profile page. The earlier team used session storage to store the preferred language. This session resets on every logout, but since the preferred language can easily be set from any page this won’t be much of an issue.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;Storing language preference in database.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	If we are moving the language preference field to the user profile page, it will create some user experience issues if the preference is stored in session. The student will have to visit the user profile page every time they log in. To avoid this scenario, it’s better to keep the language preference in the database, so that the preference stays saved across sessions.&lt;br /&gt;
	The disadvantage of moving the language preference to the database is that it brings forth a schema change and this always requires a very careful going through to ensure that nothing else is affected. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;Storing language preference in session storage.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main advantage of storing the language preference in session storage is that no schema change is involved. This decreases the chance of other features being affected. The main disadvantage is that the student will have to go to the user profile page every time they log in to set the preference, causing a user experience issue. Keep in mind that we’re moving the field away from the navbar to a user profile page.&lt;br /&gt;
&lt;br /&gt;
== Use Case Diagram ==&lt;br /&gt;
&amp;lt;li&amp;gt;An instructor can add a default language to any course. English is the default choice.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;The student has an option to change their preferred language at any time. They have the option to do so in their profile page. &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;Every non-course-related page is displayed in the student’s preferred language. Keys for which a translation is not found are displayed in the default language that is English.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;Every course-related page is displayed in the student’s preferred language. If the student doesn’t have a preferred language, the course is displayed in the course’s preferred language. Keys for which a translation is not found are displayed in the default language that is English.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:usecasediagram.png|2000px|865px]]&lt;br /&gt;
&lt;br /&gt;
== Major design patterns and principles used ==&lt;br /&gt;
&lt;br /&gt;
'''1. DRY: The i18n ‘t’ function'''&amp;lt;br&amp;gt;&lt;br /&gt;
We observe an extreme case of DRY with the t function of i18n.&lt;br /&gt;
For some background, the t function of the library takes in a key representing a text and returns the content referred to by that key in the preferred language of the user. It also performs many other functions such as falling back to a backup language if the translation for the preferred language has not been configured for that specific key. Thus since this logic has to be applied at every element of the view, it would behove us to extract this logic into a reusable function which is what the designers of the i18n library have employed&lt;br /&gt;
&lt;br /&gt;
'''2. Chain of responsibility'''&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Chainofresp.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The I18n library gives us an option to have many fall back options. When the required text for a given language is not found, we then move on to find the text for the next language in the chain and so on until we find it. And in the end we will put english as default language. So if the key value pair for the text is not found in none of the yml files then the text will be fetched from the English language yml file.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''3. Open closed principle &amp;amp; Strategy Pattern'''&amp;lt;br&amp;gt;&lt;br /&gt;
As discussed in the “Language selection&amp;quot; design proposal above, if the user has not selected a preferred language, we do not simply default the view to render in the application language (English). Instead, the project requirements state that for course specific screens such as the assignment view, we would need to render the view in the course’s language.&lt;br /&gt;
While we could implement this code into the application controller that checks the controller being access and accordingly applies overrides on the default language, this violates the open closed principle since we would need to extend this logic any time we introduce a new course specific screen. Instead a better approach is to delegate the decision of selecting the language to the view itself since the view would be most aware of whether the view is course specific or not. We can also preserve the DRYness through mix-ins.&lt;br /&gt;
&lt;br /&gt;
== Database Design ==&lt;br /&gt;
We add the locale field to the users and courses tables which has the default values 0 and 1, which is no preference and en_US respectively.&lt;br /&gt;
&lt;br /&gt;
The migrations will look as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class AddLangLocaleToUsers &amp;lt; ActiveRecord::Migration&lt;br /&gt;
  def change&lt;br /&gt;
    add_column :users, :locale, :integer, default: 0&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class AddLocaleToCourses &amp;lt; ActiveRecord::Migration&lt;br /&gt;
  def change&lt;br /&gt;
    add_column :courses, :locale, :integer, default: 1&lt;br /&gt;
  end&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Database Modification ==&lt;br /&gt;
The only need to update the users table if we are keeping the language preference in the DB.&lt;br /&gt;
The current schema of the “users” table is :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
create_table &amp;quot;users&amp;quot;, force: :cascade do |t|&lt;br /&gt;
   t.string  &amp;quot;name&amp;quot;,                      limit: 255,      default: &amp;quot;&amp;quot;,    null: false&lt;br /&gt;
   &lt;br /&gt;
   t.string  &amp;quot;crypted_password&amp;quot;,          limit: 40,       default: &amp;quot;&amp;quot;,    null: false&lt;br /&gt;
&lt;br /&gt;
   t.integer &amp;quot;role_id&amp;quot;,                   limit: 4,        default: 0,     null: false&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;password_salt&amp;quot;,             limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;fullname&amp;quot;,                  limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;email&amp;quot;,                     limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.integer &amp;quot;parent_id&amp;quot;,                 limit: 4&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;private_by_default&amp;quot;,                         default: false&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;mru_directory_path&amp;quot;,        limit: 128&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;email_on_review&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;email_on_submission&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;email_on_review_of_review&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;is_new_user&amp;quot;,                                default: true,  null: false&lt;br /&gt;
&lt;br /&gt;
   t.integer &amp;quot;master_permission_granted&amp;quot;, limit: 1,        default: 0&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;handle&amp;quot;,                    limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.text    &amp;quot;digital_certificate&amp;quot;,       limit: 16777215&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;persistence_token&amp;quot;,         limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;timezonepref&amp;quot;,              limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.text    &amp;quot;public_key&amp;quot;,                limit: 16777215&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;copy_of_emails&amp;quot;,                             default: false&lt;br /&gt;
&lt;br /&gt;
   t.integer &amp;quot;institution_id&amp;quot;,            limit: 4&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;preference_home_flag&amp;quot;,                       default: true&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which will change to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
create_table &amp;quot;users&amp;quot;, force: :cascade do |t|&lt;br /&gt;
   t.string  &amp;quot;name&amp;quot;,                      limit: 255,      default: &amp;quot;&amp;quot;,    null: false&lt;br /&gt;
   &lt;br /&gt;
   t.string  &amp;quot;crypted_password&amp;quot;,          limit: 40,       default: &amp;quot;&amp;quot;,    null: false&lt;br /&gt;
&lt;br /&gt;
   t.integer &amp;quot;role_id&amp;quot;,                   limit: 4,        default: 0,     null: false&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;password_salt&amp;quot;,             limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;fullname&amp;quot;,                  limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;email&amp;quot;,                     limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.integer &amp;quot;parent_id&amp;quot;,                 limit: 4&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;private_by_default&amp;quot;,                         default: false&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;mru_directory_path&amp;quot;,        limit: 128&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;email_on_review&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;email_on_submission&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;email_on_review_of_review&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;is_new_user&amp;quot;,                                default: true,  null: false&lt;br /&gt;
&lt;br /&gt;
   t.integer &amp;quot;master_permission_granted&amp;quot;, limit: 1,        default: 0&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;handle&amp;quot;,                    limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.text    &amp;quot;digital_certificate&amp;quot;,       limit: 16777215&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;persistence_token&amp;quot;,         limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;timezonepref&amp;quot;,              limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.text    &amp;quot;public_key&amp;quot;,                limit: 16777215&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;copy_of_emails&amp;quot;,                             default: false&lt;br /&gt;
&lt;br /&gt;
   t.integer &amp;quot;institution_id&amp;quot;,            limit: 4&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;preference_home_flag&amp;quot;,                       default: true&lt;br /&gt;
&lt;br /&gt;
   t.string “language_preference”,        limit: 255&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
&lt;br /&gt;
Through manual testing, we aim to identify if all the features of the application are working as intended when the language conversion occurs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Scenario 1&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Log in to Expertiza as a student.&lt;br /&gt;
&lt;br /&gt;
2. Go to the “user profile” page and change “preferred language” to Hindi.&lt;br /&gt;
&lt;br /&gt;
3. Check to see if the English strings on the profile page are translated to Hindi.&lt;br /&gt;
&lt;br /&gt;
4. Check if a page for which Hindi translation keys are added has its English static strings translated to Hindi.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Scenario 2&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Log in to Expertiza as a student.&lt;br /&gt;
&lt;br /&gt;
2. Go to the “user profile” page and change “preferred language” to Nil.&lt;br /&gt;
&lt;br /&gt;
3.  Check to see if the English strings on the page are unchanged, as the “user profile” translates only if the student has a preference.&lt;br /&gt;
&lt;br /&gt;
4. Go to an assignment page for which Hindi translation keys are added, which is under a course with the default language set to Hindi, and check whether the English strings are translated to Hindi.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Scenario 3&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Log in to Expertiza as a student.&lt;br /&gt;
&lt;br /&gt;
2. Go to the “user profile” page and change “preferred language” to Nil.&lt;br /&gt;
&lt;br /&gt;
3.  Check to see if the English strings on the page are unchanged, as the “user profile” translates only if the student has a preference.&lt;br /&gt;
&lt;br /&gt;
4. Go to a non-course-specific page and verify that the page is displayed in English itself, as non of the default languages set for any of the courses should have any role.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Scenario 4&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Log in to Expertiza as a student.&lt;br /&gt;
&lt;br /&gt;
2. Go to the “user profile” page and change “preferred language” to Hindi.&lt;br /&gt;
&lt;br /&gt;
3.  Go to a page where translation keys aren’t added completely and make sure that the unspecified keys display strings in English as a fallback.&lt;br /&gt;
&lt;br /&gt;
== Future Scope==&lt;br /&gt;
'''1. Expand to more languages'''&amp;lt;br&amp;gt;&lt;br /&gt;
As part of this project we have targetted Hindi as a second language, however our work makes it easy to extend to other languages as well.&lt;br /&gt;
&lt;br /&gt;
'''2. Identify and implement the course language override on more course specific screens'''&amp;lt;br&amp;gt;&lt;br /&gt;
As part of this project, we have introduced a generic framework by which any view can provide a preferred language in which it should be rendered, this is required by this project for the course language feature set by the instructor.&lt;br /&gt;
We have currently made the assignment screen display in the course’s language, however other screens such as the “Your work” screen and so on are also specific to the course could also be rendered in the course language when the user has not provided a preference.&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
&lt;br /&gt;
'''Team Members'''&lt;br /&gt;
&lt;br /&gt;
Reuben M. V. John [[mailto:rmjohn2@ncsu.edu rmjohn2@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Renji Joseph Sabu [[mailto:rsabu@ncsu.edu rsabu@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Ashwin Das [[mailto:adas9@ncsu.edu adas9@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Arnav Julka [[mailto:ajulka@ncsu.edu ajulka@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Mentor'''&lt;br /&gt;
&lt;br /&gt;
Jialin Cui [[mailto:jcui9@ncsu.edu jcui9@ncsu.edu]]&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2159._Expertiza_internationalization&amp;diff=140653</id>
		<title>CSC/ECE 517 Fall 2021 - E2159. Expertiza internationalization</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2159._Expertiza_internationalization&amp;diff=140653"/>
		<updated>2021-11-03T21:19:51Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Introduction - Purpose &amp;amp; Problem */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction - Purpose &amp;amp; Problem ==&lt;br /&gt;
&lt;br /&gt;
Currently, all Expertiza screens can only be viewed in English. Many Expertiza users are from other countries. This is a problem since this limits the accessibility of Expertiza. An important step in solving this problem is by making Expertiza available in more languages, which is a form of internationalization.&lt;br /&gt;
W3C defines [https://www.w3.org/International/questions/qa-i18n internationalization] as “''the design and development of a product, application or document content that enables easy localization for target audiences that vary in culture, region, or language.''”&lt;br /&gt;
&lt;br /&gt;
[[File:country_pie.png|none|500px|]]&amp;lt;br&amp;gt;&lt;br /&gt;
Survey of home country of Expertiza users for a given course&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Scope:''' The scope of this project is limited however only to static strings. i.e. user-generated content will not be automatically translated to other languages.&lt;br /&gt;
&lt;br /&gt;
'''Breaking down internationalization into 3 sequential subproblems:'''&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Twophase2.jpg|none|700px]]&amp;lt;br&amp;gt;&lt;br /&gt;
'''1. Language selection'''&amp;lt;br&amp;gt;&lt;br /&gt;
Internationalization is done for pages viewed by students only. Any user other than students views all pages in English. The student has the option to set a language preference.&lt;br /&gt;
&lt;br /&gt;
LOFI UI sketch&lt;br /&gt;
&lt;br /&gt;
[[File:language1inter.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
There is also an option where the instructor can choose a default language for a course. &lt;br /&gt;
&lt;br /&gt;
[[File:language2inter.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thus, the language not only varies from user to user but also across screens for the same user. Thus we need to recompute the language in which the page is to be rendered. If the student has given a language preference, then the choice is given weightage over the default language chosen by the instructor. &lt;br /&gt;
&lt;br /&gt;
'''2. Rendering the language'''&amp;lt;br&amp;gt;&lt;br /&gt;
'''How do we go about rendering the screen in that language?''' &amp;lt;br&amp;gt;&lt;br /&gt;
In the previous step, we’ve identified the language in which a view is to be rendered. It is important to note that this language may not only differ for a different user, but also for a different page for the same user. The question now becomes, how do we render the screen in this language?&amp;lt;br&amp;gt;&lt;br /&gt;
To tackle this question, we explore 2 fundamental concepts:&amp;lt;br&amp;gt;&lt;br /&gt;
'''2.1 Views are composed of independent language elements'''&amp;lt;br&amp;gt;&lt;br /&gt;
While this is something we typically take for granted, it becomes especially important in the context of translation. That is, a view is not a single contiguous block of text, nor is it an atomic visualization of information (unlike a screenshot), but rather a carefully organized collection of individual elements such as texts, buttons, etc that each contain language that needs to be translated separately. Crucially, this means that we cannot swap out a page in one language in its entirety for a page in another language in its entirety. Instead, each individual element needs to be swapped out individually so as to only impact the language and not the structural composition of the page itself.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
'''2.2 Views require translation at a large number of call sites'''&amp;lt;br&amp;gt;&lt;br /&gt;
Given that a view is composed of individual elements, this also means that the computation of how to translate such an element such as a button’s text would need to be done separately for each element. This would result in not only a single centralized &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3. Translation gaps'''&lt;br /&gt;
&lt;br /&gt;
What if the translation for the target language is not available?&lt;br /&gt;
Even translation for a language like Hindi may be available in general, the translation for a given text may not be available Hindi. This may be due to a variety of reasons:&lt;br /&gt;
The specific text may have been accidentally missed out (remember the translation is not being done at runtime through an API, but rather curated by the developer)&lt;br /&gt;
The given text is non-trivial to translate to the target language&lt;br /&gt;
Our design would thus need to accommodate this by seamlessly falling back on another language whose translation is available.&lt;br /&gt;
&lt;br /&gt;
== Scope ==&lt;br /&gt;
The scope of this project is limited however only to static strings. I.e. user-generated content will not be automatically translated to other languages.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
'''Proposed Solution''' &amp;lt;br&amp;gt;&lt;br /&gt;
We explore and solve each of the three problems above in isolation:&lt;br /&gt;
&lt;br /&gt;
'''''1. Language selection'''''&amp;lt;br&amp;gt;&lt;br /&gt;
The language in which the page is rendered depends on a set of conditions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;If the student has set a language preference, it overrides the default language setting saved by the instructor, and all pages are displayed in the language preferred by the student.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;If the student has not set a language preference and is on a page that is specific to a course for which the instructor has added a default language, the page is displayed in the course’s default language.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;If the student has not set a language preference and is not on a course-specific page, then the page is displayed in English.&lt;br /&gt;
If a language preference is obtained by following the above conditions but some keys in the page don't have a translation for the language, the English translation for that key is returned as a fallback.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''2. Rendering the language'''''&amp;lt;br&amp;gt;&lt;br /&gt;
Once we have determined the language in which to render the page, we now need to update the rails view code to actually generate the appropriate HTML in the target language. This is the responsibility of the view. However, currently, the actual content of the HTML is hardcoded in (red) English. For example:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;Summary Report for assignment: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Team: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
As discussed earlier, “Views are composed of independent language elements” and so we cannot simply swap out the entire page content for a separate page in another language (Why? - See “swap out the entire view” in the alternative approaches section):&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;Rapport de synthèse pour l'affectation: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Équipe: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Instead, the better approach is to have a single unified view that dynamically changes based on the selected language:&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;&amp;lt;%=language==’en’ ? ‘Summary Report for assignment’ : ‘Rapport de synthèse pour l'affectation’&amp;gt;: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;&amp;lt;%=language==’en’ ? ‘Team’ : ‘Équipe’&amp;gt;: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;However this is clearly infeasible considering the number of call sites where we have to apply this logic. Thus, in order to maximize how concise the call site is, we can pull out this logic into a common helper function:&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;&amp;lt;%=localized(“report_summary.page_header”)&amp;gt;: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;&amp;lt;%=localized(“report_summary.team_label”)&amp;gt;: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;Here the assumption is that the localized(“key”) is aware of the currently selected language and that “report_summary.page_header” is the key for the header which is available in English and Hindi. The helper intelligently selects and returns the right text based on the currently selected language. Through this approach, we are able to render the view in multiple possible languages without any significant increase in the verbosity of the view.&lt;br /&gt;
&lt;br /&gt;
What’s more, is that the above problem is a common problem for user-facing applications and a standard library for doing the above and much more already exists for rails applications called i18n&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''I18n - Internationalisation, How are we using I18n in Ruby on Rail'''''&amp;lt;br&amp;gt;&lt;br /&gt;
I18n is a ruby library/gem which helps us render the static string on the view dynamically. Dynamicity means that based on a local decision of choosing the current language of the view, the library returns the strings of that particular language at runtime.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
These strings, instead of hardcoding in the view.rb, are provided in external .yml files. Now at the View level, we can pass an id to the 't' function and the I18n library returns the string for that id of the current set language(called as locale). &amp;lt;br&amp;gt;&lt;br /&gt;
[[File:i18n.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
For this purpose, we have to provide .yml files for each language and in those language-specific .yml, we have to provide a map of key-value pairs where the key is the id of the string and value is the string in that particular language. By default the language or locale is set to be English(:en). &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
THE GREATEST BENEFITS of using this library are - &amp;lt;br&amp;gt;&lt;br /&gt;
*The strings aren't hardcoded in the code/build. The strings are being fetched from external files which can be easily modified. For example, if one needs to change the text from 'Please Help' to 'Help', then one just needs to make a change in the .yml file and the change would reflect on the browser. For this change, we didn't need to redeploy the server. We just Decoupled the view when and where from what content is to be shown. &lt;br /&gt;
*Adding more languages is now super easy. Adding support for another language is just one line change in the config and adding a .yml file (having all the key-value pairs for the strings) for the new language. By doing this we can extend the language support as much as we want.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
'''''3. Translation gaps'''''&lt;br /&gt;
&amp;lt;br&amp;gt;Also, if the language is set to be Hindi or any other language but the key-value pair is not set for that particular string then, automatically the library returns the default which is the English text.&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;config.i18n.fallbacks = [:en]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Alternate approaches ==&lt;br /&gt;
&lt;br /&gt;
'''1. Why not simply swap out the entire view for another language instead of each text?'''&amp;lt;br&amp;gt;&lt;br /&gt;
A view is an organized collection of multiple separate elements, views often involve dynamic generation and some level of sophistication. If we were to swap out one page in its entirety for another page this would often violate the '''DRY''' principle since we would have to have two separate implementations of the view in each language. Thus in the worst case, you have a complex view that has to be replicated dozens of times in various languages.&lt;br /&gt;
The majority of complexity of the page is not in the content itself but rather the code that executes to generate that content, thus it makes sense to instead maintain a single view and embed the language switching logic at each location where translation needs to occur to avoid replication of everything around it.&lt;br /&gt;
&lt;br /&gt;
'''2. Why did we pick i18n over implementing it ourselves?'''&amp;lt;br&amp;gt;&lt;br /&gt;
@ajulka&lt;br /&gt;
&lt;br /&gt;
'''3, Do we store the language preference, in the session or in the database?'''&amp;lt;br&amp;gt;&lt;br /&gt;
We are still deciding on whether to keep the student’s language preference in the database or in the session. We have thought about both approaches and below listed are the advantages and disadvantages.&lt;br /&gt;
&lt;br /&gt;
In the work done by the previous team, they added a dropdown in the navbar where a student can choose the preferred language. One of the changes that we intend to do is move this field to the user profile page. The earlier team used session storage to store the preferred language. This session resets on every logout, but since the preferred language can easily be set from any page this won’t be much of an issue.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;Storing language preference in database.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	If we are moving the language preference field to the user profile page, it will create some user experience issues if the preference is stored in session. The student will have to visit the user profile page every time they log in. To avoid this scenario, it’s better to keep the language preference in the database, so that the preference stays saved across sessions.&lt;br /&gt;
	The disadvantage of moving the language preference to the database is that it brings forth a schema change and this always requires a very careful going through to ensure that nothing else is affected. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;Storing language preference in session storage.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The main advantage of storing the language preference in session storage is that no schema change is involved. This decreases the chance of other features being affected. The main disadvantage is that the student will have to go to the user profile page every time they log in to set the preference, causing a user experience issue. Keep in mind that we’re moving the field away from the navbar to a user profile page.&lt;br /&gt;
&lt;br /&gt;
== Use Case Diagram ==&lt;br /&gt;
&amp;lt;li&amp;gt;An instructor can add a default language to any course. English is the default choice.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;The student has an option to change their preferred language at any time. They have the option to do so in their profile page. &amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;Every non-course-related page is displayed in the student’s preferred language. Keys for which a translation is not found are displayed in the default language that is English.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt;Every course-related page is displayed in the student’s preferred language. If the student doesn’t have a preferred language, the course is displayed in the course’s preferred language. Keys for which a translation is not found are displayed in the default language that is English.&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:usecasediagram.png|2000px|865px]]&lt;br /&gt;
&lt;br /&gt;
== Major design patterns and principles used ==&lt;br /&gt;
&lt;br /&gt;
'''1. DRY: The i18n ‘t’ function'''&amp;lt;br&amp;gt;&lt;br /&gt;
We observe an extreme case of DRY with the t function of i18n.&lt;br /&gt;
For some background, the t function of the library takes in a key representing a text and returns the content referred to by that key in the preferred language of the user. It also performs many other functions such as falling back to a backup language if the translation for the preferred language has not been configured for that specific key. Thus since this logic has to be applied at every element of the view, it would behove us to extract this logic into a reusable function which is what the designers of the i18n library have employed&lt;br /&gt;
&lt;br /&gt;
'''2. Chain of responsibility'''&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Chainofresp.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The I18n library gives us an option to have many fall back options. When the required text for a given language is not found, we then move on to find the text for the next language in the chain and so on until we find it. And in the end we will put english as default language. So if the key value pair for the text is not found in none of the yml files then the text will be fetched from the English language yml file.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''3. Open closed principle &amp;amp; Strategy Pattern'''&amp;lt;br&amp;gt;&lt;br /&gt;
As discussed in the “Language selection&amp;quot; design proposal above, if the user has not selected a preferred language, we do not simply default the view to render in the application language (English). Instead, the project requirements state that for course specific screens such as the assignment view, we would need to render the view in the course’s language.&lt;br /&gt;
While we could implement this code into the application controller that checks the controller being access and accordingly applies overrides on the default language, this violates the open closed principle since we would need to extend this logic any time we introduce a new course specific screen. Instead a better approach is to delegate the decision of selecting the language to the view itself since the view would be most aware of whether the view is course specific or not. We can also preserve the DRYness through mix-ins.&lt;br /&gt;
&lt;br /&gt;
== Database Design ==&lt;br /&gt;
Currently, we are debating between keeping the language preference in the session or in the database. If we are going with the latter, we have to add a column in the users table.&lt;br /&gt;
&lt;br /&gt;
The migration will look as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;rails generate migration add_language_preference_to_users language_preference:string&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class AddLanguagePreferenceToUsers &amp;lt; ActiveRecord::Migration[5.0] &lt;br /&gt;
  def change &lt;br /&gt;
    add_column :users, :language_preference, :string &lt;br /&gt;
  end &lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Database Modification ==&lt;br /&gt;
The only need to update the users table if we are keeping the language preference in the DB.&lt;br /&gt;
The current schema of the “users” table is :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
create_table &amp;quot;users&amp;quot;, force: :cascade do |t|&lt;br /&gt;
   t.string  &amp;quot;name&amp;quot;,                      limit: 255,      default: &amp;quot;&amp;quot;,    null: false&lt;br /&gt;
   &lt;br /&gt;
   t.string  &amp;quot;crypted_password&amp;quot;,          limit: 40,       default: &amp;quot;&amp;quot;,    null: false&lt;br /&gt;
&lt;br /&gt;
   t.integer &amp;quot;role_id&amp;quot;,                   limit: 4,        default: 0,     null: false&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;password_salt&amp;quot;,             limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;fullname&amp;quot;,                  limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;email&amp;quot;,                     limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.integer &amp;quot;parent_id&amp;quot;,                 limit: 4&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;private_by_default&amp;quot;,                         default: false&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;mru_directory_path&amp;quot;,        limit: 128&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;email_on_review&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;email_on_submission&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;email_on_review_of_review&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;is_new_user&amp;quot;,                                default: true,  null: false&lt;br /&gt;
&lt;br /&gt;
   t.integer &amp;quot;master_permission_granted&amp;quot;, limit: 1,        default: 0&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;handle&amp;quot;,                    limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.text    &amp;quot;digital_certificate&amp;quot;,       limit: 16777215&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;persistence_token&amp;quot;,         limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;timezonepref&amp;quot;,              limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.text    &amp;quot;public_key&amp;quot;,                limit: 16777215&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;copy_of_emails&amp;quot;,                             default: false&lt;br /&gt;
&lt;br /&gt;
   t.integer &amp;quot;institution_id&amp;quot;,            limit: 4&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;preference_home_flag&amp;quot;,                       default: true&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which will change to:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
create_table &amp;quot;users&amp;quot;, force: :cascade do |t|&lt;br /&gt;
   t.string  &amp;quot;name&amp;quot;,                      limit: 255,      default: &amp;quot;&amp;quot;,    null: false&lt;br /&gt;
   &lt;br /&gt;
   t.string  &amp;quot;crypted_password&amp;quot;,          limit: 40,       default: &amp;quot;&amp;quot;,    null: false&lt;br /&gt;
&lt;br /&gt;
   t.integer &amp;quot;role_id&amp;quot;,                   limit: 4,        default: 0,     null: false&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;password_salt&amp;quot;,             limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;fullname&amp;quot;,                  limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;email&amp;quot;,                     limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.integer &amp;quot;parent_id&amp;quot;,                 limit: 4&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;private_by_default&amp;quot;,                         default: false&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;mru_directory_path&amp;quot;,        limit: 128&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;email_on_review&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;email_on_submission&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;email_on_review_of_review&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;is_new_user&amp;quot;,                                default: true,  null: false&lt;br /&gt;
&lt;br /&gt;
   t.integer &amp;quot;master_permission_granted&amp;quot;, limit: 1,        default: 0&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;handle&amp;quot;,                    limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.text    &amp;quot;digital_certificate&amp;quot;,       limit: 16777215&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;persistence_token&amp;quot;,         limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.string  &amp;quot;timezonepref&amp;quot;,              limit: 255&lt;br /&gt;
&lt;br /&gt;
   t.text    &amp;quot;public_key&amp;quot;,                limit: 16777215&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;copy_of_emails&amp;quot;,                             default: false&lt;br /&gt;
&lt;br /&gt;
   t.integer &amp;quot;institution_id&amp;quot;,            limit: 4&lt;br /&gt;
&lt;br /&gt;
   t.boolean &amp;quot;preference_home_flag&amp;quot;,                       default: true&lt;br /&gt;
&lt;br /&gt;
   t.string “language_preference”,        limit: 255&lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
&lt;br /&gt;
===Manual Testing===&lt;br /&gt;
&lt;br /&gt;
Through manual testing, we aim to identify if all the features of the application are working as intended when the language conversion occurs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Scenario 1&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Log in to Expertiza as a student.&lt;br /&gt;
&lt;br /&gt;
2. Go to the “user profile” page and change “preferred language” to Hindi.&lt;br /&gt;
&lt;br /&gt;
3. Check to see if the English strings on the profile page are translated to Hindi.&lt;br /&gt;
&lt;br /&gt;
4. Check if a page for which Hindi translation keys are added has its English static strings translated to Hindi.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Scenario 2&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Log in to Expertiza as a student.&lt;br /&gt;
&lt;br /&gt;
2. Go to the “user profile” page and change “preferred language” to Nil.&lt;br /&gt;
&lt;br /&gt;
3.  Check to see if the English strings on the page are unchanged, as the “user profile” translates only if the student has a preference.&lt;br /&gt;
&lt;br /&gt;
4. Go to an assignment page for which Hindi translation keys are added, which is under a course with the default language set to Hindi, and check whether the English strings are translated to Hindi.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Scenario 3&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Log in to Expertiza as a student.&lt;br /&gt;
&lt;br /&gt;
2. Go to the “user profile” page and change “preferred language” to Nil.&lt;br /&gt;
&lt;br /&gt;
3.  Check to see if the English strings on the page are unchanged, as the “user profile” translates only if the student has a preference.&lt;br /&gt;
&lt;br /&gt;
4. Go to a non-course-specific page and verify that the page is displayed in English itself, as non of the default languages set for any of the courses should have any role.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Scenario 4&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
1. Log in to Expertiza as a student.&lt;br /&gt;
&lt;br /&gt;
2. Go to the “user profile” page and change “preferred language” to Hindi.&lt;br /&gt;
&lt;br /&gt;
3.  Go to a page where translation keys aren’t added completely and make sure that the unspecified keys display strings in English as a fallback.&lt;br /&gt;
&lt;br /&gt;
== Future Scope==&lt;br /&gt;
'''1. Expand to more languages'''&amp;lt;br&amp;gt;&lt;br /&gt;
As part of this project we have targetted Hindi as a second language, however our work makes it easy to extend to other languages as well.&lt;br /&gt;
&lt;br /&gt;
'''2. Identify and implement the course language override on more course specific screens'''&amp;lt;br&amp;gt;&lt;br /&gt;
As part of this project, we have introduced a generic framework by which any view can provide a preferred language in which it should be rendered, this is required by this project for the course language feature set by the instructor.&lt;br /&gt;
We have currently made the assignment screen display in the course’s language, however other screens such as the “Your work” screen and so on are also specific to the course could also be rendered in the course language when the user has not provided a preference.&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
&lt;br /&gt;
'''Team Members'''&lt;br /&gt;
&lt;br /&gt;
Reuben M. V. John [[mailto:rmjohn2@ncsu.edu rmjohn2@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Renji Joseph Sabu [[mailto:rsabu@ncsu.edu rsabu@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Ashwin Das [[mailto:adas9@ncsu.edu adas9@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Arnav Julka [[mailto:ajulka@ncsu.edu ajulka@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Mentor'''&lt;br /&gt;
&lt;br /&gt;
Jialin Cui [[mailto:jcui9@ncsu.edu jcui9@ncsu.edu]]&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Language2inter.png&amp;diff=140652</id>
		<title>File:Language2inter.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Language2inter.png&amp;diff=140652"/>
		<updated>2021-11-03T21:19:34Z</updated>

		<summary type="html">&lt;p&gt;Adas9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Language1inter.png&amp;diff=140650</id>
		<title>File:Language1inter.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Language1inter.png&amp;diff=140650"/>
		<updated>2021-11-03T21:18:54Z</updated>

		<summary type="html">&lt;p&gt;Adas9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2159._Expertiza_internationalization&amp;diff=140569</id>
		<title>CSC/ECE 517 Fall 2021 - E2159. Expertiza internationalization</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2159._Expertiza_internationalization&amp;diff=140569"/>
		<updated>2021-11-03T03:36:30Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Scope */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction - Purpose &amp;amp; Problem ==&lt;br /&gt;
&lt;br /&gt;
Currently, all Expertiza screens can only be viewed in English. Many Expertiza users are from other countries. This is a problem since this limits the accessibility of Expertiza. An important step in solving this problem is by making Expertiza available in more languages, which is a form of internationalization.&lt;br /&gt;
W3C defines [https://www.w3.org/International/questions/qa-i18n internationalization] as “''the design and development of a product, application or document content that enables easy localization for target audiences that vary in culture, region, or language.''”&lt;br /&gt;
&lt;br /&gt;
[[File:country_pie.png|none|500px|]]&amp;lt;br&amp;gt;&lt;br /&gt;
Survey of home country of Expertiza users for a given course&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Scope:''' The scope of this project is limited however only to static strings. i.e. user-generated content will not be automatically translated to other languages.&lt;br /&gt;
&lt;br /&gt;
'''Breaking down internationalization into 3 sequential subproblems:'''&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Twophase2.jpg|none|700px]]&amp;lt;br&amp;gt;&lt;br /&gt;
'''1. Language selection'''&lt;br /&gt;
@rsabu &amp;lt;br&amp;gt;&lt;br /&gt;
Internationalization is done for pages viewed by students only. Any user other than students views all pages in English. The student has the option to set a language preference.&lt;br /&gt;
&lt;br /&gt;
LOFI UI sketch &lt;br /&gt;
&amp;lt;Insert image here&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
There is also an option where the instructor can choose a default language for a course. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;Insert image here&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thus, the language not only varies from user to user but also across screens for the same user. Thus we need to recompute the language in which the page is to be rendered. If the student has given a language preference, then the choice is given weightage over the default language chosen by the instructor. &lt;br /&gt;
&lt;br /&gt;
'''2. Rendering the language'''&amp;lt;br&amp;gt;&lt;br /&gt;
'''How do we go about rendering the screen in that language?''' &amp;lt;br&amp;gt;&lt;br /&gt;
In the previous step, we’ve identified the language in which a view is to be rendered. It is important to note that this language may not only differ for a different user, but also for a different page for the same user. The question now becomes, how do we render the screen in this language?&amp;lt;br&amp;gt;&lt;br /&gt;
To tackle this question, we explore 2 fundamental concepts:&amp;lt;br&amp;gt;&lt;br /&gt;
'''2.1 Views are composed of independent language elements'''&amp;lt;br&amp;gt;&lt;br /&gt;
While this is something we typically take for granted, it becomes especially important in the context of translation. That is, a view is not a single contiguous block of text, nor is it an atomic visualization of information (unlike a screenshot), but rather a carefully organized collection of individual elements such as texts, buttons, etc that each contain language that needs to be translated separately. Crucially, this means that we cannot swap out a page in one language in its entirety for a page in another language in its entirety. Instead, each individual element needs to be swapped out individually so as to only impact the language and not the structural composition of the page itself.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
'''2.2 Views require translation at a large number of call sites'''&amp;lt;br&amp;gt;&lt;br /&gt;
Given that a view is composed of individual elements, this also means that the computation of how to translate such an element such as a button’s text would need to be done separately for each element. This would result in not only a single centralized &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3. Translation gaps'''&lt;br /&gt;
&lt;br /&gt;
What if the translation for the target language is not available?&lt;br /&gt;
Even translation for a language like Hindi may be available in general, the translation for a given text may not be available Hindi. This may be due to a variety of reasons:&lt;br /&gt;
The specific text may have been accidentally missed out (remember the translation is not being done at runtime through an API, but rather curated by the developer)&lt;br /&gt;
The given text is non-trivial to translate to the target language&lt;br /&gt;
Our design would thus need to accommodate this by seamlessly falling back on another language whose translation is available.&lt;br /&gt;
&lt;br /&gt;
== Scope ==&lt;br /&gt;
The scope of this project is limited however only to static strings. I.e. user-generated content will not be automatically translated to other languages.&lt;br /&gt;
&lt;br /&gt;
== Design ==&lt;br /&gt;
'''Proposed Solution'''&lt;br /&gt;
&lt;br /&gt;
'''''1. Language selection'''''&amp;lt;br&amp;gt;&lt;br /&gt;
The language in which the page is rendered depends on a set of conditions.&lt;br /&gt;
If the student has set a language preference, it overrides the default language setting saved by the instructor, and all pages are displayed in the language preferred by the student.&lt;br /&gt;
If the student has not set a language preference and is on a page that is specific to a course for which the instructor has added a default language, the page is displayed in the course’s default language.&lt;br /&gt;
If the student has not set a language preference and is not on a course-specific page, then the page is displayed in English.&lt;br /&gt;
If a language preference is obtained by following the above conditions but some keys in the page don't have a translation for the language, the English translation for that key is returned as a fallback.&lt;br /&gt;
&lt;br /&gt;
'''''2. Rendering the language'''''&amp;lt;br&amp;gt;&lt;br /&gt;
Once we have determined the language in which to render the page, we now need to update the rails view code to actually generate the appropriate HTML in the target language. This is the responsibility of the view. However, currently, the actual content of the HTML is hardcoded in (red) English. For example:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;Summary Report for assignment: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Team: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
As discussed earlier, “Views are composed of independent language elements” and so we cannot simply swap out the entire page content for a separate page in another language (Why? - See “swap out the entire view” in the alternative approaches section):&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;Rapport de synthèse pour l'affectation: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Équipe: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Instead, the better approach is to have a single unified view that dynamically changes based on the selected language:&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;&amp;lt;%=language==’en’ ? ‘Summary Report for assignment’ : ‘Rapport de synthèse pour l'affectation’&amp;gt;: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;&amp;lt;%=language==’en’ ? ‘Team’ : ‘Équipe’&amp;gt;: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;However this is clearly infeasible considering the number of call sites where we have to apply this logic. Thus, in order to maximize how concise the call site is, we can pull out this logic into a common helper function:&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;&amp;lt;%=localized(“report_summary.page_header”)&amp;gt;: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;&amp;lt;%=localized(“report_summary.team_label”)&amp;gt;: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;Here the assumption is that the localized(“key”) is aware of the currently selected language and that “report_summary.page_header” is the key for the header which is available in English and Hindi. The helper intelligently selects and returns the right text based on the currently selected language. Through this approach, we are able to render the view in multiple possible languages without any significant increase in the verbosity of the view.&lt;br /&gt;
&lt;br /&gt;
What’s more, is that the above problem is a common problem for user-facing applications and a standard library for doing the above and much more already exists for rails applications called i18n&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''I18n - Internationalisation, How are we using I18n in Ruby on Rail'''''&amp;lt;br&amp;gt;&lt;br /&gt;
I18n is a ruby library/gem which helps us render the static string on the view dynamically. Dynamicity means that based on a local decision of choosing the current language of the view, the library returns the strings of that particular language at runtime.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
These strings, instead of hardcoding in the view.rb, are provided in external .yml files. Now at the View level, we can pass an id to the 't' function and the I18n library returns the string for that id of the current set language(called as locale). &amp;lt;br&amp;gt;&lt;br /&gt;
[[File:i18n.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
For this purpose, we have to provide .yml files for each language and in those language-specific .yml, we have to provide a map of key-value pairs where the key is the id of the string and value is the string in that particular language. By default the language or locale is set to be English(:en). &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
THE GREATEST BENEFITS of using this library are - &amp;lt;br&amp;gt;&lt;br /&gt;
*The strings aren't hardcoded in the code/build. The strings are being fetched from external files which can be easily modified. For example, if one needs to change the text from 'Please Help' to 'Help', then one just needs to make a change in the .yml file and the change would reflect on the browser. For this change, we didn't need to redeploy the server. We just Decoupled the view when and where from what content is to be shown. &lt;br /&gt;
*Adding more languages is now super easy. Adding support for another language is just one line change in the config and adding a .yml file (having all the key-value pairs for the strings) for the new language. By doing this we can extend the language support as much as we want.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
'''''3. Translation gaps'''''&lt;br /&gt;
&amp;lt;br&amp;gt;Also, if the language is set to be Hindi or any other language but the key-value pair is not set for that particular string then, automatically the library returns the default which is the English text.&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;config.i18n.fallbacks = [:en]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Alternate approaches ==&lt;br /&gt;
&lt;br /&gt;
'''1. Why not simply swap out the entire view for another language instead of each text?'''&amp;lt;br&amp;gt;&lt;br /&gt;
A view is an organized collection of multiple separate elements, views often involve dynamic generation and some level of sophistication. If we were to swap out one page in its entirety for another page this would often violate the '''DRY''' principle since we would have to have two separate implementations of the view in each language. Thus in the worst case, you have a complex view that has to be replicated dozens of times in various languages.&lt;br /&gt;
The majority of complexity of the page is not in the content itself but rather the code that executes to generate that content, thus it makes sense to instead maintain a single view and embed the language switching logic at each location where translation needs to occur to avoid replication of everything around it.&lt;br /&gt;
&lt;br /&gt;
'''2. Why did we pick i18n over implementing it ourselves?'''&amp;lt;br&amp;gt;&lt;br /&gt;
@ajulka&lt;br /&gt;
&lt;br /&gt;
'''3, Do we store the language preference, in the session or in the database?'''&amp;lt;br&amp;gt;&lt;br /&gt;
@rsabu&lt;br /&gt;
&lt;br /&gt;
== Use Case Diagram ==&lt;br /&gt;
== Major design patterns and principles used ==&lt;br /&gt;
&lt;br /&gt;
'''1. DRY: The i18n ‘t’ function'''&amp;lt;br&amp;gt;&lt;br /&gt;
We observe an extreme case of DRY with the t function of i18n.&lt;br /&gt;
For some background, the t function of the library takes in a key representing a text and returns the content referred to by that key in the preferred language of the user. It also performs many other functions such as falling back to a backup language if the translation for the preferred language has not been configured for that specific key. Thus since this logic has to be applied at every element of the view, it would behove us to extract this logic into a reusable function which is what the designers of the i18n library have employed&lt;br /&gt;
&lt;br /&gt;
'''2. Chain of responsibility'''&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Chainofresp.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The I18n library gives us an option to have many fall back options. When the required text for a given language is not found, we then move on to find the text for the next language in the chain and so on until we find it. And in the end we will put english as default language. So if the key value pair for the text is not found in none of the yml files then the text will be fetched from the English language yml file.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''3. Open closed principle &amp;amp; Strategy Pattern'''&amp;lt;br&amp;gt;&lt;br /&gt;
As discussed in the “Language selection&amp;quot; design proposal above, if the user has not selected a preferred language, we do not simply default the view to render in the application language (English). Instead, the project requirements state that for course specific screens such as the assignment view, we would need to render the view in the course’s language.&lt;br /&gt;
While we could implement this code into the application controller that checks the controller being access and accordingly applies overrides on the default language, this violates the open closed principle since we would need to extend this logic any time we introduce a new course specific screen. Instead a better approach is to delegate the decision of selecting the language to the view itself since the view would be most aware of whether the view is course specific or not. We can also preserve the DRYness through mix-ins.&lt;br /&gt;
&lt;br /&gt;
== Database Design ==&lt;br /&gt;
Database Modification ==&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
Test Details&lt;br /&gt;
Manual Testing&lt;br /&gt;
Scenario 1&lt;br /&gt;
Scenario 2&lt;br /&gt;
Scenario 3&lt;br /&gt;
Scenario 4&lt;br /&gt;
Scenario 5&lt;br /&gt;
== Future Scope==&lt;br /&gt;
'''1. Expand to more languages'''&amp;lt;br&amp;gt;&lt;br /&gt;
As part of this project we have targetted Hindi as a second language, however our work makes it easy to extend to other languages as well.&lt;br /&gt;
&lt;br /&gt;
'''2. Identify and implement the course language override on more course specific screens'''&amp;lt;br&amp;gt;&lt;br /&gt;
As part of this project, we have introduced a generic framework by which any view can provide a preferred language in which it should be rendered, this is required by this project for the course language feature set by the instructor.&lt;br /&gt;
We have currently made the assignment screen display in the course’s language, however other screens such as the “Your work” screen and so on are also specific to the course could also be rendered in the course language when the user has not provided a preference.&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
&lt;br /&gt;
'''Team Members'''&lt;br /&gt;
&lt;br /&gt;
Reuben M. V. John [[mailto:rmjohn2@ncsu.edu rmjohn2@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Renji Joseph Sabu [[mailto:rsabu@ncsu.edu rsabu@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Ashwin Das [[mailto:adas9@ncsu.edu adas9@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Arnav Julka [[mailto:ajulka@ncsu.edu ajulka@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Mentor'''&lt;br /&gt;
&lt;br /&gt;
Jialin Cui [[mailto:jcui9@ncsu.edu jcui9@ncsu.edu]]&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2159._Expertiza_internationalization&amp;diff=140568</id>
		<title>CSC/ECE 517 Fall 2021 - E2159. Expertiza internationalization</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2159._Expertiza_internationalization&amp;diff=140568"/>
		<updated>2021-11-03T03:35:29Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Design */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction - Purpose &amp;amp; Problem ==&lt;br /&gt;
&lt;br /&gt;
Currently, all Expertiza screens can only be viewed in English. Many Expertiza users are from other countries. This is a problem since this limits the accessibility of Expertiza. An important step in solving this problem is by making Expertiza available in more languages, which is a form of internationalization.&lt;br /&gt;
W3C defines [https://www.w3.org/International/questions/qa-i18n internationalization] as “''the design and development of a product, application or document content that enables easy localization for target audiences that vary in culture, region, or language.''”&lt;br /&gt;
&lt;br /&gt;
[[File:country_pie.png|none|500px|]]&amp;lt;br&amp;gt;&lt;br /&gt;
Survey of home country of Expertiza users for a given course&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Scope:''' The scope of this project is limited however only to static strings. i.e. user-generated content will not be automatically translated to other languages.&lt;br /&gt;
&lt;br /&gt;
'''Breaking down internationalization into 3 sequential subproblems:'''&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Twophase2.jpg|none|700px]]&amp;lt;br&amp;gt;&lt;br /&gt;
'''1. Language selection'''&lt;br /&gt;
@rsabu &amp;lt;br&amp;gt;&lt;br /&gt;
Internationalization is done for pages viewed by students only. Any user other than students views all pages in English. The student has the option to set a language preference.&lt;br /&gt;
&lt;br /&gt;
LOFI UI sketch &lt;br /&gt;
&amp;lt;Insert image here&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
There is also an option where the instructor can choose a default language for a course. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;Insert image here&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thus, the language not only varies from user to user but also across screens for the same user. Thus we need to recompute the language in which the page is to be rendered. If the student has given a language preference, then the choice is given weightage over the default language chosen by the instructor. &lt;br /&gt;
&lt;br /&gt;
'''2. Rendering the language'''&amp;lt;br&amp;gt;&lt;br /&gt;
'''How do we go about rendering the screen in that language?''' &amp;lt;br&amp;gt;&lt;br /&gt;
In the previous step, we’ve identified the language in which a view is to be rendered. It is important to note that this language may not only differ for a different user, but also for a different page for the same user. The question now becomes, how do we render the screen in this language?&amp;lt;br&amp;gt;&lt;br /&gt;
To tackle this question, we explore 2 fundamental concepts:&amp;lt;br&amp;gt;&lt;br /&gt;
'''2.1 Views are composed of independent language elements'''&amp;lt;br&amp;gt;&lt;br /&gt;
While this is something we typically take for granted, it becomes especially important in the context of translation. That is, a view is not a single contiguous block of text, nor is it an atomic visualization of information (unlike a screenshot), but rather a carefully organized collection of individual elements such as texts, buttons, etc that each contain language that needs to be translated separately. Crucially, this means that we cannot swap out a page in one language in its entirety for a page in another language in its entirety. Instead, each individual element needs to be swapped out individually so as to only impact the language and not the structural composition of the page itself.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
'''2.2 Views require translation at a large number of call sites'''&amp;lt;br&amp;gt;&lt;br /&gt;
Given that a view is composed of individual elements, this also means that the computation of how to translate such an element such as a button’s text would need to be done separately for each element. This would result in not only a single centralized &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3. Translation gaps'''&lt;br /&gt;
&lt;br /&gt;
What if the translation for the target language is not available?&lt;br /&gt;
Even translation for a language like Hindi may be available in general, the translation for a given text may not be available Hindi. This may be due to a variety of reasons:&lt;br /&gt;
The specific text may have been accidentally missed out (remember the translation is not being done at runtime through an API, but rather curated by the developer)&lt;br /&gt;
The given text is non-trivial to translate to the target language&lt;br /&gt;
Our design would thus need to accommodate this by seamlessly falling back on another language whose translation is available.&lt;br /&gt;
&lt;br /&gt;
== Scope ==&lt;br /&gt;
== Design ==&lt;br /&gt;
'''Proposed Solution'''&lt;br /&gt;
&lt;br /&gt;
'''''1. Language selection'''''&amp;lt;br&amp;gt;&lt;br /&gt;
The language in which the page is rendered depends on a set of conditions.&lt;br /&gt;
If the student has set a language preference, it overrides the default language setting saved by the instructor, and all pages are displayed in the language preferred by the student.&lt;br /&gt;
If the student has not set a language preference and is on a page that is specific to a course for which the instructor has added a default language, the page is displayed in the course’s default language.&lt;br /&gt;
If the student has not set a language preference and is not on a course-specific page, then the page is displayed in English.&lt;br /&gt;
If a language preference is obtained by following the above conditions but some keys in the page don't have a translation for the language, the English translation for that key is returned as a fallback.&lt;br /&gt;
&lt;br /&gt;
'''''2. Rendering the language'''''&amp;lt;br&amp;gt;&lt;br /&gt;
Once we have determined the language in which to render the page, we now need to update the rails view code to actually generate the appropriate HTML in the target language. This is the responsibility of the view. However, currently, the actual content of the HTML is hardcoded in (red) English. For example:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;Summary Report for assignment: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Team: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
As discussed earlier, “Views are composed of independent language elements” and so we cannot simply swap out the entire page content for a separate page in another language (Why? - See “swap out the entire view” in the alternative approaches section):&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;Rapport de synthèse pour l'affectation: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Équipe: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Instead, the better approach is to have a single unified view that dynamically changes based on the selected language:&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;&amp;lt;%=language==’en’ ? ‘Summary Report for assignment’ : ‘Rapport de synthèse pour l'affectation’&amp;gt;: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;&amp;lt;%=language==’en’ ? ‘Team’ : ‘Équipe’&amp;gt;: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;However this is clearly infeasible considering the number of call sites where we have to apply this logic. Thus, in order to maximize how concise the call site is, we can pull out this logic into a common helper function:&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;&amp;lt;%=localized(“report_summary.page_header”)&amp;gt;: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;&amp;lt;%=localized(“report_summary.team_label”)&amp;gt;: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;Here the assumption is that the localized(“key”) is aware of the currently selected language and that “report_summary.page_header” is the key for the header which is available in English and Hindi. The helper intelligently selects and returns the right text based on the currently selected language. Through this approach, we are able to render the view in multiple possible languages without any significant increase in the verbosity of the view.&lt;br /&gt;
&lt;br /&gt;
What’s more, is that the above problem is a common problem for user-facing applications and a standard library for doing the above and much more already exists for rails applications called i18n&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''I18n - Internationalisation, How are we using I18n in Ruby on Rail'''''&amp;lt;br&amp;gt;&lt;br /&gt;
I18n is a ruby library/gem which helps us render the static string on the view dynamically. Dynamicity means that based on a local decision of choosing the current language of the view, the library returns the strings of that particular language at runtime.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
These strings, instead of hardcoding in the view.rb, are provided in external .yml files. Now at the View level, we can pass an id to the 't' function and the I18n library returns the string for that id of the current set language(called as locale). &amp;lt;br&amp;gt;&lt;br /&gt;
[[File:i18n.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
For this purpose, we have to provide .yml files for each language and in those language-specific .yml, we have to provide a map of key-value pairs where the key is the id of the string and value is the string in that particular language. By default the language or locale is set to be English(:en). &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
THE GREATEST BENEFITS of using this library are - &amp;lt;br&amp;gt;&lt;br /&gt;
*The strings aren't hardcoded in the code/build. The strings are being fetched from external files which can be easily modified. For example, if one needs to change the text from 'Please Help' to 'Help', then one just needs to make a change in the .yml file and the change would reflect on the browser. For this change, we didn't need to redeploy the server. We just Decoupled the view when and where from what content is to be shown. &lt;br /&gt;
*Adding more languages is now super easy. Adding support for another language is just one line change in the config and adding a .yml file (having all the key-value pairs for the strings) for the new language. By doing this we can extend the language support as much as we want.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
'''''3. Translation gaps'''''&lt;br /&gt;
&amp;lt;br&amp;gt;Also, if the language is set to be Hindi or any other language but the key-value pair is not set for that particular string then, automatically the library returns the default which is the English text.&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;config.i18n.fallbacks = [:en]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Alternate approaches ==&lt;br /&gt;
&lt;br /&gt;
'''1. Why not simply swap out the entire view for another language instead of each text?'''&amp;lt;br&amp;gt;&lt;br /&gt;
A view is an organized collection of multiple separate elements, views often involve dynamic generation and some level of sophistication. If we were to swap out one page in its entirety for another page this would often violate the '''DRY''' principle since we would have to have two separate implementations of the view in each language. Thus in the worst case, you have a complex view that has to be replicated dozens of times in various languages.&lt;br /&gt;
The majority of complexity of the page is not in the content itself but rather the code that executes to generate that content, thus it makes sense to instead maintain a single view and embed the language switching logic at each location where translation needs to occur to avoid replication of everything around it.&lt;br /&gt;
&lt;br /&gt;
'''2. Why did we pick i18n over implementing it ourselves?'''&amp;lt;br&amp;gt;&lt;br /&gt;
@ajulka&lt;br /&gt;
&lt;br /&gt;
'''3, Do we store the language preference, in the session or in the database?'''&amp;lt;br&amp;gt;&lt;br /&gt;
@rsabu&lt;br /&gt;
&lt;br /&gt;
== Use Case Diagram ==&lt;br /&gt;
== Major design patterns and principles used ==&lt;br /&gt;
&lt;br /&gt;
'''1. DRY: The i18n ‘t’ function'''&amp;lt;br&amp;gt;&lt;br /&gt;
We observe an extreme case of DRY with the t function of i18n.&lt;br /&gt;
For some background, the t function of the library takes in a key representing a text and returns the content referred to by that key in the preferred language of the user. It also performs many other functions such as falling back to a backup language if the translation for the preferred language has not been configured for that specific key. Thus since this logic has to be applied at every element of the view, it would behove us to extract this logic into a reusable function which is what the designers of the i18n library have employed&lt;br /&gt;
&lt;br /&gt;
'''2. Chain of responsibility'''&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Chainofresp.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The I18n library gives us an option to have many fall back options. When the required text for a given language is not found, we then move on to find the text for the next language in the chain and so on until we find it. And in the end we will put english as default language. So if the key value pair for the text is not found in none of the yml files then the text will be fetched from the English language yml file.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''3. Open closed principle &amp;amp; Strategy Pattern'''&amp;lt;br&amp;gt;&lt;br /&gt;
As discussed in the “Language selection&amp;quot; design proposal above, if the user has not selected a preferred language, we do not simply default the view to render in the application language (English). Instead, the project requirements state that for course specific screens such as the assignment view, we would need to render the view in the course’s language.&lt;br /&gt;
While we could implement this code into the application controller that checks the controller being access and accordingly applies overrides on the default language, this violates the open closed principle since we would need to extend this logic any time we introduce a new course specific screen. Instead a better approach is to delegate the decision of selecting the language to the view itself since the view would be most aware of whether the view is course specific or not. We can also preserve the DRYness through mix-ins.&lt;br /&gt;
&lt;br /&gt;
== Database Design ==&lt;br /&gt;
Database Modification ==&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
Test Details&lt;br /&gt;
Manual Testing&lt;br /&gt;
Scenario 1&lt;br /&gt;
Scenario 2&lt;br /&gt;
Scenario 3&lt;br /&gt;
Scenario 4&lt;br /&gt;
Scenario 5&lt;br /&gt;
== Future Scope==&lt;br /&gt;
'''1. Expand to more languages'''&amp;lt;br&amp;gt;&lt;br /&gt;
As part of this project we have targetted Hindi as a second language, however our work makes it easy to extend to other languages as well.&lt;br /&gt;
&lt;br /&gt;
'''2. Identify and implement the course language override on more course specific screens'''&amp;lt;br&amp;gt;&lt;br /&gt;
As part of this project, we have introduced a generic framework by which any view can provide a preferred language in which it should be rendered, this is required by this project for the course language feature set by the instructor.&lt;br /&gt;
We have currently made the assignment screen display in the course’s language, however other screens such as the “Your work” screen and so on are also specific to the course could also be rendered in the course language when the user has not provided a preference.&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
&lt;br /&gt;
'''Team Members'''&lt;br /&gt;
&lt;br /&gt;
Reuben M. V. John [[mailto:rmjohn2@ncsu.edu rmjohn2@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Renji Joseph Sabu [[mailto:rsabu@ncsu.edu rsabu@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Ashwin Das [[mailto:adas9@ncsu.edu adas9@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Arnav Julka [[mailto:ajulka@ncsu.edu ajulka@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Mentor'''&lt;br /&gt;
&lt;br /&gt;
Jialin Cui [[mailto:jcui9@ncsu.edu jcui9@ncsu.edu]]&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2159._Expertiza_internationalization&amp;diff=140567</id>
		<title>CSC/ECE 517 Fall 2021 - E2159. Expertiza internationalization</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2159._Expertiza_internationalization&amp;diff=140567"/>
		<updated>2021-11-03T03:31:16Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Introduction - Purpose &amp;amp; Problem */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction - Purpose &amp;amp; Problem ==&lt;br /&gt;
&lt;br /&gt;
Currently, all Expertiza screens can only be viewed in English. Many Expertiza users are from other countries. This is a problem since this limits the accessibility of Expertiza. An important step in solving this problem is by making Expertiza available in more languages, which is a form of internationalization.&lt;br /&gt;
W3C defines [https://www.w3.org/International/questions/qa-i18n internationalization] as “''the design and development of a product, application or document content that enables easy localization for target audiences that vary in culture, region, or language.''”&lt;br /&gt;
&lt;br /&gt;
[[File:country_pie.png|none|500px|]]&amp;lt;br&amp;gt;&lt;br /&gt;
Survey of home country of Expertiza users for a given course&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Scope:''' The scope of this project is limited however only to static strings. i.e. user-generated content will not be automatically translated to other languages.&lt;br /&gt;
&lt;br /&gt;
'''Breaking down internationalization into 3 sequential subproblems:'''&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Twophase2.jpg|none|700px]]&amp;lt;br&amp;gt;&lt;br /&gt;
'''1. Language selection'''&lt;br /&gt;
@rsabu &amp;lt;br&amp;gt;&lt;br /&gt;
Internationalization is done for pages viewed by students only. Any user other than students views all pages in English. The student has the option to set a language preference.&lt;br /&gt;
&lt;br /&gt;
LOFI UI sketch &lt;br /&gt;
&amp;lt;Insert image here&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
There is also an option where the instructor can choose a default language for a course. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;Insert image here&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thus, the language not only varies from user to user but also across screens for the same user. Thus we need to recompute the language in which the page is to be rendered. If the student has given a language preference, then the choice is given weightage over the default language chosen by the instructor. &lt;br /&gt;
&lt;br /&gt;
'''2. Rendering the language'''&amp;lt;br&amp;gt;&lt;br /&gt;
'''How do we go about rendering the screen in that language?''' &amp;lt;br&amp;gt;&lt;br /&gt;
In the previous step, we’ve identified the language in which a view is to be rendered. It is important to note that this language may not only differ for a different user, but also for a different page for the same user. The question now becomes, how do we render the screen in this language?&amp;lt;br&amp;gt;&lt;br /&gt;
To tackle this question, we explore 2 fundamental concepts:&amp;lt;br&amp;gt;&lt;br /&gt;
'''2.1 Views are composed of independent language elements'''&amp;lt;br&amp;gt;&lt;br /&gt;
While this is something we typically take for granted, it becomes especially important in the context of translation. That is, a view is not a single contiguous block of text, nor is it an atomic visualization of information (unlike a screenshot), but rather a carefully organized collection of individual elements such as texts, buttons, etc that each contain language that needs to be translated separately. Crucially, this means that we cannot swap out a page in one language in its entirety for a page in another language in its entirety. Instead, each individual element needs to be swapped out individually so as to only impact the language and not the structural composition of the page itself.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
'''2.2 Views require translation at a large number of call sites'''&amp;lt;br&amp;gt;&lt;br /&gt;
Given that a view is composed of individual elements, this also means that the computation of how to translate such an element such as a button’s text would need to be done separately for each element. This would result in not only a single centralized &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3. Translation gaps'''&lt;br /&gt;
&lt;br /&gt;
What if the translation for the target language is not available?&lt;br /&gt;
Even translation for a language like Hindi may be available in general, the translation for a given text may not be available Hindi. This may be due to a variety of reasons:&lt;br /&gt;
The specific text may have been accidentally missed out (remember the translation is not being done at runtime through an API, but rather curated by the developer)&lt;br /&gt;
The given text is non-trivial to translate to the target language&lt;br /&gt;
Our design would thus need to accommodate this by seamlessly falling back on another language whose translation is available.&lt;br /&gt;
&lt;br /&gt;
== Scope ==&lt;br /&gt;
== Design ==&lt;br /&gt;
Proposed Solution&lt;br /&gt;
1. Language selection&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''2. Rendering the language'''''&amp;lt;br&amp;gt;&lt;br /&gt;
Rendering the language&amp;lt;br&amp;gt;&lt;br /&gt;
Once we have determined the language in which to render the page, we now need to update the rails view code to actually generate the appropriate HTML in the target language. This is the responsibility of the view. However, currently, the actual content of the HTML is hardcoded in (red) English. For example:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;Summary Report for assignment: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Team: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
As discussed earlier, “Views are composed of independent language elements” and so we cannot simply swap out the entire page content for a separate page in another language (Why? - See “swap out the entire view” in the alternative approaches section):&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;Rapport de synthèse pour l'affectation: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Équipe: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Instead, the better approach is to have a single unified view that dynamically changes based on the selected language:&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;&amp;lt;%=language==’en’ ? ‘Summary Report for assignment’ : ‘Rapport de synthèse pour l'affectation’&amp;gt;: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;&amp;lt;%=language==’en’ ? ‘Team’ : ‘Équipe’&amp;gt;: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;However this is clearly infeasible considering the number of call sites where we have to apply this logic. Thus, in order to maximize how concise the call site is, we can pull out this logic into a common helper function:&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;&amp;lt;%=localized(“report_summary.page_header”)&amp;gt;: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;&amp;lt;%=localized(“report_summary.team_label”)&amp;gt;: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;Here the assumption is that the localized(“key”) is aware of the currently selected language and that “report_summary.page_header” is the key for the header which is available in English and Hindi. The helper intelligently selects and returns the right text based on the currently selected language. Through this approach, we are able to render the view in multiple possible languages without any significant increase in the verbosity of the view.&lt;br /&gt;
&lt;br /&gt;
What’s more, is that the above problem is a common problem for user-facing applications and a standard library for doing the above and much more already exists for rails applications called i18n&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''I18n - Internationalisation, How are we using I18n in Ruby on Rail'''''&amp;lt;br&amp;gt;&lt;br /&gt;
I18n is a ruby library/gem which helps us render the static string on the view dynamically. Dynamicity means that based on a local decision of choosing the current language of the view, the library returns the strings of that particular language at runtime.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
These strings, instead of hardcoding in the view.rb, are provided in external .yml files. Now at the View level, we can pass an id to the 't' function and the I18n library returns the string for that id of the current set language(called as locale). &amp;lt;br&amp;gt;&lt;br /&gt;
[[File:i18n.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
For this purpose, we have to provide .yml files for each language and in those language-specific .yml, we have to provide a map of key-value pairs where the key is the id of the string and value is the string in that particular language. By default the language or locale is set to be English(:en). &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
THE GREATEST BENEFITS of using this library are - &amp;lt;br&amp;gt;&lt;br /&gt;
*The strings aren't hardcoded in the code/build. The strings are being fetched from external files which can be easily modified. For example, if one needs to change the text from 'Please Help' to 'Help', then one just needs to make a change in the .yml file and the change would reflect on the browser. For this change, we didn't need to redeploy the server. We just Decoupled the view when and where from what content is to be shown. &lt;br /&gt;
*Adding more languages is now super easy. Adding support for another language is just one line change in the config and adding a .yml file (having all the key-value pairs for the strings) for the new language. By doing this we can extend the language support as much as we want.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
'''''3. Translation gaps'''''&lt;br /&gt;
&amp;lt;br&amp;gt;Also, if the language is set to be Hindi or any other language but the key-value pair is not set for that particular string then, automatically the library returns the default which is the English text.&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;config.i18n.fallbacks = [:en]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Alternate approaches ==&lt;br /&gt;
&lt;br /&gt;
'''1. Why not simply swap out the entire view for another language instead of each text?'''&amp;lt;br&amp;gt;&lt;br /&gt;
A view is an organized collection of multiple separate elements, views often involve dynamic generation and some level of sophistication. If we were to swap out one page in its entirety for another page this would often violate the '''DRY''' principle since we would have to have two separate implementations of the view in each language. Thus in the worst case, you have a complex view that has to be replicated dozens of times in various languages.&lt;br /&gt;
The majority of complexity of the page is not in the content itself but rather the code that executes to generate that content, thus it makes sense to instead maintain a single view and embed the language switching logic at each location where translation needs to occur to avoid replication of everything around it.&lt;br /&gt;
&lt;br /&gt;
'''2. Why did we pick i18n over implementing it ourselves?'''&amp;lt;br&amp;gt;&lt;br /&gt;
@ajulka&lt;br /&gt;
&lt;br /&gt;
'''3, Do we store the language preference, in the session or in the database?'''&amp;lt;br&amp;gt;&lt;br /&gt;
@rsabu&lt;br /&gt;
&lt;br /&gt;
== Use Case Diagram ==&lt;br /&gt;
== Major design patterns and principles used ==&lt;br /&gt;
&lt;br /&gt;
'''1. DRY: The i18n ‘t’ function'''&amp;lt;br&amp;gt;&lt;br /&gt;
We observe an extreme case of DRY with the t function of i18n.&lt;br /&gt;
For some background, the t function of the library takes in a key representing a text and returns the content referred to by that key in the preferred language of the user. It also performs many other functions such as falling back to a backup language if the translation for the preferred language has not been configured for that specific key. Thus since this logic has to be applied at every element of the view, it would behove us to extract this logic into a reusable function which is what the designers of the i18n library have employed&lt;br /&gt;
&lt;br /&gt;
'''2. Chain of responsibility'''&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Chainofresp.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The I18n library gives us an option to have many fall back options. When the required text for a given language is not found, we then move on to find the text for the next language in the chain and so on until we find it. And in the end we will put english as default language. So if the key value pair for the text is not found in none of the yml files then the text will be fetched from the English language yml file.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''3. Open closed principle &amp;amp; Strategy Pattern'''&amp;lt;br&amp;gt;&lt;br /&gt;
As discussed in the “Language selection&amp;quot; design proposal above, if the user has not selected a preferred language, we do not simply default the view to render in the application language (English). Instead, the project requirements state that for course specific screens such as the assignment view, we would need to render the view in the course’s language.&lt;br /&gt;
While we could implement this code into the application controller that checks the controller being access and accordingly applies overrides on the default language, this violates the open closed principle since we would need to extend this logic any time we introduce a new course specific screen. Instead a better approach is to delegate the decision of selecting the language to the view itself since the view would be most aware of whether the view is course specific or not. We can also preserve the DRYness through mix-ins.&lt;br /&gt;
&lt;br /&gt;
== Database Design ==&lt;br /&gt;
Database Modification ==&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
Test Details&lt;br /&gt;
Manual Testing&lt;br /&gt;
Scenario 1&lt;br /&gt;
Scenario 2&lt;br /&gt;
Scenario 3&lt;br /&gt;
Scenario 4&lt;br /&gt;
Scenario 5&lt;br /&gt;
== Future Scope==&lt;br /&gt;
'''1. Expand to more languages'''&amp;lt;br&amp;gt;&lt;br /&gt;
As part of this project we have targetted Hindi as a second language, however our work makes it easy to extend to other languages as well.&lt;br /&gt;
&lt;br /&gt;
'''2. Identify and implement the course language override on more course specific screens'''&amp;lt;br&amp;gt;&lt;br /&gt;
As part of this project, we have introduced a generic framework by which any view can provide a preferred language in which it should be rendered, this is required by this project for the course language feature set by the instructor.&lt;br /&gt;
We have currently made the assignment screen display in the course’s language, however other screens such as the “Your work” screen and so on are also specific to the course could also be rendered in the course language when the user has not provided a preference.&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
&lt;br /&gt;
'''Team Members'''&lt;br /&gt;
&lt;br /&gt;
Reuben M. V. John [[mailto:rmjohn2@ncsu.edu rmjohn2@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Renji Joseph Sabu [[mailto:rsabu@ncsu.edu rsabu@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Ashwin Das [[mailto:adas9@ncsu.edu adas9@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Arnav Julka [[mailto:ajulka@ncsu.edu ajulka@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Mentor'''&lt;br /&gt;
&lt;br /&gt;
Jialin Cui [[mailto:jcui9@ncsu.edu jcui9@ncsu.edu]]&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2159._Expertiza_internationalization&amp;diff=140566</id>
		<title>CSC/ECE 517 Fall 2021 - E2159. Expertiza internationalization</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2159._Expertiza_internationalization&amp;diff=140566"/>
		<updated>2021-11-03T03:29:01Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Introduction - Purpose &amp;amp; Problem */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction - Purpose &amp;amp; Problem ==&lt;br /&gt;
&lt;br /&gt;
Currently, all Expertiza screens can only be viewed in English. Many Expertiza users are from other countries. This is a problem since this limits the accessibility of Expertiza. An important step in solving this problem is by making Expertiza available in more languages, which is a form of internationalization.&lt;br /&gt;
W3C defines [https://www.w3.org/International/questions/qa-i18n internationalization] as “''the design and development of a product, application or document content that enables easy localization for target audiences that vary in culture, region, or language.''”&lt;br /&gt;
&lt;br /&gt;
[[File:country_pie.png|none|500px|]]&amp;lt;br&amp;gt;&lt;br /&gt;
Survey of home country of Expertiza users for a given course&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Scope:''' The scope of this project is limited however only to static strings. i.e. user-generated content will not be automatically translated to other languages.&lt;br /&gt;
&lt;br /&gt;
'''Breaking down internationalization into 3 sequential subproblems:'''&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Twophase2.jpg|none|700px]]&amp;lt;br&amp;gt;&lt;br /&gt;
'''1. Language selection'''&lt;br /&gt;
@rsabu &amp;lt;br&amp;gt;&lt;br /&gt;
Internationalization is done for pages viewed by students only. Any user other than students views all pages in English. The student has the option to set a language preference.&lt;br /&gt;
&lt;br /&gt;
LOFI UI sketch &lt;br /&gt;
&amp;lt;Insert image here&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
There is also an option where the instructor can choose a default language for a course. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;Insert image here&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Thus, the language not only varies from user to user but also across screens for the same user. Thus we need to recompute the language in which the page is to be rendered. If the student has given a language preference, then the choice is given weightage over the default language chosen by the instructor. &lt;br /&gt;
&lt;br /&gt;
'''2. Rendering the language'''&amp;lt;br&amp;gt;&lt;br /&gt;
'''How do we go about rendering the screen in that language?''' &amp;lt;br&amp;gt;&lt;br /&gt;
In the previous step, we’ve identified the language in which a view is to be rendered. It is important to note that this language may not only differ for a different user, but also for a different page for the same user. The question now becomes, how do we render the screen in this language?&amp;lt;br&amp;gt;&lt;br /&gt;
To tackle this question, we explore 2 fundamental concepts:&amp;lt;br&amp;gt;&lt;br /&gt;
'''2.1 Views are composed of independent language elements'''&amp;lt;br&amp;gt;&lt;br /&gt;
While this is something we typically take for granted, it becomes especially important in the context of translation. That is, a view is not a single contiguous block of text, nor is it an atomic visualization of information (unlike a screenshot), but rather a carefully organized collection of individual elements such as texts, buttons, etc that each contain language that needs to be translated separately. Crucially, this means that we cannot swap out a page in one language in its entirety for a page in another language in its entirety. Instead, each individual element needs to be swapped out individually so as to only impact the language and not the structural composition of the page itself.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
'''2.2 Views require translation at a large number of call sites'''&amp;lt;br&amp;gt;&lt;br /&gt;
Given that a view is composed of individual elements, this also means that the computation of how to translate such an element such as a button’s text would need to be done separately for each element. This would result in not only a single centralized &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''3. Translation gaps'''&lt;br /&gt;
&lt;br /&gt;
== Scope ==&lt;br /&gt;
== Design ==&lt;br /&gt;
Proposed Solution&lt;br /&gt;
1. Language selection&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
'''''2. Rendering the language'''''&amp;lt;br&amp;gt;&lt;br /&gt;
Rendering the language&amp;lt;br&amp;gt;&lt;br /&gt;
Once we have determined the language in which to render the page, we now need to update the rails view code to actually generate the appropriate HTML in the target language. This is the responsibility of the view. However, currently, the actual content of the HTML is hardcoded in (red) English. For example:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;Summary Report for assignment: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Team: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
As discussed earlier, “Views are composed of independent language elements” and so we cannot simply swap out the entire page content for a separate page in another language (Why? - See “swap out the entire view” in the alternative approaches section):&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;Rapport de synthèse pour l'affectation: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;Équipe: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;Instead, the better approach is to have a single unified view that dynamically changes based on the selected language:&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;&amp;lt;%=language==’en’ ? ‘Summary Report for assignment’ : ‘Rapport de synthèse pour l'affectation’&amp;gt;: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;&amp;lt;%=language==’en’ ? ‘Team’ : ‘Équipe’&amp;gt;: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;However this is clearly infeasible considering the number of call sites where we have to apply this logic. Thus, in order to maximize how concise the call site is, we can pull out this logic into a common helper function:&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;&amp;lt;h2&amp;gt;&amp;lt;%=localized(“report_summary.page_header”)&amp;gt;: &amp;lt;%= @assignment.name %&amp;gt;&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;h4&amp;gt;&amp;lt;%=localized(“report_summary.team_label”)&amp;gt;: &amp;lt;%= @team.name %&amp;gt;&amp;lt;/h4&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;Here the assumption is that the localized(“key”) is aware of the currently selected language and that “report_summary.page_header” is the key for the header which is available in English and Hindi. The helper intelligently selects and returns the right text based on the currently selected language. Through this approach, we are able to render the view in multiple possible languages without any significant increase in the verbosity of the view.&lt;br /&gt;
&lt;br /&gt;
What’s more, is that the above problem is a common problem for user-facing applications and a standard library for doing the above and much more already exists for rails applications called i18n&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''''I18n - Internationalisation, How are we using I18n in Ruby on Rail'''''&amp;lt;br&amp;gt;&lt;br /&gt;
I18n is a ruby library/gem which helps us render the static string on the view dynamically. Dynamicity means that based on a local decision of choosing the current language of the view, the library returns the strings of that particular language at runtime.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
These strings, instead of hardcoding in the view.rb, are provided in external .yml files. Now at the View level, we can pass an id to the 't' function and the I18n library returns the string for that id of the current set language(called as locale). &amp;lt;br&amp;gt;&lt;br /&gt;
[[File:i18n.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
For this purpose, we have to provide .yml files for each language and in those language-specific .yml, we have to provide a map of key-value pairs where the key is the id of the string and value is the string in that particular language. By default the language or locale is set to be English(:en). &lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
THE GREATEST BENEFITS of using this library are - &amp;lt;br&amp;gt;&lt;br /&gt;
*The strings aren't hardcoded in the code/build. The strings are being fetched from external files which can be easily modified. For example, if one needs to change the text from 'Please Help' to 'Help', then one just needs to make a change in the .yml file and the change would reflect on the browser. For this change, we didn't need to redeploy the server. We just Decoupled the view when and where from what content is to be shown. &lt;br /&gt;
*Adding more languages is now super easy. Adding support for another language is just one line change in the config and adding a .yml file (having all the key-value pairs for the strings) for the new language. By doing this we can extend the language support as much as we want.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
'''''3. Translation gaps'''''&lt;br /&gt;
&amp;lt;br&amp;gt;Also, if the language is set to be Hindi or any other language but the key-value pair is not set for that particular string then, automatically the library returns the default which is the English text.&amp;lt;br&amp;gt;&amp;lt;pre&amp;gt;config.i18n.fallbacks = [:en]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Alternate approaches ==&lt;br /&gt;
&lt;br /&gt;
'''1. Why not simply swap out the entire view for another language instead of each text?'''&amp;lt;br&amp;gt;&lt;br /&gt;
A view is an organized collection of multiple separate elements, views often involve dynamic generation and some level of sophistication. If we were to swap out one page in its entirety for another page this would often violate the '''DRY''' principle since we would have to have two separate implementations of the view in each language. Thus in the worst case, you have a complex view that has to be replicated dozens of times in various languages.&lt;br /&gt;
The majority of complexity of the page is not in the content itself but rather the code that executes to generate that content, thus it makes sense to instead maintain a single view and embed the language switching logic at each location where translation needs to occur to avoid replication of everything around it.&lt;br /&gt;
&lt;br /&gt;
'''2. Why did we pick i18n over implementing it ourselves?'''&amp;lt;br&amp;gt;&lt;br /&gt;
@ajulka&lt;br /&gt;
&lt;br /&gt;
'''3, Do we store the language preference, in the session or in the database?'''&amp;lt;br&amp;gt;&lt;br /&gt;
@rsabu&lt;br /&gt;
&lt;br /&gt;
== Use Case Diagram ==&lt;br /&gt;
== Major design patterns and principles used ==&lt;br /&gt;
&lt;br /&gt;
'''1. DRY: The i18n ‘t’ function'''&amp;lt;br&amp;gt;&lt;br /&gt;
We observe an extreme case of DRY with the t function of i18n.&lt;br /&gt;
For some background, the t function of the library takes in a key representing a text and returns the content referred to by that key in the preferred language of the user. It also performs many other functions such as falling back to a backup language if the translation for the preferred language has not been configured for that specific key. Thus since this logic has to be applied at every element of the view, it would behove us to extract this logic into a reusable function which is what the designers of the i18n library have employed&lt;br /&gt;
&lt;br /&gt;
'''2. Chain of responsibility'''&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Chainofresp.png]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The I18n library gives us an option to have many fall back options. When the required text for a given language is not found, we then move on to find the text for the next language in the chain and so on until we find it. And in the end we will put english as default language. So if the key value pair for the text is not found in none of the yml files then the text will be fetched from the English language yml file.&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''3. Open closed principle &amp;amp; Strategy Pattern'''&amp;lt;br&amp;gt;&lt;br /&gt;
As discussed in the “Language selection&amp;quot; design proposal above, if the user has not selected a preferred language, we do not simply default the view to render in the application language (English). Instead, the project requirements state that for course specific screens such as the assignment view, we would need to render the view in the course’s language.&lt;br /&gt;
While we could implement this code into the application controller that checks the controller being access and accordingly applies overrides on the default language, this violates the open closed principle since we would need to extend this logic any time we introduce a new course specific screen. Instead a better approach is to delegate the decision of selecting the language to the view itself since the view would be most aware of whether the view is course specific or not. We can also preserve the DRYness through mix-ins.&lt;br /&gt;
&lt;br /&gt;
== Database Design ==&lt;br /&gt;
Database Modification ==&lt;br /&gt;
== Test Plan ==&lt;br /&gt;
Test Details&lt;br /&gt;
Manual Testing&lt;br /&gt;
Scenario 1&lt;br /&gt;
Scenario 2&lt;br /&gt;
Scenario 3&lt;br /&gt;
Scenario 4&lt;br /&gt;
Scenario 5&lt;br /&gt;
== Future Scope==&lt;br /&gt;
'''1. Expand to more languages'''&amp;lt;br&amp;gt;&lt;br /&gt;
As part of this project we have targetted Hindi as a second language, however our work makes it easy to extend to other languages as well.&lt;br /&gt;
&lt;br /&gt;
'''2. Identify and implement the course language override on more course specific screens'''&amp;lt;br&amp;gt;&lt;br /&gt;
As part of this project, we have introduced a generic framework by which any view can provide a preferred language in which it should be rendered, this is required by this project for the course language feature set by the instructor.&lt;br /&gt;
We have currently made the assignment screen display in the course’s language, however other screens such as the “Your work” screen and so on are also specific to the course could also be rendered in the course language when the user has not provided a preference.&lt;br /&gt;
&lt;br /&gt;
== Team ==&lt;br /&gt;
&lt;br /&gt;
'''Team Members'''&lt;br /&gt;
&lt;br /&gt;
Reuben M. V. John [[mailto:rmjohn2@ncsu.edu rmjohn2@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Renji Joseph Sabu [[mailto:rsabu@ncsu.edu rsabu@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Ashwin Das [[mailto:adas9@ncsu.edu adas9@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
Arnav Julka [[mailto:ajulka@ncsu.edu ajulka@ncsu.edu]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''Mentor'''&lt;br /&gt;
&lt;br /&gt;
Jialin Cui [[mailto:jcui9@ncsu.edu jcui9@ncsu.edu]]&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139936</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139936"/>
		<updated>2021-10-23T21:53:22Z</updated>

		<summary type="html">&lt;p&gt;Adas9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* Issue 1: finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Issue 2: Update .first to .last (Line 24)&lt;br /&gt;
* Issue 3: Check @participant variable name (Line 28)&lt;br /&gt;
* Issue 4: Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Issue 5: Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* Issue 6: record_response needs a method comment (Line 98)&lt;br /&gt;
* Issue 7: Fix the English in the message (Line 110)&lt;br /&gt;
* Issue 8: Refactor review_questions method (Line 119)&lt;br /&gt;
&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Issue 9: Create public &amp;amp; private late policies&lt;br /&gt;
* Issue 10: Fix duplicate code in create and update method.&lt;br /&gt;
* Issue 11: create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Issue 4 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 5 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Issue 6 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 7 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 8 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 9 ===&lt;br /&gt;
----&lt;br /&gt;
It seems like some other team already fixed this issue, as all late policies are already shown in index. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # GET /late_policies&lt;br /&gt;
  # GET /late_policies.xml&lt;br /&gt;
  def index&lt;br /&gt;
    @penalty_policies = LatePolicy.all&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      format.html # index.html.erb&lt;br /&gt;
      format.xml  { render xml: @penalty_policies }&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 10 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found an existing bug in the code. In an update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Codebug.png|3000px|948px]] &amp;lt;br&amp;gt;&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Bugfix.png|2000px|865px]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because the view already handled duplicate code using the partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    valid = validate(params, false, &amp;quot;&amp;quot;)&lt;br /&gt;
    if !valid[:invalid_penalty_per_unit] &amp;amp;&amp;amp; !valid[:policy_name_already_exists]&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    valid = validate(params, true, @penalty_policy.policy_name)&lt;br /&gt;
    if !valid[:policy_name_already_exists] &amp;amp;&amp;amp; !valid[:invalid_penalty_per_unit]&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif valid[:invalid_penalty_per_unit]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif valid[:policy_name_already_exists]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 11 ===&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
We removed 'same_policy_name' and 'invalid_penalty_per_unit' and used a hash for that functionality. Then we changed the 'same_policy_name' to 'policy_name_already_exists'. We also added comments to the validator function which is called in create and update.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Affected Classes==&lt;br /&gt;
Changed existent classes&lt;br /&gt;
* controllers/student_quizzes_controller.rb&lt;br /&gt;
* controllers/late_policies_controller.rb&lt;br /&gt;
&lt;br /&gt;
==Test Plan==&lt;br /&gt;
As this is a refactoring project with mostly adding comments and updating variable names we can check if the code is working by running the existing tests itself.&lt;br /&gt;
&lt;br /&gt;
Test the student quizzes controller with the following command:&lt;br /&gt;
&amp;lt;pre&amp;gt;rspec spec/controllers/student_quizzes_controller_spec.rb&amp;lt;/pre&amp;gt;&lt;br /&gt;
Test the late policies controller with the following command:&lt;br /&gt;
&amp;lt;pre&amp;gt;rspec spec/controllers/late_policies_controller_spec.rb&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139887</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139887"/>
		<updated>2021-10-21T07:42:50Z</updated>

		<summary type="html">&lt;p&gt;Adas9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* Issue 1: finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Issue 2: Update .first to .last (Line 24)&lt;br /&gt;
* Issue 3: Check @participant variable name (Line 28)&lt;br /&gt;
* Issue 4: Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Issue 5: Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* Issue 6: record_response needs a method comment (Line 98)&lt;br /&gt;
* Issue 7: Fix the English in the message (Line 110)&lt;br /&gt;
* Issue 8: Refactor review_questions method (Line 119)&lt;br /&gt;
&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Issue 9: Create public &amp;amp; private late policies&lt;br /&gt;
* Issue 10: Fix duplicate code in create and update method.&lt;br /&gt;
* Issue 11: create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Issue 4 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 5 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Issue 6 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 7 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 8 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 9 ===&lt;br /&gt;
----&lt;br /&gt;
It seems like some other team already fixed this issue, as all late policies are already shown in index. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # GET /late_policies&lt;br /&gt;
  # GET /late_policies.xml&lt;br /&gt;
  def index&lt;br /&gt;
    @penalty_policies = LatePolicy.all&lt;br /&gt;
    respond_to do |format|&lt;br /&gt;
      format.html # index.html.erb&lt;br /&gt;
      format.xml  { render xml: @penalty_policies }&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 10 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found an existing bug in the code. In an update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Codebug.png|3000px|948px]] &amp;lt;br&amp;gt;&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Bugfix.png|2000px|865px]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because the view already handled duplicate code using the partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    valid = validate(params, false, &amp;quot;&amp;quot;)&lt;br /&gt;
    if !valid[:invalid_penalty_per_unit] &amp;amp;&amp;amp; !valid[:policy_name_already_exists]&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    valid = validate(params, true, @penalty_policy.policy_name)&lt;br /&gt;
    if !valid[:policy_name_already_exists] &amp;amp;&amp;amp; !valid[:invalid_penalty_per_unit]&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif valid[:invalid_penalty_per_unit]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif valid[:policy_name_already_exists]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 11 ===&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
We removed 'same_policy_name' and 'invalid_penalty_per_unit' and used a hash for that functionality. Then we changed the 'same_policy_name' to 'policy_name_already_exists'. We also added comments to the validator function which is called in create and update.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Affected Classes==&lt;br /&gt;
Changed existent classes&lt;br /&gt;
* controllers/student_quizzes_controller.rb&lt;br /&gt;
* controllers/late_policies_controller.rb&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139885</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139885"/>
		<updated>2021-10-21T07:36:28Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Issue 10 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* Issue 1: finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Issue 2: Update .first to .last (Line 24)&lt;br /&gt;
* Issue 3: Check @participant variable name (Line 28)&lt;br /&gt;
* Issue 4: Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Issue 5: Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* Issue 6: record_response needs a method comment (Line 98)&lt;br /&gt;
* Issue 7: Fix the English in the message (Line 110)&lt;br /&gt;
* Issue 8: Refactor review_questions method (Line 119)&lt;br /&gt;
&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Issue 9: Create public &amp;amp; private late policies&lt;br /&gt;
* Issue 10: Fix duplicate code in create and update method.&lt;br /&gt;
* Issue 11: create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Issue 4 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 5 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Issue 6 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 7 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 8 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 9 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 10 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found an existing bug in the code. In an update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Codebug.png|3000px|948px]] &amp;lt;br&amp;gt;&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy. &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Bugfix.png|2000px|865px]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because the view already handled duplicate code using the partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    valid = validate(params, false, &amp;quot;&amp;quot;)&lt;br /&gt;
    if !valid[:invalid_penalty_per_unit] &amp;amp;&amp;amp; !valid[:policy_name_already_exists]&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    valid = validate(params, true, @penalty_policy.policy_name)&lt;br /&gt;
    if !valid[:policy_name_already_exists] &amp;amp;&amp;amp; !valid[:invalid_penalty_per_unit]&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif valid[:invalid_penalty_per_unit]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif valid[:policy_name_already_exists]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 11 ===&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
We removed 'same_policy_name' and 'invalid_penalty_per_unit' and used a hash for that functionality. Then we changed the 'same_policy_name' to 'policy_name_already_exists'. We also added comments to the validator function which is called in create and update.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139884</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139884"/>
		<updated>2021-10-21T07:33:53Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Issue 10 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* Issue 1: finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Issue 2: Update .first to .last (Line 24)&lt;br /&gt;
* Issue 3: Check @participant variable name (Line 28)&lt;br /&gt;
* Issue 4: Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Issue 5: Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* Issue 6: record_response needs a method comment (Line 98)&lt;br /&gt;
* Issue 7: Fix the English in the message (Line 110)&lt;br /&gt;
* Issue 8: Refactor review_questions method (Line 119)&lt;br /&gt;
&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Issue 9: Create public &amp;amp; private late policies&lt;br /&gt;
* Issue 10: Fix duplicate code in create and update method.&lt;br /&gt;
* Issue 11: create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Issue 4 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 5 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Issue 6 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 7 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 8 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 9 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 10 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found out an existing bug in the code. In an update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error.&lt;br /&gt;
[[File:Codebug.png|3000px|948px]]&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy.&lt;br /&gt;
[[File:Bugfix.png|2000px|865px]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because view already handled duplicate code using the partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    valid = validate(params, false, &amp;quot;&amp;quot;)&lt;br /&gt;
    if !valid[:invalid_penalty_per_unit] &amp;amp;&amp;amp; !valid[:policy_name_already_exists]&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    valid = validate(params, true, @penalty_policy.policy_name)&lt;br /&gt;
    if !valid[:policy_name_already_exists] &amp;amp;&amp;amp; !valid[:invalid_penalty_per_unit]&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif valid[:invalid_penalty_per_unit]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif valid[:policy_name_already_exists]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 11 ===&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
We removed 'same_policy_name' and 'invalid_penalty_per_unit' and used a hash for that functionality. Then we changed the 'same_policy_name' to 'policy_name_already_exists'. We also added comments to the validator function which is called in create and update.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Bugfix.png&amp;diff=139883</id>
		<title>File:Bugfix.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Bugfix.png&amp;diff=139883"/>
		<updated>2021-10-21T07:31:42Z</updated>

		<summary type="html">&lt;p&gt;Adas9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139882</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139882"/>
		<updated>2021-10-21T07:31:18Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Issue 10 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* Issue 1: finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Issue 2: Update .first to .last (Line 24)&lt;br /&gt;
* Issue 3: Check @participant variable name (Line 28)&lt;br /&gt;
* Issue 4: Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Issue 5: Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* Issue 6: record_response needs a method comment (Line 98)&lt;br /&gt;
* Issue 7: Fix the English in the message (Line 110)&lt;br /&gt;
* Issue 8: Refactor review_questions method (Line 119)&lt;br /&gt;
&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Issue 9: Create public &amp;amp; private late policies&lt;br /&gt;
* Issue 10: Fix duplicate code in create and update method.&lt;br /&gt;
* Issue 11: create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Issue 4 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 5 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Issue 6 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 7 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 8 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 9 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 10 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found out an existing bug in the code. In an update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error.&lt;br /&gt;
[[File:Codebug.png|3000px|948px]]&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy.&lt;br /&gt;
[[File:file:///Users/macbookpro/Desktop/Screenshot%202021-10-21%20at%202.24.33%20AM.png]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because view already handled duplicate code using the partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    valid = validate(params, false, &amp;quot;&amp;quot;)&lt;br /&gt;
    if !valid[:invalid_penalty_per_unit] &amp;amp;&amp;amp; !valid[:policy_name_already_exists]&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    valid = validate(params, true, @penalty_policy.policy_name)&lt;br /&gt;
    if !valid[:policy_name_already_exists] &amp;amp;&amp;amp; !valid[:invalid_penalty_per_unit]&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif valid[:invalid_penalty_per_unit]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif valid[:policy_name_already_exists]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 11 ===&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
We removed 'same_policy_name' and 'invalid_penalty_per_unit' and used a hash for that functionality. Then we changed the 'same_policy_name' to 'policy_name_already_exists'. We also added comments to the validator function which is called in create and update.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139881</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139881"/>
		<updated>2021-10-21T07:30:34Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Issue 10 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* Issue 1: finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Issue 2: Update .first to .last (Line 24)&lt;br /&gt;
* Issue 3: Check @participant variable name (Line 28)&lt;br /&gt;
* Issue 4: Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Issue 5: Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* Issue 6: record_response needs a method comment (Line 98)&lt;br /&gt;
* Issue 7: Fix the English in the message (Line 110)&lt;br /&gt;
* Issue 8: Refactor review_questions method (Line 119)&lt;br /&gt;
&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Issue 9: Create public &amp;amp; private late policies&lt;br /&gt;
* Issue 10: Fix duplicate code in create and update method.&lt;br /&gt;
* Issue 11: create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Issue 4 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 5 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Issue 6 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 7 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 8 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 9 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 10 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found out an existing bug in the code. In an update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error.&lt;br /&gt;
[[File:Codebug.png|3000px|948px]]&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy.&lt;br /&gt;
[[File:UpdateBug.png]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because view already handled duplicate code using the partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    valid = validate(params, false, &amp;quot;&amp;quot;)&lt;br /&gt;
    if !valid[:invalid_penalty_per_unit] &amp;amp;&amp;amp; !valid[:policy_name_already_exists]&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    valid = validate(params, true, @penalty_policy.policy_name)&lt;br /&gt;
    if !valid[:policy_name_already_exists] &amp;amp;&amp;amp; !valid[:invalid_penalty_per_unit]&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif valid[:invalid_penalty_per_unit]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif valid[:policy_name_already_exists]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 11 ===&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
We removed 'same_policy_name' and 'invalid_penalty_per_unit' and used a hash for that functionality. Then we changed the 'same_policy_name' to 'policy_name_already_exists'. We also added comments to the validator function which is called in create and update.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Codebug.png&amp;diff=139879</id>
		<title>File:Codebug.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Codebug.png&amp;diff=139879"/>
		<updated>2021-10-21T07:24:23Z</updated>

		<summary type="html">&lt;p&gt;Adas9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139878</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139878"/>
		<updated>2021-10-21T07:23:22Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Issue 10 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* Issue 1: finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Issue 2: Update .first to .last (Line 24)&lt;br /&gt;
* Issue 3: Check @participant variable name (Line 28)&lt;br /&gt;
* Issue 4: Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Issue 5: Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* Issue 6: record_response needs a method comment (Line 98)&lt;br /&gt;
* Issue 7: Fix the English in the message (Line 110)&lt;br /&gt;
* Issue 8: Refactor review_questions method (Line 119)&lt;br /&gt;
&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Issue 9: Create public &amp;amp; private late policies&lt;br /&gt;
* Issue 10: Fix duplicate code in create and update method.&lt;br /&gt;
* Issue 11: create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Issue 4 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 5 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Issue 6 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 7 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 8 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 9 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 10 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found out an existing bug in the code. In an update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error.&lt;br /&gt;
[[File:file:///Users/macbookpro/Desktop/bug.png]]&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy.&lt;br /&gt;
[[File:UpdateBug.png]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because view already handled duplicate code using the partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    valid = validate(params, false, &amp;quot;&amp;quot;)&lt;br /&gt;
    if !valid[:invalid_penalty_per_unit] &amp;amp;&amp;amp; !valid[:policy_name_already_exists]&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    valid = validate(params, true, @penalty_policy.policy_name)&lt;br /&gt;
    if !valid[:policy_name_already_exists] &amp;amp;&amp;amp; !valid[:invalid_penalty_per_unit]&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif valid[:invalid_penalty_per_unit]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif valid[:policy_name_already_exists]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 11 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139877</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139877"/>
		<updated>2021-10-21T07:13:37Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Issue 7 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* Issue 1: finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Issue 2: Update .first to .last (Line 24)&lt;br /&gt;
* Issue 3: Check @participant variable name (Line 28)&lt;br /&gt;
* Issue 4: Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Issue 5: Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* Issue 6: record_response needs a method comment (Line 98)&lt;br /&gt;
* Issue 7: Fix the English in the message (Line 110)&lt;br /&gt;
* Issue 8: Refactor review_questions method (Line 119)&lt;br /&gt;
&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Issue 9: Create public &amp;amp; private late policies&lt;br /&gt;
* Issue 10: Fix duplicate code in create and update method.&lt;br /&gt;
* Issue 11: create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Issue 4 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 5 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Issue 6 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 7 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 8 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 9 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 10 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found out an existing bug in the code. In update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error.&lt;br /&gt;
[[File:UpdateBugExisting.png]]&lt;br /&gt;
&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy.&lt;br /&gt;
[[File:UpdateBug.png]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because view already handled duplicate code using partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    valid = validate(params, false, &amp;quot;&amp;quot;)&lt;br /&gt;
    if !valid[:invalid_penalty_per_unit] &amp;amp;&amp;amp; !valid[:policy_name_already_exists]&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    valid = validate(params, true, @penalty_policy.policy_name)&lt;br /&gt;
    if !valid[:policy_name_already_exists] &amp;amp;&amp;amp; !valid[:invalid_penalty_per_unit]&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif valid[:invalid_penalty_per_unit]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif valid[:policy_name_already_exists]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 11 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139876</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139876"/>
		<updated>2021-10-21T07:13:24Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Modifications made to late_policies_controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* Issue 1: finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Issue 2: Update .first to .last (Line 24)&lt;br /&gt;
* Issue 3: Check @participant variable name (Line 28)&lt;br /&gt;
* Issue 4: Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Issue 5: Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* Issue 6: record_response needs a method comment (Line 98)&lt;br /&gt;
* Issue 7: Fix the English in the message (Line 110)&lt;br /&gt;
* Issue 8: Refactor review_questions method (Line 119)&lt;br /&gt;
&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Issue 9: Create public &amp;amp; private late policies&lt;br /&gt;
* Issue 10: Fix duplicate code in create and update method.&lt;br /&gt;
* Issue 11: create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Issue 4 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 5 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Issue 6 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 7 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Issue 7 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 8 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 9 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 10 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found out an existing bug in the code. In update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error.&lt;br /&gt;
[[File:UpdateBugExisting.png]]&lt;br /&gt;
&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy.&lt;br /&gt;
[[File:UpdateBug.png]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because view already handled duplicate code using partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    valid = validate(params, false, &amp;quot;&amp;quot;)&lt;br /&gt;
    if !valid[:invalid_penalty_per_unit] &amp;amp;&amp;amp; !valid[:policy_name_already_exists]&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    valid = validate(params, true, @penalty_policy.policy_name)&lt;br /&gt;
    if !valid[:policy_name_already_exists] &amp;amp;&amp;amp; !valid[:invalid_penalty_per_unit]&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif valid[:invalid_penalty_per_unit]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif valid[:policy_name_already_exists]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 11 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139875</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139875"/>
		<updated>2021-10-21T07:12:56Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Issue 9 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* Issue 1: finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Issue 2: Update .first to .last (Line 24)&lt;br /&gt;
* Issue 3: Check @participant variable name (Line 28)&lt;br /&gt;
* Issue 4: Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Issue 5: Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* Issue 6: record_response needs a method comment (Line 98)&lt;br /&gt;
* Issue 7: Fix the English in the message (Line 110)&lt;br /&gt;
* Issue 8: Refactor review_questions method (Line 119)&lt;br /&gt;
&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Issue 9: Create public &amp;amp; private late policies&lt;br /&gt;
* Issue 10: Fix duplicate code in create and update method.&lt;br /&gt;
* Issue 11: create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Issue 4 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 5 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Issue 6 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 7 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Issue 7 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 8 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found out an existing bug in the code. In update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error.&lt;br /&gt;
[[File:UpdateBugExisting.png]]&lt;br /&gt;
&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy.&lt;br /&gt;
[[File:UpdateBug.png]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because view already handled duplicate code using partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    valid = validate(params, false, &amp;quot;&amp;quot;)&lt;br /&gt;
    if !valid[:invalid_penalty_per_unit] &amp;amp;&amp;amp; !valid[:policy_name_already_exists]&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    valid = validate(params, true, @penalty_policy.policy_name)&lt;br /&gt;
    if !valid[:policy_name_already_exists] &amp;amp;&amp;amp; !valid[:invalid_penalty_per_unit]&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif valid[:invalid_penalty_per_unit]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif valid[:policy_name_already_exists]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139874</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139874"/>
		<updated>2021-10-21T07:12:46Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Issue 8 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* Issue 1: finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Issue 2: Update .first to .last (Line 24)&lt;br /&gt;
* Issue 3: Check @participant variable name (Line 28)&lt;br /&gt;
* Issue 4: Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Issue 5: Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* Issue 6: record_response needs a method comment (Line 98)&lt;br /&gt;
* Issue 7: Fix the English in the message (Line 110)&lt;br /&gt;
* Issue 8: Refactor review_questions method (Line 119)&lt;br /&gt;
&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Issue 9: Create public &amp;amp; private late policies&lt;br /&gt;
* Issue 10: Fix duplicate code in create and update method.&lt;br /&gt;
* Issue 11: create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Issue 4 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 5 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Issue 6 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 7 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Issue 7 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 9 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found out an existing bug in the code. In update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error.&lt;br /&gt;
[[File:UpdateBugExisting.png]]&lt;br /&gt;
&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy.&lt;br /&gt;
[[File:UpdateBug.png]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because view already handled duplicate code using partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    valid = validate(params, false, &amp;quot;&amp;quot;)&lt;br /&gt;
    if !valid[:invalid_penalty_per_unit] &amp;amp;&amp;amp; !valid[:policy_name_already_exists]&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    valid = validate(params, true, @penalty_policy.policy_name)&lt;br /&gt;
    if !valid[:policy_name_already_exists] &amp;amp;&amp;amp; !valid[:invalid_penalty_per_unit]&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif valid[:invalid_penalty_per_unit]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif valid[:policy_name_already_exists]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139873</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139873"/>
		<updated>2021-10-21T07:09:30Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Modifications made to student_quizzes_controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* Issue 1: finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Issue 2: Update .first to .last (Line 24)&lt;br /&gt;
* Issue 3: Check @participant variable name (Line 28)&lt;br /&gt;
* Issue 4: Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Issue 5: Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* Issue 6: record_response needs a method comment (Line 98)&lt;br /&gt;
* Issue 7: Fix the English in the message (Line 110)&lt;br /&gt;
* Issue 8: Refactor review_questions method (Line 119)&lt;br /&gt;
&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Issue 9: Create public &amp;amp; private late policies&lt;br /&gt;
* Issue 10: Fix duplicate code in create and update method.&lt;br /&gt;
* Issue 11: create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Issue 4 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 5 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Issue 6 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 7 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Issue 8 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 9 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found out an existing bug in the code. In update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error.&lt;br /&gt;
[[File:UpdateBugExisting.png]]&lt;br /&gt;
&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy.&lt;br /&gt;
[[File:UpdateBug.png]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because view already handled duplicate code using partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    valid = validate(params, false, &amp;quot;&amp;quot;)&lt;br /&gt;
    if !valid[:invalid_penalty_per_unit] &amp;amp;&amp;amp; !valid[:policy_name_already_exists]&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    valid = validate(params, true, @penalty_policy.policy_name)&lt;br /&gt;
    if !valid[:policy_name_already_exists] &amp;amp;&amp;amp; !valid[:invalid_penalty_per_unit]&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif valid[:invalid_penalty_per_unit]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif valid[:policy_name_already_exists]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139872</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139872"/>
		<updated>2021-10-21T07:08:45Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Lines 53-96 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* Issue 1: finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Issue 2: Update .first to .last (Line 24)&lt;br /&gt;
* Issue 3: Check @participant variable name (Line 28)&lt;br /&gt;
* Issue 4: Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Issue 5: Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* Issue 6: record_response needs a method comment (Line 98)&lt;br /&gt;
* Issue 7: Fix the English in the message (Line 110)&lt;br /&gt;
* Issue 8: Refactor review_questions method (Line 119)&lt;br /&gt;
&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Issue 9: Create public &amp;amp; private late policies&lt;br /&gt;
* Issue 10: Fix duplicate code in create and update method.&lt;br /&gt;
* Issue 11: create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Issue 4 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 5 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found out an existing bug in the code. In update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error.&lt;br /&gt;
[[File:UpdateBugExisting.png]]&lt;br /&gt;
&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy.&lt;br /&gt;
[[File:UpdateBug.png]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because view already handled duplicate code using partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    valid = validate(params, false, &amp;quot;&amp;quot;)&lt;br /&gt;
    if !valid[:invalid_penalty_per_unit] &amp;amp;&amp;amp; !valid[:policy_name_already_exists]&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    valid = validate(params, true, @penalty_policy.policy_name)&lt;br /&gt;
    if !valid[:policy_name_already_exists] &amp;amp;&amp;amp; !valid[:invalid_penalty_per_unit]&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif valid[:invalid_penalty_per_unit]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif valid[:policy_name_already_exists]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139871</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139871"/>
		<updated>2021-10-21T07:08:25Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Line 34 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* Issue 1: finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Issue 2: Update .first to .last (Line 24)&lt;br /&gt;
* Issue 3: Check @participant variable name (Line 28)&lt;br /&gt;
* Issue 4: Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Issue 5: Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* Issue 6: record_response needs a method comment (Line 98)&lt;br /&gt;
* Issue 7: Fix the English in the message (Line 110)&lt;br /&gt;
* Issue 8: Refactor review_questions method (Line 119)&lt;br /&gt;
&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Issue 9: Create public &amp;amp; private late policies&lt;br /&gt;
* Issue 10: Fix duplicate code in create and update method.&lt;br /&gt;
* Issue 11: create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Issue 4 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lines 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found out an existing bug in the code. In update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error.&lt;br /&gt;
[[File:UpdateBugExisting.png]]&lt;br /&gt;
&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy.&lt;br /&gt;
[[File:UpdateBug.png]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because view already handled duplicate code using partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    valid = validate(params, false, &amp;quot;&amp;quot;)&lt;br /&gt;
    if !valid[:invalid_penalty_per_unit] &amp;amp;&amp;amp; !valid[:policy_name_already_exists]&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    valid = validate(params, true, @penalty_policy.policy_name)&lt;br /&gt;
    if !valid[:policy_name_already_exists] &amp;amp;&amp;amp; !valid[:invalid_penalty_per_unit]&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif valid[:invalid_penalty_per_unit]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif valid[:policy_name_already_exists]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139870</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139870"/>
		<updated>2021-10-21T07:08:10Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Line 28 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* Issue 1: finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Issue 2: Update .first to .last (Line 24)&lt;br /&gt;
* Issue 3: Check @participant variable name (Line 28)&lt;br /&gt;
* Issue 4: Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Issue 5: Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* Issue 6: record_response needs a method comment (Line 98)&lt;br /&gt;
* Issue 7: Fix the English in the message (Line 110)&lt;br /&gt;
* Issue 8: Refactor review_questions method (Line 119)&lt;br /&gt;
&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Issue 9: Create public &amp;amp; private late policies&lt;br /&gt;
* Issue 10: Fix duplicate code in create and update method.&lt;br /&gt;
* Issue 11: create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lines 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found out an existing bug in the code. In update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error.&lt;br /&gt;
[[File:UpdateBugExisting.png]]&lt;br /&gt;
&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy.&lt;br /&gt;
[[File:UpdateBug.png]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because view already handled duplicate code using partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    valid = validate(params, false, &amp;quot;&amp;quot;)&lt;br /&gt;
    if !valid[:invalid_penalty_per_unit] &amp;amp;&amp;amp; !valid[:policy_name_already_exists]&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    valid = validate(params, true, @penalty_policy.policy_name)&lt;br /&gt;
    if !valid[:policy_name_already_exists] &amp;amp;&amp;amp; !valid[:invalid_penalty_per_unit]&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif valid[:invalid_penalty_per_unit]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif valid[:policy_name_already_exists]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139869</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139869"/>
		<updated>2021-10-21T07:07:53Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Line 24 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* Issue 1: finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Issue 2: Update .first to .last (Line 24)&lt;br /&gt;
* Issue 3: Check @participant variable name (Line 28)&lt;br /&gt;
* Issue 4: Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Issue 5: Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* Issue 6: record_response needs a method comment (Line 98)&lt;br /&gt;
* Issue 7: Fix the English in the message (Line 110)&lt;br /&gt;
* Issue 8: Refactor review_questions method (Line 119)&lt;br /&gt;
&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Issue 9: Create public &amp;amp; private late policies&lt;br /&gt;
* Issue 10: Fix duplicate code in create and update method.&lt;br /&gt;
* Issue 11: create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 28 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lines 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found out an existing bug in the code. In update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error.&lt;br /&gt;
[[File:UpdateBugExisting.png]]&lt;br /&gt;
&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy.&lt;br /&gt;
[[File:UpdateBug.png]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because view already handled duplicate code using partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    valid = validate(params, false, &amp;quot;&amp;quot;)&lt;br /&gt;
    if !valid[:invalid_penalty_per_unit] &amp;amp;&amp;amp; !valid[:policy_name_already_exists]&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    valid = validate(params, true, @penalty_policy.policy_name)&lt;br /&gt;
    if !valid[:policy_name_already_exists] &amp;amp;&amp;amp; !valid[:invalid_penalty_per_unit]&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif valid[:invalid_penalty_per_unit]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif valid[:policy_name_already_exists]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139868</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139868"/>
		<updated>2021-10-21T07:07:41Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Line 23 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* Issue 1: finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Issue 2: Update .first to .last (Line 24)&lt;br /&gt;
* Issue 3: Check @participant variable name (Line 28)&lt;br /&gt;
* Issue 4: Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Issue 5: Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* Issue 6: record_response needs a method comment (Line 98)&lt;br /&gt;
* Issue 7: Fix the English in the message (Line 110)&lt;br /&gt;
* Issue 8: Refactor review_questions method (Line 119)&lt;br /&gt;
&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Issue 9: Create public &amp;amp; private late policies&lt;br /&gt;
* Issue 10: Fix duplicate code in create and update method.&lt;br /&gt;
* Issue 11: create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 28 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lines 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found out an existing bug in the code. In update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error.&lt;br /&gt;
[[File:UpdateBugExisting.png]]&lt;br /&gt;
&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy.&lt;br /&gt;
[[File:UpdateBug.png]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because view already handled duplicate code using partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    valid = validate(params, false, &amp;quot;&amp;quot;)&lt;br /&gt;
    if !valid[:invalid_penalty_per_unit] &amp;amp;&amp;amp; !valid[:policy_name_already_exists]&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    valid = validate(params, true, @penalty_policy.policy_name)&lt;br /&gt;
    if !valid[:policy_name_already_exists] &amp;amp;&amp;amp; !valid[:invalid_penalty_per_unit]&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif valid[:invalid_penalty_per_unit]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif valid[:policy_name_already_exists]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139867</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139867"/>
		<updated>2021-10-21T07:07:22Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Issues in late_policies_controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* Issue 1: finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Issue 2: Update .first to .last (Line 24)&lt;br /&gt;
* Issue 3: Check @participant variable name (Line 28)&lt;br /&gt;
* Issue 4: Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Issue 5: Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* Issue 6: record_response needs a method comment (Line 98)&lt;br /&gt;
* Issue 7: Fix the English in the message (Line 110)&lt;br /&gt;
* Issue 8: Refactor review_questions method (Line 119)&lt;br /&gt;
&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Issue 9: Create public &amp;amp; private late policies&lt;br /&gt;
* Issue 10: Fix duplicate code in create and update method.&lt;br /&gt;
* Issue 11: create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Line 23 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 28 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lines 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found out an existing bug in the code. In update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error.&lt;br /&gt;
[[File:UpdateBugExisting.png]]&lt;br /&gt;
&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy.&lt;br /&gt;
[[File:UpdateBug.png]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because view already handled duplicate code using partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    valid = validate(params, false, &amp;quot;&amp;quot;)&lt;br /&gt;
    if !valid[:invalid_penalty_per_unit] &amp;amp;&amp;amp; !valid[:policy_name_already_exists]&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    valid = validate(params, true, @penalty_policy.policy_name)&lt;br /&gt;
    if !valid[:policy_name_already_exists] &amp;amp;&amp;amp; !valid[:invalid_penalty_per_unit]&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif valid[:invalid_penalty_per_unit]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif valid[:policy_name_already_exists]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139866</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139866"/>
		<updated>2021-10-21T07:06:59Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Issues in student_quizzes_controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* Issue 1: finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Issue 2: Update .first to .last (Line 24)&lt;br /&gt;
* Issue 3: Check @participant variable name (Line 28)&lt;br /&gt;
* Issue 4: Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Issue 5: Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* Issue 6: record_response needs a method comment (Line 98)&lt;br /&gt;
* Issue 7: Fix the English in the message (Line 110)&lt;br /&gt;
* Issue 8: Refactor review_questions method (Line 119)&lt;br /&gt;
&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Create public &amp;amp; private late policies&lt;br /&gt;
* Fix duplicate code in create and update method.&lt;br /&gt;
* create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Line 23 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 28 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lines 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found out an existing bug in the code. In update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error.&lt;br /&gt;
[[File:UpdateBugExisting.png]]&lt;br /&gt;
&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy.&lt;br /&gt;
[[File:UpdateBug.png]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because view already handled duplicate code using partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # validate checks if the entered penalty per unit and policy name is valid&lt;br /&gt;
  def validate(params, is_update, current_policy_name)&lt;br /&gt;
    valid = {}&lt;br /&gt;
    # penalty per unit cannot be greater than max penalty&lt;br /&gt;
    valid[:invalid_penalty_per_unit] = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if valid[:invalid_penalty_per_unit]&lt;br /&gt;
    valid[:policy_name_already_exists] = false&lt;br /&gt;
    # entered policy name cannot be same as an existing one&lt;br /&gt;
    if (is_update &amp;amp;&amp;amp; current_policy_name != params[:late_policy][:policy_name]) || !is_update&lt;br /&gt;
      if LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
        valid[:policy_name_already_exists] = true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    valid&lt;br /&gt;
  end&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    valid = validate(params, false, &amp;quot;&amp;quot;)&lt;br /&gt;
    if !valid[:invalid_penalty_per_unit] &amp;amp;&amp;amp; !valid[:policy_name_already_exists]&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    valid = validate(params, true, @penalty_policy.policy_name)&lt;br /&gt;
    if !valid[:policy_name_already_exists] &amp;amp;&amp;amp; !valid[:invalid_penalty_per_unit]&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif valid[:invalid_penalty_per_unit]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif valid[:policy_name_already_exists]&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139864</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139864"/>
		<updated>2021-10-21T07:04:52Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
===Background===&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc). It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
===Motivation===&lt;br /&gt;
This project in particular intends that the students collaborate with each other and work on making enhancements to the code base by applying the concepts of Rails, RSpec, DRY code, Test-driven development, etc. This provides an opportunity for students to contribute to an open-source project and learn further about software deployment etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;student_quizzes_controller&amp;lt;/b&amp;gt; needs several comments to explain the methods and the code in general while &amp;lt;b&amp;gt;late_policies_controller&amp;lt;/b&amp;gt; has code duplication which could be refactored to make it DRY and follow the Ruby style guide and Rails 4 syntax.&lt;br /&gt;
===Issues in student_quizzes_controller===&lt;br /&gt;
* finished_quiz method needs a comment describing its purpose (Line 23)&lt;br /&gt;
* Update .first to .last (Line 24)&lt;br /&gt;
* Check @participant variable name (Line 28)&lt;br /&gt;
* Fix method comment for self.take_quiz (Line 34)&lt;br /&gt;
* Refactor calculate_score method (Line 53-96 and Line 108)&lt;br /&gt;
* record_response needs a method comment (Line 98)&lt;br /&gt;
* Fix the English in the message (Line 110)&lt;br /&gt;
* Refactor review_questions method (Line 119)&lt;br /&gt;
===Issues in late_policies_controller===&lt;br /&gt;
* Create public &amp;amp; private late policies&lt;br /&gt;
* Fix duplicate code in create and update method.&lt;br /&gt;
* create and update method need comments and better identifier naming&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Line 23 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 28 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lines 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
We started by exploring the create and update methods in the late_policies_controller. We found out an existing bug in the code. In update, if the new policy name is the name of an existing policy, an error wasn't returned and the call went through, resulting in multiple policies with the same name. We fixed that error.&lt;br /&gt;
[[File:UpdateBugExisting.png]]&lt;br /&gt;
&lt;br /&gt;
After the fix, the error message is shown properly when the new policy name is the name of an existing policy.&lt;br /&gt;
[[File:UpdateBug.png]]&lt;br /&gt;
&lt;br /&gt;
We also moved the duplicate code from update and create to a validator function which validates the policy name and penality points per unit for both create and update. The fix was done in the controller itself because view already handled duplicate code using partial form.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # POST /late_policies&lt;br /&gt;
  # POST /late_policies.xml&lt;br /&gt;
  def create&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    if same_policy_name != LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
      flash[:error] = &amp;quot;A policy with the same name already exists.&amp;quot;&lt;br /&gt;
      same_policy_name = true&lt;br /&gt;
    end&lt;br /&gt;
    if !invalid_penalty_per_unit &amp;amp;&amp;amp; !same_policy_name&lt;br /&gt;
      @late_policy = LatePolicy.new(late_policy_params)&lt;br /&gt;
      @late_policy.instructor_id = instructor_id&lt;br /&gt;
      begin&lt;br /&gt;
        @late_policy.save!&lt;br /&gt;
        flash[:notice] = &amp;quot;The penalty policy was successfully created.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while saving the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'new'&lt;br /&gt;
      end&lt;br /&gt;
    else&lt;br /&gt;
      redirect_to action: 'new'&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  # PUT /late_policies/1&lt;br /&gt;
  # PUT /late_policies/1.xml&lt;br /&gt;
  def update&lt;br /&gt;
    @penalty_policy = LatePolicy.find(params[:id])&lt;br /&gt;
    invalid_penalty_per_unit = params[:late_policy][:max_penalty].to_i &amp;lt; params[:late_policy][:penalty_per_unit].to_i&lt;br /&gt;
    flash[:error] = &amp;quot;The maximum penalty cannot be less than penalty per unit.&amp;quot; if invalid_penalty_per_unit&lt;br /&gt;
    same_policy_name = false&lt;br /&gt;
    # if name has changed then only check for this&lt;br /&gt;
    if params[:late_policy][:policy_name] != @penalty_policy.policy_name&lt;br /&gt;
      if same_policy_name == LatePolicy.check_policy_with_same_name(params[:late_policy][:policy_name], instructor_id)&lt;br /&gt;
        flash[:error] = &amp;quot;The policy could not be updated because a policy with the same name already exists.&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    if !same_policy_name &amp;amp;&amp;amp; !invalid_penalty_per_unit&lt;br /&gt;
      begin&lt;br /&gt;
        @penalty_policy.update_attributes(late_policy_params)&lt;br /&gt;
        @penalty_policy.save!&lt;br /&gt;
        LatePolicy.update_calculated_penalty_objects(@penalty_policy)&lt;br /&gt;
        flash[:notice] = &amp;quot;The late policy was successfully updated.&amp;quot;&lt;br /&gt;
        redirect_to action: 'index'&lt;br /&gt;
      rescue StandardError&lt;br /&gt;
        flash[:error] = &amp;quot;The following error occurred while updating the penalty policy: &amp;quot;&lt;br /&gt;
        redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
      end&lt;br /&gt;
    elsif invalid_penalty_per_unit&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. The maximum penalty cannot be less than penalty per unit.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    elsif same_policy_name&lt;br /&gt;
      flash[:error] = &amp;quot;Cannot edit the policy. A policy with the same name &amp;quot; + params[:late_policy][:policy_name] + &amp;quot; already exists.&amp;quot;&lt;br /&gt;
      redirect_to action: 'edit', id: params[:id]&lt;br /&gt;
    end&lt;br /&gt;
  end &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139832</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139832"/>
		<updated>2021-10-21T03:35:43Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Modifications made to student_quizzes_controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc)[https://github.com/expertiza/expertiza Expertiza on GitHub] [http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza Wiki Page]. It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;StudentQuiz controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;LatePolicies Controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Line 23 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 28 ===&lt;br /&gt;
----&lt;br /&gt;
Method: finished_quiz&lt;br /&gt;
&lt;br /&gt;
The code under consideration is the following &amp;lt;pre&amp;gt;@participant = AssignmentTeam.find(@map.reviewee_id).participants.first&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We get the first participant from the list of participants from AssignmentTeam, which is stored in the variable &amp;lt;b&amp;gt;@participant&amp;lt;/b&amp;gt;. Therefore no refactor is required for this issue.&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lines 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139743</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139743"/>
		<updated>2021-10-21T02:32:38Z</updated>

		<summary type="html">&lt;p&gt;Adas9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc)[https://github.com/expertiza/expertiza Expertiza on GitHub] [http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza Wiki Page]. It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;StudentQuiz controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;LatePolicies Controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Line 23 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lines 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139736</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139736"/>
		<updated>2021-10-21T02:30:55Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Line 34 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc)[https://github.com/expertiza/expertiza Expertiza on GitHub] [http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza Wiki Page]. It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;StudentQuiz controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;LatePolicies Controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Line 23 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lines 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139734</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139734"/>
		<updated>2021-10-21T02:30:20Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Modifications made to student_quizzes_controller */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc)[https://github.com/expertiza/expertiza Expertiza on GitHub] [http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza Wiki Page]. It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;StudentQuiz controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;LatePolicies Controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Line 23 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lines 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139729</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139729"/>
		<updated>2021-10-21T02:23:27Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Line 108 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc)[https://github.com/expertiza/expertiza Expertiza on GitHub] [http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza Wiki Page]. It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;StudentQuiz controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;LatePolicies Controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 23 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139728</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139728"/>
		<updated>2021-10-21T02:23:19Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Line 53-96 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc)[https://github.com/expertiza/expertiza Expertiza on GitHub] [http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza Wiki Page]. It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;StudentQuiz controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;LatePolicies Controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 23 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
As the method &amp;lt;b&amp;gt;calculate_score&amp;lt;/b&amp;gt; has not yet been completed, skipping this issue, as directed by Professor Gehringer.&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139725</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139725"/>
		<updated>2021-10-21T02:20:13Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Line 119 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc)[https://github.com/expertiza/expertiza Expertiza on GitHub] [http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza Wiki Page]. It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;StudentQuiz controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;LatePolicies Controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 23 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
Update the method comment to better describe &amp;lt;b&amp;gt;review_questions&amp;lt;/b&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139722</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139722"/>
		<updated>2021-10-21T02:18:22Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Line 23 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc)[https://github.com/expertiza/expertiza Expertiza on GitHub] [http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza Wiki Page]. It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;StudentQuiz controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;LatePolicies Controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 23 ===&lt;br /&gt;
----&lt;br /&gt;
Added a method comment to better describe the purpose of &amp;lt;b&amp;gt;finished_quiz&amp;lt;/b&amp;gt; method.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139720</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139720"/>
		<updated>2021-10-21T02:16:30Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Line 34 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc)[https://github.com/expertiza/expertiza Expertiza on GitHub] [http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza Wiki Page]. It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;StudentQuiz controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;LatePolicies Controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the method comment to better explain its purpose.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 23 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139717</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139717"/>
		<updated>2021-10-21T02:14:40Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Line 98 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc)[https://github.com/expertiza/expertiza Expertiza on GitHub] [http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza Wiki Page]. It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;StudentQuiz controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;LatePolicies Controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
Added method comment to record response to describe its purpose. &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : record_response&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 23 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139713</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139713"/>
		<updated>2021-10-21T02:12:36Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Line 24 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc)[https://github.com/expertiza/expertiza Expertiza on GitHub] [http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza Wiki Page]. It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;StudentQuiz controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;LatePolicies Controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : calculate_score&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 23 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139712</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139712"/>
		<updated>2021-10-21T02:12:17Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Line 110 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc)[https://github.com/expertiza/expertiza Expertiza on GitHub] [http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza Wiki Page]. It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;StudentQuiz controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;LatePolicies Controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
Fixed the english of the flash message as the word records was ambiguous.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : calculate_score&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 23 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139704</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139704"/>
		<updated>2021-10-21T02:10:04Z</updated>

		<summary type="html">&lt;p&gt;Adas9: /* Line 24 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc)[https://github.com/expertiza/expertiza Expertiza on GitHub] [http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza Wiki Page]. It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;StudentQuiz controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;LatePolicies Controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
Updated the query from &amp;lt;b&amp;gt;.first&amp;lt;/b&amp;gt; to  &amp;lt;b&amp;gt;.last&amp;lt;/b&amp;gt; as we want to get the latest score and not the first score, in the case a team/student submitted the quiz multiple times.&lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : calculate_score&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 23 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139681</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139681"/>
		<updated>2021-10-21T01:57:46Z</updated>

		<summary type="html">&lt;p&gt;Adas9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc)[https://github.com/expertiza/expertiza Expertiza on GitHub] [http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza Wiki Page]. It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;StudentQuiz controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;LatePolicies Controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : calculate_score&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 23 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 53-96 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Line 108 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Modifications made to late_policies_controller ==&lt;br /&gt;
&lt;br /&gt;
=== Issue 1 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 2 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Issue 3 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139348</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139348"/>
		<updated>2021-10-20T06:58:23Z</updated>

		<summary type="html">&lt;p&gt;Adas9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc)[https://github.com/expertiza/expertiza Expertiza on GitHub] [http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza Wiki Page]. It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;StudentQuiz controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;LatePolicies Controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : calculate_score&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 23 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for a particular assignment &amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139347</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139347"/>
		<updated>2021-10-20T06:57:06Z</updated>

		<summary type="html">&lt;p&gt;Adas9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc)[https://github.com/expertiza/expertiza Expertiza on GitHub] [http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza Wiki Page]. It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;StudentQuiz controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;LatePolicies Controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;br /&gt;
&lt;br /&gt;
== Modifications made to student_quizzes_controller ==&lt;br /&gt;
=== Line 24 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).first &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; @response = Response.where(map_id: params[:map_id]).last # Get the last score if a student took a quiz multiple times &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 110 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : record_response &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz, below are the records for your responses.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; flash[:error] = &amp;quot;You have already taken this quiz. Please find your previous submission below.&amp;quot; &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Line 98 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt;&lt;br /&gt;
&lt;br /&gt;
Method : calculate_score&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Saves the response by the student only if the student has not taken the quiz before. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 34 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : self.take_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Create an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Returns an array of candidate quizzes for current reviewer &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 23 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : finished_quiz &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets the last submission for a quiz by a student &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Line 119 ===&lt;br /&gt;
----&lt;br /&gt;
&amp;lt; Add description here &amp;gt; &lt;br /&gt;
&amp;lt;br&amp;gt; Method : review_questions &amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Before Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # This method is only for quiz questionnaires, it is called when instructors click &amp;quot;view quiz questions&amp;quot; on the pop-up panel. &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;After Refactoring&amp;lt;/b&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt; # Gets all the questionnaire responses by all the teams for an particular a &amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139005</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139005"/>
		<updated>2021-10-13T21:23:49Z</updated>

		<summary type="html">&lt;p&gt;Adas9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
__TOC__&lt;br /&gt;
==Introduction==&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc)[https://github.com/expertiza/expertiza Expertiza on GitHub] [http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza Wiki Page]. It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;StudentQuiz controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;LatePolicies Controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139004</id>
		<title>CSC/ECE 517 Fall 2021 - E2128. Refactor student quizzes controller.rb &amp; late policies controller.rb</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Fall_2021_-_E2128._Refactor_student_quizzes_controller.rb_%26_late_policies_controller.rb&amp;diff=139004"/>
		<updated>2021-10-13T21:22:09Z</updated>

		<summary type="html">&lt;p&gt;Adas9: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This wiki page is for the description of changes made under E2128 OSS assignment for Fall 2021, CSC/ECE 517.&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
Expertiza is a web application developed using Ruby on Rails that serves as a peer-review system. The application allows students to submit and peer-review learning objects (articles, code, websites, etc)[https://github.com/expertiza/expertiza Expertiza on GitHub] [http://wikis.lib.ncsu.edu/index.php/Expertiza Expertiza Wiki Page]. It is an open-source project and its codebase is maintained on GitHub. We are contributing to Expertiza as a part of our Object-Oriented Design and Development's Open-Source Software (OSS) Project. Our goal in this project is to refactor the &amp;lt;b&amp;gt;StudentQuiz controller&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;LatePolicies Controller&amp;lt;/b&amp;gt;. In this Wiki Page, we would be explaining the changes that we have made for the same.&lt;/div&gt;</summary>
		<author><name>Adas9</name></author>
	</entry>
</feed>