Get and add values from JSON - ruby-on-rails

Here is my Hash:
{"graph"=>[{"1"=>16, "2"=>44, "3"=>53, "4"=>53, "5"=>80, "6"=>71, "7"=>63, "8"=>54, "9"=>53, "10"=>44, "11"=>76, "12"=>82, "13"=>66, "14"=>59, "15"=>64, "16"=>39, "17"=>19, "18"=>14, "19"=>5, "20"=>6, "21"=>5, "22"=>7, "23"=>6, "24"=>7}]}
I'm trying to get the values of each and add them together. The long and incorrect way would be to get each value and add them together like so:
first_number = json["graph"][0]["1"]
second_number = json["graph"][0]["2"]
How can I simplify this to get that total count?

If all you need is the sum of those values...
json['graph'][0].values.inject{|sum,val| sum+val}
If you are using rails, you have the option to use the sum method instead:
json['graph'][0].values.sum
inject takes a given block and executes the block once for every element in the Array. val is the current value being evaluated, and sum is the value that was last returned from the block. Thus, if you add the two every time the block runs, and return the result, you will get a sum of your values at the end of execution.
You can see the documentation here: http://apidock.com/ruby/Enumerable/inject

Related

ruby on rails pass a value to .last()

I'm pretty new to ruby on rails, so I'm probably missing some syntax. Big picture I am trying to get the value for a specified percentile. Conceptually I am taking my table 'Scores', sorting it, getting the last 'x' values, and then taking the first value. I can't seem to figure out how to pass 'x', which is based on the length of the dataset to the chain.
def get_percentile()
record_count = Scores.count(:id)*0.05
record_threshold = record_count.round()
Score_percentile = Scores.order(:points).last(record_threshold).first().points
return Score_percentile
end
get_percentile
If I just enter .last(20) this works as I expect, so I just don't know how to pass the variable.
Thanks.
You may be passing a 0 into your .last() function with your rounding.
There are a variety of options to make sure you pass at least a 1
[record_threshold, 1].max will give you at least 1. https://apidock.com/ruby/Enumerable/max
Changing .round() to .ceil() rounds up in all instances. https://apidock.com/ruby/Float/ceil

We giving a task for Lua table but it is not working as expectable

Our task is create a table, and read values to the table using a loop. Print the values after the process is complete. - Create a table. - Read the number of values to be read to the table. - Read the values to the table using a loop. - Print the values in the table using another loop. for this we had written code as
local table = {}
for value in ipairs(table) do
io.read()
end
for value in ipairs(table) do
print(value)
end
not sure where we went wrong please help us. Our exception is
Input (stdin)
3
11
22
abc
Your Output (stdout)
~ no output ~
Expected Output
11
22
abc
Correct Code is
local table1 = {}
local x = io.read()
for line in io.lines() do
table.insert(table1, line)
end
for K, value in ipairs(table1) do
print(value)
end
Let's walk through this step-by-step.
Create a table.
Though the syntax is correct, table is a reserved pre-defined global name in Lua, and thus cannot should not be declared a variable name to avoid future issues. Instead, you'll need to want to use a different name. If you're insistent on using the word table, you'll have to distinguish it from the function global table. The easiest way to do this is change it to Table, as Lua is a case-sensitive language. Therefore, your table creation should look something like:
local Table = {}
Read values to the table using a loop.
Though Table is now established as a table, your for loop is only iterating through an empty table. It seems your goal is to iterate through the io.read() instead. But io.read() is probably not what you want here, though you can utilize a repeat loop if you wish to use io.read() via table.insert. However, repeat requires a condition that must be met for it to terminate, such as the length of the table reaching a certain amount (in your example, it would be until (#Table == 4)). Since this is a task you are given, I will not provide an example, but allow you to research this method and use it to your advantage.
Print the values after the process is complete.
You are on the right track with your printing loop. However, it must be noted that iterating through a table always returns two results, an index and a value. In your code, you would only return the index number, so your output would simply return:
1
2
3
4
If you are wanting the actual values, you'll need a placeholder for the index. Oftentimes, the placeholder for an unneeded variable in Lua is the underscore (_). Modify your for loop to account for the index, and you should be set.
Try modifying your code with the suggestions I've given and see if you can figure out how to achieve your end result.
Edited:
Thanks, Piglet, for corrections on the insight! I'd forgotten table itself wasn't a function, and wasn't reserved, but still bad form to use it as a variable name whether local or global. At least, it's how I was taught, but your comment is correct!

Print ResponseIDs of missing values SPSS

I'm creating a variable that will hold missing values from a specific variable. Currently, this works but it gives the missing a value a 1. How do I tell spss to print the respondent's ResponseID instead?
My code below:
COMPUTE Q_2_MIS = MISSING(Q_2).
EXECUTE.
Thanks
Your code returns value of 1 because the condition missing(q_2) is evaluated to TRUE.
Try this:
DO IF MISSING(Q_2).
COMPUTE Q_2_MIS = ResponseID .
END IF.
EXECUTE.
or (as per eli-k's comment) simply use IF:
IF MISSING(Q_2) Q_2_MIS = ResponseID .
EXECUTE.
Note that you might need to create the Q_2_MIS variable first, if you do not have it in your dataset.
Alternatively, if you want to print out the IDs of the respondents with missing in Q_2:
TEMPORARY.
SELECT IF missing(q_2).
LIST ResponseID q_2.
You will see a list of IDs in the SPSS Output, with a (blank) Q_2 next to each ID.

Storing value of calculation that query result is being ordered by with Rails

I'm new to rails but I still feel I should know the answer to this. Drawing a complete blank.
I have the following query that returns the expected results. However I want to also store the value the calculation they are being ordered by returns.
What is the best way of extracting this value.
Here is the line of code
#service = Service.order("ST_Distance(services.lon_lat, ST_GeomFromText('POINT (lat lon)', 4326))").limit(10)
As I said it returns the correct results but I'd also like to find the distance for each result
Thank you
Try this:
#services = Service.select("*, ST_Distance(services.lon_lat, ST_GeomFromText('POINT (lat lon)', 4326)) as st_distance").order("st_distance").limit(10)
the objects you get back in #services (note i changed this to the plural in keeping with convention) should have an additional method .st_distance, which is what i set the results of that function to be called with as st_distance

How do I collect and combine multiple arrays for calculation?

I am collecting the values for a specific column from a named_scope as follows:
a = survey_job.survey_responses.collect(&:base_pay)
This gives me a numeric array for example (1,2,3,4,5). I can then pass this array into various functions I have created to retrieve the mean, median, standard deviation of the number set. This all works fine however I now need to start combining multiple columns of data to carry out the same types of calculation.
I need to collect the details of perhaps three fields as follows:
survey_job.survey_responses.collect(&:base_pay)
survey_job.survey_responses.collect(&:bonus_pay)
survey_job.survey_responses.collect(&:overtime_pay)
This will give me 3 arrays. I then need to combine these into a single array by adding each of the matching values together - i.e. add the first result from each array, the second result from each array and so on so I have an array of the totals.
How do I create a method which will collect all of this data together and how do I call it from the view template?
Really appreciate any help on this one...
Thanks
Simon
s = survey_job.survey_responses
pay = s.collect(&:base_pay).zip(s.collect(&:bonus_pay), s.collect(&:overtime_pay))
pay.map{|i| i.compact.inject(&:+) }
Do that, but with meaningful variable names and I think it will work.
Define a normal method in app/helpers/_helper.rb and it will work in the view
Edit: now it works if they contain nil or are of different sizes (as long as the longest array is the one on which zip is called.
Here's a method that will combine an arbitrary number of arrays by taking the sum at each index. It'll allow each array to be of different length, too.
def combine(*arrays)
# Get the length of the largest array, that'll be the number of iterations needed
maxlen = arrays.map(&:length).max
out = []
maxlen.times do |i|
# Push the sum of all array elements at a given index to the result array
out.push( arrays.map{|a| a[i]}.inject(0) { |memo, value| memo += value.to_i } )
end
out
end
Then, in the controller, you could do
base_pay = survey_job.survey_responses.collect(&:base_pay)
bonus_pay = survey_job.survey_responses.collect(&:bonus_pay)
overtime_pay = survey_job.survey_responses.collect(&:overtime_pay)
#total_pay = combine(base_pay, bonus_pay, overtime_pay)
And then refer to #total_pay as needed in your view.

Resources