2
\$\begingroup\$

What do you think about this code I wrote. It reads several json files ( I attached them as pastebins) and the code outputs summary information calculated from the input.

# 1) calculate the
# engagement rate from the first JSON file (the user's Instagram media)
# - Calculate the average number of comments - Calculate the average
# number of likes - Calculate the engagement rate using (Average Likes +
# Average Comments)/# of Followers which is 435
# 
# 2) Combine the 2 sets of JSON data (Instagram media objects with their
# Instagram insights), then output a single JSON file where the insights
# are paired with their media objects in a clean format.
#
# Question 1.json: https://pastebin.com/V3Ue87H4
# Question2A.json: https://pastebin.com/YifXzimZ
# Question2B.json: https://pastebin.com/6X0JYXtD

require 'json'
input = JSON.parse( File.read('Question 1.json') )["data"]
avg_likes    = input.map { |x| x["like_count"] }.    inject{ |sum, el| sum + el }.to_f / input.size
avg_comments = input.map { |x| x["comments_count"] }.inject{ |sum, el| sum + el }.to_f / input.size
puts "Answer for Question 1: #{avg_likes + avg_comments / 435}\n\n"


input_a = JSON.parse( File.read('Question2A.json') )["data"]
input_b = JSON.parse( File.read('Question2B.json') ).map { |x| x["data"] }.flatten
output = input_a.map do |post|
  {
    :permalink => post["permalink"],
    :impressions => input_b.find { |x| x["id"] == "#{post['id']}/insights/impressions/lifetime" }["values"][0]["value"],
    :engagement  => input_b.find { |x| x["id"] == "#{post['id']}/insights/engagement/lifetime"  }["values"][0]["value"],
    :reach       => input_b.find { |x| x["id"] == "#{post['id']}/insights/reach/lifetime"       }["values"][0]["value"],
    :saved       => input_b.find { |x| x["id"] == "#{post['id']}/insights/saved/lifetime"       }["values"][0]["value"]
  }
end
puts "Answer for Question 2: " + JSON.pretty_generate(output)


# EXAMPLE OUTPUT - generated by running ruby coding_test.rb
#
# Answer for Question 1: 22.704827586206896
# 
# Answer for Question 2: [
#   {
#     "permalink": "https://www.instagram.com/p/B40LKjkAlDV/",
#     "impressions": 236,
#     "engagement": 33,
#     "reach": 187,
#     "saved": 2
#   },
#   {
#     "permalink": "https://www.instagram.com/p/B4z4Vq5Ag5g/",
#     "impressions": 212,
#     "engagement": 22,
#     "reach": 170,
#     "saved": 0
#   },
#   {
#     "permalink": "https://www.instagram.com/p/B4xnmtygmi-/",
#     "impressions": 297,
#     "engagement": 28,
#     "reach": 218,
#     "saved": 1
#   },
#   {
#     "permalink": "https://www.instagram.com/p/B4uyfrLgjVi/",
#     "impressions": 248,
#     "engagement": 21,
#     "reach": 194,
#     "saved": 0
#   },
#   {
#     "permalink": "https://www.instagram.com/p/B4nic12AFps/",
#     "impressions": 292,
#     "engagement": 15,
#     "reach": 219,
#     "saved": 0
#   }
# ]
\$\endgroup\$
2
\$\begingroup\$

Good work.

Here are some points where you can improve:

  • You can use input.sum { |x| x["like_count"] }.to_f instead of input.map { |x| x["like_count"] }.inject{ |sum, el| sum + el }
  • It is a good idea to do calculations with BigDecimal instead of Float.
  • 435 is a magic number, you can put it into a constant with a good name.
  • The spaces before the parentheses aren't usual in the Ruby community style guide.
  • Check the dig method available for Hash instances.
  • You can use the new syntax for Hash instances when the keys are symbols: { hello: "world" }
  • Use double-quotes or single-quotes, you're mixing both.
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ hey thanks for reviewing the code \$\endgroup\$ – american-ninja-warrior Dec 30 '19 at 14:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.