Consider the following code:
x = 4
y = 5
z = (y + x)
puts z
As you'd expect, the output is 9. If you introduce a newline:
x = 4
y = 5
z = y
+ x
puts z
Then it outputs 5. This makes sense, because it's interpreted as two separate statements (z = y and +x).
However, I don't understand how it works when you have a newline within parentheses:
x = 4
y = 5
z = (y
+ x)
puts z
The output is 4. Why?
(Disclaimer: I'm not a Ruby programmer at all. This is just a wild guess.)
With parens, you get z being assigned the value of
y
+x
Which evaluates to the value of the last statement executed.
End the line with \ in order to continue the expression on the next line. This gives the proper output:
x = 4
y = 5
z = (y \
+ x)
puts z
outputs 9
I don't know why the result is unexpected without escaping the newline. I just learned never to do that.
Well you won't need the escaping character \ if your lines finishes with the operator
a = 4
b = 5
z = a +
b
puts z
# => 9
Related
Just a quick question which I cannot find the answer too.
which piece of code is more efficient/faster
this:
#client.event
async def message(message):
if message.content == 'x':
await message.channel.send('y')
or this:
#client.command()
async def x(ctx):
await ctx.send('y')
syntax might be a little off for the client.command() part, I have only used client.event method so far.
Before answering, it's important to understand, on_message is the base of commands extension.
What it does is
commands = {} # example dictionary
#bot.command() # this registers the function in the command dictionary
async def test(ctx: commands.Context):
# some code here
# after this line is executed, your commands dictionary would look somethig like
# commands = {'test': test} (here, test is coroutine function you made)
on_message looks for a message.content, if it starts with the prefix, it gets the message without the prefix, then checks if the command called is in the dictionary, if yes, then call the command on that part with the arguments provided. If not, raise commands.CommandsNotFound
The above on_message I spoke about is the default on_message event bound to the bot. This is also a reason why commands extension doesn't work if one overrides the on_message event
Now with that out of the way, python dictionaries are implemented as hash tables. If the amount of if else staement is less then yes, they might be equally performative but in the longer run, dictionary lookup will prevail. Thus, I would say the commands extesnion is better to use.
In addition to the long run benefit, commands extension offers a much better way to manage your code.
if x == "test":
s = 1
y = 1
j = 1
print(s, y, z)
elif x == "test2":
s = 2
y = 2
j = 2
print(s, y, z)
elif x == "test3":
s = 3
y = 3
j = 3
print(s, y, z)
elif x == "test4":
s = 4
y = 4
j = 4
print(s, y, z)
elif x == "test5":
s = 5
y = 5
j = 5
print(s, y, z)
is certainly not appealing comapred to
def test1():
s = 1
y = 1
j = 1
print(s, y, z)
def test2():
s = 2
y = 2
j = 2
print(s, y, z)
def test3():
s = 3
y = 3
j = 3
print(s, y, z)
def test4():
s = 4
y = 4
j = 4
print(s, y, z)
def test5():
s = 5
y = 5
j = 5
print(s, y, z)
And it's also much easier to navigate and maintain your code with the command extension!
So, there is no reason for anyone to use if else in on_message to create commands when given a superior choice, i.e commands extesnion
Is there a less verbose way to compare three integer values in Ruby?
For example, in Python the following return True:
x = 2
y = 3
z = 4
x < y < z
With the same variable bindings in Ruby the following will both return true:
x < y && y < z
x.send(:<, y) && y.send(:<, z)
but this:
x < y < z
returns NoMethodError:
NoMethodError: undefined method `<' for true:TrueClass
I presume this is because the first comparison of x < y evaluates to true and the error is raised from the resulting TrueClass.instance < z? Is there a way in Ruby to compare three integer values without the use of &&?
Thank you.
You can write
(x+1...z).cover? y
or (my preference)
(x+1..z-1).cover? y
Because x, y and z are numeric, this is the same as
(x+1..z-1).include? y
See Range#cover? and Range#include?.
I'd like to write a conditional lambda in Ruby. The Python equivalent of what I'd like to write is:
even = (lambda x: x if x % 2 == 0 else 0)
My attempt to write this in Ruby looks like:
even = -> (x) {x if x % 2 == 0 else 0}
Unfortunately, that does not work. Is there any way to fix this?
You have several options here to express this. The long-form is this:
if (x % 2 == 0)
x
else
0
end
Note that a trailing if or unless cannot have a secondary condition like else. You need to use the full form.
If you want a short version, you use the ternary operator:
(x % 2 == 0) ? x : 0
What you could also do is this:
(x % 2 == 0) and x or 0
As others have observed there's a method called even? which does the modulo for you, so that can collapse this further:
x.even? ? x : 0
Ruby's ternary operator has this syntax
x % 2 == 0 ? x : 0
You don't even need a conditional.
p = ->(x) { x*(1-x%2) }
p.call(4) #=> 4
p.call(5) #=> 0
Note procs can be called in multiple ways:
p[4] #=> 4
p.(4) #=> 4
p.yield(4) #=> 4
p === 4 #=> 4
p(4) #=> 4
The last of these may be archaic.
Wrong syntax. You can write it like this:
even = -> (x) {if x % 2 == 0; x; else; 0; end}
However, for such one-liners, it is more common to use the ternary ?: operator, as other have suggested in this thread.
Your syntax is wrong:
The then-block comes after the condition, not before it.
The then-block is separated from the condition by the then keyword, a semicolon, or a newline.
The conditional expression is terminated with an end keyword.
So, any of the following is valid:
# idiomatic:
if x % 2 == 0 then x else 0 end
# idiomatic:
if x % 2 == 0
x
else
0
end
# non-idiomatic:
if x % 2 == 0; x else 0 end
# non-idiomatic:
if x % 2 == 0 then
x
else
0
end
# non-idiomatic:
if x % 2 == 0
x else 0 end
# … and many other non-idiomatic variations
Ruby also has a conditional operator:
x % 2 ? x : 0
But I personally find it ugly and unreadable. It also has different precedence than the conditional expression, which may be surprising to some. (Witness the myriad of variations of the same question about the conditional operator here on StackOverflow.) And it is completely unnecessary: in C, where if is a conditional statement, the conditional operator is required because it is an expression. In Ruby, everything is an expression anyway, there are no statements, so of course if is an expression, too.
This is the code
x = 10
y = 11
def z(q,x,y)
q = q - (x + y)
end
q = 30
z(q,x,y)
puts "#{q}"
q = 40
z(q,x,y)
puts "#{q}"
Is there a way that z(q,x,y) would reset every time I use it?
Try this:
x = 10
y = 11
def z(q,x,y)
q = q - (x + y)
end
q = 30
z1 = z(q,x,y)
puts "#{z1}"
q = 40
z2 = z(q,x,y)
puts "#{z2}"
prints (using puts):
9
19
Generally, you shouldn't modify params. In function z, q is a parameter that's been set but I think you are also wanting it to be an outside variable and mutate its state.
Here's what you want to do but please do not do this.
x = 10
y = 11
def z(q,x,y)
$q = q - (x + y)
end
$q = 30
z($q,x,y)
puts "#{$q}"
$q = 40
z($q,x,y)
puts "#{$q}"
# Prints:
# 9
# 19
This is probably bad code. Why? Globals are bad. Mutating state like this when we are blessed to have a mathematical function so pure like this is a war crime and might cause rioting. We have a math function that doesn't need to change state. We don't really want z to be responsible for:
computing a new value
setting a local variable for use later
The second part is the damning part. Z knows about its outside world when it doesn't need to.
Look at this which is similar to the other answer already here:
x = 10
y = 11
def z(q, x, y)
q - (x + y)
end
q = z(30, x, y)
puts q
q = z(40, x, y)
puts q
If you are starting out with Ruby or programming in general, read a lot of code and watch screencasts of people working live. It's the fastest route to leveling up a little bit. It's ok if it doesn't happen right away, the next time you try will be easier (years later maybe).
Given an integer - say, x=20, I'd like to convert this into a string containing its escaped octal character. I.e. ...
x=20
# y = ... Some magic
p y # => "\024"
The closest I've managed to get is by using:
x.to_s(8) # => "24"
However, I'm completely stumpted on how to convert this string into an escaped octal character! Any ideas, internet?
Just use Kernel#sprintf to format the number.
Like this
x = 20
y = sprintf('\%03o', x)
puts y
output
\024
Update
Maybe I misunderstood you. If you just want a character with the given code point then just use Integer#chr.
Like this
x = 20
y = x.chr
p y
output
"\x14"
You could use Array#pack:
[20].pack("C") #=> "\x14"
x = 20
y = '\%03o' % x
puts y
If you use p to display y you would see 2 backslashes as p outputs ruby parsable strings.