Reading lists from a file in Ruby - ruby

I have a txt file which contains data in the following format:
X1 Y1
X2 Y2
etc..
I want to read the data from this file and create two lists in ruby (X containing X1, X2 and Y containing Y1, Y2). How can I do this in Ruby?
Thanks.

A real one-liner:
x, y = File.foreach("filename").collect {|line| line.split}.transpose

Pseudocode
File.new("source.txt", "r").each_line do |line|
x, y = line.split
xs << x
ys << y
end
You might want to checkout the Rdoc for detail API.

I prefer using the readlines method for things such as this.
x = []
y = []
File.readlines(filename).each do |line|
x << line.split[0]
y << line.split[1]
end
As Mladen (from the comments of this answer) suggests, I am splitting it twice which is probably slower than assigning it to a variable and referencing that. He also mentions that using foreach is better than readlines, and I agree. Using their advice, this is how we would both go about doing it:
x = []
y = []
File.foreach(filename).each do |line|
line = line.split
x << line[0]
y << line[1]
end

Something like this if you have exactly two columns:
one = Array.new
two = Array.new
File.open("filename") do |file|
while line = file.gets
one << line.split[0]
two << line.split[1]
end
end

Related

is '#client command' or '#client event' with if statements more efficient (discord.py)

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 way I make a defined variable reset every time I use it?

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).

adequate solution to hand over variables in nested functions (in ruby)

I have several step_1-methods which are based on x and y variables.
step_2 creates new methods based on step_1-methods but the variables aren't needed (just passed through)!
The same goes for step_3 (based on step_2-methods).
My problem is I have about 20 step_2-methods which consists dozens of step_1-methods (5 differents kinds). And for each one I have to pass the same two variables.
I need this kind of construction for iteration purposes.
Now, is there a way to hand over the variables directly form step_3(x, y) to step_1 (x, y) without using global variables?
# example
def step_1 (x, y)
return x + y
end
def step_2 (*foo)
return step_1(*foo)
end
def step_3 (*foo)
return step_2(*foo)
end
x, y = 2, 2 # example
puts step_3(x, y) # ==> 4
Thanks for any suggestion
When I read "I have to pass the same two variables", this naturally brings to mind the idea of creating a simple container you can pass around instead:
class NumberTuple
attr_accessor :x
attr_accessor :y
def initialize(x, y)
#x = x
#y = y
end
end
tuple = NumberTuple.new(2,2)
step_3(tuple)
This often leads to the conclusion that creating a simple calculation class that can internalize all of this state. That's what class instances excel at:
class NumberCalculator
def initialize(x, y)
#x = x
#y = y
end
def step_3
step_2
end
def step_2
step_1
end
def step_1
#x + #y
end
end
calculator = NumberCalculator.new(2,2)
calculator.step_3
alias step_3 :step_1
or if you want to go through intermediate steps,
alias step_2 :step_1
alias step_3 :step_2

how to curry a method?

consider this code
def f x, y
x + y
end
g = lambda(&method(:f)).curry.(1)
g.(2) # => 3
the expression for g is too hard to read. Can it be simplified?
If you are using Ruby 2.2.0 or later, you can use Method#curry:
def f(x, y)
x + y
end
g = method(:f).curry[1]
p g[2] # => 3
I think the shortest (and most readable!) you can get is
g = method(:f).to_proc.curry[1]
g[2] # => 3

Ruby: Print un-printable data string

If I have a variable, x, that will sometime be a normal printable string, and sometimes be some random hex data (including unprintable chars), how can I reliably print that will space padding? ex:
def print(x)
puts("%-15s" % x)
end
x = "test"
print(x)
x = Array.new(256) { rand(256) }.pack('c*')
print(x)
def print(x)
puts "%-15s" % [x.inspect]
end
And if you want to get rid of the "...":
puts "%-15s" % [x.inspect[1..-2]]

Resources