Страницы

Поиск по вопросам

пятница, 30 ноября 2018 г.

Фоновый ввод информации C++

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


Ответ

Хорошо. Это решение выводит числа, пока не будет нажата какая-либо клавиша клавиатуры. В данной задаче очень полезен метод kbhit()
#include #include
using namespace std;
int main() { bool run = true; while (run) { for (int i = 1; i<1000000; i++) { if (kbhit()) { run = false; break; } cout << i << "
"; } } system("pause"); return 0; }
Если Вам необходимо, чтобы юзер ввёл именно слово "стоп", то моё решение, к сожалению, Вам категорически не подходит...

JavaFx: TreeView

Как можно сделать такие полосы (штриховку) в TreeView? Перегуглил как мог, нигде и намёка нет на подобную штуку
javafx: swing:


Ответ

Очень просто:
TreeItem item=new TreeItem(new HBox(new ImageView(new Image(inputStream)),new Label("Root"))); item.getChildren().add(new TreeItem(new HBox(new ImageView(new Image(inputStream)),new Label("Item1")))); TreeView treeView=new TreeView(item);
При желании можно сделать вместо HBox класс, который будет автоматически менять изображение в зависимости от строения TreeItem.

Регулярные выражения: из массива строк исключить подстроку

Возникла необходимость в большом куске кода внести массовую замену. Использую штатный инструмент Visual Studio 2017 и регулярные выражения для поиска. Подразумеваю, что синтаксис выражений в строке поиска соответствует синтаксису регулярных выражений в C#. Есть следующая строка
get_Label().get_UserLocalizedLabel().get_Label();
В поиске задаю выражение get_(\w*)\(\)
Получаю результат поиска:
get_Label()get_UserLocalizedLabel()get_Label()
А нужен вот такой результат:
get_Label()get_UserLocalizedLabel()get_Label()
То есть необходимо исключить слово между get_ и (). Пробовал get_(?!\w*)\(\), но не преуспел.


Ответ

Если нужно заменить get_ и () на что-то, то подойдёт такой вариант:
Find what:
get_(\w*)\(\)
Replace with:
Get$1
Для
get_Label().get_UserLocalizedLabel().get_Label()
результат:
GetLabel.GetUserLocalizedLabel.GetLabel

App.config и приложение на C#

У меня есть небольшая программа на 2 версии .NET, но новых версиях Windows она не запускается, но если создать файл настроек, то она запустится.

Есть какие-нибудь варианты, что можно сделать, чтоб было не 2 файла, а 1? Т.е внедрить этот файл настроек в exe или ещё как-нибудь.


Ответ

Встроить файл конфигурации в EXE-файл нельзя (так как весь смысл конфигурации - это возможность редактирования параметров без перекомпиляции программы, такой возможности не предусмотрели). Влиять на параметр supportedRuntime из кода на C# также нельзя, так этот параметр используется неуправляемым кодом загрузчика до того, как в процесс загружена CLR, и в этот момент управляемый код еще не может выполняться.
Если нужно управлять выбором версии CLR без файла конфигурации, единственный способ - написать свой собственный загрузчик на С++, пользуясь Unmanaged .NET API
Например, создадим такую программу на C#:
using System;
namespace ConsoleApplication1 { class Program { static int Run(string arg) { Console.WriteLine("Hello from .NET " + Environment.Version.ToString()); Console.ReadKey(); return 0; }
static void Main(string[] args) { Run(""); } } }
Скомпилируем ее, получаем файл Program.exe. Создадим проект С++, добавим в него файл Program.exe и создадим файл ресурсов resource.rc следующего содержания:
#define IDR_RCDATA1 101
IDR_RCDATA1 RCDATA "Program.exe"
Напишем на С++ код загрузчика, который находит первую установленную версию CLR, загружает ее, извлекает из ресурсов программу на C# во временную папку и запускает ее:
#include #include #include #include
#pragma comment(lib, "mscoree.lib")
#define IDR_RCDATA1 101
int wmain(int argc, wchar_t* argv[]) { LPCWSTR prog_name = L"Program.exe"; //имя программы на C#
//построим путь к временному файлу WCHAR temppath[300] = L"c:\\temp\\"; GetTempPath(300,temppath); wcscat(temppath,prog_name);
//извлечем программу из ресурсов HRSRC myResource = ::FindResource(NULL, MAKEINTRESOURCE(IDR_RCDATA1), RT_RCDATA); UINT Size = ::SizeofResource(NULL, myResource); HGLOBAL myResourceData = ::LoadResource(NULL, myResource); void* pMyBinaryData = ::LockResource(myResourceData); FILE* f = _wfopen(temppath,L"wb"); fwrite(pMyBinaryData,Size,1,f); fclose(f);
//инициализация CLR... HRESULT hr; ICLRMetaHost *pMetaHost = NULL; ICLRRuntimeInfo *pRuntimeInfo = NULL; ICLRRuntimeHost *pClrRuntimeHost = NULL; IEnumUnknown* pEnum= NULL; ICLRRuntimeInfo* pInfo= NULL; IUnknown* pUnk = NULL;
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost)); if(FAILED(hr)){printf("CLRCreateInstance failed
");goto End;}
//поиск установленных версий CLR... pMetaHost->EnumerateInstalledRuntimes(&pEnum); if(FAILED(hr)){printf("EnumerateInstalledRuntimes failed
");goto End;}
ULONG c= 0; WCHAR buffer[250]; DWORD cch = 250;
while(1){ if(pInfo!=NULL){pInfo->Release();pInfo = NULL;} if(pUnk!=NULL){pUnk->Release();pUnk = NULL;} if(pRuntimeInfo!=NULL){pRuntimeInfo->Release();pRuntimeInfo = NULL;}
hr = pEnum->Next(1,&pUnk,&c); if(hr != S_OK)break;
pUnk->QueryInterface(IID_ICLRRuntimeInfo, (void**)&pInfo); if(FAILED(hr)){printf("QueryInterface failed
");continue;}
pInfo->GetVersionString(buffer,&cch); if(FAILED(hr)){printf("GetVersionString failed
");continue;}
hr = pMetaHost->GetRuntime(buffer, IID_PPV_ARGS(&pRuntimeInfo)); if(hr == S_OK){break;} else {wprintf(L".NET %s: GetRuntime HRESULT 0x%x
",buffer,(UINT)hr);} }
if(pRuntimeInfo == NULL){printf("Failed to initialize CLR
");goto End;}
/* Можно также указать версию явно, например: pMetaHost->GetRuntime(L"v2.0.50727", IID_PPV_ARGS(&pRuntimeInfo)); pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo)); и т.п. */
hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_PPV_ARGS(&pClrRuntimeHost)); if(FAILED(hr)){printf("GetInterface failed
");goto End;}
//запуск CLR hr = pClrRuntimeHost->Start(); if(FAILED(hr)){printf("Start failed
");goto End;}
//Запуск программы на C# DWORD pReturnValue; hr = pClrRuntimeHost->ExecuteInDefaultAppDomain( temppath, L"ConsoleApplication1.Program", //класс L"Run", //метод L"", //параметр &pReturnValue); if(FAILED(hr)){printf("ExecuteInDefaultAppDomain failed 0x%x
",(UINT)hr);goto End;}
End:
//Освобождение ресурсов if(pMetaHost != NULL) pMetaHost->Release(); if(pRuntimeInfo != NULL) pRuntimeInfo->Release(); if(pClrRuntimeHost != NULL) pClrRuntimeHost->Release(); if(pEnum != NULL) pEnum->Release(); if(pInfo != NULL) pInfo->Release(); if(pUnk != NULL) pUnk->Release(); return 0; }
В результате программа, собранная под .NET 2.0, при его отсутствии будет запускаться на имеющейся версии .NET, как и при использовании параметра supportedRuntime
Источники:
Embedding supportedRuntime into exe file - ответ Ondrej Svejdar
How to load a custom binary resource in a VC++ static library as part of a dll? - ответ LihO

Как перегрузить оператор для класса с произвольным типом

как я могу перегрузить оператор "+", чтобы можно было получить сумму двух узлов двоичного дерева поиска, учитывая то, что тип я у них сделал произвольным, но если будет тип Int у узлов, то тогда можно сложить, а если другой тип, то нельзя.
Вот код:
class Node { internal T value;
public static Node operator +(Node A, Node B) { return new Node(A.value + B.value); }
public int Balance { get { if (Left == null && Right == null) return 0; else if (Left == null && Right != null) return 0 - Right.Height; else if (Left != null && Right == null) return Left.Height; return (Left.Height - Right.Height); } private set { } } public int Height { get { if (Left == null && Right != null) return 1 + Right.Height; else if (Left != null && Right == null) return 1 + Left.Height; else if (Left != null && Right != null) { if (Left.Height >= Right.Height) return Left.Height + 1; else return Right.Height + 1; } else return 0; }
private set { }
}
Я хочу
сделать так, чтобы эти оператором можно было воспользоваться только если тип значения узла Int не использовать для этого отдельный новый класс IntNode : Node , а сделать это прямо в Node
Мне выводит такую ошибку:
Тип одного из параметров бинарного оператора должен быть вмещающим.


Ответ

сделать так, чтобы эти оператором можно было воспользоваться только если тип значения узла Int
Невозможно. Это невозможно даже в C++ с его текстовыми шаблонами формата "найти-заменить" (оператор будет доступен, но при компиляции вывалится 10КБ текста ошибок в потрохах инклюдов).
Если класс имеет разные члены в зависимости от параметров, то это не один класс. Вряд ли от этого принципа отступятся.
не использовать для этого отдельный новый класс IntNode : Node, а сделать это прямо в Node
Много вариантов:
Построить Expression с оператором, скомпилировать. Сгенерировать IL в рантайме. Воспользоваться отражениями. Воспользоваться dynamic, который воспользуется отражениями.
Чистого варианта нет. Возможно, когда-нибудь будет, но я бы не сильно надеялся, что это случится скоро: у задачи Exploration: Shapes and Extensions нет ни статуса, ни майлстона (даже "X.0").

Ошибка при переводе выражения в обратную польскую запись

Имеется код:
#include #include using namespace std; struct stack { char info; stack* next; }; void addToStack(char sym, stack *&begin); void showStack(stack *begin); int priority(char op); void showElementsInBrackets(string &output, stack *&begin); void executeFromStackElements(string &output, stack *&begin); int main() { stack *begin = NULL; string input, output = ""; cin >> input; for (int i = 0; i < input.length(); i++) { if (input[i] >= 'a' && input[i] <= 'z') { output += input[i]; } else if (input[i] == '+' || input[i] == '-' || input[i] == '*' || input[i] == '/' || input[i] == '%' || input[i] =='(') { if (begin == NULL || input[i] == '(') { addToStack(input[i], begin); } else { if (priority(begin->info) <= priority(input[i])) { addToStack(input[i], begin); } else { executeFromStackElements(output, begin); addToStack(input[i], begin); } } } else if (input[i] == ')') { showElementsInBrackets(output, begin); } } executeFromStackElements(output, begin); cout << "Output:" << endl; cout << output << endl; system("pause"); return 0; }
void addToStack(char sym, stack *& begin) { stack *t = new stack; t->info = sym; t->next = begin; begin = t; }
void showStack(stack * begin) { stack *t = begin; while (t != NULL) { cout << t->info << endl; t = t->next; } }
int priority(char op) { if (op == '(') { return 1; } else if (op == '+' || op == '-') { return 2; } else if (op == '*' || op == '/' || op == '%') { return 3; } }

void showElementsInBrackets(string & output, stack *& begin) { while (begin->info != '(' && begin != NULL) { output += begin->info; begin = begin->next; } begin = begin->next; }
void executeFromStackElements(string & output, stack *& begin) { while (begin != NULL) { output += begin->info; begin = begin->next; } }
Задача - перевод выражения в ОПЗ. Однако при определенном вводе, возникают проблемы со скобками. Например, при вводе a+bcd+(e-f)(gh+i), возникает ошибка
Вызвано исключение по адресу 0x010F3CD3 в OPZ.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0x00000000. И указывает на строку
while (begin->info != '(') {
Смотрю по отладке, там выходная строка это abcd**+ef-gh*(*+i+ Как я понимаю, ошибка из-за того, что открывающая скобка извлекается из стека, но не понимаю, почему это происходит


Ответ

первая ошибка:
stack *begin = NULL;
поскольку после прочтения буквы в следующем цикле begin остается нулевым, а компилятор не сможет осуществить проверку:
else { if (priority(begin->info) <= priority(input[i])) //...
поэтому:
stack *begin = new stack;
и не связанные с вашим вопросом ошибки:`
вторая ошибка:
вы нигде не удаляете обьекты, созданные в свободной области памяти через new, т.е. обьекты стека.
третья ошибка:
вы не возвращаете из функции int priority(char op) ничего, если op не является ни один из вами перечисленных символов (лучше возвращать ноль и это использовать в ваших условиях, т.е. если priority(char op)== 0, значит` op не является символом математической операции
и напоследок: еслибы вы хранили один string("*/()%+-"}, то использовав string::find могли бы сделать этот же код компактней и с меньшим количеством if/else ов

Преобразование случайной величины с равномерным распределением в величину с нормальным распределением

У меня есть некое кол-во случайных величин float в диапазоне [0;1] и эти величины имеют равномерное распределение.
Если такая величина X имеет нормальное распределение, то, величина K = m + a * tan(PI*(X-0.5)) имеет распределение коши.
Возможно ли по аналогии преобразовать такую величину X, в величину имеющую нормальное распределение?


Ответ

Написал грубо и точно ;) функцию InverseErf. Она очень сложна для вычислений.
// g++ inverf.cpp -o inverf # include # include // -1 => -Inf ; 0 => 0 ; +1 => Inf // -0.85 .. +0.85 => кубически // 0.85 .. 0.99 => сложно double InverseErf(double x){ bool flagneg = (x < 0.0); x=fabs(x); double result; if(x<0.85) result =(0.886+(-0.315+0.773*x)*x)*x; else { x=log(1.0-x); double const HalfPi = 1.57 ; result = sqrt(-x-log(-HalfPi*(log(HalfPi)+2.0*x))/2.0);} return flagneg ? -result : result ; }
double SimpleToNormal(double x , double med , double sigma){ return med + sqrt(2.0)*sigma*InverseErf(2.0*x-1.0);}
int main() { std::cout<<"inverf(0.999)="<Метод Мюллера спровоцировал на ещё один красивый вариант формулы InverseErf
double InverseErf2(double x){ double result = sqrt(-log(1.0-x*x))*0.9; return (x < 0.0) ? -result : result ; }

Содержит ли normal elements - custom elements?

Входит ли custom elements в группу normal elements?
Из одной главы я понял что существуют несколько типов групп элементов, самая большая это normal elements. Но я так и не понял входит ли туда custom elements
В пункте сказано:
Normal elements: All other allowed HTML elements are normal elements
В этой ссылке говорится что любые определения в пространстве содержатся в http://www.w3.org/1999/xhtml
А также цитата:
The term "HTML elements" refers to any element in that namespace, even in XML documents.
Но вот определения custom elements нет в http://www.w3.org/1999/xhtml , значит ли это что custom elements не входит в группу normal elements?


Ответ

Все исходит из того, что XHTML является подмножеством языка XML. В языке XML вы можете создавать и использовать абсолютно любые теги, которые только ваша душа пожелает. Это Custom Elements:
<Планеты> <Планета ID="1"> <Название>Меркурий <Планета ID="2"> <Название>Сатурн
А в XHTML прописаны только известные браузерам теги для которые он может генерировать внешний вид, эти элементы называются Normal Elements:
Заголовок Содержимое документа
То есть по факту Custom Elements это огромная группа элементов в которую так же (теоретически) входят и Normal Elements. Но шанс встретить Custom Elements в разметке мизерный.
Правда стандарт HTML накладывает ограничения на имена Custom Elements: RuSO: Нестандартные HTML теги

GNU Readline, статическое подключение к Qt

Имеется Qt Creator с собранным Qt с флагом -static. Библиотеки qt успешно вшиваются в программу, а вот readline (GNU Readline) никак не желает. Каким образом надо настроить .pro - файл, чтобы readline вшилась в программу?
ОС: Ubuntu 14.xx. Файл libreadline.a в системе есть.
P.S.: проект с открытым исходным кодом будет, так что про GNU в курсе.


Ответ

Сразу предупреждаю, на ответ не тянет, но в комментарий не поместится.
Собрал тест с readline (но без QT -)).
В самом деле
gcc -o t-r t-readline.c -static -lreadline
выдает предупреждения для некоторых функций libc (связанных с аутентификацией) и ошибки на отсутствие функций tgetent, tputs, tgetflag и т.п., вызываемых из функций библиотеки readline
Понятно, что я не задал линкеру какую-то библиотеку (или несколько).
Узнать, какие библиотеки нужны помогает утилита ldd (print shared object dependencies).
Итак, собираем shared версию
gcc -o t-r t-readline.c -lreadline
и запускаем ldd
avp@avp-ubu1:hashcode$ ldd -v ./t-r linux-vdso.so.1 => (0x00007ffeb73e5000) libreadline.so.6 => /lib/x86_64-linux-gnu/libreadline.so.6 (0x00007fb39dd17000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb39d94d000) libtinfo.so.5 => /lib/x86_64-linux-gnu/libtinfo.so.5 (0x00007fb39d724000) /lib64/ld-linux-x86-64.so.2 (0x00007fb39df5d000)
Version information: ./t-r: libc.so.6 (GLIBC_2.7) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.4) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/libreadline.so.6: libtinfo.so.5 (NCURSES_TINFO_5.0.19991023) => /lib/x86_64-linux-gnu/libtinfo.so.5 libc.so.6 (GLIBC_2.11) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.14) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.15) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.4) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.3.4) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.3) => /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/libc.so.6: ld-linux-x86-64.so.2 (GLIBC_2.3) => /lib64/ld-linux-x86-64.so.2 ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2 /lib/x86_64-linux-gnu/libtinfo.so.5: libc.so.6 (GLIBC_2.3) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.14) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.16) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.4) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.3.4) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6
Из полученного вывода делаем предположение, что скорее всего нам нужна libtinfo
Пробуем
avp@avp-ubu1:hashcode$ gcc -o t-r t-readline.c -static -lreadline -ltinfo /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libreadline.a(complete.o): In function `rl_username_completion_function': (.text+0x3f69): warning: Using 'getpwent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libreadline.a(tilde.o): In function `tilde_expand_word': (.text+0x1c4): warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libreadline.a(shell.o): In function `sh_get_home_dir': (.text+0xf9): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libreadline.a(complete.o): In function `rl_username_completion_function': (.text+0x3f5f): warning: Using 'setpwent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libreadline.a(complete.o): In function `rl_username_completion_function': (.text+0x4009): warning: Using 'endpwent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking avp@avp-ubu1:hashcode$
смотрим результат
avp@avp-ubu1:hashcode$ file t-r t-r: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=e0ee17d4201c7070bf650e9ac2bac441f6628a51, not stripped avp@avp-ubu1:hashcode$
потом слегка "тестируем"
avp@avp-ubu1:hashcode$ ./t-r > djjdjj line: djjdjj > kdkk dkkdkk dk line: kdkk dkkdkk dk > kdkk dkkm 49949 dkk dk line: kdkk dkkm 49949 dkk dk > End avp@avp-ubu1:hashcode$
и видим, что затея удалась.
P.S. Warnings, наверное, тоже можно побороть.

Kак активировать Aякс при нажатие Enter в поле input

Надо отправлять Aяксом инфу из поля на сервер (при этом, при нажатии на Enter, должна отправляться эта инфа) без использования


Ответ

Примерно так
var element = document.querySelector("input"); element.addEventListener('keydown', function(e){ var key = e.keyCode ? e.keyCode : e.which; if (key == 13) { var request = new XMLHttpRequest(); var formData = new FormData(); formData.append("input", this.value) request.open("POST", "url"); request.send(formData); } });

Выполнять действие пока нажата кнопка

Нужна кнопка нажав, на которую можно выполнить действие и если кнопка зажата дальше чем, скажем, 200 мс., то выполнять действие до тех пор, пока кнопка не будет отпущена. Но оказывается не все так просто. Я не могу просто написать в вызове что-то вроде:
if(pressed){ Thread.sleep(100); doIt(); }
Это остановит поток пользовательского интерфейса. Значит это надо перенести в другой поток.
То есть, по нажатию кнопку должен создаваться новый поток, который будет следить за тем нажата ли кнопка, сколько прошло времени,выполнять нужное действие.
К тому же, обязательно придется проследить чтобы поток был завершен вместе с закрытием приложения и т.д.
Может есть другие разумные способы решить данную задачу? Идеально если бы был какой-то функционал отложенной задачи, по типу __Platform.runLater__ , но только выполнить задачу через 100 мс, но я ничего подобного не нашел.


Ответ

Написал вот такую вот конструкцию.
private Thread pressingThread;
@FXML void onPress() { System.out.println("do something"); final int initDelay = 200; final int repeatDelay = 50; pressingThread = new Thread(() -> { try { Thread.sleep(initDelay); while (true) { Platform.runLater(() -> System.out.println("do something again")); Thread.sleep(repeatDelay); } } catch (InterruptedException ignored) { } }); pressingThread.setDaemon(true); pressingThread.start(); }
@FXML void onRelease() { pressingThread.interrupt(); }
Создается поток, который ждет необходимое время, потом в бесконечном цикле передает управление в поток пользовательского интерфейса нужное действие. Чтобы завершить работу необходимо вызывать метод interrupt().
Пробовал реализовать через переменную pressed, которая хранила бы состояние кнопки, и потом проверять не зажата ли кнопка, но тут есть тонкость, что если быстро нажать дважды на кнопку, то можно создать два потока, которые будут думать что кнопка не была отпущена. Потому все равно придется использовать interrupt()
Ред. Переписал в более удобный вид
import javafx.application.Platform;
public class DoWhilePressed { private int initDelay = 200; private int repeatDelay = 50; private Runnable doWhilePressed = ()->{};
private Thread pressingThread;
private pressed = false; public void press(){ if(pressed)return; pressed = true; doWhilePressed.run(); pressingThread = new Thread(() -> { try { Thread.sleep(initDelay); while (true) { Platform.runLater(() -> doWhilePressed.run()); Thread.sleep(repeatDelay); } } catch (InterruptedException ignored) { } }); pressingThread.setDaemon(true); pressingThread.start(); }
public void release(){ pressed = false; pressingThread.interrupt(); }
public int getInitDelay() { return initDelay; }
public DoWhilePressed setInitDelay(int initDelay) { this.initDelay = initDelay; return this; }
public int getRepeatDelay() { return repeatDelay; }
public DoWhilePressed setRepeatDelay(int repeatDelay) { this.repeatDelay = repeatDelay; return this; }
public Runnable getDoWhilePressed() { return doWhilePressed; }
public DoWhilePressed setDoWhilePressed(Runnable doWhilePressed) { this.doWhilePressed = doWhilePressed; return this; } }
Использовать можно как
private DoWhilePressed doWhilePressed = new DoWhilePressed() .setInitDelay(300) .setRepeatDelay(30) .setDoWhilePressed(() -> System.out.println("pressed"));
@FXML void onPress() { doWhilePressed.press(); }
@FXML void onRelease() { doWhilePressed.release(); }

Qt под android 7+

Всем доброго времени суток. Занимаюсь разработкой qt под android и начал сталкиваться с проблемой отсутствия интернета на андроид 7 и выше в приложении, при том что интернет в телефоне есть. Вот вопрос, который уже поднимал здесь, но его решение рассчитано на android studio, а не на qt: internet android 7+ Как можно запросить права на интернет в рантайме(qt 5.10.1)? пытаюсь это сделать такой конструкцией, но результата нет:
#include "my_app.h" #include #ifdef ANDROID #include #endif #include
bool checkPermission(const QString& perm) { #ifdef ANDROID QtAndroid::PermissionResult r = QtAndroid::checkPermission(perm); if(r == QtAndroid::PermissionResult::Denied) { QtAndroid::requestPermissionsSync( QStringList() << perm ); r = QtAndroid::checkPermission(perm); if(r == QtAndroid::PermissionResult::Denied) { QMessageBox::information(0, "Ошибка", "получить разрешение не удалось"); return false; } } #endif return true; }
int main(int argc, char *argv[]) {
checkPermission("android.permission.ACCESS_WIFI_STATE"); checkPermission("android.permission.ACCESS_NETWORK_STATE"); checkPermission("android.permission.INTERNET");
QApplication a(argc, argv); MyApp w; w.show();
return a.exec(); }


Ответ

Всё оказалось банально. В android 7+ нет поддержки ssl "из коробки" (google убрал). Обычный http заработал без проблем

Где реализован IEnumerator?

У меня появился вопрос, который не дает мне покоя вот уже несколько часов. Для того, чтобы использовать foreach для кастомной коллекции, нужно реализовать метод интерфейса IEnumerable.
IEnumerator IEnumerable.GetEnumerator(){ return arr.GetEnumerator(); }
С этим все ясно. Но какой класс реализует интерфейс IEnumerator? По началу я думал System.Array, но после того, как я не увидел IEnumerator в списке родителей System.Array решил обратиться сюда.


Ответ

IEnumerator реализован типом, объект которого возвращает arr.GetEnumerator()
IEnumerator IEnumerable.GetEnumerator() { IEnumerator result = arr.GetEnumerator(); Console.WriteLine(result.GetType().FullName); return result; }
Тип возвращаемого объекта - System.Array.SZArrayEnumerator. Вот этот SZArrayEnumerator и реализует IEnumerator

Политика конфиденциальности (Privacy policy) для android приложения

Пришло письмо от Google
Hi developers at Starikov Mark, After review, (название приложения), (пакет приложения), has been removed from Google Play due to a policy violation. This app won’t be available to users until you submit a compliant update. Issue: Violation of Usage of Android Advertising ID policy and section 4.8 of the Developer Distribution Agreement Google Play requires developers to provide a valid privacy policy when the app requests or handles sensitive user or device information. We’ve identified that your app collects and transmits the Android advertising identifier, which is subject to a privacy policy requirement. If your app collects the Android advertising ID, you must provide a valid privacy policy in both the designated field in the Play Console, and from within the app. Next steps: Submit your app for another review Read through the Usage of Android Advertising ID and User Data policies, as well as the Developer Distribution Agreement, and make appropriate changes to your app. If you decide to collect sensitive user information, be sure to abide by the above policies, and include a link to a valid privacy policy on your app's store listing page and within your app. Make sure that your app is compliant with all other Developer Program Policies. Additional enforcement could occur if there are further policy violations. Sign in to your Play Console and submit the update to your app. Alternatively, you may opt-out of this requirement by removing any requests for sensitive permissions or user data. If approved, your app will again be available with all installs, ratings, and reviews intact. If you’ve reviewed the policy and feel this removal may have been in error, please reach out to our policy support team. One of my colleagues will get back to you within 2 business days. Thanks for helping us provide a clear and transparent experience for Google Play users. Regards, Jaime The Google Play Team
Они проверили мое приложение, опубликованное в Google Play, и обнаружили то, что я использую ID рекламных баннеров, но не предоставляю Privacy Policy

Проблема заключается в следующем:
Я никогда не писал политику конфиденциальности и без понятия, что в ней писать, как оформлять и прочее. Необходимо выложить URL. У меня нет своего сайта или блога. Можно ли использовать README файл на GitHub или можно сделать это как-то проще? А также необходимо добавить в приложение. Куда именно ее нужно добавить? При первом запуске приложения? Где-нибудь в настройках или в разделе "О приложении"?
Очень буду благодарен за вашу помощь!


Ответ

Если никогда не писали политику конфиденциальности, то можете воспользоваться таким бесплатным инструментом, как Privacy Policy Generator.
Данный генератор учитывает такие сервисы, как Google Play Services, AdMob, Fabric, Crashlytics, Firebase Analytics и прочие. А также полностью бесплатный с открытым исходным кодом
Вы можете залить политику на GitHub или создать бесплатный Google сайт
Главное, чтобы было возможным указать URL на политику.
После всего, указать URL с политикой в Google Console и добавить (или создать) в раздел "О приложении". Если у Вас есть регистрация в приложении, то нужно, чтобы сначала была возможность ознакомиться с политикой, т.е. указать ссылку под кнопкой регистрация.

Как работать с git через HTTP прокси на Ubuntu?

При попытке извлечения кода git выдает ошибку: repo init -u git://...
Getting repo ... from git://... fatal: Unable to look up ... (port 9418) (Name or service not known)


Ответ

Нужно прописать параметры прокси в настройках git.
Создать скрипт git_proxy_command.sh
(echo "CONNECT $1:$2 HTTP/1.0"; echo; cat ) | nc прокси порт | (read a; read a; cat ) Установить переменную окружения GIT_PROXY_COMMAND
export GIT_PROXY_COMMAND=git_proxy_command.sh

Точка входа в .NET dll

Существует ли стандартный механизм, с помощью которого можно было бы автоматически выполнять определённый код при загрузке сборки в домен? Понятно, что реализовать такое несложно (пометить сборки своим атрибутом, указывающим тип, в статический конструктор которого следует поместить код инициализации, подписаться на AppDomain.CurrentDomain.AssemblyLoaded и дёргать в обработчике указанный тип, если сборка помечена), но всё же хотелось бы использовать стандартный механизм, если есть.


Ответ

Лично мне кажется, что event AssemblyLoaded как раз и является "стандартным механизмом" для таких целей.
А как его применять - т.е все то, что написано у вас в вопросе, включая использование кастомных атрибутов и пометку сборок - это просто некоторый syntactic sugar, который так или иначе диспатчит AssemblyLoaded

Другое дело, что в общем случае задача выполнения нужного кода в момент загрузки некоторой сборки нетривиальна и корректно решается только с помощью module initializers.
Рекомендую к прочтению .Net: Running code when assembly is loaded, если есть еще вопросы, то готов ответить.

Как поместить в буфер обмена (копировать) данные по нажатию кнопки?

В общем, нужна возможность помещать данные в буфер, как будто пользователь сам нажал Copy (Ctrl+V). Для IE есть простое решение: document.execCommand("Copy"); Для FF есть документация здесь (работоспособность не проверял). А как это сделать в Хроме и Сафари? Или может быть есть кроссбраузерное решение?


Ответ

Может быть Вам подойдет первая ссылка из гугла по запросу "jquery copy to clipboard"?

Модульное тестирование: работа с файлами

Как лучше всего тестировать работу с файлами? Например, я пишу тесты для класса работы с конфигами (чтение/запись). У него есть конструктор, в которое передается имя файла и методы get (получить значение параметра из конфиг. файла), set (установить значение параметра для конфиг. файла) и commit(применить изменения). Как сделать тестирование get и set - ясно. Но как (и надо ли) сделать работу с файлами при создании объекта и при сохранении? PS. Также, хотелось бы увидеть наиболее интересные, с Вашей точки зрения, книги по модульному тестированию (желательно, именно с такой теоретической информацией, без привязки к языку; ну или применительно к java/php). Книжку нашел вот такую. Вроде бы довольно интересная. Спасибо.


Ответ

Сам недавно столкнулся с подобной проблемой. Правда в связке .net+sqlite+nunit если интересно будет вот ссылка на статью Test a DataReader

Странная компиляция

Добрый день, есть у меня кусок кода, который я компилирую компилятором из VS 2008: while(static int i = 0 < 5) { i++; } Я ожидал от него исполнения тела цикла 5 раз. А вот что сделал компилятор: while(static int i = 0 < 5) 00401605 cmp dword ptr [i (40701Ch)],0 0040160C je wmain+2Fh (40161Fh) { i++; 0040160E mov ecx,dword ptr [i (40701Ch)] 00401614 add ecx,1 00401617 mov dword ptr [i (40701Ch)],ecx } Я ожидал от переменной i, что она, будучи статической, будет проинициализирована на стадии компиляции значением 0. Она действительно была проинициализирована на стадии компиляции, но значением 1 (!?). Мне абсолютно не понятно, почему условие цикла while, i<5, скомпилировалось как cmp dword ptr [i (40701Ch)],0 Исходя из листинга и пункта 1 очевидно, что программа уходит в бесконечный цикл. Я не понимаю какого-то соответствующего момента в C++, или это баг компилятора?


Ответ

Дело в приоритете операций. Сравнение имеет бОльший приоритет, чем присвоение. Поэтому сначала происходит сравнение констант 0 и 5, которое компилятор производит на этапе компиляции, а далее его результат (т.е. 1) присваивается переменной i.

Сериализация в Windows Phone 7.

Доброго времени суток, Хэшкод. Пытаюсь сделать Serializable class, по привычке пишу: using System.Runtime.Serialization;
namespace someNamespace { [Serializable()] public sealed class SomeClass: ISerializable { private readonly long someField; . . . } Однако под WinPhone7 это не работает, VS радостно заявляет, что не знает, что такое Serializable & ISerializable. Как это исправить? Приложение является портом с Java(Android), насколько помню Javовское "implements Serializable" это как раз C#-ское ":ISerializable". Не может такого быть, чтоб под winPhone не было такой возможности.


Ответ

Дело в том, что для Windows Phone нужно использовать вместо атрибута Serializable атрибут DataContract. Кое-какие подробности: DataContract DataContractSerializer

Как правильно логировать работу приложения?

Иногда хочется знать, что происходит с приложением в релизном варианте в боевом режиме под руками безжалостного пользователя... Возникают ошибки в приложении, а польз ователь ничего не может сказать, что он нажимал, куда мышкой водил, и какой текст набирал - как всегда оно само сломалось. Возникает вопрос, как правильно построить логику программы, чтобы было удобно логировать ее работу, а также удобно внедрять в готовые продукты. Сам экспериментирую на небольших программных продуктах (до 3000 строчек функционального кода на C#, но на мой взгляд пока не нашел идеального варианта). Из того что пробовал: Создание класса, со свойствами (для управления уровнем логирования, предварительных настроек). Класс инициализируется при старте программы, после из основного модуля ему передаются настройки, вызывается из основного модуля функция записи в лог. Сам класс решает писать ему только в свой список, в контрол, который ему передали, в файл. Нужно ли вообще писать это сообщение в зависимости от уровня логирования. ну и прочие фишечки рюшечки. недостаток того, что в каждой функции, которую хочется залогировать, приходится явно вызывать этот класс, требуется точно быть уверенным что он создан (ну это обходится созданием функции записи в лог, с проверкой созданного класса логирования и отловлей эксепшенов от него). Недостаточно глубоко в классы можно залезть. Создание класса приемерно такого же, за тем исключением, что запись вызывается путем отловли пользовательского сообщения на уровне приложения. Проблемы примерно такие же. Приходится каждое действие отдельно описывать в момент выполнения действий, что не удобно и загромождает полезный код программы. НУ и в случае падения программы, в лог данные могут не попасть, т.к. приложение не примет сообщение. Тоже что и выше, только ловля сообщений происходит в отдельном потоке - пробелемы схода - более менее серьезное падение программы приводит к повисанию потока, который соответственно сообщение не примет и не запишет в лог. Вариант с отдельным процессом для меня видится не лучшим вариантом. т.к. это лишние проблемы и не нужные вещи, к которым я крайне плохо отношусь. ИТОГО: Интересуют два момента: как писать в лог, не загромождая полезный код программы и не усложняя его чтение. как зафиксировать наиболее подробный лог, даже в случае падения, повисания программы.


Ответ

По общему вопросу. Log4Net - почти стандарт (не нужно изобретать велосипед) Может помочь AOP (типа PostSharp), в таком случае не нужно "коверкать" исходный код. как писать в лог, не загромождая полезный код программы и не усложняя его чтение. Писать в отдельный лог-файл или другое хранилище, очевидно же. Ну или в том же log4Net используются различные уровни записей. как зафиксировать наиболее подробный лог, даже в случае падения, повисания программы. Наиболее подробный лог получается, как ни странно, при логировании исключения. Во-первых что-бы иметь актуальный стек, ошибка не должна скрываться во "внутренних деталях реализации" и дойти до глобального обработчика ошибок в своем начальном виде или со своими дополнениями. Во-вторых, должна обработаться либо с записью в какое-то хранилище, либо передана по почте разработчикам и прочее.

четверг, 29 ноября 2018 г.

Книги по теме Concurrency и Parallel Programming [закрыт]

Доброго времени суток! Посоветуйте книги по теме соответственно. Во многообразии выдачи поисковиков можно потеряться и хочется услышать совета опытных людей, что почитать новичку и разобраться как можно глубже в теме. Желательно в порядке нарастания сложности для изучения. Начал пока с этой C++ Concurrency in Action P.S. на данный момент есть задача: общая очередь заданий, несколько потоков кладут их туда, а несколько читают и соответственно выполняют. В общем, вроде укладывается в паттерн Poducer-Consumer.


Ответ

В упомянутой книге упор делается на практический аспект многопоточности. Начинать погружение в тему лучше с неё. На ней же можно и закончить. Для большинства реальных задач этого будет достаточно. Если же хочется познать многопоточность на полную глубину и стать мастером, то без изучения теории не обойтись. Для этого есть другая книга - "Параллельное и распределенное программирование с использованием C++". Описание на ozon.ru совершенно не соответствует содержанию. Оно выглядит легкомысленно и ничуть не пугает. Можно подумать, что эта книга для начинающих. В действительности же она представляет собой академический хардкор, читать который очень непросто. А что касается конкретно паттерна Producer-Consumer, то его реализацию лучше всего делать в lock-free манере. В журнале Dr. Dobb's была статья о том, как это сделать. Правда в вашем случае всё равно потребуется кое-какая блокировка. Нужно будет блокировать отдельно Producer'ов и отдельно Consumer'ов, чтобы в очередь одновременно не лезло более одного потока каждого вида.

typedef в лямбда-выражениях

Недавно обнаружил странный "баг" или "недофичу" в реализации лямбда-функций vs2010: template< typename Anc > class A : public Anc{ // typedef SomeJobClassSpec JOB; // void something(){ std::for_each( Some.begin(), Some.end(), []( SOME&x ){ new JOB::TASK( ... ); // ошибка: JOB не определен!!! } ); } }; Решение: template< typename Anc > class A : public Anc{ // typedef SomeJobClassSpec JOB; // void something(){ std::for_each( Some.begin(), Some.end(), []( SOME&x ){ typedef JOB _JOB; // new _JOB::TASK( ... ); // OK!!! } ); } }; Выходит, typedef в лямбдах видит несколько больше?


Ответ

Это, должно быть, баг VS 2010. У gcc-4.7.2 проблем с похожим кодом нету: http://ideone.com/Pi6slP

WinForm компоненты .NET или OpenSource(конструктор схем)

Доброго времени суток. Есть ли какие-нибудь компоненты или примерные open source проекты для создания WinForm приложений .NET C# или уже реализованные проекты OpenSource.
Как мне кажется, в явном виде реализованных проектов(open source) не должно быть много, но хотя бы какие-то наброски или части проектов, возможно, кто-то в сети выкладывал. Данная схема(чертеж) показывает работу подстанции с различным набором использованных частей: - трансформаторы - регуляторы - шины - и т.д
p.s. Мне не обязательно нужен полностью реализованный проект. Достаточно и наброска, в котором был бы конструктор таких схем без излишеств. В нем нужна панель с набором различных элементов, которые как в Visio можно "перетаскивать" на рабочую область, чтобы потом их соединять и создавать общую схему. В последствие, чтобы можно было её сохранять в XML и потом подгружать.


Ответ

Для реализации подобной задачи (схема тех.процесса) использовал в свое время вот этот вот компонент (он же на codeplex). Называется он NShape и в использовании достаточно удобен.

В C++ при наследовании определяется доступность только открытых элементов родителя?

Прочитав несколько статей по этому поводу не могу сказать, что точно все понял. Такая конструкция
class Child : private Parent ...
сделает все публичные элементы родителя приватными у наследника? И так же, если там указать public или protected, то это влияет только на публичные родительские элементы или нет?


Ответ

private (закрытый, внутренний член класса) — обращения к члену допускаются только из методов того класса, в котором этот член определён. Любые наследники класса уже не смогут получить доступ к этому члену. Наследование по типу private делает все члены родительского класса (в том числе public и protected) private-членами класса-наследника (С++) protected (защищённый, внутренний член иерархии классов) — обращения к члену допускаются из методов того класса, в котором этот член определён, а также из любых методов его классов-наследников. Наследование по типу protected делает все public-члены родительского класса protected-членами класса-наследника (С++) public (открытый член класса) — обращения к члену допускаются из любого кода. Наследование по типу public не меняет модификаторов родительского класса (С++)

Таким образом, ответ на ваш вопрос: class Child : private Parent - да, такое наследование сделает все публичные элементы родителя приватными у наследника.

Плагин для размытия любой области страницы в стиле iOS 7

Однажды делая свой сайт мне захотелось сделать overlay'и так же как это сделала Apple в своей iOS 7: вместо какого либо background оставить его прозрачным, только лишь размыть то, что находиться позади этого div'a и иногда слегка наложить полупрозрачный цвет.
Первое место куда я пошел это были форумы, и сколько я не пытался найти что то подобное, я находил лишь не закрытые вопросы, но не ответы на них. Поэтому остался лишь один вариант это сделать этот велосипед самому. В результате очень долгих мучений, времени и усилий я все таки смог получить желаемый результат.
Потом мне пришла великолепная идея выложить это на GitHub. Я его собрал в качестве плагина для jQuery. Страница на GitHub. Страница плагина. Очень рад буду принимать ваши pull reqest'ы, issue, отзывы, звезды и так далее))) Не примите за рекламу, просто мне кажется что плагин действительно нужный в наше время, судя по стольким не закрытым вопросам на форумах, в большинстве своем "stackoverflow", а по другому никто о нем не узнает.


Ответ

Блурить по координатам нужно крайне редко, обычно это делается для конкретного элемента, так что css filters + polyfill самое оно; Вы делаете расширение для jQuery, то добавьте return this в конец, сейчас после вызова вашего метода, невозможно продолжить цеполчку вызовов jquery-методов; Внутри функции $.fn.blurBg вы получаете html, стирает его, а потом, на onrendered, заново вставляете. Это совсем плохо. Во первых, html2canvas работает асинхронно, поэтому элемент, с которым работает ваше расширение может быть за это время уже модифицирован. Во вторых, если в элементе находился тег script, то при использовании метода $.fn.html он опять будет выполнен, что может привести к нежелательным результатам, вот пример Вместо метода position, нужно использовать offset Если вы пишите для jQuery, то лучше использовать его, а не скатываться в native код; Заблуреный вариант, вставляется через background, что опять же может привести к нежелательным последствиям, если у элемента уже есть style="background: ..." Если ресайзить страницу, то совсем печально :]

Запретить выполнение функций

Доброго времени суток! как мне сделать так, чтобы если у элемента есть класс disabled, обработчики, навешанные на него не выполнялись?


Ответ

Просто добавьте ко всем селекторам :not(.disabled), когда навешиваете функцию, например так: $("#gameboard").on("click", "td:not(.disabled)", handler); Или так: $("td:not(.disabled)").on("click", handler);

Как организовано кэширование в клиентах соцсетей?

Всем добрый вечер! В процессе написания приложения возникла необходимость кэширования определенной информации на устройстве, но для меня пока не понятен алгоритм такого кэширования! То есть, например в приложении клиент ВК на андроид в режиме оффлайн я могу просмотреть довольно большое кол-во заранее просмотренной информации, например переписку, собственный профиль, некоторые фото, список друзей и т.д.. Я пытаюсь написать подобный клиент и меня интересует как это лучше организовать, может существуют готовые рекомендации или набор определенных правил, алгоритмов. Буду рад вашей помощи! Заранее всем большое спасибо!


Ответ

По науке делается так: Пишем сервис/фоновый поток который берет из сервера по расписанию необходимые данные и складывает их в SQLite базу. Этот же поток/сервис должен следить за размером кэша, авторизацией и проч. вещами. Наружу он практически не должен высовываться - тихо сидеть в фоне и подгружать данные по мере необходимости Над SQLite базой организуем ContentProvider выдающий наружу интересующие нас поля Сверху ContentProvider'а нахлобучиваем CursorAdapter, который в свою очередь отображает данные на кастомный ListView Если сделать ListView по уму то можно его "научить" операциям pull-to-refresh - то есть при достижении донышка "дергать" фоновый поток и подгружать старые записи.

Выделение памяти С++

Вопрос достаточно простой, но для меня он неясен. Всем известно, что в С++ у нас есть несколько способов выделения памяти. В моем случае у нас есть главный объект приложения. В нем создаются главные части: объект ядра и объект интерфейса. Мой вопрос состоит в следующем. Каким образом лучше выделять память под эти объекты. 1 вариант: GlCore gl_core; Gui gui; 2 вариант: GlCore *gl_core; Gui *gui; В первом случае я вижу плюсы в том, что не нужно думать о delete и в том, что память выделиться на этапе запуска приложения. Но я использую wxwidgets и там элементы интерфейса советуют создавать по второму варианту. Оно ясно, что это чем-то обусловлено, но я к сожалению не могу понять и сделать для себя какой-то вывод. Мне интересны обоснованные плюсы в пользу того или иного варианта выделения памяти.


Ответ

Вы не должны думать о мелких несущественных технических деталях, наподобие «нужно вызывать delete или сэкономим одну строчку». Не экономьте на спичках. Думайте о смысле. Нужны ли вам объекты gl_core и gui всегда, или вы хотите создать их в какой-то определённый, контролируемый вами момент? Требуют ли они, чтобы что-то было инициализировано до их создания? Если да, глобальный объект — не лучшее место. Требуют ли объекты gl_core и gui подчистить за собой, когда они больше не нужны (например, когда приложение завершает работу графической части)? Если да, вам неплохо бы вызвать деструктор (посредством delete) вручную, а не дожидаться автоматической деаллокации в конце жизни приложения.

Оптимизация IDE Android Studio (JetBrains)

Программирую под Андроид на очень слабом ноутбуке (ОС Убунту Линукс) под Android Studio (форк IntelliJ IDEA, если там можно выразиться). 1 ГБ ОЗУ, 2 ядра Intel Centrino. Всё жутко лагает. Как можно оптимизировать работу IDE? Может какие-нибудь настройки или плагины лишние? Кроме анимации окон и каких-то иконок ничего не выключал. Большое спасибо за помощь!


Ответ

Есть такое понятие "девелоперская машина" - обычно довольно навороченная и уступающая геймерским только в плане наворотов с видеокартой и проч. попсовой периферией. На процессоре и оперативной памяти, среди девелоперов, не принято экономить.
Посмотрите например здесь - что народ юзает

Как работает программа показа живых обоев на рабочем столе (winVista/7/8/8.1)?

Существует программа DreamScenes, которая позволяет устанавливать видео обои на рабочий стол (обычное видео в формате dream/wmv/mpg). Также в VLC media player есть функция показа видео в режиме обоев (исходники данной программы доступны, но разобраться в них не получилось: Исходники). Как выглядит код, реализующий такую фичу? Пока я смогла реализовать такое "чудо" таким образом (примерный код, рабочий): #include #include #include
using namespace std;
void main() { WIN32_FIND_DATA File; HANDLE F; for(int i=0; i < 10; i++) { F=FindFirstFile("C:\\leto\\*.jpg", &File); if (F!=INVALID_HANDLE_VALUE) { do { ofstream bat("C:\\logo.bat", ios_base::out); bat << "REG ADD \"HKCU\\Control Panel\\Desktop\" /v Wallpaper /d \"C:\\leto\\" << File.cFileName <<"\" /f" << endl << "rundll32.exe user32.dll,UpdatePerUserSystemParameters" << endl; bat.close(); system("C:\\logo.vbs"); Sleep(200); } while (FindNextFile(F,&File)!=0); FindClose(F); } } system("pause"); } Описание: В папке находятся картинки (кадры анимации). Находим первую картинку, в батнике прописываем код, который меняет обои рабочего стола на мою картинку, запускаем vbs-скрипт, который позволяет выполнять батник в фоновом режиме, затем делаем паузу между выполнением следующей команды в программе С++ (0.2 сек). Таким образом наблюдается анимация на рабочем столе (но на первом проходе она виснет, почти не выполняется, потом работает, в этом и проблема). Как реализовать нормально, без зависа и кучи картинок, как в упомянутых в начале темы программах?


Ответ

Отрисовку можно сделать посредством DirectDraw, вот тут есть пример. Но, решение несовместимо с Aero, придется выключать.

Ssms T-SQL Formatter

Подскажите плагин для форматирования Sql. Использую ssms 2014. Попробовал установить: http://www.architectshack.com/PoorMansTSqlFormatter.ashx Безрезультатно, видимо нужно теперь установить плагин непосредственно в ssms, как это сделать?


Ответ

Ниже список плагинов, пригодных не только для форматирования (юзаю собственноручно):
ApexSQL Refactor - лучший, на мой взгляд форматтер. Позволяет выполнять тонкую настройку стилей форматирования, сохранять её и импортировать/экспортировать. SSMSBOOST - неплохой форматтер (а в целом - вообще крутой и полезный инструмент), однако после обновленния в ноябре была обновлена и политика лицензирования, что повлияло на функциональность бесплатной версии. Однако же на форматирование это не распространяется - это доступно по-прежнему.

Так же рекомендую ознакомиться с неплохой статьёй по теме расширения возможностей SSMS (следует, однако, иметь в виду, что информация могла устареть):
TOP (10) бесплатных плагинов для SSMS

не работает justify (CSS)

Почему не работает text-align:justify;?
Например:

Кухни спальни прихожие детские шкафы шкафы-купе гостиные винные комнаты
рабочие кабинеты библиотеки гардеробные комоды тумбы полки


Ответ

По идее, за выравнивание последней строки отвечает text-align-last, но его поддержка браузерами оставляет желать лучшего. Поэтому пока стоит воспользоваться хаком с inline-block'ом из соседнего ответа (правда, его кроссбраузерность я не проверял).
body { text-align: justify; -moz-text-align-last: justify; text-align-last: justify; } I just want this to justify..

Использование нескольких типов пользователей в ASP.NET Identity

В приложении должно присутствовать несколько типов учётных записей пользователей и у каждой должен быть свой набор полей. Одним из вариантов я вижу создание иерархии наследования:
public class ApplicationUser : IdentityUser { public string Name { get; set; } public string Surname { get; set; } public IImage AvatarImage { get; set; } public bool IsBlocked { get; set; } public School School { get; set; }
public async Task GenerateUserIdentityAsync(UserManager manager) { var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); return userIdentity; } }
public class StudentUser : ApplicationUser { public TeachingType TeachingType { get; set; } public int Grade { get; set; } }
public class TeacherUser : ApplicationUser { public bool IsConfirmed { get; set; } public List Subjects { get; set; } }
Контекст я вижу таким:
public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext() : base("DefaultConnection", throwIfV1Schema: false) { }
public DbSet TeacherUsers { get; set; } public DbSet StudentUsers { get; set; } }
Есть ли способ научить Identity работать с этой иерархией и возвращать сущность пользователя нужного мне типа?


Ответ

Identity в вашем случае использует самый обычный Entity Framework для хранения учетных записей пользователей - а Entity Framework всегда имел такую возможность.
Только контекст вы привели неправильный.
Независимо от способа хранения, DbSet должен быть один на иерархию и в нем должен храниться базовый класс.
А способов хранения - три:
Table per Hierarchy (TPH) - все свалено в одну таблицу. Table per Type (TPT) - на каждый класс по таблице, их первичные ключи объединены отношениями вида 1 - (0..1). Table per Concrete class (TPC) - по таблице на каждый неабстрактный класс. Но DbSet при этом все равно один!
Для создания БД первого типа просто добавьте DbSet с базовым типом в контекст - все потомки будут свалены в ту же таблицу автоматически.
Если вам больше нравится второй тип - добавьте потомкам атрибут Table. Или перегрузите метод OnModelCreating, указав там примерно следующее:
modelBuilder.Entity().ToTable("TeacherUsers"); modelBuilder.Entity().ToTable("StudentUsers");
Ну а если больше всего нравится третий тип - используйте вот такую конструкцию в том же методе:
modelBuilder.Entity().Map(m => { m.MapInheritedProperties(); m.ToTable("TeacherUsers"); });
modelBuilder.Entity().Map(m => { m.MapInheritedProperties(); m.ToTable("StudentUsers"); });

Использование 2 камер android одновременно

Здравствуйте, возможно ли использование фронтальной и задней камера телефона одновременно, и последующий одновременный вывод их в 2 SurfaceViee. Если да то как и начиная с какой версии? Пробовал писать 2 класса (1 класс вывод в Surface фронтальной камеры, 2 класс вывод во 2 Surfsce задней) и вызывать классы ро очереди, результат - Fail connect to camera service, потом прочитал где-то что нельзя в 1 приложении использовать больше 1 объекта камеры, переписал все это с 1 объектом + перед открытием другого типа камеры прописал .relese();, результат - тоже самое.


Ответ

Во многих случаях это не поддерживается самим устройством. Наверняка ваш случай. То есть, камер две, но активной может быть максимум одна. Надёжных хаков вокруг этого найдено не было.
Samsung Galaxy S4 поддерживает это в закрытом API, недоступном широкому кругу разработчиков. Штатный способ работает не на всех устройствах. Этим приложением можно выяснить, поддерживаются ли две камеры штатно, и никакого заумного кода там нет — просто создаются две камеры с номерами 0 и 1 и вешаются каждая на свою превьюшку.
Что касается:
нельзя в 1 приложении использовать больше 1 объекта камеры
Не верьте. Вот что думает документация
Your application should only have one Camera object active at a time for a particular hardware camera
Перевожу:
Ваше приложение должно держать не больше одного объекта Camera активным в любой момент времени на каждую отдельную аппаратную камеру
К сожалению, насколько это возможно реально, зависит не только от количества камер, но и от возможностей чипсета (dual ISP) по приёму сигнала от двух сразу.
В таблице видно, что у Qualcomm это есть у Snapdragon 800 и новее. У Samsung Exynos придётся покопаться
Благодарить за материал надо автора вот этого ответа

Как установить AltLinux 7.0.5 из .iso при помощи GRUB2?

Что надо написать в конфиг grub2, чтобы загрузился дистрибутив AltLinux 7.0.5 ?
Понятно, что нужно указать loop для grub.
menuentry "AltLinux 7.0.5"{ insmod loopback # search --set --fs-uuid b316cbc2-4695-480c-b9b9-a555350d458a set isofile=/iso/altlinux-7.0.5-school-master-x86_64-ru-install-dvd5.iso loopback loop (${root})${isofile} linux (loop)/syslinux/alt0/vmlinuz iso-scan/filename=$isofile initrd (loop)/syslinux/alt0/full.cz }
Непонятно, какие параметры передавать в строке параметров ядра, так как для этого надо знать, как собирался full.cz (=initrd от altlinux) и какие параметры он понимает.
Такая загрузка совершенно точно возможна в Ubuntu, в Debian и в Fedora
вот такой же вопрос, только он там не отвечен: https://www.linux.org.ru/forum/linux-install/5934581 вот этот вопрос в виде обобщенном для любых дистрибутивов: Как загрузиться с iso? (отвечен на примере Ubuntu)
Этот вопрос социально значимый и глобального масштаба, так как флешки - это дополнительные материальные расходы, а возможность устанавливать без них увеличивает степень проникновения Linux в бедных регионах.


Ответ

menuentry "AltLinux 7.0.5, simply install" { set gfxpayload=keep insmod gzio insmod part_msdos insmod ext2 insmod xfs set bootpart=uuid:df46d821-e7f9-4e35-bbd2-728bdce8d89a set isodir=/iso/Alt705simple set isofile=altlinux-7.0.5-simply-x86_64-install-dvd5.iso loopback loop (${root})${isodir}/${isofile} linux (loop)/syslinux/alt0/vmlinuz automatic=method:disk,${bootpart},directory:${isodir}/${isofile} ramdisk_size=183210 changedisk lang=ru_RU splash noeject xdriver=auto quiet=1 showopts initrd (loop)/syslinux/alt0/full.cz }

Важно ли использование --no-ff при слиянии веток?

При слиянии веток в git можно указать флаг --no-ff, который отключит fast-forward. Какие есть +/- --no-ff кроме возможности увидеть красивый график наследования веток? Где вы используете --no-ff?


Ответ

--no-ff удобен для реверта. Если много людей делают код и много коммитят в свои ветки (а в случае гита - это абсолютно нормально), то с включенным fast-forward история превратится в нечитаемое мессиво. И если потом нужно будет какой-то объем работ откатить, то это может быть сложно. Да, я знаю о том, что коммиты можно перегруппировать перед мерджем. Но некоторых нужно ещё научить этому.
В одном с моих проектов этот флаг установлен глобально по желанию менеджмента.

Ubuntu. Запуск скрипта при блокировке экрана по Ctrl+Alt+L

Возможно ли прикрутить скрипт в дополнение к горячим клавишам (Ctrl+Alt+L) на блокировку экрана?
Есть в Ubuntu такой баг https://bugs.launchpad.net/ubuntu/+source/gnome-screensaver/+bug/1286910), если при блокировке экрана стоит раскладка RU, то и на экране блокировки при вводе пароля будет эта же раскладка вместо дефолтной системной EN.
Хочу запускать скрипт для смены раскладки клавиатуры на английский язык при блокировке экрана, чтобы при вводе пароля не отслеживать, на каком языке его набираю. Надоело, т. к. в день вводить пароль приходится десятки раз. Скрипт такой:
#!/bin/sh kbd=`setxkbmap -print | sed -n 's#xkb_symbols[^"]*"\([^"]*\)".*$#\1#p' | awk -F+ '{print $2}'` if [ $kbd != us ]; then xdotool key 'alt+shift' fi
В скрипте выполняется проверка и меняется раскладка на EN.
А может у кого-нибудь есть решение по исправлению данного бага и при блокировке экрана по-умолчанию можно сделать английский язык.
Ubuntu 15.04.


Ответ

Сделал так:
Вариант 1 (проверка по наличию процесса lockscreen)
Создал скрипт
cat ~/scripts/enru.sh
#!/bin/bash CHKSTR=`ps aux| grep -v grep | grep lockscreen` if [[ $CHKSTR == *lockscreen* ]]; then kbd=`setxkbmap -print | sed -n 's#xkb_symbols[^"]*"\([^"]*\)".*$#\1#p' | awk -F+ '{print $2}'` if [[ $kbd == ru ]]; then xdotool key 'alt+shift' fi fi
Добавил в crontab от имени пользователя строку
crontab -u USERNAME -e
* * * * * DISPLAY=:0 bash ~/scripts/enru.sh >/dev/null 2>/dev/null
Скрипт каждую минуту проверяет, запущен ли процесс usr/lib/unity/unity-panel-service --lockscreen-mode и, при его наличии, запускает проверку и изменение раскладки клавиатуры. Уверен, что можно сделать более красиво - предлагайте варианты.
Вариант 2 (запуск при нажатии Ctrl+Alt+L)
Создал скрипт
$ cat ~/scripts/enru2.sh
#!/bin/bash gnome-screensaver-command --lock && gsettings set org.gnome.desktop.input-sources current 0 # current 0 говорит о том, что нужно включить дефолтную раскладку en_EN. current 1, соответственно, ru_RU Проверяем, есть ли у нас дополнительные комбинации клавиш, которые мы уже используем:
$ gsettings get org.gnome.settings-daemon.plugins.media-keys custom-keybindings
['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/']
custom0 говорит о том, что одна комбинация уже добавлена, поэтому надо добавить следующую - custom1
$ gsettings set org.gnome.settings-daemon.plugins.media-keys custom-keybindings "['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/', '/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/']"
Если же вы добавляете свою первую комбинацию клавиш, то выполните команду
$ gsettings set org.gnome.settings-daemon.plugins.media-keys custom-keybindings "['/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom0/']" Отключаем хоткеи для системного lockscreen'а:
$ gsettings set org.gnome.settings-daemon.plugins.media-keys screensaver '' Задаём имя нашему хоткею:
$ gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/ name 'Lockscreen' Указываем, какую команду надо выполнять:
$ gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/ command "/home/$USER/scripts/enru2.sh" Задаём комбинацию клавиш для запуска блокировки экрана:
$ gsettings set org.gnome.settings-daemon.plugins.media-keys.custom-keybinding:/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/custom1/ binding 'l'

Многопроцессорные ПК - что стоит знать?

К примеру есть многопоточное приложение (Task + Async\Await, в редких случаях Thread), частично на управляемом коде, частично - на неуправляемом. На однопроцессорной системе приложение работает стабильно.
Могут ли возникнуть баги при использовании на многопроцессорной системе? Что стоит знать при разработке приложений под многопроцессорные системы? Какие особенности, костыли, известные баги? Чего стоит ожидать?


Ответ

Проблемы могут быть при несинхронизированном доступе к разделяемой между потоками памяти.
Например, если один из потоков меняет значение разделяемой переменной, а другой читает её без синхронизации, и эти потоки попадут на разные процессоры, то у них может оказаться разное мнение по поводу содержания переменной. Если управляющая логика завязана на значение переменной, получится deadlock.
Если вы пользуетесь Task'ами, во многих случаях переход из потока в поток сделает для вас фреймворк автоматически, с нужной расстановкой memory barrier'ов (но всё же проверьте для случая, если вы пользуетесь нестандартным SyncronizationContext'ом). Использование общих переменных для коммуникации между бегущими Task'ами всё так же плохо и не рекомендуется — впрочем, с async/await такого практически никогда и не надо.

Как правильно регулировать уровень громкости?

У меня получилось использовать только через winmm.dll, но в windows 10 звук регулируется только у приложения, а мне нужно регулировать общий уровень громкости.
[DllImport("winmm.dll")] public static extern int waveOutSetVolume(IntPtr hwo, uint dwVolume); ... waveOutSetVolume(IntPtr.Zero, NewVolumeAllChannels);
По описанию этой функции она принимает указатель на устройство вывода, но как его получить ?
так же пробовал через NAudio, но он отказался работать на windows 10. + перепробовал почти все способы на stackoverflow


Ответ

Это легко сделать с помощью AudioEndpoint API. Работает начиная с Windows 7.
[ComImport] [Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] internal class MMDeviceEnumerator { }
internal enum EDataFlow { eRender, eCapture, eAll, EDataFlow_enum_count }
internal enum ERole { eConsole, eMultimedia, eCommunications, ERole_enum_count }
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IMMDeviceEnumerator { int NotImpl1();
[PreserveSig] int GetDefaultAudioEndpoint(EDataFlow dataFlow, ERole role, out IMMDevice ppDevice);
// the rest is not implemented }
[Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IMMDevice { [PreserveSig] int Activate(ref Guid iid, int dwClsCtx, IntPtr pActivationParams, [MarshalAs(UnmanagedType.IUnknown)] out object ppInterface);
// the rest is not implemented }
[Guid("657804FA-D6AD-4496-8A60-352752AF4F89"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IAudioEndpointVolumeCallback { int OnNotify(IntPtr pNotifyData); };
[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] internal interface IAudioEndpointVolume { int RegisterControlChangeNotify(IAudioEndpointVolumeCallback pNotify); int UnregisterControlChangeNotify(IAudioEndpointVolumeCallback pNotify); int GetChannelCount(out int pnChannelCount); int SetMasterVolumeLevel(float fLevelDB, Guid pguidEventContext); int SetMasterVolumeLevelScalar(float fLevel, Guid pguidEventContext); int GetMasterVolumeLevel(out float pfLevelDB); int GetMasterVolumeLevelScalar(out float pfLevel); int SetChannelVolumeLevel(uint nChannel, float fLevelDB, Guid pguidEventContext); int SetChannelVolumeLevelScalar(uint nChannel, float fLevel, Guid pguidEventContext); int GetChannelVolumeLevel(uint nChannel, out float pfLevelDB); int GetChannelVolumeLevelScalar(uint nChannel, out float pfLevel); int SetMute([MarshalAs(UnmanagedType.Bool)] Boolean bMute, Guid pguidEventContext); int GetMute(out bool pbMute); int GetVolumeStepInfo(out uint pnStep, out uint pnStepCount); int VolumeStepUp(Guid pguidEventContext); int VolumeStepDown(Guid pguidEventContext); int QueryHardwareSupport(out uint pdwHardwareSupportMask); int GetVolumeRange(out float pflVolumeMindB, out float pflVolumeMaxdB, out float pflVolumeIncrementdB); }
static void Main(string[] args) { IMMDeviceEnumerator deviceEnumerator = (IMMDeviceEnumerator)(new MMDeviceEnumerator()); IMMDevice speakers = null; IAudioEndpointVolume vol = null; try { deviceEnumerator.GetDefaultAudioEndpoint(EDataFlow.eRender, ERole.eMultimedia, out speakers); Guid IID_IAudioEndpointVolume = typeof(IAudioEndpointVolume).GUID; object o; speakers.Activate(ref IID_IAudioEndpointVolume, 0, IntPtr.Zero, out o); vol = (IAudioEndpointVolume)o; vol.SetMasterVolumeLevelScalar(0.7f, Guid.Empty); } catch (Exception ex) { Console.WriteLine(ex.Message); } if (vol != null) { Marshal.ReleaseComObject(vol); } if (speakers != null) { Marshal.ReleaseComObject(speakers); }
if (deviceEnumerator != null) { Marshal.ReleaseComObject(deviceEnumerator); } }

Как вытащить строку из системных mui файлов?

Мне нужно использовать строку из системных ресурсов которые находятся в c:\windows\system32 и имеют расширение *mui. Например poqexec.exe.mui. Программа Resource hacker выдаёт такую структуру
1 MESSAGETABLE { 0x40000001, "Обновление системы... (%5!Iu!%%)%r%0
" 0xC0000002, "Ошибка %4!lX! при операции обновления %1!Iu! из %2!Iu! (%3)%r%0
" 0xC0000003, "Неустранимая ошибка %4!lX! при операции обновл. %1!Iu! из %2!Iu! (%3)%r%0
" }

Как мне вытащить строку по адресу 0x40000001 и использовать в дальнейшем в моей программе?
Пробую что-то типа этого:
HMODULE resContainer = LoadLibrary(L"C:\\Windows\\System32\
u-RU\\poqexec.exe.mui"); HRSRC myResource= FindResource(resContainer, MAKEINTRESOURCE(0x40000001), RT_MESSAGETABLE); HGLOBAL myResourceData = LoadResource(resContainer, myResource);


Ответ

Для этого есть функция FormatMessage. Ваше приложение должно иметь ту же архитектуру (32бит или 64бит), что и DLL.
HMODULE resContainer = LoadLibrary(L"C:\\Windows\\System32\
u-RU\\poqexec.exe.mui");
LPTSTR pBuffer; // Buffer to hold the textual error description. if (FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | // Function will handle memory allocation. FORMAT_MESSAGE_FROM_HMODULE | // Using a module's message table. FORMAT_MESSAGE_IGNORE_INSERTS, resContainer, // Handle to the DLL. 0x40000001, // Message identifier. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language. (LPTSTR)&pBuffer, // Buffer that will hold the text string. 256, // Allocate at least this many chars for pBuffer. NULL // No insert values. )) { MessageBox(0, pBuffer, 0, 0); LocalFree(pBuffer); }

Организация кода C++. Необходимоть писать имя класса в `.cpp`

Мне кажется немного дикой, неудобной, и осложняющей читабельность кода необходимость указывать имя_класса перед каждой функцией в файле реализации класса.
файл A.hpp
class A { int func(int par); }
файл A.cpp
int A::func(int par){ return par*2/4+1; }
Чтобы упаковать реализацию функций в класс можно писать код в заголовках (получится аля в Java). Там же написано почему это не круто.
class A { int func(int par){ return 2; }; }
Может вам извесны другие варианты записи и организации кода?


Ответ

Это проблема/фича модели компиляции языка C++.
Дело в том, что C++ компилирует только .cpp-файлы, и из них каждый независимо. Это значит, что он при компиляции не знает, к чему относится данный текст, не знает контекста. Когда C++ видит методы файла, компилятор к этому моменту просмотрел сотни (это не преувеличение!) header'ов и видел предварительные описания сотен классов. Он не может просто так прикинуть, к какому из них относится данный метод.
Даже если другой метод организации компиляции можно придумать (например, использовать как-нибудь препроцессор) метод, который вы описали, является привычным и практически единственным общепринятым методом организации исходного кода в C++. Поэтому любая другая организация кода вызовет скорее всего недоумение у ваших коллег.
В других языках, например, C#, нету подобной особенности, потому что все функции определяются внутри класса. Проблем с компиляцией, как в указанном вами вопросе, не возникает, потому что для нахождения других классов не используется #include (который по сути является простой текстовой подстановкой), а двухпроходная и нераздельная компиляция: компилятор при чтении очередного .cs-файла не «забывает» то, что он видел в других файлах.
В других, например, Javascript, проблема даже шире, потому что методы класса объекта могут быть определены где угодно и «появиться» в объекте на любом этапе его жизненного цикла.

Об алгоритме вывода типов рекурсивных функций

В Scala не реализован вывод типов для рекурсивных функций, в качестве аргумента Кей Хорстман в своей книжки пишет что "Алгоритм Хиндли-Милнера не стабильно себя ведёт в языках с ООП". Но, например, в F# и OCaml реализован вывод типов для рекурсивных функций и возникают вопросы: что же тогда имел ввиду Кей Хорстман? Есть ли примеры программ на ООП языке в которых алгоритм даёт сбой(ошибка согласованности типов в рантайме при успешно пройденной проверке типов на этапе компиляции)? Или косяк именно в каких-то особенностях Scala?


Ответ

Система типов Scala однозначно содержит F \sub. Вероятно содержит намного больше (это сейчас активное направление исследований у нас) но уже в F \sub многие вопросы, и в том числе этот - неразрешимая задача.
Ссылка на статью
Если честно, я не знаю как это работает в F# и OCaml. Думаю они делают best-effort.

Проектирование БД для многоязычного проекта

Мой мозг, размягченный NoSQL, совсем отказывается проектировать нормальную реляционную БД.
Задача такова:
Есть сущности: карточки, теги, категории. Возможно, позже появится что-то еще; У каждой сущности есть связи, которые не зависят от языка; У каждой сущности есть текстовые поля, которые надо переводить (количество языков не велико, в начале проекта будет 2, позже добавится еще 2-3).
Нужно спроектировать базу так, что бы минимизировать время работы запросов на получение отдельной карточки и списка карточек с переводом текстовых полей на нужный язык.
Стек технологий проекта: PostgreSQL, SQLAlchemy, Flask
UPDATE
gettext не подойдет, так как требуется перевод для описаний и т.п. с возможностью редактирования в админке.


Ответ

Набор языков фиксированный? Если да, добавляйте локализованные поля к полям, которым нужен перевод, постфиксы *_ru, *_en и т.д.
Если нет - создайте что нибудь типа translation: id, key, value - и используйте ссылки на них, вместо прямых значений полей.

Как используется пространство имён tools в XML?

Подскажите для чего используется пространство имён tools в XML-разметке?
xmlns:tools="http://schemas.android.com/apk/res-auto"
Пример: tools:uiLayout="..."


Ответ

В двух словах - применив к элементу атрибут в этом пространстве имён вместо привычного "android", вы увидите эффект в режиме предпросмотра, но на реальном устройстве или эмуляторе при дебаге ничего не изменится. Удобно использовать для заполнения текстовых болванок, когда хотелось бы посмотреть, как оно будет выглядеть на самом деле, а хардкодить сам текст в XML-разметке не хорошо.
tools:text="Тестовый текст"
Тоже самое можно делать с цветами, да и ещё много с чем. Здесь про это неплохо написано.

Как правильно написать сервер на сокетах?

public static void main(String[] args) throws IOException { playerses = new ArrayList<>(); serverSocket = new ServerSocket(7475); while (true) { Socket socket = serverSocket.accept(); new Thread(new Runnable() { @Override public void run() { try { while (true) { String asd = new BufferedReader(new InputStreamReader(socket.getInputStream())).readLine(); System.out.println(asd); } } catch (IOException e) { e.printStackTrace(); } } }).start(); } }
Нужно сделать так, чтобы сервер после того, как к нему подключится клиент по сокету, начинал его слушать.
while(true) - это не плохой код? На производительность влиять не будет? Память потребляет, питание на ноутбуке ест? Или есть другой способ?


Ответ

Не вижу ничего особенно плохого в вашем коде.
Написание собственного велосипедного сервера — шаг, через который стоит пройти.
Из минусов — выделение потока на каждый клиент. Это потенциально приведёт к невозможности обработки, скажем, 10000 клиентов одновременно. В братском .NET проблема решается при помощи паттерна async/await, в Java, судя по всему, вам придётся поддерживать состояние работы с каждым из клиентов вручную.
Затем, если ваш сервер на деле использует более высокоуровневый протокол (HTTP?) имеет смысл воспользоваться готовым клиентом, правильный разбор высокоуровневых сложных протоколов — та ещё задача. Хотя да, этот клиент будет делать по сути примерно то же самое.

Как сделать прокрутку QListWidget свайпом

Пытаюсь разобраться с Qt под Android. На форме размещен QListWidget, при этом привычная сенсорная прокрутка свайпом не работает.
Собсвтенно как реализовать прокрутку свайпом?
Файл проекта .pro:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = AndroidMainWindow TEMPLATE = app
SOURCES += main.cpp\ mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
CONFIG += mobility MOBILITY =
В .cpp только заполнение QListWidget больше никаких изменений

for( short i = 0; i < 50; i++ ) { QListWidgetItem * item = new QListWidgetItem(); item->setSizeHint( QSize(0, 70) ); item->setText( "Элемент списка номер " + QString::number(i) ); ui->listWidget->addItem( item ); }


Ответ

Вначале обработку сенсора надо включить с помощью функции QWidget::grabGesture
QListWidget * my_list = ... my_list->grabGesture(Qt::SwipeGesture);
Второй вариант, использовать класс QScroller
QScroller::grabGesture(my_list, QScroller::LeftMouseButtonGesture);
Если QScroller не устраивает можно обрабатывать события от сенсора QGestureEvent самостоятельно (пример с doc.qt.io):
bool MyWidget::event(QEvent *event) { if (event->type() == QEvent::Gesture) return gestureEvent(static_cast(event)); return QWidget::event(event); }
bool MyWidget::gestureEvent(QGestureEvent *event) { if (QGesture *swipe = event->gesture(Qt::SwipeGesture)) swipeTriggered(static_cast(swipe)); else if (QGesture *pan = event->gesture(Qt::PanGesture)) panTriggered(static_cast(pan)); if (QGesture *pinch = event->gesture(Qt::PinchGesture)) pinchTriggered(static_cast(pinch));
return true; }
Более подробно обо всей кухне

Как перехватить ответ сервера в XMLHttpRequest?

Можно ли имея возможность изменить (inject) XMLHttpRequest изменить его так, чтобы можно было перехватить содержимое ответа не подменяя целиком весь объект со всеми его методами ? Предполагается, что далее в коде будут вызовы вроде:
x = new XMLHttpRequest(); x.open( "GET", "/" ); x.onreadystatechange = function () {...}; x.send( null );
или даже с учетом однопоточности:
x = new XMLHttpRequest(); x.open( "GET", "/" ); x.send( null ); x.onreadystatechange = function () {...};


Ответ

Решение для Blink
Blink - это Chrome, Opera etc.
В прототипе XMLHttpRequest onreadystatechange объявлен как геттер/сеттер и задавая свой геттер/сеттер нужно не сломать логику работы XMLHttpRequest:
var oldXMLHttpRequest = XMLHttpRequest;
XMLHttpRequest = function() { var xhr = new oldXMLHttpRequest(); // получаем дескриптор прототипных setter/getter var descrGetSet = Object.getOwnPropertyDescriptor( Object.getPrototypeOf( xhr ), "onreadystatechange" );
var newSet = function( val ) { console.log ( "setter" ); descrGetSet.set.call( xhr, function() { // прототипный setter console.log( "Inject "+this.status ); // this.responseText return val.apply( xhr, arguments ); } ); }
Object.defineProperty( xhr, "onreadystatechange", { set: newSet, // новый setter get: descrGetSet.get // старый getter } );
return xhr; }
Теперь сделав:
x = new XMLHttpRequest(); x.open( "GET", "/" ); x.send( null ) x.onreadystatechange = function () { console.log( this.statusText+' is 2' )};
Увидим
Inject 200 OK is 2 Inject 200 OK is 2 Inject 200 OK is 2
Что и должно быть при смене readyState

Решение для Webkit
Webkit - Safari, PhantomJS
Проблема в этом движке- onreadystatechange это геттер/сеттер объекта XHR, а не XHR.prototype. В итоге переопределить его нельзя. Унаследоваться от XHR тоже нельзя, поэтому нужно применять обертку для XHR Весьма хороша эта обертка: https://github.com/ilinsky/xmlhttprequest

Работа с модулями в GIT

Есть внешний репозиторий в котором реализован базовый функционал по работе с бд, в дальнейшем буду называть его DAL — слой доступа к данным).
Создаю новый проект, подключаю DAL в качестве модуля:
git submodule add ../Projects/DataAccessLayer DAL
В текущем проекте мне необходимо его немного допилить напильником, данные изменения уникальны в рамках текущего проекта, в основном репозиторий DAL они мне не нужны.
Как правильно организовать/сделать такую работу?
UPD.:
На текущий момент я построил свою работу так:
Создаю новую ветку: git checkout -b НоваяВетка Делаю необходимые мне изменения: добавляю новые классы, реорганизую, ну и т.п.; Индексирую изменения, комичу: git add ... -> git commit -m 'Здесь какой то текст' Вливаю изменения в главную ветку: git checkout master -> git merge НоваяВетка Повторяю с начала списка по мере рефакторинга, добавления нового функционала;
UPD2
Master v.0.1 | \ | \ | \ | \ | v.0.1 | / | dal | / | / Master
т.е. я подключаю модуль в ветке dal, улучшения модуля dal делаем в ветках которые пойдут от dal
я правильно понял?


Ответ

Вариант 1.
Подумайте, можно ли допиливание осуществить за счет конфигурации? Например, вынести разные константы в отдельный конфиг. В составе субмодуля у вас будет один конфиг с дефолтными значениями, а в конкретном проекте — второй, в котором некоторые из значений могут быть переопределены. Тогда необходимость вносить изменения в субмодуль исчезнет.
Вариант 2.
Сделайте в субмодуле новую ветку, специфическую для этого проекта. Вносите изменения в нее. Если вы внесете какие-то общие изменения в DAL и захотите обновить их в репозитории, то вам нужно будет обновить master, а потом сделать rebase ваших изменений на новый последний коммит.
Было:
master feature Y | C X | / B | A
Станет:
master feature Y' | X' / C | B | A

Как подключить Android телефон к AndroidStudio Ubuntu

Все сделал согласно этой инструкции...
Подключаю через usb свой HTC и появляется такое сообщение
Unable to mount Android Phone,
а потом еще такое окно
Unable to open a folder for Android Phone
а потом такое
Unable to find the requested file. Please check the spelling and try again.
и конечно же Android Studio не видит подключения...
lsusb выводит:
aleksey@aleksey:~$ lsusb Bus 003 Device 005: ID 0bda:0129 Realtek Semiconductor Corp. RTS5129 Card Reader Controller Bus 003 Device 006: ID 0cf3:0036 Atheros Communications, Inc. Bus 003 Device 003: ID 0c45:670b Microdia Bus 003 Device 002: ID 8087:8000 Intel Corp. Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub


Ответ

Откройте эмулятор терминала и наберите:
lsusb
С телефоном и без телефона и найдите разницу. Если разницы нет, либо дело в кабеле, либо в настройках смартфона. В моём случае это строка:
Bus 002 Device 045: ID 0bb4:0c03 HTC (High Tech Computer Corp.)
Первую группу цифр (0bb4) следует вставить вначале в /etc/udev/rules.d/51-android.rules
SUBSYSTEM=="usb", ATTR{idVendor}=="0bb4", MODE="0666"
Затем в ~/.android/adb_usb.ini с префиксом 0x. Некоторые значения adb знает сам, тогда вторая строка может не понадобиться, но мешать не будет:
# ANDROID 3RD PARTY USB VENDOR ID LIST -- DO NOT EDIT. # USE 'android update adb' TO GENERATE. # 1 USB VENDOR ID PER LINE. 0x2207 0x0bb4

Как увеличить пинг?

Делаю игру на сокетах, чтобы сделать отладку интерполяции и экстраполяции нужно увеличить пинг и возможно эмулировать потерю пакетов на открытой вкладке в Chrome. Может быть у кого то была подобная задача, нашёл только через виртуалку WANem http://habrahabr.ru/post/127274/
Но не очень хочется поднимать целую виртуалку для небольшой задачи.


Ответ

В developer tools есть уже все что нужно.
Нажать f12. В верхнем левом углу нажать на иконку телефона. Вверху будет секция network и там в старых версиях будет список возможных задержек, а в новых - кнопка "configure throttling". Там можно как увеличить пинг, так и ограничить скорость соединения.

Что такое ?

Копался в исходниках .NET Framework и обнаружил непонятные мне комментарии. Что это за теги что они дают и как ими пользоваться?
/// /// /// Provides /// methods and properties /// to manage an application, such as methods to run and quit an application, /// to process Windows messages, and properties to get information about an application. This /// class cannot be inherited. ///


Ответ

Как можно догадаться devdoc означает developer documentation, т.е. комменты для девелоперов.
Тут в пункте 2.4.2 чуть более подробно.

Как узнать почему меняется таблица маршрутизации Linux

Подключил к серверу (centos7) Yota через USB как резервный канал связи. В первые секунды всё ок, маршрут определяется правильно. Через несколько секунд маршрут по умолчанию из таблицы маршрутизации пропадает.
При задании маршрута статически в конфиге и/или вручную через ip route ситуация повторяется. Адреса/маршруты на остальных картах прописаны статически.
Как узнать почему меняется таблица маршрутизации?


Ответ

команда
ip monitor
по ней в реальном времени выводятся все изменения с IP-адресами, маршрутизацией и т.п.
В данном конкретном случае я увидел, что маршрут по-умолчанию удаляется каждый раз при попытке создать ppp-соединение (основной способ подключения к интернет) и потом восстанавливается снова.