Задать вопрос
  • Есть ли смысл учить школьную статистику и вероятность?

    @alexalexes
    Берете вузовкий учебник Вентцель Е.С. "Теория вероятностей".
    Если чувствуете, что текст написан на птичьем языке, то понижаете планку до школьной программы (в школе, кроме про подбрасывание монетки ничего не рассказывали, поэтому подсказать литературу не могу).
    Ответ написан
    Комментировать
  • GUI для DeepSeek — есть ли?

    dollar
    @dollar
    Делай добро и бросай его в воду.
    https://openrouter.ai/
    Можно этим пользоваться. Там сразу есть выбор - бесплатный вариант или платный от различных провайдеров. То есть сразу выбираешь модель и пользуешься UI через браузер.

    Вот платные варианты (видно, где больше перегруженность серверов):
    spoiler
    6800c5973a7f2069239369.png

    Добавить свой ключ вроде как
    можно
    6800c70c96331590000075.png
    Но лично я этого не делал, единый счёт на все нейронки удобнее.
    Ответ написан
    7 комментариев
  • Как сконвертировать список в JSON?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Python
    Седой и строгий
    from itertools import batched
    
    a = ['A', 123, 'B', 321, 'C', 1234]
    b = dict(batched(a, 2))
    Ответ написан
    Комментировать
  • Какой сервер собрать для ИИ?

    @rPman
    Если вариант 'только ИИ и никакими другими адекватными способами' уже решен и вас не перспорить то...

    Забудьте про анализ на процессоре, будете ждать часами документ. Вам нужна видеокарта, а точнее достаточный объем vram что бы вместить и веса сети (ориентируйтесь на исходные веса и 8бит квантизацию) и kv-cache для контекстного окна (а его объем значимый) и кеша желательно 4-х кратно, что бы batching работал лучше.

    Адекватные серверные GPU купить в россии (да и не только) за адекватные деньги не возможно.

    Адекватные деньги - это только десктопное железо, самое доступное это 4060ti 16gb vram (по 55т.р. они тормозные для игр поэтому и дешевые). В самом лучшем варианте их можно будет вставить 4шт (можно и больше но почти наверняка будут проблемы в других местах) и при этом работать они будут максимум pci-e 4x (это повлияет на время загрузки весов но не на их работу!)

    Если готовы переплатить, берите любые nvidia с 24gb vram. В принципе будет работать и amd, но по софту будете ограничены только llama.cpp, а он с видеокартами не самый эффективный (он заточен на работу на процессоре, но зато лучше всех)

    С двумя gpu например отлично работает 14b сеть qwen и qwen distiled r1, я пока еще не пробовал но 27b гугловская так же будет работать. С четырьмя gpu можно пробовать 70b модели (c 4бит квантизацией точно), что llama что qwen.
    Ответ написан
    2 комментария
  • Почему именно такой порядок вывода в консоль?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Исследования в первоначальной версии ответа (ниже) натолкнули на поведение, которое смог объяснить Jonas Wilms в ответе на SO.

    Возврат промиса из C1 then() создаёт ТРИ последовательных микротаска:
    1. NewPromiseResolveThenableJob, который вызывает then() на том уже отресолвленном промисе, что вернули в C1. И т.к. этот промис уже отресолвлен, сразу же в очередь вставляется следующий микротаск:
    2. NewPromiseReactionJob этого уже разрешенного промиса, и этот, в свою очередь, добавляет третью микрозадачу:
    3. ещё одну NewPromiseReactionJob, которая уже выводит в лог "2".


    Если возвращать не промис (и не thenable объект), а "простое" значение или undefined, то добавляется всего один микротаск.

    Раньше подобная задержка в три шага была и для await, но потом её оптимизировали в движке V8. А вот про then() забыли.

    Подробнее стоит посмотреть ответ на SO, ссылка в начале.

    [первая версия ответа]

    Интересный вопрос! Больше экспериментов.
    Вспомогательная функция для читаемости:
    const log = (value, returnPromise) => () => {
      console.log(value);
      if (returnPromise) return Promise.resolve();
    };
    Возвращает функцию, которая обычный console.log() с переданным значением. И если второй аргумент трушный, то вернёт отрезолвленный промис.

    Эксперимент 1. «Застёжка-молния»
    Promise.resolve()
      .then(log('a1'))
      .then(log('a2'))
      .then(log('a3'))
      .then(log('a4'))
      .then(log('a5'))
      .then(log('a6'))
    ;
    
    Promise.resolve()
      .then(log('b1'))
      .then(log('b2'))
      .then(log('b3'))
      .then(log('b4'))
      .then(log('b5'))
      .then(log('b6'))
    ;
    Выводит поочередные a1 b1 a2 b2 a3 b3 ...
    Эксперимент 2. «Отстаём на 2»

    Единственное отличие: в первом А возвращаем отресолвленный промис.
    Promise.resolve()
      .then(log('a1', true))
      .then(log('a2'))
      .then(log('a3'))
      .then(log('a4'))
      .then(log('a5'))
      .then(log('a6'))
    ;
    
    Promise.resolve()
      .then(log('b1'))
      .then(log('b2'))
      .then(log('b3'))
      .then(log('b4'))
      .then(log('b5'))
      .then(log('b6'))
    ;

    Выводит
    a1 b1 b2 b3 a2 b4 a3 b5 a4 b6 a5 a6
    А-шки после 1-й отстают на 2, пропустив вперёд b2 и b3.

    Очередь микрозадач работает как FIFO буфер: первый пришёл, первый ушёл.

    Цепочка из then() выполняется асинхронно. После выполнения очередного, создаётся следующий microtask. Несколько цепочек, как видно из 1-го эксперимента, выполняются параллельно-пошагово, «молнией».

    Возврат созданного выполненного промиса, и ожидание его разрешения вызывает задержку в очереди микрозадач на 1 микротаск + «перемещение» цепочки "А" в конец (меняется порядок a-b => b-a):
    "молния"
    a1 b1 ; a2 b2 ; a3 b3 ; a4 b4 ; a5 b5 ; a6 b6
    
    с промисом в А1
    a1 b1 ; b2 ; b3 a2 ; b4 a3 ; b5 a4 ; b6 a5 ; a6


    Подробнее с тремя цепочками

    На этот раз три цепочки промисов "a", "b", "c". Цепочка "А" вернёт промис на 1-м шаге, "С" — на 4-м. Код эксперимента:
    const output = [];
    
    const makeChain = (key, n = 5, trueStep = false) => {
      let p = Promise.resolve();
      const arrow = isArrow => isArrow ? '->' : '';
      for (let i = 1; i <= n; i++) {
        const returnPromise = trueStep === i;
        const afterPromise = trueStep === i - 1;
        p = p.then(() => {
          output.push(`${arrow(afterPromise)}${key}${i}${arrow(returnPromise)}`);
          if (returnPromise) return Promise.resolve();      
        });
      }
      return p.catch(console.error);
    };
    
    const n = 7;
    makeChain('a', n, 1),
    makeChain('b', n),
    makeChain('c', n, 4),
    
    // мАкрозадача выполнится после всех мИкрозадач:
    setTimeout(() => console.log(output.join(' ')));

    Результат c вручную добавленными разбивками:
    a1-> b1 c1 ; b2 c2 ; b3 c3 ->a2 ; b4 c4-> a3 ; b5 a4 ; b6 a5 ; b7 ->c5 a6 c6 ; a7 c7
    Тут всё ещё не вполне мне понятен порядок после возврата промиса из C4.
    Ответ написан
  • Авторизация Django + Vue на ESIA, с чего начать?

    AlexNest
    @AlexNest
    Работаю с Python/Django
    Примерная схема будет следующая:
    67c723baaaec0889036898.png
    Ответ написан
    Комментировать
  • Оцените код html и css. Можно ли так делать?

    @Hovo_Varosyan
    для проверки html можешь использовать https://validator.w3.org/
    а для css https://jigsaw.w3.org/css-validator/#validate_by_u... (лично не использовал)
    Ответ написан
    Комментировать
  • Как найти и сгруппировать элементы с одинаковым классом?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Где, кого и во что надо обернуть:

    const parent = document.querySelector('.parent');
    const toWrapClass = 'child';
    const wrapperTag = 'div';
    const wrapperClass = 'wrapper';

    Оборачиваем:

    [...parent.children].reduce((wrapper, n) => {
      if (n.classList.contains(toWrapClass)) {
        if (!wrapper) {
          wrapper = document.createElement(wrapperTag);
          wrapper.classList.add(wrapperClass);
          n.before(wrapper);
        }
        wrapper.appendChild(n);
        return wrapper;
      }
      return null;
    }, null);

    или

    Array.prototype.reduce.call(
      parent.querySelectorAll(`:scope > .${toWrapClass}`),
      (acc, n, i, a) => (
        n.previousElementSibling !== a[i - 1] && acc.push([]),
        acc.at(-1).push(n),
        acc
      ),
      []
    ).forEach(n => {
      const wrapper = document.createElement(wrapperTag);
      wrapper.className = wrapperClass;
      parent.insertBefore(wrapper, n[0]);
      wrapper.append(...n);
    });

    или

    const toWrapSelector = `.${toWrapClass}`;
    const wrapperHTML = `<${wrapperTag} class="${wrapperClass}"></${wrapperTag}>`;
    for (
      let curr = parent.firstElementChild, next = null, prev = null, wrapper = null;
      next = curr?.nextElementSibling, curr;
      prev = curr, curr = next
    ) {
      if (!curr.matches(toWrapSelector)) {
        continue;
      }
      if (!prev?.matches(toWrapSelector)) {
        curr.insertAdjacentHTML('beforebegin', wrapperHTML);
        wrapper = curr.previousSibling;
      }
      wrapper.insertAdjacentElement('beforeend', curr);
    }
    Ответ написан
    1 комментарий
  • Как посчитать сумму элементов в большом вложенном словаре?

    Mike_Ro
    @Mike_Ro Куратор тега Python
    Python, JS, WordPress, SEO, Bots, Adversting

    Выдаёт ошибку:
    Traceback (most recent call last):
    line 46, in
    for m in n.values():
    AttributeError: 'int' object has no attribute 'values'

    Метод values() у чисел? Может не стоит?
    Подскажите как посчитать сумму элементов в данном словаре

    А если глубина словаря изменится, опять все вложенные for переписывать? С рекурсией лучше выглядит:
    def best_function(d):
        sum = 0
        for v in d.values():
            if isinstance(v, dict):
                sum += best_function(v)
            else:
                sum += v
        return sum
    
    print(best_function(dct)) # 3906

    Ну и как правильно подметил Влад Григорьев - почему отладкой кода не занимаетесь? А если задача будет сложнее, например в 100 раз, 100 вопросов зададите?
    Ответ написан
    2 комментария
  • Как сделать список destination в iptables?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Например, так:

    iptables -t mangle -N SPISOK
    iptables -t mangle -A SPISOK -d 10.9.0.0/24 -j RETURN
    iptables -t mangle -A SPISOK -d 10.11.0.0/24 -j RETURN
    iptables -t mangle -A SPISOK -d 10.14.0.0/24 -j RETURN
    iptables -t mangle -A SPISOK -j MARK --set-mark 4
    iptables -t mangle -A PREROUTING -i enp1s0 -s 10.8.0.0/24 -j SPISOK
    Ответ написан
    Комментировать
  • Как изменить текст в консоли питона?

    Daemon23RUS
    @Daemon23RUS
    Из простого (в строке)
    print('|о----|', end='\r', flush=True)
    time.sleep(5)
    print('|----o|', end='\r', flush=True)

    из библиотек sys stdout tqdm rich curses
    Ответ написан
    Комментировать
  • Как сделать грамотный счетчик в питоне?

    grantur5707
    @grantur5707
    Full Stack Web Developer
    По феншую и правильно по хорошему бы реализовать класс, в котором будешь хранить состояние счётчиков

    import subprocess
    from time import sleep
    
    class CameraMonitor:
        def __init__(self):
            self.IP12 = '192.168.0.100'
            self.IP13 = '192.168.0.101'
            self.RODOS12 = '192.168.1.100'
            self.RODOS13 = '192.168.1.101'
            
            self.fail_count = {'Купол 12': 0, 'Купол 13': 0}
            self.reboot_count = {'Купол 12': 0, 'Купол 13': 0}
    
        def ping_camera(self, ip):
            cmd = f'ping {ip} -n 1 -w 100'
            response = subprocess.call(cmd, stdout=subprocess.DEVNULL)
            return response == 0
    
        def cameras_checker(self):
            r_dict = {'Купол 12': self.IP12, 'Купол 13': self.IP13}
            while True:
                for camera, ip in r_dict.items():
                    if self.ping_camera(ip):
                        print(f'Camera {camera} - OK')
                        self.fail_count[camera] = 0
                    else:
                        self.fail_count[camera] += 1
                        print(f'Camera {camera} - Died')
    
                        if self.fail_count[camera] >= 5:
                            self.cameras_reboot(camera)
    
                sleep(5)
    
        def cameras_reboot(self, camera):
            if camera == 'Купол 12':
                ip = self.RODOS12
            else:
                ip = self.RODOS13
            
            self.reboot_count[camera] += 1 
            print(f'Rebooting {camera} at IP {ip}')
    
        def info(self):
            for camera, count in self.reboot_count.items():
                print(f'Перезагрузок {camera}: {count}')
    
    
    if __name__ == "__main__":
        monitor = CameraMonitor()
        monitor.cameras_checker()
    Ответ написан
    3 комментария
  • Как получить битовое представление скрина для передачи через сокет, не сохраняя его?

    vollossy
    @vollossy
    Веб-разработчик с небольшим опытом работы
    Для изображений с компрессией (скорее всего, вы работаете jpeg, png или чем-то ещё), можно использовать метод Image.save(fp: str | bytes | PathLike[str] | PathL..., передав в качестве параметра fp экземпляр BytesIO.

    В принципе, для работы с байтами в памяти программы, рекомендую использовать этот класс, весьма удобно.
    Ответ написан
    Комментировать
  • Как можно оптимизировать этот код?

    Vindicar
    @Vindicar
    RTFM!
    Для начала определи, что у тебя занимает время - скачивание, или парсинг. Подходы будут разные.
    Если хочется в лоб решать задачу - то multiprocessing в руки, даёшь дочернему процессу URL, он тебе возвращает структуру данных. Главный процесс раздаёт URLы и собирает ответы в какое-то итоговое хранилище.
    Пример работы с пулом процессов.
    Ответ написан
    Комментировать
  • Как можно оптимизировать этот код?

    fox_12
    @fox_12 Куратор тега Python
    Расставляю биты, управляю заряженными частицами
    Все не смотрел, но простыни типа:
    def get_contact(ids):
        for id in ids:
            template = f'https://etender.gov.az/api/events/{id}/contact-persons'
            try:
                response = requests.get(template, timeout=20)
                if response.status_code == 200:
                    data_list = response.json()
                    for data in data_list:
                        main_data['Full_name'].append(data.get('fullName', 'None') if data.get('fullName') else 'None')
                        main_data['Contact'].append(data.get('contact', 'None') if data.get('contact') else 'None')
                        main_data['Position'].append(data.get('position', 'None') if data.get('position') else 'None')
                        main_data['Phone_number'].append(data.get('phoneNumber', 'None') if data.get('phoneNumber') else 'None')
    
                else:
                    main_data['Full_name'].append('None')
                    main_data['Contact'].append('None')
                    main_data['Position'].append('None')
                    main_data['Phone_number'].append('None')
            except requests.Timeout:
                main_data['Full_name'].append('None')
                main_data['Contact'].append('None')
                main_data['Position'].append('None')
                main_data['Phone_number'].append('None')


    пишутся гораздо проще. Да и структуру данных я бы поправил. К примеру простыня выше заменяется более лаконичным кодом:
    main_data = []
    ...
    
    def get_contact(ids):
        for id in ids:
        	current_data = {'Full_name': 'None', 'Contact': 'None', 'Position': 'None',  'Phone_number': 'None'}
            template = f'https://etender.gov.az/api/events/{id}/contact-persons'
            try:
                response = requests.get(template, timeout=20)
                if response.status_code == 200:
                    data_list = response.json()
                    for (elem_to, elem_from) in [
                         ('Full_name', 'fullName'),
                         ('Contact', 'contact'),
                         ('Position', 'position'),
                         ('Phone_number', 'phoneNumber')
                    ]:
                    	current_data[elem_to] = data.get(elem_from, 'None')
             except requests.Timeout:
                   pass
            main_data.append(current_data)
    Ответ написан
    Комментировать
  • Как отобразить даты в виде недельного интервала?

    Geleoss
    @Geleoss
    Любитель таблиц
    66deeb597c61e326369648.pngДата понедельника на текущей неделе:
    mon; TODAY()-WEEKDAY(TODAY();3)
    Дата в на текущей неделе:
    sun; TODAY()-WEEKDAY(TODAY();3)+6
    Даты недели:
    1. TO_TEXT(mon) & "-" & TO_TEXT(sun)
    2. TEXT(mon;"dd.mm") & "-" & TEXT(sun; "dd.mm")
    Пример.
    Ответ написан
    1 комментарий
  • Как в Obsidian увеличть ширину заметки?

    @oghmios
    Можно не править CSS, а просто отключить конфигурационный параметр "Ограничить максимальную длину строки":

    Настройки (иконка "шестерёнка" внизу слева) -> Редактор -> Отображение -> выключить переключатель "Ограничить максимальную длину строки"

    На английском это "Readable file length", эта настройка появилась ещё в версии 0.7.0: https://obsidian.md/changelog/2020-06-09-desktop-v...
    https://readmedium.com/obsidian-editor-settings-fo...
    Ответ написан
    2 комментария
  • Как с помощью JS организовать запись и чтение данных?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    GM_setValue GM_getValue - будут храниться в сторе самого расширения.

    Всякие куки, localStorage, indexedDb - всё может почитститься самом сайтом или случайно тобой.

    Надёжнее - только свой сервак завести и к нему запросами отправлять-получать.:)
    Ответ написан
    Комментировать
  • Почему все говорят что писать ботов это сложно?

    Vindicar
    @Vindicar
    RTFM!
    А сложность начинается, как только задачи, стоящие перед ботом, перерастают уровень примера в документации видеотуториале пятилетней давности.

    Нужно сделать несколько под-команд у команды. Напишу цепочку if-elif-else, делов то. Ой, а теперь простыня кода на пять экранов, в которой фиг чего найдёшь. Потому что нет привычки структурировать код.

    Нужно, чтобы несколько команд/событий формировали цепочку (сценарий). Например, пользователь отправил тре сообщения, первое с именем, второе с возрастом, третье с адресом. Ой, а как это сделать вообще? Не зная понятия "конечный автомат" (finite state machine, FSM), очень трудно догадаться, как тут поступить.

    Нужно, чтобы ботом могли пользоваться несколько человек. Ой, их данные перепутались! Потому что бот использует глобальные переменные.

    Нужно, чтобы бот выполнил длительную задачу, и написал сообщение, когда она выполнится. Не вопрос, напишу функцию, вызову её, а сразу после отправлю сообщение. Ой, а бот не отвечает! Потому что рабочий цикл asyncio занят этой длительной операцией и не может отреагировать на поступающие данные. Нужно иметь хорошее представление о том, как работает асинхронная программа.

    Нужно добавить боту графический интерфейс - админку. Ой, а работает или интерфейс, или сам бот! Потому что нужно представлять, как устроено большинство GUI-фреймворков, и как устроена асинхронное приложение. А заодно понимать многопоточность, вопросы синхронизации действий между двумя потоками, и особенности работы с asyncio в многопоточных приложениях. Потому что одним потоком тут обойтись будет очень непросто.

    Нужно хранить данные в БД. Ой, а почему у меня проблемы при записи в БД имени пользователя? А потому что погромист собирает SQL-запрос через форматирование строк. Надо было почитать доки, чтобы наткнуться на prepared statements, они же parameterized queries.

    Нужно хранить данные в БД. Вот только данные имеют связи многие-ко-многим. Я знаю! Я буду просто добавлять или удалять столбцы в таблицу! Потому что не освоены даже азы проектирования БД. Тут уже nuff said. И да, я такое видел на этом сайте.

    Незнание средств языка и основных приемов построения алгоритмов и структур данных приводит к диким велосипедам, которые создают больше проблем, чем пользы. Особенно если к этому добавляется нежелание находить и читать документацию на фреймворк, на котором построен бот.
    Ответ написан
    2 комментария
  • Как в sql прибавить число и сравнить с другим?

    @Zzzz9
    Ответ написан
    Комментировать