When I type the following:
print "2+2 is equal to" +2+2
I get an error message saying I can't convert a number into a string, but when I type:
print "2+2 is equal to", 2+2
it's accepting it and displays:
2+2 is equal to4
What's the difference between the two? It's not making logical sense to me. Could someone please explain it?
print "2+2 is equal to" + 2 + 2
Here you're trying to add a number to a string. This operation doesn't make sense. It's like adding an apple to a cat. The addition fails, but if it were to succeed, then print would print the result.
print "2+2 is equal to", 2 + 2
Here you're telling the print command to print this string and also result of summing these two numbers. it knows how to print strings and how to print numbers. Strings and numbers don't have to be mixed together in this case, they are handled separately. That's why this operation succeeds.
You can make the first operation work too. For this, you must be explicit that you want this number as a string, so that both addition operands are strings and can be actually added together.
print "2+2 is equal to" + (2 + 2).to_s
or
print "2+2 is equal to #{2 + 2}" # this is called string interpolation
Some languages try to be friendly and, if you're adding a number to a string, will stringify the number for you. Results can be... surprising.
Javascript:
"2 + 2 equals to " + 2 + 2
# => "2 + 2 equals to 22"
"2 + 2 equals to " + (2 + 2)
# => "2 + 2 equals to 4"
It's good that ruby doesn't do this kind of tricks :)
Everybody's pointed out how print works, so i thought i'd shed a bit of light on +.
These two operators look the same, right?
'2'+'2'
2+2
In actual fact, there are two very different operations happening:
String#+ - This concatenates the argument to the source string. Argument must be a string.
Fixnum#+ - This adds the argument to the source number. Argument must be a number.
So if String#+ only works on string objects, how is it that we can print different types of objects?
Some classes are very 'string-like' and can be treated as strings in most contexts (eg. Exception before Ruby 1.9) as they implement to_str(implicit conversion).
We can also implement to_s in our own objects to allow it to return a String representation of the object (explicit conversion).
You can read more about this at http://codeloveandboards.com/blog/2014/03/18/explicit-vs-implicit-conversion-methods/
print "2+2 is equal to" +2+2
is equivalent to:
print("2+2 is equal to" +2+2)
You are trying to add an integer 2 to a string "2+2 is equal to".
print "2+2 is equal to", 2+2
is equivalent to:
print("2+2 is equal to", 2+2)
Here print takes two arguemnts, one is a string, the other is an expression 2+2.
print "2+2 is equal to" + 2+2
fails because it tries to add a integer to a string before the result is send to print. An operation that does not make sense. Whereas:
print "2+2 is equal to", 2+2
is a other operation. Here you send two argument to print. A string and an integer. Internally print calls to_s on both values.
From the documentation:
print(obj, ...) → nil
Prints each object in turn to $stdout. [...] Objects that aren't strings will be converted by calling their to_s method.
Another way to do this is string interpolation, that also calls to_s automatically:
print "2+2 is equal to #{2+2}"
Related
The following code always outputs "not":
print "input a number please. "
TestNumber = gets
if TestNumber % 2 == 0
print "The number is even"
else
print "The number is not even"
end
What is going wrong with my code?
The gets() method returns an object of type String.
When you call %() on a String object, the return value is a new String object (usually it changes the text. You can read more about string formatting here).
Since there are no String objects that == 0, the if/else will always take the same path.
If you want to use the return value of gets() like a number, you will need to transform it into one first. The simplest approach is probably to use the to_i() method on String objects, which returns a new 'Integer' object. If you're doing something where the user input will not always be an integer (e.g. 3.14 or 1.5), you might need to use a different approach.
One last thing: in your example the result of gets() is saved into a constant called TestNumber. Constants are different to normal variables, and they will probably cause problems if you're not using them intentionally. Normal variables don't start with capital letters. (You can read more about ruby variables here). In ruby you need to write you variable names like this: test_number.
I suspect your Testnumber variable might be interpreted as a string during the operation. make sure the testnum is converted to an integer first even if you put in say 100 it could be its being interpreted as the stirng "100" and not the integer 100.
A similar issue can be found here: Ruby Modulo Division
You have to convert TestNumber from string to integer, as your input has linefeed and/or other unwanted characters that do not match an integer.
Use TestNumber = gets.to_i to convert to integer before testing.
I am wondering how to make something where if X=5 and Y=2, then have it output something like
Hello 2 World 5.
In Java I would do
String a = "Hello " + Y + " World " + X;
System.out.println(a);
So how would I do that in TI-BASIC?
You have two issues to work out, concatenating strings and converting integers to a string representation.
String concatenation is very straightforward and utilizes the + operator. In your example:
"Hello " + "World"
Will yield the string "Hello World'.
Converting numbers to strings is not as easy in TI-BASIC, but a method for doing so compatible with the TI-83+/84+ series is available here. The following code and explanation are quoted from the linked page:
:"?
:For(X,1,1+log(N
:sub("0123456789",ipart(10fpart(N10^(-X)))+1,1)+Ans
:End
:sub(Ans,1,length(Ans)-1?Str1
With our number stored in N, we loop through each digit of N and store
the numeric character to our string that is at the matching position
in our substring. You access the individual digit in the number by
using iPart(10fPart(A/10^(X, and then locate where it is in the string
"0123456789". The reason you need to add 1 is so that it works with
the 0 digit.
In order to construct a string with all of the digits of the number, we first create a dummy string. This is what the "? is used
for. Each time through the For( loop, we concatenate the string from
before (which is still stored in the Ans variable) to the next numeric
character that is found in N. Using Ans allows us to not have to use
another string variable, since Ans can act like a string and it gets
updated accordingly, and Ans is also faster than a string variable.
By the time we are done with the For( loop, all of our numeric characters are put together in Ans. However, because we stored a dummy
character to the string initially, we now need to remove it, which we
do by getting the substring from the first character to the second to
last character of the string. Finally, we store the string to a more
permanent variable (in this case, Str1) for future use.
Once converted to a string, you can simply use the + operator to concatenate your string literals with the converted number strings.
You should also take a look at a similar Stack Overflow question which addresses a similar issue.
For this issue you can use the toString( function which was introduced in version 5.2.0. This function translates a number to a string which you can use to display numbers and strings together easily. It would end up like this:
Disp "Hello "+toString(Y)+" World "+toString(X)
If you know the length of "Hello" and "World," then you can simply use Output() because Disp creates a new line after every statement.
Right now I am working on a project that issues IDs consisting of both letters and numbers, for example 345A22. I need this program to be able to tell that for example, 345B22 is greater than 345A22. I can't assume that the letters will be in the same position all the time (ie we do have some id's with 22335Q) but when I compare two numbers the letters will be in the same position.
How do I accomplish this in Ruby?
You can use the String#<=> method to compare strings. See documentation here.
>> "345B22" <=> "345A22"
=> 1
Where the 1 return value means that 345B22 is greater.
If a simple string comparison won't do the trick (e.g. different lengths, etc.), try converting the IDs (assuming they all match ^[0-9A-Z]*$) into integers by treating them as base36-encoded data.
In Ruby strings have the same comparison methods as numbers have.
2 > 1 #=> true
"2" > "1" #=> true
"B" > "A" #=> true
Not sure I understand your question, but I'm guessing that you mentally parse the ids into components (so 345B22 is 345, B, 22) and then are wishing for a numeric sort for things that are numbers (i.e., 12 > 2) and a string sort for things that are strings (AB < B).
If this is what you intend, something like the following would do the trick:
ids.sort_by do |id|
id.scan(/\d+|[a-zA-Z]+/).map {|c| c =~ /\d/ ? c.rjust(20) : c.ljust(20) }.join
end
What this does is extract out all consecutive numbers or letters and then justify them right or left based on their type, concatenates the result and then sorts based on this (expanded and canonicalized) id.
I'm just starting with "The Well-Grounded Rubyist", and they gave the following example:
print "Hello. Please enter a Celsius value: "
print "The Fahrenheit equivalent is ", gets.to_i * 9 / 5 + 32, ".\n"
In particular, I'm looking at line 2, where they seem to be using commas for string concatenation. I assume the + symbol isn't being used because of the + 32 portion of the code. However, can someone explain to me what the commas actually are doing?
The commas are argument separators. The print method can take any number of arguments and will print them in sequence. Any string concatenation (if any occurs here) would take place inside the print method itself.
The commas are delimiting the arguments to the print function.
Argument separators, i.e. print is called with three arguments.
-> irb
>> (Date.today +3).to_s
=> "2009-10-22"
>> (Date.today + 3).to_s
=> "2009-10-25"
between "+3" and "+ 3", there is a difference?
"+3" with no space means positive 3, which gets passed to the today method as an argument, while "+ 3" means plus three, so the return value of the today method gets added to 3.
In case you're curious, the optional parameter to the today method "specifies the Day of Calendar Reform", for conversions to other date formats.
I realize this must have been a frustrating bug to discover. When using a language where method invocation has optional parentheses, whitespace is a delicate matter. Consider the following:
square(2+2)*2 # square(4)*2 = 16*2 = 32
square (2+2)*2 # square(4*2) = square(8) = 64
Your case is trickier because the +3 with no space is actually a unary operator. ! ~ and + unary operators have the highest precedence.
Also interesting the - unary operator has a lower precedence than the exponentiation operator. Therefor
-4**2 # -(4**2) = -16
It seems to me that the + binds to the 3 in the first case. That is the interpreter sees Date.today(+3). If there's a space after the plus the interpreter instead sees (Date.today) + (3).
Using + to denote positive numbers isn't very common since numbers are positive to begin with, but consider the case of negative numbers: it's easier to see that Date.today -3 means something else than Date.today - 3.