How to have an ouput without symbols and quotations etc. in Ruby - ruby-on-rails

In this particular code when the input[0] = "status", I want the output to remove the symbols "" [] and , but I can't seem to find the solution, I've tried using each but I think what I'm doing is wrong, and I'm new to Ruby please help. Thanks!
class Main
puts "Welcome to the automated Parking Lot"
start = true
parking_lot = []
allocated_slot = 0
slot_number = 0
plate_number = ""
color = ""
x = ""
while (start == true) do
parking = Array.new
input = gets.split(' ')
case input[0]
when input[0] = "create_parking_lot"
parking_lot.clear
allocated_slot = input[1]
puts "Created a parking lot with #{allocated_slot} slots."
when input[0] = "park"
plate_number = input[1]
color = input[2]
if parking_lot.length < allocated_slot.to_i
slot_number = slot_number + 1
parking = [slot_number, input[1], input[2]]
parking_lot.push(parking)
parking_lot.sort!
puts "Allocated slot number: #{slot_number}"
else
puts "Sorry, parking lot is full"
end
when input[0] = "leave"
slot_number = input[1].to_i
puts "Slot number #{slot_number} is now free."
slot_number = slot_number - 1
parking_lot.delete_at(slot_number)
parking_lot[slot_number]
#puts parking_lot
when input[0] = "quit"
break
when input[0] = "status"
if parking_lot.count == 0
puts "No cars are parked."
else
puts "Slot No. Registration No. Color"
parking.sort!
i = 0
y = ""
while i < allocated_slot.to_i do
x = parking_lot[i].to_s
y = x.split(' ')
puts "#{y[0]} #{y[1]} #{y[2]}" #
#y.each { |a| print a, " " }
i = i+1
end
end
when input[0] = "registration_numbers_for_cars_with_color"
puts "registration number for cars"
when input[0] = "slot_numbers_for_cars_with_color"
puts "slot number for cars with color"
when input[0] = "slot_number_for_registration_number"
puts "slot number for registration number"
when input[0] = "check"
puts parking_lot
else
puts "Command Error"
end
end
and the output goes like this:
[1, "HA-312424242", "Green"]

If you have an array being outputted that looks like this:
[1, "HA-312424242", "Green"]
Then you can call the join method on it like this:
[1, "HA-312424242", "Green"].join(' ')
and it will produce:
"1 HA-312424242 Green"

Related

How to not allowed taking in a number into a variable in Ruby

Given a string S of length N that is indexed from 0 to N-1 , print its even-indexed and odd-indexed characters as space-separated strings on a single line (see the Sample below for more detail).
Sample Input:
2
Hacker
Rank
Sample output:
Hce akr
Rn ak
explanation:
S="Hacker" S[0]="H", S[1]="a", S[2]= "c", S[3]="k", S[4]="e", S[5]="r"
However, with the following code I haven't been able to complete the challenge. How do I constraint taken input as an integer?
S = gets.chomp.chars.to_a
for i in 0..S.length
if i%2 == 0
s1 = S[i]
else
s2 = S[i]
end
end
puts s1.to_s + " " + s2.to_s
Code
def doit(str)
str.each_char.each_slice(2).with_object(['','']) do |(c_even, c_odd), (s_even, s_odd)|
s_even << c_even
s_odd << c_odd unless c_odd.nil?
end.join(' ')
end
Examples
doit "abracadabra"
#=> "arcdba baaar"
doit "Jack be nimble, Jack be quick"
#=> "Jc enml,Jc eqik akb ibe akb uc"
Explanation
For
str = "abracadabra"
enum0 = str.each_char
#=> #<Enumerator: "abracadabra":each_char>
We can convert the enumerator enum0 to an array to see what values it will generate:
enum0.to_a
#=> ["a", "b", "r", "a", "c", "a", "d", "a", "b", "r", "a"]
enum1 = enum0.each_slice(2)
#=> #<Enumerator: #<Enumerator: "abracadabra":each_char>:each_slice(2)>
enum1.to_a
#=> [["a", "b"], ["r", "a"], ["c", "a"], ["d", "a"], ["b", "r"], ["a"]]
enum2 = enum1.with_object(['',''])
#=> #<Enumerator: #<Enumerator: #<Enumerator: "abracadabra":each_char>:each_slice(2)>
# :with_object(["", ""])>
enum2.to_a
#=> [[["a", "b"], ["", ""]], [["r", "a"], ["", ""]], [["c", "a"], ["", ""]],
# [["d", "a"], ["", ""]], [["b", "r"], ["", ""]], [["a"], ["", ""]]]
If you examine the return values obtained when constructing enum1 and enum2, you will see that they can be thought of as "compound" enunerators.
The first element of enum2 is generated and passed to the block, assigning values to the four block variables1:
(c_even, c_odd), (s_even, s_odd) = enum2.next
#=> [["a", "b"], ["", ""]]
c_even #=> "a"
c_odd #=> "b"
s_even #=> ""
s_odd #=> ""
The block calculation is now performed.
s_even << c_even
#=> "a"
s_odd << c_odd unless c_odd.nil?
# s_odd << c_odd unless false
# s_odd << c_odd
#=> "b"
The return values "a" and "b" are the new values of s_even and s_odd, respectively.
Now the next element of enum_2 is generated, passed to the block and the block calculations are performed:
(c_even, c_odd), (s_even, s_odd) = enum2.next
#=> [["r", "a"], ["a", "b"]]
s_even << c_even
# "a" << "r"
#=> "ar"
s_odd << c_odd unless c_odd.nil?
# s_odd << c_odd unless "a".nil?
# s_odd << c_odd
#=> "ba"
Calculations continue in this way until the last value of enum2 is generated: ["a"]. This has the effect of assigning nil to c_odd, so the second line of the block is not executed2. Lastly, the array of two strings is joined with a separating space.
Another way
def doit(str)
str.each_char.with_index.with_object(' ') { |(c,i),s|
s.insert(i.even? ? s.index(' ') : s.size, c) }
end
doit "abracadabra"
#=> "arcdba baaar"
1 The following expression employs parallel assignment (sometimes called multiple assignment) and disambiguation (sometimes referred to as decomposition) to assign values to the variables.
2 The second line could alternatively be written s_odd << c_odd.to_s or s_odd << c_odd || ''.
First input should be treated as an integer (namely, the amount of following strings to come):
amount = gets.to_i
Now we are to get amount strings and do our job (using Enumerable#partition):
amount.times do
input = gets.chomp
puts (input.split('').partition.with_index do |_, i|
i.even?
end.map(&:join).join(' '))
end
Note that instead of inspecting each character's index, you could also use scan:
'Hacker'.scan(/(.)(.?)/) #=> [["H", "a"], ["c", "k"], ["e", "r"]]
.transpose #=> [["H", "c", "e"], ["a", "k", "r"]]
.map(&:join) #=> ["Hce", "akr"]
.join(' ') #=> "Hce akr"
Or, using temporary variables:
s1 = ''
s2 = ''
'Hacker'.scan(/(.)(.?)/) { |a, b| s1 << a ; s2 << b }
puts "#{s1} #{s2}"
Here is the basic algorithm that would take O(n).
tests = gets.to_i
# run the loop for number of tests given
tests.times do
string = gets.chomp # sanitize string from input, i.e. removes \n \r
s_length = string.length # String length N
new_string = " " * s_length # create of string of length N
even_index = 0 # because evens are going to come first
odd_index = s_length - (s_length/2) + 1 # odds are going to start where even numbers end + 1
0.upto(s_length-1) do |i|
if i%2 == 0
new_string[even_index] = string[i]
even_index += 1
elsif
new_string[odd_index] = string[i]
odd_index += 1
end
end
puts new_string
end
Benchmark:
require 'benchmark'
def using_ugly_algo(tests, string)
# tests = gets.to_i
tests.times do
string = string
s_length = string.length # String length N
new_string = " " * s_length # creat of string of length N
even_index = 0
odd_index = s_length - (s_length/2) + 1
0.upto(s_length-1) do |i|
if i%2 == 0
new_string[even_index] = string[i]
even_index += 1
elsif
new_string[odd_index] = string[i]
odd_index += 1
end
end
# new_string
end
end
def with_partition(amount, string)
amount.times do
input = string
(input.split('').partition.with_index do |_, i|
i.even?
end.map(&:join).join(' '))
end
end
n = 10_000
string = (0...500).map { ('a'..'z').to_a[rand(26)] }.join
Benchmark.bmbm(100) do |x|
x.report("using_ugly_algo "){ n.times { using_ugly_algo(5, string) } }
x.report("with_partition "){ n.times { with_partition(5, string) } }
end
Report:
Rehearsal ----------------------------------------------------------------------------------------------------------------------------------------
using_ugly_algo 13.790000 0.030000 13.820000 ( 13.843560)
with_partition 16.790000 0.030000 16.820000 ( 16.830992)
------------------------------------------------------------------------------------------------------------------------------ total: 30.640000sec
user system total real
using_ugly_algo 13.930000 0.060000 13.990000 ( 14.070378)
with_partition 18.640000 0.210000 18.850000 ( 19.392816)
Well, the problem you are having is, if I am using the right term, a usage error. Your code is setting s1 and s2 to whatever the last checked letter is instead of concatenating. Modifying you code, I suppose what you are looking for is something like this:
S = gets.chomp.chars.to_a
s1 = ""
s2 = ""
for i in 0...S.length
if i%2 == 0
s1.concat(S[i])
else
s2.concat(S[i])
end
end
puts s1.to_s + " " + s2.to_s

Error with virtual tree program ruby

I have just started learning ruby and have made this program following a tutorial.
I keep getting an error when trying to run and can't find an answer.
The program is suppose to be able to pick fruit, count the fruit, give the height and grow.
C:\Sites\testfolder>ruby orangetree.rb
orangetree.rb:2:in `initialize': wrong number of arguments (1 for 0) (ArgumentEr
ror)
from orangetree.rb:51:in `new'
from orangetree.rb:51:in `<class:OrangeTree>'
from orangetree.rb:1:in `<main>'
C:\Sites\testfolder>
Here is the program
class OrangeTree
def initialize
#age = 0
#tall = 0
#fruit = 0
puts 'You have planted a new tree!'
def height
puts 'The tree is ' + #tall.to_s + 'foot tall.'
end
def pickAFruit
if #fruit <= 1
puts 'There is not enough fruit to pick this year.'
else
puts 'You pick an orange from the tree.'
#fruit = #fruit - 1
end
end
def countOranges
puts 'The tree has ' + #fruit.to_s + 'pieces of fruit'
end
def oneYearPasses
#age = #age + 1
#tall = #tall + 3
#fruit = 0
if dead?
puts 'The Orange Tree Dies'
exit
end
if #age > 2
#fruit = #age*10
else
#fruit = 0
end
end
private
def dead?
#age > 5
end
end
tree = OrangeTree.new 'tree'
command = ''
while command != 'exit'
puts 'please enter a command for the virual tree'
command = gets.chomp
if command == 'tree height'
tree.height
elsif command == 'pick fruit'
tree.pickAFruit
elsif command == 'wait'
tree.oneYearPasses
elsif command == 'count fruit'
tree.countOranges
elsif command == 'exit'
exit
else
puts 'Cant understand your command, try again'
end
end
end
Can anybody help?
You have some syntax errors. I have fixed them below. The syntax errors were:
You had an extra end on the last line (for closing the class declaration)
You were passing an argument to OrangeTree.new ("tree") that was unexpected. This is what the wrong number of arguments (1 for 0) error message in your question is referring to.
You were missing an end to close your initialize method declaration (after the puts 'You have planted a new tree!' line)
I have also fixed the indentation, which makes the code more readable and much easier to spot syntax errors like this.
class OrangeTree
def initialize
#age = 0
#tall = 0
#fruit = 0
puts 'You have planted a new tree!'
end
def height
puts 'The tree is ' + #tall.to_s + 'foot tall.'
end
def pickAFruit
if #fruit <= 1
puts 'There is not enough fruit to pick this year.'
else
puts 'You pick an orange from the tree.'
#fruit = #fruit - 1
end
end
def countOranges
puts 'The tree has ' + #fruit.to_s + 'pieces of fruit'
end
def oneYearPasses
#age = #age + 1
#tall = #tall + 3
#fruit = 0
if dead?
puts 'The Orange Tree Dies'
exit
end
if #age > 2
#fruit = #age*10
else
#fruit = 0
end
end
private
def dead?
#age > 5
end
end
tree = OrangeTree.new
command = ''
while command != 'exit'
puts 'please enter a command for the virual tree'
command = gets.chomp
if command == 'tree height'
tree.height
elsif command == 'pick fruit'
tree.pickAFruit
elsif command == 'wait'
tree.oneYearPasses
elsif command == 'count fruit'
tree.countOranges
elsif command == 'exit'
exit
else
puts 'Cant understand your command, try again'
end
end

Array not returning most frequent value

def most_common_letter(string)
letter = nil
final_letter = nil
letter_count = nil
idx1 = 0
idx2 = 0
count = 0
while idx1 < string.length
letter = string[idx1]
while idx2 < string.length
if letter == string[idx2]
count += 1
end
idx2 += 1
end
if (letter_count == nil) || (count > letter_count)
letter_count = count
final_letter = letter
end
idx1 += 1
end
arr = []
arr.push(final_letter)
arr.push(letter_count)
return arr
end
puts(most_common_letter("abbab") == ["b", 3])
#should be true
Keep getting [a,2] which leads me to believe it is only executing parts of the code when in my mind the code should be resetting the value of final letter and letter count every time there is a more frequent letter. Where have I gone wrong?
Often a counting hash is used for this type of problem:
def most_frequent_letter(str)
str.each_char.with_object(Hash.new(0)) { |c,h| h[c] += 1 }.max_by(&:last)
end
most_frequent_letter("bananas are so-so")
#=> ["a",4]
The steps:
h = "bananas are so-so".each_char.with_object(Hash.new(0)) { |c,h| h[c] += 1 }
#=> {"b"=>1, "a"=>4, "n"=>2, "s"=>3, " "=>2, "r"=>1, "e"=>1, "o"=>2, "-"=>1}
h.max_by(&:last)
#=> ["a",4]
Here is an easier way to solve this:
def most_common_letter(string)
letters = string.split('').sort!
frequency = letters.inject(Hash.new(0)) { |h,v| h[v] += 1; h }
frequency.max_by{|k,v| v}
end
most_common_letter("abbab")
=> ["b", 3]
Let me go through this code line-by-line to explain.
1) Get the letters of the string and sort them alphabetically:
string = "abbab"
letters = string.split('').sort!
=> ["a", "a", "b", "b", "b"]
2) Create a hash with keys (letters) and values (occurrence)
frequency = letters.inject(Hash.new(0)) { |h,v| h[v] += 1; h }
=> {"a"=>2, "b"=>3}
3) Find the highest value, and return the key value pair as an array.
frequency.max_by{|k,v| v}
=> ["b", 3]
The problem you are running into is that you are not resetting your idx2 after the loop.
You can debug this if you puts the idx two as follows:
def most_common_letter(string)
letter = nil
final_letter = nil
letter_count = nil
idx1 = 0
idx2 = 0
count = 0
while idx1 < string.length
letter = string[idx1]
while idx2 < string.length
if letter == string[idx2]
count += 1
end
idx2 += 1
end
puts "#{idx2}" #=> This is always 5
if (letter_count == nil) || (count > letter_count)
letter_count = count
final_letter = letter
end
idx1 += 1
end
arr = []
arr.push(final_letter)
arr.push(letter_count)
return arr
end
puts(most_common_letter("abbab"))
Your algorithm is simply doing the following:
comparing idx1 with idx2:
str[0] with str[0]
str[0] with str[1]
str[0] with str[2]
str[0] with str[3]
str[0] with str[4]
then idx2 is out of range and will never satisfy idx2 < string.length again, because the value is not reset.
This is where the logical error is. I won't give you another solution because it seems like you are trying to figure this out on your own. Hope this helps.
Try this
def most_common_letter(str)
str.chars.
group_by{|v| v}.
map{|k, l| [k, l.size]}.
sort_by{|k, size| size}.
last
end
Now:
puts(most_common_letter("abbab") == ["b", 3])
# true

After a process why Memory continuously stay up in Ruby?

I'm using Rails 4 with Ruby 2.1.0. I have a code which taking about 2 GB of memory to complete process, but problem is after finish process...why is memory usage still up?
I also assign nil to variable after used which save 300 MB but still large amount of memory using by Ruby process.
Here is sample code to reproduce the problem:
def download_data(params, options = {})
$file_name = ''
portfolio_names = Portfolio.get_names
building_names = Building.get_names
tenant_names = Tenant.get_names
meter_names = Meter.get_meter_names
#portfolio_info, #building_info, #tenant_info, #meter_id, #from_date, #to_date = params[:portfolio_name], params[:building_name], params[:tenant_name], params[:meter_id], params[:from_date], params[:to_date]
#from_date = DateTime.parse(#from_date).to_i
#to_date = DateTime.parse(#to_date).to_i
#building_f_name = building_names["#{#building_info}"]
unless params[:fields].nil?
#fields = params[:fields].split('_')
#columns = []
#fields.each do |f|
if f.length > 0
#columns << MeterData.new.show_real_value_of_meter_data_field_revert(f).to_sym
end
end
#columns << 'date_time'.to_sym
#columns << 'tenant'.to_sym
#columns << 'meter_id'.to_sym
else
#columns = [:id, :date_time, :w3pht, :whintvlrec, :w__3phmaxavgdmd, :tenant, :meter_id]
end
#### database fetch ###########
#meter_data = MeterData.find_by_sql("SELECT tenant, meter_id, SUM(van) as van, SUM(vbn) as vbn,
SUM(vcn) as vcn, SUM(ia) as ia, SUM(ib) as ib, SUM(ic) as ic,
SUM(w3pht) as w3pht, SUM(pf3pht) as pf3pht, SUM(f) as f,
SUM(whrec) as whrec, SUM(whtot) as whtot, SUM(varhrec) as varhrec,
SUM(varhtot) as varhtot, SUM(whintvlrec) as whintvlrec,
SUM(whintvldel) as whintvldel, SUM(w__phavg) as w__phavg,
SUM(var__3phavg) as var__3phavg, SUM(w_3phavg) as w_3phavg,
SUM(var_3phavg) as var_3phavg, SUM(phai) as phai, SUM(phbi) as phbi,
SUM(phci) as phci, SUM(w__3phmaxavgdmd) as w__3phmaxavgdmd,
MAX(w__3phmaxavgdmd) as w__3phmaxavgdmd_max, SUM(var__3phmaxavgdmd) as var__3phmaxavgdmd,
SUM(w_3phmaxavgdmd) as w_3phmaxavgdmd, SUM(var_3phmaxavgdmd) as var_3phmaxavgdmd,
date_time FROM `meter_data` WHERE (`date_time_i` >= #{#from_date} AND `date_time_i` <= #{#to_date}
AND building = '#{#building_info}') GROUP by tenant, meter_id, date_time
ORDER BY `meter_data`.`date_time_i` ASC")
sleep 0.5
#meter_sum = MeterData.find_by_sql("SELECT meter_id, SUM(van) as van, SUM(vbn) as vbn, SUM(vcn) as vcn,
SUM(ia) as ia, SUM(ib) as ib, SUM(ic) as ic, SUM(w3pht) as w3pht,
SUM(pf3pht) as pf3pht, SUM(f) as f, SUM(whrec) as whrec,
SUM(whtot) as whtot, SUM(varhrec) as varhrec, SUM(varhtot) as varhtot,
SUM(whintvlrec) as whintvlrec, SUM(whintvldel) as whintvldel,
SUM(w__phavg) as w__phavg, SUM(var__3phavg) as var__3phavg,
SUM(w_3phavg) as w_3phavg, SUM(var_3phavg) as var_3phavg,
SUM(phai) as phai, SUM(phbi) as phbi, SUM(phci) as phci,
SUM(w__3phmaxavgdmd) as w__3phmaxavgdmd, MAX(w__3phmaxavgdmd) as w__3phmaxavgdmd_max,
SUM(var__3phmaxavgdmd) as var__3phmaxavgdmd, SUM(w_3phmaxavgdmd) as w_3phmaxavgdmd,
SUM(var_3phmaxavgdmd) as var_3phmaxavgdmd, date_time FROM `meter_data`
WHERE (`date_time_i` >= #{#from_date} AND `date_time_i` <= #{#to_date} AND building = '#{#building_info}')
GROUP by meter_id ORDER BY `meter_data`.`date_time_i` ASC")
#meter_data_max = MeterData.find_by_sql("SELECT tenant, meter_id, MAX(w__3phmaxavgdmd) as w__3phmaxavgdmd,
date_time FROM `meter_data` WHERE (`date_time_i` >= #{#from_date} AND `date_time_i` <= #{#to_date}
AND building = '#{#building_info}') GROUP by tenant, meter_id
ORDER BY `meter_data`.`date_time_i` ASC")
sleep 0.5
#uniq_meter_id = MeterData.select(:meter_id).where("`date_time_i` >= #{#from_date} AND `date_time_i` <= #{#to_date} AND building = '#{#building_info}'").uniq(:meter_id)
#### database fetch ###########
p = Axlsx::Package.new
wb = p.workbook
wb.styles do |s|
styles_hash = AxlsxStylesHash.get s
wb.add_worksheet(:name => "Building data details") do |sheet|
$row_num = 0
meter_extra = MeterExtra.new
columns_ = []; #columns.each { |s| columns_ << "#{s}_".to_s }
sheet.add_row []
$row_num += 1
sheet.add_row ["Building report of #{#building_f_name} #{#from_date} to #{#to_date}"], :style => styles_hash[:heading_cell]
$row_num += 1
sheet.add_row []
$row_num += 1
sheet.add_row []
$row_num += 1
sheet.merge_cells("A2:Q2")
new_columns_ = []
new_columns_ << "Date & Time" if columns_.include?('date_time_')
new_columns_ << "Building" if columns_.include?('building_')
new_columns_ << "Tenant" if columns_.include?('tenant_')
new_columns_ << "Meter ID" if columns_.include?('meter_id_')
new_columns_ << "Meter Name" if columns_.include?('meter_id_')
new_columns_ << "van" if columns_.include?('van_')
new_columns_ << "vbn" if columns_.include?('vbn_')
new_columns_ << "vcn" if columns_.include?('vcn_')
new_columns_ << "ia" if columns_.include?('ia_')
new_columns_ << "ib" if columns_.include?('ib_')
new_columns_ << "ic" if columns_.include?('ic_')
new_columns_ << "w3pht" if columns_.include?('w3pht_')
new_columns_ << "pf3pht" if columns_.include?('pf3pht_')
new_columns_ << "f" if columns_.include?('f_')
new_columns_ << "whrec" if columns_.include?('whrec_')
new_columns_ << "whtot" if columns_.include?('whtot_')
new_columns_ << "varhrec" if columns_.include?('varhrec_')
new_columns_ << "varhtot" if columns_.include?('varhtot_')
new_columns_ << "whintvlrec" if columns_.include?('whintvlrec_')
new_columns_ << "whintvldel" if columns_.include?('whintvldel_')
new_columns_ << "w+phavg" if columns_.include?('w__phavg_')
new_columns_ << "var+3phavg" if columns_.include?('var__3phavg_')
new_columns_ << "w-3phavg" if columns_.include?('w_3phavg_')
new_columns_ << "var-3phavg" if columns_.include?('var_3phavg_')
new_columns_ << "phai" if columns_.include?('phai_')
new_columns_ << "phbi" if columns_.include?('phbi_')
new_columns_ << "phci" if columns_.include?('phci_')
new_columns_ << "w+3phmaxavgdmd" if columns_.include?('w__3phmaxavgdmd_')
new_columns_ << "var+3phmaxavgdmd" if columns_.include?('var__3phmaxavgdmd_')
new_columns_ << "w-3phmaxavgdmd" if columns_.include?('w_3phmaxavgdmd_')
new_columns_ << "var-3phmaxavgdmd" if columns_.include?('var_3phmaxavgdmd_')
sheet.add_row new_columns_, :style => styles_hash[:green_bold_border_cell]
$row_num += 1
t = 1; #meter_data.each do |m|
new_columns_data = []
if columns_.include?('date_time_')
m_date_time = m['date_time']
new_columns_data << ( m_date_time.nil? ? '--' : m_date_time)
end
if columns_.include?('building_')
m_building = m_building
new_columns_data << ( m_building.nil? ? '--' : building_names["#{m_building}"])
end
if columns_.include?('tenant_')
m_tenant = m['tenant']
new_columns_data << ( m_tenant.nil? ? '--' : tenant_names["#{m_tenant}"])
end
if columns_.include?('meter_id_')
m_meter_id = m['meter_id']
new_columns_data << ( m_meter_id.nil? ? '--' : m_meter_id)
end
if columns_.include?('meter_id_')
m_meter_id = m['meter_id']
new_columns_data << ( meter_extra.get_meter_name(m_meter_id.nil? ? '--' : m_meter_id) )
end
if columns_.include?('van_')
m_van = m.van
new_columns_data << ( m_van.nil? ? '--' : m_van )
end
if columns_.include?('vbn_')
m_vbn = m.vbn
new_columns_data << ( m_vbn.nil? ? '--' : m_vbn )
end
if columns_.include?('vcn_')
m_vcn = m.vcn
new_columns_data << ( m_vcn.nil? ? '--' : m_vcn )
end
if columns_.include?('ia_')
m_ia = m.ia
new_columns_data << ( m_ia.nil? ? '--' : m_ia )
end
if columns_.include?('ib_')
m_ib = m.ib
new_columns_data << ( m_ib.nil? ? '--' : m_ib )
end
if columns_.include?('ic_')
m_ic = m.ic
new_columns_data << ( m_ic.nil? ? '--' : m_ic )
end
if columns_.include?('w3pht_')
m_w3pht = m.w3pht
new_columns_data << ( m_w3pht.nil? ? '--' : m_w3pht )
end
if columns_.include?('pf3pht_')
m_pf3pht = m.pf3pht
new_columns_data << ( m_pf3pht.nil? ? '--' : m_pf3pht )
end
if columns_.include?('f_')
m_f = m.f
new_columns_data << ( m_f.nil? ? '--' : m_f )
end
if columns_.include?('whrec_')
m_whrec = m.whrec
new_columns_data << ( m_whrec.nil? ? '--' : m_whrec )
end
if columns_.include?('whtot_')
m_whtot = m.whtot
new_columns_data << ( m_whtot.nil? ? '--' : m_whtot )
end
if columns_.include?('varhrec_')
m_varhrec = m.varhrec
new_columns_data << ( m_varhrec.nil? ? '--' : m_varhrec )
end
if columns_.include?('varhtot_')
m_varhtot = m.varhtot
new_columns_data << ( m_varhtot.nil? ? '--' : m_varhtot )
end
if columns_.include?('whintvlrec_')
m_whintvlrec = m.whintvlrec
new_columns_data << ( m_whintvlrec.nil? ? '--' : m_whintvlrec )
end
if columns_.include?('whintvldel_')
m_whintvldel = m.whintvldel
new_columns_data << ( m_whintvldel.nil? ? '--' : m_whintvldel )
end
if columns_.include?('w__phavg_')
m_w__phavg = m.w__phavg
new_columns_data << ( m_w__phavg.nil? ? '--' : m_w__phavg )
end
if columns_.include?('var__3phavg_')
m_var__3phavg = m.var__3phavg
new_columns_data << ( m_var__3phavg.nil? ? '--' : m_var__3phavg )
end
if columns_.include?('w_3phavg_')
m_w_3phavg = m.w_3phavg
new_columns_data << ( m_w_3phavg.nil? ? '--' : m_w_3phavg )
end
if columns_.include?('var_3phavg_')
m_var_3phavg = m.var_3phavg
new_columns_data << ( m_var_3phavg.nil? ? '--' : m_var_3phavg )
end
if columns_.include?('phai_')
m_phai = m.phai
new_columns_data << ( m_phai.nil? ? '--' : m_phai )
end
if columns_.include?('phbi_')
m_phbi = m.phbi
new_columns_data << ( m_phbi.nil? ? '--' : m_phbi )
end
if columns_.include?('phci_')
m_phci = m.phci
new_columns_data << ( m_phci.nil? ? '--' : m_phci )
end
if columns_.include?('w__3phmaxavgdmd_')
m_w__3phmaxavgdmd = m.w__3phmaxavgdmd
new_columns_data << ( m_w__3phmaxavgdmd.nil? ? '--' : m_w__3phmaxavgdmd )
end
if columns_.include?('var__3phmaxavgdmd_')
m_var__3phmaxavgdmd = m.var__3phmaxavgdmd
new_columns_data << ( m_var__3phmaxavgdmd.nil? ? '--' : m_var__3phmaxavgdmd )
end
if columns_.include?('w_3phmaxavgdmd_')
m_w_3phmaxavgdmd = m.w_3phmaxavgdmd
new_columns_data << (m_w_3phmaxavgdmd.nil? ? '--' : m_w_3phmaxavgdmd )
end
if columns_.include?('var_3phmaxavgdmd_')
m_var_3phmaxavgdmd = m.var_3phmaxavgdmd
new_columns_data << ( m_var_3phmaxavgdmd.nil? ? '--' : m_var_3phmaxavgdmd )
end
if t == 1
sheet.add_row new_columns_data , :style => styles_hash[:simple_green_cell], :widths=>[20]
else
sheet.add_row new_columns_data, :style => styles_hash[:simple_white_cell], :widths=>[20]
end
$row_num += 1
t = 0 if t == 2
t += 1
puts $row_num
m = nil
end
#meter_data = nil
## logo ##
ReportBillLogo.put sheet, $row_num
sheet = nil;
end
## summary calculation ##
wb.add_worksheet(:name => "Summary") do |sheet|
$row_num = 0
sheet.add_row []
$row_num += 1
sheet.add_row ["Summary report of #{#building_f_name} #{#from_date} to #{#to_date}"], :style => styles_hash[:heading_cell]
$row_num += 1
sheet.add_row []
$row_num += 1
sheet.add_row []
$row_num += 1
sheet.merge_cells("A1:Q1")
columns_ = []; #columns.each { |s| columns_ << "#{s}_".to_s }
new_columns_ = []
new_columns_ << "Meter ID"
new_columns_ << "Meter Name"
new_columns_ << "Max KW"
sheet.add_row new_columns_, :style => styles_hash[:green_bold_border_cell]
$row_num += 1
t = 0
#meter_data_max.each do |m|
new_columns_data = []
new_columns_data << m.meter_id
new_columns_data << meter_names["#{m.meter_id}"]
new_columns_data << ( m.w__3phmaxavgdmd.nil? ? '' : m.w__3phmaxavgdmd )
if t == 1
sheet.add_row new_columns_data, :style => styles_hash[:simple_green_cell], :widths=>[25]
else
sheet.add_row new_columns_data, :style => styles_hash[:simple_white_cell], :widths=>[25]
end
$row_num += 1
t = 0 if t == 2
t += 1
m = nil;
end
## logo ##
ReportBillLogo.put sheet, $row_num
sheet = nil
end
## summary calculation ##
## summary calculation ##
wb.add_worksheet(:name => "Energy consumed") do |sheet|
$row_num = 0
sheet.add_row []
$row_num += 1
sheet.add_row ["Energy consumed report of #{#building_f_name} #{#from_date} to #{#to_date}"], :style => styles_hash[:heading_cell]
$row_num += 1
sheet.add_row []
$row_num += 1
sheet.add_row []
$row_num += 1
sheet.merge_cells("A2:Q2")
engery = []
#uniq_meter_id.each do |f|
start = MeterData.find_by_sql("select whtot from meter_data where `date_time_i` >= #{#from_date} AND meter_id = '#{f.meter_id}' ORDER BY date_time_i ASC limit 1")
eand = MeterData.find_by_sql("select whtot from meter_data where `date_time_i` <= #{#from_date} AND meter_id = '#{f.meter_id}' ORDER BY date_time_i DESC limit 1")
sleep 0.009
begin
engery << (eand.last.whtot.to_i - start.first.whtot.to_i)
rescue
engery << '--'
end
start = nil; eand = nil;
f = nil;
end
columns_ = []; #columns.each { |s| columns_ << "#{s}_".to_s }
new_columns_ = []
new_columns_ << "Meter ID"
new_columns_ << "Meter Name"
new_columns_ << "Subtraction result"
new_columns_ << "Aggregate result"
sheet.add_row new_columns_, :style => styles_hash[:green_bold_border_cell]
$row_num += 1
flage = 0
t = 0
#meter_sum.each do |m|
new_columns_data = []
new_columns_data << m.meter_id
new_columns_data << meter_names["#{m.meter_id}"]
new_columns_data << engery[flage]
new_columns_data << m.whintvlrec
if t == 1
sheet.add_row new_columns_data, :style => styles_hash[:simple_green_cell], :widths=>[25]
else
sheet.add_row new_columns_data, :style => styles_hash[:simple_white_cell], :widths=>[25]
end
$row_num += 1
flage += 1
t = 0 if t == 2
t += 1
m = nil
end
## logo ##
ReportBillLogo.put sheet, $row_num
sheet = nil;
end
end
$file_name = "tmp/#{#building_info} . #{#from_date} - #{#to_date} _ #{Time.new.to_i}.xlsx"
p.serialize($file_name)
p = nil; wb = nil;
#meter_data = nil; #meter_data_max = nil; #meter_sum = nil;
return $file_name
end
# total records = 5, 00, 000
When ruby process is running out of memory it access a huge bit of memory from the system called heap slab. This big chunk is then internally divided into many small bits, which holds your variables and your code. When you assign nil to some variable, garbage collector will mark this small bit as empty, but the whole slab is never returned to the system until process is terminated.
I'm not exactly sure if this is actually the problem that you're having, but there's a known issue with Ruby 2.1.x's generational garbage collection where allocated objects in memory that are supposed to be "short-lived" end up being accidentally promoted to "long-lived" instead, causing memory to bloat because the garbage collector doesn't run frequently enough to clean up these objects:
Koichi Sasada, the author of the generational GC in Ruby 2.1:
“Some ‘short-lived’ young objects will be promoted to ‘old-gen’ accidentally….if such ‘short-lived’ objects consume huge memory we need to free such objects.”
A current workaround that is being mentioned a lot right now in the Ruby community is to change a default Ruby setting in order to tell it to garbage collect more often:
Expect memory doubling with Ruby 2.1.1. Not happy with that? You have 2 options:
Tune it down by reducing RUBY_GC_HEAP_OLDOBJECT_LIMIT_FACTOR. At 1 your memory consumption will be on par with 2.0. It ships with the 2 default.
Option 2, wait for a future release of Ruby, this will be fixed in 2.2 maybe even patched a bit more in 2.1.2 . See:
https://bugs.ruby-lang.org/issues/9607 and
http://vimeo.com/89491942 and
https://speakerdeck.com/samsaffron/why-ruby-2-dot-1-excites-me

Rails - Simple Loop Not Working

In my controller I am trying to do a bulk insert into a table, in my first attempt it works but the names somehow get mangled as the following: (loop runs 24 times which is what I want)
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11
test-port-name-0-1-2-3-4-5-6-7-8-9-10
test-port-name-0-1-2-3-4-5-6-7-8-9
test-port-name-0-1-2-3-4-5-6-7-8
test-port-name-0-1-2-3-4-5-6
test-port-name-0-1-2-3-4-5-6-7
test-port-name-0-1-2-3-4-5
test-port-name-0-1-2-3-4
test-port-name-0-1-2
test-port-name-0-1-2-3
test-port-name-0
test-port-name-0-1
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22
test-port-name-0-1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23
instead of test-port-name-0 .... test-port-name-23
def bulk_port_import
if request.post?
#attempt create
count = 0
for i in 1..session[:no_ports]
params[:dp][:name] = params[:dp][:name] + '-' + count.to_s
#dp = DevicePort.create params[:dp]
count = count + 1
end
end
#success = "Saved." if #dp.valid?
#error = ""
#dp.errors.each_full {|e| #error += e + ", "}
redirect_to '/device/update/' + params[:dp][:device_id]
end
Different attempt:
def bulk_port_import
if request.post?
#attempt create
i = 0
while i < session[:no_ports] do
params[:dp][:name] = params[:dp][:name] + '-' + i.to_s
#dp = DevicePort.create params[:dp]
i++
end
end
session.delete(:no_ports)
#success = "Saved." if #dp.valid?
#error = ""
#dp.errors.each_full {|e| #error += e + ", "}
redirect_to '/device/update/' + params[:dp][:device_id]
end
but with this I get syntax error, unexpected kEND and I can't see what I'm doing wrong in either case, it's probably something stupid, again.
Its because you are changing params[:dp][:name] in the loop
def bulk_port_import
if request.post?
#attempt create
count = 0
for i in 1..session[:no_ports]
dp_name = params[:dp][:name] + '-' + count.to_s
#dp = DevicePort.create(params[:dp].merge(:name => dp_name))
count = count + 1
end
end
#success = "Saved." if #dp.valid?
#error = ""
#dp.errors.each_full {|e| #error += e + ", "}
redirect_to '/device/update/' + params[:dp][:device_id]
end

Resources