Skip to content

Commit

Permalink
add edit function for parsons problem
Browse files Browse the repository at this point in the history
  • Loading branch information
keweizhan committed Mar 25, 2024
1 parent 6aa0507 commit c7223e4
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 90 deletions.
2 changes: 2 additions & 0 deletions app/assets/javascripts/simple_code.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ $(document).ready(function(){
Sk.canvas = "studentCanvas";
$.getJSON('/data/simple_code.json', function(response) {
data = response;
var externalIdElement = document.getElementById("exercise-data");
var externalId = externalIdElement.getAttribute("data-external-id");
var initial = data[index]['initial'];
var initialArray = initial.split('\n');
var config = data[index]['parsonsConfig'];
Expand Down
44 changes: 44 additions & 0 deletions app/controllers/exercises_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ class ExercisesController < ApplicationController
require 'oauth/request_proxy/rack_request'
require 'zip'
require 'tempfile'
require 'json'


load_and_authorize_resource
Expand Down Expand Up @@ -225,7 +226,50 @@ def edit
end
session[:return_to] = @return_to
end
# -------------------------------------------------------------
def edit_parsons
step = params[:step]
full_name = "parsons_s#{step}"
puts "full_name = #{full_name}"
@exercise = Exercise.where('name LIKE ?', "%#{full_name}%").first
json_file_path = Rails.root.join('public', 'data', 'simple_code.json')
if File.exist?(json_file_path)
file_content = File.read(json_file_path)
json_content = JSON.parse(file_content)
@step_data = json_content["s#{step}"]
else
@step_data = {}
end
end

# -------------------------------------------------------------
def update_parsons
step = params[:step]
json_data = params[:step_json_data] # Ensure this matches the name attribute from the form
Rails.logger.debug "Received JSON data: #{json_data}"

json_file_path = Rails.root.join('public', 'data', 'simple_code.json')

unless File.exist?(json_file_path)
redirect_to edit_parsons_exercise_path(step: step), alert: 'JSON file not found.'
return
end

begin
content = JSON.parse(File.read(json_file_path))
updated_data = JSON.parse(json_data)
if content["s#{step}"].present?
content["s#{step}"] = updated_data
File.write(json_file_path, JSON.pretty_generate(content))
redirect_to edit_parsons_exercise_path(step: step), notice: 'Parsons updated successfully.'
else
redirect_to edit_parsons_exercise_path(step: step), alert: "Step not found in JSON."
end
rescue JSON::ParserError => e
Rails.logger.debug e.inspect # Log the error for inspection
redirect_to edit_parsons_exercise_path(step: step), alert: "Failed to parse JSON: #{e.message}"
end
end

# -------------------------------------------------------------
# POST /exercises
Expand Down
9 changes: 7 additions & 2 deletions app/views/exercises/_exercise.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,14 @@
= link_to exercise.display_name, show_exercise_path(step: "s#{step}")
- else
= link_to exercise.display_name, exercise_practice_path(exercise)

- is_parsons = exercise.name.downcase.include?('parsons')
- if [ 'show', 'index', 'search' ].include?(action_name) && (current_user.andand.can? :edit, exercise)
.right= button_link 'Edit', edit_exercise_path(exercise), class: 'btn btn-primary btn-sm'
.right
- if is_parsons
- step = exercise.name.downcase.match(/parsons_s(\d+)/)[1]
= button_link 'Edit', edit_parsons_exercise_path(step: step), class: 'btn btn-primary btn-sm'
- else
= button_link 'Edit', edit_exercise_path(exercise), class: 'btn btn-primary btn-sm'

- if !new_workout
.summary
Expand Down
29 changes: 29 additions & 0 deletions app/views/exercises/edit_parsons.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
- if !@lti_launch
= render partial: 'layouts/breadcrumb'

%h1
Edit Parsons:
- if @exercise
= link_to @exercise.display_name, exercise_practice_path(@exercise)
- else
%span Error: Exercise not found.


%h2
Edit JSON Data for Step: #{params[:step]}
= form_tag update_parsons_exercise_path(step: params[:step]), method: :post do
%fieldset
.field
= label_tag :step_json_data, "Step JSON Data"
= text_area_tag :step_json_data, JSON.pretty_generate(@step_data), class: 'json-editor', rows: 20, cols: 80
.actions
= submit_tag "Save JSON Changes", class: 'btn btn-primary'

:css
.json-editor {
font-family: monospace;
background-color: #f9f9f9;
border: 1px solid #ccc;
width: 100%;
margin-top: 5px;
}
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@
get 'exercises/download_attempt_data' =>
'exercises#download_attempt_data', as: :download_exercise_attempt_data
get '/gym/exercises/Jsparson/exercise/simple/:step', to: 'exercises#show_exercise', as: 'show_exercise'
get '/exercises/Jsparson/exercise/simple/:step/parsons_edit', to: 'exercises#edit_parsons', as: 'edit_parsons_exercise'
post '/exercises/Jsparson/exercise/simple/:step/update_parsons', to: 'exercises#update_parsons', as: 'update_parsons_exercise'
# At the bottom, so the routes above take precedence over existing ids
resources :exercises

Expand Down
175 changes: 87 additions & 88 deletions public/data/simple_code.json
Original file line number Diff line number Diff line change
@@ -1,95 +1,94 @@
{
"s3":{
"initial": "IF $$toggle::a::b$$ $$toggle::<::>::<>$$ b THEN\n min := a\nELSE\n min := b\nENDIF",
"parsonsConfig": {
"max_wrong_lines": 1,
"vartests": [
{
"initcode": "min = None\na = 0\nb = 2",
"code": "",
"message": "Testing with a = 0 ja b = 2",
"variables": {
"min": 0
}
},
{
"initcode": "min = None\na = 7\nb = 4\n",
"code": "",
"message": "Testing with a = 7 ja b = 4",
"variables": {
"min": 4
}
}
],
"executable_code": "if $$toggle$$ $$toggle::<::>::!=$$ b:\nmin = a\nelse:\nmin = b\npass",
"programmingLang": "pseudo"
"s3": {
"initial": "IF $$toggle::a::b$$ $$toggle::<::>::<>$$ b THEN\n min := a\nELSE\n min := b\nENDIF",
"parsonsConfig": {
"max_wrong_lines": 1,
"vartests": [
{
"initcode": "min = None\na = 1\nb = 2",
"code": "",
"message": "Testing with a = 1 ja b = 2",
"variables": {
"min": 1
}
},
"title": "Find minimum",
"instructions": "Construct a function by drag&amp dropping and reordering lines from the left to the right.The constructed function should set the value of variable min to be the smaller of variables a and b.",
"order": 0
{
"initcode": "min = None\na = 7\nb = 4\n",
"code": "",
"message": "Testing with a = 7 ja b = 4",
"variables": {
"min": 4
}
}
],
"executable_code": "if $$toggle$$ $$toggle::<::>::!=$$ b:\nmin = a\nelse:\nmin = b\npass",
"programmingLang": "pseudo"
},
"s4":{
"initial": "$$toggle::x::y::tmp$$ = $$toggle::x::y::tmp$$\n$$toggle::x::y::tmp$$ = $$toggle::x::y::tmp$$\n$$toggle::x::y::tmp$$ = $$toggle::x::y::tmp$$",
"parsonsConfig": {
"max_wrong_lines": 1,
"vartests": [
{
"initcode": "x = 0\ny=2",
"code": "",
"message": "Testing with initial variable values x = 0 and y = 2",
"variables": {
"x": 2
}
},
{
"initcode": "x = 3\ny=4\n",
"code": "",
"message": "Testing with initial variable values x = 3 and y = 4",
"variables": {
"x": 4,
"y": 3
}
}
],
"executable_code": "tmp = x\nx = y\ny = tmp\npass" ,
"programmingLang": "pseudo"
"title": "Find minimum",
"instructions": "Construct a function by drag&amp dropping and reordering lines from the left to the right.The constructed function should set the value of variable min to be the smaller of variables a and b.",
"order": 0
},
"s4": {
"initial": "$$toggle::x::y::tmp$$ = $$toggle::x::y::tmp$$\n$$toggle::x::y::tmp$$ = $$toggle::x::y::tmp$$\n$$toggle::x::y::tmp$$ = $$toggle::x::y::tmp$$",
"parsonsConfig": {
"max_wrong_lines": 1,
"vartests": [
{
"initcode": "x = 0\ny=2",
"code": "",
"message": "Testing with initial variable values x = 0 and y = 2",
"variables": {
"x": 2
}
},
"title": "Variable Swap",
"instructions": "Construct a program that swaps the values of variables <code>x</code> and <code>y</code> using the helper variable <code>tmp</code>. You can change the names of the variables",
"order": 1
{
"initcode": "x = 3\ny=4\n",
"code": "",
"message": "Testing with initial variable values x = 3 and y = 4",
"variables": {
"x": 4,
"y": 3
}
}
],
"executable_code": "tmp = x\nx = y\ny = tmp\npass",
"programmingLang": "pseudo"
},
"s5":{
"initial": "for (int i=0;i<3;i++) {\nSystem.out.print(\"I \");\nSystem.out.print(\"am \");\nSystem.out.print(\"a Java program \");\n}",
"parsonsConfig": {
"max_wrong_lines": 1,
"vartests": [
{
"initcode": "output = ''",
"code": "",
"message": "Testing...",
"variables": {
"output": "I am a Java program I am a Java program I am a Java program "
}
}
],
"executable_code": "for x in range(3):\noutput += 'I '\noutput += 'am '\noutput += 'a Java program '\npass\n",
"programmingLang": "java"
},
"title": "Print message with loop",
"instructions": "Construct code by reordering and indenting the lines.",
"order": 2
"title": "Variable Swap",
"instructions": "Construct a program that swaps the values of variables <code>x</code> and <code>y</code> using the helper variable <code>tmp</code>. You can change the names of the variables",
"order": 1
},
"s5": {
"initial": "for (int i=0;i<3;i++) {\nSystem.out.print(\"I \");\nSystem.out.print(\"am \");\nSystem.out.print(\"a Java program \");\n}",
"parsonsConfig": {
"max_wrong_lines": 1,
"vartests": [
{
"initcode": "output = ''",
"code": "",
"message": "Testing...",
"variables": {
"output": "I am a Java program I am a Java program I am a Java program "
}
}
],
"executable_code": "for x in range(3):\noutput += 'I '\noutput += 'am '\noutput += 'a Java program '\npass\n",
"programmingLang": "java"
},
"s6":{
"initial": "REPEAT 3 TIMES\nforward(100)\nleft(120)\nENDREPEAT",
"parsonsConfig": {
"max_wrong_lines": 1,
"turtleModelCode":"modelTurtle.forward(100)\nmodelTurtle.left(120)\nmodelTurtle.forward(100)\nmodelTurtle.left(120)\nmodelTurtle.forward(100)\nmodelTurtle.left(120)",
"executable_code": "for i in range(0,3):\nmyTurtle.forward(100)\nmyTurtle.left(120)\npass",
"programmingLang": "pseudo"
},
"title": "draw triangle",
"instructions": "Construct a program by drag&amp;dropping and reordering lines from the left to the right.The constructed program should draw a triangle like shown below.",
"order": 3
}

"title": "Print message with loop",
"instructions": "Construct code by reordering and indenting the lines.",
"order": 2
},
"s6": {
"initial": "REPEAT 3 TIMES\nforward(100)\nleft(120)\nENDREPEAT",
"parsonsConfig": {
"max_wrong_lines": 1,
"turtleModelCode": "modelTurtle.forward(100)\nmodelTurtle.left(120)\nmodelTurtle.forward(100)\nmodelTurtle.left(120)\nmodelTurtle.forward(100)\nmodelTurtle.left(120)",
"executable_code": "for i in range(0,3):\nmyTurtle.forward(100)\nmyTurtle.left(120)\npass",
"programmingLang": "pseudo"
},
"title": "draw triangle",
"instructions": "Construct a program by drag&amp;dropping and reordering lines from the left to the right.The constructed program should draw a triangle like shown below.",
"order": 3
}
}

0 comments on commit c7223e4

Please sign in to comment.