Рассмотрим структуру этого файла на примере нескольких вопросов:
[ { "id" : 1, "question" : "Ассаламу Алейкум!", "answers" : ["Ваалейкум Ассалам", "Привет", "Здорово", "Хай"] }, { "id" : 2, "question" : "Как дела?", "answers" : ["альхамдуЛилягь", "Плохо", "хорошо", "шикарно"] }, …..(другие вопросы в таком же порядке) ]
У нас таким образом в json массив из хеш элементов.
Ответы в массиве по ключу answers, в котором первый вариант ответа является правильным.
Второй файл mutaAlim.rb в котором код приложения.
Рассмотрим его поближе. Первые строчки подключают гемы sinatra и json:
require 'sinatra' require 'json'
Для перехода на страницу приветствия следующий код
get '/' do erb :index end
При переходе по адресу у нас откроется страничка, которая описана в том же файле:
@@index <!DOCTYPE html> <html> <head> <title>Главная</title> </head> <body> <h1> Ассаламу гIалайкум ва раhматуЛлаhи ва баракатуhу!</h1> <h1> Мира вам, Милости и Благославления Всевышнего!</h1> <h1> Сайт для тестирования базовых знаний</h1> <h2>Описание </h2> <div> <p> Этот сайт предназначен для тех кто хочет проверить свои знания. </p> </div> <input value="Начать тест" name="test_begin" onclick="location.href='/test'" type="button"> </body> </html>
Простая страничка с кнопкой для перехода на страничку тестов. Далее в коде у нас переменные необходимые для работы приложения:
#хеш с тестами @@test_hash #количество тестов @@kol_testov = 13 #массив из случайно выбранных неповторяющихся вопросов @@mas_test_number = Array.new(@@kol_testov) #массив с ответами, -1 если не ответили на вопрос иначе номер ответа @@mas_test_answer #считываем файл с тестами test_file = File.open('mutaAlim.json',"rb") @@test_hash = JSON.parse(test_file.read) test_file.close #для таблицы результатов @@not_answer = "Вы не дали ответ" #количество ответов @@answers #количество правильных ответов @@ball #процент правильных ответов @@procent_tru_answers #массив в котором хранится
Как вы заметили пришлось все переменные объявить в классе, иначе на вывод в erb были ошибки, которые я не смог понять и исправить. Далее основной элемент приложения это код странички тестов:
# страничка тестов get '/test' do if params[:var] == nil @@mas_test_answer = Array.new(@@kol_testov) { |i| -1} # заносим случайные вопросы в массив @@mas_test_number @@mas_test_number[0] = Random.rand(@@test_hash.length) @@mas_test_number.each_index do |i| begin flag = true buf = Random.rand(@@test_hash.length) 0..i.times do |j| if @@mas_test_number[j]==buf flag = false end end if flag @@mas_test_number[i] = buf end end until flag==true end @@test_number = 0; # заносим случайные варианты ответов в массив @@mas_random_variants @@mas_random_variants = Array.new(@@kol_testov) @@mas_random_variants.each_index do |i| @@mas_random_variants[i] = Array.new(@@test_hash[@@mas_test_number[i]]["answers"].size) end @@mas_random_variants.each_index do |i| @@mas_random_variants[i][0] = Random.rand(@@test_hash[@@mas_test_number[i]]["answers"].size) @@mas_random_variants[i].each_index do |j| begin flag = true buf = Random.rand(@@test_hash[@@mas_test_number[i]]["answers"].size) 0..j.times do |k| if @@mas_random_variants[i][k]==buf flag = false end end if flag @@mas_random_variants[i][j] = buf end end until flag==true end end else #сохраняем выбранный вариант ответа в массив @@mas_test_answer @@mas_test_answer[@@test_number] = params[:var].to_i #если возможно выдаем след вопрос if @@test_number != @@kol_testov - 1 @@test_number += 1 end end erb :test end
По условию params[:var] == nil
мы определяем что пользователь впервые на страничке и «готовим» все необходимое(случайно выбираем тесты из базы, случайно «перемешиваем» варианты ответов и создаем массив для хранения ответов), иначе записываем выбранный пользователем ответ в массив. Весь функционал приложения построен на get запросах, а много путаницы в следствии того, что писалось оно в режиме «лишь бы работало». К примеру если пользователь переходит по ссылке http://localhost:4567/test?var=0 то в массиве ответов на текущий вопрос будет установлено значение 0.
Рассмотрим код странички тестов
@@test <!DOCTYPE html> <html> <head> <title>Тесты</title> </head> <body> <div> <h2> Вопрос №<%= @@test_number +1 %> <h2> <h3> <%= @@test_hash[@@mas_test_number[@@test_number]]["question"] %> </h3> </div> <p> <form method="get" action="/test"> <% @@test_hash[@@mas_test_number[@@test_number]]["answers"].each_index do |i| %> <input type="radio" name="var" value="<%= @@mas_random_variants[@@test_number][i] %>"> <%= @@test_hash[@@mas_test_number[@@test_number]]["answers"][@@mas_random_variants[@@test_number][i]] %> <% end %> <input type="submit" value="Ответить"/> </form> </p> <div> <input type="button" name="next_question" value="Предыдущий вопрос" onclick="location.href='/test/pred'"> <% @@mas_test_number.each_index do |i| %> <a href='/test/question/<%= i + 1 %>'> № <%= i + 1 %> </a> <% end %> <input type="button" name="pred_question" value="Следующий вопрос" onclick="location.href='/test/next'"> </div> <input type="button" name="result" value="Завершить тестирование" onclick="location.href='/test/result'"> </body> </html>
Как вы заметили вставка кода на страничку проиcходит при помощи erb следующим образом <%= #код с выводом данных %>
и <% код без вывода данных %>
. На самой страничке вопрос, варианты ответов(radiobutton), ссылки на все вопросы. кнопки навигации по тестам и кнопка завершения тестирования, которая направляет пользователя на страничку результатов теста.
Работа кнопок навигации и ссылок на вопросы:
# ссылки на каждый вопрос get '/test/question/:id' do @@test_number = params[:id].to_i - 1 erb :test end # следующий вопрос get '/test/next' do if @@test_number != @@kol_testov - 1 @@test_number += 1 end erb :test end # предыдущий вопрос get '/test/pred' do if @@test_number != 0 @@test_number -= 1 end erb :test end
Осталось разобрать код странички результатов теста которая подсчитывает итоги
# страничка результатов get '/test/result' do @@ball = 0 @@answers = 0 #подсчет правильных ответов @@mas_test_answer.each do |i| if i == 0 @@ball += 1 end if i != -1 @@answers += 1 end end @@procent_tru_answers = (100/@@kol_testov) * @@ball erb :result end
И код на html + erb
@@result <!DOCTYPE html> <html> <head> <title>Результат</title> </head> <body> <h1> Результаты вашего теста </h1> <div> <table cellspacing="2" border="1" cellpadding="5"> <tr> <td> № </td> <td> Вопрос </td> <td> Ваш ответ </td> <td> Правильный ответ </td> <tr> <% @@mas_test_answer.each_index do |i| %> <tr> <td> <%= i+1 %> </td> <td> <%= @@test_hash[@@mas_test_number[i]]["question"] %> </td> <td> <%= if (@@mas_test_answer[i] == -1) @@not_answer else @@test_hash[@@mas_test_number[i]]["answers"][@@mas_test_answer[i]] end %> </td> <td> <%= @@test_hash[@@mas_test_number[i]]["answers"][0] %> </td> <tr> <% end %> </table> </div> <div> <h3> Количество тестов = <%= @@kol_testov %> </h3> <h3> Количество ответов = <%= @@answers %> </h3> <h3> Количество правильных ответов = <%= @@ball %> </h3> <h3> Процент правильных ответов = <%= @@procent_tru_answers %> %</h3> <div> <div> <p> Этот сайт предназначен для тех кто хочет проверить свои знания. </p> </div> <input value="Пройти снова" name="test_begin" onclick="location.href='/test'" type="button"> </body> </html>
Я понимаю что данное приложение легче написать с нуля и правильно, нежели понять или сопровождать это. Язык ruby я начал изучать на этом приложении ровно как движок sinatra, язык разметки erb и формат json, поэтому прошу строго не судить за то, что и как использовал.
В дальнейшем планируется переход от sinatra к ror, от json к полноценной базе данных, от erb к haml, от однотипных вопросов(radiobutton) к вопросам 5-6 типов, от тестов к игре и плюс дизайн с версткой.
Приложение в рабочем виде можно увидеть на сайте.
Репозиторий на гитхабе.
ссылка на оригинал статьи http://habrahabr.ru/post/226869/
Добавить комментарий