#ruby #function
Вопрос:
Это код, который я хотел использовать для повторного кода, поместив его в другую функцию и сохранив переменные в этой другой функции. Я не новичок в этом типе функций, поэтому мне действительно нужна помощь, большое вам спасибо за помощь.
def main
marks = 0
puts "1. What does the == operator do?"
puts "(a) calculates an arithmetic solution."
puts "(c) checks for e"
puts "Your answer: "
begin
answer = gets.chomp
end while (answer != 'a' amp;amp; answer != 'b' amp;amp; answer != 'c' amp;amp; answer != 'd')
if answer == 'c'
score = 1
puts "Correct "
else
puts "Wrong "
end
puts "2. Which is NOT a C keyword?"
puts "(a) when"
puts "(b) const"
puts "(c) unsigned"
puts "Your answer: "
begin
answer = gets.chomp
end while (answer != 'a' amp;amp; answer != 'b' amp;amp; answer != 'c' amp;amp; answer != 'd')
if answer == 'a'
score = 1
puts "Correct "
else
puts "Wrong "
end
puts "3. In function call, the actual parameters are separated by"
puts "(a) semicolons"
puts "(b) colons"
puts "(c) commas"
puts "Your answer: "
note
answer = gets.chomp
if answer != 'a' amp;amp; answer != 'b' amp;amp; answer != 'c' amp;amp; answer != 'd'
if answer == 'c'
score = 1
puts "Correct "
else
puts "Wrong "
end
end
main
Комментарии:
1. Вам не нужна функция — вам нужны объекты. Вы, вероятно, захотите иметь объекты вопросов (отвечающие за хранение ваших данных о вопросах — вопрос, сам по себе, ответы и то, какой из них правильный, позже вы можете добавить специальную логику подсчета очков и различные типы вопросов), объект викторины (содержащий массив вопросов) и QuizAttempt (ссылка на викторину, выбранные ответы и итоговый балл) в качестве уровня данных. Затем простой объект QuizRunner будет выступать в качестве консольного интерфейса для перебора вопросов викторины и создания QuizAttempt.
2. не могли бы вы научить меня, как это сделать
3. @BroiSatse: хотя это довольно большой скачок. Лучше действовать детскими шагами: сначала извлеките пару СУХИХ методов.
4. @SergioTulentsev — Я согласен, что это огромный скачок, но его (ИМО) необходимо предпринять. По моему опыту, разработчики на тренировках очень неохотно совершают этот прыжок, что только закрепляет их в процедурном программировании. OO — это другой тип навыка для самостоятельного владения языком и/или алгоритмического мышления, и его можно научить, даже если кто-то вообще не знает, как программировать-я иногда провожу семинары в начальных школах, и дети просто любят рисовать диаграммы «что говорит с чем»:)
Ответ №1:
это непростой шаг, но, согласно комментариям @BroiSatse, создание различных аспектов объекта в виде классов:
Определение объекта для хранения возможных ответов
class Answer
attr_accessor :text, :correct
def initialize text, correct
@text = text
@correct = correct
end
end
Определение объекта для хранения вопросов, который будет содержать массив возможных ответов
class Question
attr_accessor :text, :answers
def initialize text
@text = text
@answers = []
end
end
Определение класса «Викторина», который содержит оценку и набор вопросов. он также включает в себя процедуру для просмотра вопросов и ответов, хранящихся в викторине
class Quiz
attr_accessor :questions, :score
def initialize
@questions = []
@score = 0
end
def ask_questions
@questions.each_with_index do |question, i|
puts "#{i 1}. #{question.text}"
question.answers.each_with_index do |answer,i|
a_letter = (i 'a'.ord).chr
puts "(#{a_letter}) #{answer.text}"
end
while true
puts "Your answer: "
user_answer = gets.chomp
break if (user_answeramp;.ord - 'a'.ord)amp;.between?(0, question.answers.count-1)
end
if (question.answers[(user_answer.ord - 'a'.ord)]amp;.correct)
@score = 1
puts "Correct tYour score is now " @score.to_s
else
puts "Wrong tYour score is still " @score.to_s
end
end
end
end
Используйте новые классы/объекты
Теперь, когда классы настроены, мы можем создать нашу «Викторину».:
quiz=Quiz.new
question = Question.new("What does the == operator do?")
question.answers << Answer.new('calculates an arithmetic solution.', false)
question.answers << Answer.new('assigns a value to a variable.', false)
question.answers << Answer.new("checks for equality", true)
question.answers << Answer.new("draws the '=' character", false)
quiz.questions << question
question = Question.new("Which is NOT a C keyword?")
question.answers << Answer.new('when', true)
question.answers << Answer.new('const', false)
question.answers << Answer.new('unsigned', false)
question.answers << Answer.new('do', false)
quiz.questions << question
question = Question.new("In function call, the actual parameters are separated by")
question.answers << Answer.new('semicolons', false)
question.answers << Answer.new('colons', false)
question.answers << Answer.new('commas', true)
question.answers << Answer.new('space', false)
quiz.questions << question
и, наконец, запустите процедуру «ask_questions»
quiz.ask_questions
демонстрационный вывод
2.7.2 :124 > quiz.ask_questions
1. What does the == operator do?
(a) calculates an arithmetic solution.
(b) assigns a value to a variable.
(c) checks for equality
(d) draws the '=' character
Your answer:
c
Correct Your score is now 1
2. Which is NOT a C keyword?
(a) when
(b) const
(c) unsigned
(d) do
Your answer:
c
Wrong Your score is still 1
3. In function call, the actual parameters are separated by
(a) semicolons
(b) colons
(c) commas
(d) space
Your answer:
c
Correct Your score is now 2
Комментарии:
1. Придираюсь, но ответ сам по себе не является правильным или неправильным, это зависит от вопроса. Это могло бы иметь больше смысла, если бы объект, содержащий ответы, знал, какой из них правильный.
2. Мой допускает несколько возможных правильных ответов и позволяет изменять порядок элементов массива на лету … Но я понимаю вашу точку зрения
3. Вы могли бы еще больше сократить объем кода, используя структуру ruby. Определения классов для
Question
иAnswer
могут быть заменены одиночными строкамиQuestion = Struct.new(:text, :answers)
иAnswer = Struct.new(:text, :correct)
, соответственно.
Ответ №2:
это мой код, все в порядке или слишком неаккуратно
class Question
attr_accessor :prompt, :answer
def initialize(prompt, answer)
@prompt = prompt
@answer = answer
end
end
p1 =
"1. What does the == operator do?n
(c) checks for equalityn
(d) draws the '=' charactern
Your answer: n"
p2 =
"1. What does the == operator do?n
(b) assigns a value to a variable.n
(c) checks for equalityn
(d) draws the '=' charactern
Your answer: "
p3 =
"3. the actual parameters are separated byn
(b) colonsn
(c) commasn
Your answer: "
questions = [
Question.new(p1, "c"),
Question.new(p2, "a"),
Question.new(p3, "c"),
]
def run_test(questions)
answer = ""
score = 0
for question in questions
puts question.prompt
answer = gets.chomp
(answer != 'a' amp;amp; answer != 'b' amp;amp; answer != 'c' amp;amp; answer != 'd')
if answer == question.answer
score = 1
puts "Correct " =
else
puts "Wrong "
end
end
end
run(questions)
Комментарии:
1. Это намного лучше! Ваш исходный код был чрезвычайно процедурным и функционально ориентированным. Здесь у вас есть некоторые признаки ОО — вы абстрагировали как идею вопроса, которая теперь прекрасно инкапсулирует данные викторины, так и концепцию запуска викторины. Теперь обратите внимание, что любое изменение самого теста не требует каких — либо изменений в вашем методе run_test, что значительно повышает удобство обслуживания. Кроме того, вы
run_test
делаете всего несколько предположений оquestions
— он ожидает, что это будет массив объектов, отвечающих наprompt
иanswer
. Это отличная база для последующего внедрения полиморфизма2. Однако давайте сделаем это еще лучше. Во — первых, похоже, что вы происходите из семьи Си-мы редко используем
for
while
циклы и в ruby. Так что вместоfor question in questions
того, чтобы делатьquestions.each do |question|
то, что гораздо больше похоже на рубин. в данном конкретном случаеwhile
используется правильно, но вам это не нужноbegin/end
:answer = gets.chomp while asnwer != ...
тоже сработает. Поскольку мы здесь — здесь есть важное и опасное предположение — вы предполагаете, что на каждый вопрос будет 4 ответа. Попробуйте исправить это и сделать его более гибким.3. Все данные вопросов / ответов делают ваш код более раздутым, чем он есть на самом деле. Возможно, было бы неплохо разделить данные и код и перенести вопросы в другой файл.