Евгений Степанищев

Эксперт в области разработки веб-приложений и безопасности в интернете. Каждый месяц мой блог посещают около 90 тысяч человек. Работаю техническим директором в «Системах документооборота», занимаюсь электронным правительством.

Ерунда на itertools и генераторах

Я люблю itertools и генераторы в Пайтоне, но как-то по работе пока не удаётся их применить, поэтому, чтобы не завять, приходится время от времени писать всякую ерунду.

Прочитал тут на «Хабре», что дробь 1/998001 даёт последовательность из чисел от нуля до 997. Вот я и написал код с использованием генераторов и itertools, который берёт эту дробь и выводит из неё все числа последовательно, пока не попадутся числа с разницей не равной единице.
from decimal import Decimal, getcontext
from itertools import groupby, islice, izip, takewhile, chain, imap

getcontext().prec = 3000

n = (
    groupby(
        enumerate(
            islice(str(1 / Decimal(998001)), 2, None)
        ),
        lambda n: n[0] // 3)
    )

n = (int(''.join(n[1] for n in n[1])) for n in n)

n = chain(*takewhile(lambda n: n[1] - n[0] == 1, izip(n, n)))

print ', '.join(imap(str, n))
Кстати, для вычисления дроби с точностью до трёхтысячного знака, используется модуль decimal.

Подумалось, что многим, наверное, было интересно сравнить как выглядит эквивалентный код на Пайтоне без всех этих страшных (на взгляд большинства) ленивых выражений. А то некоторые ребята по моей вине уже думают, что Пайтон какой-то адский язык. Ничего подобного. Вот, посмотрите, более традиционное решение:
from decimal import Decimal, getcontext

getcontext().prec = 3000

number, prev, out = str(1 / Decimal(998001)), -1, []

for i in xrange(2, len(number), 3):
    curr = int(number[i:i+3])

    if curr - prev != 1: break

    prev = curr
    out.append(str(curr))

print ', '.join(out)
17 комментариев
28 января 2012 17:14

Некоторые проблемы SQLite

Товарищ Адепт пишет в ЖЖ про проблемы SQLite. Если вкратце, то выявлены минимум две проблемы.

SQLite при снятии дампа «CREATE VIEW» выписываются в порядке создания. Если у нас две вьшки, «A» и «Б», созданные в порядке перечисления и мы пересоздаём вьюху «А» с использованием «Б», то при заливке дампа будет ошибка — в дампе-то первым будет создание вьюшки «А», которая попытается использовать несуществующую вью «Б».

Если создана вью, в конце которой комментарий стоит, то и в дампе будет комментарий в конце строки создания, экранирующий конечную точку с запятой.
create view commented_view
  as select something
       from some_table -- pretty useless view;
create view another_view as…
5 комментариев
28 января 2012 11:44