Страницы

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

четверг, 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-соединение (основной способ подключения к интернет) и потом восстанавливается снова.

OnTouchListener у Layout


Имеется два Layout:
A - RelativeLayout. B - LinearLayout.
Вот пример разметки:




На Layout A я установил слушатель OnTouchListener. Мне нужно, чтобы при нажатии на область Layout B или на его потомков, слушатель не срабатывал, а при касании за границей Layout A срабатывал.
При нажатии на Spinner слушатель Layout A не срабатывает, т.к. на нем (спиннере) есть свой родной слушатель, однако у View его нет. Установить на него слушатель не вариант. Что делать?


Ответ

Добавьте OnTouchListener для Layout B и в нём устанавливайте значение булевой переменной, а в OnTouchListener для Layout A проверяйте значение этой переменной. Например, так:
boolean ChildTouched = false; RelativeLayout ParentLayout = (RelativeLayout)findViewById(R.id.menuParentLayout); ParentLayout.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (ChildTouched) { ChildTouched = false; return true; } System.out.println("Touch parent activity"); return true; } });
LinearLayout ChildLayout = (LinearLayout)findViewById(R.id.menuLayout); ChildLayout.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { System.out.println("Touch child activity"); ChildTouched = true; return true; } });

Как сделать так, что бы активность автоматически запускалась при включении телефона?

Пишу экран блокировки, имеется главная активность (MainActivity), содержащая настройки экрана блокировки и сама активность экрана блокировки (LockScreenActivity), так вот: как сделать так, что бы активность экрана блокировки запускалась автоматически при включении телефона? Т.е. что бы она постоянно была запущена, пока её в настройках (MainActivity) не отключит пользователь?


Ответ

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

Как использовать urlib для адреса с кириллицей

Как правильно использовать urlib.request для получения кода страницы, при условии, что в URL есть кириллица
UPD. Есть функция:
def get_html(url): return urllib.request.urlopen(url).read()
Она отдает html-код страницы по URL (да-да, кэп). Она работает ровно до того момента как в заголовке появляется кириллица и интерпретатор отдает ошибку:
UnicodeEncodeError: 'ascii' codec can't encode characters in position 10-18: ordinal not in range(128)


Ответ

В рамках протокола HTTP не-ASCII символы в URI не допускаются. Например кириллица может быть введена и отображена в адресной строке браузера, но браузер переводит эту строку запроса (в виде IRI) в правильный, с точки зрения протокола HTTP URI. Соответственно для имени хоста применяется Punycode, а для остальных компонентов URL-кодирование
В вашем случае можно воспользоваться дополнительной функцией для перевода из кириллического IRI в ASCII URI
from urllib.parse import quote, urlsplit, urlunsplit
def iri_to_uri(iri): parts = urlsplit(iri) uri = urlunsplit(( parts.scheme, parts.netloc.encode('idna').decode('ascii'), quote(parts.path), quote(parts.query, '='), quote(parts.fragment), )) return uri
И вызывать вашу функцию так:
content = get_html(iri_to_uri(url))

Работа со звуком в приложениях Windows 10

В проекте UWP при использовании MediaElement, когда сворачиваешь окно проигрывание трека останавливается. В сети пишут что нужно использовать BackgroundMediaPlayer, только хотелось бы объяснений как его использовать. Или есть какой-то другой способ решения этой проблемы?


Ответ

Вкратце: да, нужно использовать BackgroundMediaPlayer плюс имплементировать IBackgroundTask. Это входная точка для работы приложения, когда оно свернуто. Позволит управлять произведением музыки в свернутом состоянии. У Microsoft есть официальный пример

Как сравнить значения из соседних строк в отсортированном наборе?

Есть выборка вида:
Id Value 1 5 2 5 3 6 4 3 5 5
Мне нужно сравнить значения Value из строк с Id равными N и N+1 (соседними строками). Т.е. для простоты считаем, что Id - непрерывная последовательность натуральных чисел.
Вопросы:
1) Как это лучше, а главное, оптимальней сделать?
2) Всё то же самое, но мне нужно сравнить значения N подряд идущих строк... Как это оптимальней сделать?


Ответ

Ну тут, собственно, какие варианты могут быть.
Если данные из соседних строк часто требуются, то думаю, оптимальнее всего будет выбрать и сохранить их в отдельный(-е) столбец(-цы), чтобы затем использовать.
Если вычислять на лету - то либо windowed функции, либо join-ы на себя:
select d.id, d.value, prev = lag(d.value) over (order by d.id) from data d
select d.id, d.value, prev = d_lag.value from data d left join data d_lag on d_lag.id = d.id - 1
Если используются оконные функции, то для оптимальной производительности желательно придерживаться т.н. POC (Partitioning, Ordering, Coverage) индексации. Т.е. в данном случае должен быть кластерный индекс по Id, либо некластерный покрывающий index (Id) include (Value). При использовании join-ов эти индексы также пригодятся.
Не совсем понятно, что значит "сравнить значения N подряд идущих строк". Вам нужно N предыдущих строк разложить по столбцам?
select id, value, prev = lag(value) over (order by id), prev2 = lag(value, 2) over (order by id), prev3 = lag(value, 3) over (order by id), prev4 = lag(value, 4) over (order by id) from data
select d.id, d.value, prev = d_lag.value, prev2 = d_lag2.value, prev3 = d_lag3.value, prev4 = d_lag4.value from data d left join data d_lag on d_lag.id = d.id - 1 left join data d_lag2 on d_lag2.id = d.id - 2 left join data d_lag3 on d_lag3.id = d.id - 3 left join data d_lag4 on d_lag4.id = d.id - 4
Или нужно скользящее среднее по N предыдущим строкам?
select d.id, [ma20(-1)] = avg(d.value) over (order by d.id rows between 20 preceding and 1 preceding) [ma20(0)] = avg(d.value) over (order by d.id rows between 19 preceding and current row), from data d
select d.id, [ma20(-1)] = [s-1].ma20, [ma20(0)] = s0.ma20 from data d cross apply ( select ma20 = avg(d2.value) from data d2 where d2.id between d.id - 19 and d.id ) s0 cross apply ( select ma20 = avg(d2.value) from data d2 where d2.id between d.id - 20 and d.id - 1 ) [s-1]
Можете попробовать эти запросы на своих данных. На тестовых данных в 100 тыс. строк время исполнения запросов для двух методов (windowed и join) у меня получалось сравнимо, только последний запрос выигрывал по времени за счёт параллелелизма, но IO всюду в пользу windowed версий (в случае со скользящим средним - значительно). Вообще по IO все эти windowed запросы сравнимы с простым select id, value from data
Поскольку оконные функции экономнее по IO, подход с их использованием может быть предпочтительнее в случаях, когда IO является узким местом (например, в системах с большим количеством одновременно работающих пользователей). В иных случаях между join и windowed следует, вероятно, предпочесть то, что работает быстрее на конкретных данных.

Передача значения из View в Model и последующий вызов метода - как?

Следуя паттерну MVVM имеем View, ViewModel и некие классы для Model, в частности ExcelImporter для импорта и парсинга экселевского файла.
Во вьюхе есть поле ввода адреса файла. Биндится к соответствующему свойству в VM:
public string ExcelPath { get { return excelPath; }
set { excelPath = value; OnPropertyChanged("ExcelPath"); //? } }
Вопрос 1: если значение ExcelPath меняется только из вьюхи пользователем через диалоговое окно выбора файла, то во ViewModel в сеттере ему ведь не нужно делать OnPropertyChanged("ExcelPath")? И, следовательно, нужно в биндинге оставить Mode=Default (он же OneWay)?
Также в VM есть экземпляр класса ExcelImporter, который отвечает за импорт файла, со свойством, опять же, ExcelPath
Вопрос 2: где будет корректным передавать значение из VM.ExcelPath в ExcelImporter.ExcelPath? В сеттере VM.ExcelPath? Или ещё была шальная мысль сделать событие ExcelPathChanged, на которое подписать саму же VM, и в обработчике устанавливать ExcelImporter.ExcelPath = ExcelPath. Или подписать на это событие ExcelImporter, но это по MVVM вроде как совсем неправильно.
public string ExcelPath { get { return excelPath; }
set { excelPath = value; ExcelImporter.ExcelPath = ExcelPath; //? } }
Вопрос 2.1: а можно вообще вот так сделать свойство в VM?
public string ExcelPath { get { return ExcelImporter.ExcelPath; }
set { ExcelImporter.ExcelPath = value; } }
Вопрос 3: если в сеттере, то что именно присваивать: value, excelPath или, как в вопросе 2, ExcelPath?
public string ExcelPath { get { return excelPath; }
set { excelPath = value; ExcelImporter.ExcelPath = value; //? ExcelImporter.ExcelPath = excelPath; //? ExcelImporter.ExcelPath = ExcelPath; //? } }
Вопрос 4: чтобы ExcelImporter сразу же после получения ExcelPath выполнял метод Import() - т.е. чтобы с точки зрения пользователя всё автоматически происходило после выбора файла из обычного OpenFileDialog, без всяких лишних нажатий кнопки типа "Импортировать" - этот метод должен вызываться где? В сеттере VM.ExcelPath, в сеттере ExcelImporter.ExcelPath или через событие в ExcelImporter, какой-нибудь ExcelPathChanged, на которое подписан... сам же ExcelImporter или VM, и уже там в обработчике вызывать ExcelImporter.Import()? Больше ничего в голову не приходит, а такое активное использование сеттера для кучи дополнительных действий вызывает сомнение.
Вообще задача простая: получить из View адрес файла, передать его в ExcelImporter и вызвать метод Import(). Может, вообще все вопросы неправильные, и это делается как-то по-другому? И суть вопросов не в том как это сделать вообще, а как сделать правильно, религиозно верно, так сказать, а не мартышкиным методом "абы работало" :)
PS Прошу прощения за некоторое нарушение правил SO, за несколько вопросов сразу, но как видите они взаимосвязаны, и создавать несколько отдельных тем показалось лишним.
UPD1
@andrey-k
Мне сложно было представить такую ситуацию, что импорт происходит сразу после ввода имени файла, минуя нажатие кнопки
Ну поле, оно же TextBox, существует постольку-поскольку, чтобы была возможность скопипастить адрес файла, но в осноном конечно же выбор через винапишный OpenFileDialog. Хотя всё это сводится к одному - по сути что ввод ручками пользователя, что OpenFileDialog возвращает строкой путь к файлу. Разумеется, его нужно проверить. Но не вижу никакого смысла вынуждать пользователя тыкаться лишний раз ещё в какие-то кнопки после указания файла. Выбор документа и выуживание из него определённых данных - это первые 50% функционала.


Ответ

По вопросу 1: View не должно знать, кто и как меняет свойства в VM. Завтра вы поменяете VM, и при этом вы не должны менять ещё и View. Пусть каждый из уровней заботится только о себе.
По поводу OnPropertyChanged("ExcelPath"); //?: лучше писать, конечно, так:
void NotifyPropertyChanged([CallerMemberName] string propertyName = null) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); }
и пользоваться просто NotifyPropertyChanged()
string excelPath; public string ExcelPath { get { return excelPath; } set { if (excelPath != value) { excelPath = value; NotifyPropertyChanged(); } } }
По поводу того, когда обновлять модель — это решать вам и только вам. Может быть, обновлять модель сразу неправильно, а нужно подождать, пока пользователь скомандует «вот сейчас давайте». А может быть, нужно обновлять её как можно скорее. Вы как архитектор вашего приложения должны решать такие вопросы сами.
В любом случае, обновление модели — дело VM, а не наоборот.
По вопросу 2.1 — технически так делать можно, да (но не забудьте NotifyPropertyChanged()). Вопрос в том, правильно ли это для вашего случая. Например, если модель бежит не в главном потоке, то доступ к ней из UI-потока может быть неверным.
По вопросу 3 — не имеет ровно никакого значения. Все три значат одно и то же. (Я всё же не использовал бы ExcelPath, чтобы не идти лишний раз через getter, но это вопрос личных предпочтений.)
По поводу вопроса 4 — опять-таки это не диктуется паттерном MVVM. Всё определяется лично вами. Я бы делал так: при выставлении setter'а проверял значение на правильность, проверял, можно ли запускать импорт, и при этом условии запускал бы:
string excelPath; public string ExcelPath { get { return excelPath; } set { if (excelPath == value) return; excelPath = value; NotifyPropertyChanged(); OnPathChanged(); } }
async void OnPathChanged() { if (!IsValidPath(excelPath)) { SetInvalidFlag(); // so UI can pick it up return; }
await BookNewImport(); }
ExcelImporter currentImporter, pendingImporter; async Task BookNewImport() { var importer = new ExcelImporter(ExcelPath); if (currentImporter != null) { pendingImporter = importer; await currentImporter.CancelAsync(); if (pendingImporter != importer) // new import booked return; // so not run ours } currentImporter = importer; await currentImporter.ImportAsync(); if (currentImporter == importer) currentImporter = null; // else there's other importer running }
Это лучше тем, что модель дёргается только после всех проверок. Плюс, поскольку импорт — процесс по сути длительный, я бы сделал к нему async-интерфейс, и не блокировал вызывающий поток (как это сделано в сниппете выше).

Как использовать перенос строки в левой части sed?

Отслеживаю логи через tailf (tail -f). Для удобства отображения хотелось бы после каждой строки добавлять пустую строку.
Например:
$ tailf /var/log/some.log log1 log2 log3
$ tailf /var/log/some.log | magic log1
log2
log3
Пробовал через sed двумя способами, но получаю то же без изменений. Идея в том, чтобы поматчить перенос строки и заменить его на два переноса. Общий синтаксис такой: sed 's/substitute_this/to_this/g'
Способ 1: вставить перенос строки как $'
'
$ tailf /var/log/some.log | sed "s/$'
'/test/g" log1 log2 log3
Похоже, что $'
' не матчится на переносы строк в моем логе.
Способ 2: вставить перенос строку как перенос строки при вводе команды:
$ tailf /var/log/some.log | sed "s/ > /test/g" sed: -e expression #1, char 2: unterminated `s' command
$ tailf /var/log/some.log | sed "s/\ /test/g" sed: -e expression #1, char 0: no previous regular expression
Если бы это был shell-скрипт, можно было бы использовать хак
newline=' '
Но я-то хочу "на ходу" использовать. Сделать фукцию или alias тоже не подойдёт, т.к. я работаю с большим количеством хостов и не имею возможности индивидуально настраивать .bashrc
Собственно, вопрос: что должно быть на месте magic?


Ответ

Еще вариант с sed:
tailf foo.log
init.lxc 1455930731.917 ERROR lxc_initutils - initutils.c:mount_fs:36 - failed to mount /proc : Device or resource busy init.lxc 1455930758.674 ERROR lxc_initutils - initutils.c:mount_fs:36 - failed to mount /proc : Device or resource busy init.lxc 1455986152.381 ERROR lxc_initutils - initutils.c:mount_fs:36 - failed to mount /proc : Device or resource busy init.lxc 1455986234.349 ERROR lxc_initutils - initutils.c:mount_fs:36 - failed to mount /proc : Device or resource busy
tailf foo.log | sed 'a\ '
init.lxc 1455930731.917 ERROR lxc_initutils - initutils.c:mount_fs:36 - failed to mount /proc : Device or resource busy
init.lxc 1455930758.674 ERROR lxc_initutils - initutils.c:mount_fs:36 - failed to mount /proc : Device or resource busy
init.lxc 1455986152.381 ERROR lxc_initutils - initutils.c:mount_fs:36 - failed to mount /proc : Device or resource busy
init.lxc 1455986234.349 ERROR lxc_initutils - initutils.c:mount_fs:36 - failed to mount /proc : Device or resource busy

Различные положения экранов для разных устройств

Здравствуйте. Появилась проблема, заключающаяся в том, чтобы ограничить положение изображения на экране. Если конкретно, то нужно, чтобы на tablet/phablet устройствах приложение работало в landscape режиме, а на всех остальных - в portrait режиме. Как это можно реализовать? Заранее благодарю за ответ.


Ответ

В ресурсах для разных размеров экранов вы можете создать файл для хранения булевских переменных, и для смартфона хранить false, а для планшетов true. Далее в активити вызывать метод setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); проверяя перед этом значение и файле. Хороший пример здесь

Ubuntu 16.04 LTS не переходит в ждущий режим

После обновления до Ubuntu 16.04 LTS мой ноутбук перестал переходит в ждущий режим. Просто гаснет экран, но ноутбук продолжает работать, на какие либо действия со стороны пользователя перестает отвечать. Из такого состояния его никак не вывести, только с помощью перезагрузки через кнопку питания.
Ноутбук hp pavilion dv6 6169er. В Ubuntu 15.10 все работало нормально.
После установки сделал очистку системы от неиспользуемых пакетов и удалил старые ядра. Возможно после этих действий, я случайно удалил библиотеку, отвечающую за корректный переход в "ждущий режим", Но это только предположение, все делалось через стандартный менеджер пакетов.


Ответ

Как я понял, это нормальная практика пока. У меня аналогичная ситуация. Вот, что пишут в сети по этому поводу: http://www.omgubuntu.co.uk/2016/03/ubuntu-drops-amd-catalyst-fglrx-driver-16-04
Ещё можешь попробовать поставить новое ядро, вот, что нарыл я по этому поводу: http://lifepluslinux.blogspot.ru/2016/04/ubuntu-1604-wont-wake-up-from-suspend.html Мне, кстати, это помого. =)

Доступ к serial port из nativescript

Как можно работать на android с usb serial port из nativescript в anroid? Я не имею представления как работают с ним на java и не могу найти нечего подобного в api. Я читал что обычные npm модули не будут работать на nativescript , как тогда вообще можно докопаться до serial port? Возможно как то через файловую систему можно долезть до serial port?


Ответ

К сожалению похоже что нету вариантов доступа к serial port из nativescript Из подобных кросс платформенных библиотек, получить доступ получилось в phonegap, через плагин cordovarduino всё работает, не скажу что идеально, но работает, в отличии от nativescript в котором как оказалось нету доступа к serial port.

Ошибка spring security на wildfly

При логине в приложение на spring-security выдает следующее сообщение:
{"timestamp":1464679377206,"status":999,"error":"None","message":"No message available"}
и редиректит на error-page в приложении развернутом на wildfly, при запуске spring-boot такой проблемы нет. При чем, если затем вбить правильный адрес руками все работает корректно. Класс запуска приложения:
@SpringBootApplication public class Application extends SpringBootServletInitializer {
public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); }
@Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(applicationClass); }
private static Class applicationClass = Application.class;
}
Thymeleaf форма логина

ORACLE. Необходимо обрезать вывод SQL запроса

Запрос
select LTRIM(RUN_DURATION ) from SYS.USER_SCHEDULER_JOB_RUN_DETAILS WHERE LOG_ID = 218737;
возвращает:+000 00:01:27. Мне нужны только секунды т.е. от 0 до 59 - два последних символа
Сам догадался только до TRIM
select LTRIM(RUN_DURATION , '+000 00:00')) from SYS.USER_SCHEDULER_JOB_RUN_DETAILS WHERE LOG_ID = 218737;
Но значение минут может быть разное и данный вариант мне не подходит.
Как отформатировать вывод до двух знаков справа?


Ответ

select SUBSTR(RUN_DURATION,12) from SYS.USER_SCHEDULER_JOB_RUN_DETAILS ...
Берем символы начиная с 12. Если надо вырезать из середины, то третьим параметром substr можно задавать длину.

диагностика с помощью telnet

как при помощи программы telnet проверить, доступен ли указанный tcp-порт на указанной машине, и слушает ли этот порт какая-нибудь программа?

приветствуются канонические ответы с примерами для разных операционных систем и реализаций программы telnet


Ответ

unix-подобные операционные системы
вероятно, чаще всего здесь можно встретить bsd- и gnu-реализации: netkit-telnet и inetutils-telnet. для указанной диагностики разница между ними несущественна.

пример неудачного подключения к порту 12345 на каком-нибудь из серверов, в ip-адрес которого резолвится имя github.com
$ telnet github.com 12345 Trying 192.30.253.113...
прервать неудачную попытку можно с помощью ctrl+c

пример удачного подключения к тому же серверу на порт 22
$ telnet 192.30.253.113 22 Trying 192.30.253.113... Connected to 192.30.253.113. Escape character is '^]'. SSH-2.0-libssh-0.7.0
последняя строчка здесь — это уже информация от программы, слушающей 22 порт на опрашиваемом сервере.
если соединение сразу же не было разорвано слушающей программой (это зависит от её реализации и настроек), то прервать telnet-сессию можно, нажав предложенную программой комбинацию ctrl+], а затем клавишу enter, после чего появится приглашение программы telnet
telnet>
в котором можно ввести команду q (или полностью — quit) и нажать клавишу enter
Microsoft Windows
Действия практически идентичны варианту для unix-подобных ОС. В Windows имеется встроенный telnet-клиент, но он может быть отключен. Чтобы его включить нужно выполнить шаги, описанные на сайте Microsoft
Когда всё готово, запустить telnet-клиент можно так:
Пуск - Выполнить - telnet - ОК
В открывшемся консольном окне будут видны следующие строки:
Welcome to Microsoft Telnet Client Escape Character is 'CTRL+]' Microsoft Telnet>
Чтобы попытаться открыть тот или иной адрес и порт нужно написать букву o, а затем адрес и порт. Например:
Microsoft Telnet> o github.com 12345

Слияние веток, в одной из которых файлы были не переименованы, а удалены и созданы в другом каталоге


В последнем коммите ветки hometype есть изменения, которые должны быть в ветке master, но влить ее в мастер не получается, потому что в коммите Rename были изменены названия пакетов, что в общем означает новое местоположение файла/класса.
Получается, что в ветке master файлы, для которых есть изменения в hometype, находятся в других местах.
Как их теперь объединить, если это вообще возможно?


Ответ

судя по всему, git «не знает» о произведённых (в ветке master) переименованиях, и не может «связать» изменения, произведённые в другой (hometype) ветке (со «старыми» файлами), с файлами «новыми».

один из возможных (но не самый «изящный» из) путей «влить» изменения из другой ветки (hometype) в основную — получить патч из изменений, внесённых в ветке hometype, вручную исправить в нём имена файлов, и «наложить» патч в основной ветке командой git apply файл.с.патчем (см. man git-apply).
совет: тренироваться лучше на тестовой ветке, создав её командой git checkout -b тестовая-ветка исходная-ветка

изменять надо будет такие примерно строки:
diff --git a/file1 b/file1 index 88621c5..af3bc11 100644 --- a/file1 +++ b/file1
здесь имя файла, которое надо будет вручную исправить — file1, оно встречается четыре раза, и все четыре его появления надо исправить. будьте внимательны: так как у вас были исправления, судя по всему, нескольких файлов, то блоков таких будет больше одного.

получить патч из изменений, внесённых commit-ом, зная его хэш, можно, например, так:
$ git diff хэш^ хэш
запись хэш^ означает в данном случае «родительский» (parent) commit для данного commit-а
см. man git-diff на предмет подробностей об этой команде и man gitrevisions о смысле ^ и подобных модификаторов.

в будущем я бы порекомендовал переименования файлов/каталогов делать отдельным коммитом (отдельным от изменения содержимого этих же файлов). тогда программа git без дополнительных указаний должна распознавать такие переименования.
другой путь решения озвученной в вопросе проблемы (он более «изящен», но требует довольно длинного описания) как раз и основывается на указании программе git, какую долю изменений в файле, «удалённом в одном месте и созданном в другом», следует считать переименованием. для команды merge это делается с помощью опции rename-threshold стратегии recursive. см. описание этой опции в man git-merge и опции -M в man git-diff

Postgres ограничить время запроса в SQL

если я напишу
set statement_timeout to 1000; select * from bigtable
то это ограничит время действия только этого скрипта? или моей сессии? или глобально для всего сервера?


Ответ

документация
If SET (or equivalently SET SESSION) is issued within a transaction that is later aborted, the effects of the SET command disappear when the transaction is rolled back. Once the surrounding transaction is committed, the effects will persist until the end of the session, unless overridden by another SET.
Т.е. это изменение настройки на сессию.
Если set был вызван внутри транзакции и транзакция была отменена, то значение настройки откатится на предыдущее. При коммите транзакции или вызове вне транзакции - будет продолжать действовать на текущую сессию и настройка может быть изменена другим set'ом.

Уведомление о новом письме в Outlook

Имеется плагин в outlook для уведомления и новом письме в дополнительном ящике. Но проблема в том что когда приходит новое письмо и Outlook находится в свёрнутом состоянии то уведомлении не отображается
Код ниже:
private void ThisAddIn_Startup(object sender, EventArgs e) {
var ns = Application.GetNamespace("MAPI"); const string recipientName = "mymail@mydomain.com";
var recip = ns.CreateRecipient(recipientName); recip.Resolve();
if (!recip.Resolved) return; var inboxFolder = ns.GetSharedDefaultFolder(recip, Outlook.OlDefaultFolders.olFolderInbox); inboxFolder.Items.ItemAdd += InboxFolderItemAdded;
}
private static void InboxFolderItemAdded(object item) { if (item is Outlook.MailItem) { MessageBox.Show("Новое сообщение", "new message", MessageBoxButtons.OK, MessageBoxIcon.Information); } }
Прошу оказать помощь в решении проблемы


Ответ

Последуйте официальному примеру: сделайте Items полем. Проблема в том, что подписка действует до тех пор, пока объект жив. А после выхода из метода ThisAddIn_Startup() переменная inboxFolder и, соответственно, поле Items становится доступным для сборки мусора. Также имейте в виду, что согласно документации на это событие, оно не триггерится, если приходит сразу много сообщений (насколько много -- не уточняется :)).
Outlook.Items _items;
private void ThisAddIn_Startup(object sender, EventArgs e) {
var ns = Application.GetNamespace("MAPI"); const string recipientName = "mymail@mydomain.com";
var recip = ns.CreateRecipient(recipientName); recip.Resolve();
if (!recip.Resolved) return; var inboxFolder = ns.GetSharedDefaultFolder(recip, Outlook.OlDefaultFolders.olFolderInbox); _items = inboxFolder.Items; _items.ItemAdd += InboxFolderItemAdded;
}
private static void InboxFolderItemAdded(object item) { if (item is Outlook.MailItem) { MessageBox.Show("Новое сообщение", "new message", MessageBoxButtons.OK, MessageBoxIcon.Information); } }

Сочетания клавиш в консоли, ввод-вывод

Учу С++. Хочу разобраться, как работает ввод-вывод в консоли. Уже понял, что если вводишь в cin слова через пробел/табуляцию, он считывает их через этот данный разделитель и выводит в cout. К примеру, ввожу "hello man", - выводит "helloman". Это нормально, все ясно. Также я узнал, что CTRL+Z останавливает процесс и означает символ конца файлы при считывании. Нажимаю ctrl+Z (перед этим не ввожу символы) и процесс завершается.
Вопрос 1: почему, если я ввожу, к примеру "hello ^Z" (^Z я именно ввел сочетанием клавиш, а не вручную сначала ^, потом Z), то сначала в потоке вывода появляется hello, а за ним ничего не появляется, только если нажму enter, выводится вопросительный знак в квадратике! (что это вообще такое?)
Вопрос 2: Если потом cin считывает символы через разделители, почему тогда он не считал сначала hello, потом ^Z и в соответствии с командой не завершил процесс, считав символ конца файла, как его называют в книге Страуструп. Объясните, пожалуйста.
int main() {
string current;
while(cin>>current){
cout << current; } }


Ответ

Это особенности работы cmd.exe
cmd.exe отправляет текст в поток ввода построчно, и Ctrl+Z закрывает поток ввода только если до него не были введены другие символы. В этом можно убедиться переписав программу следующим образом:
#include #include int main() { std::string s; while (std::cin >> s) for (int b : s) std::cout << std::hex << b << ' '; }
Если что-то было введено до ^Z, то он интерпретируется как \x1a (символ замены), и всё что введено в этой строке далее - игнорируется:
> test.exe 1^Z23 4 31 1a 34
При этом по умолчанию std::istream не считает \1a разделителем слов.
Если до ^Z ничего не вводить, то поток закрывается, а последующие символы в строке игнорируются:
> test.exe 123 31 32 33 ^Z456
>

Почему результат SELECT COUNT(*) FROM information_schema.tables -1?

Может мне кто-то объяснить в чем моя ошибка, что я получаю результыт от SQL-запроса -1? Вот мой код:
public static void proveIfQueryExecuted(String query, String database) { String sqlConnectionString = String.Format("Server = server; Database = {0}; Trusted_Connection = True;", database);
using (SqlConnection connection = new SqlConnection(sqlConnectionString)) { var server = new Server(new ServerConnection(connection)); var result = server.ConnectionContext.ExecuteNonQuery(query);
if (result != 0) { Console.WriteLine("tables exist"); } else { Console.WriteLine("No tables exist"); }
} }


Ответ

В данном случае вместо метода ExecuteNonQuery следует использовать метод ExecuteScalar
var result = server.ConnectionContext.ExecuteScalar(query);
Метод ExecuteNonQuery обычно используется для выполнения команд, которые не предполагают возвращения какого-либо результирующего значения.
Тогда как ExecuteScalar используется для выполнения команд, предполагающих возвращение какого-либо скалярного результирующего значения.

Есть ли универсальный способ для пропорционального уменьшения всех элементов сайта, в зависимости от разрешения экрана?

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


Ответ

Не утверждаю, что метод универсальный, т.к. требует поддержки CSS3, но посмотрите в сторону свойства CSS transform и @media Например здесь приводится вариант его использования для увеличения до 150%:
body { transform: scale(1.5); transform-origin: 0 0; }
С помощью CSS запроса @media можно установить требуемые значения для различных разрешений экрана, а также комбинировать их с дополнительными условиями, такими как ориентация экрана или тип устройства (более подробно об использовании @media здесь или на русском здесь):
@media all (max-width: 800px) { body { transform: scale(1.0); transform-origin: 0 0; } } @media screen and (max-width: 1024px) and (orientation: landscape) and (device-aspect-ratio: 16/9) { body { transform: scale(1.1); transform-origin: 0 0; } }

Обращение к git-dir через work-tree без симлинка

Есть ~/work/project и ~/Dropbox/, в котором project → ~/work/project
В самом ~/work/project папка .git вынесена в ~/work/project-git
Так вот, как без создания симлинка можно по прежнему вызывать git в ~/work/project?
Симлинк использовать нельзя так как дропбокс скопирует все содержимое. Может, ему можно как-то сказать не делать этого?


Ответ

адресоваться к каталогу с хранилищем (если он находится не в каталоге .git в корне проекта) можно разными способами.
в вашем случае подойдёт адресация с помощью файла .git, описанная, например, в этом ответе

покажу на примере:
рабочую копию (workdir) вы хотите держать в каталоге /путь/к/проекту а само хранилище (gitdir) хотите держать в каталоге /путь/к/хранилищу

сделайте текущим каталог /путь/к/проекту
$ cd /путь/к/проекту инициализируйте хранилище:
для программы git версии 1.7.5 или выше
$ git --separate-git-dir /путь/к/хранилищу init
в каталоге /путь/к/хранилищу будет создано полноценное хранилище со всеми необходимыми файлами/каталогами: branches, config, description и т.д., а в текущем каталоге будет создан файл .git с «отсылкой» к месторасположению хранилища, такого содержания:
gitdir: /путь/к/хранилищу для программы git версии ниже 1.7.5 надо будет проделать описанное в полу-ручном режиме:
$ git --git-dir=/путь/к/хранилищу --work-tree=. init $ echo "gitdir: /путь/к/хранилищу" > .git

для случая, если хранилище уже существует в каталоге .git в корне вашего проекта, потребуются такие действия:
сделайте текущим каталог /путь/к/проекту
$ cd /путь/к/проекту установите явно в конфигурации хранилища путь к рабочему каталогу:
$ git config core.worktree /путь/к/проекту переместите каталог .git в нужное место с нужным именем (целевой каталог /путь/к/хранилищу не должен существовать в этот момент, иначе файлы/каталоги хранилища попадут в /путь/к/хранилищу/.git):
$ mv .git /путь/к/хранилищу создайте файл .git в текущем каталоге:
$ echo "gitdir: /путь/к/хранилищу" > .git

Сделать, чтоб определенные объекты не исчезали при уменьшении масштаба - google map js api v3

Возможно ли на гугл картах сделать, чтобы определенные объекты были видны при любом масштабе? Например, по умолчанию местные дороги исчезают после зума меньше 8, остаются только только автобаны, потом после зума 6 исчезают и автобаны. Так вот можно ли как-то сделать, чтоб все, например, дороги были видны при любом зуме?


Ответ

Можно изменить цвет, вес, прозрачность и некоторые другие свойства объектов, можно вообще их сделать невидимыми, но видимость в зависимости от зума менять нельзя

Правильная сетка на bootstrap

Вот два варианта одной и той же верстки. Выглядят одинаково но подход к ним разный. Берут сомнения что какой то из них не правильный. Вопрос: какой из этих вариантов правильный?
№1:

Шапка сайта
Левый блок
Основной блок
Подвал сайта

№2:
Шапка сайта
Левый блок
Основной блок
Подвал сайта


Ответ

При условии, что вы не указываете для .row и .col отличные от нуля margin и padding (а указывать их, к слову, не следует никогда) - внешне оба варианта будут выглядеть одинаково.
Мало того, в первом варианте вы можете даже не использовать блок .clearfix. Потому что .col-sm-4 и .col-sm-8 и так займут всю ширину экрана, и следующий .col, каким бы он ни был - гарантированно будет перенесен на следующую строку.
Какой из вариантов выбрать - зависит от ситуации.
Первый вариант лучше подходит тогда, когда содержимое сетки строится вами динамически. Например, когда вы можете взять записи из БД, и последовательно, в цикле, выводить их в .col-блоках в верстке. Блоки просто будут переноситься на следующие строки при необходимости. При условии, что блоки одной строки в сумме будут давать 12, и при условии, что высоты содержимого колонов будут одинаковы.
Второй вариант лучше подходит, когда все блоки в сетке заранее вам известны. За счет .row вы ограждаете колонки разных строк друг от друга, читабельность при таком способе - выше.

Нестандартное (для меня) поведение параметров в контролере asp.net core

Когда-то в Web Api 2 я мог написать такой action:
public class INP { public string value { get; set; } } public string Post(INP con) { return con.value; }
и все отлично работало как с ContentType: application/x-www-form-urlencoded отправленным от клиента, так и с ContentType: application/json
Однако, в asp.net core все не так просто: с вышеприведенным кодом ContentType: application/x-www-form-urlencoded работает, а вот ContentType: application/json оставляет мне просто null в коде. Если обрамлять параметр атрибутом [FromBody], то ситуация меняется: с ContentType: application/json все отлично, а вот с ContentType: application/x-www-form-urlencoded мне вовсе приходит ответ вида 415 Unsupported Media Type
Итак, сам вопрос: как в asp.net core написать action, который бы принимал мне параметр разных ContentType'ов, как это было в Web Api 2? И почему поведение изменилось?


Ответ

Этот вопрос можно решить таким путем: нужно создать две разные Action method-ы, которые смогут специфически байндить данные необходимые для отправки, а затем делегировать обработку вызовов к общему методу.
Например:
public class MyController : Controller { //для ContentType: application/x-www-form-urlencoded [HttpPost] public IActionResult Index(MyClass myclass){ return DoSomething(myclass); }
//и для ContentType: application/json [HttpPost] public IActionResult IndexFromBody([FromBody] MyClass myclass){ return DoSomething(myclass); }
private IActionResult DoSomething(MyClass myclass){ // сделай тут что нибудь с myclass // ... // ... return Json(myclass); } }
Зачем Изменения?
Разве раньше не было попроще? Может быть, но по мнению Дэмиана Эдвардса в сообществе Standup, основная причина это безопасность, в частности - предотвращение Межсайтовой подделки запросов (CSRF)
UPDATE
Вы должны решить эту проблему routing-ом, но если вы попытаетесь отобразить две вышеуказанные действия по одному и тому же маршруту, это приведет к ошибке. Решением этого будет создание пользовательского маршрута и вызов соответствующего метода по заголовку. Я понимаю что это требует больше усилий, чем этого стоит, но они говорят что эти изменения в целях безопасности, я не стал глубоко изучать как именно это предотвращает CSRF. Вы можете погуглить или же посмотреть тут