Prime Number - Data while loading - ruby-on-rails

I was trying in Ruby on Rails how to find a prime number. Here is my code :
helper : app/helpers/test_helper.rb
module TestHelper
def prime_number? number
index = 2
tmp = 0
while index <= number
if tmp < 1
if (number % index) == 0
tmp += 1
end
else
return false
end
index += 1
end
return true
end
end
and my view : app/views/test/index.html.erb
<% (2..100).each do |i| -%>
<% if prime_number? i %>
<%= i %>
<% end -%>
<% end -%>
So my question is : How can you load data while it's calculating ? I mean if I replace 100 by 100000 in my view, how can I see data on my view while my helper method is calculating ?
Do I need to use ajax or rails provide a tool for that ?
Thank you.

Short answer: yes, you'll need AJAX.
Longer answer: you can use the Prototype Helper periodically_call_remote to poll one of your actions and add new prime numbers to the end of the list.
There is an issue though, Ruby is very slow compared to native OS languages such as C. If you want to get the most prime number results, I'd write the prime number code in C and find a mechanism to access the results. One way to do that would be to have your C application write prime numbers to a file and you can tail -f that file to get the new primes. I'm sure you can find a C example for finding prime numbers somewhere.
Even if you were to write the prime number code in Ruby, you'd have to run it as a separate process from your Rails application for it to continually calculate primes, so you might as well do it in something faster. Actually, Ruby might not be too terribly slow for this calculation, it'd be interesting to benchmark the two.

Related

Rails batch convert one object to another object

I am looking for the most efficient way (in speed) to converts a huge number of objects (1M instances) to another object type.
Unfortunately I don't have the choice of what I am getting as an input (the million object).
So far I've tried with each_slice but it does not show much improvement when it comes to speed!
It looks like this:
expected_objects_of_type_2 = []
huge_array.each_slice(3000) do |batch|
batch.each do |object_type_1|
expected_objects_of_type_2 << NewType2.new(object_type_1)
end
end
Any idea?
Thanks!
I did a quick test with a few different methods of looping the array and measured the timings:
huge_array = Array.new(10000000){rand(1..1000)}
a = Time.now
string_array = huge_array.map{|x| x.to_s}
b = Time.now
puts b-a
Same with:
sa = []
huge_array.each do |x|
sa << x.to_s
end
and
sa = []
huge_array.each_slice(3000) do |batch|
batch.each do |x|
sa << x.to_s
end
end
No idea what you are converting so I did a bit of simple int to string.
Timings
Map: 1.7
Each: 2.3
Slice: 3.2
So apparently your slice overhead makes things slower. Map seems to be the fastest (which is internally just a for loop but with a non-dynamic length array as output). The << seems to slow things down a bit.
So if each object needs an individual converting you are stuck with O(n) complexity and can't speed things up by a lot. Just avaid overhead.
Depending on your data, sorting and exploiting caching effects might help or avoiding duplicates if you have a lot of identical data but we have no way to know if we don't know your actual conversions.
I would treat each slice in its own thread:
huge_array.each_slice(3000) do |batch|
Thread.new do
batch.each do |object_type_1|
expected_objects_of_type_2 << NewType2.new(object_type_1)
end
end
end
Then you have to wait for the threads to terminate using join. They should be accumulated in an array and joined.

Lua - generate sequence of numbers

How do I generate a sequence of integer numbers based on first and last number for for to loop over?
The following pseudocode
for i in sequence(4,9) do
print(i)
end
should produce the following output
4
5
6
7
8
9
Please include a short explanation what the solution does in the background and what terminology would have allowed one to find the solution.
Search attempts lead to unsearchable huge pages of documentation.
You can use numeric for loop to do that. You will find details in Programming in Lua section I referenced or the Lua manual section on For statement.
Just for the full record, there are basically 3 ways you could do this loop, one with a slightly different syntax, and 2 with the exact syntax as your pseudocode. Links point to relevant chapters in Programming in Lua (which is a great book to read, by the way).
1) Using a simple numeric for loop - in this case you won't use sequence:
for i=4,9 do
print(i)
end
2) Implement sequence as a closure:
function sequence(from,to)
local i = from - 1
return function()
if i < to then
i = i + 1
return i
end
end
end
for i in sequence(4,9) do print(i) end
3) Implement sequence as a coroutine:
function sequence(from, to)
return coroutine.wrap(function()
for i=from,to do
coroutine.yield(i)
end
end)
end
for i in sequence(4,9) do print(i) end

How to dividie entries into different pages in Rails?

For example, I have 30 entries, and I wish to divide them so that it only displays 3 of them on each page (and having many pages of course).
Currently, I have implemented it by passing a parameter in the URL and writing Ruby code in the action.
x = params[:id]
if x
#problems = []
x = params[:id].to_i
t = Problem.all.count
i = 1
problem_numbers = -3 * (x - 1)
while t > 0 do
if Problem.exists?(i)
problem_numbers += 1
t -= 1
if problem_numbers > 0
#problems = #problems + [Problem.find(i)]
end
end
if problem_numbers == 3
break
end
i += 1
end
end
It works quite well, but I think this piece of code might a bit complicated for such a feature; also if there are many entries, visiting pages would be slow because I counted through all the entries.
Is there a more convenient way to do this? Thanks in advance.
Displaying items across multiple pages is called pagination. will_paginate and Kaminari are two very popular gems that provide this functionality in a way that is very easily integrated into Ruby on Rails applications.

What's the difference between these two LUA scripts?

local times=0
function rTA(v)
times=times+1
if times % 3 <= 0 then
print(v)
end
end
or
local times=0
function rTA(v)
times=times+1
if times == 3 then
print(v)
times=0
end
end
rTA("N1")
rTA("N2")
rTA("N3")
rTA("N4")
rTA("N5")
rTA("N6")
rTA("N7")
rTA("N8")
rTA("N9")
They both return the same output (N3, N6, N9), but I can't seem to understand the difference in both of them..
As pointed out both are checking if "times" is multiple of 3, although the first version is a little more "elegant" it costs more in terms of processing. The second is a little less readable in terms of meaning (you can understand that it is trying to check for multiples of 3, but it is not a first sight thing, you have to think for a moment).
Cheers

How to read a file from bottom to top in Ruby?

I've been working on a log viewer for a Rails app and have found that I need to read around 200 lines of a log file from bottom to top instead of the default top to bottom.
Log files can get quite large, so I've already tried and ruled out the IO.readlines("log_file.log")[-200..-1] method.
Are there any other ways to go about reading a file backwards in Ruby without the need for a plugin or gem?
The only correct way to do this that also works on enormous files is to read n bytes at a time from the end until you have the number of lines that you want. This is essentially how Unix tail works.
An example implementation of IO#tail(n), which returns the last n lines as an Array:
class IO
TAIL_BUF_LENGTH = 1 << 16
def tail(n)
return [] if n < 1
seek -TAIL_BUF_LENGTH, SEEK_END
buf = ""
while buf.count("\n") <= n
buf = read(TAIL_BUF_LENGTH) + buf
seek 2 * -TAIL_BUF_LENGTH, SEEK_CUR
end
buf.split("\n")[-n..-1]
end
end
The implementation is a little naive, but a quick benchmark shows what a ridiculous difference this simple implementation can already make (tested with a ~25MB file generated with yes > yes.txt):
user system total real
f.readlines[-200..-1] 7.150000 1.150000 8.300000 ( 8.297671)
f.tail(200) 0.000000 0.000000 0.000000 ( 0.000367)
The benchmark code:
require "benchmark"
FILE = "yes.txt"
Benchmark.bmbm do |b|
b.report "f.readlines[-200..-1]" do
File.open(FILE) do |f|
f.readlines[-200..-1]
end
end
b.report "f.tail(200)" do
File.open(FILE) do |f|
f.tail(200)
end
end
end
Of course, other implementations already exist. I haven't tried any, so I cannot tell you which is best.
There's a module Elif available (a port of Perl's File::ReadBackwards) which does efficient line-by-line backwards reading of files.
Since I'm too new to comment on molf awesome answer I have to post it as a separate answer.
I needed this feature to read log files while they're written , and the last portion of the logs contain the string I need to know it's done and I can start parsing it.
Hence handling small sized files is crucial for me (I might ping the log while it's tiny).
So I enhanced molf code:
class IO
def tail(n)
return [] if n < 1
if File.size(self) < ( 1 << 16 )
tail_buf_length = File.size(self)
return self.readlines.reverse[0..n-1]
else
tail_buf_length = 1 << 16
end
self.seek(-tail_buf_length,IO::SEEK_END)
out = ""
count = 0
while count <= n
buf = self.read( tail_buf_length )
count += buf.count("\n")
out += buf
# 2 * since the pointer is a the end , of the previous iteration
self.seek(2 * -tail_buf_length,IO::SEEK_CUR)
end
return out.split("\n")[-n..-1]
end
end

Resources