понедельник, 11 ноября 2013 г.

Динамические библиотеки под Linux на С++.

Для того, чтобы действительно научиться работать с какой-то технологией, по ней надо рассказать. Этим я сегодня и займусь. Итак. Буду я писать, как пользоваться динамическими библиотеками в C++ на GNU Linux. Использовать буду компилятор g++.
А писать мы будем библиотечку, реализующую какое-нибудь простенькое шифрование.


Читать дальше......

четверг, 31 октября 2013 г.

Qt 5.0 Работа с сетью. и Лайф-хак по запуску Qt программ без зависимостей.

Понадобилось как-то мне передавать достаточно специфичные данные по TCP, а на другом конце другая программа их принимает и возвращает некоторый ответ. В Linux  есть замечательная улитка nc для тестирования подобных велосипедов. Хоть она и не идеально подходит для моих нужд( мне нужны 16-ричные данные ), но я бы ей обошелся. Под виндой я нашел только Гипертерминал, который работает из рук вот плохо и умеет только подключатся к портам, а сам открывать не умеет. После недолгого и безуспешного гугления, было принято решение самостоятельно написать свой велосипед для этих нужд с преферансом и сеньоритами да ещё и кросс платформенный.  

Читать дальше......

среда, 31 июля 2013 г.

Использование api vk python : Скачивание стены Вконтакте

Аватарка группы
Евгений Онегин: Глава 11
  


Введение



Добрый день, давно я ничего не писал - много было причин. За это время накопилось достаточно большое количество материала и я постараюсь его сюда выставить как можно полнее. Сегодня  я хочу рассказать о работе с API контакта через Python, а примером послужит - скачивание стены журнала Евгений Онегин. Глава 11. Если вам лень читать как я всё это делал, а охота поскорее скачать свою стену, переходите сразу к разделу "Отчёт и тестирование".


Читать дальше......

четверг, 15 ноября 2012 г.

С++ Дата из строки ( c миллисекундами)

Случилась мне необходимость считать из FITS файла время и дату снимка. В этом посту я расскажу, как считать атрибуты с FITS файла и простой способ перевести время и дату из строки в реальные дату и время. Кому интересно, прошу пожаловать под кат...
1 часть - чтения атрибутов FITS файла
Начнём с более простого - вспомним и прошлого моего поста,как мы читали fits файл:
 pFits.reset(new FITS(path,Read,true));
    image = &pFits->pHDU();// get main image from file
    image->readAllKeys();//read Keys
    image->read(contents); // read DATA to valarray
Я ведь не просто так выполнял тогда readAllKeys. Этот метод считывает все дополнительные параметры файла FITS. У PHDU есть ещё один интересный метод - keyWord(). Он возвращает ассоциативный массив(map), ключом которого является строка(название атрибута), а значением - ссылка на специальный тим Keyword (значение атрибута).То есть, этот метод возвращает map<string,*Keyword>. Как работать с map я не буду рассказывать, а из Keyword можно считать в строку с помощью его метода value(). В моем файле дата записана под ключом DATE, а время - TIME-OBS. Вот и считаем сначала в ассоциативный массив, а потом из ассоциативного массива получим дату и время по ключу.
    Keyword* Date = keys.at("DATE");
    Keyword* Time = keys.at("TIME-OBS");

    std::string Dateval;
    std::string Timeval;

    Date->value(Dateval);
    Time->value(Timeval);
Теперь у нас есть 2 строки - дата и время.
2 часть - Перевод из строки в дату
Киким классом даты и времени вам удобно пользоваться? QDateTime? tm? time_t? - Не важно.Любой из ваших любимых типов вы можете создать, если у вас в интовых значениях есть кол-во годов, месяцев, дней, часов, минут, секунд, миллисекунд ... В начале, мне приглянулся тип tm, но в нем нет миллисекунд, поэтому, я создал свой struct для времени. Вот такой:
struct my_tm
{
    int tm_msec;
    int tm_sec;
    int tm_min;
    int tm_hour;
    int tm_mday;
    int tm_mon;
    int tm_year;
    int tm_wday;
    int tm_yday;
    int tm_isdst;
};
А читаем мы в него с помошью замечательной функции sscanf вот таким образом:
 my_tm tm1;
 sscanf(Dateval.c_str(),"%4d-%2d-%2d",&tm1.tm_year,&tm1.tm_mon,&tm1.tm_mday);
 sscanf(Timeval.c_str(),"%2d:%2d:%2d.%3d",&tm1.tm_hour,&tm1.tm_min,&tm1.tm_sec,&tm1.tm_msec);
Вот теперь, мы можем создать любой, необходимый нам класс времени и даты:
    QDate qdate(tm1.tm_year,tm1.tm_mon,tm1.tm_mday);
    QTime qtime(tm1.tm_hour,tm1.tm_min,tm1.tm_sec);
    QDateTime qdatetime(qdate,qtime);
А самое вкусное - то, что функция sscanf реализована в самых разных языках кроме Си, а это значит, что данный метод работает очень много где....
Читать дальше......

четверг, 1 ноября 2012 г.

Чтение - запись Fits C++

В прошлый раз я рассказал, как подключить библиотеку для работы с файлами FITS к g++ в линукс. Сегодня мы займёмся непосредственно чтением картинки, небольшим её редактированием и записью в новую картинку. На данном этапе мы не будем учитывать сотни возможностей формата Fits(большое кол-во слоев изображения, дополнительные параметры , многомерные таблицы и т.д. ). В качестве преобразования изображения, мы возьмём инвертирование. Мы просто составим программу вот такого алгоритма


Читать дальше......

понедельник, 29 октября 2012 г.

std::valarray и std::slice в С++

Разбирал стандартные примеры из CCfits. Эти ребята очень активно(не всегда оправдано) используют стандартную библиотеку C++. Как оказалось, я в ней плаваю. Сегодня я узнал о замечательном шаблоне массива С++ std - valarray и классом - slice,который позволяет очень удобно стучатся одновременно к многим элементам массива. Я провёл некоторую сравнительную характеристику и построил графики быстродействия. Хочу поскорее рассказать вам, что к чему. valarray - одна из реализаций массива C++.Она действительно удобная. Написана она для выполнения векторных операций. Посмотрите только, какие вкусности нам предлагают. Одна из этих вкусностей - класс slice, который работает как указатель сразу на большое кол-во элементов valarray. К примеру, у нас есть RGB картинка, записанная в одномерный массив. std::valarray row(n); и мы хотим дать картинке определённый цвет( каждый 3*i пиксель заменить на значение R, 3*i+1 на значение G, 3*i+2 на значение B). Как мы делали это раньше?
unsigned char red = 255;
 unsigned char green = 128;
 unsigned char blue = 0;
 for(int i =0;i<n; i = i 3)
  row[i]=red;
 for(int i =1;i<n;i =3)
  row[i]=green;
 for(int i =2;i<n;i =3)
  row[i]=blue;
А с помощью групповых указателей мы можем поступить так:
    slice red(1,n/3,3);
 slice green(2,n/3,3);
 slice blue(3,n/3,3);
 
 row[red]=255;
 row[green]=128;
 row[blue]=0;
Удобно не правда ли?
Slice принимает 3 параметра:
  1.  slice::start  -  первый элемент в выборке 
  2.  slice::size -  количество элементов в выборке
  3.  slice::stride - шаг или расстояние между элементами, которые выбраны
 Это правда удобно и я захотел проверить быстродействие этого метода, в сравнении со старым-дедовским. Буду проверять 3 метода:


   1-ый : Simple - старый добрый массив указателей в связке с циклом for
   2-й :  Valarray - массив valarray в связке с циклом for
   3-й :  Slice - массив valarray в связке с объектом slice

Суть эксперимента:  есть массив из n элементов. В этом массиве нужно заменить каждый 3 элемент массива на какое-либо значение. Замена производится 3 вышеперечисленными способами с замером быстродействия каждого. Кол-во элементов массива варьируется от          1 000 000 до 100 000 000 c с шагом в 1 000 000. Для каждого метода и кол-ва элементов массива проверка осуществляется 50 раз с нахождением среднего времени. По окончании замера производительности, построить графики зависимости времени исполнения замены от  кол-ва элементов массива по 3 методам. Проанализировать динамику каждого из методов.
Цель эксперимента:
  Сравнить быстродействие 3 методов доступа к элементам массива на запись. 

Для построения графиков я использовал библиотеку QT. Рисовал просто на QLable, её и вывел на экран.

Ниже представлена программа реализующая вышеуказанную задачу:
#include <QApplication>
#include "QPainter"
#include <QLabel>
#include <QRect>
#include <QPixmap>
#include <QDebug>

#include <iostream>
#include <valarray>
#include <unistd.h>
#include <time.h>
#define ZAMENA 1

using namespace std;

long Simple(long count){
 int * na = new int[count];
 long t1 = clock();
 for(int i = 1;i<count;i =3)
  na[i]=ZAMENA;
 long t2 = clock();
 delete[] na;
 return t2-t1;

}

long Valarray(long count){
 std::valarray<int> a(count);
 long t1 = clock();
 for(int i = 1;i<count;i =3)
  a[i]=ZAMENA;
 long t2 = clock();
 return t2-t1;
}



long Slice(long count){
 std::valarray<int> a (count);
 long t1 = clock();
 slice s (1,count/3,3);
 a[s]=ZAMENA;
 long t2 = clock();
 return t2-t1;
}


int main(int argc, char *argv[]) {
 int w =500;
 int h = 500;
 QColor SimplePen(255,0,0);
 QColor SlicePen(0,255,0);
 QColor ValarrayPen(0,0,255);
 
 
 QApplication app(argc, argv);
 QLabel *MainLable = new QLabel("Graphs");
 MainLable->setBaseSize(w,h); 
 QPixmap MainPixMap(w,h);
 MainPixMap.fill(MainLable,0,0);
 QPainter MainPainter(&MainPixMap);
 MainPainter.fillRect(MainPainter.viewport(),QColor(255,255,255));
    MainPainter.setPen(SimplePen);
    MainPainter.drawLine(10,10,100,10);
    MainPainter.drawText(110,10,"Simple");
    MainPainter.setPen(SlicePen);
    MainPainter.drawLine(10,25,100,25);
    MainPainter.drawText(110,25,"Slice");
    MainPainter.setPen(ValarrayPen);
    MainPainter.drawLine(10,40,100,40);
    MainPainter.drawText(110,40,"Valarray");


    /*
     * Example of drawing y = f%u043E%u043E(x)
    int count = 1000000;
    int dx = 1000;
    double maxy= foo(count);
    for(double x = dx;x<count;x =dx){
  double y = foo(x);
  double y2 = foo(x dx);
  double x2 = x dx; 
  MainPainter.drawLine((x/count)*w,h-((y/maxy)*h),(x2/count)*w,h-((y2/maxy)*h));
 }
 */
 
  int count_tests =50;
  long n = 100000000;
  long dx  = 1000000;
  long *args = new long[n/dx];
  long *SimpleTimes = new long[n/dx];
  long *SliceTimes = new long[n/dx];
  long *ValarrayTimes = new long[n/dx];
  
  for (int i = 0 ;i<n/dx;i  ){
   args[i]=dx*i;
  }
  
  long max =0;
  
  qDebug()<<"Simple begins";
  
  for (int j=0 ;j<n/dx-1;j  ){
   long S=0;
   for (int i = 0;i<count_tests;i  )
    S =Simple(args[j]);
   S = S/count_tests;
   SimpleTimes[j]=S;
   max = max<S?S:max;
   if (j%10==0)
    qDebug()<<j;
  }
  qDebug()<<"Simple ends";
  qDebug()<<"Valarray begins";
  for (int j=0 ;j<n/dx-1;j  ){
   long S=0;
   for (int i = 0;i<count_tests;i  )
    S =Valarray(args[j]);
   S = S/count_tests;
   ValarrayTimes[j]=S;
   max = max<S?S:max;
   if (j%10==0)
    qDebug()<<j;
  }
  qDebug()<<"ValarrayTimes ends";
  
  qDebug()<<"Slice begins";
  for (int j=0 ;j<n/dx-1;j  ){
   long S=0;
   for (int i = 0;i<count_tests;i  )
    S =Slice(args[j]);
   S = S/count_tests;
   SliceTimes[j]=S;
   max = max<S?S:max;
   if (j%10==0)
    qDebug()<<j;
  }
  qDebug()<<"Slice ends";
  qDebug() <<"max"<< max;
  
  for (int j=0 ;j<n/dx-2;j  ){
   MainPainter.setPen(SimplePen);
   MainPainter.drawLine(w*args[j]/n,h-(h*SimpleTimes[j]/max),w*args[j 1]/n,h-(h*SimpleTimes[j 1]/max));
   MainPainter.setPen(SlicePen);
   MainPainter.drawLine(w*args[j]/n,h-(h*SliceTimes[j]/max),w*args[j 1]/n,h-(h*SliceTimes[j 1]/max));
   MainPainter.setPen(ValarrayPen);
   MainPainter.drawLine(w*args[j]/n,h-(h*ValarrayTimes[j]/max),w*args[j 1]/n,h-(h*ValarrayTimes[j 1]/max));
  }
 MainLable->setPixmap(MainPixMap);
 MainLable->show();
 return app.exec();

}
Выполнялась она долго. Если есть желание - компильте на здоровье: текстовку выше выкиньте в файл main.cpp, создайте файл tryValarray.pro следующего содержания:
TARGET = app
SOURCES +=   main.cpp \

Выполнить
qmake
make
./app 

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

2 и 3 методы практически идентичны по времени исполнения и активно выигрывают у старого дедовского. Однако, третьим методом пользоваться удобней и быстрей с точки зрения скорости написания кода. Очень советую valarray и slice при обработке массивов больших размерностей в олимпиадах - важность критерия быстродействия программы и скорости написания кода там очевидна.


Читать дальше......

пятница, 19 октября 2012 г.

Маленькие Заметки о проблемах и их решениях


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

Читать дальше......