There is a task (condition before the code). In theory, the program works correctly, but there are a couple of nuances in its work. At the same time I will ask a few questions that worry me no less

  1. What if we have several people have a maximum print speed?
  2. How to simplify the value in the hash (a random number is taken as close as possible to the real one)
  3. In your opinion, is it justified to use the class in this situation? And how would you generally change the structure.
  4. Why the result.better.med_speed.low_speed(list) construction does not work

PS, please do not swear if the written code caused you pain.

Condition

For a certain group of students (a total of 25 people in the group) data on the speed of text input from the keyboard (the number of characters entered per 10 minutes) is known. It is required to make a report in the following form: print the name and speed of entry of the most effective student; the average entry rate in this group, the names of those students whose entry rate is lower than the average.

 class Speed @med=0 def better(list) #puts (list.sort_by{ |k,v| v}).to_s max=[] max << list.max_by { |k,v| v } puts max.to_s #puts list.to_a.to_s end def med_speed(list) @med=(list.values.inject(0){ |res,v| res+v})/25 puts "#{@med} -- средняя скорость печати" end def low_speed(list) bad_stud = list.find_all{|k,v| v<@med} puts "#Скорость печати ниже среднего имеют: #{bad_stud.to_s}" end end list = { Tim: (10 * (rand(150) + 100)), Tereza: (10 * (rand(150) + 100)), Otto: (10 * (rand(150) + 100)), Pavel: (10 * (rand(150) + 100)), Kitti: (10 * (rand(150) + 100)), George: (10 * (rand(150) + 100)), Sandra: (10 * (rand(150) + 100)), Patrik: (10 * (rand(150) + 100)), Nelson: (10 * (rand(150) + 100)), Fedel: (10 * (rand(150) + 100)), Hillary: (10 * (rand(150) + 100)), Marsel: (10 * (rand(150) + 100)), Boris: (10 * (rand(150) + 100)), Nikolay: (10 * (rand(150) + 100)), Juna: (10 * (rand(150) + 100)), Ivan: (10 * (rand(150) + 100)), Liza: (10 * (rand(150) + 100)), Karin: (10 * (rand(150) + 100)), Helga: (10 * (rand(150) + 100)), Josh: (10 * (rand(150) + 100)), Morris: (10 * (rand(150) + 100)), Wally: (10 * (rand(150) + 100)), Brigt: (10 * (rand(150) + 100)), Polina: (10 * (rand(150) + 100)), Markiz: (10 * (rand(150) + 100)) } #list.each{ |k,v| puts "#{k} : #{v}" } result = Speed.new result.better(list) result.med_speed(list) result.low_speed(list) 

    1 answer 1

    1. What if we have several people have a maximum print speed?

    It is best to return an array with users who have the maximum print speed. For example, you can sort your hash by print speed, and then select the first elements of the array with the same print speed

     arr = list.sort_by { |_k, v| -v } arr.select { |e| arr.first[1] == e[1] } 
    1. How to simplify the value in the hash (a random number is taken as close as possible to the real one)

    For a start, you can replace the expression (10 * (rand(150) + 100)) with a simpler rand(1500) + 1000 - it is shorter and easier to perceive. Further, only the names in your hash differ - the expression for getting the value is the same for everyone. To reduce the size of the code, you can proceed as follows. We form an array of names, and then convert it into an array of arrays of the form [[:Tim, 1558], ... [:Markiz, 2349]] . Such an array is easily converted to a hash using the to_h method to_h

     list = %w(Tim Tereza Otto Pavel Kitti George Sandra Patrik Nelson Fedel Hillary Marsel Boris Nikolay Juna Ivan Liza Karin Helga Josh Morris Wally Brigt Polina Markiz) list = list.map{ |e| [e.to_sym, rand(1500) + 1000]}.to_h 
    1. In your opinion, is it justified to use the class in this situation? And how would you change the overall structure?

    Using the class is possible and justified, why not. Only the class you have turned out is not quite object-oriented, you use it as a container of methods.

    Moreover, your order of calling methods depends on each other, while the @med variable @med not formed, you cannot use the low_speed method.

    In addition, you format and output text within methods. It is not right. If you want to change the text, you have to climb inside the class, and this violates the principle of encapsulation, and it is simply not convenient.

    Each time you pass a list , instead of giving it away once when the object is initialized. It would be better if you get the initialize() method, which you pass to the list parameter, and remove it from all other methods

     def initialize(list) @list = list end 

    With all the above, you can convert your code as follows

     class Speed def initialize(list) @list = list end def better arr = @list.sort_by { |_k, v| -v } arr.select { |e| arr.first[1] == e[1] } end def med_speed (@list.values.inject(0) { |res, v| res + v }) / 25 end def low_speed med = med_speed @list.select { |_k, v| v < med } end end list = %w(Tim Tereza Otto Pavel Kitti George Sandra Patrik Nelson Fedel Hillary Marsel Boris Nikolay Juna Ivan Liza Karin Helga Josh Morris Wally Brigt Polina Markiz) list = list.map{ |e| [e.to_sym, rand(1500) + 1000] }.to_h result = Speed.new(list) puts "Лучшие (скорость набора #{result.better.first.last})" result.better.each do |e| puts e.first end puts "#{result.med_speed} -- средняя скорость печати" puts 'Скорость печати ниже среднего имеют:' result.low_speed.each do |e| puts "#{e.first} #{e.last}" end 
    1. Why the result.better.med_speed.low_speed (list) construction does not work

    Because at the end of the methods you do not return self , until you return an object of the Speed class, you cannot call its methods.

    • one
      Thank you for learning something for myself and my program. However, I did not understand the moment arr = @list.sort_by { |_k, v| -v } arr = @list.sort_by { |_k, v| -v } Why do we put an underscore in front of the key? And one more question is not quite on the topic of how to embed an array into an array. That is: m1 = [] m2 = [1,2,3] m3 = [4,5,6] ... и чтобы в результате было m1 = [[1,2,3], [4,5,6]] through << \ .push did not work, to my surprise - QWD666
    • @ QWD666 An underscore in front of a variable or sometimes just an underscore denotes a variable that should be present in syntax, but not actually used. In fact, I didn’t even set it up, but rubocop, I just drove the script out of habit, before I drop it here rubocop -a test.rb - cheops
    • one
      @ QWD666, strangely, I didn’t have problems with embedding arrays m1 = [] m2 = [1,2,3] m3 = [4,5,6] m1 << m2 m1 << m3 p m1 But in general, of course, better for new questions, to get new topics - here in the comments it is not very convenient to write and format the code. - cheops