Форум сайта python.su
py.user.next, огромное спасибо за пояснение! Теперь намного понятнее.
Но у меня еще пара вопросов…
1. Что конкретно делает вот эта строка? Я понимаю, что это очень похоже на первый вопрос в этом треде, но я туплю… Я понимаю, что к self.cache_index мы обращаемся только если нужно нужного правила нет в cache, но почему тут “минус 1”?
return self.cache[self.cache_index - 1]
def build_match_and_apply_functions(pattern, search, replace): def matches_rule(word): return re.search(pattern, word) def apply_rule(word): return re.sub(search, replace, word) return (matches_rule, apply_rule) def plural(noun): for matches_rule, apply_rule in rules: if matches_rule(noun): return apply_rule(noun) raise ValueError('no matching rule for {0}'.format(noun))
Отредактировано endless_lama (Ноя. 25, 2017 11:58:20)
Офлайн
endless_lamaЕсли у нас есть заполненный кеш и мы начали итератор заново перебирать, то нам надо вернуть первое правило из кеша. При этом нужно запомнить, что первое правило прочитано, чтобы при следующем чтении бралось уже второе правило. Но так как мы первое правило сразу же должны вернуть из функции __next__(), то мы не сможем после возврата из функции переставить индекс кеша внутри функции. Поэтому индекс переставляется до возврата из функции, а во время возврата из функции просто берётся предыдущее значение индекса. Тогда мы выходим и у нас как первое правило вернулось из кеша, так и индекс кеша переставлен на второе правило. При следующем чтении кеша будет читаться второе правило и индекс кеша будет указывать на третье правило.
Что конкретно делает вот эта строка?
endless_lamaПотому что в одном случае это определение функции, а в другому случае это вызов функции.
Почему в одном случае matches_rule(word), а ниже - matches_rule(noun)?
endless_lamaЭто не атрибуты, а аргументы функции. Аргументы функции (или параметры функции) бывают формальными и бывают фактическими. Формальный параметр - это параметр в определении функции. Фактический параметр - это параметр в вызове функции.
Разве атрибуты не должны одинаково в данном случае называться?
def matches_rule(word):
if matches_rule(noun):
if matches_rule('abc'):
>>> def f(n): ... return n * n ... >>> f(3) 9 >>> f(5) 25 >>> x = 4 >>> f(x) 16 >>>
Отредактировано py.user.next (Ноя. 25, 2017 15:10:32)
Офлайн
py.user.next, большое спасибо за объяснения, теперь все намного понятнее! Думаю, в будущем еще не раз буду к Вам обращаться. Может, посоветуете какой-нибудь хороший понятный учебник по Python?
Офлайн
Дальше идет глава про криптарифмы, где рассматривается вот этот код:
import re import itertools def solve(puzzle): words = re.findall('[A-Z]+', puzzle.upper()) unique_characters = set(''.join(words)) assert len(unique_characters) <= 10, 'Too many letters' first_letters = {word[0] for word in words} n = len(first_letters) sorted_characters = ''.join(first_letters) + \ ''.join(unique_characters - first_letters) characters = tuple(ord(c) for c in sorted_characters) digits = tuple(ord(c) for c in '0123456789') zero = digits[0] for guess in itertools.permutations(digits, len(characters)): if zero not in guess[:n]: equation = puzzle.translate(dict(zip(characters, guess))) if eval(equation): return equation if __name__ == '__main__': import sys for puzzle in sys.argv[1:]: print(puzzle) solution = solve(puzzle) if solution: print(solution)
first_letters = {word[0] for word in words} n = len(first_letters) sorted_characters = ''.join(first_letters) + \ ''.join(unique_characters - first_letters)
Офлайн
endless_lamaПервые буквы слов не могут быть нулями. Поэтому он их выносит и складывает в одно место. А потом берёт все размещения (а их дофига) и отбрасывает те из них, которые точно не подойдут, потому что они попадают на нули. А оставшиеся размещения, которые могут подойти, он проверяет уже через вычисление уравнения.
Вроде все понятно, кроме:
Отредактировано py.user.next (Дек. 2, 2017 02:46:46)
Офлайн
py.user.next
Первые буквы слов не могут быть нулями.
characters = tuple(ord(c) for c in sorted_characters) digits = tuple(ord(c) for c in '0123456789')
equation = puzzle.translate(dict(zip(characters, guess)))
Отредактировано endless_lama (Дек. 3, 2017 09:45:09)
Офлайн
Далее автор создает две функции:
Первая преобразует числа в Римские числа:
roman_numeral_map = (('M', 1000), ('CM', 900), ('D', 500), ('CD', 400), ('C', 100), ('XC', 90), ('L', 50), ('XL', 40), ('X', 10), ('IX', 9), ('V', 5), ('IV', 4), ('I', 1)) def to_roman(n): '''converts integers to Roman numerals''' if not (0 < n < 4000): raise OutOfRangeError('Number out of range (must be 1...3999)') if not isinstance(n, int): raise NotIntegerError('non-integers cannot be converted') result = '' for numeral, integer in roman_numeral_map: while n >= integer: result += numeral n -=integer return result
def from_roman(s): '''converts Roman numerals to integers''' result = 0 index = 0 for numeral, integer in roman_numeral_map: while s[index:index+len(numeral)] == numeral: result += integer index += len(numeral) return result
index:index+len(numeral)
Отредактировано endless_lama (Дек. 20, 2017 08:13:42)
Офлайн