Как перебрать, используя .each и очистить данные в Ruby? - PullRequest
0 голосов
/ 13 апреля 2019

Я довольно новичок в программировании и мне нужна помощь / обратная связь по моему коду. Моя цель - очистить местоположение, его данные и затем отобразить эти данные для моего пользователя в нумерованном списке. У меня просто возникают проблемы с отображением этих данных. У меня проблемы с итерацией с использованием метода .each. Я пытался сделать итерацию с travel_details, но она не работает. Какие-либо предложения? Заранее благодарен за любую помощь / обратную связь!

Вывод, который я хочу, будет выглядеть так:

Which location you would like to know more about?
 1. Nairobi, Kenya
2. Juneau, United States
3. Hong Kong
4. Litchfield National Park, Australia
5. Patagonia, Chile
6. Yukon, Canada
7. San Juan, Puerto Rico
8. Panama
9. Matera, Italy
10. Yokohama, Japan

---- ОБНОВЛЕНИЕ ---

Мне удалось обновить мой код. Ниже ввод. Я хотел бы помочь с show_selection и получить методы выбора сейчас. Как только пользователь вводит номер для места, которое он хочет увидеть, код должен посмотреть на массив класса Travel_Cli :: Place.all и поместить соответствующее имя и сводку. Затем он должен отобразить его в методе show_selection. Я думаю, что я должен использовать индекс .find, чтобы увидеть, равен ли он входу, но не уверен, как. В коде я разместил желаемый вывод. Это позволит пользователю решить, о каком месте он хотел бы узнать больше.

# CLI Controller
class TravelCli::Cli

  attr_accessor :locale

def call
  welcome
  list_places
  input = nil
  while input != "exit"
    input = gets.chomp.downcase
  if input == "list"
      list_places
  elsif !(0..10).include?(input.to_i)
      puts "You have not selected a valid option."
  elsif input != "exit"
      @locale = input
      show_selection
    end
    menu
  end
  #goodbye
end


def get_selection
   #Place instance that you will get from Place.all
    #TravelCli::Place.all.each {|place| puts "#{place.summary}"}
    #TravelCli::Place.all.find_index { |p| place.summary == locale } #have to define input
    #TravelCli::Place.find_index {|place| place == @locale }
    TravelCli::Place.all.each_with_index do |place, i|
    if locale == place.name[i+1]
        return true
    end
   #binding.pry
end

def show_selection
  get_selection
  puts "Here is more information about  #{locale}."
  puts
  puts " display details from get_selection"


  #outputs the summary of the input from the place.all array
end

def menu
puts "Type 'exit' to quit"
puts "Type 'list' to list places"
end


def welcome
  puts " Feel Like Traveling? "
  puts "     "
  puts "----10 Of The Best Travel Destinations You Should Visit In 2019-----"
  puts "     "
end

def get_places
  TravelCli::Scrape.scrape_places
end

def list_places
  get_places
  TravelCli::Place.all.each.with_index(1) {|place, i| puts "#{i}. #{place.name}"}
  puts
  puts " Which Location would you like to learn more about?:   "
end


 def goodbye
   puts "Happy Travels!"
 end

end

class TravelCli::Scrape

  URL = 'https://www.buzzfeed.com/louisekhong/bring-me-2019-best-travel-destinations'

    def self.scrape_places
        Nokogiri::HTML(open(URL)).css('.subbuzz').each do |place|
          TravelCli::Place.new(
            place.css('.js-subbuzz__title-text').text.strip,
            place.css('.subbuzz__description').text.strip)
        end
    end
  end
class TravelCli::Place
  attr_accessor :name, :summary, :place

  @@all = []


def initialize(name, summary)
    @name = name
    @summary = summary
    @@all << self
 end

 def self.all
   @@all
 end



end

Ответы [ 2 ]

1 голос
/ 13 апреля 2019

Вы были довольно близко. Вы хотите выяснить, что является контейнером для каждого отдельного местоположения, и зацикливаться на этом. В данном случае это .subbuzz. Каждый .subbuzz имеет .js-subbuzz__title-text (название местоположения) и .subbuzz__description (текст описания). Кроме того, я использовал один массив объектов для представления каждого местоположения, вместо того, чтобы пытаться поддерживать несколько массивов и синхронизировать значения.

В вашем коде также была важная опечатка. Вы инициализировали @travel_details = [], но заполнили его, используя @@travel_details << ele..... @travel_details является переменной экземпляра. @@travel_details является переменной класса. Они совсем другие. Я полагаю, вы получили Undefined method << for nil:NilClass, когда из-за этого запустили свой код.

Если у вас есть какие-либо вопросы по этому поводу, обязательно задавайте!

Код:

# frozen_string_literal: true

require 'nokogiri'
require 'open-uri'

module TravelCli
  Place = Struct.new(:title, :description, :image_url) do
    def to_s
      <<~TEXT
        Title: #{title}
        Description: #{description}
      TEXT
    end
  end

  class Places
    URL = 'https://www.buzzfeed.com/louisekhong/bring-me-2019-best-travel-destinations'

    def self.print
      places = new
      places.scrape

      puts places.list.map(&:to_s).join("\n")
    end

    attr_reader :list

    def scrape
      @list = Nokogiri::HTML(open(URL)).css('.subbuzz').map do |place|
        Place.new(
          place.css('.js-subbuzz__title-text').text.strip,
          place.css('.subbuzz__description').text.strip,
        )
      end
    end

  end
end

TravelCli::Places.print

Выход:

Title: Nairobi, Kenya
Description: Who'll love it: animal loversWhy go in 2019: Thanks to the recent launch of a direct flight route between Nairobi and New York City, spotting elusive lions and leopards on safari is now just that liiiiitttle bit easier. As both Africa's safari capital and one of the continent's fastest growing cities, Nairobi offers a unique contrast between the city and the wild.

Title: Juneau, United States
Description: Who’ll love it: foodiesWhy go in 2019: Juneau, Alaska, is having a foodie moment (I mean, why else would it be hosting the 2019 International Food Blogger Conference?). Focusing on fresh, local seafood and wild fruits, the food scene here is understated, delicious, and eco-friendly by nature. Be sure to check out Salt, an up-and-coming modern Alaskan restaurant that serves food foraged by the chef himself.

Title: Hong Kong
Description: Who’ll love it: solo travelers Why go in 2019: Hong Kong may be a small island, but it's bursting with culture! New and exciting attractions, including museums and a huge cultural center, make it the perfect city to explore solo. M+ Museum is slated to open this year and at 17,000 square meters, it'll be one of the largest museums of modern visual culture in the world. It's also one of the world's safest cities, which is comforting to know if you’re traveling on your own.

Title: Litchfield National Park, Australia
Description: Who'll love it: escapistsWhy go in 2019: With hiking trails through striking landscapes, epic 4WD tracks, and stunning waterfalls that lead to glistening natural pools, a visit to Litchfield National Park will make you forget that the rest of the world exists. Located ~90 minutes south of Darwin, it's smaller than the popular Kakadu National Park (and has fewer tourists!), and it's currently undergoing improvements that'll see new campgrounds and swimming spots open this year.

Title: Patagonia, Chile
Description: Who’ll love it: adventure seekersWhy go in 2019: Any serious adventurer will love the new massive hiking trail that connects 17 different national parks. Created as part of a huge conservation effort, the Route of Parks in Patagonian spans 1,740 miles and takes travelers on a scenic journey through parks like Torres del Paine and San Rafael Lagoon. It's the perfect way to experience some of Chile's incredible natural beauty.

Title: Yukon, Canada
Description: Who'll love it: nature loversWhy go in 2019: The Yukon territory is a prime place to catch a glimpse of the northern lights, and soon you'll be able to see them in a whole new way — on board a private jet! The Aurora 360 is taking flight for the first time in February, but if you don't make it in time for that, camping out in a tent is equally as magical. While you're there, make sure you visit Kluane National Park and Reserve to hike up Mount Logan, Canada's tallest peak.

Title: San Juan, Puerto Rico
Description: Who'll love it: conscientious travelers Why go in 2019: Since the devastation of Hurricane Maria in 2017, Puerto Rico has made huge strides in rebuilding the island and tourism is a key way to keep that regrowth underway. With amazing food (visit the famous Pork Highway just outside of San Juan), colorful architecture, and gorgeous natural beauty, traveling to the island this year doesn’t just benefit Puerto Ricans, but will also be a trip of a lifetime.

Title: Panama
Description: Who'll love it: party goers and beach bumsWhy go in 2019: This year marks the 500 year anniversary of Panama City and a celebration you won't want to miss. Special events such as parades, exhibitions, and musical shows are running until mid-August, but you can party with the locals and explore the historic old town year-round. When you're ready for some R&R, head up north to the blindingly white sand and clear waters of Bocas Del Toro.

Title: Matera, Italy
Description: Who’ll love it: history buffsWhy go in 2019: As one of the world’s oldest continuously inhabited cities, Matera has been named one of 2019’s European Capitals of Culture for its cultural importance (and stunning beauty). Its blend of ancient architecture and modern dining and entertainment is absolutely enchanting. Any place where you can spend days learning about 12th-century churches and nights dining on Italian food in an underground grotto restaurant is a winner for us.

Title: Yokohama, Japan
Description: Who'll love it: sports fansWhy go in 2019: Sporting fever is taking over Japan as it gears up for the 2019 Rugby World Cup in September (and let's not forget the Olympics in 2020). Just over 30 minutes south of Tokyo, the colorful harbor city of Yokohama is home to Japan's largest stadium and will play host to seven games — including the final. The food is also incredible: we recommend visiting the Shin-Yokohama Ramen Museum and snacking your way through Chinatown (it's the biggest in Japan!).
0 голосов
/ 13 апреля 2019

Вот ваша программа, основанная на предыдущем ответе, включая исправление ошибки, связанной с разбиванием предложений в скребке, просто удалите strip:

# frozen_string_literal: true
require 'nokogiri'
require 'open-uri'
require 'pry'

module TravelCli
  Place = Struct.new(:title, :description, :image_url) do
    def to_s
      <<~TEXT
        Title: #{title}
        Description: #{description}
      TEXT
    end
  end

  class Places
    URL = 'https://www.buzzfeed.com/louisekhong/bring-me-2019-best-travel-destinations'

    def self.run
      places = new
      places.scrape
      list = places.list
      output = lambda do
        list.each_with_index{|l, i| puts "#{i+1}. #{l.title}"}
        puts "\nSelect a place by number or type exit: "
      end
      input = ''
      loop do
        output.call
        input = gets.chomp
        break if input == "exit"
        item = list[input.to_i-1]
        puts "\n"
        puts item[:title]
        puts item[:description]
        puts "\n"
      end
    end

    attr_reader :list

    def scrape
      @list = Nokogiri::HTML(open(URL)).css('.subbuzz').map do |place|
        Place.new(
          place.css('.js-subbuzz__title-text').text,
          place.css('.subbuzz__description').text,
        )
      end
    end
  end
end

TravelCli::Places.run

Запустите программу, и вы получите такой вывод:

1. Nairobi, Kenya
2. Juneau, United States
3. Hong Kong
4. Litchfield National Park, Australia
5. Patagonia, Chile
6. Yukon, Canada
7. San Juan, Puerto Rico
8. Panama
9. Matera, Italy
10. Yokohama, Japan

Select a place by number or type exit:
...