Trying to convert a number to binary form - ruby

I wrote a simple program which works:
a = 4.to_s(2)
puts a.reverse
I want to be able to change it based on input from the user in the terminal. This is what I wrote:
puts 'Please enter a number you would like to see expressed in binary form'
i = gets.chomp
b = i.to_s(2)
puts b
This is the error that I keep getting:
`to_s': wrong number of arguments(1 for 0) (ArgumentError)

You're starting with a string, so you need to convert it:
i.to_i.to_s(2)
The #to_s method on a string doesn't take any arguments.

You do not need the chomp method, #to_i will take care of it.
Write it as:
puts 'Please enter a number you would like to see expressed in binary form'
i = gets.to_i
b = i.to_s(2)
puts b
You are calling to_s on an string, not on integer as you are thinking, because Kernel#gets always gives you a String object.
First, convert it to Fixnum, then call Fixnum#to_s on the Fixnum instance, which takes an argument, but String#to_s doesn't accept arguments, which was why you got a complaint from Ruby.

It seems that you want to use Fixnum#to_s but in your program gets.chomp returns a string, so you actually call String#to_s
You can could do:
i = gets.chomp.to_i

Related

Convert Integer to Octal using class Integer and multiple methods

I have a script started but am receiving an error message. I typically have the right idea, but incorrect syntax or formatting.
Here are the exact instructions given:
Extend the Integer class by adding a method called to_oct which returns a string representing the integer in octal. We'll discuss the algorithm in class. Prompt the user for a number and output the octal string returned by to_oct.
Add another method to your Integer extension named "to_base". This method should take a parameter indicating the base that the number should be converted to. For example, to convert the number 5 to binary, I would call 5.to_base(2). This would return "101". Assume that the input parameter for to_base is an integer less than 10. to_base should return a string representing the decimal in the requested number base.
#!/usr/bin/ruby
class Integer
def to_base(b)
string=""
while n > 0
string=(n%b)+string
n = n/b
end
end
def to_oct
n.to_base(8)
end
end
puts "Enter a number: "
n=gets.chomp
puts n.to_base(2)
When I run the script I do get the enter a number prompt, but then I get this error message:
tryagain.rb:16:in `<main>': undefined method `to_base' for "5":String (NoMethodError)
As suggested, do something like this:
class Integer
def to_base b
to_s b #same as self.to_s(b)
end
def to_oct
to_base 8 #same as self.to_base(8)
end
end
5.to_base 2 #=> "101"
65.to_oct #=> "101"

How to make Ruby sleep for amount input by user?

I've tried to make Ruby sleep for an amount that the user has input by doing this:
puts "Time?"
time = gets.chomp
time.to_i
sleep(time)
Does anyone know what I'm trying to do and what I'm doing wrong?
The following works for me:
puts "Time?"
time = gets.chomp
sleep(time.to_i)
.to_i doesn't convert the value and overrides the variable, it simply returns the converted result. So it needs to either be used directly in the sleep argument or set its own (or another variable):
time = time.to_i
sleep(time)
Calling time.to_i returns an integer, but doesn't change time itself. Therefore time is still a string.
Change it to:
puts 'Time?'
string = gets.chomp
time = string.to_i
sleep(time)
Because to_i doesn't care if there is a "\n" at the end of the string, you can skip the chomp call. Therefore you can just write:
puts 'Time?'
time = gets.to_i
sleep(time)

Ruby: Take input and take it as loop range

a = $stdin.read
for i in 0..(a)
puts "Hi"
end
This is giving syntax error-in `
': bad value for range (ArgumentError). What should be improved to get output for a=3 as
Hi
Hi
Hi
The error is because a is a string, you can make it an integer by:
a = a.to_i
You have to convert the string to an integer (.to_i).
Note: prefer to use times:
a.to_i.times { puts "Hi" }
You need an integer to be used, or you get the ArgumentError. This will accept your input and ensure that it can be converted to an Integer. You can read about the Kernel#Integer method for specifics.
a = Integer($stdin.read)
for i in 0..(a)
puts "Hi"
end

How to force/check user to input desired date-type

How do I write code to fore a user to enter a certain value type such as an int, and then force or loop a prompt until a user enters an int, rather than a string or numbers with string characters? I am thinking some type of Boolean with for or while loop.
Let's start with some basics. Put this into a file userinput.rb:
print "Please enter a number: "
input = gets
puts input
Then run with ruby userinput.rb. You get a prompt and the program outputs whatever you type in.
You want your input to be an integer, so let's use Integer() to convert the input:
print "Please enter a number: "
input = gets
puts Integer(input)
Type in an integer and you'll get an integer output. Type in anything else and you'll get something like this:
userinput.rb:3:in `Integer': invalid value for Integer(): "asdf\n" (ArgumentError)
from userinput.rb:3:in `<main>'
Now you can build a loop that prompts the user until an integer is typed in:
input = nil # initialize the variable so you can invoke methods on it
until input.is_a?(Fixnum) do
print "Please enter a number: "
input = Integer(gets) rescue nil
end
The interesting part is input = Integer(gets) rescue nil which converts the integer and, in case of an ArgumentError like above, the error gets rescued and the input var is nil again.
A more verbose way of writing this (except that this catches only ArgumentError exceptions) would be:
input = nil # initialize the variable so you can invoke methods on it
until input.is_a?(Fixnum) do
print "Please enter a number: "
begin
input = Integer(gets)
rescue ArgumentError # calling Integer with a string argument raises this
input = nil # explicitly reset input so the loop is re-entered
end
end
Some notes:
Please don't get confused by Integer and Fixnum. Integer is the parent class that also encapsulates big numbers, but it's fairly standard to test for Fixnum (as in the loop head). You could also just use .is_a?(Integer) without changing the behavior.
Most Ruby tutorials probably use puts over print, the latter's output doesn't end with a newline, which makes the prompt appear in one line.

In Ruby irb, can't access a number in a array like fashion

I tried this in irb:
x = 123456
Then I wanted to get a specific position of the number like:
puts x[2]
it returns 0
why is that?
The only (sensible) way to do this is to first convert it to a string then use the [] method:
x_str = x.to_s
puts x_str[0..2] #prints "12"
If you want to retrieve the position of a string within another string, use the index method
puts x_str.index('2') #prints 1
Fixnum does supply a [] method, but it's obviously not what you want.
In your code, it's returning 0 because that is the 3rd (zero-indexed) bit in the binary representation of 123456.

Resources