C++. Qt5.6. Combobox with checkboxes

На днях работал с замечательной библиотекой Qt. Нужно было добавить возможность выбора элементов по флажкам в выпадающем списке. Вроде тривиальная gui задача, но у меня немного вызвало затруднение. Ниже приведено мое решение. Исходная платформа - Win64.


multilist.h

#ifndef MULTILIST
#define MULTILIST

#include <QtWidgets>

class MultiList : public QComboBox {
    Q_OBJECT

private:
    QString displayText;
    QStandardItemModel *model;

public:
    MultiList(QWidget *parent = 0) : QComboBox(parent) {
        setEditable(true);

        displayText = "";
        model = new QStandardItemModel;
        slotUpdateText();

        connect(model, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(slotUpdate()));
    }

    void addItem(const QString &text) {
        int row = model->rowCount();
        QStandardItem* item = new QStandardItem();
        item->setText(text);
        item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
        item->setData(Qt::Unchecked, Qt::CheckStateRole);
        model->setItem(row, 0, item);
        this->setModel(model);
    }

    void addItems(const QStringList &texts) {
        for (int i = 0; i < texts.count(); i++) {
            addItem(texts.at(i));
        }
    }

    QStringList getCheckedItems() const {
        QStringList checkedItems;

        for (int i = 0; i < model->rowCount(); i++) {
            if (model->item(i, 0)->checkState() == Qt::Checked) {
                checkedItems << model->item(i, 0)->text();
            }
        }

        return checkedItems;
    }

    void setCheckedItems(const QStringList &items) {
        for (int i = 0; i < items.count(); i++) {
            int index = findText(items.at(i));

            if (index != -1) {
                model->item(index)->setData(Qt::Checked, Qt::CheckStateRole);
            }
        }

        slotUpdate();
    }

public slots:
    void slotUpdateText() {
        lineEdit()->setText(displayText);
    }

    void slotUpdate() {
        displayText = "";

        for (int i = 0; i < model->rowCount(); i++) {
            if (model->item(i, 0)->checkState() == Qt::Checked) {
                displayText = displayText + model->item(i, 0)->text() + "; ";
            }
        }

        QTimer::singleShot(0, this, SLOT(slotUpdateText()));
    }
};


#endif

main.cpp

#include "multilist.h"

int main(int argc, char** argv) {
    QApplication app(argc, argv);

    MultiList *multiList = new MultiList();

    multiList->addItems(QStringList() << "One" << "Two" << "Three" << "Four");
    multiList->setCheckedItems(QStringList() << "One" << "Two");

    QHBoxLayout *layout = new QHBoxLayout();

    layout->addWidget(new QLabel("Select items:"));
    layout->addWidget(multiList, 1);

    QWidget widget;
    widget.setWindowTitle("MultiList example");
    widget.setLayout(layout);
    widget.show();

    return app.exec();

}

PLSQL. UTL_HTTP package. Sending cyrillic chars

Если Вы используете встроенный пакет utl_http, то возможно Вы сталкивались с проблемой кодировок при отправке текстовых данных на кириллице. Для решения данной проблемы необходимо воспользоваться методов escape встроенного пакета utl_url:

utl_url.escape('Привет, мир!', true, 'utf-8')

Данный метод возвращает строку, готовую к отправке. Ниже приведен пример:

declare
  req utl_http.req;
  res utl_http.resp;
  url varchar2(4000) := 'http://some_address:port?test=1';
  l_data varchar2(100);
begin
  l_data := 'Привет, мир!';

  l_data := utl_url.escape(l_data, true, 'utf-8');

  utl_http.set_response_error_check(false);
  req := utl_http.begin_request(url, 'POST', 'HTTP/1.1');
 
  /* if need proxy connection
  utl_http.set_proxy('company.proxy.com:port', '');
  utl_http.set_authentication(req, 'user', 'password', for_proxy => true);
  */
 
  utl_http.set_header(req, 'Content-Type', 'charset=UTF-8');
  utl_http.set_header(req, 'Content-Length', length(l_data));
  utl_http.set_header(req, 'Content-Encoding', 'UTF-8');

  -- send post data
  utl_http.write_text(req, l_data);
  res := utl_http.get_response(req);
  utl_http.end_response(res);

  /* if need check status code
  res.status_code
  */

  exception
    when utl_http.end_of_body then
      utl_http.end_response(res);
    when others then
      dbms_output.put_line(sqlerrm);
end;

PLSQL. UTL_HTTP package

Ниже приведены примеры использования встроенного пакета utl_http. Например, если Вам необходимо запросить некоторые данные по веб адресу, тогда можно воспользоваться пакетом utl_http следующим образом: 

declare
  req utl_http.req;
  res utl_http.resp;
  url varchar2(4000) := 'http://aviationweather.gov/adds/tafs/';
  param varchar2(200) := '?station_ids=vhhh' || '&' || 'std_trans=standart' || '&' || 'submit_both=Get+TAFs+and+METARs';
  l_data varchar2(32000);
begin
  dbms_output.enable(1000000000);
 
  utl_http.set_response_error_check(false);
  req := utl_http.begin_request(url || param); -- GET
    

  /* if need proxy
  utl_http.set_proxy('company.proxy.com:port', '');
  utl_http.set_authentication(req, 'user', 'password', for_proxy => true);

  */
   
  utl_http.set_header(req, 'User-Agent', 'Mozilla/4.0');
   
  res := utl_http.get_response(req);
   
  loop
    utl_http.read_line(res, l_data, true);
    dbms_output.put_line(l_data);
  end loop;
   
  utl_http.end_response(res);

  exception
    when utl_http.end_of_body then
      utl_http.end_response(res);
    when others then
      dbms_output.put_line(sqlerrm);
end;


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

declare
  req utl_http.req;
  res utl_http.resp;
  url varchar2(4000) := 'http://some_address:port?test=1';
  l_data varchar2(32767);
begin
  l_data := 'bla-bla-bla';

  utl_http.set_response_error_check(false);
  req := utl_http.begin_request(url, 'POST', 'HTTP/1.1');
 
  /* if need proxy connection
  utl_http.set_proxy('company.proxy.com:port', '');
  utl_http.set_authentication(req, 'user', 'password', for_proxy => true);
  */
 
  utl_http.set_header(req, 'Content-Type', 'charset=UTF-8');
  utl_http.set_header(req, 'Content-Length', length(l_data));
  utl_http.set_header(req, 'Content-Encoding', 'UTF-8');

  -- send post data
  utl_http.write_text(req, l_data);
  res := utl_http.get_response(req);
  utl_http.end_response(res);

  /* if need check status code
  res.status_code
  */

  exception
    when utl_http.end_of_body then
      utl_http.end_response(res);
    when others then
      dbms_output.put_line(sqlerrm);
end;


Ниже приведен еще один пример POST запроса, но в примере рассмотрена возможность возврата полученного ответа в виде данных типа CLOB:

create or replace package body test_pkg is

  procedure send_message(p_message in varchar2,
                         p_status out integer,
                         p_response out clob)
    is
      req utl_http.req;
      res utl_http.resp;
      url varchar2(4000) := 'http://some_address:port?test=1';
      buffer varchar2(4000);
      clob_buffer clob;
    begin
      utl_http.set_response_error_check(false);
      req := utl_http.begin_request(url, 'POST', ' HTTP/1.1');
     
      /* if need proxy connection
      utl_http.set_proxy('company.proxy.com:port', '');
      utl_http.set_authentication(req, 'user', 'password', for_proxy => true);
      */
     
      utl_http.set_header(req, 'Content-Type', 'charset=UTF-8');
      utl_http.set_header(req, 'Content-Length', length(p_message));
      utl_http.set_header(req, 'Content-Encoding', 'UTF-8');

      -- send post data
      utl_http.write_text(req, p_message);
      res := utl_http.get_response(req);

      -- set response status
      if res.status_code = 200 then
        p_status := 1;
      else
        p_status := 0;
      end if;

      -- read response
      begin
        clob_buffer := empty_clob;

        loop
          utl_http.read_text(res, buffer, length(buffer));
          clob_buffer := clob_buffer || buffer;
        end loop;

        p_response := clob_buffer;
        utl_http.end_response(res);

        exception
          when utl_http.end_of_body then
            p_response := clob_buffer;
            utl_http.end_response(res);
          when others then null;
            dbms_output.put_line(sqlerrm);
            dbms_output.put_line(dbms_utility.format_error_backtrace);
            utl_http.end_response(res);
      end;

      exception
        when others then
          dbms_output.put_line(sqlerrm);
    end;
 
begin
  -- init
  null;
end test_pkg;

Oracle. Linear Regression

Довольно-таки распространенной статистической задачей анализа ряда данных является поиск линейной регрессии. Oracle предоставляет для данной цели ряд функций. Ниже приведен пример нахождения коэффициентов линейной регрессии y = kx + b:

with
  src(y, x) as (
    select 3, 0 from dual union all
    select 5, 1 from dual union all
    select 7, 2 from dual union all
    select 9, 3 from dual union all
    select 11, 4 from dual union all
    select 13, 5 from dual
  )

select 
  regr_slope(y, x) as k, 
  regr_intercept(y, x) as b 
from src

На выходе получим вот такую зависимость:

y = 2x + 3

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

Nginx with Apache. 504 Gateway time-out

В моем случае Nginx работает в связке с Apache в роли проксирующего веб-сервера. Попробовали выполнить тяжелый скрипт и получили вот такой ответ:

504 Gateway time-out

На стороне Apache ограничений нет. Как выяснилось время ожидания при чтении ответа и время ожидания при передаче запроса у Nginx по умолчанию выставлено в одну минуту. Поэтому для решения данной проблемы достаточно прописать в конфиге (например в location) следующие строки:

server {
...
  location / {
    ...
    proxy_read_timeout 600; # время ожидания при чтении ответа
    proxy_send_timeout 600; # время ожидания при передаче запроса
    ...
  }
...
}

После перегружаем настройку Nginx

sudo nginx -s reload