• Как понять нижеуказанный код Javascript?

    @antares4045
    function largestOfFour(arr) { 
      let results = []; //аккамулятор результатов
      for (let i = 0; i < arr.length; i++) { //для каждой строки матрицы arr
        let largestNumber = arr[i][0]; //пердпологаем, что первое число в строке является максимальным
        for (let j = 1; j < arr[i].length; j++) { //для всех чисел в строке, начиная со второго
          if (arr[i][j] > largestNumber) { // если текущее число больше нашего текущего максимума
            largestNumber = arr[i][j]; // обновляем значение максимума
          }
        }
        results[i] = largestNumber; //кладём текущий максимум в аккамулятор
      }
    
      return results; //возвращаем аккамулятор как результат работы функции
    }
    Ответ написан
    Комментировать
  • Как записать несколько строк в файл bash?

    @antares4045
    ещё можно так, если строчки короткие

    printf "str1\nstr2\nstr3" >> /home/2.txt
    Ответ написан
    Комментировать
  • Как увеличить допустимое число вводимых знаков?

    @antares4045
    Возможно это не финал решения, но из нашего общения в коментариях я вынес предположение, что строка у вас хранится в виде

    "абвгдежзийклмнопрстуфхцчшщъыьэюя"

    дальше суть проблемы:
    position =alphabet.find('я') # 31
    newPosition = position + key # 36
    alphabet [newPosition] # ааааа! нет такой буквы

    предпологаю, что вы хотели забацать шифр соломона, в котором при переходе через край счёт начинается заново

    position =s.find('я') # 31
    newPosition = (position + key) % len(alphabet) # 4
    alphabet [newPosition] # д


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

    А из-за чего сдвиг шифра неправильный без понятия: скиньте ка свой алфавит.
    Ответ написан
    4 комментария
  • Писать типы вначале или рассчитывать на вывод типов компилятором?

    @antares4045
    Вопрос сугубо религиозный. Если у вас в команде нет требований к кодстайлу, то пишите так, как вам проще и не парьтесь.

    Но если включить на время зануду, то очень хочется отметить, что вы взяли тайпскрипт чтобы всеравно писать на js. Все эти истории с автоматическим выводом типов выводила людей из себя: пропустив одну букву они получали программу которая работает, но делает что-то не то. И если эта "одна буква" где-то в корнер кейсе, то ошибка может оставаться незамнченой годами. Можно покрывать весь код юнит тестами. Но это долго и бизнес (по крайней мере средний) на такие траты ни за что не пойдёт. К тому же в тестах тоже могут быть косяки... И тут люди "вспомнили" о ещё одном способе избегать такого рода ошибок: если пользователь сам распишет типы, то совсем грубые семантические ошибки компьютер отловит: тайпсерипт специально сделан, чтобы ваш код не запускался.

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

    @antares4045
    В языках этого семейства есть два мира: то что вы напечатали обрабатывается статическим анализатором, который выдаёт вам пачку рекомендаций, и если по его мнению, вы написали что-то "не то" дезактивирует вам кнопку запуска/компиляции. А потом ваш код с парой настроечных флагов попадает в компилятор, который вообще другая программа и ему абсолютно плевать на каком вы языке писали свою программу и какие настройки были в вашей среде -- он знает один язык и пытается всё подогнать под него. Причём, учитывая отсутствие единого стандарта gcc, mingw и msvc якобы одного года могут себя вести с одним и тем же кодом совсем по разному.

    И да. Есть ещё оптимизация на уровне компилятора флаг -O3 заставит компилятор чуть ли не с нуля написать программу, которая ведёт себя точно как ваша, но при этом написана она будет по всем канонам высокопроизводительного кода. И ваша среда какую-нибудь оптимизацию (не о3 конечно, но о1-о2 наверняка) от компилятора требует.

    Так что да получившийся exe файл, к написанному вами текстовому файлу с расширением "c", имеет весьма косвенное отношение.

    В вижуал студии не работал. По всей видимости флажок "устаревший MSVC" это скорее ваше обещание себе использовать старый компилятор, а сама среда не особо следит.
    Ответ написан
    Комментировать
  • Так включается многопоточность?

    @antares4045
    у вас же не сработает -- попробуйте. такого параметра даже нет.
    Зато есть check_same_thread (который кстати позволит пойти по "пути А" из моего ответа на ваш предыдущий вопрос про sqlite)
    Ответ написан
    6 комментариев
  • Задача по Python с использованием словаря?

    @antares4045
    вопрос из серии какой цвет выбрать для обоев: сейчас получите от человека по способу.
    Я сегодня ленивый:
    marks = {
        'a' : [1,2,3],
        'b' : [0,1,2],
        'c' : [5,6,6],
        'd' : [4,4,4]
    }
    
    def mean(lst):
        return sum(lst) / len(lst)
    
    sortedIds = sorted(marks.keys(), key=lambda studentId: mean(marks[studentId]))
    
    print('лучший:', sortedIds[-1])
    print('худший:', sortedIds[0])

    Вывод:
    лучший: c
    худший: b
    Ответ написан
    3 комментария
  • Нужен бесплатный хостинг для бота Discord на python. 404 строчки. Есть такой?

    @antares4045
    Попробуйте любой VPS сервис с вечным бесплатным периодом сейчас такие есть у Amazon, Azure, Google cloud. Чтобы ими воспользоваться придётся правда немножко подружиться с удалённым администрированием unix, но в остальном это серебряная пуля для задач хостинга чего угодно.
    Ответ написан
    1 комментарий
  • Как использовать sqlite python в многопоточности?

    @antares4045
    Коннект надо поднять ОДИН раз в главном потоке а курсоров из него уже можете понаделать на все потоки (вроде). Если не поможет: то только открывать-закрывать подключение для каждой операции, например так: https://qna.habr.com/q/1062578#answer_2040432.

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

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

    В абсолютно любой файловой системе многопоточный доступ к одному файлу не существует. совсем. программа может считать файл (или его часть) в оперативную память, а потом заменить файл на что-то вычисленное на основе считанного (есть ещё возможность делать "аппенд", но это синтаксический сахар реализованный на уровне ос (возможно я не прав: знатоки поправьте меня)).

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

    Sqlite это просто файл у вас на диске, и еcли бы не та защита которая вам не даёт создать многопоточную программу, то вам бы казалось, что она вообще не работает: каждый поток видит в базе только то, что сделал в базе он сам, а после перезапуска вы вообще видите в лучшем случае версию базы от потока, закрывшего соединение последним (а то и вообще битый файл).
    Для того, чтобы всякие профессионалы не писали, что "этим вашим sqlite не возможно пользоваться", была встроена защита (куда более адекватный аналог которой есть на всех файлах microsoft office) если хоть кто-то сейчас работает с файлом, то его открывать нельзя и, если не оговорено обратное, падает с ошибкой.

    Проблеме столько же лет, сколько люди пытаются одновременно менять что-то в одном предмете. К сожалению, этот случай, когда приходящий сходу в голову достаточно затратный подход единственно работоспособен в общем случае (в конкретно вашем случае может можно придумать какое-то более простое правило, но изложенное дальше будет работать всегда и везде): первый агент берёт эталон, и оставляет записку "я работаю, ждите", вносит свои изменения и не оставляет эталон у себя, за время его работы у записки уже собралась уже недовольная очередь, которой тоже работать надо -- когда эталон освобождается, первый в очереди забирает его себе оставив уже свою записку. и так далее.

    Правила организации этих очередей целая наука от которой сойти с ума можно, но в случае sqlite настраиваемый параметр у нас ровно один: сколько мы готовы ждать.

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

    cursor.execute(clause, props)
    result = cursor.fetchall()

    или что там у вас было пишем

    with sqlite3.connect(`Ваши параметры подключения`, timeout=`Какое-то зверски большое число секунд, которое мы готовы "стоять в очереди"`) as connect: 
      # создаём подключение к базе которое существует только в рамках блока with 
      # то что мы здесь напишем должно отработать максимально быстро
      cursor = connect.cursor()
      cursor.execute(clause, props)
      result = cursor.fetchall()

    В идеале вообще вынесите это в отдельную функцию

    p.s. если вы зашли сюда в поисках истины, то мы продолжили общение тут и в итоге победили.
    Ответ написан
    9 комментариев
  • Выставление Cookie и получение их через Fetch API?

    @antares4045
    Сегодня браузеры стали черезчур умные и у них есть гигантское количество причин проигнорировать установку кукиса. Скорее всего (в случае браузеров на хромиуме (тоесть не в опере)) в инструментах разработчика в детализации запроса на вкладке HEADERS сразу за хедером респонса будет маленький желтый треугольник, наведя мышь на который вы сможете прочитать, в чём причина на этот раз.

    Как то так например
    61792042219ba341444647.png

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

    @antares4045
    если список плоский, то os.listdir
    если с подпапками os.walk
    потом открываем файл папки как байтовый поток и с правильным mime пересылаем (этот пункт возможно сделать и проще, но так прозрачнее)
    Ответ написан
  • Получение количества открытых окон через WinApi?

    @antares4045
    Учитывая, что код на питоне принимается "на крайняк", не уверен, что это можно считать полноценным ответом: на питоне есть такая презамечательная либа: psutil при помощи которой я переодически пишу всякую грязь опираясь на шаблон
    import psutil
    import win32gui
    import win32process
    
    
    def enum_window_callback(hwnd, pid):
            tid, current_pid = win32process.GetWindowThreadProcessId(hwnd)
            if pid == current_pid and win32gui.IsWindowVisible(hwnd):
                windows.append(hwnd)
    
    for process in psutil.process_iter():
        pid = process.pid
        windows = []
        win32gui.EnumWindows(enum_window_callback, pid)
        windownames = [win32gui.GetWindowText(item) for item in windows]
        
        if len(windownames):
            exeName = process.name()
            for windowName in windownames:
                hwnd = win32gui.FindWindow(None, windowName)
                print(f'"{exeName}" - "{windowName}" - "{hwnd}"')

    Вывод:
    "NVIDIA Share.exe" - "NVIDIA GeForce Overlay" - "66250"
    "Code.exe" - "list of windows.py - grabscrren - Visual Studio Code" - "459882"
    "Code.exe" - "● N-mer-Krammer.py - Рандомный habr - Visual Studio Code" - "132316"
    "Battle.net.exe" - "Battle.net" - "132384"
    "explorer.exe" - "" - "65860"
    "explorer.exe" - "D:\" - "263030"
    "explorer.exe" - "" - "65860"
    "explorer.exe" - "" - "65860"
    "explorer.exe" - "" - "65860"
    "explorer.exe" - "" - "65860"
    "explorer.exe" - "Program Manager" - "131380"
    "python.exe" - "Jupyter Notebook" - "1639536"
    "chrome.exe" - "Получение количества открытых окон через WinApi? — Хабр Q&A - Google Chrome" - "1442268"


    На выходе имеем список формата запущенный экзешник - имя окна - pid
    для вашей задачи если вам не нравится какой-либо экзешник -- можете банить.

    но с трансляцией в плюсы есть проблема: psutil (я пытался разобраться пару лет назад) под капотом творит какую-то чёрную магию, так что единственное, что могу вам предложить, это скомпилировать этот скрипт в отдельный экзешник и вызывать его субпроцессом (ну или игнорировать мой ответ).

    Правда если вы знаете способ (вдруг), как под виндой получить список всех pid, то поделитесь -- буду очень рад.

    UPD:
    не смог отпустить и сделал реализацию полностью на winapi
    import win32gui
    import win32process
    import win32api
    import win32process
    import win32con
    
    
    def enum_window_callback(hwnd, _):
            if win32gui.IsWindowVisible(hwnd):
                tid, current_pid = win32process.GetWindowThreadProcessId(hwnd)
                handle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ, False, current_pid)
                proc_name = win32process.GetModuleFileNameEx(handle, 0)
                windows.append({
                    "hwnd":hwnd, 
                    "pid" : current_pid, 
                    "tid" : tid,
                    "window title" : win32gui.GetWindowText(hwnd),
                    "process name" : proc_name
                    })
    
    windows = []
    
    win32gui.EnumWindows(enum_window_callback, None)
    
    for window in windows:
        print(f'"{window["process name"]}"', window['pid'], f'"{window["window title"]}"', window['hwnd'], sep=' - ')

    Вывод:
    "C:\Windows\explorer.exe" - 8084 - "" - 65736
    "C:\Users\Тоха\AppData\Local\Programs\Microsoft VS Code\Code.exe" - 6124 - "list of windows.py - grabscrren - Visual Studio Code" - 459882
    "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" - 11696 - "windows - How can I get process name using Python - Stack Overflow - Google Chrome" - 131222
    "C:\Users\Тоха\AppData\Local\Programs\Microsoft VS Code\Code.exe" - 6124 - "● N-mer-Krammer.py - Рандомный habr - Visual Studio Code" - 132316
    "C:\Qt\Tools\QtCreator\bin\qtcreator.exe" - 11308 - "main.cpp @ processScan - Qt Creator" - 1967294
    "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" - 11696 - "Получение количества открытых окон через WinApi? — Хабр Q&A - Google Chrome" - 1442268
    "C:\Anaconda3\python.exe" - 9912 - "Jupyter Notebook" - 1639536
    "C:\Program Files (x86)\Battle.net\Battle.net.exe" - 6396 - "Battle.net" - 132384
    "C:\Windows\explorer.exe" - 8084 - "D:\" - 263030
    "C:\Windows\SystemApps\MicrosoftWindows.Client.CBS_cw5n1h2txyewy\InputApp\TextInputHost.exe" - 12956 - "Microsoft Text Input Application" - 131658
    "C:\Program Files\NVIDIA Corporation\NVIDIA GeForce Experience\NVIDIA Share.exe" - 5488 - "NVIDIA GeForce Overlay" - 66250
    "C:\Windows\explorer.exe" - 8084 - "" - 65924
    "C:\Windows\explorer.exe" - 8084 - "" - 65932
    "C:\Windows\explorer.exe" - 8084 - "" - 65892
    "C:\Windows\explorer.exe" - 8084 - "" - 65890
    "C:\Windows\explorer.exe" - 8084 - "Program Manager" - 131380

    При переносе на плюсы столкнулся с тем, что не помню, как нормально импортировать всех этих винюзеров -- если напишете скиньте в комметарии, а мне надоело)
    Ответ написан
    2 комментария
  • Какая формула аппроксимации многомерными полиномами?

    @antares4045
    решать проблему в лоб сильно затратно по памяти: лучше гляньте как задачу регрессии оптимизируют mashine learning библиотеки. но в лоб
    на numpy это выглядит так:

    XtX = X.T * X
    result = inv(XtX).dot(X.T).dot(Y)

    X = матрица MxN*K где строкам соответствуют точкам а столбцам координаты возведённые в соответствующие степени
    Y = вектор столбец из M нулей

    Matrix.T - транспонирование матрицы
    inv(Matrix) -- функция inv вычисляет обратную матрицу
    MatrixA.dot(MatrixB) -- вычисляет произведение матриц

    На выходе получаете вектор result -- коэффициэнты полинома соответствующие колонкам матрицы X (Соответственно, если хотите, чтобы свободный коэфициент был, столбец единиц в матрице X должен быть)

    ещё раз обращу внимание, что матрица XtX имеет размерность MxM что при попытке обработать любые реальные данные с миллионами измерений просто сожжёт вам то, на чём вы там считаете.

    За нотацию извиняюсь -- классическую математическую подзабыл, и честно говоря вспоминать не очень хочется.

    UPD:

    После некоторых посиделок оформил всё в такую конструкцию:
    import numpy as np
    
    K = 2 #степень целевой плоскости
    points = np.array([[a, 5 + 2*a + 6 * a**2] for a in range(0, 60)]) # точки, по которым строим
    
    
    
    class Symbolic:
      def __init__(self, letter=None):
        self.letters = dict() if letter is None else {letter : 1}
      def addLetter(self, letter, power=1):
        if letter not in self.letters:
          self.letters[letter] = 0
        self.letters[letter] += power
      def __pow__(self, pow):
          res = Symbolic()
          for letter in self.letters:
            res.letters[letter] = self.letters[letter] * pow
          return res
      def __mul__(self, right):
        res = Symbolic()
        for letter in self.letters:
          res.addLetter(letter, self.letters[letter])
        for letter in right.letters:
          res.addLetter(letter, right.letters[letter])
        return res
      def __repr__(self):
        return '*'.join(map(lambda letter: f'{letter}**{self.letters[letter]}', self.letters.keys()))
    
    def pointsToPower(points, power):
      result = points ** power
    
      if points.shape[1] > 1 and power > 1:
        for startpower in range(power-1, 0, -1):
          for index in range(points.shape[1] - 1) :
            base = np.array(points[:,index]) ** startpower
            submatrix = pointsToPower(
                points[:, index+1:],
                power - startpower
            )
            result = np.hstack([result, np.array([submatrix[lineIndex, :] * base[lineIndex] for lineIndex in range(base.shape[0])])])
      return result
    
    def pointsToX(points, K=1):
      return np.hstack([
            #  np.array([[1]] * points.shape[0]), 
            *[pointsToPower(points, power=i+1) for i in range(K)]
        ])
    
    
    def krammer(X, sigma=1):
      XtX = X.T.dot(X)
      baseDet = np.linalg.det(XtX)
      if baseDet == 0:
          return [[None]]
      Y = np.array([[sigma] * X.shape[0]]).T
      return np.linalg.inv(XtX).dot(X.T).dot(Y)
    
    
    X = pointsToX(points,K)
    values = krammer(X).T[0]
    if values[0] is None:
        print('''Обратной матрицы не существует, и решить систему матричным методом невозможно. 
    В этом случае система решается методом исключения неизвестных (методом Гаусса). 
    Но его реализовывать мне влом''')
    
    symbols = pointsToX(np.array([[Symbolic(chr(ord('a') + i)) for i in range(points.shape[1])]]),K)[0]print('Уравнение целевой плоскости:')
    print(*[f'{value} * {symbol}' for symbol,value in  zip(symbols, values)], sep=' + \n', end=' = 1')
    Ответ написан
    8 комментариев
  • Как лучше реализовать такую страницу?

    @antares4045
    Не совсем понятен стек. Но в любом случае выбор в любом дропменю не приводит к обновлению страницы. а всего лишь вызывает событие onchange и каким образом его обработать -- полностью в вашей власти.

    Фреймы здесь невероятно избыточны, избавьтесь от них.
    Ответ написан
    Комментировать
  • Как получить рабочую категорию Linux (Ubuntu)?

    @antares4045
    os.getcwd() -- это путь до места из которого была отдана команда на запуск скрипта
    что может совсем не совпадать с путём до скрипта
    я обычно юзаю os.path.dirname(__file__) -- ещё ни в одной os меня не подвело
    Ответ написан
    2 комментария
  • В чем заключается ошибка RecursionError в функции-декоратор?

    @antares4045
    в wrapper_1 должно вызываться func а не summator:
    у вас получилось, что сумматор заменён на враппер вокруг чего-то, что вызывает сумматор, который в свою очередь является враппером вокруг сумматора... и так до бесконечности
    Ответ написан
    Комментировать
  • Как чётко распознать текст с капчи?

    @antares4045
    61721e3575f7d636235081.png
    Вот эта нейрнока.
    Только конкретно эта сеть натаскана на китайский язык (даже не буду показывать, как она это прочитала). Это скорее доказательство работоспособности.
    Ответ: CTPN для обнаружения слов на картинке; CRNN для распознавания слов.
    Переучите на русский и будет вам счастье.
    Ответ написан
  • Можно ли сделать так, чтобы бот мог удалять сообщения в теллеграмме в определённое время?

    @antares4045
    Теоретически, специалисту потребуется меньше часа. Но это комплексный вопрос требующий коснуться кучи разных областей IT.
    Навскидку нужно быть поверхностно знакомым с принципами взаимодействия с api, неплохо знать какой-нибудь высокоуровневый язык, не бояться удалённого администрирования VPS (что за собой влечёт уменее работать с unix консолью скорее всего), мочь сделать деплой проекта (тоесть справится с докером). И это только навскидку -- что там может ещё вылезти из того, что айтишнику очевидно а мимокрокодилу не особо -- фиг знает.

    Плюс ещё есть тонкость: писал похожую систему для не слишком активного чата (где-то пяток сообщений в час в среднем) и бесплатного трафика на амазоновском сервере мне не хватило -- так что встаёт ещё вопрос размещения бота (около 200р/месяц (а может и 600)).

    Человек, который "полный ноль в программировании и ботах" боюсь через пару месяцев писания разношёрстных вопросов на форумах забьёт. Лучше наймите спеца: студент младшекурсник согласится за пачку дошираков.
    Ответ написан
    1 комментарий
  • Как работать с реестром?

    @antares4045
    Если под нодой, то мне видится наболее простым работа чарез консольные комманды при помощи либы вроде node-cmd (но есть и узкоспециализированые либы)

    Если же вы под браузером, то никак (это была бы просто космических масштабов дыра в безопасности).
    Ответ написан
    Комментировать
  • Можно ли не указывать функцию полченную из хука в зависимостях useEffect?

    @antares4045
    Варнинги на то и варнинги, что система не уверена, что вы написали не то, что имели в виду.
    useEffect без зависимостей выполнится при первом рендере компонента и всё; если же вы добавите что-то в зависимость (не doSomething), то калбек будет выполняться при каждом изменении зависимостей, НО doSomething будет использоваться из первого рендера, что с высокой вероятностью будет приводить к ошибкам. Именно по этой логике линтер действует по принципу: всё что используется в хуке, должно быть указано в зависимостях. И это отлично работает, пока все контрибюторы проекта в адеквате, код не раздулся до десятков (а то и сотен) тысяч строк и лично вы можете быть уверены, что функция doSomething действительно обновляется только в случае когда её нужно перевызвать (тоесть не обновляется).
    Могу вам гарантировать, что если в прокте больше двух человек, и вы работаете над ним суммарно больше десяти тысяч часов чистого времени, то у вас в проекте обязательно что-то отвалится, из-за того, что в зависимостях прописали что-то, что линтер просил, но там быть не должно. Но и по обратной причние тоже. Конкретно в вашем случае лучше расширять список зависимостей не стоит. но каждый раз при написании/изменении хука надо думать отдельно.
    Ответ написан