Обновить
89
0
Сергей Шашков@ShashkovS

Менеджер продукта, методист, разработчик

Отправить сообщение
Добавлю, что можно добавить mtproto в автозапуск, используя Systemd.

nano /lib/systemd/system/mtproxyd.service

[Unit]
Description=MTproxy service
After=network.target
StartLimitIntervalSec=0


[Service]
Type=simple
Restart=always
RestartSec=1
User=setup_user  # Юзер должен иметь права к mtproto-proxy, proxy-secret и proxy-multi.conf
ExecStart=/path_to_1/mtproto-proxy -u nobody -p 8888 -H 443 -S you_secret --aes-pwd /path_to_2/proxy-secret /path_to_3/proxy-multi.conf -M 1
# path_to_1, path_to_2, path_to_3 зависит от того, как вы устанавливали

[Install]
WantedBy=multi-user.target

systemctl daemon-reload
systemctl start mtproxyd
systemctl status mtproxyd
systemctl enable mtproxyd


А ещё можно настроить sslh: habr.com/post/412779
Спасибо! У меня был настроенный 3proxy, отлично и стабильно работающий.
Вчера тоже ткнулся с MTProto на CentOS7 — и фиг. Попробую сегодня эту инструкцию.
Это же треш. У вас в последней строчке таблицы с числом цифр несчётное количество последовательностей. И нет последовательности, «следующей» за 0,(0).
Судя по вашим комментариям, вы представляете себе биекцию «вычислимых» чисел (для которых есть алгоритм, вычисляющий каждую цифру) и натурального ряда. Он существует. Но описываете не его. Всё это из-за того, что для бесконечной дроби не может быть следующей дроби. Какой хвост бы не поменяли, всё равно пропустим континуум чисел.
Вроде бы есть достаточно симпатичные www.zennioptical.com, которые за десятку доставляют в РФ. Но всё равно сначала нужен правильный рецепт.
Ну, вообще можно и pdf сделать. Правда теперь мне нужно перелить часть изменений из хабра в оригинальный html. Ещё от коллег была «заявка» на упрощение введения для тех, кто совсем не в теме.
Ну, непосредственного перевода в статье примерно нет. Всё, кроме нескольких предложений, писалось «своими словами».
И да, в статье вообще нет ничего из «теории» такого, чего нет в документации. Документация у питона весьма приличная. И на английском вообще есть суперские ресурсы: www.regular-expressions.info и www.rexegg.com. На последнем так вообще есть такие штуки, что ого-го.

Но мне нужен был понятный последовательный cookbook с привязкой к питону на русском языке, в котором есть все «нужные» штуки.
Ускорения кот наплакал, кроме случая, когда тексты очень-очень короткие. Тогда ускорения 30%.
Берём 10 регулярок.
    r'\b[a-z]+\b',  # слова только из маленьких букв
    r'\b[A-Z]\w+\b',  # слова с заглавной
    r'\b(\w{10})\b',  # слова из 10 символов с сохранением
    r'te\w*st',  # Ищем тест
    r'a\w*b\w*c',  # a*b*c
    r'\(([^)]*)\)',  # (...) с сохранением
    r'\W{3,}',  # Длинные не-слова
    r'[aeiouy]+',  # Только гласные
    r'(?:[aeiouy][bcdfghjklmnpqrstvwxz])+',  # Читаем по слогам
    r'[\s,.!?;]+',  # Для сплит'а


Если берём 1000 текстов по 10000 символов и каждый послед. прогоняем по этим 10 regex:
100000 finditer runs total. 50.33 sec for raw VS 48.33 sec for compiled
Raw      regexp run: 0.000503 seconds per regexp, x0.960 faster
Compiled regexp run: 0.000483 seconds per regexp, x1.041 faster

Если берём 10000 текстов по 1000 символов и каждый послед. прогоняем по этим 10 regex:
1000000 finditer runs total. 50.72 sec for raw VS 50.44 sec for compiled
Raw      regexp run: 5.07e-05 seconds per regexp, x0.994 faster
Compiled regexp run: 5.04e-05 seconds per regexp, x1.006 faster

Если берём 100000 текстов по 100 символов и каждый послед. прогоняем по этим 10 regex:
10000000 finditer runs total. 89.23 sec for raw VS 74.75 sec for compiled
Raw      regexp run: 8.92e-06 seconds per regexp, x0.838 faster
Compiled regexp run: 7.47e-06 seconds per regexp, x1.194 faster

Если берём 500000 текстов по 20 символов и каждый послед. прогоняем по этим 10 regex:
15000000 finditer runs total. 76.47 sec for raw VS 56.42 sec for compiled
Raw      regexp run: 5.1e-06 seconds per regexp, x0.738 faster
Compiled regexp run: 3.76e-06 seconds per regexp, x1.355 faster


Код для тестирования
from time import perf_counter
import re
import random
from string import ascii_lowercase, ascii_uppercase
chars = ''.join(chr(i) for i in range(33, 127))
chars += ascii_uppercase * 1 + ascii_lowercase * 7
chars += ' ' * 30

NUM_RUNS = 10
NUM_TEXTS = 10000
TEXT_LENS = 1000

texts = []
for __ in range(NUM_TEXTS):
    texts.append(''.join(random.choices(chars, k=TEXT_LENS)))

regexps = [
    r'\b[a-z]+\b',  # слова только из маленьких букв
    r'\b[A-Z]\w+\b',  # слова с заглавной
    r'\b(\w{10})\b',  # слова из 10 символов с сохранением
    r'te\w*st',  # Ищем тест
    r'a\w*b\w*c',  # a*b*c
    r'\(([^)]*)\)',  # (...) с сохранением
    r'\W{3,}',  # Длинные не-слова
    r'[aeiouy]+',  # Только гласные
    r'(?:[aeiouy][bcdfghjklmnpqrstvwxz])+',  # Читаем по слогам
    r'[\s,.!?;]+',  # Для сплит'а
]

def test_raw():
    tot = 0
    st = perf_counter()
    for text in texts:
        for regex in regexps:
            tot += sum(1 for m in re.finditer(regex, text))
    en = perf_counter()
    print(f'{tot} matches found in {en-st:0.4} seconds (without compiling)')
    return en-st


def test_compiled():
    tot = 0
    st = perf_counter()
    regexps_compiled = [re.compile(r) for r in regexps]
    for text in texts:
        for regex in regexps_compiled:
            tot += sum(1 for m in regex.finditer(text))
    en = perf_counter()
    print(f'{tot} matches found in {en-st:0.4} seconds (with compiling)')
    return en-st


raw_durs = [test_raw() for __ in range(NUM_RUNS)]
compiled_durs = [test_compiled() for __ in range(NUM_RUNS)]
tot_runs = NUM_RUNS*NUM_TEXTS*len(regexps)
raw_per_regex = sum(raw_durs) / tot_runs
comp_per_regex = sum(compiled_durs) / tot_runs

print(f'{tot_runs} finditer runs total. {sum(raw_durs):.2f} sec for raw VS {sum(compiled_durs):.2f} sec for compiled')
print(f'Raw      regexp run: {raw_per_regex:.3} seconds per regexp, x{comp_per_regex/raw_per_regex:.3f} faster')
print(f'Compiled regexp run: {comp_per_regex:.3} seconds per regexp, x{raw_per_regex/comp_per_regex:.3f} faster')



Спасибо за отзыв! Времени, конечно, очень много ушло. Раза в 3 больше, чем изначально планировал…
ИМХО, re.match — способ отстрелить себе ногу. По имени от re.search фиг отличишь, а поведение совсем другое. re.fullmatch называется понятно: полностью-соответствует.

re.compile частично упомянут в «Прочие фичи».
re.compile добавляет фичу, связанную с указанием позиций в строке, на которые нужно смотреть. Без лишнего среза. Ещё в некоторых случаях немного ускорят работу, но не сильно, так как python кеширует регулярки.

re.match и re.compile в данном контексте вступает в противоречие с куском zen of python:
There should be one-- and preferably only one --obvious way to do it.

Поэтому не стал упоминать.
А вы знаете какие-то реальные применения сверхжадных квантификаторов? Кроме попыток ускорения работы регулярок в некоторых случаях (с риском отстрелить себе ногу, если ошибся)? Про жадность/ленивость у меня пример со скобками такой же по смыслу.

Есть ещё atomic groups, (?>…), это — полезная штука, хотя немного сложная для восприятия. Может быть, добавлю.
Хорошо, что мы не про реальные адреса спорим. Там такой беспредел бывает… :)
Но про локализацию номеров уточню, да.
Да, конечно. Но в JS, например, нет lookbehind и нужно ставить /.../g. Везде есть тонкости именно в использовании регулярок в языке.
Скажем, в bash я бы ре стал писать
rm <регулярка,_которая_в_питоне_делает_то,_что_нужно>
Спасибо, поправил и расширил этот пример.
В \Bвал есть ограничение только на левый край. А на правый — нет.
Если было бы написано \Bвал\B, то да, перевал бы не подошёл, а Перевалка — подошла.
Вообще говоря в домене может не быть ни одной точки. Конечно, никто таких адресов не использует (денег столько нету), но… То есть у кого-нибудь может быть адрес ivanoff@yandex.
(Вроде бы так, где-то про это читал, но пруфлинка пока нет)
Да, уже несколько дней так. Надеюсь, оживёт. Один из немногих визуализаторов, которые умеют
а) python flavor;
б) русские буквы;
Плюс там есть классная отладка
Спасибо, это ценно!
В прошлом году я предлагал своим школьникам написать что-нибудь на kivy. И один из них в итоге даже сделал относительно успешное приложение и даже сумел залить его в магазины приложений google и apple. Но стрясти с него адаптированных инструкций мне пока не удалось :) А у самого пока руки не доходят.

Информация

В рейтинге
Не участвует
Откуда
Россия
Дата рождения
Зарегистрирован
Активность

Специализация

Бэкенд разработчик, Менеджер продукта
Ведущий
Python
Управление проектами
Алгоритмы и структуры данных
Asyncio