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

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

Отправить сообщение

Ужасно не хватает возможности добавлять дополнительные символы «под» клавиши (которые доступны по долгому тапу). Отсутствие этой фичи меня останавливает от перехода на яндекс.клавиатуру или ещё куда-то.

Мне как программисту и как математику это супер-удобно. Под русскими буквами английские как на клаве и наоборот. Под цифрами — символы с клавиатуры. А в допклавиатуре греческие буквы, матсимволы, индексы и степени. Кроме того, у меня ещё есть типографские штуки: длинное тире, кавычки-ёлочки и вот это всё. Поэтому я могу писать сразу вот такое:
«Круто» — α×β − λ² ⩾ x₁ + x₂; x ∈ A; ∀ε>0 ∃δ>0 ∀x:|x-a|<δ => |f(x)−f(y)|<ε

Кажется, что фича эта достаточно дешёвая: у вас уже есть клавиши с несколькими символами «под» ней. Всё, что нужно — дать возможность подсунуть свои настройки.

А можно примеры автоматически сгенерированных комментариев? По BLEU не особо-то оценишь, получилось ли что-то осмысленное. Комменты к коммитам — только в мире розовых пони — лучший образец «перевода» изменений на человеческий язык.

В питоне можно переопределять естественные операции умножения и возведения в степень, чтобы не писать MultiplyMatrix(a, b), а писать коротко a @ b

Для этого нужно определить __matmul__ и __pow__.

А ещё для вычислений с боооольшими числами помогает библиотека gpmy2.

Чтобы считать время выполнения, можно использовать библиотеку timeit, и запускать код десяток раз. Тогда графики будут гладкими, а не такими скачущими.

Код
from timeit import timeit
from gmpy2 import mpz
from matplotlib import pyplot as plt


class Mat2x2:
    __slots__ = ['a', 'b', 'c', 'd', 'use_mpz']

    def __init__(self, a, b, c, d, use_mpz=False):
        self.a = mpz(a) if use_mpz else a
        self.b = mpz(b) if use_mpz else b
        self.c = mpz(c) if use_mpz else c
        self.d = mpz(d) if use_mpz else d
        self.use_mpz = use_mpz

    def __matmul__(x, y):
        ans = x.copy()
        ans @= y
        return ans

    def __imatmul__(x, y):
        x.a, x.b, x.c, x.d = x.a * y.a + x.b * y.c, x.a * y.b + x.b * y.d, x.c * y.a + x.d * y.c, x.c * y.b + x.d * y.d
        return x

    def __pow__(self, exp):
        cur = Mat2x2(1, 0, 0, 1, self.use_mpz)
        base = self.copy()
        while exp:
            if exp & 1:
                exp -= 1
                cur @= base
            else:
                exp >>= 1
                base @= base
        return cur

    def copy(self):
        return Mat2x2(self.a, self.b, self.c, self.d, self.use_mpz)

    def __repr__(self):
        return f'{self.__class__.__name__}({self.a}, {self.b}, {self.c}, {self.d})'


def matrix_fib(n, *, fib_mat=Mat2x2(0, 1, 1, 1)):
    fib_pow = fib_mat ** n
    return fib_pow.d


def matrix_fib_mpz(n, *, fib_mat=Mat2x2(0, 1, 1, 1, use_mpz=True)):
    fib_pow = fib_mat ** n
    return fib_pow.d


def fib(num, key=1):
    fib_1 = 0
    fib_2 = key
    for dec in range(num):
        fib_1, fib_2 = fib_2, fib_1 + fib_2
    return fib_2


setup = 'from __main__ import fib, matrix_fib, matrix_fib_mpz'
number = 10
from_i = 0
till_i = 500000
step = 51237
fib_base = []
run_times_fib = []
run_times_matrix_fib = []
run_times_matrix_fib_mpz = []
for i in range(from_i, till_i, step):
    assert fib(i) == matrix_fib(i)
    t1 = timeit(stmt=f'fib({i})', setup=setup, number=number) / number
    t2 = timeit(stmt=f'matrix_fib({i})', setup=setup, number=number) / number
    t3 = timeit(stmt=f'matrix_fib_mpz({i})', setup=setup, number=number) / number
    fib_base.append(i)
    run_times_fib.append(t1)
    run_times_matrix_fib.append(t2)
    run_times_matrix_fib_mpz.append(t3)
    print(i, t1, t2, t3)

ax = plt.gca()
ax.plot(fib_base, run_times_fib, label='simple fib')
ax.plot(fib_base, run_times_matrix_fib, label='matrix fib')
ax.plot(fib_base, run_times_matrix_fib_mpz, label='matrix fib with mpz')
for x, v1, v2, v3 in zip(fib_base, run_times_fib, run_times_matrix_fib, run_times_matrix_fib_mpz):
    ax.annotate(f'{v1:0.3}', xy=(x, v1))
    ax.annotate(f'{v2:0.3}', xy=(x, v2))
    ax.annotate(f'{v3:0.3}', xy=(x, v3))
ax.set_title('Время на возведение в степень')
ax.set_xlabel('Номер числа Фибоначчи')
ax.set_ylabel('Время на вычисление в секундах')
ax.legend()
plt.show()

Да-да, вон в «соседнем» посте прикручивали похожее на Rust: https://habr.com/ru/post/546208/ (перевод, но всё гораздо подробнее).

А с голосовыми рекламными звонками роботов с «обычных» мобильных номеров вы уже научились бороться? С смс-спамом я бороться через УФАС научился (и мегафон оштрафовали на 500К).
А вот назойливые звонки ещё не «освоил».

a = 7
b = 9
while a:
  a = ~-a
  b = -~b
print(b)
# 16

Пароли, которые вводят сами пользователи, и не хранились в отрытом виде, только солёный хеш. Открытыми хранились пароли школьников, которые должны быть доступны учителю и родителю в открытом же виде. Ибо дети 6-7-8-9 лет пароль свой регулярно не помнят. И возможности сбросить его через почту не имеют. А учителю нужно это на уроке, то есть вот-прямо-сейчас-залогиньтесь, 5 минут ждать кого-то каждый урок — не вариант. Какое бы вы предложили решение с такими требованиями?


Не знаю, какое там сейчас с этим решение. Можно, конечно, нагородить криптографии так, чтобы пароль школьника можно было расшифровать, если известен либо пароль (условно) учителя, либо пароль родителя, либо пароль администратора (каждый из которых не хранится в открытом виде). Но это такое...

Если нет зачатка коренного зуба, то корень молочного зуба не рассасывается (обычно), и молочный зуб не выпадает. У молочных зубов вообще корни почти как у «взрослых», пока они не начинают рассасываться. Ну, почти, на рентгене достаточно необычно выглядит.

Вы — крутые, оборудование — тоже! Рентген прямо в кресле и фрезер для коронок в соседней комнате — огонь!
Снимки зубов до, во время и после лечения — прямо кайф! Только пока к сожалению это работает не совсем идеально: у меня было много зубов и по отдельному много визитов. И разобраться сейчас что и как примерно невозможно. Не у всех зубов есть «фотки», долгий зуб разрезан на два визита странно. Это — крутейшая фича, реально! Дополируйте, и будет огонь. Кажется, не хватает вам какой-то интеграции нормальной: врачу нужно слишком много тыкать мышкой и перевтыкать флешки из одного места в другое, чтобы добавить «фоток».
Например, бывают wifi-флешки, которые в девайсе выглядят на sd-флешка, а снаружи доступны по wifi.


Теперь про тонкости. У меня один зуб — молочный. И он, условно, не 34, а 74. И по нему информацию в приложении увидеть нельзя.


Ещё про цены. Я поймал такую крайне неприятную штуку. В «плане лечения» есть цены, они соблюдаются (если всё по плану), и это — кайф. Но мне не внесли кучу зубов в план лечения до увеличения цены. И это — неприятно, получается, мне нужно было самому трясти врача, чтобы он внёс всё-всё, а не оставил на потом. Я об этом не знал, и… оказалось дороже, чем могло бы...


Ещё про скидки при внесении средств заранее. Супер непрозрачно оно работает. У меня в плане было лечения на 107К. Но если внести 100К, то будет скидка 10%. На что? Я думал, что как в спортивных магазинах: накопил 100к трат — получи скидку 10% навсегда. Но не угадал… Бонусом мне предлагали внести 107к, хотя если скидка применится, то будет 98К. Потом обнаружился ещё зуб, и уже ни скидки, ни старой цены… Ценовая дискриминация, всё понятно, но оказаться под её катком — не очень.


Ещё не хватает удобной связи с врачом после. У меня были вопросы после приёма, но написать вопрос врачу крайне непрямолинейно.

Это они ещё не пытались правильно учесть российскую банковскую комиссию в валюте, выставленную на 365 дней, пересекающих високосный год, списываемую со счёта в другой валюте, которую клиент оплачивает где-то в середине срока. Там могут быть и учёт доходов будущих периодов, и доходы/расходы от встроенных производных инструментов, неотделяемым от основного договора (из-за колебания курсов валют). А ещё для такой комиссии может потребоваться возврат… или клиент её может так и не оплатить… Или оплатить частично…
Jаva нужно писать через русскую «а», а pythоn — через русскую «о». Тогда роботы их не будут видеть, а люди — будут.
common = set(a).intersection(set(b))  # найдём общие элементы
for el in common:
    occurs = min(a.count(el), b.count(el))  # и посчитаем, сколько они встречаются

Простите, не смог пройти мимо. Если a и b — один и тот же набор из 1000 различных чисел, то эта программа пройдет по каждому из списков по 1001 разу. Получится пара миллионов сравнений и прибавлений счётчиков. Короче получилось O(n²).
Ещё очень не хватает отзывов-предупреждений по заправкам. Я вот знаю, что отдельные заправки о-о-о-очень любят «налить» в 42-литровый бак 42-45 литров. Типа нефтьмагистрали, у которых ещё часто цены самые низкие. На небольших доливах невозможно отловить «обвес», а вот если заливаешь доверху сразу, как загорелась лампочка, или в почти пустой бак, то там объём будет очень предсказуемым. Выбор заправки по пути будет как раз подсказывать такие заправки с самой низкой ценой, которые догоняются «обвешиванием».
Странно сравнивать финансовый результат 500 отправок против 10000 отправок.
Нужно было «подкручивать» алгоритмы так, чтобы число писем было примерно одинаковым.
Может «секрет» тупо в том, чтобы отправлять в 20 раз больше писем? Тем более, что «доход» на письмо упал.
У меня такой с tomato-прошивкой «трудится» до сих пор на даче. Все имеющиеся 50Мбит/с выдаёт.

Доход мегафона от спама — порядка 280М. Штрафов за 2019 год было всего 13 — они перечислены в моём постановлении. Вот и считайте…
Между прочим, даже физики могут заказать спам, то есть, рассылку рекламного предложения партнёров: https://target.megafon.ru/ml_catalog/our-clients.html

А у меня другая история, тариф «Административный 500к», по высшему разряду:
br.fas.gov.ru/to/moskovskoe-ufas-rossii/f34252e1-964c-40d3-8291-223dbf528fb5
Но ждать долго: 10.01.2020 спам, 16.01.2020 — жалоба, 23.12.2012 — постановление со штрафом в 0.5М.
ifap
Чтобы дополнительно мотивировать народ, вот пример моего дела, тариф «Административный 500к», по высшему разряду:
br.fas.gov.ru/to/moskovskoe-ufas-rossii/f34252e1-964c-40d3-8291-223dbf528fb5

Смс-спам обошёлся мегaфoну в 500000 рублей (да, 0.5М!)
Но ждать нужно долго: 10.01.2020 спам, 16.01.2020 — жалоба, 23.12.2012 — постановление со штрафом в 0.5М.
Рекомендую Lenovo Legion 5 15ARH05 c Ryzen 7 4800H, если работать с розеткой норм. Проц шикарный. И железяка без винды стоит около 76К. Основной минус — внутри две плашки оперативы по 8, поэтому если хочется нарастить до 32, то нужно две плашки покупать.
Для отладки в расте есть `dbg!` (что для отладки куда удобнее питоновских f-strings).

Информация

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

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

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