Перевод кода с Python на Ruby - PullRequest
       5

Перевод кода с Python на Ruby

2 голосов
/ 25 января 2010

Я хотел бы преобразовать несколько строк Python на Ruby из этой замечательной статьи, подписанной Томасом Гестом по адресу: http://wordaligned.org/articles/drawing-chess-positions

(примечание: я действительно больше Noob 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 ]

2 голосов
/ 25 января 2010

Рассматривая каждый метод по очереди, начиная с outer_join.

В Python join - это метод для строк, который принимает последовательность и объединяет элементы, разделенные строкой. например '|'.join(['p, 'p', 'p'])

В Ruby join - это метод для массивов, который принимает разделитель в качестве аргумента, например ['p', 'p', 'p'].join('|')

так что Ruby-версия outer_join будет:

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 в качестве эквивалента методу replace в Python и использовать функцию map в Ruby вместо того, что было достигнуто с помощью понимания списка в 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 голос
/ 25 января 2010

Это будет делать то, что вы хотите:

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-per или http://www.ruby -lang.org / ru / Documentation / ruby-from-other-languages ​​/ to- ruby-from-python / и несколько хороших примеров см. в http://ruby.brian -amberg.de / editierdistanz / .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...