Forum: Ruby Force user to input text to move on

076a2b44d85eb8731301da032cc4280c?d=identicon&s=25 GLENN CHAMBERLAIN (rubynewb)
on 2017-02-19 15:29
Good morning everyone. I've been struggling over this one seemingly
difficult concept. I need to force the player to actually input text to
progress to the next screen while still enforcing the current rules.
I've tried using loop and case blocks. ANY input would be greatly
appreciated.

def present_test(challenge)

      Console_Screen.cls

      print challenge +"\n\n: "
      result = STDIN.gets
      result.chop!

      if challenge == result then


            $noRight += 1
            Console_Screen.cls
            print "Correct!\n\nPress Enter to continue."
            Console_Screen.pause

        else

            Console_Screen.cls
            print "Incorrect!\n\nPress Enter to continue." + "\n\n"
            print result + "\n\n"
            print challenge
            Console_Screen.pause

      end
0fa73332c8e4a3b06ea439fd3f034322?d=identicon&s=25 Ronald Fischer (rovf)
on 2017-02-20 10:55
With "force the user to input text", I guess you mean that the user
doesn't just press the return key, but also types something in addition,
and that you are concerned with the user response for
Console_Screen.pause. Right?

You didn't show the code for Console_Screen.pause, but I assume that you
will there also do some STDIN.gets, so why don't you simply look at what
has been returned?
076a2b44d85eb8731301da032cc4280c?d=identicon&s=25 GLENN CHAMBERLAIN (rubynewb)
on 2017-02-21 03:40
Ronald Fischer wrote in post #1185572:
> With "force the user to input text", I guess you mean that the user
> doesn't just press the return key, but also types something in addition,
> and that you are concerned with the user response for
> Console_Screen.pause. Right?
>
> You didn't show the code for Console_Screen.pause, but I assume that you
> will there also do some STDIN.gets, so why don't you simply look at what
> has been returned?


Ronald,

That is what I meant why "force the user to input text." And I am
concerned with the input for Console_Screen.pause. I don't understand
what you mean for the code for Console_Screen.pause tho. I've pasted the
whole script below. I don't expect you to help me with the whole thing
but this is about 4 weeks into my class and I'm unsure of what to
provide to answer your question.


class Screen
  def cls
    puts ("\n" * 25)
    puts "\a"
  end

  def pause
    STDIN.gets

  end
end


class Test

  def display_greeting

       Console_Screen.cls


      print "\t\t  Welcome to the Ruby Typing Challenge game!" +
      "\n\n\n\n\n\n\n\n\n\n\n\n\nPress Enter to " +
              "continue. \n\n: "

    Console_Screen.pause

  end


  def display_instructions

    Console_Screen.cls
         puts "\t\t\tInstructions:\n\n"
         #Altered the instructions to provide grading instructions
         puts %Q{  This test consists of a series of 10 typing
           challenges. The Challenge sentences are presented
         one at a time. To respond correctly, you must retype
         each sentence exactly as shown and press the Enter key.
         Your grade is presented as a letter grade with 9-10
         correct being an A, 8 a B, 7 a C, 6 is a D and anything
         less being a F. Your grade will be displayed at the end
         of the test.
         \n\n\n\n\n\n
         Press Enter to continue\n\n}

    Console_Screen.pause

  end

  def present_test(challenge)

    Console_Screen.cls

    print challenge +"\n\n: "
    result = STDIN.gets
    result.chop!




    if challenge == result then


          $noRight += 1
          Console_Screen.cls
          print "Correct!\n\nPress Enter to continue."
          Console_Screen.pause

      else

          Console_Screen.cls
          #Ex 4. Will present the incorrectly typed message above the
expected result.
          print "Incorrect!\n\nPress Enter to continue." + "\n\n"
          print result + "\n\n"
          print challenge
          Console_Screen.pause



      end
    end



  def determine_grade

      Console_Screen.cls

    #Increased the passing score from 3 to 6.
    # if $noRight >= 6 then

      answer = $noRight
      case
      when  (answer.between?(9,10))
        puts "A"
      when answer == 8
        puts "B"
      when answer == 7

        puts "C"
      when answer == 6
        puts "D"
      when (answer.between?(0,5))
        puts "F"

      if answer >=6
        print "You retyped " + $noRight.to_s + " sentence(s) correctly.
"
        puts "You have passed the typing test!\n\nPress Enter to
continue."

      else


        print "You retyped " + $noRight.to_s + " sentence(s) correctly.
"
        puts "You have failed the typing test!\n\nPress Enter to
continue."

      end

  end

end



# Main Script Logic -----------------------------------------------


$noRight = 0

         Console_Screen = Screen.new


                   Typing_Test = Test.new

         Typing_Test.display_greeting

         Console_Screen.cls
         print "Would you like to test your typing skills? (y/n)" +
           "\n\n"

         answer = STDIN.gets
         answer.chop!


until answer == "y" || answer == "n"

  Console_Screen.cls

  print "Would you like to test your typing skills? (y/n)\n\n: "
  answer = STDIN.gets
  answer.chop!

end


if answer == "n"

    Console_Screen.cls

    puts "Okay, perhaps another time.\n\n"
else

  Typing_Test.display_instructions
         #Extended the typing test to cover 10 Sentences from 5 for Ex 1
         Typing_Test.present_test"In the end there can be only" +
           " one."
         Typing_Test.present_test "Once a great plague swept" +
           " across the land"
         Typing_Test.present_test "Welcome to the principles of Ruby"
         Typing_Test.present_test "There are very few problems in" +
         " the world that enough moms cannot fix."
         Typing_Test.present_test  "Perhaps today is a good day to" +
         " die. Fight beside me and let us die together"
         Typing_Test.present_test "I sure hope I get an A in this class"
          Typing_Test.present_test "Full time employment does not mix
well" +
            " well full time student status"
          Typing_Test.present_test "May of 2018 cannot come quick
enough"
          Typing_Test.present_test "Life will be simpler once a student
graduates"
          Typing_Test.present_test  "College will be worth it after
getting that degree"



  Typing_Test.determine_grade

  Console_Screen.pause

  Console_Screen.cls

  puts "Thank you for taking the Ruby Typing Challenge.\n\n"

end

end
0fa73332c8e4a3b06ea439fd3f034322?d=identicon&s=25 Ronald Fischer (rovf)
on 2017-02-21 07:34
Well, you are using a method named 'pause', which sits in class
Console_Screen, and you want the behaviour of this method to change. To
do this, we need to see, how this method is written, because how else
could we modify the code or provide an alternative?

Actually, a better idea is not to modify the method, but provide an
alternative. In Ruby, you have several possibilities. In your case, I
suggest to add a new method to an existing class - this is called
"monkey patching":

    class Console_Screen

      def self.pause_with_input
         # your code goes here ....
      end

    end

and you call it as

    Console_Screen.pause_with_input

But even if you monkey patch Console_Screen, it would be a good idea to
have a look at the original code of Console_Screen::pause, to find out
whether it is maybe doing something else besides waiting for user input,
which perhaps in important for the correct working of the Console_Screen
class.
076a2b44d85eb8731301da032cc4280c?d=identicon&s=25 GLENN CHAMBERLAIN (rubynewb)
on 2017-02-22 02:28
Ronald,

Thank you very much for that detailed response. You cleared up a lot of
merky understanding on my end. I'm still not sure what code to put into
the monkey patched code but my overall understanding of how everything
works feel much more complete. I feel you gave me more than enough for
now to work with.

Thanks again.
4828d528e2e46f7c8160c336eb332836?d=identicon&s=25 Robert Heiler (shevegen)
on 2017-02-25 23:57
I don't even see why monkey patching is necessary.

It is your code and it is locally right, in some files?

Then just modify the code to have the behaviour.

If you only need to let the user input one character,
such as the "n" key for next, without the enter key,
have a look at io/console.

  char = $stdin.getch

or

  hidden_char = STDIN.noecho(&:gets)

By the way most of your code can be made
simpler. Such as:

  result = STDIN.gets
  result.chop!

Use:

  result = STDIN.gets.chop

or even better:

  result = STDIN.gets.chomp

Also $stdin is better than STDIN in this context,
but you can omit both, to use:

  result = gets.chomp

instead.
0fa73332c8e4a3b06ea439fd3f034322?d=identicon&s=25 Ronald Fischer (rovf)
on 2017-02-27 11:27
> I don't even see why monkey patching is necessary.

We don't know to what extent it is the OPs code. Console_Screen could be
a class which was developed by a different team than the OP is in; or,
it could be an exercise in a Ruby programming course and Console_Screen
could be a gem supplied by the programming school.

In particular since the OP was reluctant so far to show us the code of
Console_Screen, I suspect that he is not familiar with the internals of
this class and hence concluded that he has not probably developped
himself.
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.