跳转至

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