Ruby Lab¶
第一天练习¶
第一题¶
打印字符串"Hello, world."
puts "Hello, world."
第二题¶
在字符串"Hello, Ruby."中,找出"Ruby."所在下标
str = "Hello, Ruby."
index = str.index("Ruby")
puts index
第三题¶
打印你的名字十遍
10.times do
puts "m310ct"
end
第四题¶
打印字符串"This is sentence number 1.",其中的数字1会一直变化到10
10.times do |i|
i += 1
puts "This is sentence number #{i.to_s}."
end
第五题¶
从文件运行Ruby程序
控制台运行 ruby 文件名
加分题¶
如果你感觉意犹未尽,还可以写一个选随机数的程序。该程序让玩家猜随机数是多少,并告诉玩家是猜大了还是猜小了
flag = true
while flag
rand_num = rand(10) + 1
puts "Guess a number (1 - 10): "
guess_num = gets.to_i
until guess_num == rand_num
if guess_num > rand_num
puts "Big, guess again:"
guess_num = gets.to_i
end
if guess_num < rand_num
puts "Small, guess again:"
guess_num = gets.to_i
end
end
puts "You are right!"
puts "Do you want to play again (y or n): "
again = gets.chomp.downcase
if again != 'y'
flag = false
end
end
第二天¶
第一题¶
有一个数组,包含16个数字。仅用each方法打印数组中的内容,一次打印4个数字。然后, 用可枚举模块的each_slice方法重做一遍。
each方法
numlist = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16]
group = []
numlist.each do |i|
group.append(i)
if group.length == 4 #获取数组长度并且判断是否为4
group.each {|num| print("#{num} ")}
puts ""
group = []
end
end
第二题¶
** 我们前面实现了一个有趣的树类Tree,但它不具有简洁的用户接口,来设置一棵新树, 为它写一个初始化方法,接受散列表和数组嵌套的结构。写好之后,你可以这样设置新 树:{'grandpa' => { 'dad' => {'child 1' => {}, 'child 2' => {} }, 'uncle' => {'child 3' => {}, 'child 4' => {} } } } **
class Tree
attr_accessor :children, :node_name
def initialize(tree_hash)
# 提取当前节点名和它的子节点 hash
@node_name = tree_hash.keys.first
children_hash = tree_hash[@node_name]
# 递归构建子树
@children = children_hash.map do |child_name, grand_children|
Tree.new({ child_name => grand_children })
end
end
def visit_all(&block)
visit(&block)
children.each { |child| child.visit_all(&block) }
end
def visit(&block)
block.call self
end
end
tree_data = {
'grandpa' => {
'dad' => {
'child 1' => {},
'child 2' => {}
},
'uncle' => {
'child 3' => {},
'child 4' => {}
}
}
}
tree = Tree.new(tree_data)
tree.visit_all { |node| puts node.node_name }
第三题¶
**写一个简单的grep程序,把文件中出现某词组的行全都打印出来。这需要使用简单的正则 表达式匹配,并从文件中读取各行。(这在Ruby中超乎想象地简单。)如果你愿意的话, 还可以加上行号。 **
keyword = ARGV[0] #ARGV返回命令行参数列表
filename = ARGV[1]
File.open(filename).each_with_index do |line,index| #line 是文件中对应的某一行
if line =~ /#{keaword}/
puts "#{index + 1}:#{line}"
end
end
第三天¶
第一题¶
修改前面的CSV应用程序,使它可以用each方法返回CsvRow对象。然后,在CsvRow对象上, 对某个给定标题,用method_missing方法返回标题所在列的值。
# acts_as_csv_module.rb
require 'csv'
module ActsAsCsv
def self.included(base)
base.extend ClassMethods
end
module ClassMethods
def acts_as_csv
include InstanceMethods
end
end
module InstanceMethods
attr_reader :headers, :csv_contents
def read
@csv_contents = []
filename = self.class.to_s.downcase + '.txt'
file = File.open(filename)
@headers = file.gets.chomp.split(', ')
file.each do |row|
@csv_contents << CsvRow.new(@headers, row.chomp.split(', '))
end
end
def each(&block)
@csv_contents.each(&block)
end
def initialize
read
end
end
end
class CsvRow
def initialize(headers, values)
@data = Hash[headers.zip(values)]
end
def method_missing(name, *args)
@data[name.to_s]
end
def respond_to_missing?(name, include_private = false)
@data.key?(name.to_s) || super
end
end
class RubyCsv
include ActsAsCsv
acts_as_csv
end
csv = RubyCsv.new
csv.each do |row|
puts "Name: #{row.name}, Age: #{row.age}, City: #{row.city}"
end