Pull to refresh
86
0.1
Сергей Шашков @ShashkovS

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

Send message

XRay и раздельное туннелирование — просто мечта!
Было бы круто сделать так, чтобы при раздельном туннелирование в случае проблем с VPN приложение просто не получало доступ в интернет. Иногда хочется иметь «чистый» браузер, и очень не хочется, чтобы он по случайности вышел в интернет не через туннель.
Ну и MacOS не хватает...

Справедливости ради «типичному» программисту не нужно думать. В том смысле, что ему нужно любым приемлемым способом решить конкретную задачу бизнеса, ему не за «думать» платят. Думать программистам приходится тогда, когда бизнес не знает точно, чего хочет, или когда задача достаточно сложна, чтобы не было очевидных способов её решить так, чтобы не жалеть об этом в будущем.
Вот и GPT через пару лет так и не будет думать, просто будет выдавать на грамотно написанный промпт сразу «бездуховное» решение всё более и более сложных задач.

отправлять конкретному пользователю сообщения чаще чем раз в секунду

А лимиты того же, но в рамках одного и того же получателя у вас есть? По факту можно гораздо больше сообщений в секунду отправлять, скажем 20. Но такие «ускорения» должны быстро заканчиваться. Хотелось бы конкретики.

Ну только когтеточки правда ценный артефакт: кошки их любят драть примерно поголовно.

Для больших корпораций выбор между монорепой и сотнями-тысячами репозиторев. Если обновили что-то «системное», то может потребоваться дорабатывать десятки репозиторев, которые ещё нужно найти-вычислить. И синхронная работа с изменениями по этим десяткам реп — та ещё дрянь.

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

Но цена у монорепы тоже «велика».

Пока ещё не придумал, что делать с обучением печати. Но с владением мышкой сейчас у меня пока такой «рецепт»: играем вместе в Age of Empires II.

Гипотеза: обычные и супер-группы по-разному шардируются или что-то ещё такое с расположением по физическим серверам для оптимизации доступа.

Добавить к lodash или webpack — и пусть весь frontend-мир подождёт (превратится в тыкву). У них больше 1М загрузок в сутки. А на lodash — больше 60К зависимостей.

«уязвимость» в том, что если проект почему-то требует слишком много оперативки/ресурсов, то npm ломается. Вместо «npm ломается» должен быть внятный memory limit error. А уж почему он требует слишком много — можно разбираться потом. И можно даже забанить автора «злого» пакета за abuse системы.

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

Вот эта страница https://learn.javascript.ru/class (и следующие за ней) куда более информативна.

У питона, безусловно, есть свои проблемы.
Но в смысле универсального доступа к "достижениям человечества" у питона немного альтернатив. У Kotlin и C# есть свои ниши, не вполне универсальные.

ИМХО, у обучения C++ как первому языку программирования должна быть какая-то внятная мотивация. Условно, если хочется школьником взять всеросс по информатике, то от C++ не уйдёшь. Плюсы — сложный язык с очень сложным взаимодействием с библиотеками.

В моём случае речь о питоне.
Так что завтра — точно. Через пять лет — не факт, но это и не важно: если 5 лет не пользоваться языком, то всё забудется.
Ну, то есть одна из моих личных мысленных KPI при обучении программированию: доля школьников, которые в пределах года после обучения смогли решить какую-то свою задачу при помощи программирования.

Ох уж эти ценители стюардесс

Если серьёзно, то когда-то давно ~25 лет назад Pascal был моим вторым языком программирования после года с basiс и каким-то учебником. И тогда мне требовалось полгода, чтобы на Pascal сделать что-то интересное и красивое.
Может быть, PascalABC и вправду чем-то хорош как учебный язык. Но я как преподаватель не хочу связываться с подобными учебными языками: ученики может и поймут какие-то концепции лучше, но в большинстве своём никогда в своей жизни ни для какой своей потребности им не воспользуются. То есть обучение пройдёт только ради обучения.

Классная идея и реализация!
Было бы любопытно сравнить этот результат с каким-нибудь Javascript-движком.

Слово должно быть другое. Например, «Передохнуть»

А что в итоге с производительностью? Я как-то в надежде на ускорение от перехода на python3.11 обновил версию sanic'а и обвязки и... получил ощутимое ухудшение производительности плюс непонятные покебания по памяти. Пришлось откатить всё назад, так как необходимости в обновлении версии не было. Но у нас было 100-200prs.

Чтобы на этой странице было побольше полезно, то приведу два примера как быстро считать числа Фибоначчи при помощи матриц 2×2 и чисел вида a+b√5.
Мы реализуем класс матриц с операцией умножения и возведения в степень.
И класс чисел вида a+b√5 с основной арифметикой.

По формуле Бине $$F_n = \dfrac{ \frac{1+\sqrt5}{2}^n - \frac{1-\sqrt5}{2}^n }{\sqrt{5}}$$
А с матрицами Фибоначчи лезет при возведении матрицы (1 1) (1 0) в степень. А в степень можно возводить быстро.

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

    def __init__(self, a, b, c, d):
        self.a = a
        self.b = b
        self.c = c
        self.d = d

    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)
        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)

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


class R5:
    def __init__(self, a=0, b=0):
        self.a = a
        self.b = b

    def __repr__(self):
        return f'R5({self.a}, {self.b})'

    def __str__(self):
        if self.a and self.b:
            return f'({self.a}{self.b:+}√5)'
        elif self.b:
            return f'{self.b}√5'
        else:
            return f'{self.a}'

    def __add__(x, y):
        return R5(x.a + y.a, x.b + y.b)

    def __sub__(x, y):
        return R5(x.a - y.a, x.b - y.b)

    def __mul__(x, y):
        return R5(x.a * y.a + x.b * y.b * 5, x.a * y.b + x.b * y.a)

    def __pow__(x, power):
        if power == 0:
            return R5(1, 0)
        elif power % 2 == 1:
            return x * (x ** (power - 1))
        else:
            sq = x ** (power // 2)
            return sq * sq

    def __floordiv__(x, n):
        return R5(x.a // n, x.b // n)


def fib_stupid(n):
    c, p = 0, 1
    for _ in range(n):
        c, p = c + p, c
    return c


def fib_bine(n):
    return (R5(1, 1) ** n - R5(1, -1) ** n).b // 2 ** n


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


# Проверка корректности
for i in range(0, 100):
    assert fib_bine(i) == fib_stupid(i) == fib_matrix(i)

print(fib_matrix(100))

Вместо длинного и уникального для каждой таблицы

# Преобразуем результаты в список словарей
users_list = []
for user in users:
  user_dict = {
    'id': user[0],
    'username': user[1],
    'email': user[2],
    'age': user[3]
  }
users_list.append(user_dict)

можно писать короткое и универсальное

connection.row_factory = sqlite3.Row

Тогда все fetch'и будут возвращать не кортежи, а словаре-кортежи — можно обращаться к полям и по индексу, и по имени.

Справедливости ради mutable default, который определяется в момент создания функции, позволяет коротко писать функции, которым нужно что-то хранить между вызовами:

def do_some(x, *, _counter=[0]):
    _counter[0] += 1
    return x, _counter[0]

print(do_some('foo'))  # ('foo', 1)
print(do_some('boo'))  # ('boo', 2)
const do_some = (() => {
    let _counter = 0;
    return (x) => {
        _counter += 1;
        return [x, _counter];
    };
})();

console.log(do_some('foo'));  // ['foo', 1]
console.log(do_some('boo'));  // ['boo', 2],

Без этого нужно либо делать глобальную переменную, либо делать «фабрику», замыкание, класс или ещё что-то подобное.

Мне вот в питоне больше всего не хватает удобных распаковок словарей. То, что в js коротко:

const d = {foo: 1, boo: 2, zoo: 3};
const {foo, zoo} = d;

в питоне это громоздкое

d = {'foo': 1, 'boo': 2, 'zoo': 3}
foo, zoo = d['foo'], d['zoo']
1
23 ...

Information

Rating
2,310-th
Location
Россия
Date of birth
Registered
Activity

Specialization

Backend Developer, Product Manager
Lead
Python
Project management
Algorithms and data structures
asyncio