How do I create an average for a temperature data set? - ruby-on-rails

I am writing a program which takes a set of data and then averages it. This data set is the average temperature at Laguardia Airport for every month which corresponds with a temperature.
Here is an example one data point:
2009-07,23.6
Which is year-month, temp.
I have 163 data points. All of the data points are in a .txt file, each on a new line.
I made the data into an array and split it. For some reason, my program says my average is 0 every time I try to run it
Here is my code:
data = File.open("avg_temp.txt", "r+")
contents = data.read
contents = contents.split("\r\n")
contents.collect! do |x|
x.split(',')
end
sum = 0
data.each do |x|
sum = sum + x[1].to_f
end
avg = sum / contents.length
puts avg

assign avg = sum/contents.length outside the loop after the end. Variables defined within a loop have a scope limited to that loop. Also you are looping over data, should be content
contents.each do |x|
puts x[1] # to check if the right value is being evaluated
sum = sum + x[1].to_f
end
avg = sum/contents.length

Your avg is not the top level local variable. Thus you can't access it from the top level. avg is scoped to the block only. You can do below :-
avg = 0
data.each do |x|
sum = sum + temp[1].to_f
avg = sum / contents.length
end
puts avg

sum = 0
data.each do |x|
sum = sum + temp[1].to_f
avg = sum / contents.length
end
puts avg
The avg variable is no longer in scope, as it's outside of the each block. To print the avg, simply move it inside of the block like so
sum = 0
data.each do |x|
sum = sum + temp[1].to_f
avg = sum / contents.length
puts avg
end
Or move the avg variable outside of the loop (to perform the action once, after your loop has exited)
sum = 0
data.each do |x|
sum = sum + temp[1].to_f
end
avg = sum / contents.length
puts avg
More info at http://rubyflare.com/2009/09/30/variables-scope-and-iterators/

I'd write this more simply:
lines = 0
sum = 0
File.foreach("avg_temp.txt") do |data|
sum += data.split(',').last.to_f
lines = $.
end
puts 'Average: %f over %d datapoints' % [sum / lines.to_i, lines]
# >> Average: 23.375000 over 4 datapoints
Which outputs:
Average: 23.375000 over 4 datapoints
Starting with "avg_temp.txt" looking like:
2009-07,23.6
2009-08,23.7
2009-09,23.6
2009-10,22.6
To 'splain it:
$. is the current line number. Each time through the loop it reassigns the last read line-number to lines so we know how many to divide by.
foreach reads line-by-line, so there's no need to split the file. That also explains why I use $. to keep track of the number of elements. It also means this could read a file containing millions or billions of values without a problem, where read would go to its knees.

Related

VBA SUMIF on Array

OK, so I am wanting to do a sumif on a column on an array because I don't want to print to the worksheet in order to obtain a range type for a Worksheet.function.Sumif, the idea is to stay completely out in VBA code and write to the worksheet as little as possible. I am trying to optimize for speed: 4814 rows by 40 columns X 60.
The first column total is total of 197,321,164 is correct, the next columns are low and instead of going to quarter 40 the Else kicks in and everything after 8 is 0. The first "To_Quarter" in the array is 9 so with the >= I would think it would go to 9. I tried putting my Next I before the End IF but then it just asks for the For.
image of locals box: https://ibb.co/cgFQhxY
Any help would be much appreciated.
Sub SumifONarray()
Dim arrQuarters, arrNumber_of_Assets As Variant
Dim I As Long, J As Long
arrNumber_of_Assets = Range("Costs_Number_of_Assets")
arrQuarters = Range("Quarters_1to40")
Dim MaxRecov_If_result, arr_Row10_Resolution_Physical_Possession_Expenses_To_Quarter, arr_Row10_Resolution__Max_Recovery_Grid As Variant
arr_Row10_Resolution_Physical_Possession_Expenses_To_Quarter = Range("_Row10_Resolution_Physical_Possession_Expenses_To_Quarter")
arr_Row10_Resolution__Max_Recovery_Grid = Range("_Row10_Resolution__Max_Recovery_Grid")
ReDim arrIf_Max_Recovery_Amount_Sum(1 To 1, 1 To UBound(arrQuarters, 2))
For J = LBound(arrQuarters, 2) To UBound(arrQuarters, 2)
For I = LBound(arrNumber_of_Assets, 1) To UBound(arrNumber_of_Assets, 1)
If arr_Row10_Resolution_Physical_Possession_Expenses_To_Quarter(I, 1) >= arrQuarters(1, J) Then
MaxRecov_If_result = MaxRecov_If_result + arr_Row10_Resolution__Max_Recovery_Grid(I, J)
Else: MaxRecov_If_result = 0
End If
Next I
arrIf_Max_Recovery_Amount_Sum(1, J) = MaxRecov_If_result
MaxRecov_If_result = 0
Next J
End Sub
I've uploaded a sample below with code with 10 rows.
https://easyupload.io/wfixds

Lua multiple inputs in table

I'm new to lua and I have this assignment and one of the questions I'm really stumped on is asking:
"A program that asks the user repeatedly for students' scores, will stop when the user enters a score of 999 then the program should calculate and display the number of scores entered, highest score, lowest score, and the average score. Make sure to display an error message if a score less than zero or more than 100 is entered by user. "
I've been at this all week long and still can't figure out what to do and its due at 11:59pm est. Any insight and direction would be great.
-How do I input multiple values in a growing table scores = {}? Where the size is given by the number of inputs for variable s after the user enters 999 and ends the repeat loop. This is actually my BIGGEST problem.
My Code:
local scores = {}, avg
repeat
io.write("Enter score(s)")
local s = tonumber(io.read()) --input and convert data type
print(s, type(s)) --s value, check input type
if(s < 0 or s > 100) then
print("Error.")
end
until (s == 999)
for i = 0, #s, 1 do
sum = 0
if s then
sum = sum + s
end
end
-- -----------------------------------------------------------Attemps to find a way to put s values in scores table-----------------------------------------------------------------------------------------
--[[scores[#scores+1] = s ----Attempt 1
print (scores)
for i = 0, #s, 1 do ----Attempt 2
scores{s} = s[i]
print (i, scores) --tried a multitude of different ways and
--kept getting the same number printed once or memory location of last entered number
end
for i, s in ipairs (scores) do --Attempt 3
print (i, s)
end
for i = 0, #s, 1 do
sum = 0
if s then
sum = sum + s
end
end --]]
-- -----------------------------------------------------------------------------------------------------------------------------------------------------------------------
--[[function average(myTable)
local sum = 0
for i in scores do
sum = sum + i
end
return (sum / #scores)
end
print ("The number of values in the table"..#scores)
print ("The average of the scores is "..average(s))
print ("The max value in the table is "..math.max(s))
print ("The minimum value in the table is "..math.min(s))
table.maxn(scores), table.minn(scores)
--]]
io.write("Please press enter to continue")
io.read()

Random sum of elements in an array equals to y - ruby [duplicate]

This question already has answers here:
Finding all possible combinations of numbers to reach a given sum
(32 answers)
Closed 6 years ago.
Need to create an array whose sum should be equal to expected value.
inp = [1,2,3,4,5,6,7,8,9,10]
sum = 200
output:
out = [10,10,9,1,3,3,3,7,.....] whose sum should be 200
or
out = [10,7,3,....] Repeated values can be used
or
out = [2,3,4,9,2,....]
I tried as,
arr = [5,10,15,20,30]
ee = []
max = 200
while (ee.sum < max) do
ee << arr.sample(1).first
end
ee.pop(2)
val = max - ee.sum
pair = arr.uniq.combination(2).detect { |a, b| a + b == val }
ee << pair
ee.flatten
Is there any effective way to do it.
inp = [1,2,3,4,5,6,7,8,9,10]
sum = 20
inp.length.downto(1).flat_map do |i|
inp.combination(i).to_a # take all subarrays of length `i`
end.select do |a|
a.inject(:+) == sum # select only those summing to `sum`
end
One might take a random element of resulting array.
result = inp.length.downto(1).flat_map do |i|
inp.combination(i).to_a # take all subarrays of length `i`
end.select do |a|
a.inject(:+) == sum # select only those summing to `sum`
end
puts result.length
#⇒ 31
puts result.sample
#⇒ [2, 4, 5, 9]
puts result.sample
#⇒ [1, 2, 3, 6, 8]
...
Please note, that this approach is not efficient for long-length inputs. As well, if any original array’s member might be taken many times, combination above should be changed to permutation, but this solution is too ineffective to be used with permutation.
I found an answer of this question in the following link:
Finding all possible combinations of numbers to reach a given sum
def subset_sum(numbers, target, partial=[])
s = partial.inject 0, :+
#check if the partial sum is equals to target
puts "sum(#{partial})=#{target}" if s == target
return if s >= target #if we reach the number why bother to continue
(0..(numbers.length - 1)).each do |i|
n = numbers[i]
remaining = numbers.drop(i+1)
subset_sum(remaining, target, partial + [n])
end
end
subset_sum([1,2,3,4,5,6,7,8,9,10],20)

Easiest way to find divisors of 60 in Ruby on Rails

Other than hardcoding or using the Math module, Is there any way I can find divisors of 60 in Ruby on Rails. Any helper methods/regular expression that I can make use of? Thanks for your help.
One of the easiest ways to achieve this would be to create a list of numbers between 1 and 60, and then only select the ones that divide 60 with no remainder.
To expand on SteveTurczyn's answer, we can do:
(1..60).select { |n| 60 % n == 0 }
The (1..60) part creates an enumerator (which in this case we can think of as an array of the numbers between 1 and 60).
Then you want to take this array, and select only the elements are divisors of 60.
We can use the modulus operator %, which gives us the remainder left over when we divide a number by another (e.g., 5 % 2 returns 1). Of course, if there is no remainder, then we know that the number divided cleanly, and is therefore a divisor of that number (i.e., if a % b == 0, then b is a divisor of a).
So what we want to do, is use the above as a criteria for selecting elements out of the array of numbers between 1 and 60, which we are able to do with the Array#select method.
If we have something, like an array (technically, I think, an Enumerable), we can use #select and a block to pull out only the elements that satisfy whatever criteria we specify in the block.
The { |n| 60 % n == 0 } is the block we are passing to #select, which will return true whenever 60 % n is 0 (each n is an element from the array of numbers 1 through 60). Array#select only returns the elements in the array for which the block evaluates to true- which is how SteveTurczyn's solution works.
This will give you the array of divisors
(1..60).select { |n| 60 % n == 0}
=> [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60]
For small numbers it's okay to use the brute force search, but for large numbers this approach doesn't suite. You can speed up your method significantly by selecting divisors as pairs.
Some examples with benchmarks:
require 'benchmark'
n = 10_000_000
def brute_force(n)
(1..n).select { |i| n % i == 0 }
end
def faster_way(n)
(1..Math.sqrt(n)).each_with_object([]) { |i, arr| (n % i).zero? && arr << i && n/i != i && arr << n/i }
end
Benchmark.bm do |x|
x.report { brute_force(n) }
x.report { faster_way(n) }
end
# Benchmark output
user system total real
0.799491 0.001417 0.800908 ( 0.802341)
0.000580 0.000002 0.000582 ( 0.000581)
As you can see the second approach is 1376 times faster for n = 10_000_000.

Rails Average - Discount 0 values

I create arrays which I need to find the averages of as follows:
total_rating = []
#add numbers to total_rating
average = total_rating.inject(:+).to_f / total_rating.size
How can I remove values of 0 from this average calculation? I dont want the 0 row to be computed in the average calculation.
total_rating.reject(&:zero?)

Resources