I'm new to rails and I'm working on this project:
I have done a ruby script which needs an input and that prints some outputs.
Basically it takes the first n decimal digits of PI and then it calculates some stats.
I need to use a rails web app to insert the input, which is a number, and to print the decimal digits and 10 stats rows.
This is the ruby script
require 'bigdecimal/math'
#PI decimals generator
i = 0
j = 0
a_pi = Array.new
print "Insert how many digits do you want to calculate: "
dig_n = gets.chomp.to_i
x = BigMath.PI(dig_n)
a_pi = x.to_s.split('')
begin
a_pi.shift
i += 1
end until i == 3
arr_length = a_pi.length
begin
a_pi.pop
j += 1
end until j == arr_length - dig_n
pi_dec = a_pi.join.to_i
puts pi_dec
I'm using Ruby 2.6 and Rails 6
I think you are thinking about this the wrong way around. What you want is more "a web app/web form that does something with input". Rails might be too much for your use case. If you are not bound to Rails you might want to look into other / lighter web frameworks in ruby like Sinatra or Hanami. This could help: Run ruby script from a HTML form
Related
I want to generate 5 buttons with different values based on one integer.
For example I've got 30, I want to create buttons with 10 20 30 40 50
value = 30
int1 = value - 20
int2 = value - 10
int3 = value
int4 = value + 10
int5 = value + 20
buttoncode = ""
%w{int1 int2 int3 int4 int5}.each do |minutes|
buttoncode += 'buttoncode'
end
I can do it in a very bad way, but it could be done a smarter solution I guess.
Is it possible to make something like that?
%w{sum(max-20) sum(max-10) max sum(max+10) sum(max+20)}.each do |minutes|
end
See Ruby: How to iterate over a range, but in set increments?
So in your case it would be:
(min..max).step(10) do |n|
n += 'buttoncode'
end
By the way, this is not really Rails specific, but Ruby specific. Rails is a web framework that handles the interaction between browser and the web server that is built on top of Ruby.
If you feel like you aren't that up to speed with Ruby, try https://learnrubythehardway.org/book/ and do some exercise on HackerRank or ProjectEuler in Ruby.
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.
How do I turn "1.5k" into 1500 or "1,766" into "1766" with ruby or rails?
Thanks!
You can do it using ruby without rails.
n = "1,200.5k"
n = n.to_s.gsub(/,+/, '')
n = (n[-1] == 'k' ? n[0...-1].to_f * 1000 : n).to_i
puts n
As for the case "1.5k" you can write a quick method that, if the .to_i() fails, looks for a k as the last character. You can get the last character by doing num_str[-1, 1], where num_str is the original string.
For the other case, I would recommend looking into the money gem. num = Money.parse("1,766").
I'm trying to generate random data in my rails application.
But I am having a problem with decimal amount. I get an error
saying bad value for range.
while $start < $max
$donation = Donation.new(member: Member.all.sample, amount: [BigDecimal('5.00')...BigDecimal('200.00')].sample,
date_give: Random.date_between(:today...Date.civil(2010,9,11)).to_date,
donation_reason: ['tithes','offering','undisclosed','building-fund'].sample )
$donation.save
$start +=1
end
If you want a random decimal between two numbers, sample isn't the way to go. Instead, do something like this:
random_value = (200.0 - 5.0) * rand() + 5
Two other suggestions:
1. if you've implemented this, great, but it doesn't look standard Random.date_between(:today...Date.civil(2010,9,11)).to_date
2. $variable means a global variable in Ruby, so you probably don't want that.
UPDATE --- way to really get random date
require 'date'
def random_date_between(first, second)
number_of_days = (first - second).abs
[first, second].min + rand(number_of_days)
end
random_date_between(Date.today, Date.civil(2010,9,11))
=> #<Date: 2012-05-15 ((2456063j,0s,0n),+0s,2299161j)>
random_date_between(Date.today, Date.civil(2010,9,11))
=> #<Date: 2011-04-13 ((2455665j,0s,0n),+0s,2299161j)>
I've been at this for awhile. I am building a simple lottery website and I am generating random tickets. On my local machine random numbers are generated, however, on the server they are duplicated.
I have tried multiple versions of what I have, but the duplicates is the same.
I need to create a random ticket number per ticket and ensure that it hasn't bee created.
This my like 50th version:
a = Account.find(current_account)
numTics = params[:num_tickets].to_i
t = a.tickets.where(:item_id => item.id).count
total = t + numTics
if total > 5
left = 5 - t
flash[:message] = "The total amount of tickets you can purchase per item is five. You can purchase #{left} more tickets."
redirect_to buy_tickets_path(item.id)
else
i = 1
taken = []
random = Random.new
taken.push(random.rand(100.10000000000000))
code = 0
while i <= numTics do
while(true)
code = random.rand(100.10000000000000)
if !taken.include?(code)
taken.push(code)
if Ticket.exists?(:ticket_number => code) == false
a.tickets.build(
:item_id => item.id,
:ticket_number => code
)
a.save
break
end
code = 0
end
end
i = i + 1
end
session['item_name'] = item.name
price = item.price.to_i * 0.05
total = price * numTics
session['amount_due'] = total.to_i
redirect_to confirmation_path
end
You should be using SecureRandom if possible, not Random. It works the same way but is much more random and doesn't need to be initialized like Random does:
SecureRandom.random_number * 100.1
If you're using Ruby 1.8.7 you can try the ActiveSupport::SecureRandom equivalent.
Also if you're generating lottery tickets, you will want to make sure your generator is cryptographically secure. Generating random numbers alone is probably not sufficient. You will likely want to apply some other function to generate these.
Keep in mind that most actual lotteries do not generate random tickets at the point of purchase, but generate large batches in advance and then issue these to purchasers. This means you are able to preview the tickets and ensure they are sufficiently random.
The problem is not with Ruby's pseudo random number generator but that fact that you are creating generators all the time with Random.new. As explained in this answer, you should not have to call Random.new more than once. Store the result in a global object and you'll be good to go.