MarkUs Blog

MarkUs Developers Blog About Their Project

Archive for December, 2012

Punchlines ECN – 12th December 2012

without comments

Here are the punchlines from our group (students from Centrale Nantes):

Amandine:

Status :

  • Order contents of the final reports
  • Reuse the controller results to get the results of an assignment
  • Creation of the code to insert graphs

Next steps :

  • Repartition of the parts of the final report
  • Continue the views and hope they will run!

Road block :

  • None

Alexy & Nora:

Status :

  • Revert a wrong method to define skills and objective
  • Creation of the reusable concept : when created, a criterion can be chosen as “reusable” with a checkbox. Then, when changing a marking scheme, a reusable criterion can be chosen among a list of reusable criteria. He is then added to the marking scheme (so than he can be edited if needed).

Next steps :

  • Finishing the creation and the implementation of reusable criterion

Road block :

  • None

Nicolas and Sebastien:

Status :

  • Revert our wrong changes to the views.
  • Reflexion on how to adapt the results and home controllers to display the new graphs and marks in the right way and at the right place.

Next steps :

  • Validate the final report’s plan and write the report.

Road block :

  • All other changes we need to do are too long and too complex for us to do it in time.

Antoine

Status :

  • Start adding methods to the controller “assignments” so as to get the data used to display results graphs in the assignment view as a student
  • Start writing the html and javascript to display those data

Next steps :

  • Finish it
  • Work on the final report

Written by amandine.lavergne

December 12th, 2012 at 10:36 am

Posted in Status Reports

Tagged with ,

Object Oriented Model Design In Rails

without comments

As a developer coming from a  traditional PHP/MySQL stack environment, representing Object Oriented models in Rails can be a difficult concept to comprehend using the built in ActiveRecord abstraction layer. In this post I will attempt to outline most common way to implement an inheritance hierarchy and as a result limit opportunities to write repeated Model validation code,  create attribute repitition, and finally to limit the introduction of refactoring bugs into your rails project.

For example purposes, we will use a MarkUs specific case. As part of the student code testing framework, the MarkUs application is required to keep track of a number of files submitted by either TA’s or professors which contain either test scripts themselves or test support data required to drive their test scripts.

Test Support File

File Name – String, Description – String, Assignment ID – Integer

Test Script – I’ve abstracted some of the fields in this object for purposes of this post

Script Name – String, Description – String, Assignment ID – Integer

Display Results – Boolean, Run On Submission – Boolean

As you can see, there are three fields in both models that overlap. On top of this, since File Name and Description require user input that we can’t control, we are required to validate/sanitize these attributes before we can allow them to enter our database for security reasons. As you might imagine, these requirements could easily be implemented using polymorphism allowing the base implementation of both Test Scripts and Test Support Files to be handled in one ruby Model. This would roughly cut our validation code in half, make database schemas much easier to change and implement, and finally fewer database queries would be necessary.

Unfortunately our current implementation consists of two completely separate ruby Models. This has created the need for redundant code in the following places:

Controllers – Automated_Tests_Helper.rb: add_test_script_link, add_test_support_file_link, and process_test_form

Models – Test_Support_File.rb & Test_Script.rb: write_file, delete_old_file, sanitize_filename, delete_file, and many of the validation statements

Views – _test_support_file_upload.html.erb & _test_script_upload.html.erb & _form.html.erb

As you can see, this makes refactoring, upgrading, and bug hunting much more difficult. For this reason I have outlined below the simplest way inheritance can be implemented in the MarkUs project.

Single Table Inheritance(STI)

The method we will be covering is that of STI. “In a nutshell, STI allows you to create subclasses of a particular database table. Using a single table, you can cast rows to specific objects that extend the base model.”(Water Cooler) As you may have inferred from the name, this supports inheritance from only a single super class as well. This works mainly by adding an inheritance column to the table(model) you’d like to extend from. By default Rails looks for a column named “type” that is of type string to store this information in.

Essentially this works by using column “type” to store  model names which are represented in that table allowing us to determine which type of model we are dealing with for the given row. One very important note, and downside to consider, is that any additional columns that are needed to represent subclasses will also be included in the same table. This means that there could be potentially many additional null columns that aren’t used by the base class but would still play a factor if a table join is performed for any operations.

Taking a MarkUs specific example:

create_table “test_file”, :force => true do |t|

t.integer              “assignment_id”

t.string                 “file_name”

t.string                 “description”

t.string                 “type”  //this handles the inheritance look ups

end

class TestFile < ActiveRecord::Base

#common file implementation here

end

test_script.rb:

class TestScript < TestFile

#specific implementation here

end

test_support_file.rb:

class TestSupportFile < TestFile

#specific implementation here

end

As you can see implementing inheritance is accomplished quite simply using this technique. Once you have implemented these model objects and have populated the database with different types of objects, you can access them using standard select or find calls using ActiveRecord. Rails will automatically convert the returned object into their specified model types.

That about concludes my basic overview of Single Table Inheritence. Hopefully this has been useful and will be considered for future versions of the MarkUs Testing Framework. For another great explanation, read: http://code.alexreisner.com/articles/single-table-inheritance-in-rails.html

Written by deredowl

December 8th, 2012 at 11:38 pm

Introduction to the Debugger gem

without comments

Though this post is probably coming a little late in the term to help anyone out with their Rails debugging right now, I’m hoping it might at least give a few people some insight onto how you can quickly debug in Rails without using an IDE, and also to newcomers to the Markus project who are also experiencing Rails for the first time.

Probably the first thing you’ll want to know, is how the debugger is included in the Rails project, and how you will have access to it.  By looking at the “Gemfile”, which specifies what “add-ons” our rails project is using, in the root of the project we see that the debugger gem is included for the Development and Test environments:

gem "debugger", :platforms => :mri_19

We need to include the debugger to have access to it, and if we check the config files for development and test under /config/environments, the lines:

require 'ruby-debug' if RUBY_VERSION == "1.8.7"
require 'debugger' if RUBY_VERSION > "1.9"

Show us that it will always be available for every file in these 2 environments. This enabled us to use the “debugger” command, to stop execution in any file, and then inspect the current state, modify variables, and run commands both under “rails server” and when running unit and functional tests.
For example, let’s put a “debugger” statement in the assignments controller:

# Called when editing assignments form is submitted (PUT).
def update
debugger
@assignment = Assignment.find_by_id(params[:id])
@assignments = Assignment.all
@sections = Section.all

When you now submit an update on the assignments page, you’ll notice that the page response stalls. If you check the console containing the rails server, you’ll see that you now have an interactive prompt:

/home/ioev/Projects/Markus/app/controllers/assignments_controller.rb:188
@assignment = Assignment.find_by_id(params[:id])
(rdb:1)

Here we see a listing of the line number the debugger stopped at, and the contents of the line as well. If you type “help” at the prompt, you’ll get a listing of all of the available commands:

(rdb:1) help
ruby-debug help v0.10.4
Type 'help ' for help on a specific command

Available commands:
backtrace delete enable help method putl set trace
break disable eval info next quit show undisplay
catch display exit irb p reload source up
condition down finish kill pp restart step var
continue edit frame list ps save thread where

The most useful commands to us right now, are “next, continue, list, p and pp” but you should experiment with the others as well.
“next” or “n” will execute the next line of code.
“continue” or “c” will continue to the end of execution, or to the next breakpoint. You can use this to end debugging (unless you’ve got a debugger statement in a loop, where you’ll just end up at the next iteration)
“list” will list the line the debugger is stopped on, and the lines surrounding it.
“p” and “pp” allow you to print out variables, or execute any ruby code.

So if we type “l” for list, we get:
(rdb:1) l
[183, 192] in /home/ioev/Projects/Markus/app/controllers/assignments_controller.rb
183 end
184
185 # Called when editing assignments form is submitted (PUT).
186 def update
187 debugger
=> 188 @assignment = Assignment.find_by_id(params[:id])
189 @assignments = Assignment.all
190 @sections = Section.all
191
192 if !params[:assignment].nil?

And say we want to print out the current value of params, which are the parameters passed in by the form, we can type “p params” or “pp params”:
(“pp” stands for “pretty print” and will print with a little bit more formatting that the regular print, which makes it really useful for arrays and hashes. “ps” is similar.)
(rdb:1) pp params
{"action"=>"update",
"id"=>"1",
"authenticity_token"=>"EN8RfAGUY/EfKNepI6VZqWPs9rUaOGSMlCWPCS9x5Y4=",
"_method"=>"put",
"assignment"=>
{"display_grader_names_to_students"=>"false",
"marking_scheme_type"=>"flexible",
"message"=>"Learn to use conditional statements, and loops.",
"remark_message"=>"",
"group_name_autogenerated"=>"0",
"repository_folder"=>"A1",
"remark_due_date"=>"",
"description"=>"Conditionals and Loops",
"submission_rule_attributes"=>{"id"=>"1", "type"=>"NoLateSubmissionRule"},
"allow_web_submits"=>"true",
"due_date"=>"2012-11-21 16:17",
"short_identifier"=>"A1",
"allow_remarks"=>"true",
"student_form_groups"=>"0"},
"controller"=>"assignments",
"utf8"=>"?",
"locale"=>"en"}

Since “debugger” is a command, you can also use conditionals to only activate the debugger only under certain conditions. For example:

debugger if variable.nil?

Which is really useful if you’re looping through a large set of data, and are having trouble with only one piece, this will help you narrow things down.
So now that you have an idea how to use the Rails debugger, I hope you never have to use a “puts” statement and search the console for the output ever again!
Good luck!

Written by Joey Perry

December 6th, 2012 at 11:24 pm

Old Results not Showing when Remarking

without comments

This problem was raised in issue904. The design of Markus’s current remark request feature is, when a grader is remarking a submission, he/she should be able to see the old mark of each rubric category as well as the total before giving new marks(as shown below).

But old marks do not appear!

As it turns out, old marks will show up after the grader marks a category and refresh the page. When I first saw this issue and try to reproduce it on our demo server and my own local server everything works fine. I also learned that the server is running ruby 1.8.7 so I decided to setup RVM+ruby1.93 at home to test it which wasted me quite a few hours with no success due to svn binding.

Meanwhile, it was found out that this issue only happens when one is using PostgreSql. Lesson learned: although including configuration details in an issue might be tedious, those details sometimes helps. However I do like the fact that Markus project has no strict rules on how to “compose” an issue so one can decide what info is useful and what is not.

After yet a few hours of struggling with setting up RVM ruby 1.8.7 + PostgreSQL, I finally got Postgresql working by giving up RVM. I still believe RVM is great but somehow it doesn’t work for me.

In results_controller.rb, somewhere around line35 we have:

if @submission.remark_submitted?
@old_result = @submission.result

But debugger shows that @submission.result is not giving us the old result. As pointed out by Joey(ioev), this is because in submission.rb, the definition of the Submission class states:

has_one    :result, :dependent => :destroy
……
belongs_to :remark_result, :class_name => “Result”

The “has_one” relation means that the Results table has foreign keys that points to rows in Submission table. See the below example(from Rails tutorial):

But Submission also belongs_to remark_result which is also a row in the Results table. Below is an example of belongs_to relation(also from rails tutorial):

So we can have two rows in the Results table that points to the same submission. @submission.remark_result should give us the desired result because it’s one-to-one, but @submission.result can return the wrong result because database will just find any result in the Results table that has a matching submission id and return that.

Joey also noticed the time-stamps of the result entries and how they affect which result will be returned by the database. In results_controller.rb, update_remark_request is the method that creates the remark_result(a new result in the Results table). By swapping the order of the following two line:

@result.save
@old_result.save

to:

@old_result.save
@result.save

I am able to ensure that the old result row will have an older time-stamp and will be return by @submission.result. Testings show that this removes the problem with Postgresql without introducing problem back to Mysql or Sqlite. Obviously this is not a good solution at all and I will work on a better solution based on Joey’s comments.

 

 
 

Written by antez

December 6th, 2012 at 4:13 am

Posted in Remarks

A Better Dashboard

without comments

What to Change:

  • Submitted Assignment to Collected Assignments
  • Order of Assignment by Descending Due Date

What to add to Assignment Information:

  • Median
  • Number of zeros
  • Number of fails
  • Number of Submitted Assignments

There is definitely more to add, but only with time and testing it will be clear what we need.

Written by andreykul

December 5th, 2012 at 5:28 pm

C.R.A.P Design Principles at MarkUs

without comments

What’s C.R.A.P?

C.R.A.P stands for Contrast, Repetition, Alignment and Proximity.

 

Contrast

Different elements (titles, heading, body text, etc.) must look different from each other. This can be achieved by varying fonts, line thickness, colours, shapes, sizes, space, etc.

 

Repetition

Repeat an aspect of the design throughout the website, for example all titles will use the same font, size, weight, etc. This makes the website consistent.

 

Alignment

Don’t place elements arbitrarily on the page. Elements of the same importance should be aligned vertically and horizontally.

 

Proximity

Group related elements together, for example a heading should be closer to the text it belongs to than to the text of the previous paragraph. Physical close elements imply a relationship.

 

C.R.A.P at MarkUs


The Problems

Dashboard

The dashboard is overall fine. there small problems with the alignment of the assignment information.

 

Assignments

On the main page the proximity was violated when the class average was equally close to both assignments.It should be closer to assignment 1 and farther from assignment 2. It was also directly under the assignment. It is part of the assignment therefore it should be under the details of the assignment. The rounding is also different then the one on the dashboard. All pages should follow the same rounding rules.

The submission page has options right next to the name of the assignment. While they should be underneath. The options for sorting the table were using completely different style, using buttons rather than text as the options above them. I would suggest changing all the options to look like buttons. There is the rounding issue again.

On the groups page the options for each student are at different place depending on the length of the name. They all should be in the same place right underneath each other. The tabs for managing groups should be on the same line, if there is no space then at least the search should be on a separate line then the tabs.

 

Annotation

The annotation page the Help is the same size of the assignment title. They should be different size and style since they are different things. The options are directly next to the title. They should be underneath and changed to buttons.

 

Grading

On the Grading page The previous and next submission are higher than the rest of the options for some reason. They should be vertically aligned. Same applies to the check box for released. For unreleased assignments under the summary is a complete mess. There are issues with alignment and proximity. Most of the things there are done with tables but then it just stopped and things got out of alignment.

 

Users

The options on this page are all of a sudden on the right and not next to title like on other pages. This breaks the repetition between pages.

 

Student

On the student view the assignment rules are completely different than the rest of the section. Also all the details there are on the same line while the message is underneath. This is inconsistent.


The Pictures

 



The Good

 


Over all there is good contrast through out the website. The website is pretty consistent about its’ layout and there is pretty good proximity.

Written by andreykul

December 5th, 2012 at 5:20 pm

Punchlines ECN – 5th December 2012

without comments

Here are the punchlines from our group (students from Centrale Nantes):

Amandine & Antoine :

Status :

  • Seen how we could access to the grades, to which controller it was associated, in which views it was used and how to use it.

Next steps :

  • Finish views.

Road block :

  • Exam to prepare.

Alexy & Nora :

Status :

  • Creation of models flexible_criterion_assignment_association and rubric_criterion_assignment_association
  • Correction of migration
  • Modifying flexible_criterion and rubric_criterion to add relationship with new tables
  • Working on the radio button for the marking_scheme of a new assignement

Next steps :

  • Modifying the UI to cope with the disappearance of the current radio button (see the status)
  • (Nora) Working on the final report

Road block :

  • Understanding the way to add the “new” criterion (skill/objective)

Nicolas & Sébastien :

Status :

  • Worked on the controllers and views. Determine which should be used to display the new marks, and understanding what needs to be changed.

Next steps :

  • Because there won’t be a specific marking_scheme_type, each time it is used we need to use critere.instanceof? (flexible_criterion) instead.

Road block :

  • Exam to prepare

Written by amandine.lavergne

December 5th, 2012 at 11:14 am