воскресенье, 14 декабря 2025 г.

Релиз r49-20251214

 


Версии компонентов:
  • libtoxic v7.6.4
  • cr49 v1.3.0
  • Qr49 v3.12.13
Изменения:
  1. Qr49: исправлена ошибка, связанная с появлением некорректных символов в имени по умолчанию для шаблона импорта данных при его сохранении;
  2. Qr49: новый формат дата-время;
  3. libtoxic: новый формат дата-время;
  4. libtoxic: исправлена ошибка выбора допустимого значения gCO по циклу R96_I8;
  5. Общее: сборка под Windows выполнена с использованием Qt версии 5.15.18.

вторник, 3 декабря 2024 г.

Релиз r49-20241109



Версии компонентов:
  • libtoxic v7.6.2
  • cr49 v1.3.0
  • Qr49 v3.12.11
Изменения:
  1. libtoxic: в отчет по результатам расчета выбросов твердых частиц (текстовый вариант) добавлены параметры wfei и w_status;
  2. libtoxic: в отчет по результатам расчета выбросов твердых частиц (вариант HTML) добавлен параметр wfei;
  3. libtoxic: в файл с отладочными данными добавлен параметр wfei;
  4. libtoxic: исправлена ошибка в функции формирования отчета по результатам выбросов газообразных вредных веществ (вариант HTML);
  5. Qr49: оптимизирована функция loadAllSourceData;
  6. Qr49: устранена ошибка переключения языка интерфейса из главного меню;
  7. Общее: сборка под Windows выполнена с использованием Qt версии 5.15.15.

четверг, 7 января 2021 г.

Emacs Lisp. Представление чисел в различных системах счисления (dec, hex, bin)

При работе с текстом мне постоянно приходится менять представление чисел, переводя из одной системы счисления в другую. Что я хотел сказать? Emacs прекрасен. Взял и накидал несколько функций на elisp. Теперь, выделив число в тексте, можно быстро представить его в другой системе. Ниже привожу листинг.

;; convert decimal to binary
(defun pa23-dec2bin (start end)
  "Convert decimal to binary."
  (interactive "r")
  (let ((var 0) (res ""))
    (setq var (string-to-number (buffer-substring-no-properties start end)))
    (while (not (= var 0))
      (setq res (concat (if (= 1 (logand var 1)) "1" "0") res))
      (setq var (lsh var -1)) )
    (if (string= res "") (setq res "0"))
    (delete-region start end)
    (insert res) ) )

;; convert decimal to hexadecimal
(defun pa23-dec2hex (start end)
  "Convert decimal to hexadecimal."
  (interactive "r")
  (let ((var 0) (res ""))
    (setq var (string-to-number (buffer-substring-no-properties start end)))
    (setq res (upcase (format "%x" var)))
    (delete-region start end)
    (insert res) ) )

;; convert hexadecimal to binary
(defun pa23-hex2bin (start end)
  "Convert hexadecimal to binary."
  (interactive "r")
  (let ((var "") (res ""))
    (setq var (string-to-number (buffer-substring-no-properties start end) 16))
    (while (not (= var 0))
      (setq res (concat (if (= 1 (logand var 1)) "1" "0") res))
      (setq var (lsh var -1)) )
    (if (string= res "") (setq res "0"))
    (delete-region start end)
    (insert res) ) )

;; convert hexadecimal to decimal
(defun pa23-hex2dec (start end)
  "Convert hexadecimal to decimal."
  (interactive "r")
  (let ((var 0) (res ""))
    (setq var (string-to-number (buffer-substring-no-properties start end) 16))
    (setq res (number-to-string var))
    (delete-region start end)
    (insert res) ) )

;; convert binary to decimal
(defun pa23-bin2dec (start end)
  "Convert binary to decimal."
  (interactive "r")
  (let ((var 0) (res ""))
    (setq var (string-to-number (buffer-substring-no-properties start end) 2))
    (setq res (number-to-string var))
    (delete-region start end)
    (insert res) ) )

;; convert binary to hexadecimal
(defun pa23-bin2hex (start end)
  "Convert binary to hexadecimal."
  (interactive "r")
  (let ((var 0) (res ""))
    (setq var (string-to-number (buffer-substring-no-properties start end) 2))
    (setq res (upcase (format "%x" var)))
    (delete-region start end)
    (insert res) ) )

вторник, 5 января 2021 г.

cmake и wxwidgets на archlinux

Так уж получается, что потянуло меня опять по ряду причин на WxWidgets. Системой моей по-прежнему является ArchLinux, а для сборки программ я предпочитаю cmake. Подготовил файлы, запускаю

cmake -G "Unix Makefiles"

и получаю сообщение об ошибке

Расследование привело меня к файлу /usr/lib/wx/config/gtk3-unicode-3.0, на который есть символическая ссылка в /usr/bin. Вот только называется файл-ссылка wx-config-gtk3, а cmake хотел просто wx-config.

Решение проблемы:

sudo ln -s /usr/lib/wx/config/gtk3-unicode-3.0 /usr/bin/wx-config

И наш 

cmake -G "Unix Makefiles"

теперь отрабатывает без ошибок.

вторник, 7 января 2020 г.

Настройка шрифтов в Arch Linux

Хотелось бы еще раз остановиться на вопросе настройки шрифтов в Arch, так как, столкнувшись с чистой установкой, которую не делал уже не знаю даже сколько лет, пришлось искать информацию для решения некоторых проблем, и это оказалось непросто.
  1. Устанавливаем желаемую версию интерпретатора freetype2 в файле /etc/profile.d/freetype2.sh. Для этого необходимо раскомментировать строку export FREETYPE... и отредактировать ее. Лично я предпочитаю версию 35 (classic mode), ибо только она дает прекрасное сглаживание шрифтов (в основном я использую шрифты семейств Dejavu и Ubuntu).
  2. Настраиваем шрифты, создавая/удаляя символические ссылки (symlinks) в /etc/fonts/conf.d на соответствующие файлы в /etc/fonts/conf.avail. Для себя я считаю необходимым добавить ссылки на следующие файлы:
    10-hinting-full.conf
    10-sub-pixel-rgb.conf
    11-lcdfilter-default.conf
  3. Настраиваем шрифты в окружении рабочего стола. Я использую xfce4, поэтому привожу снимок окна для этого DE.
  4. Если необходимо перезагрузиться, перезагружаемся и убеждаемся, что шрифты во всех приложениях выглядят идеально, просто прекрасно, за исклюнием некоторых, использующих qt5 (например, virtualbox и vlc). В следующих пунктах решаем эту проблему.
  5. Проверяем, установлен ли пакет qt5ct. Если нет, его необходимо установить.
  6. В файле /etc/profile дописываем пару строк:
    export QT_QPA_PLATFORMTHEME="qt5ct"
    export QT_AUTO_SCREEN_SCALE_FACTOR=0

    Сколько же у меня ушло времени на поиск второй строки. Весь интернет говорит только о первой (а этого мало, эффект ноль), и только установив на виртуальную машину manjaro и поковырявшись в ней, я понял что нужно.
  7. Выбираем желаемые шрифты для приложений, использующих qt5 в конфигураторе qt5ct. Достаточно просто выбрать шрифты, создавать fonts.conf не нужно.
Ну вот и все. Теперь абсолютно все программы выглядят замечательно и пользоваться системой приятно, глаза благодарны.
Вот так теперь выглядят шрифты в разных приложениях.
 
UPD 2023-04-29
 
При переходе некоторых приложений на использование библиотеки gtk4 отрисовка шрифтов у них поломалась. Шрифты выглядят размыто. Для исправления этой ситуации необходимо создать файл конфигурации ~/.config/gtk-4.0/settings.ini, в котором прописать параметры gtk-hint-font-metrics, gtk-xft-antialias, gtk-xft-hinting, gtk-xft-hintstyle и gtk-xft-rgba. Привожу содержимое моего файла.
 
[Settings]
gtk-hint-font-metrics=1
gtk-theme-name=Adwaita
gtk-icon-theme-name=elementary
gtk-font-name=DejaVu Sans ExtraLite 10
gtk-cursor-theme-name=Adwaita
gtk-cursor-theme-size=0
gtk-toolbar-style=GTK_TOOLBAR_BOTH_HORIZ
gtk-toolbar-icon-size=GTK_ICON_SIZE_LARGE_TOOLBAR
gtk-button-images=1
gtk-menu-images=1
gtk-enable-event-sounds=0
gtk-enable-input-feedback-sounds=0
gtk-xft-antialias=1
gtk-xft-hinting=1
gtk-xft-hintstyle=hintfull
gtk-xft-rgba=none
gtk-application-prefer-dark-theme=0
 
UPD 2024-12-08
 
Пишу, конечно, с большим опозданием, но, как говорится, лучше поздно, чем никогда. Пара новостей. Во-первых, разработчики gtk4, похоже, никак не уймутся и опять поломали отрисовку шрифтов. Мне это порядком надоело. Я использовал две программы на gtk4: transmission и pavucontrol. Первую заменил на qbittorrent, а вторую вообще выкинул. Во-вторых, так как уже достаточно приличное количество программ перешло с qt5 на qt6, то пришлось внести поправки в файлы /etc/profile и ~/.profile. А именно заменить строки
export QT_QPA_PLATFORMTHEME="qt5ct"
export QT_AUTO_SCREEN_SCALE_FACTOR=0
на
export QT_QPA_PLATFORMTHEME="qt6ct"
export QT_AUTO_SCREEN_SCALE_FACTOR=0
export QT_ENABLE_HIGHDPI_SCALING=0

Разумеется, должна быть установлена утилита qt6ct, с помощью которой выставлены желаемые настройки шрифтов. Да, еще одно изменение в моей системе касательно шрифтов. С семейства ubuntu я давно уже перешел на Dejavu Sans, чего и всем желаю. По мне так это самые приятные шрифты.

воскресенье, 20 января 2019 г.

Таблично заданные функции и линейная интерполяция на C++

Время от времени в наших программах, при решении различных расчетных задач, возникает необходимость получать значения таблично заданных функций одной или двух переменных. Наиболее простым и надежным решением в данном случае является линейная интерполяция. В данной заметке я хочу привести пример определения значения таблично заданной функции двух переменных в виде реализации на C++.
В случаях, когда значения аргументов функции выходят за пределы таблицы, можно поступать по-разному: останавливать расчет и возвращать код ошибки или урезать значение аргумента до крайнего, представленного в таблице. В примере приведем первый вариант.
Стоит также учесть, что в зависимости от значений аргументов наш подход к работе с таблицей будет отличаться.
  1. Значения обоих аргументов совпадают со значениями сетки. В этом случае, не прибегая ни к каким вычислениям, мы выбираем значение функции из таблицы.
  2. Один из аргументов функции совпал со значением сетки. Тогда следует воспользоваться формулой линейной интерполяции для функции одной переменной.
  3. Ни один из аргументов функции не совпал со значениями сетки. Используем в таком случае формулы линейной интерполяции для функции двух переменных, что, собственно, не сильно отличается от работы по п.2 - то же самое, только в два захода.
Хорошо, теперь, наконец, переходим к коду. Пусть наша таблица определена несколькими векторами, содержащими значения сетки по оси X, значения сетки по оси Y и сами значения функции, то есть Z.
const vector<double> X = { 1, 1.5, 2, 2.5 };
const vector<double> Y = { 25, 30, 40 };
const vector< vector<double> > Z =
{ {0.392, 0.476, 0.574, 0.658},
  {0.406, 0.588, 0.770, 1.050},
  {0.434, 0.700, 0.980, 1.119} };
Затем приведем функции линейной интерполяции. В случае 3D, для пущей наглядности, я привожу в коде схему обозначения точек.
double linInterp2D(
    double x1,  double y1,
    double x2,  double y2,
    double x
    ) {

    double y = y1 + (x - x1) * (y2 - y1) / (x2 - x1);

    return y;
}

double linInterp3D(
    double x1,  double y1,
    double x2,  double y2,
    double z11, double z21, double z12, double z22,
    double x,   double y
    ) {

    /*

         |
      y2-| z12       z22
         |
       y-|      z
         |
      y1-| z11       z21
         |_______________
           |    |    |
           x1   x    x2

    */

    double z1 = z11 + (z12 - z11) * (y - y1) / (y2 - y1);
    double z2 = z21 + (z22 - z21) * (y - y1) / (y2 - y1);
    double z = z1 + (z2 - z1) * (x - x1) / (x2 - x1);

    return z;
}
И, наконец, нахождение значения таблично заданной функции по заданным x и y.
double findZ(double x, double y) {

    double x1 = 0; double x1i = 0;
    double y1 = 0; double y1i = 0;
    double x2 = 0; double x2i = 0;
    double y2 = 0; double y2i = 0;
    double z11 = 0;
    double z21 = 0;
    double z12 = 0;
    double z22 = 0;

    bool x_inside_range = false;
    bool y_inside_range = false;

    for (size_t i=0; i<X.size()-1; i++) {

        if ( x == X[i] ) {
            x1 = x2 = X[i];
            x1i = x2i = i;
            x_inside_range = true;
            break;
        }
        else if ( (x > X[i]) && (x < X[i+1]) ) {
            x1 = X[i];
            x1i = i;
            x2 = X[i+1];
            x2i = i+1;
            x_inside_range = true;
            break;
        }
        else if ( x == X[i+1] ) {
            x1 = x2 = X[i+1];
            x1i = x2i = i+1;
            x_inside_range = true;
            break;
        }
    }

    if ( !x_inside_range ) {
        cout << "x is outside of X axis range!\n";
        return -666;
    }

    for (size_t i=0; i<Y.size()-1; i++) {

        if ( y == Y[i] ) {
            y1 = y2 = Y[i];
            y1i = y2i = i;
            y_inside_range = true;
            break;
        }
        else if ( (y > Y[i]) && (y < Y[i+1]) ) {
            y1 = Y[i];
            y1i = i;
            y2 = Y[i+1];
            y2i = i+1;
            y_inside_range = true;
            break;
        }
        else if ( y == Y[i+1] ) {
            y1 = y2 = Y[i+1];
            y1i = y2i = i+1;
            y_inside_range = true;
            break;
        }
    }

    if ( !y_inside_range ) {
        cout << "y is outside of Y axis range!\n";
        return -666;
    }

    z11 = Z[y1i][x1i];
    z21 = Z[y1i][x2i];
    z12 = Z[y2i][x1i];
    z22 = Z[y2i][x2i];

    if ( (x1 == x2) && (y1 == y2) ) {
        return Z[y1i][x1i];
    }
    else if ( (x1 == x2) && (y1 != y2) ) {
        return linInterp2D(y1, z11, y2, z12, y);
    }
    else if ( (x1 != x2) && (y1 == y2) ) {
        return linInterp2D(x1, z11, x2, z21, x);
    }
    else {
        return linInterp3D(x1, y1, x2, y2, z11, z21, z12, z22, x, y);
    }
}
Вот и все. Вроде бы совершенно ничего сложного, но такие вот заготовочки весьма полезны, когда сроки поджимают, а некоторые функции уже написаны. Это здорово экономит время.

пятница, 10 ноября 2017 г.

ogg в mp3 без лишней возьни с мышью и окошками

До чего же мне нравится команда find. Итак, если, к примеру, у вас в машине магнитола отказывается читать правильные форматы типа ogg и требует mp3, то деваться некуда, придется ее уважить, ибо музыку в дороге послушать иногда хочется, особенно если дорога дальняя. Для конвертирования всех файлов ogg в текущем каталоге в mp3 с битрейтом, например, 320 кбит/с, можно использовать связку find и ffmpeg следующим образом:
find . -name "*.ogg" -exec ffmpeg -i {} -ab 320k {}.mp3 \;

понедельник, 15 мая 2017 г.

Релиз r49-20170515



Версии компонентов:
  • libtoxic v7.5.4
  • cr49 v1.3.0
  • Qr49 v3.12.9
Изменения:
  1. Qr49: устранена ошибка, приводившая к неверному выбору файла для диалога "Отладочные данные" (проявлялась случайным образом);
  2. Qr49: улучшен алгоритм выбора файлов для вкладки "Отчеты" (по завершению расчетов).

воскресенье, 5 марта 2017 г.

Релиз r49-20170305



Версии компонентов:
  • libtoxic v7.5.4
  • cr49 v1.3.0
  • Qr49 v3.12.7
Изменения:
  1. Qr49: устранена ошибка с диапазонами данных в диалоге ввода масс фильтров ТЧ;
  2. Общее: сборка под Windows выполнена с использованием Qt версии 5.8.0.

суббота, 31 декабря 2016 г.

Релиз r49-20161231



Версии компонентов:
  • libtoxic v7.5.4
  • cr49 v1.3.0
  • Qr49 v3.12.6
Изменения:
  1. libtoxic: устранена ошибка, приводящая к появлению мусора в отчете ReportGAS_OST_37.001.234-81 при некоторых сочетаниях исходных данных;
  2. Qr49: некоторые внутренние улучшения;
  3. Общее: сборка под Windows выполнена с использованием Qt версии 5.7.1.

Релиз reup-1.11.0


Да, вот так после 1.7.0 сразу 1.11.0. На самом деле скачка не было, просто промежуточные версии не публиковались. Из изменений в 1.11.0: обеспечена работа с файлами edc, оптимизированы правила генерации makefile, незначительные внутренние улучшения.

четверг, 29 декабря 2016 г.

Emacs Lisp. Конвертирование массива ASCII в текст и обратно

По работе мне достаточно часто приходится работать с текстовыми файлами, содержащими строки в виде массивов ASCII, где значения отдельных символов разделены точкой с запятой. Что-то типа "118;50;48;49;54;49;50;50;57". Разумеется, хотелось бы увидеть эту информацию в более комфортном для человека виде, как то "v20161229", откорректировать и преобразовать обратно в массив ASCII. Так как с текстом я почти всегда работаю в emacs, то самым логичным решением было бы написать пару функций на emacs lisp. Тем более, что пользоваться какими-то приложениями, таская текст из редактора в буфер, потом в специальный конвертер, потом опять в буфер и, наконец, обратно в редактор, ну вообще не вариант.
Код функций получился вот таким.
(defun pa23-ascii2text (start end)
  "Convert ASCII codes to text."
  (interactive "r")
  (let ((text))
    (progn
      (setq line  (buffer-substring-no-properties start end))
      (setq ascii (split-string line ";"))
      (mapc
       (lambda (code)
         (push (string-to-number code) text)
         )
       ascii )
      )
    (delete-region start end)
    (insert (apply 'string (reverse text)))
    )
  )

(defun pa23-text2ascii (start end)
  "Convert text to ASCII codes."
  (interactive "r")
  (let ((temp) (ascii))
    (progn
      (setq temp (string-to-list (buffer-substring-no-properties start end)))
      (mapc
       (lambda (code)
         (setq ascii (concat ascii (number-to-string code) ";"))
         )
       temp )
      )
    (delete-region start end)
    (insert (substring ascii 0 -1))
    )
  )
Работа с функциями выглядит следующим образом: выделяем нужный текст, вызываем соответствующую функцию, выделенный текст будет заменен выхлопом функции.

пятница, 12 августа 2016 г.

ICU for Windows (MinGW)

Для одного из проектов мне потребовался драйвер qsqlite с поддержкой icu. Разумеется, для пересборки драйвера мне, в данном случае, потребовались также и сами библиотеки icu, которые, ввиду отсутствия необходимых бинарников, пришлось собирать из исходников.
Для тех, кто под Windows тоже использует gcc, я решил выложить бинарники icu на sourceforge. Пожалуйста, пользуйтесь.