代码翻译,从Python到Ruby

时间:2010-01-24 22:44:36

标签: python ruby

我想在Ruby上转换一些Python行,来自Thomas Guest在http://wordaligned.org/articles/drawing-chess-positions

签署的这篇优秀文章

(注意:我是一个非常大的Python菜鸟)

以下是原始Python版本的副本:

def expand_blanks(fen):
    '''Expand the digits in an FEN string into spaces

    >>> expand_blanks("rk4q3")
    'rk    q   '
    '''
    def expand(match):
        return ' ' * int(match.group(0))
    return re.compile(r'\d').sub(expand, fen)

def outer_join(sep, ss):
    '''Like string.join, but encloses the result with outer separators.

    Example:
    >>> outer_join('|', ['1', '2', '3'])
    '|1|2|3|'
    '''
    return '%s%s%s' % (sep, sep.join(ss), sep)

def ascii_draw_chess_position(fen):
    '''Returns an ASCII picture of pieces on a chessboard.'''
    pieces = expand_blanks(fen).replace('/', '')
    divider = '+-+-+-+-+-+-+-+-+\n'
    rows = ((outer_join('|', pieces[r: r + 8]) + '\n')
            for r in range(0, 8 * 8, 8))
    return outer_join(divider, rows)

用法示例:

>>> fen = "r2q1rk1/pp2ppbp/1np2np1/2Q3B1/3PP1b1/2N2N2/PP3PPP/3RKB1R"
>>> print ascii_draw_chess_position(fen)
+-+-+-+-+-+-+-+-+
|r| | |q| |r|k| |
+-+-+-+-+-+-+-+-+
|p|p| | |p|p|b|p|
+-+-+-+-+-+-+-+-+
| |n|p| | |n|p| |
+-+-+-+-+-+-+-+-+
| | |Q| | | |B| |
+-+-+-+-+-+-+-+-+
| | | |P|P| |b| |
+-+-+-+-+-+-+-+-+
| | |N| | |N| | |
+-+-+-+-+-+-+-+-+
|P|P| | | |P|P|P|
+-+-+-+-+-+-+-+-+
| | | |R|K|B| |R|
+-+-+-+-+-+-+-+-+

我试图做一些修改来转换Ruby中的每一行......我想知道它是不是很糟糕的开始:s但是我还是发布了它:

def expand_blanks(fen)
  def expand(match)
    return ' ' * int(match.group(0))
  end

  # bugged:
  re.compile(r'\d').sub(expand, fen)
end

def outer_join(sep, ss)
  sep + sep.join(ss) + sep
end

def ascii_draw_chess_position(fen)
  pieces = expand_blanks(fen).replace('/', '')
  puts pieces.class
  divider = "+-+-+-+-+-+-+-+-+\n"

  # bugged lines:
  rows = ((outer_join('|', pieces[r, r + 8]) + '\n')
  for r in range(0, 8 * 8, 8))
    return outer_join(divider, rows)
  end
end

fen = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR"
puts ascii_draw_chess_position(fen)

如果你看到我可以解决的一些问题,那对我来说会很酷。谢谢大家。

2 个答案:

答案 0 :(得分:2)

依次查看每个方法,从outer_join开始。

在Python中,join是一个字符串上的方法,它接受一个序列并连接由字符串分隔的元素。例如'|'.join(['p, 'p', 'p'])

在Ruby中,join是数组上的一种方法,它将分隔符作为参数,例如['p', 'p', 'p'].join('|')

因此outer_join的Ruby版本将是:

def outer_join(sep, ss):
  sep + ss.join(sep) + sep
end

接下来看一下expand_blanks,这里的意图是用等效的空格数替换一个数字。在Ruby中,可以使用gsub来替换字符串中所有出现的模式。可以使用将在每个匹配子字符串传递的块调用gsub,并返回应该替换匹配的字符串。所以Ruby代码将是:

def expand_blanks(fen)
  fen.gsub(/\d/) { |match| ' ' * match.to_i }
end

最后在ascii_draw_chess_position我们可以再次使用gsub作为Python的replace方法的等价物,并使用Ruby的map函数代替使用列表推导所实现的功能Python如下:

def ascii_draw_chess_position(fen)
  pieces = expand_blanks(fen).gsub('/', '')
  divider = "+-+-+-+-+-+-+-+-+\n"
  rows = (0...8).map do |i|
    row = pieces[i * 8...(i + 1) * 8].split('')
    outer_join("|",row) + "\n"
  end
  puts outer_join(divider, rows)
end

如果您需要更多有关上述内容的详细信息,请与我们联系。

答案 1 :(得分:1)

这将做你想要的:

def expand(match)
  ' ' * match.to_i
end

def expand_blanks(fen)
  fen.gsub(/\d/) {|d| expand d}
end

def outer_join(sep, ss)
  sep + ss.join(sep) + sep
end

def ascii_draw_chess_position(fen)
  pieces = expand_blanks(fen).gsub('/', '')
  divider = "+-+-+-+-+-+-+-+-+\n"
  rows = (0...8).collect do |i|
    row = pieces[i*8...(i+1)*8].split('')
    outer_join("|",row) + "\n"
  end
  puts outer_join(divider, rows)
end

如果您有任何不明白的代码,请告诉我 - 但请确保您已查看ruby docs

中的方法

如果您对ruby和python之间的差异感兴趣,请参阅此处https://stackoverflow.com/questions/234721/what-are-the-biggest-differences-between-python-and-ruby-from-a-philosophical-perhttp://www.ruby-lang.org/en/documentation/ruby-from-other-languages/to-ruby-from-python/,有关一些好的示例,请参阅http://ruby.brian-amberg.de/editierdistanz/