ruby 查看csv文件_如何使用CSV和Ruby构建终端游戏

ruby 查看csv文件

by Andrew Bales

通过安德鲁·巴尔斯

如何使用CSV和Ruby构建终端游戏 (How you can build a terminal game with CSV and Ruby)

In this article, you’ll learn how to build a terminal game with a CSV and a few Ruby gems! See a demo in the video above, and find the code on GitHub.

在本文中,您将学习如何使用CSV和一些Ruby gem构建终端游戏! 观看上面的视频中的演示,并在GitHub上找到代码。

This project comes from a lecture I gave at Ada Developers Academy in Seattle. The topic was the Ruby CSV library, and I wanted a fun way to illustrate its methods and potential.

这个项目来自我在西雅图Ada开发人员学院的一次演讲。 主题是Ruby CSV库,我想以一种有趣的方式来说明其方法和潜力。

In class, we discussed how most people use programs like Excel to create and edit CSVs. They make updates by clicking cells and changing values. But the question for us became: what can we do with a CSV if we approach it as programmers? Using a programming language like Ruby, how can you open, read, and manipulate those values? Can those orderly rows and columns become a database for an application?

在课堂上,我们讨论了大多数人如何使用Excel之类的程序来创建和编辑CSV。 他们通过单击单元格并更改值来进行更新。 但是对我们来说,问题变成了:如果以程序员的身份使用CSV,该怎么办? 使用像Ruby这样的编程语言,如何打开,读取和操纵这些值? 那些有序的行和列可以成为应用程序的数据库吗?

This article covers those questions in three sections:

本文分三部分介绍了这些问题:

  1. Comma-separated values

    逗号分隔值
  2. Ruby’s CSV library: creating, opening, appending, using headers

    Ruby的CSV库:使用标头创建,打开,追加
  3. Building the game

    制作游戏

逗号分隔值 (Comma-Separated Values)

CSV stands for comma-separated values, and that’s exactly what it sounds like. If you’ve ever opened one of these files in a program like Excel, you’ve seen these values rendered in a spreadsheet.

CSV代表用逗号分隔的值,这听起来确实如此。 如果您曾经在Excel之类的程序中打开过这些文件之一,则已经在电子表格中看到了这些值。

However, if you were to open that same file in a text editor like Atom or Sublime, you’d find a series of — you guessed it — comma-separated values. As you see below, Excel uses those raw values to render a user-friendly table.

但是,如果要在诸如Atom或Sublime之类的文本编辑器中打开相同的文件,则会发现一系列(用猜测的方式)用逗号分隔的值。 如下所示,Excel使用这些原始值来呈现用户友好的表。

快速设置 (Quick Setup)

It’s easiest to follow along if you download this GitHub repository. Once you’ve done that, navigate to that folder in your terminal. This repo includes all of the examples below, so please know that you’ll need to comment out sections that you don’t want to run.

如果下载此GitHub存储库 ,则最容易遵循。 完成此操作后,导航至终端中的该文件夹。 此回购包括所有 下面的示例中的所有示例,因此请注意,您需要注释掉不想运行的部分。

Also, you’ll want to install Awesome Print, which beautifies terminal output:

另外,您将需要安装Awesome Print ,它可以美化终端输出:

gem install awesome_print

Ruby的CSV库 (Ruby’s CSV Library)

Ruby comes with a CSV library that allows us to open, read, and manipulate CSV files.

Ruby带有CSV库 ,该库允许我们打开,读取和操作CSV文件。

创建CSV (Creating a CSV)

Let’s start by making our own CSV. In the Github repo, you’ll find planets.rb. This file begins by setting the variable planets equal to a two-dimensional array (an array of arrays).

让我们开始制作自己的CSV。 在Github存储库中,您将找到planets.rb。 该文件首先将可变行星设置为等于二维数组(数组的数组)。

In each, we have planet attributes: id, name, mass, and distance. We’ve assigned the attribute names to the headers variable as another array.

在每一个中,我们都有行星属性:id,名称,质量和距离。 我们已经将属性名称分配给headers变量作为另一个数组。

require 'csv'require 'awesome_print'
planets = [  [1, "Mercury", 0.055, 0.4],  [2, "Venus", 0.815, 0.7],  [3, "Earth", 1.0, 1.0],  [4, "Mars", 0.107, 1.5]]headers = ["id", "name", "mass", "distance"]CSV.open("planet_data.csv", "w") do |file|  file << headers  planets.each do |planet|    file << planet  endend

Above, CSV.open accepts up to three arguments:

上面的CSV.open最多接受三个参数:

CSV.open(file name, mode, options)

We have given it a file name (planet_data.csv). Because we have also given the mode of “w” (Write-only), it creates a new file for us even if it didn’t exist already. No options were passed in this time.

我们给了它一个文件名(planet_data.csv)。 因为我们还给了“ w”模式(仅写),所以即使它不存在,它也会为我们创建一个新文件。 这次没有通过任何选项。

The following block does a few things:

以下块执行一些操作:

  1. It adds the headers array to the file we’ve created. This creates a single row with four columns — each with a string entry of the property name.

    它将headers数组添加到我们创建的文件中。 这将创建一个包含四列的单行,每列都有一个属性名称的字符串条目。
  2. We use planets.each to iterate through the planet array (filled with info about its id, name, and so on) and append each entry as an individual row.

    我们使用planets.each遍历Planet数组(填充有关其ID,名称等的信息),并将每个条目附加为单独的行。

If you run this bit of code, you’ll find the following CSV has been created:

如果运行这段代码,您将发现已创建以下CSV:

模式 (Modes)

Above, we used “w” as our mode to write a new file. You have a number of other options available to you, depending on the task at hand. The biggest factors to consider are if you want to read and/or write, and where in the CSV you’d like to start your work.

上面,我们使用“ w”作为写入新文件的方式。 根据手头的任务,您还有许多其他选项可用。 要考虑的最大因素是您是否要阅读和/或书写,以及您想在CSV中的何处开始工作。

For instance, if you are using the file to populate your website with listings, “r” (read-only) would be an appropriate mode. If you want to add new planets to your CSV, the “a” mode (append read-write) would begin at the end of the file and immediately let you append those rows.

例如,如果您使用该文件在列表中填充网站,则“ r”(只读)将是一种合适的模式。 如果要将新的行星添加到CSV,则“ a”模式(附加读写)将在文件末尾开始,并立即让您附加这些行。

Here’s a complete list of modes:

这是模式的完整列表:

“r”  Read-only, starts at beginning of file (default mode).“r+” Read-write, starts at beginning of file.“w”  Write-only, truncates existing file to zero length.“w+” Read-write, truncates existing file to zero length.“a”  Append write-only, starts at end of file if file exists.“a+” Append read-write, starts at end of file if file exists.“b”  Binary file mode.“t”  Text file mode.
追加中 (Appending)

We can append a new planet to planet_data.csv like this:

我们可以像这样将新的行星添加到planet_data.csv:

CSV.open("planet_data.csv", "a") do |file|  file << [5, "Jupiter", 1234, 3321]end

In the mode list above, “a” is “write-only” and “starts at end of file.” So Jupiter’s information will be inserted at the end of the existing CSV.

在上面的模式列表中,“ a”是“只写”,并且“在文件末尾开始”。 因此,木星的信息将插入到现有CSV的末尾。

反复进行 (Iterating)

Because .open with the “r” mode will return an array of arrays, we can use .each to iterate over the rows. The code below will print every row of the CSV in the terminal.

因为使用“ r”模式的.open将返回一个数组数组,所以我们可以使用.each遍历行。 下面的代码将在终端中打印CSV的每一行。

CSV.open("planet_data.csv", "r").each do |row|  ap rowend

You can take this a step further to create interpolated sentences!

您可以更进一步以创建内插句子!

CSV.open("planet_data.csv", "r").each do |row|  ap "#{row[1]} has a mass of #{row[2]} and distance of #{row[3]}."end

This is great, but it could be a bit better. We’re having to use indices (1, 2, 3) to access the data. This is prone to errors and generally no fun. Next, we’ll see how to fix this by passing in options.

这很好,但可能会更好。 我们必须使用索引(1、2、3)来访问数据。 这容易出错,并且通常没有乐趣。 接下来,我们将看到如何通过传入选项来解决此问题。

使用标题 (Using Headers)

When you add in the option for headers to be true, you’ll get back a new CSV::Table object.

当您添加标头为true的选项时,您将获得一个新的CSV :: Table对象。

csv_with_headers = CSV.open("planet_data.csv", "r", headers: true, header_converters: :symbol)csv_with_headers.each do |row|  ap rowend

Reading with headers and converting those headers to symbols, we will get back a unique object: an array of hashes. That means it’s possible to iterate through each row as we did before, but then we can also use the symbols in the hash to isolate key data.

阅读标头并将这些标头转换为符号,我们将获得一个唯一的对象:一个哈希数组。 这意味着可以像以前一样遍历每一行,但是随后我们还可以使用哈希中的符号来隔离关键数据。

If we return to the sentence example, it becomes:

如果我们回到句子示例,它将变为:

CSV.open("planet_data.csv", "r", headers: true, header_converters: :symbol).each do |row|  ap "#{row[:name]} has a mass of #{row[:mass]} and distance of #{row[:distance]}."end

That’s much more readable than the number indices we used before!

这比我们之前使用的数字索引更具可读性!

When headers are set to true, the library gives us the CSV::Table object, which also gives us access to some handy methods. Below, .read is synonymous with .open in the “r” mode:

将标头设置为true时,该库将为我们提供CSV :: Table对象,这也使我们可以访问一些方便的方法。 下面,“ read”在“ r”模式下与.open是同义词:

csv = CSV.read("planet_data.csv", headers: true, header_converters: :symbol)ap csv               # ap csv.headers       # Returns an array of headersap csv.by_col[:id]   # Array of id column dataap csv.by_col[:name] # Array of name column dataap csv.by_row[0]     # Entire row at 0 (or any position)ap csv[:name][3]     # Name of the 3rd entry => "Mars"ap csv[3][:name]     # 3rd row's name => "Mars"

建立太阳系游戏! (Building a Solar System Game!)

We know how to open and use data in a CSV file with Ruby, so let’s put those methods to work to make a solar system game.

我们知道如何使用Ruby打开和使用CSV文件中的数据,因此让我们将这些方法用于制作太阳系游戏。

建立 (Setup)

You’ll need to install Catpix and Launchy. Catpix allows illustrations in the terminal and Launchy lets us to control a browser window. In the terminal:

您需要安装Catpix和Launchy。 Catpix允许在终端中显示插图,而Launchy则允许我们控制浏览器窗口。 在终端中:

gem install catpix gem install launchy
CSV作为数据库 (CSV as a Database)

You may want to open “Solar System.csv” in Excel to visually get a sense of the attributes for each entry. Once you’re comfortable with the data, we’ll use Ruby to read the CSV file and assign it to a global variable ($solar_system_data). This will serve as our database.

您可能需要在Excel中打开“ Solar System.csv”,以直观地了解每个条目的属性。 熟悉数据后,我们将使用Ruby读取CSV文件并将其分配给全局变量($ solar_system_data)。 这将用作我们的数据库。

As the game opens, we welcome the user TO THE SOLAR SYSTEM! and create that database like so:

游戏开始时,我们欢迎用户使用太阳能系统! 并像这样创建该数据库:

require 'catpix'require 'launchy'$solar_system_data = CSV.read("Solar System.csv", headers: true, header_converters: :symbol)
ap "WELCOME TO THE SOLAR SYSTEM!"

The game really starts up when we call the method explore_planet. That method contains this code:

当我们调用explorer_planet方法时,游戏真的开始了。 该方法包含以下代码:

ap $solar_system_data.by_col[:name]prompt = "Where would you like to start? 0 - #{$solar_system_data.length}"
ap promptinput = gets.chomp
until $selected_planet && /\d/.match(input)  ap prompt  input = gets.chomp  $selected_planet = $solar_system_data[input.to_i]end
ap $selected_planet

Above, the terminal prints all of the names from the “name” column. It then asks the user select an entry between the first (0-index) to the last (our data length). This is a good point to pause to consider the following:

上方,终端从“名称”列中打印所有名称。 然后,它要求用户在第一个(0索引)到最后一个(我们的数据长度)之间选择一个条目。 这是暂停考虑以下内容的好方法:

Question: If we’ve used headers in order to get a hash, how can solar_system_data.length == 14?

问题:如果我们使用标头来获取哈希,那么solar_system_data.length == 14怎么能?

Answer: This CSV::Table may look like a hash, but it’s actually an array of hashes. Therefore, it has a length and we can iterate through each hash. To select the correct record, we just need to convert the input from a string to an integer (.to_i)

答:这个CSV :: Table 看起来像一个哈希,但实际上是一个哈希数组。 因此,它有一个长度,我们可以遍历每个哈希。 要选择正确的记录,我们只需要将输入从字符串转换为整数(.to_i)

You’ll also see that we used an until statement. This validates the selection — requesting a response until the user gives us a valid number. Once a proper selection is made, the terminal prints out the planet info.

您还将看到我们使用了直到语句。 这可以验证选择-请求答复,直到用户给我们有效的号码为止。 正确选择后,终端会打印出行星信息。

The user can then pick if they want to LEARN about or SEE the planet:

然后,用户可以选择是否要了解或查看行星:

prompt = "Do you want to LEARN or SEE?"ap prompt
while input = gets.chomp  case input.downcase  when "learn"    Launchy.open($selected_planet[:uri])    return  when "see"    Catpix::print_image $selected_planet[:image]    return  else    ap prompt  endend

Similar to before, a while statement is used to make sure we get a valid entry. This time, it either uses Launchy to open the associated URI for the planet or prints the image in the terminal with Catpix.

与之前类似,while语句用于确保我们获得有效的条目。 这次,它要么使用Launchy打开行星的关联URI,要么使用Catpix在终端中打印图像。

The game has one more piece of functionality. This is held in the select_attribute method. We use the CSV methods we’ve just covered to return specific attributes for every planet in our database.

游戏还具有一项功能。 这保存在select_attribute方法中。 我们使用刚刚介绍的CSV方法返回数据库中每个行星的特定属性。

ap "Which attribute do want to see for each planet (ex: number_of_moons)?"
ap $solar_system_data.headers.to_sattribute = gets.chomp
ap "Here are the #{attribute} findings:"
$solar_system_data.each do |row|  ap "#{row[:name]} --> #{attribute}: #{row[attribute.to_sym]}"end

First, we print out all of the headers as strings. This gives the user a list of attributes to pick from. With the user response, we can list out the planet name along with the attribute requested and its value.

首先,我们将所有标题打印为字符串。 这为用户提供了可供选择的属性列表。 通过用户响应,我们可以列出行星名称以及所请求的属性及其值。

Finally, they can SELECT another attribute or start over and EXPLORE individual planets:

最后,他们可以选择另一个属性,或者重新开始并探索各个行星:

prompt = "SELECT another attribute or EXPLORE another planet?"ap prompt
while input = gets.chomp  case input.downcase  when "select"    select_attribute()  when "explore"    explore_planet()  else    ap prompt  endend

I hope this helps clarify CSV methods and gets you excited to make your own games.

我希望这有助于阐明CSV方法,并使您兴奋地制作自己的游戏。

If you expand on this one or design something new, leave a comment. I’d love to see what you come up with!

如果您对此进行扩展或设计新的东西,请发表评论。 我很乐意看到您的想法!

翻译自: https://www.freecodecamp.org/news/how-you-can-build-a-terminal-game-with-csv-and-ruby-a269f17b88b0/

ruby 查看csv文件

你可能感兴趣的:(数据库,python,java,linux,大数据)