• Tkinter. Как растянуть Form на весь Canvas?

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    import customtkinter as ctk
    
    app = ctk.CTk()
    
    def resize_frame(event):
        # Растягиваем frame на всю площадь canvas
        canvas.itemconfig(frame_id, width=event.width-2*padx)
    
    # Ширина и высота отступов
    padx =20
    pady = 20
    
    # Canvas
    canvas = ctk.CTkCanvas(app, bg="blue", highlightthickness=0)
    canvas.pack(fill='both', expand=True, padx=padx, pady=pady)
    
    # Функция привязки изменения размера Canvas
    canvas.bind('<Configure>', resize_frame)
    
    main_frame = ctk.CTkFrame(app, bg_color='white')
    frame_id = canvas.create_window((20, 20), window=main_frame, anchor='nw')
    
    scrollbar = ctk.CTkScrollbar(app, command=canvas.yview)
    canvas.configure(yscrollcommand=scrollbar.set)
    scrollbar.place(relx=1, rely=0, relheight=1, anchor='ne')
    # наполнение
    for i in range(40):
        ctk.CTkButton(main_frame, text='Click Me').pack(pady=10)
    
    canvas.update_idletasks()
    canvas.configure(scrollregion=canvas.bbox("all"))
    app.mainloop()
    Ответ написан
    Комментировать
  • Какие модули есть в Python для целей анализа, форматирования, вывода текста?

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    Для анализа и обработки текста в Python существует множество библиотек, которые могут помочь вам с различными задачами, включая поиск совпадений слов, подсчет символов и знаков препинания, а также форматирование и вывод результатов в различные форматы файлов, включая PDF. Вот некоторые из них:

    1. Стандартная библиотека Python:
    - re: модуль для работы с регулярными выражениями, который может помочь в поиске совпадений слов.
    - string: предоставляет набор стандартных операций со строками, включая подсчет символов.
    - collections.Counter: полезен для подсчета вхождений элементов в итерируемых объектах.

    2. Анализ текста:
    - nltk (Natural Language Toolkit): обширный набор инструментов для работы с человеческим языком, включая поиск и анализ слов.
    - spacy: продвинутая библиотека для обработки естественного языка, которая может использоваться для лемматизации, распознавания сущностей и других задач NLP.

    3. Работа с текстом и файлами:
    - Pandas: предоставляет функционал для анализа и обработки данных в табличном формате, позволяет экспортировать результаты в различные форматы файлов.
    - openpyxl или pandas: для работы с файлами Excel.
    - python-docx: для создания, изменения и извлечения информации из документов Word.

    4. Форматирование текста:
    - rich: позволяет создавать стилизованный вывод в терминал с поддержкой markdown, подсветкой синтаксиса, таблицами и т.д.
    - textwrap: стандартный модуль Python для форматирования абзацев текста, чтобы он красиво выводился.

    5. Работа с PDF:
    - reportlab: мощный инструмент для создания сложных PDF-документов с возможностью добавления графики и текста с различным форматированием.
    - PyPDF2 или PyMuPDF (fitz): библиотеки для чтения и записи PDF-файлов, манипуляции с существующими PDF, включая соединение, разделение и т.д.

    Все эти модули и библиотеки позволяют выполнять широкий спектр задач, связанных с текстом, начиная от простого поиска и анализа слов и символов до сложного форматирования и вывода в файлы различных форматов, включая PDF. Большая часть из них имеет обширную документацию и примеры использования, что позволяет сравнительно легко начать работу с ними.
    Ответ написан
    3 комментария
  • Стоит ли дальше учиться программировать?

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    На счет AI вы правы. Уже сейчас он может выдавать код на уровне мидл-специалиста. И каждое новое поколение будет лучше и совершеннее. Но есть одно но... Чтобы получить от AI хороший код - нужно составить правильный качественный промт-запрос, а сделать это может именно качественный специалист. Кроме того, оценить насколько хороший получился код - может только профильный специалист (то что код работает и даже выдает правильный результат - еще не означает что код удовлетворяет всем критериям).
    Еще одна особенность, заключается в том, что современный AI может фокусироваться хорошо на небольшом количестве аспектов. Чем больше ему задаешь критериев и требований - тем больше у него происходит "расфокусировка" - код становится похожим на код написанный "склеротиком", появляются банальные ошибки и даже какая-то халтура. Поэтому при написании сложного кода с большим количеством требований - приходится получать варианты кода сначала с одними критериями, потом с другими и уже из полученных вариантов самому собирать итоговый рабочий код.
    Итого: не думаю, что в ближайшие 20-30 лет AI сможет полностью заменить программистов. Будут повышаться требования к знаниям и опыту, вероятно даже к уровню интеллекта - но востребованность специалистов, скорее всего будет расти.
    Ответ написан
    4 комментария
  • Как перезапустить таймер с теми же функцией и параметрами, но новым временем?

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    Чтобы выполнить перезапуск таймера в TypeScript, вы не сможете использовать свойства, такие как _onTimeout и _timerArgs, поскольку они не являются частью стандартного API и обычно не доступны для типобезопасного кода. В TypeScript (и в JavaScript в целом) для более чистого подхода рекомендуется создать обёртку для таймера, которая будет управлять поведением и позволит перезапустить таймер с новым временем.
    Попробуйте так:
    function restartTimer(
      originalFunc: (...args: any[]) => void,
      newDelay: number,
      ...args: any[]
    ): number {
      clearTimeout(timerId); // timerId должен быть доступен в области видимости
      return setTimeout(originalFunc, newDelay, ...args);
    }
    
    // Используйте так:
    let timerId: number; // Храните timerId в доступном месте
    
    function testFunc(param1: string, param2: string) {
      console.log(param1);
      console.log(param2);
    }
    
    // Запуск таймера
    timerId = setTimeout(testFunc, 5000, 'asd', 'qwe');
    
    // В нужный момент перезапустить таймер с новым временем. Например, с 10000 мс.
    timerId = restartTimer(testFunc, 10000, 'asd', 'qwe');

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

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    Ключ к эффективному алгоритму здесь – определить, достаточно ли места по каждой из четырех сторон (сверху, снизу, слева, справа) от активатора, чтобы тултип вместился без выхода за пределы экрана.

    Вот базовая идея алгоритма:

    1. Определить размеры и положение элемента-активатора, используя getBoundingClientRect.
    2. Определить размер окна браузера.
    3. Рассчитать доступное пространство в каждом из направлений: сверху, снизу, слева, и справа от элемента.
    4. Используя размеры тултипа, определить может ли он поместиться в каждом из этих направлений.
    5. Если тултип не помещается в первоначальном направлении:
    - Испытать альтернативные позиции на основе доступного пространства и размеров тултипа.
    - Выбрать позицию, которая наилучшим образом подходит и не заходит за пределы экрана.
    В реальной реализации вам нужно будет также учесть размеры самого тултипа, чтобы точно определить, поместится ли он в доступном пространстве, и возможно, предусмотреть отступы от краев экрана.

    Также важно обеспечить динамическую перепроверку позиции тултипа при событиях, которые могут изменить положение или размер активатора, например, при изменении размера окна браузера (event resize) или прокрутке страницы (event scroll).

    И наконец, поскольку это может быть ресурсоемкий процесс, обдумайте использование debounce функции для событий, вызываемых слишком часто.
    Ответ написан
    1 комментарий
  • Как упростить запрос к БД?

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    Да, существует способ упростить запрос и сразу получить значения объекта objectId при помощи проекции в MongoDB. Проекция позволяет вам указать, какие поля должны возвращаться в результате запроса. Чтобы получить только объект objectId, можно использовать второй аргумент findOne, который определяет проекцию:
    const data = await this._db.collection('counters').findOne(
      { "objectId": { $exists: true } },
      { projection: { _id: 0, objectId: 1 } }
    );
    
    // Теперь data уже будет содержать только 'objectId',
    // и вы можете обращаться так: data.objectId.last

    Также, если вы хотите обновить данные более эффективно, вы можете использовать оператор $inc, который инкрементирует поле на указанное значение:
    await this._db.collection('counters').updateOne(
      { "objectId": { $exists : true } },
      { $inc: { "objectId.last": 1 } } // инкрементируем поле 'last' объекта 'objectId' на 1
    );

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

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    Чтобы сделать так, чтобы кастомные сниппеты и типы предлагались раньше встроенных при автодополнении, выполните следующие шаги:

    1. Откройте Настройки (можно использовать комбинацию клавиш Ctrl + , на Windows/Linux или Cmd + , на macOS).
    2. В поиске настроек введите "snippet" или "autocomplete".
    3. Найдите настройку Editor: Snippet Suggestions и измените её на "top". Это приведет к тому, что сниппеты будут отображаться в начале списка автодополнения.
    Ответ написан
    2 комментария
  • Как показать вес ребра графа в алгоритме Дейкстры?

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    Чтобы показать вес ребра графа в алгоритме Дейкстры, нам необходимо сохранять информацию о весах ребер между предыдущей вершиной в пути и текущей вершиной. Для этого мы можем вести отдельный объект, который будет хранить веса ребер для каждой вершины в path.

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

    Вот обновленная функция:
    function shortPathWithDistances(graph, start, end) {
      const distances = {};
      const visited = new Set();
      const path = {};
      const edgeWeights = {}; // Новый объект для хранения весов ребер
    
      for (const key in graph) {
        if (key !== start) {
          distances[key] = Infinity;
        } else {
          distances[start] = 0;
        }
      }
      while (!visited.has(end)) {
        let lowestDistance = Infinity;
        let node = null;
    
        for (const key in distances) {
          if (lowestDistance > distances[key] && !visited.has(key)) {
            lowestDistance = distances[key];
            node = key;
          }
        }
        const neighbors = graph[node];
        for (const key in neighbors) {
          const newDistance = distances[node] + neighbors[key];
          if (newDistance < distances[key]) {
            distances[key] = newDistance;
            path[key] = node;
            edgeWeights[key] = neighbors[key]; // Сохраняем вес ребра
          }
        }
        visited.add(node);
      }
      const shortPath = [];
      let current = end;
      while (current !== start) {
        const currentWithDistance = { node: current, edgeWeight: edgeWeights[current] };
        shortPath.unshift(currentWithDistance);
        current = path[current];
      }
      shortPath.unshift({ node: start, edgeWeight: 0 });
      return shortPath;
    }

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

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    Изменение прав доступа к папке в Dockerfile с помощью RUN chmod не действует на тома (volumes), примонтированные при помощи инструкции volumes в docker-compose.yml. Это связано с тем, что тома подключаются после выполнения всех команд указанных в Dockerfile, и их содержимое не изменяется в процессе построения образа, что означает, что фактические данные тома и права доступа управляются внешним хостом.

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

    Если же настройка прав доступа должна выполняться внутри контейнера (например, при инициализации или запуске), вы можете использовать команду entrypoint или command в docker-compose.yml для запуска скрипта, который будет устанавливать нужные права доступа при запуске контейнера каждый раз. Пример такого скрипта:
    # Dockerfile
    ...
    
    # Установка прав доступа в скрипте инициализации
    COPY ./set-permissions.sh /usr/local/bin/set-permissions.sh
    RUN chmod +x /usr/local/bin/set-permissions.sh
    
    # Запуск скрипта при старте контейнера
    ENTRYPOINT ["set-permissions.sh"]
    CMD ["apache2-foreground"]

    bash:
    # set-permissions.sh
    #!/bin/bash
    chmod o+w /app/web/uploads
    chmod o+w /app/web/uploads/result
    exec "$@"

    Этот скрипт изменит права на каталоги при каждом запуске контейнера, не зависимо от прав на машине хоста.
    Ответ написан
    Комментировать
  • Какую версию стоит учить?

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    Вам не нужно учить каждую версию по отдельности, и обычно изучение последней версии является наилучшим выбором, так как она будет содержать все последние функции и улучшения. На момент вашего вопроса это Angular 17. Вам не обязательно начинать с Angular 2, так как разработчики Angular постарались обеспечить обратную совместимость между версиями.

    Ключевыми аспектами, которые вы должны понимать при изучении Angular, являются компоненты, модули, сервисы, маршрутизация, формы, HTTP-коммуникация и управление состоянием. Основные концепции остаются стабильными, даже когда версия фреймворка обновляется.

    Если вы уже хорошо знаете React и Vue, то вам будет легче перейти на Angular, так как вы уже понимаете основы создания одностраничных приложений (SPA) и реактивного программирования.

    Я бы посоветовал вам — начать с изучения последней стабильной версии Angular, доступной для установки через CLI (Command Line Interface). Это позволит вам разрабатывать приложения, используя актуальный стек технологий и лучшие практики.
    Ответ написан
    Комментировать
  • Что такое культура программирования?

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    А что тут непонятного?
    -Поклонение богу программирования
    -Умение чистить программистскую карму
    -Умение проводить обряды (вроде танцев с бубном)
    -...
    Ответ написан
    Комментировать
  • Почему у nav есть внешний отступ?

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    Потому что у него есть сброс типа такого
    *{
      margin: 0;
      padding: 0;
    }

    а у вас нету
    Ответ написан
    Комментировать
  • Почему CSSTransition не вешает стили?

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    key={uniqid()}

    так нельзя делать. Ключи при каждом рендере должны быть одни и те же. В этом их смысл.
    Ответ написан
    Комментировать
  • Что посоветуете по GUI для питона?

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    хочу сделать поиск как в браузере

    И вот тут я подумал про Electron в JavaScript! Визуалка, контроль, анимация - обычный HTML, CSS и JS. Проект можно скомпилировать под винду, мак и линукс.
    Ответ написан
    Комментировать
  • Почему var отрабатывает после того, как отработал цикл for?

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    Миллион объяснений по всему инету. Добавлю еще одно.
    1 Сначала пролетает весь цикл. Внутрь setTimeout исполнение не заходит - откладывается на "потом"
    2 Наступает "потом" - исполнение входит в первый setTimeout и вот тут проявляется разница:
    если была использована var-переменная - то она не ограничена скобками цикла for, поэтому в каждой итерации цикла она менялась в глобальной области видимости и в итоге равна 6. Т.е. все setTimeout будут искать свою переменную сначала в своей области видимости (между скобок), не найдут её там, а затем увидят ее в глобальной области, а там она одна и равна 6
    а если была использована let-переменная - то она объявляется локально и остается в каждой итерации цикла своя - т.е. внутри скобок. И когда setTimeout ищет переменную - то каждый находит своё значение локально
    Ответ написан
    1 комментарий
  • Как заставить gulp.watch реагировать только на сохранение, а не любое изменение файлов?

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    Никак он не может отслеживать изменения в файле, пока его не сохранят. В каком редакторе вы пишите? Отключите опцию автосохранение редактора. В самом ватчере, можно использовать параметр задержки
    function watcher() {
      gulp.watch('./src/style.css', { delay: 500 }, styles);
    }
    // в данном случае будет задержка в полсекунды после сохранения файла.
    Ответ написан
    1 комментарий
  • Как вводить в интерфейсе mysql русские символы?

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    чтобы можно было вводить русские буквы в консоли mysql, нужно чтобы команда locale в системе выдавала:
    LANG=ru_RU.UTF-8
    LANGUAGE=
    LC_CTYPE="ru_RU.UTF-8"
    LC_NUMERIC="ru_RU.UTF-8"
    LC_TIME="ru_RU.UTF-8"
    LC_COLLATE="ru_RU.UTF-8"
    LC_MONETARY="ru_RU.UTF-8"
    LC_MESSAGES="ru_RU.UTF-8"
    LC_PAPER="ru_RU.UTF-8"
    LC_NAME="ru_RU.UTF-8"
    LC_ADDRESS="ru_RU.UTF-8"
    LC_TELEPHONE="ru_RU.UTF-8"
    LC_MEASUREMENT="ru_RU.UTF-8"
    LC_IDENTIFICATION="ru_RU.UTF-8"
    LC_ALL=

    а в докере выдает локали POSIX
    Поэтому либо ищите образ собранный на основе нужной локали, либо доустанавливайте сами нужные инструменты для генерации локали (locale-gen отсутствует)
    Ответ написан
    Комментировать
  • Не могу решать задачи по программированию?

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    но когда доходит до задач, у меня появляются проблемы

    Просто, наверное никто не сказал вам, что правильная постановка задачи - это уже половина решения. Помню физичка, на меня дико орала в школе, когда я на доске сразу начинал писать решение - она требовала, чтобы сначала я писал секцию: 'Дано:'. Потом, я понял насколько это было важным. Перед решением любой задачи, сначала необходимо осмыслить все исходные данные и четко прописать их. Почему, это нужно делать? - потому что некоторые важные условия могут быть заданы неявно и ускользать от внимания. К примеру, в условиях пишут: 'машина начала двигаться и достигла скорости 70км/ч' - если вы просто прочитаете это, то в голове у вас будет вертеться только одна цифра (скорость 70). Но если обратить внимание на фразу начала двигаться - можно записать что начальная скорость была 0. И уже имеем: v0 = 0км/ч, v1 = 70км/ч После того как все исходные данные выписаны и установлены - остается протоптать из них дорожку к результату - это и будет решение, которое обычно само напрашивается при таком подходе.
    Ответ написан
    3 комментария
  • Как правильно использовать get и set в классах?

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    где свойства firstName, lastName можно читать и менять.

    вы добавили методы только чтобы менять эти свойства. Добавьте геттеры тоже
    get firstName() {
       return this._firstName;
      }

    если не хотите, чтобы свойства вида _firstName светились наружу объекта - сделайте их приватными - замените все _firstName на #firstName
    Ответ написан
    Комментировать
  • При установке gulp-sass происходит ошибка, что делать?

    rqdkmndh
    @rqdkmndh
    Web-разработчик
    а что мешает забить ошибку в переводчик и узнать, что gulp-sass не содержит компилятор sass и его нужно установить отдельно?
    Решение npm i sass и в gulp-файле
    const sass = require('gulp-sass')(require('sass'));
    Ответ написан
    Комментировать