Write a program that recommends how to dress today.

The files are clothes in the format:

название шмотки тип шмотки диапазон температур 

For example,

 шапка-ушанка из зайца шапка (-20, -5) 

or

 шлепанцы ботинки (+20, +30) 

The program asks the user what the temperature is now, and then generates a set of clothes, displays the name on the screen (in the console) one random item of each type (if found): шапка, шарф, кофта, куртка, штаны, ботинки, перчатки.

Clarification:

Under the range can fit 2 or 3 items of each type for example:

 валенки ботинки (-35, -15) унты ботинки (-25, -15) утепленные кроссовки ботинки (-25, -10) 

and if the user enters -18, then all 3 types will come out, and 1 random type is needed, you cannot go outside and put on felt boots on top of the warmed sneakers.

 Какая сегодня температура? -18 Рекомендуется надеть: шапку вязанную, шарф, куртка с мехом, джинсы с начесом, валенки. 

To solve the problem, I created the ClothesItem class

 class ClothesItem attr_accessor :title, :type, :line def initialize(path) File.open(path) do |file| arr = file.readlines @title = arr[0].chomp @type = arr[1].chomp @line = arr[2].chomp end end def in_interval?(t) int1, int2 = @line.gsub(/[() ]/, '').split(',') (int1.to_i..int2.to_i).include?(t) end end 

And here is my unfinished main program (I put the files in the clothes folder)

 require_relative 'clothes_item' puts 'Какая сегодня температура?' temperature = STDIN.gets.chomp.to_i all_clothes = Array.new Dir["#{File.dirname(__FILE__)}/data/*.txt"].each do |path| all_clothes << ClothesItem.new(path) end suit_clothes = Array.new types_of_clothes = Array.new all_clothes.each do |c| if c.in_interval?(temperature) types_of_clothes << c.type suit_clothes << [c.title, c.type] end end 

I can not understand how to do so to display the name of clothes 1 random type of clothing.

I only learn ruby I know how syntax I know a lot of methods, but I’m somehow lacking in logic.

  • 2
    I vote for the closure of this issue as not relevant to the topic, because the work for the author - Vladimir Martyanov
  • Vadis, describe how they themselves tried to solve the problem, otherwise you will just be crushed, and the question may be closed. Thank. - Sasha Chernykh
  • Well I will try to do and apply. And thank you. - Vadis
  • Not bad, however, an Enumerable exercise! Simple, but informative. - D-side
  • Once you have chosen the right temperature, then group them by type and take one random element from each group and get a set. - vitidev

2 answers 2

Well, you began to argue correctly. You need a class for the type of thing. If you talk further - you also need a class in order to store and process collections. For example:

 class ClothesCollection attr_reader :collection def initialize(data_folder, item_class) @collection = Dir[File.join(data_folder, "*.txt")].map do |item_file| item_class.new(item_file) end end def by_temperature(temperature) typed_collection.each_value do |type_group| type_group .find_all { |item| item.in_interval?(temperature) } .example end end private def typed_collection @typed_collection ||= collection.group_by(&:type) end end 

Accordingly, use this:

 collection = ClothesCollection.new(File.expand_path("data", __FILE__), ClothesItem) collection.by_temperature(-5) 

I will make a reservation: the code is far from ideal (for example, nested blocks are not good) and I did not check it for operability. This is just an example.

  • Thank you anoam !!! I myself would not have thought up so accurately. - Vadis

So it turned out, not quite elegant but still worked.

 require_relative 'clothes_item' puts 'Какая сегодня температура?' temperature = STDIN.gets.chomp.to_i all_clothes = Array.new Dir["#{File.dirname(__FILE__)}/clothes/*.txt"].each do |path| all_clothes << ClothesItem.new(path) end suit_clothes = Array.new types_of_clothes = Array.new all_clothes.each do |c| if c.in_interval?(temperature) suit_clothes << c types_of_clothes << c.type end end recommended_clothes = Array.new types_of_clothes.uniq.each do |type| for_rand_name = Array.new suit_clothes.each do |clothes_item| if type == clothes_item.type for_rand_name << clothes_item.title end end # для того чтобы не добавлять nil unless for_rand_name.empty? recommended_clothes << for_rand_name.sample end end puts "Сегодня, из вашего гардероба рекомендую одеть: #{recommended_clothes.join(', ')}." 

I will do another class as suggested by anoam , I think it will be just fine.